Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | first commit |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | descendants | master | trunk |
Files: | files | file ages | folders |
SHA3-256: |
52e2986e7563cad253570ce65c4dd4b9 |
User & Date: | git@tuxproject.de 2016-09-25 00:40:50 |
Context
2017-05-03
| ||
08:10 | LICENSE: Copyright erweitert; README ergänzt; Flask-Server wird jetzt über gevent gestartet. check-in: b097839206 user: git@tuxproject.de tags: master, trunk | |
2016-09-25
| ||
00:40 | first commit check-in: 52e2986e75 user: git@tuxproject.de tags: master, trunk | |
Changes
Added LICENSE.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. |
Added README.md.
> > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # Plakate-App Dies ist eine Webanwendung, die eine anklickbare Straßenkarte anzeigt, über die (zum Beispiel) die Position von Plakaten im Wahlkampf bestimmt werden kann. ## Hä? Haste mal ein Beispiel? Klar. Nehmen wir an, ihr wollt für irgendeinen Verein eure Stadt vollplakatieren, wollt aber den Überblick behalten, wo überall Plakate hängen, um sie später wieder entfernen zu können. Genau diesem Zweck dient diese Anwendung. ## Technik Ihr braucht auf eurem Server nur Python und das Flask-Modul (`pip install flask`), alles Weitere lädt die Website automatisch: python ./server.py Die Karte ist anschließend über den Port 6090 (einstellbar direkt in der Datei `server.py`) erreichbar. Unter `/manageplakate` gibt es auch eine einfache Liste aller eingetragenen Plakate zum schnellen Löschen. Das Großteil des UIs wurde mit [Leafjet.js](http://leafletjs.com/) programmiert. ## Urheberrecht? Quatsch. Die Plakateapp wurde ursprünglich für den Kommunalwahlkampf in Niedersachsen 2016 von [@tux0r](https://twitter.com/tux0r) hektisch (also eher zweckmäßig als gut) für die Piratenpartei Braunschweig programmiert (weshalb der Standard für die Position mitten in Braunschweig liegt, aber das könnt ihr im Javascript-Code ändern). All dies hier steht unter der [WTFPL v2](http://www.wtfpl.net/txt/copying/), ihr dürft also gern damit wegrennen und es teuer verscherbeln. Viel Spaß! |
Added src/plakate.db.
cannot compute difference between binary files
Added src/server.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import sqlite3 import json from flask import Flask, render_template, request, send_from_directory, redirect app = Flask(__name__) PORT = 6090 @app.route('/') def hauptseite(): return render_template("index.htm") @app.route("/manageplakate") def manage_plakate(): try: conn = sqlite3.connect("plakate.db") with conn: c = conn.cursor() c.execute("SELECT * FROM plakate") plakate = [dict(id=row[0], lat=row[1], lon=row[2]) for row in c.fetchall()] return render_template("delete.htm",plakate=plakate) except: return "err" @app.route("/listplakate", methods=['POST']) def list_plakate(): try: conn = sqlite3.connect("plakate.db") with conn: c = conn.cursor() c.execute("SELECT * FROM plakate") plakate = [dict(id=row[0], lat=row[1], lon=row[2]) for row in c.fetchall()] return json.dumps(plakate) except: return "err" @app.route("/neuesplakat", methods=['POST']) def neues_plakat(): try: latitude = request.form["lat"] longitude = request.form["lon"] conn = sqlite3.connect("plakate.db", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) with conn: c = conn.cursor() c.execute("INSERT INTO plakate (lat, lon) VALUES ({}, {});".format(float(latitude), float(longitude))) conn.commit() return "Plakat erfolgreich eingetragen!" except sqlite3.Error as e: return "Fehler! :-( {}".format(e.message) @app.route("/del/<int:plakatid>", strict_slashes = False) def del_plakat(plakatid): try: conn = sqlite3.connect("plakate.db", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) with conn: c = conn.cursor() c.execute("DELETE FROM plakate WHERE id={}".format(plakatid)) conn.commit() return redirect("/manageplakate") except sqlite3.Error as e: return "Fehler! :-( {}".format(e.message) @app.route("/delpost", methods=['POST']) def delpost(): try: plakatid = request.form["id"] conn = sqlite3.connect("plakate.db", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) with conn: c = conn.cursor() c.execute("DELETE FROM plakate WHERE id={}".format(plakatid)) conn.commit() return "Geklappt." except sqlite3.Error as e: return "Fehler! :-( {}".format(e.message) @app.route('/templates/<path:path>', strict_slashes = False) def web_static(path): # Statische Templatedateien ausliefern return send_from_directory('templates', path) app.run(host='0.0.0.0', port=PORT, debug=False) |
Added src/templates/delete.htm.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <table> <tr> <th><b>Latitude</b></th> <th><b>Longitude</b></th> <th><b>Löschen</b></th> </tr> {% for plakat in plakate %} <tr> <td>{{ plakat.lat }}</td> <td>{{ plakat.lon }}</td> <td><a href="/del/{{ plakat.id }}">X</a></td> </tr> {% endfor %} </table> |
Added src/templates/index.htm.
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!doctype html> <html> <head> <title>Piratenplakate</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <link rel="stylesheet" href="https://npmcdn.com/leaflet@1.0.0-rc.2/dist/leaflet.css" /> <script src="https://npmcdn.com/leaflet@1.0.0-rc.2/dist/leaflet.js"></script> <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script> <script src="/templates/script.js"></script> </head> <body style="overflow:none"> <div id="map" style="height:100%;width:100%;position:absolute;top:0px;left:0px;"></div> </body> </html> |
Added src/templates/script.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | var map; var ajaxRequest; var plotlist; var plotlayers=[]; function initmap() { // Karte initialisieren map = new L.Map('map'); var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; var osmAttrib='Karte von <a href="http://openstreetmap.org">OpenStreetMap</a>'; var osm = new L.TileLayer(osmUrl, {minZoom: 12, maxZoom: 28, attribution: osmAttrib}); // OSM anzeigen map.addLayer(osm); // bei Ortungserfolg Standort anzeigen: map.on('locationfound', function() { var radius = e.accuracy / 2; L.marker(e.latlng).addTo(map) .bindPopup("Du bist ungefähr hier.").openPopup(); L.circle(e.latlng, radius).addTo(map); }); // bei Ortungsmisserfolg Karte mitten in Braunschweig setzen: map.on('locationerror', function() { map.setView(new L.LatLng(52.269167, 10.521111), 17); }); // bestehende Marker laden: $.post( "/listplakate", {}, function(data) { var json = JSON.parse(data); for (var i = 0; i < json.length; i++) { var plakat = json[i]; var plakatlatlng = new L.LatLng(plakat.lat,plakat.lon) var marker = new L.Marker(plakatlatlng, {draggable:false}) .bindPopup("<input type='button' value='Plakat löschen' data-id='"+plakat.id+"' class='marker-delete-button'/>"); marker.on("popupopen", onPopupOpen); map.addLayer(marker); } } ); // neue Marker setzen: map.on('click', function(e) { if (confirm("Möchtest du hier ein neues Plakat melden?")) { var marker = new L.Marker(e.latlng, {draggable:false}); marker.on("popupopen", onPopupOpen); map.addLayer(marker); $.post( "/neuesplakat", { lat: e.latlng.lat, lon: e.latlng.lng }, function(data) { alert(data); } ); } }); $(".dellink").on("click", function() { }); // Ortung versuchen: map.locate({ setView: true, maxZoom: 28 }); } function onPopupOpen() { var tempMarker = this; $(".marker-delete-button:visible").click(function () { $.post( "/delpost", { id: $(this).attr("data-id") }, function(data) { // noop } ); map.removeLayer(tempMarker); }); } $(document).ready(function() { initmap(); }); |