Handle Discourse users with multiple emails.

This commit is contained in:
Julien Palard 2023-03-19 00:11:57 +01:00
parent 6c79b9ac76
commit 6c06f32d09
Signed by: mdk
GPG Key ID: 0EFC1AC1006886F8
1 changed files with 36 additions and 32 deletions

View File

@ -1,15 +1,14 @@
import argparse
import json
import re
from itertools import count, groupby
import json
from pathlib import Path
from typing import Any, Dict, Set
from urllib.parse import urljoin
from time import sleep
from tabulate import tabulate
import requests
from helloasso_api import HaApiV5
from tabulate import tabulate
def parse_args():
@ -51,6 +50,7 @@ class Discourse:
self.url = url
self.api_key = api_key
self.session = None
self._email_to_user_map = None
def __enter__(self):
self.session = requests.Session()
@ -70,6 +70,9 @@ class Discourse:
response.raise_for_status()
return response.json()
def get_badge(self, badge_id):
return self.get(f"/user_badges.json?badge_id={badge_id}")
def users(self, flag="active"):
all_users = []
for page in count(1):
@ -82,25 +85,17 @@ class Discourse:
all_users.extend(users)
return all_users
def user_by_email(self, email):
users = self.get(
"/admin/users/list/active.json",
params={"filter": email, "show_emails": "true"},
)
for user in users:
if user["email"] == email:
return user
# Maybe, like me, he has a tag in its email address...
users = self.get(
"/admin/users/list/active.json",
params={
"show_emails": "true",
"filter": re.sub("@.*$", "", remove_email_tag(email)),
},
)
for user in users:
if remove_email_tag(user["email"]) == remove_email_tag(email):
return user
@property
def email_to_user_map(self) -> Dict[str, Dict[str, Any]]:
if self._email_to_user_map:
return self._email_to_user_map
email_to_user = {}
for user in self.users():
email_to_user[remove_email_tag(user["email"])] = user
for secondary_email in user["secondary_emails"]:
email_to_user[remove_email_tag(secondary_email)] = user
self._email_to_user_map = email_to_user
return email_to_user
def assign_badge(self, badge_id, username):
return self.post(
@ -155,15 +150,24 @@ def main_sync(args):
and "payer" in item
and "email" in item["payer"]
}
discourse_users_by_email = {
remove_email_tag(user["email"]): user for user in discourse.users()
}
for email in set(discourse_users_by_email) & from_helloasso:
print(
discourse.assign_badge(
args.badge, discourse_users_by_email[email]["username"]
)
)
print(f"Found {len(from_helloasso)} emails in HelloAsso")
badge = discourse.get_badge(args.badge)
badge_name = badge["badges"][0]["name"]
already_assigned = {user["username"] for user in badge["users"]}
print(f"Found {len(discourse.email_to_user_map)} emails in Discourse")
common_emails = set(discourse.email_to_user_map) & from_helloasso
print(f"Found {len(common_emails)} in common")
already_assigned_count = 0
for email in common_emails:
discourse_user = discourse.email_to_user_map[email]
if discourse_user["username"] in already_assigned:
already_assigned_count += 1
continue
print(f"Assigning {badge_name!r} to {discourse_user['username']!r}")
discourse.assign_badge(args.badge, discourse_user["username"])
print(
f"{already_assigned_count} Discourse users already have the badge {badge_name!r}"
)
def main_fetch(args):