3 # Copyright 2021 Oskar Sharipov <oskarsh[at]riseup[dot]net
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
19 from typing
import List
, Optional
23 from requests
.exceptions
import ConnectionError
, Timeout
, TooManyRedirects
25 logging
.basicConfig(format
="%(asctime)s - %(levelname)s - %(message)s")
26 BASE_URL
= "https://pro-api.coinmarketcap.com/v1/{}"
29 Every element must be the same structure:
31 "sign_of_when_cell": (
32 "the string used in \"currency costs {} it was expected\"",
33 lambda asked, from_cap: whether_approaches(asked, from_cap)),
38 ">": ("more than", lambda asked
, from_cap
: from_cap
> asked
),
39 "<": ("less than", lambda asked
, from_cap
: from_cap
< asked
),
43 def currencies(key
: str, symbols
: List
[str]):
44 headers
= {"Accepts": "application/json", "X-CMC_PRO_API_KEY": key
}
45 params
= {"symbol": ",".join(symbols
)}
47 url
= BASE_URL
.format("cryptocurrency/quotes/latest")
49 response
= requests
.get(url
, params
=params
, headers
=headers
)
53 'Couldn\'t fetch currency listings. Possibly "key" is invalid.'
57 except (ConnectionError
, Timeout
, TooManyRedirects
) as e
:
58 logging
.error("Couldn't fetch currency listings: %s.", e
)
62 def cmp_function(s
: str, msg
: Optional
[str] = None):
64 than_what
= float(s
[1:])
65 then_what
, then_how
= WHEN_TRANSLATER
[s
[0]]
69 + " it was expected. Its current price is {price:.4f} USD."
72 then_what
+= f
" Message: {msg}"
73 f
= lambda from_cap
: then_what
if then_how(than_what
, from_cap
) else None
75 except (IndexError, ValueError, KeyError):
76 logging
.error('Asked "when" is a trash: "%s".', s
)
82 document
= hjson
.load(sys
.stdin
)
85 except hjson
.scanner
.HjsonDecodeError
as e
:
86 logging
.error("Invalid syntax in stdin: %s", e
)
89 logging
.error('No "key" or "watch" cell in stdin.')
93 for el
in document
["watch"]:
94 asked
.add(el
["symbol"])
96 quotes
= currencies(document
["key"], list(asked
))
100 watching
= document
["watch"]
101 functions
= [None] * len(watching
)
102 for i
, w
in enumerate(watching
):
103 functions
[i
] = cmp_function(w
["when"], w
.get("msg"))
106 for currency
in quotes
.values():
107 for i
in range(len(watching
)):
108 if watching
[i
]["symbol"] != currency
["symbol"]:
111 s
= functions
[i
](currency
["quote"]["USD"]["price"])
114 "Fetched currency listings are ugly. Where is the price placed?\n%s",
115 hjson
.dumps(currency
),
120 symbol
=currency
["symbol"], price
=currency
["quote"]["USD"]["price"]
128 if __name__
== "__main__":
131 logging
.info("Terminating...")