Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Automated script for outdated contact information #1137

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/updateContacts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Contact Email Update

on:
schedule:
- cron: '0 0 31 1,7 *'

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout Main repo
uses: actions/checkout@v2

- name: Contact Email Update
env:
API_KEY: ${{ secrets.NotifyAPIKey }}
TEMPLATE_ID: ""
run: ./assets/py/emailUpdateScript.py
2 changes: 1 addition & 1 deletion _data/spdx
Submodule spdx updated 140 files
122 changes: 122 additions & 0 deletions assets/py/emailUpdateScript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/env python3
# This Python file uses the following encoding: utf-8
import json, os
import urllib.request
from datetime import date, timedelta, datetime
from notifications_python_client.notifications import NotificationsAPIClient
###############################################################################
###From ore-ero folder, run with ./assets/py/emailUpdateScript.py ###
###############################################################################
#Maximum amount of days since last update, half a year default
maxDaysNoUpdate = 182

frTypes = {"code": "code",
"design": "design",
"software": "logiciel",
"standard": "norme",
"partnership": "partenariat"}

formName = {"code": {"en": "open-source-code-form", "fr": "code-source-ouvert-formulaire"},
"design": {"en": "open-design-form", "fr": "design-libre-formulaire"},
"software": {"en": "open-source-software-form", "fr": "logiciel-libre-formulaire"},
"standard": {"en": "open-standard-form", "fr": "norme-ouverte-formulaire"},
"partnership": {"en": "partnership-form", "fr": "partenariat-formulaire"}}


def sendEmails(emailData):
client = NotificationsAPIClient(os.getenv("API_KEY"), "https://api.notification.alpha.canada.ca")
for data in emailData:
#Replace data[0] with any address to test the script
client.send_notification(
data[0], os.getenv("TEMPLATE_ID"),
{'EN_NAME': data[1], 'FR_NAME': data[2], 'LAST_UPDATED': data[3],
'EN_TYPE': data[4], 'FR_TYPE': frTypes[data[4]],
'EN_FORM': formName[data[4]]["en"], 'FR_FORM': formName[data[4]]["fr"]})


def checkCodeEmails():
codeDb = urllib.request.urlopen("https://code.open.canada.ca/code.json")
data = json.loads(codeDb.read())
codeData = []
if data is not None:
for level in data.values():
for admin in level.values():
for release in admin["releases"]:
if (datetime.strptime(release["date"]["metadataLastUpdated"], '%Y-%m-%d').date()
+ timedelta(days=maxDaysNoUpdate) < date.today()):
if "noreply" not in release["contact"]["email"]:
codeData.append((release["contact"]["email"], release["name"]["en"],
release["name"]["fr"], release["date"]["metadataLastUpdated"],
"code"))
return codeData


def checkDesignEmails():
designDb = urllib.request.urlopen("https://code.open.canada.ca/design.json")
data = json.loads(designDb.read())
designData = []
if data is not None:
for project in data.values():
for administration in project["administrations"]:
for use in administration["uses"]:
if (datetime.strptime(use["date"]["metadataLastUpdated"], '%Y-%m-%d').date()
+ timedelta(days=maxDaysNoUpdate) < date.today()):
if "noreply" not in use["contact"]["email"]:
designData.append((use["contact"]["email"], project["name"]["en"],
project["name"]["fr"], use["date"]["metadataLastUpdated"],
"design"))
return designData

def checkSoftwareEmails():
softwareDb = urllib.request.urlopen("https://code.open.canada.ca/software.json")
data = json.loads(softwareDb.read())
softwareData = []
if data is not None:
for project in data.values():
for administration in project["administrations"]:
for use in administration["uses"]:
if (datetime.strptime(use["date"]["metadataLastUpdated"], '%Y-%m-%d').date()
+ timedelta(days=maxDaysNoUpdate) < date.today()):
if "noreply" not in use["contact"]["email"]:
softwareData.append((use["contact"]["email"], project["name"]["en"],
project["name"]["fr"], use["date"]["metadataLastUpdated"],
"software"))
return softwareData

def checkStandardEmails():
standardDb = urllib.request.urlopen("https://code.open.canada.ca/standard.json")
data = json.loads(standardDb.read())
standardData = []
if data is not None:
for project in data.values():
for administration in project["administrations"]:
if (datetime.strptime(administration["date"]["metadataLastUpdated"], '%Y-%m-%d').date()
+ timedelta(days=maxDaysNoUpdate) < date.today()):
if "noreply" not in administration["contact"]["email"]:
standardData.append((administration["contact"]["email"], project["standardAcronym"],
project["standardAcronym"], administration["date"]["metadataLastUpdated"],
"standard"))
return standardData

def checkPartnershipEmails():
partnershipDb = urllib.request.urlopen("https://code.open.canada.ca/partnership.json")
data = json.loads(partnershipDb.read())
partnershipData = []
if data is not None:
for level in data.values():
for admin in level.values():
for project in admin["projects"]:
if (datetime.strptime(project["date"]["metadataLastUpdated"], '%Y-%m-%d').date()
+ timedelta(days=maxDaysNoUpdate) < date.today()):
if "noreply" not in project["contact"]["email"]:
partnershipData.append((project["contact"]["email"], project["name"]["en"],
project["name"]["fr"], project["date"]["metadataLastUpdated"],
"partnership"))
return partnershipData


print("Started task at: " + datetime.now().isoformat(' ', 'seconds'))
sendEmails(checkCodeEmails() + checkDesignEmails() + checkSoftwareEmails()
+ checkStandardEmails() + checkPartnershipEmails())
print("Finished task at: " + datetime.now().isoformat(' ', 'seconds'))

30 changes: 30 additions & 0 deletions assets/py/messageTemplates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class Templates:
##This file can be erased once the template is setup on the Notify API
##To have this template on the Notify API, replace {} with (())
plain = """
English Message:

Automated message about {EN_NAME} on the ORE platform, last updated {LAST_UPDATED}.
You are receiving this message because our information concerning {EN_NAME} has not been
updated in the last 6 months and your email address is currently listed as the contact
information for this {EN_TYPE}.
If you are no longer the contact for {EN_NAME}, you can use this form
"https://code.open.canada.ca/en/{EN_FORM}.html" to update our platform.

"https://code.open.canada.ca/en/index.html"

Message en français:

Message automatisé concernant {FR_NAME} sur la plateforme Échange de Ressources Ouvert,
mise à jour la plus récente {LAST_UPDATED}
Vous recevez ce message parce que notre information concernant {FR_NAME} n'a pas été
mis a jour dans les 6 derniers mois et votre adresse email est inscrite comme
adresse de contact pour ce {FR_TYPE}.
Si vous n'êtes plus la personne à contacter pour {FR_NAME}, vous pouvez utiliser
ce formulaire "https://code.open.canada.ca/en/{FR_FORM}.html" pour mettre
a jour notre plateforme.

"https://code.ouvert.canada.ca/fr/index.html"
"""