Giter Site home page Giter Site logo

meine-stadt-transparent / meine-stadt-transparent Goto Github PK

View Code? Open in Web Editor NEW
45.0 4.0 15.0 14.19 MB

A website to bring municipal politics to citizens

Home Page: https://meine-stadt-transparent.de

License: MIT License

Python 69.59% JavaScript 7.17% HTML 18.27% Dockerfile 0.28% Shell 0.06% SCSS 4.64%
ratsinformationssystem oparl politics prototype-fund city-council council-information

meine-stadt-transparent's Introduction

🪦 Note: This project isn't maintained anymore, sorry 🪦


Meine Stadt Transparent

Tests FOSSA Status Docker build Code style: black

Meine Stadt Transparent is a free council information system. Its current main focus is presenting data from offical German council information systems, so called "Ratsinformationssysteme". Those are imported using the OParl API, which can easily customized. You can even write your own importer for arbitrary data sources.

Our sample live system using the data of the city Krefeld is available at: https://krefeld.meine-stadt-transparent.de/. We provide a public chat on riot at #meine-stadt-transparent:matrix.org, which you can join on matrix.

The project was sponsored by the Prototype Fund.

Logo of the Prototype Fund Gefördert von Bundesministetrium für Bilduung und Forschung Logo of the Open Knowledge Foundation Germany

About this project

Meine Stadt Transparent makes decision-making in city councils and administrations more transparent by providing easy access to information about the city council, including published documents, motions and meeting agendas. As a successor to Munich's München Transparent, its aim is to be easily deployable for as many cities as possible.

It includes many features regarding data research and staying up to date, targeted both towards citizens and journalists:

  • Information about city councillors, administrative organizations and meetings of the city council are provided.
  • All published documents are searchable in a flexible manner, be it motions, resolutions, meeting agendas or protocols. The search supports both simple full-text searches and flexible criteria-based filters.
  • Documents are automatically searched for mentioned places. A map is provided indicating places that are mentioned. Thus, it is easy to identify documents that affect places in your living neighborhood.
  • You can subscribe to topics / search expressions to get notified by e-mail, once new documents matching your query are published.
  • It supports several ways of subscribing to new content: different kinds of RSS-feeds and subscribing to the meeting calendar using the iCal-format.
  • We try to make Meine Stadt Transparent accessible by everyone: the layout is responsive to provide a good experience on mobile device, and we follow accessibility standards (WCAG 2.0 AA, ARIA) as close as possible.

Meine Stadt Transparent is not a complete replacement for traditional council information systems, however: it focuses on displaying already published information to the public. It does not provide a user-accessible backend for content authoring. It relies on the availability of an API provided by a council information system backend. Currently, the open Oparl-Standard is supported.

Production setup with docker compose

Prerequisites: A host with root access and enough ram for elasticsearch and mariadb. If you don't have much ram, create a big swapfile for memory spikes in the import.

All services will run in docker containers orchestrated by docker compose, with nginx as reverse proxy in front of them which also serves static files.

First, install docker and docker compose. Then adjust max_map_count on the host system for elasticsearch.

Download etc/docker-compose.yml from the root of this repository. Replace all changeme with real random passwords (Hint: openssl rand -hex 32).

Download etc/template.env to .env. Change REAL_HOST to your domain, SECRET_KEY to a randomly generated secret and use the same passwords as in docker-compose.yml for DATABASE_URL, ELASTIC_PASSWORD and MINIO_SECRET_KEY. You most likely want to configure third-party services as described later, but you can postpone that until after the base site works.

To deliver the assets through nginx, we need to mount them to a local container:

mkdir log
chown 33:33 log
rm -rf /var/www/meine-stadt-transparent-static # Delete existing or it will land in a subdirectory 
docker compose cp django:/static /var/www/meine-stadt-transparent-static

You can change the directory to any other as long as you match that later in your nginx conf.

Start everything:

docker compose up

Wait until the elasticsearch log says Cluster health status changed from [RED] to [YELLOW] and open another terminal. You can later start the services as daemons with -d or stop them with docker compose down.

Then we can run the migrations, create the buckets for minio (our file storage) and create the elasticsearch indices. If something failed you can rerun the setup command, it will only create missing indices.

docker compose run --rm django ./manage.py setup

Let's load some dummy data to check everything works:

docker compose run --rm django ./manage.py loaddata mainapp/fixtures/initdata.json

You should now get a 200 response from localhost:8000.

If you've not familiar with nginx, you should start with this tutorial. Install nginx, certbot and the certbot nginx integration. For ubuntu it is e.g.

sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

Download etc/nginx-http.conf, add it to your nginx sites and replace changeme.tld with your domain. Then run certbot and follow the instructions:

certbot --nginx

Certbot will rewrite the nginx configuration to a version with strong encryption. You might also want to activate http/2 by adding http2 after both 443 ssl.

You now have a proper site at your domain!

Now that everything is in place, drop the dummy data:

docker compose run --rm django ./manage.py flush

Instead, import real data by replacing Springfield with the name of your city. See docs/Import.md for details.

docker compose run --rm django ./manage.py import Springfield

You should now have a usable instance!

Finally, create a daily cronjob with the following. This will import changed objects from the oparl api and then notify the users. Also make sure that there is a cronjob for certbot.

docker compose run --rm django ./manage.py cron

You can execute all the other commands from this readme by prepending them with docker compose run --rm django (or starting a shell in the container). Note for advanced users: .venv/bin/python is configured as entrypoint.

Next, have a look at docs/Customization.md.

Updates

After pulling a new version of the docker container, you need to run the following commands to update the assets:

docker compose down
rm -r /var/www/meine-stadt-transparent-static
mkdir /var/www/meine-stadt-transparent-static
docker compose run --rm django ./manage.py setup
docker compose up -d

Kubernetes

If you have a Kubernetes cluster, you can have a look at this experimental setup which is used by Münster.

Manual Setup

Requirements

  • Python 3.8, 3.9, 3.10 or 3.11 with pip and poetry 1.4
  • A recent node version (v18) with npm (v8)
  • A webserver (nginx or apache is recommended)
  • A Database (MariaDB is recommended, though anything that django supports should work)
  • minio
  • If you want to use elasticsearch, you either need docker and docker compose or will have to install elasticsearch 7.9 yourself

On Debian/Ubuntu:

sudo apt install python3-pip python3-venv python3-dev nodejs \
    git libmysqlclient-dev libmagickwand-dev poppler-utils libssl-dev gettext

Install dependencies.

poetry config virtualenvs.in-project true # This is not mandatory, yet quite useful
poetry install
npm install

Activate the virtualenv created by poetry. You either need to run this in your shell before running any other python command or prefix any python command with poetry run.

poetry shell

Copy etc/template.env to .env and adjust the values. You can specify a different dotenv file with the ENV_PATH environment variable.

Configure your webserver, see e.g. etc/nginx.conf

Production

The following steps are only required when you want to deploy the site to production. For development, see the corresponding section below

npm run build:prod
npm run build:email
./manage.py collectstatic

Follow the the official guide. Unlike the guide, we recommend gunicorn over wsgi as gunicorn is much simpler to configure.

The site is now ready 🎉. Next, have a look at docs/Customization.md and docs/Import.md.

Development

Please refer to docs/Development.md

Known Problems

If you hit problems regarding memory when starting elasticsearch, please have a look at this documentation.

If MySQL/MariaDB is to be used as a database backend, a Version of at least 5.7 (MySQL) or 10.2 (MariaDB) is needed, with Barracuda being set as the default format for new InnoDB-Tables (default), otherwise you will run into errors about too long Indexes.

License

This software is published under the terms of the MIT license. The json files under testdata/oparl are adapted from the oparl project and licensed under CC-BY-SA-4.0. The license of the included animal pictures mainapp/assets/images are CC0 and CC-BY-SA Luigi Rosa. The redistribution of etc/Donald Knuth - The Complexity of Songs.pdf is explicitly allowed in its last paragraph.

FOSSA Status

meine-stadt-transparent's People

Contributors

catoth avatar cyroxx avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar fossabot avatar jfehre avatar konstin avatar stv0g avatar ubergesundheit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

meine-stadt-transparent's Issues

Refactor `_extract_text`

_extract_text in document_parsing.py ist durch die Menge an Metaprogrammierung absolut unverständlich. Außerdem werden die Funktionsparameter nicht genutzt.

Test the importer

Abuse the caching mechanism to create an oparl api which is actually just a bunch of predefined text files. The test should check for basic import as well as it should check the modified and deleted detection.

It should als check the organization type story.

Änderungshistorie

Alle wichtigen Tabellen brauchen eine Änderungshistorie und zumindest eine rudimentäre Oberfläche, um die Änderungen im zeitlichen Verlauf anzuzeigen.

Body-Seiten

Bei einem Body sollte die Body versteckt werden, für die anderen Fälle sollte eine minimale Body-Seite angezeigt werden.

More search filter

  • Person
  • Any organization
  • Sort by: Best Match | Newest first | Oldest first

Nicht geänderte Objekte nicht aktualisieren

Aktuell scheinen z.B. bei den Files bei jedem Import immer alle Dateien neu eingelesen zu werden. Im Code scheint mir zwar eine Variable do_update angelegt, aber nicht weiter berücksichtigt zu werden. Schaust du dir das mal an?

Direktlinks zu Dateien in der Tagesordnung

Es sollte direkt in der Tagesordnung nicht nur Links zum Paper geben, sondern auch direkt zu den Dokumenten. Evtl. mit einer Mini-Drop-Down-Auswahl, wenn es mehrere gibt. Wichtig: wenn man von der Tagesordnung zu einer Datei geht, und dann mit der Datei-Auswahl-Sidebar alle Dateien durchliest, muss es wieder einen Weg zurück zur Tagesordnung geben.

Highlighting der Suchergebnisse verbessern

  • Anordnung der einzelnen Elemente verbessern (evtl. Typ / Datum rechtsbündig und die Fundstelle links davon?)
  • Falls die Fundstelle im Titel ist, sollte direkt der Titel gehighlightet werden uns nicht nochmal wiederholt werden

Django complains about readded timezones

RuntimeWarning: DateTimeField Paper.modified received a naive datetime (2017-10-10 00:00:00) while time zone support is active.

Something must be wrong with the timestamp conversion and/or storing which should be investigated.

OParl Export

Ist zwar im momentanen Status nicht relevant, steht aber in der Featureliste drinnen.

Warn on outdated brosers

In our sector it's unfortunately quite common that users have dangerously outdated browsers. We should warn about them about that with a big red sign.

Feedback vom 34c3 einarbeiten

  • Dokumententyp -> Person ist verwirrend, wenn es noch Person als eigenes Dropdown gibt
  • Leere Woche sollte nicht scrollbar sein
  • Loading im Kalender anzeigen
  • Beschreibung zur Uhr im Gremium
  • Übergeordnetes Dokument über dem pdfjs als solches bezeichnen
  • Animation ist schick
  • Bei den Migliedschaften die Ausschussnamen ausschreiben, s. /person/82
  • Marker auf der Karte erklären
  • Nicht die Kontaktseite Impressum überschreiben
  • Nicht direkt auf Prototype Fund und Github verlinken, sondern eine Seite (about) dazwischenschalten

Use Minio as object storage

Instead of just dropping dynamic files (i.e. the pdfs from the oparl api) to a docker volume we should drop them into minio. Docker compose integration should be easy.

django-admin makemessages fails

> django-admin makemessages -a
CommandError: Unable to find a locale path to store translations for file bedburg_transparent/templates/info/contact.html

RSS-Feeds

Fast 20 Jahre alt, aber nicht tot zu kriegen und erfüllt noch immer seinen Zweck.

  • Neueste Dokumente
  • Pauschal jede Suche (indem man /rss/ an die URL angängt)
  • Alle abonnierten Benachrichtigungen auf einmal
  • Tests
  • Per Meta-link im HEAD abonnierbar
  • In der UI verlinken
  • Description for other types, especially files and meetings

Datumssortierung verbessern

Problem bei der Datumssortierung:

  • Im längerfristigen Betrieb dürfte wahrscheinlich das modified-Feld relevanter sein als das legal_date, u.a. da nicht alle Datenobjekte ein legal_date haben
  • modified ist aber erst ab dem Zeitpunkt sinnvoll, wann die Erstindizierung abgeschlossen ist.

Vorschlag:
Es gibt eine setzbare Django-Setting "Erstindizierung" und in Elasticsearch ein zusätzliches Feld sort_date. Wenn das modified neuer ist als die Erstindizierung, zählt modified. Wenn älter, dann abhängig vom Datentyp: legal_date wenn vorhanden, ansonsten Zeitpunkt der Erstindizierung. (Ergebnis wäre: bei Sortierung nach Datum würden Personen, Gremien etc. zu dem Zeitpunkt der Erstindizierung einsortiert werden. Alternative wäre: sort_datum auf null setzen, sprich dass sie gar nicht / nur am Schluss auftauchen)

Feld "Mit Tabelle"

Feedback von Hacks/Hackers, da das bei kleineanfragen sehr praktisch ist

Kalender-Export / abonnieren

Es sollten nicht nur einzelne Termine per iCal abrufbar sein, sondern auch der komplette Kalender abonnierbar - damit man neue Termine automatisch im Kalender bekommt. Sollte dank der Vorarbeit beim Einzel-Termin-Export ziemlich simpel einzurichten sein.

Namen besser kürzen

Momentan kürzt der Importer zu lange Namen recht krude zusammen. Stattdessen sollte er für alle Kurztitel sinnvoll kürzen, vermutlich am besten weiterhin mit der \u2026 (…). Die richtigen Namen sollten dafür auf keinen Fall gekürzt werden.

Die Oberfläche, insbesondere die Antrags-, die Gremien-, und die Dokumentenseiten sollten auch sehr lange Titel passend anzeigen, sowohl auf dem Desktop als auch mobil.

Fix travis build

There is an apparently non-deterministic build failure in travis ci. This should be investigated.

Seite, um einen Kartenbereich zu abonnieren

Der momentane Weg (Suche -> Punkt auf Karte auswählen -> Text löschen -> abonnieren drücken) ist zu versteckt. Das abonnieren von Kartenausschnitten sollte daher wie bei Politik bei Uns 2 auf einer Seite oder wie bei München Transparent auf der Nutzerseite möglich sein.

Leaflet has missing images

Linkchecker found there were missing files:

  • /static/bundles/_/node_modules/leaflet/dist/images/layers.png
  • /static/bundles/_/node_modules/leaflet/dist/images/layers-2x.png
  • /static/bundles/_/node_modules/leaflet/dist/images/marker-icon.png
$ linkchecker http://127.0.0.1:8000
INFO 2017-10-24 19:56:33,626 MainThread Checking intern URLs only; use --check-extern to check extern URLs.
LinkChecker 9.3              Copyright (C) 2000-2014 Bastian Kleineidam
LinkChecker comes with ABSOLUTELY NO WARRANTY!
This is free software, and you are welcome to redistribute it
under certain conditions. Look at the file `LICENSE' within this
distribution.
Die neueste Version gibt es unter http://wummel.github.io/linkchecker/
Schreiben Sie Kommentare und Fehler an https://github.com/wummel/linkchecker/issues
Unterstütze dieses Projekt unter http://wummel.github.io/linkchecker/donations.html

Beginne Prüfen am 2017-10-24 19:56:33+002
 1 thread active,     0 links queued,    0 links in   0 URLs checked, Laufzeit 1 Sekunden
 1 thread active,     0 links queued,    0 links in   0 URLs checked, Laufzeit 6 Sekunden
10 threads active,    44 links queued,   25 links in   4 URLs checked, Laufzeit 11 Sekunden
10 threads active,   153 links queued,  114 links in  18 URLs checked, Laufzeit 16 Sekunden

URL             `_/node_modules/leaflet/dist/images/layers.png'
Vater URL       http://127.0.0.1:8000/static/bundles/mainapp.css, Zeile 1, Spalte 5631
Tats. URL       http://127.0.0.1:8000/static/bundles/_/node_modules/leaflet/dist/images/layers.png
Prüfzeit        2.621 Sekunden
Ergebnis        Fehler: 404 Not Found

URL             `_/node_modules/leaflet/dist/images/layers-2x.png'
Vater URL       http://127.0.0.1:8000/static/bundles/mainapp.css, Zeile 1, Spalte 5769
Tats. URL       http://127.0.0.1:8000/static/bundles/_/node_modules/leaflet/dist/images/layers-2x.png
Prüfzeit        2.622 Sekunden
Ergebnis        Fehler: 404 Not Found

URL             `_/node_modules/leaflet/dist/images/marker-icon.png'
Vater URL       http://127.0.0.1:8000/static/bundles/mainapp.css, Zeile 1, Spalte 6572
Tats. URL       http://127.0.0.1:8000/static/bundles/_/node_modules/leaflet/dist/images/marker-icon.png
Prüfzeit        2.483 Sekunden
Ergebnis        Fehler: 404 Not Found
10 threads active,   191 links queued,  226 links in  35 URLs checked, Laufzeit 21 Sekunden
/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py:823: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
10 threads active,   171 links queued,  328 links in  50 URLs checked, Laufzeit 26 Sekunden
10 threads active,   181 links queued,  449 links in  61 URLs checked, Laufzeit 31 Sekunden
10 threads active,   192 links queued,  618 links in  76 URLs checked, Laufzeit 36 Sekunden
10 threads active,    78 links queued,  860 links in  90 URLs checked, Laufzeit 41 Sekunden
10 threads active,    71 links queued, 1023 links in 101 URLs checked, Laufzeit 46 Sekunden
10 threads active,    55 links queued, 1274 links in 104 URLs checked, Laufzeit 51 Sekunden
10 threads active,    26 links queued, 1433 links in 111 URLs checked, Laufzeit 56 Sekunden
10 threads active,    14 links queued, 1581 links in 114 URLs checked, Laufzeit 1 Minute, 1 Sekunden
10 threads active,     1 link queued, 1737 links in 116 URLs checked, Laufzeit 1 Minute, 6 Sekunden

Statistik:
Downloaded: 652.03KB.
Inhalte: 1 Bild, 1224 Text, 0 Video, 0 Audio, 316 Anwendung, 0 E-Mail und 317 andere Inhalte.
URL Längen: min=21, max=303, mittel=41

Das war's. 1858 links in 117 URLs checked. 0 Warnungen gefunden. 3 Fehler gefunden.
Beende Prüfen am 2017-10-24 19:57:43+002 (1 Minute, 9 Sekunden)

Finish Dockerization

docker-compose up should start all the services. Also research how to start services from the docker compose config selectively. (Maybe it's as simple as using the override file)

Kleinigkeiten

  • Erklärtext auf der Registrierungsseite (Benachrichtigungen brauchen das technisch / Wir verkaufen keine Nutzerdaten / Ehrenamtlich)
  • Benachrichtigungen statt einloggen auf der Startseite
  • "Wie funktioniert Stadtpolitik" rauswerfen
  • Das Personen-Modul für Gremium weiterverwerten
  • Links zu leeren Gremien auf der Gremienseite deaktivieren
  • "Zur Suche" in Person und in Gremium
  • Seitenleiste in File mit den anderen Dateien der Drucksache
  • Kalendar wackelt durch den Spinner
  • Kalendar Tests von js-Injection auf URLs umstellen
  • Neue Termine auf der Startseite
  • Sitze pro Fraktion / Mitglieder pro Gremium
  • Leerer Dropdown Header unter mein Zugang
  • Get rid of simple_model_view
  • Die Übersetzungen für das "Submitting" in der Historie sind noch etwas unstimmig
  • https://meine-stadt-transparent.de/paper/60/
  • Die Signup-Seite braucht auch die Social Login Buttons und passende CSP
  • Bekannte Typen in der Organisationsübersicht übersetzen

Titel im Importer verbessern

Z.B. indem bei Dateinamen Sitzungsvorlage \((.*)\) nach $1 umgeschrieben wird, wenn die Vorlage schon passend heißt.

Dafür sollte eine recht allgemeine Lösung gebaut werden, die die Regeln aus einer Konfigurationsdatei liest. Das hat aber keine hohe Priorität, da die jetzigen Titel und Namen an sich korrekt sind, wenn auch nicht schön.

Delete embedded objects

If an object has been set to deleted, the importer deletes the object and returns, so all the embedded objects stay. Fixing this will need some refactoring.

Alternative Dokumentenanzeige

Wir sollten zumindest die Möglichkeit einbauen, Bilder anzuzeigen, und einen guten Fallback für sonstige Dateitypen haben.

Stable links for the calendar

The calendar should provide stable urls to each view and each selected timeframe. If this isn't possible with the current library, we should consider alternative libraries as well as evaluate adding this to the library. If both isn't feasible this ticket should be closed as wontfix.

Import automization

There should be a command where you only need to enter the name of a city and it imports the oparl data and sets the correct settings.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.