document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. #!/usr/bin/env python
  2. #
  3. # Humandate - a web service to humanize dates with Yahoo! Pipes
  4. # MS-potilas 2012. See http://yabtb.blogspot.com/2012/05/extending-yahoo-pipes-with-google-app.html
  5. #
  6. from google.appengine.ext import webapp
  7. from google.appengine.ext.webapp import util
  8. import simplejson
  9. #
  10. # MS-potilas: time humanizing code begins, borrowed from Django\'s "contrib.humanize".
  11. #
  12. import time
  13. from datetime import datetime, timedelta, date
  14.  
  15. def _now():
  16.     return datetime.now()
  17.  
  18. def abs_timedelta(delta):
  19.     """Returns an "absolute" value for a timedelta, always representing a
  20.    time distance."""
  21.     if delta.days < 0:
  22.         now = _now()
  23.         return now - (now + delta)
  24.     return delta
  25.  
  26. def date_and_delta(value):
  27.     """Turn a value into a date and a timedelta which represents how long ago
  28.    it was.  If that\'s not possible, return (None, value)."""
  29.     now = _now()
  30.     if isinstance(value, datetime):
  31.         date = value
  32.         delta = now - value
  33.     elif isinstance(value, timedelta):
  34.         date = now - value
  35.         delta = value
  36.     else:
  37.         try:
  38.             value = int(value)
  39.             delta = timedelta(seconds=value)
  40.             date = now - delta
  41.         except (ValueError, TypeError):
  42.             return (None, value)
  43.     return date, abs_timedelta(delta)
  44.  
  45. def naturaldelta(value, months=True, onlyoneyear=True):
  46.     """Given a timedelta or a number of seconds, return a natural
  47.    representation of the amount of time elapsed.  This is similar to
  48.    ``naturaltime``, but does not add tense to the result.  If ``months``
  49.    is True, then a number of months (based on 30.5 days) will be used
  50.    for fuzziness between years.
  51.  
  52.    MS-potilas: if ``onlyoneyear`` is True, no fuzziness between years 1-2.
  53.    Changed "an hour" to "1 hour" etc. (don\'t change "a moment"!) """
  54.  
  55.     date, delta = date_and_delta(value)
  56.     if date is None:
  57.         return value
  58.     use_months = months
  59.     seconds = abs(delta.seconds)
  60.     days = abs(delta.days)
  61.     years = days // 365
  62.     days = days % 365
  63.     months = int(days // 30.5)
  64.     if not years and days < 1:
  65.         if seconds == 0:
  66.             return "a moment"
  67.         elif seconds == 1:
  68.             return "1 second"
  69.         elif seconds < 60:
  70.             return "%d seconds" % (seconds)
  71.         elif 60 <= seconds < 120:
  72.             return "1 minute"
  73.         elif 120 <= seconds < 3600:
  74.             return "%d minutes" % (seconds // 60)
  75.         elif 3600 <= seconds < 3600*2:
  76.             return "1 hour"
  77.         elif 3600 < seconds:
  78.             return "%d hours" % (seconds // 3600)
  79.     elif years == 0:
  80.         if days == 1:
  81.             return "1 day"
  82.         if not use_months:
  83.             return "%d days" % days
  84.         else:
  85.             if not months:
  86.                 return "%d days" % days
  87.             elif months == 1:
  88.                 return "1 month"
  89.             else:
  90.                 return "%d months" % months
  91.     elif years == 1:
  92.         if onlyoneyear:
  93.             return "1 year"
  94.         if not months and not days:
  95.             return "1 year"
  96.         elif not months:
  97.             return "1 year, %d days" % days
  98.         elif use_months:
  99.             if months == 1:
  100.                 return "1 year, 1 month"
  101.             else:
  102.                 return "1 year, %d months" % months
  103.         else:
  104.             return "1 year, %d days" % days
  105.     else:
  106.         return "%d years" % years
  107.  
  108. def naturaltime(value, future=False, months=True):
  109.     """Given a datetime or a number of seconds, return a natural representation
  110.    of that time in a resolution that makes sense.  This is more or less
  111.    compatible with Django\'s ``naturaltime`` filter.  ``future`` is ignored for
  112.    datetimes, where the tense is always figured out based on the current time.
  113.    If an integer is passed, the return value will be past tense by default,
  114.    unless ``future`` is set to True."""
  115.     now = _now()
  116.     date, delta = date_and_delta(value)
  117.     if date is None:
  118.         return value
  119.     # determine tense by value only if datetime/timedelta were passed
  120.     if isinstance(value, (datetime, timedelta)):
  121.         future = date > now
  122.     ago = \'from now\' if future else \'ago\'
  123.     delta = naturaldelta(delta)
  124.     if delta == "a moment":
  125.         return "now"
  126.     return "%s %s" % (delta, ago)
  127. #
  128. # MS-potilas: time humanizing code ends.
  129. #
  130.  
  131. class MainHandler(webapp.RequestHandler):
  132.     def get(self):
  133.         try:
  134.             utime = int(self.request.get("unixtime"))
  135.             if utime > 0:
  136.                 dt = datetime.fromtimestamp(utime)
  137.                 self.response.headers[\'Content-Type\'] = \'text/plain\'
  138.                 self.response.out.write(naturaltime(dt))
  139.         except:
  140.             self.response.headers.add_header("Cache-Control", "public, max-age=14400")
  141.             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>.\')
  142.             self.response.out.write(\'</body></html>\')
  143.         return 0;
  144.  
  145.     def post(self):
  146.         try:
  147.             data = self.request.get("data")
  148.             items = simplejson.loads(data)
  149.             items = items["items"]
  150.  
  151.             for item in items:
  152.                 utime = int(item[\'y:published\'][\'utime\'])
  153.                 dt = datetime.fromtimestamp(utime)
  154.                 item[\'when\'] = naturaltime(dt)
  155.  
  156.             self.response.content_type = "application/json"
  157.             simplejson.dump(items, self.response.out)
  158.         finally:
  159.             return 0;
  160.  
  161. def main():
  162.     application = webapp.WSGIApplication([(\'/\', MainHandler)],
  163.                                          debug=True)
  164.     util.run_wsgi_app(application)
  165.  
  166. if __name__ == \'__main__\':
  167.     main()
');