diff --git a/fifo/datetimeconverter.py b/fifo/datetimeconverter.py index c3f96ee..def0403 100644 --- a/fifo/datetimeconverter.py +++ b/fifo/datetimeconverter.py @@ -4,13 +4,14 @@ from typing import TYPE_CHECKING from discord.ext.commands import BadArgument, Converter from dateutil import parser +from fifo.timezones import assemble_timezones if TYPE_CHECKING: DatetimeConverter = datetime else: class DatetimeConverter(Converter): async def convert(self, ctx, argument) -> datetime: - dt = parser.parse(argument, fuzzy=True) + dt = parser.parse(argument, fuzzy=True, tzinfos=assemble_timezones()) if dt is not None: return dt raise BadArgument() diff --git a/fifo/fifo.py b/fifo/fifo.py index b65b681..4c174ee 100644 --- a/fifo/fifo.py +++ b/fifo/fifo.py @@ -1,6 +1,6 @@ import logging from datetime import datetime, timedelta -from typing import Dict, Union +from typing import Dict, List, Union import discord from apscheduler.job import Job @@ -63,7 +63,7 @@ class FakeMessage2(discord.Message): class FakeMessage: def __init__(self, message: discord.Message): - d = {k: getattr(message, k) for k in dir(message)} + d = {k: getattr(message, k, None) for k in dir(message)} self.__dict__.update(**d) @@ -102,20 +102,21 @@ class Task: if t["type"] == "date": # Convert into datetime dt: datetime = t["time_data"] - triggers.append( - { - "type": t["type"], - "time_data": { - "year": dt.year, - "month": dt.month, - "day": dt.day, - "hour": dt.hour, - "minute": dt.minute, - "second": dt.second, - "tzinfo": dt.tzinfo - }, - } - ) + triggers.append({"type": t["type"], "time_data": dt.isoformat()}) + # triggers.append( + # { + # "type": t["type"], + # "time_data": { + # "year": dt.year, + # "month": dt.month, + # "day": dt.day, + # "hour": dt.hour, + # "minute": dt.minute, + # "second": dt.second, + # "tzinfo": dt.tzinfo, + # }, + # } + # ) continue if t["type"] == "cron": @@ -134,7 +135,8 @@ class Task: continue if t["type"] == "date": # Convert into datetime - self.data["triggers"][n]["time_data"] = datetime(**t["time_data"]) + # self.data["triggers"][n]["time_data"] = datetime(**t["time_data"]) + self.data["triggers"][n]["time_data"] = datetime.fromisoformat(t["time_data"]) continue if t["type"] == "cron": @@ -161,7 +163,16 @@ class Task: await self._decode_time_triggers() return self.data - async def get_trigger(self) -> Union[BaseTrigger, None]: + async def get_triggers(self) -> List[Union[IntervalTrigger, DateTrigger]]: + if not self.data: + await self.load_from_config() + + if self.data is None or "triggers" not in self.data: # No triggers + return [] + + return [get_trigger(t) for t in self.data["triggers"]] + + async def get_combined_trigger(self) -> Union[BaseTrigger, None]: if not self.data: await self.load_from_config() @@ -178,7 +189,7 @@ class Task: data_to_save = self.default_task_data.copy() if self.data: - data_to_save["command_str"] = self.data.get("command_str", "") + data_to_save["command_str"] = self.get_command_str() data_to_save["triggers"] = await self._encode_time_triggers() to_save = { @@ -202,7 +213,7 @@ class Task: ) async def execute(self): - if not self.data or not self.data.get("command_str", False): + if not self.data or not self.get_command_str(): log.warning(f"Could not execute task due to data problem: {self.data=}") return False @@ -236,7 +247,7 @@ class Task: else: prefix = prefixes[0] - message.content = f"{prefix}{self.data['command_str']}" + message.content = f"{prefix}{self.get_command_str()}" if not message.guild or not message.author or not message.content: log.warning(f"Could not execute task due to message problem: {message}") @@ -257,6 +268,9 @@ class Task: async def set_author(self, author: Union[discord.User, str]): self.author_id = getattr(author, "id", None) or author + def get_command_str(self): + return self.data.get("command_str", "") + async def set_commmand_str(self, command_str): if not self.data: self.data = self.default_task_data.copy() @@ -348,10 +362,10 @@ class FIFO(commands.Cog): return new_ctx.valid async def _process_task(self, task: Task): - job = await self._get_job(task) + job: Union[Job, None] = await self._get_job(task) if job is not None: - job.remove() - + job.reschedule(await task.get_combined_trigger()) + return job return await self._add_job(task) async def _get_job(self, task: Task) -> Job: @@ -362,7 +376,7 @@ class FIFO(commands.Cog): _execute_task, args=[task.__getstate__()], id=_assemble_job_id(task.name, task.guild_id), - trigger=await task.get_trigger(), + trigger=await task.get_combined_trigger(), ) async def _pause_job(self, task: Task): @@ -375,10 +389,10 @@ class FIFO(commands.Cog): @commands.command() async def fifoclear(self, ctx: commands.Context): """Debug command to clear all current fifo data""" + self.scheduler.remove_all_jobs() await self.config.guild(ctx.guild).tasks.clear() await self.config.jobs.clear() await self.config.jobs_index.clear() - self.scheduler.remove_all_jobs() await ctx.tick() @checks.is_owner() # Will be reduced when I figure out permissions later @@ -390,6 +404,47 @@ class FIFO(commands.Cog): if ctx.invoked_subcommand is None: pass + @fifo.command(name="details") + async def fifo_details(self, ctx: commands.Context, task_name: str): + """ + Provide all the details on the specified task name + + """ + task = Task(task_name, ctx.guild.id, self.config, bot=self.bot) + await task.load_from_config() + + if task.data is None: + await ctx.maybe_send_embed( + f"Task by the name of {task_name} is not found in this guild" + ) + return + + embed = discord.Embed(title=task_name) + + embed.add_field( + name="Task command", value=f"{ctx.prefix}{task.get_command_str()}", inline=False + ) + + guild: discord.Guild = self.bot.get_guild(task.guild_id) + + if guild is not None: + author: discord.Member = guild.get_member(task.author_id) + channel: discord.TextChannel = guild.get_channel(task.channel_id) + embed.add_field(name="Server", value=guild.name) + if author is not None: + embed.add_field(name="Author", value=author.mention) + if channel is not None: + embed.add_field(name="Channel", value=channel.mention) + + else: + embed.add_field(name="Server", value="Server not found") + + trigger_str = "\n".join(str(t) for t in await task.get_triggers()) + if trigger_str: + embed.add_field(name="Triggers", value=trigger_str, inline=False) + + await ctx.send(embed=embed) + @fifo.command(name="list") async def fifo_list(self, ctx: commands.Context, all_guilds: bool = False): """ @@ -473,8 +528,12 @@ class FIFO(commands.Cog): ) return await task.save_data() - await self._process_task(task) - await ctx.tick() + job: Job = await self._process_task(task) + delta_from_now: timedelta = job.next_run_time - datetime.now(job.next_run_time.tzinfo) + await ctx.maybe_send_embed( + f"Task `{task_name}` added interval of {interval_str} to its scheduled runtimes\n" + f"Next run time: {job.next_run_time} ({delta_from_now.total_seconds()} seconds)" + ) @fifo_trigger.command(name="date") async def fifo_trigger_date( @@ -502,9 +561,10 @@ class FIFO(commands.Cog): await task.save_data() job: Job = await self._process_task(task) + delta_from_now: timedelta = job.next_run_time - datetime.now(job.next_run_time.tzinfo) await ctx.maybe_send_embed( f"Task `{task_name}` added {datetime_str} to its scheduled runtimes\n" - f"Next run time: {job.next_run_time}" + f"Next run time: {job.next_run_time} ({delta_from_now.total_seconds()} seconds)" ) @fifo_trigger.command(name="cron") @@ -527,7 +587,7 @@ class FIFO(commands.Cog): # await task.load_from_data(task_data) # # job = self.scheduler.add_job( - # task.execute, id=task_name + "_" + guild_id, trigger=await task.get_trigger(), + # task.execute, id=task_name + "_" + guild_id, trigger=await task.get_combined_trigger(), # ) # # self.scheduler.start() diff --git a/fifo/redconfigjobstore.py b/fifo/redconfigjobstore.py index 4921dca..cbbe0ab 100644 --- a/fifo/redconfigjobstore.py +++ b/fifo/redconfigjobstore.py @@ -2,6 +2,8 @@ import asyncio import base64 import logging import pickle +from datetime import datetime +from typing import Tuple, Union from apscheduler.job import Job from apscheduler.jobstores.base import ConflictingIdError, JobLookupError @@ -36,7 +38,7 @@ class RedConfigJobStore(MemoryJobStore): self._jobs_index = {job.id: (job, timestamp) for job, timestamp in self._jobs} def _encode_job(self, job: Job): - log.info(f"Encoding job id: {job.id}") + # log.debug(f"Encoding job id: {job.id}") job_state = job.__getstate__() new_args = list(job_state["args"]) new_args[0]["config"] = None @@ -52,7 +54,6 @@ class RedConfigJobStore(MemoryJobStore): new_args[0]["config"] = self.config new_args[0]["bot"] = self.bot job_state["args"] = tuple(new_args) - log.info(f"After encode: Check job args: {job.args=}") return out async def _decode_job(self, job_state): @@ -72,20 +73,20 @@ class RedConfigJobStore(MemoryJobStore): # # job.func = task.execute - log.info(f"Decoded job id: {job.id}") + # log.debug(f"Decoded job id: {job.id}") return job def add_job(self, job: Job): if job.id in self._jobs_index: raise ConflictingIdError(job.id) - log.info(f"Check job args: {job.args=}") + # log.debug(f"Check job args: {job.args=}") timestamp = datetime_to_utc_timestamp(job.next_run_time) index = self._get_job_index(timestamp, job.id) # This is fine self._jobs.insert(index, (job, timestamp)) self._jobs_index[job.id] = (job, timestamp) asyncio.create_task(self._async_add_job(job, index, timestamp)) - log.info(f"Added job: {self._jobs[index][0].args}") + # log.debug(f"Added job: {self._jobs[index][0].args}") async def _async_add_job(self, job, index, timestamp): async with self.config.jobs() as jobs: @@ -94,7 +95,11 @@ class RedConfigJobStore(MemoryJobStore): return True def update_job(self, job): - old_job, old_timestamp = self._jobs_index.get(job.id, (None, None)) + old_tuple: Tuple[Union[Job, None], Union[datetime, None]] = self._jobs_index.get( + job.id, (None, None) + ) + old_job = old_tuple[0] + old_timestamp = old_tuple[1] if old_job is None: raise JobLookupError(job.id) @@ -123,8 +128,8 @@ class RedConfigJobStore(MemoryJobStore): self._jobs_index[old_job.id] = (job, new_timestamp) await self.config.jobs_index.set_raw(old_job.id, value=(encoded_job, new_timestamp)) - log.info(f"Async Updated {job.id=}") - log.info(f"Check job args: {job.args=}") + log.debug(f"Async Updated {job.id=}") + log.debug(f"Check job args: {job.args=}") def remove_job(self, job_id): job, timestamp = self._jobs_index.get(job_id, (None, None)) diff --git a/fifo/timezones.py b/fifo/timezones.py new file mode 100644 index 0000000..5a322a4 --- /dev/null +++ b/fifo/timezones.py @@ -0,0 +1,195 @@ +""" +Timezone information for the dateutil parser + +All credit to https://github.com/prefrontal/dateutil-parser-timezones +""" + +from dateutil.tz import gettz + + +def assemble_timezones(): + """ + Assembles a dictionary of timezone abbreviations and values + :return: Dictionary of abbreviation keys and timezone values + """ + timezones = {} + + timezones['ACDT'] = gettz('Australia/Darwin') # Australian Central Daylight Savings Time (UTC+10:30) + timezones['ACST'] = gettz('Australia/Darwin') # Australian Central Standard Time (UTC+09:30) + timezones['ACT'] = gettz('Brazil/Acre') # Acre Time (UTC−05) + timezones['ADT'] = gettz('America/Halifax') # Atlantic Daylight Time (UTC−03) + timezones['AEDT'] = gettz('Australia/Sydney') # Australian Eastern Daylight Savings Time (UTC+11) + timezones['AEST'] = gettz('Australia/Sydney') # Australian Eastern Standard Time (UTC+10) + timezones['AFT'] = gettz('Asia/Kabul') # Afghanistan Time (UTC+04:30) + timezones['AKDT'] = gettz('America/Juneau') # Alaska Daylight Time (UTC−08) + timezones['AKST'] = gettz('America/Juneau') # Alaska Standard Time (UTC−09) + timezones['AMST'] = gettz('America/Manaus') # Amazon Summer Time (Brazil)[1] (UTC−03) + timezones['AMT'] = gettz('America/Manaus') # Amazon Time (Brazil)[2] (UTC−04) + timezones['ART'] = gettz('America/Cordoba') # Argentina Time (UTC−03) + timezones['AST'] = gettz('Asia/Riyadh') # Arabia Standard Time (UTC+03) + timezones['AWST'] = gettz('Australia/Perth') # Australian Western Standard Time (UTC+08) + timezones['AZOST'] = gettz('Atlantic/Azores') # Azores Summer Time (UTC±00) + timezones['AZOT'] = gettz('Atlantic/Azores') # Azores Standard Time (UTC−01) + timezones['AZT'] = gettz('Asia/Baku') # Azerbaijan Time (UTC+04) + timezones['BDT'] = gettz('Asia/Brunei') # Brunei Time (UTC+08) + timezones['BIOT'] = gettz('Etc/GMT+6') # British Indian Ocean Time (UTC+06) + timezones['BIT'] = gettz('Pacific/Funafuti') # Baker Island Time (UTC−12) + timezones['BOT'] = gettz('America/La_Paz') # Bolivia Time (UTC−04) + timezones['BRST'] = gettz('America/Sao_Paulo') # Brasilia Summer Time (UTC−02) + timezones['BRT'] = gettz('America/Sao_Paulo') # Brasilia Time (UTC−03) + timezones['BST'] = gettz('Asia/Dhaka') # Bangladesh Standard Time (UTC+06) + timezones['BTT'] = gettz('Asia/Thimphu') # Bhutan Time (UTC+06) + timezones['CAT'] = gettz('Africa/Harare') # Central Africa Time (UTC+02) + timezones['CCT'] = gettz('Indian/Cocos') # Cocos Islands Time (UTC+06:30) + timezones['CDT'] = gettz('America/Chicago') # Central Daylight Time (North America) (UTC−05) + timezones['CEST'] = gettz('Europe/Berlin') # Central European Summer Time (Cf. HAEC) (UTC+02) + timezones['CET'] = gettz('Europe/Berlin') # Central European Time (UTC+01) + timezones['CHADT'] = gettz('Pacific/Chatham') # Chatham Daylight Time (UTC+13:45) + timezones['CHAST'] = gettz('Pacific/Chatham') # Chatham Standard Time (UTC+12:45) + timezones['CHOST'] = gettz('Asia/Choibalsan') # Choibalsan Summer Time (UTC+09) + timezones['CHOT'] = gettz('Asia/Choibalsan') # Choibalsan Standard Time (UTC+08) + timezones['CHST'] = gettz('Pacific/Guam') # Chamorro Standard Time (UTC+10) + timezones['CHUT'] = gettz('Pacific/Chuuk') # Chuuk Time (UTC+10) + timezones['CIST'] = gettz('Etc/GMT-8') # Clipperton Island Standard Time (UTC−08) + timezones['CIT'] = gettz('Asia/Makassar') # Central Indonesia Time (UTC+08) + timezones['CKT'] = gettz('Pacific/Rarotonga') # Cook Island Time (UTC−10) + timezones['CLST'] = gettz('America/Santiago') # Chile Summer Time (UTC−03) + timezones['CLT'] = gettz('America/Santiago') # Chile Standard Time (UTC−04) + timezones['COST'] = gettz('America/Bogota') # Colombia Summer Time (UTC−04) + timezones['COT'] = gettz('America/Bogota') # Colombia Time (UTC−05) + timezones['CST'] = gettz('America/Chicago') # Central Standard Time (North America) (UTC−06) + timezones['CT'] = gettz('Asia/Chongqing') # China time (UTC+08) + timezones['CVT'] = gettz('Atlantic/Cape_Verde') # Cape Verde Time (UTC−01) + timezones['CXT'] = gettz('Indian/Christmas') # Christmas Island Time (UTC+07) + timezones['DAVT'] = gettz('Antarctica/Davis') # Davis Time (UTC+07) + timezones['DDUT'] = gettz('Antarctica/DumontDUrville') # Dumont d'Urville Time (UTC+10) + timezones['DFT'] = gettz('Europe/Berlin') # AIX equivalent of Central European Time (UTC+01) + timezones['EASST'] = gettz('Chile/EasterIsland') # Easter Island Summer Time (UTC−05) + timezones['EAST'] = gettz('Chile/EasterIsland') # Easter Island Standard Time (UTC−06) + timezones['EAT'] = gettz('Africa/Mogadishu') # East Africa Time (UTC+03) + timezones['ECT'] = gettz('America/Guayaquil') # Ecuador Time (UTC−05) + timezones['EDT'] = gettz('America/New_York') # Eastern Daylight Time (North America) (UTC−04) + timezones['EEST'] = gettz('Europe/Bucharest') # Eastern European Summer Time (UTC+03) + timezones['EET'] = gettz('Europe/Bucharest') # Eastern European Time (UTC+02) + timezones['EGST'] = gettz('America/Scoresbysund') # Eastern Greenland Summer Time (UTC±00) + timezones['EGT'] = gettz('America/Scoresbysund') # Eastern Greenland Time (UTC−01) + timezones['EIT'] = gettz('Asia/Jayapura') # Eastern Indonesian Time (UTC+09) + timezones['EST'] = gettz('America/New_York') # Eastern Standard Time (North America) (UTC−05) + timezones['FET'] = gettz('Europe/Minsk') # Further-eastern European Time (UTC+03) + timezones['FJT'] = gettz('Pacific/Fiji') # Fiji Time (UTC+12) + timezones['FKST'] = gettz('Atlantic/Stanley') # Falkland Islands Summer Time (UTC−03) + timezones['FKT'] = gettz('Atlantic/Stanley') # Falkland Islands Time (UTC−04) + timezones['FNT'] = gettz('Brazil/DeNoronha') # Fernando de Noronha Time (UTC−02) + timezones['GALT'] = gettz('Pacific/Galapagos') # Galapagos Time (UTC−06) + timezones['GAMT'] = gettz('Pacific/Gambier') # Gambier Islands (UTC−09) + timezones['GET'] = gettz('Asia/Tbilisi') # Georgia Standard Time (UTC+04) + timezones['GFT'] = gettz('America/Cayenne') # French Guiana Time (UTC−03) + timezones['GILT'] = gettz('Pacific/Tarawa') # Gilbert Island Time (UTC+12) + timezones['GIT'] = gettz('Pacific/Gambier') # Gambier Island Time (UTC−09) + timezones['GMT'] = gettz('GMT') # Greenwich Mean Time (UTC±00) + timezones['GST'] = gettz('Asia/Muscat') # Gulf Standard Time (UTC+04) + timezones['GYT'] = gettz('America/Guyana') # Guyana Time (UTC−04) + timezones['HADT'] = gettz('Pacific/Honolulu') # Hawaii-Aleutian Daylight Time (UTC−09) + timezones['HAEC'] = gettz('Europe/Paris') # Heure Avancée d'Europe Centrale (CEST) (UTC+02) + timezones['HAST'] = gettz('Pacific/Honolulu') # Hawaii-Aleutian Standard Time (UTC−10) + timezones['HKT'] = gettz('Asia/Hong_Kong') # Hong Kong Time (UTC+08) + timezones['HMT'] = gettz('Indian/Kerguelen') # Heard and McDonald Islands Time (UTC+05) + timezones['HOVST'] = gettz('Asia/Hovd') # Khovd Summer Time (UTC+08) + timezones['HOVT'] = gettz('Asia/Hovd') # Khovd Standard Time (UTC+07) + timezones['ICT'] = gettz('Asia/Ho_Chi_Minh') # Indochina Time (UTC+07) + timezones['IDT'] = gettz('Asia/Jerusalem') # Israel Daylight Time (UTC+03) + timezones['IOT'] = gettz('Etc/GMT+3') # Indian Ocean Time (UTC+03) + timezones['IRDT'] = gettz('Asia/Tehran') # Iran Daylight Time (UTC+04:30) + timezones['IRKT'] = gettz('Asia/Irkutsk') # Irkutsk Time (UTC+08) + timezones['IRST'] = gettz('Asia/Tehran') # Iran Standard Time (UTC+03:30) + timezones['IST'] = gettz('Asia/Kolkata') # Indian Standard Time (UTC+05:30) + timezones['JST'] = gettz('Asia/Tokyo') # Japan Standard Time (UTC+09) + timezones['KGT'] = gettz('Asia/Bishkek') # Kyrgyzstan time (UTC+06) + timezones['KOST'] = gettz('Pacific/Kosrae') # Kosrae Time (UTC+11) + timezones['KRAT'] = gettz('Asia/Krasnoyarsk') # Krasnoyarsk Time (UTC+07) + timezones['KST'] = gettz('Asia/Seoul') # Korea Standard Time (UTC+09) + timezones['LHST'] = gettz('Australia/Lord_Howe') # Lord Howe Standard Time (UTC+10:30) + timezones['LINT'] = gettz('Pacific/Kiritimati') # Line Islands Time (UTC+14) + timezones['MAGT'] = gettz('Asia/Magadan') # Magadan Time (UTC+12) + timezones['MART'] = gettz('Pacific/Marquesas') # Marquesas Islands Time (UTC−09:30) + timezones['MAWT'] = gettz('Antarctica/Mawson') # Mawson Station Time (UTC+05) + timezones['MDT'] = gettz('America/Denver') # Mountain Daylight Time (North America) (UTC−06) + timezones['MEST'] = gettz('Europe/Paris') # Middle European Summer Time Same zone as CEST (UTC+02) + timezones['MET'] = gettz('Europe/Berlin') # Middle European Time Same zone as CET (UTC+01) + timezones['MHT'] = gettz('Pacific/Kwajalein') # Marshall Islands (UTC+12) + timezones['MIST'] = gettz('Antarctica/Macquarie') # Macquarie Island Station Time (UTC+11) + timezones['MIT'] = gettz('Pacific/Marquesas') # Marquesas Islands Time (UTC−09:30) + timezones['MMT'] = gettz('Asia/Rangoon') # Myanmar Standard Time (UTC+06:30) + timezones['MSK'] = gettz('Europe/Moscow') # Moscow Time (UTC+03) + timezones['MST'] = gettz('America/Denver') # Mountain Standard Time (North America) (UTC−07) + timezones['MUT'] = gettz('Indian/Mauritius') # Mauritius Time (UTC+04) + timezones['MVT'] = gettz('Indian/Maldives') # Maldives Time (UTC+05) + timezones['MYT'] = gettz('Asia/Kuching') # Malaysia Time (UTC+08) + timezones['NCT'] = gettz('Pacific/Noumea') # New Caledonia Time (UTC+11) + timezones['NDT'] = gettz('Canada/Newfoundland') # Newfoundland Daylight Time (UTC−02:30) + timezones['NFT'] = gettz('Pacific/Norfolk') # Norfolk Time (UTC+11) + timezones['NPT'] = gettz('Asia/Kathmandu') # Nepal Time (UTC+05:45) + timezones['NST'] = gettz('Canada/Newfoundland') # Newfoundland Standard Time (UTC−03:30) + timezones['NT'] = gettz('Canada/Newfoundland') # Newfoundland Time (UTC−03:30) + timezones['NUT'] = gettz('Pacific/Niue') # Niue Time (UTC−11) + timezones['NZDT'] = gettz('Pacific/Auckland') # New Zealand Daylight Time (UTC+13) + timezones['NZST'] = gettz('Pacific/Auckland') # New Zealand Standard Time (UTC+12) + timezones['OMST'] = gettz('Asia/Omsk') # Omsk Time (UTC+06) + timezones['ORAT'] = gettz('Asia/Oral') # Oral Time (UTC+05) + timezones['PDT'] = gettz('America/Los_Angeles') # Pacific Daylight Time (North America) (UTC−07) + timezones['PET'] = gettz('America/Lima') # Peru Time (UTC−05) + timezones['PETT'] = gettz('Asia/Kamchatka') # Kamchatka Time (UTC+12) + timezones['PGT'] = gettz('Pacific/Port_Moresby') # Papua New Guinea Time (UTC+10) + timezones['PHOT'] = gettz('Pacific/Enderbury') # Phoenix Island Time (UTC+13) + timezones['PKT'] = gettz('Asia/Karachi') # Pakistan Standard Time (UTC+05) + timezones['PMDT'] = gettz('America/Miquelon') # Saint Pierre and Miquelon Daylight time (UTC−02) + timezones['PMST'] = gettz('America/Miquelon') # Saint Pierre and Miquelon Standard Time (UTC−03) + timezones['PONT'] = gettz('Pacific/Pohnpei') # Pohnpei Standard Time (UTC+11) + timezones['PST'] = gettz('America/Los_Angeles') # Pacific Standard Time (North America) (UTC−08) + timezones['PYST'] = gettz('America/Asuncion') # Paraguay Summer Time (South America)[7] (UTC−03) + timezones['PYT'] = gettz('America/Asuncion') # Paraguay Time (South America)[8] (UTC−04) + timezones['RET'] = gettz('Indian/Reunion') # Réunion Time (UTC+04) + timezones['ROTT'] = gettz('Antarctica/Rothera') # Rothera Research Station Time (UTC−03) + timezones['SAKT'] = gettz('Asia/Vladivostok') # Sakhalin Island time (UTC+11) + timezones['SAMT'] = gettz('Europe/Samara') # Samara Time (UTC+04) + timezones['SAST'] = gettz('Africa/Johannesburg') # South African Standard Time (UTC+02) + timezones['SBT'] = gettz('Pacific/Guadalcanal') # Solomon Islands Time (UTC+11) + timezones['SCT'] = gettz('Indian/Mahe') # Seychelles Time (UTC+04) + timezones['SGT'] = gettz('Asia/Singapore') # Singapore Time (UTC+08) + timezones['SLST'] = gettz('Asia/Colombo') # Sri Lanka Standard Time (UTC+05:30) + timezones['SRET'] = gettz('Asia/Srednekolymsk') # Srednekolymsk Time (UTC+11) + timezones['SRT'] = gettz('America/Paramaribo') # Suriname Time (UTC−03) + timezones['SST'] = gettz('Asia/Singapore') # Singapore Standard Time (UTC+08) + timezones['SYOT'] = gettz('Antarctica/Syowa') # Showa Station Time (UTC+03) + timezones['TAHT'] = gettz('Pacific/Tahiti') # Tahiti Time (UTC−10) + timezones['TFT'] = gettz('Indian/Kerguelen') # Indian/Kerguelen (UTC+05) + timezones['THA'] = gettz('Asia/Bangkok') # Thailand Standard Time (UTC+07) + timezones['TJT'] = gettz('Asia/Dushanbe') # Tajikistan Time (UTC+05) + timezones['TKT'] = gettz('Pacific/Fakaofo') # Tokelau Time (UTC+13) + timezones['TLT'] = gettz('Asia/Dili') # Timor Leste Time (UTC+09) + timezones['TMT'] = gettz('Asia/Ashgabat') # Turkmenistan Time (UTC+05) + timezones['TOT'] = gettz('Pacific/Tongatapu') # Tonga Time (UTC+13) + timezones['TVT'] = gettz('Pacific/Funafuti') # Tuvalu Time (UTC+12) + timezones['ULAST'] = gettz('Asia/Ulan_Bator') # Ulaanbaatar Summer Time (UTC+09) + timezones['ULAT'] = gettz('Asia/Ulan_Bator') # Ulaanbaatar Standard Time (UTC+08) + timezones['USZ1'] = gettz('Europe/Kaliningrad') # Kaliningrad Time (UTC+02) + timezones['UTC'] = gettz('UTC') # Coordinated Universal Time (UTC±00) + timezones['UYST'] = gettz('America/Montevideo') # Uruguay Summer Time (UTC−02) + timezones['UYT'] = gettz('America/Montevideo') # Uruguay Standard Time (UTC−03) + timezones['UZT'] = gettz('Asia/Tashkent') # Uzbekistan Time (UTC+05) + timezones['VET'] = gettz('America/Caracas') # Venezuelan Standard Time (UTC−04) + timezones['VLAT'] = gettz('Asia/Vladivostok') # Vladivostok Time (UTC+10) + timezones['VOLT'] = gettz('Europe/Volgograd') # Volgograd Time (UTC+04) + timezones['VOST'] = gettz('Antarctica/Vostok') # Vostok Station Time (UTC+06) + timezones['VUT'] = gettz('Pacific/Efate') # Vanuatu Time (UTC+11) + timezones['WAKT'] = gettz('Pacific/Wake') # Wake Island Time (UTC+12) + timezones['WAST'] = gettz('Africa/Lagos') # West Africa Summer Time (UTC+02) + timezones['WAT'] = gettz('Africa/Lagos') # West Africa Time (UTC+01) + timezones['WEST'] = gettz('Europe/London') # Western European Summer Time (UTC+01) + timezones['WET'] = gettz('Europe/London') # Western European Time (UTC±00) + timezones['WIT'] = gettz('Asia/Jakarta') # Western Indonesian Time (UTC+07) + timezones['WST'] = gettz('Australia/Perth') # Western Standard Time (UTC+08) + timezones['YAKT'] = gettz('Asia/Yakutsk') # Yakutsk Time (UTC+09) + timezones['YEKT'] = gettz('Asia/Yekaterinburg') # Yekaterinburg Time (UTC+05) + + return timezones \ No newline at end of file diff --git a/infochannel/infochannel.py b/infochannel/infochannel.py index c7297b8..b8d36a3 100644 --- a/infochannel/infochannel.py +++ b/infochannel/infochannel.py @@ -1,4 +1,5 @@ import asyncio +from typing import Union import discord from redbot.core import Config, checks, commands @@ -61,10 +62,9 @@ class InfoChannel(Cog): guild: discord.Guild = ctx.guild channel_id = await self.config.guild(guild).channel_id() + channel = None if channel_id is not None: - channel: discord.VoiceChannel = guild.get_channel(channel_id) - else: - channel: discord.VoiceChannel = None + channel: Union[discord.VoiceChannel, None] = guild.get_channel(channel_id) if channel_id is not None and channel is None: await ctx.send("Info channel has been deleted, recreate it?")