4 from xml.dom import minidom
8 class Optional(object):
11 Even you don't have to worry about knowing when to perform None checks
12 When the NULL object pattern just isn't good enough
17 >>> a.get_nothrow("Blacksheep")
22 >>> a.get_nothrow("Blacksheep"), a.get(), a()
23 ('Lamb', 'Lamb', 'Lamb')
27 >>> a.get_nothrow("Blacksheep")
30 >>> b = Optional("Lamb")
34 >>> a.get_nothrow("Blacksheep"), a.get(), a()
35 ('Lamb', 'Lamb', 'Lamb')
39 >>> a.get_nothrow("Blacksheep")
43 class NonExistent(object):
46 def __init__(self, value = NonExistent):
53 self._value = self.NonExistent
56 return self._value is not self.NonExistent
58 def get_nothrow(self, default = None):
59 return self._value if self.is_good() else default
62 if not self.is_good():
63 raise ReferenceError("Optional not initialized")
67 # Implemented to imitate weakref
71 return str(self.get_nothrow(""))
74 return "<Optional at %x; to %r>" % (
75 id(self), self.get_nothrow("Nothing")
79 def open_anything(source, alternative=None):
80 """URI, filename, or string --> stream
82 This function lets you define parsers that take any input source
83 (URL, pathname to local or network file, or actual data as a string)
84 and deal with it in a uniform manner. Returned object is guaranteed
85 to have all the basic stdio read methods (read, readline, readlines).
86 Just .close() the object when you're done with it.
88 if hasattr(source, "read"):
94 # try to open with urllib (if source is http, ftp, or file URL)
96 return urllib.urlopen(source)
97 except (IOError, OSError):
99 print "ERROR with URL ("+source+")!\n"
101 # try to open with native open function (if source is pathname)
104 except (IOError, OSError):
106 print "ERROR with file!\n"
108 # treat source as string
109 if alternative == None:
110 print 'LAST RESORT. String is "'+source+'"\n'
111 return StringIO.StringIO(str(source))
113 print 'LAST RESORT. String is "'+alternative+'"\n'
114 return StringIO.StringIO(str(alternative))
117 def load_xml(source, alternative=None):
118 """load XML input source, return parsed XML document
120 - a URL of a remote XML file ("http://diveintopython.org/kant.xml")
121 - a filename of a local XML file ("~/diveintopython/common/py/kant.xml")
122 - standard input ("-")
123 - the actual XML document, as a string
125 sock = open_anything(source, alternative)
127 xmldoc = minidom.parse(sock).documentElement
128 except (IOError, OSError):
129 print "ERROR with data"
131 sock = open_anything('<response method="getProjects"><project projName="ERROR!"/></response>')
132 xmldoc = minidom.parse(sock).documentElement
137 def to_fuzzy_date(targetDate, todaysDate = datetime.datetime.today()):
139 Conert a date/time/datetime object to a fuzzy date
141 delta = targetDate - todaysDate
142 days = abs(delta.days)
143 noDifference = datetime.timedelta()
144 isFuture = noDifference < delta
145 directionBy1 = "Next" if isFuture else "Last"
146 directionByN = "Later" if isFuture else "Earlier"
148 yearDelta = abs(targetDate.year - todaysDate.year)
150 directionByInf = "from now" if isFuture else "ago"
151 return "Forever %s" % directionByInf
153 return "%s year" % directionBy1
155 monthDelta = abs(targetDate.month - todaysDate.month)
157 return "%s this year" % directionByN
159 return "%s month" % directionBy1
161 dayDelta = abs(targetDate.day - todaysDate.day)
163 return "%s this month" % directionByN
165 directionInWeek = "This" if isFuture else "Last"
166 days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
167 return "%s %s" % (directionInWeek, days[targetDate.weekday()])
169 return "%s day" % directionBy1