Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
91f924a75a | |||
e1605aab29 | |||
1164d492a3 |
3
.envrc
3
.envrc
@@ -1 +1,2 @@
|
|||||||
use flake
|
# devenv needs to know the path to the current working directory to create and manage mutable state
|
||||||
|
use flake . --no-pure-eval
|
||||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,9 +1,12 @@
|
|||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
**/__pycache__
|
.venv
|
||||||
dibbler.egg-info
|
.direnv
|
||||||
|
.devenv
|
||||||
|
|
||||||
dist
|
dist
|
||||||
|
|
||||||
|
config.ini
|
||||||
test.db
|
test.db
|
||||||
|
|
||||||
.ruff_cache
|
.ruff_cache
|
||||||
|
59
README.md
59
README.md
@@ -2,48 +2,47 @@
|
|||||||
|
|
||||||
EDB-system for PVVVV
|
EDB-system for PVVVV
|
||||||
|
|
||||||
## Hva er dette?
|
|
||||||
|
|
||||||
Dibbler er et system laget av PVVere for PVVere for å byttelåne både matvarer og godis.
|
|
||||||
Det er designet for en gammeldags VT terminal, og er laget for å være enkelt både å bruke og å hacke på.
|
|
||||||
|
|
||||||
Programmet er skrevet i Python, og bruker en sql database for å lagre data.
|
|
||||||
|
|
||||||
Samlespleiseboden er satt opp slik at folk kjøper inn varer, og får dibblerkreditt, og så kan man bruke
|
|
||||||
denne kreditten til å kjøpe ut andre varer. Det er ikke noen form for authentisering, så hele systemet er basert på tillit.
|
|
||||||
Det er anbefalt å koble en barkodeleser til systemet for å gjøre det enklere å både legge til og kjøpe varer.
|
|
||||||
|
|
||||||
## Kom i gang
|
|
||||||
|
|
||||||
Installer python, og lag og aktiver et venv. Installer så avhengighetene med `pip install`.
|
|
||||||
|
|
||||||
Deretter kan du kjøre programmet med
|
|
||||||
|
|
||||||
```console
|
|
||||||
python -m dibbler -c example-config.ini create-db
|
|
||||||
python -m dibbler -c example-config.ini loop
|
|
||||||
```
|
|
||||||
|
|
||||||
## Nix
|
## Nix
|
||||||
|
|
||||||
### Bygge nytt image
|
### Hvordan kjøre
|
||||||
|
|
||||||
|
nix run github:Programvareverkstedet/dibbler
|
||||||
|
|
||||||
|
### Hvordan utvikle?
|
||||||
|
|
||||||
|
python -m venv .venv
|
||||||
|
source .venv/activate
|
||||||
|
pip install -e .
|
||||||
|
cp example-config.ini config.ini
|
||||||
|
dibbler -c config.ini create-db
|
||||||
|
dibbler -c config.ini loop
|
||||||
|
|
||||||
|
eller hvis du tolererer nix og postgres:
|
||||||
|
|
||||||
|
direnv allow # eller bare `nix develop`
|
||||||
|
devenv up
|
||||||
|
dibbler create-db
|
||||||
|
dibbler loop
|
||||||
|
|
||||||
|
### Bygge image
|
||||||
|
|
||||||
For å bygge et image trenger du en builder som takler å bygge for arkitekturen du skal lage et image for.
|
For å bygge et image trenger du en builder som takler å bygge for arkitekturen du skal lage et image for.
|
||||||
|
|
||||||
(Eller be til gudene om at cross compile funker)
|
_(Eller be til gudene om at cross compile funker)_
|
||||||
|
|
||||||
Flaket exposer en modul som autologger inn med en bruker som automatisk kjører dibbler, og setter opp et minimalistisk miljø.
|
Flaket exposer en modul som autologger inn med en bruker som automatisk kjører dibbler, og setter opp et minimalistisk miljø.
|
||||||
|
|
||||||
Før du bygger imaget burde du kopiere og endre `example-config.ini` lokalt til å inneholde instillingene dine. **NB: Denne kommer til å ligge i nix storen, ikke si noe her som du ikke vil at moren din skal høre.**
|
Før du bygger imaget burde du lage en `config.ini` fil lokalt som inneholder instillingene dine. **NB: Denne kommer til å ligge i nix storen.**
|
||||||
|
|
||||||
Du kan også endre hvilken config-fil som blir brukt direkte i pakken eller i modulen.
|
Du kan også endre hvilken `config.ini` som blir brukt direkte i pakken eller i modulen.
|
||||||
|
|
||||||
Se eksempelet for hvordan skrot er satt opp i `flake.nix` og `nix/skrott.nix`
|
Se eksempelet for hvordan skrot er satt opp i `flake.nix`
|
||||||
|
|
||||||
### Bygge image for skrot
|
### Bygge image for skrot
|
||||||
Skrot har et image definert i flake.nix:
|
|
||||||
|
|
||||||
1. endre `example-config.ini`
|
Skrot har et system image definert i `flake.nix`:
|
||||||
|
|
||||||
|
1. lag `config.ini` (`cp {example-,}config.ini`)
|
||||||
2. `nix build .#images.skrot`
|
2. `nix build .#images.skrot`
|
||||||
3. ???
|
3. ???
|
||||||
4. non-profit
|
4. non-profit!
|
||||||
|
4
default.nix
Normal file
4
default.nix
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{ pkgs ? import <nixos-unstable> { } }:
|
||||||
|
{
|
||||||
|
dibbler = pkgs.callPackage ./nix/dibbler.nix { };
|
||||||
|
}
|
@@ -1,16 +1,12 @@
|
|||||||
from pathlib import Path
|
import os
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
from dibbler.conf import config
|
from dibbler.conf import config
|
||||||
|
|
||||||
if (url := config.get("database", "url")) is not None:
|
engine = create_engine(
|
||||||
database_url = url
|
os.environ.get("DIBBLER_DATABASE_URL")
|
||||||
|
or config.get("database", "url")
|
||||||
elif (url_file := config.get("database", "url_file")) is not None:
|
)
|
||||||
with Path(url_file).open() as file:
|
|
||||||
database_url = file.read().strip()
|
|
||||||
|
|
||||||
engine = create_engine(database_url)
|
|
||||||
Session = sessionmaker(bind=engine)
|
Session = sessionmaker(bind=engine)
|
||||||
|
@@ -2,7 +2,7 @@ import os
|
|||||||
|
|
||||||
from PIL import ImageFont
|
from PIL import ImageFont
|
||||||
from barcode.writer import ImageWriter, mm2px
|
from barcode.writer import ImageWriter, mm2px
|
||||||
from brother_ql.labels import ALL_LABELS
|
from brother_ql.devicedependent import label_type_specs
|
||||||
|
|
||||||
|
|
||||||
def px2mm(px, dpi=300):
|
def px2mm(px, dpi=300):
|
||||||
@@ -12,15 +12,14 @@ def px2mm(px, dpi=300):
|
|||||||
class BrotherLabelWriter(ImageWriter):
|
class BrotherLabelWriter(ImageWriter):
|
||||||
def __init__(self, typ="62", max_height=350, rot=False, text=None):
|
def __init__(self, typ="62", max_height=350, rot=False, text=None):
|
||||||
super(BrotherLabelWriter, self).__init__()
|
super(BrotherLabelWriter, self).__init__()
|
||||||
label = next([l for l in ALL_LABELS if l.identifier == typ])
|
assert typ in label_type_specs
|
||||||
assert label is not None
|
|
||||||
self.rot = rot
|
self.rot = rot
|
||||||
if self.rot:
|
if self.rot:
|
||||||
self._h, self._w = label.dots_printable
|
self._h, self._w = label_type_specs[typ]["dots_printable"]
|
||||||
if self._w == 0 or self._w > max_height:
|
if self._w == 0 or self._w > max_height:
|
||||||
self._w = min(max_height, self._h / 2)
|
self._w = min(max_height, self._h / 2)
|
||||||
else:
|
else:
|
||||||
self._w, self._h = label.dots_printable
|
self._w, self._h = label_type_specs[typ]["dots_printable"]
|
||||||
if self._h == 0 or self._h > max_height:
|
if self._h == 0 or self._h > max_height:
|
||||||
self._h = min(max_height, self._w / 2)
|
self._h = min(max_height, self._w / 2)
|
||||||
self._xo = 0.0
|
self._xo = 0.0
|
||||||
|
@@ -2,10 +2,9 @@ import os
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import barcode
|
import barcode
|
||||||
from brother_ql.brother_ql_create import create_label
|
from brother_ql import BrotherQLRaster, create_label
|
||||||
from brother_ql.raster import BrotherQLRaster
|
|
||||||
from brother_ql.backends import backend_factory
|
from brother_ql.backends import backend_factory
|
||||||
from brother_ql.labels import ALL_LABELS
|
from brother_ql.devicedependent import label_type_specs
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
from .barcode_helpers import BrotherLabelWriter
|
from .barcode_helpers import BrotherLabelWriter
|
||||||
@@ -18,11 +17,10 @@ def print_name_label(
|
|||||||
label_type="62",
|
label_type="62",
|
||||||
printer_type="QL-700",
|
printer_type="QL-700",
|
||||||
):
|
):
|
||||||
label = next([l for l in ALL_LABELS if l.identifier == label_type])
|
|
||||||
if not rotate:
|
if not rotate:
|
||||||
width, height = label.dots_printable
|
width, height = label_type_specs[label_type]["dots_printable"]
|
||||||
else:
|
else:
|
||||||
height, width = label.dots_printable
|
height, width = label_type_specs[label_type]["dots_printable"]
|
||||||
|
|
||||||
font_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "ChopinScript.ttf")
|
font_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "ChopinScript.ttf")
|
||||||
fs = 2000
|
fs = 2000
|
||||||
|
@@ -76,8 +76,12 @@ class Database:
|
|||||||
personDatoVerdi = defaultdict(list) # dict->array
|
personDatoVerdi = defaultdict(list) # dict->array
|
||||||
personUkedagVerdi = defaultdict(list)
|
personUkedagVerdi = defaultdict(list)
|
||||||
# for global
|
# for global
|
||||||
personPosTransactions = {} # personPosTransactions[trygvrad] == 100 #trygvrad har lagt 100kr i boksen
|
personPosTransactions = (
|
||||||
personNegTransactions = {} # personNegTransactions[trygvrad» == 70 #trygvrad har tatt 70kr fra boksen
|
{}
|
||||||
|
) # personPosTransactions[trygvrad] == 100 #trygvrad har lagt 100kr i boksen
|
||||||
|
personNegTransactions = (
|
||||||
|
{}
|
||||||
|
) # personNegTransactions[trygvrad» == 70 #trygvrad har tatt 70kr fra boksen
|
||||||
globalVareAntall = {} # globalVareAntall[Oreo] == 3
|
globalVareAntall = {} # globalVareAntall[Oreo] == 3
|
||||||
globalVareVerdi = {} # globalVareVerdi[Oreo] == 30 #[kr]
|
globalVareVerdi = {} # globalVareVerdi[Oreo] == 30 #[kr]
|
||||||
globalPersonAntall = {} # globalPersonAntall[trygvrad] == 3
|
globalPersonAntall = {} # globalPersonAntall[trygvrad] == 3
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
from dibbler.conf import config
|
from dibbler.conf import config
|
||||||
|
|
||||||
@@ -10,6 +12,7 @@ parser.add_argument(
|
|||||||
help="Path to the config file",
|
help="Path to the config file",
|
||||||
type=str,
|
type=str,
|
||||||
required=False,
|
required=False,
|
||||||
|
default=os.environ.get("DIBBLER_CONFIG_FILE", None)
|
||||||
)
|
)
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(
|
subparsers = parser.add_subparsers(
|
||||||
@@ -20,11 +23,12 @@ subparsers = parser.add_subparsers(
|
|||||||
subparsers.add_parser("loop", help="Run the dibbler loop")
|
subparsers.add_parser("loop", help="Run the dibbler loop")
|
||||||
subparsers.add_parser("create-db", help="Create the database")
|
subparsers.add_parser("create-db", help="Create the database")
|
||||||
subparsers.add_parser("slabbedasker", help="Find out who is slabbedasker")
|
subparsers.add_parser("slabbedasker", help="Find out who is slabbedasker")
|
||||||
subparsers.add_parser("seed-data", help="Fill with mock data")
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
if args.config is None:
|
||||||
|
print("ERROR: no config was provided", file=sys.stderr)
|
||||||
config.read(args.config)
|
config.read(args.config)
|
||||||
|
|
||||||
if args.subcommand == "loop":
|
if args.subcommand == "loop":
|
||||||
@@ -42,11 +46,6 @@ def main():
|
|||||||
|
|
||||||
slabbedasker.main()
|
slabbedasker.main()
|
||||||
|
|
||||||
elif args.subcommand == "seed-data":
|
|
||||||
import dibbler.subcommands.seed_test_data as seed_test_data
|
|
||||||
|
|
||||||
seed_test_data.main()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@@ -180,7 +180,7 @@ When finished, write an empty line to confirm the purchase.\n"""
|
|||||||
print(f"User {t.user.name}'s credit is now {t.user.credit:d} kr")
|
print(f"User {t.user.name}'s credit is now {t.user.credit:d} kr")
|
||||||
if t.user.credit < config.getint("limits", "low_credit_warning_limit"):
|
if t.user.credit < config.getint("limits", "low_credit_warning_limit"):
|
||||||
print(
|
print(
|
||||||
f"USER {t.user.name} HAS LOWER CREDIT THAN {config.getint('limits', 'low_credit_warning_limit'):d},",
|
f'USER {t.user.name} HAS LOWER CREDIT THAN {config.getint("limits", "low_credit_warning_limit"):d},',
|
||||||
"AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.",
|
"AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
__all__ = [
|
__all__ = [
|
||||||
"Base",
|
'Base',
|
||||||
"Product",
|
'Product',
|
||||||
"Purchase",
|
'Purchase',
|
||||||
"PurchaseEntry",
|
'PurchaseEntry',
|
||||||
"Transaction",
|
'Transaction',
|
||||||
"User",
|
'User',
|
||||||
"UserProducts",
|
'UserProducts',
|
||||||
]
|
]
|
||||||
|
|
||||||
from .Base import Base
|
from .Base import Base
|
||||||
|
@@ -1,48 +0,0 @@
|
|||||||
import json
|
|
||||||
from dibbler.db import Session
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
from dibbler.models.Product import Product
|
|
||||||
|
|
||||||
from dibbler.models.User import User
|
|
||||||
|
|
||||||
JSON_FILE = Path(__file__).parent.parent.parent / "mock_data.json"
|
|
||||||
|
|
||||||
|
|
||||||
def clear_db(session):
|
|
||||||
session.query(Product).delete()
|
|
||||||
session.query(User).delete()
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
session = Session()
|
|
||||||
clear_db(session)
|
|
||||||
product_items = []
|
|
||||||
user_items = []
|
|
||||||
|
|
||||||
with open(JSON_FILE) as f:
|
|
||||||
json_obj = json.load(f)
|
|
||||||
|
|
||||||
for product in json_obj["products"]:
|
|
||||||
product_item = Product(
|
|
||||||
bar_code=product["bar_code"],
|
|
||||||
name=product["name"],
|
|
||||||
price=product["price"],
|
|
||||||
stock=product["stock"],
|
|
||||||
)
|
|
||||||
product_items.append(product_item)
|
|
||||||
|
|
||||||
for user in json_obj["users"]:
|
|
||||||
user_item = User(
|
|
||||||
name=user["name"],
|
|
||||||
card=user["card"],
|
|
||||||
rfid=user["rfid"],
|
|
||||||
credit=user["credit"],
|
|
||||||
)
|
|
||||||
user_items.append(user_item)
|
|
||||||
|
|
||||||
session.add_all(product_items)
|
|
||||||
session.add_all(user_items)
|
|
||||||
session.commit()
|
|
@@ -1,18 +1,20 @@
|
|||||||
[general]
|
[general]
|
||||||
quit_allowed = true
|
; quit_allowed = false
|
||||||
stop_allowed = false
|
; stop_allowed = false
|
||||||
|
quit_allowed = true ; not for prod
|
||||||
|
stop_allowed = true ; not for prod
|
||||||
show_tracebacks = true
|
show_tracebacks = true
|
||||||
input_encoding = 'utf8'
|
input_encoding = 'utf8'
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
# url = "postgresql://robertem@127.0.0.1/pvvvv"
|
; url = postgresql://dibbler:hunter2@127.0.0.1/pvvvv
|
||||||
url = "sqlite:///test.db"
|
url = sqlite:///test.db ; devenv will override this to postgres using DIBBLER_DATABASE_URL
|
||||||
|
|
||||||
[limits]
|
[limits]
|
||||||
low_credit_warning_limit = -100
|
low_credit_warning_limit = -100
|
||||||
user_recent_transaction_limit = 100
|
user_recent_transaction_limit = 100
|
||||||
|
|
||||||
# See https://pypi.org/project/brother_ql/ for label types
|
# See https://pypi.org/project/brother_ql_next/ for label types
|
||||||
# Set rotate to False for endless labels
|
# Set rotate to False for endless labels
|
||||||
[printer]
|
[printer]
|
||||||
label_type = "62"
|
label_type = "62"
|
||||||
|
249
flake.lock
generated
249
flake.lock
generated
@@ -1,5 +1,93 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"cachix": {
|
||||||
|
"inputs": {
|
||||||
|
"devenv": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"flake-compat": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"git-hooks": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1728672398,
|
||||||
|
"narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "cachix",
|
||||||
|
"rev": "aac51f698309fd0f381149214b7eee213c66ef0a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"ref": "latest",
|
||||||
|
"repo": "cachix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devenv": {
|
||||||
|
"inputs": {
|
||||||
|
"cachix": "cachix",
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"git-hooks": "git-hooks",
|
||||||
|
"nix": "nix",
|
||||||
|
"nixpkgs": "nixpkgs_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731619804,
|
||||||
|
"narHash": "sha256-wyxFaVooL8SzvQNpolpx32X+GoBPnCAg9E0i/Ekn3FU=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"rev": "87edaaf1dddf17fe16eabab3c8edaf7cca2c3bc2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-compat": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696426674,
|
||||||
|
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "edolstra",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"devenv",
|
||||||
|
"nix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1712014858,
|
||||||
|
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
@@ -13,17 +101,117 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"id": "flake-utils",
|
"owner": "numtide",
|
||||||
"type": "indirect"
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"git-hooks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"gitignore": "gitignore",
|
||||||
|
"nixpkgs": [
|
||||||
|
"devenv",
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"nixpkgs-stable": [
|
||||||
|
"devenv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730302582,
|
||||||
|
"narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gitignore": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"devenv",
|
||||||
|
"git-hooks",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1709087332,
|
||||||
|
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "gitignore.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libgit2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1697646580,
|
||||||
|
"narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=",
|
||||||
|
"owner": "libgit2",
|
||||||
|
"repo": "libgit2",
|
||||||
|
"rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "libgit2",
|
||||||
|
"repo": "libgit2",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"libgit2": "libgit2",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"nixpkgs-23-11": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"nixpkgs-regression": [
|
||||||
|
"devenv"
|
||||||
|
],
|
||||||
|
"pre-commit-hooks": [
|
||||||
|
"devenv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1727438425,
|
||||||
|
"narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=",
|
||||||
|
"owner": "domenkozar",
|
||||||
|
"repo": "nix",
|
||||||
|
"rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "domenkozar",
|
||||||
|
"ref": "devenv-2.24",
|
||||||
|
"repo": "nix",
|
||||||
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1749143949,
|
"lastModified": 1730531603,
|
||||||
"narHash": "sha256-QuUtALJpVrPnPeozlUG/y+oIMSLdptHxb3GK6cpSVhA=",
|
"narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d3d2d80a2191a73d1e86456a751b83aa13085d7d",
|
"rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -33,10 +221,59 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1717432640,
|
||||||
|
"narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "88269ab3044128b7c2f4c7d68448b2fb50456870",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "release-24.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1716977621,
|
||||||
|
"narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "devenv-nixpkgs",
|
||||||
|
"rev": "4267e705586473d3e5c8d50299e71503f16a6fb6",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"ref": "rolling",
|
||||||
|
"repo": "devenv-nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_4": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731611831,
|
||||||
|
"narHash": "sha256-R51rOqkWMfubBkZ9BY4Y1VaRoeqEBshlfQ8mMH5RjqI=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "cea28c811faadb50bee00d433bbf2fea845a43e4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable-small",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
|
"devenv": "devenv",
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs_4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
151
flake.nix
151
flake.nix
@@ -1,65 +1,128 @@
|
|||||||
{
|
{
|
||||||
description = "Dibbler samspleisebod";
|
description = "Dibbler samspleisebod";
|
||||||
|
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
devenv.url = "github:cachix/devenv";
|
||||||
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }: let
|
nixConfig = {
|
||||||
inherit (nixpkgs) lib;
|
extra-trusted-public-keys = [
|
||||||
|
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
|
||||||
|
];
|
||||||
|
extra-substituters = [
|
||||||
|
"https://devenv.cachix.org"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
systems = [
|
outputs = { self, ... } @ inputs:
|
||||||
"x86_64-linux"
|
inputs.flake-utils.lib.eachDefaultSystem (system: let
|
||||||
"aarch64-linux"
|
pkgs = inputs.nixpkgs.legacyPackages.${system};
|
||||||
"x86_64-darwin"
|
inherit (pkgs) lib;
|
||||||
"aarch64-darwin"
|
in {
|
||||||
|
|
||||||
|
packages = {
|
||||||
|
default = self.packages.${system}.dibbler;
|
||||||
|
|
||||||
|
dibbler = pkgs.python311Packages.callPackage ./nix/dibbler.nix { };
|
||||||
|
skrot-vm = self.nixosConfigurations.skrot.config.system.build.vm;
|
||||||
|
|
||||||
|
# devenv cruft
|
||||||
|
devenv-up = self.devShells.${system}.default.config.procfileScript;
|
||||||
|
devenv-test = self.devShells.${system}.default.config.test;
|
||||||
|
};
|
||||||
|
|
||||||
|
devShells = {
|
||||||
|
default = self.devShells.${system}.dibbler;
|
||||||
|
dibbler = inputs.devenv.lib.mkShell {
|
||||||
|
inherit inputs pkgs;
|
||||||
|
modules = [({ config, ... }: {
|
||||||
|
# https://devenv.sh/reference/options/
|
||||||
|
|
||||||
|
enterShell = ''
|
||||||
|
if [[ ! -f config.ini ]]; then
|
||||||
|
cp -v example-config.ini config.ini
|
||||||
|
fi
|
||||||
|
|
||||||
|
export REPO_ROOT=$(realpath .) # used by mkPythonEditablePackage
|
||||||
|
export DIBBLER_CONFIG_FILE=$(realpath config.ini)
|
||||||
|
export DIBBLER_DATABASE_URL=postgresql://dibbler:hunter2@/dibbler?host=${config.env.PGHOST}
|
||||||
|
'';
|
||||||
|
|
||||||
|
packages = [
|
||||||
|
|
||||||
|
/* self.packages.${system}.dibbler */
|
||||||
|
(pkgs.python311Packages.mkPythonEditablePackage {
|
||||||
|
inherit (self.packages.${system}.dibbler)
|
||||||
|
pname version
|
||||||
|
build-system dependencies;
|
||||||
|
scripts = (lib.importTOML ./pyproject.toml).project.scripts;
|
||||||
|
root = "$REPO_ROOT";
|
||||||
|
})
|
||||||
|
|
||||||
|
pkgs.python311Packages.black
|
||||||
|
pkgs.ruff
|
||||||
];
|
];
|
||||||
|
|
||||||
forAllSystems = f: lib.genAttrs systems (system: let
|
services.postgres = {
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
enable = true;
|
||||||
in f system pkgs);
|
initialDatabases = [
|
||||||
in {
|
{
|
||||||
packages = forAllSystems (system: pkgs: {
|
name = "dibbler";
|
||||||
default = self.packages.${system}.dibbler;
|
user = "dibbler";
|
||||||
dibbler = pkgs.callPackage ./nix/dibbler.nix {
|
pass = "hunter2";
|
||||||
python3Packages = pkgs.python312Packages;
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
skrot = self.nixosConfigurations.skrot.config.system.build.sdImage;
|
|
||||||
});
|
|
||||||
|
|
||||||
apps = forAllSystems (system: pkgs: {
|
})];
|
||||||
default = self.apps.${system}.dibbler;
|
|
||||||
dibbler = flake-utils.lib.mkApp {
|
|
||||||
drv = self.packages.${system}.dibbler;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
overlays = {
|
|
||||||
default = self.overlays.dibbler;
|
|
||||||
dibbler = final: prev: {
|
|
||||||
inherit (self.packages.${prev.system}) dibbler;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
devShells = forAllSystems (system: pkgs: {
|
})
|
||||||
default = self.devShells.${system}.dibbler;
|
|
||||||
dibbler = pkgs.callPackage ./nix/shell.nix {
|
|
||||||
python = pkgs.python312;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
# Note: using the module requires that you have applied the overlay first
|
//
|
||||||
|
|
||||||
|
{
|
||||||
|
# Note: using the module requires that you have applied the
|
||||||
|
# overlay first
|
||||||
nixosModules.default = import ./nix/module.nix;
|
nixosModules.default = import ./nix/module.nix;
|
||||||
|
|
||||||
nixosConfigurations.skrot = nixpkgs.lib.nixosSystem (rec {
|
images.skrot = self.nixosConfigurations.skrot.config.system.build.sdImage;
|
||||||
|
|
||||||
|
nixosConfigurations.skrot = inputs.nixpkgs.lib.nixosSystem {
|
||||||
system = "aarch64-linux";
|
system = "aarch64-linux";
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system;
|
|
||||||
overlays = [ self.overlays.dibbler ];
|
|
||||||
};
|
|
||||||
modules = [
|
modules = [
|
||||||
(nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64.nix")
|
(inputs.nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64.nix")
|
||||||
self.nixosModules.default
|
self.nixosModules.default
|
||||||
./nix/skrott.nix
|
({...}: {
|
||||||
|
system.stateVersion = "22.05";
|
||||||
|
|
||||||
|
networking = {
|
||||||
|
hostName = "skrot";
|
||||||
|
domain = "pvv.ntnu.no";
|
||||||
|
nameservers = [ "129.241.0.200" "129.241.0.201" ];
|
||||||
|
defaultGateway = "129.241.210.129";
|
||||||
|
interfaces.eth0 = {
|
||||||
|
useDHCP = false;
|
||||||
|
ipv4.addresses = [{
|
||||||
|
address = "129.241.210.235";
|
||||||
|
prefixLength = 25;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# services.resolved.enable = true;
|
||||||
|
# systemd.network.enable = true;
|
||||||
|
# systemd.network.networks."30-network" = {
|
||||||
|
# matchConfig.Name = "*";
|
||||||
|
# DHCP = "no";
|
||||||
|
# address = [ "129.241.210.235/25" ];
|
||||||
|
# gateway = [ "129.241.210.129" ];
|
||||||
|
# };
|
||||||
|
})
|
||||||
];
|
];
|
||||||
});
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,76 +0,0 @@
|
|||||||
{
|
|
||||||
"products": [
|
|
||||||
{
|
|
||||||
"product_id": 1,
|
|
||||||
"bar_code": "1234567890123",
|
|
||||||
"name": "Wireless Mouse",
|
|
||||||
"price": 2999,
|
|
||||||
"stock": 150,
|
|
||||||
"hidden": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"product_id": 2,
|
|
||||||
"bar_code": "9876543210987",
|
|
||||||
"name": "Mechanical Keyboard",
|
|
||||||
"price": 5999,
|
|
||||||
"stock": 75,
|
|
||||||
"hidden": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"product_id": 3,
|
|
||||||
"bar_code": "1112223334445",
|
|
||||||
"name": "Gaming Monitor",
|
|
||||||
"price": 19999,
|
|
||||||
"stock": 20,
|
|
||||||
"hidden": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"product_id": 4,
|
|
||||||
"bar_code": "5556667778889",
|
|
||||||
"name": "USB-C Docking Station",
|
|
||||||
"price": 8999,
|
|
||||||
"stock": 50,
|
|
||||||
"hidden": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"product_id": 5,
|
|
||||||
"bar_code": "4445556667771",
|
|
||||||
"name": "Noise Cancelling Headphones",
|
|
||||||
"price": 12999,
|
|
||||||
"stock": 30,
|
|
||||||
"hidden": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"name": "Albert",
|
|
||||||
"credit": 42069,
|
|
||||||
"card": "NTU12345678",
|
|
||||||
"rfid": "a1b2c3d4e5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lorem",
|
|
||||||
"credit": 2000,
|
|
||||||
"card": "9876543210",
|
|
||||||
"rfid": "f6e7d8c9b0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ibsum",
|
|
||||||
"credit": 1000,
|
|
||||||
"card": "11122233",
|
|
||||||
"rfid": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dave",
|
|
||||||
"credit": 7500,
|
|
||||||
"card": "NTU56789012",
|
|
||||||
"rfid": "1234abcd5678"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "eve",
|
|
||||||
"credit": 3000,
|
|
||||||
"card": null,
|
|
||||||
"rfid": "deadbeef1234"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,21 +1,25 @@
|
|||||||
{ lib
|
{ lib
|
||||||
, python3Packages
|
|
||||||
, fetchFromGitHub
|
, fetchFromGitHub
|
||||||
|
, buildPythonApplication
|
||||||
|
, setuptools
|
||||||
|
, brother-ql
|
||||||
|
, matplotlib
|
||||||
|
, psycopg2
|
||||||
|
, python-barcode
|
||||||
|
, sqlalchemy
|
||||||
}:
|
}:
|
||||||
python3Packages.buildPythonApplication {
|
|
||||||
|
buildPythonApplication {
|
||||||
pname = "dibbler";
|
pname = "dibbler";
|
||||||
version = "unstable";
|
version = "0.0.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
src = lib.cleanSource ../.;
|
src = lib.cleanSource ../.;
|
||||||
|
|
||||||
format = "pyproject";
|
build-system = [ setuptools ];
|
||||||
|
dependencies = [
|
||||||
# brother-ql is breaky breaky
|
# we override pname to satisfy mkPythonEditablePackage
|
||||||
# https://github.com/NixOS/nixpkgs/issues/285234
|
(brother-ql.overridePythonAttrs { pname = "brother-ql-next"; })
|
||||||
dontCheckRuntimeDeps = true;
|
|
||||||
|
|
||||||
nativeBuildInputs = with python3Packages; [ setuptools ];
|
|
||||||
propagatedBuildInputs = with python3Packages; [
|
|
||||||
brother-ql
|
|
||||||
matplotlib
|
matplotlib
|
||||||
psycopg2
|
psycopg2
|
||||||
python-barcode
|
python-barcode
|
||||||
|
@@ -1,31 +1,16 @@
|
|||||||
{ config, pkgs, lib, ... }: let
|
{ config, pkgs, lib, ... }: let
|
||||||
cfg = config.services.dibbler;
|
cfg = config.services.dibbler;
|
||||||
|
|
||||||
format = pkgs.formats.ini { };
|
|
||||||
in {
|
in {
|
||||||
options.services.dibbler = {
|
options.services.dibbler = {
|
||||||
enable = lib.mkEnableOption "dibbler, the little kiosk computer";
|
|
||||||
|
|
||||||
package = lib.mkPackageOption pkgs "dibbler" { };
|
package = lib.mkPackageOption pkgs "dibbler" { };
|
||||||
|
config = lib.mkOption {
|
||||||
settings = lib.mkOption {
|
default = ../conf.py;
|
||||||
description = "Configuration for dibbler";
|
|
||||||
default = { };
|
|
||||||
type = lib.types.submodule {
|
|
||||||
freeformType = format.type;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config = let
|
||||||
screen = "${pkgs.screen}/bin/screen";
|
screen = "${pkgs.screen}/bin/screen";
|
||||||
in lib.mkIf cfg.enable {
|
in {
|
||||||
services.dibbler.settings = lib.pipe ../example-config.ini [
|
|
||||||
builtins.readFile
|
|
||||||
builtins.fromTOML
|
|
||||||
(lib.mapAttrsRecursive (_: lib.mkDefault))
|
|
||||||
];
|
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
consoleLogLevel = 0;
|
consoleLogLevel = 0;
|
||||||
enableContainers = false;
|
enableContainers = false;
|
||||||
@@ -38,7 +23,10 @@ in {
|
|||||||
group = "dibbler";
|
group = "dibbler";
|
||||||
extraGroups = [ "lp" ];
|
extraGroups = [ "lp" ];
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
shell = (pkgs.writeShellScriptBin "login-shell" "${screen} -x dibbler") // {shellPath = "/bin/login-shell";};
|
shell = (
|
||||||
|
(pkgs.writeShellScriptBin "login-shell" "${screen} -x dibbler")
|
||||||
|
// {shellPath = "/bin/login-shell";}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,9 +35,7 @@ in {
|
|||||||
wantedBy = [ "default.target" ];
|
wantedBy = [ "default.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStartPre = "-${screen} -X -S dibbler kill";
|
ExecStartPre = "-${screen} -X -S dibbler kill";
|
||||||
ExecStart = let
|
ExecStart = "${screen} -dmS dibbler -O -l ${cfg.package}/bin/dibbler --config ${cfg.config} loop";
|
||||||
config = format.generate "dibbler-config.ini" cfg.settings;
|
|
||||||
in "${screen} -dmS dibbler -O -l ${cfg.package}/bin/dibbler --config ${config} loop";
|
|
||||||
ExecStartPost = "${screen} -X -S dibbler width 42 80";
|
ExecStartPost = "${screen} -X -S dibbler width 42 80";
|
||||||
User = "dibbler";
|
User = "dibbler";
|
||||||
Group = "dibbler";
|
Group = "dibbler";
|
||||||
@@ -72,6 +58,30 @@ in {
|
|||||||
serviceConfig.Restart = "always"; # restart when session is closed
|
serviceConfig.Restart = "always"; # restart when session is closed
|
||||||
};
|
};
|
||||||
|
|
||||||
services.getty.autologinUser = lib.mkForce "dibbler";
|
services = {
|
||||||
|
openssh = {
|
||||||
|
enable = true;
|
||||||
|
permitRootLogin = "yes";
|
||||||
|
};
|
||||||
|
|
||||||
|
getty.autologinUser = lib.mkForce "dibbler";
|
||||||
|
udisks2.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.logRefusedConnections = false;
|
||||||
|
console.keyMap = "no";
|
||||||
|
programs.command-not-found.enable = false;
|
||||||
|
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" ];
|
||||||
|
environment.noXlibs = true;
|
||||||
|
|
||||||
|
documentation = {
|
||||||
|
info.enable = false;
|
||||||
|
man.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
security = {
|
||||||
|
polkit.enable = lib.mkForce false;
|
||||||
|
audit.enable = false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
mkShell,
|
|
||||||
python,
|
|
||||||
ruff,
|
|
||||||
uv,
|
|
||||||
}:
|
|
||||||
|
|
||||||
mkShell {
|
|
||||||
packages = [
|
|
||||||
ruff
|
|
||||||
uv
|
|
||||||
(python.withPackages (ps: with ps; [
|
|
||||||
brother-ql
|
|
||||||
matplotlib
|
|
||||||
psycopg2
|
|
||||||
python-barcode
|
|
||||||
sqlalchemy
|
|
||||||
]))
|
|
||||||
];
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
{...}: {
|
|
||||||
system.stateVersion = "25.05";
|
|
||||||
|
|
||||||
services.dibbler.enable = true;
|
|
||||||
|
|
||||||
networking = {
|
|
||||||
hostName = "skrot";
|
|
||||||
domain = "pvv.ntnu.no";
|
|
||||||
nameservers = [ "129.241.0.200" "129.241.0.201" ];
|
|
||||||
defaultGateway = "129.241.210.129";
|
|
||||||
interfaces.eth0 = {
|
|
||||||
useDHCP = false;
|
|
||||||
ipv4.addresses = [{
|
|
||||||
address = "129.241.210.235";
|
|
||||||
prefixLength = 25;
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# services.resolved.enable = true;
|
|
||||||
# systemd.network.enable = true;
|
|
||||||
# systemd.network.networks."30-network" = {
|
|
||||||
# matchConfig.Name = "*";
|
|
||||||
# DHCP = "no";
|
|
||||||
# address = [ "129.241.210.235/25" ];
|
|
||||||
# gateway = [ "129.241.210.129" ];
|
|
||||||
# };
|
|
||||||
}
|
|
@@ -8,12 +8,13 @@ authors = []
|
|||||||
description = "EDB-system for PVV"
|
description = "EDB-system for PVV"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
|
license = {text = "BSD-3-Clause"}
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"SQLAlchemy >= 2.0, <2.1",
|
"SQLAlchemy >= 2.0, <2.1",
|
||||||
"brother-ql",
|
"brother_ql_next",
|
||||||
"matplotlib",
|
"matplotlib",
|
||||||
"psycopg2 >= 2.8, <2.10",
|
"psycopg2 >= 2.8, <2.10",
|
||||||
"python-barcode",
|
"python-barcode",
|
||||||
|
Reference in New Issue
Block a user