diff --git a/.github/workflows/gcal-sync.yml b/.github/workflows/gcal-sync.yml new file mode 100644 index 0000000..4bdcb4d --- /dev/null +++ b/.github/workflows/gcal-sync.yml @@ -0,0 +1,43 @@ +name: GCal Sync + +on: + schedule: + - cron: '0 4 * * *' # Daily at 04:00 UTC + workflow_dispatch: # Manual trigger + +jobs: + sync: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: firethunder.github.io/package-lock.json + + - name: Install dependencies + run: npm ci + working-directory: firethunder.github.io + + - name: Run GCal Sync + run: npm run sync-gcal + working-directory: firethunder.github.io + + - name: Commit and push changes + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add public/ffwtool/termine.json + if git diff --staged --quiet; then + echo "No changes to commit" + else + git commit -m "chore(data): automated gcal sync" + git push + fi + working-directory: firethunder.github.io diff --git a/package.json b/package.json index be06936..3249a00 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build:pwa": "vite build -c vite.pwa.config.js && node scripts/post-build-pwa.js", "preview": "vite preview", "preview:pwa": "vite preview -c vite.pwa.config.js --port 4173 --strictPort", + "sync-gcal": "node scripts/sync-gcal-headless.js", "test": "vitest run" }, "dependencies": { diff --git a/public/ffwtool/termine.json b/public/ffwtool/termine.json index f7a9bba..33f3edd 100644 --- a/public/ffwtool/termine.json +++ b/public/ffwtool/termine.json @@ -1,5 +1,2491 @@ { "termine": [ + { + "datum": "2018-09-07 20:00:00", + "name": "Gruppe B Zirkeltraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Icalfe7a447219f024c1f43f61975659b133", + "id": "790" + }, + { + "datum": "2018-09-07 20:00:00", + "name": "Gruppe A Zimmerbrand Bürgerhaus + Kindergarten", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Ical5e17a613c7dc9e8bd6c997afc716cdab", + "id": "897" + }, + { + "datum": "2018-09-25 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "55li97666fevdvdpukjq7223of@google.com", + "id": "734" + }, + { + "datum": "2018-10-05 20:00:00", + "name": "Gruppe A Zirkeltraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Icalc19a28072082584d2de68cbd6cbf50c2", + "id": "819" + }, + { + "datum": "2018-10-05 20:00:00", + "name": "Gruppe B Zimmerbrand Bürgerhaus", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Icala52ac4019df656aef23776d598756107", + "id": "926" + }, + { + "datum": "2018-10-12 18:30:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 240, + "source": "gcal", + "external_id": "Ical71d4c98a934246d6fea7aed0597f0e23", + "id": "895" + }, + { + "datum": "2018-10-25 18:30:00", + "name": "Jugendfeuerwehr in Brittheim Zirkeltraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 60, + "source": "gcal", + "external_id": "Ical24a999c67dab2df29bb60fa8ecf90308", + "id": "878" + }, + { + "datum": "2018-10-26 00:00:00", + "name": "Übung mit Bickelsberg in Brittheim", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 1440, + "source": "gcal", + "external_id": "Icald14621082d45848052c80c24d2246f26", + "id": "798" + }, + { + "datum": "2018-10-27 19:00:00", + "name": "Absturzsicherung Kletterhalle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "4qv89qsmckjvah04b3vlk2v2p3@google.com", + "id": "902" + }, + { + "datum": "2018-11-02 20:00:00", + "name": "Atemschutzübung Selbstrettung/Löschangriff", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Ical15496e9f94fb5f60ca1ec6890dda07f8", + "id": "828" + }, + { + "datum": "2018-11-16 20:00:00", + "name": "GF-Besprechung Rosenfeld Wasserförderung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Icalf0af1087f4b8089b4459ccf1c74ed9c1", + "id": "829" + }, + { + "datum": "2018-12-07 20:00:00", + "name": "Erste Hilfe in Rosenfeld - Defibrilator", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Ical8d49b69250aa93f98b6769095f5fa74a", + "id": "776" + }, + { + "datum": "2018-12-13 18:30:00", + "name": "Jungendfeuerwehr Weihnachtsfeier", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 60, + "source": "gcal", + "external_id": "Ical49173b44588b6d259cd685ccabe5ed82", + "id": "924" + }, + { + "datum": "2018-12-28 20:00:00", + "name": "Übungsplanaufstellung 2019", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Icaleef7c931b0c12cafc09ec5f30ed3d442", + "id": "844" + }, + { + "datum": "2019-01-11 20:00:00", + "name": "Geräteprüfung/Hydrantenkontrolle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "Ical488bc89daffdd4795f31929a7d279aaf", + "id": "860" + }, + { + "datum": "2019-01-18 20:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 240, + "source": "gcal", + "external_id": "Ical5e420b616c81ec735a1d4de80de81865", + "id": "810" + }, + { + "datum": "2019-01-22 00:00:00", + "name": "Absturzsicherung Grundlagen/Knoten", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 1440, + "source": "gcal", + "external_id": "CSVConvertfa051a473ed0bb13a074fcb14f30d956", + "id": "894" + }, + { + "datum": "2019-01-22 20:00:00", + "name": "Absturzsicherung Grundlagen/Knoten", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert3f6404e7718930e681b56193d691dbe4", + "id": "748" + }, + { + "datum": "2019-02-01 20:00:00", + "name": "Fahrzeugkunde ELW / UVV", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert79ffd69eee2773332966f539c78d081e", + "id": "797" + }, + { + "datum": "2019-03-01 20:00:00", + "name": "Funkübung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertca3b5589f6a71fb71a4d10f3450bd990", + "id": "738" + }, + { + "datum": "2019-03-08 18:30:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 150, + "source": "gcal", + "external_id": "CSVConvert8e9e48ff41c9144ebe6a97e6ac52f32d", + "id": "904" + }, + { + "datum": "2019-03-22 19:30:00", + "name": "Hauptversammlung Hlgz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 269, + "source": "gcal", + "external_id": "CSVConvertef0dc588176329e4fbbb230cd58a6ebc", + "id": "737" + }, + { + "datum": "2019-03-26 20:00:00", + "name": "Absturzsicherung ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert553431e406f88525262aac4f7aa71701", + "id": "811" + }, + { + "datum": "2019-03-30 13:00:00", + "name": "KFV-Versammlung Bitz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 420, + "source": "gcal", + "external_id": "CSVConvert8417514f335db46fde266a5c728324bd", + "id": "886" + }, + { + "datum": "2019-04-06 13:00:00", + "name": "Apre´s Ski Party", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 599, + "source": "gcal", + "external_id": "CSVConvert51166759c4cc9a627077f65678cbf0b3", + "id": "762" + }, + { + "datum": "2019-04-12 20:00:00", + "name": "Zugübung Hlgz (ZF Günter K.)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverta6e3b620900916c6a73a1f83ca86ba43", + "id": "824" + }, + { + "datum": "2019-04-26 20:00:00", + "name": "Brandübungsanlage Netze BW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert86c6c0489920cd77d6632c0bb6b0b6d1", + "id": "726" + }, + { + "datum": "2019-04-30 18:00:00", + "name": "Maibaum", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 359, + "source": "gcal", + "external_id": "CSVConvert08254262d057857d7d58775fa8eb5f8a", + "id": "862" + }, + { + "datum": "2019-05-03 20:00:00", + "name": "Gr. A Fahrzeugkunde ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert3751eb8795536f52a25b917ad479498b", + "id": "728" + }, + { + "datum": "2019-05-03 20:00:00", + "name": "Gr. B Wasserförderpläne", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertfb28079833134a70541d9e608a91d06e", + "id": "755" + }, + { + "datum": "2019-05-10 20:00:00", + "name": "Zugübung Bickelsberg (ZF Steven)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert0f6412a1e9bc70af9607ad2648f8bfbb", + "id": "727" + }, + { + "datum": "2019-05-21 20:00:00", + "name": "Absturzsicherung + DLK", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc2a16c1eec68ac7cba143a02d69cd40e", + "id": "921" + }, + { + "datum": "2019-06-07 20:00:00", + "name": "Gr. B Fahrzeugkunde ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert270054f4774079861d9bf06f23c4d653", + "id": "711" + }, + { + "datum": "2019-06-07 20:00:00", + "name": "Gr. A Wasserförderpläne", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertfe8e7ab7c015e3c797ca21dd068c174d", + "id": "908" + }, + { + "datum": "2019-06-13 20:00:00", + "name": "Übung mit Rosenfeld und Leidringen", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert1d7e6fca45403d0c163775506a2ac13f", + "id": "784" + }, + { + "datum": "2019-06-28 18:30:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 210, + "source": "gcal", + "external_id": "CSVConvert7ddf4ee39caa1b65d0c5fcb89a485cbe", + "id": "918" + }, + { + "datum": "2019-07-05 20:00:00", + "name": "Übung mit Altersabt. + DLK u. ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc55320fa1816b716cb1044f8f9ea3ef3", + "id": "846" + }, + { + "datum": "2019-07-06 00:00:00", + "name": "Festakt 30 Jahre JF Rosenfeld", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 1439, + "source": "gcal", + "external_id": "CSVConvert313599841918934761d4db6599dd7154", + "id": "853" + }, + { + "datum": "2019-07-09 20:00:00", + "name": "Besprechung Kdt. + Abt.-Kdt. in Brittheim", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert4d56998b8b9673e9881ceffc2acf0332", + "id": "778" + }, + { + "datum": "2019-07-18 20:00:00", + "name": "Zugübung Isingen (ZF Eddi B.)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertb7c91e181d6f2fc4f7844b19294c61c8", + "id": "698" + }, + { + "datum": "2019-07-30 19:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "CSVConvert598e96a4e96d2e310c6ccec9e381eb84", + "id": "890" + }, + { + "datum": "2019-08-31 00:00:00", + "name": "Actionausflug", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 1440, + "source": "gcal", + "external_id": "CSVConvert0b42001753a01ccf18dfbaf9426685f3", + "id": "912" + }, + { + "datum": "2019-09-06 20:00:00", + "name": "Gr. B Löscheinsatz TSF-W", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert1a26248d1da03c4b66bea91cfd4c515e", + "id": "816" + }, + { + "datum": "2019-09-06 20:00:00", + "name": "Gr. A Löscheinsatz ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertbcc07b681db2c2abc415eca8af60d451", + "id": "863" + }, + { + "datum": "2019-09-12 18:45:00", + "name": "JF Höhensicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 195, + "source": "gcal", + "external_id": "CSVConvertfdfe5a621c5f91035c4ca8eb3d255631", + "id": "756" + }, + { + "datum": "2019-09-21 00:00:00", + "name": "Abteilungsausflug 1 od. 2-tägig", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 2880, + "source": "gcal", + "external_id": "CSVConvertee8d4c9fb22bc85c796b13750091d8d4", + "id": "786" + }, + { + "datum": "2019-09-24 20:00:00", + "name": "Absturzsicherung + DLK", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert2fcef8877769976d7650621f54ec163b", + "id": "814" + }, + { + "datum": "2019-09-27 20:00:00", + "name": "Zugübung Leidringen (ZF Gerd Z.)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverta89a3c368a280e32a029c0af19360099", + "id": "779" + }, + { + "datum": "2019-10-04 20:00:00", + "name": " Gr. A Löscheinsatz TSF-W", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc6d7396630bfa72f85453f709328f03f", + "id": "714" + }, + { + "datum": "2019-10-04 20:00:00", + "name": "Gr. B Löscheinsatz ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert7d475c2fb6d2601d7bed001527f40282", + "id": "906" + }, + { + "datum": "2019-10-11 20:00:00", + "name": "Zugübung Täbingen (ZF Bernd F.)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertbb49c99c173088dd719fc3978843b4c6", + "id": "864" + }, + { + "datum": "2019-10-26 21:00:00", + "name": "Zeitsprungparty", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 179, + "source": "gcal", + "external_id": "CSVConvert0bb373a7602eacac26d681cb324a84d4", + "id": "845" + }, + { + "datum": "2019-11-08 20:00:00", + "name": "Zugübung Brittheim (ZF Thomas T.)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert540202ccce4e59080203ccdacc70dc90", + "id": "856" + }, + { + "datum": "2019-11-15 20:00:00", + "name": "Übung in Bickelsberg", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert2601daad9ab520eefcf4339bd32754c4", + "id": "858" + }, + { + "datum": "2019-11-26 19:00:00", + "name": "Absturzsicherung Kletterhalle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "CSVConvert9fe1d14d6b1d0e27c352f528f6249a19", + "id": "822" + }, + { + "datum": "2019-12-06 20:00:00", + "name": "Erste Hilfe in Ros – Motorradunfall", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc142d81fe3623ed594ce560e11b1c0cd", + "id": "729" + }, + { + "datum": "2019-12-30 20:00:00", + "name": "Übungsplanaufstellung 2020", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert84d606eb2675f6393585706a9560cca4", + "id": "745" + }, + { + "datum": "2020-01-10 20:00:00", + "name": "Geräteprüfung / Hydrantenkontrolle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc678ef129d0de7e4e9602d35fee77475", + "id": "825" + }, + { + "datum": "2020-01-17 20:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert76a2ef44077d3f961dee3f286df7b8cb", + "id": "717" + }, + { + "datum": "2020-01-28 20:00:00", + "name": "Absturzsicherung Grundlagen/Knoten", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert418a0063efb3e5b5af9d673c475e4c26", + "id": "861" + }, + { + "datum": "2020-02-07 20:00:00", + "name": "Ausleuchten RTH / Theorie Staffel", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert6a08f65cea676cd9e550e693324c339b", + "id": "752" + }, + { + "datum": "2020-03-06 20:00:00", + "name": "Zirkeltraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert29fea6226fe4bd849893a2dc07790df7", + "id": "759" + }, + { + "datum": "2020-03-13 20:00:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertf5766f9116aa21ece9a874e3a02b7567", + "id": "859" + }, + { + "datum": "2020-03-24 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert8a2517b09bb815dc8d5761e0cce8fb5a", + "id": "848" + }, + { + "datum": "2020-03-27 19:30:00", + "name": "Hauptversammlung in Brittheim", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 90, + "source": "gcal", + "external_id": "CSVConvert6874e997dc2a715852fe58478289da70", + "id": "715" + }, + { + "datum": "2020-03-28 13:00:00", + "name": "KFV-Versammlung Weilstetten", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert94ba3d5b00b1c98412ca5a384b46aef3", + "id": "869" + }, + { + "datum": "2020-04-04 13:00:00", + "name": "Après Ski Party Aufbau", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert5f5fb63d378122e2d604708a55d21e6a", + "id": "934" + }, + { + "datum": "2020-04-24 20:00:00", + "name": "Zugübung Bickelsberg ZF Günther Kopf", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert299076068120cdec8a423954b975192e", + "id": "849" + }, + { + "datum": "2020-04-29 20:00:00", + "name": "Gesamtausschusssitzung Bickelsberg", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert4138f733a9fd25e06294628fcc3e65d0", + "id": "896" + }, + { + "datum": "2020-04-30 18:00:00", + "name": "Maibaum", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverte34a583928859ece9577396379ab44b6", + "id": "901" + }, + { + "datum": "2020-05-08 20:00:00", + "name": "Zugübung Leidringen ZF Steven", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertb8303c1c910955aa6e61d96426ea170c", + "id": "837" + }, + { + "datum": "2020-05-15 20:00:00", + "name": "24-Stunden Übung Jugendfeuerwehr", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverte4ea7d2a718544faaff7cda7ab8dc18a", + "id": "713" + }, + { + "datum": "2020-05-15 20:00:00", + "name": "Löschangriff offenes Gewässer", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverte71c644d89db41fbe8e3f0c8f10aa4a4", + "id": "789" + }, + { + "datum": "2020-05-16 00:00:00", + "name": "Hochzeit Kevin + Jana", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 1440, + "source": "gcal", + "external_id": "CSVConvertff64cd13130d2781a84847d78ef45c64", + "id": "710" + }, + { + "datum": "2020-05-19 20:00:00", + "name": "Zugübung Täbingen ZF Marian", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert0bd4e42df793865b62f786d649b92928", + "id": "704" + }, + { + "datum": "2020-05-26 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert3da5c8f11b5e73b8deb0533006ce5ed1", + "id": "791" + }, + { + "datum": "2020-06-05 20:00:00", + "name": "Gr. A DLK + ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert1287e46b835257f4b9e0f823a5c7ee60", + "id": "868" + }, + { + "datum": "2020-06-05 20:00:00", + "name": "Gr. B TSF-W", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertf4f38b84f4e7a4bf419cf2eaa3087a69", + "id": "884" + }, + { + "datum": "2020-07-03 20:00:00", + "name": "Zugübung Brittheim ZF Wolfgang F", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert9a707f5710dff053cc17ab9aa581bf21", + "id": "840" + }, + { + "datum": "2020-07-10 20:00:00", + "name": "Gr. B ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert30776e92dc0eec92c13b49bc89e8da0a", + "id": "712" + }, + { + "datum": "2020-07-10 20:00:00", + "name": "Gr. A TSF-W", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertbab7760634e84f318a08e458bc1276e2", + "id": "914" + }, + { + "datum": "2020-07-16 19:00:00", + "name": "Grillfest Jugendfeuerwehr in Brittheim", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert1410aceb333ac8594ec127c818f04b84", + "id": "919" + }, + { + "datum": "2020-07-21 18:30:00", + "name": "Gesamtausschusssitzung in Heiligenzimmern", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 90, + "source": "gcal", + "external_id": "CSVConvertaf1dfb832549c8190c383cc3b1e4251f", + "id": "900" + }, + { + "datum": "2020-07-24 18:30:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 90, + "source": "gcal", + "external_id": "CSVConvertb30f981c510baa4561e5e59df936b35c", + "id": "780" + }, + { + "datum": "2020-07-28 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert520bf05ad0d174b5a2075145f56b8ea9", + "id": "903" + }, + { + "datum": "2020-09-04 20:00:00", + "name": "Gr. A Löschangriff + ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert69e7c322e7cc99b9563ad8c4fb7c844d", + "id": "787" + }, + { + "datum": "2020-09-11 20:00:00", + "name": "Gr. B Löschangriff + ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert387d68e5078fd26996be1021f50df0e1", + "id": "770" + }, + { + "datum": "2020-09-26 00:00:00", + "name": "Hauptübung Leidringen", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertd1ecfb70d8a91ef8a34e492cc7eee4e8", + "id": "731" + }, + { + "datum": "2020-09-29 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert497c551a2a3e1c9a1397a79f11ea47ef", + "id": "799" + }, + { + "datum": "2020-10-09 20:00:00", + "name": "Gr. B Technische Hilfe", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert398a15162fb518549d4e67e1d24a4fab", + "id": "821" + }, + { + "datum": "2020-10-09 20:00:00", + "name": "Gr. A Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert995e47cd2054828bfa55bf3ed4d431e9", + "id": "899" + }, + { + "datum": "2020-10-10 00:00:00", + "name": "1-Tägiger Ausflug", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 1440, + "source": "gcal", + "external_id": "CSVConvert9f4eb65598c9b7c8ba132d895317049a", + "id": "741" + }, + { + "datum": "2020-10-16 20:00:00", + "name": "Übung mit Bickelsberg in Brittheim", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert1f04b1dcf3d0b3a3cbd50fbbc89f6f41", + "id": "910" + }, + { + "datum": "2020-10-29 20:00:00", + "name": "Zugübung Rosenfeld ZF Bernd F.", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert6af62c21cac61fd724aaf4b7f402e282", + "id": "875" + }, + { + "datum": "2020-11-03 19:00:00", + "name": "Gesamtausschusssitzung in Rosenfeld", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert693ba1c7c88acd97f9a3575d66c1e895", + "id": "706" + }, + { + "datum": "2020-11-06 20:00:00", + "name": "Zugübung Heiligenzimmern ZF Thomas T.", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverte43f5bd1b6f43718007407bcd06ca9ee", + "id": "876" + }, + { + "datum": "2020-11-13 18:30:00", + "name": "Brandübungsanlage", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 90, + "source": "gcal", + "external_id": "CSVConvertf0fd274915c9d9c8f03cf570ea92c4a3", + "id": "839" + }, + { + "datum": "2020-11-13 20:00:00", + "name": "Zirkeltraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertbf50c5a8988de35a50597032294ae0e1", + "id": "847" + }, + { + "datum": "2020-11-15 20:00:00", + "name": "Volkstrauertag Kranzniederlegung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert9fc960aee8a0a52dd8d3210c19659185", + "id": "792" + }, + { + "datum": "2020-11-20 20:00:00", + "name": "Gruppenführer Besprechung in Rosenfeld", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert4707452845523d5d9fcb2404a23f9f6f", + "id": "700" + }, + { + "datum": "2020-11-24 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertaac4e81e544541ec53b5c6e97a275e26", + "id": "768" + }, + { + "datum": "2020-12-04 20:00:00", + "name": "Erste Hilfe in Rosenfeld – Kindernotfall", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert45b121c0721090caf20713d8da25ada7", + "id": "823" + }, + { + "datum": "2020-12-28 20:00:00", + "name": "Übungsplanaufstellung 2021", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert79260ca92b7f0a2f3c6b69fe09c394ca", + "id": "783" + }, + { + "datum": "2021-01-08 20:00:00", + "name": "Geräteprüfung / Hydrantenkontrolle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert00f299e041b5fbe1477703479355f0a6", + "id": "774" + }, + { + "datum": "2021-01-15 20:00:00", + "name": "Abteilungsversammlung 2020", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert4a66eeb2c05135e9f302a2063f83100d", + "id": "803" + }, + { + "datum": "2021-06-25 19:45:00", + "name": "Zirkeltraining und Atemschutzbelastungsübung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "27c0ljgact7lq7op99iqir8v3g@google.com", + "id": "782" + }, + { + "datum": "2021-07-27 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "51cgpjokc115314ne9jb9s641n@google.com", + "id": "907" + }, + { + "datum": "2021-08-06 20:00:00", + "name": "Löschangriff Staffel (Tiefbrunnen)", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "3h1ue80imhg5hr52erlj2f09qp@google.com", + "id": "801" + }, + { + "datum": "2021-09-03 20:00:00", + "name": "Gruppe A Funkübung 4m", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "774199v0109jlkgoaelgi3u5rb@google.com", + "id": "765" + }, + { + "datum": "2021-09-10 20:00:00", + "name": "Gruppe B Funkübung 4m", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "0mfenl7dcdbep2ecjoghb2eug7@google.com", + "id": "699" + }, + { + "datum": "2021-09-24 20:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "7c2j82dor7hau8unukj6h5td8k@google.com", + "id": "867" + }, + { + "datum": "2021-10-01 20:00:00", + "name": "Gruppe A Strahlrohrtraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "5jdig4u1fb0oq69nl4lr2555ls@google.com", + "id": "794" + }, + { + "datum": "2021-10-08 20:00:00", + "name": "Gruppe B Strahlrohrtraining", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "2ocopaf659m4cr5tb8pkqgas5c@google.com", + "id": "771" + }, + { + "datum": "2021-10-22 20:00:00", + "name": "Hauptversammlung in Rosenfeld", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "7nho5gqc01enje58ivvuai9h5m@google.com", + "id": "820" + }, + { + "datum": "2021-11-12 20:00:00", + "name": "Einheiten im Löscheinsatz/UVV", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "52ne6059onq8dnr95qprj71p5o@google.com", + "id": "866" + }, + { + "datum": "2021-11-19 20:00:00", + "name": "GF/ZF-Besprechung in Rosenfeld", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "2eg548s3dbnq1fgjj51cv1at27@google.com", + "id": "758" + }, + { + "datum": "2021-11-23 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "0ul0ng9em56vgkqn1nhe5bk59a@google.com", + "id": "888" + }, + { + "datum": "2021-12-03 20:00:00", + "name": "Übung Gruppe A", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "633fr1eu1g3kqmet2dm77b4a89@google.com", + "id": "870" + }, + { + "datum": "2021-12-10 20:00:00", + "name": "Übung Gruppe B", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "1s1cg9u94tu6k3en2dr3mag24t@google.com", + "id": "877" + }, + { + "datum": "2021-12-18 08:00:00", + "name": "Arbeitseinsatz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "7iat476po0f1i69pjarkgdjehf@google.com", + "id": "724" + }, + { + "datum": "2021-12-30 20:00:00", + "name": "Übungsplanaufstellung 2022", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "4muhemh0nuq19mobqgfihne98o@google.com", + "id": "865" + }, + { + "datum": "2022-01-07 20:00:00", + "name": "Hydrantenkontrolle / Geräteprüfung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "4ro6s4u69iu032fp8n2ucn890v@google.com", + "id": "795" + }, + { + "datum": "2022-01-07 21:00:00", + "name": "Hydrantenkontrolle/Gerätewartung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "8jgomg5clrvu9slg9stqqjqnsk@google.com", + "id": "832" + }, + { + "datum": "2022-01-14 20:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "7pc62c4igtis2qi73evbumldlf@google.com", + "id": "772" + }, + { + "datum": "2022-02-04 21:00:00", + "name": "Gr. A TSF-W intensiv", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "1v54pnjk8du6dtp2ui154r76mg@google.com", + "id": "705" + }, + { + "datum": "2022-02-11 21:00:00", + "name": "Gr. B TSF-W intensiv", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "7iq9kpvuomsn970djjsf2cdfqg@google.com", + "id": "854" + }, + { + "datum": "2022-03-04 21:00:00", + "name": "Gr. A Löschangriff Staffel", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "ekrvdklg6ftsb5s67hnveoakpk@google.com", + "id": "769" + }, + { + "datum": "2022-03-11 21:00:00", + "name": "Gr. B Löschangriff Staffel", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "e1rgr62o5euld9rv50lb8jm9no@google.com", + "id": "808" + }, + { + "datum": "2022-03-18 20:00:00", + "name": "Hauptversammlung Leidringen", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "ck6u4c1olish8of1oq57gfdac4@google.com", + "id": "827" + }, + { + "datum": "2022-04-01 22:00:00", + "name": "Tragetechnik Personenrettung/Knoten", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "35on9d0lhro4vfukbuq7mr1iqk@google.com", + "id": "874" + }, + { + "datum": "2022-04-22 22:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "gk3cmk3u3jbn3escf1d52udca8@google.com", + "id": "760" + }, + { + "datum": "2022-04-27 22:00:00", + "name": "GA Bick", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "qnshgct4h7b06dral5cotgr9js@google.com", + "id": "812" + }, + { + "datum": "2022-04-30 20:00:00", + "name": "Maibaum", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "uprlhcae73pr530jkb322d00bs@google.com", + "id": "749" + }, + { + "datum": "2022-05-06 20:00:00", + "name": "Saugen offenes Gewässer", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "bbasn8578tm407h692m40c7at8@google.com", + "id": "883" + }, + { + "datum": "2022-06-03 20:00:00", + "name": "Löschangriff", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "k9kd0klce3p0jnq30ta1kmcoi4@google.com", + "id": "753" + }, + { + "datum": "2022-07-01 20:00:00", + "name": "Absturzsicherung für alle mit DLK", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "2h3s15mac6r9f7hpc94tbo3fj0@google.com", + "id": "707" + }, + { + "datum": "2022-07-05 20:00:00", + "name": "Besprechung Abt.-Kdt. in Ros", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "sc8ohahj7ohioskkv309km6b54@google.com", + "id": "879" + }, + { + "datum": "2022-09-02 20:00:00", + "name": "Technische Hilfe", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "i4d3365jsk7eqpi0ff42kv4oig@google.com", + "id": "887" + }, + { + "datum": "2022-10-07 20:00:00", + "name": "Technische Hilfe VU mit RW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "ohavtot1v0ub5sotmmedqbq59c@google.com", + "id": "925" + }, + { + "datum": "2022-10-08 02:00:00", + "name": "Hauptübung Hlgz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "girb06rhsl80dk02ql7vn2lrhg@google.com", + "id": "763" + }, + { + "datum": "2022-10-28 20:00:00", + "name": "Übung mit Bick in Brit", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "9gfppd0qfogpnn3fh166hj6mvo@google.com", + "id": "882" + }, + { + "datum": "2022-11-04 20:00:00", + "name": "PKW-Brand", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "l2kqht9oqs22apj3emb53rod5g@google.com", + "id": "889" + }, + { + "datum": "2022-11-25 20:00:00", + "name": "GF/ZF-Besprechung in Ros", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "ue9625c98b4qop01t4jjfsupt8@google.com", + "id": "917" + }, + { + "datum": "2022-12-02 20:00:00", + "name": "Erste Hilfe in Ros", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "7h6p7ooi69nqcauedppscisuc4@google.com", + "id": "911" + }, + { + "datum": "2022-12-09 19:00:00", + "name": "Arbeitseinsatz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "75i3cd356lhm2b9nc5j34b9k6cs3cbb174qjgbb56oomadhn6lj38c9m6k@google.com", + "id": "702" + }, + { + "datum": "2022-12-30 20:00:00", + "name": "Übungsplanaufstellung 2023", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "dis0fpuqi45v9kn43drsiap4qg@google.com", + "id": "833" + }, + { + "datum": "2023-01-13 20:00:00", + "name": "Geräteprüfung / Hydrantenkontrolle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "7jr0981t92m97famfvvkn33i94@google.com", + "id": "920" + }, + { + "datum": "2023-01-20 20:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Brittheim,", + "dauer": 120, + "source": "gcal", + "external_id": "qmdqmgu8m7km90d8tct14e5928@google.com", + "id": "855" + }, + { + "datum": "2023-02-03 20:00:00", + "name": "Ausleuchten RTH", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertbfc9240cb4f701757380903a2b4fb441", + "id": "881" + }, + { + "datum": "2023-02-09 18:30:00", + "name": "JuFeu Knoten + Stiche", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertb7bfe7863ce3ab5159ce08c4bdcc8a39", + "id": "932" + }, + { + "datum": "2023-02-23 18:30:00", + "name": "JuFeu Knoten + Stiche ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertda643de151fc01c1ee92290bac827c41", + "id": "744" + }, + { + "datum": "2023-03-03 20:00:00", + "name": "BIG-FIRELINER / Zirkeltraining + Knoten ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertd7dbd967f3706770cb722eda3e57f3e8", + "id": "913" + }, + { + "datum": "2023-03-09 20:00:00", + "name": "Aufbau Hauptversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "2nr8obnl5n5dpn3emjmhk6qpes@google.com", + "id": "722" + }, + { + "datum": "2023-03-10 18:30:00", + "name": "Hauptversammlung in Brittheim", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 390, + "source": "gcal", + "external_id": "CSVConvertdde069397a32bfcd81abf92b6b01a749", + "id": "929" + }, + { + "datum": "2023-03-21 20:00:00", + "name": "Absturzsicherung ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverta983aad0754fddd6a10b903a66870ada", + "id": "850" + }, + { + "datum": "2023-03-31 14:00:00", + "name": "Aufbau Apre ́s Ski ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertb512feb515220ac7707ca2d832fd88f6", + "id": "817" + }, + { + "datum": "2023-04-01 20:00:00", + "name": "Apre ́s Ski Party ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 720, + "source": "gcal", + "external_id": "CSVConvert5d2d35ac8beaecccd45453db88db1f9a", + "id": "838" + }, + { + "datum": "2023-04-14 20:00:00", + "name": "Gr. A Strahlrohrtraining Gr. B Löschangriff Staffel ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert9ccd954ce92dfdd015ea422e5ce157ac", + "id": "857" + }, + { + "datum": "2023-04-25 20:00:00", + "name": "GA in Bick ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert53fbf4925fafcdb866772e62539b0a1c", + "id": "775" + }, + { + "datum": "2023-04-27 20:00:00", + "name": "Zugübung Ros - ZvD Faiss/Fuoss ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert4c734bc083f7be9dd59c9a6fe13b5951", + "id": "802" + }, + { + "datum": "2023-04-30 18:00:00", + "name": "Maibaum ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert7aa169987f39411b5a9d96bb3129b817", + "id": "736" + }, + { + "datum": "2023-05-05 20:00:00", + "name": "Gr. B Strahlrohrtraining Gr. A Löschangriff Staffel ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertfdc313aecaf22a6811fe9b83a619191e", + "id": "804" + }, + { + "datum": "2023-05-06 00:00:00", + "name": "Einweihung LF10 Leid ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 1440, + "source": "gcal", + "external_id": "CSVConvert1890d5655f52f110475d0fb95b6dd0c4", + "id": "701" + }, + { + "datum": "2023-05-12 20:00:00", + "name": "Zugübung Hlgz - ZvD Leopold/Traub ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert6dd0e15444bc6c8c6edcecf69ba5c222", + "id": "842" + }, + { + "datum": "2023-05-26 18:30:00", + "name": "Atemschutzstrecke Sulz ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 210, + "source": "gcal", + "external_id": "CSVConvertaa51969cfc6006c8f183466df3b6904f", + "id": "905" + }, + { + "datum": "2023-06-02 20:00:00", + "name": "Gefahrgutübung ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert358993c049a1b0dcea90d51894266cc9", + "id": "766" + }, + { + "datum": "2023-06-09 20:00:00", + "name": "Zugübung Bick - ZvD Bukenb/Eger ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert9a05d6e7a6a3ea787dfc4ad47c717e30", + "id": "809" + }, + { + "datum": "2023-06-18 13:00:00", + "name": "60 Jahre Uschi Rosenfeld ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 300, + "source": "gcal", + "external_id": "CSVConvert9e6431bbdf01f8a88fc43b5660cf6f63", + "id": "730" + }, + { + "datum": "2023-06-20 20:00:00", + "name": "Absturzsicherung am Wachturm mit DLK ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert2f938c573995bc9ebb01db4308ce68fc", + "id": "935" + }, + { + "datum": "2023-06-30 20:00:00", + "name": "Atemschutzstrecke Sulz ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert281c8b2db453d92f983098345cce2e17", + "id": "735" + }, + { + "datum": "2023-07-07 20:00:00", + "name": "Netze BW Brandcontainer ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert0dae1bc187a7f8e65e45ed9d9865f414", + "id": "725" + }, + { + "datum": "2023-07-11 20:00:00", + "name": "Besprechung Abt.-Kdt. in Ros ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert998e8b77a84ee438ee13f62d172eaaed", + "id": "916" + }, + { + "datum": "2023-07-13 20:00:00", + "name": "Zugübung Leid - ZvD Habicht/Schäfer ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert83dc1b6615860890d77a575aaa3e8e7a", + "id": "922" + }, + { + "datum": "2023-07-14 20:00:00", + "name": "Ausleuchten (Stativ, Powermoon, TSF-W) ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc541d4cabce8f17aeeddef1aa915b7bc", + "id": "815" + }, + { + "datum": "2023-07-18 20:00:00", + "name": "GA Hlgz ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertbfb1a8adfaf9051abcb88900a777eb2f", + "id": "813" + }, + { + "datum": "2023-09-01 20:00:00", + "name": "Übung mit Altersabteilung am Wachturm mit DLK ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertf838ef75664ab9083d2dc211eca54c99", + "id": "718" + }, + { + "datum": "2023-09-19 20:00:00", + "name": "Absturzsicherung ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert68ffe9e0581e19c568bed0b2363f5219", + "id": "927" + }, + { + "datum": "2023-09-29 20:00:00", + "name": "Zugübung Täb - ZvD Holweger/Kopf ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertaeef7a93360b9e80571c9fb5acd9c2b9", + "id": "739" + }, + { + "datum": "2023-10-06 20:00:00", + "name": "Gr. A Überraschungsübung + Gr. B Quiz-App ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert25d1c085fe6c5387f82d0e1519bb18bb", + "id": "703" + }, + { + "datum": "2023-10-07 14:00:00", + "name": "Hauptübung Täbingen ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertdd0df3b7c092e7e3d11e92504380b4d0", + "id": "909" + }, + { + "datum": "2023-10-20 20:00:00", + "name": "Übung in Bick ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert4c8f8424b979429540ccc9dd92a4f7d4", + "id": "835" + }, + { + "datum": "2023-10-27 20:00:00", + "name": "Zugübung Britt - ZvD Ziegler/Huber ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverteccb637cabb6b82ebf1d8ea270fa6271", + "id": "933" + }, + { + "datum": "2023-11-03 20:00:00", + "name": "Gr. B Überraschungsübung + Gr. A Quiz-App ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertccf06f2ddd288488b4b827de0f47e7df", + "id": "891" + }, + { + "datum": "2023-11-10 19:00:00", + "name": "GA Rosenfeld ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConverta4b858d2aea58e4fbcbeabe64878f8f8", + "id": "742" + }, + { + "datum": "2023-11-18 00:00:00", + "name": "2-tägige Klausurtagung Schwarzwald ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 1440, + "source": "gcal", + "external_id": "CSVConvertb4c21121642302fd1f2408f63b6c3333", + "id": "800" + }, + { + "datum": "2023-11-19 10:00:00", + "name": "Volkstrauertag ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert9f1640eed8d4cc4054ce582763af7b61", + "id": "826" + }, + { + "datum": "2023-11-24 20:00:00", + "name": "GF/ZF-Besprechung in Ros ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert13625d3ce9aa12784ba27ae4fce4eab2", + "id": "851" + }, + { + "datum": "2023-12-01 20:00:00", + "name": "UVV ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertd3ff2564c840227a04e936e38ffac397", + "id": "923" + }, + { + "datum": "2023-12-08 18:00:00", + "name": "Arbeitseinsatz ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertc31945d5b4233323c63693a4f02d60f1", + "id": "757" + }, + { + "datum": "2023-12-30 20:00:00", + "name": "Übungsplanaufstellung 2024 ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertdc8f25c9396f3ec94df26b52974dadf7", + "id": "807" + }, + { + "datum": "2024-01-12 20:00:00", + "name": "Geräteprüfung / Hydrantenkontrolle ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvert36bb65c1c8f834f23d4d12a0e7bd94f8", + "id": "781" + }, + { + "datum": "2024-01-19 20:00:00", + "name": "Abteilungsversammlung ", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehr Magazin Brittheim", + "dauer": 120, + "source": "gcal", + "external_id": "CSVConvertd84bdff21d0c36bb3006570dcc0569a1", + "id": "915" + }, + { + "datum": "2024-02-02 20:00:00", + "name": "Zirkeltraining TSF-W / ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "5ibu9n1l982g4df82fcvg2nuhv@google.com", + "id": "721" + }, + { + "datum": "2024-03-01 20:00:00", + "name": "Rettung aus unwegsamen Gelände", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "15n8uvoflunhdnmud6tg37c1fg@google.com", + "id": "873" + }, + { + "datum": "2024-03-15 19:00:00", + "name": "Hauptversammlung Leidrigen", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "50c9o7lpbcp9h1vdqdntpvml9s@google.com", + "id": "872" + }, + { + "datum": "2024-03-19 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "0e073o458k6rcpm38fog5dh57t@google.com", + "id": "788" + }, + { + "datum": "2024-03-22 20:00:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "75inis3hnmusphiusi9cvqv84d@google.com", + "id": "746" + }, + { + "datum": "2024-04-05 20:00:00", + "name": "AGT-Training / Saugstellen Ros", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "4v57p2acst45jvlnlvt933g4ns@google.com", + "id": "836" + }, + { + "datum": "2024-04-12 20:00:00", + "name": "Zugübung Brittheim ZF Leopold/Traub", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "5gag8o5b5113j43bupkar7mbo9@google.com", + "id": "931" + }, + { + "datum": "2024-04-16 20:00:00", + "name": "GA in Bick", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "748ir958jhlaiqtdntuv2ivfqv@google.com", + "id": "708" + }, + { + "datum": "2024-04-20 13:00:00", + "name": "KFV-Versammlung in Ros", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 300, + "source": "gcal", + "external_id": "42b18jfredu66nasspvf11dla5@google.com", + "id": "830" + }, + { + "datum": "2024-04-30 18:00:00", + "name": "Maibaum", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 600, + "source": "gcal", + "external_id": "02ulgah9n9egt2qm24g1vkhib1@google.com", + "id": "751" + }, + { + "datum": "2024-05-03 20:00:00", + "name": "Zugübung Hlgz ZF Bukenberger/Eger", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "6ki15h3oc9mn0tgt3k5gb8vs67@google.com", + "id": "716" + }, + { + "datum": "2024-05-10 20:00:00", + "name": "Gr. A Löschangriff Staffel", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "5tki9erje2g23ost223u1h8rgn@google.com", + "id": "719" + }, + { + "datum": "2024-05-10 20:00:00", + "name": "Gr. B Funkübung ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "7dogfnobigd4a1lntrj9646uua@google.com", + "id": "928" + }, + { + "datum": "2024-05-14 20:00:00", + "name": "Absturzsicherung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "24joipadic06cab8g0gld1cjh5@google.com", + "id": "898" + }, + { + "datum": "2024-06-07 20:00:00", + "name": "Gr. B Löschangriff Staffel", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "7a7bn8v2orc90tafm67c7l8lpv@google.com", + "id": "785" + }, + { + "datum": "2024-06-07 20:00:00", + "name": "Gr. A Funkübung ELW", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "2f6g5ok69dqo0s83tevr8ibjmo@google.com", + "id": "843" + }, + { + "datum": "2024-06-13 20:00:00", + "name": "Zugübung Rosenfeld ZF Kopf/Schäfer", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "5nntod4ioru2dk996dnfvsv5t1@google.com", + "id": "806" + }, + { + "datum": "2024-06-21 20:00:00", + "name": "Atemschutzstrecke Sulz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "4iorjogjo5qehk07rik6v3b037@google.com", + "id": "885" + }, + { + "datum": "2024-06-29 13:00:00", + "name": "Fototermin Jubiläum", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 240, + "source": "gcal", + "external_id": "12f3k8bvbthrfatfqglkifc6aj@google.com", + "id": "754" + }, + { + "datum": "2024-07-05 18:00:00", + "name": "Kindi-Übung und Grillabend mit Juckie + DLK", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 240, + "source": "gcal", + "external_id": "0986ie5kfhcaa1dfgsfnkfh8ot@google.com", + "id": "831" + }, + { + "datum": "2024-07-09 20:00:00", + "name": "Besprechung Kdt. + Abt-Kdt.", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "4vofupgu53c3jvp7af220idqmb@google.com", + "id": "743" + }, + { + "datum": "2024-07-16 20:00:00", + "name": "GA in Täb", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "6lt8rnqja4ru59pno4dfpgqjo7@google.com", + "id": "796" + }, + { + "datum": "2024-07-19 20:00:00", + "name": "Zugübung Bickelsberg ZF Ziegler/Huber", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "225av5cgnjqmo45e37aajf9ghe@google.com", + "id": "773" + }, + { + "datum": "2024-09-06 20:00:00", + "name": "Feuerlöschertraining mit AH", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "1f9qid2kg04nf7kmri58937efq@google.com", + "id": "709" + }, + { + "datum": "2024-09-19 18:30:00", + "name": "JuFeu Hlgz", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 150, + "source": "gcal", + "external_id": "0mgmqhmn30hn5co3t0b21b0ms4@google.com", + "id": "805" + }, + { + "datum": "2024-09-20 20:00:00", + "name": "Zugübung Leidringen ZF Fuoß/Faiss", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "2dhbrqg3flvdnlh5aqjvej3l76@google.com", + "id": "834" + }, + { + "datum": "2024-09-27 19:00:00", + "name": "Arbeitsdienst Kuchen von Michael/Carmen", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "21l4jnnec59pvbsm8m9vgj5j64@google.com", + "id": "733" + }, + { + "datum": "2024-10-01 20:00:00", + "name": "Absturzsicherung mit DLK", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Hosi", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "ckq3copk68sj0b9h6lgm8b9k69h6cbb270sj2bb26dgjee1mchhm6c9gc8@google.com", + "id": "723" + }, + { + "datum": "2024-10-04 20:00:00", + "name": "Gr. A Überraschungsübung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "6h4ul0lnol71ikppf4qbic34ku@google.com", + "id": "764" + }, + { + "datum": "2024-10-04 20:00:00", + "name": "Gr. B Quizapp", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "6419qsvrnp2fr3kcr950s7iqpr@google.com", + "id": "767" + }, + { + "datum": "2024-10-10 18:30:00", + "name": "JuFeu RTH Nachtlandung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 150, + "source": "gcal", + "external_id": "27deph0qi12c72ifkdl6238hjb@google.com", + "id": "880" + }, + { + "datum": "2024-10-18 20:00:00", + "name": "Zugübung Täbingen ZF Holweger/Wagner", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Zug", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "2glo2ol9o3ti7o7tppafk7j68d@google.com", + "id": "793" + }, + { + "datum": "2024-10-24 18:30:00", + "name": "JuFeu RTH Nachtlandung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 150, + "source": "gcal", + "external_id": "6il09apfvjli13oj0k8nbl0rss@google.com", + "id": "750" + }, + { + "datum": "2024-10-25 20:00:00", + "name": "Übung mit Bick in Bri", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "373ms09knelfsmte0mgoqododb@google.com", + "id": "930" + }, { "id": "599", "datum": "2024-10-26 15:00:00", @@ -9,12 +2495,114 @@ "send": "0" }, { - "id": "600", - "datum": "2025-02-07 20:00:00", - "name": "Fahrzeugkunde und Ausleuchten", - "veranstalter": "Harry und Valentin", + "datum": "2024-10-26 15:00:00", + "name": "Ausflug by Matthias Weisser & Co.", + "veranstalter": "Feuerwehr Rosenfeld", "Gruppe": "Alle", - "send": "0" + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 660, + "source": "gcal", + "external_id": "5709gckeer85r634sjh927ejfr@google.com", + "id": "852" + }, + { + "datum": "2024-11-08 19:00:00", + "name": "GA in Leidr", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "0ftl8pbdkclfg3et81mifrl7i2@google.com", + "id": "841" + }, + { + "datum": "2024-11-15 20:00:00", + "name": "Gr. B Überraschungsübung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "6008p0hsjg2j3jsrft60172rhi@google.com", + "id": "740" + }, + { + "datum": "2024-11-15 20:00:00", + "name": "Gr. A Quizapp", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "544s25vbernpp0mhgstic6602i@google.com", + "id": "747" + }, + { + "datum": "2024-11-17 09:00:00", + "name": "Volkstrauertag", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 60, + "source": "gcal", + "external_id": "4coesf7j6frfnfev043drm9eom@google.com", + "id": "732" + }, + { + "datum": "2024-12-05 18:30:00", + "name": "JuFeu Jahresabschluss in Bri", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 150, + "source": "gcal", + "external_id": "15sckt460opfubtiednpjuirok@google.com", + "id": "818" + }, + { + "datum": "2024-12-06 20:00:00", + "name": "Erste Hilfe in Ros", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "3k8f5cktk8vjab1o2e4i9rlfnb@google.com", + "id": "777" + }, + { + "datum": "2024-12-27 20:00:00", + "name": "Dienstplanaufstellung 2025", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "60puo2fhu4hsvdjm7s6m3i1ki2@google.com", + "id": "892" + }, + { + "datum": "2025-01-10 20:00:00", + "name": "Abteilungsversammlung", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "0n9rkimamn5m7sq3i6hjetpj2v@google.com", + "id": "720" + }, + { + "datum": "2025-01-17 20:00:00", + "name": "Hydrantenkontrolle", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 120, + "source": "gcal", + "external_id": "06qomieeq9fvls9tn49vi6sucn@google.com", + "id": "871" }, { "id": "601", @@ -24,6 +2612,14 @@ "Gruppe": "Alle", "send": "0" }, + { + "id": "600", + "datum": "2025-02-07 20:00:00", + "name": "Fahrzeugkunde und Ausleuchten", + "veranstalter": "Harry und Valentin", + "Gruppe": "Alle", + "send": "0" + }, { "id": "602", "datum": "2025-02-07 20:00:00", @@ -216,6 +2812,17 @@ "Gruppe": "Hosi", "send": "0" }, + { + "datum": "2025-07-04 18:00:00", + "name": "Kinderfeuerwehr", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 60, + "source": "gcal", + "external_id": "1s52pp09j456qpj144glfpcjsn@google.com", + "id": "893" + }, { "id": "626", "datum": "2025-07-04 20:00:00", @@ -224,6 +2831,17 @@ "Gruppe": "Alle", "send": "0" }, + { + "datum": "2025-07-04 20:00:00", + "name": "Arbeitsdient mit anschließendem Grillen", + "veranstalter": "Feuerwehr Rosenfeld", + "Gruppe": "Alle", + "ort": "Feuerwehrhaus Rosenfeld", + "dauer": 180, + "source": "gcal", + "external_id": "4f2ho61d2l8f4jp322b29coaui@google.com", + "id": "761" + }, { "id": "627", "datum": "2025-07-08 20:00:00", @@ -793,7 +3411,7 @@ "send": "0" } ], - "stand": "2026-04-26 22:42:22", + "stand": "2026-05-17 19:36:14", "Gruppen": { "A": [ "Michael Baumann", @@ -823,4 +3441,4 @@ "Amelie Hoffmann" ] } -} +} \ No newline at end of file diff --git a/scripts/sync-gcal-headless.js b/scripts/sync-gcal-headless.js new file mode 100644 index 0000000..e631562 --- /dev/null +++ b/scripts/sync-gcal-headless.js @@ -0,0 +1,174 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { parseString } from 'cal-parser'; + +// Constants +const GCAL_ICS_URL = "https://calendar.google.com/calendar/ical/florian.brittheim%40web.de/public/basic.ics"; + +// Re-implementing necessary date logic to avoid dependency issues in headless script +const formatDate = (date) => { + if (!date) return ''; + const d = new Date(date); + const pad = n => n.toString().padStart(2, '0'); + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; +}; + +/** + * Sanitizes and maps a GCal event to the local termin format. + */ +function sanitizeEvent(event) { + const title = event.summary ? event.summary.value : "Unbenannter Termin"; + const location = event.location ? event.location.value : "Feuerwehrhaus Rosenfeld"; + + let gruppe = "Alle"; + const lowerTitle = title.toLowerCase(); + if (lowerTitle.includes("zugübung")) gruppe = "Zug"; + else if (lowerTitle.includes("absturzsicherung")) gruppe = "Hosi"; + + const startDate = event.dtstart ? event.dtstart.value : new Date(); + const endDate = event.dtend ? event.dtend.value : null; + const duration = (endDate && startDate) ? Math.round((endDate.getTime() - startDate.getTime()) / 60000) : 120; + + // Return ONLY allowed fields to prevent leakage + return { + datum: formatDate(startDate), + name: title, + veranstalter: "Feuerwehr Rosenfeld", + Gruppe: gruppe, + ort: location, + dauer: duration, + source: "gcal", + external_id: event.uid ? event.uid.value : `gcal-${startDate.getTime()}-${title.substring(0, 10)}` + }; +} + +/** + * Core sync logic, extracted for testability. + */ +export async function syncGCalLogic(localData, icsString) { + const data = { ...localData }; + const localTermine = data.termine || []; + + console.log(`[Fetch] Parsing iCal string...`); + const { events } = parseString(icsString); + console.log(`[Fetch] Fetched external events: ${events.length}`); + + if (events.length === 0) { + console.warn('[Fetch] GCal feed is empty. Skipping merge to prevent data loss.'); + return { data, changed: false }; + } + + // 3. Map and Sanitize GCal events + const externalTermine = events.map(sanitizeEvent); + + // 4. Merge logic + console.log(`[Merge] Starting merge with ${localTermine.length} local appointments...`); + let addedCount = 0; + let updatedCount = 0; + const merged = [...localTermine]; + let currentMaxId = Math.max(0, ...localTermine.map((t) => parseInt(t.id) || 0)); + + externalTermine.forEach(ext => { + let existingIndex = -1; + + // UID match + if (ext.external_id) { + existingIndex = merged.findIndex(l => l.external_id === ext.external_id); + } + + // Title + Date match fallback + if (existingIndex === -1) { + const normalize = (s) => s.toLowerCase().replace(/\s/g, ""); + const extKey = `${ext.datum.substring(0, 16)}|${normalize(ext.name)}`; + + existingIndex = merged.findIndex(l => { + const lKey = `${l.datum.substring(0, 16)}|${normalize(l.name)}`; + return lKey === extKey; + }); + } + + if (existingIndex !== -1) { + const l = merged[existingIndex]; + const hasChanged = l.ort !== ext.ort || + l.dauer !== ext.dauer || + l.Gruppe !== ext.Gruppe || + l.veranstalter !== ext.veranstalter || + l.datum !== ext.datum || + l.name !== ext.name; + + if (hasChanged) { + updatedCount++; + merged[existingIndex] = { ...l, ...ext, id: l.id }; + } + } else { + addedCount++; + currentMaxId++; + merged.push({ ...ext, id: currentMaxId.toString() }); + } + }); + + console.log(`[Merge] Complete: ${addedCount} added, ${updatedCount} updated.`); + + if (addedCount > 0 || updatedCount > 0) { + // 5. Sort by date + console.log(`[Sort] Sorting ${merged.length} appointments by date...`); + merged.sort((a, b) => new Date(a.datum) - new Date(b.datum)); + + data.termine = merged; + data.stand = formatDate(new Date()); + return { data, changed: true }; + } + + return { data, changed: false }; +} + +async function run() { + console.log('--- GCal Headless Sync Started ---'); + + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + const DATA_FILE = path.resolve(__dirname, '../public/ffwtool/termine.json'); + + try { + // 1. Read local data + console.log(`[Read] Loading local data from ${DATA_FILE}`); + const rawData = fs.readFileSync(DATA_FILE, 'utf8'); + const localData = JSON.parse(rawData); + + // 2. Fetch GCal + console.log(`[Fetch] Fetching GCal from: ${GCAL_ICS_URL}`); + const response = await fetch(GCAL_ICS_URL); + if (!response.ok) { + console.error(`[Fetch] Failed: ${response.status} ${response.statusText}`); + process.exit(1); + } + + const icsString = await response.text(); + + // 3. Sync Logic + const { data, changed } = await syncGCalLogic(localData, icsString); + + // 4. Save back + if (changed) { + console.log(`[Save] Writing updates to ${DATA_FILE}`); + fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2), 'utf8'); + console.log(`[Save] Done.`); + } else { + console.log('[Save] No changes detected. Skipping write.'); + } + + console.log('--- GCal Headless Sync Finished Successfully ---'); + process.exit(0); + + } catch (error) { + console.error('--- GCal Headless Sync FAILED ---'); + console.error(error); + process.exit(1); + } +} + +// Only run if called directly +if (process.argv[1] === fileURLToPath(import.meta.url)) { + run(); +} diff --git a/scripts/sync-gcal-headless.test.js b/scripts/sync-gcal-headless.test.js new file mode 100644 index 0000000..3b3c94f --- /dev/null +++ b/scripts/sync-gcal-headless.test.js @@ -0,0 +1,141 @@ +import { describe, it, expect, vi } from 'vitest'; +import { syncGCalLogic } from './sync-gcal-headless.js'; +import * as calParser from 'cal-parser'; + +vi.mock('cal-parser', () => ({ + parseString: vi.fn() +})); + +describe('syncGCalLogic', () => { + const localDataTemplate = { + stand: "2026-05-17 10:00:00", + termine: [ + { + id: "1", + datum: "2026-06-01 19:00:00", + name: "Existing Event", + veranstalter: "Feuerwehr Rosenfeld", + Gruppe: "Alle", + ort: "Feuerwehrhaus", + dauer: 120, + source: "manual" + } + ] + }; + + it('adds new events with unique IDs', async () => { + // We use a specific date that we can predict the format of + const startDate = new Date(2026, 5, 15, 18, 0, 0); // June 15, 18:00 + + calParser.parseString.mockReturnValue({ + events: [ + { + uid: { value: 'uid-2' }, + summary: { value: 'New GCal Event' }, + dtstart: { value: startDate }, + dtend: { value: new Date(startDate.getTime() + 2 * 3600000) }, + location: { value: 'Training Ground' } + } + ] + }); + + const { data, changed } = await syncGCalLogic(localDataTemplate, 'ics-string'); + + expect(changed).toBe(true); + expect(data.termine.length).toBe(2); + const newEvent = data.termine.find(t => t.name === 'New GCal Event'); + expect(newEvent).toBeDefined(); + expect(newEvent.id).toBe('2'); + expect(newEvent.ort).toBe('Training Ground'); + }); + + it('updates existing events matched by title and date', async () => { + // Existing event is at 2026-06-01 19:00:00 + const startDate = new Date(2026, 5, 1, 19, 0, 0); + + calParser.parseString.mockReturnValue({ + events: [ + { + uid: { value: 'uid-updated' }, + summary: { value: 'Existing Event' }, + dtstart: { value: startDate }, + dtend: { value: new Date(startDate.getTime() + 3 * 3600000) }, // Changed duration + location: { value: 'Updated Location' } + } + ] + }); + + const { data, changed } = await syncGCalLogic(localDataTemplate, 'ics-string'); + + expect(changed).toBe(true); + expect(data.termine.length).toBe(1); + expect(data.termine[0].id).toBe('1'); + expect(data.termine[0].ort).toBe('Updated Location'); + expect(data.termine[0].dauer).toBe(180); + }); + + it('sorts appointments by date after merge', async () => { + const dateLater = new Date(2026, 6, 1, 10, 0, 0); + const dateEarlier = new Date(2026, 4, 1, 10, 0, 0); + + calParser.parseString.mockReturnValue({ + events: [ + { + uid: { value: 'uid-later' }, + summary: { value: 'Later Event' }, + dtstart: { value: dateLater } + }, + { + uid: { value: 'uid-earlier' }, + summary: { value: 'Earlier Event' }, + dtstart: { value: dateEarlier } + } + ] + }); + + const { data, changed } = await syncGCalLogic(localDataTemplate, 'ics-string'); + + expect(changed).toBe(true); + expect(data.termine.length).toBe(3); + expect(data.termine[0].name).toBe('Earlier Event'); + expect(data.termine[1].name).toBe('Existing Event'); + expect(data.termine[2].name).toBe('Later Event'); + }); + + it('handles empty GCal feed gracefully (Task 3)', async () => { + calParser.parseString.mockReturnValue({ + events: [] + }); + + const { data, changed } = await syncGCalLogic(localDataTemplate, 'ics-string'); + + expect(changed).toBe(false); + expect(data.termine.length).toBe(1); + expect(data.termine).toEqual(localDataTemplate.termine); + }); + + it('sanitizes external fields and prevents leakage', async () => { + const startDate = new Date(2026, 7, 1, 10, 0, 0); + + calParser.parseString.mockReturnValue({ + events: [ + { + uid: { value: 'uid-leak' }, + summary: { value: 'Clean Event' }, + dtstart: { value: startDate }, + secret_field: "should not be here", + other_garbage: { stuff: 123 } + } + ] + }); + + const { data, changed } = await syncGCalLogic(localDataTemplate, 'ics-string'); + + const leakedEvent = data.termine.find(t => t.name === 'Clean Event'); + expect(leakedEvent.secret_field).toBeUndefined(); + expect(leakedEvent.other_garbage).toBeUndefined(); + expect(Object.keys(leakedEvent).sort()).toEqual([ + 'Gruppe', 'datum', 'dauer', 'external_id', 'id', 'name', 'ort', 'source', 'veranstalter' + ].sort()); + }); +}); diff --git a/src/utils/gcal.js b/src/utils/gcal.js index efe7518..147500f 100644 --- a/src/utils/gcal.js +++ b/src/utils/gcal.js @@ -25,7 +25,8 @@ export async function syncGoogleCalendar(defaultOrt, defaultDauer) { // Auto-tagging logic let gruppe = "Alle"; const lowerTitle = title.toLowerCase(); - if (lowerTitle.includes("zug�bung")) { + if (lowerTitle.includes("zugübung")) { + gruppe = "Zug"; } else if (lowerTitle.includes("absturzsicherung")) { gruppe = "Hosi";