Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- #
- # Humandate - a web service to humanize dates with Yahoo! Pipes
- # MS-potilas 2012. See http://yabtb.blogspot.com/2012/05/extending-yahoo-pipes-with-google-app.html
- #
- from google.appengine.ext import webapp
- from google.appengine.ext.webapp import util
- import simplejson
- #
- # MS-potilas: time humanizing code begins, borrowed from Django's "contrib.humanize".
- #
- import time
- from datetime import datetime, timedelta, date
- def _now():
- return datetime.now()
- def abs_timedelta(delta):
- """Returns an "absolute" value for a timedelta, always representing a
- time distance."""
- if delta.days < 0:
- now = _now()
- return now - (now + delta)
- return delta
- def date_and_delta(value):
- """Turn a value into a date and a timedelta which represents how long ago
- it was. If that's not possible, return (None, value)."""
- now = _now()
- if isinstance(value, datetime):
- date = value
- delta = now - value
- elif isinstance(value, timedelta):
- date = now - value
- delta = value
- else:
- try:
- value = int(value)
- delta = timedelta(seconds=value)
- date = now - delta
- except (ValueError, TypeError):
- return (None, value)
- return date, abs_timedelta(delta)
- def naturaldelta(value, months=True, onlyoneyear=True):
- """Given a timedelta or a number of seconds, return a natural
- representation of the amount of time elapsed. This is similar to
- ``naturaltime``, but does not add tense to the result. If ``months``
- is True, then a number of months (based on 30.5 days) will be used
- for fuzziness between years.
- MS-potilas: if ``onlyoneyear`` is True, no fuzziness between years 1-2.
- Changed "an hour" to "1 hour" etc. (don't change "a moment"!) """
- date, delta = date_and_delta(value)
- if date is None:
- return value
- use_months = months
- seconds = abs(delta.seconds)
- days = abs(delta.days)
- years = days // 365
- days = days % 365
- months = int(days // 30.5)
- if not years and days < 1:
- if seconds == 0:
- return "a moment"
- elif seconds == 1:
- return "1 second"
- elif seconds < 60:
- return "%d seconds" % (seconds)
- elif 60 <= seconds < 120:
- return "1 minute"
- elif 120 <= seconds < 3600:
- return "%d minutes" % (seconds // 60)
- elif 3600 <= seconds < 3600*2:
- return "1 hour"
- elif 3600 < seconds:
- return "%d hours" % (seconds // 3600)
- elif years == 0:
- if days == 1:
- return "1 day"
- if not use_months:
- return "%d days" % days
- else:
- if not months:
- return "%d days" % days
- elif months == 1:
- return "1 month"
- else:
- return "%d months" % months
- elif years == 1:
- if onlyoneyear:
- return "1 year"
- if not months and not days:
- return "1 year"
- elif not months:
- return "1 year, %d days" % days
- elif use_months:
- if months == 1:
- return "1 year, 1 month"
- else:
- return "1 year, %d months" % months
- else:
- return "1 year, %d days" % days
- else:
- return "%d years" % years
- def naturaltime(value, future=False, months=True):
- """Given a datetime or a number of seconds, return a natural representation
- of that time in a resolution that makes sense. This is more or less
- compatible with Django's ``naturaltime`` filter. ``future`` is ignored for
- datetimes, where the tense is always figured out based on the current time.
- If an integer is passed, the return value will be past tense by default,
- unless ``future`` is set to True."""
- now = _now()
- date, delta = date_and_delta(value)
- if date is None:
- return value
- # determine tense by value only if datetime/timedelta were passed
- if isinstance(value, (datetime, timedelta)):
- future = date > now
- ago = 'from now' if future else 'ago'
- delta = naturaldelta(delta)
- if delta == "a moment":
- return "now"
- return "%s %s" % (delta, ago)
- #
- # MS-potilas: time humanizing code ends.
- #
- class MainHandler(webapp.RequestHandler):
- def get(self):
- try:
- utime = int(self.request.get("unixtime"))
- if utime > 0:
- dt = datetime.fromtimestamp(utime)
- self.response.headers['Content-Type'] = 'text/plain'
- self.response.out.write(naturaltime(dt))
- except:
- self.response.headers.add_header("Cache-Control", "public, max-age=14400")
- self.response.out.write('<html><head><link rel="shortcut icon" href="/favicon.ico" /><title>Humanized Dates Web Service</title></head><body>Works either as Yahoo! Pipes <a target="_blank" href="http://pipes.yahoo.com/pipes/docs?doc=operators#WebService">web service</a>: makes a new field "when" based on "y:published.utime",<br />or by giving url parameter unixtime, <a href="/?unixtime=1337752504">example</a>. By MS-potilas 2012. See <a href="http://yabtb.blogspot.com/2012/05/extending-yahoo-pipes-with-google-app.html">yabtb.blogspot.com</a>.')
- self.response.out.write('</body></html>')
- return 0;
- def post(self):
- try:
- data = self.request.get("data")
- items = simplejson.loads(data)
- items = items["items"]
- for item in items:
- utime = int(item['y:published']['utime'])
- dt = datetime.fromtimestamp(utime)
- item['when'] = naturaltime(dt)
- self.response.content_type = "application/json"
- simplejson.dump(items, self.response.out)
- finally:
- return 0;
- def main():
- application = webapp.WSGIApplication([('/', MainHandler)],
- debug=True)
- util.run_wsgi_app(application)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement