refactor!: rewrite in python

This commit is contained in:
AngeD 2023-07-14 17:29:18 +02:00
parent b9c6d533c2
commit f2a906633c
6 changed files with 204 additions and 206 deletions

222
.gitignore vendored
View File

@ -1,60 +1,176 @@
# Created by https://www.toptal.com/developers/gitignore/api/c # Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=c # Edit at https://www.toptal.com/developers/gitignore?templates=python
### C ### ### Python ###
# Prerequisites # Byte-compiled / optimized / DLL files
*.d __pycache__/
*.py[cod]
*$py.class
# Object files # C extensions
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so *.so
*.so.*
*.dylib
# Executables # Distribution / packaging
*.exe .Python
*.out build/
*.app develop-eggs/
*.i*86 dist/
*.x86_64 downloads/
*.hex eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# Debug files # PyInstaller
*.dSYM/ # Usually these files are written by a python script from a template
*.su # before PyInstaller builds the exe, so as to inject date/other infos into it.
*.idb *.manifest
*.pdb *.spec
# Kernel Module Compile Results # Installer logs
*.mod* pip-log.txt
*.cmd pip-delete-this-directory.txt
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# End of https://www.toptal.com/developers/gitignore/api/c # Unit test / coverage reports
config.h htmlcov/
crypto .tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python

View File

@ -1,34 +0,0 @@
CFLAGS := -Wall -Wpedantic -Wextra -MMD
LDFLAGS := -lcurl
SRC := crypto.c \
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
NAME := crypto
all: crypto
$(OBJ): config.h
config.h:
cp config.def.h $@
$(NAME): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ)
clean:
$(RM) $(OBJ) $(DEP)
fclean: clean
$(RM) $(NAME)
re: fclean
$(MAKE)
debug: fclean
CFLAGS=-g3 $(MAKE)
.PHONY: all clean fclean re debug
-include $(DEP)

View File

@ -1,25 +1,13 @@
# crypto # crypto
Get your current holding in crypto from Binance in your own currency. Get your current holding in crypto from CoinGecko in your own currency.
Makefile inspired from suckless
## Dependencies
### Arch
```console
# pacman -S curl
```
### Debian 11+
```console
# apt-get install libcurl4-dev
```
## How-To ## How-To
Set your coins, your currency and the format you want the output in crypto
You can get a list of valid id with:
```console ```console
$ make $ curl https://api.coingecko.com/api/v3/coins/list
``` ```
Set your settings in config.h
```console ```console
$ make
$ ./crypto $ ./crypto
``` ```

View File

@ -1,12 +0,0 @@
#define FMT "%s=$%.2f"
// curl https://api.coingecko.com/api/v3/simple/supported_vs_currencies
#define VS "usd"
// curl https://api.coingecko.com/api/v3/coins/list
static const struct wallet_s {
char *id; char *fmt;
} WALLET[] = {
{"bitcoin", "BTC"},
{0},
};

30
crypto Executable file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env python3
import json
import requests
# [[id, symbol]]
COINS = [
["bitcoin", "BTC"],
]
CUR = "usd"
FMT = "{coin}=${price:.0f}"
def main():
coin_ids = ",".join([coin for coin in list(zip(*COINS))[0]])
url = f"https://api.coingecko.com/api/v3/simple/price?ids={coin_ids}&vs_currencies={CUR}"
# {'bitcoin': {'usd': 69420}}
prices = json.loads(requests.get(url).text)
print(
*[
FMT.format(coin=coin[1], price=prices[coin[0]][CUR])
for coin in COINS
]
)
if __name__ == "__main__":
main()

View File

@ -1,90 +0,0 @@
#include <curl/curl.h>
#include <errno.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include "config.h"
#define ARRLEN(a) (sizeof (a) / sizeof *(a))
#define BUF_SIZE 256 * ARRLEN(WALLET)
// {"bitcoin":{"usd":69420.69}}
static int get_next_symbol(char *buf, float *price)
{
static const char output[] = "\"%*[a-z]\":{\"" VS "\":%f}";
char *tmp = strtok(buf, ",");
if (!tmp) {
return 1;
}
return !sscanf(tmp, output, price);
}
static size_t write_callback(char *response, size_t s, size_t n, void *buf)
{
return snprintf(buf, MIN(s * n, BUF_SIZE), response);
}
static char *build_url(void)
{
const char base[] =
"https://api.coingecko.com/api/v3/simple/price?ids=%s&vs_currencies="
VS;
size_t ids_size = 0;
char *url;
char ids[BUF_SIZE] = {0};
for (size_t i = 0; WALLET[i].id; i++) {
strcpy(ids + ids_size, WALLET[i].id);
ids_size += strlen(WALLET[i].id);
ids[ids_size++] = ',';
}
ids[ids_size - 1] = '\0';
url = malloc(sizeof base + ids_size * (sizeof *url));
if (!url) {
return NULL;
}
sprintf(url, base, ids);
return url;
}
static int perform_request(char *response)
{
char *url = build_url();
CURL *curl = curl_easy_init();
if (!url || !curl) {
free(url);
curl_easy_cleanup(curl);
return 1;
}
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
free(url);
return 0;
}
int main(void)
{
char response[BUF_SIZE];
int err = perform_request(response);
float price;
if (err) {
error(1, errno, "cannot init curl");
}
err = get_next_symbol(response + 1, &price);
for (size_t i = 0; !err && WALLET[i].id; i++) {
if (i) {
printf(" ");
}
printf(FMT, WALLET[i].fmt, price);
err = get_next_symbol(NULL, &price);
}
printf("\n");
return 0;
}