Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f24880c09a | |||
| 3622cbca05 | |||
| 637a5f7ad5 | |||
| 15ba3c060a | |||
| bde9a50767 | |||
| 60e221146a | |||
| d34f2adb2f | |||
| a6f229e7fb | |||
| 5a453a140e | |||
| 0f6f76a66b | |||
| 14b7e1f84c | |||
| 560016cc18 | |||
| b57dbba5d6 | |||
| 7ae57ae3a4 | |||
| 04a13635dc | |||
| 5c46a24338 | |||
| f41fdd076b | |||
| 4d1e7eb944 | |||
| 6c0fa5a58b | |||
| 5e4a59e15f | |||
| d311b6f8cf | |||
| 8e17a2fb25 | |||
| dceda1446f | |||
| b21284f640 |
44
.github/workflows/main.yml
vendored
44
.github/workflows/main.yml
vendored
@ -4,19 +4,47 @@ on:
|
|||||||
tags:
|
tags:
|
||||||
- '*'
|
- '*'
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: https://gitea.com/actions/checkout@master
|
||||||
- name: Archive Server
|
- name: Zip Artifacts
|
||||||
uses: thedoctor0/zip-release@master
|
uses: https://github.com/thedoctor0/zip-release@master
|
||||||
with:
|
with:
|
||||||
type: 'zip'
|
type: 'zip'
|
||||||
filename: 'server.zip'
|
filename: 'server.zip'
|
||||||
exclusions: '*.git*'
|
exclusions: '*.git*'
|
||||||
- name: Release Archive
|
- name: Release Archive
|
||||||
uses: ncipollo/release-action@v1
|
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||||
with:
|
with:
|
||||||
allowUpdates: true
|
server_url: https://gitea.wpgcommunity.net
|
||||||
artifacts: "server.zip"
|
files: 'server.zip'
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: https://gitea.com/actions/checkout@master
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ vars.DOCKER_REPO }}/costhive
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
config-inline: |
|
||||||
|
[registry."${{ vars.DOCKER_REPO }}"]
|
||||||
|
http = true
|
||||||
|
insecure = true
|
||||||
|
- name: Login to Gitea Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ vars.DOCKER_REPO }}
|
||||||
|
username: ${{ vars.DOCKER_USER }}
|
||||||
|
password: ${{ secrets.DOCKER_PASS }}
|
||||||
|
- name: Build and push
|
||||||
|
uses: https://github.com/docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
context: .
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
@ -339,7 +339,9 @@ pip-selfcheck.json
|
|||||||
# Misc
|
# Misc
|
||||||
config.yaml
|
config.yaml
|
||||||
scans.json
|
scans.json
|
||||||
|
test_*.*
|
||||||
test.*
|
test.*
|
||||||
|
tests*
|
||||||
*.db
|
*.db
|
||||||
.vscode
|
.vscode
|
||||||
*.tar
|
*.tar
|
||||||
@ -348,3 +350,9 @@ test.*
|
|||||||
.flaskenv*
|
.flaskenv*
|
||||||
!.env.project
|
!.env.project
|
||||||
!.env.vault
|
!.env.vault
|
||||||
|
*.ps1
|
||||||
|
*.pdf
|
||||||
|
*.backup
|
||||||
|
Dockerfile.*
|
||||||
|
docker-compose.*
|
||||||
|
*debug.py
|
||||||
24
Dockerfile
24
Dockerfile
@ -1,23 +1,25 @@
|
|||||||
FROM python@sha256:075fe10ae13ea0f081540bead850eeb7b6c71d07ed4766d75f8529abd0101c44
|
FROM python@sha256:c66cf219ac0083a9af2ff90e16530f16cd503c59eb7909feb3b8f3524dc1a87e
|
||||||
# python:3.10.10-slim-bullseye
|
# python:3.12.2-slim-bullseye (amd64)
|
||||||
RUN useradd costhive
|
RUN useradd costhive
|
||||||
|
|
||||||
WORKDIR /home/costhive
|
WORKDIR /home/costhive
|
||||||
|
|
||||||
RUN apt update && apt -y upgrade
|
RUN apt update && apt -y upgrade; \
|
||||||
RUN apt install -y libpq-dev gcc g++ swig make
|
apt install -y libpq-dev gcc g++ swig make cmake m4; \
|
||||||
|
rm -rf /var/lib/apt/lists
|
||||||
|
|
||||||
COPY boot.sh requirements.txt ./
|
COPY boot.sh backend/requirements.txt ./
|
||||||
RUN python -m venv venv
|
RUN python -m venv venv; \
|
||||||
RUN venv/bin/pip install -r requirements.txt
|
venv/bin/pip install --upgrade pip; \
|
||||||
RUN venv/bin/pip install gunicorn
|
venv/bin/pip install wheel gunicorn; \
|
||||||
RUN chmod +x boot.sh
|
venv/bin/pip install -r requirements.txt
|
||||||
|
|
||||||
COPY backend backend
|
COPY backend backend
|
||||||
|
|
||||||
ENV FLASK_APP run.py
|
ENV FLASK_APP=run.py
|
||||||
|
|
||||||
RUN chown -R costhive:costhive ./
|
RUN chmod +x boot.sh; \
|
||||||
|
chown -R costhive:costhive .
|
||||||
|
|
||||||
USER costhive
|
USER costhive
|
||||||
|
|
||||||
|
|||||||
12
Pipfile
12
Pipfile
@ -1,12 +0,0 @@
|
|||||||
[[source]]
|
|
||||||
url = "https://pypi.org/simple"
|
|
||||||
verify_ssl = true
|
|
||||||
name = "pypi"
|
|
||||||
|
|
||||||
[packages]
|
|
||||||
flask-cors = "*"
|
|
||||||
|
|
||||||
[dev-packages]
|
|
||||||
|
|
||||||
[requires]
|
|
||||||
python_version = "3.10"
|
|
||||||
141
Pipfile.lock
generated
141
Pipfile.lock
generated
@ -1,141 +0,0 @@
|
|||||||
{
|
|
||||||
"_meta": {
|
|
||||||
"hash": {
|
|
||||||
"sha256": "2f46680952b8ccfaf093f8ef1315053afb3d2e15fc244d50f313d0961890dfc3"
|
|
||||||
},
|
|
||||||
"pipfile-spec": 6,
|
|
||||||
"requires": {
|
|
||||||
"python_version": "3.10"
|
|
||||||
},
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"name": "pypi",
|
|
||||||
"url": "https://pypi.org/simple",
|
|
||||||
"verify_ssl": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"click": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
|
||||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.7'",
|
|
||||||
"version": "==8.1.3"
|
|
||||||
},
|
|
||||||
"colorama": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44",
|
|
||||||
"sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"
|
|
||||||
],
|
|
||||||
"markers": "platform_system == 'Windows'",
|
|
||||||
"version": "==0.4.6"
|
|
||||||
},
|
|
||||||
"flask": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:7eb373984bf1c770023fce9db164ed0c3353cd0b53f130f4693da0ca756a2e6d",
|
|
||||||
"sha256:c0bec9477df1cb867e5a67c9e1ab758de9cb4a3e52dd70681f59fa40a62b3f2d"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.7'",
|
|
||||||
"version": "==2.2.3"
|
|
||||||
},
|
|
||||||
"flask-cors": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438",
|
|
||||||
"sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==3.0.10"
|
|
||||||
},
|
|
||||||
"itsdangerous": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
|
|
||||||
"sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.7'",
|
|
||||||
"version": "==2.1.2"
|
|
||||||
},
|
|
||||||
"jinja2": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
|
|
||||||
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.7'",
|
|
||||||
"version": "==3.1.2"
|
|
||||||
},
|
|
||||||
"markupsafe": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed",
|
|
||||||
"sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc",
|
|
||||||
"sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2",
|
|
||||||
"sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460",
|
|
||||||
"sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7",
|
|
||||||
"sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0",
|
|
||||||
"sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1",
|
|
||||||
"sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa",
|
|
||||||
"sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03",
|
|
||||||
"sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323",
|
|
||||||
"sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65",
|
|
||||||
"sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013",
|
|
||||||
"sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036",
|
|
||||||
"sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f",
|
|
||||||
"sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4",
|
|
||||||
"sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419",
|
|
||||||
"sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2",
|
|
||||||
"sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619",
|
|
||||||
"sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a",
|
|
||||||
"sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a",
|
|
||||||
"sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd",
|
|
||||||
"sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7",
|
|
||||||
"sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666",
|
|
||||||
"sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65",
|
|
||||||
"sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859",
|
|
||||||
"sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625",
|
|
||||||
"sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff",
|
|
||||||
"sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156",
|
|
||||||
"sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd",
|
|
||||||
"sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba",
|
|
||||||
"sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f",
|
|
||||||
"sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1",
|
|
||||||
"sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094",
|
|
||||||
"sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a",
|
|
||||||
"sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513",
|
|
||||||
"sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed",
|
|
||||||
"sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d",
|
|
||||||
"sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3",
|
|
||||||
"sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147",
|
|
||||||
"sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c",
|
|
||||||
"sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603",
|
|
||||||
"sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601",
|
|
||||||
"sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a",
|
|
||||||
"sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1",
|
|
||||||
"sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d",
|
|
||||||
"sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3",
|
|
||||||
"sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54",
|
|
||||||
"sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2",
|
|
||||||
"sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6",
|
|
||||||
"sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.7'",
|
|
||||||
"version": "==2.1.2"
|
|
||||||
},
|
|
||||||
"six": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
|
||||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
|
|
||||||
"version": "==1.16.0"
|
|
||||||
},
|
|
||||||
"werkzeug": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe",
|
|
||||||
"sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612"
|
|
||||||
],
|
|
||||||
"markers": "python_version >= '3.7'",
|
|
||||||
"version": "==2.2.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"develop": {}
|
|
||||||
}
|
|
||||||
@ -7,20 +7,25 @@ name = "pypi"
|
|||||||
email-validator = "*"
|
email-validator = "*"
|
||||||
flask = "*"
|
flask = "*"
|
||||||
flask-bootstrap = "*"
|
flask-bootstrap = "*"
|
||||||
|
flask-cors = "*"
|
||||||
flask-login = "*"
|
flask-login = "*"
|
||||||
flask-mail = "*"
|
flask-mail = "*"
|
||||||
|
flask-marshmallow = "*"
|
||||||
flask-migrate = "*"
|
flask-migrate = "*"
|
||||||
flask-sqlalchemy = "*"
|
flask-sqlalchemy = "*"
|
||||||
flask-wtf = "*"
|
flask-wtf = "*"
|
||||||
|
marshmallow-sqlalchemy = "*"
|
||||||
psycopg2-binary = "*"
|
psycopg2-binary = "*"
|
||||||
pyjwt = "*"
|
pyjwt = "*"
|
||||||
python-dotenv = "*"
|
python-dotenv = "*"
|
||||||
pymupdf = "*"
|
pymupdf = "*"
|
||||||
|
requests = "*"
|
||||||
sqlalchemy-utils = "*"
|
sqlalchemy-utils = "*"
|
||||||
marshmallow = "*"
|
wtforms-sqlalchemy = "*"
|
||||||
|
pytest = "*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
|
|
||||||
[requires]
|
[requires]
|
||||||
python_version = "3.10"
|
python_version = "3.11"
|
||||||
python_full_version = "3.10.10"
|
python_full_version = "3.11.4"
|
||||||
|
|||||||
846
backend/Pipfile.lock
generated
846
backend/Pipfile.lock
generated
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@ from dotenv import load_dotenv
|
|||||||
basedir = os.path.abspath(os.path.dirname(__file__))
|
basedir = os.path.abspath(os.path.dirname(__file__))
|
||||||
load_dotenv(os.path.join(basedir, '.env'))
|
load_dotenv(os.path.join(basedir, '.env'))
|
||||||
|
|
||||||
|
os.environ["TESSDATA_PREFIX"] = os.path.join(basedir, 'tessdata')
|
||||||
class Config(object):
|
class Config(object):
|
||||||
SECRET_KEY = os.environ.get('SECRET_KEY') or "s0m37h!n6-obfu5c471ng"
|
SECRET_KEY = os.environ.get('SECRET_KEY') or "s0m37h!n6-obfu5c471ng"
|
||||||
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', '').replace(
|
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', '').replace(
|
||||||
@ -18,4 +19,5 @@ class Config(object):
|
|||||||
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
|
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
|
||||||
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
|
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
|
||||||
ADMINS = ['postmaster@wpgcommunity.net']
|
ADMINS = ['postmaster@wpgcommunity.net']
|
||||||
POSTS_PER_PAGE = 10
|
POSTS_PER_PAGE = 15
|
||||||
|
RECEIPT_FOLDER = f"{basedir}/../PDFReceipts"
|
||||||
BIN
backend/configs/tessdata/ScrollView.jar
Normal file
BIN
backend/configs/tessdata/ScrollView.jar
Normal file
Binary file not shown.
1
backend/configs/tessdata/configs/alto
Normal file
1
backend/configs/tessdata/configs/alto
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_create_alto 1
|
||||||
7
backend/configs/tessdata/configs/ambigs.train
Normal file
7
backend/configs/tessdata/configs/ambigs.train
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
tessedit_ambigs_training 1
|
||||||
|
load_freq_dawg 0
|
||||||
|
load_punc_dawg 0
|
||||||
|
load_system_dawg 0
|
||||||
|
load_number_dawg 0
|
||||||
|
ambigs_debug_level 3
|
||||||
|
load_fixed_length_dawgs 0
|
||||||
1
backend/configs/tessdata/configs/api_config
Normal file
1
backend/configs/tessdata/configs/api_config
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_zero_rejection T
|
||||||
5
backend/configs/tessdata/configs/bigram
Normal file
5
backend/configs/tessdata/configs/bigram
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
load_bigram_dawg True
|
||||||
|
tessedit_enable_bigram_correction True
|
||||||
|
tessedit_bigram_debug 3
|
||||||
|
save_raw_choices True
|
||||||
|
save_alt_choices True
|
||||||
12
backend/configs/tessdata/configs/box.train
Normal file
12
backend/configs/tessdata/configs/box.train
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
disable_character_fragments T
|
||||||
|
file_type .bl
|
||||||
|
textord_fast_pitch_test T
|
||||||
|
tessedit_zero_rejection T
|
||||||
|
tessedit_minimal_rejection F
|
||||||
|
tessedit_write_rep_codes F
|
||||||
|
edges_children_fix F
|
||||||
|
edges_childarea 0.65
|
||||||
|
edges_boxarea 0.9
|
||||||
|
tessedit_resegment_from_boxes T
|
||||||
|
tessedit_train_from_boxes T
|
||||||
|
textord_no_rejects T
|
||||||
13
backend/configs/tessdata/configs/box.train.stderr
Normal file
13
backend/configs/tessdata/configs/box.train.stderr
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
file_type .bl
|
||||||
|
#tessedit_use_nn F
|
||||||
|
textord_fast_pitch_test T
|
||||||
|
tessedit_zero_rejection T
|
||||||
|
tessedit_minimal_rejection F
|
||||||
|
tessedit_write_rep_codes F
|
||||||
|
edges_children_fix F
|
||||||
|
edges_childarea 0.65
|
||||||
|
edges_boxarea 0.9
|
||||||
|
tessedit_resegment_from_boxes T
|
||||||
|
tessedit_train_from_boxes T
|
||||||
|
#textord_repeat_extraction F
|
||||||
|
textord_no_rejects T
|
||||||
1
backend/configs/tessdata/configs/digits
Normal file
1
backend/configs/tessdata/configs/digits
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_char_whitelist 0123456789-.
|
||||||
1
backend/configs/tessdata/configs/get.images
Normal file
1
backend/configs/tessdata/configs/get.images
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_write_images T
|
||||||
2
backend/configs/tessdata/configs/hocr
Normal file
2
backend/configs/tessdata/configs/hocr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
tessedit_create_hocr 1
|
||||||
|
hocr_font_info 0
|
||||||
2
backend/configs/tessdata/configs/inter
Normal file
2
backend/configs/tessdata/configs/inter
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
interactive_display_mode T
|
||||||
|
tessedit_display_outwords T
|
||||||
4
backend/configs/tessdata/configs/kannada
Normal file
4
backend/configs/tessdata/configs/kannada
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
textord_skewsmooth_offset 8
|
||||||
|
textord_skewsmooth_offset2 8
|
||||||
|
textord_merge_desc 0.5
|
||||||
|
textord_no_rejects 1
|
||||||
2
backend/configs/tessdata/configs/linebox
Normal file
2
backend/configs/tessdata/configs/linebox
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
tessedit_resegment_from_line_boxes 1
|
||||||
|
tessedit_make_boxes_from_boxes 1
|
||||||
1
backend/configs/tessdata/configs/logfile
Normal file
1
backend/configs/tessdata/configs/logfile
Normal file
@ -0,0 +1 @@
|
|||||||
|
debug_file tesseract.log
|
||||||
11
backend/configs/tessdata/configs/lstm.train
Normal file
11
backend/configs/tessdata/configs/lstm.train
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
file_type .bl
|
||||||
|
textord_fast_pitch_test T
|
||||||
|
tessedit_zero_rejection T
|
||||||
|
tessedit_minimal_rejection F
|
||||||
|
tessedit_write_rep_codes F
|
||||||
|
edges_children_fix F
|
||||||
|
edges_childarea 0.65
|
||||||
|
edges_boxarea 0.9
|
||||||
|
tessedit_train_line_recognizer T
|
||||||
|
textord_no_rejects T
|
||||||
|
tessedit_init_config_only T
|
||||||
1
backend/configs/tessdata/configs/lstmbox
Normal file
1
backend/configs/tessdata/configs/lstmbox
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_create_lstmbox 1
|
||||||
4
backend/configs/tessdata/configs/lstmdebug
Normal file
4
backend/configs/tessdata/configs/lstmdebug
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
stopper_debug_level 1
|
||||||
|
classify_debug_level 1
|
||||||
|
segsearch_debug_level 1
|
||||||
|
language_model_debug_level 3
|
||||||
1
backend/configs/tessdata/configs/makebox
Normal file
1
backend/configs/tessdata/configs/makebox
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_create_boxfile 1
|
||||||
1
backend/configs/tessdata/configs/pdf
Normal file
1
backend/configs/tessdata/configs/pdf
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_create_pdf 1
|
||||||
1
backend/configs/tessdata/configs/quiet
Normal file
1
backend/configs/tessdata/configs/quiet
Normal file
@ -0,0 +1 @@
|
|||||||
|
debug_file /dev/null
|
||||||
2
backend/configs/tessdata/configs/rebox
Normal file
2
backend/configs/tessdata/configs/rebox
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
tessedit_resegment_from_boxes 1
|
||||||
|
tessedit_make_boxes_from_boxes 1
|
||||||
12
backend/configs/tessdata/configs/strokewidth
Normal file
12
backend/configs/tessdata/configs/strokewidth
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
textord_show_blobs 0
|
||||||
|
textord_debug_tabfind 3
|
||||||
|
textord_tabfind_show_partitions 1
|
||||||
|
textord_tabfind_show_initial_partitions 1
|
||||||
|
textord_tabfind_show_columns 1
|
||||||
|
textord_tabfind_show_blocks 1
|
||||||
|
textord_tabfind_show_initialtabs 1
|
||||||
|
textord_tabfind_show_finaltabs 1
|
||||||
|
textord_tabfind_show_strokewidths 1
|
||||||
|
textord_tabfind_show_vlines 0
|
||||||
|
textord_tabfind_show_images 1
|
||||||
|
tessedit_dump_pageseg_images 0
|
||||||
1
backend/configs/tessdata/configs/tsv
Normal file
1
backend/configs/tessdata/configs/tsv
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_create_tsv 1
|
||||||
3
backend/configs/tessdata/configs/txt
Normal file
3
backend/configs/tessdata/configs/txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This config file should be used with other config files which create renderers.
|
||||||
|
# usage example: tesseract eurotext.tif eurotext txt hocr pdf
|
||||||
|
tessedit_create_txt 1
|
||||||
2
backend/configs/tessdata/configs/unlv
Normal file
2
backend/configs/tessdata/configs/unlv
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
tessedit_write_unlv 1
|
||||||
|
unlv_tilde_crunching T
|
||||||
1
backend/configs/tessdata/configs/wordstrbox
Normal file
1
backend/configs/tessdata/configs/wordstrbox
Normal file
@ -0,0 +1 @@
|
|||||||
|
tessedit_create_wordstrbox 1
|
||||||
BIN
backend/configs/tessdata/deu.traineddata
Normal file
BIN
backend/configs/tessdata/deu.traineddata
Normal file
Binary file not shown.
BIN
backend/configs/tessdata/deu.traineddata.old
Normal file
BIN
backend/configs/tessdata/deu.traineddata.old
Normal file
Binary file not shown.
BIN
backend/configs/tessdata/eng.traineddata
Normal file
BIN
backend/configs/tessdata/eng.traineddata
Normal file
Binary file not shown.
2
backend/configs/tessdata/eng.user-patterns
Normal file
2
backend/configs/tessdata/eng.user-patterns
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1-\d\d\d-GOOG-411
|
||||||
|
www.\n\\\*.com
|
||||||
5
backend/configs/tessdata/eng.user-words
Normal file
5
backend/configs/tessdata/eng.user-words
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
the
|
||||||
|
quick
|
||||||
|
brown
|
||||||
|
fox
|
||||||
|
jumped
|
||||||
BIN
backend/configs/tessdata/jaxb-api-2.3.1.jar
Normal file
BIN
backend/configs/tessdata/jaxb-api-2.3.1.jar
Normal file
Binary file not shown.
BIN
backend/configs/tessdata/osd.traineddata
Normal file
BIN
backend/configs/tessdata/osd.traineddata
Normal file
Binary file not shown.
BIN
backend/configs/tessdata/pdf.ttf
Normal file
BIN
backend/configs/tessdata/pdf.ttf
Normal file
Binary file not shown.
BIN
backend/configs/tessdata/piccolo2d-core-3.0.1.jar
Normal file
BIN
backend/configs/tessdata/piccolo2d-core-3.0.1.jar
Normal file
Binary file not shown.
BIN
backend/configs/tessdata/piccolo2d-extras-3.0.1.jar
Normal file
BIN
backend/configs/tessdata/piccolo2d-extras-3.0.1.jar
Normal file
Binary file not shown.
1
backend/configs/tessdata/tessconfigs/batch
Normal file
1
backend/configs/tessdata/tessconfigs/batch
Normal file
@ -0,0 +1 @@
|
|||||||
|
# No content needed as all defaults are correct.
|
||||||
2
backend/configs/tessdata/tessconfigs/batch.nochop
Normal file
2
backend/configs/tessdata/tessconfigs/batch.nochop
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
chop_enable 0
|
||||||
|
wordrec_enable_assoc 0
|
||||||
7
backend/configs/tessdata/tessconfigs/matdemo
Normal file
7
backend/configs/tessdata/tessconfigs/matdemo
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#################################################
|
||||||
|
# Adaptive Matcher Using PreAdapted Templates
|
||||||
|
#################################################
|
||||||
|
|
||||||
|
classify_enable_adaptive_debugger 1
|
||||||
|
matcher_debug_flags 6
|
||||||
|
matcher_debug_level 1
|
||||||
12
backend/configs/tessdata/tessconfigs/msdemo
Normal file
12
backend/configs/tessdata/tessconfigs/msdemo
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#################################################
|
||||||
|
# Adaptive Matcher Using PreAdapted Templates
|
||||||
|
#################################################
|
||||||
|
|
||||||
|
classify_enable_adaptive_debugger 1
|
||||||
|
matcher_debug_flags 6
|
||||||
|
matcher_debug_level 1
|
||||||
|
|
||||||
|
wordrec_display_splits 0
|
||||||
|
wordrec_display_all_blobs 1
|
||||||
|
wordrec_display_segmentations 2
|
||||||
|
classify_debug_level 1
|
||||||
1
backend/configs/tessdata/tessconfigs/nobatch
Normal file
1
backend/configs/tessdata/tessconfigs/nobatch
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
9
backend/configs/tessdata/tessconfigs/segdemo
Normal file
9
backend/configs/tessdata/tessconfigs/segdemo
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#################################################
|
||||||
|
# Adaptive Matcher Using PreAdapted Templates
|
||||||
|
#################################################
|
||||||
|
|
||||||
|
wordrec_display_splits 0
|
||||||
|
wordrec_display_all_blobs 1
|
||||||
|
wordrec_display_segmentations 2
|
||||||
|
classify_debug_level 1
|
||||||
|
stopper_debug_level 1
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
"""Add table for logintoken de-/activation dates
|
||||||
|
|
||||||
|
Revision ID: 015f4256bb4c
|
||||||
|
Revises: 9a8c73f0ab11
|
||||||
|
Create Date: 2023-11-19 20:52:03.377745
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '015f4256bb4c'
|
||||||
|
down_revision = '9a8c73f0ab11'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('login_token_dates',
|
||||||
|
sa.Column('token', sa.String(length=15), nullable=False),
|
||||||
|
sa.Column('activation_date', sa.Date(), server_default=sa.text('now()'), nullable=False),
|
||||||
|
sa.Column('deactivation_date', sa.Date(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['token'], ['login_token.token'], ),
|
||||||
|
sa.PrimaryKeyConstraint('token', 'activation_date')
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('login_token_dates')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
"""receipt id serial
|
||||||
|
|
||||||
|
Revision ID: 0fa2ef37e440
|
||||||
|
Revises: f6f97ed9c053
|
||||||
|
Create Date: 2023-07-25 21:26:25.353435
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '0fa2ef37e440'
|
||||||
|
down_revision = 'f6f97ed9c053'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.execute("CREATE SEQUENCE receipt_id_seq;")
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('id',
|
||||||
|
existing_type=sa.BIGINT(),
|
||||||
|
type_=sa.Integer(),
|
||||||
|
existing_nullable=False,
|
||||||
|
server_default=sa.sql.func.next_value(sa.Sequence('receipt_id_seq')))
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('receipt',
|
||||||
|
existing_type=sa.BIGINT(),
|
||||||
|
type_=sa.Integer(),
|
||||||
|
existing_nullable=False)
|
||||||
|
|
||||||
|
op.execute("ALTER SEQUENCE receipt_id_seq OWNED BY receipt.id;")
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('receipt',
|
||||||
|
existing_type=sa.Integer(),
|
||||||
|
type_=sa.BIGINT(),
|
||||||
|
existing_nullable=False)
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('id',
|
||||||
|
existing_type=sa.Integer(),
|
||||||
|
type_=sa.BIGINT(),
|
||||||
|
existing_nullable=False)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
"""new table for bought entries with unknown items 2
|
||||||
|
|
||||||
|
Revision ID: 2a64d3b9235a
|
||||||
|
Revises: 015f4256bb4c
|
||||||
|
Create Date: 2024-06-02 13:19:59.901053
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2a64d3b9235a'
|
||||||
|
down_revision = '015f4256bb4c'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('bought_with_unknown_item',
|
||||||
|
sa.Column('token', sa.String(length=15), nullable=False),
|
||||||
|
sa.Column('item', sa.BigInteger(), nullable=False),
|
||||||
|
sa.Column('date', sa.Date(), nullable=False),
|
||||||
|
sa.Column('amount', sa.SmallInteger(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['token'], ['login_token.token'], ),
|
||||||
|
sa.PrimaryKeyConstraint('token', 'item', 'date')
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('bought_with_unknown_item')
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
"""Remove accepted from receiptitem
|
||||||
|
|
||||||
|
Revision ID: 36f532800705
|
||||||
|
Revises: cdbe3f5e3b30
|
||||||
|
Create Date: 2023-11-11 10:45:44.652161
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '36f532800705'
|
||||||
|
down_revision = 'cdbe3f5e3b30'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('accepted')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('accepted', sa.BOOLEAN(), autoincrement=False, nullable=False))
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
"""Delete unnecessary columns
|
||||||
|
|
||||||
|
Revision ID: 4fec22c35530
|
||||||
|
Revises: 610854a6e2a0
|
||||||
|
Create Date: 2023-05-28 08:10:27.689070
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '4fec22c35530'
|
||||||
|
down_revision = '610854a6e2a0'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('bought', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('registered')
|
||||||
|
|
||||||
|
with op.batch_alter_table('login_token', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('paid')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('login_token', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('paid', sa.BIGINT(), server_default=sa.text("'0'::bigint"), autoincrement=False, nullable=False))
|
||||||
|
|
||||||
|
with op.batch_alter_table('bought', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('registered', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=False))
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -26,7 +26,7 @@ def upgrade():
|
|||||||
sa.PrimaryKeyConstraint('user', 'establishment')
|
sa.PrimaryKeyConstraint('user', 'establishment')
|
||||||
)
|
)
|
||||||
op.create_table('payment',
|
op.create_table('payment',
|
||||||
sa.Column('id', sa.BigInteger(), nullable=False),
|
sa.Column('id', sa.BigInteger(), nullable=False, autoincrement=True),
|
||||||
sa.Column('token', sa.String(length=15), nullable=False),
|
sa.Column('token', sa.String(length=15), nullable=False),
|
||||||
sa.Column('date', sa.Date(), server_default=sa.text('now()'), nullable=False),
|
sa.Column('date', sa.Date(), server_default=sa.text('now()'), nullable=False),
|
||||||
sa.Column('amount', sa.BigInteger(), server_default='0', nullable=False),
|
sa.Column('amount', sa.BigInteger(), server_default='0', nullable=False),
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
"""raise password char length
|
||||||
|
|
||||||
|
Revision ID: 782a2409df41
|
||||||
|
Revises: 926395732c3e
|
||||||
|
Create Date: 2025-06-03 21:01:23.169897
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '782a2409df41'
|
||||||
|
down_revision = '926395732c3e'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('password_hash',
|
||||||
|
existing_type=sa.VARCHAR(length=128),
|
||||||
|
type_=sa.String(length=255),
|
||||||
|
existing_nullable=False)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('password_hash',
|
||||||
|
existing_type=sa.String(length=255),
|
||||||
|
type_=sa.VARCHAR(length=128),
|
||||||
|
existing_nullable=False)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
"""raise bonid digits
|
||||||
|
|
||||||
|
Revision ID: 926395732c3e
|
||||||
|
Revises: 2a64d3b9235a
|
||||||
|
Create Date: 2024-08-24 10:33:39.109944
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '926395732c3e'
|
||||||
|
down_revision = '2a64d3b9235a'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('bonid',
|
||||||
|
existing_type=sa.NUMERIC(precision=24, scale=0),
|
||||||
|
type_=sa.Numeric(precision=28, scale=0),
|
||||||
|
existing_nullable=True)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('bonid',
|
||||||
|
existing_type=sa.Numeric(precision=28, scale=0),
|
||||||
|
type_=sa.NUMERIC(precision=24, scale=0),
|
||||||
|
existing_nullable=True)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
"""add receiptitem names
|
||||||
|
|
||||||
|
Revision ID: 9a8c73f0ab11
|
||||||
|
Revises: 36f532800705
|
||||||
|
Create Date: 2023-11-18 23:38:56.865780
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '9a8c73f0ab11'
|
||||||
|
down_revision = '36f532800705'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('name', sa.String(), nullable=True))
|
||||||
|
op.execute("UPDATE receipt_item SET name='Unknown' WHERE name IS NULL;")
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('name', nullable=False)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('name')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
"""Remove item.receiptitem relationship
|
||||||
|
|
||||||
|
Revision ID: cdbe3f5e3b30
|
||||||
|
Revises: 0fa2ef37e440
|
||||||
|
Create Date: 2023-09-19 19:02:23.003034
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'cdbe3f5e3b30'
|
||||||
|
down_revision = '0fa2ef37e440'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('id',
|
||||||
|
existing_type=sa.INTEGER(),
|
||||||
|
type_=sa.BigInteger(),
|
||||||
|
existing_nullable=False,
|
||||||
|
autoincrement=True)
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('price', sa.SmallInteger(), nullable=False))
|
||||||
|
batch_op.alter_column('receipt',
|
||||||
|
existing_type=sa.INTEGER(),
|
||||||
|
type_=sa.BigInteger(),
|
||||||
|
existing_nullable=False)
|
||||||
|
batch_op.alter_column('item',
|
||||||
|
existing_type=sa.BIGINT(),
|
||||||
|
type_=sa.SmallInteger(),
|
||||||
|
existing_nullable=False)
|
||||||
|
batch_op.drop_constraint('item_receipt_item_fkey', type_='foreignkey')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.create_foreign_key('item_receipt_item_fkey', 'item', ['item'], ['id'])
|
||||||
|
batch_op.alter_column('item',
|
||||||
|
existing_type=sa.SmallInteger(),
|
||||||
|
type_=sa.BIGINT(),
|
||||||
|
existing_nullable=False)
|
||||||
|
batch_op.alter_column('receipt',
|
||||||
|
existing_type=sa.BigInteger(),
|
||||||
|
type_=sa.INTEGER(),
|
||||||
|
existing_nullable=False)
|
||||||
|
batch_op.drop_column('price')
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('id',
|
||||||
|
existing_type=sa.BigInteger(),
|
||||||
|
type_=sa.INTEGER(),
|
||||||
|
existing_nullable=False,
|
||||||
|
autoincrement=True)
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
"""receipt-id reorganized
|
||||||
|
|
||||||
|
Revision ID: f6f97ed9c053
|
||||||
|
Revises: 4fec22c35530
|
||||||
|
Create Date: 2023-07-02 14:16:06.260479
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'f6f97ed9c053'
|
||||||
|
down_revision = '4fec22c35530'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('accepted', sa.Boolean(), nullable=False))
|
||||||
|
batch_op.drop_constraint("item_receipt_receipt_fkey")
|
||||||
|
batch_op.alter_column('receipt',
|
||||||
|
existing_type=sa.NUMERIC(precision=24, scale=0),
|
||||||
|
type_=sa.BigInteger(),
|
||||||
|
existing_nullable=False)
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.add_column(sa.Column('bonid', sa.Numeric(precision=24, scale=0), nullable=True))
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.execute("UPDATE receipt SET bonid=id;")
|
||||||
|
batch_op.alter_column('id',
|
||||||
|
existing_type=sa.NUMERIC(precision=24, scale=0),
|
||||||
|
type_=sa.BigInteger(),
|
||||||
|
existing_nullable=False,
|
||||||
|
autoincrement=True)
|
||||||
|
batch_op.create_unique_constraint(None, ['bonid'])
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.create_foreign_key(None, 'receipt', ['receipt'], ['id'])
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
with op.batch_alter_table('receipt_item', schema=None) as batch_op:
|
||||||
|
batch_op.alter_column('receipt',
|
||||||
|
existing_type=sa.BigInteger(),
|
||||||
|
type_=sa.NUMERIC(precision=24, scale=0),
|
||||||
|
existing_nullable=False)
|
||||||
|
batch_op.drop_column('accepted')
|
||||||
|
|
||||||
|
with op.batch_alter_table('receipt', schema=None) as batch_op:
|
||||||
|
batch_op.drop_constraint(None, type_='unique')
|
||||||
|
batch_op.alter_column('id',
|
||||||
|
existing_type=sa.BigInteger(),
|
||||||
|
type_=sa.NUMERIC(precision=24, scale=0),
|
||||||
|
existing_nullable=False,
|
||||||
|
autoincrement=True)
|
||||||
|
batch_op.drop_column('bonid')
|
||||||
|
|
||||||
|
# ### end Alembic commands ###
|
||||||
18
backend/models/__init__.py
Normal file
18
backend/models/__init__.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from .payment import Payment
|
||||||
|
from .receipt_item import ReceiptItem
|
||||||
|
from .receipt import Receipt
|
||||||
|
from .login_token import LoginToken
|
||||||
|
from .bought import Bought
|
||||||
|
from .bought_with_unknown_item import BoughtWithUnknownItem
|
||||||
|
from .establishment import Establishment
|
||||||
|
from .establishment_candidate import EstablishmentCandidate
|
||||||
|
from .user import User
|
||||||
|
from .amount_change import AmountChange
|
||||||
|
from .price_change import PriceChange
|
||||||
|
from .category import Category
|
||||||
|
from .item import Item
|
||||||
|
from .brand import Brand
|
||||||
|
from .item_category import item_category
|
||||||
|
from .login_token_dates import LoginTokenDates
|
||||||
|
|
||||||
|
from .schemas import *
|
||||||
@ -1,9 +1,12 @@
|
|||||||
from src import db
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
class AmountChange(db.Model):
|
class AmountChange(db.Model):
|
||||||
item = db.Column(db.ForeignKey('item.id'), primary_key=True, server_onupdate=db.FetchedValue())
|
item = db.Column(db.ForeignKey('item.id'), primary_key=True,
|
||||||
date = db.Column(db.Date, primary_key=True, server_default=str(date(2021, 12, 1)))
|
server_onupdate=db.FetchedValue())
|
||||||
|
date = db.Column(db.Date, primary_key=True,
|
||||||
|
server_default=str(date(2021, 12, 1)))
|
||||||
amount = db.Column(db.SmallInteger, nullable=False, server_default=str(1))
|
amount = db.Column(db.SmallInteger, nullable=False, server_default=str(1))
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
13
backend/models/bought.py
Normal file
13
backend/models/bought.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
|
class Bought(db.Model):
|
||||||
|
token = db.Column(db.ForeignKey('login_token.token'),
|
||||||
|
primary_key=True, server_onupdate=db.FetchedValue())
|
||||||
|
item = db.Column(db.ForeignKey('item.id'), primary_key=True,
|
||||||
|
server_onupdate=db.FetchedValue())
|
||||||
|
date = db.Column(db.Date, primary_key=True)
|
||||||
|
amount = db.Column(db.SmallInteger, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Bought Object>"
|
||||||
14
backend/models/bought_with_unknown_item.py
Normal file
14
backend/models/bought_with_unknown_item.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from src import db
|
||||||
|
from .bought import Bought
|
||||||
|
|
||||||
|
|
||||||
|
class BoughtWithUnknownItem(db.Model):
|
||||||
|
token = db.Column(db.ForeignKey('login_token.token'),
|
||||||
|
primary_key=True, server_onupdate=db.FetchedValue())
|
||||||
|
item = db.Column(db.BigInteger, primary_key=True,
|
||||||
|
server_onupdate=db.FetchedValue())
|
||||||
|
date = db.Column(db.Date, primary_key=True)
|
||||||
|
amount = db.Column(db.SmallInteger, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Bought Object>"
|
||||||
@ -1,10 +1,14 @@
|
|||||||
from src import db
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
class Brand(db.Model):
|
class Brand(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||||
name = db.Column(db.String(32), nullable=False)
|
name = db.Column(db.String(32), nullable=False)
|
||||||
|
|
||||||
Item = db.relationship("Item", backref='Brand', lazy='dynamic')
|
Item = db.relationship("Item", backref='Brand', lazy='dynamic')
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<Brand {self.id} ({self.name})>"
|
return f"<Brand {self.id} ({self.name})>"
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"{self.name}"
|
||||||
13
backend/models/category.py
Normal file
13
backend/models/category.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import db
|
||||||
|
from .item_category import item_category
|
||||||
|
|
||||||
|
|
||||||
|
class Category(db.Model):
|
||||||
|
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
|
||||||
|
name = db.Column(db.String(32), nullable=False, unique=True)
|
||||||
|
|
||||||
|
Item = db.relationship("Item", secondary=item_category,
|
||||||
|
lazy="dynamic", back_populates="Category")
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Category {self.id} ({self.name})>"
|
||||||
17
backend/models/establishment.py
Normal file
17
backend/models/establishment.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
|
class Establishment(db.Model):
|
||||||
|
id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
|
||||||
|
name = db.Column(db.String(64), nullable=False)
|
||||||
|
owner = db.Column(db.ForeignKey('user.id'), nullable=False)
|
||||||
|
|
||||||
|
LoginToken = db.relationship(
|
||||||
|
"LoginToken", backref='Establishment', lazy='dynamic')
|
||||||
|
Bought = db.relationship("Bought", secondary="login_token",
|
||||||
|
lazy='dynamic', overlaps="Establishment,LoginToken,Bought")
|
||||||
|
EstablishmentCandidate = db.relationship(
|
||||||
|
"EstablishmentCandidate", backref='Establishment', lazy='dynamic')
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Establishment {self.id} ({self.name})>"
|
||||||
@ -1,8 +1,10 @@
|
|||||||
from src import db
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentCandidate(db.Model):
|
class EstablishmentCandidate(db.Model):
|
||||||
user = db.Column(db.ForeignKey('user.id'), primary_key=True)
|
user = db.Column(db.ForeignKey('user.id'), primary_key=True)
|
||||||
establishment = db.Column(db.ForeignKey('establishment.id'), primary_key=True)
|
establishment = db.Column(db.ForeignKey(
|
||||||
|
'establishment.id'), primary_key=True)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<EstablishmentCandidate {self.user} ({self.establishment})>"
|
return f"<EstablishmentCandidate {self.user} ({self.establishment})>"
|
||||||
24
backend/models/item.py
Normal file
24
backend/models/item.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from src import db, ma
|
||||||
|
from .item_category import item_category
|
||||||
|
|
||||||
|
|
||||||
|
class Item(db.Model):
|
||||||
|
id = db.Column(db.BigInteger, primary_key=True, autoincrement=False)
|
||||||
|
name = db.Column(db.String(64), nullable=False)
|
||||||
|
brand = db.Column(db.ForeignKey('brand.id'), nullable=False,
|
||||||
|
server_onupdate=db.FetchedValue())
|
||||||
|
description = db.Column(db.Text, nullable=False)
|
||||||
|
|
||||||
|
AmountChange = db.relationship(
|
||||||
|
"AmountChange", backref='Item', lazy='dynamic')
|
||||||
|
Bought = db.relationship("Bought", backref='Item', lazy='dynamic')
|
||||||
|
Category = db.relationship(
|
||||||
|
"Category", secondary=item_category, lazy="dynamic", back_populates="Item")
|
||||||
|
PriceChange = db.relationship(
|
||||||
|
"PriceChange", backref='Item', lazy='dynamic')
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Item {self.id} ({self.name})>"
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f"({self.id}) {self.description}"
|
||||||
@ -1,10 +1,14 @@
|
|||||||
from src import db
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
class LoginToken(db.Model):
|
class LoginToken(db.Model):
|
||||||
user = db.Column(db.ForeignKey('user.id'), primary_key=True, server_onupdate=db.FetchedValue())
|
user = db.Column(db.ForeignKey('user.id'), primary_key=True,
|
||||||
establishment = db.Column(db.ForeignKey('establishment.id'), primary_key=True, server_onupdate=db.FetchedValue())
|
server_onupdate=db.FetchedValue())
|
||||||
|
establishment = db.Column(db.ForeignKey(
|
||||||
|
'establishment.id'), primary_key=True, server_onupdate=db.FetchedValue())
|
||||||
token = db.Column(db.String(15), nullable=False, unique=True)
|
token = db.Column(db.String(15), nullable=False, unique=True)
|
||||||
|
|
||||||
|
LoginTokenDates = db.relationship("LoginTokenDates", backref='LoginToken', lazy='dynamic')
|
||||||
Payment = db.relationship("Payment", backref='LoginToken', lazy='dynamic')
|
Payment = db.relationship("Payment", backref='LoginToken', lazy='dynamic')
|
||||||
Receipt = db.relationship("Receipt", backref='LoginToken', lazy='dynamic')
|
Receipt = db.relationship("Receipt", backref='LoginToken', lazy='dynamic')
|
||||||
|
|
||||||
13
backend/models/login_token_dates.py
Normal file
13
backend/models/login_token_dates.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import db
|
||||||
|
|
||||||
|
class LoginTokenDates(db.Model):
|
||||||
|
token = db.Column(db.ForeignKey('login_token.token'),
|
||||||
|
nullable = False, primary_key=True,
|
||||||
|
server_onupdate=db.FetchedValue())
|
||||||
|
activation_date = db.Column(db.Date,
|
||||||
|
nullable=False, primary_key=True,
|
||||||
|
server_default=db.func.now())
|
||||||
|
deactivation_date = db.Column(db.Date, nullable=True)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<LoginTokenDates {self.token, self.activation_date, self.deactivation_date}>"
|
||||||
12
backend/models/payment.py
Normal file
12
backend/models/payment.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
|
class Payment(db.Model):
|
||||||
|
id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
|
||||||
|
token = db.Column(db.ForeignKey('login_token.token'),
|
||||||
|
server_onupdate=db.FetchedValue(), nullable=False)
|
||||||
|
date = db.Column(db.Date, nullable=False, server_default=db.func.now())
|
||||||
|
amount = db.Column(db.BigInteger, nullable=False, server_default=str(0))
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Payment {self.id}>"
|
||||||
13
backend/models/price_change.py
Normal file
13
backend/models/price_change.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from datetime import date
|
||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
|
class PriceChange(db.Model):
|
||||||
|
item = db.Column(db.ForeignKey('item.id'), primary_key=True,
|
||||||
|
server_onupdate=db.FetchedValue())
|
||||||
|
date = db.Column(db.Date, primary_key=True,
|
||||||
|
server_default=str(date(2021, 12, 1)))
|
||||||
|
price = db.Column(db.SmallInteger, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Price_Change {self.item} ({self.date})>"
|
||||||
17
backend/models/receipt.py
Normal file
17
backend/models/receipt.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
|
class Receipt(db.Model):
|
||||||
|
id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
|
||||||
|
date = db.Column(db.Date, nullable=False)
|
||||||
|
bonid = db.Column(db.Numeric(precision=28, scale=0), unique=True)
|
||||||
|
from_user = db.Column(db.ForeignKey("login_token.token"),
|
||||||
|
server_onupdate=db.FetchedValue())
|
||||||
|
registered = db.Column(db.Boolean, nullable=False,
|
||||||
|
server_default=str(False))
|
||||||
|
|
||||||
|
ReceiptItem = db.relationship(
|
||||||
|
"ReceiptItem", backref='Receipt', lazy='dynamic')
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<Receipt {self.id}>"
|
||||||
13
backend/models/receipt_item.py
Normal file
13
backend/models/receipt_item.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import db
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiptItem(db.Model):
|
||||||
|
receipt = db.Column(db.ForeignKey("receipt.id"),
|
||||||
|
primary_key=True, server_onupdate=db.FetchedValue())
|
||||||
|
item = db.Column(db.SmallInteger, primary_key=True, nullable=False)
|
||||||
|
name = db.Column(db.String, nullable=False)
|
||||||
|
amount = db.Column(db.SmallInteger, nullable=False, default=str(1))
|
||||||
|
price = db.Column(db.SmallInteger, nullable=False)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<ReceiptItem {self.receipt}: {self.item}>"
|
||||||
13
backend/models/schemas/__init__.py
Normal file
13
backend/models/schemas/__init__.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from .brand import BrandSchema
|
||||||
|
from .item import ItemSchema
|
||||||
|
from .category import CategorySchema
|
||||||
|
from .price_change import PriceChangeSchema
|
||||||
|
from .amount_change import AmountChangeSchema
|
||||||
|
from .user import UserSchema
|
||||||
|
from .establishment import EstablishmentSchema
|
||||||
|
from .establishment_candidate import EstablishmentCandidateSchema
|
||||||
|
from .login_token import LoginTokenSchema
|
||||||
|
from .bought import BoughtSchema
|
||||||
|
from .receipt import ReceiptSchema
|
||||||
|
from .receipt_item import ReceiptItemSchema
|
||||||
|
from .payment import PaymentSchema
|
||||||
13
backend/models/schemas/amount_change.py
Normal file
13
backend/models/schemas/amount_change.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..amount_change import AmountChange
|
||||||
|
from .item import ItemSchema
|
||||||
|
|
||||||
|
|
||||||
|
class AmountChangeSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = AmountChange
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
Item = ma.Nested(ItemSchema)
|
||||||
|
date = ma.auto_field()
|
||||||
|
amount = ma.auto_field()
|
||||||
15
backend/models/schemas/bought.py
Normal file
15
backend/models/schemas/bought.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..bought import Bought
|
||||||
|
from .login_token import LoginTokenSchema
|
||||||
|
from .item import ItemSchema
|
||||||
|
|
||||||
|
|
||||||
|
class BoughtSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Bought
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
LoginToken = ma.Nested(LoginTokenSchema)
|
||||||
|
Item = ma.Nested(ItemSchema)
|
||||||
|
date = ma.auto_field()
|
||||||
|
amount = ma.auto_field()
|
||||||
10
backend/models/schemas/brand.py
Normal file
10
backend/models/schemas/brand.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..brand import Brand
|
||||||
|
|
||||||
|
|
||||||
|
class BrandSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Brand
|
||||||
|
|
||||||
|
id = ma.auto_field()
|
||||||
|
name = ma.auto_field()
|
||||||
11
backend/models/schemas/category.py
Normal file
11
backend/models/schemas/category.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# from marshmallow import Schema, fields
|
||||||
|
from src import ma
|
||||||
|
from ..category import Category
|
||||||
|
|
||||||
|
|
||||||
|
class CategorySchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Category
|
||||||
|
|
||||||
|
id = ma.auto_field()
|
||||||
|
name = ma.auto_field()
|
||||||
13
backend/models/schemas/establishment.py
Normal file
13
backend/models/schemas/establishment.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..establishment import Establishment
|
||||||
|
from .user import UserSchema
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Establishment
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
id = ma.auto_field()
|
||||||
|
name = ma.auto_field()
|
||||||
|
User = ma.Nested(UserSchema)
|
||||||
13
backend/models/schemas/establishment_candidate.py
Normal file
13
backend/models/schemas/establishment_candidate.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..establishment_candidate import EstablishmentCandidate
|
||||||
|
from .establishment import EstablishmentSchema
|
||||||
|
from .user import UserSchema
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentCandidateSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = EstablishmentCandidate
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
User = ma.Nested(UserSchema)
|
||||||
|
Establishment = ma.Nested(EstablishmentSchema)
|
||||||
18
backend/models/schemas/item.py
Normal file
18
backend/models/schemas/item.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..item import Item
|
||||||
|
from .brand import BrandSchema
|
||||||
|
|
||||||
|
class ItemSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Item
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
id = ma.auto_field()
|
||||||
|
name = ma.auto_field()
|
||||||
|
description = ma.auto_field()
|
||||||
|
Brand = ma.Nested(BrandSchema)
|
||||||
|
PriceChange = ma.List(ma.Nested(lambda: PriceChangeSchema(exclude=("Item",))))
|
||||||
|
AmountChange = ma.List(ma.Nested(lambda: AmountChangeSchema(exclude=("Item",))))
|
||||||
|
|
||||||
|
from .price_change import PriceChangeSchema
|
||||||
|
from .amount_change import AmountChangeSchema
|
||||||
14
backend/models/schemas/login_token.py
Normal file
14
backend/models/schemas/login_token.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..login_token import LoginToken
|
||||||
|
from .establishment import EstablishmentSchema
|
||||||
|
from .user import UserSchema
|
||||||
|
|
||||||
|
|
||||||
|
class LoginTokenSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = LoginToken
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
User = ma.Nested(UserSchema)
|
||||||
|
Establishment = ma.Nested(EstablishmentSchema)
|
||||||
|
token = ma.auto_field()
|
||||||
14
backend/models/schemas/payment.py
Normal file
14
backend/models/schemas/payment.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..payment import Payment
|
||||||
|
from .login_token import LoginTokenSchema
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Payment
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
id = ma.auto_field()
|
||||||
|
LoginToken = ma.Nested(LoginTokenSchema)
|
||||||
|
date = ma.auto_field()
|
||||||
|
amount = ma.auto_field()
|
||||||
12
backend/models/schemas/price_change.py
Normal file
12
backend/models/schemas/price_change.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from src import ma
|
||||||
|
from .item import ItemSchema
|
||||||
|
from ..price_change import PriceChange
|
||||||
|
|
||||||
|
class PriceChangeSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = PriceChange
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
Item = ma.Nested(ItemSchema)
|
||||||
|
date = ma.auto_field()
|
||||||
|
price = ma.auto_field()
|
||||||
15
backend/models/schemas/receipt.py
Normal file
15
backend/models/schemas/receipt.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..receipt import Receipt
|
||||||
|
from .login_token import LoginTokenSchema
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiptSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = Receipt
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
id = ma.auto_field()
|
||||||
|
date = ma.auto_field()
|
||||||
|
bonid = ma.auto_field()
|
||||||
|
registered = ma.auto_field()
|
||||||
|
LoginToken = ma.Nested(LoginTokenSchema)
|
||||||
16
backend/models/schemas/receipt_item.py
Normal file
16
backend/models/schemas/receipt_item.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..receipt_item import ReceiptItem
|
||||||
|
from .item import ItemSchema
|
||||||
|
from .receipt import ReceiptSchema
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiptItemSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = ReceiptItem
|
||||||
|
include_fk = True
|
||||||
|
|
||||||
|
Receipt = ma.Nested(ReceiptSchema)
|
||||||
|
item = ma.auto_field()
|
||||||
|
name = ma.auto_field()
|
||||||
|
amount = ma.auto_field()
|
||||||
|
price = ma.auto_field()
|
||||||
10
backend/models/schemas/user.py
Normal file
10
backend/models/schemas/user.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from src import ma
|
||||||
|
from ..user import User
|
||||||
|
|
||||||
|
|
||||||
|
class UserSchema(ma.SQLAlchemySchema):
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
id = ma.auto_field()
|
||||||
|
email = ma.auto_field()
|
||||||
|
password_hash = ma.auto_field()
|
||||||
@ -1,21 +1,23 @@
|
|||||||
import jwt
|
import jwt
|
||||||
from src import db, login
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask_login import UserMixin
|
from flask_login import UserMixin
|
||||||
from marshmallow import Schema, fields
|
from src import db, login
|
||||||
from time import time
|
from time import time
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
|
|
||||||
class User(UserMixin, db.Model):
|
class User(UserMixin, db.Model):
|
||||||
id = db.Column(db.BigInteger, primary_key=True)
|
id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
|
||||||
email = db.Column(db.String(255), nullable=False, unique=True)
|
email = db.Column(db.String(255), nullable=False, unique=True)
|
||||||
password_hash = db.Column(db.String(128), nullable=False)
|
password_hash = db.Column(db.String(255), nullable=False)
|
||||||
|
|
||||||
LoginToken = db.relationship("LoginToken", backref='User', lazy='dynamic')
|
LoginToken = db.relationship("LoginToken", backref='User', lazy='dynamic')
|
||||||
Bought = db.relationship("Bought", secondary="login_token",
|
Bought = db.relationship("Bought", secondary="login_token",
|
||||||
lazy='dynamic', overlaps="User,LoginToken")
|
lazy='dynamic', overlaps="User,LoginToken")
|
||||||
EstablishmentCandidate = db.relationship("EstablishmentCandidate", backref='User', lazy='dynamic')
|
EstablishmentCandidate = db.relationship(
|
||||||
Establishment = db.relationship("Establishment", backref="User", lazy="dynamic")
|
"EstablishmentCandidate", backref='User', lazy='dynamic')
|
||||||
|
Establishment = db.relationship(
|
||||||
|
"Establishment", backref="User", lazy="dynamic")
|
||||||
|
|
||||||
def set_password(self, password):
|
def set_password(self, password):
|
||||||
self.password_hash = generate_password_hash(password)
|
self.password_hash = generate_password_hash(password)
|
||||||
@ -40,10 +42,6 @@ class User(UserMixin, db.Model):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<User {self.id} ({self.email})>"
|
return f"<User {self.id} ({self.email})>"
|
||||||
|
|
||||||
class UserSchema(Schema):
|
|
||||||
id = fields.Number()
|
|
||||||
email = fields.Str()
|
|
||||||
password_hash = fields.Str()
|
|
||||||
|
|
||||||
@login.user_loader
|
@login.user_loader
|
||||||
def load_user(id):
|
def load_user(id):
|
||||||
44
backend/requirements.txt
Normal file
44
backend/requirements.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
-i https://pypi.org/simple
|
||||||
|
alembic==1.12.1; python_version >= '3.7'
|
||||||
|
blinker==1.7.0; python_version >= '3.8'
|
||||||
|
certifi==2023.7.22; python_version >= '3.6'
|
||||||
|
charset-normalizer==3.3.2; python_full_version >= '3.7.0'
|
||||||
|
click==8.1.7; python_version >= '3.7'
|
||||||
|
colorama==0.4.6; sys_platform == 'win32'
|
||||||
|
dnspython==2.4.2; python_version >= '3.8' and python_version < '4.0'
|
||||||
|
dominate==2.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
|
||||||
|
email-validator==2.1.0.post1
|
||||||
|
flask==3.0.0
|
||||||
|
flask-bootstrap==3.3.7.1
|
||||||
|
flask-cors==4.0.0
|
||||||
|
flask-login==0.6.3
|
||||||
|
flask-mail==0.9.1
|
||||||
|
flask-marshmallow==0.15.0
|
||||||
|
flask-migrate==4.0.5
|
||||||
|
flask-sqlalchemy==3.1.1
|
||||||
|
flask-wtf==1.2.1
|
||||||
|
greenlet==3.0.1; platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))
|
||||||
|
idna==3.4; python_version >= '3.5'
|
||||||
|
iniconfig==2.0.0; python_version >= '3.7'
|
||||||
|
itsdangerous==2.1.2; python_version >= '3.7'
|
||||||
|
jinja2==3.1.2; python_version >= '3.7'
|
||||||
|
mako==1.3.0; python_version >= '3.8'
|
||||||
|
markupsafe==2.1.3; python_version >= '3.7'
|
||||||
|
marshmallow==3.20.1; python_version >= '3.8'
|
||||||
|
marshmallow-sqlalchemy==0.29.0
|
||||||
|
packaging==23.2; python_version >= '3.7'
|
||||||
|
pluggy==1.3.0; python_version >= '3.8'
|
||||||
|
psycopg2-binary==2.9.9
|
||||||
|
pyjwt==2.8.0
|
||||||
|
pymupdf==1.23.6
|
||||||
|
pytest==7.4.3
|
||||||
|
python-dotenv==1.0.0
|
||||||
|
requests==2.31.0
|
||||||
|
sqlalchemy==2.0.23; python_version >= '3.7'
|
||||||
|
sqlalchemy-utils==0.41.1
|
||||||
|
typing-extensions==4.8.0; python_version >= '3.8'
|
||||||
|
urllib3==2.0.7; python_version >= '3.7'
|
||||||
|
visitor==0.1.3
|
||||||
|
werkzeug==3.0.1; python_version >= '3.8'
|
||||||
|
wtforms==3.1.1; python_version >= '3.8'
|
||||||
|
wtforms-sqlalchemy==0.3
|
||||||
@ -1,10 +1,12 @@
|
|||||||
from src import create_app, db
|
from src import create_app, db
|
||||||
from src.models import Bought, Establishment, Item, LoginToken, Receipt, User, UserSchema
|
from models import *
|
||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
||||||
|
|
||||||
@app.shell_context_processor
|
@app.shell_context_processor
|
||||||
def make_shell_context():
|
def make_shell_context():
|
||||||
return {'db': db, 'User': User, 'Bought': Bought, 'Item': Item,
|
return {'db': db, 'User': User, 'Bought': Bought, "Brand": Brand, 'Item': Item,
|
||||||
"LoginToken": LoginToken, "Establishment": Establishment, "Receipt": Receipt,
|
"LoginToken": LoginToken, "Establishment": Establishment, "Receipt": Receipt,
|
||||||
'UserSchema': UserSchema}
|
"brandschema": BrandSchema(), "itemschema": ItemSchema(), "testitem": Item.query.get(4311501628485),
|
||||||
|
"testuser": User.query.get(1)}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ from flask_bootstrap import Bootstrap
|
|||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from flask_login import LoginManager
|
from flask_login import LoginManager
|
||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
|
from flask_marshmallow import Marshmallow
|
||||||
from flask_migrate import Migrate
|
from flask_migrate import Migrate
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
@ -31,17 +32,21 @@ cors = CORS()
|
|||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
login = LoginManager()
|
login = LoginManager()
|
||||||
login.login_view = 'auth.web_login'
|
login.login_view = 'auth.web_login'
|
||||||
|
ma = Marshmallow()
|
||||||
mail = Mail()
|
mail = Mail()
|
||||||
migrate = Migrate()
|
migrate = Migrate(transaction_per_migration=True)
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_class=Config):
|
def create_app(config_class=Config):
|
||||||
app = Flask(__name__)
|
if not exists(config_class.RECEIPT_FOLDER):
|
||||||
|
makedirs(config_class.RECEIPT_FOLDER)
|
||||||
|
app = Flask(__name__, template_folder="../web/templates", static_folder="../web/static")
|
||||||
app.config.from_object(config_class)
|
app.config.from_object(config_class)
|
||||||
bootstrap.init_app(app)
|
bootstrap.init_app(app)
|
||||||
cors.init_app(app)
|
cors.init_app(app)
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
login.init_app(app)
|
login.init_app(app)
|
||||||
|
ma.init_app(app)
|
||||||
mail.init_app(app)
|
mail.init_app(app)
|
||||||
migrate.init_app(app, db, render_as_batch=True)
|
migrate.init_app(app, db, render_as_batch=True)
|
||||||
|
|
||||||
@ -62,4 +67,4 @@ def create_app(config_class=Config):
|
|||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
from src.models import *
|
from models import *
|
||||||
@ -2,5 +2,5 @@ from flask import Blueprint
|
|||||||
|
|
||||||
bp = Blueprint('api', __name__, url_prefix='/api')
|
bp = Blueprint('api', __name__, url_prefix='/api')
|
||||||
|
|
||||||
from src.api.v1 import bp as bp_v1
|
from .v1 import bp as bp_v1
|
||||||
bp.register_blueprint(bp_v1)
|
bp.register_blueprint(bp_v1)
|
||||||
@ -2,4 +2,4 @@ from flask import Blueprint
|
|||||||
|
|
||||||
bp = Blueprint('v1', __name__, url_prefix='/v1')
|
bp = Blueprint('v1', __name__, url_prefix='/v1')
|
||||||
|
|
||||||
from src.api.v1 import routes
|
from . import routes
|
||||||
@ -1,6 +1,6 @@
|
|||||||
from src import LOGGER
|
from src import LOGGER
|
||||||
from src.api.v1 import bp
|
from src.api.v1 import bp
|
||||||
from src.models.login_token import LoginToken
|
from models.login_token import LoginToken
|
||||||
from src.utils import database_utils
|
from src.utils import database_utils
|
||||||
from flask import abort, request
|
from flask import abort, request
|
||||||
from flask.json import jsonify
|
from flask.json import jsonify
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from flask import Blueprint
|
|||||||
|
|
||||||
bp = Blueprint('auth', __name__, url_prefix='/auth')
|
bp = Blueprint('auth', __name__, url_prefix='/auth')
|
||||||
|
|
||||||
from src.auth import forms, routes
|
from . import forms, routes
|
||||||
@ -1,4 +1,4 @@
|
|||||||
from src.models.user import User
|
from models.user import User
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import BooleanField, PasswordField, StringField, SubmitField
|
from wtforms import BooleanField, PasswordField, StringField, SubmitField
|
||||||
from wtforms.validators import DataRequired, Email, EqualTo, ValidationError
|
from wtforms.validators import DataRequired, Email, EqualTo, ValidationError
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user