summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-04-30 19:44:08 +0200
committerWojtek Kosior <koszko@koszko.org>2022-04-30 19:44:08 +0200
commitb3c0f821cf03daa79be4cf57e79f6428acd38177 (patch)
tree7c0a974b1732559ffb136359f0e62585799678e5
parentb95455c255523cc1aa9f061de26e75c8a53c2c06 (diff)
downloaddigital-freedom-hints-b3c0f821cf03daa79be4cf57e79f6428acd38177.tar.gz
digital-freedom-hints-b3c0f821cf03daa79be4cf57e79f6428acd38177.zip
make it useful
-rwxr-xr-xformat.py124
-rw-r--r--hints.json90
2 files changed, 202 insertions, 12 deletions
diff --git a/format.py b/format.py
new file mode 100755
index 0000000..7873494
--- /dev/null
+++ b/format.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+
+# SPDX-License-Identifier: CC0-1.0
+#
+# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org>
+#
+# Available under the terms of Creative Commons Zero v1.0 Universal.
+
+import json
+import random
+import click
+import sys
+from pathlib import Path
+
+MAX_WIDTH = 80
+INDENT = 3
+
+here = Path(__file__).resolve().parent
+
+trans_suggestions = {
+ 'en': 'suggestions',
+ 'pl': 'sugestie'
+}
+
+trans_hint = {
+ 'en': 'Random digital freedom hint',
+ 'pl': 'Losowa wskazówka dla wolności cyfrowej'
+}
+
+trans_note = {
+ 'en': 'FSF concerns',
+ 'pl': 'zastrzeżenia FSF'
+}
+
+no_dangling_chars_langs = {'pl'}
+
+def wrap_text_block(text, max_width, forbid_dangling_chars=False,
+ subsequent_indent=0):
+ lines = []
+
+ for paragraph in text.split('\n'):
+ line = ''
+ accumulated_word = ''
+
+ for word in paragraph.split(' '):
+ if not word:
+ continue
+
+ accumulated_word += word
+
+ if forbid_dangling_chars and len(accumulated_word) == 1:
+ accumulated_word += ' '
+ continue
+
+ if len(line) + len(accumulated_word) + 1 <= max_width:
+ if line:
+ line += ' '
+ line += accumulated_word
+ else:
+ lines.append(line)
+ line = ' ' * subsequent_indent + accumulated_word
+
+ accumulated_word = ''
+
+ if line and line != ' ' * subsequent_indent:
+ lines.append(line)
+ line = ''
+
+ return lines
+
+def format_hint(hint, hint_id, langs, max_width=MAX_WIDTH, indent=INDENT):
+ lines = []
+
+ for lang in langs:
+ lines.append(f'{trans_hint[lang]} #{hint_id}: {hint["name"][lang]}')
+
+ block = wrap_text_block(hint['text'][lang], max_width - indent,
+ lang in no_dangling_chars_langs)
+
+ lines.extend(' ' * indent + l for l in block)
+
+ suggested = hint.get('suggested')
+ if suggested:
+ lines.append('/'.join(trans_suggestions[l] for l in langs) + ':')
+
+ for sug_id, sug in enumerate(suggested):
+ sug_line = f'{sug_id + 1}. {sug["name"]} <{sug["url"]}>'
+ block = wrap_text_block(sug_line, max_width,
+ lang in no_dangling_chars_langs, indent)
+ lines.extend(block)
+
+ note = sug.get('note')
+ if not note:
+ continue
+
+ for lang in langs:
+ block = wrap_text_block(f'{trans_note[lang]}: {note[lang]}',
+ max_width - indent,
+ lang in no_dangling_chars_langs, indent)
+
+ lines.extend(' ' * indent + l for l in block)
+
+ return '\n'.join(lines)
+
+hints = json.load((here / 'hints.json').open())
+
+@click.command()
+@click.option('-i', '--hint-id', default='-1', type=click.types.INT,
+ show_default=True, help='which hint to format (-1 for random)')
+def main(hint_id):
+ if hint_id == -1:
+ [(hint_id, hint)] = random.sample([*hints.items()], 1)
+ else:
+ hint_id = str(hint_id)
+ hint = hints.get(hint_id)
+
+ if hint is None:
+ print("No such hint!", file=sys.stderr)
+ return sys.exit(1)
+
+ print(format_hint(hint, hint_id, [*hint['name'].keys()]))
+
+if __name__ == '__main__':
+ main()
diff --git a/hints.json b/hints.json
index b90671f..be48117 100644
--- a/hints.json
+++ b/hints.json
@@ -3,7 +3,7 @@
"name": {
"en": "web browsers",
"pl": "przeglądarki internetowe"
- }
+ },
"text": {
"en": "Running Google Chrome, Mozilla Firefox of Apple Safari? Consider switching to an ethical browser that respects your freedom.",
"pl": "Używasz Google Chrome, Mozilla Firefox lub Apple Safari? Rozważ przerzucenie się na etyczną przeglądarkę, która szanuje Twoją wolność."
@@ -11,7 +11,11 @@
"suggested": [
{
"name": "LibreWolf",
- "url": "https://librewolf.net/"
+ "url": "https://librewolf.net/",
+ "note": {
+ "en": "Supprts enabling harmful DRM in the options.",
+ "pl": "Wspiera włączanie szkodliwego DRM'a w opcjach."
+ }
},
{
"name": "TorBrowser",
@@ -87,23 +91,35 @@
"name": {
"en": "mobile operating systems",
"pl": "mobilne systemy operacyjne"
- }
+ },
"text": {
"en": "If you wisely plan your next mobile phone purchase, you can avoid being exploited by megacorporations. An easy option is to choose a device that runs a liberated version of Android. You might also consider a GNU/Linux phone if you feel you're a geek.",
- "pl": "Jeśli mądrze zaplanujesz zakup swojego następnego telefonu komórkwego, możesz uniknąć bycia wykorzystywanym przez megakorporacje. Łatwą opcją jest wybranie urządzenia, które działa pod wolną wersją Androida. Możesz też rozważyć telefon z GNU/Linuxem jeśli czujesz, że jesteś gikiem."
+ "pl": "Jeśli mądrze zaplanujesz zakup swojego następnego telefonu komórkwego, możesz uniknąć bycia wykorzystywanym przez megakorporacje. Łatwą opcją jest wybranie urządzenia, które działa pod wolną wersją Androida. Możesz też rozważyć telefon z GNU/Linuxem, jeśli czujesz, że jesteś gikiem."
},
"suggested": [
{
"name": "/e/OS",
- "url": "https://e.foundation/e-os/"
+ "url": "https://e.foundation/e-os/",
+ "note": {
+ "en": "Is not 100% Free Software.",
+ "pl": "Nie jest w 100% Wolnym Oprogramowaniem."
+ }
},
{
"name": "PinePhone & Postmarket OS",
- "url": "https://pine64.com/product-category/pinephone/"
+ "url": "https://pine64.com/product-category/pinephone/",
+ "note": {
+ "en": "Is not 100% Free Software.",
+ "pl": "Nie jest w 100% Wolnym Oprogramowaniem."
+ }
},
{
"name": "NitroPhone & GrapheneOS",
- "url": "https://shop.nitrokey.com/shop/product/nitrophone-1-199"
+ "url": "https://shop.nitrokey.com/shop/product/nitrophone-1-199",
+ "note": {
+ "en": "Is not 100% Free Software.",
+ "pl": "Nie jest w 100% Wolnym Oprogramowaniem."
+ }
}
]
},
@@ -135,7 +151,11 @@
"suggested": [
{
"name": "F-Droid",
- "url": "https://f-droid.org/"
+ "url": "https://f-droid.org/",
+ "note": {
+ "en": "It does not meet \"Free Software Distribution Guidelines\".",
+ "pl": "Nie spełnia \"Free Software Distribution Guidelines\"."
+ }
}
]
},
@@ -151,11 +171,27 @@
"suggested": [
{
"name": "BugBlueButton",
- "url": "https://bigbluebutton.org/"
+ "url": "https://bigbluebutton.org/",
+ "note": {
+ "en": "Not all JS is labeled and integration with unethical services is possible.",
+ "pl": "Nie cały JS jest otagowany i możliwa jest integracja z nieetecznymi serwisami."
+ }
},
{
"name": "Jitsi Meet",
- "url": "https://jitsi.org/jitsi-meet/"
+ "url": "https://jitsi.org/jitsi-meet/",
+ "note": {
+ "en": "Not all JS is labeled and integration with unethical services is possible.",
+ "pl": "Nie cały JS jest otagowany i możliwa jest integracja z nieetecznymi serwisami."
+ }
+ },
+ {
+ "name": "CHATONS (VIDEO-CONFERENCE)",
+ "url": "https://entraide.chatons.org/en/",
+ "note": {
+ "en": "Not all JS is labeled.",
+ "pl": "Nie cały JS jest otagowany."
+ }
}
]
},
@@ -165,8 +201,38 @@
"pl": "czaty"
},
"text": {
- "en": "WatsApp, Facebook Messenger, Discord - they are all proprietary and centralized. XMPP is a decent chat protocol with video calls support that can replace them. Wnd-to-end encryption included!",
+ "en": "WatsApp, Facebook Messenger, Discord - they are all proprietary and centralized. XMPP is a decent chat protocol with video calls support that can replace them. End-to-end encryption included!",
"pl": "WatsApp, Facebook Messenger, Discord, Slack - one wszystkie są własnościowe i zcentralizowane. XMPP jest przyzwoitym protokołem czatu ze wsparciem dla rozmów wideo, który może je zastąpić. Szyfrowanie od-końca-do-końca w zestawie!"
- }
+ },
+ "suggested": [
+ {
+ "name": "Disroot",
+ "url": "https://disroot.org/en/services/xmpp"
+ },
+ {
+ "name": "list.jabber.at",
+ "url": "https://list.jabber.at/"
+ }
+ ]
+ },
+ "8": {
+ "name": {
+ "en": "collaborative spreadsheets",
+ "pl": "arkusze kalkulacyjne z możliwością współpracy"
+ },
+ "text": {
+ "en": "Many of us are getting told to enter data into Google Sheets. Worse, the some of the data is often personal or sensitive. Meanwhile, there exist other in-browser spreadsheets that are libre and snooping-free.",
+ "pl": "Wielu z nas każe się pisywać dane do Arkuszy Google. Jakby tego było mało, część z tego to często dane osobowe lub poufne. Tymczasem istnieją inne przeglądarkowe arkusze, które są wolnym oprogramowaniem i nie śledzą."
+ },
+ "suggested": [
+ {
+ "name": "CHATONS (COLLABORATIVE SPREADSHEET)",
+ "url": "https://entraide.chatons.org/en/",
+ "note": {
+ "en": "Not all JS is labeled.",
+ "pl": "Nie cały JS jest otagowany."
+ }
+ }
+ ]
}
}