Ronald Oussoren avatar Ronald Oussoren committed 79cb82f

add support for custom url types to the argv_emulation code

Comments (0)

Files changed (3)

doc/changelog.rst

   will tell you abou this instead of silently failing to 
   build a working bundle.
 
+- add support for custom URLs to the argv emulation code
+  (patch by Brendan Simon). 
+  
+  You will have to add a "CFBundleURLTypes" key to your Info.plist to 
+  use this, the argv emulation code will ensure that the URL
+  to open will end up in ``sys.argv``.
+
 Bug fixes:
 
 - The ``--alias`` option didn't work when building a plugin

py2app/bootstrap/argv_emulation.py

         import traceback
         from Carbon import AE
         from Carbon.AppleEvents import kCoreEventClass, kAEOpenApplication, \
-            kAEOpenDocuments, keyDirectObject, typeAEList, typeAlias
+            kAEOpenDocuments, keyDirectObject, typeAEList, typeAlias, \
+            kAEInternetSuite, kAEISGetURL, typeChar
         from Carbon import Evt
         from Carbon import File
         from Carbon.Events import highLevelEventMask, kHighLevelEvent
                     self.__runapp)
                 AE.AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
                     self.__openfiles)
+                AE.AEInstallEventHandler(kAEInternetSuite, kAEISGetURL,
+                        self.__geturl)
+
+                # The definition of kAEInternetSuite seems to be wrong,
+                # the lines below ensures that the code will work anyway.
+                AE.AEInstallEventHandler('GURL', 'GURL', self.__geturl)
 
             def close(self):
                 AE.AERemoveEventHandler(kCoreEventClass, kAEOpenApplication)
 
                 self._quit()
 
+            def __geturl(self, requestevent, replyevent):
+                try:
+                    listdesc = requestevent.AEGetParamDesc(keyDirectObject, typeAEList)
+                    for i in range(listdesc.AECountItems()):
+                        desc = listdesc.AEGetNthDesc(i+1, typeChar)[1]
+                        #url = desc.data.decode('utf8')
+                        url = desc.data
+                        sys.argv.append(url)
+                except Exception, e:
+                    print "argvemulator.py warning: can't unpack a GetURL event"
+                    import traceback
+                    traceback.print_exc()
+
+                self._quit()
+
         return ArgvCollector()
 
     def _argv_emulation():

py2app_tests/test_argv_emulation.py

 
 class TestArgvEmulation (unittest.TestCase):
     py2app_args = []
+    setup_file = "setup.py"
+    open_argument = '/usr/bin/ssh'
     app_dir = os.path.join(DIR_NAME, 'argv_app')
 
     # Basic setup code
     def setUpClass(cls):
         p = subprocess.Popen([
                 sys.executable,
-                    'setup.py', 'py2app'] + cls.py2app_args,
+                    cls.setup_file, 'py2app'] + cls.py2app_args,
             cwd = cls.app_dir,
             stdout=subprocess.PIPE,
             stderr=subprocess.STDOUT,
         path = os.path.join( self.app_dir, 'dist/BasicApp.app')
 
         p = subprocess.Popen(["/usr/bin/open",
-            '-a', path, 'file:/usr/bin/ssh'])
+            '-a', path, self.open_argument])
         exit = p.wait()
 
         self.assertEqual(exit, 0)
         data = fp.read().strip()
         fp.close()
 
-        self.assertEqual(data.strip(), repr([os.path.join(self.app_dir, 'dist/BasicApp.app/Contents/Resources/main.py'), '/usr/bin/ssh']))
+        self.assertEqual(data.strip(), repr([os.path.join(self.app_dir, 'dist/BasicApp.app/Contents/Resources/main.py'), self.open_argument]))
 
+class TestArgvEmulationWithUrL (TestArgvEmulation):
+    py2app_args = []
+    setup_file = "setup-with-urlscheme.py"
+    open_argument = 'myurl:mycommand'
+    app_dir = os.path.join(DIR_NAME, 'argv_app')
 
 
 if __name__ == "__main__":
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.