Removing useless doctest since its dependent on non-existent stuff
[doneit] / src / toolbox.py
1 import sys
2 import StringIO
3 import urllib
4 from xml.dom import minidom
5 import datetime
6
7
8 def open_anything(source, alternative=None):
9         """URI, filename, or string --> stream
10
11         This function lets you define parsers that take any input source
12         (URL, pathname to local or network file, or actual data as a string)
13         and deal with it in a uniform manner.  Returned object is guaranteed
14         to have all the basic stdio read methods (read, readline, readlines).
15         Just .close() the object when you're done with it.
16         """
17         if hasattr(source, "read"):
18                 return source
19
20         if source == '-':
21                 return sys.stdin
22
23         # try to open with urllib (if source is http, ftp, or file URL)
24         try:
25                 return urllib.urlopen(source)
26         except (IOError, OSError):
27                 ##pass
28                 print "ERROR with URL ("+source+")!\n"
29
30         # try to open with native open function (if source is pathname)
31         try:
32                 return open(source)
33         except (IOError, OSError):
34                 ##pass
35                 print "ERROR with file!\n"
36
37         # treat source as string
38         if alternative == None:
39                 print 'LAST RESORT.  String is "'+source+'"\n'
40                 return StringIO.StringIO(str(source))
41         else:
42                 print 'LAST RESORT.  String is "'+alternative+'"\n'
43                 return StringIO.StringIO(str(alternative))
44
45
46 def load_xml(source, alternative=None):
47         """load XML input source, return parsed XML document
48
49         - a URL of a remote XML file ("http://diveintopython.org/kant.xml")
50         - a filename of a local XML file ("~/diveintopython/common/py/kant.xml")
51         - standard input ("-")
52         - the actual XML document, as a string
53         """
54         sock = open_anything(source, alternative)
55         try:
56                 xmldoc = minidom.parse(sock).documentElement
57         except (IOError, OSError):
58                 print "ERROR with data"
59                 sock.close()
60                 sock = open_anything('<response method="getProjects"><project projName="ERROR!"/></response>')
61                 xmldoc = minidom.parse(sock).documentElement
62         sock.close()
63         return xmldoc
64
65
66 def to_fuzzy_date(targetDate, todaysDate = datetime.datetime.today()):
67         """
68         Conert a date/time/datetime object to a fuzzy date
69
70         @bug Not perfect, but good enough for now
71         """
72         delta = targetDate - todaysDate
73         days = abs(delta.days)
74         directionBy1 = "Next" if 0 < delta.days else "Last"
75         directionByN = "Later" if 0 < delta.days else "Earlier"
76         directionByInf = "from now" if 0 < delta.days else "ago"
77         if 2*365 < days:
78                 return "Forever %s" % directionByInf
79         elif 365 < days:
80                 return "%s year" % directionBy1
81         elif 2*30 < days:
82                 return "%s this year" % directionByN
83         elif 30 < days:
84                 return "%s month" % directionBy1
85         elif 14 < days:
86                 return "%s this month" % directionByN
87         elif 7 < days:
88                 return "%s week" % directionBy1
89         elif 2 < days:
90                 return "%s this week" % directionByN
91         elif 1 < days:
92                 return "%s day" % directionByN
93         else:
94                 return "Today"