jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/314847 )
Change subject: archivebot stops supporting 'm' and 'M' qualifiers ......................................................................
archivebot stops supporting 'm' and 'M' qualifiers
'm' and 'M' are confusing while there are more commonly used time scales (such as 'days' and 'seconds', introduced here) that can be used instead.
Minutes and months qualifiers were introduced for archivebot.str2localized_duration but was missing for str2time function. Thus they are safe to remove because they have not been in real use.
A follow-up to If06a7d2a0f1cbe6ca3a64cabfb1108cc24b0226d.
- Make MW_KEYS a FrozenDict constant to be used by both functions str2time and str2localized_duration. - Make offset qualifier mandatory. Introduce 's' for seconds. Show a warning if 's' is missing for (undocumentd) seconds offset. - Add seconds to the doc string. - Calculate a more precise result for years using math.ceil() - Use an optional timestamp to calculate an accurate result for years. - Additional tests.
Bug: T147739 Change-Id: I0a6043fec740487e4c7050f69af6100c92aa50ae --- M scripts/archivebot.py M tests/archivebot_tests.py 2 files changed, 64 insertions(+), 35 deletions(-)
Approvals: Mpaa: Looks good to me, approved jenkins-bot: Verified Xqt: Looks good to me, but someone else must approve Whym: Looks good to me, but someone else must approve
diff --git a/scripts/archivebot.py b/scripts/archivebot.py index 4e28140..785d6af 100755 --- a/scripts/archivebot.py +++ b/scripts/archivebot.py @@ -35,8 +35,9 @@ supported. algo specifies the maximum age of a thread. Must be in the form old(<delay>) where <delay> specifies the age in - minutes (m), hours (h), days (d), weeks(w), months (M) or - years (y) like 24h or 5d. Default is old(24h) + seconds (s), hours (h), days (d), weeks(w), or years (y) + like 24h or 5d. + Default is old(24h). counter The current value of a counter which could be assigned as variable. Will be actualized by bot. Initial value is 1. maxarchivesize The maximum archive size before incrementing the counter. @@ -98,6 +99,7 @@ # import datetime import locale +import math import os import re import time @@ -107,11 +109,22 @@
import pywikibot
+from pywikibot.date import apply_month_delta from pywikibot import i18n from pywikibot.textlib import TimeStripper from pywikibot.textlib import to_local_digits +from pywikibot.tools import issue_deprecation_warning, FrozenDict
ZERO = datetime.timedelta(0) + +MW_KEYS = FrozenDict({ + 's': 'seconds', + 'h': 'hours', + 'd': 'days', + 'w': 'weeks', + 'y': 'years', + # 'months' and 'minutes' were removed because confusion outweights merit +}, 'MW_KEYS is a dict constant')
class ArchiveBotSiteConfigError(pywikibot.Error): @@ -155,50 +168,62 @@ Translates a duration written in the shorthand notation (ex. "24h", "7d") into an expression in the local language of the wiki ("24 hours", "7 days"). """ - mw_keys = { - 'm': 'minutes', - 'h': 'hours', - 'd': 'days', - 'w': 'weeks', - 'M': 'months', - 'y': 'years', - } - - template = site.mediawiki_message(mw_keys[string[-1]]) + template = site.mediawiki_message(MW_KEYS[string[-1]]) if template: duration = string[:-1] # replace plural variants exp = i18n.translate(site.code, template, {'$1': int(duration)}) - return exp.replace('$1', to_local_digits(duration, site.code)) else: return to_local_digits(string, site.code)
-def str2time(string): +def str2time(string, timestamp=None): """ Return a timedelta for a shorthand duration.
- Accepts a string defining a time period: - 7d - 7 days - 36h - 36 hours - 2w - 2 weeks (14 days) - 1y - 366 days # to be on the safe side - Returns the corresponding timedelta object. + @param string: a string defining a time period: + 300s - 300 seconds + 36h - 36 hours + 7d - 7 days + 2w - 2 weeks (14 days) + 1y - 1 year + @type string: str + @param timestamp: a timestamp to calulate a more accurate duration offset + used by years + @type timestamp: datetime.datetime + @return: the corresponding timedelta object + @rtype: datetime.timedelta """ - if string.endswith('h'): - return datetime.timedelta(hours=int(string[:-1])) - elif string.endswith('d'): - return datetime.timedelta(days=int(string[:-1])) - elif string.endswith('w'): - return datetime.timedelta(weeks=int(string[:-1])) - elif string.endswith('y'): - return datetime.timedelta(days=int(string[:-1]) * 366) + key = string[-1] + if string.isdigit(): + key = 's' + duration = string + issue_deprecation_warning('Time period without qualifier', + string + key, 1, UserWarning) else: - if string.isdigit(): - return datetime.timedelta(seconds=int(string)) - else: - raise MalformedConfigError('Unrecognized parameter in template: %s' % string) + duration = string[:-1] + + if duration.isdigit(): + duration = int(duration) + else: + key = '' + + if key in ['d', 's', 'h', 'w']: # days, seconds, minutes, hours, weeks + return datetime.timedelta(**{MW_KEYS[key]: duration}) + + if key == 'y': # years + days = math.ceil(duration * 365.25) + duration *= 12 + else: + raise MalformedConfigError( + 'Unrecognized parameter in template: {0}'.format(string)) + + if timestamp: + return apply_month_delta( + timestamp.date(), month_delta=duration) - timestamp.date() + else: + return datetime.timedelta(days=days)
def str2size(string): @@ -352,7 +377,7 @@ return '' # TODO: handle this: # return 'unsigned' - maxage = str2time(re_t.group(1)) + maxage = str2time(re_t.group(1), self.timestamp) if self.now - self.timestamp > maxage: duration = str2localized_duration(archiver.site, re_t.group(1)) return i18n.twtranslate(self.code, diff --git a/tests/archivebot_tests.py b/tests/archivebot_tests.py index 8a132cd..08108f1 100644 --- a/tests/archivebot_tests.py +++ b/tests/archivebot_tests.py @@ -81,9 +81,13 @@
def test_str2time(self): """Test for parsing the shorthand notation of durations.""" - self.assertEqual(archivebot.str2time('0'), timedelta(0)) + date = datetime(2017, 1, 1) # non leap year + self.assertEqual(archivebot.str2time('0d'), timedelta(0)) + self.assertEqual(archivebot.str2time('4000s'), timedelta(seconds=4000)) self.assertEqual(archivebot.str2time('4000h'), timedelta(hours=4000)) - self.assertEqual(archivebot.str2time('4000h'), timedelta(hours=4000)) + self.assertEqual(archivebot.str2time('7d'), archivebot.str2time('1w')) + self.assertEqual(archivebot.str2time('3y'), timedelta(1096)) + self.assertEqual(archivebot.str2time('3y', date), timedelta(1095)) self.assertRaises(archivebot.MalformedConfigError, archivebot.str2time, '4000@') self.assertRaises(archivebot.MalformedConfigError, archivebot.str2time, '$1')
pywikibot-commits@lists.wikimedia.org