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 is_same_year(targetDate, todaysDate = datetime.datetime.today()):
138 return targetDate.year == todaysDate.year
141 def is_same_month(targetDate, todaysDate = datetime.datetime.today()):
142 return targetDate.month == todaysDate.month
145 def is_same_day(targetDate, todaysDate = datetime.datetime.today()):
146 return targetDate.day == todaysDate.day
149 def to_fuzzy_date(targetDate, todaysDate = datetime.datetime.today()):
151 Conert a date/time/datetime object to a fuzzy date
153 delta = targetDate - todaysDate
154 days = abs(delta.days)
155 noDifference = datetime.timedelta()
156 isFuture = noDifference < delta
157 directionBy1 = "Next" if isFuture else "Last"
158 directionByN = "Later" if isFuture else "Earlier"
160 yearDelta = abs(targetDate.year - todaysDate.year)
162 directionByInf = "from now" if isFuture else "ago"
163 return "Forever %s" % directionByInf
165 return "%s year" % directionBy1
167 monthDelta = abs(targetDate.month - todaysDate.month)
169 return "%s this year" % directionByN
171 return "%s month" % directionBy1
173 dayDelta = abs(targetDate.day - todaysDate.day)
175 return "%s this month" % directionByN
177 directionInWeek = "This" if isFuture else "Last"
178 days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
179 return "%s %s" % (directionInWeek, days[targetDate.weekday()])
181 return "%s day" % directionBy1