Compare commits

..

420 Commits

Author SHA1 Message Date
b3yond 491182760b first try on database schema 2019-06-10 13:43:19 +02:00
b3yond 79f16f13d4
Merge pull request #92 from ticketfrei/masto502
don't log Mastodon 502 errors.
2019-05-04 12:04:55 +02:00
b3yond 61097576aa
Merge pull request #94 from ticketfrei/images
Images
2019-05-04 10:24:49 +02:00
sid d1b11fe932
Update active_bots/telegrambot.py
Co-Authored-By: b3yond <b3yond@riseup.net>
2019-05-04 10:22:03 +02:00
b3yond 7a7e8f0a30 Notify that telegram image reports are not supported. #90 2019-05-03 14:35:06 +02:00
b3yond e18244e149 don't log Mastodon 502 errors. 2019-05-03 10:07:16 +02:00
b3yond 39cf3bd070 Merge branch 'templates' into stable3 2019-01-27 23:41:37 +01:00
b3yond 382532cf5c remove redundant import stuff 2019-01-27 23:35:55 +01:00
b3yond cfb9eabee9
Merge pull request #85 from ticketfrei/templates
Templates
2019-01-27 23:17:30 +01:00
b3yond a27d47eb8b templates from bots/*/ are correctly imported 2019-01-27 23:09:25 +01:00
b3yond e34944fcaa started splitting up the templates, wondering how to include them 2019-01-27 22:44:23 +01:00
b3yond d6db1879f9
Merge pull request #84 from ticketfrei/master
Added CSRF protection
2019-01-27 17:59:01 +01:00
b3yond 02f117a864
Merge pull request #82 from ticketfrei/csrf
Building in CSRF prevention
2019-01-27 17:56:53 +01:00
b3yond 482350f8c7 Merge branch 'csrf' of github:ticketfrei/ticketfrei into csrf 2019-01-27 17:55:23 +01:00
b3yond 6b52a6303a better crypto 2019-01-27 17:53:37 +01:00
b3yond 2a90573d5e cleaning up the code. 2019-01-27 17:39:31 +01:00
b3yond e735936c7a hardened the token and fixed the signature 2019-01-27 16:31:59 +01:00
b3yond ee9b051c71 added CSRF token to settings template 2019-01-27 16:24:58 +01:00
b3yond 139195fd02 added CSRF token to settings template 2019-01-27 16:08:45 +01:00
b3yond 3dd976ef40 This was a weird merge conflict with my own branch o.0 2019-01-27 16:05:53 +01:00
b3yond cdecd170a0 give CSRF token to template engine 2019-01-27 15:56:19 +01:00
b3yond ec68f17b32 write and read CSRF cookie 2019-01-27 15:39:49 +01:00
b3yond ddefc2aafa write and read CSRF cookie 2019-01-27 14:52:42 +01:00
b3yond 60e1d8ec30 found last db.secret and fixed to use the getter 2019-01-27 11:37:21 +01:00
b3yond 4882930516 adjusted the README to the version 3 branch 2019-01-12 10:02:27 +01:00
b3yond d5b0ba9b6d removed redundant photo (how did it end up here? I should take a break.) 2019-01-12 01:20:22 +01:00
b3yond 26fa98ad9b Merge branch 'envs' 2019-01-12 01:09:38 +01:00
b3yond de525adb7a Merge branch 'master' of github:b3yond/ticketfrei 2019-01-12 00:34:13 +01:00
b3yond 30c49bbfc8 apparently I didn't find all calls to db.secret 2019-01-12 00:34:03 +01:00
b3yond 880b327b20 new default background image 2019-01-12 00:19:02 +01:00
b3yond 467fdaa42a new default background image 2019-01-12 00:10:55 +01:00
b3yond a4996266a1
Merge pull request #74 from ticketfrei/version-number
Version number
2019-01-11 23:31:25 +01:00
b3yond c9c153117e
Merge pull request #76 from ticketfrei/envs
Use environment variables for config values
2019-01-11 23:25:31 +01:00
b3yond 54489807da no need for such a verbose error message. 2019-01-11 15:16:37 +01:00
b3yond 4b8798ddea fixing shutdown when exim4 is not set up 2019-01-11 14:52:58 +01:00
sid 6a5e7f5028
Merge pull request #75 from ticketfrei/git-sid-patch-1
Update LICENSE
2019-01-11 13:49:16 +01:00
sid 7507d0392d
Update LICENSE 2019-01-11 13:48:29 +01:00
b3yond 4bd99ebb90 updated the issue template 2019-01-11 13:44:27 +01:00
b3yond 12a0b1efe5 added call to GET version (commit hash) 2019-01-11 13:38:47 +01:00
b3yond a38c2316f2
Merge pull request #72 from ticketfrei/confirm-37
check if account already exists to avoid double use of confirmation mail
2019-01-11 13:33:04 +01:00
b3yond 76b3b574f0 replaced attribute with get call 2019-01-11 13:23:37 +01:00
b3yond 2ce27fc52f nicer error messages 2019-01-11 13:21:47 +01:00
b3yond 1c8853341a check if account already exists #37 2019-01-11 12:15:28 +01:00
b3yond a529f4eb23 formatting #70 2019-01-11 11:41:20 +01:00
b3yond 521f0e7ef2
Merge pull request #71 from patcon/patch-1
Add mission to README
2019-01-11 11:39:37 +01:00
Patrick Connolly 2bee67bf84
Add mission to README. 2019-01-07 14:51:37 -05:00
git-sid cb2f3cb2e1 Fix pep8 non-compliant linebreak 2019-01-07 19:05:39 +01:00
git-sid a47ad74619 Replace 3 dots with ellipsis to save space 2019-01-07 19:05:32 +01:00
b3yond f6c19abad6 fixing the original TypeError 2018-12-31 15:33:50 +01:00
b3yond e7e230b2f0 when you get crashes bc of your log messages -. 2018-12-31 15:32:19 +01:00
b3yond e72d4872c0 more verbose telegram error messages 2018-12-31 15:27:11 +01:00
b3yond d5823ee1ad removed redundant table declaration 2018-12-28 14:43:18 +01:00
b3yond 268b9748c3 introduce extra var bc can't write to private attribute 2018-11-12 12:32:28 +01:00
b3yond 8e1234d9b5 removed wrong comment - not only testing, also docker containers use this 2018-11-07 09:22:02 +01:00
b3yond 4c61b1ba99 setting host to 0.0.0.0 - it never worked with smth else anyway 2018-11-07 01:57:47 +01:00
b3yond 5a4763366b if an env var is an empty string, use values from example config 2018-11-06 18:08:51 +01:00
b3yond 945a90c7e1 make config.py output directly applicable 2018-11-06 17:50:57 +01:00
b3yond bc7a4a72f8 beauty overhaul of config.py 2018-11-06 16:23:47 +01:00
b3yond d964927a3f fix small bug, print current config if directly called #64 2018-11-06 16:22:11 +01:00
b3yond 238dd20d20 if no config.toml, set config through environment #64 2018-11-06 16:17:47 +01:00
b3yond f274d25822 updated example config options + 1 little fix 2018-11-06 08:56:24 +01:00
b3yond 710a89c282 fix mailbot crash:
File "/srv/ticketfrei/active_bots/mailbot.py", line 37, in post
    if rec not in report.author:
TypeError: argument of type 'NoneType' is not iterable
2018-10-26 18:20:01 +02:00
b3yond 8b36589557 added 502 to unlogged Telegram error codes 2018-10-26 17:27:00 +02:00
b3yond 7cb211b4cb polishing the wording of RSS subscription 2018-10-26 17:25:25 +02:00
git-sid 9508618347 add rss feed notification option to info page 2018-10-19 08:26:20 +02:00
b3yond 651e684316 add another issue template 2018-10-18 17:09:21 +02:00
b3yond 1a0ae78ac1
Merge pull request #57 from ticketfrei/issue-templates
Update issue templates
2018-10-18 17:06:14 +02:00
b3yond 01f33ea29a Update issue templates 2018-10-18 17:04:06 +02:00
b3yond 400e15d18a fix screenshot links in default city page 2018-10-13 20:01:51 +02:00
b3yond 55db252f44 mastodon seen toots work differently now; function deprecated 2018-10-13 19:34:16 +02:00
b3yond f64142d882 reworked front page text 2018-10-13 19:01:54 +02:00
b3yond f286c127ba brought README.md up to date 2018-10-13 18:56:09 +02:00
b3yond 4428fa932f excepted return message 34 so it doesn't get logged #39 2018-10-11 22:22:37 +02:00
b3yond cc5ab22be5 excepted with wrong Exception 2018-10-11 21:30:55 +02:00
b3yond 56e948b798 called wrong user method 2018-10-11 21:29:02 +02:00
b3yond c36b8ab673 fixing bug; twitterDM object wasn't created 2018-10-11 21:24:53 +02:00
b3yond 17df4f15e4 check if mention is in reply to anything #41 2018-10-08 23:32:33 +02:00
b3yond b5de7cde9f Revert "crawl the username only once from twitter and save to db #45"
This reverts commit 9836ec7752.
2018-10-08 23:27:45 +02:00
b3yond 8eb2d98c03 Merge remote-tracking branch 'origin/master' 2018-10-08 22:14:35 +02:00
b3yond 9836ec7752 crawl the username only once from twitter and save to db #45 2018-10-08 21:31:25 +02:00
b3yond 9e8cfa624c fix repost bug 2018-10-08 21:26:39 +02:00
b3yond 084049bbfe fix repost bug 2018-10-08 15:09:18 +02:00
b3yond 6a8cf5c6af ignore PGP signatures; I hope those messages get posted now #40 2018-10-08 15:02:27 +02:00
b3yond de657ba350 really fix shutdown in #40 2018-10-07 23:28:29 +02:00
b3yond bbe27e2586 fix shutdown in #40 2018-10-07 23:27:06 +02:00
b3yond 9a3c09b119
Merge pull request #50 from ticketfrei/rate-limit-39
missing newlines in /etc/aliases
2018-10-07 23:05:52 +02:00
b3yond 30de2196ac missing newlines in /etc/aliases 2018-10-07 23:01:14 +02:00
b3yond 9ca521493a
Merge pull request #49 from ticketfrei/rate-limit-39
Rate limit 39
2018-10-07 22:19:57 +02:00
b3yond 0449d892a3 insert empty row at account creation 2018-10-07 22:16:00 +02:00
b3yond f59be986e2 reverting #39 - make rate limits per account, not app 2018-10-07 22:10:48 +02:00
b3yond 79d5a6f112 fixed sendmail calls 2018-10-07 21:02:48 +02:00
b3yond 9800b52153 cleaned up 2018-10-07 19:21:04 +02:00
b3yond 54930a32f6
Merge pull request #43 from b3yond/multi-deployment
Merge the multi-deployment branch to master finally, so we can continue development on master!
2018-10-07 19:17:04 +02:00
b3yond 0b862e35c8 changed promotion repo link #21 2018-10-07 19:15:18 +02:00
b3yond 13fcb41148 Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-10-07 19:13:50 +02:00
b3yond d3d7bd098d moved promotion to own repository: https://github.com/ticketfrei/promotion #21 2018-10-07 19:13:23 +02:00
b3yond 8a4cc17575 moved promotion to own repository: https://github.com/ticketfrei/promotion 2018-10-07 19:12:44 +02:00
b3yond 3d669e6caf fixing #42 - excepting more Telegram error codes 2018-10-07 19:09:02 +02:00
b3yond e032ecbcc3 Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment 2018-10-07 18:48:05 +02:00
b3yond 30f1f8a21c fixing #40 - treating different message MIMEtypes 2018-10-07 18:47:37 +02:00
b3yond 942f19fefe comments, because the use of this file is not obvious. 2018-10-06 11:58:08 +02:00
b3yond 5119c6bfbb globals are in a separate python file now #39 #45 2018-10-06 10:44:07 +02:00
b3yond 2068b99b87 fixing #44 - refactoring how mails are sent 2018-10-06 10:20:37 +02:00
b3yond 4851fc0b63 manually merging multi-deployment with master 2018-10-06 09:29:34 +02:00
b3yond b9a4899981 fixing #38: putting the city into the From address of report mails 2018-10-06 02:46:54 +02:00
b3yond 304d83ffad fixing #39 - saving last request in global var, not db. 2018-10-06 00:56:12 +02:00
b3yond 9b3efd7bd2 fixed #41 - mention has to be in status text now 2018-10-05 23:40:41 +02:00
b3yond 24598f0b87 crawl only mentions, no replies 2018-10-05 11:02:12 +02:00
b3yond dc8f51c632 payload is extracted later, we need the message object here 2018-10-05 10:56:34 +02:00
b3yond 34d43f1911 get text of email, not message object 2018-09-25 11:06:08 +02:00
b3yond 2a4d517f1d only save newer tweets, don't override with older 2018-09-24 23:16:05 +02:00
b3yond 2d12aa7107 save the newest id, not the current 2018-09-24 23:08:29 +02:00
b3yond 47a7452eb4 excepting and logging Twitter Errors to prevent crashes 2018-09-24 23:02:10 +02:00
b3yond 234ed59049 don't require correctly cased mail addresses 2018-09-24 22:40:29 +02:00
b3yond 5efea773b8 get text from db, not rows 2018-09-24 22:27:11 +02:00
b3yond 3b19278774 repaired seen_tweets, this time 4 real 2018-09-24 22:14:17 +02:00
b3yond 03033d26d7 repaired seen_tweets 2018-09-24 22:10:23 +02:00
b3yond b35e885ae2 bug in pattern matching 2018-09-24 21:11:28 +02:00
b3yond d61d5750bb fuck sql 2018-09-24 21:02:10 +02:00
b3yond aa9267e8d1 1 comma too much 2018-09-24 21:00:55 +02:00
b3yond 732ac1c5d3 changed toot logic 2018-09-24 20:54:57 +02:00
b3yond b94ead7041 weird log logic 2018-09-24 19:58:17 +02:00
b3yond b20a080129 transmitted wrong variable 2018-09-24 19:51:23 +02:00
b3yond 1412dbc54c simple var name error 2018-09-24 19:46:21 +02:00
b3yond f28df3ce3e logging reports for debugging 2018-09-24 19:41:48 +02:00
b3yond 0cf1d8b603 sqlite3 syntax error because of trailing " 2018-09-24 17:14:23 +02:00
b3yond 244bde51b6 added email routing with exim4 via /etc/aliases 2018-09-23 18:53:46 +02:00
b3yond 36c21dbfbb style guides ftw 2018-09-15 19:30:37 +02:00
b3yond f360c4f8fd Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment
# Conflicts:
#	template/settings.tpl
2018-09-15 19:20:25 +02:00
b3yond fcab07246b blacklist -> blocklist #31 to honor zuckerimtank@twitter.com 2018-09-15 19:01:58 +02:00
b3yond 11f3c5713b
Merge pull request #36 from git-sid/multi-deployment
merge small stylechanges
2018-09-15 18:58:08 +02:00
b3yond 1a793657af
right of = should be right of = 2018-09-15 18:50:37 +02:00
b3yond e9ac7286d9
peak readability 2018-09-15 18:47:43 +02:00
b3yond 823df7b04a fix TypeError when updates == None 2018-09-14 19:59:45 +02:00
git-sid 1703eb3802 Make code even more PEP8 compliant
It could be made even more compliant, but that would actually decrease
readability imo.
2018-09-14 12:45:49 +02:00
git-sid 72d6798022 WIP: #31 fix: blacklist -> blocklist.
Replace all relevant instances of "blacklist" with blocklist.
Untested due to OS restricitions. Please check before merge.
2018-09-14 09:44:21 +02:00
git-sid c2ed73bafc Make code more pep8 compliant 2018-09-13 17:33:33 +02:00
git-sid c576888da5 small fix 2018-09-13 17:24:19 +02:00
b3yond 25bfe8e838 Merge branch 'multi-deployment' of github:b3yond/ticketfrei into multi-deployment 2018-09-09 21:38:22 +02:00
b3yond eae077cb9b Merge branch 'multi-deployment' of github:git-sid/ticketfrei into multi-deployment 2018-09-09 21:37:30 +02:00
b3yond 91181e1cf8 added telegram to default city page text. 2018-09-09 21:36:27 +02:00
b3yond 6757e62242 those error messages are a bit universal. 2018-09-09 21:36:01 +02:00
b3yond c37a447392
Merge pull request #20 from git-sid/multi-deployment
added basic telegram backend support & smaller changes
2018-09-09 21:26:57 +02:00
b3yond 3e83ba95da those error messages are a bit universal. 2018-09-09 20:32:10 +02:00
b3yond faaf8ac5f4 default values are bad practice 2018-09-09 20:28:13 +02:00
b3yond a54538bcea fixed seen_toot problem 2018-09-09 20:22:41 +02:00
b3yond 6f3c953736 fixed telegram spam problem!!111 2018-09-09 18:06:12 +02:00
b3yond 0624bcb378 Merge branch 'multi-deployment' of github:git-sid/ticketfrei into multi-deployment
# Conflicts:
#	active_bots/telegrambot.py
2018-09-09 17:52:23 +02:00
b3yond 6cac81e444 fixing more telegram bugs 2018-09-09 17:51:07 +02:00
git-sid f68a869309 added message type filtering -> only text messages get crawled 2018-09-09 17:47:38 +02:00
b3yond a0bd5e69e1 Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment 2018-09-09 17:29:29 +02:00
b3yond 4b953f54e5 Making Twitter Rate Limiting intelligent #35 2018-09-09 17:29:06 +02:00
git-sid 8acbfb4569 added offset to telegram message polling to prevent duplicated responses 2018-09-09 17:22:00 +02:00
b3yond 439dbeb1fa telegram troubleshooting and fine-tuning 2018-09-09 16:58:07 +02:00
b3yond fd8b29c55f appropriate success message 2018-09-09 15:45:25 +02:00
b3yond f1d7215eba debug level was not enough 2018-09-09 15:09:40 +02:00
b3yond 4586e14ee4 Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment 2018-09-09 14:58:12 +02:00
b3yond 40c834020a logging confirmation links for debug purposes 2018-09-09 14:57:40 +02:00
git-sid b85360b0a8 added twx dependency to README.md instruction 2018-09-09 14:26:46 +02:00
git-sid 185014a452 fixed telegram api bug (from -> sender) 2018-09-09 13:25:42 +02:00
b3yond b5f6854a1c host is configurable now 2018-09-08 16:31:02 +02:00
b3yond 7ca904564c Port is configurable now 2018-09-08 16:06:25 +02:00
b3yond b80b80dc43
Merge pull request #32 from b3yond/mailbot
Rewriting the Mailbot, included subscription mechanism
2018-09-08 11:14:57 +02:00
b3yond 96329e968e finished #23 code. rw city page info display. Unsubscribe = Delete 2018-09-08 11:14:00 +02:00
b3yond c7aa87cb3b BE & FE store secret in DB. Unsubscribing works 2018-09-08 09:33:40 +02:00
b3yond ad4e65e0fa Merge branch 'multi-deployment' of github:b3yond/ticketfrei into multi-deployment 2018-09-01 14:01:18 +02:00
b3yond 9c599cec37 wait on rate limit option for twitter APIs 2018-09-01 14:01:03 +02:00
b3yond 848b7b1cb5
Merge pull request #30 from jorgesumle/multi-deployment
HTML fixes
2018-08-11 17:28:00 +02:00
Jorge Maldonado Ventura 0ffe4daac8 HTML fixes 2018-08-11 17:19:12 +02:00
b3yond 372e0612a6 wrote unsubscribe function, but BE & FE have different secrets 2018-08-09 15:01:51 +02:00
b3yond 57a2e4dcb1 the mailbot can now receive messages from /var/mail/test 2018-08-08 17:09:26 +02:00
b3yond ec399db2eb started to build a mailbot implementing bot.py 2018-08-08 14:04:31 +02:00
b3yond ef0ce8f9f1 Advertising mail notifications on the city page 2018-08-08 10:55:51 +02:00
b3yond 27b63d9f8f Merge remote-tracking branch 'origin/multi-deployment' into multi-deployment 2018-08-08 10:42:08 +02:00
b3yond cc0b3378a9 you can now subscribe to mail notifications! Also db bugfixes. 2018-08-08 10:24:20 +02:00
b3yond d002969377 mail subscription confirm functions;
confirmation code & mail template still missing
2018-08-07 15:10:28 +02:00
b3yond 1f0583da74 debugging the backend, adding mail subscribe page, finished VAG zeitung 2018-08-02 22:30:57 +02:00
b3yond e1eb737ad0 markus s. 2018-08-02 22:04:26 +02:00
b3yond 9beb864a2f added mail subscriber function, confirm missing 2018-07-22 13:56:15 +02:00
b3yond a05205289f added mail template callback functions 2018-07-22 13:47:56 +02:00
b3yond 89fce872f3 added template for subscribing to mail notifications (untested) 2018-07-21 15:07:47 +02:00
b3yond d7eba3d233 replaced illegal flyer parts 2018-07-17 23:41:33 +02:00
b3yond 10b3550ad6 fixed backend deployment with systemd 2018-07-14 17:17:36 +02:00
b3yond 2d879383d4 took out mailbot for now. development of mailbot continues on the mailbot branch. 2018-07-14 16:49:11 +02:00
b3yond 4343be7e06 bots are safely imported in the backend, except twitterDMs 2018-07-14 16:39:53 +02:00
b3yond 55a804f0d6 removing redundant p tags 2018-07-13 15:55:40 +02:00
b3yond cae74a5715 fixing missing /form tag #28 2018-07-13 15:55:14 +02:00
b3yond 3d23b47a6e included aktionsschwarzfahren in promotion newspaper 2018-07-13 15:12:48 +02:00
sid 57a4a50254 modified telegram bot subscribe implementation 2018-06-30 22:11:41 +02:00
sid a8504971ea
completed telegram subscriber list functionality 2018-06-30 21:32:22 +02:00
b3yond 9db71e485d fixing settings issue with required forms 2018-06-25 21:14:22 +02:00
b3yond 8dfffffe76 Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-06-25 21:13:47 +02:00
b3yond 4fb2930c6c small changes to default markdown 2018-06-25 21:13:43 +02:00
b3yond fd8f236cdd you need to checkout the multi-deployment branch, if you're actively developing 2018-06-24 00:26:00 +02:00
b3yond 44cd1308ba added development instructions to README 2018-06-24 00:24:01 +02:00
b3yond 4c6ab2d3ae css fixes 2018-06-24 00:12:39 +02:00
b3yond 0719b094f8 added telegram to frontend 2018-06-24 00:00:48 +02:00
sid a48ba9ebf8 added /start, /stop, /help command check & small fixes 2018-05-29 07:07:15 +02:00
sid 4b37c0df3d Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-05-29 00:10:22 +02:00
b3yond 83d8700e30 updated install instructions & gitignore 2018-05-28 22:26:07 +02:00
sid 86d63fe9a0
Merge branch 'multi-deployment' into multi-deployment 2018-05-28 21:18:22 +02:00
b3yond bfd9a2d5fe only markdown shit still missing, is displaying äöü on production server. 2018-05-25 19:21:30 +02:00
b3yond 7543bf3e6e last markdown fixes, I swear! 2018-05-25 17:12:41 +02:00
b3yond cd5eeb3917 You can now edit markdown in settings. #18 2018-05-25 16:50:02 +02:00
b3yond f4736c91dd fixed markdiown render issues. Closing #22 2018-05-25 16:31:08 +02:00
b3yond 559b709b8f more markdown fixes 2018-05-25 16:27:30 +02:00
b3yond 628fcb4f95 small markdown fixes 2018-05-25 16:15:44 +02:00
b3yond 2a9c5c657f you can now set goodlist & blacklist in settings. render city page #18. fixed #24 and #25. 2018-05-25 15:57:20 +02:00
b3yond c9dfb6611a Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-05-25 14:45:07 +02:00
b3yond 04a6b82c1b You can now set data for the city page. #22 2018-05-25 14:44:45 +02:00
sid 29a577508f added basic telegram backend support 2018-05-25 02:38:27 +02:00
b3yond d4d58daf40 backported the typo fixes by @git-sid in #19 2018-05-24 21:59:58 +02:00
b3yond 48d44cf698 backported the typo fixes by @git-sid in #19 2018-05-24 21:58:20 +02:00
b3yond 9274dfdecb Add API to get content of the user facing page 2018-04-27 01:20:37 +02:00
b3yond 5ec4d1aab0 displaying city or other titles on various pages. still ugly. 2018-04-26 23:48:26 +02:00
b3yond 62eb588b28 BETTER cat images!!11 2018-04-26 22:30:34 +02:00
b3yond 9885e39d68 added cat pictures <3333 2018-04-26 22:28:51 +02:00
b3yond 01b3657c8e fixing file not found 500 error 2018-04-26 22:23:58 +02:00
Tech 6996cbfc09 merrrrge 2018-04-26 22:07:00 +02:00
b3yond 591020f8cc Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-04-26 21:50:56 +02:00
b3yond d706c4f1cc created a user-facing page 2018-04-26 21:50:52 +02:00
Thomas L 642cf429e5 serve jquery from own server 2018-04-26 21:00:29 +02:00
b3yond dd24a2b265 fixing import error 2018-04-16 09:38:55 +02:00
b3yond 3afa73ccaf removed outdated images 2018-04-15 22:42:20 +02:00
b3yond 1a76cba4fb changed background image to jpg & more beautiful 2018-04-15 22:41:33 +02:00
b3yond 84746a6d01 better log messages 2018-04-15 12:11:49 +02:00
b3yond 064ca181c0 Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-04-15 11:59:50 +02:00
b3yond 16580f3181 implemented twitter DMs 2018-04-15 11:58:19 +02:00
b3yond 7f8697947c twitter & masto sign limit 2018-04-15 11:42:34 +02:00
b3yond 758ff1db46 implemented mastodon DMs, city, and backend.shutdown function 2018-04-15 11:26:48 +02:00
b3yond 9b01ac7eac save db in a persistent folder, /var/run is not persistent in every OS 2018-04-15 09:41:27 +02:00
b3yond 898f229145 Twitter OAuth dance works now!!1111 wuuuuhhuuuu 2018-04-14 18:16:05 +02:00
b3yond 0b41b43421 fixed db scheme error 2018-04-14 18:12:55 +02:00
b3yond 24beedf467 fixed several id typos 2018-04-14 17:56:48 +02:00
Thomas L fd2a389d12 add error message for empty form. 2018-04-14 17:53:08 +02:00
b3yond 25c57039ea fixed small, but nasty bug 2018-04-14 17:49:19 +02:00
b3yond 20cfe159e9 query is a dict, not a function 2018-04-14 17:38:49 +02:00
Thomas L 57cf3bd7d6 no return needed, redirect throws 2018-04-14 17:34:43 +02:00
Thomas L 1af14a5db4 Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-04-14 17:32:15 +02:00
Thomas L 22de5e7e4e add default triggerpattern 2018-04-14 17:31:53 +02:00
b3yond 4d556ec595 don't do except all -.- rather repair the fcking logging. 2018-04-14 17:31:01 +02:00
b3yond bf7c21c113 request token is a dict, not a string 2018-04-14 17:19:20 +02:00
b3yond 45d4cd2062 fixed url() call 2018-04-14 17:00:30 +02:00
b3yond 034513718f generate url with dedicated function 2018-04-14 16:36:57 +02:00
b3yond 261496c097 fixed config key error 2018-04-14 16:34:02 +02:00
b3yond 19cc64d00d added logging for unstable functions 2018-04-14 16:31:45 +02:00
b3yond 27497e7129 log python errors to extra file 2018-04-14 15:22:05 +02:00
Thomas L d280130b29 fix login and registration. 2018-03-29 21:58:55 +02:00
Thomas L 78331212e6 improve sendmail function. 2018-03-29 02:40:22 +02:00
b3yond 10fb150c21 merge 2018-03-29 02:00:28 +02:00
b3yond 29c35be8a5 reworked mailbot to implement bot.py 2018-03-29 01:50:05 +02:00
Thomas L bfc311b6c9 omit bare except. 2018-03-29 01:25:17 +02:00
Thomas L 4981223ee8 catch some error cases. 2018-03-29 01:13:53 +02:00
Thomas L 9339015101 fix account confirmation. 2018-03-29 00:59:13 +02:00
Thomas L 4850860f82 use local mail daemon for confirmation links 2018-03-29 00:57:17 +02:00
b3yond c9fd91de74 getting logging stuff 2018-03-29 00:39:45 +02:00
b3yond affd209a3b changed logging to new scheme in sendmail.py 2018-03-29 00:33:29 +02:00
b3yond ca55223be9 Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-03-29 00:31:38 +02:00
b3yond 5670c92d33 added logging to sendmail.py 2018-03-29 00:31:21 +02:00
Thomas L 2b6b3a2263 log to stderr 2018-03-29 00:24:56 +02:00
b3yond 0aa1d79621 changed default config after deployment learnings 2018-03-29 00:21:14 +02:00
b3yond 788f55860b Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-03-29 00:13:11 +02:00
b3yond ba6e13a2be started mail rewrite 2018-03-29 00:13:00 +02:00
Thomas L 8e08eb9c2e fix recursive import 2018-03-29 00:12:19 +02:00
b3yond c71bc8574a solved loop bug 2018-03-28 23:50:55 +02:00
b3yond bc41d7460c Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-03-28 23:47:02 +02:00
b3yond 9425fde917 clean up 2018-03-28 23:46:06 +02:00
Thomas L 88afab1270 cleanup 2018-03-28 23:40:26 +02:00
Tech 5db529702c Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-03-28 23:33:43 +02:00
b3yond 66bb1f86a3 reworked twitterbot according to new scheme 2018-03-28 23:33:04 +02:00
b3yond 49bd00fba3 clean up after refactor 2018-03-28 22:12:57 +02:00
b3yond ec3053a0ab small bugfixes 2018-03-28 20:24:21 +02:00
Tech 036c742f34 Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-03-28 18:47:44 +02:00
Thomas L 1dd75c10d5 Refactoring. 2018-03-28 17:36:35 +02:00
Thomas L 890e720c91 Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-03-27 23:37:19 +02:00
Tech a3e33c36c6 added deployment instructions and fixed some deployment issues. 2018-03-27 20:02:47 +02:00
Tech 670a1a6d8f Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-03-27 19:21:47 +02:00
b3yond 51dec7e072 tested deployment and brought learnings to README. added nginx config. 2018-03-27 01:04:07 +02:00
Tech c3f9f86d3f Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-03-26 22:24:06 +02:00
b3yond 2d7b222c21 removed attribution of author in bridged reports. #2 2018-03-26 21:21:51 +02:00
Tech dde4e6af7b Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-03-26 20:55:23 +02:00
Thomas L cb764f2ec3 Merge branch 'multi-deployment' of dl6tom.de:public/ticketfrei into multi-deployment 2018-03-25 23:42:45 +02:00
b3yond d207d4e960
Merge pull request #16 from d24phant/multi-deployment
propaganda - added our mission-draft
2018-03-25 22:57:40 +02:00
b3yond 5d2ffbd935
more paragraphs, some typos 2018-03-25 22:49:14 +02:00
d24phant ce79b37b38
fixed some fails_pt2
Hopefully.... :)
2018-03-25 22:32:15 +02:00
d24phant 2fdc6f1f28
Delete propaganda.tpl 2018-03-25 22:31:00 +02:00
d24phant f99b44d815
Fixed some fails
:)
2018-03-25 22:30:17 +02:00
d24phant c980e7abb5
Added "our_mission"-draft 2018-03-25 22:06:31 +02:00
b3yond 95ada7ba62 Lorem Ipsum -> actual promotion text 2018-03-25 18:23:42 +02:00
b3yond 9ac7ab3b70 config format changed 2018-03-25 17:50:28 +02:00
b3yond 64f1fff275 don't even dare to try it out. I already changed it. :P 2018-03-25 17:31:51 +02:00
Thomas L 3ea06d1e93 Add .editorconfig 2018-03-24 16:35:16 +01:00
Thomas L daf6fe831f cleanup 2018-03-24 16:26:35 +01:00
Thomas L 751f9154cc Add files for deployment. Make testing use memory-DB. 2018-03-24 15:02:11 +01:00
b3yond 061fb62bdc started reworking the README 2018-03-24 11:58:15 +01:00
Tech 305fb8e06a Merge branch 'multi-deployment' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-03-24 11:33:32 +01:00
b3yond ba9b28f254 removed a lot of unnecessary clutter 2018-03-24 11:32:59 +01:00
b3yond a8efcd7825 removed a lot of unnecessary clutter 2018-03-24 11:30:12 +01:00
b3yond 17d044ec20 changed config.toml layout for ticketfrei 2.0 #12 2018-03-24 11:25:14 +01:00
b3yond be118fb4bd renamed retweetbot & retootbot (wtf, those names) 2018-03-23 18:06:59 +01:00
b3yond aa5669b019 changed trigger to work with db 2018-03-23 18:00:05 +01:00
b3yond 5f55eb88ff changed twitter to work with db 2018-03-23 17:35:04 +01:00
b3yond c548a81272 removed waste 2018-03-23 17:07:00 +01:00
b3yond a65d410e4f changing mail to use db, part 1; seen mails 2018-03-23 17:00:52 +01:00
b3yond 570792ba37 reworked mastodon to work with frontend. user, config, logging -> new files. 2018-03-23 15:51:52 +01:00
b3yond c612a9dee0 rename to frontend.py & backend.py 2018-03-23 13:19:39 +01:00
b3yond bd2599c91a tested Mastodon OAuth Login - works now. 2018-03-23 13:14:06 +01:00
b3yond 81e2357e2f merging toms commits 2018-03-23 11:21:10 +01:00
b3yond a3b74dcfff initializing logger is also done by ticketfrei now 2018-03-23 11:18:00 +01:00
b3yond 32e86a3c0e ticketfrei can be imported now, takes care of loading config & logging 2018-03-23 11:05:24 +01:00
b3yond b9613a60de added twitter & masto OAuth to new web.py - untested, take care! 2018-03-23 02:28:00 +01:00
Thomas L 404be47d1b Use IF NOT EXISTS instead of sqlite specific hack. Clean up formating. Other minor fixes. 2018-03-22 21:15:15 +01:00
b3yond 235b8524f8 db is persistent now 2018-03-22 11:32:43 +01:00
b3yond 9e09dcea84 fixed db init, fixed confirmation mails, added logout button 2018-03-22 11:22:28 +01:00
b3yond c48704ea73 modified gitignore 2018-03-22 10:37:53 +01:00
b3yond cdc88e3ee3 this file should have been ignored, I guess 2018-03-22 10:35:51 +01:00
b3yond ee8040893e fixed login error, db is now saved between different test runs 2018-03-22 10:34:53 +01:00
b3yond 390f4dc76e if table "user" doesn't exist, db is created 2018-03-22 10:25:00 +01:00
b3yond a176f856d8 unified formatting of db_init SQL 2018-03-22 10:05:49 +01:00
b3yond 529270a396 complete db create statement 2018-03-22 09:51:50 +01:00
Thomas L 3f4ec83abe start refactoring web-frontend. 2018-03-22 02:23:31 +01:00
b3yond f9033a009f added mastodon oauth dance 2018-03-20 21:24:20 +01:00
b3yond eb0252f235 added twitter OAuth dance. 2018-03-20 20:00:19 +01:00
b3yond 9cc2bf4228 typo 2018-03-18 21:37:34 +01:00
b3yond 28891d5069 outline for masto oauth 2018-03-18 21:36:46 +01:00
b3yond 9e70ff6866 removed debug messages, small layout changes 2018-03-17 15:57:56 +01:00
b3yond 87302faf9e good- and blacklist configuration works now! <3 2018-03-16 18:59:40 +01:00
b3yond 8a7c2f0110 writing good/blacklist to db. Cookies don't work yet 2018-03-16 17:55:27 +01:00
b3yond 7bbcbe1ab1 writing goodlist & blacklist -> db 2018-03-16 15:17:12 +01:00
b3yond 4b21dddddf created twitter/masto OAuth login stub 2018-03-16 14:21:15 +01:00
b3yond 26d1282413 implemented the enable button 2018-03-16 12:41:34 +01:00
b3yond 79f301d823 added OpenGraph data, started enable button 2018-03-16 09:51:10 +01:00
b3yond 2ce2a45f7b fixed bg image on some browsers. fixed invalid email error. 2018-02-17 15:51:33 +01:00
b3yond 52c2d1e341 fixed FPD for bot.html 2018-02-17 12:31:49 +01:00
b3yond 1f01938a8c This time I really fixed the css. almost. 2018-02-17 12:30:06 +01:00
b3yond a7bae0aed9 login check with cookies works now. fixed some layout stuff 2018-02-16 17:46:43 +01:00
b3yond 1b75e03fc5 check if user already exists on registering 2018-02-16 14:16:50 +01:00
b3yond 7ccf6917c8 create db manually 2018-02-16 12:02:58 +01:00
b3yond 2e89f9bf2d It's unfortunate, but apparently it is impossible to keep this file in the repo. >.< 2018-02-16 11:59:58 +01:00
b3yond fb36221a40 readded db stub 2018-02-16 11:51:58 +01:00
b3yond 0c04ce4b70 delete db file 2018-02-16 11:50:23 +01:00
b3yond 1e0a8a09ed gitignore readd. how do I prevent ticketfrei.sqlite from updating the stub in the repo? 2018-02-16 11:46:10 +01:00
b3yond 27902954e8 fixed wallpaper after confirmation mail 2018-02-16 11:39:31 +01:00
b3yond 821f201454 confirmation emails work now, accounts can be created. 2018-02-16 11:33:27 +01:00
b3yond 9e221ed290 Excepted IMAP connection Error 2018-01-30 16:10:33 +01:00
b3yond 3bc1010edf small steps... 2018-01-26 17:54:11 +01:00
b3yond 0ba2438541 fix sqlite commands, rename to website.py 2018-01-26 15:19:03 +01:00
b3yond 0acb89ebf0 excepted IMAP4 error with unknown cause 2018-01-23 09:18:59 +01:00
b3yond c9d5f7441a excepted IMAP4 error with unknown cause 2018-01-23 09:17:26 +01:00
b3yond ace28ee25a summary: what is ticketfrei? 2018-01-19 16:42:43 +01:00
b3yond 63cf134ffa merged ticketfrei 1.0 into multi-deployment #3 2018-01-19 16:33:46 +01:00
b3yond c0328be3a4 one \ to much lol 2018-01-19 16:27:30 +01:00
b3yond c9e6a35372 updated README to version 1.0. you can disable accounts now 2018-01-19 16:00:36 +01:00
b3yond 04e05ee8ca excepted Mastodon API Error with a too broad exception 2018-01-19 00:17:09 +01:00
b3yond 37b2706a3b excepted TweepError that was raised without an explanation further than 503 2018-01-18 21:48:36 +01:00
b3yond 9305a32eb7 added more save_last(), schadet nicht 2018-01-18 20:15:41 +01:00
b3yond 12fbbde79c bots don't own trigger anymore 2018-01-18 15:18:20 +01:00
b3yond 21e4af6fa9 twitter accidentially crawled too many tweets 2018-01-18 15:14:04 +01:00
b3yond c8e67d1937 better error handling of FileExistsError, fixed regex for mastobot 2018-01-18 15:10:05 +01:00
b3yond 10de40549c added regex magic so twitter & masto don't mention themselves by accident 2018-01-18 14:48:53 +01:00
b3yond ee61ba19e6 mailbot doesn't crawl mails which it wrote itself anymore 2018-01-18 14:23:11 +01:00
b3yond 72d0acb20a bugfix: gave Report.__init__() twitter User object, not screen_name 2018-01-18 13:59:37 +01:00
b3yond b174db3cfe twitterbot.crawl() returns reports now, not statuses 2018-01-18 13:54:32 +01:00
b3yond 048bad181b only send one status at a time 2018-01-18 13:42:23 +01:00
b3yond b5288f341c bugfix: FileExistsError 2018-01-18 13:40:07 +01:00
b3yond 75e1ff902c function needs to take an argument 2018-01-18 13:19:11 +01:00
b3yond d6a0c6d377 changed ticketfrei flow logic, integrated mailbot!!! #11 2018-01-18 13:06:53 +01:00
b3yond cde5494de3 mailbot uses reports now, and doesn't need to own trigger 2018-01-18 12:42:37 +01:00
b3yond ff73c5dc21 Standardized reports; moved flow() logic to crawl(), repost(), & post(); bots don't own Trigger anymore 2018-01-18 11:41:08 +01:00
b3yond 9ef0b27970 Tried to make confirm link work (WIP) 2018-01-18 09:39:06 +01:00
b3yond 9f060b405e added nice slogan! 2018-01-09 23:01:01 +01:00
b3yond 5feb6cf5be check hashes at login (not tested) 2018-01-09 23:00:00 +01:00
b3yond da421769e9 generating confirmation links 2018-01-08 22:56:05 +01:00
b3yond 89ce129b38 first attempt at confirmation mails 2018-01-08 01:16:34 +01:00
b3yond 2f74791dd6 renamed promotion directory on master, too 2018-01-08 00:17:19 +01:00
b3yond 2e80d10222 renamed promotion directory 2018-01-08 00:16:29 +01:00
b3yond 2b4d8650c9 Merge branch 'master' of https://github.com/b3yond/ticketfrei into multi-deployment 2018-01-08 00:14:38 +01:00
b3yond 7689eb25f8 Started with the index page, worked on login & register. 2018-01-08 00:09:25 +01:00
Thomas L f2a0cf18b4 replace logger class with standard python loggin 2018-01-07 20:22:32 +01:00
Thomas L f0aaa4dc54 remove our api-keys m( 2018-01-07 18:48:35 +01:00
b3yond b9e1b38963 blacklisted certain racist slurs 2018-01-07 01:33:10 +01:00
b3yond 409f9e80f8 exchanged link & QR-Code 2018-01-07 00:52:03 +01:00
b3yond 851992803f created a flyer for autonomous centers 2018-01-06 22:20:36 +01:00
b3yond 79a8965d1c wrote 3 articles for a false-flag-flyer :D 2018-01-06 21:31:23 +01:00
b3yond a0ca940008 wrote fully fleshed out mailbot. has to be connected to ticketfrei.py #11 2018-01-05 17:13:41 +01:00
b3yond 5c98aa7677 started an IMAP listener to implement a 3rd bot: the Mailbot. #11 2018-01-05 14:16:24 +01:00
b3yond 01ad0e1c40 attach logfiles to shutdown mails 2018-01-05 11:20:07 +01:00
b3yond e962bbbe85 removed unused shutdown contact, renamed variable 2018-01-05 11:02:45 +01:00
b3yond 0b89a52da3 log traceback of all unexpected Exceptions 2018-01-05 10:52:15 +01:00
b3yond 31a54fc19f documented log config 2018-01-05 10:43:38 +01:00
b3yond 654af44534 reworked logger class - also handles bot crashes and tbs now. added configline for log directory. 2018-01-05 10:42:31 +01:00
b3yond 8357be7f7d typo 2018-01-04 12:23:41 +01:00
b3yond 98dd5e4212 improved the traceback messages 2018-01-04 12:20:59 +01:00
b3yond aa45a8e814 small fix 2018-01-04 11:05:36 +01:00
b3yond 0f6fc60b5e crash reports are now sent via mail. documented config.toml.example 2018-01-04 11:02:42 +01:00
b3yond df32f3c614 added class to write mails to users 2018-01-01 11:23:50 +01:00
b3yond d7dea7df00 finished changes to class structure 2017-12-30 16:33:34 +01:00
b3yond 96ef5e2a3f typo 2017-12-30 16:23:53 +01:00
b3yond e64e3702f6 moved log to own class 2017-12-30 16:20:25 +01:00
Thomas L 594b3fb5de fix fd mode 2017-12-30 11:31:16 +01:00
b3yond d22c85da1b Renamed config file to config.toml #6 2017-12-30 10:32:20 +01:00
b3yond 4aa4846527 optimized install docs 2017-12-30 01:21:57 +01:00
b3yond 7a1a857ab4 added documentation -> python3 #7 2017-12-30 01:17:13 +01:00
b3yond cbf16b8f74 changed ticketfrei.py to python3 #7 2017-12-30 01:15:22 +01:00
b3yond fb24c758a8 changed twitterbot to python3 + tweepy #7 2017-12-30 01:11:28 +01:00
b3yond 15d2c75b5a Merge branch 'master' of https://github.com/b3yond/ticketfrei 2017-12-10 20:20:39 +01:00
b3yond 2c21fb09ca added todo 2017-12-10 20:20:30 +01:00
b3yond 42aa60a968 wrote documentation 2017-11-28 15:11:09 +01:00
b3yond a4eef4b086 updated gitignore 2017-11-24 18:16:38 +01:00
b3yond 9e38906898 new image 2017-11-24 18:15:56 +01:00
b3yond b1348e5578 Merge branch 'master' of https://github.com/b3yond/ticketfrei 2017-11-24 18:13:52 +01:00
b3yond 1ee464cf97 patc designed a more readable sticker :D 2017-11-01 23:10:40 +01:00
b3yond 3ee52532d2 added nbg_ticketfrei logo 2017-10-18 19:15:16 +02:00
b3yond 357d6c4fc2 would be a nice feature 2017-10-17 15:29:09 +02:00
b3yond 36f919826f Merge branch 'master' of https://github.com/b3yond/ticketfrei 2017-10-17 15:27:56 +02:00
b3yond 694a930d73 Merge branch 'master' of dl6tom.de:public/ticketfrei 2017-10-17 00:16:51 +02:00
b3yond d6a94432c8 added another todo point 2017-10-17 00:15:56 +02:00
Thomas L aefe78eb50 add license 2017-10-17 00:14:57 +02:00
b3yond 150e3579b7 added 2 todo points 2017-10-17 00:04:21 +02:00
ng0 f4b8300ac1
minor correction to ticketfrei.cfg.example 2017-10-14 19:54:57 +00:00
25 changed files with 531 additions and 480 deletions

146
README.md
View File

@ -32,13 +32,15 @@ Today, you can use a Twitter, Mastodon, Telegram, and Mail with the account.
They will communicate with each other; if someone warns others via Mail,
Telegram, Twitter and Mastodon users will also see the message. And vice versa.
In version 2, this repository contains a web application. On this website,
In version 3, this repository contains a web application. On this website,
people can register an own bot for their city - the website manages multiple
bots for multiple citys. This way, you do not have to host it yourself.
bots for multiple citys, which run in parallel. This way, you do not have to
host it yourself, if you lack the know-how. But it is easily possible to do so
with docker: http://github.com/ticketfrei/docker-ticketfrei/
In the promotion folder, you'll find some promotion material you can use to
build up such a community in your city. Unfortunately it is in german - but
it's editable, feel free to translate it!
In https://github.com/ticketfrei/promotion, you'll find some promotion material
you can use to build up such a community in your city. Unfortunately it is in
german - but it's editable, feel free to translate it!
Website (our flagship instance): https://ticketfrei.links-tech.org
@ -108,7 +110,7 @@ virtualenv -p python3 .
Install the dependencies:
```shell
pip install tweepy pytoml Mastodon.py bottle pyjwt pylibscrypt Markdown twx gitpython
pip install tweepy pytoml Mastodon.py bottle pyjwt pylibscrypt Markdown twx gitpython SQLAlchemy
```
Configure the bot:
@ -152,19 +154,10 @@ echo "Enter your domain name into the following prompt:" && read DOMAIN
# configure nginx
sudo sed -r "s/example.org/$DOMAIN/g" deployment/example.org.conf > /etc/nginx/sites-enabled/$DOMAIN.conf
# create folder for database
# create folder for socket & database
sudo mkdir /var/ticketfrei
sudo chown www-data:www-data -R /var/ticketfrei
# create folder for socket
sudo mkdir /var/run/ticketfrei
sudo chown -R www-data:www-data /var/run/ticketfrei
sudo -s
echo "mkdir /var/run/ticketfrei" >> /etc/rc.local
echo "chown -R www-data:www-data /var/run/ticketfrei" >> /etc/rc.local
echo "service ticketfrei-web restart" >> /etc/rc.local
exit
# change /etc/aliases permissions to be able to receive reports per mail
sudo chown root:www-data /etc/aliases
sudo chmod 664 /etc/aliases
@ -187,17 +180,6 @@ sudo systemctl daemon-reload
sudo systemctl start ticketfrei-backend.service
```
### Backup
For automated backups, you need to backup these files:
* `/var/ticketfrei/db.sqlite`
* `/srv/ticketfrei/config.toml`
* `/etc/aliases`
You can find an example how to do this with borgbackup in the deployment
folder. Adjust it to your needs.
### Logs
There are several logfiles which you can look at:
@ -267,113 +249,3 @@ sudo chown $USER:$USER -R /var/log/ticketfrei
./frontend.py & ./backend.py &
```
# Project History
## Version 1
- more of less hacked together during a mate-fueled weekend
- backend-only, twitter & mastodon
- just a script, which crawled & retweeted tweets, if they match a whitelist & blocklist
- whitelist & blocklist were just 2 files
## Version 2
Reasons for the rewrite:
- user management: Users should be able to run a Ticketfrei bot in their city
- without needing a server, without needing command line skills
- more networks; not only Twitter & Mastodon, also Email & Telegram
2 processes: backend & frontend.
The two Processes talk via a database.
The two Processes have separate log files.
Both processes take some config values from config.toml.
### Backend
The Backend takes care of crawling & spreading the reports.
backend.py:
- main loop which does the crawling & posting.
- loops through all cities in the database
- per city it tries all of the networks/bots:
- per network/bot it runs the crawl()-function to ask the social network for new reports
- then it checks whether the report is appropriate
- if yes, it posts the report via all networks/bots, which belong to the city.
config.py: imports config values
- Imports values from config.toml
- If there is no config file it tries to use environment variables,
- Apart from that it uses the default values.
bot.py: bot parent Class
- just the absolute minimum what a bot needs to be able to do: crawl + post
- is never instantiated, only inherited from
report.py: report Class
- defines how reports are supposed to look like
active_bots/mailbot.py as an example for how a network/bot works
- crawl():
- mails arrive at an mbox file through exim4
- the bot checks whether they are new
- the bot generates a report object from the mail and returns it to the backend.py-loop
- post():
- asks the database for the list of mails which want to receive reports for this city
- sends the report.text to those mail addresses
### Frontend
the architecture of the frontend is loosely oriented off [Model View
Controller](https://blog.codinghorror.com/understanding-model-view-controller/).
user.py (Model)
- high-level interface to talk to the database
- database calls; almost all values in the database are specific to a city/user
- user.py is also a Class for frontend web authentication
- user.py keeps the user-id, through which the frontend tracks authentication
db.py (Model)
- DB-Layout; creates the database if it doesn't exist yet.
- holds some database calls which are not city-specific.
frontend.py (Controller): bottle web application
- handles POST/GET requests
- talks to the database through user.py
- everyone can look at the pages, and register
- but only authenticated users can login and change settings
session.py: User Authentication
- takes care of session cookies and "403 unauthenticated" error messages
sendmail.py: helper script to send mails
- sends all mails the frontend, backend, and bots need to send
static/
- css, images, javascript for the login form etc.
template/ (view)
- base for the HTML generation, uses the bottle-template-framework
- wrapper.tpl is the base template for every other template
### active_bots: how to implement a new network
If you want to write a new bot, e.g. a Wire-Bot, you have to take these steps:
- look for a python-library which can talk to Wire
- the city/users have to provide authentication details; this needs a form in
the settings
- depending on the network either a password, a token, or an implementation
of the OAuth login flow
- the backend needs to crawl messages from the network, & post reports to the
network
Files you need to change:
1. active_bots/wire.py - crawl & post functions
2. settings.tpl - form to authenticate to the network & possible network specific settings.
3. frontend.py - routes for the forms you added to settings.tpl
4. db.py - database layout, to store the account credentials/tokens, and to save which message you have last seen
5. user.py - database calls to get or set values

View File

@ -10,7 +10,7 @@ from bot import Bot
from config import config
from db import db
logger = logging.getLogger("main")
logger = logging.getLogger(__name__)
class Mailbot(Bot):
@ -58,16 +58,30 @@ def make_report(msg, user):
date = get_date_from_header(msg['Date'])
author = msg['From'] # get mail author from email header
for part in msg.walk():
if part.get_content_type() == 'text/plain':
text = part.get_payload()
elif part.get_content_type() == 'text/html':
text = re.sub(r'<[^>]*>', '', msg.get_payload())
try:
post = report.Report(author, "mail", text, None, date)
except UnboundLocalError:
logger.error('No suitable message body')
return
if msg.is_multipart():
text = []
for part in msg.get_payload():
if part.get_content_type() == "text":
text.append(part.get_payload())
elif part.get_content_type() == "application/pgp-signature":
pass # ignore PGP signatures
elif part.get_content_type() == "multipart/mixed":
for p in part:
if isinstance(p, str):
text.append(p)
elif p.get_content_type() == "text":
text.append(part.get_payload())
else:
logger.error("unknown MIMEtype: " +
p.get_content_type())
else:
logger.error("unknown MIMEtype: " +
part.get_content_type())
text = '\n'.join(text)
else:
text = msg.get_payload()
post = report.Report(author, "mail", text, None, date)
user.save_seen_mail(date)
return post

View File

@ -2,12 +2,12 @@
from bot import Bot
import logging
import mastodon
from mastodon import Mastodon, MastodonServerError
import re
from report import Report
logger = logging.getLogger("main")
logger = logging.getLogger(__name__)
class MastodonBot(Bot):
@ -19,93 +19,42 @@ class MastodonBot(Bot):
"""
mentions = []
try:
m = mastodon.Mastodon(*user.get_masto_credentials())
m = Mastodon(*user.get_masto_credentials())
except TypeError:
# No Mastodon Credentials in database.
# logger.error("No Mastodon Credentials in database.", exc_info=True)
return mentions
try:
notifications = m.notifications()
except mastodon.MastodonNetworkError:
logger.error("Mastodon Network Error.")
return mentions
except mastodon.MastodonAPIError:
try:
logger.error("Mastodon API Error: " + m.instance()['urls']['streaming_api'] + ", city: " + str(user.uid))
except mastodon.MastodonServerError:
logger.error("Mastodon Server Error 500, can't get instance.")
except mastodon.MastodonVersionError:
logger.error("Mastodon Server Error 500, server version too low.")
return mentions
except mastodon.MastodonInternalServerError:
try:
logger.error("Mastodon Error: 500. Server: " + m.instance()['urls']['streaming_api'])
except mastodon.MastodonServerError:
logger.error("Mastodon Server Error 500, can't get instance.")
except mastodon.MastodonVersionError:
logger.error("Mastodon Server Error 500, server version too low.")
return mentions
except mastodon.MastodonBadGatewayError:
try:
logger.error("Mastodon Error: 502. Server: " + m.instance()['urls']['streaming_api'])
except mastodon.MastodonServerError:
logger.error("Mastodon Server Error 502, can't get instance.")
except mastodon.MastodonVersionError:
logger.error("Mastodon Server Error 502, server version too low.")
return mentions
except mastodon.MastodonServiceUnavailableError:
try:
logger.error("Mastodon Error: 503. Server: " + m.instance()['urls']['streaming_api'])
except mastodon.MastodonServerError:
logger.error("Mastodon Server Error 503, can't get instance.")
except mastodon.MastodonVersionError:
logger.error("Mastodon Server Error 503, server version too low.")
return mentions
except mastodon.MastodonGatewayTimeoutError:
try:
logger.error("Mastodon Error: 504. Server: " + m.instance()['urls']['streaming_api'])
except mastodon.MastodonServerError:
logger.error("Mastodon Server Error 504, can't get instance.")
except mastodon.MastodonVersionError:
logger.error("Mastodon Server Error 504, server version too low.")
return mentions
except mastodon.MastodonServerError:
try:
logger.error("Unknown Mastodon Server Error. Server: " + m.instance()['urls']['streaming_api'], exc_info=True)
except mastodon.MastodonServerError:
logger.error("Unknown Mastodon Server Error.", exc_info=True)
except mastodon.MastodonVersionError:
logger.error("Unknown Mastodon Server Error.", exc_info=True)
except MastodonServerError:
logger.error("Unknown Mastodon API Error: 502")
return mentions
for status in notifications:
try:
if (status['type'] == 'mention' and
if (status['type'] == 'mention' and
not user.toot_is_seen(status['status']['uri'])):
# save state
user.toot_witness(status['status']['uri'])
# add mention to mentions
text = re.sub(r'<[^>]*>', '', status['status']['content'])
text = re.sub(
"(?<=^|(?<=[^a-zA-Z0-9-_.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
"", text)
if status['status']['visibility'] == 'public':
mentions.append(Report(status['account']['acct'],
self,
text,
status['status']['id'],
status['status']['created_at']))
else:
mentions.append(Report(status['account']['acct'],
'mastodonPrivate',
text,
status['status']['id'],
status['status']['created_at']))
except TypeError:
pass
# save state
user.toot_witness(status['status']['uri'])
# add mention to mentions
text = re.sub(r'<[^>]*>', '', status['status']['content'])
text = re.sub(
"(?<=^|(?<=[^a-zA-Z0-9-_.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
"", text)
if status['status']['visibility'] == 'public':
mentions.append(Report(status['account']['acct'],
self,
text,
status['status']['id'],
status['status']['created_at']))
else:
mentions.append(Report(status['account']['acct'],
'mastodonPrivate',
text,
status['status']['id'],
status['status']['created_at']))
return mentions
def post(self, user, report):
try:
m = mastodon.Mastodon(*user.get_masto_credentials())
m = Mastodon(*user.get_masto_credentials())
except TypeError:
return # no mastodon account for this user.
if report.source == self:

View File

@ -3,7 +3,8 @@ import logging
from report import Report
from twx.botapi import TelegramBot as Telegram
logger = logging.getLogger("main")
logger = logging.getLogger(__name__)
class TelegramBot(Bot):
@ -12,10 +13,9 @@ class TelegramBot(Bot):
seen_tg = user.get_seen_tg()
try:
updates = tb.get_updates(offset=seen_tg + 1,
allowed_updates="message",
timeout=5).wait()
allowed_updates="message").wait()
except TypeError:
updates = tb.get_updates(timeout=5).wait()
updates = tb.get_updates().wait()
reports = []
if updates == None:
return reports
@ -23,7 +23,6 @@ class TelegramBot(Bot):
# return when telegram returns an error code
if update in [303, 404, 420, 500, 502]:
return reports
# log unusual telegram error messages
if isinstance(update, int):
try:
logger.error("City " + str(user.uid) +
@ -32,25 +31,13 @@ class TelegramBot(Bot):
except TypeError:
logger.error("Unknown Telegram error code: " + str(update))
return reports
# save the last message, so it doesn't get crawled again
user.save_seen_tg(update.update_id)
# skip if message is None
if update.message is None:
continue
# complain if message is a photo
if update.message.photo is not None:
if update.message.photo:
tb.send_message(
update.message.sender.id,
"Sending Photos is not supported for privacy reasons. Can "
"you describe it as text instead?")
continue
# complain if message is a media file
if update.message.text is None:
tb.send_message(
update.message.sender.id,
"We only support text reporting for privacy reasons. Can "
"you describe it as text instead?")
continue
if update.message.text.lower() == "/start":
user.add_telegram_subscribers(update.message.sender.id)
tb.send_message(

74
active_bots/twitterDMs.py Normal file
View File

@ -0,0 +1,74 @@
#!/usr/bin/env python3
import logging
import tweepy
import re
import requests
import report
from time import time
from bot import Bot
logger = logging.getLogger(__name__)
class TwitterDMListener(Bot):
def get_api(self, user):
keys = user.get_twitter_credentials()
auth = tweepy.OAuthHandler(consumer_key=keys[0],
consumer_secret=keys[1])
auth.set_access_token(keys[2], # access_token_key
keys[3]) # access_token_secret
return tweepy.API(auth, wait_on_rate_limit=True)
def crawl(self, user):
"""
crawls all Tweets which mention the bot from the twitter rest API.
:return: reports: (list of report.Report objects)
"""
reports = []
try:
if user.get_last_twitter_request() + 60 > time():
return reports
except TypeError:
user.set_last_twitter_request(time())
try:
api = self.get_api(user)
except TypeError:
return reports # no twitter account for this user.
last_dm = user.get_seen_dm()
try:
if last_dm is None:
mentions = api.direct_messages()
else:
mentions = api.direct_messages(since_id=last_dm[0])
user.set_last_twitter_request(time())
for status in mentions:
text = re.sub(
"(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
"", status.text)
reports.append(report.Report(status.author.screen_name,
"twitterDM",
text,
status.id,
status.created_at))
user.save_seen_dm(last_dm)
return reports
except tweepy.RateLimitError:
logger.error("Twitter API Error: Rate Limit Exceeded",
exc_info=True)
# :todo implement rate limiting
except requests.exceptions.ConnectionError:
logger.error("Twitter API Error: Bad Connection", exc_info=True)
except tweepy.TweepError as terror:
# Waiting for https://github.com/tweepy/tweepy/pull/1109 to get
# merged, so direct messages work again
if terror.api_code == 34:
return reports
logger.error("Twitter API Error: General Error", exc_info=True)
return reports
def post(self, user, report):
pass

View File

@ -9,7 +9,7 @@ import report
from bot import Bot
logger = logging.getLogger("main")
logger = logging.getLogger(__name__)
class TwitterBot(Bot):
@ -67,13 +67,13 @@ class TwitterBot(Bot):
except requests.exceptions.ConnectionError:
logger.error("Twitter API Error: Bad Connection", exc_info=True)
except tweepy.TweepError:
logger.error("Twitter API Error: General Error. User: " + str(user.uid), exc_info=True)
logger.error("Twitter API Error: General Error", exc_info=True)
return []
def post(self, user, report):
try:
api = self.get_api(user)
except TypeError:
except IndexError:
return # no twitter account for this user.
try:
if report.source == self:

View File

@ -5,7 +5,7 @@ from config import config
from db import db
import logging
from sendmail import sendmail
from time import sleep
def shutdown():
try:
@ -16,14 +16,11 @@ def shutdown():
if __name__ == '__main__':
logger = logging.getLogger("main")
logger.setLevel(logging.DEBUG)
logger = logging.getLogger()
fh = logging.FileHandler('/var/log/ticketfrei/backend.log')
formatter = logging.Formatter('%(asctime)s %(levelname)8s: %(message)s')
fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
logger.info("Backend Daemon was started...")
bots = []
for ActiveBot in active_bots.__dict__.values():
@ -34,14 +31,12 @@ if __name__ == '__main__':
while True:
for user in db.active_users:
for bot in bots:
sleep(1)
reports = bot.crawl(user)
for status in reports:
if not user.is_appropriate(status):
logger.info("Inaproppriate message: %d %s %s" % (user.uid, status.author, status.text))
continue
for bot2 in bots:
sleep(1)
bot2.post(user, status)
logger.info("Resent: %d %s %s" % (user.uid, status.author, status.text))
except Exception:

19
bots/mail/settings.tpl Normal file
View File

@ -0,0 +1,19 @@
<div>
<h2>Edit your mail subscription page</h2>
<p>
There is also a page where users can subscribe to mail notifications:
<a href="/city/mail/{{city}}" target="_blank">Ticketfrei {{city}}</a>.
You can change what your users will read there, and adjust it to your
needs.
</p>
<p>
So this is the default text we suggest:
</p>
<form action="/settings/mail_md" method="post">
<textarea id="mail_md" rows="20" cols="70" name="mail_md" wrap="physical">{{mail_md}}</textarea>
<input name='csrf' value='{{csrf}}' type='hidden' />
<input name='confirm' value='Save' type='submit'/>
</form>
</div>

View File

@ -0,0 +1,51 @@
<section>
<h2>Log in with Mastodon</h2>
<form action="/login/mastodon" method='post'>
<label for="email">E-Mail of your Mastodon-Account</label>
<input type="text" placeholder="Enter Email" name="email" id="email" required>
<label for="pass">Mastodon Password</label>
<input type="password" placeholder="Enter Password" name="pass" id="pass" required>
<label>Mastodon instance:
<input type='text' name='instance_url' list='instances' placeholder='social.example.net'/>
</label>
<datalist id='instances'>
<option value=''>
<option value='anticapitalist.party'>
<option value='awoo.space'>
<option value='cybre.space'>
<option value='mastodon.social'>
<option value='glitch.social'>
<option value='botsin.space'>
<option value='witches.town'>
<option value='social.wxcafe.net'>
<option value='monsterpit.net'>
<option value='mastodon.xyz'>
<option value='a.weirder.earth'>
<option value='chitter.xyz'>
<option value='sins.center'>
<option value='dev.glitch.social'>
<option value='computerfairi.es'>
<option value='niu.moe'>
<option value='icosahedron.website'>
<option value='hostux.social'>
<option value='hyenas.space'>
<option value='instance.business'>
<option value='mastodon.sdf.org'>
<option value='pawoo.net'>
<option value='pouet.it'>
<option value='scalie.business'>
<option value='sleeping.town'>
<option value='social.koyu.space'>
<option value='sunshinegardens.org'>
<option value='vcity.network'>
<option value='octodon.social'>
<option value='soc.ialis.me'>
</datalist>
<input name='csrf' value='{{csrf}}' type='hidden' />
<input name='confirm' value='Log in' type='submit'/>
</form>
</section>

View File

@ -0,0 +1,23 @@
<%
# todo: hide this part, if there is already a telegram bot connected.
%>
<div>
<h2>Connect with Telegram</h2>
<p>
If you have a Telegram account, you can register a bot there. Just
write to @botfather. There are detailed instructions on
<a href="https://botsfortelegram.com/project/the-bot-father/" target="_blank">
Bots for Telegram</a>.
</p>
<p>
The botfather will give you an API key - with the API key, Ticketfrei
can use the Telegram bot. Enter it here:
</p>
<form action="/settings/telegram" method="post">
<input type="text" name="apikey" placeholder="Telegram bot API key" id="apikey">
<input name='csrf' value='{{csrf}}' type='hidden' />
<input name='confirm' value='Login with Telegram' type='submit'/>
</form>
</div>

10
bots/twitter/settings.tpl Normal file
View File

@ -0,0 +1,10 @@
<a class='button' style="padding: 1.5em;" href="/login/twitter">
<picture>
<source type='image/webp' sizes='20px' srcset="/static-cb/1517673283/twitter-20.webp 20w,/static-cb/1517673283/twitter-40.webp 40w,/static-cb/1517673283/twitter-80.webp 80w,"/>
<source type='image/png' sizes='20px' srcset="/static-cb/1517673283/twitter-20.png 20w,/static-cb/1517673283/twitter-40.png 40w,/static-cb/1517673283/twitter-80.png 80w,"/>
<img src="https://patriciaannbridewell.files.wordpress.com/2014/04/official-twitter-logo-tile.png" alt="" />
</picture>
Log in with Twitter
</a>

View File

24
db.py
View File

@ -1,13 +1,12 @@
from config import config
import jwt
import logging
from os import urandom, system
from os import urandom
from pylibscrypt import scrypt_mcf
import sqlite3
from time import sleep, time
logger = logging.getLogger("main")
logger = logging.getLogger(__name__)
class DB(object):
@ -20,20 +19,7 @@ class DB(object):
return self.cur.execute(*args, **kwargs)
def commit(self):
start_time = time()
while 1:
try:
self.conn.commit()
break
except sqlite3.OperationalError as error:
# another thread may be writing, give it a chance to finish
sleep(0.5)
logger.exception()
if time() - start_time > 5:
# if it takes this long, something is wrong
system("rcctl restart frontend_daemon")
logger.warning("frontend_daemon is getting restarted")
self.conn.commit()
self.conn.commit()
def close(self):
self.conn.close()
@ -259,10 +245,6 @@ u\d\d?"""
uid = json['uid']
with open("/etc/aliases", "a+") as f:
f.write(city + ": " + config["mail"]["mbox_user"] + "\n")
try:
os.system("newaliases")
except:
logger.exception()
self.execute("INSERT INTO email (user_id, email) VALUES(?, ?);",
(uid, json['email']))
self.execute("""INSERT INTO telegram_accounts (user_id, apikey,

View File

@ -1,15 +0,0 @@
#!/bin/ksh
daemon="/usr/local/bin/python3 /srv/ticketfrei/backend.py"
daemon_user="root"
. /etc/rc.d/rc.subr
rc_bg=YES
rc_reload=NO
rc_start() {
rc_exec "cd /srv/ticketfrei; /usr/bin/nice -n15 ${daemon} ${daemon_flags}"
}
rc_cmd $1

View File

@ -1,15 +0,0 @@
#!/bin/ksh
. /etc/borg-env
export BORG_REPO=nathan@nephilim:repositories-borg/ticketfrei
export BORG_RSH="ssh \
-o TCPKeepAlive=no \
-o ServerAliveInterval=15 \
-o ServerAliveCountMax=10 \
-o Compression=no"
rcctl stop backend_daemon
rcctl stop frontend_daemon
/usr/local/bin/borg create --stats ::'backup{now:%Y%m%d-%H%M}' /srv/ticketfrei /var/ticketfrei /etc
rcctl start backend_daemon
rcctl start frontend_daemon

View File

@ -0,0 +1,31 @@
server {
listen 443 ssl;
server_name example.org;
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/example.org_access.log;
error_log /var/log/nginx/example.org_error.log;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
include uwsgi_params;
uwsgi_pass unix:///var/run/ticketfrei/ticketfrei.sock;
}
location /.well-known/acme-challenge {
root /var/www/acme;
}
}
server {
listen 80;
listen [::]:80;
server_name example.org;
return 301 https://$server_name$request_uri;
}

View File

@ -1,15 +0,0 @@
#!/bin/ksh
daemon="/usr/local/bin/python3 /srv/ticketfrei/frontend.py"
daemon_user="frontend"
. /etc/rc.d/rc.subr
rc_bg=YES
rc_reload=NO
rc_start() {
rc_exec "env > /tmp/envars; cd /srv/ticketfrei; ${daemon} ${daemon_flags}"
}
rc_cmd $1

View File

@ -0,0 +1,17 @@
[Unit]
Description=Ticketfrei Backend
After=syslog.target network.target
[Service]
WorkingDirectory=/srv/ticketfrei
ExecStart=/srv/ticketfrei/bin/python3 backend.py
# Requires systemd version 211 or newer
#RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=simple
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,17 @@
[Unit]
Description=Ticketfrei Web Application
After=syslog.target network.target
[Service]
WorkingDirectory=/srv/ticketfrei
ExecStart=/usr/bin/uwsgi --ini /srv/ticketfrei/deployment/uwsgi.ini
# Requires systemd version 211 or newer
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3
import bottle
from os import listdir, path
from bottle import get, post, redirect, request, response, view
from config import config
from db import db

View File

@ -1,9 +0,0 @@
tweepy
pytoml
Mastodon.py
bottle
pyjwt
pylibscrypt
Markdown
twx
gitpython

View File

@ -8,7 +8,7 @@ import smtplib
from socket import getfqdn
logger = logging.getLogger("main")
logger = logging.getLogger(__name__)
def sendmail(to, subject, city=None, body=''):

160
sqlalchemy.py Normal file
View File

@ -0,0 +1,160 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.engine import create_engine
from sqlalchemy.schema import Table, Column, ForeignKey, UniqueConstraint
from sqlalchemy.types import Integer, String, DateTime, BLOB, REAL
#from sqlalchemy.orm import relationship, backref
# Get Base class where table objects inherit from
Base = declarative_base()
engine = create_engine("sqlite:///:memory:")
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
passhash = Column(String)
enabled = Column(Integer, default=1)
def __repr__(self):
return '<User(id=%s, passhash=%s, enabled=%s)>' % (
self.id, self.passhash, self.enabled)
class Email(Base):
__tablename__ = 'email'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
email = Column(String)
# necessary? https://docs.sqlalchemy.org/en/13/orm/tutorial.html#building-a-relationship
# user = relationship(User, back_populates='email')
# necessary?
# User.email = relationship('email', order_by=Email.id, back_populates='user')
class TriggerPatterns(Base):
__tablename__ = 'triggerpatterns'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
patterns = Column(String)
class BadWords(Base):
__tablename__ = 'badwords'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
words = Column(String)
class MastodonInstances(Base):
__tablename__ = 'mastodon_instances'
id = Column(Integer, primary_key=True)
instance = Column(String)
client_id = Column(String)
client_secret = Column(String)
class MastodonAccounts(Base):
__tablename__ = 'mastodon_accounts'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
access_token = Column(String)
instance_id = Column(Integer, ForeignKey('mastodon_instances.id'))
active = Column(Integer) # could be default=1
class SeenToots(Base):
__tablename__ = 'seen_toots'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
toot_uri = Column(String)
class SeenTelegrams(Base):
__tablename__ = 'seen_telegrams'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
tg_id = Column(Integer)
class TwitterRequestTokens(Base):
__tablename__ = 'twitter_request_tokens'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
request_token = Column(String)
request_token_secret = Column(String)
class TwitterAccounts(Base):
__tablename__ = 'twitter_accounts'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
client_id = Column(String)
client_secret = Column(String)
active = Column(Integer) # could be default=1
class TelegramAccounts(Base):
__tablename__ = 'telegram_accounts'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
apikey = Column(String)
active = Column(Integer) # could be default=1
class SeenTweets(Base):
__tablename__ = 'seen_tweets'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
tweet_id = Column(String)
class SeenDMs(Base):
__tablename__ = 'seen_dms'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
twitter_accounts = Column(Integer, ForeignKey('twitter_accounts.id'))
message_id = Column(String)
class TelegramSubscribers(Base):
__tablename__ = 'telegram_subscribers'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
subscriber_id = Column(Integer)
# how to get this to work?
# https://docs.sqlalchemy.org/en/13/dialects/sqlite.html#on-conflict-support-for-constraints
# UniqueConstraint('id', 'subscriber_id', sqlite_on_conflict='IGNORE')
class Mailinglist(Base):
__tablename__ = 'mailinglist'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
email = Column(String)
# It would be good to have a Unique on conflict ignore here, just as in
# telegram_subscribers.
class SeenMail(Base):
__tablename__ = 'seen_mail'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
mail_date = Column(REAL) # could be Datetime, too
class TwitterLastRequest(Base):
__tablename__ = 'twitter_last_request'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
date = Column(Integer)
class Cities(Base):
__tablename__ = 'cities'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.id'))
city = Column(String)
markdown = Column(String)
mail_md = Column(String)
masto_link = Column(String)
twit_link = Column(String)
# how to get this to work?
# https://docs.sqlalchemy.org/en/13/dialects/sqlite.html#on-conflict-support-for-constraints
# UniqueConstraint('id', 'city', sqlite_on_conflict='IGNORE')
class Secret(Base):
__tablename__ = 'secret'
id = Column(Integer, primary_key=True)
secret = Column(BLOB)
Base.metadata.create_all(engine)

View File

@ -7,86 +7,15 @@
<div id="enablebutton" style="float: right; padding: 2em;" color="red">Enable</div>
% end
<a class='button' style="padding: 1.5em;" href="/login/twitter">
<picture>
<source type='image/webp' sizes='20px' srcset="/static-cb/1517673283/twitter-20.webp 20w,/static-cb/1517673283/twitter-40.webp 40w,/static-cb/1517673283/twitter-80.webp 80w,"/>
<source type='image/png' sizes='20px' srcset="/static-cb/1517673283/twitter-20.png 20w,/static-cb/1517673283/twitter-40.png 40w,/static-cb/1517673283/twitter-80.png 80w,"/>
<img src="https://patriciaannbridewell.files.wordpress.com/2014/04/official-twitter-logo-tile.png" alt="" />
</picture>
Log in with Twitter
</a>
<section>
<h2>Log in with Mastodon</h2>
<form action="/login/mastodon" method='post'>
<label for="email">E-Mail of your Mastodon-Account</label>
<input type="text" placeholder="Enter Email" name="email" id="email" required>
<label for="pass">Mastodon Password</label>
<input type="password" placeholder="Enter Password" name="pass" id="pass" required>
<label>Mastodon instance:
<input type='text' name='instance_url' list='instances' placeholder='social.example.net'/>
</label>
<datalist id='instances'>
<option value=''>
<option value='anticapitalist.party'>
<option value='awoo.space'>
<option value='cybre.space'>
<option value='mastodon.social'>
<option value='glitch.social'>
<option value='botsin.space'>
<option value='witches.town'>
<option value='social.wxcafe.net'>
<option value='monsterpit.net'>
<option value='mastodon.xyz'>
<option value='a.weirder.earth'>
<option value='chitter.xyz'>
<option value='sins.center'>
<option value='dev.glitch.social'>
<option value='computerfairi.es'>
<option value='niu.moe'>
<option value='icosahedron.website'>
<option value='hostux.social'>
<option value='hyenas.space'>
<option value='instance.business'>
<option value='mastodon.sdf.org'>
<option value='pawoo.net'>
<option value='pouet.it'>
<option value='scalie.business'>
<option value='sleeping.town'>
<option value='social.koyu.space'>
<option value='sunshinegardens.org'>
<option value='vcity.network'>
<option value='octodon.social'>
<option value='soc.ialis.me'>
</datalist>
<input name='csrf' value='{{csrf}}' type='hidden' />
<input name='confirm' value='Log in' type='submit'/>
</form>
</section>
<%
# todo: hide this part, if there is already a telegram bot connected.
# import all the settings templates from bots/*/settings.tpl
import os
bots = os.listdir('bots')
for bot in bots:
include('bots/' + bot + '/settings.tpl', csrf=csrf, city=city)
end
%>
<div>
<h2>Connect with Telegram</h2>
<p>
If you have a Telegram account, you can register a bot there. Just
write to @botfather. There are detailed instructions on
<a href="https://botsfortelegram.com/project/the-bot-father/" target="_blank">
Bots for Telegram</a>.
</p>
<p>
The botfather will give you an API key - with the API key, Ticketfrei
can use the Telegram bot. Enter it here:
</p>
<form action="/settings/telegram" method="post">
<input type="text" name="apikey" placeholder="Telegram bot API key" id="apikey">
<input name='csrf' value='{{csrf}}' type='hidden' />
<input name='confirm' value='Login with Telegram' type='submit'/>
</form>
</div>
<div>
<h2>Edit your city page</h2>
@ -113,24 +42,6 @@
</form>
</div>
<div>
<h2>Edit your mail subscription page</h2>
<p>
There is also a page where users can subscribe to mail notifications:
<a href="/city/mail/{{city}}" target="_blank">Ticketfrei {{city}}</a>.
You can change what your users will read there, and adjust it to your
needs.
</p>
<p>
So this is the default text we suggest:
</p>
<form action="/settings/mail_md" method="post">
<textarea id="mail_md" rows="20" cols="70" name="mail_md" wrap="physical">{{mail_md}}</textarea>
<input name='csrf' value='{{csrf}}' type='hidden' />
<input name='confirm' value='Save' type='submit'/>
</form>
</div>
<div>
<h2>Edit your trigger patterns</h2>
<p>

98
user.py
View File

@ -5,9 +5,7 @@ import jwt
from mastodon import Mastodon
from pylibscrypt import scrypt_mcf, scrypt_mcf_check
from os import urandom
import logging
logger = logging.getLogger("main")
class User(object):
def __init__(self, uid):
@ -76,7 +74,6 @@ class User(object):
break
else:
# no pattern matched
logger.error("Message didn't trigger goodlist: " + report.text)
return False
default_badwords = """
bitch
@ -96,15 +93,12 @@ schlitz
db.execute("SELECT words FROM badwords WHERE user_id=?;",
(self.uid, ))
badwords = db.cur.fetchone()
for word in report.text.lower().split():
if word in badwords[0].splitlines():
logger.error("Word " + word + " triggered the spam filter on message: " + report.text)
for word in report.text.lower().splitlines():
if word in badwords:
return False
for word in report.text.lower().split():
if word in default_badwords.splitlines():
logger.error("Word " + word + " triggered the spam filter on message: " + report.text)
for word in default_badwords.splitlines():
if word in badwords:
return False
logger.info("Valid report: " + report.text + " | username: " + report.author)
return True
def get_last_twitter_request(self):
@ -118,16 +112,16 @@ schlitz
db.commit()
def get_telegram_credentials(self):
db.execute("""SELECT apikey
FROM telegram_accounts
db.execute("""SELECT apikey
FROM telegram_accounts
WHERE user_id = ? AND active = 1;""",
(self.uid,))
row = db.cur.fetchone()
return row[0]
def get_telegram_subscribers(self):
db.execute("""SELECT subscriber_id
FROM telegram_subscribers
db.execute("""SELECT subscriber_id
FROM telegram_subscribers
WHERE user_id = ?;""",
(self.uid,))
rows = db.cur.fetchall()
@ -140,21 +134,21 @@ schlitz
db.commit()
def remove_telegram_subscribers(self, subscriber_id):
db.execute("""DELETE
FROM telegram_subscribers
db.execute("""DELETE
FROM telegram_subscribers
WHERE user_id = ?
AND subscriber_id = ?;""",
(self.uid, subscriber_id))
db.commit()
def get_masto_credentials(self):
db.execute("""SELECT access_token, instance_id
FROM mastodon_accounts
db.execute("""SELECT access_token, instance_id
FROM mastodon_accounts
WHERE user_id = ? AND active = 1;""",
(self.uid,))
row = db.cur.fetchone()
db.execute("""SELECT instance, client_id, client_secret
FROM mastodon_instances
db.execute("""SELECT instance, client_id, client_secret
FROM mastodon_instances
WHERE id = ?;""",
(row[1],))
instance = db.cur.fetchone()
@ -272,11 +266,11 @@ schlitz
db.commit()
def get_request_token(self):
db.execute("""SELECT request_token, request_token_secret
FROM twitter_request_tokens
db.execute("""SELECT request_token, request_token_secret
FROM twitter_request_tokens
WHERE user_id = ?;""", (self.uid,))
request_token = db.cur.fetchone()
db.execute("""DELETE FROM twitter_request_tokens
db.execute("""DELETE FROM twitter_request_tokens
WHERE user_id = ?;""", (self.uid,))
db.commit()
return {"oauth_token": request_token[0],
@ -287,8 +281,6 @@ schlitz
user_id, client_id, client_secret
) VALUES(?, ?, ?);""",
(self.uid, access_token, access_token_secret))
db.execute("""INSERT INTO seen_tweets(user_id, tweet_id) VALUES (?, ?);""",
(self.uid, 0))
db.commit()
def get_twitter_token(self):
@ -309,8 +301,8 @@ schlitz
db.commit()
def get_mastodon_app_keys(self, instance):
db.execute("""SELECT client_id, client_secret
FROM mastodon_instances
db.execute("""SELECT client_id, client_secret
FROM mastodon_instances
WHERE instance = ?;""", (instance,))
try:
row = db.cur.fetchone()
@ -329,8 +321,8 @@ schlitz
return client_id, client_secret
def save_masto_token(self, access_token, instance):
db.execute("""SELECT id
FROM mastodon_instances
db.execute("""SELECT id
FROM mastodon_instances
WHERE instance = ?;""", (instance,))
instance_id = db.cur.fetchone()[0]
db.execute("INSERT INTO mastodon_accounts(user_id, access_token, instance_id, active) "
@ -366,20 +358,20 @@ Schau einfach auf das Profil unseres Bots: """ + twit_link + """
Hat jemand vor kurzem etwas über Kontrolleur\*innen gepostet?
* Wenn ja, dann kauf dir vllt lieber ein Ticket. In Nürnberg
* Wenn ja, dann kauf dir vllt lieber ein Ticket. In Nürnberg
haben wir die Erfahrung gemacht, dass Kontis normalerweile
ungefähr ne Woche aktiv sind, ein paar Stunden am Tag. Wenn es
also in den letzten Stunden einen Bericht gab, pass lieber
ungefähr ne Woche aktiv sind, ein paar Stunden am Tag. Wenn es
also in den letzten Stunden einen Bericht gab, pass lieber
auf.
* Wenn nicht, ist es wahrscheinlich kein Problem :)
Wir können natürlich nicht garantieren, dass es sicher ist,
Wir können natürlich nicht garantieren, dass es sicher ist,
also pass trotzdem auf, wer auf dem Bahnsteig steht.
Aber je mehr Leute mitmachen, desto eher kannst du dir sicher
Aber je mehr Leute mitmachen, desto eher kannst du dir sicher
sein, dass wir sie finden, bevor sie uns finden.
Wenn du immer direkt gewarnt werden willst, kannst du auch die
Benachrichtigungen über E-Mail, Telegram, oder den Mastodon RSS
Benachrichtigungen über E-Mail, Telegram, oder den Mastodon RSS
feed aktivieren. Entweder:
* Gibt hier [deine E-Mail-Adresse an](/city/mail/""" + city + """)
* Subscribe dem Telegram-Bot [@ticketfrei_""" + city + \
@ -387,7 +379,7 @@ feed aktivieren. Entweder:
* oder subscribe dem RSS feed von [""" + city + """](""" + masto_link + \
""".atom?replies=false&boosts=true)
Also, wenn du weniger Glück hast, und der erste bist, der einen
Also, wenn du weniger Glück hast, und der erste bist, der einen
Kontrolleur sieht:
## Was mache ich, wenn ich Kontis sehe?
@ -398,10 +390,10 @@ Ganz einfach, du schreibst es den anderen. Das geht entweder
* über Twitter: [Link zu unserem Profil](""" + twit_link + """)
* über Telegram an [@ticketfrei_""" + city + "_bot](https://t.me/ticketfrei_" \
+ city + """_bot)
* Oder per Mail an [""" + mailinglist + "](mailto:" + mailinglist + """), wenn
* Oder per Mail an [""" + mailinglist + "](mailto:" + mailinglist + """), wenn
ihr kein Social Media benutzen wollt.
Schreibe einfach einen Toot oder einen Tweet, der den Bot
Schreibe einfach einen Toot oder einen Tweet, der den Bot
mentioned, und gib an
* Wo du die Kontis gesehen hast
@ -413,11 +405,11 @@ Zum Beispiel so:
![A toot ready to be shared](https://github.com/b3yond/ticketfrei/raw/stable1/guides/toot_screenshot.png)
Der Bot wird die Nachricht dann weiterverbreiten, auch zu den
Der Bot wird die Nachricht dann weiterverbreiten, auch zu den
anderen Netzwerken.
Dann können andere Leute das lesen und sicher vor Kontis sein.
Danke, dass du mithilfst, öffentlichen Verkehr für alle
Danke, dass du mithilfst, öffentlichen Verkehr für alle
sicherzustellen!
## Kann ich darauf vertrauen, was random stranger from the Internet mir da erzählen?
@ -426,31 +418,31 @@ Aber natürlich! Wir haben Katzenbilder!
![Katzenbilder!](https://lorempixel.com/550/300/cats)
Glaubt besser nicht, wenn jemand postet, dass die Luft da und
Glaubt besser nicht, wenn jemand postet, dass die Luft da und
da gerade rein ist.
Das ist vielleicht sogar gut gemeint - aber klar könnte die
Das ist vielleicht sogar gut gemeint - aber klar könnte die
VAG sich hinsetzen und einfach lauter Falschmeldungen posten.
Aber Falschmeldungen darüber, dass gerade Kontis i-wo unterwegs
Aber Falschmeldungen darüber, dass gerade Kontis i-wo unterwegs
sind?
Das macht keinen Sinn.
Im schlimmsten Fall kauft jmd mal eine Fahrkarte mehr - aber
Das macht keinen Sinn.
Im schlimmsten Fall kauft jmd mal eine Fahrkarte mehr - aber
kann sonst immer schwarz fahren.
Also ja - es macht Sinn, uns zu vertrauen, wenn wir sagen, wo
Also ja - es macht Sinn, uns zu vertrauen, wenn wir sagen, wo
gerade Kontis sind.
## Was ist Mastodon und warum sollte ich es benutzen?
Mastodon ist ein dezentrales soziales Netzwerk - so wie
Mastodon ist ein dezentrales soziales Netzwerk - so wie
Twitter, nur ohne Monopol und Zentralismus.
Ihr könnt Kurznachrichten (Toots) über alles mögliche
Ihr könnt Kurznachrichten (Toots) über alles mögliche
schreiben, und euch mit anderen austauschen.
Mastodon ist Open Source, Privatsphäre-freundlich und relativ
Mastodon ist Open Source, Privatsphäre-freundlich und relativ
sicher vor Zensur.
Um Mastodon zu benutzen, besucht diese Seite:
Um Mastodon zu benutzen, besucht diese Seite:
[https://joinmastodon.org/](https://joinmastodon.org/)
"""
mail_md = """# Immer up-to-date
@ -460,15 +452,15 @@ zu schauen? Kein Problem. Unsere Mail Notifications benachrichtigen dich, wenn
irgendwo Kontis gesehen werden.
Wenn du uns deine E-Mail-Adresse gibst, kriegst du bei jedem Konti-Report eine
Mail. Wenn du eine Mail-App auf dem Handy hast, so wie
Mail. Wenn du eine Mail-App auf dem Handy hast, so wie
[K9Mail](https://k9mail.github.io/), kriegst du sogar eine Push Notification. So
bist du immer Up-to-date über alles, was im Verkehrsnetz passiert.
## Keine Sorge
Wir benutzen deine E-Mail-Adresse selbstverständlich für nichts anderes. Du
Wir benutzen deine E-Mail-Adresse selbstverständlich für nichts anderes. Du
kannst die Benachrichtigungen jederzeit deaktivieren, mit jeder Mail wird ein
unsubscribe-link mitgeschickt.
unsubscribe-link mitgeschickt.
"""
db.execute("""INSERT INTO cities(user_id, city, markdown, mail_md,
masto_link, twit_link) VALUES(?,?,?,?,?,?)""",