timApp.lecture package#

Submodules#

timApp.lecture.askedjson module#

class timApp.lecture.askedjson.AskedJson(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

asked_json_id#
asked_questions#
hash#
json#
to_json(hide_points=False)[source]#
timApp.lecture.askedjson.find_json(q)[source]#
timApp.lecture.askedjson.get_asked_json_by_hash(json_hash: str) timApp.lecture.askedjson.AskedJson | None[source]#
timApp.lecture.askedjson.make_error_question(desc: str)[source]#
timApp.lecture.askedjson.normalize_question_json(q: dict[str, Any])[source]#

Normalizes the JSON data of a question.

The question data format has changed a few times over the years. This function normalizes all possible formats to a single format that is easier to handle in other code.

Parameters

q – The data to normalize.

Returns

The normalized data.

timApp.lecture.askedjson.normalize_rows(rows)[source]#
timApp.lecture.askedjson.process_json(json_data: dict[str, Any], normalized: dict[str, str | dict | list], skip_keys: Optional[set[str]] = None)[source]#

timApp.lecture.askedquestion module#

class timApp.lecture.askedquestion.AskedQuestion(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

add_activity(kind: timApp.lecture.questionactivity.QuestionActivityKind, user: timApp.timdb.models.user.User)[source]#
answers#
answers_all#
asked_id#
asked_json: timApp.lecture.askedjson.AskedJson#
asked_json_id#
asked_time#
build_answer_and_points(answer, u: timApp.timdb.models.user.User)[source]#

Checks whether question was randomized If so, set question point input accordingly and expand answer to contain randomization data

doc_id#
property end_time: datetime.datetime | None#
expl#
get_default_points()[source]#
get_effective_points()[source]#
has_activity(kind: timApp.lecture.questionactivity.QuestionActivityKind, user: timApp.timdb.models.user.User)[source]#
property is_running#
lecture: timApp.lecture.lecture.Lecture#
lecture_id#
par_id#
points#
questionactivity#
running_question#
showpoints#
property time_limit#
to_json(hide_points=False)[source]#
timApp.lecture.askedquestion.get_asked_question(asked_id: int) timApp.lecture.askedquestion.AskedQuestion | None[source]#
timApp.lecture.askedquestion.user_activity_lock(user: timApp.timdb.models.user.User)[source]#

timApp.lecture.lecture module#

class timApp.lecture.lecture.Lecture(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

asked_questions#
doc_id#
end_time#
static find_by_code(lecture_code: str, doc_id: int) Optional[timApp.lecture.lecture.Lecture][source]#
static find_by_id(lecture_id: int) Optional[timApp.lecture.lecture.Lecture][source]#
static get_all_in_document(doc_id: int, time: Optional[datetime.datetime] = None) list['Lecture'][source]#
property is_full#
property is_running#
lecture_code#
lecture_id#
lecturer#
property max_students#
messages#
options#
property options_parsed#
owner#
password#
running_questions#
start_time#
to_json(show_password=False)[source]#
useractivity#
users#

timApp.lecture.lectureanswer module#

class timApp.lecture.lectureanswer.LectureAnswer(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

answer#
answer_id#
answered_on#
asked_question#
static get_by_id(ans_id: int) Optional[timApp.lecture.lectureanswer.LectureAnswer][source]#
get_parsed_answer()[source]#
lecture_id#
points#
question_id#
to_json(include_question=True, include_user=True)[source]#
user#
user_id#
timApp.lecture.lectureanswer.get_totals(lecture: timApp.lecture.lecture.Lecture, user: Optional[timApp.user.user.User] = None) list[tuple[timApp.user.user.User, float, int]][source]#
timApp.lecture.lectureanswer.unshuffle_lectureanswer(answer: list[list[str]], question_type: str, row_count: int, rand_arr: list[int]) list[list[str]][source]#

timApp.lecture.lectureusers module#

class timApp.lecture.lectureusers.LectureUsers(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

lecture_id#
user_id#

timApp.lecture.lectureutils module#

class timApp.lecture.lectureutils.CurrentLectureInfo(in_lecture: bool, is_lecturer: bool)[source]#

Bases: object

in_lecture: bool#
is_lecturer: bool#
timApp.lecture.lectureutils.get_current_lecture_info() timApp.lecture.lectureutils.CurrentLectureInfo[source]#
timApp.lecture.lectureutils.is_lecturer_of(l: timApp.lecture.lecture.Lecture) bool[source]#
timApp.lecture.lectureutils.verify_is_lecturer(l: timApp.lecture.lecture.Lecture) None[source]#

timApp.lecture.message module#

class timApp.lecture.message.Message(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

lecture#
lecture_id#
message#
msg_id#
timestamp#
to_json()[source]#
user#
user_id#

timApp.lecture.question module#

class timApp.lecture.question.Question(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

answer#
doc_id#
expl#
par_id#
points#
question_id#
question_title#
questionjson#

timApp.lecture.question_utils module#

timApp.lecture.question_utils.calculate_points_from_json_answer(single_answers: list[list[str]], points_table: list[dict[str, float]] | None, default_points: float | None | marshmallow.utils._Missing = 0) float[source]#
timApp.lecture.question_utils.create_points_table(points: str) list[dict[str, float]][source]#
timApp.lecture.question_utils.qst_filter_markup_points(points: str, question_type: str, rand_arr: list[int]) str[source]#

filter markup’s points field based on pre-generated array

timApp.lecture.question_utils.qst_handle_randomization(jso: dict) None[source]#

Check if markup calls for randomization, or previous state contains randomization data Update answer options, explanations and points accordingly.

Parameters

jso – request json to modify

timApp.lecture.question_utils.qst_pick_expls(orig_expls: dict[str, T], order_array: list[int]) dict[str, T][source]#

pick items from dict where keys are str converted integers in order given by order_array indices start from 1

timApp.lecture.question_utils.qst_rand_array(max_count: int, randoms: int, seed_word: str, random_seed: int = 0, locks: Optional[Union[int, list[int]]] = None) list[int][source]#

Get array of count integers between 1 and max_count (incl.) using word and extra number as seed.

Parameters
  • max_count – highest possible number (incl.) and max return list length

  • randoms – how many random numbers to fill the array with

  • seed_word – input word to generate random seed

  • random_seed – extra number to edit the seed

  • locks – positions that can’t be shuffled, indexing starting from 1. Any position over max_count will be

interpreted as max_count :return: shuffled array of integers of up to max_count values

timApp.lecture.question_utils.qst_set_array_order(arr: list[T], order_array: list[int]) list[T][source]#

pick items from arr in order given by order_array indices start from 1

timApp.lecture.questionactivity module#

class timApp.lecture.questionactivity.QuestionActivity(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

asked_id#
asked_question#
kind#
user#
user_id#
class timApp.lecture.questionactivity.QuestionActivityKind(value)[source]#

Bases: enum.Enum

An enumeration.

Pointsclosed = 1#
Pointsshown = 2#
Useranswered = 3#
Userextended = 4#
Usershown = 5#

timApp.lecture.routes module#

class timApp.lecture.routes.AnswerToQuestionModel(asked_id: int, input: list[list[str]])[source]#

Bases: timApp.lecture.routes.AskedIdModel

input: list[list[str]]#
class timApp.lecture.routes.AskedIdModel(asked_id: int)[source]#

Bases: object

asked_id: int#
class timApp.lecture.routes.DeleteLectureModel(lecture_id: int)[source]#

Bases: object

lecture_id: int#
class timApp.lecture.routes.GetUpdatesModel(client_last_id: int, current_points_id: int | None = None, current_question_id: int | None = None, doc_id: int | None = None, use_questions: bool = False, use_wall: bool = False)[source]#

Bases: object

client_last_id: int#
current_points_id: int | None = None#
current_question_id: int | None = None#
doc_id: int | None = None#
use_questions: bool = False#
use_wall: bool = False#
class timApp.lecture.routes.SendMessageModel(message: str)[source]#

Bases: object

message: str#
class timApp.lecture.routes.ShowAnswerPointsModel(asked_id: int)[source]#

Bases: timApp.lecture.routes.AskedIdModel

current_points_id: int | None = None#
current_question_id: int | None = None#
timApp.lecture.routes.answer_to_question(m: timApp.lecture.routes.AnswerToQuestionModel)[source]#
timApp.lecture.routes.ask_question()[source]#
timApp.lecture.routes.check_if_lecture_is_ending(lecture: timApp.lecture.lecture.Lecture)[source]#

Checks if the lecture is about to end. 1 -> ends in 1 min. 5 -> ends in 5 min. 100 -> goes on atleast for 5 mins.

Parameters

lecture – The lecture object.

Returns

timApp.lecture.routes.check_lecture()[source]#

Route to check if the current user is in some lecture in specific document.

timApp.lecture.routes.clean_dictionaries_by_lecture(lecture: timApp.lecture.lecture.Lecture)[source]#

Cleans data from lecture that isn’t running anymore.

Parameters

lecture – The lecture.

timApp.lecture.routes.close_points()[source]#
timApp.lecture.routes.create_lecture()[source]#
timApp.lecture.routes.delete_activity(question: timApp.lecture.askedquestion.AskedQuestion, kinds)[source]#
timApp.lecture.routes.delete_lecture(m: timApp.lecture.routes.DeleteLectureModel)[source]#
timApp.lecture.routes.delete_question_temp_data(question: timApp.lecture.askedquestion.AskedQuestion, lecture: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.do_get_updates(m: timApp.lecture.routes.GetUpdatesModel)[source]#

Gets updates from some lecture.

Checks updates in 1 second frequently and answers if there is updates.

timApp.lecture.routes.empty_lecture(lec: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.end_lecture()[source]#
timApp.lecture.routes.extend_lecture()[source]#
timApp.lecture.routes.extend_question()[source]#
timApp.lecture.routes.get_all_lectures()[source]#
timApp.lecture.routes.get_all_messages()[source]#

Route to get all the messages from some lecture.

timApp.lecture.routes.get_asked_question_by_id()[source]#
timApp.lecture.routes.get_current_lecture() timApp.lecture.lecture.Lecture | None[source]#
timApp.lecture.routes.get_current_lecture_or_abort() timApp.lecture.lecture.Lecture[source]#
timApp.lecture.routes.get_lecture_answer_totals(lecture_id)[source]#
timApp.lecture.routes.get_lecture_answers()[source]#

Changing this to long poll requires removing threads.

timApp.lecture.routes.get_lecture_from_request(check_access=True, lecture_id: Optional[int] = None) timApp.lecture.lecture.Lecture[source]#
timApp.lecture.routes.get_lecture_info()[source]#

Route to get info from lectures.

Gives answers, and messages and other necessary info.

timApp.lecture.routes.get_lecture_session_data()[source]#
timApp.lecture.routes.get_lecture_users(lecture: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.get_new_question(lecture: timApp.lecture.lecture.Lecture, current_question_id=None, current_points_id=None, force=False)[source]#
Parameters
  • current_points_id – TODO: what is this?

  • current_question_id – The id of the current question.

  • lecture – lecture to get running questions from

  • force – Return question, even if it already has been shown to user

Returns

None if no questions are running dict with data of new question if there is a question running and user hasn’t answered to that question. {‘type’: ‘already_answered’} if there is a question running and user has answered to that.

timApp.lecture.routes.get_question_answer_by_id()[source]#
timApp.lecture.routes.get_question_by_par_id()[source]#
timApp.lecture.routes.get_question_manually()[source]#

Route to use to get question manually (instead of getting question in /getUpdates).

timApp.lecture.routes.get_running_lectures(doc_id=None)[source]#

Gets all running and future lectures.

Parameters

doc_id – The document id for which to get lectures.

timApp.lecture.routes.get_shown_points(lecture) timApp.lecture.askedquestion.AskedQuestion | None[source]#
timApp.lecture.routes.get_updates(m: timApp.lecture.routes.GetUpdatesModel)[source]#
timApp.lecture.routes.hide_points_and_try_shuffle_question(question: timApp.lecture.askedquestion.AskedQuestion, user_id: int)[source]#
timApp.lecture.routes.join_lecture()[source]#

Route to join lecture.

Checks that the given password is correct.

timApp.lecture.routes.leave_lecture(lecture: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.leave_lecture_route()[source]#
timApp.lecture.routes.lecture_before_request()[source]#
timApp.lecture.routes.lecture_dict(lecture: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.lecture_needs_password()[source]#
timApp.lecture.routes.q_log(s: str)[source]#
timApp.lecture.routes.send_message(m: timApp.lecture.routes.SendMessageModel)[source]#

Route to add message to database.

timApp.lecture.routes.show_lecture_info(lecture_id)[source]#
timApp.lecture.routes.show_lecture_info_given_name()[source]#
timApp.lecture.routes.show_points(m: timApp.lecture.routes.ShowAnswerPointsModel)[source]#
timApp.lecture.routes.start_future_lecture()[source]#
timApp.lecture.routes.stop_question(m: timApp.lecture.routes.AskedIdModel)[source]#

Route to stop question from running.

timApp.lecture.routes.stop_showing_points(lecture: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.switch_to_lecture(l: timApp.lecture.lecture.Lecture)[source]#
timApp.lecture.routes.update_activity(lecture: timApp.lecture.lecture.Lecture, u: timApp.user.user.User)[source]#
timApp.lecture.routes.update_question_points()[source]#

Route to get add question to database.

timApp.lecture.runningquestion module#

class timApp.lecture.runningquestion.Runningquestion(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

ask_time#
asked_id#
asked_question: timApp.lecture.askedquestion.AskedQuestion#
end_time#
lecture#
lecture_id#

timApp.lecture.showpoints module#

class timApp.lecture.showpoints.Showpoints(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

asked_id#
asked_question#

timApp.lecture.useractivity module#

class timApp.lecture.useractivity.Useractivity(**kwargs)[source]#

Bases: sqlalchemy.ext.declarative.api.Model

active#
lecture#
lecture_id#
user#
user_id#

Module contents#