Lots of goodies in this one. More work on the default web front page, a few extra utility functions for functions_db as well. Some cleanup in the session code to use some of the new abstraction I added a while back. Player's last login time is now also set on the User object. Issue 28: Forward slashes causing crashes, found by Kuros, fixed by me.
This commit is contained in:
parent
270db06820
commit
e2cc754441
7 changed files with 57 additions and 25 deletions
|
|
@ -8,6 +8,7 @@ from django.contrib.auth.models import User
|
||||||
from django.utils import simplejson
|
from django.utils import simplejson
|
||||||
|
|
||||||
from apps.news.models import NewsEntry
|
from apps.news.models import NewsEntry
|
||||||
|
import functions_db
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This file contains the generic, assorted views that don't fall under one of
|
This file contains the generic, assorted views that don't fall under one of
|
||||||
|
|
@ -23,6 +24,9 @@ def page_index(request):
|
||||||
pagevars = {
|
pagevars = {
|
||||||
"page_title": "Front Page",
|
"page_title": "Front Page",
|
||||||
"news_entries": news_entries,
|
"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)
|
context_instance = RequestContext(request)
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,10 @@ def handle(cdat):
|
||||||
# Player-visible idle time, not used in idle timeout calcs.
|
# Player-visible idle time, not used in idle timeout calcs.
|
||||||
session.cmd_last_visible = time.time()
|
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.
|
# Shortened say alias.
|
||||||
if parsed_input['root_cmd'][0] == '"':
|
if parsed_input['root_cmd'][0] == '"':
|
||||||
parsed_input['splitted'].insert(0, "say")
|
parsed_input['splitted'].insert(0, "say")
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,9 @@ def cmd_inventory(cdat):
|
||||||
|
|
||||||
money = int(pobject.get_attribute_value("MONEY", default=0))
|
money = int(pobject.get_attribute_value("MONEY", default=0))
|
||||||
if money == 1:
|
if money == 1:
|
||||||
money_name = functions_db.get_server_config("MONEY_NAME_SINGULAR")
|
money_name = gameconf.get_configvalue("MONEY_NAME_SINGULAR")
|
||||||
else:
|
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))
|
session.msg("You have %d %s." % (money,money_name))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ def cmd_connect(cdat):
|
||||||
password = cdat['uinput']['splitted'][2]
|
password = cdat['uinput']['splitted'][2]
|
||||||
|
|
||||||
# Match an email address to an account.
|
# 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!"
|
autherror = "Specified email does not match any accounts!"
|
||||||
# No username match
|
# No username match
|
||||||
|
|
@ -36,7 +36,6 @@ def cmd_connect(cdat):
|
||||||
if not user.check_password(password):
|
if not user.check_password(password):
|
||||||
session.msg(autherror)
|
session.msg(autherror)
|
||||||
else:
|
else:
|
||||||
user = email_matches[0]
|
|
||||||
uname = user.username
|
uname = user.username
|
||||||
session.login(user)
|
session.login(user)
|
||||||
|
|
||||||
|
|
@ -70,7 +69,7 @@ def cmd_create(cdat):
|
||||||
# Search for a user object with the specified username.
|
# Search for a user object with the specified username.
|
||||||
account = User.objects.filter(username=uname)
|
account = User.objects.filter(username=uname)
|
||||||
# Match an email address to an account.
|
# 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:
|
if not account.count() == 0:
|
||||||
session.msg("There is already a player with that name!")
|
session.msg("There is already a player with that name!")
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,42 @@
|
||||||
import sets
|
import sets
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from apps.objects.models import Object, Attribute
|
from apps.objects.models import Object, Attribute
|
||||||
from apps.config.models import ConfigValue
|
|
||||||
import defines_global as defines_global
|
import defines_global as defines_global
|
||||||
import gameconf
|
import gameconf
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Common database functions.
|
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> 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):
|
def is_unsavable_flag(flagname):
|
||||||
"""
|
"""
|
||||||
|
|
@ -211,9 +233,9 @@ def is_dbref(dbstring):
|
||||||
else:
|
else:
|
||||||
return True
|
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)
|
return User.objects.filter(email__iexact=uemail)
|
||||||
|
|
||||||
|
|
|
||||||
10
session.py
10
session.py
|
|
@ -1,4 +1,5 @@
|
||||||
import time, sys
|
import time, sys
|
||||||
|
from datetime import datetime
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
|
|
||||||
from twisted.conch.telnet import StatefulTelnetProtocol
|
from twisted.conch.telnet import StatefulTelnetProtocol
|
||||||
|
|
@ -147,11 +148,16 @@ class SessionProtocol(StatefulTelnetProtocol):
|
||||||
session_mgr.disconnect_duplicate_session(self)
|
session_mgr.disconnect_duplicate_session(self)
|
||||||
self.msg("You are now logged in as %s." % (self.name,))
|
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)
|
pobject.get_location().emit_to_contents("%s has connected." % (pobject.get_name(),), exclude=pobject)
|
||||||
cdat = {"session": self, "uinput":'look', "server": self.factory.server}
|
self.execute_cmd("look")
|
||||||
cmdhandler.handle(cdat)
|
|
||||||
functions_general.log_infomsg("Login: %s" % (self,))
|
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("Last", "%s" % (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),))
|
||||||
pobject.set_attribute("Lastsite", "%s" % (self.address[0],))
|
pobject.set_attribute("Lastsite", "%s" % (self.address[0],))
|
||||||
|
|
||||||
|
# Load their channel selection from a pickled attribute.
|
||||||
self.load_user_channels()
|
self.load_user_channels()
|
||||||
|
|
||||||
def msg(self, message):
|
def msg(self, message):
|
||||||
|
|
|
||||||
|
|
@ -77,15 +77,12 @@
|
||||||
|
|
||||||
<div class="rowOfBoxes dividingBorderAbove">
|
<div class="rowOfBoxes dividingBorderAbove">
|
||||||
<div class="quarter noBorderOnLeft">
|
<div class="quarter noBorderOnLeft">
|
||||||
<h1>Standards</h1>
|
|
||||||
<p><span lang="la">Prosimii</span> is 100% compliant with
|
|
||||||
<acronym title="eXtensible HyperText Markup Language">XHTML</acronym> 1.0 Strict and
|
|
||||||
uses <acronym title="Cascading Style Sheets">CSS</acronym>.
|
|
||||||
<span class="doNotPrint">[Validate
|
|
||||||
<a href="http://validator.w3.org/check/referer">XHTML</a>]</span></p>
|
|
||||||
|
|
||||||
<p>Unlike this design’s inspiration, no tables have been used to layout elements
|
<h1>Players</h1>
|
||||||
and text.</p>
|
<p>
|
||||||
|
There are currently <strong>{{players_connected}}</strong> connected,
|
||||||
|
and a total of <strong>{{players_registered}}</strong> registered. Of these, {{players_recent}} were created this week, and <strong>{{players_connected_recent}}</strong> have connected within the last seven days.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="quarter">
|
<div class="quarter">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue