Lars Yencken avatar Lars Yencken committed 0ea2f47

An initial implementation of doko.

Comments (0)

Files changed (5)

+.DS_Store
+*.pyc
+*.pyo
+*.orig
+*.bak
+*.tmp
+*.egg-info
+build
+dist
+doko (どこ)
+=========
+
+A Python clone of Victor Jalencas's `whereami <https://github.com/victor/whereami>`_ utility, which uses CoreLocation services on OS X to determine your geographical coordinates. It requires OS X 10.6 (Mountain Lion) or later to function.
+
+Kudos to `Rich Healey <https://github.com/richo/>`_ for getting me started.
+
+Installing
+----------
+
+::
+  $ pip install doko
+
+Enabling Core Location
+----------------------
+
+On OS X 10.6 (Mountain Lion) or later, you can enable Core Location in System Preferences, in the "Security" or "Security & Privacy" section.
+
+Using as a module
+-----------------
+
+::
+  > import doko
+  > doko.whereami()
+  Location(latitude=35.674851, longitude=139.701419)
+
+
+Using on the command-line
+-------------------------
+
+::
+  $ doko
+  35.674851, 139.701419
+# -*- coding: utf-8 -*-
+#
+#  whereami.py
+#  whereami
+#
+
+"""
+Use the Core Location framework.
+"""
+
+import sys
+import optparse
+import time
+from collections import namedtuple
+
+import CoreLocation
+
+Location = namedtuple('Location', 'latitude longitude')
+
+DEFAULT_TIMEOUT = 5
+DEFAULT_RETRIES = 10
+
+
+class LocationServiceException(Exception):
+    pass
+
+
+def whereami(timeout=DEFAULT_TIMEOUT):
+    """
+    Fetch and return a Location from OS X Core Location, or throw
+    a LocationServiceException trying.
+    """
+    m = CoreLocation.CLLocationManager.new()
+
+    if not m.locationServicesEnabled():
+        raise LocationServiceException(
+                'location services not enabled -- check privacy settings in System Preferences'  # noqa
+            )
+
+    if not m.locationServicesAvailable():
+        raise LocationServiceException('location services not available')
+
+    m.startUpdatingLocation()
+    CoreLocation.CFRunLoopStop(CoreLocation.CFRunLoopGetCurrent())
+    l = m.location()
+
+    # retry up to ten times, possibly sleeping between tries
+    for i in xrange(DEFAULT_RETRIES):
+        if l:
+            break
+
+        time.sleep(float(timeout) / DEFAULT_RETRIES)
+        CoreLocation.CFRunLoopStop(CoreLocation.CFRunLoopGetCurrent())
+        l = m.location()
+
+    if not l:
+        raise LocationServiceException(
+                'location could not be found -- is wifi enabled?'
+            )
+
+    c = l.coordinate()
+    return Location(c.latitude, c.longitude)
+
+
+def _create_option_parser():
+    usage = \
+"""%prog [options]
+
+Use CoreServices to find your current geolocation as latitude and longitude
+coordinates. Exits with status code 1 on failure."""
+
+    parser = optparse.OptionParser(usage)
+    parser.add_option('--timeout', action='store', dest='timeout',
+            type='float', default=10,
+            help='Time to keep trying for if no location is found.')
+    parser.add_option('--quiet', action='store_true', dest='quiet',
+            help='Suppress any error messages.')
+
+    return parser
+
+
+def main():
+    argv = sys.argv[1:]
+    parser = _create_option_parser()
+    (options, args) = parser.parse_args(argv)
+
+    if args:
+        parser.print_help()
+        sys.exit(1)
+
+    try:
+        l = whereami(options.timeout)
+        print ' '.join(map(str, l))
+    except LocationServiceException, e:
+        if not options.quiet:
+            print >> sys.stderr, e.message
+        sys.exit(1)
+pyobjc==2.4
+pyobjc-core==2.4
+pyobjc-framework-Accounts==2.4
+pyobjc-framework-AddressBook==2.4
+pyobjc-framework-AppleScriptKit==2.4
+pyobjc-framework-AppleScriptObjC==2.4
+pyobjc-framework-Automator==2.4
+pyobjc-framework-CFNetwork==2.4
+pyobjc-framework-CalendarStore==2.4
+pyobjc-framework-Cocoa==2.4
+pyobjc-framework-Collaboration==2.4
+pyobjc-framework-CoreData==2.4
+pyobjc-framework-CoreLocation==2.4
+pyobjc-framework-CoreText==2.4
+pyobjc-framework-DictionaryServices==2.4
+pyobjc-framework-EventKit==2.4
+pyobjc-framework-ExceptionHandling==2.4
+pyobjc-framework-FSEvents==2.4
+pyobjc-framework-InputMethodKit==2.4
+pyobjc-framework-InstallerPlugins==2.4
+pyobjc-framework-InstantMessage==2.4
+pyobjc-framework-LatentSemanticMapping==2.4
+pyobjc-framework-LaunchServices==2.4
+pyobjc-framework-Message==2.4
+pyobjc-framework-PreferencePanes==2.4
+pyobjc-framework-PubSub==2.4
+pyobjc-framework-QTKit==2.4
+pyobjc-framework-Quartz==2.4
+pyobjc-framework-ScreenSaver==2.4
+pyobjc-framework-ScriptingBridge==2.4
+pyobjc-framework-SearchKit==2.4
+pyobjc-framework-ServerNotification==2.4
+pyobjc-framework-ServiceManagement==2.4
+pyobjc-framework-Social==2.4
+pyobjc-framework-SyncServices==2.4
+pyobjc-framework-SystemConfiguration==2.4
+pyobjc-framework-WebKit==2.4
+# -*- coding: utf-8 -*-
+#
+#  setup.py
+#  doko
+#
+
+"""
+Package information for doko package.
+"""
+
+from setuptools import setup
+
+VERSION = '0.1.0'
+
+setup(
+        name='doko',
+        description="Detect location using CoreLocation on OS X.",
+        long_description=open('README.rst').read(),
+        url="http://bitbucket.org/larsyencken/doko/",
+        version=VERSION,
+        author="Lars Yencken",
+        author_email="lars@yencken.org",
+        license="BSD",
+        packages=[
+            'doko',
+        ],
+        entry_points={
+            'console_scripts': [
+                    'doko = doko:main',
+                ],
+        },
+        install_requires=[
+            'pyobjc==2.4',
+            'pyobjc-core==2.4',
+            'pyobjc-framework-CoreLocation==2.4',
+        ],
+    )
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.