changeset 0:d6fa501af82f

initial commit of smartopen
author k0s <k0scist@gmail.com>
date Sat, 21 Nov 2009 15:46:01 -0500
parents
children 10fc4904c10f
files setup.py smartopen/__init__.py smartopen/address.py smartopen/handlers.py smartopen/smartopen.py smartopen/states.py
diffstat 6 files changed, 361 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.py	Sat Nov 21 15:46:01 2009 -0500
@@ -0,0 +1,30 @@
+from setuptools import setup, find_packages
+import sys, os
+
+version = '0.0'
+
+setup(name='smartopen',
+      version=version,
+      description="open text in a browser contextually",
+      long_description="""\
+""",
+      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
+      keywords='',
+      author='Jeff Hammel',
+      author_email='k0scist@gmail.com',
+      url='http://k0s.org',
+      license='GPL',
+      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          # -*- Extra requirements: -*-
+      ],
+      entry_points="""
+      # -*- Entry points: -*-
+      [console_scripts]
+      smartopen = smartopen.smartopen:main
+
+      [smartopen.locations]
+      """,
+      )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smartopen/__init__.py	Sat Nov 21 15:46:01 2009 -0500
@@ -0,0 +1,1 @@
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smartopen/address.py	Sat Nov 21 15:46:01 2009 -0500
@@ -0,0 +1,69 @@
+#!/usr/bin/python
+
+import sys
+from states import *
+
+def validate_zipcode(zip, zip4=None):
+    """ validate a zipcode"""
+    
+    if not zip:
+        # a non-existant zip-code is a valid zipcode
+        # ... i think....
+        return True 
+
+    if '-' in zip: # in this case, split zip into zip5 + zip4
+        zip, zip4 = zip.split('-')
+
+    zdict = { 'zip5': zip, 'zip4': zip4 }
+        
+    # if the 4-digit extension exists, add it to zip
+    if zip4:
+        zip += '-' + zip4
+
+    # validate zip code format
+    for i in 5, 4:
+        zstring = 'zip' + str(i)
+        z = zdict.get(zstring, '')
+        if z:
+            if (not z.isdigit()) or (len(z) != i):
+                return False
+
+    return zip
+
+def normalizeaddress(query):
+    """ returns normalize address, if it is an address """
+
+    # normalize the address
+    query = ','.join([i.strip() for i in query.split('\n')])
+    querylist = [i.strip() for i in query.split(',')]
+    
+    lastentry = querylist[-1]
+    
+    if lastentry[-1].isdigit():
+        # it must be a zip code
+        if lastentry[1].isalpha():
+            querylist = querylist[:-1] + lastentry.split()
+        if not validate_zipcode(querylist[-1]):
+            return False
+        state = querylist[-2]
+    else:
+        state = querylist[-1]
+
+    if not getstate(state):
+        return False
+
+    return ', '.join(querylist)
+
+def address(query):
+    """ 
+    format an address 
+    -- query should be a string
+    """
+    
+if __name__ == '__main__':
+    i = normalizeaddress(' '.join(sys.argv[1:]))
+    if i:
+        print i
+    else:
+        print 'Not an address'
+        sys.exit(1)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smartopen/handlers.py	Sat Nov 21 15:46:01 2009 -0500
@@ -0,0 +1,129 @@
+import address
+import urllib
+import urllib2
+
+class Location:
+    """
+    generic class for locations
+    """
+
+    def __init__(self, baseurl=""):
+        self.baseurl = baseurl
+
+    def url(self, query):
+        return self.baseurl + self.process(query)
+
+    def process(self, query):
+        return query
+
+    def test(self, query):
+        return True
+
+    def open(self, query):
+        if not self.test(query):
+            return False
+        url = self.url(query)
+        os.system("firefox '%s'" % url)
+        return True
+
+class URL(Location):
+    """a straight URL"""
+
+    def process(self, query):
+        if '://' in query:
+            return query
+        return 'http://' + query
+
+    def test(self, query):
+        """try to open the url"""
+
+        if ' ' in query or '\n' in query:
+            return False
+
+        try:
+            site = urllib.urlopen(self.process(query))
+        except IOError:
+            return False
+        return True
+
+class GoogleMap(Location):
+    """try to google-maps the address"""
+
+    def __init__(self):
+        gmapsurl='http://maps.google.com/maps?f=q&hl=en&q='
+        Location.__init__(self, gmapsurl)
+
+    def process(self, query):
+        theaddress = address.normalizeaddress(query)
+        if not theaddress:
+            return theaddress
+        return urllib.quote_plus(theaddress)
+
+    def test(self, query):
+        return bool(self.process(query))
+
+class Revision(Location):
+    def __init__(self):
+        revision_url = 'http://trac.openplans.org/openplans/changeset/'
+        Location.__init__(self, revision_url)
+
+    def process(self, query):
+        return query[1:]
+
+    def test(self, query):
+        if query[0] != 'r':
+            return False
+        return query[1:].isdigit()
+            
+        
+
+class TracTicket(Location):
+    def __init__(self):
+        # url for # data
+        number_url = 'http://trac.openplans.org/openplans/ticket/'
+        Location.__init__(self, number_url)
+
+    def process(self, query):
+        if query.startswith('#'):
+            return query[1:]        
+        return query
+
+    def test(self, query):
+        query = self.process(query)
+        if len(query.split()) != 1:
+            return False
+        return query.isdigit()
+
+class Wikipedia(Location):
+    """try to open the query in wikipedia"""
+    def __init__(self):        
+        wikiurl = 'http://en.wikipedia.org/wiki/'
+        Location.__init__(self, wikiurl)
+
+    def process(self, query):
+        return urllib.quote_plus('_'.join(query.split()))
+        
+    def test(self, query):
+        'test to see if the article exists'
+
+        # need a phony user agent so wikipedia won't know we're a bot
+        headers = {}
+        headers['User-Agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4'
+
+        request = urllib2.Request(self.url(query), None, headers)
+        try:
+            f = urllib2.urlopen(request).read()
+        except urllib2.HTTPError, e:
+            return False
+
+        if 'Wikipedia does not have an article with this exact name' in f:
+            return False
+        return True
+
+class Google(Location):
+    def __init__(self):        
+        googleurl = 'http://www.google.com/search?hl=en&q='
+        Location.__init__(self, googleurl)
+        
+    def process(self, query):
+        return urllib.quote_plus(query)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smartopen/smartopen.py	Sat Nov 21 15:46:01 2009 -0500
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+""" smart open the data passed in """
+
+import os
+import sys
+import urllib
+import urllib2
+
+from optparse import OptionParser
+
+from handlers import *
+
+def main(args=sys.argv[1:]):
+
+    # parse command line optioins
+    parser = OptionParser()
+    parser.add_option('-u', '--url', dest="url", 
+                      action='store_true', default=False,
+                      help="print the first url handled")
+    parser.add_option('-a', '--all', dest="all", 
+                      action='store_true', default=False,
+                      help="print all handlers that match the query")
+    options, args = parser.parse_args(args)
+
+    # sanity check
+    assert not (options.url and options.all)
+
+    # get data to be operated on
+    if args:
+        data = ' '.join(args)
+    else:
+        data = sys.stdin.read()
+
+    locations = [ URL, 
+                  GoogleMap,
+                  Revision,
+                  TracTicket,
+                  Wikipedia,
+                  Google
+                  ]
+
+    for loc in locations:
+        loc = loc()
+        if options.url: # print url
+            if loc.test(data):
+                print loc.url(data)
+                sys.exit(0)
+        elif options.all: 
+            if loc.test(data):
+                print '%s: %s' % (loc.__class__.__name__, loc.url(data))
+        else:
+            if loc.open(data):
+                sys.exit(0)
+
+if __name__ == '__main__':
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smartopen/states.py	Sat Nov 21 15:46:01 2009 -0500
@@ -0,0 +1,75 @@
+states =  {			
+    "AL": "Alabama",
+    "AK": "Alaska",
+    "AS": "American Samoa",
+    "AZ": "Arizona",
+    "AR": "Arkansas",
+    "AE": "Army P.O. Box",
+    "AP": "Army Post Office",
+    "CA": "California",
+    "CO": "Colorado",
+    "CT": "Connecticut",
+    "DE": "Delaware",
+    "DC": "District of Columbia",
+    "FL": "Florida",
+    "GA": "Georgia",
+    "GU": "Guam",
+    "HI": "Hawaii",
+    "ID": "Idaho",
+    "IL": "Illinois",
+    "IN": "Indiana",
+    "IA": "Iowa",
+    "KS": "Kansas",
+    "KY": "Kentucky",
+    "LA": "Louisiana",
+    "ME": "Maine",
+    "MD": "Maryland",
+    "MA": "Massachusetts",
+    "MI": "Michigan",
+    "MN": "Minnesota",
+    "MS": "Mississippi",
+    "MO": "Missouri",
+    "MT": "Montana",
+    "NE": "Nebraska",
+    "NV": "Nevada",
+    "NH": "New Hampshire",
+    "NJ": "New Jersey",
+    "NM": "New Mexico",
+    "NY": "New York",
+    "NC": "North Carolina",
+    "ND": "North Dakota",
+    "OH": "Ohio",
+    "OK": "Oklahoma",
+    "OR": "Oregon",
+    "OT": "Other",
+    "PA": "Pennsylvania",
+    "PR": "Puerto Rico",
+    "RI": "Rhode Island",
+    "SC": "South Carolina",
+    "SD": "South Dakota",
+    "TN": "Tennessee",
+    "TX": "Texas",
+    "US": "United States",
+    "UT": "Utah",
+    "VT": "Vermont",
+    "VI": "Virgin Islands",
+    "VA": "Virginia",
+    "WA": "Washington",
+    "WV": "West Virginia",
+    "WI": "Wisconsin",
+    "WY": "Wyoming",
+}
+
+def getstate(query):
+    """ 
+    return the state name of the query,
+    or None if its not in the list
+    """
+    
+    if query in states.keys():
+        return states[query]
+
+    if query in states.values():
+        return query
+
+    return None