Skip to content
Snippets Groups Projects
Commit adb98101 authored by Tomáš's avatar Tomáš
Browse files

add pre-commit hooks, wip readme, run hooks

parent d885005f
No related branches found
No related tags found
No related merge requests found
.env .env
__pycache__/ __pycache__/
staticfiles
node_modules/* node_modules/*
shared/static/* shared/static/*
webpack-stats.json
default_language_version:
python: python3.10
exclude: snapshots/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
exclude: ^.*\.md$
- id: end-of-file-fixer
- id: debug-statements
- id: mixed-line-ending
args: [--fix=lf]
- id: detect-private-key
- id: check-merge-conflict
- repo: https://github.com/timothycrosley/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
...@@ -30,6 +30,11 @@ install: venv ...@@ -30,6 +30,11 @@ install: venv
${VENV}/bin/nodeenv --python-virtualenv --node=19.3.0 ${VENV}/bin/nodeenv --python-virtualenv --node=19.3.0
${VENV}/bin/npm install ${VENV}/bin/npm install
install-hooks:
pre-commit install --install-hooks
hooks:
pre-commit run -a
build: venv build: venv
${VENV}/bin/npm run build ${VENV}/bin/npm run build
......
# Contract registry
The Czech Pirate Party's transparent evidence system for its contracts and
information about them.
## Basic requirements
- `make`
- `python`, 3.9 or newer
- `python-virtualenv`
- A PostgreSQL server
## Setup
Copy `env.example` to `.env`.
Set the ``DATABASE_URL`` environment variable in `.env` to one you can access your database server with. The format should be as per RFC 1738, such as `postgresql://login:password@localhost:5432/database_name`. It's also important to change the ``SECRET_KEY`` variable.
Then, run the following commands:
```bash
make venv # Create virtual environment
make install # Install Python and Node.js dependencies
make build # Build static files
```
## Running
To run with the default settings on the port set in `Makefile`, run:
```bash
make run
```
For more customization, it's better practice to run the server starting command directly:
```bash
source .venv/bin/activate # Load the virtual environment
python manage.py runserver # [ Your settings here ]
```
...@@ -6,7 +6,7 @@ import sys ...@@ -6,7 +6,7 @@ import sys
def main(): def main():
"""Run administrative tasks.""" """Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'registry.settings') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings")
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:
...@@ -18,5 +18,5 @@ def main(): ...@@ -18,5 +18,5 @@ def main():
execute_from_command_line(sys.argv) execute_from_command_line(sys.argv)
if __name__ == '__main__': if __name__ == "__main__":
main() main()
...@@ -11,6 +11,6 @@ import os ...@@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'registry.settings') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings")
application = get_asgi_application() application = get_asgi_application()
...@@ -13,8 +13,8 @@ https://docs.djangoproject.com/en/4.0/ref/settings/ ...@@ -13,8 +13,8 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
import os import os
import pathlib import pathlib
import environ
import dj_database_url import dj_database_url
import environ
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = pathlib.Path(__file__).parents[2] BASE_DIR = pathlib.Path(__file__).parents[2]
...@@ -45,7 +45,6 @@ INSTALLED_APPS = [ ...@@ -45,7 +45,6 @@ INSTALLED_APPS = [
"django.contrib.sessions", "django.contrib.sessions",
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"shared", "shared",
] ]
...@@ -83,9 +82,7 @@ WSGI_APPLICATION = "registry.wsgi.application" ...@@ -83,9 +82,7 @@ WSGI_APPLICATION = "registry.wsgi.application"
# Database # Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases # https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = { DATABASES = {"default": dj_database_url.config(conn_max_age=600)}
"default": dj_database_url.config(conn_max_age=600)
}
# Password validation # Password validation
......
...@@ -17,5 +17,5 @@ from django.contrib import admin ...@@ -17,5 +17,5 @@ from django.contrib import admin
from django.urls import path from django.urls import path
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path("admin/", admin.site.urls),
] ]
...@@ -11,6 +11,6 @@ import os ...@@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'registry.settings') os.environ.setdefault("DJANGO_SETTINGS_MODULE", "registry.settings")
application = get_wsgi_application() application = get_wsgi_application()
...@@ -2,5 +2,5 @@ from django.apps import AppConfig ...@@ -2,5 +2,5 @@ from django.apps import AppConfig
class SharedConfig(AppConfig): class SharedConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = "django.db.models.BigAutoField"
name = 'shared' name = "shared"
This diff is collapsed.
# Generated by Django 4.1.4 on 2023-02-03 05:01 # Generated by Django 4.1.4 on 2023-02-03 05:01
from django.db import migrations, models
import django_countries.fields import django_countries.fields
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('shared', '0001_initial'), ("shared", "0001_initial"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='department', name="department",
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Organizační složka'), field=models.CharField(
blank=True, max_length=128, null=True, verbose_name="Organizační složka"
),
), ),
migrations.AddField( migrations.AddField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='representative_name', name="representative_name",
field=models.CharField(blank=True, max_length=256, null=True, verbose_name='Zástupce'), field=models.CharField(
blank=True, max_length=256, null=True, verbose_name="Zástupce"
),
), ),
migrations.AddField( migrations.AddField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='representative_role', name="representative_role",
field=models.CharField(blank=True, max_length=256, null=True, verbose_name='Funkce zástupce'), field=models.CharField(
blank=True, max_length=256, null=True, verbose_name="Funkce zástupce"
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='address_country', name="address_country",
field=django_countries.fields.CountryField(default='CZ', max_length=2, verbose_name='Země'), field=django_countries.fields.CountryField(
default="CZ", max_length=2, verbose_name="Země"
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='address_district', name="address_district",
field=models.CharField(default='Praha 2', max_length=256, verbose_name='Obec'), field=models.CharField(
default="Praha 2", max_length=256, verbose_name="Obec"
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='address_street_with_number', name="address_street_with_number",
field=models.CharField(default='Na Moráni 360/3', max_length=256, verbose_name='Ulice, č.p.'), field=models.CharField(
default="Na Moráni 360/3", max_length=256, verbose_name="Ulice, č.p."
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='address_zip', name="address_zip",
field=models.CharField(default='128 00', max_length=16, verbose_name='PSČ'), field=models.CharField(default="128 00", max_length=16, verbose_name="PSČ"),
), ),
migrations.AlterField( migrations.AlterField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='ico_number', name="ico_number",
field=models.CharField(blank=True, default='71339698', max_length=16, null=True, verbose_name='IČO'), field=models.CharField(
blank=True,
default="71339698",
max_length=16,
null=True,
verbose_name="IČO",
),
), ),
migrations.AlterField( migrations.AlterField(
model_name='contractlocalsigner', model_name="contractlocalsigner",
name='name', name="name",
field=models.CharField(default='Česká pirátská strana', max_length=256, verbose_name='Jméno'), field=models.CharField(
default="Česká pirátská strana", max_length=256, verbose_name="Jméno"
),
), ),
] ]
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django_countries.fields import CountryField from django_countries.fields import CountryField
from markdownx.models import MarkdownxField from markdownx.models import MarkdownxField
from pirates import models as pirates_models from pirates import models as pirates_models
...@@ -16,12 +15,10 @@ class ContractExternalSigner(models.Model): ...@@ -16,12 +15,10 @@ class ContractExternalSigner(models.Model):
verbose_name="Jméno", verbose_name="Jméno",
) )
is_legal_entity = models.BooleanField( is_legal_entity = models.BooleanField(
verbose_name="Je právnická osoba", verbose_name="Je právnická osoba",
) )
address_street_with_number = models.CharField( address_street_with_number = models.CharField(
max_length=256, max_length=256,
verbose_name="Ulice, č.p.", verbose_name="Ulice, č.p.",
...@@ -41,7 +38,6 @@ class ContractExternalSigner(models.Model): ...@@ -41,7 +38,6 @@ class ContractExternalSigner(models.Model):
verbose_name="Země", verbose_name="Země",
) )
ico_number = models.CharField( ico_number = models.CharField(
max_length=16, max_length=16,
blank=True, blank=True,
...@@ -55,7 +51,6 @@ class ContractExternalSigner(models.Model): ...@@ -55,7 +51,6 @@ class ContractExternalSigner(models.Model):
verbose_name="Datum narození", verbose_name="Datum narození",
) # WARNING: Legal entity status dependent! ) # WARNING: Legal entity status dependent!
representative_name = models.CharField( representative_name = models.CharField(
max_length=256, max_length=256,
blank=True, blank=True,
...@@ -70,7 +65,6 @@ class ContractExternalSigner(models.Model): ...@@ -70,7 +65,6 @@ class ContractExternalSigner(models.Model):
verbose_name="Funkce zástupce", verbose_name="Funkce zástupce",
) )
department = models.CharField( department = models.CharField(
max_length=128, max_length=128,
blank=True, blank=True,
...@@ -78,7 +72,6 @@ class ContractExternalSigner(models.Model): ...@@ -78,7 +72,6 @@ class ContractExternalSigner(models.Model):
verbose_name="Organizační složka", verbose_name="Organizační složka",
) )
class Meta: class Meta:
verbose_name = "Druhá smluvní strana" verbose_name = "Druhá smluvní strana"
verbose_name_plural = "Druhé smluvní strany" verbose_name_plural = "Druhé smluvní strany"
...@@ -91,7 +84,6 @@ class ContractLocalSigner(models.Model): ...@@ -91,7 +84,6 @@ class ContractLocalSigner(models.Model):
verbose_name="Jméno", verbose_name="Jméno",
) )
address_street_with_number = models.CharField( address_street_with_number = models.CharField(
max_length=256, max_length=256,
default=settings.DEFAULT_LCOAL_SIGNER_STREET, default=settings.DEFAULT_LCOAL_SIGNER_STREET,
...@@ -115,7 +107,6 @@ class ContractLocalSigner(models.Model): ...@@ -115,7 +107,6 @@ class ContractLocalSigner(models.Model):
verbose_name="Země", verbose_name="Země",
) )
ico_number = models.CharField( ico_number = models.CharField(
max_length=16, max_length=16,
blank=True, blank=True,
...@@ -124,7 +115,6 @@ class ContractLocalSigner(models.Model): ...@@ -124,7 +115,6 @@ class ContractLocalSigner(models.Model):
verbose_name="IČO", verbose_name="IČO",
) )
representative_name = models.CharField( representative_name = models.CharField(
max_length=256, max_length=256,
blank=True, blank=True,
...@@ -139,7 +129,6 @@ class ContractLocalSigner(models.Model): ...@@ -139,7 +129,6 @@ class ContractLocalSigner(models.Model):
verbose_name="Funkce zástupce", verbose_name="Funkce zástupce",
) )
department = models.CharField( department = models.CharField(
max_length=128, max_length=128,
blank=True, blank=True,
...@@ -147,14 +136,12 @@ class ContractLocalSigner(models.Model): ...@@ -147,14 +136,12 @@ class ContractLocalSigner(models.Model):
verbose_name="Organizační složka", verbose_name="Organizační složka",
) )
# TODO: Input validation # TODO: Input validation
color = models.CharField( color = models.CharField(
max_length=6, # e.g. "ffffff" max_length=6, # e.g. "ffffff"
verbose_name="Barva", verbose_name="Barva",
) )
class Meta: class Meta:
verbose_name = "Naše smluvní strana" verbose_name = "Naše smluvní strana"
verbose_name_plural = "Naše smlouvní strany" verbose_name_plural = "Naše smlouvní strany"
...@@ -166,7 +153,6 @@ class ContractSubtype(models.Model): ...@@ -166,7 +153,6 @@ class ContractSubtype(models.Model):
verbose_name="Jméno", verbose_name="Jméno",
) )
class Meta: class Meta:
verbose_name = "Podtyp smlouvy" verbose_name = "Podtyp smlouvy"
verbose_name_plural = "Podtypy smlouvy" verbose_name_plural = "Podtypy smlouvy"
...@@ -178,7 +164,6 @@ class ContractIssue(models.Model): ...@@ -178,7 +164,6 @@ class ContractIssue(models.Model):
verbose_name="Jméno", verbose_name="Jméno",
) )
class Meta: class Meta:
verbose_name = "Problém se smlouvou" verbose_name = "Problém se smlouvou"
verbose_name_plural = "Problémy se smlouvou" verbose_name_plural = "Problémy se smlouvou"
...@@ -195,7 +180,6 @@ class ContractFilingArea(models.Model): ...@@ -195,7 +180,6 @@ class ContractFilingArea(models.Model):
verbose_name="Odpovědná osoba", verbose_name="Odpovědná osoba",
) )
class Meta: class Meta:
verbose_name = "Spisovna" verbose_name = "Spisovna"
verbose_name_plural = "Spisovny" verbose_name_plural = "Spisovny"
...@@ -220,7 +204,6 @@ class Contract(models.Model): ...@@ -220,7 +204,6 @@ class Contract(models.Model):
verbose_name="Podtyp", verbose_name="Podtyp",
) )
contains_nda = models.BooleanField( contains_nda = models.BooleanField(
default=False, default=False,
verbose_name="Obsahuje NDA", verbose_name="Obsahuje NDA",
...@@ -231,7 +214,6 @@ class Contract(models.Model): ...@@ -231,7 +214,6 @@ class Contract(models.Model):
verbose_name="Je anonymizovaná", verbose_name="Je anonymizovaná",
) # WARNING: Seems to only be used for amendments ) # WARNING: Seems to only be used for amendments
external_signer = models.ForeignKey( external_signer = models.ForeignKey(
ContractExternalSigner, ContractExternalSigner,
on_delete=models.CASCADE, on_delete=models.CASCADE,
...@@ -255,15 +237,11 @@ class Contract(models.Model): ...@@ -255,15 +237,11 @@ class Contract(models.Model):
verbose_name="Datum podpisu všech stran", verbose_name="Datum podpisu všech stran",
) # WARNING: Exclude in admin, autofill ) # WARNING: Exclude in admin, autofill
valid_start_date = models.DateField(verbose_name="Začátek účinnosti")
valid_start_date = models.DateField(
verbose_name="Začátek účinnosti"
)
valid_end_date = models.DateField( valid_end_date = models.DateField(
verbose_name="Začátek platnosti", verbose_name="Začátek platnosti",
) )
uploaded_by = models.ForeignKey( uploaded_by = models.ForeignKey(
User, User,
on_delete=models.CASCADE, on_delete=models.CASCADE,
...@@ -271,7 +249,6 @@ class Contract(models.Model): ...@@ -271,7 +249,6 @@ class Contract(models.Model):
verbose_name="Nahráno uživatelem", verbose_name="Nahráno uživatelem",
) )
class LegalStates(models.TextChoices): class LegalStates(models.TextChoices):
VALID = "valid", "Platná" VALID = "valid", "Platná"
EFFECTIVE = "effective", "Účinná" EFFECTIVE = "effective", "Účinná"
...@@ -307,7 +284,6 @@ class Contract(models.Model): ...@@ -307,7 +284,6 @@ class Contract(models.Model):
verbose_name="Stav papírové formy", verbose_name="Stav papírové formy",
) )
public_status_set_by = models.ForeignKey( public_status_set_by = models.ForeignKey(
User, User,
on_delete=models.CASCADE, on_delete=models.CASCADE,
...@@ -315,7 +291,6 @@ class Contract(models.Model): ...@@ -315,7 +291,6 @@ class Contract(models.Model):
verbose_name="Zveřejněno / nezveřejněno uživatelem", verbose_name="Zveřejněno / nezveřejněno uživatelem",
) )
publishing_rejection_comment = models.CharField( publishing_rejection_comment = models.CharField(
max_length=65536, max_length=65536,
blank=True, blank=True,
...@@ -323,7 +298,6 @@ class Contract(models.Model): ...@@ -323,7 +298,6 @@ class Contract(models.Model):
verbose_name="Důvod nezveřejnění", verbose_name="Důvod nezveřejnění",
) )
tender_url = models.URLField( tender_url = models.URLField(
max_length=256, max_length=256,
blank=True, blank=True,
...@@ -331,16 +305,13 @@ class Contract(models.Model): ...@@ -331,16 +305,13 @@ class Contract(models.Model):
verbose_name="Odkaz na výběrové řízení", verbose_name="Odkaz na výběrové řízení",
) )
identifier = models.CharField( identifier = models.CharField(
max_length=128, max_length=128,
verbose_name="Identifikační číslo", verbose_name="Identifikační číslo",
) )
issues = models.ManyToManyField(ContractIssue) issues = models.ManyToManyField(ContractIssue)
summary = models.CharField( summary = models.CharField(
max_length=65536, max_length=65536,
blank=True, blank=True,
...@@ -348,7 +319,6 @@ class Contract(models.Model): ...@@ -348,7 +319,6 @@ class Contract(models.Model):
verbose_name="Rekapitulace", verbose_name="Rekapitulace",
) )
contract_file = models.FileField( contract_file = models.FileField(
verbose_name="Smlouva (PDF)", verbose_name="Smlouva (PDF)",
) )
...@@ -361,23 +331,13 @@ class Contract(models.Model): ...@@ -361,23 +331,13 @@ class Contract(models.Model):
verbose_name="Hlavní smlouva", verbose_name="Hlavní smlouva",
) # WARNING: Dependent on the type! ) # WARNING: Dependent on the type!
expected_cost_total = models.IntegerField(verbose_name="Očekáváná celková cena")
expected_cost_total = models.IntegerField( expected_cost_year = models.IntegerField(verbose_name="Očekáváná cena za rok")
verbose_name="Očekáváná celková cena"
)
expected_cost_year = models.IntegerField( expected_cost_month = models.IntegerField(verbose_name="Očekáváná cena za měsíc")
verbose_name="Očekáváná cena za rok"
)
expected_cost_month = models.IntegerField(
verbose_name="Očekáváná cena za měsíc"
)
expected_cost_hour = models.IntegerField(
verbose_name="Očekáváná cena za hodinu"
)
expected_cost_hour = models.IntegerField(verbose_name="Očekáváná cena za hodinu")
intent_url = models.URLField( intent_url = models.URLField(
max_length=256, max_length=256,
...@@ -393,7 +353,6 @@ class Contract(models.Model): ...@@ -393,7 +353,6 @@ class Contract(models.Model):
verbose_name="Odkaz na schválení", verbose_name="Odkaz na schválení",
) # WARNING: Dependent on the type! ) # WARNING: Dependent on the type!
filing_area = models.ForeignKey( filing_area = models.ForeignKey(
ContractFilingArea, ContractFilingArea,
on_delete=models.CASCADE, on_delete=models.CASCADE,
...@@ -401,7 +360,6 @@ class Contract(models.Model): ...@@ -401,7 +360,6 @@ class Contract(models.Model):
null=True, null=True,
) # WARNING: Dependent on the type! ) # WARNING: Dependent on the type!
class Meta: class Meta:
verbose_name = "Smlouva" verbose_name = "Smlouva"
verbose_name_plural = "Smlouvy" verbose_name_plural = "Smlouvy"
...@@ -413,7 +371,6 @@ class ContractNote(models.Model): ...@@ -413,7 +371,6 @@ class ContractNote(models.Model):
on_delete=models.CASCADE, on_delete=models.CASCADE,
) )
author = models.ForeignKey( author = models.ForeignKey(
User, User,
related_name="contract_notes", related_name="contract_notes",
...@@ -429,7 +386,6 @@ class ContractNote(models.Model): ...@@ -429,7 +386,6 @@ class ContractNote(models.Model):
verbose_name="Obsah", verbose_name="Obsah",
) )
class Meta: class Meta:
verbose_name = "Poznámka ke smlouvě" verbose_name = "Poznámka ke smlouvě"
verbose_name_plural = "Poznámky ke smlouvě" verbose_name_plural = "Poznámky ke smlouvě"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment