Add src/Cache.py, use it in modules/coins.py

This commit is contained in:
jesopo 2018-09-29 12:53:39 +01:00
parent c5a7978c9b
commit 47ec11bbef
4 changed files with 69 additions and 14 deletions

View file

@ -101,6 +101,9 @@ class Module(object):
all_coins[nickname])) for nickname in top_10) all_coins[nickname])) for nickname in top_10)
event["stdout"].write("Richest users: %s" % top_10) event["stdout"].write("Richest users: %s" % top_10)
def _redeem_cache(self, server, user):
return "redeem|%s|%s@%s" % (server.id, user.username, user.hostname)
@Utils.hook("received.command.redeemcoins") @Utils.hook("received.command.redeemcoins")
def redeem_coins(self, event): def redeem_coins(self, event):
""" """
@ -109,21 +112,20 @@ class Module(object):
user_coins = decimal.Decimal(event["user"].get_setting( user_coins = decimal.Decimal(event["user"].get_setting(
"coins", "0.0")) "coins", "0.0"))
if user_coins == DECIMAL_ZERO: if user_coins == DECIMAL_ZERO:
last_redeem = event["user"].get_setting("last-redeem", None) cache = self._redeem_cache(event["server"], event["user"])
redeem_delay = event["server"].get_setting("redeem-delay", if not self.bot.cache.has_item(cache):
DEFAULT_REDEEM_DELAY)
if last_redeem == None or (time.time()-last_redeem
) >= redeem_delay:
redeem_amount = decimal.Decimal(event["server" redeem_amount = decimal.Decimal(event["server"
].get_setting("redeem-amount", DEFAULT_REDEEM_AMOUNT)) ].get_setting("redeem-amount", DEFAULT_REDEEM_AMOUNT))
event["user"].set_setting("coins", str( event["user"].set_setting("coins", str(
user_coins+redeem_amount)) user_coins+redeem_amount))
event["stdout"].write("Redeemed %s coins" % "{0:.2f}".format( event["stdout"].write("Redeemed %s coins" % "{0:.2f}".format(
redeem_amount)) redeem_amount))
event["user"].set_setting("last-redeem", time.time())
redeem_delay = event["server"].get_setting("redeem-delay",
DEFAULT_REDEEM_DELAY)
self.bot.cache.temporary_cache(cache, redeem_delay)
else: else:
time_left = (last_redeem+redeem_delay)-time.time() time_left = self.bot.cache.until_expiration(cache)
event["stderr"].write("Please wait %s before redeeming" % event["stderr"].write("Please wait %s before redeeming" %
Utils.to_pretty_time(math.ceil(time_left))) Utils.to_pretty_time(math.ceil(time_left)))
else: else:

50
src/Cache.py Normal file
View file

@ -0,0 +1,50 @@
import time, uuid
class Cache(object):
def __init__(self):
self._items = {}
self._item_to_id = {}
def cache(self, item):
return self._cache(item, None)
def temporary_cache(self, item, timeout):
return self._cache(item, timeout)
def _cache(self, item, timeout):
id = str(uuid.uuid4())
self._items[id] = [item, time.monotonic()+timeout]
self._item_to_id[item] = id
return id
def next_expiration(self):
expirations = [self._items[id][1] for id in self._items]
expirations = list(filter(None, expirations))
if not expirations:
return None
expirations = [e-time.monotonic() for e in expirations]
return max(min(expirations), 0)
def expire(self):
now = time.monotonic()
expired = []
for id in self._items:
item, expiration = self._items[id]
if expiration and expiration <= now:
expired.append(id)
for id in expired:
del self._items[id]
del self._item_to_id[item]
def has_item(self, item):
return item in self._item_to_id
def get(self, id):
item, expiration = self._items[id]
return item
def get_expiration(self, item):
id = self._item_to_id[item]
item, expiration = self._items[id]
return expiration
def until_expiration(self, item):
expiration = self.get_expiration(item)
return expiration-time.monotonic()

View file

@ -2,12 +2,12 @@ import os, select, sys, threading, time, traceback, uuid
from . import EventManager, Exports, IRCLineHandler, IRCServer, Logging from . import EventManager, Exports, IRCLineHandler, IRCServer, Logging
from . import ModuleManager from . import ModuleManager
class Bot(object): class Bot(object):
def __init__(self, directory, args, config, database, events, exports, def __init__(self, directory, args, cache, config, database, events,
line_handler, log, modules, timers): exports, line_handler, log, modules, timers):
self.directory = directory self.directory = directory
self.args = args self.args = args
self.cache = cache
self.config = config self.config = config
self.database = database self.database = database
self._events = events self._events = events
@ -79,6 +79,7 @@ class Bot(object):
timeouts.append(self.next_send()) timeouts.append(self.next_send())
timeouts.append(self.next_ping()) timeouts.append(self.next_ping())
timeouts.append(self.next_read_timeout()) timeouts.append(self.next_read_timeout())
timeouts.append(self.cache.next_expiration())
return min([timeout for timeout in timeouts if not timeout == None]) return min([timeout for timeout in timeouts if not timeout == None])
def register_read(self, server): def register_read(self, server):
@ -120,6 +121,7 @@ class Bot(object):
self.lock.acquire() self.lock.acquire()
events = self.poll.poll(self.get_poll_timeout()) events = self.poll.poll(self.get_poll_timeout())
self.timers.call() self.timers.call()
self.cache.expire()
for fd, event in events: for fd, event in events:
if fd in self.servers: if fd in self.servers:

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse, os, sys, time import argparse, os, sys, time
from src import Config, Database, EventManager, Exports, IRCBot from src import Cache, Config, Database, EventManager, Exports, IRCBot
from src import IRCLineHandler, Logging, ModuleManager, Timers from src import IRCLineHandler, Logging, ModuleManager, Timers
def bool_input(s): def bool_input(s):
@ -31,6 +31,7 @@ args = arg_parser.parse_args()
log = Logging.Log(args.log) log = Logging.Log(args.log)
cache = Cache.Cache()
config = Config.Config(args.config) config = Config.Config(args.config)
database = Database.Database(log, args.database) database = Database.Database(log, args.database)
events = events = EventManager.EventHook(log) events = events = EventManager.EventHook(log)
@ -40,8 +41,8 @@ line_handler = IRCLineHandler.LineHandler(events, timers)
modules = modules = ModuleManager.ModuleManager(events, exports, config, log, modules = modules = ModuleManager.ModuleManager(events, exports, config, log,
os.path.join(directory, "modules")) os.path.join(directory, "modules"))
bot = IRCBot.Bot(directory, args, config, database, events, exports, bot = IRCBot.Bot(directory, args, cache, config, database, events,
line_handler, log, modules, timers) exports, line_handler, log, modules, timers)
whitelist = bot.get_setting("module-whitelist", []) whitelist = bot.get_setting("module-whitelist", [])
blacklist = bot.get_setting("module-blacklist", []) blacklist = bot.get_setting("module-blacklist", [])