def update_database(chaptitles, subtitles, app): """ When the build is completely finished output the information gathered about chapters and subchapters into the database. """ if not engine: print("You need to install a DBAPI module - psycopg2 for Postgres") print("Or perhaps you have not set your DBURL environment variable") return course_id = app.env.config.html_context.get('course_id', "unknown") chapters = Table('chapters', meta, autoload=True, autoload_with=engine) sub_chapters = Table('sub_chapters', meta, autoload=True, autoload_with=engine) questions = Table('questions', meta, autoload=True, autoload_with=engine) basecourse = app.config.html_context.get('basecourse', "unknown") print("Cleaning up old chapters info") engine.execute(chapters.delete().where(chapters.c.course_id == course_id)) print("Populating the database with Chapter information") for chap in chaptitles: # insert row for chapter in the chapter table and get the id print(u"Adding chapter subchapter info for {}".format(chap)) ins = chapters.insert().values(chapter_name=chaptitles.get(chap, chap), course_id=course_id, chapter_label=chap) res = engine.execute(ins) currentRowId = res.inserted_primary_key[0] for sub in subtitles[chap]: # insert row for subchapter q_name = u"{}/{}".format(chaptitles.get(chap, chap), subtitles[chap][sub]) ins = sub_chapters.insert().values( sub_chapter_name=subtitles[chap][sub], chapter_id=str(currentRowId), sub_chapter_label=sub) engine.execute(ins) sel = select([questions]).where( and_(questions.c.chapter == chap, questions.c.subchapter == sub, questions.c.question_type == 'page', questions.c.base_course == basecourse)) res = engine.execute(sel).first() if res and res.name != q_name: # In this case the title has changed upd = questions.update().where( questions.c.id == res['id']).values(name=q_name) engine.execute(upd) if not res: # this is a new subchapter ins = questions.insert().values( chapter=chap, subchapter=sub, question_type='page', name=q_name, timestamp=datetime.datetime.now(), base_course=basecourse) engine.execute(ins)
def build_finished(app, ex): """ When the build is completely finished output the information gathered about chapters and subchapters into the database. """ if not engine: print("You need to install a DBAPI module - psycopg2 for Postgres") return print("Populating the database with Chapter information") course_id = app.env.config.html_context.get('course_id', "unknown") chapters = Table('chapters', meta, autoload=True, autoload_with=engine) sub_chapters = Table('sub_chapters', meta, autoload=True, autoload_with=engine) print("Cleaning up old chapters info") engine.execute(chapters.delete().where(chapters.c.course_id == course_id)) if 'Labs' in sub_ids_for_chapter: chap_order.append('Labs') subchap_order['Labs'] = sub_ids_for_chapter['Labs'] for chap in chap_order: # insert row for chapter in the chapter table and get the id print("Adding chapter subchapter info for {}".format(chap)) ins = chapters.insert().values(chapter_name=chaptitles.get(chap, chap), course_id=course_id, chapter_label=chap) res = engine.execute(ins) currentRowId = res.inserted_primary_key[0] for sub in subchap_order[chap]: # insert row for subchapter ins = sub_chapters.insert().values( sub_chapter_name=subtitles[chap][sub], chapter_id=str(currentRowId), sub_chapter_label=sub) engine.execute(ins)
def update_database(chaptitles, subtitles, skips, app): """ When the build is completely finished output the information gathered about chapters and subchapters into the database. """ if not engine: print("You need to install a DBAPI module - psycopg2 for Postgres") print("Or perhaps you have not set your DBURL environment variable") return course_id = app.env.config.html_context.get('course_id', "unknown") chapters = Table('chapters', meta, autoload=True, autoload_with=engine) sub_chapters = Table('sub_chapters', meta, autoload=True, autoload_with=engine) questions = Table('questions', meta, autoload=True, autoload_with=engine) basecourse = app.config.html_context.get('basecourse',"unknown") print("Cleaning up old chapters info") engine.execute(chapters.delete().where(chapters.c.course_id == course_id)) print("Populating the database with Chapter information") for chap in chaptitles: # insert row for chapter in the chapter table and get the id print(u"Adding chapter subchapter info for {}".format(chap)) ins = chapters.insert().values(chapter_name=chaptitles.get(chap, chap), course_id=course_id, chapter_label=chap) res = engine.execute(ins) currentRowId = res.inserted_primary_key[0] for sub in subtitles[chap]: if (chap,sub) in skips: skipreading = 'T' else: skipreading = 'F' # insert row for subchapter # todo: check if this chapter/subchapter is in the non-reading list q_name = u"{}/{}".format(chaptitles.get(chap,chap), subtitles[chap][sub]) ins = sub_chapters.insert().values(sub_chapter_name=subtitles[chap][sub], chapter_id=str(currentRowId), sub_chapter_label=sub, skipreading=skipreading) engine.execute(ins) # Three possibilities: # 1) The chapter and subchapter labels match existing, but the q_name doesn't match; because you changed # heading in a file. # 2) The chapter and subchapter labels don't match (new file name), but there is an existing q_name match, # because you renamed the file # 3) Neither match, so insert a new question sel = select([questions]).where(or_(and_(questions.c.chapter == chap, questions.c.subchapter == sub, questions.c.question_type == 'page', questions.c.base_course == basecourse), and_(questions.c.name == q_name, questions.c.question_type == 'page', questions.c.base_course == basecourse)) ) res = engine.execute(sel).first() if res and ((res.name != q_name) or (res.chapter != chap) or (res.subchapter !=sub)): # Something changed upd = questions.update().where(questions.c.id == res['id']).values(name=q_name, chapter = chap, subchapter = sub) engine.execute(upd) if not res: # this is a new subchapter ins = questions.insert().values(chapter=chap, subchapter=sub, question_type='page', name=q_name, timestamp=datetime.datetime.now(), base_course=basecourse) engine.execute(ins)
def run(self): """ process the multiplechoice directive and generate html for output. :param self: :return: .. datafile:: identifier :edit: Option that makes the datafile editable :cols: If editable, number of columns--default is 20 :rows: If editable, number of rows--default is 40 :hide: Flag that sets a non-editable datafile to be hidden :fromfile: path to file that contains the data """ super(DataFile, self).run() env = self.state.document.settings.env if not hasattr(env,'datafilecounter'): env.datafilecounter = 0 env.datafilecounter += 1 import os if 'fromfile' in self.options: ffpath = os.path.dirname(self.srcpath) print(self.srcpath, os.getcwd()) filename = os.path.join(env.srcdir, ffpath, self.options['fromfile']) with open(filename, 'rb') as f: self.content = [x[:-1].decode('utf8') for x in f.readlines()] if 'cols' in self.options: self.options['cols'] = self.options['cols'] else: self.options['cols'] = min(65,max([len(x) for x in self.content])) if 'rows' in self.options: self.options['rows'] = self.options['rows'] else: self.options['rows'] = 20 if self.content: source = "\n".join(self.content)+"\n" else: source = '\n' self.options['filecontent'] = source if 'hide' in self.options: self.options['hidden'] = 'data-hidden' else: self.options['hidden'] = '' if 'edit' in self.options: self.options['edit'] = "true" else: self.options['edit'] = "false" if engine: Source_code = Table('source_code', meta, autoload=True, autoload_with=engine) course_name = env.config.html_context['course_id'] divid = self.options['divid'] engine.execute(Source_code.delete().where(Source_code.c.acid == divid).where(Source_code.c.course_id == course_name)) engine.execute(Source_code.insert().values( acid = divid, course_id = course_name, main_code= source, )) else: print("Unable to save to source_code table in datafile__init__.py. Possible problems:") print(" 1. dburl or course_id are not set in conf.py for your book") print(" 2. unable to connect to the database using dburl") print() print("This should only affect the grading interface. Everything else should be fine.") data_file_node = DataFileNode(self.options, rawsource=self.block_text) data_file_node.source, data_file_node.line = self.state_machine.get_source_and_line(self.lineno) return [data_file_node]
def run(self): addQuestionToDB(self) env = self.state.document.settings.env # keep track of how many activecodes we have.... # could be used to automatically make a unique id for them. if not hasattr(env, 'activecodecounter'): env.activecodecounter = 0 env.activecodecounter += 1 self.options['name'] = self.arguments[0].strip() self.options['divid'] = self.arguments[0] if not self.options['divid']: raise Exception( "No divid for ..activecode or ..actex in activecode.py") explain_text = None if self.content: if '~~~~' in self.content: idx = self.content.index('~~~~') explain_text = self.content[:idx] self.content = self.content[idx + 1:] source = "\n".join(self.content) else: source = '\n' self.options['initialcode'] = source str = source.replace("\n", "*nline*") str0 = str.replace("\"", "*doubleq*") str1 = str0.replace("(", "*open*") str2 = str1.replace(")", "*close*") str3 = str2.replace("'", "*singleq*") self.options['argu'] = str3 complete = "" no_of_buttons = 0 okeys = list(self.options.keys()) for k in okeys: if '_' in k: x, label = k.split('_') no_of_buttons = no_of_buttons + 1 complete = complete + self.options[k] + "*atype*" newcomplete = complete.replace("\"", "*doubleq*") self.options['ctext'] = newcomplete self.options['no_of_buttons'] = no_of_buttons if 'caption' not in self.options: self.options['caption'] = '' else: self.options[ 'caption'] = "data-caption='%s'" % self.options['caption'] if 'include' not in self.options: self.options['include'] = '' else: lst = self.options['include'].split(',') lst = [x.strip() for x in lst] self.options['include'] = 'data-include="' + " ".join(lst) + '"' if 'hidecode' in self.options: self.options['hidecode'] = 'data-hidecode="true"' else: self.options['hidecode'] = '' if 'language' not in self.options: self.options['language'] = 'python' if self.options['language'] == 'html': self.options['language'] = 'htmlmixed' self.options['initialcode'] = escape(self.options['initialcode']) if 'nocodelens' in self.options or self.options['language'] != 'python': self.options['codelens'] = '' else: self.options['codelens'] = 'data-codelens="true"' if 'timelimit' not in self.options: self.options['timelimit'] = 'data-timelimit=25000' else: self.options[ 'timelimit'] = 'data-timelimit=%s' % self.options['timelimit'] if 'autorun' not in self.options: self.options['autorun'] = '' else: self.options['autorun'] = 'data-autorun="true"' if 'coach' in self.options: self.options['coach'] = 'data-coach="true"' else: self.options['coach'] = '' # livecode options if 'stdin' in self.options: self.options['stdin'] = "data-stdin='%s'" % self.options['stdin'] else: self.options['stdin'] = "" if 'datafile' not in self.options: self.options['datafile'] = "" else: self.options[ 'datafile'] = "data-datafile='%s'" % self.options['datafile'] if 'sourcefile' not in self.options: self.options['sourcefile'] = "" else: self.options['sourcefile'] = "data-sourcefile='%s'" % self.options[ 'sourcefile'] if 'gradebutton' not in self.options: self.options['gradebutton'] = '' else: self.options['gradebutton'] = "data-gradebutton=true" if self.content: if '====' in self.content: idx = self.content.index('====') source = "\n".join(self.content[:idx]) suffix = "\n".join(self.content[idx + 1:]) else: source = "\n".join(self.content) suffix = "\n" else: source = '\n' suffix = '\n' course_name = env.config.html_context['course_id'] divid = self.options['divid'] if engine: engine.execute( Source_code.delete().where(Source_code.c.acid == divid).where( Source_code.c.course_id == course_name)) engine.execute(Source_code.insert().values( acid=divid, course_id=course_name, main_code=source, suffix_code=suffix, includes=self.options['include'], available_files=self.options.get('available_files', ""))) else: print( "Unable to save to source_code table in activecode.py. Possible problems:" ) print( " 1. dburl or course_id are not set in conf.py for your book") print(" 2. unable to connect to the database using dburl") print("") print( "This should only affect the grading interface. Everything else should be fine." ) acnode = ActivcodeNode(self.options, rawsource=self.block_text) acnode.source, acnode.line = self.state_machine.get_source_and_line( self.lineno) self.add_name( acnode) # make this divid available as a target for :ref: if explain_text: self.state.nested_parse(explain_text, self.content_offset, acnode) return [acnode]
def update_database(chaptitles, subtitles, skips, app): """ When the build is completely finished output the information gathered about chapters and subchapters into the database. """ if not engine: logger.warning("You need to install a DBAPI module - psycopg2 for Postgres") logger.warning("Or perhaps you have not set your DBURL environment variable") return course_id = app.env.config.html_context.get('course_id', "unknown") chapters = Table('chapters', meta, autoload=True, autoload_with=engine) sub_chapters = Table('sub_chapters', meta, autoload=True, autoload_with=engine) questions = Table('questions', meta, autoload=True, autoload_with=engine) basecourse = app.config.html_context.get('basecourse',"unknown") logger.info("Cleaning up old chapters info") engine.execute(chapters.delete().where(chapters.c.course_id == course_id)) logger.info("Populating the database with Chapter information") for chap in chaptitles: # insert row for chapter in the chapter table and get the id logger.info(u"Adding chapter subchapter info for {}".format(chap)) ins = chapters.insert().values(chapter_name=chaptitles.get(chap, chap), course_id=course_id, chapter_label=chap) res = engine.execute(ins) currentRowId = res.inserted_primary_key[0] for sub in subtitles[chap]: if (chap,sub) in skips: skipreading = 'T' else: skipreading = 'F' # insert row for subchapter # todo: check if this chapter/subchapter is in the non-reading list q_name = u"{}/{}".format(chaptitles.get(chap,chap), subtitles[chap][sub]) ins = sub_chapters.insert().values(sub_chapter_name=subtitles[chap][sub], chapter_id=str(currentRowId), sub_chapter_label=sub, skipreading=skipreading) engine.execute(ins) # Three possibilities: # 1) The chapter and subchapter labels match existing, but the q_name doesn't match; because you changed # heading in a file. # 2) The chapter and subchapter labels don't match (new file name), but there is an existing q_name match, # because you renamed the file # 3) Neither match, so insert a new question sel = select([questions]).where(or_(and_(questions.c.chapter == chap, questions.c.subchapter == sub, questions.c.question_type == 'page', questions.c.base_course == basecourse), and_(questions.c.name == q_name, questions.c.question_type == 'page', questions.c.base_course == basecourse)) ) res = engine.execute(sel).first() if res and ((res.name != q_name) or (res.chapter != chap) or (res.subchapter !=sub)): # Something changed upd = questions.update().where(questions.c.id == res['id']).values(name=q_name, chapter = chap, subchapter = sub) engine.execute(upd) if not res: # this is a new subchapter ins = questions.insert().values(chapter=chap, subchapter=sub, question_type='page', name=q_name, timestamp=datetime.datetime.now(), base_course=basecourse) engine.execute(ins)
def run(self): super(ActiveCode, self).run() addQuestionToDB(self) env = self.state.document.settings.env # keep track of how many activecodes we have.... # could be used to automatically make a unique id for them. if not hasattr(env, "activecodecounter"): env.activecodecounter = 0 env.activecodecounter += 1 self.options["name"] = self.arguments[0].strip() explain_text = None if self.content: if "~~~~" in self.content: idx = self.content.index("~~~~") explain_text = self.content[:idx] self.content = self.content[idx + 1:] source = "\n".join(self.content) else: source = "\n" self.options["initialcode"] = source str = source.replace("\n", "*nline*") str0 = str.replace('"', "*doubleq*") str1 = str0.replace("(", "*open*") str2 = str1.replace(")", "*close*") str3 = str2.replace("'", "*singleq*") self.options["argu"] = str3 # TODO: This is BAD -- using '_' as a key for audio tour stuff is wrong. complete = "" no_of_buttons = 0 okeys = list(self.options.keys()) for k in okeys: if "tour_" in k: x, label = k.split("_") no_of_buttons = no_of_buttons + 1 complete = complete + self.options[k] + "*atype*" newcomplete = complete.replace('"', "*doubleq*") self.options["ctext"] = newcomplete self.options["no_of_buttons"] = no_of_buttons if "caption" not in self.options: self.options["caption"] = "" else: self.options[ "caption"] = "data-caption='%s'" % self.options["caption"] if "include" not in self.options: self.options["include"] = "" else: lst = self.options["include"].split(",") lst = [x.strip() for x in lst] self.options["include"] = 'data-include="' + " ".join(lst) + '"' if "hidecode" in self.options: self.options["hidecode"] = 'data-hidecode="true"' else: self.options["hidecode"] = "" if "enabledownload" in self.options: self.options["enabledownload"] = 'data-enabledownload="true"' else: self.options["enabledownload"] = "" if "chatcodes" in self.options: self.options["chatcodes"] = 'data-chatcodes="true"' else: self.options["chatcodes"] = "" if "language" not in self.options: self.options["language"] = "python" if self.options["language"] == "html": self.options["language"] = "htmlmixed" self.options["initialcode"] = escape(self.options["initialcode"]) if "nocodelens" in self.options or self.options["language"] != "python": self.options["codelens"] = "" else: self.options["codelens"] = 'data-codelens="true"' if "nopair" in self.options: self.options["nopair"] = 'data-nopair="true"' else: self.options["nopair"] = "" if "timelimit" not in self.options: self.options["timelimit"] = "data-timelimit=25000" else: self.options[ "timelimit"] = "data-timelimit=%s" % self.options["timelimit"] if "autorun" not in self.options: self.options["autorun"] = "" else: self.options["autorun"] = 'data-autorun="true"' if "coach" in self.options: self.options["coach"] = 'data-coach="true"' else: self.options["coach"] = "" # livecode options if "stdin" in self.options: self.options["stdin"] = "data-stdin='%s'" % self.options["stdin"] else: self.options["stdin"] = "" if "datafile" not in self.options: self.options["datafile"] = "" else: self.options[ "datafile"] = "data-datafile='%s'" % self.options["datafile"] if "sourcefile" not in self.options: self.options["sourcefile"] = "" else: self.options["sourcefile"] = ("data-sourcefile='%s'" % self.options["sourcefile"]) if "tie" in self.options: self.options["tie"] = "data-tie='{}'".format(self.options["tie"]) else: self.options["tie"] = "" if "dburl" in self.options: self.options["dburl"] = "data-dburl='{}'".format( self.options["dburl"]) else: self.options["dburl"] = "" for opt, tp in [ ("compileargs", "cargs"), ("linkargs", "largs"), ("runargs", "rargs"), ("interpreterargs", "iargs"), ]: if opt in self.options: self.options[tp] = 'data-{}="{}"'.format( opt, escape(self.options[opt])) else: self.options[tp] = "" if "gradebutton" not in self.options: self.options["gradebutton"] = "" else: self.options["gradebutton"] = "data-gradebutton=true" self.options["divclass"] = env.config.activecode_div_class if env.config.activecode_hide_load_history: self.options["hidehistory"] = "data-hidehistory=true" else: self.options["hidehistory"] = "" if env.config.wasm_uri: self.options["wasmuri"] = f"data-wasm={env.config.wasm_uri}" else: self.options["wasmuri"] = "" if self.content: if "====" in self.content: idx = self.content.index("====") source = "\n".join(self.content[:idx]) suffix = "\n".join(self.content[idx + 1:]) else: source = "\n".join(self.content) suffix = "\n" else: source = "\n" suffix = "\n" course_name = env.config.html_context["course_id"] divid = self.options["divid"] if engine: engine.execute( Source_code.delete().where(Source_code.c.acid == divid).where( Source_code.c.course_id == course_name)) engine.execute(Source_code.insert().values( acid=divid, course_id=course_name, main_code=source, suffix_code=suffix, includes=self.options["include"], available_files=self.options.get("available_files", ""), )) else: if (not hasattr(env, "dberr_activecode_reported") or not env.dberr_activecode_reported): env.dberr_activecode_reported = True print( "Unable to save to source_code table in activecode.py. Possible problems:" ) print( " 1. dburl or course_id are not set in conf.py for your book" ) print(" 2. unable to connect to the database using dburl") print("") print( "This should only affect the grading interface. Everything else should be fine." ) acnode = ActivcodeNode(self.options, rawsource=self.block_text) acnode.source, acnode.line = self.state_machine.get_source_and_line( self.lineno) self.add_name( acnode) # make this divid available as a target for :ref: if explain_text: self.state.nested_parse(explain_text, self.content_offset, acnode) return [acnode]
def run(self): super(ActiveCode, self).run() addQuestionToDB(self) env = self.state.document.settings.env # keep track of how many activecodes we have.... # could be used to automatically make a unique id for them. if not hasattr(env, 'activecodecounter'): env.activecodecounter = 0 env.activecodecounter += 1 self.options['name'] = self.arguments[0].strip() explain_text = None if self.content: if '~~~~' in self.content: idx = self.content.index('~~~~') explain_text = self.content[:idx] self.content = self.content[idx + 1:] source = "\n".join(self.content) else: source = '\n' self.options['initialcode'] = source str = source.replace("\n", "*nline*") str0 = str.replace("\"", "*doubleq*") str1 = str0.replace("(", "*open*") str2 = str1.replace(")", "*close*") str3 = str2.replace("'", "*singleq*") self.options['argu'] = str3 complete = "" no_of_buttons = 0 okeys = list(self.options.keys()) for k in okeys: if '_' in k: x, label = k.split('_') no_of_buttons = no_of_buttons + 1 complete = complete + self.options[k] + "*atype*" newcomplete = complete.replace("\"", "*doubleq*") self.options['ctext'] = newcomplete self.options['no_of_buttons'] = no_of_buttons if 'caption' not in self.options: self.options['caption'] = '' else: self.options[ 'caption'] = "data-caption='%s'" % self.options['caption'] if 'include' not in self.options: self.options['include'] = '' else: lst = self.options['include'].split(',') lst = [x.strip() for x in lst] self.options['include'] = 'data-include="' + " ".join(lst) + '"' if 'hidecode' in self.options: self.options['hidecode'] = 'data-hidecode="true"' else: self.options['hidecode'] = '' if 'enabledownload' in self.options: self.options['enabledownload'] = 'data-enabledownload="true"' else: self.options['enabledownload'] = '' if 'chatcodes' in self.options: self.options['chatcodes'] = 'data-chatcodes="true"' else: self.options['chatcodes'] = '' if 'language' not in self.options: self.options['language'] = 'python' if self.options['language'] == 'html': self.options['language'] = 'htmlmixed' self.options['initialcode'] = escape(self.options['initialcode']) if 'nocodelens' in self.options or self.options['language'] != 'python': self.options['codelens'] = '' else: self.options['codelens'] = 'data-codelens="true"' if 'timelimit' not in self.options: self.options['timelimit'] = 'data-timelimit=25000' else: self.options[ 'timelimit'] = 'data-timelimit=%s' % self.options['timelimit'] if 'autorun' not in self.options: self.options['autorun'] = '' else: self.options['autorun'] = 'data-autorun="true"' if 'runortest' not in self.options: self.options['runortest'] = '' else: lst = self.options['runortest'].split(',') lst = [x.strip() for x in lst] self.options['runortest'] = 'data-runortest="' + " ".join( lst) + '"' if 'playtask' not in self.options: self.options['playtask'] = '' elif self.options['runortest']: raise self.error( 'There must not be interference between runortest and playtask options' ) else: self.options['playtask'] = 'data-playtask="true"' if 'help' not in self.options: self.options['help'] = '' else: self.options['help'] = 'data-help="true"' if 'passivecode' not in self.options: self.options['passivecode'] = '' else: self.options[ 'passivecode'] = 'data-passivecode="%s"' % self.options[ 'passivecode'] if 'modaloutput' not in self.options: self.options['modaloutput'] = '' else: self.options['modaloutput'] = 'data-modaloutput="true"' if 'enablecopy' not in self.options: self.options['enablecopy'] = '' else: self.options['enablecopy'] = 'data-enablecopy="true"' if 'coach' in self.options: self.options['coach'] = 'data-coach="true"' else: self.options['coach'] = '' # livecode options if 'stdin' in self.options: self.options['stdin'] = "data-stdin='%s'" % self.options['stdin'] else: self.options['stdin'] = "" if 'datafile' not in self.options: self.options['datafile'] = "" else: self.options[ 'datafile'] = "data-datafile='%s'" % self.options['datafile'] if 'sourcefile' not in self.options: self.options['sourcefile'] = "" else: self.options['sourcefile'] = "data-sourcefile='%s'" % self.options[ 'sourcefile'] for opt, tp in [('compileargs', 'cargs'), ('linkargs', 'largs'), ('runargs', 'rargs'), ('interpreterargs', 'iargs')]: if opt in self.options: self.options[tp] = 'data-{}="{}"'.format( opt, escape(self.options[opt])) else: self.options[tp] = "" if 'gradebutton' not in self.options: self.options['gradebutton'] = '' else: self.options['gradebutton'] = "data-gradebutton=true" self.options['divclass'] = env.config.activecode_div_class if env.config.activecode_hide_load_history: self.options['hidehistory'] = 'data-hidehistory=true' else: self.options['hidehistory'] = '' if 'includesrc' in self.options: fname = self.options['includesrc'].replace('\\', '/') cwd = os.path.abspath(os.getcwd()) path = os.path.join(cwd, fname) with open(path, encoding='utf-8') as f: self.options[ 'includesrc'] = 'data-includesrc="%s"' % html_escape( f.read()) else: self.options['includesrc'] = "" if 'includehsrc' in self.options: fname = self.options['includehsrc'].replace('\\', '/') cwd = os.path.abspath(os.getcwd()) path = os.path.join(cwd, fname) with open(path, encoding='utf-8') as f: self.options[ 'includehsrc'] = 'data-includehsrc="%s"' % html_escape( f.read()) else: self.options['includehsrc'] = "" if 'includexsrc' in self.options: fname = self.options['includexsrc'].replace('\\', '/') cwd = os.path.abspath(os.getcwd()) path = os.path.join(cwd, fname) with open(path, encoding='utf-8') as f: self.options[ 'includexsrc'] = 'data-includexsrc="%s"' % html_escape( f.read()) else: self.options['includexsrc'] = "" if self.content: if '====' in self.content: idx = self.content.index('====') source = "\n".join(self.content[:idx]) suffix = "\n".join(self.content[idx + 1:]) else: source = "\n".join(self.content) suffix = "\n" else: source = '\n' suffix = '\n' course_name = env.config.html_context['course_id'] divid = self.options['divid'] if engine: engine.execute( Source_code.delete().where(Source_code.c.acid == divid).where( Source_code.c.course_id == course_name)) engine.execute(Source_code.insert().values( acid=divid, course_id=course_name, main_code=source, suffix_code=suffix, includes=self.options['include'], available_files=self.options.get('available_files', ""))) else: if not hasattr(env, 'dberr_activecode_reported' ) or not env.dberr_activecode_reported: env.dberr_activecode_reported = True print( "Unable to save to source_code table in activecode.py. Possible problems:" ) print( " 1. dburl or course_id are not set in conf.py for your book" ) print(" 2. unable to connect to the database using dburl") print("") print( "This should only affect the grading interface. Everything else should be fine." ) acnode = ActivcodeNode(self.options, rawsource=self.block_text) acnode.source, acnode.line = self.state_machine.get_source_and_line( self.lineno) self.add_name( acnode) # make this divid available as a target for :ref: if explain_text: self.state.nested_parse(explain_text, self.content_offset, acnode) return [acnode]
def run(self): super(ActiveCode, self).run() addQuestionToDB(self) env = self.state.document.settings.env # keep track of how many activecodes we have.... # could be used to automatically make a unique id for them. if not hasattr(env, 'activecodecounter'): env.activecodecounter = 0 env.activecodecounter += 1 self.options['name'] = self.arguments[0].strip() explain_text = None if self.content: if '~~~~' in self.content: idx = self.content.index('~~~~') explain_text = self.content[:idx] self.content = self.content[idx+1:] source = "\n".join(self.content) else: source = '\n' self.options['initialcode'] = source str = source.replace("\n", "*nline*") str0 = str.replace("\"", "*doubleq*") str1 = str0.replace("(", "*open*") str2 = str1.replace(")", "*close*") str3 = str2.replace("'", "*singleq*") self.options['argu'] = str3 complete = "" no_of_buttons = 0 okeys = list(self.options.keys()) for k in okeys: if '_' in k: x, label = k.split('_') no_of_buttons = no_of_buttons + 1 complete = complete + self.options[k] + "*atype*" newcomplete = complete.replace("\"", "*doubleq*") self.options['ctext'] = newcomplete self.options['no_of_buttons'] = no_of_buttons if 'caption' not in self.options: self.options['caption'] = '' else: self.options['caption'] = "data-caption='%s'" % self.options['caption'] if 'include' not in self.options: self.options['include'] = '' else: lst = self.options['include'].split(',') lst = [x.strip() for x in lst] self.options['include'] = 'data-include="' + " ".join(lst) + '"' if 'hidecode' in self.options: self.options['hidecode'] = 'data-hidecode="true"' else: self.options['hidecode'] = '' if 'enabledownload' in self.options: self.options['enabledownload'] = 'data-enabledownload="true"' else: self.options['enabledownload'] = '' if 'chatcodes' in self.options: self.options['chatcodes'] = 'data-chatcodes="true"' else: self.options['chatcodes'] = '' if 'language' not in self.options: self.options['language'] = 'python' if self.options['language'] == 'html': self.options['language'] = 'htmlmixed' self.options['initialcode'] = escape(self.options['initialcode']) if 'nocodelens' in self.options or self.options['language'] != 'python': self.options['codelens'] = '' else: self.options['codelens'] = 'data-codelens="true"' if 'timelimit' not in self.options: self.options['timelimit'] = 'data-timelimit=25000' else: self.options['timelimit'] = 'data-timelimit=%s' % self.options['timelimit'] if 'autorun' not in self.options: self.options['autorun'] = '' else: self.options['autorun'] = 'data-autorun="true"' if 'coach' in self.options: self.options['coach'] = 'data-coach="true"' else: self.options['coach'] = '' # livecode options if 'stdin' in self.options: self.options['stdin'] = "data-stdin='%s'" % self.options['stdin'] else: self.options['stdin'] = "" if 'datafile' not in self.options: self.options['datafile'] = "" else: self.options['datafile'] = "data-datafile='%s'" % self.options['datafile'] if 'sourcefile' not in self.options: self.options['sourcefile'] = "" else: self.options['sourcefile'] = "data-sourcefile='%s'" % self.options['sourcefile'] for opt,tp in [('compileargs','cargs'),('linkargs','largs'),('runargs','rargs'),('interpreterargs','iargs')]: if opt in self.options: self.options[tp] = 'data-{}="{}"'.format(opt, escape(self.options[opt])) else: self.options[tp] = "" if 'gradebutton' not in self.options: self.options['gradebutton'] = '' else: self.options['gradebutton'] = "data-gradebutton=true" self.options['divclass'] = env.config.activecode_div_class if env.config.activecode_hide_load_history: self.options['hidehistory'] = 'data-hidehistory=true' else: self.options['hidehistory'] = '' if self.content: if '====' in self.content: idx = self.content.index('====') source = "\n".join(self.content[:idx]) suffix = "\n".join(self.content[idx+1:]) else: source = "\n".join(self.content) suffix = "\n" else: source = '\n' suffix = '\n' course_name = env.config.html_context['course_id'] divid = self.options['divid'] if engine: engine.execute(Source_code.delete().where(Source_code.c.acid == divid).where(Source_code.c.course_id == course_name)) engine.execute(Source_code.insert().values( acid = divid, course_id = course_name, main_code= source, suffix_code = suffix, includes = self.options['include'], available_files = self.options.get('available_files', "") )) else: if not hasattr(env, 'dberr_activecode_reported') or not env.dberr_activecode_reported: env.dberr_activecode_reported = True print("Unable to save to source_code table in activecode.py. Possible problems:") print(" 1. dburl or course_id are not set in conf.py for your book") print(" 2. unable to connect to the database using dburl") print("") print("This should only affect the grading interface. Everything else should be fine.") acnode = ActivcodeNode(self.options, rawsource=self.block_text) acnode.source, acnode.line = self.state_machine.get_source_and_line(self.lineno) self.add_name(acnode) # make this divid available as a target for :ref: if explain_text: self.state.nested_parse(explain_text, self.content_offset, acnode) return [acnode]
def run(self): """ process the multiplechoice directive and generate html for output. :param self: :return: .. datafile:: identifier :edit: Option that makes the datafile editable :cols: If editable, number of columns--default is 20 :rows: If editable, number of rows--default is 40 :hide: Flag that sets a non-editable datafile to be hidden """ super(DataFile, self).run() env = self.state.document.settings.env if not hasattr(env,'datafilecounter'): env.datafilecounter = 0 env.datafilecounter += 1 #if 'cols' not in self.options: # self.options['cols'] = min(65,max([len(x) for x in self.content])) #if 'rows'not in self.options: # self.options['rows'] = 20 if 'cols' in self.options: self.options['cols'] = self.options['cols'] else: self.options['cols'] = min(65,max([len(x) for x in self.content])) if 'rows' in self.options: self.options['rows'] = self.options['rows'] else: self.options['rows'] = 20 if self.content: source = "\n".join(self.content)+"\n" else: source = '\n' self.options['filecontent'] = source if 'hide' in self.options: self.options['hidden'] = 'data-hidden' else: self.options['hidden'] = '' if 'edit' in self.options: self.options['edit'] = "true" else: self.options['edit'] = "false" if engine: Source_code = Table('source_code', meta, autoload=True, autoload_with=engine) course_name = env.config.html_context['course_id'] divid = self.options['divid'] engine.execute(Source_code.delete().where(Source_code.c.acid == divid).where(Source_code.c.course_id == course_name)) engine.execute(Source_code.insert().values( acid = divid, course_id = course_name, main_code= source, )) else: print("Unable to save to source_code table in datafile__init__.py. Possible problems:") print(" 1. dburl or course_id are not set in conf.py for your book") print(" 2. unable to connect to the database using dburl") print() print("This should only affect the grading interface. Everything else should be fine.") data_file_node = DataFileNode(self.options, rawsource=self.block_text) data_file_node.source, data_file_node.line = self.state_machine.get_source_and_line(self.lineno) return [data_file_node]