canvasapp/apphelp.py

1620 lines
31 KiB
Python

import os,re
output = ''
todos = 0
todos_d = {}
# TODO: Make a second pass, and look for fxn calls inside of
# each function. Draw a graphviz.
#
def fxns(fname):
global output, todos
lines = open(fname).readlines()
prev_L = ""
for L in lines:
# is it a todo
a = re.search(r'(TODO|todo)\s*:?\s*(.*)$',L)
if a:
output += "\t\ttodo: " + a.group(2) + "\n"
todos += 1
if fname in todos_d:
todos_d[fname] += 1
else:
todos_d[fname] = 1
# is it a function def?
if re.search('^\s*def\s',L):
output += "\n"
if re.search('^#',prev_L): output += "\t"+prev_L
output += "\t"+L+""
prev_L = L
files = os.listdir('.')
files.sort()
for F in files:
if F=='apphelp.py': continue
if re.search('\.py$',F):
output += "\n" + F + "\n"
fxns(F)
prog_in = open('apphelp.py','r')
prog_out = ''
td = '# Total TODOs remaining: %i' % todos
td2 = '# TODOs per file: \n#\n'
for k in sorted(todos_d.keys()):
td2 += "#\t%i - %s \n" % (todos_d[k],k)
for R in prog_in.readlines():
if re.search('^##\sF',R):
prog_out += "## Functions\n#\n%s\n#\n%s\n#\n" % (td,td2)
break
prog_out += R
prog_out += '\n"""\n\n' + output + '\n\n"""\n\n'
prog_in.close()
prog_write = open('apphelp.py','w')
prog_write.write(prog_out)
prog_write.close()
## Functions
#
# Total TODOs remaining: 57
#
# TODOs per file:
#
# 1 - checker.py
# 1 - content.py
# 6 - courses.py
# 3 - curriculum.py
# 5 - depricated.py
# 6 - localcache.py
# 2 - outcomes.py
# 20 - pipelines.py
# 2 - server.py
# 2 - tasks.py
# 1 - tempget.py
# 8 - users.py
#
"""
__init__.py
checker.py
todo: make this sweet
def safe_html(html):
def _attr_name_whitelisted(attr_name):
def safe_css(attr, css):
def plaintext(input):
def _unescape(text):
def fixup(m):
def check_folder(fname,path):
def check_class(folder):
def check_all():
content.py
def d(s):
def stripper(s):
def mycleaner(s):
def freshdesk():
# Build a master file with the entire class content
def accessible_check(id=""):
todo: include linked pages even if they aren't in module
def pan_testing():
# Given course, page url, and new content, upload the new revision of a page
def create_page(course_num,new_title,new_content):
def md_to_course():
# DL pages only
def grab_course_pages(course_num=-1):
# Appears to not be used
def put_course_pages():
# Also not used
def put_revised_pages():
# Download, clean html, and reupload page
def update_page():
# Given course, page url, and new content, upload the new revision of a page
def upload_page(course_num,pageurl,new_content):
# Use template to build html page with homegrown subtitles
def build_srt_embed_php(data):
def yt_title(code):
def swap_youtube_subtitles():
def test_swap():
def multiple_downloads():
courses.py
todo:
def int_or_zero(x):
def float_or_zero(x):
# Gott 1 Bootcamp - report on who completed it.
def get_gott1_passers():
# Plagiarism Module - report on who completed it.
def get_plague_passers():
# Who, in a class, passed?
def get_course_passers(course, min_passing, passers_filename, still_active_filename):
# Change courses to show 2 announcements
def change_course_ann_homepage(id="10458"):
def scrape_bookstore():
todo: where does the most recent schedule come from?
# Input: xxxx_sched.json. Output: xxxx_latestarts.txt
def list_latestarts():
# All students enrolled in a class in the given semester. Simpler verson of below. Return SET of course_ids.
def users_in_semester():
todo:
# All students in STEM (or any list of depts.. match the course_code). Return SET of canvas ids.
def users_in_depts_live(depts=[], termid='171'):
def course_enrollment(id=''):
def askForTerms():
# Return a list of term names and IDs. Also store in cache/courses/terms.txt
def getTerms(printme=1, ask=1):
todo: unsafe overwrite
def getCourses(): # a dict
# Relevant stuff trying to see if its even being used or not
def course_term_summary():
# Fetch all courses in a given term
def getCoursesInTerm(term=0,show=1,active=0): # a list
def getCoursesTermSearch(term=0,search='',v=0):
def courseLineSummary(c,sections={}):
def xlistLineSummary(c,sections={}):
def eslCrosslister():
def xlist(parasite='', host=''): # section id , new course id
todo: need to get the section id from each course:
def unenroll_student(courseid,enrolid):
def enroll_stem_students_live():
def enroll_orientation_students():
def summarize_proportion_online_classes(u):
def summarize_num_term_classes(u):
def make_ztc_list(sem='sp20'):
def course_search_by_sis():
def add_evals(section=0):
todo: wanted: group shell for each GP (guided pathway) as a basic student services gateway....
curriculum.py
todo: These secrets
def another_request(url,startat):
def fetch_all_classes():
def fetch_all_programs():
def sortable_class(li):
def c_name(c):
def show_classes(createoutput=1):
def clean_d_name(d):
def show_programs():
def dd(): return defaultdict(dd)
def organize_courses():
def check_de():
def clean_programs():
def course_lil_format(s):
def header_lil_format(s):
def organize_programs():
def divide_courses_list(li,rwd,online):
def organize_programs2():
# sorting by order key of dict
def cmp_2(a):
def cmp_order(a,b):
# decipher the grouped up courses line
def split_course(st):
# Any number gets an X (checked). Blank or zero gets no check.
def units_to_x(u):
def p_block_rule(r,printme,doc,out=0):
def p_cert_header(type,doc,r='',out=0):
def p_block_header(r,doc,out=0):
def p_cert_course_missing(cd,doc,out=0):
def p_cert_course(cd,history,doc,out=0):
def p_end_block(out=0):
def p_end_cert(bigdoc, out=0):
def ask_for_rule(r):
def action_to_english(a):
# Return True if the courses satisfy the rule
def check_a_block(b, courses, verbose=False):
def read_block_english_to_code():
def read_section_online_history():
todo: this file depends on other fxns. which?
# This is the 3rd attempt.
def simple_find_online_programs():
todo: courses with a HYPHEN in NAME get parsed wrong.
def check_a_block_a(b,verbose=False):
def smart_find_online_programs():
def show_contained_class(c):
def show_block(c):
def show_block(c):
def is_online(c):
def is_online(c):
def is_online_inblock(c):
def is_online_inblock(c):
# of all the programs, what can be accomplished online?
def find_online_programs():
# take a string of all the types of classes offered, return a vector of [tot,lec,hyb,onl]
def string_to_types(st):
def my_default_counter():
# Of the recent schedules, what was actually offered online?
def summarize_online_sections():
def fibonacci(n):
def test_pampy():
def cq_parse_experiment(root=0, indent=''):
def cq_start():
def cq_pattern_backup1(root=0, indent=''):
def found(*x):
def lookForMatch(rules,item):
def cq_pattern(root=0, indent=''):
def myprinter(item, indent=''):
def cq_pattern_start():
def baby_int(j):
def find_deg_in_cluster( clusters, deg ):
def try_match_deg_programs():
def dict_generator(indict, pre=None):
def print_dict(v, prefix='',indent=''):
def walk_file():
def tag(x,y): return "<%s>%s</%s>" % (x,y,x)
def tagc(x,c,y): return '<%s class="%s">%s</%s>' % (x,c,y,x)
def a(t,h): return '<a href="%s">%s</a>' % (h,t)
def server_save(key,value):
def flask_thread(q):
def home():
def s(key,val):
def hello():
def sd():
def serve():
def attempt_match8020(rules,item):
def clever_printer(item, indent=''):
def print_return(x):
def cq_8020(root=0, indent=''):
def cq_8020_start():
curriculum2020.py
def to_md(s):
def print_return(x):
def cq_8020(root,indent=0):
def cq_8021(root,indent=0):
def cq_8021_start():
def cq_8022(root,indent=0):
def cq_8022_start():
def sortable_class(li):
def c_name(c):
def show_classes2020():
def show_classes2020_start():
curriculum_patterns.py
def div1(a,b):
def d2(a,b):
def d3(a,b):
def pp1(a,b):
def pp2(a,b):
def pp3(a,b,c,d,e,f,g):
def pp4(a,b):
def pp5(a,b,c):
def pp6(a,b):
def pp7(a,b):
def pp8(a,b):
def jj1(a,b,c,d,e):
def jj2(a,b,c,d,e,f):
def jj3(a,b,c,d,e):
def jj4(a,b,c,d):
def jj5(a,b,c,d,e,f):
def jj6(a,b,c,d):
def jj2(a,b,c,d):
def jj2(a,b,c,d):
depricated.py
# Don't know
def demo():
def stats():
def dict_generator(indict, pre=None):
def print_dict(v, prefix='',indent=''):
def walk_file():
def tag(x,y): return "<%s>%s</%s>" % (x,y,x)
def tagc(x,c,y): return '<%s class="%s">%s</%s>' % (x,c,y,x)
def a(t,h): return '<a href="%s">%s</a>' % (h,t)
def server_save(key,value):
def flask_thread(q):
def home():
def s(key,val):
def hello():
def sd():
def serve():
todo: this duplicates courses.py ??
# Prompt for course id, return list of user dicts. TODO this duplicates courses.py ??
def getUsersInCourse(id=0): # returns list
todo:
# NO LONGER USED - SEE COURSES
def enroll_stem_students():
# unused?
def getAllTeachersInTerm(): # a list
todo: hits in courses by teachers https://gavilan.instructure.com:443/api/v1/users/2/page_views?end_time=Dec%2010%2C%202018
def teacherActivityLog(uid=1): ### Next: save results in a hash and return that....
def summarize_student_teacher_role(u):
def user_roles2():
def req_to_db(fname_list):
def has_online(series):
def has_lecture(series):
def has_hybrid(series):
# Wrapper to get 2 schedules at once
def dl_sched():
todo: these semesters
# Send a personalized email regarding ZTC
def send_z_email(fullname, firstname, addr, courses_list):
def getInactiveTeachersInTerm(t=23): # a list
def course_location(course):
def course_time(course):
def course_teacher(course):
def reg_nums():
# In the schedule, is this a class or a continuation of the class above?
def categorize():
todo: must we open all these files?
# Deprecated. call perl.
def constructSchedule():
def fetch_dict(target,params={}):
def get_schedule(term='201870', sem='fall'):
interactive.py
def dict_generator(indict, pre=None):
def print_dict(v, prefix='',indent=''):
def walk_file():
def tag(x,y): return "<%s>%s</%s>" % (x,y,x)
def tagc(x,c,y): return '<%s class="%s">%s</%s>' % (x,c,y,x)
def a(t,h): return '<a href="%s">%s</a>' % (h,t)
def server_save(key,value):
def flask_thread(q):
def before_request():
def save_post():
def restart():
def dispatch3(func,arg,arrg):
def dispatch2(func,arg):
def dispatch(func):
def dispatch3j(func,arg,arrg):
def dispatch2j(func,arg):
def dispatch1j(func):
def home():
def send_jslib(path):
def send_cachedata(path):
def send_js(path):
def s(key,val):
def do_sample():
def media(file_id):
def podcast():
def weblec():
def hello():
def sd():
def test_message(message):
def serve():
def make_teacher_rel(self, tchr, clss):
def __init__(self, uri, user, password):
def close(self):
def print_greeting(self, message):
def _create_and_return_greeting(tx, message):
def make_teacher_rel(g, tchr, clss):
def testgraph():
def Memoize( func):
def wrapper(*args):
def startup(self, outfile):
def set_my_dict(self,d):
def cycle_color(self, s):
def ascii_art(self, text):
def close_window(self, ):
def suggest(self, word):
def curses_print_word(self, word,color_pair_code):
def curses_print_line(self, line,color_pair_code):
def redraw(self, start_y,end_y,fallback_y,fallback_x):
def scroll_down(self, noredraw,fallback_y,fallback_x):
def clear_upside(self, n,y,x):
def display_suggest(self, y,x,word):
def inputloop(self, ):
def setup_command(self,outfile):
def cleanup_command(self):
def handle_command(self, cmd):
def repl_staff():
def repl_degs():
def repl():
def repl():
interactivex.py
def dict_generator(indict, pre=None):
def print_dict(v, prefix='',indent=''):
def walk_file():
def tag(x,y): return "<%s>%s</%s>" % (x,y,x)
def tagc(x,c,y): return '<%s class="%s">%s</%s>' % (x,c,y,x)
def a(t,h): return '<a href="%s">%s</a>' % (h,t)
def server_save(key,value):
def flask_thread(q):
def before_request():
def restart():
def dispatch3(func,arg,arrg):
def dispatch2(func,arg):
def dispatch(func):
def dispatch3j(func,arg,arrg):
def dispatch2j(func,arg):
def dispatch1j(func):
def home():
def send_jslib(path):
def send_cachedata(path):
def send_js(path):
def s(key,val):
def do_sample():
def hello():
def sd():
def serve():
def make_teacher_rel(self, tchr, clss):
def __init__(self, uri, user, password):
def close(self):
def print_greeting(self, message):
def _create_and_return_greeting(tx, message):
def make_teacher_rel(g, tchr, clss):
def Memoize( func):
def wrapper(*args):
def startup(self, outfile):
def set_my_dict(self,d):
def cycle_color(self, s):
def ascii_art(self, text):
def close_window(self, ):
def suggest(self, word):
def curses_print_word(self, word,color_pair_code):
def curses_print_line(self, line,color_pair_code):
def redraw(self, start_y,end_y,fallback_y,fallback_x):
def scroll_down(self, noredraw,fallback_y,fallback_x):
def clear_upside(self, n,y,x):
def display_suggest(self, y,x,word):
def inputloop(self, ):
def setup_command(self,outfile):
def cleanup_command(self):
def handle_command(self, cmd):
def repl_staff():
def repl_degs():
def repl():
def repl():
ipython_log.py
localcache.py
def db():
def setup_table(table='requests'):
# Help the next function to upload new users directly to conf database on gavilan.
def employees_refresh_flex(data):
# Everyone in iLearn DB with an xyz@gavilan.edu email address.
def all_gav_employees():
#
def teachers_courses_semester():
#
def teachers_by_term():
# Report for AEC
def aec_su20_report():
# Return the most up do date version of the given file. Useful for 'dimensions'.
def most_recent_file_of( target ):
def finder(st):
# Given a table schema, parse log file, return a list of dicts. Optionally remove some columns.
def parse_file_with( file, format, with_gid=0 ):
# I return a list of the read lines if the log dates in the file are within dates (top of this file), or FALSE
def is_requestfile_interesting(fname):
todo: more robust here
todo: - investigate pearson, developer key: 170000000000376 and their ridiculous amounts of hits.
# Return a 'timeblock'. An integer number of 15 minute blocks from my epoch. Expects a datetime object in PST timezone.
def timeblock_from_dt(dt_obj):
# Returns a time in PST, given a 'timeblock'. Will be used in translating back to human time
def dt_from_timeblock(tb):
# Twenty Four hour timeblocks
def timeblock_24hr_from_dt(dt_obj):
# Returns a time in PST, given a 'timeblock'. Will be used in translating back to human time
def dt_from_24hr_timeblock(tb):
# Four hour timeblocks
def timeblock_4hr_from_dt(dt_obj):
# Returns a time in PST, given a 'timeblock'. Will be used in translating back to human time
def dt_from_4hr_timeblock(tb):
# I make the line into a dict, erase keys with no data, make a DT field called date, make a time_block (int) field.
def requests_line(line,i=0):
# Bulk insert of requests logs. Too much data to be useful.
def requests_file(fname_list):
todo: select if timeblock exists
# Insert or update a request line.
def upsert_request(line, vals):
# Generic insert of a dict into a table. Keys of dict must match table columns.
def dict_to_insert(thisline,table): # a dict
# This now does tallying by timeblock.
def merge_requests():
def merge_comm_channel():
def merge_pseudonym():
def merge_users():
def merge_courses():
def merge_enrollment():
def merge_term():
def merge_roles():
def merge_convos():
# For returning sqlite results as dicts
def dict_factory(cursor, row):
todo: ... approaches to all this data... list requests in order descending time, unique users, and just
# Attempt to do tallying
def make_views_summarys():
# original without time_blocks info.
def make_views_summarys_v1():
# Setup my basic db stats base from scratch
def full_reload():
def guess_dept(t):
# Main view of all class / all user overview...
def dept_with_studentviews(dept="", sem=''):
def f(x):
# get student count and teacher name from local db
def course_quick_stats(canvasid):
# What a student has taken / teacher has taught
def user_enrolled_in(userid):
# All students in this semester ...
def users_this_semester_db(sem=''):
# Everyone whose first semester is .....
def users_new_this_semester(sem=''):
# All student users in STEM - from local db
def user_in_stem():
# Get all the classes in one dept
def dept_classes(dept,sem=''):
todo:
def depts_with_classcounts(sem=''):
todo:
def f(x):
def name_with_count(name,li):
def arrange_data_for_web(dept='', sem=''):
def f(x):
# Get enrollments. (Best to freshly run pipelines/get_rosters) and put them into DB
def build_tables(headers,name):
def load_tables(table,headers,row,verbose=0):
def semester_enrollments(verbose=0):
def qstrip(txt): return txt.strip('"')
def more_unused_xreferencing():
def user_role_and_online():
def comm_channel_file():
def pseudonym_file():
def users_p_file():
def com_channel_dim():
def abcd():
def crns_to_teachers():
main.py
outcomes.py
def outcome_overview(term=21):
def create_acct_lvl_outcomes(src,dept,makefolder='',folder=0):
def connect_acct_oc_to_course(course_id,oc_group_id):
def outcome_groups():
def outcome_groups_backup():
def x_ref_dept_names():
def create_course_group(short,parent):
def create_dept_group(short):
def outcomes_attached_to_courses(term=65,limitdept=''):
todo: Handle this: CSIS/DM85 WEB DESIGN 40823/24
def summarize_course_online_slo(outcome_list):
def fetch_outcome_details(id):
# Report on the actual evaluation data?
def outcome_report1():
todo:
# For the given course, get all outcome measurements, and display scores and stats.
def outcome_report2():
def fix_joined_class(str):
def split_slo_name(str):
def outcome_report3():
def read_slo_source():
def slo_source_by_dept():
patterns_8020.py
patterns_topdown.py
def pp0(a,b,c,d,e):
def pp1(a,b,c,d,e,f):
def pp2(a,b,c,d,e):
def pp3(a,b,c,d):
def pp4(a,b,c):
def pp5(a,b,c):
def pp6(a,b,c):
def div1(a,b):
def d2(a,b):
def d3(a,b):
def pp1(a,b):
def pp2(a,b):
def pp3(a,b,c,d,e,f,g):
def pp4(a,b):
def pp5(a,b,c):
def pp6(a,b):
def pp7(a,b):
def pp8(a,b):
def jj3(a,b,c,d,e):
def jj5(a,b,c,d,e,f):
def jj2(a,b,c,d):
def jj2(a,b,c,d):
pipelines.py
todo: secrets
todo: all these constants for SSB -- line 1008
todo: secrets
def d(s):
# Main canvas querying fxn
def fetch(target,verbose=0):
# Main canvas querying fxn - stream version - don't die on big requests
def fetch_stream(target,verbose=0):
# paging makes problems... example: enrollment_terms
def fetch_collapse(target,collapse='',verbose=0):
# Teacher name format changed. Remove commas and switch first to last
def fix_t_name(str):
# Separate dept and code
def split_class_dept(c):
def split_class_code(c):
def split_class_code_letter(c):
# go from sp20 to 2020spring
def shortToLongSem(s):
# Go to the semesters folder and read the schedule. Return dataframe
def getSemesterSchedule(short='sp21'): # I used to be current_schedule
todo: Some semesters have a different format.... partofday type site xxx i just dL'd them again
def prep_online_courses_df():
def course_is_online(crn):
def get_crn_from_name(name):
def get_enrlmts_for_user(user,enrollments):
# Get something from Canvas Data
def do_request(path):
# Canvas data, download all new files
def sync_non_interactive():
# list files in canvas_data (online) and choose one or some to download.
def interactive():
def todays_date_filename(): # helper
def nowAsStr(): # possible duplicate
def row_has_data(r): # helper
def row_text(r): # helper
# Take banner's html and make a csv(?) file
def ssb_to_csv(src):
def clean_funny(str):
def clean_funny2(str):
def clean_funny3(str):
### course is a list of 1-3 lists, each one being a line in the schedule's output. First one has section
def course_start(course):
todo: use this to make a early/late/short field and store semester dates w/ other constants
def time_to_partofday(t):
todo: account for multiple sites/rows
# Deduce a 'site' field, based on room name and known offsite locations
def room_to_site(room,verbose=0):
todo: account for multiple sites/rows
todo: better way to store these offsite labels
# take text lines and condense them to one dict per section
def to_section_list(input_text,verbose=0):
todo: no output files
todo: if extra line is different type?
# Log the history of enrollments per course during registration
def log_section_filling(current_sched_list):
# Same as above, but compressed, act only
def log_section_filling2(current_sched_list):
# Use Firefox and log in to ssb and get full schedule. Only works where selenium is installed
def scrape_schedule():
todo: my data here.... secret
todo:
# recreate schedule json files with most current online schedule format.
def recent_schedules():
todo: sems is a global in this file. Is that the right thing to do?
todo: the pipeline is disorganized. Organize it to have
todo: where does this belong in the pipeline? compare with recent_schedules()
# Take the generically named rosters uploads files and move them to a semester folder and give them a date.
def move_to_folder(sem,year,folder):
# This relates to enrollment files, not schedule.
def convert_roster_files(semester="",year="",folder=""):
# From instructure sftp site
def fetch_current_rosters():
todo: secret
def fetch_current_rosters_auto():
# read schedule file with an eye toward watching what's filling up
def schedule_filling():
todo: hardcoded
# Upload a json file to www
def put_file(remotepath,localpath, localfile,prompt=1):
todo: remove this secret
todo: these paths
def sec(t): return "<h3>"+t+"</h3>\n"
def para(t): return "<p>"+t+"</p>\n"
def ul(t): return "<ul>"+t+"</ul>\n"
def li(t): return "<li>"+t+"</li>\n"
def question(t,bracket=1):
def answer(t):
def read_paragraph_element(element,type="NORMAL_TEXT"):
def get_doc(docid, bracket=1, verbose=0):
todo: x link, x bold, list, image.
def read_paragraph_element_2(element,type="NORMAL_TEXT"):
# t is a string that begins with "Icons: " ... and contains comma(space) separated list
def handle_icons(t):
# t is a string that begins with "Tags: " ... and contains comma(space) separated list
def handle_tags(t):
def handle_question(t,bracket=1):
def handle_answer(t):
def handle_sec(t): return ('section',t)
def handle_para(t): return ('paragraph',t)
def handle_ul(t): return ('unorderdedlist',t)
def handle_li(t): return ('listitem',t)
def fetch_doc_image(k,value):
def get_doc_generic(docid, bracket=1, verbose=0):
def scrape_schedule_py():
server.py
def tag(x,y): return "<%s>%s</%s>" % (x,y,x)
def tagc(x,c,y): return '<%s class="%s">%s</%s>' % (x,c,y,x)
def a(t,h): return '<a href="%s">%s</a>' % (h,t)
def homepage():
def orgline(L):
todo: \s\[\#A\](.*)$', L)
def editor(src):
def in_form(txt,path):
def mytime(fname):
def index():
def writing(fname):
def dashboard():
def dash():
def mycalendar():
def most_recent_file_of( target, folder ):
def finder(st):
def news():
def randPic():
def sample():
def sample2(a=""):
# Filter a stream of loglines for those that match a course's url / id
def has_course(stream,courseid):
def js(s):
def sem_from_array_crn(crn):
def user_courses(uid):
def user_course_history_summary(usr_id):
def roster(crn):
def user_course_hits(usr,courseid):
def profiles(id=1,b=2,c=3):
# Departments, classes in each, and students (with hits) in each of those.
def enrollment(a):
# All the classes in this dept, w/ all the students in each, with count of their views.
def dept(d=''):
def user(canvas_id=None):
def lectures():
def web_lectures():
todo: update: dept, title, any of the other fields.
# update a value: dept id of a personnel id
def update_pers_title(pid, tid):
# update a value: dept id of a personnel id
def update_pers_dept(pid, did):
def user_edit(canvas_id='2'):
def staff_dir(search=''):
def server_save(key,value):
def server_dispatch_json(function_name,arg='', arg2=''):
def server_dispatch(function_name,arg='', arg2=''):
stats.py
def grades_rundown():
def class_logs():
def user_logs():
def recent_logins():
def userHitsThisSemester(uid=2):
def getCurrentActivity(): # a dict
def externaltool(): # a list
tasks.py
def survey_answer(q=0):
def survey_organize():
def build_quiz(filename=""):
# Send an email
def send_email(fullname, firstname, addr, subj, content):
def convert_to_pdf(name1, name2):
# Build (docx/pdf) certificates for gott graduates
def certificates_gott_build():
# Email experiment
def mail_test():
# Change LTI Settings. Experimental
def modify_x_tool():
# Upload with sftp to www website folder: student/online/srt/classfoldername
def put_file(classfoldername):
todo: ',cnopts=cnopts) as sftp:
# Switch everyone in a class to a teacher
def switch_enrol():
# Change dates & term of a class to unrestrict enrollment
def unrestrict_course():
# Bulk enroll users into a course
def enroll_accred():
# Calculate attendance stats based on enrollment/participation at 20% of term progressed, then 60% of term progressed.
def twenty_sixty_stats(li):
# Older positive attendance hours calculation.
def hours_calc():
def course_2060_dates(crn=""):
todo:
def course_update_all_users_locallogs(course_id=''):
def hours_calc_pulldata(course_id=''):
def xlist_cwe():
def pos_atten():
temp.py
tempget.py
# Use Firefox and log in to ssb and get full schedule
def login():
todo: my data here.... secret
def filename_friendly(str):
def otter():
templates.py
def item_to_masonry(item):
def try_untemplate():
def php_remove(m):
def php_add(m):
def do_template(temp,source,side):
def remove_filetype(f):
def make():
def txt_2_table():
def studenttech_faq():
# https://docs.google.com/document/d/1tI_b-q75Lzu25HcA0GCx9bGfUt9ccM8m2YrrioDFZcA/edit?usp=sharing
def de_faq():
def degwork_faq():
def vrc_faq():
def counseling_faq():
def finaid_faq():
def coun_loc():
def tutor_faq():
def test_repl():
timer.py
def func(a, b):
users.py
todo: these constants
# All users to a cache file cache/allusers.json
def fetchAllUsers():
# Fetch teacher users objects from local cache
def teacherRolesCache(): # I used to be load_users
# Canvas: Fetch all people with gavilan.edu email address
def teacherRolesUpdateCache(): # I used to be get_users
# Fetch preferred email address for a given user id. ( Canvas )
def getEmail(user_id):
# All teachers in a particular course
def getAllTeachers(course_id=59): # a list
#
def classType(t):
todo: fix bug in schedule parser so non-online classes have a type field
def my_blank_string(): return "no data"
def my_blank_dict(): return {'name':'NoName','email':'noemail@gavilan.edu'}
def my_empty_dict(): return defaultdict(my_blank_string)
def get_email_from_rec(name,name_to_record):
# Pull the staff directory on the webpage. Convert to pandas dataframe
def staff_dir(get_fresh=False):
todo: lol get fresh again...
def schedForTeacherOverview(long,short):
# Return a dataframe of the last 4 semester schedules put together
def oneYearSchedule():
def num_sections_last_year(line):
def sec_type_stats(line):
def prct_online(line):
def prct_lecture(line):
def prct_hybrid(line):
# Given the names of teachers in last year's schedules, fill in email, etc. from ilearn files
def teacher_basic_info(sched, from_ilearn, names):
def find_that_name(x):
# Outputs: cache/teacher_by_semester.csv,
def teacherModalityHistory(sched=[],names=[]):
def teacherCourseHistory(a,names):
todo: sort by dept also
# Outputs: cache/course_teacher_combos.csv,
def teacherSharedCourses(a=[]):
# How many courses in each department were taught in the last year?
def departmentCountCourses(a=[]):
def clean_nonprint(s):
def read_cmte(names):
def read_training_records():
# open a file and mark the people with their ids given. Return a dataframe
def read_bootcamp1(filename):
# open a file and mark the people with their ids given. Return a dataframe
def read_bootcamp2(filename):
def not_blank_or_pound(L):
def temp1(x):
def add_realnames(df,names): # the surveys. raw name is in 2nd column
def compareToughNames(a,b):
def compareNames(a,b,verbose=0):
def find_ilearn_record(ilearn_records,manual_records, othername,verbose=0):
def manualNamesAndDept():
def manualNames():
# given a list of class codes, return the most common (academic) department
def guessDept(d_list):
# Make one big csv file of everything I know about a teacher
def getTeachersInfoMain():
def enroll_staff_shell():
# take a list of raw hits.
def activity_summary(hits):
todo: month is hardcoded here
# Get views counts on current teachers. todo: month is hardcoded here
def get_recent_views(id=1):
# Have they taught online or hybrid classes?
def categorize_user(u):
todo: threaded
# Doest the account have a photo loaded?
def checkForAvatar(id=2):
# Grab em. Change the first if when continuing after problems....
def downloadPhoto():
def mergePhotoFolders():
def mergePhotoFolders2():
# Go through my local profile pics, upload any that are missing.
def uploadPhoto():
def test_email():
def create_ztc_list():
def get_user_info(id):
# these are any messages that get pushed out to their email
def comm_mssgs_for_user(uid=0):
#
def convos_for_user(uid=0):
# single q sub
def quiz_get_sub(courseid, quizid, subid=0):
# quiz submissions for quiz id x, in course id y
def quiz_submissions(courseid=9768, quizid=32580):
# return (timeblock, course, read=0,write=1)
def requests_line(line,i=0):
#
def report_logs(id=0):
def track_users_in_sem():
def track_users_in_class(L=[]):
def track_user_q(id, q):
# Maintain local logs. Look to see if we have some, download logs since then for a user.
def track_user(id=0,qid=0):
todo: set up this info file if it isn't there. check any changes too. it
todo:
#
def track_users_by_teacherclass():
def nlp_sample():
def nlp_sample2():
def one_course_enrol():
util.py
def print_table(table):
def remove_nl(str):
def UnicodeDictReader(utf8_data, **kwargs):
def minimal_string(s):
def to_file_friendly(st):
def clean_title(st):
def match59(x):
def item_2(x): return x[2]
def unix_time_millis(dt):
# ENGL250 returns ENGL
def dept_from_name(n):
def most_common_item(li):
def srt_times(a,b):
def how_long_ago(a): # number of hours ago 'a' was...
def partition(times_list):
"""