Merge lp:~stefanor/ibid/exchange-343775 into lp:~ibid-core/ibid/old-trunk-pack-0.92

Proposed by Stefano Rivera
Status: Merged
Approved by: Jonathan Hitchcock
Approved revision: 592
Merged at revision: 586
Proposed branch: lp:~stefanor/ibid/exchange-343775
Merge into: lp:~ibid-core/ibid/old-trunk-pack-0.92
Diff against target: None lines
To merge this branch: bzr merge lp:~stefanor/ibid/exchange-343775
Reviewer Review Type Date Requested Status
Jonathan Hitchcock Approve
Michael Gorven Approve
Review via email: mp+4576@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Stefano Rivera (stefanor) wrote :

Vhata, you'd better be appreciative :P

Query: exchange 20 .za for .gb
Response: 20.00 ZAR = 1.43166 GBP
Query: exchange 20 south africas for dollar
Response: 20.00 ZAR = 2.01424 USD
Query: exchange 100 zimbabwe for rand
Response: 100.00 ZWD = 6.92097 ZAR

lp:~stefanor/ibid/exchange-343775 updated
588. By Stefano Rivera

Include country and currency it exchange output

Revision history for this message
Michael Gorven (mgorven) wrote :
Download full text (6.7 KiB)

Stefano Rivera proposed lp:~stefanor/ibid/exchange-343775 for merging into lp:ibid

Vhata, you'd better be appreciative :P

Query: exchange 20 .za for .gb
Response: 20.00 ZAR = 1.43166 GBP
Query: exchange 20 south africas for dollar
Response: 20.00 ZAR = 2.01424 USD
Query: exchange 100 zimbabwe for rand
Response: 100.00 ZWD = 6.92097 ZAR

=== modified file 'ibid/plugins/lookup.py'
--- a/ibid/plugins/lookup.py 2009-03-11 11:49:44 +0000
+++ b/ibid/plugins/lookup.py 2009-03-18 08:24:57 +0000
@@ -9,10 +9,31 @@

 from ibid.plugins import Processor, match, handler
 from ibid.config import Option
-from ibid.utils import ago, decode_htmlentities, get_html_parse_tree
+from ibid.utils import ago, decode_htmlentities, get_html_parse_tree, cacheable_download

 help = {}

+def get_country_codes():
+ # The XML download doesn't include things like UK, so we consume this steaming pile of crud instead
+ filename = cacheable_download('http://www.iso.org/iso/country_codes/iso_3166_code_lists/iso-3166-1_decoding_table.htm', 'lookup/iso-3166-1_decoding_table.htm')
+ etree = get_html_parse_tree('file://' + filename, treetype='etree')
+ table = [x for x in etree.getiterator('table')][2]
+
+ countries = {}
+ for tr in table.getiterator('tr'):
+ abbr = [x.text for x in tr.getiterator('div')][0]
+ eng_name = [x.text for x in tr.getchildren()][1]
+
+ if eng_name and eng_name.strip():
+ # Cleanup:
+ if u',' in eng_name:
+ eng_name = u' '.join(reversed(eng_name.split(',', 1)))
+ eng_name = u' '.join(eng_name.split())
+
+ countries[abbr.upper()] = eng_name.title()
+
+ return countries
+
 help['bash'] = u'Retrieve quotes from bash.org.'
 class Bash(Processor):
     u"bash[.org] (random|<number>)"
@@ -179,6 +200,7 @@

     headers = {'User-Agent': 'Mozilla/5.0', 'Referer': 'http://www.xe.com/'}
     currencies = {}
+ country_codes = {}

     def _load_currencies(self):
         etree = get_html_parse_tree('http://www.xe.com/iso4217.php', headers=self.headers, treetype='etree')
@@ -197,22 +219,72 @@
                         place, name = place.split(',', 1)
                     self.currencies[code] = (place.strip(), name.strip())

- @match(r'^(exchange|convert)\s+([0-9.]+)\s+(\S+)\s+(?:for|to|into)\s+(\S+)$')
+ def _resolve_currency(self, name):
+ "Return the canonical name for a currency"
+
+ name = name.lower()
+
+ # .TLD
+ if name.startswith(u".") and len(name) == 3:
+ name = name[1:]
+
+ # Make singular
+ if name.endswith(u's') and len(name) > 3:
+ name = name[:-1]
+
+ # TLD
+ if len(name) == 2:
+ if name.upper() in self.country_codes:
+ name = self.country_codes[name.upper()].lower()
+
+ # Currency Name
+ if name == u'dollar':
+ name = 'usd'
+ if name.upper() not in self.currencies:
+ for code, (place, currency) in self.currencies.iteritems():
+ if name in currency.lower():
+ name = code
+ break
+
+ # Country Name
+ if name.upper...

Read more...

Revision history for this message
Michael Gorven (mgorven) wrote :

The 'tld for' regex doesn't allow arbitrary whitespace, but otherwise looks good.

review: Approve
lp:~stefanor/ibid/exchange-343775 updated
589. By Stefano Rivera

Refactor _resolve_currency

590. By Stefano Rivera

Match the canonical country, and search all countries that represent each currency

591. By Stefano Rivera

Whitespace around TLD queries

Revision history for this message
Jonathan Hitchcock (vhata) wrote :

Solid.

review: Approve
lp:~stefanor/ibid/exchange-343775 updated
592. By Stefano Rivera

Whoops, overdid the last commit

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ibid/plugins/lookup.py'
2--- ibid/plugins/lookup.py 2009-03-11 11:49:44 +0000
3+++ ibid/plugins/lookup.py 2009-03-17 10:07:39 +0000
4@@ -9,10 +9,31 @@
5
6 from ibid.plugins import Processor, match, handler
7 from ibid.config import Option
8-from ibid.utils import ago, decode_htmlentities, get_html_parse_tree
9+from ibid.utils import ago, decode_htmlentities, get_html_parse_tree, cacheable_download
10
11 help = {}
12
13+def get_country_codes():
14+ # The XML download doesn't include things like UK, so we consume this steaming pile of crud instead
15+ filename = cacheable_download('http://www.iso.org/iso/country_codes/iso_3166_code_lists/iso-3166-1_decoding_table.htm', 'lookup/iso-3166-1_decoding_table.htm')
16+ etree = get_html_parse_tree('file://' + filename, treetype='etree')
17+ table = [x for x in etree.getiterator('table')][2]
18+
19+ countries = {}
20+ for tr in table.getiterator('tr'):
21+ abbr = [x.text for x in tr.getiterator('div')][0]
22+ eng_name = [x.text for x in tr.getchildren()][1]
23+
24+ if eng_name and eng_name.strip():
25+ # Cleanup:
26+ if u',' in eng_name:
27+ eng_name = u' '.join(reversed(eng_name.split(',', 1)))
28+ eng_name = u' '.join(eng_name.split())
29+
30+ countries[abbr.upper()] = eng_name.title()
31+
32+ return countries
33+
34 help['bash'] = u'Retrieve quotes from bash.org.'
35 class Bash(Processor):
36 u"bash[.org] (random|<number>)"
37@@ -179,6 +200,7 @@
38
39 headers = {'User-Agent': 'Mozilla/5.0', 'Referer': 'http://www.xe.com/'}
40 currencies = {}
41+ country_codes = {}
42
43 def _load_currencies(self):
44 etree = get_html_parse_tree('http://www.xe.com/iso4217.php', headers=self.headers, treetype='etree')
45@@ -197,17 +219,60 @@
46 place, name = place.split(',', 1)
47 self.currencies[code] = (place.strip(), name.strip())
48
49- @match(r'^(exchange|convert)\s+([0-9.]+)\s+(\S+)\s+(?:for|to|into)\s+(\S+)$')
50+ def _resolve_currency(self, name):
51+ "Return the canonical name for a currency"
52+
53+ name = name.lower()
54+
55+ # .TLD
56+ if name.startswith(u".") and len(name) == 3:
57+ name = name[1:]
58+
59+ # Make singular
60+ if name.endswith(u's') and len(name) > 3:
61+ name = name[:-1]
62+
63+ # TLD
64+ if len(name) == 2:
65+ if name.upper() in self.country_codes:
66+ name = self.country_codes[name.upper()].lower()
67+
68+ # Currency Name
69+ if name == u'dollar':
70+ name = 'usd'
71+ if name.upper() not in self.currencies:
72+ for code, (place, currency) in self.currencies.iteritems():
73+ if name in currency.lower():
74+ name = code
75+ break
76+
77+ # Country Name
78+ if name.upper() not in self.currencies:
79+ for code, (place, currency) in self.currencies.iteritems():
80+ if name in place.lower():
81+ name = code
82+ break
83+
84+ if name.upper() in self.currencies:
85+ return name.upper()
86+ return False
87+
88+ @match(r'^(exchange|convert)\s+([0-9.]+)\s+(.+)\s+(?:for|to|into)\s+(.+)$')
89 def exchange(self, event, command, amount, frm, to):
90 if not self.currencies:
91 self._load_currencies()
92
93- if frm not in self.currencies or to not in self.currencies:
94+ if not self.country_codes:
95+ self.country_codes = get_country_codes()
96+
97+ canonical_frm = self._resolve_currency(frm)
98+ canonical_to = self._resolve_currency(to)
99+ if not canonical_frm or not canonical_to:
100 if command.lower() == "exchange":
101- event.addresponse(u"Sorry, I don't know about a currency called %s", (frm not in self.currencies and frm or to))
102+ event.addresponse(u"Sorry, I don't know about a currency for %s", (not canonical_frm and frm or to))
103 return
104
105- data = {'Amount': amount, 'From': frm, 'To': to}
106+ data = {'Amount': amount, 'From': canonical_frm, 'To': canonical_to}
107 etree = get_html_parse_tree('http://www.xe.com/ucc/convert.cgi', urlencode(data), self.headers, 'etree')
108
109 result = u" ".join(tag.text for tag in etree.getiterator('h2'))
110@@ -232,6 +297,44 @@
111 else:
112 event.addresponse(u'No currencies found')
113
114+help['tld'] = u"Resolve country TLDs (ISO 3166)"
115+class TLD(Processor):
116+ u""".<tld>
117+ tld for <country>"""
118+ feature = 'tld'
119+
120+ country_codes = {}
121+
122+ @match(r'^\.([a-zA-Z]{2})$')
123+ def tld_to_country(self, event, tld):
124+ if not self.country_codes:
125+ self.country_codes = get_country_codes()
126+
127+ tld = tld.upper()
128+
129+ if tld in self.country_codes:
130+ event.addresponse(u'%(tld)s is the TLD for %(country)s', {
131+ 'tld': tld,
132+ 'country': self.country_codes[tld],
133+ })
134+ else:
135+ event.addresponse(u"ISO doesn't know about any such TLD")
136+
137+ @match(r'^tld for (.+)$')
138+ def country_to_tld(self, event, location):
139+ if not self.country_codes:
140+ self.country_codes = get_country_codes()
141+
142+ for tld, country in self.country_codes.iteritems():
143+ if location.lower() in country.lower():
144+ event.addresponse(u'%(tld)s is the TLD for %(country)s', {
145+ 'tld': tld,
146+ 'country': country,
147+ })
148+ return
149+
150+ event.addresponse(u"ISO doesn't know about any TLD for %s", location)
151+
152 help['weather'] = u'Retrieves current weather and forecasts for cities.'
153 class Weather(Processor):
154 u"""weather in <city>

Subscribers

People subscribed via source and target branches