diff --git a/VPN-Manager-3.2.alfredworkflow b/VPN-Manager-3.3.alfredworkflow
similarity index 74%
rename from VPN-Manager-3.2.alfredworkflow
rename to VPN-Manager-3.3.alfredworkflow
index e38a065..d6d297d 100644
Binary files a/VPN-Manager-3.2.alfredworkflow and b/VPN-Manager-3.3.alfredworkflow differ
diff --git a/src/docopt.py b/src/docopt.py
index 7b927e2..11b564b 100644
--- a/src/docopt.py
+++ b/src/docopt.py
@@ -478,7 +478,7 @@ def formal_usage(printable_usage):
def extras(help, version, options, doc):
if help and any((o.name in ('-h', '--help')) and o.value for o in options):
- print(doc.strip("\n"))
+ print((doc.strip("\n")))
sys.exit()
if version and any(o.name == '--version' and o.value for o in options):
print(version)
@@ -487,7 +487,7 @@ def extras(help, version, options, doc):
class Dict(dict):
def __repr__(self):
- return '{%s}' % ',\n '.join('%r: %r' % i for i in sorted(self.items()))
+ return '{%s}' % ',\n '.join('%r: %r' % i for i in sorted(self.items(), key=lambda x: str(x)))
def docopt(doc, argv=None, help=True, version=None, options_first=False):
diff --git a/src/info.plist b/src/info.plist
index 3eceadb..549c6ad 100644
--- a/src/info.plist
+++ b/src/info.plist
@@ -125,7 +125,7 @@
escaping
0
script
- /usr/bin/python vpn.py $action "$1"
+ /usr/bin/python3 vpn.py $action "$1"
scriptargtype
1
scriptfile
@@ -166,7 +166,7 @@
runningsubtext
Loading VPN information…
script
- /usr/bin/python vpn.py list "$1"
+ /usr/bin/python3 vpn.py list "$1"
scriptargtype
1
scriptfile
@@ -213,7 +213,7 @@
runningsubtext
Loading apps…
script
- /usr/bin/python vpn.py conf "$1"
+ /usr/bin/python3 vpn.py conf "$1"
scriptargtype
1
scriptfile
@@ -337,7 +337,7 @@
echo "query=$query" >&2
app=$( echo "$query" | cut -d: -f2 )
-/usr/bin/python vpn.py app "$app"
+/usr/bin/python3 vpn.py app "$app"
echo "$app"
scriptargtype
@@ -477,7 +477,7 @@ or Tunnelblick app from https://tunnelblick.net/
VPN_APP
version
- 3.2
+ 3.3
webaddress
https://github.com/deanishe/alfred-vpn-manager
diff --git a/src/vpn.py b/src/vpn.py
index 4a83840..5aab027 100755
--- a/src/vpn.py
+++ b/src/vpn.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
# encoding: utf-8
#
# Copyright (c) 2015 deanishe@deanishe.net
@@ -23,7 +23,7 @@
-h, --help Show this message and exit.
"""
-from __future__ import print_function, absolute_import
+
import abc
from collections import namedtuple
@@ -92,11 +92,9 @@ def timed(name=None):
# 88 88 88
# dP dP dP
-class VPNApp(object):
+class VPNApp(object, metaclass=abc.ABCMeta):
"""Base class for application classes."""
- __metaclass__ = abc.ABCMeta
-
def __init__(self):
"""Create new initialised `VPNApp`."""
self._info = False
@@ -142,7 +140,7 @@ def connect(self, name):
"""Connect to named VPN."""
connections = self.filter_connections(name=name, active=False)
for c in connections:
- log.info(u'connecting "%s" ...', c.name)
+ log.info('connecting "%s" ...', c.name)
cmd = self.program + ['connect', c.name]
run_command(cmd)
@@ -151,7 +149,7 @@ def disconnect(self, name):
"""Disconnect from named VPN."""
connections = self.filter_connections(name=name, active=True)
for c in connections:
- log.info(u'disconnecting "%s" ...', c.name)
+ log.info('disconnecting "%s" ...', c.name)
cmd = self.program + ['disconnect', c.name]
run_command(cmd)
@@ -204,7 +202,7 @@ def _fetch_connections(self):
data = json.loads(run_command(cmd))
- for t in data.items():
+ for t in list(data.items()):
connections.append(VPN(*t))
return connections
@@ -291,7 +289,7 @@ def show_update():
"""Add an 'update available!' item."""
if wf.update_available:
wf.add_item('Workflow Update Available!',
- u'↩ or ⇥ to install update',
+ '↩ or ⇥ to install update',
autocomplete='workflow:update',
valid=False,
icon=ICON_UPDATE_AVAILABLE)
@@ -314,7 +312,7 @@ def do_config(query):
items.append(dict(
title=title,
- subtitle=u'↩ or ⇥ to install update',
+ subtitle='↩ or ⇥ to install update',
autocomplete='workflow:update',
valid=False,
icon=icon,
@@ -325,8 +323,8 @@ def do_config(query):
for app in get_all_apps():
if app.selected and app.installed:
items.append(dict(
- title=u'{} (active)'.format(app.name),
- subtitle=u'{} is the active application'.format(app.name),
+ title='{} (active)'.format(app.name),
+ subtitle='{} is the active application'.format(app.name),
icon=app.info.path,
icontype='fileicon',
valid=False,
@@ -334,8 +332,8 @@ def do_config(query):
else:
if app.installed:
items.append(dict(
- title=u'{}'.format(app.name),
- subtitle=u'↩ to use {}'.format(app.name),
+ title='{}'.format(app.name),
+ subtitle='↩ to use {}'.format(app.name),
icon=app.info.path,
icontype='fileicon',
arg='app:' + app.name,
@@ -343,8 +341,8 @@ def do_config(query):
))
else:
items.append(dict(
- title=u'{} (not installed)'.format(app.name),
- subtitle=u'↩ to get {}'.format(app.name),
+ title='{} (not installed)'.format(app.name),
+ subtitle='↩ to get {}'.format(app.name),
icon=ICON_WEB,
arg=app.download_url,
valid=True,
@@ -404,7 +402,7 @@ def do_list(query):
try:
app = get_app()
except NotInstalled as err:
- wf.add_item(err.message,
+ wf.add_item(str(err),
'Use "vpnconf" to change the application',
valid=False,
icon=ICON_WARNING)
@@ -473,7 +471,7 @@ def do_list(query):
it = wf.add_item(
con.name,
- u'↩ to connect',
+ '↩ to connect',
uid=uid,
arg=con.name,
valid=True,
@@ -512,7 +510,7 @@ def main(wf):
"""Run workflow."""
args = docopt.docopt(__doc__, wf.args, version=wf.version)
- log.debug('args : %r', args)
+ log.debug('args : !r', args)
if args['list']:
return do_list(args.get(''))
diff --git a/src/workflow/__init__.py b/src/workflow/__init__.py
index 17636a4..87a7fde 100644
--- a/src/workflow/__init__.py
+++ b/src/workflow/__init__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# encoding: utf-8
#
# Copyright (c) 2014 Dean Jackson
diff --git a/src/workflow/background.py b/src/workflow/background.py
index ba5c52a..d4643f9 100644
--- a/src/workflow/background.py
+++ b/src/workflow/background.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# encoding: utf-8
#
# Copyright (c) 2014 deanishe@deanishe.net
@@ -17,7 +17,7 @@
and examples.
"""
-from __future__ import print_function, unicode_literals
+
import signal
import sys
@@ -25,7 +25,7 @@
import subprocess
import pickle
-from workflow import Workflow
+from .workflow import Workflow
__all__ = ['is_running', 'run_in_background']
@@ -96,7 +96,7 @@ def _job_pid(name):
if not os.path.exists(pidfile):
return
- with open(pidfile, 'rb') as fp:
+ with open(pidfile, 'r') as fp:
pid = int(fp.read())
if _process_exists(pid):
@@ -143,7 +143,7 @@ def _fork_and_exit_parent(errmsg, wait=False, write=False):
if pid > 0:
if write: # write PID of child process to `pidfile`
tmp = pidfile + '.tmp'
- with open(tmp, 'wb') as fp:
+ with open(tmp, 'w') as fp:
fp.write(str(pid))
os.rename(tmp, pidfile)
if wait: # wait for child process to exit
@@ -233,7 +233,7 @@ def run_in_background(name, args, **kwargs):
_log().debug('[%s] command cached: %s', name, argcache)
# Call this script
- cmd = ['/usr/bin/python', __file__, name]
+ cmd = ['/usr/bin/python3', __file__, name]
_log().debug('[%s] passing job to background runner: %r', name, cmd)
retcode = subprocess.call(cmd)
diff --git a/src/workflow/notify.py b/src/workflow/notify.py
index a4b7f40..e0e9066 100644
--- a/src/workflow/notify.py
+++ b/src/workflow/notify.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# encoding: utf-8
#
# Copyright (c) 2015 deanishe@deanishe.net
@@ -23,7 +23,7 @@
icon and then calls the application to post notifications.
"""
-from __future__ import print_function, unicode_literals
+
import os
import plistlib
@@ -34,7 +34,7 @@
import tempfile
import uuid
-import workflow
+from . import workflow
_wf = None
diff --git a/src/workflow/update.py b/src/workflow/update.py
index 6affc94..bd4c55f 100644
--- a/src/workflow/update.py
+++ b/src/workflow/update.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# encoding: utf-8
#
# Copyright (c) 2014 Fabio Niephaus ,
@@ -21,7 +21,7 @@
"""
-from __future__ import print_function, unicode_literals
+
from collections import defaultdict
from functools import total_ordering
@@ -31,8 +31,8 @@
import re
import subprocess
-import workflow
-import web
+from . import workflow
+from . import web
# __all__ = []
@@ -119,7 +119,7 @@ def from_releases(cls, js):
release['prerelease']))
valid = True
- for ext, n in dupes.items():
+ for ext, n in list(dupes.items()):
if n > 1:
wf().logger.debug('ignored release "%s": multiple assets '
'with extension "%s"', tag, ext)
@@ -143,7 +143,7 @@ def __init__(self, url, filename, version, prerelease=False):
pre-release. Defaults to False.
"""
- if isinstance(version, basestring):
+ if isinstance(version, str):
version = Version(version)
self.url = url
@@ -172,7 +172,7 @@ def __str__(self):
'version={dl.version!r}, '
'prerelease={dl.prerelease!r})'.format(dl=self))
- return u.encode('utf-8')
+ return u
def __repr__(self):
"""Code-like representation of `Download`."""
diff --git a/src/workflow/util.py b/src/workflow/util.py
index 27209d8..f8ea4ed 100644
--- a/src/workflow/util.py
+++ b/src/workflow/util.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# encoding: utf-8
#
# Copyright (c) 2017 Dean Jackson
@@ -10,7 +10,7 @@
"""A selection of helper functions useful for building workflows."""
-from __future__ import print_function, absolute_import
+
import atexit
from collections import namedtuple
@@ -86,9 +86,9 @@ def jxa_app_name():
"""
if os.getenv('alfred_version', '').startswith('3'):
# Alfred 3
- return u'Alfred 3'
+ return 'Alfred 3'
# Alfred 4+
- return u'com.runningwithcrayons.Alfred'
+ return 'com.runningwithcrayons.Alfred'
def unicodify(s, encoding='utf-8', norm=None):
@@ -108,8 +108,8 @@ def unicodify(s, encoding='utf-8', norm=None):
unicode: Decoded, optionally normalised, Unicode string.
"""
- if not isinstance(s, unicode):
- s = unicode(s, encoding)
+ if not isinstance(s, str):
+ s = str(s, encoding)
if norm:
from unicodedata import normalize
@@ -136,7 +136,7 @@ def utf8ify(s):
if isinstance(s, str):
return s
- if isinstance(s, unicode):
+ if isinstance(s, str):
return s.encode('utf-8')
return str(s)
@@ -161,7 +161,7 @@ def applescriptify(s):
unicode: Escaped string
"""
- return s.replace(u'"', u'" & quote & "')
+ return s.replace('"', '" & quote & "')
def run_command(cmd, **kwargs):
@@ -181,7 +181,7 @@ def run_command(cmd, **kwargs):
"""
cmd = [utf8ify(s) for s in cmd]
- return subprocess.check_output(cmd, **kwargs)
+ return subprocess.check_output(cmd, **kwargs).decode('utf8', errors='ignore')
def run_applescript(script, *args, **kwargs):
@@ -383,7 +383,7 @@ class LockFile(object):
>>> path = '/path/to/file'
>>> with LockFile(path):
- >>> with open(path, 'wb') as fp:
+ >>> with open(path, 'w') as fp:
>>> fp.write(data)
Args:
diff --git a/src/workflow/web.py b/src/workflow/web.py
index 0781911..1e7b63b 100644
--- a/src/workflow/web.py
+++ b/src/workflow/web.py
@@ -18,13 +18,13 @@
import socket
import string
import unicodedata
-import urllib
-import urllib2
-import urlparse
+import urllib.request, urllib.parse, urllib.error
+import urllib.request, urllib.error, urllib.parse
+import urllib.parse
import zlib
-USER_AGENT = u'Alfred-Workflow/1.36 (+http://www.deanishe.net/alfred-workflow)'
+USER_AGENT = 'Alfred-Workflow/1.36 (+http://www.deanishe.net/alfred-workflow)'
# Valid characters for multipart form data boundaries
BOUNDARY_CHARS = string.digits + string.ascii_letters
@@ -87,16 +87,16 @@ def str_dict(dic):
dic2 = CaseInsensitiveDictionary()
else:
dic2 = {}
- for k, v in dic.items():
- if isinstance(k, unicode):
- k = k.encode('utf-8')
- if isinstance(v, unicode):
- v = v.encode('utf-8')
+ for k, v in list(dic.items()):
+ if isinstance(k, bytes):
+ k = k.decode('utf-8')
+ if isinstance(v, bytes):
+ v = v.decode('utf-8')
dic2[k] = v
return dic2
-class NoRedirectHandler(urllib2.HTTPRedirectHandler):
+class NoRedirectHandler(urllib.request.HTTPRedirectHandler):
"""Prevent redirections."""
def redirect_request(self, *args):
@@ -120,7 +120,7 @@ class CaseInsensitiveDictionary(dict):
def __init__(self, initval=None):
"""Create new case-insensitive dictionary."""
if isinstance(initval, dict):
- for key, value in initval.iteritems():
+ for key, value in initval.items():
self.__setitem__(key, value)
elif isinstance(initval, list):
@@ -147,34 +147,34 @@ def get(self, key, default=None):
def update(self, other):
"""Update values from other ``dict``."""
- for k, v in other.items():
+ for k, v in list(other.items()):
self[k] = v
def items(self):
"""Return ``(key, value)`` pairs."""
- return [(v['key'], v['val']) for v in dict.itervalues(self)]
+ return [(v['key'], v['val']) for v in super(CaseInsensitiveDictionary, self).values()]
def keys(self):
"""Return original keys."""
- return [v['key'] for v in dict.itervalues(self)]
+ return [v['key'] for v in super(CaseInsensitiveDictionary, self).values()]
def values(self):
"""Return all values."""
- return [v['val'] for v in dict.itervalues(self)]
+ return [v['val'] for v in super(CaseInsensitiveDictionary, self).values()]
def iteritems(self):
"""Iterate over ``(key, value)`` pairs."""
- for v in dict.itervalues(self):
+ for v in super(CaseInsensitiveDictionary, self).values():
yield v['key'], v['val']
def iterkeys(self):
"""Iterate over original keys."""
- for v in dict.itervalues(self):
+ for v in super(CaseInsensitiveDictionary, self).values():
yield v['key']
def itervalues(self):
"""Interate over values."""
- for v in dict.itervalues(self):
+ for v in super(CaseInsensitiveDictionary, self).values():
yield v['val']
@@ -220,8 +220,8 @@ def __init__(self, request, stream=False):
# Execute query
try:
- self.raw = urllib2.urlopen(request)
- except urllib2.HTTPError as err:
+ self.raw = urllib.request.urlopen(request)
+ except urllib.error.HTTPError as err:
self.error = err
try:
self.url = err.geturl()
@@ -240,9 +240,8 @@ def __init__(self, request, stream=False):
# Parse additional info if request succeeded
if not self.error:
headers = self.raw.info()
- self.transfer_encoding = headers.getencoding()
- self.mimetype = headers.gettype()
- for key in headers.keys():
+ self.mimetype = headers.get_content_type()
+ for key in list(headers.keys()):
self.headers[key.lower()] = headers.get(key)
# Is content gzipped?
@@ -327,7 +326,7 @@ def text(self):
"""
if self.encoding:
- return unicodedata.normalize('NFC', unicode(self.content,
+ return unicodedata.normalize('NFC', str(self.content,
self.encoding))
return self.content
@@ -400,7 +399,7 @@ def save_to_path(self, filepath):
self.stream = True
- with open(filepath, 'wb') as fileobj:
+ with open(filepath, 'w') as fileobj:
for data in self.iter_content():
fileobj.write(data)
@@ -519,14 +518,14 @@ def request(method, url, params=None, data=None, headers=None, cookies=None,
if auth is not None: # Add authorisation handler
username, password = auth
- password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
+ password_manager = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_manager.add_password(None, url, username, password)
- auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
+ auth_manager = urllib.request.HTTPBasicAuthHandler(password_manager)
openers.append(auth_manager)
# Install our custom chain of openers
- opener = urllib2.build_opener(*openers)
- urllib2.install_opener(opener)
+ opener = urllib.request.build_opener(*openers)
+ urllib.request.install_opener(opener)
if not headers:
headers = CaseInsensitiveDictionary()
@@ -554,28 +553,25 @@ def request(method, url, params=None, data=None, headers=None, cookies=None,
new_headers, data = encode_multipart_formdata(data, files)
headers.update(new_headers)
elif data and isinstance(data, dict):
- data = urllib.urlencode(str_dict(data))
+ data = urllib.parse.urlencode(str_dict(data))
# Make sure everything is encoded text
headers = str_dict(headers)
- if isinstance(url, unicode):
- url = url.encode('utf-8')
-
if params: # GET args (POST args are handled in encode_multipart_formdata)
- scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
+ scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url)
if query: # Combine query string and `params`
- url_params = urlparse.parse_qs(query)
+ url_params = urllib.parse.parse_qs(query)
# `params` take precedence over URL query string
url_params.update(params)
params = url_params
- query = urllib.urlencode(str_dict(params), doseq=True)
- url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
+ query = urllib.parse.urlencode(str_dict(params), doseq=True)
+ url = urllib.parse.urlunsplit((scheme, netloc, path, query, fragment))
- req = urllib2.Request(url, data, headers)
+ req = urllib.request.Request(url, data, headers)
return Response(req, stream)
@@ -644,30 +640,30 @@ def get_content_type(filename):
output = []
# Normal form fields
- for (name, value) in fields.items():
- if isinstance(name, unicode):
- name = name.encode('utf-8')
- if isinstance(value, unicode):
- value = value.encode('utf-8')
+ for (name, value) in list(fields.items()):
+ if isinstance(name, bytes):
+ name = name.decode('utf-8')
+ if isinstance(value, bytes):
+ value = value.decode('utf-8')
output.append('--' + boundary)
output.append('Content-Disposition: form-data; name="%s"' % name)
output.append('')
output.append(value)
# Files to upload
- for name, d in files.items():
- filename = d[u'filename']
- content = d[u'content']
- if u'mimetype' in d:
- mimetype = d[u'mimetype']
+ for name, d in list(files.items()):
+ filename = d['filename']
+ content = d['content']
+ if 'mimetype' in d:
+ mimetype = d['mimetype']
else:
mimetype = get_content_type(filename)
- if isinstance(name, unicode):
- name = name.encode('utf-8')
- if isinstance(filename, unicode):
- filename = filename.encode('utf-8')
- if isinstance(mimetype, unicode):
- mimetype = mimetype.encode('utf-8')
+ if isinstance(name, bytes):
+ name = name.decode('utf-8')
+ if isinstance(filename, bytes):
+ filename = filename.decode('utf-8')
+ if isinstance(mimetype, bytes):
+ mimetype = mimetype.decode('utf-8')
output.append('--' + boundary)
output.append('Content-Disposition: form-data; '
'name="%s"; filename="%s"' % (name, filename))
diff --git a/src/workflow/workflow.py b/src/workflow/workflow.py
index 2a057b0..629256f 100644
--- a/src/workflow/workflow.py
+++ b/src/workflow/workflow.py
@@ -19,10 +19,10 @@
"""
-from __future__ import print_function, unicode_literals
+
import binascii
-import cPickle
+import pickle
from copy import deepcopy
import json
import logging
@@ -44,8 +44,8 @@
import xml.etree.ElementTree as ET
# imported to maintain API
-from util import AcquisitionError # noqa: F401
-from util import (
+from .util import AcquisitionError # noqa: F401
+from .util import (
atomic_writer,
LockFile,
uninterruptible,
@@ -619,7 +619,7 @@ def dump(cls, obj, file_obj):
:type file_obj: ``file`` object
"""
- return json.dump(obj, file_obj, indent=2, encoding='utf-8')
+ return json.dump(obj, file_obj, indent=2)
class CPickleSerializer(object):
@@ -644,7 +644,7 @@ def load(cls, file_obj):
:rtype: object
"""
- return cPickle.load(file_obj)
+ return pickle.load(file_obj)
@classmethod
def dump(cls, obj, file_obj):
@@ -658,7 +658,7 @@ def dump(cls, obj, file_obj):
:type file_obj: ``file`` object
"""
- return cPickle.dump(obj, file_obj, protocol=-1)
+ return pickle.dump(obj, file_obj, protocol=-1)
class PickleSerializer(object):
@@ -826,7 +826,7 @@ def __init__(self, filepath, defaults=None):
if os.path.exists(self._filepath):
self._load()
elif defaults:
- for key, val in defaults.items():
+ for key, val in list(defaults.items()):
self[key] = val
self.save() # save default settings
@@ -834,7 +834,7 @@ def _load(self):
"""Load cached settings from JSON file `self._filepath`."""
data = {}
with LockFile(self._filepath, 0.5):
- with open(self._filepath, 'rb') as fp:
+ with open(self._filepath, 'r') as fp:
data.update(json.load(fp))
self._original = deepcopy(data)
@@ -858,9 +858,8 @@ def save(self):
data.update(self)
with LockFile(self._filepath, 0.5):
- with atomic_writer(self._filepath, 'wb') as fp:
- json.dump(data, fp, sort_keys=True, indent=2,
- encoding='utf-8')
+ with atomic_writer(self._filepath, 'w') as fp:
+ json.dump(data, fp, sort_keys=True, indent=2)
# dict methods
def __setitem__(self, key, value):
@@ -996,7 +995,7 @@ def __init__(self, default_settings=None, update_settings=None,
@property
def alfred_version(self):
"""Alfred version as :class:`~workflow.update.Version` object."""
- from update import Version
+ from .update import Version
return Version(self.alfred_env.get('version'))
@property
@@ -1100,7 +1099,7 @@ def bundleid(self):
if self.alfred_env.get('workflow_bundleid'):
self._bundleid = self.alfred_env.get('workflow_bundleid')
else:
- self._bundleid = unicode(self.info['bundleid'], 'utf-8')
+ self._bundleid = str(self.info['bundleid'], 'utf-8')
return self._bundleid
@@ -1163,7 +1162,7 @@ def version(self):
filepath = self.workflowfile('version')
if os.path.exists(filepath):
- with open(filepath, 'rb') as fileobj:
+ with open(filepath, 'r') as fileobj:
version = fileobj.read()
# info.plist
@@ -1171,7 +1170,7 @@ def version(self):
version = self.info.get('version')
if version:
- from update import Version
+ from .update import Version
version = Version(version)
self._version = version
@@ -1299,7 +1298,7 @@ def workflowdir(self):
# the library is in. CWD will be the workflow root if
# a workflow is being run in Alfred
candidates = [
- os.path.abspath(os.getcwdu()),
+ os.path.abspath(os.getcwd()),
os.path.dirname(os.path.abspath(os.path.dirname(__file__)))]
# climb the directory tree until we find `info.plist`
@@ -1571,7 +1570,7 @@ def stored_data(self, name):
self.logger.debug('no data stored for `%s`', name)
return None
- with open(metadata_path, 'rb') as file_obj:
+ with open(metadata_path, 'r') as file_obj:
serializer_name = file_obj.read().strip()
serializer = manager.serializer(serializer_name)
@@ -1594,7 +1593,7 @@ def stored_data(self, name):
return None
- with open(data_path, 'rb') as file_obj:
+ with open(data_path, 'r') as file_obj:
data = serializer.load(file_obj)
self.logger.debug('stored data loaded: %s', data_path)
@@ -1658,10 +1657,10 @@ def delete_paths(paths):
@uninterruptible
def _store():
# Save file extension
- with atomic_writer(metadata_path, 'wb') as file_obj:
+ with atomic_writer(metadata_path, 'w') as file_obj:
file_obj.write(serializer_name)
- with atomic_writer(data_path, 'wb') as file_obj:
+ with atomic_writer(data_path, 'w') as file_obj:
serializer.dump(data, file_obj)
_store()
@@ -2083,7 +2082,7 @@ def run(self, func, text_errors=False):
if not sys.stdout.isatty(): # Show error in Alfred
if text_errors:
- print(unicode(err).encode('utf-8'), end='')
+ print(str(err).encode('utf-8'), end='')
else:
self._items = []
if self._name:
@@ -2093,7 +2092,7 @@ def run(self, func, text_errors=False):
else: # pragma: no cover
name = os.path.dirname(__file__)
self.add_item("Error in workflow '%s'" % name,
- unicode(err),
+ str(err),
icon=ICON_ERROR)
self.send_feedback()
return 1
@@ -2217,7 +2216,7 @@ def last_version_run(self):
version = self.settings.get('__workflow_last_version')
if version:
- from update import Version
+ from .update import Version
version = Version(version)
self._last_version_run = version
@@ -2245,8 +2244,8 @@ def set_last_version(self, version=None):
version = self.version
- if isinstance(version, basestring):
- from update import Version
+ if isinstance(version, str):
+ from .update import Version
version = Version(version)
self.settings['__workflow_last_version'] = str(version)
@@ -2324,13 +2323,13 @@ def check_update(self, force=False):
# version = self._update_settings['version']
version = str(self.version)
- from background import run_in_background
+ from .background import run_in_background
# update.py is adjacent to this file
update_script = os.path.join(os.path.dirname(__file__),
- b'update.py')
+ 'update.py')
- cmd = ['/usr/bin/python', update_script, 'check', repo, version]
+ cmd = ['/usr/bin/python3', update_script, 'check', repo, version]
if self.prereleases:
cmd.append('--prereleases')
@@ -2354,7 +2353,7 @@ def start_update(self):
installed, else ``False``
"""
- import update
+ from . import update
repo = self._update_settings['github_slug']
# version = self._update_settings['version']
@@ -2363,13 +2362,13 @@ def start_update(self):
if not update.check_update(repo, version, self.prereleases):
return False
- from background import run_in_background
+ from .background import run_in_background
# update.py is adjacent to this file
update_script = os.path.join(os.path.dirname(__file__),
- b'update.py')
+ 'update.py')
- cmd = ['/usr/bin/python', update_script, 'install', repo, version]
+ cmd = ['/usr/bin/python3', update_script, 'install', repo, version]
if self.prereleases:
cmd.append('--prereleases')
@@ -2456,7 +2455,7 @@ def get_password(self, account, service=None):
h = groups.get('hex')
password = groups.get('pw')
if h:
- password = unicode(binascii.unhexlify(h), 'utf-8')
+ password = str(binascii.unhexlify(h), 'utf-8')
self.logger.debug('got password : %s:%s', service, account)
@@ -2698,8 +2697,8 @@ def decode(self, text, encoding=None, normalization=None):
"""
encoding = encoding or self._input_encoding
normalization = normalization or self._normalizsation
- if not isinstance(text, unicode):
- text = unicode(text, encoding)
+ if not isinstance(text, str):
+ text = str(text, encoding)
return unicodedata.normalize(normalization, text)
def fold_to_ascii(self, text):
@@ -2718,7 +2717,7 @@ def fold_to_ascii(self, text):
if isascii(text):
return text
text = ''.join([ASCII_REPLACEMENTS.get(c, c) for c in text])
- return unicode(unicodedata.normalize('NFKD',
+ return str(unicodedata.normalize('NFKD',
text).encode('ascii', 'ignore'))
def dumbify_punctuation(self, text):
diff --git a/src/workflow/workflow3.py b/src/workflow/workflow3.py
index b92c4be..f1b56dd 100644
--- a/src/workflow/workflow3.py
+++ b/src/workflow/workflow3.py
@@ -23,7 +23,7 @@
"""
-from __future__ import print_function, unicode_literals, absolute_import
+
import json
import os
@@ -72,7 +72,7 @@ def obj(self):
o = {}
if self:
d2 = {}
- for k, v in self.items():
+ for k, v in list(self.items()):
d2[k] = v
o['variables'] = d2
@@ -95,7 +95,7 @@ def __unicode__(self):
if self.arg:
return self.arg
else:
- return u''
+ return ''
return json.dumps(self.obj)
@@ -106,7 +106,7 @@ def __str__(self):
str: UTF-8 encoded ``alfredworkflow`` JSON object
"""
- return unicode(self).encode('utf-8')
+ return str(self)
class Modifier(object):
@@ -438,7 +438,7 @@ def _modifiers(self):
"""
if self.modifiers:
mods = {}
- for k, mod in self.modifiers.items():
+ for k, mod in list(self.modifiers.items()):
mods[k] = mod.obj
return mods
@@ -689,7 +689,7 @@ def obj(self):
o['rerun'] = self.rerun
return o
- def warn_empty(self, title, subtitle=u'', icon=None):
+ def warn_empty(self, title, subtitle='', icon=None):
"""Add a warning to feedback if there are no items.
.. versionadded:: 1.31