def i_format(loc, s, *a, **kw): if a: a = list(a) for c, f in [(a, enumerate), (kw, dict.items)]: for k, o in f(c): o, wrapper = (o.value, o.wrapper) if isinstance(o, Wrap) else (o, None) if isinstance(o, text_type): pass elif isinstance(o, Decimal): c[k] = format_decimal(o, locale=loc) elif isinstance(o, int): c[k] = format_number(o, locale=loc) elif isinstance(o, Money): c[k] = loc.format_money(o) elif isinstance(o, MoneyBasket): c[k] = loc.format_money_basket(o) elif isinstance(o, Age): c[k] = format_timedelta(o, locale=loc, **o.format_args) elif isinstance(o, timedelta): c[k] = format_timedelta(o, locale=loc) elif isinstance(o, datetime): c[k] = format_datetime(o, locale=loc) elif isinstance(o, date): c[k] = format_date(o, locale=loc) elif isinstance(o, Locale): c[k] = loc.languages.get(o.language) or o.language.upper() elif isinstance(o, Currency): c[k] = loc.currencies.get(o, o) if wrapper: c[k] = wrapper % (c[k],) return s.format(*a, **kw)
def test_format_narrow(self): string = dates.format_timedelta(timedelta(hours=1), locale='en', format='narrow') self.assertEqual('1h', string) string = dates.format_timedelta(timedelta(hours=-2), locale='en', format='narrow') self.assertEqual('2h', string)
def _format_date(self): """ Return this block's date in a human-readable format. If the date is None, returns the empty string. """ if self.date is None: return '' locale = to_locale(get_language()) delta = self.date - datetime.now(utc) try: relative_date = format_timedelta(delta, locale=locale) # Babel doesn't have translations for Esperanto, so we get # a KeyError when testing translations with # ?preview-lang=eo. This should not happen with any other # languages. See https://github.com/python-babel/babel/issues/107 except KeyError: relative_date = format_timedelta(delta) date_has_passed = delta.days < 0 # Translators: 'absolute' is a date such as "Jan 01, # 2020". 'relative' is a fuzzy description of the time until # 'absolute'. For example, 'absolute' might be "Jan 01, 2020", # and if today were December 5th, 2020, 'relative' would be "1 # month". date_format = _(u"{relative} ago - {absolute}") if date_has_passed else _(u"in {relative} - {absolute}") return date_format.format( relative=relative_date, absolute=self.date.astimezone(self.time_zone).strftime(self.date_format.encode('utf-8')).decode('utf-8'), )
def get_context(self): """Return the template context used to render this summary block.""" date = '' if self.date is not None: # Translators: relative_date is a fuzzy description of the # time from now until absolute_date. For example, # absolute_date might be "Jan 01, 2020", and if today were # December 5th, 2020, relative_date would be "1 month". locale = to_locale(get_language()) try: relative_date = format_timedelta(self.date - datetime.now(pytz.UTC), locale=locale) # Babel doesn't have translations for Esperanto, so we get # a KeyError when testing translations with # ?preview-lang=eo. This should not happen with any other # languages. See https://github.com/python-babel/babel/issues/107 except KeyError: relative_date = format_timedelta(self.date - datetime.now(pytz.UTC)) date = _("in {relative_date} - {absolute_date}").format( relative_date=relative_date, absolute_date=self.date.strftime(self.date_format), ) return { 'title': self.title, 'date': date, 'description': self.description, 'css_class': self.css_class, 'link': self.link, 'link_text': self.link_text, }
def _release_threshold_select(self): return {0: "Don't ignore.", 1: format_timedelta(helper.releaseThresholdDelta[1], locale=common.getLocale()), 2: format_timedelta(helper.releaseThresholdDelta[2], locale=common.getLocale()), 3: format_timedelta(helper.releaseThresholdDelta[3], locale=common.getLocale()), 4: format_timedelta(helper.releaseThresholdDelta[4], locale=common.getLocale()), 5: format_timedelta(helper.releaseThresholdDelta[5], locale=common.getLocale()), 6: 'Completely ignore'}
def test_small_value_with_granularity(self): string = dates.format_timedelta(timedelta(seconds=42), granularity='hour', locale='en') self.assertEqual('1 hour', string) string = dates.format_timedelta(timedelta(seconds=42), granularity='hour', locale='en', format='short') self.assertEqual('1 hr', string)
def test_direction_adding(self): string = dates.format_timedelta(timedelta(hours=1), locale='en', add_direction=True) self.assertEqual('in 1 hour', string) string = dates.format_timedelta(timedelta(hours=-1), locale='en', add_direction=True) self.assertEqual('1 hour ago', string)
def timedelta2(self, seconds, **kwargs): for (i, (nm, tm)) in enumerate(TIMEDELTA_UNITS): if tm < seconds: result = format_timedelta(seconds, threshold=1, locale=self, **kwargs) smaller_tm = seconds % tm not_last = i < len(TIMEDELTA_UNITS) - 1 if not_last and smaller_tm > TIMEDELTA_UNITS[i+1][1]: result += ' ' + self.format.timedelta(smaller_tm, threshold=1, **kwargs) return result return format_timedelta(seconds, locale=self, **kwargs)
def _release_threshold_select(self): _local = common.getLocale() return { 0: "Don't ignore.", 1: format_timedelta(self._releaseThresholdDelta[1], locale=_local), 2: format_timedelta(self._releaseThresholdDelta[2], locale=_local), 3: format_timedelta(self._releaseThresholdDelta[3], locale=_local), 4: format_timedelta(self._releaseThresholdDelta[4], locale=_local), 5: format_timedelta(self._releaseThresholdDelta[5], locale=_local), 6: "Completely ignore", }
def test_zero_seconds(self): string = dates.format_timedelta(timedelta(seconds=0), locale='en') self.assertEqual('0 seconds', string) string = dates.format_timedelta(timedelta(seconds=0), locale='en', format='short') self.assertEqual('0 sec', string) string = dates.format_timedelta(timedelta(seconds=0), granularity='hour', locale='en') self.assertEqual('0 hours', string) string = dates.format_timedelta(timedelta(seconds=0), granularity='hour', locale='en', format='short') self.assertEqual('0 hr', string)
def time_localed(time, member): delta = time - datetime.datetime.now() if member: locale = member.native_lang else: locale = 'en' return format_timedelta(delta, locale=locale)
def test_format_timedelta(): assert (dates.format_timedelta(timedelta(weeks=12), locale='en_US') == u'3 months') assert (dates.format_timedelta(timedelta(seconds=1), locale='es') == u'1 segundo') assert (dates.format_timedelta(timedelta(hours=3), granularity='day', locale='en_US') == u'1 day') assert (dates.format_timedelta(timedelta(hours=23), threshold=0.9, locale='en_US') == u'1 day') assert (dates.format_timedelta(timedelta(hours=23), threshold=1.1, locale='en_US') == u'23 hours')
def serialize_content_for_general_list(content: Content, context: Context): content_type = ContentType(content.type) last_activity_date = content.get_last_activity_date() last_activity_date_formatted = format_datetime(last_activity_date, locale=tg.i18n.get_lang()[0]) last_activity_label = format_timedelta( datetime.utcnow() - last_activity_date, locale=tg.i18n.get_lang()[0], ) last_activity_label = last_activity_label.replace(' ', '\u00A0') # espace insécable return DictLikeClass( id=content.content_id, folder = DictLikeClass({'id': content.parent_id}) if content.parent else None, workspace=context.toDict(content.workspace) if content.workspace else None, label=content.get_label(), url=ContentType.fill_url(content), type=DictLikeClass(content_type.toDict()), status=context.toDict(content.get_status()), is_deleted=content.is_deleted, is_archived=content.is_archived, is_editable=content.is_editable, last_activity = DictLikeClass({'date': last_activity_date, 'label': last_activity_date_formatted, 'delta': last_activity_label}) )
def format_timedelta(datetime_or_timedelta, granularity="second"): """Format the elapsed time from the given date to now of the given timedelta. """ if isinstance(datetime_or_timedelta, datetime): datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta return dates.format_timedelta(datetime_or_timedelta, granularity, locale=get_locale())
def reltime(date): if date == common.FAKEDATE or not date: return "unknown" # FIXME use isinstance() ... but test it if type(date).__name__ not in ('date', 'datetime'): return "reltime needs a date or datetime we got: '%s'" % repr(date) return format_timedelta(date - datetime.now(), locale=common.getLocale(), add_direction=True)
def humanize(obj, type=None, length=None): if obj is None: obj = '' elif type and type.startswith('time'): tz = type[len('time'):].lstrip('-') tz = timezone(tz) if tz else current_app.timezone or utc obj = format_time(float(obj), tz) if obj else '' elif type and type.startswith('natural-time'): tz = type[len('natural-time'):].lstrip('-') tz = timezone(tz) if tz else current_app.timezone or utc delta = datetime.now(tz) - datetime.fromtimestamp(float(obj), tz) if delta < timedelta(days=1): obj = format_timedelta(delta, locale='en_US') + ' ago' else: obj = format_time(float(obj), tz) if obj else '' elif isinstance(obj, string_types) and not re.match(UUID_REGEX, obj): obj = obj.replace('-', ' ').replace('_', ' ') obj = re.sub('|'.join(KEYWORDS_UP), lambda m: m.group(0).upper(), obj) if obj and obj not in KEYWORDS_DOWN: obj = obj[0].upper() + obj[1:] elif isinstance(obj, list): if all(isinstance(x, (int, float) + string_types) for x in obj): obj = ', '.join(map(str, obj)) if length is not None and len(obj) > length: obj = obj[:length - 4] + ' ...' return obj
def format_timedelta(self, datetime_or_timedelta, granularity='second', threshold=.85): """Formats the elapsed time from the given date to now or the given timedelta. This currently requires an unreleased development version of Babel. :param datetime_or_timedelta: A ``timedelta`` object representing the time difference to format, or a ``datetime`` object in UTC. :param granularity: Determines the smallest unit that should be displayed, the value can be one of "year", "month", "week", "day", "hour", "minute" or "second". :param threshold: Factor that determines at which point the presentation switches to the next higher unit. :returns: A string with the elapsed time. """ if isinstance(datetime_or_timedelta, datetime.datetime): datetime_or_timedelta = datetime.datetime.utcnow() - \ datetime_or_timedelta return dates.format_timedelta(datetime_or_timedelta, granularity, threshold=threshold, locale=self.locale)
def show(self, index): self.print_short(index) data = [] data.append('Added by ' + Reviewer.get(self.by).nice()) relative = format_timedelta( datetime.datetime.now(pytz.utc) - self.created ) data.append(TERM.bold_magenta(' {0} ago'.format(relative))) data.append('\n\n') data.append(self.body.strip()) data.append('\n\n') scores = [] for email, score in self.reviewers.items(): scores.append( Reviewer.get(email).nice() + TERM.bright_black(': ') ) if score >= 1: fun = TERM.bold_green score = '+{0}'.format(score) elif score == 0: fun = TERM.bold_white else: fun = TERM.bold_red scores.append(fun(str(score))) scores.append('\n') data.append(''.join(scores)) print(''.join(data))
def timedelta_filter(delta_or_date): """Format :class:`~datetime.datetime` or :class:`~datetime.timedelta` into localized string. If given parameter is a :class:`~datetime.datetime`, it will be subtracted by :func:`railgun.common.dateutil.utcnow` to get the :class:`~datetime.timedelta`. Usage: .. code-block:: html {{ handin.get_ctime() | timedelta }} :param delta_or_date: A :class:`~datetime.datetime` or a :class:`~datetime.timedelta` object. :return: :data:`None` if `delta_or_date` is :data:`None`, otherwise the localized timedelta string. """ if not delta_or_date: return None if isinstance(delta_or_date, datetime): delta_or_date = delta_or_date - g.utcnow return format_timedelta(delta_or_date, locale=get_locale())
def update(self): self.news = feedparser.parse(self.feed_url) article_list = [] xlocale = locale.getlocale(locale.LC_TIME) locale.setlocale(locale.LC_TIME, 'en_US.utf-8') if not self.news['items']: Logger.error('NEWS: Seems there\'s no news') return # Return here so we keep old news (if any) for x in self.news['items']: description = unicode(x['description']).strip() description = description.split('<', 1)[0].strip() title = unicode(x['title']).strip() if description == '.': title = u'[color=#FFDD63]{}[/color]'.format(title) description = '' article_date = (datetime.strptime(x['published'], "%a, %d %b %Y %H:%M:%S %Z") + timedelta(hours=2)) article_relative_date = format_timedelta(article_date - datetime.now(), granularity='minute', locale='ro_RO.utf-8', add_direction=True) article_list.append(u'{}\n[color=#777777]{}[/color]\n\n{}'.format(title, article_relative_date, description)) locale.setlocale(locale.LC_TIME, xlocale) self.articles = deque(article_list)
def age(x): if not x: return "never" from babel.dates import format_timedelta from datetime import datetime return format_timedelta(datetime.now()-x, locale='en_US')
def format_infotext(self, text): return text.format( id=self.id, name=self.name, contact=self.contact, since=format_timedelta( datetime.now() - datetime.fromtimestamp(self.lastseen) ), )
def format_timesince(self, timestamp, locale=None): return format_timedelta( datetime.now() - datetime.fromtimestamp( timestamp), locale=( locale or self.locale_code or self.default_locale))
def i_format(loc, s, *a, **kw): if a: a = list(a) for c, f in [(a, enumerate), (kw, dict.items)]: for k, o in f(c): if isinstance(o, Decimal): c[k] = format_decimal(o, locale=loc) elif isinstance(o, int): c[k] = format_number(o, locale=loc) elif isinstance(o, Money): c[k] = format_money(*o, locale=loc) elif isinstance(o, datedelta): c[k] = format_timedelta(o, locale=loc, granularity='day') elif isinstance(o, timedelta): c[k] = format_timedelta(o, locale=loc) elif isinstance(o, datetime): c[k] = format_datetime(o, locale=loc) return s.format(*a, **kw)
def format_timedelta(datetime_or_timedelta, granularity='second'): """Format the elapsed time from the given date to now or the given timedelta. This currently requires an unreleased development version of Babel. """ if isinstance(datetime_or_timedelta, datetime): datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta return dates.format_timedelta(datetime_or_timedelta, granularity, locale=get_locale())
def rel_datetime_format(dt, fmt=None, relative=False): """Template filter for readable formatting of datetime.datetime""" if relative: time = dates.format_timedelta(datetime.utcnow() - dt, locale=get_locale()) return gettext('{time} ago').format(time=time) else: fmt = fmt or 'MMM dd, yyyy hh:mm a' return dates.format_datetime(dt, fmt, locale=get_locale())
def test_local_date_timesince(settings): timestamp = time.time() - 1000000 assert ( timesince(timestamp) == format_timedelta( datetime.now() - datetime.fromtimestamp(timestamp), locale=( localdate.locale_code or localdate.default_locale)))
def timedelta(self, delta, granularity='second', threshold=.85): """Return a time delta according to the rules of the given locale. >>> fmt = Format('en_US') >>> fmt.timedelta(timedelta(weeks=11)) == u('3 mths') True :see: `babel.dates.format_timedelta` """ return format_timedelta(delta, granularity=granularity, threshold=threshold, locale=self.locale)
def time_since(time): # pragma: no cover """Returns a string representing time since e.g. 3 days ago, 5 hours ago. :param time: A datetime object """ delta = time - datetime.utcnow() locale = "en" return format_timedelta(delta, add_direction=True, locale=locale)
def format_timedelta(datetime_or_timedelta, granularity="second"): """Format the elapsed time from the given date to now or the given timedelta. This currently requires an unreleased development version of Babel. This function is also available in the template context as filter named `timedeltaformat`. """ if isinstance(datetime_or_timedelta, datetime): datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta return dates.format_timedelta(datetime_or_timedelta, granularity, locale=get_locale())
def _articles_to_json(articles): now, locale = datetime.now(), get_locale() fd_hash = { feed.id: { 'title': feed.title, 'icon_url': url_for('icon.icon', url=feed.icon_url) if feed.icon_url else None } for feed in FeedController(current_user.id).read() } return { 'articles': [{ 'title': art.title, 'liked': art.like, 'read': art.readed, 'article_id': art.id, 'selected': False, 'feed_id': art.feed_id, 'category_id': art.category_id or 0, 'feed_title': fd_hash[art.feed_id]['title'], 'icon_url': fd_hash[art.feed_id]['icon_url'], 'date': format_datetime(localize(art.date), locale=locale), 'rel_date': format_timedelta(art.date - now, threshold=1.1, add_direction=True, locale=locale) } for art in articles.limit(1000)] }
async def fban_export(message, fed, strings): fed_id = fed["fed_id"] key = "fbanlist_lock:" + str(fed_id) if redis.get(key) and message.from_user.id not in OPERATORS: ttl = format_timedelta( timedelta(seconds=redis.ttl(key)), strings["language_info"]["babel"] ) await message.reply(strings["fbanlist_locked"] % ttl) return redis.set(key, 1) redis.expire(key, 600) msg = await message.reply(strings["creating_fbanlist"]) fields = ["user_id", "reason", "by", "time", "banned_chats"] with io.StringIO() as f: writer = csv.DictWriter(f, fields) writer.writeheader() async for banned_data in db.fed_bans.find({"fed_id": fed_id}): await asyncio.sleep(0) data = {"user_id": banned_data["user_id"]} if "reason" in banned_data: data["reason"] = banned_data["reason"] if "time" in banned_data: data["time"] = int(time.mktime(banned_data["time"].timetuple())) if "by" in banned_data: data["by"] = banned_data["by"] if "banned_chats" in banned_data: data["banned_chats"] = banned_data["banned_chats"] writer.writerow(data) text = strings["fbanlist_done"] % html.escape(fed["fed_name"], False) f.seek(0) await message.answer_document(InputFile(f, filename="fban_export.csv"), text) await msg.delete()
def log_ratelimit_headers(self, domain, limit, remaining, reset): """Emit log messages if we're running out of ratelimit. """ if None in (limit, remaining, reset): return percent_remaining = remaining / limit if percent_remaining < 0.5: reset_delta = reset - datetime.utcnow().replace(tzinfo=utc) reset_delta = format_timedelta(reset_delta, add_direction=True, locale='en') log_msg = ('{0}: {1:.1%} of ratelimit has been consumed, ' '{2} requests remaining, resets {3}.').format( domain, 1 - percent_remaining, remaining, reset_delta) log_lvl = logging.WARNING if percent_remaining < 0.2: log_lvl = logging.ERROR elif percent_remaining < 0.05: log_lvl = logging.CRITICAL logger.log(log_lvl, log_msg)
async def convert(self, ctx: core.Context, argument): me = _("me") # Like as "Remind me..." if argument.startswith(me): argument = argument[len(me):].strip() languages = [locale_to_lang(locale) for locale in i18n.LOCALES] date = search.search_dates(argument, languages=languages) if date is None: raise commands.BadArgument(_("Could not recognize the date.")) try: now = ctx.message.created_at.replace(tzinfo=pytz.utc) date = date[0] when = date[1].astimezone(pytz.utc) except OSError: raise commands.BadArgument( _("An error occurred converting the date.")) if not self.past and when <= now: raise commands.BadArgument(_("This time is in the past.")) if not self.future and when > now: raise commands.BadArgument(_("This time is in the future.")) if when - now > self.max_delta: raise commands.BadArgument( _("Maximum timedelta: {0}").format( format_timedelta(self.max_delta, locale=ctx.locale))) self.dt = when remaining = (argument.replace(date[0], "")).strip() if not remaining: if not self.default: raise commands.BadArgument( _("Missing argument before or after the time.")) else: self.arg = self.default if self.converter is not None: self.arg = await self.converter.convert(ctx, remaining) else: self.arg = remaining return self
def plcmon_status(): last_events = get_db().execute( "SELECT datetime(timestamp, 'localtime'), app_name, app_label," " event_source, " " event_text, priority FROM events ORDER BY timestamp DESC LIMIT 20" " ").fetchall() try: is_open = get_db().execute( "SELECT plcmon_data FROM events " "WHERE plcmon_data IN (1, 2) ORDER BY " " timestamp DESC LIMIT 1").fetchone()[0] == 2 except TypeError: is_open = False try: is_alarm = get_db().execute( "SELECT plcmon_data FROM events " "WHERE plcmon_data IN (3, 4) ORDER BY " " timestamp DESC LIMIT 1").fetchone()[0] == 3 except TypeError: is_alarm = False try: last_change = get_db().execute( "SELECT datetime( timestamp , 'localtime') AS '[timestamp]' FROM " " events WHERE plcmon_data IN (1, 2, 4) " " ORDER BY timestamp DESC LIMIT 1").fetchone()[0] except TypeError: last_change = "N/A" delta = format_timedelta(datetime.datetime.now() - last_change) return render_template("status.html", events=last_events, status=is_open, alarm=is_alarm, last_change=delta)
def get_sub(name): try: usdata = requests.get('https://phuks.co/api/getSub/{0}'.format(name)) except: return "Could not contact Phuks" if usdata.status_code != 200: return "Could not contact Phuks" usdata = usdata.json() if usdata['status'] != "ok": return "Error: " + usdata['error'] usdata = usdata['sub'] resp = "Sub \002{0}\002".format(usdata['name']) if usdata['nsfw']: resp += " [NSFW]" regist = datetime.datetime.strptime(usdata['created'], "%Y-%m-%d %H:%M:%S.%f") del_regist = datetime.datetime.utcnow() - regist resp += " Created \002{0}\002 ago by {1},".format( format_timedelta(del_regist, locale='en_US'), usdata['creator']) resp += " {0} posts, {1} subscribers, {2} mods".format( usdata['posts'], usdata['subscribers'], len(usdata['mods'])) return resp
def serialize_content_for_general_list(content: Content, context: Context): content_type = ContentType(content.type) last_activity_date = content.get_last_activity_date() last_activity_date_formatted = format_datetime(last_activity_date, locale=tg.i18n.get_lang()[0]) last_activity_label = format_timedelta(datetime.now() - last_activity_date, locale=tg.i18n.get_lang()[0]) last_activity_label = last_activity_label.replace(' ', '\u00A0') # espace insécable return DictLikeClass( id=content.content_id, folder = DictLikeClass({'id': content.parent_id}) if content.parent else None, workspace=context.toDict(content.workspace) if content.workspace else None, label=content.get_label(), url=ContentType.fill_url(content), type=DictLikeClass(content_type.toDict()), status=context.toDict(content.get_status()), last_activity = DictLikeClass({'date': last_activity_date, 'label': last_activity_date_formatted, 'delta': last_activity_label}) )
def humanize(obj, type=None, length=None): if obj is None: obj = '' elif type == 'time': obj = format_time(float(obj)) if obj else '' elif type == 'natural-time': delta = time.time() - float(obj) if timedelta(seconds=delta) < timedelta(days=1): obj = format_timedelta(delta, locale='en_US') + ' ago' else: obj = format_time(float(obj)) if obj else '' elif isinstance(obj, string_types) and not re.match(UUID_REGEX, obj): obj = obj.replace('-', ' ').replace('_', ' ') obj = re.sub('|'.join(KEYWORDS_UP), lambda m: m.group(0).upper(), obj) if obj and obj not in KEYWORDS_DOWN: obj = obj[0].upper() + obj[1:] elif isinstance(obj, list): if all(isinstance(x, (int, float) + string_types) for x in obj): obj = ', '.join(map(str, obj)) if length is not None and len(obj) > length: obj = obj[:length - 4] + ' ...' return obj
async def explosive(self, ctx: MyContext): """ Buy Explosive ammo to TRIPLE the damage you do to super ducks. [25 exp/24 hrs] """ ITEM_COST = 25 _ = await ctx.get_translate_function() if self.bot.current_event == Events.UN_TREATY: await ctx.reply( _( "❌ A UN treaty bans the use of Armor Piercing and Explosive ammo for now, " "I can't sell that to you. (`{ctx.prefix}event`)", )) return False language_code = await ctx.get_language_code() db_hunter: Player = await get_player(ctx.author, ctx.channel) self.ensure_enough_experience(db_hunter, ITEM_COST) if db_hunter.is_powerup_active("explosive_ammo"): time_delta = get_timedelta( db_hunter.active_powerups['explosive_ammo'], time.time()) await ctx.reply( _("❌ Your gun is already using explosive ammo for {time_delta}!", time_delta=format_timedelta(time_delta, locale=language_code))) return False await db_hunter.edit_experience_with_levelups(ctx, -ITEM_COST) db_hunter.active_powerups["explosive_ammo"] = int(time.time()) + DAY db_hunter.bought_items['explosive_ammo'] += 1 await db_hunter.save() await ctx.reply( _("💸 You bought some **EXPLOSIVE** ammo. Thrice the damage, that'll be bloody! [Bought: -{ITEM_COST} exp, total {db_hunter.experience} exp]", db_hunter=db_hunter, ITEM_COST=ITEM_COST))
def timedelta_filter( delta: Union[int, timedelta, datetime], granularity: str = 'second', threshold: float = 0.85, add_direction: bool = False, format: str = 'long', # NOQA: A002 # skipcq: PYL-W0622 locale: Union[Locale, str] = None, ) -> str: """ Render a timedelta or int (representing seconds) as a duration. :param delta: A timedelta object representing the time difference to format, or the delta in seconds as an int value :param granularity: Determines the smallest unit that should be displayed, the value can be one of “year”, “month”, “week”, “day”, “hour”, “minute” or “second” :param threshold: Factor that determines at which point the presentation switches to the next higher unit :param add_direction: If this flag is set to True the return value will include directional information. For instance a positive timedelta will include the information about it being in the future, a negative will be information about the value being in the past. If a datetime is provided for delta, add_direction will be forced to True :param format: The format, can be “narrow”, “short” or “long” :param locale: A Locale object or a locale identifier (defaults to current locale) """ if isinstance(delta, datetime): # Convert datetimes into a timedelta from present and turn on add_direction if not delta.tzinfo: delta = utc.localize(delta) delta = delta - request_timestamp() add_direction = True return format_timedelta( delta, granularity=granularity, threshold=threshold, add_direction=add_direction, format=format, locale=locale if locale else get_locale() or DEFAULT_LOCALE, )
async def background_loop(self): status_channel = self.bot.get_channel(self.config()["status_channel_id"]) if not status_channel or not isinstance(status_channel, discord.TextChannel): self.bot.logger.warning("The status channel for the support server command is misconfigured.") return self.bot.logger.debug("Updating status message", guild=status_channel.guild, channel=status_channel) await purge_channel_messages(status_channel) embed = discord.Embed(colour=discord.Colour.blurple(), title=f"{self.bot.user.name}'s status") embed.add_field(name="Guilds Count", value=f"{len(self.bot.guilds)}", inline=True) embed.add_field(name="Users Count", value=f"{len(self.bot.users)}", inline=True) embed.add_field(name="Messages in cache", value=f"{len(self.bot.cached_messages)}", inline=True) ping_f = status_channel.trigger_typing() t_1 = time.perf_counter() await ping_f # tell Discord that the bot is "typing", which is a very simple request t_2 = time.perf_counter() ping = round((t_2 - t_1) * 1000) # calculate the time needed to trigger typing embed.add_field(name="Average Latency", value=f"{round(self.bot.latency, 2)}ms", inline=True) embed.add_field(name="Current ping", value=f"{ping}ms", inline=True) embed.add_field(name="Shards Count", value=f"{self.bot.shard_count}", inline=True) embed.add_field(name="Cogs loaded", value=f"{len(self.bot.cogs)}", inline=True) embed.add_field(name="Commands loaded", value=f"{len(self.bot.commands)}", inline=True) embed.add_field(name="Uptime", value=f"{self.get_bot_uptime()}", inline=True) embed.timestamp = datetime.datetime.utcnow() next_it = self.background_loop.next_iteration now = pytz.utc.localize(datetime.datetime.utcnow()) delta = dates.format_timedelta(next_it - now, locale='en') embed.set_footer(text=f"This should update every {delta} - Last update") await status_channel.send(embed=embed)
async def wlcm_sec_time_state(message: Message, chat: dict, strings: dict, state, **_): async with state.proxy() as data: level = data["level"] try: con_time = convert_time(message.text) except (ValueError, TypeError): await message.reply(strings["invalid_time"]) else: await db.greetings.update_one( {"chat_id": chat["chat_id"]}, {"$set": {"welcome_security.expire": message.text}} ) await get_greetings_data.reset_cache(chat['chat_id']) await message.reply( strings["welcomesecurity_enabled:customized_time"].format( chat_name=chat['chat_title'], level=level, time=format_timedelta( con_time, locale=strings['language_info']['babel'] ) ) ) finally: await state.finish()
async def import_fun(message, document, chat, strings): chat_id = chat['chat_id'] key = 'import_lock:' + str(chat_id) if redis.get(key) and message.from_user.id not in OPERATORS: ttl = format_timedelta(timedelta(seconds=redis.ttl(key)), strings['language_info']['babel']) await message.reply(strings['imports_locked'] % ttl) return redis.set(key, 1) redis.expire(key, 7200) msg = await message.reply(strings['started_importing']) if document['file_size'] > 52428800: await message.reply(strings['big_file']) return data = await bot.download_file_by_id(document.file_id, io.BytesIO()) data = ujson.load(data) if 'general' not in data: await message.reply(strings['bad_file']) return file_version = data['general']['version'] if file_version > VERSION: await message.reply(strings['file_version_so_new']) return imported = [] for module in [m for m in LOADED_MODULES if hasattr(m, '__import__')]: module_name = module.__name__.replace('sophie_bot.modules.', '') if module_name in data: imported.append(module_name) await asyncio.sleep(0.2) await module.__import__(chat_id, data[module_name]) await msg.delete() await message.answer(strings['import_done'], reply=message.message_id)
async def ducks_list(self, ctx: MyContext): """ Show ducks currently on the channel """ if not ctx.invoked_subcommand: _ = await ctx.get_translate_function(user_language=True) language_code = await ctx.get_language_code(user_language=True) ducks_spawned = self.bot.ducks_spawned[ctx.channel] ducks_spawned_count = len(ducks_spawned) ducks_left = self.bot.enabled_channels[ctx.channel] message = [ _("{ducks_spawned_count} ducks are on the channel, {ducks_left} ducks left to spawn today.", ducks_spawned_count=ducks_spawned_count, ducks_left=ducks_left), ] if ducks_spawned: message.append(_("Here's the list of ducks spawned :")) message.append('```') for duck in ducks_spawned: spawned_for = datetime.timedelta(seconds=-duck.spawned_for) time_delta = format_timedelta(spawned_for, locale=language_code, add_direction=True) duck_lives = await duck.get_lives() message.append( _("{duck.category} ({duck.lives_left}/{duck_lives}), spawned {time_delta}.", duck=duck, duck_lives=duck_lives, time_delta=time_delta)) message.append('```') await ctx.author.send(content='\n'.join(message))
def run(self, log_dir='.', keep_log=False, recompute_stats=10, update_cached_amounts=True): """This is the starting point for payday. It is structured such that it can be run again safely (with a newly-instantiated Payday object) if it crashes. """ self.db.self_check() _start = pando.utils.utcnow() log("Greetings, program! It's PAYDAY!!!!") self.shuffle(log_dir) self.end() self.recompute_stats(limit=recompute_stats) if update_cached_amounts: self.update_cached_amounts() self.notify_participants() _end = pando.utils.utcnow() _delta = _end - _start msg = "Script ran for %s ({0})." log(msg.format(_delta) % format_timedelta(_delta, locale='en')) if keep_log: output_log_name = 'payday-%i.txt' % self.id output_log_path = log_dir+'/'+output_log_name if website.s3: s3_bucket = website.app_conf.s3_payday_logs_bucket s3_key = 'paydays/'+output_log_name website.s3.upload_file(output_log_path+'.part', s3_bucket, s3_key) log("Uploaded log to S3.") os.rename(output_log_path+'.part', output_log_path) self.db.run("UPDATE paydays SET stage = NULL WHERE id = %s", (self.id,))
def timedelta( self, delta, granularity="second", threshold=.85, format="medium", add_direction=False, ): """Return a time delta according to the rules of the given locale. >>> from datetime import timedelta >>> fmt = Format('en_US') >>> fmt.timedelta(timedelta(weeks=11)) u'3 months' """ return format_timedelta( delta, granularity=granularity, threshold=threshold, format=format, add_direction=add_direction, locale=self.locale, )
def format_timedelta( datetime_or_timedelta, granularity="second", add_direction=False, threshold=0.85, request=None, ): """Format the elapsed time from the given date to now or the given timedelta. This function is also available in the template context as filter named `timedeltaformat`. """ if isinstance(datetime_or_timedelta, datetime): datetime_or_timedelta = datetime.utcnow() - datetime_or_timedelta return dates.format_timedelta( datetime_or_timedelta, granularity, threshold=threshold, add_direction=add_direction, locale=get_locale(request), )
def index(self): now = datetime.datetime.now() # This is a TimeDelta object ! age = now - self.company.creation_date # Create a time delta to get company "age" formatted = format_timedelta(age) age_seconds=age.total_seconds() # Yes we *could* use Jinja templating, but why for? returned = Template("""<html> <head> <meta http-equiv="refresh" content="1"> </head> <body> <table> <tr><th></th><th>Count</th><th>Per second</th></tr> <tr><td>Contracts</td><td>$contracts</td><td>$cps</td></tr> <tr><td>Quantity</td><td>$quantity</td><td>$qps</td></tr> <tr><td>Messages sent</td><td>$sent</td><td>$sps</td></tr> <tr><td>Messages received</td><td>$received</td><td>$rps</td></tr> <tr><td>Messages exchanged</td><td>$total</td><td>$tps</td></tr> </table> <p>Company age $age</p> </body> </html>""") return returned.substitute( age = formatted, contracts=humanize.intword(self.company.contracts), cps="{0:.2f}".format(self.company.contracts/age_seconds), quantity=humanize.intword(self.company.quantity), qps="{0:.2f}".format(self.company.quantity/age_seconds), sent=humanize.intword(self.company.messages["sent"]), sps="{0:.2f}".format(self.company.messages["sent"]/age_seconds), received=humanize.intword(self.company.messages["received"]), rps="{0:.2f}".format(self.company.messages["received"]/age_seconds), total=humanize.intword(self.company.messages["sent"]+self.company.messages["sent"]), tps="{0:.2f}".format((self.company.messages["sent"]+self.company.messages["sent"])/age_seconds), )
def on_response(sender, **kw): try: headers = kw['result'].headers if 'X-RateLimit-Reset' not in headers: return lists = ( parse_ratelimit_header(headers['X-RateLimit']), parse_ratelimit_header(headers['X-RateLimit-Remaining']), parse_ratelimit_header(headers['X-RateLimit-Reset']), ) now = datetime.utcnow().replace(tzinfo=utc) next_delay = 0 i = 0 for consumed, remaining, reset in zip(*lists): i += 1 limit = consumed + remaining percent_remaining = remaining / limit if percent_remaining < 0.4: # Slow down background requests reset = datetime.fromtimestamp(reset, tz=utc) reset_delta = reset - now next_delay = max( next_delay, reset_delta.total_seconds() / max(remaining, 2)) if percent_remaining < 0.2: # Log a warning reset_delta = format_timedelta(reset_delta, add_direction=True, locale='en') log_msg = ('{:.1%} of ratelimit #{} has been consumed, ' '{} requests remaining, resets {}.').format( 1 - percent_remaining, i, remaining, reset_delta) logger.warning(log_msg) Payday.transfer_delay = next_delay except Exception as e: website.tell_sentry(e, {})
def render_to_fragment(self, request, course_id, user_access, **kwargs): """ Renders a course message fragment for the specified course. """ course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key) # Get time until the start date, if already started, or no start date, value will be zero or negative now = datetime.now(UTC()) already_started = course.start and now > course.start days_until_start_string = "started" if already_started else format_timedelta(course.start - now, locale=to_locale(get_language())) course_start_data = { 'course_start_date': format_date(course.start, locale=to_locale(get_language())), 'already_started': already_started, 'days_until_start_string': days_until_start_string } # Register the course home messages to be loaded on the page self.register_course_home_messages(request, course, user_access, course_start_data) # Grab the relevant messages course_home_messages = list(CourseHomeMessages.user_messages(request)) # Return None if user is enrolled and course has begun if user_access['is_enrolled'] and already_started: return None # Grab the logo image_src = "course_experience/images/home_message_author.png" context = { 'course_home_messages': course_home_messages, 'image_src': image_src, } html = render_to_string('course_experience/course-messages-fragment.html', context) return Fragment(html)
def draw(self, helper): time = timedelta(seconds=self.directions[0]["legs"][0] ["duration_in_traffic"]["value"]) route = self.directions[0]["summary"] # Display the time helper.text( (20, self.size[1] - HEADER_SIZE + 3), format_timedelta(time, locale=self.locale), font=self.fonts["time"], fill=helper.BLACK, ) # Display the route helper.text( (20, self.size[1] - HEADER_SIZE + 37), route, font=self.fonts["route"], fill=helper.BLACK, ) # Display the image helper.img.paste( Image.open(io.BytesIO(self.map)).convert("RGB"), (0, 0))
async def clover(self, ctx: MyContext): """ Buy a 4-Leaf clover to get more exp for every duck you kill :) """ ITEM_COST = 13 _ = await ctx.get_translate_function() language_code = await ctx.get_language_code() db_hunter: Player = await get_player(ctx.author, ctx.channel) db_channel: DiscordChannel = await get_from_db(ctx.channel) self.ensure_enough_experience(db_hunter, ITEM_COST) if db_hunter.is_powerup_active('clover'): time_delta = get_timedelta(db_hunter.active_powerups['clover'], time.time()) await ctx.reply(_("❌ You already use a 4-Leaf clover. Try your luck again in {time_delta}!", time_delta=format_timedelta(time_delta, locale=language_code))) return False max_experience = db_channel.clover_max_experience if self.bot.current_event == Events.FLORIST: max_experience *= 2 clover_exp = random.randint(db_channel.clover_min_experience, max_experience) await db_hunter.edit_experience_with_levelups(ctx, -ITEM_COST) db_hunter.active_powerups["clover"] = int(time.time()) + DAY db_hunter.active_powerups["clover_exp"] = clover_exp db_hunter.bought_items['clover'] += 1 await db_hunter.save() await ctx.reply( _("🍀 You bought a 4-Leaf clover. Every time you kill a duck, you'll get {clover_exp} experience points more. [Bought: -{ITEM_COST} exp]", ITEM_COST=ITEM_COST, clover_exp=clover_exp))
}, upsert=True) await get_greetings_data.reset_cache(chat_id) buttons = InlineKeyboardMarkup() buttons.add( InlineKeyboardButton(strings["no_btn"], callback_data=wlcm_sec_config_cancel.new( user_id=message.from_user.id, level=level)), InlineKeyboardButton(strings["yes_btn"], callback_data=wlcm_sec_config_proc.new( chat_id=chat_id, user_id=message.from_user.id, level=level))) await message.reply( strings['ask_for_time_customization'].format(time=format_timedelta( convert_time(get_str_key("JOIN_CONFIRM_DURATION")), locale=strings['language_info']['babel'])), reply_markup=buttons) @register(wlcm_sec_config_cancel.filter(), f='cb', allow_kwargs=True) @chat_connection(admin=True) @get_strings_dec("greetings") async def welcome_security_config_cancel(event: CallbackQuery, chat: dict, strings: dict, callback_data: dict, **_): if int(callback_data['user_id']) == event.from_user.id and is_user_admin( chat['chat_id'], event.from_user.id): await event.message.edit_text( text=strings['welcomesecurity_enabled'].format( chat_name=chat['chat_title'], level=callback_data['level']))
async def on_command_error(self, ctx: MyContext, exception: Exception) -> None: _ = await ctx.get_translate_function() # This prevents any commands with local handlers being handled here in on_command_error. if hasattr(ctx.command, 'on_error'): return ignored = (commands.CommandNotFound, ) # Allows us to check for original exceptions raised and sent to CommandInvokeError. # If nothing is found. We keep the exception passed to on_command_error. # Anything in ignored will return and prevent anything happening. if isinstance(exception, ignored): return DELETE_ERROR_MESSAGE_AFTER = 60 command_invoke_help = f"{ctx.prefix}{ctx.command.qualified_name} {ctx.command.signature}" ctx.logger.debug( f"Error during processing: {exception} ({repr(exception)})") # https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CommandError if isinstance(exception, commands.CommandError): if isinstance(exception, commands.ConversionError): original = exception.original message = _( "There was an error converting one of your arguments with {exception.converter}. The " "correct syntax would be `{command_invoke_help}`. The converter returned the following error" ": {original}", command_invoke_help=command_invoke_help, original=escape_everything(str(original))) elif isinstance(exception, commands.UserInputError): if isinstance(exception, commands.errors.MissingRequiredArgument): message = _( "This command is missing an argument. The correct syntax would be `{command_invoke_help}`.", command_invoke_help=command_invoke_help) elif isinstance(exception, commands.errors.ArgumentParsingError): if isinstance(exception, commands.UnexpectedQuoteError): message = _( "Too many quotes were provided in your message: don't forget to escape your " "quotes like this `\\{exception.quote}`. The correct syntax for the command is " "`{command_invoke_help}`.", command_invoke_help=command_invoke_help, exception=exception) elif isinstance(exception, commands.InvalidEndOfQuotedStringError): message = _( "A space was expected after a closing quote, but I found {exception.char}. " "Please check that you are using the correct syntax: `{command_invoke_help}`.", command_invoke_help=command_invoke_help, exception=exception) elif isinstance(exception, commands.ExpectedClosingQuoteError): message = _( "A closing quote was expected, but wasn't found. Don't forget to close your " "quotes with `{exception.close_quote}` at the end of your argument. Please check " "that you are using the correct syntax: `{command_invoke_help}`.", command_invoke_help=command_invoke_help, exception=exception) elif isinstance(exception, commands.TooManyArguments): message = _( "Too many arguments were passed in this command. " "Please check that you are using the correct syntax: `{command_invoke_help}`.", command_invoke_help=command_invoke_help) else: # Should not trigger, just in case some more errors are added. message = _( "The way you are invoking this command is confusing me. The correct syntax would " "be `{command_invoke_help}`.", command_invoke_help=command_invoke_help) elif isinstance(exception, commands.BadArgument): message = _( "An argument passed was incorrect. `{exception}`." "Please check that you are using the correct syntax: `{command_invoke_help}`.", command_invoke_help=command_invoke_help, exception=exception) elif isinstance(exception, commands.BadUnionArgument): message = _( "{exception} Please check that you are using the correct syntax: `{command_invoke_help}`.", command_invoke_help=command_invoke_help, exception=str(exception)) else: message = f"{str(exception)} ({type(exception).__name__})" ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) elif isinstance(exception, commands.CheckFailure): if isinstance(exception, commands.PrivateMessageOnly): message = _( "This command can only be used in a private message.") elif isinstance(exception, commands.NoPrivateMessage): message = _( "This command cannot be used in a private message.") elif isinstance(exception, commands.CheckAnyFailure): message = _( "Multiple errors were encountered when running your command : {exception.errors}", exception=exception) elif isinstance(exception, commands.NotOwner): message = _( "You need to be the owner of the bot to run that.") # We could edit and change the message here, but the lib messages are fine and specify exactly what permissions are missing elif isinstance(exception, commands.MissingPermissions): message = f"{str(exception)}" elif isinstance(exception, commands.BotMissingPermissions): message = f"{str(exception)}" elif isinstance(exception, commands.MissingRole): message = f"{str(exception)}" elif isinstance(exception, commands.BotMissingRole): message = f"{str(exception)}" elif isinstance(exception, commands.MissingAnyRole): message = f"{str(exception)}" elif isinstance(exception, commands.BotMissingAnyRole): message = f"{str(exception)}" elif isinstance(exception, commands.NSFWChannelRequired): message = _( "You need to be in a NSFW channel to run that.") # Custom checks errors elif isinstance(exception, checks.NotInServer): correct_guild = self.bot.get_guild( exception.must_be_in_guild_id) if correct_guild: message = _( "You need to be in the {correct_guild.name} server (`{exception.must_be_in_guild_id}`).", correct_guild=correct_guild, exception=exception) else: message = _( "You need to be in a server with ID {exception.must_be_in_guild_id}.", exception=exception) elif isinstance(exception, checks.HavingPermission): message = _( "You have the `{exception.permission}` permission.", exception=exception) elif isinstance(exception, checks.MissingPermission): message = _( "You need the `{exception.permission}` permission.", exception=exception) elif isinstance(exception, checks.HavingPermissions): message = _( "You have {exception.required} or more of the following permissions : `{exception.permissions}`.", exception=exception) elif isinstance(exception, checks.MissingPermissions): message = _( "You need {exception.required} or more of the following permissions : `{exception.permissions}`.", exception=exception) elif isinstance(exception, checks.BotIgnore): return else: message = f"Check error running this command : {str(exception)} ({type(exception).__name__})" ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) elif isinstance(exception, commands.CommandNotFound): # This should be disabled. message = _("The provided command was not found.") elif isinstance(exception, commands.errors.DisabledCommand): message = _("That command has been disabled.") elif isinstance(exception, commands.CommandInvokeError): message = _( "There was an error running the specified command. Contact the bot admins." ) ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) elif isinstance(exception, commands.errors.CommandOnCooldown): if await self.bot.is_owner( ctx.author ) or checks.has_permission("bot.bypass_cooldowns"): await ctx.reinvoke() return else: delta = datetime.timedelta( seconds=min(round(exception.retry_after, 1), 1)) # NOTE : This message uses a formatted, direction date in some_time. Formatted, it'll give something like : # "This command is overused. Please try again *in 4 seconds*" message = _( "This command is overused. Please try again {some_time}.", some_time=dates.format_timedelta( delta, add_direction=True, locale=await ctx.get_language_code())) elif isinstance(exception, commands.errors.MaxConcurrencyReached): message = f"{str(exception)}" # The message from the lib is great. else: message = f"{str(exception)} ({type(exception).__name__})" ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) else: message = _( "This should not have happened. A command raised an error that does not comes from CommandError. Please inform the owner." ) ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) if message: await ctx.send("❌ " + message, delete_after=DELETE_ERROR_MESSAGE_AFTER)
def time_remaining_string(self): """ Returns the time remaining as a localized string. """ locale = to_locale(get_language()) return format_timedelta(self.date - self.current_time, locale=locale)
await message.reply(strings["setup_corrupted"]) else: await db.antiflood.update_one( {"chat_id": chat["chat_id"]}, {"$set": { "time": time, "count": int(data) }}, upsert=True, ) await get_data.reset_cache(chat["chat_id"]) kw = {"count": data} if time is not None: kw.update({ "time": format_timedelta(parsed_time, locale=strings["language_info"]["babel"]) }) await message.reply( strings["setup_success" if time is not None else "setup_success:no_exp"].format(**kw)) finally: await state.finish() @register(cmds=["antiflood", "flood"], is_admin=True) @chat_connection(admin=True) @get_strings_dec("antiflood") async def antiflood(message: Message, chat: dict, strings: dict): if not (data := await get_data(chat["chat_id"])): return await message.reply(strings["not_configured"])
def _estimate(self, target_datetime=None): target_datetime = datetime.now(tz=JAKARTA_TIMEZONE) if target_datetime is None else target_datetime diff = target_datetime - datetime.now(tz=JAKARTA_TIMEZONE) return format_timedelta(delta=diff, add_direction=True)
async def on_command_error(self, ctx: MyContext, exception: Exception) -> None: _ = await ctx.get_translate_function() # This prevents any commands with local handlers being handled here in on_command_error. if hasattr(ctx.command, 'on_error'): return ignored = (commands.CommandNotFound, ) # Allows us to check for original exceptions raised and sent to CommandInvokeError. # If nothing is found. We keep the exception passed to on_command_error. # Anything in ignored will return and prevent anything happening. if isinstance(exception, ignored): return delete_error_message_after = 60 command_invoke_help = f"{ctx.prefix}{ctx.command.qualified_name} {ctx.command.signature}" ctx.logger.warning( f"Error during processing: {exception} ({repr(exception)})") # https://discordpy.readthedocs.io/en/latest/ext/commands/api.html#discord.ext.commands.CommandError if isinstance(exception, commands.CommandError): if isinstance(exception, commands.ConversionError): original = exception.original message = _( "There was an error converting one of your arguments with {0}. The " "correct syntax would be `{1}`. The converter returned the following " "error: {2}", exception.converter, command_invoke_help, escape_everything(str(original))) elif isinstance(exception, commands.UserInputError): if isinstance(exception, commands.errors.MissingRequiredArgument): message = _( "This command is missing an argument. The correct syntax would be " "`{0}`.", command_invoke_help) elif isinstance(exception, commands.errors.ArgumentParsingError): if isinstance(exception, commands.UnexpectedQuoteError): message = _( "Too many quotes were provided in your message: don't forget to escape your " "quotes like this `\\{0}`. The correct syntax for the command is " "`{1}`.", exception.quote, command_invoke_help) elif isinstance(exception, commands.InvalidEndOfQuotedStringError): message = _( "A space was expected after a closing quote, but I found {0}. " "Please check that you are using the correct syntax: `{1}`.", exception.char, command_invoke_help) elif isinstance(exception, commands.ExpectedClosingQuoteError): message = _( "A closing quote was expected, but wasn't found. Don't forget to close your " "quotes with `{0}` at the end of your argument. Please check " "that you are using the correct syntax: `{1}`.", exception.close_quote, command_invoke_help) elif isinstance(exception, commands.TooManyArguments): message = _( "Too many arguments were passed in this command. " "Please check that you are using the correct syntax: `{0}`.", command_invoke_help) else: # Should not trigger, just in case some more errors are added. message = _( "The way you are invoking this command is confusing me. The correct syntax would " "be `{0}`.", command_invoke_help) elif isinstance(exception, commands.BadArgument): message = _( "An argument passed was incorrect. `{0}`." "Please check that you are using the correct syntax: `{1}`.", str(exception), command_invoke_help) elif isinstance(exception, commands.BadUnionArgument): message = _( "{0} Please check that you are using the correct syntax: `{1}`.", str(exception), command_invoke_help) else: message = "{str(exception)} ({type(exception).__name__})" ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) elif isinstance(exception, commands.CheckFailure): if isinstance(exception, commands.PrivateMessageOnly): message = _( "This command can only be used in a private message.") elif isinstance(exception, commands.NoPrivateMessage): message = _( "This command cannot be used in a private message.") elif isinstance(exception, commands.CheckAnyFailure): message = _( "Multiple errors were encountered when running your command: {0}", exception.errors) elif isinstance(exception, commands.NotOwner): message = _( "You need to be the owner of the bot to run that.") # We could edit and change the message here, but the lib messages are fine and specify exactly what # permissions are missing elif isinstance(exception, commands.MissingPermissions): message = _( "You are missing permissions to run this command. {0}", " ".join(exception.missing_perms)) elif isinstance(exception, commands.BotMissingPermissions): message = _( "I am missing permissions to run this command. {0}", " ".join(exception.missing_perms)) elif isinstance(exception, commands.MissingRole): message = _("You are missing the following role: {0}", exception.missing_role) elif isinstance(exception, commands.BotMissingRole): message = _("I am missing the following role: {0}", exception.missing_role) elif isinstance(exception, commands.MissingAnyRole): message = _( "You are missing one of the following roles: {0}", " ".join(exception.missing_roles)) elif isinstance(exception, commands.BotMissingAnyRole): message = _("I am missing one of the following roles: {0}", " ".join(exception.missing_roles)) elif isinstance(exception, commands.NSFWChannelRequired): message = _( "You need to be in a NSFW channel to run that.") # Custom checks errors elif isinstance(exception, checks.NotInServer): correct_guild = self.bot.get_guild( exception.must_be_in_guild_id) if correct_guild: message = _( "You need to be in the {0} server " "(`{1}`).", correct_guild.name, exception.must_be_in_guild_id) else: message = _("You need to be in a server with ID {0}.", exception.must_be_in_guild_id) elif isinstance(exception, checks.HavingPermission): message = _("You have the `{0}` permission.", exception.permission) elif isinstance(exception, checks.MissingPermission): message = _("You need the `{0}` permission.", exception.permission) elif isinstance(exception, checks.HavingPermissions): message = _( "You have {0} or more of the following permissions: " "`{1}`.", exception.required, exception.permissions) elif isinstance(exception, checks.MissingPermissions): message = _( "You need {0} or more of the following permissions: " "`{1}`.", exception.required, exception.permissions) elif isinstance(exception, checks.BotIgnore): return else: message = "Check error running this command : {str(exception)} ({type(exception).__name__})" ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) elif isinstance(exception, commands.CommandNotFound): # This should be disabled. message = _("The provided command was not found.") elif isinstance(exception, commands.errors.DisabledCommand): message = _("That command has been disabled.") elif isinstance(exception, commands.CommandInvokeError): if isinstance(exception.original, discord.errors.Forbidden): await ctx.author.send( _("I don't have permissions to send messages there! Try again somewhere I do " "have permissions to send messages!")) return elif isinstance(exception.original, RuntimeError) and exception.original.args[0] == \ "The bot hasn't been set up yet! Ensure bot.async_setup is called ASAP!": message = _( "The bot's still setting up, please wait a few minutes and try again!" ) elif isinstance(exception.original, discord.errors.NotFound): message = _( "I can't find your original message, Discord may be having issues! Try again." ) elif isinstance(exception.original, api.NoDataAvailable): message = _( "No data is available at the moment. Wait a few moments. **Spamming this command will " "result in a temporary ban!**") elif isinstance(exception.original, InvalidKeyError): message = _( "A invalid key was found. If you want to use `{` and `}`, make sure you escape them by " "using two brackets instead of one. If you don't, make sure the values are correct." "{0}", exception.original.__str__()) else: message = _( "There was an error running the specified command‽ This error has been logged." ) # we want the original instead of the CommandError one await submit_error_message(exception.original, "unknown thing", self.bot, ctx) # ctx.logger.error("".join(traceback.format_exception(type(exception), # exception, exception.__traceback__))) elif isinstance(exception, commands.errors.CommandOnCooldown): if await self.bot.is_owner(ctx.author): try: await ctx.reinvoke() except Exception as e: await self.on_command_error(ctx, e) return else: delta = datetime.timedelta(seconds=exception.retry_after) # NOTE : This message uses a formatted, direction date in some_time. Formatted, it'll give something # like: "This command is overused. Please try again *in 4 seconds*" message = _( "You are being ratelimited. Please try again {0}.", dates.format_timedelta(delta, add_direction=True, locale=await ctx.get_language_code())) elif isinstance(exception, commands.errors.MaxConcurrencyReached): bucket_types = { commands.BucketType.default: _("globally"), commands.BucketType.user: _("per user"), commands.BucketType.guild: _("per guild"), commands.BucketType.channel: _("per channel"), commands.BucketType.member: _("per member"), commands.BucketType.category: _("per category"), commands.BucketType.role: _("per role") } message = _( "Too many users are using this command. Only {0} users can use it at the same time {1}.", exception.number, bucket_types[exception.per]) else: message = "{str(exception)} ({type(exception).__name__})" ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) await submit_error_message(exception, "unknown thing", ctx.bot, ctx) else: message = _( "This should not have happened. A command raised an error that does not comes from " "CommandError. Please inform the owner.") ctx.logger.error("".join( traceback.format_exception(type(exception), exception, exception.__traceback__))) if message: await ctx.send("❌ " + message + _( "\nFor help, join the bot's support server at {0}\n" "Check <https://discordstatus.com/> for more details on Discord issues.", self.bot.support_server_invite), delete_after=delete_error_message_after) else: await ctx.send( "❌ " + _("No message was defined. This error has been logged."))
def timedelta_filter(s): return format_timedelta(s, locale="en_US")
def format_delta_filter(timestamp): '''Jinja2 fiter to format a unix timestamp to a time delta string.''' delta = datetime.now() - datetime.fromtimestamp(timestamp) return format_timedelta(delta, locale='en_US')