changeset 1:10fc4904c10f

now can pass data
author k0s <k0scist@gmail.com>
date Sat, 21 Nov 2009 17:29:39 -0500
parents d6fa501af82f
children f084e152dd47
files setup.py smartopen.ini smartopen/handlers.py smartopen/smartopen.py
diffstat 4 files changed, 143 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,12 @@
 from setuptools import setup, find_packages
 import sys, os
 
-version = '0.0'
+version = '0.1'
 
 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='',
@@ -21,10 +21,14 @@ setup(name='smartopen',
           # -*- Extra requirements: -*-
       ],
       entry_points="""
       # -*- Entry points: -*-
       [console_scripts]
       smartopen = smartopen.smartopen:main
 
       [smartopen.locations]
+      URL = smartopen.handlers:URL
+      GoogleMaps = smartopen.handlers:GoogleMaps
+      Wikipedia = smartopen.handlers:Wikipedia
+      Google = smartopen.handlers:Google
       """,
       )
new file mode 100644
--- /dev/null
+++ b/smartopen.ini
@@ -0,0 +1,5 @@
+[DEFAULTS]
+handlers = GoogleMaps, Wikipedia, Google
+
+[Trac]
+url = http://trac.openplans.org/trac
\ No newline at end of file
--- a/smartopen/handlers.py
+++ b/smartopen/handlers.py
@@ -14,22 +14,16 @@ class Location:
         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
@@ -41,63 +35,67 @@ class URL(Location):
             return False
 
         try:
             site = urllib.urlopen(self.process(query))
         except IOError:
             return False
         return True
 
-class GoogleMap(Location):
+class GoogleMaps(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 Trac(Location):
+    def __init__(self, url):
+        self.url = url
         
 
-class TracTicket(Location):
-    def __init__(self):
-        # url for # data
-        number_url = 'http://trac.openplans.org/openplans/ticket/'
-        Location.__init__(self, number_url)
+# TODO: need configuration
+# class Revision(Location):
+#     def __init__(self):
+#         revision_url = 'http://trac.openplans.org/openplans/changeset/'
+#         Location.__init__(self, revision_url)
 
-    def process(self, query):
-        if query.startswith('#'):
-            return query[1:]        
-        return query
+#     def process(self, query):
+#         return query[1:]
 
-    def test(self, query):
-        query = self.process(query)
-        if len(query.split()) != 1:
-            return False
-        return query.isdigit()
+#     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):
--- a/smartopen/smartopen.py
+++ b/smartopen/smartopen.py
@@ -1,57 +1,135 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 """ smart open the data passed in """
 
 import os
 import sys
-import urllib
-import urllib2
 
 from optparse import OptionParser
+from pkg_resources import iter_entry_points
+from ConfigParser import ConfigParser
 
-from handlers import *
+def locations(names=None, config=None):
+    """
+    list of 2-tuples of location handlers;
+    * names: order names of handlers
+    * config: nested dictionary of configuration from names
+    """
+
+    _handlers = {}
+    _names = []
+    if config is None:
+        config = {}
+    
+    for i in iter_entry_points('smartopen.locations'):
+        try:
+            handler = i.load()
+        except:
+            pass
+        _handlers[i.name] = handler
+        if not names:
+            _names.append(i.name)
+
+    if not names:
+        names = _names
+    handlers = []
+    for name in names:
+        if ':' in name:
+            _name, section = name.split(':', 1)
+        else:
+            _name = name
+        if _name in _handlers:
+            try:
+                handler = _handlers[_name](**config.get(name, {}))
+            except:
+                continue
+            handlers.append((name, handler))
+    return handlers
+
+def urls(query, handlers=None):
+    if handlers is None:
+        handlers = locations()
+    urls = []
+    for name, handler in handlers:
+        if handler.test(query):
+            urls.append((name, handler.url(query)))
+    return urls
+
+def url(query, handlers=None):
+    if handlers is None:
+        handlers = locations()
+    for name, handler in handlers:
+        if handler.test(query):
+            return handler.url(query)
 
 def main(args=sys.argv[1:]):
 
     # parse command line optioins
     parser = OptionParser()
+    parser.add_option('-c', '--config', dest="config",
+                      help="config file to read")
     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")
+    parser.add_option('-H', '--handler', dest="handlers",
+                      action='append',
+                      help="name of the handler to use, in order")
+    parser.add_option('--print-handlers', dest="print_handlers",
+                      action='store_true',
+                      help="print all handlers in order they would be tried")
     options, args = parser.parse_args(args)
 
     # sanity check
     assert not (options.url and options.all)
+    if not options.handlers:
+        options.handlers = None
+
+    # config
+    config = ConfigParser()
+    if options.config and os.path.exists(options.config):
+        config.read(options.config)
+        if not options.handlers and config.has_option('DEFAULTS', 'handlers'):
+            options.handlers = [ i.strip() for i in config.get('DEFAULTS', 'handlers').split(',') ]
+    _config = {}
+    for section in config.sections():
+        _config[section] = dict(config.items(section))
+
+    # get the handlers
+    _locations = locations(options.handlers, _config)
+
+    # print the handlers
+    if options.print_handlers:
+        for name, loc in _locations:
+            print name
+        sys.exit(0)
 
     # get data to be operated on
     if args:
         data = ' '.join(args)
     else:
         data = sys.stdin.read()
 
-    locations = [ URL, 
-                  GoogleMap,
-                  Revision,
-                  TracTicket,
-                  Wikipedia,
-                  Google
-                  ]
+    # print the URLs
+    if options.all:
+        _urls = urls(data, _locations)
+        for name, _url in _urls:
+            print '%s: %s' % (name, _url)
+        sys.exit(0)
 
-    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)
+    _url = url(data, _locations)
+
+    # print a URL
+    if options.url:
+        print _url
+        sys.exit(0)
+
+    # open the URL in a browser
+    os.system("firefox '%s'" % _url)
+    sys.exit(0)
+
 
 if __name__ == '__main__':
     main()