コード例 #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
コード例 #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
コード例 #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()
コード例 #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()
コード例 #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
コード例 #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
コード例 #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', [])
コード例 #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
コード例 #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
コード例 #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
コード例 #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
コード例 #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
コード例 #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
コード例 #14
0
ファイル: main.py プロジェクト: Asperger/PCRD-DiscordBot
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)
コード例 #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
コード例 #16
0
ファイル: args.py プロジェクト: Asperger/PCRD-DiscordBot
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
コード例 #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

コード例 #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)
コード例 #19
0
ファイル: main.py プロジェクト: Asperger/PCRD-DiscordBot
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)
コード例 #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]
コード例 #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]
コード例 #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]
コード例 #23
0
ファイル: timer.py プロジェクト: Asperger/PCRD-DiscordBot

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()