course nav cleaners
This commit is contained in:
parent
7006f0f642
commit
3a6bed425b
471
courses.py
471
courses.py
|
|
@ -1855,46 +1855,6 @@ def xlist_cwe():
|
|||
|
||||
|
||||
|
||||
def modify_courses():
|
||||
if 1:
|
||||
# enroll teacher
|
||||
c = '17987'
|
||||
usrid = '1'
|
||||
try:
|
||||
u3 = url + "/api/v1/courses/%s/enrollments" % c
|
||||
data2 = { "enrollment[type]":"TeacherEnrollment", "enrollment[user_id]":usrid,
|
||||
"enrollment[enrollment_state]":"active" }
|
||||
r4 = requests.post(u3, headers=header, params=data2)
|
||||
print(json.dumps(json.loads(r4.text),indent=2))
|
||||
print()
|
||||
except Exception as e:
|
||||
print('****%s' % str(e))
|
||||
|
||||
if 0:
|
||||
# publish and make available to auth users
|
||||
for c in [18038, 18039, 18040, 18041, 18042, 18043, 18044]:
|
||||
try:
|
||||
#print(R)
|
||||
print(f'*Doing course id: {c}')
|
||||
courseid = c
|
||||
#d = getCourses(courseid)
|
||||
#print("\tconclude on: %s" % d['end_at'])
|
||||
|
||||
data = { 'course[is_public_to_auth_users]': True, 'course[event]': 'offer' }
|
||||
t = url + '/api/v1/courses/' + str(courseid)
|
||||
r3 = requests.put(t, headers=header, params=data)
|
||||
result = json.loads(r3.text)
|
||||
if 'name' in result:
|
||||
print(f"Name: {result['name']}")
|
||||
if 'workflow_state' in result:
|
||||
print(f" State: {result['workflow_state']}")
|
||||
if 'is_public_to_auth_users' in result:
|
||||
print(f" Public: {result['is_public_to_auth_users']}")
|
||||
#x = input('enter to continue')
|
||||
except Exception as e:
|
||||
print('****%s' % str(e))
|
||||
|
||||
|
||||
def change_term(courseid,termid):
|
||||
data = { 'course[term_id]': str(termid), 'course[restrict_enrollments_to_course_dates]':'false' }
|
||||
t = f'{url}/api/v1/courses/{courseid}'
|
||||
|
|
@ -2147,6 +2107,104 @@ def add_gav_connect(course_id):
|
|||
if "id" in result:
|
||||
return 1
|
||||
|
||||
# Create a Program Mapper redirect external tool in course nav.
|
||||
def add_career_academic_pathways(course_id):
|
||||
params = { "name": "Career & Academic Pathways",
|
||||
"privacy_level": "anonymous",
|
||||
"description": "Add links to external web resources that show up as navigation items in course, user or account navigation. Whatever URL you specify is loaded within the content pane when users click the link.",
|
||||
"consumer_key": "N/A",
|
||||
"shared_secret": "N/A",
|
||||
"url": "https://www.edu-apps.org/redirect",
|
||||
"custom_fields[new_tab]": "1",
|
||||
"custom_fields[url]": "https://gavilan.programmapper.com/academics",
|
||||
"workflow_state": "anonymous",
|
||||
"course_navigation[enabled]": "true",
|
||||
"course_navigation[visibility]": "public",
|
||||
"course_navigation[label]": "Career & Academic Pathways",
|
||||
"course_navigation[selection_width]": "800",
|
||||
"course_navigation[selection_height]": "400",
|
||||
"course_navigation[icon_url]": "https://www.edu-apps.org/assets/lti_redirect_engine/redirect_icon.png",
|
||||
"course_navigation[default]": "disabled",
|
||||
}
|
||||
|
||||
# POST
|
||||
u = url + f"/api/v1/courses/{course_id}/external_tools"
|
||||
res = requests.post(u, headers = header, params=params)
|
||||
result = json.loads(res.text)
|
||||
|
||||
#print( json.dumps( result, indent=2) )
|
||||
if "errors" in result:
|
||||
return 0
|
||||
if "id" in result:
|
||||
return 1
|
||||
|
||||
# Bulk add GavConnect to a list of course ids provided by user input.
|
||||
def add_gav_connect_prompt_list():
|
||||
raw = input("Enter course ids (comma/space separated): ")
|
||||
ids = [s.strip() for s in re.split(r"[\s,]+", raw) if s.strip()]
|
||||
if not ids:
|
||||
print("No course ids provided.")
|
||||
return
|
||||
ok = 0
|
||||
for cid in ids:
|
||||
try:
|
||||
res = add_gav_connect(cid)
|
||||
print(f"{cid}: {'OK' if res else 'FAILED'}")
|
||||
if res:
|
||||
ok += 1
|
||||
except Exception as ex:
|
||||
print(f"{cid}: error {ex}")
|
||||
print(f"Added GavConnect to {ok} of {len(ids)} courses.")
|
||||
|
||||
# Add Pathways link to every course in a selected term (default OFF).
|
||||
def add_pathways_all_courses_in_term():
|
||||
t = find_term(input("term? (ex: fa25) "))
|
||||
if not t or (not 'canvas_term_id' in t) or (not 'code' in t):
|
||||
print("Couldn't find term.")
|
||||
return
|
||||
term = t['canvas_term_id']
|
||||
print("Fetching list of all active courses")
|
||||
courses = getCoursesInTerm(term, 1, 0)
|
||||
ok, total = 0, 0
|
||||
for C in courses:
|
||||
total += 1
|
||||
try:
|
||||
res = add_career_academic_pathways(C['id'])
|
||||
print(f"{C['id']} {C.get('name','')}: {'OK' if res else 'FAILED'}")
|
||||
if res:
|
||||
ok += 1
|
||||
except Exception as ex:
|
||||
print(f"{C['id']} {C.get('name','')}: error {ex}")
|
||||
print(f"Added Pathways to {ok} of {total} courses.")
|
||||
|
||||
# Ensure Pathways link exists for every course in the term; add if missing (default OFF).
|
||||
def ensure_pathways_in_term():
|
||||
t = find_term(input("term? (ex: fa25) "))
|
||||
if not t or (not 'canvas_term_id' in t) or (not 'code' in t):
|
||||
print("Couldn't find term.")
|
||||
return
|
||||
term = t['canvas_term_id']
|
||||
TARGET_LABEL = "Career & Academic Pathways"
|
||||
print("Fetching list of all active courses")
|
||||
courses = getCoursesInTerm(term, 1, 0)
|
||||
added, present, total = 0, 0, 0
|
||||
for C in courses:
|
||||
total += 1
|
||||
try:
|
||||
tabs = fetch(f"{url}/api/v1/courses/{C['id']}/tabs") or []
|
||||
has_it = any(t.get('label') == TARGET_LABEL for t in tabs)
|
||||
if has_it:
|
||||
present += 1
|
||||
print(f"{C['id']} {C.get('name','')}: already present")
|
||||
else:
|
||||
res = add_career_academic_pathways(C['id'])
|
||||
print(f"{C['id']} {C.get('name','')}: {'ADDED' if res else 'FAILED'}")
|
||||
if res:
|
||||
added += 1
|
||||
except Exception as ex:
|
||||
print(f"{C['id']} {C.get('name','')}: error {ex}")
|
||||
print(f"Present: {present}, Added: {added}, Total: {total}")
|
||||
|
||||
def mod_eval_visibility( shell_id, visible=True ):
|
||||
evals_hidden = True
|
||||
if (visible): evals_hidden = False
|
||||
|
|
@ -2366,60 +2424,261 @@ def remove_n_analytics(section=0):
|
|||
import csv
|
||||
|
||||
def my_nav_filter(row):
|
||||
#if row['state'] != 'available':
|
||||
# return False
|
||||
if row['hidden'] == True:
|
||||
# Return True for tabs that should be considered ON for reporting.
|
||||
# A nav item is ON if visibility is 'public' and 'hidden' is n/a or False.
|
||||
if str(row.get('visibility', '')).lower() != 'public':
|
||||
return False
|
||||
# Treat missing/"n/a" as not hidden
|
||||
hidden = row.get('hidden')
|
||||
if str(hidden).lower() in ['true']:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
## Multi-pass course nav tool. Pass 1: index + XLSX; Pass 2: optional hide/show ids.
|
||||
def clean_course_nav_setup_semester(section=0):
|
||||
t = find_term( input("term? (ex: fa25) ") )
|
||||
# Multi-pass course nav tool: Pass 1 indexes tabs + writes XLSX matrix; Pass 2 optionally hides/shows selected tab ids across all courses in the term.
|
||||
TESTING = False # Limit to first 10 courses while testing
|
||||
import openpyxl
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
t = find_term(input("term? (ex: fa25) "))
|
||||
|
||||
if not t or (not 'canvas_term_id' in t) or (not 'code' in t):
|
||||
print(f"Couldn't find term.")
|
||||
print("Couldn't find term.")
|
||||
return
|
||||
|
||||
term = t['canvas_term_id']
|
||||
SEM = t['code']
|
||||
|
||||
|
||||
print("Fetching list of all active courses")
|
||||
c = getCoursesInTerm(term,1,0)
|
||||
#print(c)
|
||||
ids = []
|
||||
courses = {}
|
||||
data = {'hidden':True}
|
||||
|
||||
pause = 1
|
||||
|
||||
nav_out = codecs.open(f'cache/course_nav_summary_{SEM}.csv','w','utf-8')
|
||||
courses_in_term = getCoursesInTerm(term, 1, 0)
|
||||
if TESTING:
|
||||
print("TESTING mode enabled: limiting to first 10 courses")
|
||||
courses_in_term = courses_in_term[:10]
|
||||
|
||||
# Collect course records and their tabs
|
||||
all_tabs_by_course = {} # course_id -> list of tab dicts
|
||||
all_tab_ids = {} # tab_id -> label (most recent seen) — kept for Pass 2 id operations
|
||||
any_on_labels = set() # labels that are ON in at least one course
|
||||
|
||||
# Also write a detailed CSV of visible tabs as before
|
||||
nav_out = codecs.open(f'cache/course_nav_summary_{SEM}.csv', 'w', 'utf-8')
|
||||
nav_writer = csv.writer(nav_out)
|
||||
columns = "id name code start state label position hidden visibility type url".split(" ")
|
||||
nav_writer.writerow(columns)
|
||||
|
||||
for C in c:
|
||||
|
||||
for C in courses_in_term:
|
||||
try:
|
||||
#print( f'Fetching course {json.dumps(C,indent=2)}' )
|
||||
parts = C['sis_course_id'].split('-')
|
||||
cid = str(C['id'])
|
||||
print(C['name'])
|
||||
courses[str(C['id'])] = C
|
||||
ids.append(str(C['id']))
|
||||
|
||||
u3 = f"{url}/api/v1/courses/{C['id']}/tabs"
|
||||
tabs = fetch(u3)
|
||||
tabs = fetch(u3) or []
|
||||
# Normalize hidden
|
||||
for T in tabs:
|
||||
print(f"\t{T['label']} \t visibility: {T['visibility']}")
|
||||
#print(json.dumps(T,indent=2))
|
||||
if not 'hidden' in T: T['hidden'] = "n/a"
|
||||
vals = [C['id'], C['name'], C['course_code'], C['start_at'], C['workflow_state'], T['label'], T['position'], T['hidden'], T['visibility'], T['type'], T['html_url'] ]
|
||||
if 'hidden' not in T:
|
||||
T['hidden'] = "n/a"
|
||||
# Track global set of tab ids and a sample label
|
||||
all_tab_ids[str(T.get('id'))] = T.get('label', str(T.get('id')))
|
||||
# Write summary of ON tabs
|
||||
vals = [C['id'], C['name'], C['course_code'], C.get('start_at', ''), C.get('workflow_state', ''),
|
||||
T.get('label', ''), T.get('position', ''), T.get('hidden', ''), T.get('visibility', ''),
|
||||
T.get('type', ''), T.get('html_url', '')]
|
||||
mydict = dict(zip(columns, vals))
|
||||
if my_nav_filter(mydict):
|
||||
nav_writer.writerow(vals)
|
||||
nav_out.flush()
|
||||
if T.get('label'):
|
||||
any_on_labels.add(T.get('label'))
|
||||
nav_out.flush()
|
||||
all_tabs_by_course[cid] = tabs
|
||||
except Exception as err:
|
||||
print(f"Exception: {err}")
|
||||
|
||||
# Build XLSX matrix
|
||||
try:
|
||||
# Column order: labels with at least one ON occurrence, alphabetical
|
||||
tab_labels = sorted(any_on_labels, key=lambda x: str(x).lower())
|
||||
xlsx_path = f"cache/course_nav_matrix_{SEM}.xlsx"
|
||||
wb = openpyxl.Workbook()
|
||||
ws = wb.active
|
||||
ws.title = "matrix"
|
||||
|
||||
# Headers
|
||||
static_headers = ['course_id', 'course_name', 'first_teacher']
|
||||
# Row 1: labels only (ids omitted per request)
|
||||
row1 = static_headers + tab_labels
|
||||
ws.append(row1)
|
||||
|
||||
# Rows: one per course
|
||||
for C in courses_in_term:
|
||||
cid = str(C['id'])
|
||||
cname = C.get('name', '')
|
||||
# First teacher
|
||||
teacher = ''
|
||||
try:
|
||||
tlist = teacher_list(int(cid)) or []
|
||||
if tlist:
|
||||
# list of tuples: (id, name)
|
||||
teacher = sorted([t[1] for t in tlist])[0]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
row = [cid, cname, teacher]
|
||||
# Build a set of labels that are ON for this course
|
||||
on_labels_in_course = set()
|
||||
for tdict in all_tabs_by_course.get(cid, []) or []:
|
||||
visibility = str(tdict.get('visibility', '')).lower()
|
||||
hidden_val = tdict.get('hidden', '')
|
||||
hidden_str = str(hidden_val).lower()
|
||||
if visibility == 'public' and hidden_str not in ['true']:
|
||||
lbl = tdict.get('label')
|
||||
if lbl:
|
||||
on_labels_in_course.add(lbl)
|
||||
for lbl in tab_labels:
|
||||
row.append('x' if lbl in on_labels_in_course else '')
|
||||
ws.append(row)
|
||||
|
||||
# Simple sizing for readability
|
||||
for col_idx in range(1, ws.max_column + 1):
|
||||
col_letter = get_column_letter(col_idx)
|
||||
ws.column_dimensions[col_letter].width = 16 if col_idx > 3 else 20
|
||||
|
||||
wb.save(xlsx_path)
|
||||
print(f"Wrote matrix: {xlsx_path}")
|
||||
except Exception as ex:
|
||||
print(f"Failed to write XLSX matrix: {ex}")
|
||||
|
||||
# Optional Pass 2: apply hide/show updates (by id or label)
|
||||
try_apply = input("Apply changes? [n] hide/show selected tab ids or labels across all courses (y/N): ").strip().lower() in ['y', 'yes']
|
||||
if not try_apply:
|
||||
print("Pass 1 complete. No changes applied.")
|
||||
return
|
||||
|
||||
# Gather ids to HIDE and SHOW
|
||||
def parse_id_list(s):
|
||||
if not s:
|
||||
return []
|
||||
# allow comma/space/newline separated
|
||||
tokens = []
|
||||
for line in s.replace(',', ' ').split():
|
||||
tokens.append(line.strip())
|
||||
return [x for x in tokens if x]
|
||||
|
||||
hide_src = input("Enter tab ids OR labels to HIDE (comma/space separated), or path to file in cache/ (leave blank to skip): ").strip()
|
||||
show_src = input("Enter tab ids OR labels to SHOW (add/unhide), or path to file in cache/ (leave blank to skip): ").strip()
|
||||
|
||||
hide_ids = []
|
||||
show_ids = []
|
||||
hide_labels = []
|
||||
show_labels = []
|
||||
# file helper
|
||||
def read_ids_from_path(pth):
|
||||
try:
|
||||
with codecs.open(pth, 'r', 'utf-8') as f:
|
||||
return parse_id_list(f.read())
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
# Build a set of all labels observed (from all tabs, not only ON)
|
||||
all_labels_seen = set()
|
||||
for _cid, tlist in all_tabs_by_course.items():
|
||||
for t in (tlist or []):
|
||||
if t.get('label'):
|
||||
all_labels_seen.add(t.get('label'))
|
||||
|
||||
def split_ids_labels(raw_list):
|
||||
ids_out, labels_out = [], []
|
||||
for tok in raw_list:
|
||||
if tok in all_tab_ids or re.match(r"^[a-z_]+(_[a-z0-9]+)*$", tok):
|
||||
# Heuristic: looks like an id (e.g., syllabus, pages, context_external_tool_123)
|
||||
ids_out.append(tok)
|
||||
elif tok in all_labels_seen:
|
||||
labels_out.append(tok)
|
||||
else:
|
||||
# Default to label if not recognizable as id
|
||||
labels_out.append(tok)
|
||||
return [str(x) for x in ids_out], labels_out
|
||||
|
||||
if hide_src:
|
||||
if os.path.exists(hide_src):
|
||||
toks = read_ids_from_path(hide_src)
|
||||
elif os.path.exists(os.path.join('cache', hide_src)):
|
||||
toks = read_ids_from_path(os.path.join('cache', hide_src))
|
||||
else:
|
||||
toks = parse_id_list(hide_src)
|
||||
hide_ids, hide_labels = split_ids_labels(toks)
|
||||
|
||||
if show_src:
|
||||
if os.path.exists(show_src):
|
||||
toks = read_ids_from_path(show_src)
|
||||
elif os.path.exists(os.path.join('cache', show_src)):
|
||||
toks = read_ids_from_path(os.path.join('cache', show_src))
|
||||
else:
|
||||
toks = parse_id_list(show_src)
|
||||
show_ids, show_labels = split_ids_labels(toks)
|
||||
|
||||
if not (hide_ids or show_ids or hide_labels or show_labels):
|
||||
print("No ids provided. Skipping Pass 2.")
|
||||
return
|
||||
|
||||
print(f"HIDE ids: {hide_ids}")
|
||||
print(f"HIDE labels: {hide_labels}")
|
||||
print(f"SHOW ids: {show_ids}")
|
||||
print(f"SHOW labels: {show_labels}")
|
||||
confirm = input("Proceed with updates? (y/N): ").strip().lower() in ['y', 'yes']
|
||||
if not confirm:
|
||||
print("Aborted. No changes applied.")
|
||||
return
|
||||
|
||||
# Apply changes
|
||||
for C in courses_in_term:
|
||||
cid = str(C['id'])
|
||||
try:
|
||||
course_tabs = all_tabs_by_course.get(cid)
|
||||
# Refresh tabs to reduce staleness just before applying
|
||||
if course_tabs is None:
|
||||
course_tabs = fetch(f"{url}/api/v1/courses/{cid}/tabs") or []
|
||||
tabs_by_id = {str(t.get('id')): t for t in course_tabs}
|
||||
tabs_by_label = defaultdict(list)
|
||||
for t in course_tabs:
|
||||
lbl = t.get('label')
|
||||
if lbl:
|
||||
tabs_by_label[lbl].append(t)
|
||||
|
||||
# Helpers to PUT hide/show for a tab id
|
||||
def set_hidden_for_id(tab_id, hidden_val):
|
||||
put_url = f"{url}/api/v1/courses/{cid}/tabs/{tab_id}"
|
||||
data = {'hidden': hidden_val}
|
||||
r = requests.put(put_url, headers=header, params=data)
|
||||
action = 'HIDE' if hidden_val else 'SHOW'
|
||||
print(f"{action} {cid} {C.get('name','')} -> {tab_id}: {r.status_code}")
|
||||
|
||||
# Hide by ids
|
||||
for tid in hide_ids:
|
||||
if tid in tabs_by_id:
|
||||
set_hidden_for_id(tid, True)
|
||||
|
||||
# Show by ids
|
||||
for tid in show_ids:
|
||||
if tid in tabs_by_id:
|
||||
set_hidden_for_id(tid, False)
|
||||
|
||||
# Hide by labels
|
||||
for lbl in hide_labels:
|
||||
for t in tabs_by_label.get(lbl, []):
|
||||
tid = str(t.get('id'))
|
||||
set_hidden_for_id(tid, True)
|
||||
|
||||
# Show by labels
|
||||
for lbl in show_labels:
|
||||
for t in tabs_by_label.get(lbl, []):
|
||||
tid = str(t.get('id'))
|
||||
set_hidden_for_id(tid, False)
|
||||
except Exception as ex:
|
||||
print(f"Failed applying to course {cid}: {ex}")
|
||||
|
||||
print("Pass 2 complete.")
|
||||
|
||||
|
||||
def fetch_rubric_scores(course_id=16528, assignment_id=1):
|
||||
api_url = f'{url}/api/v1/courses/{course_id}'
|
||||
|
|
@ -2788,64 +3047,66 @@ if __name__ == "__main__":
|
|||
options = { 1: ['Cross check schedule with ztc responses',make_ztc_list] ,
|
||||
2: ['Add announcements to homepage', change_course_ann_homepage],
|
||||
3: ['Unpublish a course', unpublish_a_course],
|
||||
4: ['List students who passed quiz X', get_quiz_passers],
|
||||
5: ['List the terms', getTerms],
|
||||
7: ['Show courses in a term', getCoursesInTerm],
|
||||
8: ['Save enrollments in a course', course_enrollment],
|
||||
9: ['Simple list of course data, search by sis_id', course_search_by_sis],
|
||||
10: ['Overview of a term', course_term_summary],
|
||||
20: ['process the semester overview output (10)', course_term_summary_2],
|
||||
##55: ['Check all courses & their sections in semester', all_semester_course_sanity_check],
|
||||
4: ['List the terms', getTerms],
|
||||
5: ['Show courses in a term', getCoursesInTerm],
|
||||
6: ['Save enrollments in a course', course_enrollment],
|
||||
7: ['Simple list of course data, search by sis_id', course_search_by_sis],
|
||||
8: ['Overview of a term', course_term_summary],
|
||||
9: ['process the semester overview output (8)', course_term_summary_2],
|
||||
|
||||
10: ['Enroll orientation students (refresh local db first)', enroll_orientation_students],
|
||||
11: ['Enroll ORIENTATION and STEM student shells after catching up database.', enroll_o_s_students],
|
||||
12: ['Enroll stem students', enroll_stem_students_live],
|
||||
13: ['Enroll orientation students (refresh local db first)', enroll_orientation_students],
|
||||
14: ['Enroll ART students', enroll_art_students_live],
|
||||
13: ['Enroll ART students', enroll_art_students_live],
|
||||
|
||||
22: ['Get a course info by id',getCourses],
|
||||
23: ['Reset course conclude date',update_course_conclude],
|
||||
20: ['Get a course info by id',getCourses],
|
||||
21: ['Reset course conclude date',update_course_conclude],
|
||||
22: ['Create calendar events for orientation shells', create_calendar_event],
|
||||
23: ['list all assignments', list_all_assignments],
|
||||
24: ['Bulk unenroll from course', bulk_unenroll],
|
||||
25: ['enrollment helper', enrollment_helper],
|
||||
26: ['g number list enroll to shell id', enroll_gnumber_list_to_courseid],
|
||||
|
||||
25: ['ext tools',get_ext_tools],
|
||||
26: ['set ext tools',set_ext_tools],
|
||||
32: ['Get course ext tools', get_course_ext_tools],
|
||||
33: ['Add GavConnect to a course', do_gav_connect],
|
||||
17: ['Remove "new analytics" from all courses navs in a semester', remove_n_analytics],
|
||||
21: ['Add course evals', add_evals],
|
||||
56: ['Remove course evals all sections', remove_evals_all_sections],
|
||||
52: ['Cleanup semester / course nav', clean_course_nav_setup_semester], # not done, just lists nav right now
|
||||
|
||||
29: ['* Overview semester start dates',overview_start_dates],
|
||||
30: ['* Overview semester start dates',overview_start_dates],
|
||||
31: ['Fine tune term dates and winter session', course_by_depts_terms],
|
||||
32: ['Set summer start dates', set_custom_start_dates],
|
||||
#32: ['Cross-list classes', xlist ],
|
||||
#33: ['Cross list helper', eslCrosslister],
|
||||
33: ['Cross list, ask for sections', ez_xlist],
|
||||
34: ['Cross list a semester from argos export file', semester_cross_lister],
|
||||
35: ['Cross list from manually created file', do_manual_xlist],
|
||||
36: ['Quick course list', quick_sem_course_list ],
|
||||
37: ['Cross list CWE courses', xlist_cwe],
|
||||
38: ['Create calendar events for orientation shells', create_calendar_event],
|
||||
39: ['list all assignments', list_all_assignments],
|
||||
36: ['Cross list CWE courses', xlist_cwe],
|
||||
|
||||
40: ['Enroll GOTT Workshops', enroll_gott_workshops],
|
||||
41: ['Create some sandbox courses', create_sandboxes],
|
||||
42: ['Add teacher to many shells', teacher_to_many_shells],
|
||||
43: ['Bulk unenroll from course', bulk_unenroll],
|
||||
44: ['List users who passed GOTT 1 / Bootcamp', get_gott1_passers],
|
||||
45: ['List users who passed Plagiarism Module', get_plague_passers],
|
||||
46: ['make courses visible to auth users', modify_courses],
|
||||
47: ['enrollment helper', enrollment_helper],
|
||||
48: ['g number list enroll to shell id', enroll_gnumber_list_to_courseid],
|
||||
|
||||
50: ['Fetch rubric scores and comments', fetch_rubric_scores],
|
||||
51: ['Fetch announcements in a course', fetch_announcements],
|
||||
52: ['show course audit log', course_log],
|
||||
53: ['fetch a rubric', fetch_rubric],
|
||||
|
||||
# --- Course Nav / External Tools ---
|
||||
70: ['ext tools',get_ext_tools],
|
||||
71: ['set ext tools',set_ext_tools],
|
||||
72: ['Get course ext tools', get_course_ext_tools],
|
||||
73: ['Remove "new analytics" from all courses navs in a semester', remove_n_analytics],
|
||||
74: ['Add course evals', add_evals],
|
||||
75: ['Remove course evals all sections', remove_evals_all_sections],
|
||||
76: ['Course nav: index + bulk hide/show (one semester)', clean_course_nav_setup_semester],
|
||||
77: ['Nav: add GavConnect to list of course ids', add_gav_connect_prompt_list],
|
||||
78: ['Nav: add Pathways to all courses in a term (default OFF)', add_pathways_all_courses_in_term],
|
||||
79: ['Nav: ensure Pathways exists for a term (add if missing, OFF)', ensure_pathways_in_term],
|
||||
|
||||
# 24: ['Add course evals to whole semester',instructor_list_to_activate_evals],
|
||||
# 21: ['Add announcements to homepage', change_course_ann_homepage],
|
||||
#32: ['Cross-list classes', xlist ],
|
||||
#33: ['Cross list helper', eslCrosslister],
|
||||
##55: ['Check all courses & their sections in semester', all_semester_course_sanity_check],
|
||||
#4: ['List students who passed quiz X', get_quiz_passers],
|
||||
# TODO wanted: group shell for each GP (guided pathway) as a basic student services gateway....
|
||||
#
|
||||
|
||||
50: ['Fetch rubric scores and comments', fetch_rubric_scores],
|
||||
51: ['Fetch announcements in a course', fetch_announcements],
|
||||
57: ['show course audit log', course_log],
|
||||
|
||||
60: ['fetch a rubric', fetch_rubric],
|
||||
}
|
||||
print ('')
|
||||
|
||||
|
|
|
|||
|
|
@ -1633,6 +1633,50 @@ def repl():
|
|||
### courses.py
|
||||
|
||||
|
||||
|
||||
# no longer used?
|
||||
def modify_courses():
|
||||
if 1:
|
||||
# enroll teacher
|
||||
c = '17987'
|
||||
usrid = '1'
|
||||
try:
|
||||
u3 = url + "/api/v1/courses/%s/enrollments" % c
|
||||
data2 = { "enrollment[type]":"TeacherEnrollment", "enrollment[user_id]":usrid,
|
||||
"enrollment[enrollment_state]":"active" }
|
||||
r4 = requests.post(u3, headers=header, params=data2)
|
||||
print(json.dumps(json.loads(r4.text),indent=2))
|
||||
print()
|
||||
except Exception as e:
|
||||
print('****%s' % str(e))
|
||||
|
||||
if 0:
|
||||
# publish and make available to auth users
|
||||
for c in [18038, 18039, 18040, 18041, 18042, 18043, 18044]:
|
||||
try:
|
||||
#print(R)
|
||||
print(f'*Doing course id: {c}')
|
||||
courseid = c
|
||||
#d = getCourses(courseid)
|
||||
#print("\tconclude on: %s" % d['end_at'])
|
||||
|
||||
data = { 'course[is_public_to_auth_users]': True, 'course[event]': 'offer' }
|
||||
t = url + '/api/v1/courses/' + str(courseid)
|
||||
r3 = requests.put(t, headers=header, params=data)
|
||||
result = json.loads(r3.text)
|
||||
if 'name' in result:
|
||||
print(f"Name: {result['name']}")
|
||||
if 'workflow_state' in result:
|
||||
print(f" State: {result['workflow_state']}")
|
||||
if 'is_public_to_auth_users' in result:
|
||||
print(f" Public: {result['is_public_to_auth_users']}")
|
||||
#x = input('enter to continue')
|
||||
except Exception as e:
|
||||
print('****%s' % str(e))
|
||||
|
||||
|
||||
|
||||
|
||||
##########
|
||||
########## CALCULATING SEMESTER STUFF
|
||||
##########
|
||||
|
|
|
|||
103
users.py
103
users.py
|
|
@ -1932,112 +1932,9 @@ def track_users_by_teacherclass():
|
|||
teacherfile.write(''.join(R))
|
||||
teacherfile.flush()
|
||||
teacherfile.close()
|
||||
|
||||
|
||||
|
||||
print(json.dumps(g2, indent=2))
|
||||
|
||||
|
||||
## moved: nlp_sample now in search.py
|
||||
# def nlp_sample():
|
||||
# Stream a training corpus directly from S3.
|
||||
#corpus = corpora.MmCorpus("s3://path/to/corpus")
|
||||
|
||||
stemmer = stem.porter.PorterStemmer()
|
||||
|
||||
strings = [
|
||||
"Human machine interface for lab abc computer applications",
|
||||
"A survey of user opinion of computer system response time",
|
||||
"The EPS user interface management system",
|
||||
"System and human system engineering testing of EPS",
|
||||
"Relation of user perceived response time to error measurement",
|
||||
"The generation of random binary unordered trees",
|
||||
"The intersection graph of paths in trees",
|
||||
"Graph minors IV Widths of trees and well quasi ordering",
|
||||
"Graph minors A survey",
|
||||
]
|
||||
# moved
|
||||
dct = dictionary
|
||||
print(dictionary)
|
||||
|
||||
corpus = [dictionary.doc2bow(text) for text in processed]
|
||||
|
||||
print(corpus)
|
||||
|
||||
# Train Latent Semantic Indexing with 200D vectors.
|
||||
lsi = models.LsiModel(corpus, num_topics=4)
|
||||
print(lsi.print_topics(-1))
|
||||
|
||||
# Convert another corpus to the LSI space and index it.
|
||||
#index = similarities.MatrixSimilarity(lsi[another_corpus])
|
||||
|
||||
tfidf = models.TfidfModel(corpus)
|
||||
|
||||
#index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=12)
|
||||
index = similarities.MatrixSimilarity(lsi[corpus])
|
||||
print(index)
|
||||
|
||||
|
||||
# Compute similarity of a query vs indexed documents.
|
||||
query = "tree graph".split()
|
||||
query_bow = dictionary.doc2bow(query)
|
||||
vec_lsi = lsi[query_bow]
|
||||
|
||||
print(query_bow)
|
||||
print(tfidf[query_bow])
|
||||
print(vec_lsi)
|
||||
print("ok")
|
||||
|
||||
# LdaMulticore
|
||||
|
||||
lda_model = models.LdaModel(corpus=corpus,
|
||||
id2word=dictionary,
|
||||
random_state=100,
|
||||
num_topics=4,
|
||||
passes=40,
|
||||
chunksize=1000,
|
||||
#batch=False,
|
||||
alpha='asymmetric',
|
||||
decay=0.5,
|
||||
offset=64,
|
||||
eta=None,
|
||||
eval_every=0,
|
||||
iterations=100,
|
||||
gamma_threshold=0.001,
|
||||
per_word_topics=True)
|
||||
lda_model.save('cache/lda_model.model')
|
||||
print(lda_model.print_topics(-1))
|
||||
print(lda_model)
|
||||
|
||||
for c in lda_model[corpus]:
|
||||
print("Document Topics : ", c[0]) # [(Topics, Perc Contrib)]
|
||||
print("Word id, Topics : ", c[1][:3]) # [(Word id, [Topics])]
|
||||
print("Phi Values (word id) : ", c[2][:2]) # [(Word id, [(Topic, Phi Value)])]
|
||||
print("Word, Topics : ", [(dct[wd], topic) for wd, topic in c[1][:2]]) # [(Word, [Topics])]
|
||||
print("Phi Values (word) : ", [(dct[wd], topic) for wd, topic in c[2][:2]]) # [(Word, [(Topic, Phi Value)])]
|
||||
print("------------------------------------------------------\n")
|
||||
|
||||
|
||||
sims = index[vec_lsi]
|
||||
print("ok2")
|
||||
print(list(enumerate(sims)))
|
||||
|
||||
for document_number, score in sorted(enumerate(sims), key=lambda x: x[1], reverse=True):
|
||||
print(document_number, score)
|
||||
|
||||
'''
|
||||
def nlp_sample2():
|
||||
# load english language model
|
||||
nlp = spacy.load('en_core_web_sm',disable=['ner','textcat'])
|
||||
|
||||
text = "This is a sample sentence."
|
||||
|
||||
# create spacy
|
||||
doc = nlp(text)
|
||||
|
||||
for token in doc:
|
||||
print(token.text,'->',token.pos_)
|
||||
'''
|
||||
|
||||
def section_enroll():
|
||||
user = input("user id> ")
|
||||
|
|
|
|||
Loading…
Reference in New Issue