Example #1
0
def increment(table, column_value, where):
    if not column_value:
        return False

    sets = ''
    for i in column_value:
        if where.startswith(i):
            continue
        if type(column_value[i]) is str:
            sets += f'''{i}='{column_value[i]}','''
        else:
            sets += f'''{i}={i}+{column_value[i]},'''
    sql = f'''UPDATE {table} SET {sets[:-1]} WHERE {where}'''

    cursor = _conn.cursor()
    cursor.execute("BEGIN")
    try:
        cursor.execute(sql)
    except OperationalError:
        FileLogger.exception(f'Exception at {__file__} {__name__}\nSQL: {sql}')
        _conn.rollback()
        return False
    cursor.execute("COMMIT") 
    _conn.commit()
    return True
Example #2
0
def fill_sheet(player_discord_id, description, play_number, boss_tag, damage,
               play_option, play_miss):
    global _undo, _sheet_lock
    if player_discord_id not in _player_list:
        FileLogger.warn(f'Discord ID: {player_discord_id} not found in sheet')
        return False
    player_nickname = _player_list[player_discord_id]

    today = get_settlement_time_object()
    play_tag = f"{play_number}{'B' if play_option == '補' else 'A'}"
    missing_tag = '閃' if play_miss > 0 else ''
    body = {
        'values': [[
            today.strftime("%Y/%m/%d %H:%M:%S"), player_nickname, play_tag,
            damage, boss_tag, missing_tag
        ]]
    }
    play_day_offset = today - _start_date
    range_name = f'Day {play_day_offset.days + 1}-Log!A2:F'

    _sheet_lock.acquire()
    result = append_sheet(range_name, body)
    _sheet_lock.release()

    checkResult = True
    try:
        updates = result.get('updates')
        updated_range = updates.get('updatedRange')
        _undo['undostack'].append([updated_range, body, description])
        _undo['redostack'] = []
    except Exception as e:
        FileLogger.error(f'Fail to get result: {description}\n' + str(e))
        checkResult = False

    return checkResult
Example #3
0
def setup_guild_member_list(guild, override=False):
    global timer_member, _guild_member_list
    if bool(_guild_member_list):
        elapsed_time = time() - timer_member
        if elapsed_time < 86400 and not override:
            return

    FileLogger.info(f'Setting up members in {guild.name}')
    _guild_member_list = {}
    for i in range(0, len(guild.members)):
        valid = False
        for role in guild.members[i].roles:
            if role.name == '隊員':
                valid = True
                break
        if not valid:
            continue

        nick = guild.members[i].nick
        display_name = guild.members[i].display_name
        if nick:
            _guild_member_list[guild.members[i].id] = nick
        elif display_name:
            _guild_member_list[guild.members[i].id] = display_name
        else:
            _guild_member_list[guild.members[i].id] = guild.members[i].name
    timer_member = time()
Example #4
0
def setup_guild_channel_list(guild, override=False):
    global timer_channel, _guild_channel_list, _guild_channel_board
    if bool(_guild_channel_list):
        elapsed_time = time() - timer_channel
        if elapsed_time < 86400 and not override:
            return

    FileLogger.info(f'Setting up channels in {guild.name}')
    _guild_channel_list = {}
    for channel in guild.channels:
        if channel.type.name == 'text' and channel.category.name.endswith(
                '公會戰討論區'):
            if channel.name.startswith('一王'):
                _guild_channel_list[1] = channel.id
                _guild_channel_list[channel.id] = 1
            elif channel.name.startswith('二王'):
                _guild_channel_list[2] = channel.id
                _guild_channel_list[channel.id] = 2
            elif channel.name.startswith('三王'):
                _guild_channel_list[3] = channel.id
                _guild_channel_list[channel.id] = 3
            elif channel.name.startswith('四王'):
                _guild_channel_list[4] = channel.id
                _guild_channel_list[channel.id] = 4
            elif channel.name.startswith('五王'):
                _guild_channel_list[5] = channel.id
                _guild_channel_list[channel.id] = 5
        if channel.type.name == 'text' and channel.name.endswith('刀傷登記區'):
            _guild_channel_board = channel.id
    timer_channel = time()
Example #5
0
def insert(table, column_value):
    if not column_value:
        return False

    columns = ''
    values = ''
    for i in column_value:
        columns += f'{i},'
        if type(column_value[i]) is str:
            values += f'\'{column_value[i]}\','
        else:
            values += f'{column_value[i]},'
    play_date = get_settlement_time()
    sql = f'''INSERT INTO {table} ({columns}play_date) VALUES ({values}'{play_date}')'''

    cursor = _conn.cursor()
    cursor.execute("BEGIN")
    try:
        cursor.execute(sql)
    except OperationalError:
        FileLogger.exception(f'Exception at {__file__} {__name__}\nSQL: {sql}')
        _conn.rollback()
        return False
    cursor.execute("COMMIT") 
    _conn.commit()
    return True
Example #6
0
 def backup(self):
     result = False
     with self._lock:
         with open(self._store_path, 'w', encoding="utf-8") as f:
             try:
                 f.write(repr(self._store))
                 result = True
             except Exception as e:
                 FileLogger.error(f'Fail to write dictionary: {str(e)}')
     return result
Example #7
0
def read_sheet(range_name):
    try:
        sheets = _service.spreadsheets()
        result = sheets.values().get(spreadsheetId=_spreadsheet_id,
                                     range=range_name).execute()
    except Exception as e:
        FileLogger.error(
            f'Fail to read sheet: ID={_spreadsheet_id}, range={range_name}\n' +
            str(e))
        return
    return result.get('values', [])
Example #8
0
def clear_line(boss_id: int) -> bool:
    global _guild_lines
    if boss_id in _guild_lines:
        _guild_lines[boss_id]["player_ids"] = {}
    elif boss_id == 0:
        for key in _guild_lines:
            _guild_lines[key]["player_ids"] = {}
    else:
        return False
    backup()
    FileLogger.info('clear_line executed')
    return True
Example #9
0
def get_player_list():
    global _player_list
    values = read_sheet('隊員列表!B2:C')

    if not values:
        FileLogger.error('No player list found.')
        return None
    else:
        _player_list = {}
        for row in values:
            _player_list[int(row[1])] = row[0]
        return _player_list
Example #10
0
def append_sheet(range_name, body, option='RAW'):
    try:
        sheets = _service.spreadsheets()
        result = sheets.values().append(spreadsheetId=_spreadsheet_id,
                                        range=range_name,
                                        body=body,
                                        valueInputOption=option).execute()
    except Exception as e:
        FileLogger.error(
            f'Fail to append sheet: ID={_spreadsheet_id}, range={range_name}\n'
            + str(e))
        return
    return result
Example #11
0
 def setpath(self, path: str) -> bool:
     result = False
     self._store_path = path
     if exists(path):
         with open(path, 'r', encoding="utf-8") as f:
             spam_setting_str = f.read()
             if spam_setting_str:
                 try:
                     self._store = eval(spam_setting_str)
                     result = True
                 except Exception as e:
                     FileLogger.error(f'Fail to read dictionary: {str(e)}')
                     self._store = dict()
     return result
Example #12
0
def get_start_date():
    global _start_date
    values = read_sheet('隊員列表!A1:A1')

    if not values:
        FileLogger.error('No start date found.')
        return None
    else:
        date_tokens = values[0][0].split('/')
        settlement_time = get_settlement_time_object()
        _start_date = datetime(
            year=int(date_tokens[0]),
            month=int(date_tokens[1]),
            day=int(date_tokens[2])).replace(tzinfo=settlement_time.tzinfo)
        return _start_date
Example #13
0
def query(table, where):
    cursor = _conn.cursor()

    sql = f'''SELECT * FROM {table} WHERE {where}'''
    result = []
    try:
        cursor.execute(sql)
        row = cursor.fetchone()  
        while row:
            column_value = {}
            for i in range(len(cursor.description)):
                column_value[str(cursor.description[i][0])] = row[i]
            result.append(column_value)    
            row = cursor.fetchone()
    except OperationalError:
        FileLogger.exception(f'Exception at {__file__} {__name__}\nSQL: {sql}')
    return result
Example #14
0
async def on_message(message):
    if message.content == '!stop' and message.author.guild_permissions.administrator:
        FileLogger.info('User requested shutdown')
        execute()
        await client.logout()
        return

    # we do not want the bot to reply to itself
    if message.author.bot:
        return

    if message.content.startswith('!') or message.content.startswith('!'):
        setup_guild_channel_list(message.author.guild)
        setup_guild_member_list(message.author.guild)

        user_auth = {
            'guild_id': message.author.guild.id,
            'user_id': message.author.id,
            'user_admin': message.author.guild_permissions.administrator,
            'channel_id': message.channel.id
        }

        content = message.content[1:]
        if message.attachments:
            content += f' {message.attachments[0].url}'
        msg = parse_args(user_auth, content)
        if msg:
            if isinstance(msg, Mapping):
                # it's a dict
                embed = get_embed(message.author, msg)
                await message.channel.send(embed=embed)
            elif isinstance(msg, list):
                # it's a list
                embed = embed_template(message.author)
                for i in range(len(msg)):
                    embed.add_field(name=i, value=msg[i], inline=False)
                await message.channel.send(embed=embed)
            elif is_url(msg):
                # it's an url
                embed = Embed(color=0xffa200)
                embed.set_image(url=msg)
                await message.channel.send(embed=embed)
            else:
                await message.channel.send(msg)
Example #15
0
def redo():
    global _undo, _sheet_lock
    op = _undo['redostack'][-1]
    _undo['redostack'] = _undo['redostack'][0:-1]
    (range_name, body, description) = op

    _sheet_lock.acquire()
    result = write_sheet(range_name, body)
    _sheet_lock.release()

    try:
        updated_range = result.get('updatedRange')
    except Exception as e:
        FileLogger.error(f'Fail to get redo result: {description}\n' + str(e))

    if updated_range and range_name == updated_range:
        _undo['undostack'].append([updated_range, body, description])
        return description
    else:
        FileLogger.error(f'Inconsistent redo result: {description}')
        return None
Example #16
0
def parse_args(user_auth, string):
    args = strQ2B(string).split()
    response = ''
    if not args:
        return response

    # Find command, otherwise consider it as spam
    cmd = get_cmd(args[0])
    if cmd:
        args = args[1:]
    else:
        cmd = "spam"

    # Create the instance
    try:
        inst = getattr(globals()[cmd], cmd)()
    except KeyError:
        FileLogger.warn(f'No command found')
    except Exception:
        FileLogger.exception(f'Exception at {__file__} {__name__}')

    # Execute the function
    FileLogger.info(f"{user_auth['user_id']} call {cmd} with {args}")
    try:
        if len(args) == 1 and args[0] == 'help':
            response = inst.usage
        elif not inst.check_param(args):
            response = inst.usage
        elif not inst.check_auth(user_auth):
            response = inst.auth_warning
        else:
            response = inst.run(user_auth, args)
    except Exception:
        FileLogger.exception(f'Exception at {__file__} {__name__}')

    return response
Example #17
0
# -*- coding: utf-8 -*-
import json
import functools
import traceback

from utils.log import FileLogger, Logger

DEBUG = True

if not DEBUG:
    logger = FileLogger('wshandler.txt')
else:
    logger = Logger()


def on_redis(func):
    @functools.wraps(func)
    def _wrap(*args, **kwargs):
        func(*args, **kwargs)

    return _wrap


def on_ws(func):
    @functools.wraps(func)
    def _wrap(*args, **kwargs):
        func(*args, **kwargs)

    return _wrap

Example #18
0
monkey.patch_all()
from gevent import Greenlet
import redis

from utils.redissub import RedisSub
from utils.redisvalue import RemoteRedis
import utils.exprv
from components.autohost import AutoHost
from utils.log import FileLogger, Logger
import components.hub as hub
import components.hosthandler as hosthandler

DEBUG = True

if not DEBUG:
    logger = FileLogger('expserver.txt')
else:
    logger = Logger()

exp_list = {}
rc = redis.Redis()

db = torndb.Connection("localhost", 'exp', user='******', password='******')


class Server(Greenlet):
    def __init__(self, channel='experiment'):
        super(Server, self).__init__()

        self.redis = rc
        self.sub = RedisSub(channel, self.on_message)
Example #19
0
async def on_ready():
    FileLogger.info(f'Logged in as {client.user.name}({client.user.id})')
    for guild in client.guilds:
        setup_guild_channel_list(guild, True)
        setup_guild_member_list(guild, True)
Example #20
0
def get_guild_member_nickname(user_id):
    if user_id not in _guild_member_list:
        FileLogger.warn('Unknown user id')
        return
    return _guild_member_list[user_id]
Example #21
0
def get_guild_channel_index(channel_id):
    if channel_id not in _guild_channel_list:
        FileLogger.warn('Unknown channel id')
        return
    return _guild_channel_list[channel_id]
Example #22
0
def get_guild_channel_id(boss_index):
    if boss_index not in _guild_channel_list:
        FileLogger.warn('Unknown boss index')
        return
    return _guild_channel_list[boss_index]
Example #23
0

def get_settlement_time_object():
    return datetime.now(_eu_moscow)


def get_settlement_time():
    return datetime.now(_eu_moscow).strftime('%Y-%m-%d')


_transition_point = get_settlement_time_object().replace(hour=0,
                                                         minute=0,
                                                         second=0,
                                                         microsecond=0)
_local_transition_point = _transition_point.astimezone()
FileLogger.info(f"Schedule daily task clear_line at {_local_transition_point}")
schedule.every().day.at(_local_transition_point.strftime('%H:%M:%S')).do(
    clear_line, boss_id=0)

cease_continuous_run = threading.Event()


class ScheduleThread(threading.Thread):
    @classmethod
    def run(cls):
        while not cease_continuous_run.is_set():
            schedule.run_pending()
            time.sleep(1)


continuous_thread = ScheduleThread()