jenkins-bot has submitted this change and it was merged.
Change subject: Implement support for time datatype
......................................................................
Implement support for time datatype
WbTime datatype resembles the Wikibase time format with precision, before, after, and
calendar model.
The precision can be set as integer (0-14) or with a human readable string, e.g.,
'hour'.
If the precision is not set it is determined automatically, for example: WbTime(2013, 8)
is August, 2013, precision month.
See these diffs as use case:
http://www.wikidata.org/w/index.php?title=Q150174&diff=67022161&old…
http://www.wikidata.org/w/index.php?title=Q150174&diff=67022199&old…
Change-Id: I4e13f797d7979d5944fa8822ea09076448b9990e
Original-Change-Id: Iac583043531ba3f30985244ffad2aef2ad549f51
---
M pywikibot/__init__.py
M pywikibot/page.py
M pywikibot/site.py
3 files changed, 97 insertions(+), 1 deletion(-)
Approvals:
Legoktm: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 8f53758..3eae1df 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -204,6 +204,92 @@
raise NotImplementedError
+class WbTime(object):
+ """ A Wikibase time representation"""
+
+ PRECISION = {'1000000000': 0, '100000000': 1, '10000000': 2,
'1000000': 3, '100000': 4, '10000': 5, 'millenia': 6,
'century': 7, 'decade': 8, 'year': 9, 'month': 10,
'day': 11, 'hour': 12, 'minute': 13, 'second': 14}
+ FORMATSTR = '{0:+012d}-{1:02d}-{2:02d}T{3:02d}:{4:02d}:{5:02d}Z'
+
+ def __init__(self, year=None, month=None, day=None, hour=None, minute=None,
second=None, precision=None, before=0, after=0, timezone=0,
calendarmodel='http://www.wikidata.org/entity/Q1985727')27'):
+ """ Creates a new WbTime object. The precision can be set by the
Wikibase int value (0-14) or by a human readable string, e.g., 'hour'. If no
precision is given, it is set according to the given time units."""
+ if year is None:
+ raise ValueError('no year given')
+ self.precision = WbTime.PRECISION['second']
+ if second is None:
+ self.precision = WbTime.PRECISION['minute']
+ second = 0
+ if minute is None:
+ self.precision = WbTime.PRECISION['hour']
+ minute = 0
+ if hour is None:
+ self.precision = WbTime.PRECISION['day']
+ hour = 0
+ if day is None:
+ self.precision = WbTime.PRECISION['month']
+ day = 1
+ if month is None:
+ self.precision = WbTime.PRECISION['year']
+ month = 1
+ self.year = long(year)
+ self.month = month
+ self.day = day
+ self.hour = hour
+ self.minute = minute
+ self.second = second
+ self.after = after
+ self.before = before
+ self.timezone = timezone
+ self.calendarmodel = calendarmodel
+
+ # if precision is given it overwrites the autodetection above
+ if precision is not None:
+ if isinstance(precision, int):
+ self.precision = precision
+ elif precision in WbTime.PRECISION:
+ self.precision = WbTime.PRECISION[precision]
+ else:
+ raise ValueError('Invalid precision: "%s"' %
precision)
+
+ @staticmethod
+ def fromTimestr(datetimestr, precision=14, before=0, after=0, timezone=0,
calendarmodel='http://www.wikidata.org/entity/Q1985727')27'):
+ match = re.match('([-+]?\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)Z',
datetimestr)
+ if not match:
+ raise ValueError(u"Invalid format: '%s'" % datetimestr)
+ t = match.groups()
+ return WbTime(long(t[0]), int(t[1]), int(t[2]), int(t[3]), int(t[4]), int(t[5]),
precision, before, after, timezone, calendarmodel)
+
+ def toWikibase(self):
+ """
+ Function which converts the data to a JSON object
+ for the Wikibase API.
+ """
+ json = {'time': WbTime.FORMATSTR.format(self.year, self.month, self.day,
+ self.hour, self.minute, self.second),
+ 'precision': self.precision,
+ 'after': self.after,
+ 'before': self.before,
+ 'timezone': self.timezone,
+ 'calendarmodel': self.calendarmodel
+ }
+ return json
+
+ @staticmethod
+ def fromWikibase(ts):
+ return WbTime.fromTimestr(ts[u'time'], ts[u'precision'],
ts[u'before'], ts[u'after'], ts[u'timezone'],
ts[u'calendarmodel'])
+
+ def __str__(self):
+ return str(self.toWikibase())
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+ def __repr__(self):
+ return u"WbTime(year=%(year)d, month=%(month)d, day=%(day)d, " \
+ u"hour=%(hour)d, minute=%(minute)d, second=%(second)d, " \
+ u"precision=%(precision)d, before=%(before)d, after=%(after)d, " \
+ u"timezone=%(timezone)d,
calendarmodel='%(calendarmodel)s')" % self.__dict__
+
+
def deprecated(instead=None):
"""Decorator to output a method deprecation warning.
diff --git a/pywikibot/page.py b/pywikibot/page.py
index daf37e8..fa4e5f7 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -2803,6 +2803,9 @@
elif claim.getType() == 'globecoordinate':
claim.target = pywikibot.Coordinate.fromWikibase(
data['mainsnak']['datavalue']['value'],
site)
+ elif claim.getType() == 'time':
+ claim.target = pywikibot.WbTime.fromWikibase(
+ data['mainsnak']['datavalue']['value'])
else:
# This covers string, url types
claim.target =
data['mainsnak']['datavalue']['value']
@@ -2853,6 +2856,7 @@
'commonsMedia': ImagePage,
'globecoordinate': pywikibot.Coordinate,
'url': basestring,
+ 'time': pywikibot.WbTime,
}
if self.getType() in types:
if not isinstance(value, types[self.getType()]):
@@ -2962,6 +2966,8 @@
elif self.getType() == 'commonsMedia':
value = self.getTarget().title(withNamespace=False)
elif self.getType() == 'globecoordinate':
+ value = self.getTarget().toWikibase()
+ elif self.getType() == 'time':
value = self.getTarget().toWikibase()
else:
raise NotImplementedError('%s datatype is not supported yet.'
@@ -3385,6 +3391,7 @@
link._title = title
return link
+
# Utility functions for parsing page titles
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 854ec27..d01503b 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -3709,6 +3709,10 @@
datavalue = {'type': 'string',
'value': sourceclaim._formatDataValue(),
}
+ elif sourceclaim.getType() == 'time':
+ datavalue = {'type': 'time',
+ 'value': sourceclaim._formatDataValue(),
+ }
else:
raise NotImplementedError('%s datatype is not supported yet.'
% sourceclaim.getType())
@@ -3726,7 +3730,6 @@
# if present, all claims of one source have the same hash
if not new and hasattr(sourceclaim, 'hash'):
params['reference'] = sourceclaim.hash
-
params['snaks'] = json.dumps(snak)
for arg in kwargs:
if arg in ['baserevid', 'summary']:
--
To view, visit
https://gerrit.wikimedia.org/r/81236
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I4e13f797d7979d5944fa8822ea09076448b9990e
Gerrit-PatchSet: 11
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: FelixReimann <felix(a)fex-it.de>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Legoktm <legoktm.wikipedia(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: jenkins-bot