Skip to content

Commit

Permalink
v1.3.0 Update
Browse files Browse the repository at this point in the history
* Name Change
* Bump workflow library to v1.39.0
* Patch workflow library LICENSE
  • Loading branch information
tomy0000000 committed Jun 26, 2020
1 parent d17eaa3 commit 825cc18
Show file tree
Hide file tree
Showing 21 changed files with 343 additions and 127 deletions.
Binary file not shown.
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@
<img src="./src/icon.png" width="200" height="200">
</div>

# Coon
# Coinc

Coon is an Alfred workflow which do currency conversion by using live currency rates from Open Exchange Rates API.
Coinc is an Alfred workflow which do currency conversion by using live currency rates from Open Exchange Rates API.

For list of support currencies, Installation, Setup and Usage, see [Wiki](../../wiki)

# Name Change
## Naming

I name this workflow with an online business name generator, with no background acknowledge or concept of the naming.

My thoughts are simple, "con-" for "conversion", a mistype of "coin", and a same pronunciation "cone🍦" with a food I'm in favor.

However, after the terrible, horrifing tragedy happened recently, this name is abandoned, and will be updated recently.

My sincerly apologize for any unconfort that might arouse. #BlackLivesMattters
This project has been renamed since v1.3.0. Eveything should be patched during the auto update, but if any problem happened, see this [documentation](../../wiki/Naming-&-v1.3.0-Manual-Update-Guide) for more info.

## Credit & License

Expand Down
10 changes: 5 additions & 5 deletions src/currency/__init__.py → src/coinc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""Functions to be called by workflow"""
import os
from datetime import datetime
from .exceptions import CoonError, ConfigError
from .exceptions import CoincError, ConfigError
from .query import Query
from .utils import (init_workflow, load_currencies, refresh_rates,
refresh_currencies, generate_list_items)
Expand Down Expand Up @@ -57,8 +57,8 @@ def convert(workflow):
init_workflow(workflow)
query = Query(workflow.args[1:])
query.run_pattern(workflow)
except CoonError as error:
workflow.logger.info("Coon: {}".format(type(error).__name__))
except CoincError as error:
workflow.logger.info("Coinc: {}".format(type(error).__name__))
workflow.logger.info(error)
workflow.add_item(title=error.args[0],
subtitle=error.args[1],
Expand Down Expand Up @@ -158,10 +158,10 @@ def refresh(workflow):
try:
refresh_rates(workflow.config)
refresh_currencies()
except CoonError as error:
except CoincError as error:
workflow.logger.info(error)
print("{},{}".format("❌Error occured during refresh",
"Coon: {}".format(type(error).__name__)))
"Coinc: {}".format(type(error).__name__)))
except Exception as error:
workflow.logger.info(error)
print("{},{}".format("❌Error occured during refresh",
Expand Down
File renamed without changes.
24 changes: 12 additions & 12 deletions src/currency/exceptions.py → src/coinc/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,55 @@
"""Exceptions used in this module"""


class CoonError(Exception):
"""Base Class used to declare other errors for Coon
class CoincError(Exception):
"""Base Class used to declare other errors for Coinc
Extends:
Exception
"""
pass


class ConfigError(CoonError):
class ConfigError(CoincError):
"""Raised when there are invalid value filled in Configuration Sheet
Extends:
CoonError
CoincError
"""
pass


class QueryError(CoonError):
class QueryError(CoincError):
"""Raised when invalid query were given
Extends:
CoonError
CoincError
"""
pass


class AppIDError(CoonError):
class AppIDError(CoincError):
"""Raised when App ID can not be used
Extends:
CoonError
CoincError
"""
pass


class ApiError(CoonError):
class ApiError(CoincError):
"""Raised when API is unreachable or return bad response
Extends:
CoonError
CoincError
"""
pass


class UnknownPythonError(CoonError):
class UnknownPythonError(CoincError):
"""Raised when Python runtime version can not be correctly detacted
Extends:
CoonError
CoincError
"""
pass
File renamed without changes.
140 changes: 97 additions & 43 deletions src/currency/utils.py → src/coinc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,61 @@
import unicodedata
from .exceptions import ApiError, AppIDError, UnknownPythonError

RATE_ENDPOINT = ("https://openexchangerates.org/api/latest.json"
"?show_alternative=1&app_id={}")
CURRENCY_ENDPOINT = ("https://openexchangerates.org/api/currencies.json"
"?show_alternative=1")
INFO_PLIST_PATH = "info.plist"
OLD_BUNDLE_ID = "tech.tomy.coon"
NEW_BUNDLE_ID = "tech.tomy.coinc"
WORKFLOW_DATA_PATH = "~/Library/Application Support/Alfred/Workflow Data"
RATE_ENDPOINT = (
"https://openexchangerates.org/api/latest.json" "?show_alternative=1&app_id={}"
)
CURRENCY_ENDPOINT = (
"https://openexchangerates.org/api/currencies.json" "?show_alternative=1"
)


def manual_update_patch(workflow):
"""manual update metadatas for v1.3.0 name change
Update include two section, change Bundle ID in info.plist to a new one,
and rename the old data directory into new one
Arguments:
workflow {workflow.Workflow3} -- The workflow object
Returns:
bool -- Whether any modification got invoked
Raises:
UnknownPythonError -- Raised when Python runtime version can not be
correctly detacted
"""
updated = False
# Fix Bundle ID
if workflow.bundleid.encode("utf-8") == OLD_BUNDLE_ID:
import plistlib

if sys.version_info.major == 2:
info = plistlib.readPlist(INFO_PLIST_PATH)
info["bundleid"] = NEW_BUNDLE_ID
plistlib.writePlist(info, INFO_PLIST_PATH)
elif sys.version_info.major == 3:
with open(INFO_PLIST_PATH, "rw") as file:
info = plistlib.load(file)
info["bundleid"] = NEW_BUNDLE_ID
plistlib.dump(info, INFO_PLIST_PATH)
else:
raise UnknownPythonError("Unexpected Python Version", sys.version_info)
workflow.logger.info("Bundle ID modified")
updated = True

# Move Data Directory
old_path = os.path.expanduser(os.path.join(WORKFLOW_DATA_PATH, OLD_BUNDLE_ID))
if os.path.exists(old_path):
new_path = os.path.expanduser(os.path.join(WORKFLOW_DATA_PATH, NEW_BUNDLE_ID))
os.rename(old_path, new_path)
workflow.logger.info("Data Directory moved")
updated = True
return updated


def init_workflow(workflow):
Expand All @@ -26,6 +77,7 @@ def init_workflow(workflow):
workflow -- the passed in workflow object
"""
from .config import Config

workflow.config = Config()
return workflow

Expand All @@ -43,8 +95,7 @@ def _calculate(value, from_currency, to_currency, rates, precision):
Returns:
float -- The result of the conversion
"""
return round(value * (rates[to_currency] / rates[from_currency]),
precision)
return round(value * (rates[to_currency] / rates[from_currency]), precision)


def _byteify(loaded_dict):
Expand All @@ -58,8 +109,7 @@ def _byteify(loaded_dict):
"""
if isinstance(loaded_dict, dict):
return {
_byteify(key): _byteify(value)
for key, value in loaded_dict.iteritems()
_byteify(key): _byteify(value) for key, value in loaded_dict.iteritems()
}
if isinstance(loaded_dict, list):
return [_byteify(element) for element in loaded_dict]
Expand Down Expand Up @@ -152,8 +202,9 @@ def is_it_something_mixed(query):
return (value, currency)

# Type 3: {symbol}{number}
match_result = re.match(r"^(.+?)([0-9,]+(\.\d+)?)$",
query) # Use '+?' for non-progressive match
match_result = re.match(
r"^(.+?)([0-9,]+(\.\d+)?)$", query
) # Use '+?' for non-progressive match
if match_result:
value = is_it_float(match_result.groups()[1])
currency_symbol = is_it_symbol(match_result.groups()[0])
Expand Down Expand Up @@ -189,8 +240,7 @@ def load_currencies(path="currencies.json"):
elif sys.version_info.major == 3:
currencies = json.load(file)
else:
raise UnknownPythonError("Unexpected Python Version",
sys.version_info)
raise UnknownPythonError("Unexpected Python Version", sys.version_info)
return currencies


Expand All @@ -211,6 +261,7 @@ def refresh_currencies(path="currencies.json"):
"""
if sys.version_info.major == 2:
import urllib2

try:
response = urllib2.urlopen(CURRENCY_ENDPOINT)
except urllib2.HTTPError as err:
Expand All @@ -219,6 +270,7 @@ def refresh_currencies(path="currencies.json"):
currencies = _byteify(json.load(response, "utf-8"))
elif sys.version_info.major == 3:
from urllib import request, error

try:
response = request.urlopen(CURRENCY_ENDPOINT)
except error.HTTPError as err:
Expand Down Expand Up @@ -277,27 +329,31 @@ def refresh_rates(config, path="rates.json"):
"""
if sys.version_info.major == 2:
import urllib2

try:
response = urllib2.urlopen(RATE_ENDPOINT.format(config.app_id))
except urllib2.HTTPError as err:
response = _byteify(json.load(err, "utf-8"))
if err.code == 401:
raise AppIDError("Invalid App ID: {}".format(config.app_id),
response["description"])
raise AppIDError(
"Invalid App ID: {}".format(config.app_id), response["description"]
)
elif err.code == 429:
raise AppIDError("Access Restricted", response["description"])
else:
raise ApiError("Unexpected Error", response["description"])
rates = _byteify(json.load(response, "utf-8"))
elif sys.version_info.major == 3:
from urllib import request, error

try:
response = request.urlopen(RATE_ENDPOINT.format(config.app_id))
except error.HTTPError as err:
response = json.load(err)
if err.code == 401:
raise AppIDError("Invalid App ID: {}".format(config.app_id),
response["description"])
raise AppIDError(
"Invalid App ID: {}".format(config.app_id), response["description"]
)
elif err.code == 429:
raise AppIDError("Access Restricted", response["description"])
else:
Expand Down Expand Up @@ -332,8 +388,7 @@ def load_alias(path="alias.json"):
elif sys.version_info.major == 3:
alias = json.load(file)
else:
raise UnknownPythonError("Unexpected Python Version",
sys.version_info)
raise UnknownPythonError("Unexpected Python Version", sys.version_info)
return alias


Expand All @@ -359,13 +414,11 @@ def load_symbols(path="symbols.json"):
elif sys.version_info.major == 3:
symbols = json.load(file)
else:
raise UnknownPythonError("Unexpected Python Version",
sys.version_info)
raise UnknownPythonError("Unexpected Python Version", sys.version_info)
return symbols


def generate_result_item(workflow, value, from_currency, to_currency, rates,
icon):
def generate_result_item(workflow, value, from_currency, to_currency, rates, icon):
"""Calculate conversion result and append item to workflow
Arguments:
Expand All @@ -381,29 +434,28 @@ def generate_result_item(workflow, value, from_currency, to_currency, rates,
"""
symbols = load_symbols()
result = str(
_calculate(value, from_currency, to_currency, rates,
workflow.config.precision))
_calculate(value, from_currency, to_currency, rates, workflow.config.precision)
)
result_symboled = "{}{}".format(symbols[to_currency], result)
item = workflow.add_item(title="{} {} = {} {}".format(
value, from_currency, result, to_currency),
subtitle="Copy '{}' to clipboard".format(result),
icon="flags/{}.png".format(icon),
valid=True,
arg=result,
copytext=result)
item = workflow.add_item(
title="{} {} = {} {}".format(value, from_currency, result, to_currency),
subtitle="Copy '{}' to clipboard".format(result),
icon="flags/{}.png".format(icon),
valid=True,
arg=result,
copytext=result,
)
item.add_modifier(
key="alt",
subtitle="Copy '{}' to clipboard".format(result_symboled),
icon="flags/{}.png".format(icon),
valid=True,
arg=result_symboled)
arg=result_symboled,
)
return item


def generate_list_items(query,
currency_codes,
favorite_filter=None,
sort=False):
def generate_list_items(query, currency_codes, favorite_filter=None, sort=False):
"""Generate items from currency codes that can be add to workflow
Arguments:
Expand All @@ -424,13 +476,15 @@ def generate_list_items(query,
items = []
for code in currency_codes:
if currencies_filter(query, code, currencies[code], favorite_filter):
items.append({
"title": currencies[code],
"subtitle": code,
"icon": "flags/{}.png".format(code),
"valid": True,
"arg": code
})
items.append(
{
"title": currencies[code],
"subtitle": code,
"icon": "flags/{}.png".format(code),
"valid": True,
"arg": code,
}
)
if sort:
items = sorted(items, key=lambda item: item["subtitle"])
return items
Expand Down
Empty file.
1 change: 0 additions & 1 deletion src/currency/workflow/version

This file was deleted.

Loading

0 comments on commit 825cc18

Please sign in to comment.