Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 22 additions & 25 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,38 @@ name: Testing

on:
push:
branches: [ develop, master ]
branches: [develop, master]
pull_request:
branches: [ develop, master ]
branches: [develop, master]

env:
PYTHON: python3.11

jobs:
code-quality:
test:
runs-on: ubuntu-latest
continue-on-error: false

steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: "3.11"
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt

- name: Install dependencies
run: |
sudo apt-get update
python -m pip install --upgrade pip
python -m pip install --upgrade pip-tools
make venv
- uses: actions/cache@v2
id: cache-venv
with:
path: ./.venv/ # we cache: the virtualenv
# The cache key depends on requirements*.txt
key: v4-${{ runner.os }}-${{ matrix.python-version }}-venv-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
v4-${{ runner.os }}-${{ matrix.python-version }}-venv-
# Build a virtualenv, but only if it doesn't already exist
- name: Make venv
run: make venv
if: steps.cache-venv.outputs.cache-hit != 'true'
- name: Sync dependencies
run: make pip-sync-dev
- name: Check linting
make pip-sync-dev

- name: Run lint and formatting checks
run: make lint
- name: Testing

- name: Run tests
run: make test
25 changes: 12 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
PYTHON ?= python3

test:
@. .venv/bin/activate && ${env} python3 -m pytest -vvv --cov=. --cov-report term-missing
@. .venv/bin/activate && ${env} ${PYTHON} -m pytest -vvv --cov=. --cov-report term-missing
venv: .venv/make_venv_complete ## Create virtual environment
.venv/make_venv_complete:
python3 -m venv .venv
${PYTHON} -m venv .venv
. .venv/bin/activate && ${env} pip install -U pip
. .venv/bin/activate && ${env} pip install -U pip-tools
. .venv/bin/activate && ${env} python3 -m piptools compile requirements.in
. .venv/bin/activate && ${env} python3 -m piptools compile requirements-dev.in
. .venv/bin/activate && ${env} pip install -Ur requirements.txt
. .venv/bin/activate && ${env} pip install -Ur requirements-dev.txt
touch .venv/make_venv_complete

pip-compile: ## synchronizes the .venv with the state of requirements.txt
. .venv/bin/activate && ${env} python3 -m piptools compile requirements.in
. .venv/bin/activate && ${env} python3 -m piptools compile requirements-dev.in
. .venv/bin/activate && ${env} ${PYTHON} -m piptools compile requirements.in
. .venv/bin/activate && ${env} ${PYTHON} -m piptools compile requirements-dev.in

pip-sync: ## synchronizes the .venv with the state of requirements.txt
. .venv/bin/activate && ${env} python3 -m piptools sync requirements.txt
. .venv/bin/activate && ${env} ${PYTHON} -m piptools sync requirements.txt

pip-sync-dev: ## synchronizes the .venv with the state of requirements.txt
. .venv/bin/activate && ${env} pip install -U pip-tools
. .venv/bin/activate && ${env} python3 -m piptools sync requirements.txt requirements-dev.txt
. .venv/bin/activate && ${env} ${PYTHON} -m piptools sync requirements.txt requirements-dev.txt

lint: venv ## Do basic linting
@. .venv/bin/activate && ${env} python3 -m pylint kassa.py plugins
@. .venv/bin/activate && ${env} python3 -m black --check .
@. .venv/bin/activate && ${env} ${PYTHON} -m pylint --persistent=no kassa.py plugins
@. .venv/bin/activate && ${env} ${PYTHON} -m black --check kassa.py plugins tests

check-types: venv ## Check for type issues with mypy
@. .venv/bin/activate && ${env} python3 -m mypy --check .
@. .venv/bin/activate && ${env} ${PYTHON} -m mypy --check .

fix:
@. .venv/bin/activate && ${env} python3 -m black .

@. .venv/bin/activate && ${env} ${PYTHON} -m black kassa.py plugins tests
76 changes: 36 additions & 40 deletions kassa.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import glob
import os
import time
import json
import sys
Expand Down Expand Up @@ -43,13 +44,13 @@ def __init__(self, SID, client):
def startup(self):
print("Startup", self.SID)
for fname in glob.glob("plugins/*.py"):
plugname = fname.split("/")[1].rstrip(".py")
plugname = os.path.splitext(os.path.basename(fname))[0]
if plugname != "__init__" and not plugname in self.plugins:
if plugname in sys.modules:
del sys.modules[plugname]
print(self.plugins)
for fname in glob.glob("plugins/*.py"):
plugname = fname.split("/")[1].rstrip(".py")
plugname = os.path.splitext(os.path.basename(fname))[0]
print(plugname)
if plugname != "__init__" and not plugname in self.plugins:
if plugname in sys.modules:
Expand Down Expand Up @@ -101,45 +102,49 @@ def callhook(self, hook, arg):
def donext(self, plug, function):
self.nextcall = {"plug": plug, "function": function}

def input(self, text): # pylint: disable=too-many-branches
if not text:
self.send_message(True, "message", "Enter product, command or username")
self.send_message(True, "buttons", json.dumps({}))
return

self.buttons = {}
done = 0

for plug, plugin in self.plugins.items():
def pre_input(self, text):
for _plug, plugin in self.plugins.items():
try:
plugin.pre_input(text)
except AttributeError:
pass
except:
print(traceback.format_exc())

self.prompt = ""
def handle_nextcall(self, text):
if not self.nextcall:
return False
try:
plug = self.nextcall["plug"]
func = self.nextcall["function"]
self.nextcall = {}
print(text)
print(self.nextcall)
print(getattr(plug, func))
return bool(getattr(plug, func)(text))
except:
print(traceback.format_exc())
return False

if self.nextcall:
try:
plug = self.nextcall["plug"]
func = self.nextcall["function"]
self.nextcall = {}
print(text)
print(self.nextcall)
print(getattr(plug, func))
if getattr(plug, func)(text):
done = 1
except:
print(traceback.format_exc())
def input(self, text):
if not text:
self.send_message(True, "message", "Enter product, command or username")
self.send_message(True, "buttons", json.dumps({}))
return

self.buttons = {}
self.pre_input(text)

self.prompt = ""

if done == 0:
done = self.handle_nextcall(text)
if not done:
parts = text.split()
for part in parts:
if part:
done = self.handle_part(part) # Call handle_part for each part

if done == 1 and not self.prompt:
if done and not self.prompt:
self.send_message(True, "message", "Enter product, command or username")
elif not self.prompt:
self.send_message(True, "message", "Unknown product, command or username")
Expand All @@ -149,19 +154,10 @@ def input(self, text): # pylint: disable=too-many-branches
self.send_message(True, "buttons", json.dumps({}))

def handle_part(self, part):
done = 0
if self.nextcall:
try:
plug = self.nextcall["plug"]
func = self.nextcall["function"]
self.nextcall = {}
if getattr(plug, func)(part):
done = 1
except:
print(traceback.format_exc())
done = self.handle_nextcall(part)

if done == 0:
for plug, plugin in self.plugins.items():
if not done:
for _plug, plugin in self.plugins.items():
try:
if plugin.input(part):
done = 1
Expand All @@ -171,7 +167,7 @@ def handle_part(self, part):
except:
print(traceback.format_exc())

if done == 0:
if not done:
if self.plugins.get("withdraw") and self.plugins["withdraw"].withdraw(part):
done = 1
if self.plugins.get("accounts") and self.plugins["accounts"].newuser(part):
Expand Down
16 changes: 12 additions & 4 deletions plugins/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ class accounts:
def __init__(self, SID, master):
self.master = master
self.SID = SID
self.accounts = {}
self.aliases = {}
self.members = []
self.newaccount = ""
self.adduseralias = ""

def help(self):
return {"adduseralias": "Add user key alias"}
Expand Down Expand Up @@ -94,7 +99,10 @@ def hook_abort(self, _void):

def createnew(self, text):
if text == "yes":
self.accounts[self.newaccount] = {"amount": 0, "lastupdate": 0}
self.accounts[self.newaccount] = {
"amount": 0,
"lastupdate": time.strftime("%Y-%m-%d_%H:%M:%S"),
}
return self.input(self.newaccount)
if text == "no":
return True
Expand All @@ -120,12 +128,12 @@ def createnew(self, text):

def startup(self):
self.readaccounts()
self.get_last_updated_accounts()
for name, account in self.accounts.items():
self.master.send_message(True, "accounts/" + name, json.dumps(account))
with open("data/revbank.members", encoding="utf-8") as f:
self.members = f.readlines()
self.members = [m.rstrip() for m in self.members]
self.get_last_updated_accounts()
for name, account in self.accounts.items():
self.master.send_message(True, "accounts/" + name, json.dumps(account))
self.master.send_message(True, "members", json.dumps(self.members))

def hook_pre_checkout(self, _text):
Expand Down
12 changes: 11 additions & 1 deletion plugins/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ def writeproducts(self):
def __init__(self, SID, master):
self.master = master
self.SID = SID
self.products = {}
self.aliases = {}
self.groups = {}
self.times = 1
self.aliasprod = ""
self.priceprod = 0
self.newprodprice = 0
self.newprodgroup = ""
self.newproddesc = ""
self.newprod = ""

def lookupprod(self, text):
prod = None
Expand Down Expand Up @@ -175,7 +185,7 @@ def addproductgroup(self, text):
)
return True
self.newprodgroup = text
if not self.newprodgroup in self.groups:
if self.newprodgroup not in self.groups:
self.groups[self.newprodgroup] = [self.newprod]
self.products[self.newprod] = {
"price": self.newprodprice,
Expand Down
12 changes: 11 additions & 1 deletion plugins/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ def writeproducts(self):
def __init__(self, SID, master):
self.master = master
self.SID = SID
self.products = {}
self.aliases = {}
self.groups = {}
self.times = 1
self.aliasprod = ""
self.priceprod = ""
self.newprodprice = 0
self.newprodgroup = ""
self.newproddesc = ""
self.newprod = ""

def lookupprod(self, text):
prod = None
Expand Down Expand Up @@ -179,7 +189,7 @@ def addproductgroup(self, text):
)
return True
self.newprodgroup = text
if not self.newprodgroup in self.groups:
if self.newprodgroup not in self.groups:
self.groups[self.newprodgroup] = [self.newprod]
self.products[self.newprod] = {
"price": self.newprodprice,
Expand Down
Loading
Loading