index.php (23738B)
1 <?php
2
3 /* SPDX-License-Identifier: AGPL-3.0-or-later
4 * SPDX-FileCopyrightText: 2025 JayVii <jayvii+kontra[AT]posteo[DOT]de>
5 */
6
7 /* Loading configuration */
8 $config = json_decode(
9 file_get_contents("./news-sources.json"),
10 true
11 );
12
13 /* OPML Generator */
14
15 /* Check for user input */
16 if (!is_null($_POST["action"])) {
17
18 /* Generate OPML */
19 if ($_POST["action"] === "gen_opml") {
20
21 /* Gather news sources from selection */
22 $input_keys = preg_grep(
23 "/^source-[0-9]+$/",
24 array_keys($_POST)
25 );
26 $sources = array();
27 foreach ($input_keys as $key) {
28 array_push(
29 $sources,
30 $config["sources"][$_POST[$key]]
31 );
32 }
33
34 $exp_hash = md5(serialize($sources));
35 $file_name = "kontra_" . date("Y-m-d") . "_" . $exp_hash . ".opml";
36
37 /* Set Download and content type headers */
38 header('Content-Type: application/xml; charset=UTF-8');
39 header(
40 'Content-Disposition: Attachment;filename="' . $file_name . '"'
41 );
42
43 /* Build OPML file */
44 ?>
45
46 <opml version="2.0">
47 <head>
48 <title>Nachrichten-Export von Kontra - der linke Newsaggregator</title>
49 </head>
50 <body>
51
52 <?php
53
54 /* Cycle through each source and write source entry */
55 foreach ($sources as $source) {
56
57 /* Create category list */
58 $categories = array();
59 foreach ($source["categories"] as $category) {
60 array_push(
61 $categories,
62 $config["categories"][$category]["name"]
63 );
64 }
65
66 ?>
67
68 <outline
69 title="<?php echo $source["title"]; ?>"
70 text="<?php echo $source["title"]; ?>"
71 category="<?php echo implode(",", $categories); ?>"
72 xmlUrl="<?php echo $source["rss"]; ?>"
73 />
74
75 <?php
76
77 } // foreach-source
78
79 ?>
80
81 </body>
82 </opml>
83
84 <?php
85
86 die();
87 } // if-action
88 } // if-input
89
90 ?>
91
92 <!doctype html>
93 <html>
94
95 <!-- Head -->
96 <head>
97 <meta charset=utf-8>
98 <meta name=viewport content="width=device-width,initial-scale=1">
99 <link rel=icon href=assets/img/favicon.png type=image/png>
100 <link rel=icon href=assets/img/favicon.ico type=x-image/ico>
101 <link rel=stylesheet href=assets/css/simple.min.css media=all>
102 <link rel=stylesheet href=assets/css/custom.css>
103 <script async src=assets/js/filter_engines.js></script>
104 <title>Kontra - Der Linke News Aggregator</title>
105 </head>
106
107 <!-- Body -->
108 <body>
109
110 <!-- Header -->
111 <header>
112 <nav>
113 <a href="#sources">
114 Nachrichten
115 </a>
116 <a href="#faqs">
117 Was ist das?
118 </a>
119 <a href="https://src.jayvii.de/pub/kontra/" target="_blank">
120 Hilf mit!
121 </a>
122 </nav>
123 <h1>Kontra</h1>
124 <p>Der Linke News Aggregator</p>
125 </header>
126
127 <!-- Description -->
128 <div class="fullheight">
129 <div class="description">
130 <strong style="font-size: 133%;">
131 Nachrichten von Links! Ohne Tracking, ohne Tech-Konzerne und
132 ohne algorithmisches Framing.
133 </strong>
134 <p>
135 Auf dieser Seite befinden sich viele seriöse Medienquellen
136 aus dem <em>linken Spektrum</em> von Zeitungen, Magazinen
137 und sonstigen journalistischen Veröffentlichungen, aus denen
138 sich persönliche Nachrichten-Feeds erstellt werden lassen.
139 </p>
140 </div>
141 <div class="buttonrow">
142 <a href="#usage" class="button c2">
143 Wie funktioniert das?
144 </a>
145 <a href="#sources" class="button c2">
146 Zu den Nachrichten!
147 </a>
148 </div>
149 </div>
150
151 <div class="fullheight screenshots" id="usage">
152 <h3>Was ist Kontra?</h3>
153 <figure class="buttonrow">
154 <img style="flex:26%;min-width:91px;margin:2.5px;" src="assets/img/applications/gfeeds_mobile.jpg">
155 <img style="flex:72%;min-width:252px;margin:2.5px;" src="assets/img/applications/gfeeds_desktop.jpg">
156 <figcaption style="width:100%;">
157 Nachrichten Feeds aus Kontra in <a href="https://gfeeds.gabmus.org/" target="_blank">Gnome Feeds</a>
158 </figcaption>
159 </figure>
160 <p>
161 Kontra versetzt Nutzer:innen in die Lage, selbstbestimmt
162 personalisierte Nachrichten-Feeds von seriösen <em>linken</em>
163 Quellen zu erstellen, um immer auf dem Laufenden zu bleiben.
164 Und das selbstverständlich
165 <strong>ohne <a href="https://de.wikipedia.org/wiki/Web_Analytics" target="_blank">Tracking</a></strong>,
166 <strong>ohne Datensammelwut</strong>,
167 <strong>ohne Konto-Zwang</strong>
168 <strong>ohne <a href="https://de.wikipedia.org/wiki/Soziales_Netzwerk_(Internet)#Kritik" target="_blank">Algorithmen</a></strong> und
169 <strong>ohne <a href="https://de.wikipedia.org/wiki/Lock-in-Effekt" target="_blank">Lock-In Effekte</a></strong>.
170 Wie das funktioniert, erfährst du <a href="#faqs">hier</a>!
171 </p>
172 <p>
173 Kontra ist ein Archiv mit aktuell
174 <?php echo count($config["sources"]); ?> Nachrichtenquellen in
175 <?php echo count($config["categories"]); ?> unterschiedlichen
176 Kategorien, aus dem sich Nutzer:innen nach ihren Interssen
177 eigene Feeds erzeugen können. Die hier herunterladbaren
178 <a href="https://de.wikipedia.org/wiki/Outline_Processor_Markup_Language" target="_blank">
179 Nachrichten-Feed Dateien
180 </a> können in beliebigen
181 <a href="https://de.wikipedia.org/wiki/Feedreader" target="_blank">
182 Feed-Readern
183 </a> eingeladen uns sofort genutzt werden!
184 Zum Beispiel in diesen
185 <a href="https://fsfe.org/freesoftware/freesoftware.de.html" target="_blank">
186 Freien
187 </a> und kostenlosen Apps für Android und iOS:
188 <ul>
189 <li><a href="https://apps.apple.com/us/app/netnewswire-rss-reader/id1480640210" target="_blank">NetNewsWire (iOS)</a></li>
190 <li><a href="https://apps.apple.com/us/app/twine-rss-reader/id6465694958" target="_blank">Twine (iOS)</a></li>
191 <li><a href="https://play.google.com/store/apps/details?id=com.nononsenseapps.feeder.play" target="_blank">Feeder (Android)</a></li>
192 <li><a href="https://play.google.com/store/apps/details?id=dev.sasikanth.rss.reader" target="_blank">Twine (Android)</a></li>
193 <li><a href="https://freshrss.org/" target="_blank">FreshRSS (Web)</a></li>
194 <li><a href="https://www.thunderbird.net/de/" target="_blank">Thunderbird (Windows, MacOS, Linux)</a></li>
195 <li><a href="https://gfeeds.gabmus.org/" target="_blank">Feeds (Linux)</a></li>
196 <li><a href="https://alternativeto.net/browse/search/?q=rss%20reader" target="_blank">und viele weitere</a>...</li>
197 </ul>
198 </p>
199 <p>
200 Ganz einfach in nur <strong>zwei Minuten</strong> loslegen!
201 Nachrichtenquellen aussuchen, Feed-Datei herunterladen, in
202 den Reader importieren und sofort informiert werden.
203 </p>
204
205 <div class="buttonrow">
206 <a href="#faqs" class="button c2">
207 Mehr erfahren
208 </a>
209 <a href="#sources" class="button c2">
210 Zu den Nachrichten!
211 </a>
212 </div>
213 </div>
214
215 <!-- Search Engine Lists -->
216 <h3 id="sources" style="margin-top:5em;">
217 Eigenen Nachrichten-Feed generieren
218 </h3>
219 <p>
220 Wähle beliebig viele Nachrichtenquellen aus der unteren Liste aus
221 und klicke auf den <strong>Nachrichten-Feed erzeugen</strong> Knopf.
222 Speichere die darauf angebotene OPML-Datei ab und importiere sie in
223 deinen RSS-Reader.
224 </p>
225 <!-- Filterbar -->
226 <input
227 id="sources_filterbar"
228 name="sources"
229 type="text"
230 placeholder="Suche nach Nachrichtenquellen oder Kategorien..."
231 oninput="filter_sources('sources_filterbar');"
232 >
233 <noscript>
234 <div class="notice">
235 <p>
236 Achtung: Die Nutzung der Suchfunktion benötigt aktiviertes
237 JavaScript. Entweder unterstützt dein Browser diese
238 Funktion nicht, oder du hast sie auf dieser Seite blockiert.
239 <strong>
240 Du kannst dennoch einen Nachrichten-Feed erzeugen, jedoch
241 ohne die Suchfunktion oben dafür nutzen zu können.
242 </strong>
243 </p>
244 </div>
245 </noscript>
246
247 <!-- Category Buttons -->
248 <details id="categories">
249 <summary>Kategorien</summary>
250
251 <div class="row">
252
253 <!-- List all configured categories -->
254 <?php
255 foreach ($config["categories"] as $category) {
256 ?>
257 <button
258 onclick="filter_category('<?php echo $category["name"]; ?>');"
259 title="<?php echo $category["description"]; ?>"
260 >
261 <?php echo "#" . $category["name"]; ?>
262 </button>
263 <?php
264 }
265 ?>
266
267 </div>
268
269 </details>
270
271 <!-- Sources List -->
272 <form id="sources-selection" method="post">
273
274 <!-- Submit button -->
275 <div class="submit-container">
276 <input type="submit" value="Nachrichten-Feed erzeugen!">
277 <a href="#sources" class="button" title="Nach oben">
278 👆 <stretch class="nomobile">Nach oben</stretch>
279 </a>
280 <a href="#faqs" class="button" title="Nach unten">
281 👇 <stretch class="nomobile">Nach unten</stretch>
282 </a>
283 </div>
284 <input type="hidden" name="action" value="gen_opml">
285 <?php
286 $cnt = 0;
287 foreach ($config["sources"] as $id => $source) {
288 $cnt++; // increase counter for POST field ID
289 ?>
290 <article>
291 <!-- Entry-Head -->
292 <h3>
293 <a href="<?php echo $source["web"]; ?>" target="_blank">
294 <?php echo $source["title"]; ?>
295 </a>
296 </h3>
297
298 <!-- Description -->
299 <p><?php echo $source["desc"]; ?></p>
300
301 <!-- Choose this Button -->
302 <input
303 type="checkbox"
304 name="<?php echo "source-" . $cnt; ?>"
305 value="<?php echo $id; ?>"
306 >
307 <label for="<?php echo $id; ?>">
308 Diese Nachrichtenquelle auswählen
309 </label>
310
311 <!-- Entry-Categories -->
312 <div class="categories">
313
314 <?php
315 /* List all categories of current entry */
316 foreach ($source["categories"] as $category) {
317 $catentry = $config["categories"][$category]
318 ?>
319 <mark title="<?php echo $catentry["description"];?>">
320 <?php echo "#" . $catentry["name"]; ?>
321 </mark>
322 <?php
323 }
324 ?>
325
326 </div>
327
328 </article>
329 <?php
330 }
331 ?>
332 </form>
333
334 <!-- FAQs / About-Section -->
335 <section id="faqs">
336
337 <h3>Was ist <em>Kontra</em>?</h3>
338
339 <details>
340 <summary>Welche Technik nutzt Kontra?</summary>
341 <p>
342 Millionen Webseiten und Online-Zeitungen weltweit bieten die
343 offene Schnittstelle
344 <a href="https://de.wikipedia.org/wiki/RSS_(Web-Feed)" target="_blank">
345 RSS
346 </a> (zu deutsch: <em>sehr einfache Verbreitung</em>) an.
347 Nahezu jeder Blog, jede Nachrichtenseite und
348 Online-Veröffentlichungen nutzen einen <em>RSS</em> Feed.
349 Das ist eine maschinenlesbare Datei, welche alle dort
350 veröffentlichte Nachrichten und einige Zusatzinformationen
351 (Veröffentlichungszeitpunkt, Autor:in, Kurzzusammenfassung,
352 usw.) enthält. RSS kann als <em>schwarzes Brett</em>
353 digitaler Medien verstanden werden.
354 </p>
355 <p>
356 Kontra stellt eben diese RSS-Feeds für alle von Nutzer:innen
357 ausgewählte Medien in einer herunterladbaren Datei zusammen,
358 die in üblichen Feedreadern (siehe:
359 <em><strong>Was sind Feedreader?</strong></em>) importiert
360 werden kann. Diese Datei basiert auf dem offenen
361 <a href="https://de.wikipedia.org/wiki/Outline_Processor_Markup_Language", target="_blank">
362 OPML
363 </a> Format und wird von nahezu allen RSS/Feed-Readern
364 verstanden. Damit gewährleistet Kontra, dass es keinen
365 sogenannten <em>Lock-In</em> Effekt gibt, der Nutzer:innen
366 an eine einzige App binden und der Wechsel zu Alternativen
367 erschwert.
368 </p>
369 <p>
370 Die angesprochenen OPML-Dateien enthalten nicht nur die
371 RSS-Feeds selbst, sondern auch alle Kategorien, die man
372 ihnen innerhalb des eigenen Feed-Readers zugewiesen hat. Die
373 OPML-Dateien aus Kontra enthalten alle Kategorie-Label, die
374 auch in der Liste sichtbar sind.
375 </p>
376 <p>
377 <strong>Kurzum:</strong> RSS und OPML sind die grundlegende
378 Technik, auf die <em>Kontra</em> setzt. Nachrichten können
379 darüber direkt von Blogs und Zeitungen bezogen werden, ohne
380 dass Dritte Einsicht darin haben. Feeds können in nahezu
381 allen Feedreadern importiert und exportiert werden. Ein
382 Wechsel von einer App zu einer anderen ist also innerhalb
383 von Sekunden möglich.
384 </p>
385 </details>
386
387 <details>
388 <summary>Was sind Feed-Reader / RSS-Reader?</summary>
389 <p>
390 Feed- oder RSS-Reader erlauben es, so genannte RSS-Feeds zu
391 <em>abonnieren</em>, um regelmäßig Nachrichten von diesen zu
392 erhalten. Das Konzept ist vergleichbar mit einem E-Mail
393 Newsletter.
394 </p>
395 <p>
396 Der Unterschied besteht darin, dass man, um einen Newsletter
397 erhalten zu können, den Versender:innen eine E-Mail Adresse
398 hinterlegen muss. Newsletter werden dann aktiv von den
399 Versender:innen an bekannte Empfänger:innen verschickt.
400 </p>
401 <p>
402 Bei RSS-Feeds ist es umgekehrt. Empfänger:innen (bzw. von
403 ihnen genutzt Feed-Reader) ziehen sich die Nachrichten von
404 den Nachrichten-Seiten oder Blogs selbst. Letztere wissen
405 dabei gar nicht, wer die Empfänger:innen sind oder wie viele
406 es letztendlich sind.
407 </p>
408 <p>
409 Der RSS-Reader ist lediglich die Software, welche die
410 Nachrichten empfängt und diese oft in einem Listen-Format
411 zum Lesen anzeigt. Es gibt eine Vielzahl wirklich guter
412 und zeitgemäßer RSS-Reader für alle möglichen Endgeräte,
413 ganz egal ob am PC, Smartphone, Tablet, E-Book-Reader oder
414 per Webbrowser.
415 </p>
416 <p>
417 Folgende RSS-Reader sind kostenlos und darüber hinaus noch
418 <a href="https://fsfe.org/freesoftware/freesoftware.de.html" target="_blank">
419 Freie, Open Source Software
420 </a>:
421 <ul>
422 <li><a href="https://apps.apple.com/us/app/netnewswire-rss-reader/id1480640210" target="_blank">NetNewsWire (iOS)</a></li>
423 <li><a href="https://apps.apple.com/us/app/twine-rss-reader/id6465694958" target="_blank">Twine (iOS)</a></li>
424 <li><a href="https://play.google.com/store/apps/details?id=com.nononsenseapps.feeder.play" target="_blank">Feeder (Android)</a></li>
425 <li><a href="https://play.google.com/store/apps/details?id=dev.sasikanth.rss.reader" target="_blank">Twine (Android)</a></li>
426 <li><a href="https://freshrss.org/" target="_blank">FreshRSS (Web)</a></li>
427 <li><a href="https://www.thunderbird.net/de/" target="_blank">Thunderbird (Windows, MacOS, Linux)</a></li>
428 <li><a href="https://gfeeds.gabmus.org/" target="_blank">Feeds (Linux)</a></li>
429 <li><a href="https://alternativeto.net/browse/search/?q=rss%20reader" target="_blank">und viele weitere</a>...</li>
430 </ul>
431 </p>
432 </details>
433
434 <details>
435 <summary>Kann ich weitere Nachrichten-Feeds abonnieren?</summary>
436 <p>
437 Ja! Gibt es Nachrichtenquellen, die nicht in Kontra
438 enthalten sind, kann man diese auch einzeln im eigenen
439 Feed-Reader abonnieren. Auch das ist sehr einfach und dauert
440 in der Regel nur wenige Sekunden.
441 </p>
442 <p>
443 Fast alle Online-Medien haben eine Unterseite, auf der sie
444 ihre RSS-Feeds auflisten. Folgende Medien sind
445 beispielsweise wegen des Fokus auf dediziert Linke Medien
446 nicht in Kontra enthalten, lassen sich aber sehr einfach
447 über einen RSS-Reader abonnieren:
448 <ul>
449 <li><a href="https://www.tagesschau.de/infoservices/rssfeeds" target="_blank">Tagesschau (ÖRR)</a></li>
450 <li><a href="https://www.deutschlandfunk.de/rss-angebot-102.html" target="_blank">Deutschlandfunk (ÖRR)</a></li>
451 <li><a href="https://www.sueddeutsche.de/service/updates-mit-rss-uebersicht-aller-rss-feeds-fuer-sz-de-sz-magazin-und-jetzt-de-1.393950" target="_blank">Süddeutsche Zeitung</a></li>
452 </ul>
453 </p>
454 </details>
455
456 <details>
457 <summary>Ist Kontra kostenlos?</summary>
458 <p>
459 Ja! Kontra ist und bleibt kostenlos. Es ist lediglich ein
460 kleines privates Software-Projekt einer Einzelperson.
461 </p>
462 <p>
463 Zudem wird Kontra als
464 <a href="https://fsfe.org/freesoftware/freesoftware.de.html" target="_blank">
465 Freie, Open Source Software
466 </a>
467 entwickelt. Der Programm-Code kann also von allen jederzeit
468 eingesehen werden. Verbesserungsvorschläge oder eigene
469 Code-Beiträge sind stets willkommen. Es ist auch erlaubt,
470 eigene Projekte auf Kontra aufzubauen. Diese müssen jedoch
471 ebenfalls unter einer Freien Software-Lizenz stehen.
472 </p>
473 <p>
474 Du möchtest helfen?
475 <a href="https://src.jayvii.de/pub/kontra/" target="_blank">
476 Hier
477 </a> findest du mehr Informationen dazu.
478 </p>
479 </details>
480
481 <details>
482 <summary>Ist das <em>Abonnieren</em> eines RSS-Feed kostenlos?</summary>
483 <p>
484 Ja! Allerdings kann es sein, dass einige der in den
485 Nachrichten-Feeds angebotenen Artikel hinter einer
486 Bezahlschranke liegen, also oft nicht in voller Länge
487 gelesen werden können, ohne ein Abonnement bei der
488 jeweiligen Online-Publikation, bzw. ein Zeitungsabonnement
489 abzuschließen.
490 </p>
491 <p>
492 Kontra kennzeichnet Nachrichtenquellen, bei denen einige
493 Artikel hinter einer Bezahlschranke liegen können.
494 Nachrichtenquellen, die niemals eine Bezahlschranke nutzen
495 sind ebenfalls in einer eigenen Kategorie.
496 </p>
497 </details>
498
499 <details>
500 <summary>Sammelt Kontra meine Daten?</summary>
501 <p>
502 Nein! Kontra sammelt keinerlei Datein über Personen und
503 Geräte, die diese Seite besuchen und Kontra nutzen.
504 Technisch bedingt, wird bei jedem Aufruf <em>jeder</em>
505 Webseite im Internet mindestens die eigene IP-Adresse und
506 oft noch weitere Informationen über das Betriebssystem, den
507 Webbrowser, bzw. das verwendete Gerät übermittelt. Kontra
508 speichert <strong>keine</strong> dieser Informationen.
509 </p>
510 <p>
511 Zudem stellt Kontra lediglich das Archiv von RSS-Feeds zur
512 Verfügung. Kontra speichert außerdem keine Informationen
513 darüber, welche Nachrichtenquellen von Nutzer:innen
514 ausgewählt werden.
515 </p>
516 <p>
517 Mit dem Herunterladen der Feed-Datei endet der
518 Datenaustausch zwischen den Nutzer:innen und Kontra. Kontra
519 hat technisch bedingt keinen Einblick darin, ob und welche
520 Nachrichten Nutzende in einen Feedreader einlesen oder
521 welche Nachrichten tatsächlich von Nutzer:innen gelesen
522 werden. Das liegt daran, dass die Nachrichten
523 <strong>direkt</strong> und ohne Umwege von den jeweiligen
524 Nachrichtenseiten kommen und zu keinem Zeitpunkt über Kontra
525 laufen.
526 </p>
527 </details>
528
529
530 </section>
531
532 </body>
533
534 </html>