diff --git a/CODEOWNERS b/CODEOWNERS index b0324d43..03be9857 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,9 +1,11 @@ * @fossecode -/static/no/ @fossecode -/static/nl/ @Kilian +/app/countrySpecific/sk-* @sbocinec /app/locales/nl.json @Kilian /app/locales/no.json @michaelmcmillan /app/locales/sk*.json @sbocinec -*.md @michaelmcmillan /app/repository/ @Snikanes /app/views/ @fossecode +/app/views/privacy-statements/sk-privacy-statement.ejs @sbocinec +/ops/sk/ @sbocinec +/static/no/ @fossecode +/static/nl/ @Kilian diff --git a/README.md b/README.md index a8982972..4d480c7c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,11 @@ We don't know how many people have COVID-19. So we made a website where people can self-report symptoms. We plot the submissions on a map and show graphs with trends. -### Countries where Coronastatus launches +## How can I help? + +We need people who can help translate the site, develop new features, project leads for new and existing countries, and much more. Join our group chat: https://t.me/onzecorona + +### In what countries have you launched Coronastatus? - 🇳🇴 Norway: https://coronastatus.no - 🇳🇱 The Netherlands: https://coronastatus.nl @@ -30,6 +34,7 @@ We don't know how many people have COVID-19. So we made a website where people c - 🇲🇹 Malta: https://coronastatusmt.com - 🇨🇱 Chile: https://coronastatus.cl - 🇮🇳 India: https://corona-status.in +- 🇵🇹 Portugal: https://coronastatus.pt - 🇸🇪 Sweden: coming soon - 🇵🇭 Philippines: coming soon - 🇹🇷 Turkey: coming soon (work group Telegram chat: https://t.me/turkeycoronastatus) diff --git a/app/countrySpecific/geonames-converter.py b/app/countrySpecific/geonames-converter.py index 75b153f3..2dbea149 100644 --- a/app/countrySpecific/geonames-converter.py +++ b/app/countrySpecific/geonames-converter.py @@ -4,7 +4,7 @@ # Set the country code you want to create JSON files for COUNTRY_CODE = 'bd' -# Parse CSV for a given country from Geonames.org +# Parse CSV for a given country from Geonames.org rows = [] with open('%s.txt' % COUNTRY_CODE.upper(), 'r') as f: fieldnames = [ @@ -32,7 +32,7 @@ if not municipality in municipalities: municipalities[municipality] = {'postalCodes': []} municipalities[municipality]['postalCodes'].append(row.get('postal code')) - + with open('%s-municipalities.json' % COUNTRY_CODE, 'w') as f: write_as_json(municipalities, f, indent=2, separators=(',', ': ')) diff --git a/app/locales/en-AU.json b/app/locales/en-AU.json index 93820717..866bab0a 100644 --- a/app/locales/en-AU.json +++ b/app/locales/en-AU.json @@ -182,6 +182,8 @@ "Some questions and alternatives were not a part of the form from the beginning:": "Some questions and alternatives were not a part of the form from the beginning:", "March 27": "March 27", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL AUSTRALIAN CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help Australia gain control over COVID-19.", diff --git a/app/locales/en-IN.json b/app/locales/en-IN.json index 12cf3e07..970cfaf2 100644 --- a/app/locales/en-IN.json +++ b/app/locales/en-IN.json @@ -187,6 +187,8 @@ "March 28": "March 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "In voluntary isolation to avoid potentially spreading or catching COVID-19", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL CITIZENS FROM INDIA: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help India gain control over COVID-19.", diff --git a/app/locales/en-MT.json b/app/locales/en-MT.json index 325cf2f6..c3a998aa 100644 --- a/app/locales/en-MT.json +++ b/app/locales/en-MT.json @@ -186,6 +186,8 @@ "March 28": "March 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "In voluntary isolation to avoid potentially spreading or catching COVID-19", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL MALTESE CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help Malta gain control over COVID-19.", diff --git a/app/locales/en-NG.json b/app/locales/en-NG.json index e9dd8f4c..37539d20 100644 --- a/app/locales/en-NG.json +++ b/app/locales/en-NG.json @@ -186,6 +186,8 @@ "March 28": "March 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "In voluntary isolation to avoid potentially spreading or catching COVID-19", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL NIGERIAN CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help Nigeria gain control over COVID-19.", diff --git a/app/locales/en-SG.json b/app/locales/en-SG.json index 0cfad105..54bb991d 100644 --- a/app/locales/en-SG.json +++ b/app/locales/en-SG.json @@ -186,6 +186,8 @@ "March 28": "March 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "In voluntary isolation to avoid potentially spreading or catching COVID-19", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL SINGAPOREAN CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help Singapore gain control over COVID-19.", diff --git a/app/locales/en-US.json b/app/locales/en-US.json index 17097f96..7ab8c455 100644 --- a/app/locales/en-US.json +++ b/app/locales/en-US.json @@ -186,6 +186,8 @@ "March 28": "March 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "In voluntary isolation to avoid potentially spreading or catching COVID-19", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.", diff --git a/app/locales/en.json b/app/locales/en.json index 38d43f5e..594a1200 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -187,6 +187,8 @@ "March 28": "March 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "In voluntary isolation to avoid potentially spreading or catching COVID-19", "Other": "Other", + "This page is not affiliated with the authorities.": "This page is not affiliated with the authorities.", + "Learn more!": "Learn more!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "CALL TO ALL UK CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.", "Contribute and share {{ hostname }} on": "Contribute and share {{ hostname }} on", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Fill out this form - it takes 1 minute - and help the United Kingdom gain control over COVID-19.", diff --git a/app/locales/es-AR.json b/app/locales/es-AR.json index 5debe4b8..8f59a6da 100644 --- a/app/locales/es-AR.json +++ b/app/locales/es-AR.json @@ -185,6 +185,8 @@ "March 28": "Marzo 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "En aislamiento voluntario para evitar una potencial propagación o ser contagiado de COVID-19", "Other": "Otro", + "This page is not affiliated with the authorities.": "Esta página no está afiliada con las autoridades.", + "Learn more!": "¡Conoce más!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "QUERIDOS ARGENTINOS: Así es como podemos derrotar al coronavirus: juntos podemos hacer visible el virus invisible.", "Contribute and share {{ hostname }} on": "Comparta {{ hostname }} en", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Complete este formulario (se tarda 1 minuto) y ayude a Argentina a controlar el COVID-19.", diff --git a/app/locales/es-CO.json b/app/locales/es-CO.json index 319272d8..ea99ba9a 100644 --- a/app/locales/es-CO.json +++ b/app/locales/es-CO.json @@ -187,6 +187,8 @@ "March 28": "Marzo 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "En aislamiento voluntario para evitar una potencial propagación o ser contagiado de COVID-19", "Other": "Otro", + "This page is not affiliated with the authorities.": "Esta página no está afiliada con las autoridades.", + "Learn more!": "¡Conoce más!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "QUERIDOS COLOMBIANOS: Así es como podemos derrotar al coronavirus: juntos podemos hacer visible el virus invisible.", "Contribute and share {{ hostname }} on": "Comparta {{ hostname }} en", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Complete este formulario (se tarda 1 minuto) y ayude a Colombia a controlar el COVID-19.", diff --git a/app/locales/es-ES.json b/app/locales/es-ES.json index cc3fd3b4..a5ffcfed 100644 --- a/app/locales/es-ES.json +++ b/app/locales/es-ES.json @@ -183,6 +183,8 @@ "March 28": "Marzo 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "En aislamiento voluntario para evitar una potencial propagación o ser contagiado de COVID-19", "Other": "Otro", + "This page is not affiliated with the authorities.": "Esta página no está afiliada con las autoridades.", + "Learn more!": "¡Conoce más!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "QUERIDOS ESPAÑOLES: Así es como podemos derrotar al coronavirus: juntos podemos hacer visible el virus invisible.", "Contribute and share {{ hostname }} on": "Comparta {{ hostname }} en", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Complete este formulario (se tarda 1 minuto) y ayude a España a controlar el COVID-19.", diff --git a/app/locales/es-MX.json b/app/locales/es-MX.json index 4d3bcea4..5fff52b3 100644 --- a/app/locales/es-MX.json +++ b/app/locales/es-MX.json @@ -183,6 +183,8 @@ "March 28": "Marzo 28", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "En aislamiento voluntario para evitar una potencial propagación o ser contagiado de COVID-19", "Other": "Otro", + "This page is not affiliated with the authorities.": "Esta página no está afiliada con las autoridades.", + "Learn more!": "¡Conoce más!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "QUERIDOS MEXICANOS: Así es como podemos derrotar al coronavirus: juntos podemos hacer visible el virus invisible.", "Contribute and share {{ hostname }} on": "Comparta {{ hostname }} en", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Complete este formulario (se tarda 1 minuto) y ayude a México a controlar el COVID-19.", diff --git a/app/locales/fr-FR.json b/app/locales/fr-FR.json index 04fdb827..cc19afd3 100644 --- a/app/locales/fr-FR.json +++ b/app/locales/fr-FR.json @@ -183,6 +183,8 @@ "March 28": "28 mars", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "En isolement volontaire pour éviter de propager le COVOD-19 ou d'être contaminé", "Other": "Autre", + "This page is not affiliated with the authorities.": "Cette page n'est pas affiliée aux autorités", + "Learn more!": "En savoir plus!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "APPEL À TOUS LES CITOYENS FRANÇAIS: C'est ainsi que nous vainquons le virus corona: ensemble, nous rendons visible le virus invisible.", "Contribute and share {{ hostname }} on": "Contribuez et partagez {{ hostname }} sur", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Remplissez ce formulaire - cela prend 1 minute - et aidez les États-Unis à prendre le contrôle de COVID-19.", diff --git a/app/locales/it.json b/app/locales/it.json index ecacc9b2..dede248f 100644 --- a/app/locales/it.json +++ b/app/locales/it.json @@ -49,6 +49,8 @@ "NB!": "Importante!", "This page is currently not affiliated with the authorities in any way.": "Questa pagina non è in alcun modo legata alle autorità italiane.", "Read how the data you enter is processed here!": "Leggi qui come vengono elaborati i tuoi dati!", + "This page is not affiliated with the authorities.":"Questo sito non è legato alle autorità italiane.", + "Learn more!":"Scopri di più!", "Use the link you noted down last time to update your health condition": "Utilizza il link che ti eri annotato per aggiornare la tua condizione di salute.", "Unreported cases": "Casi non segnalati", "The spread of COVID-19 in our country is unknown. Help us create a better overview.": "Non conosciamo la diffusione del COVID-19 nel nostro Paese, aiutaci quindi ad avere un quadro della situazione più dettagliato.", diff --git a/app/locales/nl.json b/app/locales/nl.json index e2286ccf..f8a990d5 100644 --- a/app/locales/nl.json +++ b/app/locales/nl.json @@ -47,8 +47,10 @@ "Make your voluntary contribution to the health care system and register your health condition now. Together we can create an overview.": "Doe uw vrijwillige bijdrage aan de gezondheidszorg en registreer nu uw gezondheidstoestand. Samen creëren we een overzicht.", "Share on": "Deel op", "NB!": "NB!", - "This page is currently not affiliated with the authorities in any way.": "Deze pagina is momenteel op geen enkele manier gelieerd aan de Nederlandse autoriteiten.", + "This page is currently not affiliated with the authorities in any way.": "Deze pagina is momenteel niet gelieerd aan de Nederlandse overheid.", "Read how the data you enter is processed here!": "Lees hier hoe de door u ingevulde gegevens worden verwerkt!", + "This page is not affiliated with the authorities.":"Deze pagina is niet gelieerd aan de overheid.", + "Learn more!":"Lees meer!", "Use the link you noted down last time to update your health condition": "Gebruik de door u opgeslagen link om uw veranderde gezondheid door te geven", "Unreported cases": "Ongemelde gevallen", "The spread of COVID-19 in our country is unknown. Help us create a better overview.": "De verspreiding van COVID-19 in ons land is onbekend. Help ons een beter overzicht te creëren.", @@ -186,7 +188,7 @@ "Other": "Anders / zeg ik liever niet", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "OPROEP AAN ALLE NEDERLANDERS: Zo verslaan we samen het coronavirus: we maken het onzichtbare virus zichtbaar.", "Contribute and share {{ hostname }} on": "Draag bij en deel {{ hostname }} via", - "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Vul dit formulier in - het kost 1 minuut - en help Nederland controle te krijgen over corona.", + "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Vul dit formulier in en help Nederland controle te krijgen over corona.", "One more thing": "Nog één dingetje", "To defeat the corona virus we need to make the invisible virus visible.": "Om het coronavirus te verslaan moeten we het onzichtbare virus zichtbaar maken.", "{{ amount }} people already shared their health status.": "Al {{ amount }} mensen hebben hun gezondheidsstatus ingevuld.", diff --git a/app/locales/no.json b/app/locales/no.json index 9396f143..62607852 100644 --- a/app/locales/no.json +++ b/app/locales/no.json @@ -49,6 +49,8 @@ "NB!": "NB!", "This page is currently not affiliated with the authorities in any way.": "Denne siden er p.t. ikke tilknyttet FHI eller norske myndigheter på noen måte.", "Read how the data you enter is processed here!": "Les hvordan dataen du oppgir blir behandlet her!", + "This page is not affiliated with the authorities.":"Denne siden er ikke tilknyttet myndighetene.", + "Learn more!":"Les mer!", "Use the link you noted down last time to update your health condition": "Bruk lenken du noterte deg sist for å endre din helsetilstand.", "Unreported cases": "Store mørketall", "The spread of COVID-19 in our country is unknown. Help us create a better overview.": "Spredningen av COVID-19 i landet vårt er ukjent. Hjelp oss med å skape en bedre oversikt.", diff --git a/app/locales/pt-BR.json b/app/locales/pt-BR.json index 1e3c70fb..55148e9f 100644 --- a/app/locales/pt-BR.json +++ b/app/locales/pt-BR.json @@ -182,6 +182,8 @@ "Some questions and alternatives were not a part of the form from the beginning:": "Algumas perguntas e alternativas não faziam parte do formulário desde o início:", "March 27": "Março 27", "Other": "Outro", + "This page is not affiliated with the authorities.": "Este site não está afiliados às autoridades.", + "Learn more!": "Saber mais!", "View Website Statistics": "Ver estatísticas do website", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "Chamada de atenção a todos os cidadãos portugueses: É assim que vencemos o coronavírus: juntos tornamos visível, o vírus invisível.", "Contribute and share {{ hostname }} on": "Contribui e partilha {{hostname}} no", diff --git a/app/locales/pt-PT.json b/app/locales/pt-PT.json index dfc0dff6..9d59292f 100644 --- a/app/locales/pt-PT.json +++ b/app/locales/pt-PT.json @@ -74,7 +74,7 @@ "Biological gender": "Sexo", "Female": "Feminino", "Male": "Masculino", - "Zip code": "Código Postal (primeiros 4 dígitos)", + "Zip code": "Código Postal", "Testing and symptoms": "Teste e sintomas", "Have you been in close contact with someone who was tested positive for COVID-19?": "Esteve em contacto próximo com alguém que testou positivo para COVID-19?", "Yes": "Sim", @@ -186,6 +186,8 @@ "Other": "Outro", "In voluntary isolation to avoid potentially spreading or catching COVID-19": "Em isolamento voluntário para evitar uma potencial propagação ou contração do COVID-19", "March 28": "28 de Março", + "This page is not affiliated with the authorities.": "Este site não está afiliados às autoridades.", + "Learn more!": "Saber mais!", "View Website Statistics": "Ver estatísticas do website", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "Chamada de atenção a todos os cidadãos portugueses: É assim que vencemos o coronavírus: juntos tornamos visível, o vírus invisível.", "Contribute and share {{ hostname }} on": "Contribui e partilha {{hostname}} no", diff --git a/app/locales/sk.json b/app/locales/sk.json index f19a21db..d2dfa477 100644 --- a/app/locales/sk.json +++ b/app/locales/sk.json @@ -48,6 +48,8 @@ "Share on": "Zdieľajte na", "NB!": "Upozornenie!", "This page is currently not affiliated with the authorities in any way.": "Táto stránka je nezávislou iniciatívou dobrovoľníkov, nesúvisí so štátnými orgánmi.", + "This page is not affiliated with the authorities.":"Táto stránka je nezávislou iniciatívou.", + "Learn more!":"Zisti viac!", "Read how the data you enter is processed here!": "Prečítajte si ako sú vami zadané dáta spracovávané", "Use the link you noted down last time to update your health condition": "Použite uložený odkaz, ktorý sa zobrazil pri vašej poslednej aktualizácii vášho zdravotného stavu", "Unreported cases": "Neoznámené prípady", diff --git a/app/locales/tr.json b/app/locales/tr.json index 8054b70f..6a10dff4 100644 --- a/app/locales/tr.json +++ b/app/locales/tr.json @@ -49,6 +49,8 @@ "NB!": "Önemli!", "This page is currently not affiliated with the authorities in any way.": "Bu sayfa hiçbir şekilde yetkili birimlere bağlı değildir.", "Read how the data you enter is processed here!": "Girdiğiniz verilerin nasıl işlendiğini öğrenin!", + "This page is not affiliated with the authorities.":"Bu sayfa yetkili birimlere bağlı değildir.", + "Learn more!":"Daha fazla bilgi edin!", "Use the link you noted down last time to update your health condition": "Daha önceden not aldığınız bağlantıyı kullanarak sağlık durumunuzu güncelleyin.", "Unreported cases": "Bildirilmemiş vakalar", "The spread of COVID-19 in our country is unknown. Help us create a better overview.": "COVID-19'un ülkemizde yayılımı bilinmemektedir. Daha iyi bir genel bakış oluşturmamıza yardımcı olun.", diff --git a/app/locales/uk-UA.json b/app/locales/uk-UA.json index 913910a4..aeb75a8a 100644 --- a/app/locales/uk-UA.json +++ b/app/locales/uk-UA.json @@ -188,6 +188,8 @@ "In voluntary isolation to avoid potentially spreading or catching COVID-19": "На самокарантині, щоб зменшити поширення або уникнути COVID-19", "What is my Zip code?": "Як знайти свій поштовий індекс?", "https://www.whatismyzip.com": "https://postcode.in.ua/", + "This page is not affiliated with the authorities.": "Ця сторінка ніяк не зв'язана із владою.", + "Learn more!": "Дізнатися більше!", "CALL TO ALL US CITIZENS: This is how we defeat the corona virus: together we make the invisible virus visible.": "ПРОХАННЯ ДО УСІХ ГРОМАДЯН: Так ми можемо перемогти коронавірус: разом ми робимо невидимий вірус - видими", "Contribute and share {{ hostname }} on": "Допомогти та поділитися {{ hostname }} у", "Fill out this form - it takes 1 minute - and help the United States gain control over COVID-19.": "Заповнення форми займає 1 хвилину і допомагає України розуміти стан поширення COVID-19.", diff --git a/app/server.ts b/app/server.ts index b2c0826a..9524e864 100644 --- a/app/server.ts +++ b/app/server.ts @@ -74,7 +74,12 @@ app.use((req, res, next) => { res.locals.zipPattern = config.ZIP_PATTERN; res.locals.zipPlaceHolder = config.ZIP_PLACEHOLDER; res.locals.redirectToGovernment = config.REDIRECT_TO_GOVERNMENT; - res.locals.thousandSeparator = config.THOUSAND_SEPARATOR; + + // eslint-disable-next-line @typescript-eslint/ban-ts-ignore + // @ts-ignore + res.locals.formatNumber = x => + x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, config.THOUSAND_SEPARATOR); + next(); }); diff --git a/app/views/pages/report.ejs b/app/views/pages/report.ejs index 07f96240..6e45e3da 100644 --- a/app/views/pages/report.ejs +++ b/app/views/pages/report.ejs @@ -3,7 +3,7 @@ profile, passcode, baseUrl, - thousandSeparator = ' ', + formatNumber, urls } = locals; const age = profile && locals.profile.age; @@ -31,10 +31,6 @@ const symptomSlimeCough = symptoms && symptoms['SLIME_COUGH']; const symptomRunnyNose = symptoms && symptoms['RUNNY_NOSE']; const symptomNauseaOrVomiting = symptoms && symptoms['NAUSEA_OR_VOMITING']; - - function numberWithSpaces(x) { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator); - } %> <%- include('partials/header', { home: true, menu: false }) -%> @@ -82,25 +78,25 @@ <%- include('partials/app-stats-block', { image: '/static/images/napkin.svg', title: __('Total reports'), - number: numberWithSpaces(aggregated.numberOfReports) + number: formatNumber(aggregated.numberOfReports) }) -%> <%- include('partials/app-stats-block', { image: '/static/images/temperature-check.svg', title: __('Infected / Have been tested'), - number: `${numberWithSpaces(aggregated.numberOfConfirmedInfected)}/${numberWithSpaces(aggregated.numberOfTested)}` + number: `${formatNumber(aggregated.numberOfConfirmedInfected)}/${formatNumber(aggregated.numberOfTested)}` }) -%> <%- include('partials/app-stats-block', { image: '/static/images/transfer.svg', title: __(`In close contact with someone who's infected`), - number: numberWithSpaces(aggregated.numberOfContacts) + number: formatNumber(aggregated.numberOfContacts) }) -%> <%- include('partials/app-stats-block', { image: '/static/images/symptoms.svg', title: __('Has symptoms'), - number: numberWithSpaces(aggregated.numberOfPeopleShowingSymptoms) + number: formatNumber(aggregated.numberOfPeopleShowingSymptoms) }) -%> @@ -452,7 +448,7 @@

<%= __(`Contribute and share {{ hostname }} on`, { hostname: baseUrl }) %>

- <%- include('partials/share', { amount: numberWithSpaces(aggregated.numberOfReports) }) -%> + <%- include('partials/share', { amount: formatNumber(aggregated.numberOfReports) }) -%>
diff --git a/app/views/pages/statistics.ejs b/app/views/pages/statistics.ejs index dbebd559..f1e909d3 100644 --- a/app/views/pages/statistics.ejs +++ b/app/views/pages/statistics.ejs @@ -2,8 +2,7 @@ locals.inContactWithInfectedStats.total; const totalInfectedPeopleWithSymptoms = locals.infectedStats.symptomStats.total; const totalPeopleWithSymptoms = locals.allSymptomsStats.symptomStats.total; const totalTested = -locals.totalTested; function numberWithSpaces(x) { return -x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); } %> +locals.totalTested; const { formatNumber } = locals; %> @@ -30,8 +29,8 @@ x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); } %> <%= __(`COVID-19 infected`) %>

- <%= __(`In total`) %> <%= numberWithSpaces(totalInfectedPeopleWithSymptoms) %> - <%= __(`people have reported that they have tested positive for COVID-19 and + <%= __(`In total`) %> <%= formatNumber(totalInfectedPeopleWithSymptoms) %> <%= + __(`people have reported that they have tested positive for COVID-19 and experience symptoms.`) %>

@@ -43,8 +42,8 @@ x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); } %>

<%= __(`Test results`) %>

- <%= __(`In total`) %> <%= numberWithSpaces(totalTested) %> <%= __(`people - have reported that they have been tested for COVID-19.`) %> + <%= __(`In total`) %> <%= formatNumber(totalTested) %> <%= __(`people have + reported that they have been tested for COVID-19.`) %>

@@ -54,8 +53,8 @@ x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); } %> <%= __(`Close contacts`) %>

- <%= __(`In total`) %> <%= numberWithSpaces(totalPeopleInContactWithInfected) - %> <%= __(`people have reported that they have been in close contact with a + <%= __(`In total`) %> <%= formatNumber(totalPeopleInContactWithInfected) %> + <%= __(`people have reported that they have been in close contact with a person who was tested positive for COVID-19.`) %>

@@ -102,7 +101,7 @@ x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); } %> <%= __(`All submissions`) %>

- <%= __("In total") %> <%= numberWithSpaces(totalPeopleWithSymptoms) %> <%= + <%= __("In total") %> <%= formatNumber(totalPeopleWithSymptoms) %> <%= __(`people have reported that they experience symptoms.`) %>

diff --git a/app/views/pages/thank-you.ejs b/app/views/pages/thank-you.ejs index ed9985b2..3ed03e17 100644 --- a/app/views/pages/thank-you.ejs +++ b/app/views/pages/thank-you.ejs @@ -1,6 +1,4 @@ -<% const numberWithSpaces = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, -locals.thousandSeparator || ' '); const amount = -numberWithSpaces(aggregated.numberOfReports) %> +<% const amount = locals.formatNumber(aggregated.numberOfReports) %> <%- include('partials/header') -%> diff --git a/app/views/partials/banner.ejs b/app/views/partials/banner.ejs index 76afb205..a2273633 100644 --- a/app/views/partials/banner.ejs +++ b/app/views/partials/banner.ejs @@ -1,7 +1,7 @@ <% const { id = null, link = null, start = null, close = false, onclick = null, style = ''} = locals; %>
> diff --git a/app/views/partials/header.ejs b/app/views/partials/header.ejs index d98c3fe1..0f6fbb59 100644 --- a/app/views/partials/header.ejs +++ b/app/views/partials/header.ejs @@ -25,6 +25,23 @@ onclick: 'hasSubmittedAlertOnClick()' }) -%>
+
+ <%- include('partials/banner', { + start: __('NB!'), + message: __('This page is not affiliated with the authorities.'), + link: urls.privacyPolicy, + linkText: __('Learn more!'), + color: '#efbc2e' + }) -%> + <%- include('partials/banner', { + start: __('Important'), + message: __('Use the link you noted down last time to update your health condition'), + color: '#62C4C3', + style: 'display: none;', + id: 'has-submitted-alert', + onclick: 'hasSubmittedAlertOnClick()' + }) -%> +
diff --git a/config-examples/sk-config.json b/config-examples/sk-config.json new file mode 100644 index 00000000..bcb3574f --- /dev/null +++ b/config-examples/sk-config.json @@ -0,0 +1,16 @@ +{ + "BASE_URL": "coronastatus.sk", + "LOCALE": "sk", + "COUNTRY":"Slovakia", + "COUNTRY_CODE":"sk", + "DB_PATH": "./covid_db", + "MAP_CENTER": "19.2688, 48.7269", + "MAP_ZOOM": 7, + "MAP_MAX_ZOOM": 13, + "PASSCODE_LENGTH": 4, + "REDIRECT_TO_GOVERNMENT": false, + "TWITTER": "coronastatusSK", + "ZIP_GUIDE": false, + "ZIP_LENGTH": 5, + "ZIP_PLACEHOLDER": "12345" +} diff --git a/ops/extract-flags-from-readme-for-github-repo-description.sh b/ops/extract-flags-from-readme-for-github-repo-description.sh new file mode 100755 index 00000000..e42cdbc8 --- /dev/null +++ b/ops/extract-flags-from-readme-for-github-repo-description.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +cat ./README.md | grep '^\-' | grep 'https://corona' | cut -c3-4 | paste -sd " " - | sed 's/ //g' diff --git a/ops/sk/README.md b/ops/sk/README.md new file mode 100644 index 00000000..37d5ed69 --- /dev/null +++ b/ops/sk/README.md @@ -0,0 +1,36 @@ +# SK deployment + +This deployment is very simple: +* requires only a VM with git client, docker engine, docker-compose installed, a TLS certificate/key pair and you are good to go. +* [Traefik v1](https://traefik.io/) edge router is used as an application proxy that is routing requests to the app on the VM. Both run as docker containers. +* [Cloudflare (free plan)](https://support.cloudflare.com/hc/en-us/articles/115000479507-Managing-Cloudflare-Origin-CA-certificates) is used at the edge as a DNS/CDN/WAF/proxy. The deployment uses [Cloudflare origin CA certificates](https://support.cloudflare.com/hc/en-us/articles/115000479507-Managing-Cloudflare-Origin-CA-certificates) on the server. It's configured to: + * rewrite all HTTP-> HTTPS (allow only TLS 1.2+) + * Redirect www.coronastatus.tld to coronastatus.tld. + * Perform the CSS/JS/HTML compression +* You can also use builtin support of Traefik to autogenerate Let's encrypt TLS certs if you don't need any LB at the edge. + +## Installation + +1. Create a VM with any OS that can run docker engine and git client - minimal/slim versions of Ubuntu 18.04 or Debian buster are recommended. +2. Install following dependencies: +- [git](https://git-scm.com/downloads) +- [Docker CE](https://docs.docker.com/install/) +- [Docker Compose](https://docs.docker.com/compose/install/) +3. Create a non-privileged user for the application: `useradd -m -s /bin/bash app` +4. Add user to `docker` group: `usermod -a -G docker app` +5. Enable docker to start on boot: `systemctl enable --now docker` +6. Apply latest OS updates +7. Do some basic system hardening (configure firewall, stop unused services, ...) and OS tuning + +## App deployment & configuration + +1. Login to the VM, switch to the app user: `sudo -i -u app` +2. Clone the repository: `git clone https://github.com/BustByte/coronastatus` +3. Move into the newly cloned directory: `cd coronastatus` +4. Create a configuration file from the example provided in this repo: `cp config.example.json config.json` +5. Review the `docker-compose.yml` file in this deployment directory +6. Create the `certs` directory and copy the Cloudflare TLS certificate/key there: `certs/tls.crt`, `certs/tls.key` +7. Install node modules: `docker-compose run --rm app yarn` +8. Start the project: `docker-compose up -d`. Containers will be automatically re/started on boot/container crash. +9. Display the logs to see everything is running properly: `docker-compose logs -f` +10. Enjoy :-) diff --git a/ops/sk/docker-compose.yml b/ops/sk/docker-compose.yml new file mode 100644 index 00000000..3788994c --- /dev/null +++ b/ops/sk/docker-compose.yml @@ -0,0 +1,47 @@ +version: "3.7" +services: + app: + image: node:lts-buster-slim + command: yarn serve + depends_on: + - proxy + environment: + - NODE_ENV=production + labels: + - "traefik.enable=true" + - "traefik.app.backend.port=7272" + - "traefik.app.frontend.rule=Host:coronastatus.sk,www.coronastatus.sk" + ports: + - "127.0.0.1:7272:7272" + networks: + - cs + restart: unless-stopped + volumes: + - ./:/app + - node_modules:/app/node_modules + working_dir: /app + proxy: + image: traefik:v1.7.23 + command: + - "--docker" + - "--docker.watch=true" + - "--docker.exposedByDefault=false" + - "--entryPoints=Name:http Address::80 Redirect.EntryPoint:https" + - "--entryPoints=Name:https Address::443 TLS:/tls.crt,/tls.key" + - "--defaultEntryPoints=http,https" + networks: + - cs + ports: + - 80:80 + - 443:443 + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./certs/tls.crt:/tls.crt + - ./certs/tls.key:/tls.key +networks: + cs: + driver: bridge +volumes: + node_modules: + driver: local