-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:openedx/license-manager into ENT-…
…8306/make-var-field-optional
- Loading branch information
Showing
12 changed files
with
942 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import logging | ||
|
||
import requests | ||
from django.conf import settings | ||
|
||
from license_manager.apps.api_client.base_oauth import BaseOAuthClient | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class LMSApiClient(BaseOAuthClient): | ||
""" | ||
API client for calls to the LMS. | ||
""" | ||
api_base_url = settings.LMS_URL | ||
user_details_endpoint = api_base_url + '/api/user/v1/accounts' | ||
|
||
def fetch_lms_user_id(self, email): | ||
""" | ||
Fetch user details for the specified user email. | ||
Arguments: | ||
email (str): Email of the user for which we want to fetch details for. | ||
Returns: | ||
str: lms_user_id of the user. | ||
""" | ||
# {base_api_url}/api/user/v1/[email protected] | ||
try: | ||
query_params = {'email': email} | ||
response = self.client.get(self.user_details_endpoint, params=query_params) | ||
response.raise_for_status() | ||
response_json = response.json() | ||
return response_json[0].get('id') | ||
except requests.exceptions.HTTPError as exc: | ||
logger.error( | ||
'Failed to fetch user details for user {email} because {reason}'.format( | ||
email=email, | ||
reason=str(exc), | ||
) | ||
) | ||
raise exc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
""" | ||
Script to help validate input file before | ||
consumption by ``local_assignment_multi.py`` | ||
To use: | ||
``` | ||
pip install -r scripts/local_assignment_requirements.txt | ||
python assignment_validation.py print_duplicates --input-file=your-input-file.csv | ||
# or | ||
python assignment_validation.py print_plan_counts --input-file=your-input-file.csv | ||
""" | ||
import csv | ||
from collections import defaultdict, Counter | ||
|
||
import click | ||
|
||
INPUT_FIELDNAMES = ['email', 'university_name'] | ||
|
||
|
||
def _iterate_csv(input_file): | ||
with open(input_file, 'r') as f_in: | ||
reader = csv.DictReader(f_in, fieldnames=INPUT_FIELDNAMES, delimiter=',') | ||
# read and skip the header | ||
next(reader, None) | ||
breakpoint() | ||
for row in reader: | ||
yield row | ||
|
||
|
||
@click.command() | ||
@click.option( | ||
'--input-file', | ||
help='Path of local file containing email addresses to assign.', | ||
) | ||
def print_duplicates(input_file): | ||
unis_by_email = defaultdict(list) | ||
for row in _iterate_csv(input_file): | ||
unis_by_email[row['email']].append(row['university_name']) | ||
|
||
for email, uni_list in unis_by_email.items(): | ||
if len(uni_list) > 1: | ||
print(email, uni_list) | ||
|
||
|
||
@click.command() | ||
@click.option( | ||
'--input-file', | ||
help='Path of local file containing email addresses to assign.', | ||
) | ||
def print_plan_counts(input_file): | ||
counts_by_plan = Counter() | ||
for row in _iterate_csv(input_file): | ||
counts_by_plan[row['university_name']] += 1 | ||
|
||
for plan, count in counts_by_plan.items(): | ||
print(plan, count) | ||
|
||
|
||
@click.group() | ||
def run(): | ||
pass | ||
|
||
|
||
run.add_command(print_duplicates) | ||
run.add_command(print_plan_counts) | ||
|
||
|
||
if __name__ == '__main__': | ||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
""" | ||
Helper to generate assignment input | ||
CSVs of fake email data. | ||
""" | ||
import csv | ||
import math | ||
|
||
import click | ||
|
||
DEFAULT_EMAIL_TEMPLATE = 'testuser+{}@example.com' | ||
|
||
|
||
def generate_multi_plan_input( | ||
subscription_plan_identifiers, number_in_plan, | ||
email_template, filename, subscription_plan_fieldname='university_name', | ||
): | ||
total = len(subscription_plan_identifiers) * sum(number_in_plan) | ||
order_mag = math.ceil(math.log(total, 10)) | ||
|
||
with open(filename, 'w') as file_out: | ||
fieldnames = ['email', subscription_plan_fieldname] | ||
writer = csv.DictWriter(file_out, fieldnames) | ||
writer.writeheader() | ||
|
||
# This offset helps us generate emails | ||
# that are unique across all sub plan identifiers that we iterate. | ||
offset = 0 | ||
for plan_id, num_emails_for_plan in zip(subscription_plan_identifiers, number_in_plan): | ||
for index in range(offset, offset + num_emails_for_plan): | ||
email = email_template.format( | ||
str(index).zfill(order_mag) | ||
) | ||
writer.writerow({'email': email, subscription_plan_fieldname: plan_id}) | ||
offset = index + 1 | ||
|
||
|
||
@click.command | ||
@click.option( | ||
'--subscription-plan-identifier', '-s', | ||
multiple=True, | ||
help='One or more subscription plan identifier, comma-separated. Could be a uuid or an external name.', | ||
) | ||
@click.option( | ||
'--subscription-plan-fieldname', '-n', | ||
help='Name of output field corresponding to subscription plans', | ||
default='university_name', | ||
show_default=True, | ||
) | ||
@click.option( | ||
'--number-in-plan', '-n', | ||
multiple=True, | ||
help='One or more: Number of emails to generate in each plan.', | ||
show_default=True, | ||
) | ||
@click.option( | ||
'--email-template', | ||
default=DEFAULT_EMAIL_TEMPLATE, | ||
help='Optional python string template to use for email address generation, must take exactly one argument', | ||
) | ||
@click.option( | ||
'--filename', | ||
help='Where to write the generated file.', | ||
) | ||
def run( | ||
subscription_plan_identifier, subscription_plan_fieldname, number_in_plan, | ||
email_template, filename, | ||
): | ||
number_in_plan = [int(s) for s in number_in_plan] | ||
generate_multi_plan_input( | ||
subscription_plan_identifier, number_in_plan, email_template, | ||
filename, subscription_plan_fieldname, | ||
) | ||
|
||
|
||
if __name__ == '__main__': | ||
run() |
Oops, something went wrong.