-from pseudoclient.collection import *\r
-from pseudoclient.sys_channels import *\r
-\r
-class ErepublikChannel(CollectionEntity):\r
- citizen = None\r
- company = None\r
- mass = False\r
- news = False\r
-\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
-\r
-class ErepublikChannelManager(ChannelManager):\r
- def __init__(self, module):\r
- ChannelManager.__init__(self, module, ErepublikChannel)\r
+from pseudoclient.collection import *
+from pseudoclient.sys_channels import *
+
+class ErepublikChannel(CollectionEntity):
+ citizen = None
+ company = None
+ mass = False
+ news = False
+
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+class ErepublikChannelManager(ChannelManager):
+ def __init__(self, module):
+ ChannelManager.__init__(self, module, ErepublikChannel)
-from pseudoclient.collection import *\r
-from pseudoclient.sys_users import *\r
-\r
-class ErepublikUser(CollectionEntity):\r
- citizen = None\r
- company = None\r
- mass = False\r
-\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
-\r
-class ErepublikUserManager(UserManager):\r
- def __init__(self, module):\r
- UserManager.__init__(self, module, ErepublikUser)\r
+from pseudoclient.collection import *
+from pseudoclient.sys_users import *
+
+class ErepublikUser(CollectionEntity):
+ citizen = None
+ company = None
+ mass = False
+
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+class ErepublikUserManager(UserManager):
+ def __init__(self, module):
+ UserManager.__init__(self, module, ErepublikUser)
-\r
-class Object:\r
- def __init__(self, **entries): \r
- self.__dict__.update(entries)\r
- \r
- def __repr__(self): \r
- return '<%s>' % str('\n '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems()))\r
-\r
-def format_ordinal(n, add_thousands_sep=False):\r
- if add_thousands_sep:\r
- nstr = format_thousand(n)\r
- else:\r
- nstr = str(n)\r
- suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(4 if 10 <= n % 100 < 20 else n % 10, "th")\r
- return nstr + suffix\r
-\r
-def format_citizen_message(citizen, message, sex=None):\r
- if citizen == None:\r
- return message\r
- else:\r
- if hasattr(citizen, 'sex'):\r
- sex = citizen.sex.lower() if citizen.sex != None else ''\r
- else:\r
- sex = sex.lower() if sex else ''\r
- \r
- if (sex == 'x'):\r
- message = message.replace('@sep', '@b@c14::@o')\r
- elif (sex == 'f'):\r
- message = message.replace('@sep', '@b@c13::@o')\r
- \r
- return message\r
-\r
+
+class Object:
+ def __init__(self, **entries):
+ self.__dict__.update(entries)
+
+ def __repr__(self):
+ return '<%s>' % str('\n '.join('%s : %s' % (k, repr(v)) for (k, v) in self.__dict__.iteritems()))
+
+def format_ordinal(n, add_thousands_sep=False):
+ if add_thousands_sep:
+ nstr = format_thousand(n)
+ else:
+ nstr = str(n)
+ suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(4 if 10 <= n % 100 < 20 else n % 10, "th")
+ return nstr + suffix
+
+def format_citizen_message(citizen, message, sex=None):
+ if citizen == None:
+ return message
+ else:
+ if hasattr(citizen, 'sex'):
+ sex = citizen.sex.lower() if citizen.sex != None else ''
+ else:
+ sex = sex.lower() if sex else ''
+
+ if (sex == 'x'):
+ message = message.replace('@sep', '@b@c14::@o')
+ elif (sex == 'f'):
+ message = message.replace('@sep', '@b@c13::@o')
+
+ return message
+
-from pseudoclient.collection import *\r
-from pseudoclient.sys_channels import *\r
-\r
-class EsimChannel(CollectionEntity):\r
- mass = False\r
-\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
-\r
- # initialise those so it doesn't fuck itself later\r
- self.news = None\r
- self.highlight = None\r
-\r
-class EsimChannelManager(ChannelManager):\r
- def __init__(self, module):\r
- ChannelManager.__init__(self, module, EsimChannel)\r
+from pseudoclient.collection import *
+from pseudoclient.sys_channels import *
+
+class EsimChannel(CollectionEntity):
+ mass = False
+
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+ # initialise those so it doesn't fuck itself later
+ self.news = None
+ self.highlight = None
+
+class EsimChannelManager(ChannelManager):
+ def __init__(self, module):
+ ChannelManager.__init__(self, module, EsimChannel)
-from pseudoclient.collection import *\r
-from pseudoclient.sys_users import *\r
-\r
-class EsimUser(CollectionEntity):\r
- citizen = None\r
- company = None\r
-\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
-\r
-class EsimUserManager(UserManager):\r
- def __init__(self, module):\r
- UserManager.__init__(self, module, EsimUser)\r
+from pseudoclient.collection import *
+from pseudoclient.sys_users import *
+
+class EsimUser(CollectionEntity):
+ citizen = None
+ company = None
+
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+class EsimUserManager(UserManager):
+ def __init__(self, module):
+ UserManager.__init__(self, module, EsimUser)
-\r
-def format_citizen_message(citizen, message, sex=None):\r
- if citizen == None:\r
- return message\r
- else:\r
- if hasattr(citizen, 'sex'):\r
- sex = citizen.sex.lower() if citizen.sex != None else ''\r
- else:\r
- sex = sex.lower() if sex else ''\r
- \r
- if (sex == 'x'):\r
- message = message.replace('@sep', '@b@c14<>@o')\r
- elif (sex == 'f'):\r
- message = message.replace('@sep', '@b@c13<>@o')\r
- \r
+
+def format_citizen_message(citizen, message, sex=None):
+ if citizen == None:
+ return message
+ else:
+ if hasattr(citizen, 'sex'):
+ sex = citizen.sex.lower() if citizen.sex != None else ''
+ else:
+ sex = sex.lower() if sex else ''
+
+ if (sex == 'x'):
+ message = message.replace('@sep', '@b@c14<>@o')
+ elif (sex == 'f'):
+ message = message.replace('@sep', '@b@c13<>@o')
+
return message
\ No newline at end of file
-from pseudoclient.collection import *\r
-from pseudoclient.sys_users import *\r
-\r
-class InternetsUser(CollectionEntity):\r
- location = None\r
-\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
-\r
-class InternetsUserManager(UserManager):\r
- def __init__(self, module):\r
- UserManager.__init__(self, module, InternetsUser)\r
+from pseudoclient.collection import *
+from pseudoclient.sys_users import *
+
+class InternetsUser(CollectionEntity):
+ location = None
+
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+class InternetsUserManager(UserManager):
+ def __init__(self, module):
+ UserManager.__init__(self, module, InternetsUser)
-\r
-def get_tempcolor(temp):\r
- if temp == None:\r
- return ''\r
- \r
- if temp < -20:\r
- code = '@c12@b'\r
- elif temp < -10:\r
- code = '@c12'\r
- elif temp < 0:\r
- code = '@c10'\r
- elif temp < 10:\r
- code = '@c09'\r
- elif temp < 20:\r
- code = '@c08'\r
- elif temp < 30:\r
- code = '@c07'\r
- elif temp < 35:\r
- code = '@c04'\r
- else:\r
- code = '@c04@b'\r
- \r
- return code\r
- \r
-def format_temperature(temp):\r
- code = get_tempcolor(temp)\r
- return '%s%s' % (code, temp)\r
-\r
-def format_weather(code, message):\r
- return message.replace('@sep', '%s::@o' % code)\r
-\r
+
+def get_tempcolor(temp):
+ if temp == None:
+ return ''
+
+ if temp < -20:
+ code = '@c12@b'
+ elif temp < -10:
+ code = '@c12'
+ elif temp < 0:
+ code = '@c10'
+ elif temp < 10:
+ code = '@c09'
+ elif temp < 20:
+ code = '@c08'
+ elif temp < 30:
+ code = '@c07'
+ elif temp < 35:
+ code = '@c04'
+ else:
+ code = '@c04@b'
+
+ return code
+
+def format_temperature(temp):
+ code = get_tempcolor(temp)
+ return '%s%s' % (code, temp)
+
+def format_weather(code, message):
+ return message.replace('@sep', '%s::@o' % code)
+
-ARG_NO = 0x1\r
-ARG_YES = 0x2\r
-ARG_OPT = 0x4\r
-ARG_OFFLINE = 0x8\r
-ARG_OFFLINE_REQ = 0x10\r
-\r
-class CommandManager(object):\r
- def __init__(self):\r
- self.prefix = self.get_prefix()\r
- self.invalid = self.get_invalid()\r
- self.commands = self.get_commands()\r
- self.generate_help()\r
-\r
- def get_prefix(self):\r
- return ''\r
-\r
- def get_invalid(self):\r
- return ''\r
-\r
- def get_commands(self):\r
- return {}\r
-\r
- def get_command(self, command):\r
- command = command.lower()\r
-\r
- if not command.startswith(self.prefix):\r
- return None\r
-\r
- command = command[len(self.prefix):]\r
-\r
- if not command in self.commands:\r
- return None\r
-\r
- command = self.commands[command]\r
-\r
- if not isinstance(command, basestring):\r
- return command\r
-\r
- command = command.lower()\r
-\r
- if not command in self.commands:\r
- return None\r
-\r
- return self.commands[command]\r
-\r
- def get_help(self, command = None):\r
- if command == None:\r
- return self.help\r
- else:\r
- if command.startswith(self.prefix):\r
- command = command[len(self.prefix):]\r
-\r
- if command in self.help_command:\r
- return self.help_command[command]\r
-\r
- return None\r
-\r
- def add_help_command(self, command):\r
- cmd = self.commands[command]\r
-\r
- if isinstance(cmd, basestring):\r
- cmd = self.commands[cmd]\r
-\r
- message = []\r
-\r
- cmd_type = cmd[1]\r
- cmd_desc = cmd[2]\r
- cmd_args = cmd[3]\r
-\r
- message.append('@b%s%s: %s' % (self.prefix, command, cmd_desc))\r
- message.append(' ')\r
-\r
- msg = 'Usage: @b%s%s@b' % (self.prefix, command)\r
-\r
- if len(cmd_args) > 0:\r
- msg += ' ' + ' '.join(['[%s%s]' % (cmd_arg[1], (' ' + cmd_arg[0]) if ('action' not in cmd_arg[3] or cmd_arg[3]['action'] != 'store_true') else '') for cmd_arg in cmd_args])\r
-\r
- if len(cmd) > 4:\r
- argument_name = cmd[4]\r
- else:\r
- argument_name = 'argument'\r
-\r
- if cmd_type & ARG_YES:\r
- msg += ' %s' % argument_name\r
- elif cmd_type & ARG_OPT:\r
- msg += ' [%s]' % argument_name\r
-\r
- message.append(msg)\r
- message.append('')\r
-\r
- longest = 0\r
-\r
- for cmd_arg in cmd_args:\r
- longest = len(cmd_arg[0]) if len(cmd_arg[0]) > longest else longest\r
-\r
- for cmd_arg in cmd_args:\r
- message.append('@b--%-*s (%s)@b %s' % (longest + 1, cmd_arg[0], cmd_arg[1], cmd_arg[2]))\r
-\r
- self.help_command[command] = message\r
-\r
-\r
- def generate_help(self):\r
- self.help = []\r
-\r
- self.help.append('@bCommands@b (type @b%shelp command name@b for detailed information):' % self.prefix)\r
- self.help.append(' ')\r
-\r
- longest = 0\r
- alias_dict = {}\r
- commands = {}\r
-\r
- for cmd in self.commands:\r
- if isinstance(self.commands[cmd], basestring):\r
- orig = self.commands[cmd]\r
-\r
- if orig in alias_dict:\r
- alias_dict[orig].append(cmd)\r
- else:\r
- alias_dict[orig] = [cmd]\r
- else:\r
- if not cmd in alias_dict:\r
- alias_dict[cmd] = []\r
-\r
- for key in alias_dict:\r
- cur = key + ('' if len(alias_dict[key]) == 0 else (' (' + ', '.join(alias_dict[key]) + ')'))\r
- longest = len(cur) if len(cur) > longest else longest\r
- commands[cur] = self.commands[key][2]\r
-\r
- for cmd in sorted(commands):\r
- self.help.append('@b%-*s@b %s' % (longest + 1, cmd, commands[cmd]))\r
-\r
- self.help_command = {}\r
-\r
- for command in self.commands:\r
- self.add_help_command(command)\r
+ARG_NO = 0x1
+ARG_YES = 0x2
+ARG_OPT = 0x4
+ARG_OFFLINE = 0x8
+ARG_OFFLINE_REQ = 0x10
+
+class CommandManager(object):
+ def __init__(self):
+ self.prefix = self.get_prefix()
+ self.invalid = self.get_invalid()
+ self.commands = self.get_commands()
+ self.generate_help()
+
+ def get_prefix(self):
+ return ''
+
+ def get_invalid(self):
+ return ''
+
+ def get_commands(self):
+ return {}
+
+ def get_command(self, command):
+ command = command.lower()
+
+ if not command.startswith(self.prefix):
+ return None
+
+ command = command[len(self.prefix):]
+
+ if not command in self.commands:
+ return None
+
+ command = self.commands[command]
+
+ if not isinstance(command, basestring):
+ return command
+
+ command = command.lower()
+
+ if not command in self.commands:
+ return None
+
+ return self.commands[command]
+
+ def get_help(self, command = None):
+ if command == None:
+ return self.help
+ else:
+ if command.startswith(self.prefix):
+ command = command[len(self.prefix):]
+
+ if command in self.help_command:
+ return self.help_command[command]
+
+ return None
+
+ def add_help_command(self, command):
+ cmd = self.commands[command]
+
+ if isinstance(cmd, basestring):
+ cmd = self.commands[cmd]
+
+ message = []
+
+ cmd_type = cmd[1]
+ cmd_desc = cmd[2]
+ cmd_args = cmd[3]
+
+ message.append('@b%s%s: %s' % (self.prefix, command, cmd_desc))
+ message.append(' ')
+
+ msg = 'Usage: @b%s%s@b' % (self.prefix, command)
+
+ if len(cmd_args) > 0:
+ msg += ' ' + ' '.join(['[%s%s]' % (cmd_arg[1], (' ' + cmd_arg[0]) if ('action' not in cmd_arg[3] or cmd_arg[3]['action'] != 'store_true') else '') for cmd_arg in cmd_args])
+
+ if len(cmd) > 4:
+ argument_name = cmd[4]
+ else:
+ argument_name = 'argument'
+
+ if cmd_type & ARG_YES:
+ msg += ' %s' % argument_name
+ elif cmd_type & ARG_OPT:
+ msg += ' [%s]' % argument_name
+
+ message.append(msg)
+ message.append('')
+
+ longest = 0
+
+ for cmd_arg in cmd_args:
+ longest = len(cmd_arg[0]) if len(cmd_arg[0]) > longest else longest
+
+ for cmd_arg in cmd_args:
+ message.append('@b--%-*s (%s)@b %s' % (longest + 1, cmd_arg[0], cmd_arg[1], cmd_arg[2]))
+
+ self.help_command[command] = message
+
+
+ def generate_help(self):
+ self.help = []
+
+ self.help.append('@bCommands@b (type @b%shelp command name@b for detailed information):' % self.prefix)
+ self.help.append(' ')
+
+ longest = 0
+ alias_dict = {}
+ commands = {}
+
+ for cmd in self.commands:
+ if isinstance(self.commands[cmd], basestring):
+ orig = self.commands[cmd]
+
+ if orig in alias_dict:
+ alias_dict[orig].append(cmd)
+ else:
+ alias_dict[orig] = [cmd]
+ else:
+ if not cmd in alias_dict:
+ alias_dict[cmd] = []
+
+ for key in alias_dict:
+ cur = key + ('' if len(alias_dict[key]) == 0 else (' (' + ', '.join(alias_dict[key]) + ')'))
+ longest = len(cur) if len(cur) > longest else longest
+ commands[cur] = self.commands[key][2]
+
+ for cmd in sorted(commands):
+ self.help.append('@b%-*s@b %s' % (longest + 1, cmd, commands[cmd]))
+
+ self.help_command = {}
+
+ for command in self.commands:
+ self.add_help_command(command)
-from datetime import datetime\r
-from utils import *\r
-from istring import *\r
-import traceback\r
-import inspect\r
-\r
-class InvariantCollection(object):\r
- def __init__(self):\r
- self.__entries = {}\r
-\r
- def __len__(self):\r
- return len(self.__entries)\r
-\r
- def __getitem__(self, key):\r
- invariant_key = istring(key)\r
-\r
- if not self.__contains__(invariant_key):\r
- raise KeyError('Entry with key %s not present.' % key)\r
-\r
- return self.__entries[invariant_key]\r
-\r
- def __setitem__(self, key, value):\r
- self.__entries[istring(key)] = value\r
-\r
- def __delitem__(self, key):\r
- invariant_key = istring(key)\r
-\r
- if not self.__contains__(invariant_key):\r
- raise KeyError('Entry with key %s not present.' % key)\r
-\r
- del(self.__entries[invariant_key])\r
-\r
- def __iter__(self):\r
- for entry in self.__entries:\r
- yield entry\r
-\r
- def __contains__(self, item):\r
- if not isinstance(item, basestring):\r
- raise TypeError('%s is not an allowed indexing type.' % type(item))\r
-\r
- return istring(item) in self.__entries\r
- \r
- def list_all(self):\r
- return [self[item] for item in self]\r
-\r
-class CollectionEntity(object):\r
- def __init__(self, id, ban_source = None, ban_reason = None, ban_date = None, ban_expiry = None):\r
- self.id = id\r
- self.ban_source = ban_source\r
- self.ban_reason = ban_reason\r
- self.ban_date = ban_date\r
- self.ban_expiry = ban_expiry\r
- self.dirty = False\r
- self.registered = self.banned = False\r
-\r
-class CollectionManager(InvariantCollection):\r
- def __init__(self, type):\r
- InvariantCollection.__init__(self)\r
- self.__type = type\r
- self.__deleted_items = []\r
-\r
- self.db_open()\r
-\r
- self.load()\r
-\r
- def load(self):\r
- self.cursor.execute("CREATE TABLE IF NOT EXISTS " + self.module.name + "_" + self.name + " (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(51) NOT NULL, PRIMARY KEY (id), UNIQUE KEY (name)) ENGINE=InnoDB")\r
-\r
- self.cursor.execute("CREATE TABLE IF NOT EXISTS " + self.module.name + "_" + self.name + "_options (id INT, name VARCHAR(32) NOT NULL, value TINYTEXT, UNIQUE KEY (id, name)) ENGINE=InnoDB")\r
- #self.cursor.execute("ALTER TABLE " + self.module.name + "_" + self.name + "_options ADD CONSTRAINT FOREIGN KEY IF NOT EXISTS (id) REFERENCES " + self.module.name + "_" + self.name + " (id)")\r
-\r
- self.cursor.execute("SELECT id, name FROM " + self.module.name + "_" + self.name)\r
- r = self.cursor.fetchall()\r
-\r
- for row in r:\r
- id = row[0]\r
- name = istring(row[1])\r
-\r
- self.module.elog.debug('Loading ' + name + ' for ' + self.module.name + '_' + self.name)\r
-\r
- self[name] = e = self.__type(id, name)\r
-\r
- self.cursor.execute("SELECT name,value FROM " + self.module.name + "_" + self.name + "_options WHERE `id` = %s", (id,))\r
- r2 = self.cursor.fetchall()\r
- for row2 in r2:\r
- setattr(e, row2[0], row2[1])\r
-\r
- def __get_attributes(self, obj):\r
- boring = dir(type('dummy', (object,), {}))\r
- return [item for item in inspect.getmembers(obj) if item[0] not in boring]\r
-\r
- def commit(self):\r
- try:\r
- deleted = [(e.id, ) for e in self.list_deleted()]\r
- changed = [e for e in self.list_dirty()]\r
-\r
- if len(deleted) > 0:\r
- self.cursor.executemany("DELETE FROM " + self.module.name + "_" + self.name + "_options WHERE id = %s", deleted)\r
- self.cursor.executemany("DELETE FROM " + self.module.name + "_" + self.name + " WHERE id = %s", deleted)\r
- self.module.elog.commit('Deleted %d %s from database.' % (len(deleted), self.name))\r
-\r
- for e in changed:\r
- if e.id == -1:\r
- self.cursor.execute("INSERT INTO " + self.module.name + "_" + self.name + " (name) VALUES(%s)", (e.name,))\r
- e.id = self.cursor.lastrowid\r
- else: # delete options as we are aboue to re-flush them\r
- self.cursor.execute("DELETE FROM " + self.module.name + "_" + self.name + "_options WHERE `id` = %s", (e.id,))\r
-\r
- for a in self.__get_attributes(e):\r
- attr_name = a[0]\r
- attr = getattr(e, attr_name)\r
- if attr:\r
- self.cursor.execute("INSERT INTO " + self.module.name + "_" + self.name + "_options (id, name, value) VALUES (%s, %s, %s)", (e.id, attr_name, attr))\r
- if len(changed) > 0:\r
- self.module.elog.commit('Committed %d %s to database.' % (len(changed), self.name))\r
-\r
- self.clear_deleted()\r
-\r
- for e in self.list_all():\r
- e.dirty = False\r
- except Exception, err:\r
- traceback.print_exc()\r
- self.module.elog.error(self.name + ' commit failed: @b%s@b' % err)\r
-\r
- def check(self, item):\r
- if not item in self:\r
- return\r
-\r
- entity = self[item]\r
-\r
- if entity.ban_expiry != None and entity.ban_expiry <= unix_time(datetime.now()):\r
- self.unban(item)\r
-\r
- def is_dirty(self, item):\r
- self.check(item)\r
-\r
- return item in self and self[item].dirty\r
-\r
- def is_valid(self, item):\r
- self.check(item)\r
-\r
- return item in self and self[item].registered and not self[item].banned\r
-\r
- def is_banned(self, item):\r
- self.check(item)\r
-\r
- return item in self and self[item].banned\r
-\r
- def get(self, item, attribute):\r
- if not item in self:\r
- return None\r
-\r
- return getattr(self[item], attribute)\r
-\r
- def set(self, item, attribute, value):\r
- entity = self.add(item)\r
- old_value = getattr(entity, attribute)\r
-\r
- if old_value != value:\r
- setattr(entity, attribute, value)\r
- entity.dirty = True\r
-\r
- def add(self, item):\r
- if not item in self:\r
- entity = self.__type(-1, item)\r
- entity.dirty = True\r
- entity.registered = True\r
- self[item] = entity\r
-\r
- self.on_added(item)\r
-\r
- return self[item]\r
-\r
- def remove(self, item):\r
- if not item in self:\r
- return\r
-\r
- entity = self[item]\r
-\r
- if entity.banned and entity.registered:\r
- entity.registered = False\r
- entity.clear()\r
- entity.dirty = True\r
- elif not entity.banned:\r
- if not item.lower() in self.__deleted_items:\r
- self.__deleted_items.append(entity)\r
-\r
- del(self[item])\r
-\r
- self.on_removed(item)\r
-\r
- def ban(self, item, source, reason, date, expiry):\r
- entity = self.add(item)\r
- entity.banned = True\r
- entity.ban_source = source\r
- entity.ban_reason = reason\r
- entity.ban_date = date\r
- entity.ban_expiry = expiry\r
- entity.dirty = True\r
-\r
- self.on_banned(item)\r
-\r
- def unban(self, item):\r
- if not item in self or not self[item].banned:\r
- return\r
-\r
- entity = self[item]\r
- entity.banned = False\r
- entity.ban_source = None\r
- entity.ban_reason = None\r
- entity.ban_date = None\r
- entity.ban_expiry = None\r
-\r
- if not entity.registered:\r
- self.remove(item)\r
- else:\r
- entity.dirty = True\r
-\r
- self.on_unbanned(item)\r
-\r
- def on_added(self, item):\r
- pass\r
-\r
- def on_removed(self, item):\r
- pass\r
-\r
- def on_banned(self, item):\r
- pass\r
-\r
- def on_unbanned(self, item):\r
- pass\r
-\r
- def clear_deleted(self):\r
- self.__deleted_items = []\r
-\r
- def list_deleted(self):\r
- return self.__deleted_items\r
-\r
- def list_dirty(self):\r
- items = [item for item in self]\r
- return [self[item] for item in items if self.is_dirty(item)]\r
-\r
- def list_valid(self):\r
- items = [item for item in self]\r
- return [self[item] for item in items if self.is_valid(item)]\r
-\r
- def list_banned(self):\r
- items = [item for item in self]\r
- return [self[item] for item in items if self.is_banned(item)]\r
+from datetime import datetime
+from utils import *
+from istring import *
+import traceback
+import inspect
+
+class InvariantCollection(object):
+ def __init__(self):
+ self.__entries = {}
+
+ def __len__(self):
+ return len(self.__entries)
+
+ def __getitem__(self, key):
+ invariant_key = istring(key)
+
+ if not self.__contains__(invariant_key):
+ raise KeyError('Entry with key %s not present.' % key)
+
+ return self.__entries[invariant_key]
+
+ def __setitem__(self, key, value):
+ self.__entries[istring(key)] = value
+
+ def __delitem__(self, key):
+ invariant_key = istring(key)
+
+ if not self.__contains__(invariant_key):
+ raise KeyError('Entry with key %s not present.' % key)
+
+ del(self.__entries[invariant_key])
+
+ def __iter__(self):
+ for entry in self.__entries:
+ yield entry
+
+ def __contains__(self, item):
+ if not isinstance(item, basestring):
+ raise TypeError('%s is not an allowed indexing type.' % type(item))
+
+ return istring(item) in self.__entries
+
+ def list_all(self):
+ return [self[item] for item in self]
+
+class CollectionEntity(object):
+ def __init__(self, id, ban_source = None, ban_reason = None, ban_date = None, ban_expiry = None):
+ self.id = id
+ self.ban_source = ban_source
+ self.ban_reason = ban_reason
+ self.ban_date = ban_date
+ self.ban_expiry = ban_expiry
+ self.dirty = False
+ self.registered = self.banned = False
+
+class CollectionManager(InvariantCollection):
+ def __init__(self, type):
+ InvariantCollection.__init__(self)
+ self.__type = type
+ self.__deleted_items = []
+
+ self.db_open()
+
+ self.load()
+
+ def load(self):
+ self.cursor.execute("CREATE TABLE IF NOT EXISTS " + self.module.name + "_" + self.name + " (id INT NOT NULL AUTO_INCREMENT, name VARCHAR(51) NOT NULL, PRIMARY KEY (id), UNIQUE KEY (name)) ENGINE=InnoDB")
+
+ self.cursor.execute("CREATE TABLE IF NOT EXISTS " + self.module.name + "_" + self.name + "_options (id INT, name VARCHAR(32) NOT NULL, value TINYTEXT, UNIQUE KEY (id, name)) ENGINE=InnoDB")
+ #self.cursor.execute("ALTER TABLE " + self.module.name + "_" + self.name + "_options ADD CONSTRAINT FOREIGN KEY IF NOT EXISTS (id) REFERENCES " + self.module.name + "_" + self.name + " (id)")
+
+ self.cursor.execute("SELECT id, name FROM " + self.module.name + "_" + self.name)
+ r = self.cursor.fetchall()
+
+ for row in r:
+ id = row[0]
+ name = istring(row[1])
+
+ self.module.elog.debug('Loading ' + name + ' for ' + self.module.name + '_' + self.name)
+
+ self[name] = e = self.__type(id, name)
+
+ self.cursor.execute("SELECT name,value FROM " + self.module.name + "_" + self.name + "_options WHERE `id` = %s", (id,))
+ r2 = self.cursor.fetchall()
+ for row2 in r2:
+ setattr(e, row2[0], row2[1])
+
+ def __get_attributes(self, obj):
+ boring = dir(type('dummy', (object,), {}))
+ return [item for item in inspect.getmembers(obj) if item[0] not in boring]
+
+ def commit(self):
+ try:
+ deleted = [(e.id, ) for e in self.list_deleted()]
+ changed = [e for e in self.list_dirty()]
+
+ if len(deleted) > 0:
+ self.cursor.executemany("DELETE FROM " + self.module.name + "_" + self.name + "_options WHERE id = %s", deleted)
+ self.cursor.executemany("DELETE FROM " + self.module.name + "_" + self.name + " WHERE id = %s", deleted)
+ self.module.elog.commit('Deleted %d %s from database.' % (len(deleted), self.name))
+
+ for e in changed:
+ if e.id == -1:
+ self.cursor.execute("INSERT INTO " + self.module.name + "_" + self.name + " (name) VALUES(%s)", (e.name,))
+ e.id = self.cursor.lastrowid
+ else: # delete options as we are aboue to re-flush them
+ self.cursor.execute("DELETE FROM " + self.module.name + "_" + self.name + "_options WHERE `id` = %s", (e.id,))
+
+ for a in self.__get_attributes(e):
+ attr_name = a[0]
+ attr = getattr(e, attr_name)
+ if attr:
+ self.cursor.execute("INSERT INTO " + self.module.name + "_" + self.name + "_options (id, name, value) VALUES (%s, %s, %s)", (e.id, attr_name, attr))
+ if len(changed) > 0:
+ self.module.elog.commit('Committed %d %s to database.' % (len(changed), self.name))
+
+ self.clear_deleted()
+
+ for e in self.list_all():
+ e.dirty = False
+ except Exception, err:
+ traceback.print_exc()
+ self.module.elog.error(self.name + ' commit failed: @b%s@b' % err)
+
+ def check(self, item):
+ if not item in self:
+ return
+
+ entity = self[item]
+
+ if entity.ban_expiry != None and entity.ban_expiry <= unix_time(datetime.now()):
+ self.unban(item)
+
+ def is_dirty(self, item):
+ self.check(item)
+
+ return item in self and self[item].dirty
+
+ def is_valid(self, item):
+ self.check(item)
+
+ return item in self and self[item].registered and not self[item].banned
+
+ def is_banned(self, item):
+ self.check(item)
+
+ return item in self and self[item].banned
+
+ def get(self, item, attribute):
+ if not item in self:
+ return None
+
+ return getattr(self[item], attribute)
+
+ def set(self, item, attribute, value):
+ entity = self.add(item)
+ old_value = getattr(entity, attribute)
+
+ if old_value != value:
+ setattr(entity, attribute, value)
+ entity.dirty = True
+
+ def add(self, item):
+ if not item in self:
+ entity = self.__type(-1, item)
+ entity.dirty = True
+ entity.registered = True
+ self[item] = entity
+
+ self.on_added(item)
+
+ return self[item]
+
+ def remove(self, item):
+ if not item in self:
+ return
+
+ entity = self[item]
+
+ if entity.banned and entity.registered:
+ entity.registered = False
+ entity.clear()
+ entity.dirty = True
+ elif not entity.banned:
+ if not item.lower() in self.__deleted_items:
+ self.__deleted_items.append(entity)
+
+ del(self[item])
+
+ self.on_removed(item)
+
+ def ban(self, item, source, reason, date, expiry):
+ entity = self.add(item)
+ entity.banned = True
+ entity.ban_source = source
+ entity.ban_reason = reason
+ entity.ban_date = date
+ entity.ban_expiry = expiry
+ entity.dirty = True
+
+ self.on_banned(item)
+
+ def unban(self, item):
+ if not item in self or not self[item].banned:
+ return
+
+ entity = self[item]
+ entity.banned = False
+ entity.ban_source = None
+ entity.ban_reason = None
+ entity.ban_date = None
+ entity.ban_expiry = None
+
+ if not entity.registered:
+ self.remove(item)
+ else:
+ entity.dirty = True
+
+ self.on_unbanned(item)
+
+ def on_added(self, item):
+ pass
+
+ def on_removed(self, item):
+ pass
+
+ def on_banned(self, item):
+ pass
+
+ def on_unbanned(self, item):
+ pass
+
+ def clear_deleted(self):
+ self.__deleted_items = []
+
+ def list_deleted(self):
+ return self.__deleted_items
+
+ def list_dirty(self):
+ items = [item for item in self]
+ return [self[item] for item in items if self.is_dirty(item)]
+
+ def list_valid(self):
+ items = [item for item in self]
+ return [self[item] for item in items if self.is_valid(item)]
+
+ def list_banned(self):
+ items = [item for item in self]
+ return [self[item] for item in items if self.is_banned(item)]
-import time\r
-import threading\r
-from sys_base import *\r
-import istring\r
-\r
-class AntiFloodManager(Subsystem):\r
- def __init__(self, module):\r
- Subsystem.__init__(self, module, module.options, 'antiflood')\r
- self.lock_user = threading.Lock()\r
- self.users = {}\r
- \r
- def on_reload(self):\r
- self.delay_base_user = self.get_option('delay_base_user', int, 1)\r
- self.delay_mult_pre_warn_user = self.get_option('delay_mult_pre_warn_user', int, 3)\r
- self.delay_mult_post_warn_user = self.get_option('delay_mult_post_warn_user', int, 10)\r
- self.ban_duration_user = self.get_option('ban_duration_user', int, 5 * 24 * 60 * 60)\r
- self.score_ban_user = self.get_option('score_ban_user', int, 6)\r
- self.score_warn_user = self.get_option('score_warn_user', int, 3)\r
- self.points_user = self.get_option('points_user', int, 1)\r
- self.points_repeat_user = self.get_option('points_repeat_user', int, 2)\r
- self.warning_message_user = self.get_option('warning_message_user', unicode, 'Slow down, wait @timeout seconds! If you continue flooding the bot you will be banned.')\r
-\r
- def get_delay_user(self, score):\r
- score_pre_warn = score\r
- score_post_warn = 0\r
-\r
- if score > self.score_warn_user:\r
- score_post_warn = score - self.score_warn_user\r
- score_pre_warn = self.score_warn_user\r
-\r
- return self.delay_base_user + (score_pre_warn * self.delay_mult_pre_warn_user) + (score_post_warn * self.delay_mult_post_warn_user)\r
-\r
- def check_user(self, username, command, argument):\r
- command = command.lower().strip()\r
- argument = argument.lower().strip()\r
- now = int(time.time())\r
-\r
- try:\r
- self.lock_user.acquire()\r
-\r
- if not username in self.users:\r
- self.users[username] = [now, 0, command, argument]\r
- return False\r
-\r
- user = self.users[username]\r
-\r
- if now - user[0] <= self.get_delay_user(user[1]):\r
- if user[2] == command and user[3] == argument:\r
- user[1] += self.points_repeat_user\r
- else:\r
- user[2] = command\r
- user[3] = argument\r
- user[1] += self.points_user\r
- else:\r
- user[1] = 0\r
- user[2] = command\r
- user[3] = argument\r
-\r
- user[0] = now\r
- finally:\r
- self.lock_user.release()\r
-\r
- if user[1] >= self.score_ban_user:\r
- self.module.users.ban(username, "anti-flood", "flooding", now, now + self.ban_duration_user)\r
- self.module.elog.warning('Banned @b%s@b for flooding.' % username)\r
- user[0] = -1\r
- return True\r
-\r
- if user[1] >= self.score_warn_user:\r
- self.module.notice(username, self.warning_message_user.replace('@timeout', istring(self.get_delay_user(user[1]))))\r
-\r
- return False\r
-\r
- def commit(self):\r
- new_users = {}\r
- now = int(time.time())\r
- self.lock_user.acquire()\r
-\r
- for username in self.users:\r
- user = self.users[username]\r
-\r
- if now - user[0] <= self.get_delay_user(user[1]):\r
- new_users[username] = user\r
-\r
- self.users = new_users\r
- self.lock_user.release()\r
+import time
+import threading
+from sys_base import *
+import istring
+
+class AntiFloodManager(Subsystem):
+ def __init__(self, module):
+ Subsystem.__init__(self, module, module.options, 'antiflood')
+ self.lock_user = threading.Lock()
+ self.users = {}
+
+ def on_reload(self):
+ self.delay_base_user = self.get_option('delay_base_user', int, 1)
+ self.delay_mult_pre_warn_user = self.get_option('delay_mult_pre_warn_user', int, 3)
+ self.delay_mult_post_warn_user = self.get_option('delay_mult_post_warn_user', int, 10)
+ self.ban_duration_user = self.get_option('ban_duration_user', int, 5 * 24 * 60 * 60)
+ self.score_ban_user = self.get_option('score_ban_user', int, 6)
+ self.score_warn_user = self.get_option('score_warn_user', int, 3)
+ self.points_user = self.get_option('points_user', int, 1)
+ self.points_repeat_user = self.get_option('points_repeat_user', int, 2)
+ self.warning_message_user = self.get_option('warning_message_user', unicode, 'Slow down, wait @timeout seconds! If you continue flooding the bot you will be banned.')
+
+ def get_delay_user(self, score):
+ score_pre_warn = score
+ score_post_warn = 0
+
+ if score > self.score_warn_user:
+ score_post_warn = score - self.score_warn_user
+ score_pre_warn = self.score_warn_user
+
+ return self.delay_base_user + (score_pre_warn * self.delay_mult_pre_warn_user) + (score_post_warn * self.delay_mult_post_warn_user)
+
+ def check_user(self, username, command, argument):
+ command = command.lower().strip()
+ argument = argument.lower().strip()
+ now = int(time.time())
+
+ try:
+ self.lock_user.acquire()
+
+ if not username in self.users:
+ self.users[username] = [now, 0, command, argument]
+ return False
+
+ user = self.users[username]
+
+ if now - user[0] <= self.get_delay_user(user[1]):
+ if user[2] == command and user[3] == argument:
+ user[1] += self.points_repeat_user
+ else:
+ user[2] = command
+ user[3] = argument
+ user[1] += self.points_user
+ else:
+ user[1] = 0
+ user[2] = command
+ user[3] = argument
+
+ user[0] = now
+ finally:
+ self.lock_user.release()
+
+ if user[1] >= self.score_ban_user:
+ self.module.users.ban(username, "anti-flood", "flooding", now, now + self.ban_duration_user)
+ self.module.elog.warning('Banned @b%s@b for flooding.' % username)
+ user[0] = -1
+ return True
+
+ if user[1] >= self.score_warn_user:
+ self.module.notice(username, self.warning_message_user.replace('@timeout', istring(self.get_delay_user(user[1]))))
+
+ return False
+
+ def commit(self):
+ new_users = {}
+ now = int(time.time())
+ self.lock_user.acquire()
+
+ for username in self.users:
+ user = self.users[username]
+
+ if now - user[0] <= self.get_delay_user(user[1]):
+ new_users[username] = user
+
+ self.users = new_users
+ self.lock_user.release()
-import time\r
-from sys_base import *\r
-from core import anope_major\r
-\r
-class Request(object):\r
- def __init__(self, user, channel, action):\r
- self.user = user\r
- self.channel = channel\r
- self.action = action\r
- self.time = int(time.time())\r
-\r
-class AuthManager(Subsystem):\r
- def __init__(self, module):\r
- Subsystem.__init__(self, module, module.options, 'auth')\r
- self.requests = {}\r
-\r
- def request(self, user, channel, action):\r
- if user in self.requests:\r
- self.module.notice(user, 'Sorry, you already have a pending request. Please retry later.')\r
- return\r
- \r
- self.requests[user] = Request(user, channel, action)\r
- \r
- if anope_major == 1:\r
- self.module.msg('ChanServ', 'WHY %s %s' % (channel, user))\r
- elif anope_major == 2:\r
- self.module.msg('ChanServ', 'STATUS %s %s' % (channel, user))\r
-\r
- def accept(self, user):\r
- if not user in self.requests:\r
- return\r
-\r
- request = self.requests[user]\r
- action = request.action\r
- channel = request.channel\r
- \r
- if self.onAccept(user, request, action, channel):\r
- pass\r
- elif action == 'request':\r
- if not channel in self.module.channels:\r
- self.module.channels.add(channel)\r
- self.module.notice(user, 'Joined @b%s@b.' % channel)\r
- elif action == 'remove':\r
- if self.module.channels.is_valid(channel):\r
- self.module.channels.remove(channel)\r
- self.module.notice(user, 'Parted @b%s@b.' % channel)\r
- else:\r
- self.module.elog.request('Invalid request. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b.' % (action, channel, user))\r
- self.module.notice(user, 'Invalid request: @b%s@b.' % action)\r
- del self.requests[user]\r
- return\r
-\r
- self.module.elog.request('Request accepted. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b.' % (action, channel, user))\r
- del self.requests[user]\r
-\r
- def onAccept(self, user, request, action, channel):\r
- return False\r
-\r
- def reject_not_founder(self, user, channel):\r
- self.reject(user, 'You are not the channel founder of @b%s@b.' % channel)\r
- \r
- def reject_not_registered(self, channel):\r
- for user in self.requests:\r
- if self.requests[user].channel == channel:\r
- self.reject(user, 'Channel @b%s@b is unregistered.' % channel)\r
- break\r
-\r
- def reject(self, user, reason = ''):\r
- if not user in self.requests:\r
- return\r
-\r
- request = self.requests[user]\r
- action = request.action\r
- channel = request.channel\r
- self.module.elog.request('Request rejected. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b. Reason: @b%s@b.' % (action, channel, user, reason))\r
- self.module.notice(user, reason)\r
- del self.requests[user]\r
-\r
- def commit(self):\r
- timeout_time = int(time.time()) - 20\r
- expired_requests = []\r
- \r
- for user in self.requests:\r
- request = self.requests[user]\r
- \r
- if request.time < timeout_time:\r
- expired_requests.append(user)\r
- action = request.action\r
- channel = request.channel\r
- \r
- try:\r
- self.module.elog.request('Request expired. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b.' % (action, channel, user))\r
- self.module.notice(user, 'Request @b%s@b expired. Please retry later.' % action)\r
- except Exception, err:\r
- pass\r
- \r
- for user in expired_requests:\r
- del self.requests[user]\r
+import time
+from sys_base import *
+from core import anope_major
+
+class Request(object):
+ def __init__(self, user, channel, action):
+ self.user = user
+ self.channel = channel
+ self.action = action
+ self.time = int(time.time())
+
+class AuthManager(Subsystem):
+ def __init__(self, module):
+ Subsystem.__init__(self, module, module.options, 'auth')
+ self.requests = {}
+
+ def request(self, user, channel, action):
+ if user in self.requests:
+ self.module.notice(user, 'Sorry, you already have a pending request. Please retry later.')
+ return
+
+ self.requests[user] = Request(user, channel, action)
+
+ if anope_major == 1:
+ self.module.msg('ChanServ', 'WHY %s %s' % (channel, user))
+ elif anope_major == 2:
+ self.module.msg('ChanServ', 'STATUS %s %s' % (channel, user))
+
+ def accept(self, user):
+ if not user in self.requests:
+ return
+
+ request = self.requests[user]
+ action = request.action
+ channel = request.channel
+
+ if self.onAccept(user, request, action, channel):
+ pass
+ elif action == 'request':
+ if not channel in self.module.channels:
+ self.module.channels.add(channel)
+ self.module.notice(user, 'Joined @b%s@b.' % channel)
+ elif action == 'remove':
+ if self.module.channels.is_valid(channel):
+ self.module.channels.remove(channel)
+ self.module.notice(user, 'Parted @b%s@b.' % channel)
+ else:
+ self.module.elog.request('Invalid request. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b.' % (action, channel, user))
+ self.module.notice(user, 'Invalid request: @b%s@b.' % action)
+ del self.requests[user]
+ return
+
+ self.module.elog.request('Request accepted. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b.' % (action, channel, user))
+ del self.requests[user]
+
+ def onAccept(self, user, request, action, channel):
+ return False
+
+ def reject_not_founder(self, user, channel):
+ self.reject(user, 'You are not the channel founder of @b%s@b.' % channel)
+
+ def reject_not_registered(self, channel):
+ for user in self.requests:
+ if self.requests[user].channel == channel:
+ self.reject(user, 'Channel @b%s@b is unregistered.' % channel)
+ break
+
+ def reject(self, user, reason = ''):
+ if not user in self.requests:
+ return
+
+ request = self.requests[user]
+ action = request.action
+ channel = request.channel
+ self.module.elog.request('Request rejected. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b. Reason: @b%s@b.' % (action, channel, user, reason))
+ self.module.notice(user, reason)
+ del self.requests[user]
+
+ def commit(self):
+ timeout_time = int(time.time()) - 20
+ expired_requests = []
+
+ for user in self.requests:
+ request = self.requests[user]
+
+ if request.time < timeout_time:
+ expired_requests.append(user)
+ action = request.action
+ channel = request.channel
+
+ try:
+ self.module.elog.request('Request expired. Action: @b%s@b. Channel: @b%s@b. User: @b%s@b.' % (action, channel, user))
+ self.module.notice(user, 'Request @b%s@b expired. Please retry later.' % action)
+ except Exception, err:
+ pass
+
+ for user in expired_requests:
+ del self.requests[user]
-import threading\r
-import MySQLdb as db\r
-\r
-class Subsystem(object):\r
- #--------------------------------------------------------------#\r
- # i'm not entirely sure if this functionality is still\r
- # required, but it seems it was removed from this module\r
- # but not from cmd_admin, so I can only assume the removal\r
- # was not intentional.\r
-\r
- db_up = True\r
-\r
- @classmethod\r
- def set_db_up(cls, up):\r
- cls.db_up = up\r
-\r
- @classmethod\r
- def get_db_up(cls):\r
- return cls.db_up\r
-\r
- #--------------------------------------------------------------#\r
-\r
- def __init__(self, module, options, name):\r
- self.module = module\r
- self.__options = options\r
- self.__lock = threading.Lock()\r
- self.name = name\r
- self.__timer = None\r
- self.conn = None\r
- self.cursor = None\r
- self.reload()\r
-\r
- def db_open(self):\r
- self.conn = db.connect(\r
- host=self.module.config.get('database', 'host'),\r
- user=self.module.config.get('database', 'user'),\r
- passwd=self.module.config.get('database', 'passwd'),\r
- db=self.module.config.get('database', 'db'),\r
- unix_socket=self.module.config.get('database','sock')\r
- )\r
- self.conn.ping(True)\r
- self.conn.autocommit(True)\r
- self.cursor = self.conn.cursor()\r
-\r
- def db_close(self):\r
- if self.cursor != None:\r
- self.cursor.close()\r
- self.cursor = None\r
- \r
- if self.conn != None:\r
- self.conn.close()\r
- self.conn = None\r
-\r
- def reload(self):\r
- self.__delay = self.get_option('update_period', int, 120)\r
-\r
- if self.__timer != None:\r
- self.stop()\r
- self.on_reload()\r
- self.start()\r
- else:\r
- self.on_reload()\r
-\r
- def on_reload(self):\r
- pass\r
-\r
- def get_option(self, name, type, default):\r
- return self.__options.get('%s_%s' % (self.name, name), type, default)\r
-\r
- def set_option(self, name, value):\r
- return self.__options.set('%s_%s' % (self.name, name), value)\r
-\r
- def start(self):\r
- self.__timer = threading.Timer(self.__delay, self.worker)\r
- self.__timer.daemon = True\r
- self.__timer.start()\r
-\r
- def stop(self):\r
- self.__lock.acquire()\r
-\r
- try:\r
- if self.__timer != None:\r
- self.__timer.cancel()\r
- self.__timer = None\r
- finally:\r
- self.__lock.release()\r
-\r
- def update(self):\r
- self.__lock.acquire()\r
-\r
- try:\r
- self.commit()\r
- finally:\r
- self.__lock.release()\r
-\r
- def force(self):\r
- self.update()\r
-\r
- def commit(self):\r
- pass\r
-\r
- def worker(self):\r
- try:\r
- if self.conn != None:\r
- self.conn.ping(True)\r
- finally:\r
- pass\r
-\r
- if self.__class__.db_up:\r
- self.update()\r
-\r
- self.__timer = threading.Timer(self.__delay, self.worker)\r
- self.__timer.daemon = True\r
- self.__timer.start()\r
-\r
+import threading
+import MySQLdb as db
+
+class Subsystem(object):
+ #--------------------------------------------------------------#
+ # i'm not entirely sure if this functionality is still
+ # required, but it seems it was removed from this module
+ # but not from cmd_admin, so I can only assume the removal
+ # was not intentional.
+
+ db_up = True
+
+ @classmethod
+ def set_db_up(cls, up):
+ cls.db_up = up
+
+ @classmethod
+ def get_db_up(cls):
+ return cls.db_up
+
+ #--------------------------------------------------------------#
+
+ def __init__(self, module, options, name):
+ self.module = module
+ self.__options = options
+ self.__lock = threading.Lock()
+ self.name = name
+ self.__timer = None
+ self.conn = None
+ self.cursor = None
+ self.reload()
+
+ def db_open(self):
+ self.conn = db.connect(
+ host=self.module.config.get('database', 'host'),
+ user=self.module.config.get('database', 'user'),
+ passwd=self.module.config.get('database', 'passwd'),
+ db=self.module.config.get('database', 'db'),
+ unix_socket=self.module.config.get('database','sock')
+ )
+ self.conn.ping(True)
+ self.conn.autocommit(True)
+ self.cursor = self.conn.cursor()
+
+ def db_close(self):
+ if self.cursor != None:
+ self.cursor.close()
+ self.cursor = None
+
+ if self.conn != None:
+ self.conn.close()
+ self.conn = None
+
+ def reload(self):
+ self.__delay = self.get_option('update_period', int, 120)
+
+ if self.__timer != None:
+ self.stop()
+ self.on_reload()
+ self.start()
+ else:
+ self.on_reload()
+
+ def on_reload(self):
+ pass
+
+ def get_option(self, name, type, default):
+ return self.__options.get('%s_%s' % (self.name, name), type, default)
+
+ def set_option(self, name, value):
+ return self.__options.set('%s_%s' % (self.name, name), value)
+
+ def start(self):
+ self.__timer = threading.Timer(self.__delay, self.worker)
+ self.__timer.daemon = True
+ self.__timer.start()
+
+ def stop(self):
+ self.__lock.acquire()
+
+ try:
+ if self.__timer != None:
+ self.__timer.cancel()
+ self.__timer = None
+ finally:
+ self.__lock.release()
+
+ def update(self):
+ self.__lock.acquire()
+
+ try:
+ self.commit()
+ finally:
+ self.__lock.release()
+
+ def force(self):
+ self.update()
+
+ def commit(self):
+ pass
+
+ def worker(self):
+ try:
+ if self.conn != None:
+ self.conn.ping(True)
+ finally:
+ pass
+
+ if self.__class__.db_up:
+ self.update()
+
+ self.__timer = threading.Timer(self.__delay, self.worker)
+ self.__timer.daemon = True
+ self.__timer.start()
+
-from collection import *\r
-from sys_base import *\r
-\r
-class Channel(CollectionEntity):\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
- \r
- news = None\r
-\r
-class ChannelManager(CollectionManager, Subsystem):\r
- def __init__(self, module, type = Channel):\r
- Subsystem.__init__(self, module, module.options, 'channels')\r
- CollectionManager.__init__(self, type)\r
-\r
- def on_added(self, channel):\r
- self.module.join(channel)\r
-\r
- def on_removed(self, channel):\r
- self.module.part(channel)\r
-\r
- def on_banned(self, channel):\r
- self.module.part(channel)\r
-\r
- def on_unbanned(self, channel):\r
- if channel in self:\r
- self.module.join(channel)\r
+from collection import *
+from sys_base import *
+
+class Channel(CollectionEntity):
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+ news = None
+
+class ChannelManager(CollectionManager, Subsystem):
+ def __init__(self, module, type = Channel):
+ Subsystem.__init__(self, module, module.options, 'channels')
+ CollectionManager.__init__(self, type)
+
+ def on_added(self, channel):
+ self.module.join(channel)
+
+ def on_removed(self, channel):
+ self.module.part(channel)
+
+ def on_banned(self, channel):
+ self.module.part(channel)
+
+ def on_unbanned(self, channel):
+ if channel in self:
+ self.module.join(channel)
-RG_NO = 0x1\r
-ARG_YES = 0x2\r
-ARG_OPT = 0x4\r
-ARG_OFFLINE = 0x8\r
-ARG_OFFLINE_REQ = 0x10\r
-\r
-class CommandManager(object):\r
- def __init__(self):\r
- self.prefix = self.get_prefix()\r
- self.invalid = self.get_invalid()\r
- self.commands = self.get_commands()\r
- self.generate_help()\r
-\r
- def get_prefix(self):\r
- return ''\r
-\r
- def get_invalid(self):\r
- return ''\r
-\r
- def get_commands(self):\r
- return {}\r
-\r
- def get_command(self, command):\r
- command = command.lower()\r
-\r
- if not command.startswith(self.prefix):\r
- return None\r
-\r
- command = command[len(self.prefix):]\r
-\r
- if not command in self.commands:\r
- return None\r
-\r
- command = self.commands[command]\r
-\r
- if not isinstance(command, basestring):\r
- return command\r
-\r
- command = command.lower()\r
-\r
- if not command in self.commands:\r
- return None\r
-\r
- return self.commands[command]\r
-\r
- def get_help(self, command = None):\r
- if command == None:\r
- return self.help\r
- else:\r
- if command.startswith(self.prefix):\r
- command = command[len(self.prefix):]\r
-\r
- if command in self.help_command:\r
- return self.help_command[command]\r
-\r
- return None\r
-\r
- def add_help_command(self, command):\r
- cmd = self.commands[command]\r
-\r
- if isinstance(cmd, basestring):\r
- cmd = self.commands[cmd]\r
-\r
- message = []\r
-\r
- cmd_type = cmd[1]\r
- cmd_desc = cmd[2]\r
- cmd_args = cmd[3]\r
-\r
- message.append('@b%s%s: %s' % (self.prefix, command, cmd_desc))\r
- message.append(' ')\r
-\r
- msg = 'Usage: @b%s%s@b' % (self.prefix, command)\r
-\r
- if len(cmd_args) > 0:\r
- msg += ' ' + ' '.join(['[%s%s]' % (cmd_arg[1], (' ' + cmd_arg[0]) if ('action' not in cmd_arg[3] or cmd_arg[3]['action'] != 'store_true') else '') for cmd_arg in cmd_args])\r
-\r
- if len(cmd) > 4:\r
- argument_name = cmd[4]\r
- else:\r
- argument_name = 'argument'\r
-\r
- if cmd_type & ARG_YES:\r
- msg += ' %s' % argument_name\r
- elif cmd_type & ARG_OPT:\r
- msg += ' [%s]' % argument_name\r
-\r
- message.append(msg)\r
- message.append('')\r
-\r
- longest = 0\r
-\r
- for cmd_arg in cmd_args:\r
- longest = len(cmd_arg[0]) if len(cmd_arg[0]) > longest else longest\r
-\r
- for cmd_arg in cmd_args:\r
- message.append('@b--%-*s (%s)@b %s' % (longest + 1, cmd_arg[0], cmd_arg[1], cmd_arg[2]))\r
-\r
- self.help_command[command] = message\r
-\r
-\r
- def generate_help(self):\r
- self.help = []\r
-\r
- self.help.append('@bCommands@b (type @b%shelp command name@b for detailed information):' % self.prefix)\r
- self.help.append(' ')\r
-\r
- longest = 0\r
- alias_dict = {}\r
- commands = {}\r
-\r
- for cmd in self.commands:\r
- if isinstance(self.commands[cmd], basestring):\r
- orig = self.commands[cmd]\r
-\r
- if orig in alias_dict:\r
- alias_dict[orig].append(cmd)\r
- else:\r
- alias_dict[orig] = [cmd]\r
- else:\r
- if not cmd in alias_dict:\r
- alias_dict[cmd] = []\r
-\r
- for key in alias_dict:\r
- cur = key + ('' if len(alias_dict[key]) == 0 else (' (' + ', '.join(alias_dict[key]) + ')'))\r
- longest = len(cur) if len(cur) > longest else longest\r
- commands[cur] = self.commands[key][2]\r
-\r
- for cmd in sorted(commands):\r
- self.help.append('@b%-*s@b %s' % (longest + 1, cmd, commands[cmd]))\r
-\r
- self.help_command = {}\r
-\r
- for command in self.commands:\r
- self.add_help_command(command)\r
+RG_NO = 0x1
+ARG_YES = 0x2
+ARG_OPT = 0x4
+ARG_OFFLINE = 0x8
+ARG_OFFLINE_REQ = 0x10
+
+class CommandManager(object):
+ def __init__(self):
+ self.prefix = self.get_prefix()
+ self.invalid = self.get_invalid()
+ self.commands = self.get_commands()
+ self.generate_help()
+
+ def get_prefix(self):
+ return ''
+
+ def get_invalid(self):
+ return ''
+
+ def get_commands(self):
+ return {}
+
+ def get_command(self, command):
+ command = command.lower()
+
+ if not command.startswith(self.prefix):
+ return None
+
+ command = command[len(self.prefix):]
+
+ if not command in self.commands:
+ return None
+
+ command = self.commands[command]
+
+ if not isinstance(command, basestring):
+ return command
+
+ command = command.lower()
+
+ if not command in self.commands:
+ return None
+
+ return self.commands[command]
+
+ def get_help(self, command = None):
+ if command == None:
+ return self.help
+ else:
+ if command.startswith(self.prefix):
+ command = command[len(self.prefix):]
+
+ if command in self.help_command:
+ return self.help_command[command]
+
+ return None
+
+ def add_help_command(self, command):
+ cmd = self.commands[command]
+
+ if isinstance(cmd, basestring):
+ cmd = self.commands[cmd]
+
+ message = []
+
+ cmd_type = cmd[1]
+ cmd_desc = cmd[2]
+ cmd_args = cmd[3]
+
+ message.append('@b%s%s: %s' % (self.prefix, command, cmd_desc))
+ message.append(' ')
+
+ msg = 'Usage: @b%s%s@b' % (self.prefix, command)
+
+ if len(cmd_args) > 0:
+ msg += ' ' + ' '.join(['[%s%s]' % (cmd_arg[1], (' ' + cmd_arg[0]) if ('action' not in cmd_arg[3] or cmd_arg[3]['action'] != 'store_true') else '') for cmd_arg in cmd_args])
+
+ if len(cmd) > 4:
+ argument_name = cmd[4]
+ else:
+ argument_name = 'argument'
+
+ if cmd_type & ARG_YES:
+ msg += ' %s' % argument_name
+ elif cmd_type & ARG_OPT:
+ msg += ' [%s]' % argument_name
+
+ message.append(msg)
+ message.append('')
+
+ longest = 0
+
+ for cmd_arg in cmd_args:
+ longest = len(cmd_arg[0]) if len(cmd_arg[0]) > longest else longest
+
+ for cmd_arg in cmd_args:
+ message.append('@b--%-*s (%s)@b %s' % (longest + 1, cmd_arg[0], cmd_arg[1], cmd_arg[2]))
+
+ self.help_command[command] = message
+
+
+ def generate_help(self):
+ self.help = []
+
+ self.help.append('@bCommands@b (type @b%shelp command name@b for detailed information):' % self.prefix)
+ self.help.append(' ')
+
+ longest = 0
+ alias_dict = {}
+ commands = {}
+
+ for cmd in self.commands:
+ if isinstance(self.commands[cmd], basestring):
+ orig = self.commands[cmd]
+
+ if orig in alias_dict:
+ alias_dict[orig].append(cmd)
+ else:
+ alias_dict[orig] = [cmd]
+ else:
+ if not cmd in alias_dict:
+ alias_dict[cmd] = []
+
+ for key in alias_dict:
+ cur = key + ('' if len(alias_dict[key]) == 0 else (' (' + ', '.join(alias_dict[key]) + ')'))
+ longest = len(cur) if len(cur) > longest else longest
+ commands[cur] = self.commands[key][2]
+
+ for cmd in sorted(commands):
+ self.help.append('@b%-*s@b %s' % (longest + 1, cmd, commands[cmd]))
+
+ self.help_command = {}
+
+ for command in self.commands:
+ self.add_help_command(command)
-IRCCOLOR_WHITE = 0\r
-IRCCOLOR_BLACK = 1\r
-IRCCOLOR_BLUE = 2\r
-IRCCOLOR_GREEN = 3\r
-IRCCOLOR_LIGHTRED = 4\r
-IRCCOLOR_BROWN = 5\r
-IRCCOLOR_PURPLE = 6\r
-IRCCOLOR_ORANGE = 7\r
-IRCCOLOR_YELLOW = 8\r
-IRCCOLOR_LIGHTGREEN = 9\r
-IRCCOLOR_CYAN = 10\r
-IRCCOLOR_LIGHTCYAN = 11\r
-IRCCOLOR_LIGHTBLUE = 12\r
-IRCCOLOR_PINK = 13\r
-IRCCOLOR_GREY = 14\r
-IRCCOLOR_LIGHTGREY = 15\r
-\r
-class LogManager(object):\r
- def __init__(self, module):\r
- self.module = module\r
- self.chan = module.chan\r
- if hasattr(module, 'options'):\r
- self.level = module.options.get('log_level', int, 7)\r
- else:\r
- self.level = 7\r
-\r
- def error(self, message):\r
- self.log(message, 0, IRCCOLOR_BROWN),\r
-\r
- def exception(self, message):\r
- self.log(message, 0, IRCCOLOR_LIGHTRED),\r
-\r
- def traceback(self, message):\r
- self.log(message, 1, IRCCOLOR_PURPLE),\r
-\r
- def operation(self, message):\r
- self.log(message, 2, IRCCOLOR_LIGHTGREEN),\r
-\r
- def warning(self, message):\r
- self.log(message, 2, IRCCOLOR_GREEN),\r
-\r
- def request(self, message):\r
- self.log(message, 3, IRCCOLOR_LIGHTCYAN),\r
-\r
- def chanserv(self, message):\r
- self.log(message, 4, IRCCOLOR_ORANGE),\r
-\r
- def commit(self, message):\r
- self.log(message, 5, IRCCOLOR_PINK),\r
-\r
- def command(self, message):\r
- self.log(message, 6, IRCCOLOR_LIGHTBLUE),\r
-\r
- def debug(self, message):\r
- self.log(message, 7, IRCCOLOR_YELLOW),\r
-\r
- def set_level(self, level):\r
- self.level = level\r
- if hasattr(module, 'options'):\r
- self.module.options.set('log_level', level)\r
-\r
- def log(self, message, level, color):\r
- if level > self.level:\r
- return\r
-\r
- self.module.msg(self.chan, '@c%d[%d] %s@o' % (color, level, message))\r
+IRCCOLOR_WHITE = 0
+IRCCOLOR_BLACK = 1
+IRCCOLOR_BLUE = 2
+IRCCOLOR_GREEN = 3
+IRCCOLOR_LIGHTRED = 4
+IRCCOLOR_BROWN = 5
+IRCCOLOR_PURPLE = 6
+IRCCOLOR_ORANGE = 7
+IRCCOLOR_YELLOW = 8
+IRCCOLOR_LIGHTGREEN = 9
+IRCCOLOR_CYAN = 10
+IRCCOLOR_LIGHTCYAN = 11
+IRCCOLOR_LIGHTBLUE = 12
+IRCCOLOR_PINK = 13
+IRCCOLOR_GREY = 14
+IRCCOLOR_LIGHTGREY = 15
+
+class LogManager(object):
+ def __init__(self, module):
+ self.module = module
+ self.chan = module.chan
+ if hasattr(module, 'options'):
+ self.level = module.options.get('log_level', int, 7)
+ else:
+ self.level = 7
+
+ def error(self, message):
+ self.log(message, 0, IRCCOLOR_BROWN),
+
+ def exception(self, message):
+ self.log(message, 0, IRCCOLOR_LIGHTRED),
+
+ def traceback(self, message):
+ self.log(message, 1, IRCCOLOR_PURPLE),
+
+ def operation(self, message):
+ self.log(message, 2, IRCCOLOR_LIGHTGREEN),
+
+ def warning(self, message):
+ self.log(message, 2, IRCCOLOR_GREEN),
+
+ def request(self, message):
+ self.log(message, 3, IRCCOLOR_LIGHTCYAN),
+
+ def chanserv(self, message):
+ self.log(message, 4, IRCCOLOR_ORANGE),
+
+ def commit(self, message):
+ self.log(message, 5, IRCCOLOR_PINK),
+
+ def command(self, message):
+ self.log(message, 6, IRCCOLOR_LIGHTBLUE),
+
+ def debug(self, message):
+ self.log(message, 7, IRCCOLOR_YELLOW),
+
+ def set_level(self, level):
+ self.level = level
+ if hasattr(module, 'options'):
+ self.module.options.set('log_level', level)
+
+ def log(self, message, level, color):
+ if level > self.level:
+ return
+
+ self.module.msg(self.chan, '@c%d[%d] %s@o' % (color, level, message))
-from collection import *\r
-from sys_base import *\r
-from istring import istring\r
-\r
-class OptionManager(InvariantCollection, Subsystem):\r
- def __init__(self, module):\r
- InvariantCollection.__init__(self)\r
- Subsystem.__init__(self, module, self, 'options')\r
- self.module = module\r
- self.db_open()\r
- self.cursor.execute("CREATE TABLE IF NOT EXISTS " + module.name + "_options (name VARCHAR(51) NOT NULL, value TEXT, PRIMARY KEY (name))")\r
- self.cursor.execute("SELECT name, value FROM " + module.name + "_options")\r
- self.deleted_values = []\r
-\r
- for row in self.cursor.fetchall():\r
- name = istring(row[0])\r
- value = istring(row[1])\r
- self[name] = [name, value, False]\r
-\r
- def get(self, name, type, default = None):\r
- if not name in self:\r
- if default != None:\r
- self[name] = [name, istring(default), True]\r
-\r
- return default\r
-\r
- return type(self[name][1])\r
-\r
- def set(self, name, value):\r
- new_value = istring(value)\r
-\r
- if not name in self:\r
- self[name] = [name, new_value, True]\r
- else:\r
- if (self[name][1] != new_value):\r
- self[name][1]= new_value\r
- self[name][2]= True\r
-\r
- return value\r
-\r
- def clear(self, name):\r
- if not name in self:\r
- return False\r
-\r
- self.deleted_values.append(name)\r
- del(self[name])\r
- return True\r
-\r
- def commit(self):\r
- try:\r
- deleted_values = [str(value) for value in self.deleted_values if value not in self]\r
- changed_values = [(str(value[0]), str(value[1])) for value in self.list_all() if value[2]]\r
-\r
- if len(deleted_values) > 0:\r
- self.cursor.executemany("DELETE FROM " + self.module.name + "_options WHERE name = %s", deleted_values)\r
- self.module.elog.commit('Deleted %d options from database.' % len(deleted_values))\r
-\r
- if len(changed_values) > 0:\r
- self.cursor.executemany("REPLACE INTO " + self.module.name + "_options (name, value) VALUES (%s, %s)", changed_values)\r
- self.module.elog.commit('Committed %d options to database.' % len(changed_values))\r
-\r
- self.deleted_values = []\r
-\r
- for value in self.list_all():\r
- value[2] = False\r
- except Exception, err:\r
- self.module.elog.error('Option commit failed: @b%s@b' % err)\r
+from collection import *
+from sys_base import *
+from istring import istring
+
+class OptionManager(InvariantCollection, Subsystem):
+ def __init__(self, module):
+ InvariantCollection.__init__(self)
+ Subsystem.__init__(self, module, self, 'options')
+ self.module = module
+ self.db_open()
+ self.cursor.execute("CREATE TABLE IF NOT EXISTS " + module.name + "_options (name VARCHAR(51) NOT NULL, value TEXT, PRIMARY KEY (name))")
+ self.cursor.execute("SELECT name, value FROM " + module.name + "_options")
+ self.deleted_values = []
+
+ for row in self.cursor.fetchall():
+ name = istring(row[0])
+ value = istring(row[1])
+ self[name] = [name, value, False]
+
+ def get(self, name, type, default = None):
+ if not name in self:
+ if default != None:
+ self[name] = [name, istring(default), True]
+
+ return default
+
+ return type(self[name][1])
+
+ def set(self, name, value):
+ new_value = istring(value)
+
+ if not name in self:
+ self[name] = [name, new_value, True]
+ else:
+ if (self[name][1] != new_value):
+ self[name][1]= new_value
+ self[name][2]= True
+
+ return value
+
+ def clear(self, name):
+ if not name in self:
+ return False
+
+ self.deleted_values.append(name)
+ del(self[name])
+ return True
+
+ def commit(self):
+ try:
+ deleted_values = [str(value) for value in self.deleted_values if value not in self]
+ changed_values = [(str(value[0]), str(value[1])) for value in self.list_all() if value[2]]
+
+ if len(deleted_values) > 0:
+ self.cursor.executemany("DELETE FROM " + self.module.name + "_options WHERE name = %s", deleted_values)
+ self.module.elog.commit('Deleted %d options from database.' % len(deleted_values))
+
+ if len(changed_values) > 0:
+ self.cursor.executemany("REPLACE INTO " + self.module.name + "_options (name, value) VALUES (%s, %s)", changed_values)
+ self.module.elog.commit('Committed %d options to database.' % len(changed_values))
+
+ self.deleted_values = []
+
+ for value in self.list_all():
+ value[2] = False
+ except Exception, err:
+ self.module.elog.error('Option commit failed: @b%s@b' % err)
-from collection import *\r
-from sys_base import *\r
-import inspect\r
-\r
-class User(CollectionEntity):\r
- def __init__(self, id, name):\r
- CollectionEntity.__init__(self, id)\r
- self.name = name\r
-\r
-class UserManager(CollectionManager, Subsystem):\r
- def __init__(self, module, type = User):\r
- Subsystem.__init__(self, module, module.options, 'users')\r
- CollectionManager.__init__(self, type)\r
+from collection import *
+from sys_base import *
+import inspect
+
+class User(CollectionEntity):
+ def __init__(self, id, name):
+ CollectionEntity.__init__(self, id)
+ self.name = name
+
+class UserManager(CollectionManager, Subsystem):
+ def __init__(self, module, type = User):
+ Subsystem.__init__(self, module, module.options, 'users')
+ CollectionManager.__init__(self, type)
-import re\r
-import time\r
-from datetime import datetime\r
-from htmlentitydefs import name2codepoint\r
-\r
-def unix_time(datetime):\r
- return int(time.mktime(datetime.timetuple()))\r
-\r
-def parse_timespan(text):\r
- buffer = ''\r
- duration = 0\r
-\r
- for char in text:\r
- if char == 'd':\r
- duration += int(buffer) * 24 * 60 * 60\r
- buffer = ''\r
- elif char == 'h':\r
- duration += int(buffer) * 60 * 60\r
- buffer = ''\r
- elif char == 'm':\r
- duration += int(buffer) * 60\r
- buffer = ''\r
- elif char == 's':\r
- duration += int(buffer)\r
- buffer = ''\r
- else:\r
- buffer += char\r
-\r
- return duration\r
-\r
-def get_timespan(date):\r
- td = datetime.now() - date\r
- if td.days > 365:\r
- y = int(td.days/365)\r
- return '%d year%s' % (y, 's' if y > 1 else '')\r
- elif td.days > 0:\r
- d = td.days\r
- return '%d day%s' % (d, 's' if d > 1 else '')\r
- elif td.seconds > 3600:\r
- h = int(td.seconds/3600)\r
- return '%d hour%s' % (h, 's' if h > 1 else '')\r
- elif td.seconds > 60:\r
- m = int(td.seconds/60)\r
- return '%d minute%s' % (m, 's' if m > 1 else '')\r
- else:\r
- s = td.seconds\r
- return '%d second%s' % (s, 's' if s > 1 else '')\r
-\r
-def format_name(name):\r
- if name.endswith('s'):\r
- return "%s'" % name\r
- else:\r
- return "%s's" % name\r
-\r
-def format_thousand(number, add_prefix = False):\r
- if not isinstance(number, int):\r
- return str(number)\r
-\r
- text = str(abs(number))\r
-\r
- length = len(text)\r
- count = (length - 1) / 3\r
-\r
- for i in xrange(1, count + 1):\r
- text = text[:length - (i * 3)] + ',' + text[length - (i * 3):]\r
-\r
- if number < 0:\r
- text = '-' + text\r
- elif add_prefix:\r
- text = '+' + text\r
-\r
- return text\r
-\r
-def format_hms(seconds):\r
- hours = seconds / 3600\r
- seconds -= 3600*hours\r
- minutes = seconds / 60\r
- seconds -= 60*minutes\r
- if hours == 0:\r
- return "%02d:%02d" % (minutes, seconds)\r
- return "%02d:%02d:%02d" % (hours, minutes, seconds)\r
-\r
-def format_ascii_irc(message):\r
- return message.replace('@errsep', '@b@c4::@o').replace('@nsep', '@b@c7::@o').replace('@sep', '@b@c3::@o').replace('@b', chr(2)).replace('@c', chr(3)).replace('@o', chr(15)).replace('@u', chr(31))\r
-\r
-def strip_ascii_irc(message):\r
- stripped = ''\r
-\r
- for char in message:\r
- if char not in [chr(2), chr(15), chr(22), chr(31)]: #Not actually stripping color codes, but we don't need that (yet)\r
- stripped += char\r
-\r
- return stripped\r
-\r
-def unescape(s):\r
- "unescape HTML code refs; c.f. http://wiki.python.org/moin/EscapingHtml"\r
-\r
- # XXX: There must be a better way than hardcoding these\r
- name2codepoint['#39'] = 39\r
- name2codepoint['#215'] = 215\r
- name2codepoint['#8260'] = 8260\r
-\r
- return re.sub('&(%s);' % '|'.join(name2codepoint),\r
- lambda m: unichr(name2codepoint[m.group(1)]), s)\r
+import re
+import time
+from datetime import datetime
+from htmlentitydefs import name2codepoint
+
+def unix_time(datetime):
+ return int(time.mktime(datetime.timetuple()))
+
+def parse_timespan(text):
+ buffer = ''
+ duration = 0
+
+ for char in text:
+ if char == 'd':
+ duration += int(buffer) * 24 * 60 * 60
+ buffer = ''
+ elif char == 'h':
+ duration += int(buffer) * 60 * 60
+ buffer = ''
+ elif char == 'm':
+ duration += int(buffer) * 60
+ buffer = ''
+ elif char == 's':
+ duration += int(buffer)
+ buffer = ''
+ else:
+ buffer += char
+
+ return duration
+
+def get_timespan(date):
+ td = datetime.now() - date
+ if td.days > 365:
+ y = int(td.days/365)
+ return '%d year%s' % (y, 's' if y > 1 else '')
+ elif td.days > 0:
+ d = td.days
+ return '%d day%s' % (d, 's' if d > 1 else '')
+ elif td.seconds > 3600:
+ h = int(td.seconds/3600)
+ return '%d hour%s' % (h, 's' if h > 1 else '')
+ elif td.seconds > 60:
+ m = int(td.seconds/60)
+ return '%d minute%s' % (m, 's' if m > 1 else '')
+ else:
+ s = td.seconds
+ return '%d second%s' % (s, 's' if s > 1 else '')
+
+def format_name(name):
+ if name.endswith('s'):
+ return "%s'" % name
+ else:
+ return "%s's" % name
+
+def format_thousand(number, add_prefix = False):
+ if not isinstance(number, int):
+ return str(number)
+
+ text = str(abs(number))
+
+ length = len(text)
+ count = (length - 1) / 3
+
+ for i in xrange(1, count + 1):
+ text = text[:length - (i * 3)] + ',' + text[length - (i * 3):]
+
+ if number < 0:
+ text = '-' + text
+ elif add_prefix:
+ text = '+' + text
+
+ return text
+
+def format_hms(seconds):
+ hours = seconds / 3600
+ seconds -= 3600*hours
+ minutes = seconds / 60
+ seconds -= 60*minutes
+ if hours == 0:
+ return "%02d:%02d" % (minutes, seconds)
+ return "%02d:%02d:%02d" % (hours, minutes, seconds)
+
+def format_ascii_irc(message):
+ return message.replace('@errsep', '@b@c4::@o').replace('@nsep', '@b@c7::@o').replace('@sep', '@b@c3::@o').replace('@b', chr(2)).replace('@c', chr(3)).replace('@o', chr(15)).replace('@u', chr(31))
+
+def strip_ascii_irc(message):
+ stripped = ''
+
+ for char in message:
+ if char not in [chr(2), chr(15), chr(22), chr(31)]: #Not actually stripping color codes, but we don't need that (yet)
+ stripped += char
+
+ return stripped
+
+def unescape(s):
+ "unescape HTML code refs; c.f. http://wiki.python.org/moin/EscapingHtml"
+
+ # XXX: There must be a better way than hardcoding these
+ name2codepoint['#39'] = 39
+ name2codepoint['#215'] = 215
+ name2codepoint['#8260'] = 8260
+
+ return re.sub('&(%s);' % '|'.join(name2codepoint),
+ lambda m: unichr(name2codepoint[m.group(1)]), s)