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 @bug Not perfect, but good enough for now
143 delta = targetDate - todaysDate
144 days = abs(delta.days)
145 noDifference = datetime.timedelta()
146 isFuture = noDifference < delta
147 directionBy1 = "Next" if isFuture else "Last"
148 directionByN = "Later" if isFuture else "Earlier"
150 yearDelta = abs(targetDate.year - todaysDate.year)
152 directionByInf = "from now" if isFuture else "ago"
153 return "Forever %s" % directionByInf
155 return "%s year" % directionBy1
157 monthDelta = abs(targetDate.month - todaysDate.month)
159 return "%s this year" % directionByN
161 return "%s month" % directionBy1
163 dayDelta = abs(targetDate.day - todaysDate.day)
165 return "%s this month" % directionByN
167 directionInWeek = "This" if isFuture else "Last"
168 days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
169 return "%s %s" % (directionInWeek, days[targetDate.weekday()])
171 return "%s day" % directionBy1