async def getlink(self, ctx, *args): """ Lấy link của bài tập trên codeforces, ví dụ nếu mình muốn lấy link bài AZNET thì dùng: ;voj getlink AZNET Hiện tại có thể lấy link của 3 contest VOI, VNOI Online và Vnoi maration, cách dùng: ;voj getlink [contest] [năm] Trong đó contest thuộc 1 trong 3 tên: [VOI, VO, VM]. Ví dụ: ;voj getlink VOI 2020 """ if len(args) == 0: embed = discord_common.embed_alert('Thiếu tên bài/tên contest') await ctx.send(embed=embed) return if len(args) == 1: name = args[0].upper() if name not in self.link: await ctx.send('Không tìm thấy bài {0}.'.format(name)) return links = self.link[name].strip(',').split(',') links = list(map(lambda x: '<' + x + '>', links)) await ctx.send('\n'.join(links)) return if len(args) != 2: embed = discord_common.embed_alert( 'Quá nhiều tham số, nếu muốn lấy link contest thì ghi tắt tên (VM, VOI, VO) thôi.' ) await ctx.send(embed=embed) return contest = args[0].upper() try: year = int(args[1]) except Exception as e: embed = discord_common.embed_alert( f"`{args[1]}` không phải là một số") await ctx.send(embed=embed) return if contest not in CONTEST_YEAR_BOUND: embed = discord_common.embed_alert( "Tên của contest phải thuộc 1 trong 3 [VOI, VO, VM]") await ctx.send(embed=embed) return contest_name = CONTEST_NAMES[contest] if year > CONTEST_YEAR_BOUND[contest][1] or year < CONTEST_YEAR_BOUND[ contest][0]: embed = discord_common.embed_alert( f"Trong dữ liệu hiện tại, contest {contest_name} chỉ có từ năm {CONTEST_YEAR_BOUND[contest][0]} " f"tới {CONTEST_YEAR_BOUND[contest][1]}") await ctx.send(embed=embed) return contest_name = contest_name + ' ' + str(year) # vnoi marathon 2008 had 2 divs if contest == 'VM' and year == 2008: await self.send_contest_info(ctx, contest_name + ' - div 1') await self.send_contest_info(ctx, contest_name + ' - div 2') elif contest == 'VOI' and year == 2019: await ctx.send('Chưa xin được test của VOI 2019.') else: await self.send_contest_info(ctx, contest_name)
async def add(self, ctx, *args): """ Thêm tag vào bài, lưu ý các tag cần cách nhau bởi space. comment cần được đặt vào giữa 2 dấu \"\". Ví dụ: `;add dp-tree bitset dsu-general `\n Hoặc: `;add dp-tree \"bài này tuy tag dp-tree nhưng có thể làm thuật toán tham lam tốt hơn\"` (comment cần có ít nhất 3 từ) """ current_problem = codeforces_api.get_current_problem(ctx.author.id) if current_problem is None: await ctx.author.send( f"{ctx.author.mention} chưa được phân công bài nào <:sadness:662197924918329365>," + "hãy dùng lệnh `;get` để được phân công bài <:dad:661181642802724894>." ) return problem_short_link = current_problem['short_link'] # parse arg params = parser.tag_parse(args) if isinstance(params, str): embed = discord_common.embed_alert(params) await ctx.author.send(embed=embed) return tags, comment = params msg = "" any_error = False for tag in tags: tag = TaggingDb.normalize_tag(tag) # get tag real_tag = await helper.tag.get_similar_tag(ctx, tag) if real_tag is None: any_error = True continue TaggingDb.TaggingDb.tagging(problem_short_link, real_tag, ctx.author.id) msg += '\n-`{}` (giống `{}`).'.format(real_tag, tag) if len(msg) != 0: await ctx.author.send('Các tag đã tìm thấy:', embed=discord_common.embed_success(msg)) if comment == parser._COMMENT_LENGTH_MSG: embed = discord_common.embed_alert("Comment cần có ít nhất 3 từ") await ctx.send(embed=embed) elif len(comment) > 0: TaggingDb.TaggingDb.commenting(problem_short_link, comment, ctx.author.id) # -------------------------------------------------------------- embed = problem_to_embed(current_problem, ctx.author.id) if any_error: await ctx.author.send('Thông tin hiện tại của bài:', embed=embed) else: await ctx.author.send( 'Nếu tag xong rồi bạn có thể dùng `;done` để lấy bài tập mới.' 'Thông tin hiện tại của bài:', embed=embed)
async def create(self, ctx, *args): """ Tạo (nhiều) tag mới, có thể có unicode, các tag cách nhau bởi dấu `;` Ví dụ ;create Quy Hoạch Động; Segment tree """ tags = list(filter(lambda x: len(x) > 0, args)) error_msg = "" added_msg = "" for tag in tags: tag = TaggingDb.normalize_tag(tag) similar = TaggingDb.TaggingDb.get_similar_tag(tag) if len(similar) > 0: if similar[0][0] >= _LCS_THRESHOLD_: error_msg += '`{}` giống `{}`\n'.format(tag, similar[0][1]) continue added_msg += tag + '\n' await self._create(None, tag) if len(error_msg) > 0: embed = discord_common.embed_alert(error_msg.strip()) await ctx.author.send( 'Các tag chưa được thêm vì giống trong database, dùng _create để force create:', embed=embed) if len(added_msg) > 0: embed = discord_common.embed_success(added_msg) await ctx.author.send('Các tag đã được thêm:', embed=embed)
async def get_similar_tag(ctx, tag): _LV1_TAGS = json.load( open('database/detailed_suggestions.json', encoding='utf-8')) if tag in _LV1_TAGS: name = _LV1_TAGS[tag]['name'] tag_codes = _LV1_TAGS[tag]['codes'] try: t = table.make_table(tag_codes) except ValueError: raise ValueError( f"Tag {name} is too long, expected length <= 30, found {len(tag_codes)}" ) table_str = f'```yml\n{t}\n```' await ctx.author.send( f'Bạn có thể ghi chi tiết hơn về tag `{name}` được không <:blowop:665243570696880129>? ' 'Dưới đây là list một số tag có thể liên quan\n' + table_str) return similar = TaggingDb.TaggingDb.get_similar_tag(tag) if len(similar) == 0: embed = discord_common.embed_alert( 'Không tìm thấy tag `{}`'.format(tag)) await ctx.author.send(embed=embed) return if similar[0][0] < _LCS_THRESHOLD_: msg = 'Không tìm thấy tag nào giống `{}`. '.format(tag) msg_similar = "" for i in range(min(5, len(similar))): if similar[i][0] == 0: break msg_similar += '\n- ' + similar[i][1] if len(msg_similar) > 0: msg += 'Một số tag có thể giống:' embed = discord_common.embed_alert(msg_similar) await ctx.author.send(msg, embed=embed) return await ctx.author.send(msg) return return similar[0][1]
async def modify(self, ctx, old_tag, new_tag): old_tag = TaggingDb.normalize_tag(old_tag) new_tag = TaggingDb.normalize_tag(new_tag) s = TaggingDb.TaggingDb.rename(old_tag, new_tag) if s is not None: embed = discord_common.embed_alert(s) await ctx.author.send(embed=embed) return # update suggestion _LV1_TAGS = json.load( open('database/detailed_suggestions.json', encoding='utf-8')) for x in _LV1_TAGS: for i, tag in enumerate(_LV1_TAGS[x]['codes']): if tag == old_tag: _LV1_TAGS[x]['codes'][i] = new_tag json.dump( _LV1_TAGS, open('database/detailed_suggestions.json', 'w', encoding='utf-8')) await ctx.author.send(f'Đã đổi tên tag {old_tag} sang {new_tag}')
async def suggest(self, ctx, lv1_tag, tag): tag = TaggingDb.normalize_tag(tag) lv1_tag = TaggingDb.normalize_tag(lv1_tag) _LV1_TAGS = json.load( open('database/detailed_suggestions.json', encoding='utf-8')) if lv1_tag not in _LV1_TAGS: msg = [x for x in _LV1_TAGS] embed = discord_common.embed_alert( f"Không thấy suggestion {lv1_tag}.\n" f"Các lv1 tag hiện có: {', '.join([x for x in _LV1_TAGS])}") await ctx.author.send(embed=embed) return _LV1_TAGS[lv1_tag]['codes'].append(tag) json.dump( _LV1_TAGS, open('database/detailed_suggestions.json', 'w', encoding='utf-8')) await ctx.author.send( f"Đã thêm. Các tag có trong `{_LV1_TAGS[lv1_tag]['name']}`:\n{_LV1_TAGS[lv1_tag]['codes']}" )
async def remove(self, ctx, *args): """ Xóa tag đã add vào bài, param giống add Ví dụ ;remove dp-tree bitset """ current_problem = codeforces_api.get_current_problem(ctx.author.id) if current_problem is None: await ctx.author.send( f"{ctx.author.mention} chưa được phân công bài nào <:sadness:662197924918329365>," "hãy dùng lệnh `;get` để được phân công bài.") return problem_short_link = current_problem['short_link'] # parse arg params = parser.tag_parse(args, True) if isinstance(params, str): embed = discord_common.embed_alert(params) await ctx.author.send(embed=embed) return tags, comment = params msg = "" for tag in tags: tag = TaggingDb.normalize_tag(tag) # get tag real_tag = await helper.tag.get_similar_tag(ctx, tag) if real_tag is None: continue TaggingDb.TaggingDb.remove_tag(problem_short_link, real_tag, ctx.author.id) msg += '\n-`{}` (giống `{}`).'.format(real_tag, tag) if len(msg) != 0: await ctx.author.send('Các tag đã tìm thấy:', embed=discord_common.embed_success(msg)) embed = problem_to_embed(current_problem, ctx.author.id) await ctx.author.send('Thông tin hiện tại của bài:', embed=embed)
async def on_command_error(ctx, error): print(error) if ctx.guild is not None and str(ctx.channel.id) != str(_LOG_CHANNEL_): # raise Exception('!!!! This is not the #bot channel, bot will do nothing') return await ctx.send(embed=discord_common.embed_alert(error))
async def on_command_error(ctx, error): print(error) await ctx.send(embed=discord_common.embed_alert(error))