Top Level Namespace
- Includes:
- Neo4jBolt
Defined Under Namespace
Modules: Nextcloud, UserRoleHelper Classes: AudioBotRepl, BackgroundRenderer, BitmapFont, DashboardSchema, DumpDatabase, ImageBotRepl, ImportNewsAttic, Integer, InvitationRepl, Main, Neo4jGlobal, Neo4jHelper, NodeBlock, Parser, PixelFont, RandomTag, SchemaRenderer, Script, SetupDatabase, StatsBotRepl, String, Timetable, TimetableRepl
Constant Summary collapse
- DASHBOARD_SERVICE =
ENV['DASHBOARD_SERVICE']
- BIB_JWT_TTL =
60
- BIB_JWT_TTL_EXTRA =
20
- TRESOR_SECOND_FACTOR_TTL =
DEVELOPMENT ? 60 * 15 : 60 * 15
- TRESOR_JWT_TTL =
60
- TRESOR_JWT_TTL_EXTRA =
20
- USER_AGENT_PARSER =
UserAgentParser::Parser.new
- WEEKDAYS =
['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa']
- WEEKDAYS_LONG =
['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag']
- MONTHS =
['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember']
- HOMEWORK_FEEDBACK_STATES =
['good', 'hmmm', 'lost']
- HOMEWORK_FEEDBACK_EMOJIS =
{'good' => '🙂', 'hmmm' => '🤔', 'lost' => '😕'}
- HOURS_FOR_KLASSE =
{}
- TUNNEL =
16
- DEVELOPMENT =
Diese Datei bitte unter credentials.rb speichern und Werte anpassen (bitte keine Credentials in Git committen)
ENV['DEVELOPMENT']
- SCHUL_NAME =
Name der Schule
"Beispielschule"
- SCHUL_NAME_AN_DATIV =
'an der' oder 'am'
"an der"
- SCHUL_ICON =
Schul-Icon
"brand.png"
- DARK_SCHUL_ICON =
"brand.png"
- SCHULLEITUNG_EMAIL =
E-Mail-Adresse der Schulleitung für das Impressum
'schulleitung@beispielschule.de'
- SCHUL_MAIL_DOMAIN =
Mail-Domain für SuS-Adressen
"mail.beispielschule.de"
- SCHUL_MAIL_LOGIN_URL =
Webmail-Login-Seite, SMTP- und IMAP-Host (nur wichtig für E-Mail-Briefe)
"https://mail.beispielmailhoster.de"
- SCHUL_MAIL_LOGIN_SMTP_HOST =
"smtp.beispielmailhoster.de"
- SCHUL_MAIL_LOGIN_IMAP_HOST =
"imap.beispielmailhoster.de"
- USE_MOCK_NAMES =
Bei Bedarf können alle Namen durch falsche Namen ersetzt werden (für Demozwecke)
false
- EXCLUDE_FROM_MOCKIFICATION =
pseudonymisiert werden sollen
[]
- SMTP_SERVER =
SMTP Hostname
'smtp.example.com'
- IMAP_SERVER =
IMAP Hostname
'imap.example.com'
- SMTP_USER =
'dashboard@beispielschule.de'
- SMTP_PASSWORD =
'1234_nein_wirklich'
- SMTP_DOMAIN =
'beispielschule.de'
- SMTP_FROM =
'Dashboard Beispielschule <dashboard@beispielschule.de>'
- DASHBOARD_SUPPORT_EMAIL =
'dashboard@beispielschule.de'
- DATENTRESOR_HOST =
''
- DATENTRESOR_UNLOCKED_FOR =
nil
- DATENTRESOR_JWT_APPKEY =
''
- SMS_GATEWAY_SECRET =
'bitte_ein_zufälliges_secret_generieren'
- SMS_PHONE_NUMBER_PASSPHRASE =
'bitte_ein_zufälliges_secret_generieren'
- DATENTRESOR_HOTLINE =
''
- DATENTRESOR_HOTLINE_MIT_NUMMERN =
''
- ZEUGNIS_USE_MOCK_NAMES =
false
- MAILING_LIST_EMAIL =
Mailing-Liste
DEVELOPMENT ? 'verteiler.dev@mail.beispielschule.de' : 'verteiler@mail.beispielschule.de'
- MAILING_LIST_PASSWORD =
'1234_bitte_generiere_ein_zufälliges_passwort'
- MAILING_LIST_DOMAIN =
'verteiler.beispielschule.de'
- VERTEILER_MAIL_HEADER =
'X-Forwarded-From-Gymnasium-Steglitz'
- VERTEILER_TEST_EMAILS =
["verteiler.test@#{MAILING_LIST_DOMAIN}"]
- VERTEILER_DEVELOPMENT_EMAILS =
['admin@beispielschule.de']
- MAIL_SUPPORT_NAME =
'Mail-Support Beispielschule'
- MAIL_SUPPORT_EMAIL =
'mailsupport@beispielschule.de'
- MAILING_LIST_FORWARDER_ACCOUNTS =
{ '@beispielschule.de' => { :address => SMTP_SERVER, :port => 587, :domain => SMTP_DOMAIN, :user_name => SMTP_USER, :password => SMTP_PASSWORD, :authentication => 'login', :enable_starttls_auto => true } }
- WEBSITE_HOST =
Domain, auf der die Live-Seite läuft
'dashboard.beispielschule.de'
- WEBSITE_MAINTAINER_NAME =
Name für Unterschriften in E-Mails (Mit freundlichen Grüßen…)
'Herr Müller'
- WEBSITE_MAINTAINER_NAME_AKKUSATIV =
'Herrn Müller'
- WEBSITE_MAINTAINER_EMAIL =
'mueller@beispielschule.de'
- VOTING_WEBSITE_URL =
Website mit Voting-System (muss noch veröffentlich werden)
'https://abstimmung.beispielschule.de'
- VOTING_CONTACT_EMAIL =
Ansprechpartner für Wahlverfahren
'admin@beispielschule.de'
- TECHNIK_HILFE_WEBSITE_URL =
Website für Technikhilfe (Chat und Speedtest)
'https://hilfe.beispielschule.de'
- WEB_ROOT =
DEVELOPMENT ? 'http://localhost:8025' : "https://#{WEBSITE_HOST}"
- ROOM_ORDER =
%w(101 102 103 104)
- ENABLE_NEXTCLOUD_SANDBOX =
true
- NEXTCLOUD_SANDBOX_INSTALL_ADMIN_USER =
'dashboard'
- NEXTCLOUD_SANDBOX_INSTALL_ADMIN_PASSWORD =
'hunter2_bitte_etwas_anderes_waehlen'
- NEXTCLOUD_URL =
Das Dashboard benötigt einen Nextcloud-Account, der Admin-Rechte hat
'http://localhost:8024'
- NEXTCLOUD_URL_FROM_RUBY_CONTAINER =
keine Rolle und der Wert sollte derselbe sein wie für NEXTCLOUD_URL
'http://nextcloud'
- NEXTCLOUD_USER =
'dashboard'
- NEXTCLOUD_PASSWORD =
'hunter2_bitte_etwas_anderes_waehlen'
- NEXTCLOUD_DASHBOARD_DATA_DIRECTORY =
NEXTCLOUD_DASHBOARD_DATA_DIRECTORY muss ein absoluter Pfad sein
__NEXTCLOUD_DASHBOARD_DATA_DIRECTORY__
- NEXTCLOUD_WAIT_SECONDS =
__NEXTCLOUD_WAIT_SECONDS__
- NEXTCLOUD_ALL_ACCESS_PASSWORD_BE_CAREFUL =
Das Skript share-nc-folders.rb muss sich als jeder Nutzer in der NextCloud anmelden können. Dazu kann die NC-App »External user authentication« verwendet werden, die fehlgeschlagene Anmeldeversuche an eine URL weiterleiten kann, die dann die Authentifizierung übernimmt. Wenn der folgende Wert != nil ist, ist dies das Passwort, mit dem sich das Skript als jeder Nutzer anmelden kann. Vorsicht ist angesagt.
'user_backends' => array( array( 'class' => 'OC_User_BasicAuth', 'arguments' => array('https://dashboard.beispielschule.de/nc_auth'), ), ),
'here_be_dragons_dont_use_this_password'
- MATRIX_DOMAIN =
'matrix.example.com'
- MATRIX_DOMAIN_SHORT =
'example.com'
- MATRIX_ALL_ACCESS_PASSWORD_BE_CAREFUL =
nil
- JITSI_HOST =
Das Dashboard vermittelt Links in Jitsi-Räume mit Hilfe von JWT (JSON Web Tokens). Dafür werden ein paar Angaben benötigt, die auf der Jitsi-Seite verifiziert werden müssen.
'meet.beispielschule.de'
- JWT_APPAUD =
'jitsi'
- JWT_APPISS =
'dashboard'
- JWT_APPKEY =
'ein_langer_langer_richtig_langer_app_key'
- JWT_SUB =
'beispielschule.de'
- JWT_APPKEY_AGRAPP =
'ein_langer_langer_richtig_langer_app_key'
- BIB_HOST =
BIB_HOST = 'gyst-bib.nhcham.org'
'https://bibliothek.beispielschule.de'
- JWT_APPKEY_BIB =
'ein_langer_langer_richtig_langer_app_key'
- EMAIL_PASSWORD_SALT =
Es folgen ein paar Salts, die bestimmen, nach welchen Regeln Passwörter und sekundäre IDs generiert werden
'bitte_jeden_salt_nur_einmal_verwenden'
- NEXTCLOUD_PASSWORD_SALT =
'bitte_jeden_salt_nur_einmal_verwenden'
- KLASSEN_ID_SALT =
'bitte_jeden_salt_nur_einmal_verwenden'
- USER_ID_SALT =
'bitte_jeden_salt_nur_einmal_verwenden'
- LESSON_ID_SALT =
'bitte_jeden_salt_nur_einmal_verwenden'
- SESSION_SCRAMBLER =
'bitte_jeden_salt_nur_einmal_verwenden'
- EXTERNAL_USER_EVENT_SCRAMBLER =
'bitte_jeden_salt_nur_einmal_verwenden'
- LOGIN_CODE_SALT =
'bitte_jeden_salt_nur_einmal_verwenden'
- WEBSITE_READ_INFO_SECRET =
'bitte_ein_zufälliges_secret_generieren'
- MESSAGE_DELAY =
DEVELOPMENT ? 1 : 1
- LOGIN_STATS_D =
[0, 7, 28, 1000]
- VPLAN_ENCODING =
'ISO-8859-1'
- JITSI_EVENT_PRE_ENTRY_TOLERANCE =
minutes
DEVELOPMENT ? 2880 : 15
- JITSI_EVENT_POST_ENTRY_TOLERANCE =
minutes
DEVELOPMENT ? 2880 : 120
- JITSI_LESSON_PRE_ENTRY_TOLERANCE =
minutes
DEVELOPMENT ? 5: 5
- JITSI_LESSON_POST_ENTRY_TOLERANCE =
minutes
DEVELOPMENT ? 10: 10
- PROVIDE_CLASS_STREAM =
false
- COOKIE_EXPIRY_TIME =
3600 * 24 * 365
- AVAILABLE_FONTS =
['Roboto', 'Alegreya']
- GEN_IMAGE_WIDTHS =
[2048, 1200, 1024, 768, 512, 384, 256].sort
- MAINTENANCE_MODE =
false
- KLASSEN_TR =
{'8o' => '8ω'}
- TIMETABLE_ENTRIES_VISIBLE_AHEAD_DAYS =
7
- AUFSICHT_ZEIT =
{1 => '08:00', 2 => '09:00', 3 => '09:55', 4 => '10:40', 6 => '12:50', 7 => '13:40', 8 => '14:30'}
- PAUSENAUFSICHT_DAUER =
{1 => 25, 2 => 15, 3 => 15, 4 => 20, 6 => 40, 7 => 40, 8 => 15}
- KLASSEN_ORDER =
['5a', '11', '12']
- TABLET_COLORS =
{}
- SCHOOL_WEBSITE_API_URL =
''
- DEVELOPMENT_MAIL_DELIVERY_POSITIVE_LIST =
[]
- UNTIS_VERTRETUNGSPLAN_BASE_URL =
'https://beispielschule.de/vertretungsplan_lehrer'
- UNTIS_VERTRETUNGSPLAN_USERNAME =
nil
- UNTIS_VERTRETUNGSPLAN_PASSWORD =
nil
- MONITOR_DEEP_LINK =
nil
- MONITOR_LZ_DEEP_LINK =
nil
- FOTO_PASSWORD =
nil
- TR =
{'String' => 'string', 'Array' => 'list', 'Hash' => 'hash', 'TrueClass' => 'true', 'FalseClass' => 'false', 'NilClass' => 'null', 'Integer' => 'int', 'Float' => 'float' }
- CONFIG =
YAML::load_file('/data/config.yaml')
- TIMETABLE_JSON_KEYS =
{ # 6 => [:klasse, :stunde, :fach, :raum, :lehrer, :text], 6 => [:stunde, :klasse, :lehrer, :raum, :fach, :text], 7 => [:vnr, :stunde, :klasse, :lehrer, :raum, :fach, :text], }
- PING_TIME =
DEVELOPMENT ? 1 : 1
- MAIL_FORWARDER_SLEEP =
DEVELOPMENT ? 10 : 60
- MAIL_FORWARD_BATCH_SIZE =
30
- SRSLY =
ARGV.include?('--srsly')
- DELAYED_UPDATE_TIME =
DEVELOPMENT ? 0 : 0
- UPDATE_INFO =
ARGV.include?('--update-info')
- SKIP_COLLECT_DATA =
true
- DEBUG_ARCHIVE_PATH =
'/data/debug_archives/2023-07-23.zip'
- SHARE_ARCHIVED_FILES =
ARGV.include?('--share-archived')
- SHARE_SOURCE_FOLDER =
SHARE_ARCHIVED_FILES ? 'Unterricht-22-23' : 'Unterricht'
- SHARE_TARGET_FOLDER =
SHARE_ARCHIVED_FILES ? 'Archiv-Jahresbeginn-23-24' : 'Unterricht'
- ALSO_SHARE_OS_FOLDERS =
true
- SHARE_READ =
1
- SHARE_UPDATE =
2
- SHARE_CREATE =
4
- SHARE_DELETE =
8
- SHARE_SHARE =
16
- HTTP_READ_TIMEOUT =
60 * 10
- ALSO_CREATE_OS_FOLDERS =
true
- BASE62_ALPHABET =
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
- SEKRETARIAT_EMAIL =
'sekretariat@beispielschule.de'
- MAX_LOGIN_TRIES =
3
- MATRIX_ADMIN_USER =
nil
- MATRIX_ADMIN_PASSWORD =
nil
- MATRIX_CORPORAL_CALLBACK_BEARER_TOKEN =
'bitte_jedes_bearer_token_nur_einmal_verwenden'
- JWT_APPAUD_STREAM =
'stream'
- JWT_APPKEY_STREAM =
'ein_langer_langer_richtig_langer_app_key'
- JWT_DOMAIN_STREAM =
'.beispielschule.de'
- JWT_APPAUD_AGRAPP =
'agrapp'
- JWT_APPISS_AGRAPP =
'dashboard'
- STREAM_SITE_URL =
'https://info.beispielschule.de/'
- JITSI_ALL_ROOMS_URL =
der alle Räume und Teilnehmer im JSON-Format zurückgibt.
nil
- WECHSELUNTERRICHT_KLASSENSTUFEN =
[]
- GROUP_AF_ICONS =
{ '' => "<span style='font-size:120%;'>🏠</span>", 'it' => "<span style='font-size:120%;'>🇮🇹</span>", 'gr' => "<span style='font-size:120%;'>🇬🇷</span>" }
- GROUP_AF_ICON_KEYS =
GROUP_AF_ICONS.keys.sort
- GROUP_FT_ICONS =
{ 'nawi' => "<span style='font-size:120%;'>🧪</span> Nawi", 'gewi' => "<span style='font-size:120%;'>👪</span> Gewi", 'musik' => "<span style='font-size:120%;'>🎹</span> Musik", 'medien' => "<span style='font-size:120%;'>📽️</span> Medien", }
- GROUP_FT_ICON_KEYS =
GROUP_FT_ICONS.keys.sort
- STREAMING_TABLET_BOOKING_TIME_PRE =
tablet booking pre and post time, in minutes
5
- STREAMING_TABLET_BOOKING_TIME_POST =
15
- LEHRBUCHVEREIN_JAHR =
2023
- TABLET_DEFAULT_COLOR =
'#d3d7cf'
- SWITCH_WEEKS =
Definition von Wechselwochen
{'2021-03-08' => ['A', 2], '2021-03-22' => nil}
- KLASSENRAUM_ACCOUNT_DEEP_LINK_CODE =
nil
- DEMO_ACCOUNT_EMAIL =
nil
- DEMO_ACCOUNT_INFO =
nil
- DEMO_ACCOUNT_FIXED_PIN =
nil
- SEMI_PUBLIC_LINKS =
[]
- EXCLUDE_FROM_SELF_TEST_REPORT =
[]
- ZEUGNISKONFERENZEN =
[]
- CLING_COLORS =
[ ["#ffe617", "daffodil"], ["#fad31c", "daisy"], ["#fdb717", "mustard"], ["#faaa21", "circus zest"], ["#f1753f", "pumpkin"], ["#ed5724", "tangerine"], ["#ef4538", "salmon"], ["#ea2830", "persimmon"], ["#bc2326", "rouge"], ["#8c0c03", "scarlet"], ["#e5185d", "hot pink"], ["#f384ae", "princess"], ["#fac6d2", "petal"], ["#b296c7", "lilac"], ["#7b67ae", "lavender"], ["#5f3577", "violet"], ["#c1d18a", "ceadon"], ["#799155", "olive"], ["#80bc42", "bamboo"], ["#4aa03f", "grass"], ["#16884a", "kelly"], ["#003f2e", "forrest"], ["#c3def1", "cloud"], ["#55beed", "dream"], ["#31a8e0", "gulf"], ["#238acc", "turquoise"], ["#0d60ae", "sky"], ["#143b86", "indigo"], ["#001b4a", "navy"], ["#7dcdc2", "sea foam"], ["#00a8a8", "teal"], ["#12959f", "peacock"], ["#094e54", "cyan"], ["#381e11", "chocolate"], ["#c05c20", "terra cotta"], ["#bf9b6b", "camel"], ["#e9d4a7", "linen"], ["#e7e6e1", "stone"], ["#cfd0d2", "smoke"], ["#8a8b8f", "steel"], ["#778590", "slate"], ["#474d4d", "charcoal"], ["#050608", "black"], ["#ffffff", "white"], ]
- DRY_RUN =
__DRY_RUN__
- LETTERS =
'BCDFHJLMNPQRSTVWYZ'
- DIGITS =
'23456789'
- DASH =
'–'
- NAME_MATCH_STOP_WORDS =
Set.new(['de', 'la', 'von'])
- BASE_DIR =
File.join(NEXTCLOUD_DASHBOARD_DATA_DIRECTORY, 'files', 'Unterricht')
- PK5_KEYS =
[ :themengebiet, :referenzfach, :betreuende_lehrkraft, :fas, :betreuende_lehrkraft_fas, :fragestellung ]
- PK5_KEY_LABELS =
{ :themengebiet => 'Themengebiet', :referenzfach => 'Referenzfach', :betreuende_lehrkraft => 'Betreuende Lehrkraft im Referenzfach', :fas => 'fächerübergreifender Aspekt', :betreuende_lehrkraft_fas => 'Betreuende Lehrkraft im fächerübergreifenden Aspekt', :fragestellung => 'Fragestellung', }
- PRESENCE_TOKEN_EXPIRY_TIME =
discard presence token after 600 seconds unless it's renewed in the meantime
60 * 10
- LOGIN_METHODS =
{:email => 'Code per E-Mail', :sms => 'Code per SMS', :otp => 'OTP-Code'}
- LOGIN_METHODS_SHORT =
{:email => 'E-Mail', :sms => 'SMS', :otp => 'OTP'}
- AVAILABLE_ROLES =
{ :teacher => 'Lehrkraft', :schueler => 'Schülerin / Schüler', :admin => 'Administrator', :developer => 'Entwickler', :sekretariat => 'Sekretariat', :zeugnis_admin => 'Zeugnis-Admin', :can_see_all_timetables => 'kann alle Stundenpläne sehen', # :can_manage_salzh, :can_upload_files => 'kann Dateien hochladen', :can_manage_news => 'kann News verwalten', :can_manage_monitors => 'kann Monitore verwalten', :can_manage_tablets => 'kann Tabletbuchungen verwalten', :can_book_tablets => 'kann Tablets buchen', :can_use_aula => 'Aulatechnik', :can_manage_antikenfahrt => 'kann Antikenfahrt verwalten', :can_manage_agr_app => 'kann die Altgriechisch-App verwalten', :can_manage_bib => 'kann die Bibliothek verwalten', :can_manage_bib_members => 'kann Bibliotheksnutzer verwalten', :can_manage_bib_payment => 'kann Bibliothekszahlungen verwalten', :can_manage_bib_special_access => 'Bibliothek Spezialzugriff', :can_manage_tech_problems => 'kann gemeldete Technikprobleme bearbeiten', :gev => 'GEV', :sv => 'Schülervertretung', :technikteam => 'Technikteam', :technikamt => 'Technikamt', :wants_to_receive_techpost_debug_mail => 'möchte E-Mails zu Technikproblemen erhalten', :datentresor_hotline => 'kann Lehrkräfte für den Datentresor freischalten', :schulbuchverein => 'Schulbuchverein', :can_receive_messages => 'kann Nachrichten empfangen', :can_write_messages => 'kann Nachrichten schreiben', :can_create_polls => 'kann Umfragen durchführen', :can_create_events => 'kann Termine anlegen', :can_use_mailing_lists => 'kann alle Mail-Verteiler verwenden', :can_use_nextcloud => 'kann die Nextcloud verwenden', :can_use_sms_gateway => 'kann die SMS-Anmeldung benutzen', :can_report_tech_problems => 'kann Technikprobleme melden', :oko => 'Oberstufenkoordination', }
- ROLE_TRANSITIONS =
<<~END_OF_STRING teacher => can_receive_messages can_write_messages can_book_tablets can_create_polls can_create_events can_use_mailing_lists can_use_nextcloud can_use_sms_gateway schueler => can_receive_messages can_use_nextcloud sv => can_write_messages can_create_polls can_use_mailing_lists can_create_events technikteam => can_write_messages can_book_tablets can_create_polls can_use_mailing_lists can_create_events can_manage_tablets can_manage_tech_problems can_report_tech_problems admin => can_upload_files can_book_tablets can_manage_news can_manage_monitors can_manage_tablets can_manage_tech_problems can_report_tech_problems schulbuchverein => can_use_nextcloud technikamt => can_report_tech_problems END_OF_STRING
- SALZH_MODE_COLORS =
{:contact_person => 'warning', :salzh => 'danger', :hotspot_klasse => 'pink'}
- SALZH_MODE_ICONS =
{:contact_person => 'fa-exclamation', :salzh => 'fa-home', :hotspot_klasse => 'fa-fire'}
- SALZH_MODE_LABEL =
{:contact_person => 'Kontaktperson', :salzh => 'saLzH', :hotspot_klasse => 'Hotspot-Klasse'}
- CW_TR =
include Magick
[ ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." ]
- PROJEKT_VOTE_CODEPOINTS =
[0x1fae5, 0x1f914, 0x1f60d, 0x1f525]
- PROJEKT_VOTE_LABELS =
[ 'Ich habe kein Interesse an diesem Projekt.', 'Ich könnte mir vorstellen, an diesem Projekt teilzunehmen.', 'Ich würde mich freuen, an diesem Projekt teilzunehmen.', 'Ich würde wirklich sehr gern an diesem Projekt teilnehmen.', ]
- TABLET_SET_WARNING_BEFORE_MINUTES =
TODO: move these to credentials
15
- TABLET_SET_WARNING_AFTER_MINUTES =
15
- COLOR_SCHEME_COLORS =
[ ['l788aa3e8a598b56576', 'Dreamy'], ['lab8bbfa27776ab8bbe', 'Einfacher Plan', 'Thanos'], ['l7146749f6976cc8b79', 'Ice cream', 'Charlie'], ['le8a598b5657600a896', 'Pearly Purple'], ['l94b2a1ff7d03e0ff03', 'Orangensaft', 'Karla'], ['lc0c0c0ff6700ebebeb', 'Orange Justice'], ['d013adedf3a01f7fe2e', 'Sunset', 'Josefine'], ['lfcbf499e0001eeba30', 'Gryffindor'], ['dfad31c8c0c03381e11', 'Exotherm'], ['d6a00009626006a0000', 'Blutroter Sommer', 'Thanos'], ['d994500663300000000', 'Sandsturm'], ['l234567890123456789', 'Sonnenuntergang', 'Leo'], ['ldf0174ff0040ffffff', 'Kirscheis', 'Seraphine'], ['l32031ba63570ff99cc', 'BOOMBAYAH'], ['lffcc00c20aa10a9ec2', 'Unicorn'], ['l55beedf9b935e5185d', 'ソフトクリーム'], ['la86fd07638a15a2b7a', 'Amethyst'], ['lcc1ccca66aaab4bbbb', 'Lavendel', 'Leo'], ['l0b2f3ad0a9f5f8e0f7', 'Passive Night', 'Jack'], ['d0000ff6600ffcc00ff', 'Purple Valley', '𝕺𝕲 𝕭𝖎𝖌'], ['l073b4c118ab2946b2d', 'Ravenclaw'], ['la2c6e80d60aea2c6e8', 'Sky'], ['l000000013adfced8f8', 'In the refrigerator', 'Josefine'], ['d053a4d001eff00d7ff', 'Unter dem Meer', 'Linus'], ['d00ff000b0b6100ff00', 'Kristallmine', 'Josefine'], ['d401364131364799d54', 'Himmel Lila', 'HoloOmar10'], ['l307fdc03396cfe0e8d', 'Zoomer'], ['l12959f094e54e7eff6', 'Wellenbad'], ['d119c7503626414a19e', '20.000 Meilen unter dem Meer', 'Astrid'], ['d160520069960025061', 'Tiefsee'], ['d043402138610043402', 'Polarnacht', 'Astrid'], ['d4aa03f003f2e80bc42', 'Thylakoid'], ['l2a9134054a29e7ecef', 'Slytherin'], ['ldf01010b6121a9f5bc', 'Watermelon'], ['lf7fe2e088a08fa5882', 'Kaktus'], ['le8e33b6ca705f8f8df', 'Zitronen & Limetten', 'Astrid'], ['lceecf5f3f781f7819f', 'Dream', 'Jack'], ['daaaaaa777777cccccc', 'Shadows', 'Leo'], ['l0c0f0a463f3affbd00', 'Hufflepuff'], ['l9afe2e1c1c1c3c74c7', 'Libelle', 'Elias'], ['d290040232323290040', 'Aschgrauer Himmel', 'Thanos'], ['d151131222526333383', 'Midnight Sky', 'Leo'], ['d00f7000a0a0a00f700', 'H4CK3Я', 'Karla'], ['d990000000000000099', 'Spooner'], ['d000099000000009900', 'FreeRot'] ]
- STANDARD_COLOR_SCHEME =
'la2c6e80d60aea2c6e80'
Instance Method Summary collapse
- #assert(condition, message = 'assertion failed', suppress_backtrace = false, delay = nil) ⇒ Object
- #assert_with_delay(condition, message = 'assertion failed', suppress_backtrace = false) ⇒ Object
- #color_palette_for_color_scheme(color_scheme) ⇒ Object
- #cw_pattern(word) ⇒ Object
- #darken(c, f = 0.2) ⇒ Object
- #debug(message, index = 0) ⇒ Object
- #debug_error(message) ⇒ Object
- #deliver_mail(plain_text = nil, &block) ⇒ Object
- #desaturate(c) ⇒ Object
- #find_available_target_paths(target_filename, cp_target_dir, mv_target_dir) ⇒ Object
- #find_email_for_name(first_name, last_name, first_name_to_email, last_name_to_email) ⇒ Object
- #fix_h_to_hh(s) ⇒ Object
- #gen_reverse_index(users, key) ⇒ Object
- #get_file_from_url(url, &block) ⇒ Object
- #get_gradient(colors, t) ⇒ Object
- #handle_html_batch(bodies) ⇒ Object
- #handle_vplan_html_file(contents, removed_days) ⇒ Object
- #head_file_from_url(url, &block) ⇒ Object
- #hex_to_rgb(c) ⇒ Object
- #hsv_to_rgb(c) ⇒ Object
- #html_to_rgb(x) ⇒ Object
- #i_to_b62(n) ⇒ Object
- #join_with_sep(list, a, b) ⇒ Object
- #luminance(color) ⇒ Object
- #mail_html_to_plain_text(s) ⇒ Object
- #mix(a, b, t) ⇒ Object
- #override_email_login_recipient_for_chat(email) ⇒ Object
- #parse_html_datum(s) ⇒ Object
- #parse_markdown(s) ⇒ Object
- #perform_refresh ⇒ Object
-
#remove_accents(s) ⇒ Object
Faye::WebSocket.load_adapter('puma').
- #rgb_to_hex(c) ⇒ Object
- #rgb_to_hsv(c) ⇒ Object
- #rgb_to_html(x) ⇒ Object
- #shift_hue(c, f = 60) ⇒ Object
- #strip_past_tables(dom) ⇒ Object
Instance Method Details
#assert(condition, message = 'assertion failed', suppress_backtrace = false, delay = nil) ⇒ Object
37 38 39 40 41 42 43 44 45 |
# File 'src/ruby/main.rb', line 37 def assert(condition, = 'assertion failed', suppress_backtrace = false, delay = nil) unless condition debug_error e = StandardError.new() e.set_backtrace([]) if suppress_backtrace sleep delay unless delay.nil? raise e end end |
#assert_with_delay(condition, message = 'assertion failed', suppress_backtrace = false) ⇒ Object
47 48 49 |
# File 'src/ruby/main.rb', line 47 def assert_with_delay(condition, = 'assertion failed', suppress_backtrace = false) assert(condition, , suppress_backtrace, DEVELOPMENT ? 0.0 : 3.0) end |
#color_palette_for_color_scheme(color_scheme) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'src/ruby/create-cling-color-palette.rb', line 170 def color_palette_for_color_scheme(color_scheme) primary_color = '#' + color_scheme[7, 6] light = luminance(primary_color) > 160 primary_color_darker = darken(primary_color, 0.8) desaturated_color = darken(desaturate(primary_color), 0.9) if light desaturated_color = rgb_to_hex(mix(hex_to_rgb(desaturate(primary_color)), hex_to_rgb('#ffffff'), 0.1)) end desaturated_color_darker = darken(desaturate(primary_color), 0.3) disabled_color = light ? rgb_to_hex(mix(hex_to_rgb(primary_color), [255, 255, 255], 0.5)) : rgb_to_hex(mix(hex_to_rgb(primary_color), [192, 192, 192], 0.5)) darker_color = rgb_to_hex(mix(hex_to_rgb(primary_color), [0, 0, 0], 0.6)) shifted_color = shift_hue(primary_color, 350) main_text_color = light ? rgb_to_hex(mix(hex_to_rgb(primary_color), [0, 0, 0], 0.7)) : rgb_to_hex(mix(hex_to_rgb(primary_color), [255, 255, 255], 0.8)) contrast_color = rgb_to_hex(mix(hex_to_rgb(primary_color), color_scheme[0] == 'l' ? [0, 0, 0] : [255, 255, 255], 0.7)) color_palette = { :is_light => light, :primary => primary_color, :primary_color_darker => primary_color_darker, :disabled => disabled_color, :darker => darker_color, :shifted => desaturated_color, :left => '#' + color_scheme[1, 6], :right => '#' + color_scheme[13, 6], :main_text => main_text_color, :contrast => contrast_color } color_palette end |
#cw_pattern(word) ⇒ Object
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 |
# File 'src/ruby/include/cypher.rb', line 12 def cw_pattern(word) pattern = '' word.each_char do |c| c = c.upcase ci = c.ord - 'A'.ord if c == ' ' pattern += ' ' while pattern.length % 8 != 0 pattern += ' ' end else cw = CW_TR[ci] (0...cw.size).each do |cwi| if cw[cwi] == '.' pattern += '.' else pattern += '...' end if cwi < cw.size - 1 pattern += ' ' else pattern += ' ' end end end end pattern end |
#darken(c, f = 0.2) ⇒ Object
146 147 148 149 150 |
# File 'src/ruby/create-cling-color-palette.rb', line 146 def darken(c, f = 0.2) hsv = rgb_to_hsv(hex_to_rgb(c)) hsv[2] *= f rgb_to_hex(hsv_to_rgb(hsv)) end |
#debug(message, index = 0) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'src/ruby/main.rb', line 130 def debug(, index = 0) index = 0 begin while index < caller_locations.size - 1 && ['transaction', 'neo4j_query', 'neo4j_query_expect_one'].include?(caller_locations[index].base_label) index += 1 end rescue index = 0 end l = caller_locations[index] ls = '' begin ls = "#{l.path.sub('/app/', '').sub('.rb', '')}:#{l.lineno}" rescue ls = "#{l[0].sub('/app/', '').sub('.rb', '')}:#{l[1]}" end STDERR.puts "#{DateTime.now.strftime('%H:%M:%S')} [#{ls}] #{}" end |
#debug_error(message) ⇒ Object
149 150 151 152 153 154 155 156 157 158 |
# File 'src/ruby/main.rb', line 149 def debug_error() l = caller_locations.first ls = '' begin ls = "#{l.path.sub('/app/', '').sub('.rb', '')}:#{l.lineno} @ #{l.base_label}" rescue ls = "#{l[0].sub('/app/', '').sub('.rb', '')}:#{l[1]}" end STDERR.puts "#{DateTime.now.strftime('%H:%M:%S')} [ERROR] [#{ls}] #{}" end |
#deliver_mail(plain_text = nil, &block) ⇒ Object
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'src/ruby/main.rb', line 206 def deliver_mail(plain_text = nil, &block) mail = Mail.new do charset = 'UTF-8' = self.instance_eval(&block) if plain_text.nil? html_part do content_type 'text/html; charset=UTF-8' body end text_part do content_type 'text/plain; charset=UTF-8' body mail_html_to_plain_text() end else text_part do content_type 'text/plain; charset=UTF-8' body plain_text end end end if DEVELOPMENT if DEVELOPMENT_MAIL_DELIVERY_POSITIVE_LIST.include?(mail.to.first) debug "Sending mail to #{mail.to.join(' / ')} because first recipient is included in DEVELOPMENT_MAIL_DELIVERY_POSITIVE_LIST..." mail.deliver! else debug "Not sending mail to because we're in development: #{mail.subject} => #{mail.to.join(' / ')}" debug mail.to_s end else mail.deliver! end end |
#desaturate(c) ⇒ Object
133 134 135 136 137 138 |
# File 'src/ruby/create-cling-color-palette.rb', line 133 def desaturate(c) hsv = rgb_to_hsv(hex_to_rgb(c)) hsv[1] *= 0.7 hsv[2] *= 0.9 rgb_to_hex(hsv_to_rgb(hsv)) end |
#find_available_target_paths(target_filename, cp_target_dir, mv_target_dir) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'src/ruby/collect-nextcloud-files-from-sus.script.rb', line 22 def find_available_target_paths(target_filename, cp_target_dir, mv_target_dir) n = 1 while true do temp_target_filename = target_filename.dup if n > 1 temp_parts = target_filename.split('.') inject_index = temp_parts.size - 2 inject_index = 0 if inject_index < 0 temp_parts[inject_index] += " (#{n})" temp_target_filename = temp_parts.join('.') end cp_path = File.join(cp_target_dir, temp_target_filename) mv_path = File.join(mv_target_dir, temp_target_filename) unless File.exist?(cp_path) || File.exist?(mv_path) return cp_path, mv_path end n += 1 end end |
#find_email_for_name(first_name, last_name, first_name_to_email, last_name_to_email) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'src/ruby/import-projekte.rb', line 40 def find_email_for_name(first_name, last_name, first_name_to_email, last_name_to_email) a = first_name_to_email[first_name.split('-').first.downcase.strip] || Set.new() b = last_name_to_email[last_name.split('-').first.downcase.strip] || Set.new() c = a & b if c.empty? STDERR.puts a.to_a.to_yaml STDERR.puts b.to_a.to_yaml raise "No email found for #{first_name} #{last_name}!" end if c.size > 1 raise "Multiple emails found for #{first_name} #{last_name}!" end return c.to_a.first end |
#fix_h_to_hh(s) ⇒ Object
160 161 162 163 164 165 166 167 |
# File 'src/ruby/main.rb', line 160 def fix_h_to_hh(s) return nil if s.nil? if s =~ /^\d:\d\d$/ '0' + s else s end end |
#gen_reverse_index(users, key) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'src/ruby/import-projekte.rb', line 24 def gen_reverse_index(users, key) index = {} users.each_pair do |email, user| value = user[key].split('-').first if value value = value.downcase.strip index[value] ||= Set.new() index[value] << email end end index end |
#get_file_from_url(url, &block) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'src/ruby/vplan-watcher.rb', line 243 def get_file_from_url(url, &block) # STDERR.puts "Getting #{url}..." uri = URI.parse(url) req = Net::HTTP::Get.new(uri) if UNTIS_VERTRETUNGSPLAN_USERNAME && UNTIS_VERTRETUNGSPLAN_PASSWORD req.basic_auth UNTIS_VERTRETUNGSPLAN_USERNAME, UNTIS_VERTRETUNGSPLAN_PASSWORD end res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') do |http| response = http.request(req) if response.code.to_i == 200 body = response.body body.force_encoding('iso-8859-1') body = body.encode('utf-8') yield(response.header, body) else STDERR.puts "WARNING: page not found: #{url}" # raise "page not found: #{url}" end end end |
#get_gradient(colors, t) ⇒ Object
160 161 162 163 164 165 166 167 168 |
# File 'src/ruby/create-cling-color-palette.rb', line 160 def get_gradient(colors, t) i = (t * (colors.size - 1)).to_i i = colors.size - 2 if i == colors.size - 1 f = (t * (colors.size - 1)) - i f1 = 1.0 - f a = html_to_rgb(colors[i]) b = html_to_rgb(colors[i + 1]) rgb_to_html([a[0] * f1 + b[0] * f, a[1] * f1 + b[1] * f, a[2] * f1 + b[2] * f]) end |
#handle_html_batch(bodies) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'src/ruby/vplan-watcher.rb', line 205 def handle_html_batch(bodies) datum_list = Set.new() removed_days = Set.new() bodies.each do |body| temp = handle_vplan_html_file(body, removed_days) if temp datum_list |= temp end end datum_list.each do |datum| File.open("/vplan/#{datum}.json", 'w') do |fout| data = {:entries => {}, :entry_ref => {}, :timetables => {}} Dir["/vplan/#{datum}/*.json"].each do |path| temp = JSON.parse(File.read(path)) (temp['entries'] || []).each do |sha1| data[:entries][sha1] = JSON.parse(File.read("/vplan/#{datum}/entries/#{sha1}.json")) end (temp['day_messages'] || []).each do |sha1| data[:entries][sha1] = JSON.parse(File.read("/vplan/#{datum}/entries/#{sha1}.json")) end end Dir["/vplan/#{datum}/*.json"].each do |path| id = File.basename(path).sub('.json', '') entry = JSON.parse(File.read(path)) unless entry.empty? data[:timetables][id] = entry (entry['entries'] || []).each do |e| data[:entry_ref][e] ||= [] data[:entry_ref][e] << id end end end fout.write(data.to_json) end end # trigger_update('all') end |
#handle_vplan_html_file(contents, removed_days) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'src/ruby/vplan-watcher.rb', line 73 def handle_vplan_html_file(contents, removed_days) dom = Nokogiri::HTML.parse(contents) dom = strip_past_tables(dom) return if dom.at_css('h2').nil? return if dom.at_css('#vertretung').nil? heading = dom.at_css('h2').text heading.gsub!('8?', '8o') heading.gsub!('9?', '9o') heading.gsub!('J11', '11') heading.gsub!('J12', '12') klasse = heading.split(' ').first if KLASSEN_ORDER.include?(klasse) heading = klasse end datum_list = Set.new() datum = nil result = {} dom.at_css('#vertretung').children.each do |child| if child.name == 'table' && datum table_mode = nil classes = child.attribute('class').to_s.split(' ') # STDERR.puts "[#{heading}] [#{datum}] [#{classes.join(' ')}]" if classes.include?('subst') # STDERR.print "(Vertretungsplan)" table_mode = :vplan else if child.css('tr').first.text == 'Nachrichten zum Tag' # STDERR.print "(Nachrichten zum Tag)" table_mode = :day_message else # STDERR.puts "classes: #{classes.to_json}" # STDERR.puts child.to_s raise 'unexpected table' end end assert(!table_mode.nil?) # STDERR.puts child.to_s child.css('tr').each do |row| row.search('s').each do |n| n.content = "__STRIKE_BEGIN__#{n.content}__STRIKE_END__" end row.search('br').each do |n| n.content = "__LINE_BREAK__" end row.search('td/*').each do |n| n.replace(n.content) unless n.name == 's' end tr = row.css('th') if tr.size == 6 # Klassenvertretungsplan: headings = tr.map { |x| x.text }.join(' / ') # assert(headings == 'Klasse(n) / Stunde / Fach / Raum / (Lehrer) / Text') assert(headings == 'Stunde / Klasse(n) / (Lehrer) / (Raum) / (Fach) / Text') elsif tr.size == 7 # Lehrervertretungsplan: Vtr-Nr. Stunde Klasse(n) (Lehrer) (Raum) (Fach) Text headings = tr.map { |x| x.text }.join(' / ') assert(headings == 'Vtr-Nr. / Stunde / Klasse(n) / (Lehrer) / (Raum) / (Fach) / Text') end cells = row.css('td') if cells.size == 1 && table_mode == :day_message result[datum] ||= {} = cells.first.text.gsub('__LINE_BREAK__', "\n").strip sha1 = Digest::SHA1.hexdigest(.to_json)[0, 8] path = "/vplan/#{datum}/entries/#{sha1}.json" FileUtils.mkpath(File.dirname(path)) File.open(path, 'w') { |f| f.write(.to_json) } result[datum][:day_messages] ||= [] result[datum][:day_messages] << sha1 elsif (cells.size == 6 || cells.size == 7) && table_mode == :vplan # Klassenvertretungsplan: Klasse(n) Stunde Fach Raum (Lehrer) Text # Lehrervertretungsplan: Vtr-Nr. Stunde Klasse(n) (Lehrer) (Raum) (Fach) Text result[datum] ||= {} result[datum][:entries] ||= [] entry = {} cells.each.with_index do |x, index| key = TIMETABLE_JSON_KEYS[cells.size][index] text = x.content || '' # replace with normal space and strip text.gsub!(/[[:space:]]+/, ' ') text.strip! entry_del = nil entry_add = nil if text.include?('__STRIKE_BEGIN__') text.gsub!('__STRIKE_BEGIN__', '') parts = text.split('__STRIKE_END__') entry_del = (parts[0] || '').strip entry_add = (parts[1] || '').strip else entry_add = (text || '').strip end entry_add = nil if entry_add && entry_add.empty? entry_del = nil if entry_del && entry_del.empty? entry_add = entry_add[1, entry_add.size - 1] if entry_add && entry_add[0] == '?' entry[key] = [entry_del, entry_add] end fixed_entry = [entry[:stunde][1], entry[:klasse], entry[:lehrer], entry[:fach], entry[:raum], entry[:text][1]] sha1 = Digest::SHA1.hexdigest(fixed_entry.to_json)[0, 8] path = "/vplan/#{datum}/entries/#{sha1}.json" FileUtils.mkpath(File.dirname(path)) File.open(path, 'w') { |f| f.write(fixed_entry.to_json) } result[datum][:entries] << sha1 end # STDERR.print " #{cells.size}" end # STDERR.puts # STDERR.puts '-' * 40 else b = nil b = child.text if child.name == 'b' child.css('b').each { |c2| b = c2.text } if b datum = parse_html_datum(b) next if datum.nil? datum_list << datum unless removed_days.include?(datum) Dir["/vplan/#{datum}/*.json"].each do |path| FileUtils::rm_f(path) end removed_days << datum end end end end result.each_pair do |datum, info| path = "/vplan/#{datum}/#{heading.gsub('/', '-')}.json" FileUtils.mkpath(File.dirname(path)) File.open(path, 'w') { |f| f.write(result[datum].to_json) } end return datum_list end |
#head_file_from_url(url, &block) ⇒ Object
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'src/ruby/vplan-watcher.rb', line 265 def head_file_from_url(url, &block) uri = URI.parse(url) req = Net::HTTP::Head.new(uri) if UNTIS_VERTRETUNGSPLAN_USERNAME && UNTIS_VERTRETUNGSPLAN_PASSWORD req.basic_auth UNTIS_VERTRETUNGSPLAN_USERNAME, UNTIS_VERTRETUNGSPLAN_PASSWORD end res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') do |http| response = http.request(req) if response.code.to_i == 200 yield(response.header) else raise "page not found: #{url}" end end end |
#hex_to_rgb(c) ⇒ Object
110 111 112 113 114 115 |
# File 'src/ruby/create-cling-color-palette.rb', line 110 def hex_to_rgb(c) r = c[1, 2].downcase.to_i(16) g = c[3, 2].downcase.to_i(16) b = c[5, 2].downcase.to_i(16) [r, g, b] end |
#hsv_to_rgb(c) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'src/ruby/create-cling-color-palette.rb', line 57 def hsv_to_rgb(c) h, s, v = c[0].to_f / 360, c[1].to_f / 100, c[2].to_f / 100 h_i = (h * 6).to_i f = h * 6 - h_i p = v * (1 - s) q = v * (1 - f * s) t = v * (1 - (1 - f) * s) r, g, b = v, t, p if h_i == 0 r, g, b = q, v, p if h_i == 1 r, g, b = p, v, t if h_i == 2 r, g, b = p, q, v if h_i == 3 r, g, b = t, p, v if h_i == 4 r, g, b = v, p, q if h_i == 5 [(r * 255).to_i, (g * 255).to_i, (b * 255).to_i] end |
#html_to_rgb(x) ⇒ Object
152 153 154 |
# File 'src/ruby/create-cling-color-palette.rb', line 152 def html_to_rgb(x) [x[1, 2].to_i(16), x[3, 2].to_i(16), x[5, 2].to_i(16)] end |
#i_to_b62(n) ⇒ Object
5 6 7 8 9 10 11 12 13 |
# File 'src/ruby/background-renderer.rb', line 5 def i_to_b62(n) s = '' while n > 0 d = n % 62 s = BASE62_ALPHABET[d] + s n /= 62 end s end |
#join_with_sep(list, a, b) ⇒ Object
246 247 248 |
# File 'src/ruby/main.rb', line 246 def join_with_sep(list, a, b) list.size == 1 ? list.first : [list[0, list.size - 1].join(a), list.last].join(b) end |
#luminance(color) ⇒ Object
117 118 119 120 |
# File 'src/ruby/create-cling-color-palette.rb', line 117 def luminance(color) r, g, b = hex_to_rgb(color) return r * 0.299 + g * 0.587 + b * 0.114 end |
#mail_html_to_plain_text(s) ⇒ Object
202 203 204 |
# File 'src/ruby/main.rb', line 202 def mail_html_to_plain_text(s) s.gsub('<p>', "\n\n").gsub(/<br\s*\/?>/, "\n").gsub(/<\/?[^>]*>/, '').strip end |
#mix(a, b, t) ⇒ Object
122 123 124 125 126 127 |
# File 'src/ruby/create-cling-color-palette.rb', line 122 def mix(a, b, t) t1 = 1.0 - t return [a[0] * t1 + b[0] * t, a[1] * t1 + b[1] * t, a[2] * t1 + b[2] * t] end |
#override_email_login_recipient_for_chat(email) ⇒ Object
231 232 233 |
# File 'src/ruby/credentials.template.rb', line 231 def override_email_login_recipient_for_chat(email) email end |
#parse_html_datum(s) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'src/ruby/vplan-watcher.rb', line 36 def parse_html_datum(s) parts = s.split('.') d = parts[0].to_i m = parts[1].to_i _ = CONFIG[:first_school_day][0, 4].to_i (_ .. (_ + 1)).each do |y| ds = sprintf('%04d-%02d-%02d', y, m, d) if ds >= CONFIG[:first_school_day] && ds <= CONFIG[:last_day] return ds end end return nil # raise 'nope' end |
#parse_markdown(s) ⇒ Object
240 241 242 243 244 |
# File 'src/ruby/main.rb', line 240 def parse_markdown(s) s ||= '' s.gsub!(/\w\*in/) { |x| x.sub('*', '\\*') } Kramdown::Document.new(s, :smart_quotes => %w{sbquo lsquo bdquo ldquo}).to_html.strip end |
#perform_refresh ⇒ Object
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'src/ruby/vplan-watcher.rb', line 282 def perform_refresh = '' = '/vplan/timestamp.txt' if File.exist?() = File.read().strip end last_modified = head_file_from_url("#{UNTIS_VERTRETUNGSPLAN_BASE_URL}/frames/navbar.htm") do |header| last_modified = DateTime.parse(header['last-modified']).strftime('%Y-%m-%d-%H-%M-%S') end return unless last_modified > STDERR.puts "Fetching vplan from #{UNTIS_VERTRETUNGSPLAN_BASE_URL}!" get_file_from_url("#{UNTIS_VERTRETUNGSPLAN_BASE_URL}/frames/navbar.htm") do |header, body| file_count = 0 bodies = [] dom = Nokogiri::HTML.parse(body) weeks = [] dom.css('select').each do |element| if element.attr('name') == 'week' element.css('option').each do |option| weeks << option.attr('value').to_i end end end classes = JSON.parse(body.match(/var classes\s*=\s*([^;]+);/)[1]) teachers = JSON.parse(body.match(/var teachers\s*=\s*([^;]+);/)[1]) weeks.each do |week| (0...teachers.size).each do |index| file_count += 1 get_file_from_url("#{UNTIS_VERTRETUNGSPLAN_BASE_URL}/#{sprintf('%02d', week)}/v/#{sprintf('v%05d', index + 1)}.htm") do |header, body| bodies << body end end (0...classes.size).each do |index| file_count += 1 get_file_from_url("#{UNTIS_VERTRETUNGSPLAN_BASE_URL}/#{sprintf('%02d', week)}/w/#{sprintf('w%05d', index + 1)}.htm") do |header, body| bodies << body end end end STDERR.puts "Fetched #{file_count} HTML files, parsing..." handle_html_batch(bodies) end File.open(, 'w') { |f| f.puts(last_modified) } STDERR.puts "Triggering timetable update..." system("curl -s http://timetable:8080/api/update/all") end |
#remove_accents(s) ⇒ Object
Faye::WebSocket.load_adapter('puma')
126 127 128 |
# File 'src/ruby/main.rb', line 126 def remove_accents(s) I18n.transliterate(s.gsub('ä', 'ae').gsub('ö', 'oe').gsub('ü', 'ue').gsub('Ä', 'Ae').gsub('Ö', 'Oe').gsub('Ü', 'Ue').gsub('ß', 'ss').gsub('ė', 'e').gsub('š', 's')) end |
#rgb_to_hex(c) ⇒ Object
129 130 131 |
# File 'src/ruby/create-cling-color-palette.rb', line 129 def rgb_to_hex(c) sprintf('#%02x%02x%02x', c[0].to_i, c[1].to_i, c[2].to_i) end |
#rgb_to_hsv(c) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'src/ruby/create-cling-color-palette.rb', line 75 def rgb_to_hsv(c) r = c[0] / 255.0 g = c[1] / 255.0 b = c[2] / 255.0 max = [r, g, b].max min = [r, g, b].min delta = max - min v = max * 100 if (max != 0.0) s = delta / max *100 else s = 0.0 end if (s == 0.0) h = 0.0 else if (r == max) h = (g - b) / delta elsif (g == max) h = 2 + (b - r) / delta elsif (b == max) h = 4 + (r - g) / delta end h *= 60.0 if (h < 0) h += 360.0 end end [h, s, v] end |
#rgb_to_html(x) ⇒ Object
156 157 158 |
# File 'src/ruby/create-cling-color-palette.rb', line 156 def rgb_to_html(x) sprintf('#%02x%02x%02x', x[0], x[1], x[2]) end |
#shift_hue(c, f = 60) ⇒ Object
140 141 142 143 144 |
# File 'src/ruby/create-cling-color-palette.rb', line 140 def shift_hue(c, f = 60) hsv = rgb_to_hsv(hex_to_rgb(c)) hsv[0] = (hsv[0] + f) % 360.0 rgb_to_hex(hsv_to_rgb(hsv)) end |
#strip_past_tables(dom) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'src/ruby/vplan-watcher.rb', line 51 def strip_past_tables(dom) dom.css('td').each do |td| if (td.text || '').strip == 'Vertretungen sind nicht freigegeben' n = td.parent.parent deleted_table = false while n != nil p = n.previous n.remove() if n && n.name == 'table' if deleted_table break else deleted_table = true end end n = p end end end dom end |