diff --git a/discogs_alert/__main__.py b/discogs_alert/__main__.py index bbf6f19..8c23bb6 100644 --- a/discogs_alert/__main__.py +++ b/discogs_alert/__main__.py @@ -1,4 +1,5 @@ import logging +import os import time import click @@ -38,6 +39,14 @@ not_required_if="list-id", help="path to your wantlist json file (including filename)", ) +@click.option( + "-ct", + "--currency-token", + required=True, + type=str, + envvar="DA_CURRENCY_TOKEN", + help="A token for the currency conversion API (api.exchangerate.host)", +) @click.option( "-ua", "--user-agent", @@ -192,6 +201,7 @@ def main( discogs_token, list_id, wantlist_path, + currency_token, user_agent, frequency, country, @@ -209,9 +219,11 @@ def main( verbose, test, ): - """This loop queries in your watchlist at regular intervals, sending alerts if a release satisfying - your criteria is found. """ + This loop queries your watchlist at regular intervals, alerting you if a release satisfying your criteria is found. + """ + + os.environ["DA_CURRENCY_TOKEN"] = currency_token # if both a list ID and a local wantlist path are provided, use the wantlist (to force-enable local testing) # TODO: combine them? diff --git a/discogs_alert/util/currency.py b/discogs_alert/util/currency.py index 248f49e..36901a5 100644 --- a/discogs_alert/util/currency.py +++ b/discogs_alert/util/currency.py @@ -1,3 +1,4 @@ +import os from typing import Dict, Union import requests @@ -12,10 +13,9 @@ class InvalidCurrencyException(Exception): ... -@time_cache(seconds=3600) +@time_cache(seconds=86400) def get_currency_rates(base_currency: str) -> CurrencyRates: - """Get live currency exchange rates (from one base currency). Cached for one hour at a time, - per currency. + """Get live currency exchange rates (from one base currency). Cached for one day at a time, per currency. Args: base_currency: one of the 3-character currency identifiers from above. @@ -25,7 +25,13 @@ def get_currency_rates(base_currency: str) -> CurrencyRates: if base_currency not in CURRENCY_CHOICES: raise InvalidCurrencyException(f"{base_currency} is not a supported currency (see `discogs_alert/types.py`).") - return requests.get(f"https://api.exchangerate.host/latest?base={base_currency}").json().get("rates") + + access_key = os.getenv("DA_CURRENCY_TOKEN") + return ( + requests.get(f"http://api.exchangerate.host/live?access_key={access_key}&source={base_currency}") + .json() + .get("quotes") + ) def convert_currency(value: float, old_currency: str, new_currency: str) -> float: @@ -40,6 +46,6 @@ def convert_currency(value: float, old_currency: str, new_currency: str) -> floa """ try: - return float(value) / get_currency_rates(new_currency)[old_currency] + return float(value) / get_currency_rates(new_currency)[f"{new_currency}{old_currency}"] except KeyError: raise InvalidCurrencyException(f"{old_currency} is not a supported currency (see `discogs_alert/types.py`)") diff --git a/tests/data/currency_rates.json b/tests/data/currency_rates.json index a6b1997..a1e73fb 100644 --- a/tests/data/currency_rates.json +++ b/tests/data/currency_rates.json @@ -1,171 +1,170 @@ { - "AED": 3.897907, - "AFN": 94.768016, - "ALL": 115.194359, - "AMD": 416.022513, - "ANG": 1.914283, - "AOA": 534.648677, - "ARS": 206.873619, - "AUD": 1.555357, - "AWG": 1.91341, - "AZN": 1.804132, - "BAM": 1.955062, - "BBD": 2.123201, - "BDT": 113.773783, - "BGN": 1.954349, - "BHD": 0.400535, - "BIF": 2206.658158, - "BMD": 1.061802, - "BND": 1.423633, - "BOB": 7.339559, - "BRL": 5.467703, - "BSD": 1.061596, - "BTC": 4.3e-05, - "BTN": 87.936222, - "BWP": 14.050659, - "BYN": 2.681676, - "BZD": 2.14144, - "CAD": 1.435974, - "CDF": 2209.342916, - "CHF": 0.987368, - "CLF": 0.03116, - "CLP": 848.933175, - "CNH": 7.313025, - "CNY": 7.305979, - "COP": 5270.596689, - "CRC": 592.616742, - "CUC": 1.062235, - "CUP": 27.325147, - "CVE": 110.181451, - "CZK": 23.663593, - "DJF": 189.117314, - "DKK": 7.440961, - "DOP": 59.47652, - "DZD": 145.350485, - "EGP": 32.511698, - "ERN": 15.918355, - "ETB": 57.114144, - "EUR": 1, - "FJD": 2.335873, - "FKP": 0.880851, - "GBP": 0.881433, - "GEL": 2.796552, - "GGP": 0.880601, - "GHS": 13.650247, - "GIP": 0.881144, - "GMD": 64.837869, - "GNF": 9140.514663, - "GTQ": 8.30433, - "GYD": 224.11919, - "HKD": 8.32407, - "HNL": 26.188059, - "HRK": 7.528459, - "HTG": 158.559346, - "HUF": 380.851942, - "IDR": 16113.673311, - "ILS": 3.854084, - "IMP": 0.880943, - "INR": 87.829116, - "IQD": 1550.26996, - "IRR": 44940.376637, - "ISK": 152.809042, - "JEP": 0.881188, - "JMD": 163.841184, - "JOD": 0.752829, - "JPY": 143.066228, - "KES": 133.940892, - "KGS": 92.767718, - "KHR": 4312.729875, - "KMF": 491.160683, - "KPW": 955.050638, - "KRW": 1376.03754, - "KWD": 0.326703, - "KYD": 0.885634, - "KZT": 477.302397, - "LAK": 17907.236579, - "LBP": 15943.110538, - "LKR": 387.6904, - "LRD": 167.4522, - "LSL": 19.403048, - "LYD": 5.115174, - "MAD": 11.043256, - "MDL": 19.964129, - "MGA": 4546.618615, - "MKD": 61.568441, - "MMK": 2230.638105, - "MNT": 3615.356528, - "MOP": 8.584437, - "MRU": 38.590114, - "MUR": 48.972887, - "MVR": 16.289475, - "MWK": 1090.2561, - "MXN": 19.47122, - "MYR": 4.708764, - "MZN": 67.915036, - "NAD": 19.388261, - "NGN": 488.597606, - "NIO": 38.812196, - "NOK": 10.9565, - "NPR": 140.699409, - "NZD": 1.699364, - "OMR": 0.409066, - "PAB": 1.062028, - "PEN": 4.073505, - "PGK": 3.743112, - "PHP": 58.401571, - "PKR": 278.024539, - "PLN": 4.746736, - "PYG": 7777.701586, - "QAR": 3.876872, - "RON": 4.913771, - "RSD": 117.257046, - "RUB": 79.604056, - "RWF": 1170.134525, - "SAR": 3.981201, - "SBD": 8.773145, - "SCR": 13.943644, - "SDG": 623.435381, - "SEK": 11.03444, - "SGD": 1.421805, - "SHP": 0.881369, - "SLL": 18745.496217, - "SOS": 603.847757, - "SRD": 35.350677, - "SSP": 138.228062, - "STD": 24220.040686, - "STN": 24.481645, - "SVC": 9.293838, - "SYP": 2666.212256, - "SZL": 19.402013, - "THB": 36.697724, - "TJS": 11.360375, - "TMT": 3.725065, - "TND": 3.345002, - "TOP": 2.486172, - "TRY": 20.036823, - "TTD": 7.207982, - "TWD": 32.195893, - "TZS": 2482.067119, - "UAH": 39.036552, - "UGX": 3939.589981, - "USD": 1.062261, - "UYU": 41.720212, - "UZS": 12020.483674, - "VES": 25.861576, - "VND": 25280.91297, - "VUV": 125.26485, - "WST": 2.862533, - "XAF": 655.538929, - "XAG": 0.04947, - "XAU": 0.001345, - "XCD": 2.868686, - "XDR": 0.796831, - "XOF": 655.539065, - "XPD": 0.001881, - "XPF": 119.256617, - "XPT": 0.001416, - "YER": 265.664202, - "ZAR": 19.333621, - "ZMW": 20.813546, - "ZWL": 341.696168 + "EURAED": 4.00965, + "EURAFN": 75.018901, + "EURALL": 103.920772, + "EURAMD": 437.476958, + "EURANG": 1.957849, + "EURAOA": 903.570398, + "EURARS": 384.006996, + "EURAUD": 1.676099, + "EURAWG": 1.964957, + "EURAZN": 1.860127, + "EURBAM": 1.95525, + "EURBBD": 2.193383, + "EURBDT": 120.306163, + "EURBGN": 1.95964, + "EURBHD": 0.409685, + "EURBIF": 3087.531618, + "EURBMD": 1.091643, + "EURBND": 1.460289, + "EURBOB": 7.506889, + "EURBRL": 5.355496, + "EURBSD": 1.086294, + "EURBTC": 2.9743319e-05, + "EURBTN": 90.447761, + "EURBWP": 14.571902, + "EURBYN": 3.578494, + "EURBYR": 21396.202226, + "EURBZD": 2.189684, + "EURCAD": 1.497898, + "EURCDF": 2866.654836, + "EURCHF": 0.966941, + "EURCLF": 0.034535, + "EURCLP": 952.921987, + "EURCNY": 7.871514, + "EURCOP": 4439.651329, + "EURCRC": 577.337621, + "EURCUC": 1.091643, + "EURCUP": 28.928539, + "EURCVE": 110.233996, + "EURCZK": 24.489537, + "EURDJF": 193.415601, + "EURDKK": 7.458764, + "EURDOP": 61.692649, + "EURDZD": 146.66446, + "EUREGP": 33.594451, + "EURERN": 16.374645, + "EURETB": 60.756612, + "EURFJD": 2.498666, + "EURFKP": 0.878435, + "EURGBP": 0.876329, + "EURGEL": 2.942022, + "EURGGP": 0.878435, + "EURGHS": 12.989347, + "EURGIP": 0.878435, + "EURGMD": 73.413415, + "EURGNF": 9334.374667, + "EURGTQ": 8.505608, + "EURGYD": 227.276078, + "EURHKD": 8.511814, + "EURHNL": 26.831454, + "EURHRK": 7.68688, + "EURHTG": 144.149457, + "EURHUF": 379.215358, + "EURIDR": 16837.828673, + "EURILS": 4.05755, + "EURIMP": 0.878435, + "EURINR": 90.924854, + "EURIQD": 1423.099747, + "EURIRR": 46135.565218, + "EURISK": 152.895936, + "EURJEP": 0.878435, + "EURJMD": 169.282389, + "EURJOD": 0.774307, + "EURJPY": 163.238875, + "EURKES": 165.443468, + "EURKGS": 97.293557, + "EURKHR": 4475.741179, + "EURKMF": 495.196586, + "EURKPW": 982.491758, + "EURKRW": 1415.184533, + "EURKWD": 0.336543, + "EURKYD": 0.905245, + "EURKZT": 504.048234, + "EURLAK": 22526.664279, + "EURLBP": 16327.407846, + "EURLKR": 356.339778, + "EURLRD": 205.065549, + "EURLSL": 20.053898, + "EURLTL": 3.223338, + "EURLVL": 0.660324, + "EURLYD": 5.26352, + "EURMAD": 11.017801, + "EURMDL": 19.374551, + "EURMGA": 4920.616056, + "EURMKD": 61.597675, + "EURMMK": 2281.258386, + "EURMNT": 3763.112256, + "EURMOP": 8.726346, + "EURMRO": 389.716353, + "EURMUR": 48.207367, + "EURMVR": 16.866297, + "EURMWK": 1828.685674, + "EURMXN": 18.807484, + "EURMYR": 5.100706, + "EURMZN": 69.046364, + "EURNAD": 20.053893, + "EURNGN": 917.024173, + "EURNIO": 39.758818, + "EURNOK": 11.783075, + "EURNPR": 144.716298, + "EURNZD": 1.820619, + "EUROMR": 0.420217, + "EURPAB": 1.086294, + "EURPEN": 4.201418, + "EURPGK": 4.103846, + "EURPHP": 60.474296, + "EURPKR": 311.230565, + "EURPLN": 4.386266, + "EURPYG": 8072.72951, + "EURQAR": 3.974714, + "EURRON": 4.977678, + "EURRSD": 117.207035, + "EURRUB": 97.538707, + "EURRWF": 1339.823169, + "EURSAR": 4.094218, + "EURSBD": 9.191265, + "EURSCR": 14.320772, + "EURSDG": 656.077796, + "EURSEK": 11.564833, + "EURSGD": 1.467391, + "EURSHP": 1.328257, + "EURSLE": 24.490293, + "EURSLL": 21559.949041, + "EURSOS": 623.328506, + "EURSRD": 41.640763, + "EURSTD": 22594.805475, + "EURSYP": 14193.347758, + "EURSZL": 19.885407, + "EURTHB": 38.639253, + "EURTJS": 11.884357, + "EURTMT": 3.82075, + "EURTND": 3.399926, + "EURTOP": 2.600335, + "EURTRY": 31.307888, + "EURTTD": 7.376925, + "EURTWD": 34.659341, + "EURTZS": 2713.636778, + "EURUAH": 39.236265, + "EURUGX": 4105.845213, + "EURUSD": 1.091643, + "EURUYU": 43.147864, + "EURUZS": 13340.247998, + "EURVEF": 3861416.594396, + "EURVES": 38.607661, + "EURVND": 26488.716684, + "EURVUV": 132.260957, + "EURWST": 3.025362, + "EURXAF": 655.772561, + "EURXAG": 0.04601, + "EURXAU": 0.000551, + "EURXCD": 2.95022, + "EURXDR": 0.820169, + "EURXOF": 655.772561, + "EURXPF": 120.572363, + "EURYER": 273.351325, + "EURZAR": 20.024193, + "EURZMK": 9826.100628, + "EURZMW": 25.229904, + "EURZWL": 351.508591 } \ No newline at end of file diff --git a/tests/test_entities.py b/tests/test_entities.py index 9f4b54d..f18c92b 100644 --- a/tests/test_entities.py +++ b/tests/test_entities.py @@ -13,19 +13,19 @@ def test_convert_listing_price_currency(mock_currency_rates, rates: da_currency. # full listing price lp1 = da_entities.ListingPrice("GBP", 10, shipping=da_entities.ShippingPrice("GBP", 5)) lp1_target = da_entities.ListingPrice( - "EUR", 10 / rates["GBP"], shipping=da_entities.ShippingPrice("EUR", 5 / rates["GBP"]) + "EUR", 10 / rates["EURGBP"], shipping=da_entities.ShippingPrice("EUR", 5 / rates["EURGBP"]) ) assert lp1.convert_currency("EUR") == lp1_target # no shipping lp2 = da_entities.ListingPrice("GBP", 10, shipping=None) - lp2_target = da_entities.ListingPrice("EUR", 10 / rates["GBP"], shipping=None) + lp2_target = da_entities.ListingPrice("EUR", 10 / rates["EURGBP"], shipping=None) assert lp2.convert_currency("EUR") == lp2_target # different currencies lp3 = da_entities.ListingPrice("GBP", 10, shipping=da_entities.ShippingPrice("AUD", 5)) lp3_target = da_entities.ListingPrice( - "EUR", 10 / rates["GBP"], shipping=da_entities.ShippingPrice("EUR", 5 / rates["AUD"]) + "EUR", 10 / rates["EURGBP"], shipping=da_entities.ShippingPrice("EUR", 5 / rates["EURAUD"]) ) assert lp3.convert_currency("EUR") == lp3_target diff --git a/tests/util/test_currency.py b/tests/util/test_currency.py index 97ba6be..80d66b5 100644 --- a/tests/util/test_currency.py +++ b/tests/util/test_currency.py @@ -27,9 +27,8 @@ def test_convert_currency(mock_currency_rates, rates: da_currency.CurrencyRates) assert da_currency.get_currency_rates("SGD") == da_currency.get_currency_rates("EUR") # make sure the currency conversion is working correctly - assert da_currency.convert_currency(1, "GBP", "EUR") == 1 / rates.get("GBP") - assert da_currency.convert_currency(1, "CHF", "EUR") == 1 / rates.get("CHF") - assert da_currency.convert_currency(1, "EUR", "GBP") == 1 # doesn't make sense given that our mocked rates are EUR + assert da_currency.convert_currency(1, "GBP", "EUR") == 1 / rates.get("EURGBP") + assert da_currency.convert_currency(1, "CHF", "EUR") == 1 / rates.get("EURCHF") # make sure invalid currencies are handled with pytest.raises(da_currency.InvalidCurrencyException):