diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3cd155e..7d19372 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -95,28 +95,6 @@ build_debian: only: - tags -build_archlinux: - stage: build - image: archlinux/base:latest # Use an archlinux image instead of the customized debian image. - script: - - pacman -Sy --noconfirm python python-setuptools python-pip python-wheel python-bottle python-jinja python-pillow python-magic base-devel - - export MATEMAT_VERSION=$(python -c 'import matemat; print(matemat.__version__)') - - cp -r static/ package/archlinux/matemat/usr/lib/matemat/static/ - - cp -r templates/ package/archlinux/matemat/usr/lib/matemat/templates/ - - python3 setup.py egg_info -d -b +master install --root=package/archlinux/matemat/ --prefix=/usr --optimize=1 - - cd package/archlinux - - mv matemat/usr/bin/matemat matemat/usr/lib/matemat/matemat - - rm -rf matemat/usr/bin - - sed -re "s/__VERSION__/${MATEMAT_VERSION}/g" -i PKGBUILD - - sudo -u nobody makepkg -c - - sha256sum *.pkg.tar.xz > SHA256SUMS - artifacts: - paths: - - "package/archlinux/*.pkg.tar.xz" - - package/archlinux/SHA256SUMS - only: - - tags - release: stage: deploy diff --git a/CHANGELOG.md b/CHANGELOG.md index d6bb1c9..93cad0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Matemat Changelog + +## Version 0.2.8 + +Feature release + +### Changes + + +- Feature: Add "custom price" products +- Fix: Buying not working when using the NullDispenser +- Breaking: Remove Arch Linux packaging + + + + ## Version 0.2.7 diff --git a/matemat/__init__.py b/matemat/__init__.py index e98cbf8..2a6353a 100644 --- a/matemat/__init__.py +++ b/matemat/__init__.py @@ -1,2 +1,2 @@ -__version__ = '0.2.7' +__version__ = '0.2.8' diff --git a/matemat/db/facade.py b/matemat/db/facade.py index 43a150f..b4eb164 100644 --- a/matemat/db/facade.py +++ b/matemat/db/facade.py @@ -354,11 +354,11 @@ class MatematDatabase(object): products: List[Product] = [] with self.db.transaction(exclusive=False) as c: for row in c.execute(''' - SELECT product_id, name, price_member, price_non_member, stock, stockable + SELECT product_id, name, price_member, price_non_member, custom_price, stock, stockable FROM products '''): - product_id, name, price_member, price_external, stock, stockable = row - products.append(Product(product_id, name, price_member, price_external, stockable, stock)) + product_id, name, price_member, price_external, custom_price, stock, stockable = row + products.append(Product(product_id, name, price_member, price_external, custom_price, stockable, stock)) return products def get_product(self, pid: int) -> Product: @@ -369,7 +369,7 @@ class MatematDatabase(object): with self.db.transaction(exclusive=False) as c: # Fetch all values to construct the product c.execute(''' - SELECT product_id, name, price_member, price_non_member, stock, stockable + SELECT product_id, name, price_member, price_non_member, custom_price, stock, stockable FROM products WHERE product_id = ?''', [pid]) @@ -377,15 +377,16 @@ class MatematDatabase(object): if row is None: raise ValueError(f'No product with product ID {pid} exists.') # Unpack the row and construct the product - product_id, name, price_member, price_non_member, stock, stockable = row - return Product(product_id, name, price_member, price_non_member, stockable, stock) + product_id, name, price_member, price_non_member, custom_price, stock, stockable = row + return Product(product_id, name, price_member, price_non_member, custom_price, stockable, stock) - def create_product(self, name: str, price_member: int, price_non_member: int, stockable: bool) -> Product: + def create_product(self, name: str, price_member: int, price_non_member: int, custom_price: bool, stockable: bool) -> Product: """ Creates a new product. :param name: Name of the product. :param price_member: Price of the product for members. :param price_non_member: Price of the product for non-members. + :param custom_price: Whether the price is customizable. If yes, the price values are understood as minimum. :param stockable: True if the product should be stockable, false otherwise. :return: A Product object representing the created product. :raises ValueError: If a product with the same name already exists. @@ -396,17 +397,18 @@ class MatematDatabase(object): if c.fetchone() is not None: raise ValueError(f'A product with the name \'{name}\' already exists.') c.execute(''' - INSERT INTO products (name, price_member, price_non_member, stock, stockable) - VALUES (:name, :price_member, :price_non_member, 0, :stockable) + INSERT INTO products (name, price_member, price_non_member, custom_price, stock, stockable) + VALUES (:name, :price_member, :price_non_member, :custom_price, 0, :stockable) ''', { 'name': name, 'price_member': price_member, 'price_non_member': price_non_member, + 'custom_price': custom_price, 'stockable': stockable }) c.execute('SELECT last_insert_rowid()') product_id = int(c.fetchone()[0]) - return Product(product_id, name, price_member, price_non_member, stockable, 0) + return Product(product_id, name, price_member, price_non_member, custom_price, stockable, 0) def change_product(self, product: Product, **kwargs) -> None: """ @@ -422,6 +424,7 @@ class MatematDatabase(object): name: str = kwargs['name'] if 'name' in kwargs else product.name price_member: int = kwargs['price_member'] if 'price_member' in kwargs else product.price_member price_non_member: int = kwargs['price_non_member'] if 'price_non_member' in kwargs else product.price_non_member + custom_price: int = kwargs['custom_price'] if 'custom_price' in kwargs else product.custom_price stock: int = kwargs['stock'] if 'stock' in kwargs else product.stock stockable: bool = kwargs['stockable'] if 'stockable' in kwargs else product.stockable with self.db.transaction() as c: @@ -431,6 +434,7 @@ class MatematDatabase(object): name = :name, price_member = :price_member, price_non_member = :price_non_member, + custom_price = :custom_price, stock = :stock, stockable = :stockable WHERE product_id = :product_id @@ -439,6 +443,7 @@ class MatematDatabase(object): 'name': name, 'price_member': price_member, 'price_non_member': price_non_member, + 'custom_price': custom_price, 'stock': stock, 'stockable': stockable }) @@ -450,6 +455,7 @@ class MatematDatabase(object): product.name = name product.price_member = price_member product.price_non_member = price_non_member + product.custom_price = custom_price product.stock = stock product.stockable = stockable @@ -469,15 +475,18 @@ class MatematDatabase(object): raise DatabaseConsistencyError( f'delete_product should affect 1 products row, but affected {affected}') - def increment_consumption(self, user: User, product: Product) -> None: + def increment_consumption(self, user: User, product: Product, custom_price: int = None) -> None: """ Decrement the user's balance by the price of the product and create an entry in the statistics table. :param user: The user buying a product. :param product: The product the user is buying. + :param custom_price: The custom price chosen by the user. :raises DatabaseConsistencyError: If the user or the product does not exist in the database. """ price: int = product.price_member if user.is_member else product.price_non_member + if product.custom_price and custom_price is not None: + price = max(price, custom_price) with self.db.transaction() as c: c.execute(''' INSERT INTO transactions (user_id, value, old_balance) diff --git a/matemat/db/migrations.py b/matemat/db/migrations.py index 6775424..8617b12 100644 --- a/matemat/db/migrations.py +++ b/matemat/db/migrations.py @@ -268,3 +268,11 @@ def migrate_schema_4_to_5(c: sqlite3.Cursor): INSERT INTO products SELECT product_id, name, stock, 1, price_member, price_non_member FROM products_temp ''') c.execute('DROP TABLE products_temp') + + +def migrate_schema_5_to_6(c: sqlite3.Cursor): + # Add custom_price column + c.execute(''' + ALTER TABLE products ADD COLUMN + custom_price INTEGER(1) DEFAULT 0; + ''') diff --git a/matemat/db/primitives/Product.py b/matemat/db/primitives/Product.py index 323d4f7..a99c37b 100644 --- a/matemat/db/primitives/Product.py +++ b/matemat/db/primitives/Product.py @@ -8,17 +8,19 @@ class Product: :param name: The product's name. :param price_member: The price of a unit of this product for users marked as "members". :param price_non_member: The price of a unit of this product for users NOT marked as "members". + :param custom_price: If true, the user can choose the price to pay, but at least the regular price. :param stock: The number of items of this product currently in stock, or None if not stockable. :param stockable: Whether this product is stockable. """ def __init__(self, _id: int, name: str, - price_member: int, price_non_member: int, + price_member: int, price_non_member: int, custom_price: bool, stockable: bool, stock: int) -> None: self.id: int = _id self.name: str = name self.price_member: int = price_member self.price_non_member: int = price_non_member + self.custom_price: bool = custom_price self.stock: int = stock self.stockable: bool = stockable @@ -29,8 +31,9 @@ class Product: self.name == other.name and \ self.price_member == other.price_member and \ self.price_non_member == other.price_non_member and \ + self.custom_price == other.custom_price and \ self.stock == other.stock and \ self.stockable == other.stockable def __hash__(self) -> int: - return hash((self.id, self.name, self.price_member, self.price_non_member, self.stock, self.stockable)) + return hash((self.id, self.name, self.price_member, self.price_non_member, self.custom_price, self.stock, self.stockable)) diff --git a/matemat/db/schemas.py b/matemat/db/schemas.py index cccb638..436c102 100644 --- a/matemat/db/schemas.py +++ b/matemat/db/schemas.py @@ -333,3 +333,83 @@ SCHEMAS[5] = [ ON DELETE SET NULL ON UPDATE CASCADE ); '''] + + +SCHEMAS[6] = [ + ''' + CREATE TABLE users ( + user_id INTEGER PRIMARY KEY, + username TEXT UNIQUE NOT NULL, + email TEXT DEFAULT NULL, + password TEXT NOT NULL, + touchkey TEXT DEFAULT NULL, + is_admin INTEGER(1) NOT NULL DEFAULT 0, + is_member INTEGER(1) NOT NULL DEFAULT 1, + balance INTEGER(8) NOT NULL DEFAULT 0, + lastchange INTEGER(8) NOT NULL DEFAULT 0, + receipt_pref INTEGER(1) NOT NULL DEFAULT 0, + created INTEGER(8) NOT NULL DEFAULT 0 + ); + ''', + ''' + CREATE TABLE products ( + product_id INTEGER PRIMARY KEY, + name TEXT UNIQUE NOT NULL, + stock INTEGER(8) DEFAULT 0, + stockable INTEGER(1) DEFAULT 1, + price_member INTEGER(8) NOT NULL, + price_non_member INTEGER(8) NOT NULL, + custom_price INTEGER(1) DEFAULT 0 + ); + ''', + ''' + CREATE TABLE transactions ( -- "superclass" of the following 3 tables + ta_id INTEGER PRIMARY KEY, + user_id INTEGER DEFAULT NULL, + value INTEGER(8) NOT NULL, + old_balance INTEGER(8) NOT NULL, + date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')), + FOREIGN KEY (user_id) REFERENCES users(user_id) + ON DELETE SET NULL ON UPDATE CASCADE + ); + ''', + ''' + CREATE TABLE consumptions ( -- transactions involving buying a product + ta_id INTEGER PRIMARY KEY, + product TEXT NOT NULL, + FOREIGN KEY (ta_id) REFERENCES transactions(ta_id) + ON DELETE CASCADE ON UPDATE CASCADE + ); + ''', + ''' + CREATE TABLE deposits ( -- transactions involving depositing cash + ta_id INTEGER PRIMARY KEY, + FOREIGN KEY (ta_id) REFERENCES transactions(ta_id) + ON DELETE CASCADE ON UPDATE CASCADE + ); + ''', + ''' + CREATE TABLE modifications ( -- transactions involving balance modification by an admin + ta_id INTEGER NOT NULL, + agent TEXT NOT NULL, + reason TEXT DEFAULT NULL, + PRIMARY KEY (ta_id), + FOREIGN KEY (ta_id) REFERENCES transactions(ta_id) + ON DELETE CASCADE ON UPDATE CASCADE + ); + ''', + ''' + CREATE TABLE receipts ( -- receipts sent to the users + receipt_id INTEGER PRIMARY KEY, + user_id INTEGER NOT NULL, + first_ta_id INTEGER DEFAULT NULL, + last_ta_id INTEGER DEFAULT NULL, + date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')), + FOREIGN KEY (user_id) REFERENCES users(user_id) + ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id) + ON DELETE SET NULL ON UPDATE CASCADE, + FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id) + ON DELETE SET NULL ON UPDATE CASCADE + ); + '''] diff --git a/matemat/db/test/test_facade.py b/matemat/db/test/test_facade.py index d3e34fb..381f37e 100644 --- a/matemat/db/test/test_facade.py +++ b/matemat/db/test/test_facade.py @@ -220,7 +220,7 @@ class DatabaseTest(unittest.TestCase): def test_create_product(self) -> None: with self.db as db: with db.transaction() as c: - db.create_product('Club Mate', 200, 200, True) + db.create_product('Club Mate', 200, 200, True, True) c.execute("SELECT * FROM products") row = c.fetchone() self.assertEqual('Club Mate', row[1]) @@ -228,13 +228,14 @@ class DatabaseTest(unittest.TestCase): self.assertEqual(1, row[3]) self.assertEqual(200, row[4]) self.assertEqual(200, row[5]) + self.assertEqual(1, row[6]) with self.assertRaises(ValueError): - db.create_product('Club Mate', 250, 250, False) + db.create_product('Club Mate', 250, 250, False, False) def test_get_product(self) -> None: with self.db as db: with db.transaction(exclusive=False): - created = db.create_product('Club Mate', 150, 250, False) + created = db.create_product('Club Mate', 150, 250, False, False) product = db.get_product(created.id) self.assertEqual('Club Mate', product.name) self.assertEqual(150, product.price_member) @@ -248,9 +249,9 @@ class DatabaseTest(unittest.TestCase): # Test empty list products = db.list_products() self.assertEqual(0, len(products)) - db.create_product('Club Mate', 200, 200, True) - db.create_product('Flora Power Mate', 200, 200, False) - db.create_product('Fritz Mate', 200, 250, True) + db.create_product('Club Mate', 200, 200, False, True) + db.create_product('Flora Power Mate', 200, 200, False, False) + db.create_product('Fritz Mate', 200, 250, False, True) products = db.list_products() self.assertEqual(3, len(products)) productcheck = {} @@ -272,13 +273,14 @@ class DatabaseTest(unittest.TestCase): def test_change_product(self) -> None: with self.db as db: - product = db.create_product('Club Mate', 200, 200, True) + product = db.create_product('Club Mate', 200, 200, False, True) db.change_product(product, name='Flora Power Mate', price_member=150, price_non_member=250, - stock=None, stockable=False) + custom_price=True, stock=None, stockable=False) # Changes must be reflected in the passed object self.assertEqual('Flora Power Mate', product.name) self.assertEqual(150, product.price_member) self.assertEqual(250, product.price_non_member) + self.assertEqual(True, product.custom_price) self.assertEqual(None, product.stock) self.assertEqual(False, product.stockable) # Changes must be reflected in the database @@ -286,11 +288,13 @@ class DatabaseTest(unittest.TestCase): self.assertEqual('Flora Power Mate', checkproduct.name) self.assertEqual(150, checkproduct.price_member) self.assertEqual(250, checkproduct.price_non_member) + self.assertEqual(True, checkproduct.custom_price) self.assertEqual(None, checkproduct.stock) + self.assertEqual(False, checkproduct.stockable) product.id = -1 with self.assertRaises(DatabaseConsistencyError): db.change_product(product) - product2 = db.create_product('Club Mate', 200, 200, True) + product2 = db.create_product('Club Mate', 200, 200, False, True) product2.name = 'Flora Power Mate' with self.assertRaises(DatabaseConsistencyError): # Should fail, as a product with the same name already exists. @@ -298,8 +302,8 @@ class DatabaseTest(unittest.TestCase): def test_delete_product(self) -> None: with self.db as db: - product = db.create_product('Club Mate', 200, 200, True) - product2 = db.create_product('Flora Power Mate', 200, 200, False) + product = db.create_product('Club Mate', 200, 200, False, True) + product2 = db.create_product('Flora Power Mate', 200, 200, False, False) self.assertEqual(2, len(db.list_products())) db.delete_product(product) @@ -344,9 +348,9 @@ class DatabaseTest(unittest.TestCase): db.deposit(user1, 1337) db.deposit(user2, 4242) db.deposit(user3, 1234) - clubmate = db.create_product('Club Mate', 200, 200, True) - florapowermate = db.create_product('Flora Power Mate', 150, 250, True) - fritzmate = db.create_product('Fritz Mate', 200, 200, True) + clubmate = db.create_product('Club Mate', 200, 200, False , True) + florapowermate = db.create_product('Flora Power Mate', 150, 250, False, True) + fritzmate = db.create_product('Fritz Mate', 200, 200, False, True) # user1 is somewhat addicted to caffeine for _ in range(3): @@ -472,7 +476,7 @@ class DatabaseTest(unittest.TestCase): admin: User = db.create_user('admin', 'supersecurepassword', 'admin@example.com', True, True) user: User = db.create_user('user', 'supersecurepassword', 'user@example.com', True, True) - product: Product = db.create_product('Flora Power Mate', 200, 200, True) + product: Product = db.create_product('Flora Power Mate', 200, 200, False, True) # Create some transactions db.change_user(user, agent=admin, @@ -561,8 +565,8 @@ class DatabaseTest(unittest.TestCase): user2: User = db.create_user('user2', 'supersecurepassword', 'user2@example.com', True, False) user3: User = db.create_user('user3', 'supersecurepassword', 'user3@example.com', True, False) user4: User = db.create_user('user4', 'supersecurepassword', 'user4@example.com', True, False) - flora: Product = db.create_product('Flora Power Mate', 200, 200, True) - club: Product = db.create_product('Club Mate', 200, 200, False) + flora: Product = db.create_product('Flora Power Mate', 200, 200, False, True) + club: Product = db.create_product('Club Mate', 200, 200, False, False) # Create some transactions db.deposit(user1, 1337) diff --git a/matemat/db/wrapper.py b/matemat/db/wrapper.py index 6f09e07..8f4354e 100644 --- a/matemat/db/wrapper.py +++ b/matemat/db/wrapper.py @@ -40,7 +40,7 @@ class DatabaseTransaction(object): class DatabaseWrapper(object): - SCHEMA_VERSION = 5 + SCHEMA_VERSION = 6 def __init__(self, filename: str) -> None: self._filename: str = filename @@ -87,6 +87,8 @@ class DatabaseWrapper(object): migrate_schema_3_to_4(c) if from_version <= 4 and to_version >= 5: migrate_schema_4_to_5(c) + if from_version <= 5 and to_version >= 6: + migrate_schema_5_to_6(c) def connect(self) -> None: if self.is_connected(): diff --git a/matemat/interfacing/dispenser/nulldispenser.py b/matemat/interfacing/dispenser/nulldispenser.py index 3b5fdfb..7aad4b4 100644 --- a/matemat/interfacing/dispenser/nulldispenser.py +++ b/matemat/interfacing/dispenser/nulldispenser.py @@ -4,5 +4,4 @@ from matemat.interfacing.dispenser import Dispenser class NullDispenser(Dispenser): def dispense(self, product, amount): - # no-op - pass + return True diff --git a/matemat/webserver/pagelets/admin.py b/matemat/webserver/pagelets/admin.py index 9b598f5..6ae506a 100644 --- a/matemat/webserver/pagelets/admin.py +++ b/matemat/webserver/pagelets/admin.py @@ -198,9 +198,10 @@ def handle_admin_change(args: FormsDict, files: FormsDict, db: MatematDatabase): name = str(args.name) price_member = parse_chf(str(args.pricemember)) price_non_member = parse_chf(str(args.pricenonmember)) + custom_price = 'custom_price' in args stockable = 'stockable' in args # Create the user in the database - newproduct = db.create_product(name, price_member, price_non_member, stockable) + newproduct = db.create_product(name, price_member, price_non_member, custom_price, stockable) # If a new product image was uploaded, process it image = files.image.file.read() if 'image' in files else None if image is not None and len(image) > 0: diff --git a/matemat/webserver/pagelets/buy.py b/matemat/webserver/pagelets/buy.py index 350b20e..e8e6d51 100644 --- a/matemat/webserver/pagelets/buy.py +++ b/matemat/webserver/pagelets/buy.py @@ -26,8 +26,11 @@ def buy(): pid = int(str(request.params.pid)) product = db.get_product(pid) if c.get_dispenser().dispense(product, 1): + price = None + if 'price' in request.params: + price = int(str(request.params.price)) # Create a consumption entry for the (user, product) combination - db.increment_consumption(user, product) + db.increment_consumption(user, product, price) stock_provider = c.get_stock_provider() if stock_provider.needs_update(): stock_provider.update_stock(product, -1) diff --git a/matemat/webserver/pagelets/modproduct.py b/matemat/webserver/pagelets/modproduct.py index 57afc0f..9200f62 100644 --- a/matemat/webserver/pagelets/modproduct.py +++ b/matemat/webserver/pagelets/modproduct.py @@ -93,13 +93,14 @@ def handle_change(args: FormsDict, files: FormsDict, product: Product, db: Matem name = str(args.name) price_member = parse_chf(str(args.pricemember)) price_non_member = parse_chf(str(args.pricenonmember)) + custom_price = 'custom_price' in args stock = int(str(args.stock)) stockable = 'stockable' in args # Attempt to write the changes to the database try: db.change_product(product, name=name, price_member=price_member, price_non_member=price_non_member, - stock=stock, stockable=stockable) + custom_price=custom_price, stock=stock, stockable=stockable) stock_provider = get_stock_provider() if stock_provider.needs_update() and product.stockable: stock_provider.set_stock(product, stock) diff --git a/package/archlinux/PKGBUILD b/package/archlinux/PKGBUILD deleted file mode 100644 index e41b2e1..0000000 --- a/package/archlinux/PKGBUILD +++ /dev/null @@ -1,30 +0,0 @@ - -# Maintainer: s3lph - -pkgname=matemat -pkgver=0.2.4 -pkgrel=1 -arch=('any') - -pkgdesc='A soda machine stock-keeping webservice' -url='https://gitlab.com/s3lph/matemat' -licence=('MIT') - -depends=( - 'python' - 'python-bottle' - 'python-jinja' - 'python-pillow' - 'python-magic' - 'file' -) - -backup=( - 'etc/matemat.conf' -) - -install=$pkgname.install - -package() { - cp -r ../matemat/* ../pkg/matemat/ -} diff --git a/package/archlinux/matemat.install b/package/archlinux/matemat.install deleted file mode 100755 index dcd0e22..0000000 --- a/package/archlinux/matemat.install +++ /dev/null @@ -1,31 +0,0 @@ - -post_install() { - - if ! getent group matemat >/dev/null; then - groupadd --system matemat - fi - - if ! getent passwd matemat >/dev/null; then - useradd --system --create-home --gid matemat --home-dir /var/lib/matemat --shell /usr/bin/nologin matemat - fi - - chown matemat:matemat /var/lib/matemat - chmod 0750 /var/lib/matemat - ln -sf /var/lib/matemat/upload /usr/lib/matemat/static/upload - - systemctl daemon-reload - -} - -pre_remove() { - - systemctl stop matemat.service - userdel matemat - -} - -post_remove() { - - systemctl daemon-reload - -} diff --git a/package/archlinux/matemat/etc/matemat.conf b/package/archlinux/matemat/etc/matemat.conf deleted file mode 100644 index 1339a49..0000000 --- a/package/archlinux/matemat/etc/matemat.conf +++ /dev/null @@ -1,32 +0,0 @@ -[Matemat] - -# The IP address to listen on -Address=:: -# The TCP port to listen on -Port=80 - -# The log level, one of NONE, DEBUG, INFO, WARNING, ERROR, CRITICAL -LogLevel=DEBUG - -[Pagelets] - -# Name of the Matemat instance, shown in the web app -InstanceName=Matemat - -# -# Configure SMTP credentials -# -# SmtpFrom=matemat@example.com -# SmtpSubj=Matemat Receipt -# SmtpHost=exmaple.com -# SmtpPort=587 -# SmtpUser=matemat@example.com -# SmtpPass=supersecurepassword - -# -# Enable to allow users to receive receipts via email -# -# SmtpSendReceipts=1 - -# Add static HTTP headers in this section -# [HttpHeaders] diff --git a/package/archlinux/matemat/usr/lib/matemat/matemat.conf b/package/archlinux/matemat/usr/lib/matemat/matemat.conf deleted file mode 100644 index 5c34f56..0000000 --- a/package/archlinux/matemat/usr/lib/matemat/matemat.conf +++ /dev/null @@ -1,11 +0,0 @@ -[Matemat] - -StaticPath=/usr/lib/matemat/static -TemplatePath=/usr/lib/matemat/templates - -LogTarget=stdout - -[Pagelets] - -UploadDir=/var/lib/matemat/upload -DatabaseFile=/var/lib/matemat/matemat.db diff --git a/package/archlinux/matemat/usr/lib/systemd/system/matemat.service b/package/archlinux/matemat/usr/lib/systemd/system/matemat.service deleted file mode 100644 index 6656268..0000000 --- a/package/archlinux/matemat/usr/lib/systemd/system/matemat.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=matemat -After=networking.target - -[Service] -ExecStart=/usr/bin/python -m matemat /etc/matemat.conf /usr/lib/matemat/matemat.conf -User=matemat -AmbientCapabilities=CAP_NET_BIND_SERVICE -NoNewPrivileges=true - -[Install] -WantedBy=multi-user.target diff --git a/package/debian/matemat/DEBIAN/control b/package/debian/matemat/DEBIAN/control index b1f8a77..f3d1373 100644 --- a/package/debian/matemat/DEBIAN/control +++ b/package/debian/matemat/DEBIAN/control @@ -1,5 +1,5 @@ Package: matemat -Version: 0.2.7 +Version: 0.2.8 Maintainer: s3lph Section: web Priority: optional diff --git a/package/release.py b/package/release.py index 6f8f46f..2e92512 100755 --- a/package/release.py +++ b/package/release.py @@ -84,14 +84,6 @@ def fetch_debian_url(base_url: str, job_ids: Dict[str, str]) -> Optional[Tuple[s return debian_url, debian_sha_url -def fetch_arch_url(base_url: str, job_ids: Dict[str, str]) -> Optional[Tuple[str, str]]: - mybase: str = f'{base_url}/jobs/{job_ids["build_archlinux"]}/artifacts/raw' - arch_sha_url: str = f'{mybase}/package/archlinux/SHA256SUMS' - arch_filename: str = fetch_single_shafile(arch_sha_url) - arch_url: str = f'{mybase}/package/archlinux/{arch_filename}' - return arch_url, arch_sha_url - - def main(): api_token: Optional[str] = os.getenv('GITLAB_API_TOKEN') release_tag: Optional[str] = os.getenv('CI_COMMIT_TAG') @@ -125,7 +117,6 @@ def main(): wheel_url, wheel_sha_url = fetch_wheel_url(base_url, job_ids) debian_url, debian_sha_url = fetch_debian_url(base_url, job_ids) - arch_url, arch_sha_url = fetch_arch_url(base_url, job_ids) augmented_changelog = f'''{changelog.strip()} @@ -133,7 +124,6 @@ def main(): - [Python Wheel]({wheel_url}) ([sha256]({wheel_sha_url})) - [Debian Package]({debian_url}) ([sha256]({debian_sha_url})) -- [Arch Linux Package]({arch_url}) ([sha256]({arch_sha_url})) - Docker image: registry.gitlab.com/{project_name}:{release_tag}''' post_body: str = json.dumps({'description': augmented_changelog}) diff --git a/static/css/matemat.css b/static/css/matemat.css index 708dea5..9504e18 100644 --- a/static/css/matemat.css +++ b/static/css/matemat.css @@ -91,18 +91,32 @@ color: blue; } -#deposit-amount { +#deposit-output { grid-column-start: 1; grid-column-end: 4; - text-align: right; grid-row: 1; - font-size: 50px; - line-heigt: 100px; - padding: 10px 0; - font-family: monospace; background: #ffffff; } +#deposit-title { + display: block; + font-family: sans-serif; + padding: 0 10px; + line-height: 30px; + font-size: 25px; + height: 30px; +} + +#deposit-amount { + display: block; + text-align: right; + font-size: 50px; + line-height: 70px; + height: 70px; + padding: 0 10px; + font-family: monospace; +} + .numpad { background: #f0f0f0; text-decoration: none; diff --git a/static/js/depositlist.js b/static/js/depositlist.js index e6b4a1f..026a800 100644 --- a/static/js/depositlist.js +++ b/static/js/depositlist.js @@ -4,25 +4,42 @@ Number.prototype.pad = function(size) { return s; } +let product_id = null; let deposit = '0'; let button = document.createElement('div'); let input = document.getElementById('deposit-wrapper'); let amount = document.getElementById('deposit-amount'); +let title = document.getElementById('deposit-title'); button.classList.add('thumblist-item'); button.classList.add('fakelink'); button.innerText = 'Deposit'; button.onclick = (ev) => { + product_id = null; deposit = '0'; + title.innerText = 'Deposit'; amount.innerText = (Math.floor(parseInt(deposit) / 100)) + '.' + (parseInt(deposit) % 100).pad(); input.classList.add('show'); }; +setup_custom_price = (pid, pname) => { + product_id = pid; + title.innerText = pname; + deposit = '0'; + amount.innerText = (Math.floor(parseInt(deposit) / 100)) + '.' + (parseInt(deposit) % 100).pad(); + input.classList.add('show'); +}; deposit_key = (k) => { if (k == 'ok') { - window.location.href = '/deposit?n=' + parseInt(deposit); + if (product_id === null) { + window.location.href = '/deposit?n=' + parseInt(deposit); + } else { + window.location.href = '/buy?pid=' + product_id + '&price=' + parseInt(deposit); + } deposit = '0'; + product_id = null; input.classList.remove('show'); } else if (k == 'del') { if (deposit == '0') { + product_id = null; input.classList.remove('show'); } deposit = deposit.substr(0, deposit.length - 1); diff --git a/templates/admin_restricted.html b/templates/admin_restricted.html index adf06ef..b5e64d3 100644 --- a/templates/admin_restricted.html +++ b/templates/admin_restricted.html @@ -49,6 +49,9 @@ CHF
+ +
+
diff --git a/templates/modproduct.html b/templates/modproduct.html index 7f80c67..d137161 100644 --- a/templates/modproduct.html +++ b/templates/modproduct.html @@ -20,6 +20,9 @@ CHF
+ +
+
diff --git a/templates/productlist.html b/templates/productlist.html index f79ecef..824307e 100644 --- a/templates/productlist.html +++ b/templates/productlist.html @@ -26,7 +26,10 @@
- 0.00 +
+ + 0.00 +
{% for i in [('1', '1'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('del', '✗'), ('0', '0'), ('ok', '✓')] %}
{{ i.1 }}
{% endfor %} @@ -38,8 +41,15 @@ {% for product in products %} {# Show an item per product, consisting of the name, image, price and stock, triggering a purchase on click #}