Пример #1
0
    def test_create_qtemplate(self):
        """ Test qtemplates creation
        """

        qt1_id = DB.create_qt(1, "TESTQ1", "Test question 1", 0, 5.0, 1)
        qt2_id = DB.create_qt(1, "TESTQ2", "Test question 2", 0, 4.1, 2)

        self.assertIsInstance(qt1_id, int)
        self.assertIsInstance(qt2_id, int)

        qt1 = DB.get_qtemplate(qt1_id)
        qt2 = DB.get_qtemplate(qt2_id)

        self.assertEqual(qt1['title'], "TESTQ1")
        self.assertEqual(qt2['title'], "TESTQ2")
        self.assertEqual(qt1['description'], "Test question 1")
        self.assertEqual(qt2['description'], "Test question 2")

        course_id = Courses.create("TEST107", "Test create qtemplate", 1, 1)
        topic1_id = Topics.create(course_id, "TESTTOPIC9", 1, 2)

        qt3_id = DB.create_qt(1, "TESTQ3", "Test question 3", 0, 5.0, 1, topic1_id)

        self.assertIsInstance(qt3_id, int)

        qt3 = DB.get_qtemplate(qt3_id)
        self.assertEqual(qt3['title'], "TESTQ3")
        self.assertEqual(qt3['description'], "Test question 3")
        self.assertEqual(DB.get_topic_for_qtemplate(qt3_id), topic1_id)
Пример #2
0
    def test_export_questions(self):
        """ Make some questions and export them."""
        course_id = Courses.create("TEST106", "Test Question Export", 1, 1)
        self.assertGreater(course_id, 0)
        topic1_id = Topics.create(course_id, "TESTEXPORT1", 1, 2)
        self.assertGreater(topic1_id, 0)

        qt1_id = DB.create_qt(1, "TESTQ1", "Test question 1", 0, 5.0, 1, topic_id=topic1_id)
        self.assertIsNotNone(qt1_id)

        ver = DB.get_qt_version(qt1_id)
        self.assertGreater(ver, 0)

        data = "2\n|1\n|2\n"
        qvars = [{'A1': "2"}, {'A1': "3"}]
        for row in range(0, len(qvars)):
            DB.add_qt_variation(qt1_id, row + 1, qvars[row], ver)
        DB.create_qt_att(qt1_id, "datfile.dat", "text/plain", data, ver)
        DB.create_qt_att(qt1_id, "qtemplate.html", "text/html", "What is <VAL A1>? <ANSWER 1>", ver)

        qt2_id = DB.create_qt(1, "TESTQ2", "Test question 2", 0, 5.0, 1, topic_id=topic1_id)
        self.assertIsNotNone(qt2_id)

        ver = DB.get_qt_version(qt2_id)
        self.assertGreater(ver, 0)

        data = "2\n|6\n|7\n"
        qvars = [{'A1': "6"}, {'A1': "7"}]
        for row in range(0, len(qvars)):
            DB.add_qt_variation(qt2_id, row + 1, qvars[row], ver)
        DB.create_qt_att(qt2_id, "datfile.dat", "text/plain", data, ver)
        DB.create_qt_att(qt2_id, "qtemplate.html", "text/html", "Question 2: What is <VAL A1>? <ANSWER 1>", ver)

        qt3_id = DB.create_qt(1, "TESTQ3", "Test question 3", 0, 5.0, 1, topic_id=topic1_id)
        self.assertIsNotNone(qt3_id)

        ver = DB.get_qt_version(qt3_id)
        self.assertGreater(ver, 0)

        data = "3\n|9\n|10\n|11\n"
        qvars = [{'A1': "9"}, {'A1': "10"}, {'A1': "11"}]
        for row in range(0, len(qvars)):
            DB.add_qt_variation(qt3_id, row + 1, qvars[row], ver)
        DB.create_qt_att(qt3_id, "datfile.dat", "text/plain", data, ver)
        DB.create_qt_att(qt3_id, "qtemplate.html", "text/html", "Question 3: What is <VAL A1>? <ANSWER 1>", ver)

        data = External.topic_to_zip(topic1_id)
        f = open("%s" % self.test_question_fname, mode='w')
        f.write(data)
        f.close()
Пример #3
0
    def test_topic_position(self):
        """ Test putting qtemplates into topics and moving them around
        """

        course_id = Courses.create("TEST101", "Test topic position logic", 1, 1)
        topic1_id = Topics.create(course_id, "TESTTOPIC1", 1, 2)
        topic2_id = Topics.create(course_id, "TESTTOPIC2", 3, 3)
        qt1_id = DB.create_qt(1, "TESTQ1", "Test question 1", 0, 5.0, 1)
        qt2_id = DB.create_qt(1, "TESTQ2", "Test question 2", 0, 4.1, 2, topic1_id)

        DB.move_qt_to_topic(qt1_id, topic1_id)

        self.assertEqual(DB.get_qtemplate_practice_pos(qt1_id), 0)
        self.assertEqual(DB.get_qtemplate_practice_pos(qt2_id), 0)

        self.assertEqual(DB.get_topic_for_qtemplate(qt1_id), topic1_id)
        self.assertEqual(DB.get_topic_for_qtemplate(qt2_id), topic1_id)

        DB.update_qt_practice_pos(qt1_id, 3)
        DB.update_qt_practice_pos(qt2_id, 2)

        self.assertEqual(DB.get_qtemplate_practice_pos(qt1_id), 3)
        self.assertEqual(DB.get_qtemplate_practice_pos(qt2_id), 2)

        self.assertEqual(DB.get_qtemplate_practice_pos(qt1_id), 3, "Broken cache?")
        self.assertEqual(DB.get_qtemplate_practice_pos(qt2_id), 2, "Broken cache?")

        DB.update_qt_practice_pos(qt1_id, 0)
        DB.update_qt_practice_pos(qt2_id, -1)

        self.assertEqual(DB.get_qtemplate_practice_pos(qt1_id), 0)
        self.assertEqual(DB.get_qtemplate_practice_pos(qt2_id), -1)

        self.assertEqual(DB.get_qtemplate_practice_pos(qt1_id), 0, "Broken cache?")
        self.assertEqual(DB.get_qtemplate_practice_pos(qt2_id), -1, "Broken cache?")

        qts = Topics.get_qts(topic1_id)

        self.assertIn(qt1_id, qts)
        self.assertIn(qt2_id, qts)
        self.assertEqual(len(qts), 2)

        DB.move_qt_to_topic(qt1_id, topic2_id)
        qts = Topics.get_qts(topic1_id)

        self.assertNotIn(qt1_id, qts)
        self.assertIn(qt2_id, qts)
        self.assertEqual(len(qts), 1)
Пример #4
0
    def test_do_question(self):
        """ Do a question"""

        course_id = Courses.create("TEST102", "Test question logic", 1, 1)
        self.assertGreater(course_id, 0)
        topic1_id = Topics.create(course_id, "TESTQUESTIONS1", 1, 2)
        self.assertGreater(topic1_id, 0)

        qt1_id = DB.create_qt(1, "TESTQ9", "Test question 9", 0, 5.0, 1, topic_id=topic1_id)
        self.assertIsNotNone(qt1_id)

        ver = DB.get_qt_version(qt1_id)
        self.assertGreater(ver, 0)

        data = "2\n|1\n|2\n"
        qvars = [{'A1': "2"}, {'A1': "3"}]
        for row in range(0, len(qvars)):
            DB.add_qt_variation(qt1_id, row + 1, qvars[row], ver)
        DB.create_qt_att(qt1_id, "datfile.dat", "text/plain", data , ver)
        DB.create_qt_att(qt1_id, "qtemplate.html", "text/html", "What is <VAL A1>? <ANSWER 1>", ver)

        q_id = DB.get_q_by_qt_student(qt1_id, 1)
        self.assertFalse(q_id)  # Not generated yet

        q_id = General.gen_q(qt1_id, 1)
        self.assertGreater(q_id, 0)

        q_id = DB.get_q_by_qt_student(qt1_id, 1)
        self.assertTrue(qt1_id)  # Better be there now

        DB.update_qt_maxscore(qt1_id, 7.0)
        score = DB.get_qt_maxscore(qt1_id)
        self.assertEqual(score, 7.0)
        DB.set_q_viewtime(q_id)
        self.assertIsNotNone(DB.get_q_viewtime(q_id))
Пример #5
0
    def test_topic_nextprev(self):
        """ Do the "next/previous" options in practice work?
        """

        course_id = Courses.create("TEST101", "Test topic next/prev logic", 1, 1)
        topic1_id = Topics.create(course_id, "TESTTOPIC1", 1, 2)

        qt1_id = DB.create_qt(1, "TESTQ1", "Test question 1", 0, 5.0, 1)
        qt2_id = DB.create_qt(1, "TESTQ2", "Test question 2", 0, 4.1, 2)
        qt3_id = DB.create_qt(1, "TESTQ3", "Test question 3", 0, 0.0, 2)
        qt4_id = DB.create_qt(1, "TESTQ4", "Test question 4", 0, 2.0, 2)

        DB.move_qt_to_topic(qt1_id, topic1_id)
        DB.move_qt_to_topic(qt2_id, topic1_id)
        DB.move_qt_to_topic(qt3_id, topic1_id)
        DB.move_qt_to_topic(qt4_id, topic1_id)

        DB.update_qt_practice_pos(qt1_id, 1)
        DB.update_qt_practice_pos(qt2_id, 2)
        DB.update_qt_practice_pos(qt3_id, 3)
        DB.update_qt_practice_pos(qt4_id, 4)

        qts = Topics.get_qts(topic1_id)
        self.assertIn(qt1_id, qts)
        self.assertIn(qt2_id, qts)
        self.assertIn(qt3_id, qts)
        self.assertIn(qt4_id, qts)
        self.assertEqual(len(qts), 4)

        self.assertTupleEqual(Practice.get_next_prev_pos(qt1_id, topic1_id), (None, 2))
        self.assertTupleEqual(Practice.get_next_prev_pos(qt2_id, topic1_id), (1, 3))
        self.assertTupleEqual(Practice.get_next_prev_pos(qt3_id, topic1_id), (2, 4))
        self.assertTupleEqual(Practice.get_next_prev_pos(qt4_id, topic1_id), (3, None))

        DB.update_qt_practice_pos(qt2_id, 3)

        self.assertEqual(DB.get_qtemplate_practice_pos(qt1_id), 1)
        self.assertEqual(DB.get_qtemplate_practice_pos(qt2_id), 3)
        self.assertEqual(DB.get_qtemplate_practice_pos(qt3_id), 3)
        self.assertEqual(DB.get_qtemplate_practice_pos(qt4_id), 4)

        self.assertTupleEqual(Practice.get_next_prev_pos(qt1_id, topic1_id), (None, 3))
        self.assertTupleEqual(Practice.get_next_prev_pos(qt2_id, topic1_id), (1, 4))
        self.assertTupleEqual(Practice.get_next_prev_pos(qt3_id, topic1_id), (1, 4))
        self.assertTupleEqual(Practice.get_next_prev_pos(qt4_id, topic1_id), (3, None))

        self.assertTupleEqual(Practice.get_next_prev_pos(qt4_id, None), (None, None))
Пример #6
0
def import_qts_from_zip(data, topic_id):
    """ Open the given OAQ file and import any qtemplates found.
        Return False if it's not valid
        Return 0 if it's valid but has no qtemplates
        Return NUM of templates imported.
    """

    # TODO: How do we protect against malicious uploads?
    # At the moment they're allowed for trusted people only,
    # but we'll eventually want this in the UI for end users.

    # eg.    unzip to huge size
    # add digital signatures?

    sdata = StringIO(data)
    tmpd = tempfile.mkdtemp(prefix="oa")
    qdir = os.path.join(tmpd, "oasisqe")
    os.mkdir(qdir)
    num = 0
    try:
        with zipfile.ZipFile(sdata, "r") as zfile:

            zfile.extractall(qdir)
            data = open("%s/info.json" % qdir, "r").read()
            info = json.loads(data)
            qtids = info['qtemplates'].keys()
            qtids.sort()
            for qtid in qtids:
                qtemplate = info['qtemplates'][qtid]['qtemplate']
                attachments = info['qtemplates'][qtid]['attachments']
                if 'position' in info['qtemplates'][qtid]:
                    position = info['qtemplates'][qtid]['position']
                else:
                    position = 0
                newid = DB.create_qt(owner=1,   # ownerid
                                     title=qtemplate['title'],
                                     desc=qtemplate['description'],
                                     marker=qtemplate['marker'],
                                     score_max=qtemplate['scoremax'],
                                     status=qtemplate['status'],
                                     topic_id=topic_id)

                DB.update_qt_practice_pos(newid, position)
                num += 1

    #            print "%s attachments" % len(attachments)
                for att in attachments:
                    (att_name, att_type, att_size) = att
                    data = open("%s/%s/attach/%s" % (qdir, qtemplate['id'], att_name)).read()
                    DB.create_qt_att(newid, att_name, att_type, data, 1)
                    if att_name == "datfile.txt" or att_name == "datfile.dat" or att_name == "datfile" or att_name == "_datfile" or att_name == "__datfile":
                        qvars = QEditor.parse_datfile(data)
                        for row in range(0, len(qvars)):
                            DB.add_qt_variation(newid, row + 1, qvars[row], 1)
    except zipfile.BadZipfile:
        return False
    Topics.flush_num_qs(topic_id)
    return num
Пример #7
0
def import_qts_from_zip(data, topicid):
    """ Open the given OAQ file and import any qtemplates found.
        Return False if it's not valid
        Return 0 if it's valid but has no qtemplates
        Return NUM of templates imported.
    """

    # TODO: How do we protect against malicious uploads?
    # At the moment they're allowed for trusted people only,
    # but we'll eventually want this in the UI for end users.

    # eg.    unzip to huge size
    # add digital signatures?

    sdata = StringIO(data)
    tmpd = tempfile.mkdtemp(prefix="oa")
    qdir = os.path.join(tmpd, "oasisqe")
    os.mkdir(qdir)
    with zipfile.ZipFile(sdata, "r") as zfile:

        zfile.extractall(qdir)
        data = open("%s/info.json" % qdir, "r").read()
        info = json.loads(data)
        print "%s questions found" % (len(info['qtemplates']))
        position = 1
        for qtid in info['qtemplates'].keys():
            qtemplate = info['qtemplates'][qtid]['qtemplate']
            print "%s" % qtemplate['title']
            newid = DB.create_qt(1,
                                 qtemplate['title'],
                                 qtemplate['description'],
                                 qtemplate['marker'],
                                 qtemplate['scoremax'],
                                 qtemplate['status'])
            DB.update_qt_pos(newid, topicid, position)
            position += 1
            attachments = info['qtemplates'][qtid]['attachments']

            print "%s attachments" % len(attachments)
            for att in attachments:
                (att_name, att_type, att_size) = att
                data = open("%s/%s/attach/%s" % (qdir, qtemplate['id'], att_name)).read()
                DB.create_qt_att(newid, att_name, att_type, data, 1)
                if att_name == "datfile.txt" or att_name == "datfile.dat" or att_name == "datfile" or att_name == "_datfile" or att_name == "__datfile":
                    qvars = QEditor.parse_datfile(data)
                    print "generating variations..."
                    for row in range(0, len(qvars)):
                        DB.add_qt_variation(newid, row + 1, qvars[row], 1)

    Topics.flush_num_qs(topicid)
    return 0
Пример #8
0
def create_exported_questions(fname):
    """ Make some questions and export them."""
    # Not really related to assessment, but can use this to create some questions to import and use multiple times
    course_id = Courses.create("TEST106", "Test Question Export", 1, 1)
    topic1_id = Topics.create(course_id, "TESTEXPORT1", 1, 2)
    qt1_id = DB.create_qt(1, "TESTQ1", "Test question 1", 0, 5.0, 1, topic_id=topic1_id)
    ver = DB.get_qt_version(qt1_id)

    data = "2\n|1\n|2\n"
    qvars = [{'A1': "2"}, {'A1': "3"}]
    for row in range(0, len(qvars)):
        DB.add_qt_variation(qt1_id, row + 1, qvars[row], ver)
    DB.create_qt_att(qt1_id, "datfile.dat", "text/plain", data, ver)
    DB.create_qt_att(qt1_id, "qtemplate.html", "text/html", "What is <VAL A1>? <ANSWER 1>", ver)

    qt2_id = DB.create_qt(1, "TESTQ2", "Test question 2", 0, 5.0, 1, topic_id=topic1_id)
    ver = DB.get_qt_version(qt2_id)
    data = "2\n|6\n|7\n"
    qvars = [{'A1': "6"}, {'A1': "7"}]
    for row in range(0, len(qvars)):
        DB.add_qt_variation(qt2_id, row + 1, qvars[row], ver)
    DB.create_qt_att(qt2_id, "datfile.dat", "text/plain", data, ver)
    DB.create_qt_att(qt2_id, "qtemplate.html", "text/html", "Question 2: What is <VAL A1>? <ANSWER 1>", ver)

    qt3_id = DB.create_qt(1, "TESTQ3", "Test question 3", 0, 5.0, 1, topic_id=topic1_id)
    ver = DB.get_qt_version(qt3_id)
    data = "3\n|9\n|10\n|11\n"
    qvars = [{'A1': "9"}, {'A1': "10"}, {'A1': "11"}]
    for row in range(0, len(qvars)):
        DB.add_qt_variation(qt3_id, row + 1, qvars[row], ver)
    DB.create_qt_att(qt3_id, "datfile.dat", "text/plain", data, ver)
    DB.create_qt_att(qt3_id, "qtemplate.html", "text/html", "Question 3: What is <VAL A1>? <ANSWER 1>", ver)

    data = External.topic_to_zip(topic1_id)
    f = open("%s" % fname, mode='w')
    f.write(data)
    f.close()
Пример #9
0
def do_topic_page_commands(request, topic_id, user_id):
    """We've been asked to perform some operations on the Topic page.

        Expecting form fields:

            selected_QTID
            position_QTID
            name_QTID

        where QTID is a question template id. May receive many.

            new_position
            new_name
            new_type

            select_cmd = 'copy' | 'move'
            select_target = TOPICID of target topic

    """

    form = request.form
    mesg = []

    # Make a list of all the commands to run
    cmdlist = []
    for command in request.form.keys():
        (cmd, data) = command.split('_', 2)
        value = form[command]
        if not value == "none":
            cmdlist += [{'cmd': cmd, 'data': data, 'value': value}]

    # Now run them:
    # Titles first
    for command in [cmd for cmd in cmdlist if cmd['cmd'] == 'name']:
        qid = int(command['data'])
        title = command['value']
        DB.update_qt_title(qid, title)

    # Then positions
    for command in [cmd for cmd in cmdlist if cmd['cmd'] == 'position']:
        qtid = int(command['data'])
        try:
            position = int(command['value'])
        except ValueError:
            position = 0
        DB.update_qt_pos(qtid, topic_id, position)

    # Then commands on selected questions
    target_cmd = form.get('target_cmd', None)
    if target_cmd:
        qtids = [int(cmd['data']) for cmd in cmdlist if cmd['cmd'] == 'select']
        try:
            target_topic = int(form.get('target_topic', 0))
        except ValueError:
            target_topic = None

        if target_cmd == 'move':
            if target_topic:
                for qtid in qtids:
                    qt_title = DB.get_qt_name(qtid)
                    topic_title = Topics.get_name(target_topic)
                    flash("Moving %s to %s" % (qt_title, topic_title))
                    DB.move_qt_to_topic(qtid, target_topic)
                    Topics.flush_num_qs(topic_id)
                    Topics.flush_num_qs(target_topic)
        if target_cmd == 'copy':
            if target_topic:
                for qtid in qtids:
                    qt_title = DB.get_qt_name(qtid)
                    topic_title = Topics.get_name(target_topic)
                    flash("Copying %s to %s" % (qt_title, topic_title))
                    newid = DB.copy_qt_all(qtid)
                    DB.add_qt_to_topic(newid, target_topic)
                    Topics.flush_num_qs(target_topic)

        if target_cmd == 'hide':
            for qtid in qtids:
                position = DB.get_qtemplate_topic_pos(qtid, topic_id)
                if position > 0:  # If visible, make it hidden
                    DB.update_qt_pos(qtid, topic_id, -position)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Hidden" % title)
                    Topics.flush_num_qs(topic_id)

        if target_cmd == 'show':
            for qtid in qtids:
                position = DB.get_qtemplate_topic_pos(qtid, topic_id)
                if position == 0:  # If hidden, make it visible
                    newpos = DB.get_qt_max_pos_in_topic(topic_id)
                    DB.update_qt_pos(qtid, topic_id, newpos + 1)
                    Topics.flush_num_qs(topic_id)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Visible" % title)
                if position < 0:  # If hidden, make it visible
                    DB.update_qt_pos(qtid, topic_id, -position)
                    Topics.flush_num_qs(topic_id)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Visible" % title)
        if target_cmd == "export":
            if len(qtids) < 1:
                flash("No questions selected to export")
            else:
                data = External.qts_to_zip(qtids, fname="oa_export", suffix="oaq")
                if not data:
                    abort(401)

                sio = StringIO.StringIO(data)
                return 2, send_file(sio, "application/oasisqe", as_attachment=True, attachment_filename="oa_export.zip")

    # Then new questions
    new_title = form.get('new_title', None)
    if new_title:
        if not (new_title == "[New Question]" or new_title == ""):
            new_position = form.get('new_position', 0)
            try:
                new_position = int(new_position)
            except ValueError:
                new_position = 0
            new_qtype = form.get('new_qtype', 'raw')
            try:
                new_maxscore = float(form.get('new_maxscore', 0))
            except ValueError:
                new_maxscore = 0
            newid = DB.create_qt(user_id,
                                 new_title,
                                 "No Description",
                                 1,
                                 new_maxscore,
                                 0)
            if newid:
                mesg.append("Created new question, id %s" % newid)
                DB.update_qt_pos(newid,
                                 topic_id,
                                 new_position)
                DB.create_qt_att(newid,
                                 "qtemplate.html",
                                 "application/oasis-html",
                                 "empty",
                                 1)
                DB.create_qt_att(newid,
                                 "qtemplate.html",
                                 "application/oasis-html",
                                 "empty",
                                 1)
                if new_qtype == "oqe":
                    mesg.append("Creating new question, id %s as OQE" % newid)
                    DB.create_qt_att(newid,
                                     "_editor.oqe",
                                     "application/oasis-oqe",
                                     "",
                                     1)
                if new_qtype == "raw":
                    mesg.append("Creating new question, id %s as RAW (%s)" %
                                (newid, new_qtype))
                    DB.create_qt_att(newid,
                                     "datfile.txt",
                                     "application/oasis-dat",
                                     "0",
                                     1)
            else:
                mesg.append("Error creating new question, id %s" % newid)
                L.error("Unable to create new question (%s) (%s)" %
                    (new_title, new_position))
    Topics.flush_num_qs(topic_id)

    return 1, {'mesg': mesg}
Пример #10
0
def do_topic_page_commands(request, topic_id, user_id):
    """We've been asked to perform some operations on the Topic page.

        Expecting form fields:

            selected_QTID
            position_QTID
            name_QTID

        where QTID is a question template id. May receive many.

            new_position
            new_name
            new_type

            select_cmd = 'copy' | 'move'
            select_target = TOPICID of target topic

    """

    form = request.form
    files = request.files

    mesg = []

    # Make a list of all the commands to run
    cmdlist = []
    for command in request.form.keys():
        if '_' in command:
            (cmd, data) = command.split('_', 2)
            value = form[command]
            if not value == "none":
                cmdlist += [{'cmd': cmd, 'data': data, 'value': value}]

    # Now run them:
    # Titles first
    for command in [cmd for cmd in cmdlist if cmd['cmd'] == 'name']:
        qid = int(command['data'])
        title = command['value']
        DB.update_qt_title(qid, title)

    # Then positions
    for command in [cmd for cmd in cmdlist if cmd['cmd'] == 'position']:
        qtid = int(command['data'])
        try:
            position = int(command['value'])
        except ValueError:
            position = 0
        DB.update_qt_practice_pos(qtid, position)

    # Then commands on selected questions
    target_cmd = form.get('target_cmd', None)
    if target_cmd:
        qtids = [int(cmd['data']) for cmd in cmdlist if cmd['cmd'] == 'select']
        try:
            target_topic = int(form.get('target_topic', 0))
        except ValueError:
            target_topic = None

        if target_cmd == 'move':
            if target_topic:
                for qtid in qtids:
                    qt_title = DB.get_qt_name(qtid)
                    topic_title = Topics.get_name(target_topic)
                    flash("Moving %s to %s" % (qt_title, topic_title))
                    DB.move_qt_to_topic(qtid, target_topic)
                    Topics.flush_num_qs(target_topic)
        if target_cmd == 'copy':
            if target_topic:
                for qtid in qtids:
                    qt_title = DB.get_qt_name(qtid)
                    topic_title = Topics.get_name(target_topic)
                    flash("Copying %s to %s" % (qt_title, topic_title))
                    position = DB.get_qtemplate_practice_pos(qtid)
                    newid = DB.copy_qt_all(qtid)
                    DB.move_qt_to_topic(newid, target_topic, position)
                    Topics.flush_num_qs(target_topic)

        if target_cmd == 'hide':
            for qtid in qtids:
                position = DB.get_qtemplate_practice_pos(qtid)
                if position > 0:  # If visible, make it hidden
                    DB.update_qt_practice_pos(qtid, -position)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Hidden" % title)

        if target_cmd == 'show':
            for qtid in qtids:
                position = DB.get_qtemplate_practice_pos(qtid)
                if position == 0:  # If hidden, make it visible
                    newpos = DB.get_qt_max_pos_in_topic(topic_id)
                    DB.update_qt_practice_pos(qtid, newpos + 1)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Visible" % title)
                if position < 0:  # If hidden, make it visible
                    DB.update_qt_practice_pos(qtid, -position)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Visible" % title)
        if target_cmd == "export":
            if len(qtids) < 1:
                flash("No questions selected to export")
            else:
                data = External.qts_to_zip(qtids)
                if not data:
                    abort(401)

                sio = StringIO.StringIO(data)
                return 2, send_file(sio, "application/oasisqe", as_attachment=True, attachment_filename="oa_export.zip")

    # Then new questions
    new_title = form.get('new_title', None)
    if new_title:
        if not (new_title == "[New Question]" or new_title == ""):
            new_position = form.get('new_position', 0)
            try:
                new_position = int(new_position)
            except ValueError:
                new_position = 0
            new_qtype = form.get('new_qtype', 'raw')
            try:
                new_max_score = float(form.get('new_maxscore', 0))
            except ValueError:
                new_max_score = 0
            new_id = DB.create_qt(owner=user_id,
                                  title=new_title,
                                  desc="No Description",
                                  marker=1,
                                  score_max=new_max_score,
                                  status=0,
                                  topic_id=topic_id)
            if new_id:
                mesg.append("Created new question, id %s" % new_id)
                if new_position and new_position >= 1:
                    DB.update_qt_practice_pos(new_id, new_position)

                if new_qtype == "qe2":
                    mesg.append("Creating new question, id %s as QE2" % new_id)
                    QEditor2.create_new(new_id, new_title)

                if new_qtype == "raw":
                    mesg.append("Creating new question, id %s as RAW (%s)" %
                                (new_id, new_qtype))
                    QEditor.create_new(new_id, new_title)

            else:
                mesg.append("Error creating new question, id %s" % new_id)
                L.error("Unable to create new question (%s) (%s)" %
                        (new_title, new_position))

    L.info("request.files = %s" % (repr(request.files.keys())))
    # Did they upload a file to import?
    if 'import_file' in request.files:
        L.info("File upload to topic %s by user %s" % (topic_id, user_id))
        data = files['import_file'].read()
        if len(data) > 1:
            for msg in _import_questions_from_file(data, topic_id):
                mesg.append(msg)

    Topics.flush_num_qs(topic_id)

    return 1, {'mesg': mesg}
Пример #11
0
def do_topic_page_commands(request, topic_id, user_id):
    """We've been asked to perform some operations on the Topic page.

        Expecting form fields:

            selected_QTID
            position_QTID
            name_QTID

        where QTID is a question template id. May receive many.

            new_position
            new_name
            new_type

            select_cmd = 'copy' | 'move'
            select_target = TOPICID of target topic

    """

    form = request.form
    mesg = []

    # Make a list of all the commands to run
    cmdlist = []
    for command in request.form.keys():
        (cmd, data) = command.split('_', 2)
        value = form[command]
        if not value == "none":
            cmdlist += [{'cmd': cmd, 'data': data, 'value': value}]

    # Now run them:
    # Titles first
    for command in [cmd for cmd in cmdlist if cmd['cmd'] == 'name']:
        qid = int(command['data'])
        title = command['value']
        DB.update_qt_title(qid, title)

    # Then positions
    for command in [cmd for cmd in cmdlist if cmd['cmd'] == 'position']:
        qtid = int(command['data'])
        try:
            position = int(command['value'])
        except ValueError:
            position = 0
        DB.update_qt_pos(qtid, topic_id, position)

    # Then commands on selected questions
    target_cmd = form.get('target_cmd', None)
    if target_cmd:
        qtids = [int(cmd['data']) for cmd in cmdlist if cmd['cmd'] == 'select']
        try:
            target_topic = int(form.get('target_topic', 0))
        except ValueError:
            target_topic = None

        if target_cmd == 'move':
            if target_topic:
                for qtid in qtids:
                    qt_title = DB.get_qt_name(qtid)
                    topic_title = Topics.get_name(target_topic)
                    flash("Moving %s to %s" % (qt_title, topic_title))
                    DB.move_qt_to_topic(qtid, target_topic)
                    Topics.flush_num_qs(topic_id)
                    Topics.flush_num_qs(target_topic)
        if target_cmd == 'copy':
            if target_topic:
                for qtid in qtids:
                    qt_title = DB.get_qt_name(qtid)
                    topic_title = Topics.get_name(target_topic)
                    flash("Copying %s to %s" % (qt_title, topic_title))
                    newid = DB.copy_qt_all(qtid)
                    DB.add_qt_to_topic(newid, target_topic)
                    Topics.flush_num_qs(target_topic)

        if target_cmd == 'hide':
            for qtid in qtids:
                position = DB.get_qtemplate_topic_pos(qtid, topic_id)
                if position > 0:  # If visible, make it hidden
                    DB.update_qt_pos(qtid, topic_id, -position)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Hidden" % title)
                    Topics.flush_num_qs(topic_id)

        if target_cmd == 'show':
            for qtid in qtids:
                position = DB.get_qtemplate_topic_pos(qtid, topic_id)
                if position == 0:  # If hidden, make it visible
                    newpos = DB.get_qt_max_pos_in_topic(topic_id)
                    DB.update_qt_pos(qtid, topic_id, newpos + 1)
                    Topics.flush_num_qs(topic_id)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Visible" % title)
                if position < 0:  # If hidden, make it visible
                    DB.update_qt_pos(qtid, topic_id, -position)
                    Topics.flush_num_qs(topic_id)
                    title = DB.get_qt_name(qtid)
                    flash("Made '%s' Visible" % title)
        if target_cmd == "export":
            if len(qtids) < 1:
                flash("No questions selected to export")
            else:
                data = External.qts_to_zip(qtids)
                if not data:
                    abort(401)

                sio = StringIO.StringIO(data)
                return 2, send_file(sio,
                                    "application/oasisqe",
                                    as_attachment=True,
                                    attachment_filename="oa_export.zip")

    # Then new questions
    new_title = form.get('new_title', None)
    if new_title:
        if not (new_title == "[New Question]" or new_title == ""):
            new_position = form.get('new_position', 0)
            try:
                new_position = int(new_position)
            except ValueError:
                new_position = 0
            new_qtype = form.get('new_qtype', 'raw')
            try:
                new_max_score = float(form.get('new_maxscore', 0))
            except ValueError:
                new_max_score = 0
            newid = DB.create_qt(user_id, new_title, "No Description", 1,
                                 new_max_score, 0)
            if newid:
                mesg.append("Created new question, id %s" % newid)
                DB.update_qt_pos(newid, topic_id, new_position)
                DB.create_qt_att(newid, "qtemplate.html",
                                 "application/oasis-html", "empty", 1)
                DB.create_qt_att(newid, "qtemplate.html",
                                 "application/oasis-html", "empty", 1)
                if new_qtype == "oqe":
                    mesg.append("Creating new question, id %s as OQE" % newid)
                    DB.create_qt_att(newid, "_editor.oqe",
                                     "application/oasis-oqe", "", 1)
                if new_qtype == "raw":
                    mesg.append("Creating new question, id %s as RAW (%s)" %
                                (newid, new_qtype))
                    DB.create_qt_att(newid, "datfile.txt",
                                     "application/oasis-dat", "0", 1)
            else:
                mesg.append("Error creating new question, id %s" % newid)
                L.error("Unable to create new question (%s) (%s)" %
                        (new_title, new_position))
    Topics.flush_num_qs(topic_id)

    return 1, {'mesg': mesg}