diff --git a/Packal-Search-1.4.alfredworkflow b/Packal-Search-1.4.1.alfredworkflow similarity index 93% rename from Packal-Search-1.4.alfredworkflow rename to Packal-Search-1.4.1.alfredworkflow index 0cec596..f88be65 100644 Binary files a/Packal-Search-1.4.alfredworkflow and b/Packal-Search-1.4.1.alfredworkflow differ diff --git a/src/packal.py b/src/packal.py index 1ae144e..bd0f83b 100644 --- a/src/packal.py +++ b/src/packal.py @@ -8,12 +8,7 @@ # Created on 2014-03-03 # -""" -Simple search of Packal.org for workflows based on the exported manifest.xml - -Uses Alfred-Workflow library: -https://github.com/deanishe/alfred-workflow -""" +"""Search Packal.org for workflows based on the exported manifest.xml""" from __future__ import print_function, unicode_literals @@ -136,11 +131,11 @@ def workflow_key(workflow): class GoBack(Exception): - """Raised when Workflows should back up""" + """Raised when Workflows should back up.""" class PackalWorkflow(object): - """Encapsulates the Workflow""" + """Encapsulates the Workflow.""" def __init__(self): self.wf = None @@ -227,10 +222,12 @@ def do_status(self): log.debug('Workflow `{}` by ignored author. Skipping.'.format( workflow['bundle'])) continue + if workflow['status'] == STATUS_UPDATE_AVAILABLE: results.append((1, workflow['updated'], workflow)) elif workflow['status'] == STATUS_SPLITTER: results.append((0, workflow['updated'], workflow)) + results.sort(reverse=True) workflows = [t[2] for t in results] return self._filter_workflows(workflows, None) @@ -264,15 +261,15 @@ def _two_stage_filter(self, key): :param key: ``tags/categories/authors/versions``. Which attribute to search. - """ + """ valid = False try: subset, query = self._split_query(self.query) except GoBack: - query = 'packal {}'.format(key) - log.debug('Going back to : {}'.format(query)) + query = 'packal ' + key + log.debug('Going back to : %s', query) run_alfred(query) return 0 else: @@ -281,7 +278,7 @@ def _two_stage_filter(self, key): if key == 'authors': key = 'author' # Enable `ignore author` - valid = False + # valid = False elif key == 'versions': key = 'osx' diff --git a/src/update_workflows.py b/src/update_workflows.py index a2a0ee8..50900ea 100644 --- a/src/update_workflows.py +++ b/src/update_workflows.py @@ -16,10 +16,11 @@ from __future__ import print_function, unicode_literals +import subprocess import sys import os from datetime import datetime -from plistlib import readPlist +from plistlib import readPlist, readPlistFromString try: from xml.etree import cElementTree as ET @@ -35,7 +36,9 @@ log = None MANIFEST_URL = 'https://raw.github.com/packal/repository/master/manifest.xml' -WORKFLOW_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +# WORKFLOW_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +ALFRED_PREFS = os.path.expanduser( + '~/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist') class Constant(object): @@ -53,6 +56,34 @@ def __str__(self): NOT_INSTALLED = Constant('NOT INSTALLED') +def read_plist(path): + """Convert plist to XML and read its contents.""" + cmd = [b'plutil', b'-convert', b'xml1', b'-o', b'-', path] + xml = subprocess.check_output(cmd) + return readPlistFromString(xml) + + +def get_workflow_directory(): + """Return path to Alfred's workflow directory.""" + prefs = read_plist(ALFRED_PREFS) + syncdir = prefs.get('syncfolder') + + if not syncdir: + log.debug('Alfred sync folder not found') + return None + + syncdir = os.path.expanduser(syncdir) + wf_dir = os.path.join(syncdir, 'Alfred.alfredpreferences/workflows') + log.debug('Workflow sync dir : %r', wf_dir) + + if os.path.exists(wf_dir): + log.debug('Workflow directory retrieved from Alfred preferences') + return wf_dir + + log.debug('Alfred.alfredpreferences/workflows not found') + return None + + def packal_metadata(xmlpath): """Return ``dict`` of metadata in ``package.xml`` file created by Packal""" tree = ET.parse(xmlpath) @@ -71,9 +102,11 @@ def get_installed_workflows(): ``version`` is ``None`` if workflow isn't from Packal.org """ workflows = {} + workflow_dir = get_workflow_directory() - for name in os.listdir(WORKFLOW_DIR): - path = os.path.join(WORKFLOW_DIR, name) + log.debug('reading workflows installed in %r ...', workflow_dir) + for name in os.listdir(workflow_dir): + path = os.path.join(workflow_dir, name) if not os.path.isdir(path): continue @@ -82,18 +115,26 @@ def get_installed_workflows(): if not os.path.exists(info_plist): continue - bundleid = readPlist(info_plist)['bundleid'] - if not bundleid: - log.warning('no bundleid in info.plist : {0}'.format(path)) + try: + bundleid = readPlist(info_plist)['bundleid'] + if not bundleid: + log.warning('no bundleid in info.plist : %s', path) + continue + except Exception as err: + log.error('bad info.plist in workflow %r: %s', path, err) continue - metadata = {'version': None, 'bundle': bundleid} - if os.path.exists(packal_xml): - metadata.update(packal_metadata(packal_xml)) + try: + metadata = {'version': None, 'bundle': bundleid} + if os.path.exists(packal_xml): + metadata.update(packal_metadata(packal_xml)) + except Exception as err: + log.error('bad packal/package.xml in workflow %r: %s', path, err) + continue workflows[metadata['bundle']] = metadata['version'] - log.debug('{0} workflows installed locally'.format(len(workflows))) + log.debug('%d workflows installed locally', len(workflows)) return workflows @@ -129,7 +170,7 @@ def get_packal_workflows(): def get_workflows(): - """Return list of workflows on on Packal.org with update status""" + """Return list of workflows on on Packal.org with update status.""" local_workflows = get_installed_workflows() packal_workflows = get_packal_workflows() for packal_workflow in packal_workflows: diff --git a/src/version b/src/version index 840ca8c..13175fd 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.4 \ No newline at end of file +1.4.1 \ No newline at end of file