diff --git a/apps/website/views.py b/apps/website/views.py index 3e19dec6cc..62a0f8f372 100644 --- a/apps/website/views.py +++ b/apps/website/views.py @@ -8,6 +8,7 @@ from django.contrib.auth.models import User from django.utils import simplejson from apps.news.models import NewsEntry +import functions_db """ This file contains the generic, assorted views that don't fall under one of @@ -23,6 +24,9 @@ def page_index(request): pagevars = { "page_title": "Front Page", "news_entries": news_entries, + "players_connected": functions_db.num_connected_players(), + "players_registered": functions_db.num_total_players(), + "players_connected_recent": functions_db.num_recently_connected_players(), } context_instance = RequestContext(request) diff --git a/cmdhandler.py b/cmdhandler.py index 28b3977f9b..1cfb3e641e 100755 --- a/cmdhandler.py +++ b/cmdhandler.py @@ -61,7 +61,7 @@ def handle(cdat): # This will hold the reference to the command's function. cmd = None - + if session.logged_in: # Store the timestamp of the user's last command. session.cmd_last = time.time() @@ -75,6 +75,10 @@ def handle(cdat): # Player-visible idle time, not used in idle timeout calcs. session.cmd_last_visible = time.time() + # Just in case. Prevents some really funky-case crashes. + if len(parsed_input['root_cmd']) == 0: + raise UnknownCommand + # Shortened say alias. if parsed_input['root_cmd'][0] == '"': parsed_input['splitted'].insert(0, "say") diff --git a/commands/general.py b/commands/general.py index 7564f24602..710de175c5 100644 --- a/commands/general.py +++ b/commands/general.py @@ -89,9 +89,9 @@ def cmd_inventory(cdat): money = int(pobject.get_attribute_value("MONEY", default=0)) if money == 1: - money_name = functions_db.get_server_config("MONEY_NAME_SINGULAR") + money_name = gameconf.get_configvalue("MONEY_NAME_SINGULAR") else: - money_name = functions_db.get_server_config("MONEY_NAME_PLURAL") + money_name = gameconf.get_configvalue("MONEY_NAME_PLURAL") session.msg("You have %d %s." % (money,money_name)) diff --git a/commands/unloggedin.py b/commands/unloggedin.py index 66e49d992f..333ead7e5f 100644 --- a/commands/unloggedin.py +++ b/commands/unloggedin.py @@ -22,7 +22,7 @@ def cmd_connect(cdat): password = cdat['uinput']['splitted'][2] # Match an email address to an account. - email_matches = functions_db.get_dbref_from_email(uemail) + email_matches = functions_db.get_user_from_email(uemail) autherror = "Specified email does not match any accounts!" # No username match @@ -36,7 +36,6 @@ def cmd_connect(cdat): if not user.check_password(password): session.msg(autherror) else: - user = email_matches[0] uname = user.username session.login(user) @@ -70,7 +69,7 @@ def cmd_create(cdat): # Search for a user object with the specified username. account = User.objects.filter(username=uname) # Match an email address to an account. - email_matches = functions_db.get_dbref_from_email(email) + email_matches = functions_db.get_user_from_email(email) if not account.count() == 0: session.msg("There is already a player with that name!") @@ -79,8 +78,8 @@ def cmd_create(cdat): elif len(password) < 3: session.msg("Your password must be 3 characters or longer.") else: - functions_db.create_user(cdat, uname, email, password) - + functions_db.create_user(cdat, uname, email, password) + def cmd_quit(cdat): """ We're going to maintain a different version of the quit command diff --git a/functions_db.py b/functions_db.py index 43022db289..63ed391a15 100644 --- a/functions_db.py +++ b/functions_db.py @@ -1,20 +1,42 @@ import sets +from datetime import datetime, timedelta from django.db import connection from django.contrib.auth.models import User from apps.objects.models import Object, Attribute -from apps.config.models import ConfigValue import defines_global as defines_global import gameconf """ Common database functions. """ -def get_server_config(configname): +def num_total_players(): """ - Returns a server config value. + Returns the total number of registered players. """ - return ConfigValue.objects.get(conf_key__iexact=configname).conf_value + return User.objects.count() + +def get_connected_players(): + """ + Returns the a QuerySet containing the currently connected players. + """ + return Object.objects.filter(nosave_flags__contains="CONNECTED") + +def num_connected_players(): + """ + Returns the number of connected players. + """ + return get_connected_players().count() + +def num_recently_connected_players(days=7): + """ + Returns a QuerySet containing the player User accounts that have been + connected within the last days. + """ + end_date = datetime.now() + tdelta = timedelta(days) + start_date = end_date - tdelta + return User.objects.filter(last_login__range=(start_date, end_date)).count() def is_unsavable_flag(flagname): """ @@ -211,9 +233,9 @@ def is_dbref(dbstring): else: return True -def get_dbref_from_email(uemail): +def get_user_from_email(uemail): """ - Returns a player's dbref when given an email address. + Returns a player's User object when given an email address. """ return User.objects.filter(email__iexact=uemail) diff --git a/session.py b/session.py index 67add8e201..d55e714493 100755 --- a/session.py +++ b/session.py @@ -1,4 +1,5 @@ import time, sys +from datetime import datetime import cPickle as pickle from twisted.conch.telnet import StatefulTelnetProtocol @@ -147,11 +148,16 @@ class SessionProtocol(StatefulTelnetProtocol): session_mgr.disconnect_duplicate_session(self) self.msg("You are now logged in as %s." % (self.name,)) pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(),), exclude=pobject) - cdat = {"session": self, "uinput":'look', "server": self.factory.server} - cmdhandler.handle(cdat) + self.execute_cmd("look") functions_general.log_infomsg("Login: %s" % (self,)) + + # Update their account's last login time. + user.last_login = datetime.now() + user.save pobject.set_attribute("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),)) pobject.set_attribute("Lastsite", "%s" % (self.address[0],)) + + # Load their channel selection from a pickled attribute. self.load_user_channels() def msg(self, message): diff --git a/webtemplates/prosimii/index.html b/webtemplates/prosimii/index.html index 9bc4ca9766..5f93668997 100644 --- a/webtemplates/prosimii/index.html +++ b/webtemplates/prosimii/index.html @@ -77,15 +77,12 @@
-

Standards

-

Prosimii is 100% compliant with - XHTML 1.0 Strict and - uses CSS. - [Validate - XHTML]

- -

Unlike this design’s inspiration, no tables have been used to layout elements - and text.

+ +

Players

+

+ There are currently {{players_connected}} connected, + and a total of {{players_registered}} registered. Of these, {{players_recent}} were created this week, and {{players_connected_recent}} have connected within the last seven days. +