Add module.
This commit is contained in:
100
bot/modules/study/time_tracker.py
Normal file
100
bot/modules/study/time_tracker.py
Normal file
@@ -0,0 +1,100 @@
|
||||
import itertools
|
||||
import traceback
|
||||
import logging
|
||||
import asyncio
|
||||
from time import time
|
||||
|
||||
from meta import client
|
||||
from core import Lion
|
||||
|
||||
from .module import module
|
||||
from . import admin
|
||||
|
||||
|
||||
last_scan = {} # guildid -> timestamp
|
||||
|
||||
|
||||
def _scan(guild):
|
||||
"""
|
||||
Scan the tracked voice channels and add time and coins to each user.
|
||||
"""
|
||||
# Current timestamp
|
||||
now = time()
|
||||
|
||||
# Get last scan timestamp
|
||||
try:
|
||||
last = last_scan[guild.id]
|
||||
except KeyError:
|
||||
return
|
||||
finally:
|
||||
last_scan[guild.id] = now
|
||||
|
||||
# Calculuate time since last scan
|
||||
interval = now - last
|
||||
|
||||
# Discard if it has been more than 20 minutes (discord outage?)
|
||||
if interval > 60 * 20:
|
||||
return
|
||||
|
||||
untracked = admin.untracked_channels.get(guild.id).data
|
||||
hourly_reward = admin.hourly_reward.get(guild.id).data
|
||||
hourly_live_bonus = admin.hourly_live_bonus.get(guild.id).data
|
||||
|
||||
channel_members = (
|
||||
channel.members for channel in guild.voice_channels if channel.id not in untracked
|
||||
)
|
||||
|
||||
members = itertools.chain(*channel_members)
|
||||
# TODO filter out blacklisted users
|
||||
|
||||
for member in members:
|
||||
lion = Lion.fetch(guild.id, member.id)
|
||||
|
||||
# Add time
|
||||
lion.addTime(interval, flush=False)
|
||||
|
||||
# Add coins
|
||||
hour_reward = hourly_reward
|
||||
if member.voice.self_stream or member.voice.self_video:
|
||||
hour_reward += hourly_live_bonus
|
||||
|
||||
lion.addCoins(hour_reward * interval / (3600), flush=False)
|
||||
|
||||
|
||||
async def _study_tracker():
|
||||
"""
|
||||
Scanner launch loop.
|
||||
"""
|
||||
while True:
|
||||
while not client.is_ready():
|
||||
await asyncio.sleep(1)
|
||||
|
||||
await asyncio.sleep(5)
|
||||
|
||||
# Launch scanners on each guild
|
||||
for guild in client.guilds:
|
||||
# Short wait to pass control to other asyncio tasks if they need it
|
||||
await asyncio.sleep(0)
|
||||
try:
|
||||
# Scan the guild
|
||||
_scan(guild)
|
||||
except Exception:
|
||||
# Unknown exception. Catch it so the loop doesn't die.
|
||||
client.log(
|
||||
"Error while scanning guild '{}'(gid:{})! "
|
||||
"Exception traceback follows.\n{}".format(
|
||||
guild.name,
|
||||
guild.id,
|
||||
traceback.format_exc()
|
||||
),
|
||||
context="VOICE_ACTIVITY_SCANNER",
|
||||
level=logging.ERROR
|
||||
)
|
||||
|
||||
|
||||
@module.launch_task
|
||||
async def launch_study_tracker(client):
|
||||
asyncio.create_task(_study_tracker())
|
||||
|
||||
|
||||
# TODO: Logout handler, sync
|
||||
Reference in New Issue
Block a user