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
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
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', [])
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
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
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
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
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