Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d2c210d

Browse files
committed
Added reverse lookup
1 parent 664b36f commit d2c210d

1 file changed

Lines changed: 94 additions & 33 deletions

File tree

Tools/world/world

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#! /usr/bin/env python
22

3-
"""Print the long name of an Internet domain.
3+
"""Print mappings between country names and DNS country codes.
44
55
This script will take an Internet address and print out where in the
66
world that message originated from, based on the top-level domain code
@@ -10,8 +10,22 @@ found in the address. Addresses can be in any of the following forms:
1010
host.domain.xx -- any Internet host or network name
1111
[email protected] -- an Internet email address
1212
13+
If the country code is not recognizable, it will attempt a reverse lookup,
14+
searching for the country name and printing a list of matching country codes.
15+
You can force reverse mappings with the `-r' flag (see below).
16+
17+
For example:
18+
19+
% world tz us
20+
tz originated from Tanzania, United Republic of
21+
us originated from United States
22+
23+
% world united
24+
25+
1326
Country codes are maintained by the RIPE Network Coordination Centre,
14-
in coordination with the ISO 3166 Maintenance Agency at DIN Berlin.
27+
in coordination with the ISO 3166 Maintenance Agency at DIN Berlin. The
28+
authoritative source of counry code mappings is:
1529
1630
<url:ftp://info.ripe.net/iso3166-countrycodes>
1731
@@ -28,29 +42,46 @@ Usage: %s [-d] [-p|-P file] [-h] addr [addr ...]
2842
Print mapping of all top-level domains.
2943
3044
--parse file
31-
--p file
32-
--P file
33-
--Parse file
34-
Parse an iso3166-countrycodes file (given as the argument).
35-
This first the two letter country code (it ignores the three
36-
letter code), followed by the country name. With -P option,
37-
output is in the form of a Python dictionary, and country
38-
names are normalized w.r.t. capitalization. This makes it
39-
appropriate for cutting and pasting back into this file.
45+
-p file
46+
Parse an iso3166-countrycodes file extracting the two letter country
47+
code followed by the country name. Note that the three leter country
48+
code and number, which are also provided in the standard format file,
49+
are ignored.
50+
51+
--outputdict
52+
-o
53+
With used in conjunction with the `-p' option, output is in the form
54+
of a Python dictionary, and country names are normalized
55+
w.r.t. capitalization. This makes it appropriate for cutting and
56+
pasting back into this file.
57+
58+
--reverse
59+
-r
60+
Force reverse lookup. In this mode the address can be any Python
61+
regular expression; this is matched against all country names and a
62+
list of matching mappings is printed. In normal mode (e.g. without
63+
this flag), reverse lookup is performed on addresses if no matching
64+
country code is found.
4065
4166
-h
4267
--help
4368
Print this message.
4469
4570
"""
46-
__version__ = '2.0'
71+
__version__ = '3.0'
4772
__author__ = 'Barry Warsaw <[email protected]>'
4873
__source__ = '<url:http://www.python.org/~bwarsaw/pyware/>'
4974

5075

5176
import sys
5277
import string
5378
import getopt
79+
try:
80+
import re
81+
except ImportError:
82+
print sys.argv[0], 'requires Python 1.5'
83+
sys.exit(1)
84+
5485

5586

5687

@@ -59,28 +90,48 @@ def usage(status=0):
5990
sys.exit(status)
6091

6192

93+
6294
def resolve(rawaddr):
6395
parts = string.splitfields(rawaddr, '.')
6496
if not len(parts):
65-
print 'No top-level domain in:', rawaddr
66-
return
97+
# no top level domain found, bounce it to the next step
98+
return rawaddr
6799
addr = parts[-1]
68-
if nameorg.has_key(addr):
69-
print rawaddr, 'is from a', nameorg[addr], 'organization'
70-
elif country.has_key(addr):
71-
print rawaddr, 'originated from', country[addr]
100+
if nameorgs.has_key(addr):
101+
print rawaddr, 'is from a', nameorgs[addr], 'organization'
102+
return None
103+
elif countries.has_key(addr):
104+
print rawaddr, 'originated from', countries[addr]
105+
return None
72106
else:
73-
print 'Where in the world is %s?' % rawaddr
107+
# Not resolved, bounce it to the next step
108+
return rawaddr
74109

75110

76111

77-
def parse(file, normalize):
78-
try:
79-
import re
80-
except ImportError:
81-
print 'Parsing requires Python 1.5'
82-
sys.exit(1)
112+
def reverse(regexp):
113+
matches = []
114+
cre = re.compile(regexp, re.IGNORECASE)
115+
for code, country in all.items():
116+
mo = cre.search(country)
117+
if mo:
118+
matches.append(code)
119+
# print results
120+
if not matches:
121+
# not resolved, bounce it to the next step
122+
return regexp
123+
if len(matches) == 1:
124+
code = matches[0]
125+
print regexp, "matches code `%s', %s" % (code, all[code])
126+
else:
127+
print regexp, 'matches %d countries:' % len(matches)
128+
for code in matches:
129+
print " %s: %s" % (code, all[code])
130+
return None
83131

132+
133+
134+
def parse(file, normalize):
84135
try:
85136
fp = open(file)
86137
except IOError, (err, msg):
@@ -149,20 +200,23 @@ def main():
149200
dump = 0
150201
parsefile = None
151202
normalize = 0
203+
forcerev = 0
152204

153-
opts, args = getopt.getopt(sys.argv[1:],
154-
'p:P:hd',
155-
['parse', 'Parse', 'PARSE', 'help', 'dump'])
205+
opts, args = getopt.getopt(
206+
sys.argv[1:],
207+
'p:rohd',
208+
['parse', 'reverse', 'outputdict', 'help', 'dump'])
156209
for arg, val in opts:
157210
if arg in ('-h', '--help'):
158211
help = 1
159212
elif arg in ('-d', '--dump'):
160213
dump = 1
161214
elif arg in ('-p', '--parse'):
162215
parsefile = val
163-
elif arg in ('-P', '--Parse', '--PARSE'):
164-
parsefile = val
216+
elif arg in ('-o', '--output'):
165217
normalize = 1
218+
elif arg in ('-r', '--reverse'):
219+
forcerev = 1
166220

167221
if help:
168222
usage(status)
@@ -182,12 +236,16 @@ def main():
182236
elif parsefile:
183237
parse(parsefile, normalize)
184238
else:
185-
map(resolve, args)
239+
if not forcerev:
240+
args = filter(None, map(resolve, args))
241+
args = filter(None, map(reverse, args))
242+
for arg in args:
243+
print 'Where in the world is %s?' % arg
186244

187245

188246

189247
# The mappings
190-
nameorg = {
248+
nameorgs = {
191249
"arpa": "Arpanet",
192250
"com": "commercial",
193251
"edu": "educational",
@@ -200,7 +258,7 @@ nameorg = {
200258

201259

202260

203-
country = {
261+
countries = {
204262
"af": "Afghanistan",
205263
"al": "Albania",
206264
"dz": "Algeria",
@@ -442,6 +500,9 @@ country = {
442500
"zw": "Zimbabwe",
443501
}
444502

503+
all = nameorgs.copy()
504+
all.update(countries)
505+
445506

446507
if __name__ == '__main__':
447508
main()

0 commit comments

Comments
 (0)