studium 0.18.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (821) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3310 -0
  3. data/bin/all_passed_exams +14 -0
  4. data/bin/check_description_of_these_lectures +7 -0
  5. data/bin/curriculum_module_displayer +7 -0
  6. data/bin/cycle +7 -0
  7. data/bin/d10 +7 -0
  8. data/bin/d100 +7 -0
  9. data/bin/d15 +7 -0
  10. data/bin/d150 +7 -0
  11. data/bin/d20 +7 -0
  12. data/bin/d25 +7 -0
  13. data/bin/d3 +7 -0
  14. data/bin/d30 +7 -0
  15. data/bin/d5 +7 -0
  16. data/bin/determine_curricula +7 -0
  17. data/bin/display_lecture_url +7 -0
  18. data/bin/exam_registration_at +7 -0
  19. data/bin/exam_statistics +7 -0
  20. data/bin/exams_per_month +9 -0
  21. data/bin/finished_exams_at_this_university +7 -0
  22. data/bin/flashcards +7 -0
  23. data/bin/from_curriculum_id_to_university +9 -0
  24. data/bin/location_to_this_exam_topic.rb +7 -0
  25. data/bin/mandatory_continuous_assessment +7 -0
  26. data/bin/mandatory_upcoming_courses +10 -0
  27. data/bin/n_ECTS +7 -0
  28. data/bin/n_exam_questions_already_answered +15 -0
  29. data/bin/names_of_all_solved_exams +7 -0
  30. data/bin/not_completed_exams +7 -0
  31. data/bin/nquestions +7 -0
  32. data/bin/nsolved +7 -0
  33. data/bin/open_last_exam_question_asked_file +7 -0
  34. data/bin/passed_exams +7 -0
  35. data/bin/passed_pr/303/274fungsimmanente_courses +7 -0
  36. data/bin/passed_this_exam_on +10 -0
  37. data/bin/pdf_for +7 -0
  38. data/bin/question_answer +7 -0
  39. data/bin/random_exam_topic +7 -0
  40. data/bin/registered_for_this_exam +15 -0
  41. data/bin/report_solved_topics +7 -0
  42. data/bin/return_n_ects_from_this_file +7 -0
  43. data/bin/return_n_questions_solved_in_total +7 -0
  44. data/bin/rti_conflict +7 -0
  45. data/bin/search_for_n_ects +7 -0
  46. data/bin/show_lectures_on_the_commandline +7 -0
  47. data/bin/show_passed_exams_having_this_grade +7 -0
  48. data/bin/show_themes +7 -0
  49. data/bin/solved +9 -0
  50. data/bin/solved_ects +7 -0
  51. data/bin/studienkennzahl +7 -0
  52. data/bin/studium +7 -0
  53. data/bin/studium_actions +7 -0
  54. data/bin/studium_skeleton +7 -0
  55. data/bin/ufind +7 -0
  56. data/bin/upcoming_exams +7 -0
  57. data/bin/week_parser +7 -0
  58. data/doc/ECTS_CONSIDERATIONS/ECTS_CONSIDERATIONS.md +85 -0
  59. data/doc/HOW_TO_DETERMINE_WHICH_PART_IS_THE_QUESTION_AND_WHICH_PART_IS_THE_ANSWER/HOW_TO_DETERMINE_WHICH_PART_IS_THE_QUESTION_AND_WHICH_PART_IS_THE_ANSWER.md +44 -0
  60. data/doc/README.gen +3263 -0
  61. data/doc/SQL_database_specification/SQL_database_specification.md +46 -0
  62. data/doc/deprecated_components/deprecated_components.md +46 -0
  63. data/doc/documentation_for_the_file_lecture_information/documentation_for_the_file_lecture_information.md +311 -0
  64. data/doc/elegant_colours/elegant_colours.md +21 -0
  65. data/doc/statistics/yearly_statistics.md +8 -0
  66. data/doc/todo/todo_for_the_graphical_parts_of_the_studium_gem_including_www_related_aspects.md +92 -0
  67. data/doc/todo/todo_for_the_studium_gem.md +55 -0
  68. data/img/STUDIES.png +0 -0
  69. data/lib/studium/actions/actions.rb +134 -0
  70. data/lib/studium/autoinclude.rb +7 -0
  71. data/lib/studium/base/base.rb +3554 -0
  72. data/lib/studium/base/commandline_arguments_module/commandline_arguments_module.rb +115 -0
  73. data/lib/studium/base/html_colours_module.rb +632 -0
  74. data/lib/studium/base/runmode_module/runmode_module.rb +103 -0
  75. data/lib/studium/c/README.md +2 -0
  76. data/lib/studium/c/a.out +0 -0
  77. data/lib/studium/c/obtain_random_entry.c +11 -0
  78. data/lib/studium/check_and_sanitize/README.md +15 -0
  79. data/lib/studium/check_and_sanitize/check_curriculum_for_correct_separation_of_bachelor_and_master.rb +141 -0
  80. data/lib/studium/check_and_sanitize/check_for_all_exam_topics_being_registered.rb +118 -0
  81. data/lib/studium/check_and_sanitize/check_for_correct_themes_of_each_course.rb +100 -0
  82. data/lib/studium/check_and_sanitize/check_for_existing_description_of_this_lecture.rb +194 -0
  83. data/lib/studium/check_and_sanitize/check_important_exams.rb +138 -0
  84. data/lib/studium/check_and_sanitize/check_the_lecture_information_file.rb +166 -0
  85. data/lib/studium/check_and_sanitize/correct_all_dates_in_the_file_lecture_information.rb +115 -0
  86. data/lib/studium/check_and_sanitize/date_sanitizer.rb +350 -0
  87. data/lib/studium/check_and_sanitize/find_duplicate_lectures.rb +124 -0
  88. data/lib/studium/check_and_sanitize/missing_priority_entry.rb +44 -0
  89. data/lib/studium/check_and_sanitize/sanitize_lecture_information.rb +434 -0
  90. data/lib/studium/colours/colours.rb +1711 -0
  91. data/lib/studium/commandline/commandline.rb +1848 -0
  92. data/lib/studium/constants/constants.rb +2063 -0
  93. data/lib/studium/css/project.css +273 -0
  94. data/lib/studium/curricula/attribute_lecture_to_curriculum/attribute_boku_lecture_to_curriculum.rb +384 -0
  95. data/lib/studium/curricula/attribute_lecture_to_curriculum/attribute_lecture_to_curriculum.rb +238 -0
  96. data/lib/studium/curricula/curricula_from_this_website/curricula_from_this_website.rb +141 -0
  97. data/lib/studium/curricula/curriculum.rb +213 -0
  98. data/lib/studium/curricula/curriculum_as_string.rb +280 -0
  99. data/lib/studium/curricula/curriculum_module_displayer/constants.rb +33 -0
  100. data/lib/studium/curricula/curriculum_module_displayer/curriculum_module_displayer.rb +417 -0
  101. data/lib/studium/curricula/curriculum_module_displayer/initialize.rb +25 -0
  102. data/lib/studium/curricula/curriculum_module_displayer/menu.rb +45 -0
  103. data/lib/studium/curricula/curriculum_module_displayer/reset.rb +74 -0
  104. data/lib/studium/curricula/curriculum_module_displayer/run.rb +20 -0
  105. data/lib/studium/curricula/curriculum_module_displayer/set_use_this_curriculum.rb +93 -0
  106. data/lib/studium/curricula/curriculum_module_displayer/show_and_report.rb +190 -0
  107. data/lib/studium/curricula/determine_curricula/constants.rb +11 -0
  108. data/lib/studium/curricula/determine_curricula/determine_curricula.rb +36 -0
  109. data/lib/studium/curricula/determine_curricula/help.rb +39 -0
  110. data/lib/studium/curricula/determine_curricula/initialize.rb +48 -0
  111. data/lib/studium/curricula/determine_curricula/menu.rb +151 -0
  112. data/lib/studium/curricula/determine_curricula/misc.rb +403 -0
  113. data/lib/studium/curricula/determine_curricula/report.rb +141 -0
  114. data/lib/studium/curricula/determine_curricula/reset.rb +59 -0
  115. data/lib/studium/curricula/determine_curricula/run.rb +19 -0
  116. data/lib/studium/curricula/determine_elective_courses_in_this_curriculum.rb +112 -0
  117. data/lib/studium/curricula/display_bachelor_curricula.rb +90 -0
  118. data/lib/studium/curricula/handle_curricula/README.md +9 -0
  119. data/lib/studium/curricula/handle_curricula/handle_curricula.rb +99 -0
  120. data/lib/studium/curricula/handle_curricula/misc.rb +798 -0
  121. data/lib/studium/curricula/mitteilungsbl/303/244tter/mitteilungsbl/303/244tter.rb +323 -0
  122. data/lib/studium/curricula/modules/display_on_the_commandline.rb +319 -0
  123. data/lib/studium/curricula/modules/return_n_ects_in_this_module.rb +74 -0
  124. data/lib/studium/curricula/n_percent_solved_in_this_curriculum.rb +73 -0
  125. data/lib/studium/curricula/prepare_individual_curriculum.rb +304 -0
  126. data/lib/studium/curricula/random_curriculum_creator/random_curriculum_creator.rb +164 -0
  127. data/lib/studium/curricula/show_all_unfinished_courses_of_this_curriculum/show_all_unfinished_courses_of_this_curriculum.rb +116 -0
  128. data/lib/studium/curricula/show_lectures_of_this_curriculum.rb +114 -0
  129. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/show_lectures_of_this_curriculum_id.rb +554 -0
  130. data/lib/studium/curricula/show_solved_percentage_among_the_registered_curricula.rb +87 -0
  131. data/lib/studium/curricula/sorted_individual_curricula.rb +121 -0
  132. data/lib/studium/ects/boku_ects_splitter.rb +128 -0
  133. data/lib/studium/ects/ects_per_university/ects_per_university.rb +179 -0
  134. data/lib/studium/ects/ects_scanner.rb +141 -0
  135. data/lib/studium/ects/ects_to_university_parser.rb +142 -0
  136. data/lib/studium/ects/last_entry_is_curriculum.rb +150 -0
  137. data/lib/studium/ects/n_ects_in_these_lectures.rb +196 -0
  138. data/lib/studium/ects/n_ects_points_in_mandatory_presence_courses.rb +47 -0
  139. data/lib/studium/ects/return_n_ects_from_this_file.rb +59 -0
  140. data/lib/studium/ects/return_n_ects_from_this_url.rb +197 -0
  141. data/lib/studium/ects/search_for_n_ects/search_for_n_ects.rb +719 -0
  142. data/lib/studium/ects/show_completed_ects_in_all_curricula.rb +245 -0
  143. data/lib/studium/ects/show_passed_credits_per_curriculum.rb +276 -0
  144. data/lib/studium/ects/simple_total_ects_points.rb +135 -0
  145. data/lib/studium/ects/solved_ects/constants.rb +19 -0
  146. data/lib/studium/ects/solved_ects/reset.rb +50 -0
  147. data/lib/studium/ects/solved_ects/solved_ects.rb +325 -0
  148. data/lib/studium/ects/solved_ects_per_university/reset.rb +25 -0
  149. data/lib/studium/ects/solved_ects_per_university/solved_ects_per_university.rb +116 -0
  150. data/lib/studium/ects/still_missing.rb +129 -0
  151. data/lib/studium/ects/sum_of_ects.rb +144 -0
  152. data/lib/studium/encoding/encoding.rb +109 -0
  153. data/lib/studium/exam_topics/RNAi_siRNA_and_miRNA +100 -0
  154. data/lib/studium/exam_topics/abfall_als_ressource +86 -0
  155. data/lib/studium/exam_topics/advanced_biochemistry +937 -0
  156. data/lib/studium/exam_topics/advanced_biotechnology +234 -0
  157. data/lib/studium/exam_topics/advanced_cellbiology +251 -0
  158. data/lib/studium/exam_topics/advanced_chemistry +547 -0
  159. data/lib/studium/exam_topics/advanced_immunology +225 -0
  160. data/lib/studium/exam_topics/advanced_microbiology +49 -0
  161. data/lib/studium/exam_topics/advanced_topics_in_plant_sciences +117 -0
  162. data/lib/studium/exam_topics/advanced_virology +273 -0
  163. data/lib/studium/exam_topics/ageing +154 -0
  164. data/lib/studium/exam_topics/agrar_ecology +67 -0
  165. data/lib/studium/exam_topics/agrarmarkt +73 -0
  166. data/lib/studium/exam_topics/agrarphysik +35 -0
  167. data/lib/studium/exam_topics/alcohols +30 -0
  168. data/lib/studium/exam_topics/algorithms +104 -0
  169. data/lib/studium/exam_topics/allergie +76 -0
  170. data/lib/studium/exam_topics/allgemeine_genetik +1006 -0
  171. data/lib/studium/exam_topics/allgemeine_mikrobiologie +1012 -0
  172. data/lib/studium/exam_topics/aminoacids +469 -0
  173. data/lib/studium/exam_topics/analytische_chemie_1 +134 -0
  174. data/lib/studium/exam_topics/analytische_chemie_2 +31 -0
  175. data/lib/studium/exam_topics/anatomie +378 -0
  176. data/lib/studium/exam_topics/anorganische_chemie +357 -0
  177. data/lib/studium/exam_topics/anthropologie +239 -0
  178. data/lib/studium/exam_topics/antibodies_and_antigens +790 -0
  179. data/lib/studium/exam_topics/apoptosis +35 -0
  180. data/lib/studium/exam_topics/archaea +112 -0
  181. data/lib/studium/exam_topics/archaeo_viruses +7 -0
  182. data/lib/studium/exam_topics/archaeology +5 -0
  183. data/lib/studium/exam_topics/architecture +8 -0
  184. data/lib/studium/exam_topics/artificial_intelligence +90 -0
  185. data/lib/studium/exam_topics/atomemissionsspektrometrie +6 -0
  186. data/lib/studium/exam_topics/audio +11 -0
  187. data/lib/studium/exam_topics/bacteriophages +266 -0
  188. data/lib/studium/exam_topics/basic_biochemistry +1008 -0
  189. data/lib/studium/exam_topics/basic_biotechnology +1011 -0
  190. data/lib/studium/exam_topics/basic_chemistry +1007 -0
  191. data/lib/studium/exam_topics/basic_virology +1008 -0
  192. data/lib/studium/exam_topics/bauwesen +6 -0
  193. data/lib/studium/exam_topics/betriebssysteme +128 -0
  194. data/lib/studium/exam_topics/betriebswirtschaftslehre +29 -0
  195. data/lib/studium/exam_topics/bioanalytik_und_biosensoren +451 -0
  196. data/lib/studium/exam_topics/biochips +80 -0
  197. data/lib/studium/exam_topics/bioelektrochemie +57 -0
  198. data/lib/studium/exam_topics/biofilms +58 -0
  199. data/lib/studium/exam_topics/bioinformatics +523 -0
  200. data/lib/studium/exam_topics/biological_therapeutics +156 -0
  201. data/lib/studium/exam_topics/biologie +152 -0
  202. data/lib/studium/exam_topics/biomarkers +137 -0
  203. data/lib/studium/exam_topics/biomaterials +90 -0
  204. data/lib/studium/exam_topics/biomedical_studies +16 -0
  205. data/lib/studium/exam_topics/biomembranes +6 -0
  206. data/lib/studium/exam_topics/bionik +65 -0
  207. data/lib/studium/exam_topics/biophysik +34 -0
  208. data/lib/studium/exam_topics/biopolymers +10 -0
  209. data/lib/studium/exam_topics/bioprozesstechnik +149 -0
  210. data/lib/studium/exam_topics/bioressourcenmanagement +78 -0
  211. data/lib/studium/exam_topics/birds +5 -0
  212. data/lib/studium/exam_topics/bodenkunde +384 -0
  213. data/lib/studium/exam_topics/bodenmikrobiologie +40 -0
  214. data/lib/studium/exam_topics/cancerbiology +488 -0
  215. data/lib/studium/exam_topics/cell_cultures +229 -0
  216. data/lib/studium/exam_topics/cellbiology +1011 -0
  217. data/lib/studium/exam_topics/cellular_transport_and_protein_secretion +27 -0
  218. data/lib/studium/exam_topics/cellular_vesicles +11 -0
  219. data/lib/studium/exam_topics/cellulose +6 -0
  220. data/lib/studium/exam_topics/chemische_technologie_anorganischer_stoffe +210 -0
  221. data/lib/studium/exam_topics/chemische_technologie_organischer_stoffe +25 -0
  222. data/lib/studium/exam_topics/chemisches_labor +60 -0
  223. data/lib/studium/exam_topics/chemokines_and_cytokines +45 -0
  224. data/lib/studium/exam_topics/chemotaxis_quorum_sensing_and_motility_in_prokaryotes +116 -0
  225. data/lib/studium/exam_topics/citric_acid_cycle +84 -0
  226. data/lib/studium/exam_topics/clinical_microbiology +520 -0
  227. data/lib/studium/exam_topics/computer_science +309 -0
  228. data/lib/studium/exam_topics/computer_vision_and_computer_graphics +15 -0
  229. data/lib/studium/exam_topics/crispr +51 -0
  230. data/lib/studium/exam_topics/cyanobacteria +45 -0
  231. data/lib/studium/exam_topics/cytogenetics_and_chromosome_biology +598 -0
  232. data/lib/studium/exam_topics/databases_and_sql +126 -0
  233. data/lib/studium/exam_topics/dna_mutation_and_dna_repair +186 -0
  234. data/lib/studium/exam_topics/dna_replication +80 -0
  235. data/lib/studium/exam_topics/ecogenetics +26 -0
  236. data/lib/studium/exam_topics/ecological_agriculture +12 -0
  237. data/lib/studium/exam_topics/ecology +332 -0
  238. data/lib/studium/exam_topics/economy +226 -0
  239. data/lib/studium/exam_topics/electron_microscopy +7 -0
  240. data/lib/studium/exam_topics/elektronenmikroskopie +356 -0
  241. data/lib/studium/exam_topics/elektrophorese +132 -0
  242. data/lib/studium/exam_topics/elektrotechnik_und_elektrizit/303/244t +42 -0
  243. data/lib/studium/exam_topics/elisa +55 -0
  244. data/lib/studium/exam_topics/embryologie_und_entwicklung +657 -0
  245. data/lib/studium/exam_topics/endospores_and_spores +104 -0
  246. data/lib/studium/exam_topics/enzymes_and_cofactors +395 -0
  247. data/lib/studium/exam_topics/epigenetik +188 -0
  248. data/lib/studium/exam_topics/erste_hilfe +414 -0
  249. data/lib/studium/exam_topics/ethik +143 -0
  250. data/lib/studium/exam_topics/evolution_and_evolutionary_genetics +372 -0
  251. data/lib/studium/exam_topics/excel +7 -0
  252. data/lib/studium/exam_topics/fish +19 -0
  253. data/lib/studium/exam_topics/fluorescence_microscopy +10 -0
  254. data/lib/studium/exam_topics/food_microbiology_and_food_biotechnology +92 -0
  255. data/lib/studium/exam_topics/forensik +65 -0
  256. data/lib/studium/exam_topics/forstwirtschaft +53 -0
  257. data/lib/studium/exam_topics/fortgeschrittene_genetik +692 -0
  258. data/lib/studium/exam_topics/fortgeschrittene_gentechnik +221 -0
  259. data/lib/studium/exam_topics/fortgeschrittene_physik +6 -0
  260. data/lib/studium/exam_topics/fungi +119 -0
  261. data/lib/studium/exam_topics/genetische_krankheiten +209 -0
  262. data/lib/studium/exam_topics/genexpression +1008 -0
  263. data/lib/studium/exam_topics/genomics_and_metagenomics +290 -0
  264. data/lib/studium/exam_topics/gentechnik_und_praktische_biochemie +961 -0
  265. data/lib/studium/exam_topics/geochemistry +67 -0
  266. data/lib/studium/exam_topics/geography +9 -0
  267. data/lib/studium/exam_topics/geologie_und_mineralogie +624 -0
  268. data/lib/studium/exam_topics/geometrie +56 -0
  269. data/lib/studium/exam_topics/geschichte +95 -0
  270. data/lib/studium/exam_topics/gluconeogenesis +72 -0
  271. data/lib/studium/exam_topics/glycogen +45 -0
  272. data/lib/studium/exam_topics/glycolysis +118 -0
  273. data/lib/studium/exam_topics/glykomik +131 -0
  274. data/lib/studium/exam_topics/glyoxylatzyklus +31 -0
  275. data/lib/studium/exam_topics/grassland_cultivation +32 -0
  276. data/lib/studium/exam_topics/hormone +152 -0
  277. data/lib/studium/exam_topics/html +8 -0
  278. data/lib/studium/exam_topics/human_ecology +8 -0
  279. data/lib/studium/exam_topics/hygiene +224 -0
  280. data/lib/studium/exam_topics/imaging_and_microscopy +270 -0
  281. data/lib/studium/exam_topics/immunanalytik +94 -0
  282. data/lib/studium/exam_topics/immunologie +1011 -0
  283. data/lib/studium/exam_topics/informatik +117 -0
  284. data/lib/studium/exam_topics/innate_immunity +52 -0
  285. data/lib/studium/exam_topics/insekten +66 -0
  286. data/lib/studium/exam_topics/insulin_and_diabetes +57 -0
  287. data/lib/studium/exam_topics/java +624 -0
  288. data/lib/studium/exam_topics/javascript +29 -0
  289. data/lib/studium/exam_topics/klima +6 -0
  290. data/lib/studium/exam_topics/kryptographie +10 -0
  291. data/lib/studium/exam_topics/landtechnik +26 -0
  292. data/lib/studium/exam_topics/lebensmittel_und_getr/303/244nke +224 -0
  293. data/lib/studium/exam_topics/lebensmitteltechnologie +16 -0
  294. data/lib/studium/exam_topics/light_microscopy +19 -0
  295. data/lib/studium/exam_topics/linux_and_unix +36 -0
  296. data/lib/studium/exam_topics/lipids +145 -0
  297. data/lib/studium/exam_topics/macroeconomics +39 -0
  298. data/lib/studium/exam_topics/marketing +53 -0
  299. data/lib/studium/exam_topics/mathematics +311 -0
  300. data/lib/studium/exam_topics/medizin_und_biomedizinische_technik +254 -0
  301. data/lib/studium/exam_topics/medizinische_chemie_und_pharmazie +441 -0
  302. data/lib/studium/exam_topics/messtechnik_und_regeltechnik +104 -0
  303. data/lib/studium/exam_topics/metabolismus +482 -0
  304. data/lib/studium/exam_topics/meteorologie_und_atmosph/303/244re +120 -0
  305. data/lib/studium/exam_topics/microbial_ecology +37 -0
  306. data/lib/studium/exam_topics/microcontrollers +11 -0
  307. data/lib/studium/exam_topics/mikrobielle_lebensgemeinschaften +58 -0
  308. data/lib/studium/exam_topics/mikrobielle_physiologie +313 -0
  309. data/lib/studium/exam_topics/mitochondria +57 -0
  310. data/lib/studium/exam_topics/mixed +287 -0
  311. data/lib/studium/exam_topics/molecular_biology_of_plants +281 -0
  312. data/lib/studium/exam_topics/molekulare_medizin +133 -0
  313. data/lib/studium/exam_topics/nanotechnologie +456 -0
  314. data/lib/studium/exam_topics/nature_conservation_and_biodiversity +247 -0
  315. data/lib/studium/exam_topics/naturstoffe +9 -0
  316. data/lib/studium/exam_topics/netzwerke +63 -0
  317. data/lib/studium/exam_topics/neuroanatomie +25 -0
  318. data/lib/studium/exam_topics/neurobiology +356 -0
  319. data/lib/studium/exam_topics/nucleotide_sequencing +41 -0
  320. data/lib/studium/exam_topics/nutztierethologie +11 -0
  321. data/lib/studium/exam_topics/object_oriented_modeling +15 -0
  322. data/lib/studium/exam_topics/obstbau +249 -0
  323. data/lib/studium/exam_topics/organische_chemie +1007 -0
  324. data/lib/studium/exam_topics/organische_chemie_2 +137 -0
  325. data/lib/studium/exam_topics/paleobiology +39 -0
  326. data/lib/studium/exam_topics/parasitic_diseases_and_molecular_infection_biology +336 -0
  327. data/lib/studium/exam_topics/patent_law +55 -0
  328. data/lib/studium/exam_topics/pathologie +761 -0
  329. data/lib/studium/exam_topics/pcr +155 -0
  330. data/lib/studium/exam_topics/pentosephosphatweg +61 -0
  331. data/lib/studium/exam_topics/peroxisomes_glycosomes_and_lysosomes +66 -0
  332. data/lib/studium/exam_topics/pflanzenanatomie +262 -0
  333. data/lib/studium/exam_topics/pflanzenbau +24 -0
  334. data/lib/studium/exam_topics/pflanzenschutz +35 -0
  335. data/lib/studium/exam_topics/pflanzenwissenschaften +1009 -0
  336. data/lib/studium/exam_topics/pharmaceutical_biotechnology +252 -0
  337. data/lib/studium/exam_topics/physik +449 -1
  338. data/lib/studium/exam_topics/physikalische_chemie +79 -0
  339. data/lib/studium/exam_topics/physiology_and_histology +592 -0
  340. data/lib/studium/exam_topics/phytochemie +33 -0
  341. data/lib/studium/exam_topics/plant_biotechnology +132 -0
  342. data/lib/studium/exam_topics/plant_breeding +64 -0
  343. data/lib/studium/exam_topics/plant_development +50 -0
  344. data/lib/studium/exam_topics/populationsgenetik +143 -0
  345. data/lib/studium/exam_topics/posttranslationale_modifikation_von_proteinen +198 -0
  346. data/lib/studium/exam_topics/programming +41 -0
  347. data/lib/studium/exam_topics/projektmanagement +226 -0
  348. data/lib/studium/exam_topics/prokaryote_genetics +587 -0
  349. data/lib/studium/exam_topics/protein_engineering +35 -0
  350. data/lib/studium/exam_topics/proteolyse +39 -0
  351. data/lib/studium/exam_topics/proteomik +42 -0
  352. data/lib/studium/exam_topics/protozoans +24 -0
  353. data/lib/studium/exam_topics/prozesstechnik +95 -0
  354. data/lib/studium/exam_topics/psychologie +21 -0
  355. data/lib/studium/exam_topics/python +391 -0
  356. data/lib/studium/exam_topics/quality_management +266 -0
  357. data/lib/studium/exam_topics/rechtsgrundlagen +126 -0
  358. data/lib/studium/exam_topics/research_topics_in_immunobiology +42 -0
  359. data/lib/studium/exam_topics/rna_and_dna +535 -0
  360. data/lib/studium/exam_topics/rna_seq +13 -0
  361. data/lib/studium/exam_topics/robotics +12 -0
  362. data/lib/studium/exam_topics/ruby +240 -0
  363. data/lib/studium/exam_topics/ruby_on_rails +63 -0
  364. data/lib/studium/exam_topics/scientific_writing_and_publishing +38 -0
  365. data/lib/studium/exam_topics/semisynthese_von_proteinen_und_nukleotiden +120 -0
  366. data/lib/studium/exam_topics/sexualbiologie +327 -0
  367. data/lib/studium/exam_topics/signal_transduction_and_laser_systems +215 -0
  368. data/lib/studium/exam_topics/sozialbiologie +17 -0
  369. data/lib/studium/exam_topics/soziologie +5 -0
  370. data/lib/studium/exam_topics/splicing_exons_and_introns +67 -0
  371. data/lib/studium/exam_topics/sport_und_sportverletzungen +6 -0
  372. data/lib/studium/exam_topics/statistik +306 -0
  373. data/lib/studium/exam_topics/stemcells +182 -0
  374. data/lib/studium/exam_topics/stickstofffixierung +91 -0
  375. data/lib/studium/exam_topics/structural_bioinformatics +54 -0
  376. data/lib/studium/exam_topics/strukturbiologie +445 -0
  377. data/lib/studium/exam_topics/system_biology_and_synthetic_biology +108 -0
  378. data/lib/studium/exam_topics/systematische_zoologie +446 -0
  379. data/lib/studium/exam_topics/technical_ecology +144 -0
  380. data/lib/studium/exam_topics/technik +5 -0
  381. data/lib/studium/exam_topics/technische_chemie +208 -0
  382. data/lib/studium/exam_topics/technische_grundlagen_der_informatik +43 -0
  383. data/lib/studium/exam_topics/technische_mikrobiologie +393 -0
  384. data/lib/studium/exam_topics/technisches_zeichnen +5 -0
  385. data/lib/studium/exam_topics/the_bacterial_cell_wall +98 -0
  386. data/lib/studium/exam_topics/the_c_plus_plus_programming_language +531 -0
  387. data/lib/studium/exam_topics/the_c_programming_language +133 -0
  388. data/lib/studium/exam_topics/the_cellcycle +102 -0
  389. data/lib/studium/exam_topics/the_european_union +121 -0
  390. data/lib/studium/exam_topics/the_interferon_system +40 -0
  391. data/lib/studium/exam_topics/the_microbiome +164 -0
  392. data/lib/studium/exam_topics/the_universe +32 -0
  393. data/lib/studium/exam_topics/theoretische_chemie +5 -0
  394. data/lib/studium/exam_topics/theoretische_informatik +161 -0
  395. data/lib/studium/exam_topics/thermodynamics +21 -0
  396. data/lib/studium/exam_topics/tierzucht +139 -0
  397. data/lib/studium/exam_topics/toxikologie +508 -0
  398. data/lib/studium/exam_topics/transcription +188 -0
  399. data/lib/studium/exam_topics/translation_ribosomes_and_translational_control +155 -0
  400. data/lib/studium/exam_topics/umweltbiotechnologie +64 -0
  401. data/lib/studium/exam_topics/umweltchemie +233 -0
  402. data/lib/studium/exam_topics/urbanism_and_traffic +19 -0
  403. data/lib/studium/exam_topics/urea_cycle +56 -0
  404. data/lib/studium/exam_topics/vaccines_and_vaccination +253 -0
  405. data/lib/studium/exam_topics/vectors_and_gene_therapy +247 -0
  406. data/lib/studium/exam_topics/verfahrenstechnik +37 -0
  407. data/lib/studium/exam_topics/verhaltensbiologie +79 -0
  408. data/lib/studium/exam_topics/veterinary_medicine +10 -0
  409. data/lib/studium/exam_topics/vitamine +32 -0
  410. data/lib/studium/exam_topics/wasserkunde +144 -0
  411. data/lib/studium/exam_topics/weinbau +86 -0
  412. data/lib/studium/exam_topics/wissenschaft +20 -0
  413. data/lib/studium/exam_topics/yeast +104 -0
  414. data/lib/studium/exam_topics/zoologie +338 -0
  415. data/lib/studium/exams/afterburn/afterburn.rb +304 -0
  416. data/lib/studium/exams/ask_exam_from_the_upcoming_exams_pool.rb +150 -0
  417. data/lib/studium/exams/ask_exam_topic_question.rb +112 -0
  418. data/lib/studium/exams/ask_question_from_alias.rb +141 -0
  419. data/lib/studium/exams/ask_question_from_any_of_the_still_missing_lectures.rb +130 -0
  420. data/lib/studium/exams/ask_question_from_grouped_themes.rb +141 -0
  421. data/lib/studium/exams/ask_question_from_last_topic.rb +91 -0
  422. data/lib/studium/exams/ask_random_question.rb +195 -0
  423. data/lib/studium/exams/autoinclude.rb +7 -0
  424. data/lib/studium/exams/average_grade/average_grade.rb +404 -0
  425. data/lib/studium/exams/csv/create_csv_passed_exams_file.rb +217 -0
  426. data/lib/studium/exams/cycle.rb +291 -0
  427. data/lib/studium/exams/dataset/dataset.rb +126 -0
  428. data/lib/studium/exams/designate_ten_random_exam_topics/designate_ten_random_exam_topics.rb +88 -0
  429. data/lib/studium/exams/exam/exam.rb +130 -0
  430. data/lib/studium/exams/exam_bubble/exam_bubble.rb +444 -0
  431. data/lib/studium/exams/exam_bubble/menu_for_the_main_loop.rb +111 -0
  432. data/lib/studium/exams/exam_question/README.md +3 -0
  433. data/lib/studium/exams/exam_question/exam_question.rb +434 -0
  434. data/lib/studium/exams/exam_registration_at/constants.rb +49 -0
  435. data/lib/studium/exams/exam_registration_at/exam_registration_at.rb +242 -0
  436. data/lib/studium/exams/exam_registration_at/help.rb +46 -0
  437. data/lib/studium/exams/exam_registration_at/menu.rb +81 -0
  438. data/lib/studium/exams/exam_registration_at/report_and_show.rb +133 -0
  439. data/lib/studium/exams/exam_registration_at/reset.rb +54 -0
  440. data/lib/studium/exams/exam_statistics_from_this_file/exam_statistics_from_this_file.rb +119 -0
  441. data/lib/studium/exams/exam_topics.rb +194 -0
  442. data/lib/studium/exams/exams.rb +20 -0
  443. data/lib/studium/exams/exams_per_month/exams_per_month.rb +2442 -0
  444. data/lib/studium/exams/exams_this_week.rb +182 -0
  445. data/lib/studium/exams/fix_exam_dates.rb +121 -0
  446. data/lib/studium/exams/frozen.rb +36 -0
  447. data/lib/studium/exams/last_exams/last_exams.rb +479 -0
  448. data/lib/studium/exams/lectures_without_exam_entry.rb +137 -0
  449. data/lib/studium/exams/mandatory_continuous_assessment/mandatory_continuous_assessment.rb +1358 -0
  450. data/lib/studium/exams/move_all_unsolved_exam_questions_to_the_top_of_the_file.rb +173 -0
  451. data/lib/studium/exams/move_the_last_exam_question_to_the_top_of_the_file/move_the_last_exam_question_to_the_top_of_the_file.rb +111 -0
  452. data/lib/studium/exams/n_exams_in_these_topics.rb +477 -0
  453. data/lib/studium/exams/next_exam.rb +106 -0
  454. data/lib/studium/exams/next_exams.rb +378 -0
  455. data/lib/studium/exams/not_completed/README.md +5 -0
  456. data/lib/studium/exams/not_completed/not_completed.rb +143 -0
  457. data/lib/studium/exams/open_exam_associated_url/open_exam_associated_url.rb +154 -0
  458. data/lib/studium/exams/open_last_exam_question_asked_file/constants.rb +15 -0
  459. data/lib/studium/exams/open_last_exam_question_asked_file/initialize.rb +29 -0
  460. data/lib/studium/exams/open_last_exam_question_asked_file/open_last_exam_question_asked_file.rb +110 -0
  461. data/lib/studium/exams/push_solved_questions_on_top.rb +180 -0
  462. data/lib/studium/exams/question_answer/question_answer.rb +2936 -0
  463. data/lib/studium/exams/questions_solved_from_day_to_day/questions_solved_from_day_to_day.rb +379 -0
  464. data/lib/studium/exams/remote_ftp_url.rb +52 -0
  465. data/lib/studium/exams/repeat_last_question.rb +78 -0
  466. data/lib/studium/exams/report_total_amount_of_questions_and_answers_for.rb +116 -0
  467. data/lib/studium/exams/show_all_passed_exams_of_this_university.rb +252 -0
  468. data/lib/studium/exams/show_backlog_of_exams/show_backlog_of_exams.rb +114 -0
  469. data/lib/studium/exams/show_exams_for/show_exams_for.rb +172 -0
  470. data/lib/studium/exams/show_themes/constants.rb +28 -0
  471. data/lib/studium/exams/show_themes/menu.rb +61 -0
  472. data/lib/studium/exams/show_themes/misc.rb +538 -0
  473. data/lib/studium/exams/show_themes/reset.rb +62 -0
  474. data/lib/studium/exams/show_themes/show_themes.rb +27 -0
  475. data/lib/studium/exams/show_upcoming_exams/show_upcoming_exams.rb +1537 -0
  476. data/lib/studium/exams/solve_all_questions_from_this_topic.rb +114 -0
  477. data/lib/studium/exams/solved/solved.rb +434 -0
  478. data/lib/studium/exams/timetable/constants.rb +142 -0
  479. data/lib/studium/exams/timetable/timetable.rb +448 -0
  480. data/lib/studium/exams/unsolve_all_questions_from_this_topic.rb +163 -0
  481. data/lib/studium/exams/upcoming_exams/upcoming_exams.rb +555 -0
  482. data/lib/studium/exams/upcoming_exams_at_the_boku/constants.rb +23 -0
  483. data/lib/studium/exams/upcoming_exams_at_the_boku/html.rb +64 -0
  484. data/lib/studium/exams/upcoming_exams_at_the_boku/upcoming_exams_at_the_boku.rb +194 -0
  485. data/lib/studium/exams/upcoming_exams_dataset.rb +247 -0
  486. data/lib/studium/exams/upcoming_registered_exams/upcoming_registered_exams.rb +257 -0
  487. data/lib/studium/exams/upload_exam_topics.rb +360 -0
  488. data/lib/studium/graphviz/README.md +4 -0
  489. data/lib/studium/graphviz/bachelor_vector_based_strategies.dot +160 -0
  490. data/lib/studium/graphviz/master_vector_based_strategies.dot +46 -0
  491. data/lib/studium/gui/gtk3/control_panel/control_panel.rb +40 -0
  492. data/lib/studium/gui/gtk3/lecture_information/lecture_information.rb +191 -0
  493. data/lib/studium/gui/java/exam_question/ExamQuestion$1.class +0 -0
  494. data/lib/studium/gui/java/exam_question/ExamQuestion.class +0 -0
  495. data/lib/studium/gui/java/exam_question/ExamQuestion.java +215 -0
  496. data/lib/studium/gui/javafx/exam_question_widget/exam_question_widget.rb +58 -0
  497. data/lib/studium/gui/jruby/exam_trainer/exam_trainer.rb +637 -0
  498. data/lib/studium/gui/jruby/show_upcoming_exams/show_upcoming_exams.rb +85 -0
  499. data/lib/studium/gui/libui/ask_exam_question/ask_exam_question.rb +347 -0
  500. data/lib/studium/gui/shared_code/control_panel/control_panel_module.rb +305 -0
  501. data/lib/studium/gui/shared_code/exam_trainer/exam_trainer_widget_module.rb +0 -0
  502. data/lib/studium/gui/shared_code/information_about_a_lecture/information_about_a_lecture_module.rb +0 -0
  503. data/lib/studium/gui/shared_code/show_upcoming_exams/show_upcoming_exams_module.rb +129 -0
  504. data/lib/studium/gui/universal_widgets/curriculum_viewer/curriculum_viewer.rb +549 -0
  505. data/lib/studium/gui/universal_widgets/ects_per_university/ects_per_university.rb +302 -0
  506. data/lib/studium/gui/universal_widgets/exam_trainer/exam_trainer.config +6 -0
  507. data/lib/studium/gui/universal_widgets/exam_trainer/exam_trainer.rb +3266 -0
  508. data/lib/studium/gui/universal_widgets/exam_trainer/manifest.yml +12 -0
  509. data/lib/studium/gui/universal_widgets/expand_time_range/expand_time_range.rb +309 -0
  510. data/lib/studium/gui/universal_widgets/information_about_a_lecture/information_about_a_lecture.rb +242 -0
  511. data/lib/studium/gui/universal_widgets/show_upcoming_exams/show_upcoming_exams.rb +252 -0
  512. data/lib/studium/images/libui_ask_exam_question.png +0 -0
  513. data/lib/studium/images/outdated.png +0 -0
  514. data/lib/studium/images/small_logos/DNA.png +0 -0
  515. data/lib/studium/images/small_logos/README.md +2 -0
  516. data/lib/studium/images/small_logos/solved.png +0 -0
  517. data/lib/studium/images/studies_favicon.png +0 -0
  518. data/lib/studium/java/README.md +5 -0
  519. data/lib/studium/java/studium/AskExamQuestion.java +461 -0
  520. data/lib/studium/java/studium/Base.java +123 -0
  521. data/lib/studium/java/studium/Constants.java +122 -0
  522. data/lib/studium/java/studium/EnsureThatTheLogDirectoryExists.java +57 -0
  523. data/lib/studium/java/studium/Mkdir.java +13 -0
  524. data/lib/studium/java/studium/OpenLastExamQuestionurlLinkViaTheBrowser.java +90 -0
  525. data/lib/studium/java/studium/ReturnNQuestionsSolvedInTotal.java +69 -0
  526. data/lib/studium/java/studium/Solved.java +112 -0
  527. data/lib/studium/java/studium/Test.java +60 -0
  528. data/lib/studium/java/studium/studium/AskExamQuestion.class +0 -0
  529. data/lib/studium/java/studium/studium/Base.class +0 -0
  530. data/lib/studium/java/studium/studium/Constants.class +0 -0
  531. data/lib/studium/java/studium/studium/EnsureThatTheLogDirectoryExists.class +0 -0
  532. data/lib/studium/java/studium/studium/Mkdir.class +0 -0
  533. data/lib/studium/java/studium/studium/OpenLastExamQuestionurlLinkViaTheBrowser.class +0 -0
  534. data/lib/studium/java/studium/studium/ReturnNQuestionsSolvedInTotal.class +0 -0
  535. data/lib/studium/java/studium/studium/Solved.class +0 -0
  536. data/lib/studium/java/studium/studium/Test.class +0 -0
  537. data/lib/studium/jobs/jobs.rb +80 -0
  538. data/lib/studium/logging/README.md +2 -0
  539. data/lib/studium/logging/ensure_that_the_log_directory_exists.rb +58 -0
  540. data/lib/studium/logging/html_log_directory.rb +42 -0
  541. data/lib/studium/logging/log_directory.rb +112 -0
  542. data/lib/studium/logging/store_last_question_asked_into_file.rb +138 -0
  543. data/lib/studium/parsers/README.md +2 -0
  544. data/lib/studium/parsers/custom_exam_results_parser.rb +209 -0
  545. data/lib/studium/parsers/parse_remote_lecture.rb +331 -0
  546. data/lib/studium/project/project.rb +88 -0
  547. data/lib/studium/requires/common_popular_requires.rb +37 -0
  548. data/lib/studium/requires/commonly_used_requires.rb +14 -0
  549. data/lib/studium/requires/require_class_exams_solved.rb +7 -0
  550. data/lib/studium/requires/require_ects_scripts.rb +27 -0
  551. data/lib/studium/requires/require_encoding.rb +7 -0
  552. data/lib/studium/requires/require_the_check_and_sanitize_files.rb +31 -0
  553. data/lib/studium/requires/require_the_curricula_files.rb +28 -0
  554. data/lib/studium/requires/require_the_exam_question_class.rb +7 -0
  555. data/lib/studium/requires/require_the_exams_files.rb +46 -0
  556. data/lib/studium/requires/require_the_logging_files.rb +23 -0
  557. data/lib/studium/requires/require_the_parsers.rb +28 -0
  558. data/lib/studium/requires/require_the_studium_constants.rb +7 -0
  559. data/lib/studium/requires/require_the_studium_project.rb +72 -0
  560. data/lib/studium/requires/require_the_toplevel_methods.rb +27 -0
  561. data/lib/studium/requires/require_the_utility_scripts.rb +34 -0
  562. data/lib/studium/requires/require_upcoming_exams.rb +7 -0
  563. data/lib/studium/requires/require_yaml.rb +7 -0
  564. data/lib/studium/requires/return_remote_homepage_of_this_lecture.rb +7 -0
  565. data/lib/studium/requires/with_GUI.rb +13 -0
  566. data/lib/studium/requires/www_mode.rb +17 -0
  567. data/lib/studium/statistics/README.md +4 -0
  568. data/lib/studium/statistics/best_exam_months.rb +92 -0
  569. data/lib/studium/statistics/curriculum_comparer/curriculum_comparer.rb +423 -0
  570. data/lib/studium/statistics/determine_exam_statistics_from_this_file.rb +142 -0
  571. data/lib/studium/statistics/exam_topics_that_are_about_to_be_completed.rb +117 -0
  572. data/lib/studium/statistics/max_stats.rb +169 -0
  573. data/lib/studium/statistics/new_questions_per_year.rb +147 -0
  574. data/lib/studium/statistics/report_how_many_ects_points_per_curriculum_were_completed.rb +167 -0
  575. data/lib/studium/statistics/report_how_many_exam_questions_were_answered.rb +473 -0
  576. data/lib/studium/statistics/show_exam_statistics.rb +75 -0
  577. data/lib/studium/statistics/show_which_courses_are_in_a_bachelor_or_master_curriculum_respectively.rb +104 -0
  578. data/lib/studium/statistics/top_stats.rb +126 -0
  579. data/lib/studium/toplevel_methods/e_and_esystem.rb +34 -0
  580. data/lib/studium/toplevel_methods/find_exam_topic_and_exam_title.rb +3986 -0
  581. data/lib/studium/toplevel_methods/install_the_project_on_the_given_hostsystem.rb +31 -0
  582. data/lib/studium/toplevel_methods/return_remote_homepage_of_this_lecture.rb +11611 -0
  583. data/lib/studium/toplevel_methods/return_remote_moodle_link_of_this_lecture.rb +2405 -0
  584. data/lib/studium/toplevel_methods/roebe.rb +16 -0
  585. data/lib/studium/toplevel_methods/runmode.rb +45 -0
  586. data/lib/studium/toplevel_methods/toplevel_methods.rb +7295 -0
  587. data/lib/studium/universities_in_austria/README.md +2 -0
  588. data/lib/studium/universities_in_austria/boku/README.md +4 -0
  589. data/lib/studium/universities_in_austria/boku/boku_/303/266ffnungszeiten.rb +28 -0
  590. data/lib/studium/universities_in_austria/boku/show_three_pillars_of_these_lectures.rb +110 -0
  591. data/lib/studium/universities_in_austria/boku/three_pillars.rb +237 -0
  592. data/lib/studium/universities_in_austria/tu_vienna/README.md +6 -0
  593. data/lib/studium/universities_in_austria/tu_vienna/tu_ferien.rb +42 -0
  594. data/lib/studium/universities_in_austria/tu_vienna/tu_/303/266ffnungszeiten.rb +34 -0
  595. data/lib/studium/university_course/university_course.rb +409 -0
  596. data/lib/studium/utility_scripts/attribute_lectures_to_university/attribute_lectures_to_university.rb +375 -0
  597. data/lib/studium/utility_scripts/audio_stats.rb +171 -0
  598. data/lib/studium/utility_scripts/auto_stud/auto_stud.rb +252 -0
  599. data/lib/studium/utility_scripts/auto_stud/constants.rb +18 -0
  600. data/lib/studium/utility_scripts/auto_stud/initialize.rb +23 -0
  601. data/lib/studium/utility_scripts/auto_stud/misc.rb +18 -0
  602. data/lib/studium/utility_scripts/autogeneration/autogeneration.rb +158 -0
  603. data/lib/studium/utility_scripts/autopurge_this_lecture_date.rb +100 -0
  604. data/lib/studium/utility_scripts/average_grade_of_this_curriculum.rb +153 -0
  605. data/lib/studium/utility_scripts/blocked_courses.rb +146 -0
  606. data/lib/studium/utility_scripts/calendar/README.md +2 -0
  607. data/lib/studium/utility_scripts/calendar/calendar.rb +251 -0
  608. data/lib/studium/utility_scripts/calendar/misc.rb +35 -0
  609. data/lib/studium/utility_scripts/check_description_of_these_lectures.rb +221 -0
  610. data/lib/studium/utility_scripts/course_registrations/course_registrations.rb +98 -0
  611. data/lib/studium/utility_scripts/courses/courses.rb +177 -0
  612. data/lib/studium/utility_scripts/create/README.md +2 -0
  613. data/lib/studium/utility_scripts/create/webpage_of_university.rb +129 -0
  614. data/lib/studium/utility_scripts/create/webpage_of_university_BOKU.rb +61 -0
  615. data/lib/studium/utility_scripts/create/webpage_of_university_TU.rb +60 -0
  616. data/lib/studium/utility_scripts/create/webpage_of_university_UniWien.rb +60 -0
  617. data/lib/studium/utility_scripts/create_database/create_database.rb +126 -0
  618. data/lib/studium/utility_scripts/current_lectures_belonging_to_both_bachelor_and_master_curriculum.rb +113 -0
  619. data/lib/studium/utility_scripts/currently_participating_in_these_lectures/currently_participating_in_these_lectures.rb +104 -0
  620. data/lib/studium/utility_scripts/display_lecture_url/display_lecture_url.rb +176 -0
  621. data/lib/studium/utility_scripts/expand_time_range/expand_time_range.rb +521 -0
  622. data/lib/studium/utility_scripts/finished_exams_at_this_university/finished_exams_at_this_university.rb +171 -0
  623. data/lib/studium/utility_scripts/foreign_language_percentage/constants.rb +23 -0
  624. data/lib/studium/utility_scripts/foreign_language_percentage/foreign_language_percentage.rb +149 -0
  625. data/lib/studium/utility_scripts/foreign_language_percentage/help.rb +31 -0
  626. data/lib/studium/utility_scripts/foreign_language_percentage/initialize.rb +25 -0
  627. data/lib/studium/utility_scripts/foreign_language_percentage/menu.rb +158 -0
  628. data/lib/studium/utility_scripts/foreign_language_percentage/report.rb +62 -0
  629. data/lib/studium/utility_scripts/foreign_language_percentage/reset.rb +50 -0
  630. data/lib/studium/utility_scripts/foreign_language_percentage/run.rb +19 -0
  631. data/lib/studium/utility_scripts/generate_spreadsheet/generate_spreadsheet.rb +353 -0
  632. data/lib/studium/utility_scripts/generate_spreadsheet/misc.rb +144 -0
  633. data/lib/studium/utility_scripts/holidays/holidays.rb +154 -0
  634. data/lib/studium/utility_scripts/homepage_of_these_courses/homepage_of_these_courses.rb +125 -0
  635. data/lib/studium/utility_scripts/lectures_attributed_to_universities/lectures_attributed_to_universities.rb +336 -0
  636. data/lib/studium/utility_scripts/lva_dates_of_the_important_courses.rb +111 -0
  637. data/lib/studium/utility_scripts/lva_nummer/lva_nummer.rb +427 -0
  638. data/lib/studium/utility_scripts/mandatory_lectures_in_this_month/mandatory_lectures_in_this_month.rb +316 -0
  639. data/lib/studium/utility_scripts/moodle/moodle.rb +214 -0
  640. data/lib/studium/utility_scripts/name_of_this_lva_id/name_of_this_lva_id.rb +110 -0
  641. data/lib/studium/utility_scripts/new_stud.rb +324 -0
  642. data/lib/studium/utility_scripts/next_week/next_week.rb +103 -0
  643. data/lib/studium/utility_scripts/not_yet_registered/not_yet_registered.rb +120 -0
  644. data/lib/studium/utility_scripts/open_last_exam_question_url_link_via_the_browser.rb +76 -0
  645. data/lib/studium/utility_scripts/passed_ects_per_year/passed_ects_per_year.rb +313 -0
  646. data/lib/studium/utility_scripts/passed_pr/303/274fungsimmanente_courses/passed_pr/303/274fungsimmanente_courses.rb +181 -0
  647. data/lib/studium/utility_scripts/pdf/README.md +2 -0
  648. data/lib/studium/utility_scripts/pdf/create_pdf_file_for_this_exam_topic.rb +352 -0
  649. data/lib/studium/utility_scripts/pdf/hexapdf_support.rb +50 -0
  650. data/lib/studium/utility_scripts/preparatory_meetings/preparatory_meetings.rb +317 -0
  651. data/lib/studium/utility_scripts/priority/priority.rb +164 -0
  652. data/lib/studium/utility_scripts/priority_points/priority_points.rb +261 -0
  653. data/lib/studium/utility_scripts/publish_my_exams/publish_my_exams.rb +174 -0
  654. data/lib/studium/utility_scripts/regexes/README.md +1 -0
  655. data/lib/studium/utility_scripts/regexes/generate_regex.rb +314 -0
  656. data/lib/studium/utility_scripts/regexes/generate_regexes_for_the_available_moodle_links.rb +55 -0
  657. data/lib/studium/utility_scripts/regexes/generate_regexes_for_the_registered_lectures.rb +48 -0
  658. data/lib/studium/utility_scripts/report_outdated_timetable_entries/report_outdated_timetable_entries.rb +142 -0
  659. data/lib/studium/utility_scripts/report_whether_this_lecture_is_registered_in_the_file_lecture_information/report_whether_this_lecture_is_registered_in_the_file_lecture_information.rb +129 -0
  660. data/lib/studium/utility_scripts/resolve_practical_courses_date_conflicts/individual_resolve_practical_courses_date_conflicts.rb +254 -0
  661. data/lib/studium/utility_scripts/resolve_practical_courses_date_conflicts/resolve_practical_courses_date_conflicts.rb +265 -0
  662. data/lib/studium/utility_scripts/scrape_remote_university_url.rb +138 -0
  663. data/lib/studium/utility_scripts/semester_schedule_creator/semester_container.rb +144 -0
  664. data/lib/studium/utility_scripts/semester_schedule_creator/semester_schedule_creator.rb +373 -0
  665. data/lib/studium/utility_scripts/semesterplaner/semesterplaner.rb +311 -0
  666. data/lib/studium/utility_scripts/set_aliases_based_on_this_file.rb +96 -0
  667. data/lib/studium/utility_scripts/show_all_passed_master_lectures/show_all_passed_master_lectures.rb +126 -0
  668. data/lib/studium/utility_scripts/show_conflicting_lva_lectures/show_conflicting_lva_lectures.rb +1385 -0
  669. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/constants.rb +23 -0
  670. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/menu.rb +63 -0
  671. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/reset.rb +33 -0
  672. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/run.rb +50 -0
  673. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/show_descriptions_of_lectures_belonging_to_this_module.rb +145 -0
  674. data/lib/studium/utility_scripts/show_lecturers/show_lecturers.rb +147 -0
  675. data/lib/studium/utility_scripts/show_lectures/show_lectures.rb +906 -0
  676. data/lib/studium/utility_scripts/show_lectures_fitting_to_this_language/show_lectures_fitting_to_this_language.rb +121 -0
  677. data/lib/studium/utility_scripts/show_lectures_fitting_to_this_theme/show_lectures_fitting_to_this_theme.rb +105 -0
  678. data/lib/studium/utility_scripts/show_lectures_on_the_commandline/show_lectures_on_the_commandline.rb +3160 -0
  679. data/lib/studium/utility_scripts/show_lectures_on_this_day/show_lectures_on_this_day.rb +150 -0
  680. data/lib/studium/utility_scripts/show_lva_dates_of_this_lecture/show_lva_dates_of_this_lecture.rb +182 -0
  681. data/lib/studium/utility_scripts/show_mixed_bachelor_master_courses/show_mixed_bachelor_master_courses.rb +92 -0
  682. data/lib/studium/utility_scripts/show_outdated_lva_dates/show_outdated_lva_dates.rb +214 -0
  683. data/lib/studium/utility_scripts/show_passed_exams_having_this_grade/show_passed_exams_having_this_grade.rb +91 -0
  684. data/lib/studium/utility_scripts/show_solved_english_lectures/show_solved_english_lectures.rb +139 -0
  685. data/lib/studium/utility_scripts/steop/README.md +4 -0
  686. data/lib/studium/utility_scripts/steop/show_all_steop_lectures.rb +93 -0
  687. data/lib/studium/utility_scripts/steop/steop_lectures_in_this_curriculum.rb +284 -0
  688. data/lib/studium/utility_scripts/steop/steop_lva_dates.rb +119 -0
  689. data/lib/studium/utility_scripts/studienkennzahl/studienkennzahl.rb +116 -0
  690. data/lib/studium/utility_scripts/studium_skeleton/studium_skeleton.rb +241 -0
  691. data/lib/studium/utility_scripts/stundenplan.rb +600 -0
  692. data/lib/studium/utility_scripts/sync_studium_relevant_entries_one_level_downwards.rb +217 -0
  693. data/lib/studium/utility_scripts/ufind/ufind.rb +106 -0
  694. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/constants.rb +26 -0
  695. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/run.rb +20 -0
  696. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/upcoming_mandatory_presence_courses.rb +187 -0
  697. data/lib/studium/utility_scripts/video_lecture_downloader/video_lecture_downloader.rb +107 -0
  698. data/lib/studium/utility_scripts/week_parser/constants.rb +23 -0
  699. data/lib/studium/utility_scripts/week_parser/help.rb +32 -0
  700. data/lib/studium/utility_scripts/week_parser/menu.rb +59 -0
  701. data/lib/studium/utility_scripts/week_parser/misc.rb +373 -0
  702. data/lib/studium/utility_scripts/week_parser/reset.rb +65 -0
  703. data/lib/studium/utility_scripts/week_parser/run.rb +18 -0
  704. data/lib/studium/utility_scripts/week_parser/show.rb +236 -0
  705. data/lib/studium/utility_scripts/week_parser/week_parser.rb +49 -0
  706. data/lib/studium/utility_scripts/weekday_parser.rb +155 -0
  707. data/lib/studium/utility_scripts/weekly_schedule.rb +198 -0
  708. data/lib/studium/utility_scripts/wochenplanung/wochenplanung.rb +267 -0
  709. data/lib/studium/version/version.rb +46 -0
  710. data/lib/studium/www/exams/exams.cgi +54 -0
  711. data/lib/studium/www/fast_ask_exam_question/fast_ask_exam_question.cgi +156 -0
  712. data/lib/studium/www/handle_curricula/handle_curricula.cgi +154 -0
  713. data/lib/studium/www/next_generation_exam_question_trainer/next_generation_exam_question_trainer.cgi +112 -0
  714. data/lib/studium/www/next_generation_exam_question_trainer/solved.cgi +26 -0
  715. data/lib/studium/www/sinatra/app.rb +231 -0
  716. data/lib/studium/www/sinatra/curriculum_displayer/curriculum_displayer.rb +162 -0
  717. data/lib/studium/www/sinatra/misc.rb +115 -0
  718. data/lib/studium/www/statistics/statistics.cgi +82 -0
  719. data/lib/studium/www/upcoming_exams/upcoming_exams.cgi +36 -0
  720. data/lib/studium/yaml/ad_hoc_trainer/README.md +2 -0
  721. data/lib/studium/yaml/ad_hoc_trainer/exam_topics.md +22 -0
  722. data/lib/studium/yaml/allowed_themes_for_courses/allowed_themes_for_courses.yml +348 -0
  723. data/lib/studium/yaml/array_allowed_entries_for_the_file_lecture_information/array_allowed_entries_for_the_file_lecture_information.yml +71 -0
  724. data/lib/studium/yaml/available_exam_topics/available_exam_topics.yml +234 -0
  725. data/lib/studium/yaml/backlog_of_exams.yml +37 -0
  726. data/lib/studium/yaml/colours/custom_colours.yml +50 -0
  727. data/lib/studium/yaml/colours/use_colours.yml +1 -0
  728. data/lib/studium/yaml/current_exams.yml +30 -0
  729. data/lib/studium/yaml/curricula/README.md +39 -0
  730. data/lib/studium/yaml/curricula/bachelor/bachelor_agrarwissenschaften_033255.yml +147 -0
  731. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_basisblock_033630.yml +71 -0
  732. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_botanik_033630.yml +100 -0
  733. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_ecology_033630.yml +74 -0
  734. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_mikrobiologie_und_genetik_033630.yml +122 -0
  735. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_molekulare_biologie_033630.yml +106 -0
  736. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_zoologie_033630.yml +87 -0
  737. data/lib/studium/yaml/curricula/bachelor/bachelor_chemie_033662.yml +165 -0
  738. data/lib/studium/yaml/curricula/bachelor/bachelor_dummy_curriculum.yml +182 -0
  739. data/lib/studium/yaml/curricula/bachelor/bachelor_elektrotechnik_und_informationstechnik_033235.yml +13 -0
  740. data/lib/studium/yaml/curricula/bachelor/bachelor_forstwirtschaft_033225.yml +115 -0
  741. data/lib/studium/yaml/curricula/bachelor/bachelor_informatik_033521.yml +134 -0
  742. data/lib/studium/yaml/curricula/bachelor/bachelor_ktww_033231.yml +84 -0
  743. data/lib/studium/yaml/curricula/bachelor/bachelor_lmbt_033217.yml +121 -0
  744. data/lib/studium/yaml/curricula/bachelor/bachelor_medizinische_informatik_033533.yml +283 -0
  745. data/lib/studium/yaml/curricula/bachelor/bachelor_molekularbiologie_033665.yml +95 -0
  746. data/lib/studium/yaml/curricula/bachelor/bachelor_nutrition_science_033638.yml +119 -0
  747. data/lib/studium/yaml/curricula/bachelor/bachelor_pharmazie_033305.yml +170 -0
  748. data/lib/studium/yaml/curricula/bachelor/bachelor_technische_chemie_033290.yml +131 -0
  749. data/lib/studium/yaml/curricula/bachelor/bachelor_technische_informatik_033535.yml +23 -0
  750. data/lib/studium/yaml/curricula/bachelor/bachelor_ubrm_033227.yml +142 -0
  751. data/lib/studium/yaml/curricula/bachelor/bachelor_verfahrenstechnik_033273.yml +167 -0
  752. data/lib/studium/yaml/curricula/bachelor/bachelor_wirtschaftsinformatik_033526.yml +29 -0
  753. data/lib/studium/yaml/curricula/experimental/bachelor_informatik_in_den_lebenswissenschaften.yml +137 -0
  754. data/lib/studium/yaml/curricula/individual/bachelor_formale_logik.yml +88 -0
  755. data/lib/studium/yaml/curricula/individual/bachelor_informatik_und_molekulare_biologie.yml +1161 -0
  756. data/lib/studium/yaml/curricula/individual/bachelor_vector_based_strategies_in_life_sciences_molecular_medicine_and_biotechnology.yml +1157 -0
  757. data/lib/studium/yaml/curricula/individual/master_bioinformatics_and_nanobiotechnology_in_molecular_medicine.yml +306 -0
  758. data/lib/studium/yaml/curricula/individual/master_vector_based_strategies_in_life_sciences_molecular_medicine_and_biotechnology.yml +741 -0
  759. data/lib/studium/yaml/curricula/master/master_bioinformatik_066875.yml +75 -0
  760. data/lib/studium/yaml/curricula/master/master_biologie_molekulare_mikrobiologie_mikrobielle_oekologie_und_immunbiologie_066830.yml +78 -0
  761. data/lib/studium/yaml/curricula/master/master_biologische_chemie_066863.yml +66 -0
  762. data/lib/studium/yaml/curricula/master/master_dummy_curriculum.yml +197 -0
  763. data/lib/studium/yaml/curricula/master/master_genetik_und_entwicklungsbiologie_066877.yml +89 -0
  764. data/lib/studium/yaml/curricula/master/master_lmbt_066418.yml +112 -0
  765. data/lib/studium/yaml/curricula/master/master_molecular_biology_066865.yml +72 -0
  766. data/lib/studium/yaml/curricula/master/master_molekulare_biologie_066834.yml +151 -0
  767. data/lib/studium/yaml/curricula/master/master_pharmazie_066605.yml +176 -0
  768. data/lib/studium/yaml/curricula/master/master_technische_chemie_066490.yml +123 -0
  769. data/lib/studium/yaml/curricula/outdated/master_bioinformatics_and_molecular_biotechnology_including_aspects_from_molecular_medicine.yml +438 -0
  770. data/lib/studium/yaml/curricula/outdated/master_food_science_and_plant_biotechnology.yml +31 -0
  771. data/lib/studium/yaml/curricula.yml +562 -0
  772. data/lib/studium/yaml/daily_questions_solved/daily_questions_solved.yml +2019 -0
  773. data/lib/studium/yaml/daily_questions_solved/daily_questions_solved.yml~ +1983 -0
  774. data/lib/studium/yaml/default_delay.yml +4 -0
  775. data/lib/studium/yaml/default_encoding.yml +1 -0
  776. data/lib/studium/yaml/directory_to_the_exam_topics.yml +0 -0
  777. data/lib/studium/yaml/editor.yml +1 -0
  778. data/lib/studium/yaml/exams/next_exams_to_do.md +9 -0
  779. data/lib/studium/yaml/file_for_exam_questions.yml +1 -0
  780. data/lib/studium/yaml/german/README.md +2 -0
  781. data/lib/studium/yaml/german/german_to_english_month_names.yml +16 -0
  782. data/lib/studium/yaml/grouped_themes/grouped_themes.yml +264 -0
  783. data/lib/studium/yaml/holidays/holidays.yml +201 -0
  784. data/lib/studium/yaml/important_exams.yml +286 -0
  785. data/lib/studium/yaml/inscription_dates_of_universities.yml +60 -0
  786. data/lib/studium/yaml/lecture_aliases.yml +138 -0
  787. data/lib/studium/yaml/lecture_information/lecture_information.yml +66145 -0
  788. data/lib/studium/yaml/log_dir.yml +1 -0
  789. data/lib/studium/yaml/main_topic/main_topic.yml +11 -0
  790. data/lib/studium/yaml/max_stats/max_stats.yml +262 -0
  791. data/lib/studium/yaml/max_stats.yml +263 -0
  792. data/lib/studium/yaml/meta_themes +1 -0
  793. data/lib/studium/yaml/mitbelegung/README.md +4 -0
  794. data/lib/studium/yaml/mitbelegung/mitbelegung.yml +21 -0
  795. data/lib/studium/yaml/mitteilungsbl/303/244tter/mitteilungsbl/303/244tter.yml +363 -0
  796. data/lib/studium/yaml/n_total_questions.yml +1 -0
  797. data/lib/studium/yaml/rename_konsole_tab.yml +1 -0
  798. data/lib/studium/yaml/roebe/ad_hoc_exam_topics.md +19 -0
  799. data/lib/studium/yaml/roebe/sommersemester_2024_opportunities.md +441 -0
  800. data/lib/studium/yaml/semester_planner/README.md +4 -0
  801. data/lib/studium/yaml/semester_planner/semester_planner.yml +189 -0
  802. data/lib/studium/yaml/show_topic.yml +1 -0
  803. data/lib/studium/yaml/statistics/lecture_information.yml +1 -0
  804. data/lib/studium/yaml/statistics/max_stats.yml +239 -0
  805. data/lib/studium/yaml/statistics/statistics.yml +77 -0
  806. data/lib/studium/yaml/week/01_monday.yml +25 -0
  807. data/lib/studium/yaml/week/02_tuesday.yml +68 -0
  808. data/lib/studium/yaml/week/03_wednesday.yml +63 -0
  809. data/lib/studium/yaml/week/04_thursday.yml +20 -0
  810. data/lib/studium/yaml/week/05_friday.yml +31 -0
  811. data/lib/studium/yaml/week/06_saturday.yml +16 -0
  812. data/lib/studium/yaml/week/07_sunday.yml +0 -0
  813. data/lib/studium/yaml/week/README.md +10 -0
  814. data/lib/studium.rb +5 -0
  815. data/studium.gemspec +82 -0
  816. data/test/testing_colourized_question_and_answer.rb +18 -0
  817. data/test/testing_studium.rb +244 -0
  818. data/test/testing_studium_base_class.rb +31 -0
  819. data/test/testing_the_file_lecture_information.rb +18 -0
  820. data/test/testing_time_component.rb +29 -0
  821. metadata +1042 -0
@@ -0,0 +1,3554 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # === Studium::Base
6
+ #
7
+ # This is the base class for other classes that are part of the Studium
8
+ # namespace.
9
+ #
10
+ # Not every class needs it though, so it is recommended to only make use
11
+ # of it if you need some "commonly shared functionality". Since as of
12
+ # November 2023, if we need more shared functionality, we'll simply
13
+ # use a dedicated module instead.
14
+ #
15
+ # Classes that belong to the Studium::Exams namespace should subclass
16
+ # from this class here as well.
17
+ #
18
+ # exit_program() was added into this file, during the changes in
19
+ # October 2020.
20
+ #
21
+ # In the past some code was stored in prototype.rb, but this was a bit
22
+ # confusing, so I decided to remove prototype.rb - if shared functionality
23
+ # is still needed we'll be using a module.
24
+ # =========================================================================== #
25
+ # To require this base class, do:
26
+ #
27
+ # require 'studium/base/base.rb'
28
+ #
29
+ # Then, to subclass from it, do:
30
+ #
31
+ # < Studium::Base
32
+ #
33
+ # In a shorter variant combining the two lines above, do this:
34
+ #
35
+ # require 'studium/base/base.rb'; < ::Studium::Base
36
+ #
37
+ # =========================================================================== #
38
+ module Studium
39
+
40
+ class Base # === Studium::Base
41
+
42
+ begin
43
+ require 'opn'
44
+ rescue LoadError; end
45
+
46
+ begin
47
+ require 'roebe/requires/require_kde_konsole.rb'
48
+ rescue LoadError; end
49
+
50
+ begin
51
+ require 'open/in_browser/in_browser.rb'
52
+ rescue LoadError; end
53
+
54
+ require 'studium/requires/require_yaml.rb' # Always have yaml available.
55
+ require 'studium/requires/require_the_studium_constants.rb' # Pull in the constants.
56
+ # ========================================================================= #
57
+ # We must support different encodings, so pull in the important files next.
58
+ # ========================================================================= #
59
+ require 'studium/requires/require_encoding.rb'
60
+
61
+ require 'studium/colours/colours.rb'
62
+ include ::Studium::Colours # Pulled in from the above .rb file.
63
+
64
+ require 'studium/base/html_colours_module.rb'
65
+ include ::Studium::HtmlColoursModule
66
+
67
+ require 'studium/base/commandline_arguments_module/commandline_arguments_module.rb'
68
+ include Studium::CommandlineArgumentsModule
69
+
70
+ require 'studium/base/runmode_module/runmode_module.rb'
71
+ include Studium::RunmodeModule
72
+
73
+ require 'studium/logging/html_log_directory.rb'
74
+ require 'studium/logging/log_directory.rb'
75
+
76
+ # ========================================================================= #
77
+ # Add the necessary (and important) toplevel_methods next:
78
+ # ========================================================================= #
79
+ require 'studium/toplevel_methods/e_and_esystem.rb'
80
+ require 'studium/toplevel_methods/toplevel_methods.rb'
81
+ require 'studium/toplevel_methods/find_exam_topic_and_exam_title.rb'
82
+ require 'studium/toplevel_methods/install_the_project_on_the_given_hostsystem.rb'
83
+ require 'studium/toplevel_methods/return_remote_homepage_of_this_lecture.rb'
84
+ require 'studium/toplevel_methods/return_remote_moodle_link_of_this_lecture.rb'
85
+
86
+ # ========================================================================= #
87
+ # === Studium::Base::NAMESPACE
88
+ # ========================================================================= #
89
+ NAMESPACE = inspect
90
+
91
+ # ========================================================================= #
92
+ # === Studium::Base::N_CHARACTERS_PER_LINE
93
+ #
94
+ # If an answer exceeds the following threshold value, then we will chop
95
+ # some bits off of it. The reason why we have defined this here in
96
+ # class Base is because at the least two other classes that are
97
+ # part of the Exam namespace, require this.
98
+ # ========================================================================= #
99
+ N_CHARACTERS_PER_LINE = 78
100
+
101
+ # ========================================================================= #
102
+ # === Studium::Base::LEFT_PADDING
103
+ #
104
+ # The default padding (for showing the answer to an exam question) is
105
+ # 4 spaces since as of July 2020. In November 2020 2 spaces are now
106
+ # tried.
107
+ # ========================================================================= #
108
+ LEFT_PADDING = ' ' * 2 # 2 spaces for now.
109
+
110
+ # ========================================================================= #
111
+ # === Studium::Base::COMMON_YEAR_DAYS_IN_MONTH
112
+ #
113
+ # This constant has the days per month, for the whole year.
114
+ #
115
+ # It will not honour leap years properly, though.
116
+ # ========================================================================= #
117
+ COMMON_YEAR_DAYS_IN_MONTH = [
118
+ nil,
119
+ 31,
120
+ 28,
121
+ 31,
122
+ 30,
123
+ 31,
124
+ 30,
125
+ 31,
126
+ 31,
127
+ 30,
128
+ 31,
129
+ 30,
130
+ 31
131
+ ]
132
+
133
+ # ========================================================================= #
134
+ # === reset (reset tag)
135
+ # ========================================================================= #
136
+ def reset
137
+ initialize_the_internal_hash # This should come first here.
138
+ # ======================================================================= #
139
+ # === :namespace
140
+ # ======================================================================= #
141
+ @internal_hash[:namespace] = NAMESPACE
142
+ # ======================================================================= #
143
+ # === :use_colours
144
+ #
145
+ # The next variable determines whether instances of this class will
146
+ # make use of colours. By default the value from a toplevel-variable
147
+ # will be used as default start value. Thus, initially, they have
148
+ # the same value.
149
+ # ======================================================================= #
150
+ @internal_hash[:use_colours] = ::Studium.use_colours?
151
+ # ======================================================================= #
152
+ # === :be_verbose
153
+ # ======================================================================= #
154
+ @internal_hash[:be_verbose] = true
155
+ # ======================================================================= #
156
+ # === :use_opn
157
+ #
158
+ # By default we will use opn in the project. The name "opn" stands
159
+ # short for "output program name".
160
+ # ======================================================================= #
161
+ @internal_hash[:use_opn] = true
162
+ # ======================================================================= #
163
+ # === @debug
164
+ #
165
+ # The next variable determines whether we will debug or whether we
166
+ # will not. If @debug is set to true, then we won't make modifications -
167
+ # instead, we will give debug information to the user.
168
+ # ======================================================================= #
169
+ @internal_hash[:debug] = false
170
+ # ======================================================================= #
171
+ # === Determine the runmode to use for this class
172
+ #
173
+ # Next, determine which "mode" is used, such as www-mode, commandline
174
+ # mode or similar.
175
+ #
176
+ # The :runmode variable can be any of these three values:
177
+ #
178
+ # :commandline
179
+ # :www
180
+ # :gui
181
+ #
182
+ # If :commandline is used as its value, then this class may colourize via
183
+ # the Colours module - otherwise, it may colourize via "websafe" colours
184
+ # instead (such as the HTML colours).
185
+ #
186
+ # Note that :gui means GUI, that is, graphical user interface. These
187
+ # are traditional "oldschool" desktop applications.
188
+ # ======================================================================= #
189
+ if Studium.runmode?
190
+ set_runmode(Studium.runmode?)
191
+ else
192
+ set_runmode(:commandline) # The default mode is commandline.
193
+ end
194
+ end
195
+
196
+ # ========================================================================= #
197
+ # === initialize_the_internal_hash
198
+ # ========================================================================= #
199
+ def initialize_the_internal_hash
200
+ # ======================================================================= #
201
+ # === @internal_hash
202
+ # ======================================================================= #
203
+ @internal_hash = {}
204
+ end; alias reset_the_internal_hash initialize_the_internal_hash # === reset_the_internal_hash
205
+
206
+ # ========================================================================= #
207
+ # === register_sigint
208
+ # ========================================================================= #
209
+ def register_sigint
210
+ Signal.trap('SIGINT') { exit }
211
+ end
212
+
213
+ # ========================================================================= #
214
+ # === yellowrev
215
+ # ========================================================================= #
216
+ def yellowrev(i)
217
+ "#{yellow(i)}#{rev}"
218
+ end
219
+
220
+ # ========================================================================= #
221
+ # === simp
222
+ # ========================================================================= #
223
+ def simp(
224
+ i = '',
225
+ use_colours = use_colours?
226
+ )
227
+ return ::Colours.simp(i) if use_colours # Delegate to module Colours in this case.
228
+ return i
229
+ end
230
+
231
+ # ========================================================================= #
232
+ # === sfancy
233
+ # ========================================================================= #
234
+ def sfancy(
235
+ i = '',
236
+ use_colours = use_colours?
237
+ )
238
+ return ::Colours.sfancy(i) if use_colours
239
+ return i
240
+ end
241
+
242
+ # ========================================================================= #
243
+ # === enable_colours_globally
244
+ # ========================================================================= #
245
+ def enable_colours_globally
246
+ ::Studium.enable_colours
247
+ end
248
+
249
+ # ========================================================================= #
250
+ # === disable_colours_globally
251
+ #
252
+ # Disable the colours globally, that is, on a per-project basis.
253
+ # ========================================================================= #
254
+ def disable_colours_globally
255
+ ::Studium.disable_colours # Delegate to the module-method here.
256
+ end
257
+
258
+ # ========================================================================= #
259
+ # === internal_hash?
260
+ # ========================================================================= #
261
+ def internal_hash?
262
+ @internal_hash
263
+ end; alias ihash? internal_hash? # === ihash?
264
+
265
+ # ========================================================================= #
266
+ # === no_file_exists_at
267
+ # ========================================================================= #
268
+ def no_file_exists_at(i)
269
+ e "#{rev}No file exists at #{sfile(i)}."
270
+ end; alias no_file_at no_file_exists_at # === no_file_at
271
+
272
+ require 'studium/project/project.rb'
273
+ # ========================================================================= #
274
+ # === yaml_dir?
275
+ # ========================================================================= #
276
+ def yaml_dir?
277
+ Studium.yaml_directory?
278
+ end
279
+
280
+ # ========================================================================= #
281
+ # === ee (ee tag)
282
+ #
283
+ # This is just a wrapper over print, essentially.
284
+ # ========================================================================= #
285
+ def ee(i = '')
286
+ print i
287
+ end
288
+
289
+ # ========================================================================= #
290
+ # === return_pwd
291
+ #
292
+ # This method will return the current working directory.
293
+ # ========================================================================= #
294
+ def return_pwd
295
+ "#{Dir.pwd}/".squeeze('/')
296
+ end; alias pwd? return_pwd # === pwd?
297
+
298
+ # ========================================================================= #
299
+ # === current_month?
300
+ #
301
+ # Show us the current month, as Integer. For example, for April, this
302
+ # method would return the number 4.
303
+ # ========================================================================= #
304
+ def current_month?
305
+ return ::Time.now.strftime('%m').to_i
306
+ end; alias month? current_month? # === month?
307
+ alias return_current_month_as_a_number current_month? # === return_current_month_as_a_number
308
+
309
+ # ========================================================================= #
310
+ # === file_important_exams?
311
+ # ========================================================================= #
312
+ def file_important_exams?
313
+ return ::Studium.file_important_exams?
314
+ end
315
+
316
+ # ========================================================================= #
317
+ # === padded_current_month?
318
+ # ========================================================================= #
319
+ def padded_current_month?(
320
+ i = current_month?
321
+ )
322
+ _ = i.to_s
323
+ return ('%02d' % _)
324
+ end
325
+
326
+ # ========================================================================= #
327
+ # === namespace?
328
+ # ========================================================================= #
329
+ def namespace?
330
+ @internal_hash[:namespace]
331
+ end
332
+
333
+ # ========================================================================= #
334
+ # === e (e tag)
335
+ # ========================================================================= #
336
+ def e(i = '')
337
+ puts i
338
+ end
339
+
340
+ # ========================================================================= #
341
+ # === yes_or_no
342
+ # ========================================================================= #
343
+ def yes_or_no(i)
344
+ case i
345
+ when true
346
+ 'yes'
347
+ when false
348
+ 'no'
349
+ end
350
+ end
351
+
352
+ # ========================================================================= #
353
+ # === enable_colours
354
+ # ========================================================================= #
355
+ def enable_colours
356
+ @internal_hash[:use_colours] = true
357
+ end
358
+
359
+ # ========================================================================= #
360
+ # === disable_colours
361
+ # ========================================================================= #
362
+ def disable_colours
363
+ @internal_hash[:use_colours] = false
364
+ end; alias no_colours disable_colours # === no_colours
365
+
366
+ # ========================================================================= #
367
+ # === use_colours?
368
+ # ========================================================================= #
369
+ def use_colours?
370
+ @internal_hash[:use_colours]
371
+ end
372
+
373
+ # ========================================================================= #
374
+ # === reset_the_internal_state
375
+ # ========================================================================= #
376
+ def reset_the_internal_state
377
+ # ======================================================================= #
378
+ # === @internal_hash[:no_connection_to_the_www]
379
+ #
380
+ # If true then we have no connection to the WWW.
381
+ # ======================================================================= #
382
+ @internal_hash[:no_connection_to_the_www] = false
383
+ end
384
+
385
+ # ========================================================================= #
386
+ # === www_connection_is_unavailable
387
+ # ========================================================================= #
388
+ def www_connection_is_unavailable
389
+ @internal_hash[:no_connection_to_the_www] = true
390
+ end; alias www_is_unavailable www_connection_is_unavailable # === www_is_unavailable
391
+
392
+ # ========================================================================= #
393
+ # === is_connected_to_the_www?
394
+ # ========================================================================= #
395
+ def is_connected_to_the_www?
396
+ !@internal_hash[:no_connection_to_the_www]
397
+ end
398
+
399
+ # ========================================================================= #
400
+ # === replace_bold_token_with_default_colour
401
+ #
402
+ # This method can be used to replace <b></b> with the corresponding
403
+ # colour code on the terminal.
404
+ # ========================================================================= #
405
+ def replace_bold_token_with_default_colour(
406
+ i, use_this_colour = :mediumseagreen
407
+ )
408
+ i.gsub(
409
+ /<b>(.+)<\/b>/,
410
+ ::Colours.bold('\1')
411
+ )
412
+ end
413
+
414
+ # ========================================================================= #
415
+ # === spacer
416
+ # ========================================================================= #
417
+ def spacer
418
+ Studium.spacer
419
+ end
420
+
421
+ # ========================================================================= #
422
+ # === is_a_registered_curriculum?
423
+ #
424
+ # This calls code stored in the file
425
+ # /require 'studium/toplevel_methods/toplevel_methods.rb'.
426
+ # ========================================================================= #
427
+ def is_a_registered_curriculum?(i)
428
+ return Studium.is_a_registered_curriculum?(i)
429
+ end
430
+
431
+ # ========================================================================= #
432
+ # === html_log_dir?
433
+ # ========================================================================= #
434
+ def html_log_directory?
435
+ Studium.html_log_directory?
436
+ end; alias html_log_dir? html_log_directory? # === html_log_dir?
437
+
438
+ # ========================================================================= #
439
+ # === opne
440
+ # ========================================================================= #
441
+ def opne(i)
442
+ opnn; e i
443
+ end
444
+
445
+ # ========================================================================= #
446
+ # === opnerev
447
+ # ========================================================================= #
448
+ def opnerev(i)
449
+ opne "#{rev}#{i}"
450
+ end
451
+
452
+ # ========================================================================= #
453
+ # === be_verbose?
454
+ # ========================================================================= #
455
+ def be_verbose?
456
+ @internal_hash[:be_verbose]
457
+ end
458
+
459
+ # ========================================================================= #
460
+ # === do_not_be_verbose
461
+ # ========================================================================= #
462
+ def do_not_be_verbose
463
+ @internal_hash[:be_verbose] = false
464
+ end; alias set_be_quiet do_not_be_verbose # === set_be_quiet
465
+
466
+ # ========================================================================= #
467
+ # === set_be_verbose
468
+ # ========================================================================= #
469
+ def set_be_verbose
470
+ @internal_hash[:be_verbose] = true
471
+ end; alias be_verbose set_be_verbose # === be_verbose
472
+
473
+ # ========================================================================= #
474
+ # === move_file
475
+ # ========================================================================= #
476
+ def move_file(this_file, target)
477
+ FileUtils.mv(this_file, target)
478
+ end
479
+
480
+ # ========================================================================= #
481
+ # === has_this_exam_topic_been_solved?
482
+ # ========================================================================= #
483
+ def has_this_exam_topic_been_solved?(i)
484
+ (Studium.return_n_percent_solved_from_this_topic(i).to_i == 100)
485
+ end
486
+
487
+ # ========================================================================= #
488
+ # === cpruby
489
+ # ========================================================================= #
490
+ def cpruby
491
+ base_dir = ENV['USERS']
492
+ base_dir = '/home' if base_dir.nil?
493
+ path_to_setup_rb_file =
494
+ "#{RUBY_SRC_DIR}roebe/lib/roebe/setup/setup.rb"
495
+ copy(path_to_setup_rb_file, '.')
496
+ end
497
+
498
+ # ========================================================================= #
499
+ # === delete_file
500
+ # ========================================================================= #
501
+ def delete_file(i)
502
+ File.delete(i) if File.exist? i
503
+ end
504
+
505
+ # ========================================================================= #
506
+ # === remove_internal_comments
507
+ # ========================================================================= #
508
+ def remove_internal_comments(i)
509
+ if i.is_a? Array
510
+ i.map {|line|
511
+ if line.include? '#'
512
+ line = line[0 .. (line.index('#') - 1)]
513
+ end
514
+ line.strip
515
+ }
516
+ end
517
+ end
518
+
519
+ # ========================================================================= #
520
+ # === return_all_numbers_from
521
+ #
522
+ # This method will return all numbers from the given input.
523
+ # ========================================================================= #
524
+ def return_all_numbers_from(i)
525
+ return_this = nil
526
+ if i.is_a? Array
527
+ return_this = i.select {|line|
528
+ line =~ /\d+/ # Any entry with a number will be returned.
529
+ }
530
+ end
531
+ return_this
532
+ end
533
+
534
+ # ========================================================================= #
535
+ # === return_all_steop_lectures
536
+ # ========================================================================= #
537
+ def return_all_steop_lectures
538
+ return_sanitized_dataset_from_the_file_lecture_information.select {|a, b|
539
+ is_a_steop_lecture = obtain(:steop, b)
540
+ is_a_steop_lecture
541
+ }
542
+ end
543
+
544
+ # ========================================================================= #
545
+ # === extract_dd_mm_yyyy
546
+ #
547
+ # This method can be used to extract the dd.mm.yyyy format from the given
548
+ # input at hand. It will discard everything else.
549
+ #
550
+ # So, for instance, if the input is "15.10.2018, 09:00-18:00" then
551
+ # this method will return only "15.10.2018".
552
+ # ========================================================================= #
553
+ def extract_dd_mm_yyyy(i)
554
+ i =~ /(\d{1,2}\.\d{1,2}\.\d{4})/ # This will also generate a match.
555
+ return $1.to_s.dup
556
+ end; alias extract_ddmmyyyy extract_dd_mm_yyyy # === extract_ddmmyyyy
557
+
558
+ # ========================================================================= #
559
+ # === return_month_fitting_to_this_input
560
+ #
561
+ # This method will return a number.
562
+ # ========================================================================= #
563
+ def return_month_fitting_to_this_input(i)
564
+ i = i.capitalize
565
+ if MONTH_NAME_TO_MONTH_NUMBER.has_key? i
566
+ i = MONTH_NAME_TO_MONTH_NUMBER[i]
567
+ end
568
+ return i.to_i
569
+ end
570
+
571
+ # ========================================================================= #
572
+ # === remove_leading_weekday_names_from
573
+ #
574
+ # Chop away the leading weekday, e. g. "Monday", from the String at hand.
575
+ # ========================================================================= #
576
+ def remove_leading_weekday_names_from(i)
577
+ Studium.remove_leading_weekday_names_from(i)
578
+ end; alias remove_german_weekdays remove_leading_weekday_names_from # === remove_german_weekdays
579
+ alias remove_german_weekdays_from remove_leading_weekday_names_from # === remove_german_weekdays_from
580
+ alias remove_leading_weeknames remove_leading_weekday_names_from # === remove_leading_weeknames
581
+ alias remove_leading_weekdays remove_leading_weekday_names_from # === remove_leading_weekdays
582
+ alias remove_workday_from_this_input remove_leading_weekday_names_from # === remove_workday_from_this_input
583
+ alias remove_german_days remove_leading_weekday_names_from # === remove_german_days
584
+
585
+ # ========================================================================= #
586
+ # === is_on_roebe?
587
+ # ========================================================================= #
588
+ def is_on_roebe?
589
+ Studium.is_on_roebe?
590
+ end; alias is_roebe? is_on_roebe? # === is_roebe?
591
+ alias on_roebe? is_on_roebe? # === on_roebe?
592
+
593
+ # ========================================================================= #
594
+ # === weekdays?
595
+ #
596
+ # This method will return all weekdays, as Array, including german
597
+ # and english names for these weekdays.
598
+ # ========================================================================= #
599
+ def weekdays?
600
+ (
601
+ ARRAY_GERMAN_WEEKDAYS+
602
+ HASH_SHORT_TO_LONG_WEEKDAYS.values
603
+ ).flatten
604
+ end
605
+
606
+ # ========================================================================= #
607
+ # === try_to_require_the_rcfiles
608
+ # ========================================================================= #
609
+ def try_to_require_the_rcfiles
610
+ begin
611
+ require 'rcfiles'
612
+ rescue LoadError; end
613
+ end
614
+
615
+ # ========================================================================= #
616
+ # === copy (copy tag)
617
+ # ========================================================================= #
618
+ def copy(from, to)
619
+ if from.is_a? Array
620
+ from.each {|entry|
621
+ copy(entry, to)
622
+ }
623
+ else
624
+ FileUtils.copy(from, to)
625
+ end
626
+ end; alias copy_file copy # === copy_file
627
+
628
+ # ========================================================================= #
629
+ # === set_xorg_buffer
630
+ # ========================================================================= #
631
+ def set_xorg_buffer(i)
632
+ begin
633
+ require 'xorg_buffer' unless Object.const_defined?(:XorgBuffer)
634
+ XorgBuffer.set_buffer(i)
635
+ rescue LoadError
636
+ if is_on_roebe?
637
+ e 'XorgBuffer is not available - can not set the buffer.'
638
+ end
639
+ end
640
+ end
641
+
642
+ # ========================================================================= #
643
+ # === open_in_editor
644
+ # ========================================================================= #
645
+ def open_in_editor(i)
646
+ Studium.open_in_editor(i)
647
+ end
648
+
649
+ # ========================================================================= #
650
+ # === editor?
651
+ # ========================================================================= #
652
+ def editor?
653
+ Studium.editor?
654
+ end
655
+
656
+ # ========================================================================= #
657
+ # === encoding?
658
+ #
659
+ # This method will return the main encoding in use, by "pointing" towards
660
+ # the constant that keeps track of this.
661
+ # ========================================================================= #
662
+ def encoding?
663
+ ::Studium.main_encoding?
664
+ end; alias main_encoding? encoding? # === main_encoding?
665
+ alias main_encoding_to_use? encoding? # === main_encoding_to_use?
666
+ alias use_this_encoding? encoding? # === use_this_encoding?
667
+ alias encoding_to_use? encoding? # === encoding_to_use?
668
+
669
+ # ========================================================================= #
670
+ # === exit_program (exit tag)
671
+ #
672
+ # Use this method to exit from the program. It is a general "exit-operation"
673
+ # for classes in the Studium project. The reason as to why we don't just
674
+ # simply use exit() is so that we
675
+ # ========================================================================= #
676
+ def exit_program(
677
+ make_newline = :no_newline
678
+ )
679
+ case make_newline
680
+ # ======================================================================= #
681
+ # === :no_newline
682
+ # ======================================================================= #
683
+ when :no_newline
684
+ make_newline = false
685
+ end
686
+ e(N) if make_newline
687
+ exit # Exit here.
688
+ end
689
+
690
+ # ========================================================================= #
691
+ # === turn_this_array_into_the_full_dataset
692
+ #
693
+ # This method accepts an Array of lectures that will be replaced with
694
+ # a full dataset.
695
+ # ========================================================================= #
696
+ def turn_this_array_into_the_full_dataset(
697
+ i, use_this_dataset
698
+ )
699
+ hash = {}
700
+ i.flatten.each {|name_of_the_lecture|
701
+ pointer = use_this_dataset[name_of_the_lecture]
702
+ hash[name_of_the_lecture] = pointer
703
+ }
704
+ hash
705
+ end
706
+
707
+ # ========================================================================= #
708
+ # === no_ext_name
709
+ #
710
+ # This method will return the name of the file (or rather the
711
+ # input given to this method) without extension.
712
+ # ========================================================================= #
713
+ def no_ext_name(i)
714
+ i.sub(/#{File.extname(i)}$/,'')
715
+ end
716
+
717
+ # ========================================================================= #
718
+ # === load_yaml_dataset
719
+ #
720
+ # This method should ideally be used whenever a .yml file is to be
721
+ # loaded.
722
+ #
723
+ # The second argument can be used to rescue missing or erroneous
724
+ # yaml files.
725
+ #
726
+ # Invocation example for this is:
727
+ #
728
+ # load_yaml_dataset(:rescue)
729
+ #
730
+ # ========================================================================= #
731
+ def load_yaml_dataset(
732
+ i,
733
+ do_rescue = false
734
+ )
735
+ case do_rescue
736
+ # ======================================================================= #
737
+ # === :rescue
738
+ # ======================================================================= #
739
+ when :rescue
740
+ do_rescue = true
741
+ end
742
+ if do_rescue
743
+ begin
744
+ YAML.load_file(i)
745
+ rescue LoadError, ArgumentError; end
746
+ else
747
+ YAML.load_file(i)
748
+ end
749
+ end
750
+
751
+ # ========================================================================= #
752
+ # === enable_debug
753
+ # ========================================================================= #
754
+ def enable_debug
755
+ @internal_hash[:debug] = true
756
+ end; alias do_debug enable_debug # === do_debug
757
+
758
+ # ========================================================================= #
759
+ # === be_silent
760
+ # ========================================================================= #
761
+ def be_silent
762
+ @internal_hash[:be_verbose] = false
763
+ end; alias be_quiet be_silent # === be_quiet
764
+
765
+ # ========================================================================= #
766
+ # === lectures_from_indi1
767
+ # ========================================================================= #
768
+ def lectures_from_indi1
769
+ obtain_lectures_from_this_curriculum(:indi1)
770
+ end
771
+
772
+ # ========================================================================= #
773
+ # === lectures_from_indi2
774
+ # ========================================================================= #
775
+ def lectures_from_indi2
776
+ obtain_lectures_from_this_curriculum(:indi2)
777
+ end
778
+
779
+ # ========================================================================= #
780
+ # === lectures_from_indi3
781
+ # ========================================================================= #
782
+ def lectures_from_indi3
783
+ obtain_lectures_from_this_curriculum(:indi3)
784
+ end
785
+
786
+ # ========================================================================= #
787
+ # === lectures_from_indi4
788
+ # ========================================================================= #
789
+ def lectures_from_indi4
790
+ obtain_lectures_from_this_curriculum(:indi4)
791
+ end
792
+
793
+ # ========================================================================= #
794
+ # === return_random_curriculum
795
+ # ========================================================================= #
796
+ def return_random_curriculum
797
+ ::Studium.return_random_curriculum
798
+ end
799
+
800
+ # ========================================================================= #
801
+ # === lectures_from_the_bachelor_genetik_curriculum
802
+ # ========================================================================= #
803
+ def lectures_from_the_bachelor_genetik_curriculum
804
+ obtain_lectures_from_this_curriculum(:bachelor_genetik_curriculum)
805
+ end
806
+
807
+ # ========================================================================= #
808
+ # === return_lectures_from_bachelor_vektor_curriculum
809
+ # ========================================================================= #
810
+ def return_lectures_from_bachelor_vektor_curriculum
811
+ obtain_lectures_from_this_curriculum(:bachelor_vektor)
812
+ end
813
+
814
+ # ========================================================================= #
815
+ # === convert_this_array_of_lectures_into_the_full_dataset
816
+ #
817
+ # The purpose of this method is to turn an Array that holds Strings
818
+ # such as "941111 Genetische Ressourcen von Nutzpflanzen" into the
819
+ # corresponding dataset.
820
+ #
821
+ # This method will return a Hash if everything went fine.
822
+ # ========================================================================= #
823
+ def convert_this_array_of_lectures_into_the_full_dataset(i)
824
+ if i.is_a? Array
825
+ if Studium.main_dataset?.nil?
826
+ Studium.initialize_main_dataset
827
+ end
828
+ _ = Studium.main_dataset?
829
+ hash = {}
830
+ i.map {|course_id_and_course_name|
831
+ if _.has_key?(course_id_and_course_name)
832
+ hash[course_id_and_course_name] = _[course_id_and_course_name]
833
+ end
834
+ }
835
+ hash
836
+ else
837
+ raise 'This method only accepts an Array as input.'
838
+ end
839
+ end
840
+
841
+ # ========================================================================= #
842
+ # === return_this_line_has_n_characters_as_html_colour_tags
843
+ # ========================================================================= #
844
+ def return_this_line_has_n_characters_as_html_colour_tags(i)
845
+ i.scan(REGEX_FOR_OPENING_AND_CLOSING_COLOUR_TAGS).map {|entry|
846
+ entry.size
847
+ }.sum
848
+ end
849
+
850
+ # ========================================================================= #
851
+ # === file_read_with_proper_encoding
852
+ # ========================================================================= #
853
+ def file_read_with_proper_encoding(this_file)
854
+ Studium.file_read_with_proper_encoding(this_file)
855
+ end
856
+
857
+ # ========================================================================= #
858
+ # === create_file
859
+ # ========================================================================= #
860
+ def create_file(i)
861
+ FileUtils.touch(i)
862
+ end; alias touch create_file # === touch
863
+
864
+ # ========================================================================= #
865
+ # === return_n_questions_were_answered_for_this_topic
866
+ # ========================================================================= #
867
+ def return_n_questions_were_answered_for_this_topic(i)
868
+ Studium::Exams.return_n_questions_were_answered_for_this_topic(i)
869
+ end
870
+
871
+ # ========================================================================= #
872
+ # === create_directory
873
+ # ========================================================================= #
874
+ def create_directory(i)
875
+ FileUtils.mkdir_p(i)
876
+ end; alias mkdir create_directory # === mkdir
877
+
878
+ # ========================================================================= #
879
+ # === change_directory
880
+ # ========================================================================= #
881
+ def change_directory(
882
+ i = Dir.pwd
883
+ )
884
+ FileUtils.chdir(i)
885
+ end; alias cd change_directory # === cd
886
+
887
+ # ========================================================================= #
888
+ # === return_passed_courses
889
+ #
890
+ # This method will quickly return all passed courses.
891
+ # ========================================================================= #
892
+ def return_passed_courses
893
+ return_dataset_from_file_lecture_information.select {|key, hash|
894
+ hash.has_key?(:already_solved) and
895
+ (hash[:already_solved] == true)
896
+ }
897
+ end
898
+
899
+ # ========================================================================= #
900
+ # === return_ects_points_from_these_lectures
901
+ #
902
+ # Input to this method should be a Hash containing our lectures.
903
+ #
904
+ # An example for this is shown next:
905
+ #
906
+ # {"051010"=>"Programmierung 1",
907
+ # "051110"=>"Mathematische Grundlagen der Informatik 1"}
908
+ #
909
+ # ========================================================================= #
910
+ def return_ects_points_from_these_lectures(hash)
911
+ n_ects_points = 0 # Keep track of the amount of ECTS points here.
912
+ hash.each_pair {|lecture_id, name_of_the_lecture|
913
+ # lecture_id = ensure_main_encoding(lecture_id)
914
+ # name_of_the_lecture = ensure_main_encoding(name_of_the_lecture)
915
+ name_of_the_lecture.squeeze!(' ')
916
+ points = Studium.return_ects_from_this_lecture_stored_in_the_file_lecture_information(
917
+ name_of_the_lecture, lecture_id
918
+ )
919
+ n_ects_points += points
920
+ }
921
+ return n_ects_points
922
+ end
923
+
924
+ # ========================================================================= #
925
+ # === select_lectures_with_this_key
926
+ #
927
+ # This method allows us to select only entries with a particular
928
+ # key. The key has to be passed to the method and - for now - has
929
+ # to be exactly the same as the key (e. g. string for strings
930
+ # and symbols for symbols; no automatic conversions for now).
931
+ #
932
+ # The advantage of this method is that it will simplify a lot of
933
+ # code; all code that requires us to select only specific
934
+ # lectures.
935
+ #
936
+ # Usage examples:
937
+ #
938
+ # .select_lectures_with_this_key(:exam_registration_at)
939
+ # .select_lectures_with_this_key(:already_solved)
940
+ #
941
+ # ========================================================================= #
942
+ def select_lectures_with_this_key(
943
+ searching_for_this_key
944
+ )
945
+ dataset = return_sanitized_dataset_from_the_file_lecture_information
946
+ dataset.select! {|name_of_the_lecture, inner_hash|
947
+ inner_hash.has_key? searching_for_this_key
948
+ } if dataset # <- Must check here, since there may be a nil.
949
+ return dataset
950
+ end
951
+
952
+ # ========================================================================= #
953
+ # === konsole_support?
954
+ # ========================================================================= #
955
+ def konsole_support?
956
+ true
957
+ end
958
+
959
+ # ========================================================================= #
960
+ # === rename_kde_konsole_tab
961
+ # ========================================================================= #
962
+ def rename_kde_konsole_tab(
963
+ title = '.'
964
+ )
965
+ if Object.const_defined?(:Roebe) and
966
+ Roebe.respond_to?(:rename_konsole_title_to)
967
+ Roebe.rename_konsole_title_to(title, :be_quiet)
968
+ end
969
+ end
970
+
971
+ # ========================================================================= #
972
+ # === last_file?
973
+ # ========================================================================= #
974
+ def last_file?
975
+ _ = Studium.file_for_exam_questions
976
+ _ = load_yaml_dataset(_).chomp
977
+ # ======================================================================= #
978
+ # If we are on roebe then we will use another path.
979
+ # ======================================================================= #
980
+ if is_on_roebe?
981
+ _ = Studium::MY_EXAM_TOPICS+File.basename(_)
982
+ end
983
+ return _
984
+ end
985
+
986
+ # ========================================================================= #
987
+ # === return_sanitized_dataset_from_the_file_lecture_information
988
+ #
989
+ # This method will return the dataset stored in the file
990
+ # 'lecture_information.yml'.
991
+ # ========================================================================= #
992
+ def return_sanitized_dataset_from_the_file_lecture_information
993
+ Studium.return_sanitized_dataset_from_the_file_lecture_information
994
+ end; alias return_dataset_from_the_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_dataset_from_the_file_lecture_information
995
+ alias return_dataset_from_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_dataset_from_file_lecture_information
996
+ alias lecture_information_dataset return_sanitized_dataset_from_the_file_lecture_information # === lecture_information_dataset
997
+ alias lecture_information return_sanitized_dataset_from_the_file_lecture_information # === lecture_information_dataset
998
+ alias dataset_from_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === dataset_from_file_lecture_information
999
+ alias dataset_from_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === dataset_from_lecture_information
1000
+ alias dataset_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === dataset_lecture_information
1001
+ alias return_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_lecture_information
1002
+ alias return_data_from_the_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_data_from_the_file_lecture_information
1003
+ alias return_all_lectures return_sanitized_dataset_from_the_file_lecture_information # === return_all_lectures
1004
+ alias all_lectures? return_sanitized_dataset_from_the_file_lecture_information # === all_lectures?
1005
+ alias return_lectures_from_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_lectures_from_file_lecture_information
1006
+ alias dataset_from_the_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === dataset_from_the_file_lecture_information
1007
+ alias return_sanitized_dataset_from_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_sanitized_dataset_from_file_lecture_information
1008
+ alias return_dataset_from_the_lectures return_sanitized_dataset_from_the_file_lecture_information # === return_dataset_from_the_lectures
1009
+ alias return_sanitized_dataset return_sanitized_dataset_from_the_file_lecture_information # === return_sanitized_dataset
1010
+ alias return_all_lectures_from_the_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_all_lectures_from_the_file_lecture_information
1011
+ alias return_dataset_from_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === return_dataset_from_lecture_information
1012
+ alias from_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === from_file_lecture_information
1013
+ alias sanitized_dataset_from_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === sanitized_dataset_from_file_lecture_information
1014
+ alias dataset_from_the_file_lecture_information return_sanitized_dataset_from_the_file_lecture_information # === dataset_from_the_file_lecture_information
1015
+
1016
+ # ========================================================================= #
1017
+ # === obtain (obtain tag)
1018
+ #
1019
+ # This method will attempt to return the entry point of our main hash.
1020
+ #
1021
+ # It is optimized towards the dataset stored in the file
1022
+ # 'lecture_information.yml'.
1023
+ #
1024
+ # Typical usage example:
1025
+ #
1026
+ # curricula = obtain(:curricula, pointer_to_the_lecture_dataset)
1027
+ #
1028
+ # ========================================================================= #
1029
+ def obtain(
1030
+ this_key, hash, be_verbose = true
1031
+ )
1032
+ if block_given?
1033
+ yielded = yield
1034
+ case yielded
1035
+ # ===================================================================== #
1036
+ # === :be_quiet
1037
+ # ===================================================================== #
1038
+ when :be_quiet
1039
+ be_verbose = false
1040
+ end
1041
+ end
1042
+ case be_verbose
1043
+ when :be_quiet,
1044
+ :be_silent
1045
+ be_verbose = false
1046
+ end
1047
+ # ======================================================================= #
1048
+ # The following case menu will make use of some common popular aliases
1049
+ # or typos.
1050
+ # ======================================================================= #
1051
+ case this_key
1052
+ # ======================================================================= #
1053
+ # === :passed_when
1054
+ # ======================================================================= #
1055
+ when :passed_when,
1056
+ :solved_at
1057
+ this_key = :already_solved_at
1058
+ # ======================================================================= #
1059
+ # === :passed_successfully
1060
+ # ======================================================================= #
1061
+ when :passed_successfully
1062
+ this_key = :already_solved
1063
+ # ======================================================================= #
1064
+ # === :steop
1065
+ # ======================================================================= #
1066
+ when :steop,
1067
+ 'steop'
1068
+ this_key = :is_a_steop_lecture
1069
+ # ======================================================================= #
1070
+ # === :curricula_entries
1071
+ # ======================================================================= #
1072
+ when :curricula_entries,
1073
+ :curricula,
1074
+ 'curricula'
1075
+ this_key = 'curricula'
1076
+ # ======================================================================= #
1077
+ # === :english_description
1078
+ # ======================================================================= #
1079
+ when :english_description
1080
+ this_key = :description_in_english
1081
+ # ======================================================================= #
1082
+ # === :german_description
1083
+ # ======================================================================= #
1084
+ when :german_description
1085
+ this_key = :description_in_german
1086
+ # ======================================================================= #
1087
+ # === :this_university
1088
+ # ======================================================================= #
1089
+ when :this_university,
1090
+ :university
1091
+ this_key = :university
1092
+ # ======================================================================= #
1093
+ # === :n_ects
1094
+ # ======================================================================= #
1095
+ when :n_ects, :n_ects_points
1096
+ this_key = :ects
1097
+ # ======================================================================= #
1098
+ # === :curricula_ids
1099
+ # ======================================================================= #
1100
+ when :curricula_ids,
1101
+ :curriculum_id
1102
+ this_key = 'curricula'
1103
+ # ======================================================================= #
1104
+ # === :lecturers
1105
+ # ======================================================================= #
1106
+ when :lecturers
1107
+ this_key = 'lecturers'
1108
+ # ======================================================================= #
1109
+ # === :semester
1110
+ # ======================================================================= #
1111
+ when 'homepage',
1112
+ :remote_url
1113
+ this_key = :homepage
1114
+ # ======================================================================= #
1115
+ # === :semester
1116
+ # ======================================================================= #
1117
+ when :semester, 'semester'
1118
+ this_key = :semester
1119
+ end
1120
+ # ======================================================================= #
1121
+ # Work on any other symbols given to us next.
1122
+ # ======================================================================= #
1123
+ if this_key.is_a? Symbol
1124
+ if hash.has_key? this_key
1125
+ # All is fine.
1126
+ elsif hash.has_key? this_key.to_s
1127
+ # Else use that String as key instead.
1128
+ this_key = this_key.to_s
1129
+ end
1130
+ end
1131
+ if hash.is_a? Symbol
1132
+ e "Symbol called :#{slateblue(hash.to_s)}"
1133
+ e swarn('This is not allowed - please correct this. '\
1134
+ '(Read the next line in how to do so.)')
1135
+ e swarn('This method requires (1) first the key, (2) then the Hash.')
1136
+ exit
1137
+ elsif hash.is_a?(Hash) and hash.has_key?(this_key)
1138
+ hash[this_key] # Return this.
1139
+ else
1140
+ if be_verbose
1141
+ case this_key
1142
+ when :is_a_steop_lecture
1143
+ # Exceptions - these keys ^^^ will NOT be shown.
1144
+ else
1145
+ e "In file #{sfile('base.rb')}, method: obtain() → No key found, "\
1146
+ "called `#{this_key.to_s}` (class '#{this_key.class.to_s})"
1147
+ e 'The hash was:'
1148
+ e
1149
+ pp hash
1150
+ e
1151
+ end
1152
+ end
1153
+ nil
1154
+ end
1155
+ end; alias obtain_this_value_from_hash obtain # === obtain_this_value_from_hash
1156
+ alias obtain_from obtain # === obtain_from
1157
+
1158
+ # ========================================================================= #
1159
+ # === colour_for_ects_points
1160
+ # ========================================================================= #
1161
+ def colour_for_ects_points(i = '')
1162
+ ::Studium.colour_for_ects_points(i)
1163
+ end; alias colourize_ects colour_for_ects_points # === colourize_ects
1164
+ alias colour_ects colour_for_ects_points # === colour_ects
1165
+
1166
+ # ========================================================================= #
1167
+ # === return_opnn
1168
+ # ========================================================================= #
1169
+ def return_opnn(
1170
+ use_this_namespace = NAMESPACE
1171
+ )
1172
+ ::Colours::GREY+
1173
+ use_this_namespace+
1174
+ ': '+
1175
+ ::Colours::REVERT
1176
+ end; alias ropnn return_opnn # === ropnn
1177
+
1178
+ # ========================================================================= #
1179
+ # === set_this_cd_alias_to
1180
+ # ========================================================================= #
1181
+ def set_this_cd_alias_to(
1182
+ cd_alias,
1183
+ new_content,
1184
+ be_verbose = :default
1185
+ )
1186
+ Studium.set_this_cd_alias_to(cd_alias, new_content, be_verbose)
1187
+ end
1188
+
1189
+ # ========================================================================= #
1190
+ # === return_all_exams_on_this_day
1191
+ # ========================================================================= #
1192
+ def return_all_exams_on_this_day(i)
1193
+ Studium.return_all_exams_on_this_day(i)
1194
+ end
1195
+
1196
+ # ========================================================================= #
1197
+ # === average_grade
1198
+ # ========================================================================= #
1199
+ def average_grade(
1200
+ i = :default,
1201
+ round_to = 2 # ← Round to two numbers.
1202
+ )
1203
+ require 'studium/exams/average_grade/average_grade.rb'
1204
+ Studium.average_grade(i, round_to)
1205
+ end
1206
+
1207
+ # ========================================================================= #
1208
+ # === remove_leading_comments
1209
+ # ========================================================================= #
1210
+ def remove_leading_comments(i)
1211
+ if i.is_a? Array
1212
+ i.reject {|line| line.start_with? '#' }
1213
+ end
1214
+ end
1215
+
1216
+ # ========================================================================= #
1217
+ # === remove_empty_strings
1218
+ #
1219
+ # This method presently only works on Arrays. We will reject empty
1220
+ # Strings from the Array at hand.
1221
+ # ========================================================================= #
1222
+ def remove_empty_strings(i)
1223
+ if i.is_a? Array
1224
+ i.reject {|line| line.empty? }
1225
+ end
1226
+ end
1227
+
1228
+ # ========================================================================= #
1229
+ # === sanitize_this_topic (sanitize tag, alias tag)
1230
+ #
1231
+ # This entry keeps all possible aliases to commonly used topics, in
1232
+ # particular abbreviations.
1233
+ # ========================================================================= #
1234
+ def sanitize_this_topic(this_topic)
1235
+ Studium.sanitize_this_theme_topic(this_topic)
1236
+ end
1237
+
1238
+ # ========================================================================= #
1239
+ # === replace_regular_numbers_with_unicode_numbers
1240
+ #
1241
+ # This method will replace numbers such as 1 with ¹.
1242
+ # ========================================================================= #
1243
+ def replace_regular_numbers_with_unicode_numbers(i)
1244
+ ::Studium.replace_regular_numbers_with_unicode_numbers(i)
1245
+ end
1246
+
1247
+ # ========================================================================= #
1248
+ # === return_dataset_for_this_topic
1249
+ # ========================================================================= #
1250
+ def return_dataset_for_this_topic(i)
1251
+ Studium.return_dataset_for_this_topic(i)
1252
+ end
1253
+
1254
+ # ========================================================================= #
1255
+ # === cheering_person
1256
+ # ========================================================================= #
1257
+ def cheering_person
1258
+ '\o/'
1259
+ end; alias cheering_person? cheering_person # === cheering_person?
1260
+ alias cheering_dude? cheering_person # === cheering_dude?
1261
+
1262
+ # ========================================================================= #
1263
+ # === return_solved_lectures
1264
+ #
1265
+ # This method will return only those entries that have the key
1266
+ # :already_solved set to true.
1267
+ # ========================================================================= #
1268
+ def return_solved_lectures
1269
+ already_solved = select_lectures_with_this_key(:already_solved).select {|a,b|
1270
+ obtain(:already_solved, b) == true
1271
+ }
1272
+ already_solved
1273
+ end
1274
+
1275
+ # ========================================================================= #
1276
+ # === sanitize_url
1277
+ #
1278
+ # This is such a useful method that we will use it for all subclasses
1279
+ # of Studium::Base.
1280
+ # ========================================================================= #
1281
+ def sanitize_url(
1282
+ i,
1283
+ optional_extra_modes = nil
1284
+ )
1285
+ Studium.sanitize_url(i, optional_extra_modes)
1286
+ end; alias sanitized_url sanitize_url # === sanitized_url
1287
+
1288
+ # ========================================================================= #
1289
+ # === web_liner
1290
+ # ========================================================================= #
1291
+ def web_liner(this_token = '*')
1292
+ (this_token * 80)+N
1293
+ end
1294
+
1295
+ # ========================================================================= #
1296
+ # === return_directory_for
1297
+ #
1298
+ # This method will try to build up the most plausible, local path to
1299
+ # an existing directory.
1300
+ # ========================================================================= #
1301
+ def return_directory_for(
1302
+ name_of_the_lecture,
1303
+ university
1304
+ )
1305
+ Studium.return_directory_for(name_of_the_lecture, university)
1306
+ end
1307
+
1308
+ # ========================================================================= #
1309
+ # === return_steop_lectures (steop tag)
1310
+ #
1311
+ # This method will return all registered STEOP lectures.
1312
+ #
1313
+ # The optional argument will determine whether solved STEOP lectures
1314
+ # will also be returned. By default this is not the case, meaning
1315
+ # that we will ignore STEOP lectures that have already been solved.
1316
+ # ========================================================================= #
1317
+ def return_steop_lectures(
1318
+ optional_ignore_already_completed_steop_lectures = true
1319
+ )
1320
+ if ::Studium.main_dataset?
1321
+ dataset = ::Studium.main_dataset?
1322
+ else
1323
+ dataset = return_dataset_from_the_file_lecture_information
1324
+ end
1325
+ selection = dataset.select {|a, b|
1326
+ b.has_key?(:is_a_steop_lecture) and (b[:is_a_steop_lecture] == true)
1327
+ }
1328
+ if optional_ignore_already_completed_steop_lectures
1329
+ selection = selection.reject {|a, b|
1330
+ b.has_key?(:already_solved) and (b[:already_solved] == true)
1331
+ }
1332
+ end
1333
+ return selection
1334
+ end
1335
+
1336
+ # ========================================================================= #
1337
+ # === remove_newlines
1338
+ #
1339
+ # This method will remove newlines, aka "\n", from Strings and Arrays.
1340
+ # ========================================================================= #
1341
+ def remove_newlines(i)
1342
+ if i.is_a? Array
1343
+ i.map {|entry| remove_newlines(entry) }
1344
+ else
1345
+ i.delete(N)
1346
+ end
1347
+ end
1348
+
1349
+ # ========================================================================= #
1350
+ # === esystem
1351
+ # ========================================================================= #
1352
+ def esystem(i)
1353
+ ::Studium.esystem(i)
1354
+ end
1355
+
1356
+ # ========================================================================= #
1357
+ # === append_what_into (append tag)
1358
+ #
1359
+ # Use this method to save data into a specific file.
1360
+ # ========================================================================= #
1361
+ def append_what_into(what, into)
1362
+ Studium.append_what_into(what, into)
1363
+ end
1364
+
1365
+ # ========================================================================= #
1366
+ # === ruby_src_dir_at_home?
1367
+ # ========================================================================= #
1368
+ def ruby_src_dir_at_home?
1369
+ Studium.ruby_src_dir_at_home?
1370
+ end
1371
+
1372
+ # ========================================================================= #
1373
+ # === replace_italic_token_with_this_colour
1374
+ #
1375
+ # This method can be used to replace <i></i> with the corresponding
1376
+ # colour code on the terminal.
1377
+ # ========================================================================= #
1378
+ def replace_italic_token_with_this_colour(
1379
+ i, use_this_colour = :mediumseagreen
1380
+ )
1381
+ use_this_regex = /<it?>([A-Za-zöäüÖÄÜ\s]+)<\/it?>/ # See: https://rubular.com/r/mZb1ZtGHCLhg2U
1382
+ if ::Colours.respond_to?(:string_italic)
1383
+ i.gsub(
1384
+ use_this_regex,
1385
+ ::Colours.string_italic('\1')+
1386
+ ::Colours.remove_trailing_escape_code(
1387
+ ::Colours.send(use_this_colour.to_sym, '')
1388
+ )
1389
+ )+::Colours.send(use_this_colour,'')
1390
+ else
1391
+ i
1392
+ end
1393
+ end
1394
+
1395
+ # ========================================================================= #
1396
+ # === return_the_remote_homepage_url
1397
+ #
1398
+ # The first parameter denotes which particular lecture is to be
1399
+ # investigated, in regards to its homepage-URL.
1400
+ #
1401
+ # The second parameter should contain the hash-dataset that is to be
1402
+ # used.
1403
+ # ========================================================================= #
1404
+ def return_the_remote_homepage_url(
1405
+ of_this_lecture, dataset_to_use
1406
+ )
1407
+ of_this_lecture.strip!
1408
+ _ = dataset_to_use
1409
+ if _.has_key? :homepage
1410
+ _ = _[:homepage]
1411
+ else
1412
+ e "No :homepage entry for `#{sfancy(of_this_lecture.to_s)}`."
1413
+ end
1414
+ return _
1415
+ end
1416
+
1417
+ # ========================================================================= #
1418
+ # === remove_tags_from_this_input
1419
+ #
1420
+ # This method will return all HTML-like tags from the given input String.
1421
+ # ========================================================================= #
1422
+ def remove_tags_from_this_input(i)
1423
+ return Studium.remove_tags(i)
1424
+ end; alias remove_tags remove_tags_from_this_input # === remove_tags
1425
+
1426
+ # ========================================================================= #
1427
+ # === use_opn?
1428
+ # ========================================================================= #
1429
+ def use_opn?
1430
+ @internal_hash[:use_opn]
1431
+ end
1432
+
1433
+ # ========================================================================= #
1434
+ # === do_not_use_opn
1435
+ # ========================================================================= #
1436
+ def do_not_use_opn
1437
+ @internal_hash[:use_opn] = false
1438
+ end
1439
+
1440
+ # ========================================================================= #
1441
+ # === studium_directory_at_home?
1442
+ # ========================================================================= #
1443
+ def studium_directory_at_home?
1444
+ Studium.studium_directory_at_home?
1445
+ end; alias studium_directory_at_home? studium_directory_at_home? # === studium_directory_at_home?
1446
+
1447
+ # ========================================================================= #
1448
+ # === has_a_master_curriculum?
1449
+ #
1450
+ # This method will return true if the given Array has any master
1451
+ # curriculum; and it will return false otherwise.
1452
+ #
1453
+ # Note that there is an alias called
1454
+ # "is_this_lecture_registered_in_a_master_curriculum?". The name is a
1455
+ # of a misnomer, since the input to this method should be an Array
1456
+ # containing the IDs of the Curricula for which that lecture is
1457
+ # registered. This may be subject for change one day, but for
1458
+ # now (Sep 2018) we will keep it that way.
1459
+ # ========================================================================= #
1460
+ def has_a_master_curriculum?(array)
1461
+ Studium.has_a_master_curriculum?(array)
1462
+ end; alias is_a_master_curriculum? has_a_master_curriculum? # === is_a_master_curriculum?
1463
+ alias has_a_master_lecture? has_a_master_curriculum? # === has_a_master_lecture?
1464
+ alias has_a_master_curriculum_entry? has_a_master_curriculum? # === has_a_master_curriculum_entry?
1465
+ alias is_this_lecture_registered_in_a_master_curriculum? has_a_master_curriculum? # === is_this_lecture_registered_in_a_master_curriculum?
1466
+ alias does_this_include_a_master_curriculum? has_a_master_curriculum? # === does_this_include_a_master_curriculum?
1467
+
1468
+ # ========================================================================= #
1469
+ # === return_file_for_this_curriculum
1470
+ #
1471
+ # This method is a wrapper over the toplevel-method called
1472
+ # Studium.return_file_for_this_curriculum().
1473
+ # ========================================================================= #
1474
+ def return_file_for_this_curriculum(
1475
+ i = :bachelor_basisblock_biologie
1476
+ )
1477
+ if i.is_a? Array
1478
+ i.map {|line|
1479
+ return_file_for_this_curriculum(line)
1480
+ }
1481
+ else
1482
+ # ===================================================================== #
1483
+ #
1484
+ # bl $RUBY_STUDIUM/constants/return_file_for_this_curriculum.rb
1485
+ #
1486
+ # ===================================================================== #
1487
+ Studium.return_file_for_this_curriculum(i)
1488
+ end
1489
+ end; alias return_curriculum_file_based_on_this_input return_file_for_this_curriculum # === return_curriculum_file_based_on_this_input
1490
+ alias curriculum_location_of return_file_for_this_curriculum # === curriculum_location_of
1491
+ alias return_path_of_this_curriculum return_file_for_this_curriculum # === return_path_of_this_curriculum
1492
+ alias return_path_to_the_curriculum_file return_file_for_this_curriculum # === return_path_to_the_curriculum_file
1493
+ alias return_file_associated_with_this_curriculum return_file_for_this_curriculum # === return_file_associated_with_this_curriculum
1494
+ alias location_of_this_curriculum_file? return_file_for_this_curriculum # === location_of_this_curriculum_file?
1495
+
1496
+ # ========================================================================= #
1497
+ # === fetch_this_curriculum
1498
+ #
1499
+ # This method can be used to specifically read in a registered local
1500
+ # curriculum.
1501
+ # ========================================================================= #
1502
+ def fetch_this_curriculum(i, &block)
1503
+ path = map_input_to_this_curriculum_filename(i)
1504
+ _ = readlines_with_proper_encoding(path, &block)
1505
+ if _
1506
+ return _.reject {|line|
1507
+ line.strip.empty? or line.strip.start_with?('#')
1508
+ }.map {|entry|
1509
+ entry.strip!
1510
+ entry.squeeze!(' ')
1511
+ if entry.include?('#')
1512
+ entry = entry.split('#').first.to_s
1513
+ end
1514
+ entry.strip
1515
+ }
1516
+ else
1517
+ false
1518
+ end
1519
+ end
1520
+
1521
+ # ========================================================================= #
1522
+ # === return_title_from_this_curriculum_file
1523
+ #
1524
+ # The first argument to this method should be the abbreviation of
1525
+ # that particular curriculum.
1526
+ #
1527
+ # Note that an Array can also be given as input to this method; this
1528
+ # may be done if a curriculum consists of more than one block.
1529
+ #
1530
+ # Usage example:
1531
+ #
1532
+ # return_title_from_this_curriculum_file(:indi2)
1533
+ #
1534
+ # ========================================================================= #
1535
+ def return_title_from_this_curriculum_file(
1536
+ i,
1537
+ use_a_shorter_name = false
1538
+ )
1539
+ Studium.return_title_from_this_curriculum_file(i, use_a_shorter_name)
1540
+ end; alias return_title_of return_title_from_this_curriculum_file # === return_title_of
1541
+ alias return_pretty_title_of_this_curriculum return_title_from_this_curriculum_file # === return_pretty_title_of_this_curriculum
1542
+ alias return_title_of_this_curriculum return_title_from_this_curriculum_file # === return_title_of_this_curriculum
1543
+
1544
+ # ========================================================================= #
1545
+ # === total_ects_points_passed
1546
+ # ========================================================================= #
1547
+ def total_ects_points_passed(i)
1548
+ Studium.total_ects_points_passed(i)
1549
+ end
1550
+
1551
+ # ========================================================================= #
1552
+ # === directory_to_my_exam_topics
1553
+ # ========================================================================= #
1554
+ def directory_to_my_exam_topics
1555
+ Studium.directory_to_my_exam_topics
1556
+ end
1557
+
1558
+ # ========================================================================= #
1559
+ # === directory_to_the_exam_topics?
1560
+ # ========================================================================= #
1561
+ def directory_to_the_exam_topics?
1562
+ Studium.directory_to_the_exam_topics?
1563
+ end; alias path_to_exam_topic? directory_to_the_exam_topics? # === path_to_exam_topic?
1564
+ alias directory_of_the_exam_topics? directory_to_the_exam_topics? # === directory_of_the_exam_topics?
1565
+
1566
+ # ========================================================================= #
1567
+ # === rename_konsole_tab?
1568
+ # ========================================================================= #
1569
+ def rename_konsole_tab?(
1570
+ i = FILE_RENAME_KONSOLE_TAB
1571
+ )
1572
+ if File.exist? i
1573
+ YAML.load_file(i)
1574
+ else
1575
+ false
1576
+ end
1577
+ end
1578
+
1579
+ # ========================================================================= #
1580
+ # === replace_italic_token_with_default_colour
1581
+ # ========================================================================= #
1582
+ def replace_italic_token_with_default_colour(i, colour_to_use = :royalblue)
1583
+ replace_italic_token_with_this_colour(i, colour_to_use)
1584
+ end
1585
+
1586
+ # ========================================================================= #
1587
+ # === replace_underline_token_with_default_colour
1588
+ # ========================================================================= #
1589
+ def replace_underline_token_with_default_colour(i, colour_to_use = :royalblue)
1590
+ replace_underline_token_with_this_colour(i, colour_to_use)
1591
+ end
1592
+
1593
+ # ========================================================================= #
1594
+ # === replace_underline_token_with_this_colour
1595
+ #
1596
+ # We can use either <ud> or <u>, so we have to check for both variants.
1597
+ # ========================================================================= #
1598
+ def replace_underline_token_with_this_colour(
1599
+ i, use_this_colour = :royalblue # This default colour is rarely in use.
1600
+ )
1601
+ if (i.include?('<ud>') and i.include?('</ud>')) or
1602
+ (i.include?('<u>') and i.include?('</u>'))
1603
+ # ===================================================================== #
1604
+ # Next, set up a non-greedy explicit regex:
1605
+ #
1606
+ # https://rubular.com/r/uNnBwWc35LKjXX
1607
+ #
1608
+ # ===================================================================== #
1609
+ use_this_regex = /<ud?>([-a-züöäA-ZÜÖÄ0-9\/%, \n\.]+?)<\/ud?>/
1610
+ i = i.dup if i.frozen?
1611
+ i.gsub!(
1612
+ use_this_regex,
1613
+ ::Colours.string_underline('\1')+
1614
+ ::Colours.remove_trailing_escape_code(
1615
+ ::Colours.send(use_this_colour.to_sym, '')
1616
+ )
1617
+ )
1618
+ end
1619
+ return i
1620
+ end
1621
+
1622
+ # ========================================================================= #
1623
+ # === roebe_exam_directory?
1624
+ # ========================================================================= #
1625
+ def roebe_exam_directory?
1626
+ "#{RUBY_STUDIUM_HOME_DIR}exam_topics/"
1627
+ end
1628
+
1629
+ # ========================================================================= #
1630
+ # === egrey
1631
+ # ========================================================================= #
1632
+ def egrey(i)
1633
+ e grey(i)
1634
+ end
1635
+
1636
+ # ========================================================================= #
1637
+ # === colourize_percentage
1638
+ #
1639
+ # This method should be used when we wish to display percentage
1640
+ # values on the commandline.
1641
+ # ========================================================================= #
1642
+ def colourize_percentage(i)
1643
+ return seagreen(i) if use_colours? # Used to be cadetblue.
1644
+ return i
1645
+ end
1646
+
1647
+ # ========================================================================= #
1648
+ # === remove_escape_sequences
1649
+ # ========================================================================= #
1650
+ def remove_escape_sequences(i)
1651
+ if Object.const_defined?(:Colours) and
1652
+ ::Colours.respond_to?(:remove_escape_sequences)
1653
+ ::Colours.remove_escape_sequences(i)
1654
+ else
1655
+ i
1656
+ end
1657
+ end
1658
+
1659
+ # ========================================================================= #
1660
+ # === eparse
1661
+ #
1662
+ # The colours for this method are defined within the method body.
1663
+ #
1664
+ # We could also delegate to ::Colours.eparse() instead.
1665
+ # ========================================================================= #
1666
+ def eparse(
1667
+ i,
1668
+ use_colours = use_colours?
1669
+ )
1670
+ if use_colours
1671
+ token = '#'
1672
+ if i.include? token
1673
+ splitted = i.split(token)
1674
+ splitted[-1] = olive(splitted[-1])
1675
+ i = splitted.join(royalblue(token))
1676
+ end
1677
+ end
1678
+ e i
1679
+ end; alias ecolourize eparse # === ecolourize
1680
+
1681
+ # ========================================================================= #
1682
+ # === vertical_bar?
1683
+ # ========================================================================= #
1684
+ def vertical_bar?
1685
+ return '|'
1686
+ end
1687
+
1688
+ # ========================================================================= #
1689
+ # === horizontal_bar?
1690
+ # ========================================================================= #
1691
+ def horizontal_bar?
1692
+ return '―'
1693
+ end
1694
+
1695
+ # ========================================================================= #
1696
+ # === shall_we_make_use_of_unicode_symbols?
1697
+ #
1698
+ # The most common idiom for using this method is actually via:
1699
+ #
1700
+ # if use_unicode_symbols?
1701
+ #
1702
+ # ========================================================================= #
1703
+ def shall_we_make_use_of_unicode_symbols?
1704
+ ::Studium.shall_we_make_use_of_unicode_symbols?
1705
+ end; alias use_unicode_symbols? shall_we_make_use_of_unicode_symbols? # === use_unicode_symbols?
1706
+ alias use_unicode? shall_we_make_use_of_unicode_symbols? # === use_unicode?
1707
+
1708
+ # ========================================================================= #
1709
+ # === unicode_blocks_line
1710
+ #
1711
+ # This method will "draw" a (horizontal) unicode-blocks line, that is,
1712
+ # a line that is "built" from unicode blocks.
1713
+ #
1714
+ # The optional first argument can be used to use a specific colour.
1715
+ #
1716
+ # Usage examples:
1717
+ #
1718
+ # unicode_blocks_line :steelblue
1719
+ # unicode_blocks_line(:steelblue) {{ n_tokens: 84 }}
1720
+ #
1721
+ # ========================================================================= #
1722
+ def unicode_blocks_line(
1723
+ optional_use_this_colour = nil,
1724
+ use_n_tokens = :default, # <- This defaults to 78.
1725
+ use_this_unicode_token = :upper_half_block
1726
+ )
1727
+ case use_n_tokens
1728
+ when :default # Must come before we check for a given block.
1729
+ use_n_tokens = 78
1730
+ end
1731
+ if block_given?
1732
+ yielded = yield
1733
+ if yielded.is_a? Hash
1734
+ if yielded.has_key? :n_tokens
1735
+ use_n_tokens = yielded.delete(:n_tokens)
1736
+ end
1737
+ end
1738
+ end
1739
+ begin
1740
+ require 'roebe/toplevel_methods/unicode/unicode_block_elements.rb'
1741
+ rescue LoadError; end
1742
+ _ = (Roebe.send(use_this_unicode_token) * use_n_tokens)
1743
+ if optional_use_this_colour
1744
+ _ = ::Studium::Colours.send(optional_use_this_colour, _)
1745
+ end
1746
+ return _
1747
+ end
1748
+
1749
+ # ========================================================================= #
1750
+ # === file_lecture_information?
1751
+ # ========================================================================= #
1752
+ def file_lecture_information?
1753
+ ::Studium.file_lecture_information?
1754
+ end
1755
+
1756
+ # ========================================================================= #
1757
+ # === infer_the_namespace
1758
+ #
1759
+ # This will assume the true namespace from the inspectable name.
1760
+ # ========================================================================= #
1761
+ def infer_the_namespace
1762
+ _ = inspect.to_s.delete('<')
1763
+ if _.include? ' '
1764
+ _ = _.split(' ').first.delete('#')
1765
+ if _.include? ':'
1766
+ _ = _.split(':')[0 .. -2].reject {|entry| entry.empty? }.join('::')
1767
+ end
1768
+ end
1769
+ @internal_hash[:namespace] = _ # And assign it here.
1770
+ end
1771
+
1772
+ # ========================================================================= #
1773
+ # === left_arrow
1774
+ # ========================================================================= #
1775
+ def left_arrow?
1776
+ '←'
1777
+ end; alias left_arrow left_arrow? # === left_arrow
1778
+
1779
+ # ========================================================================= #
1780
+ # === is_prüfungsimmanent?
1781
+ #
1782
+ # This method can determine whether a course is "prüfungsimmanent",
1783
+ # aka whether this course requires continuous, mandatory presence
1784
+ # (of the student).
1785
+ #
1786
+ # The argument to this method should be the type of the lecture at
1787
+ # hand, such as "VO" or "VU" or "SE" or "PR", as a String.
1788
+ #
1789
+ # The method will always return a boolean value, aka true or
1790
+ # false. If true is the return value then this means that "yes,
1791
+ # this course requires mandatory presence".
1792
+ # ========================================================================= #
1793
+ def is_prüfungsimmanent?(
1794
+ i, ignore_these_types = nil
1795
+ )
1796
+ Studium.is_prüfungsimmanent?(i, ignore_these_types)
1797
+ end; alias is_a_prüfungsimmanent_course? is_prüfungsimmanent? # === is_a_prüfungsimmanent_course?
1798
+ alias is_this_a_prüfungsimment_course? is_prüfungsimmanent? # === is_this_a_prüfungsimment_course?
1799
+ alias is_this_a_prüfungsimmanent_course? is_prüfungsimmanent? # === is_this_a_prüfungsimmanent_course?
1800
+
1801
+ # ========================================================================= #
1802
+ # === right_arrow?
1803
+ # ========================================================================= #
1804
+ def right_arrow?
1805
+ UNICODE_RIGHT_ARROW
1806
+ end; alias right_arrow right_arrow? # === right_arrow
1807
+ alias rarrow right_arrow? # === rarrow
1808
+ alias rarrow? right_arrow? # === rarrow?
1809
+
1810
+ # ========================================================================= #
1811
+ # === has_lva_dates_registered?
1812
+ # ========================================================================= #
1813
+ def has_lva_dates_registered?(i)
1814
+ return false if i.nil? or i.empty? # Reject impossible values quickly.
1815
+ if i.is_a?(Array) and !i.empty?
1816
+ true
1817
+ else
1818
+ false
1819
+ end
1820
+ end; alias has_any_lva_dates_registered? has_lva_dates_registered? # === has_any_lva_dates_registered?
1821
+
1822
+ # ========================================================================= #
1823
+ # === select_for_prüfungsimmanente_LVs
1824
+ #
1825
+ # We assume the input to this method is a Hash containing all lectures.
1826
+ # ========================================================================= #
1827
+ def select_for_prüfungsimmanente_LVs(i)
1828
+ i.select {|name_of_the_course, inner_hash|
1829
+ type = inner_hash[:type]
1830
+ is_prüfungsimmanent?(type)
1831
+ }
1832
+ end
1833
+
1834
+ # ========================================================================= #
1835
+ # === is_this_lecture_a_practical_course?
1836
+ # ========================================================================= #
1837
+ def is_this_lecture_a_practical_course?(
1838
+ this_lecture,
1839
+ optional_lecture_type = nil
1840
+ )
1841
+ ::Studium.is_this_lecture_a_practical_course?(this_lecture, optional_lecture_type)
1842
+ end; alias is_this_lecture_a_practical_course is_this_lecture_a_practical_course? # === is_this_lecture_a_practical_course
1843
+ alias is_it_a_practical_course? is_this_lecture_a_practical_course? # === is_it_a_practical_course?
1844
+
1845
+ # ========================================================================= #
1846
+ # === beautiful_url
1847
+ #
1848
+ # This method can be used to "beautify" a remote URL, based on shorter
1849
+ # input.
1850
+ #
1851
+ # Until 10.12.2019 this method exclusively used BeautifulUrl.
1852
+ #
1853
+ # Since as of 10.12.2019, this method will actually tap into
1854
+ # Studium.return_url_from() if it is registered.
1855
+ # ========================================================================= #
1856
+ def beautiful_url(i)
1857
+ unless Studium.respond_to? :is_this_url_registered?
1858
+ # ===================================================================== #
1859
+ # Enable support for that .rb file next.
1860
+ # ===================================================================== #
1861
+ require 'studium/toplevel_methods/return_remote_homepage_of_this_lecture.rb'
1862
+ end
1863
+ if Studium.is_this_url_registered?(i)
1864
+ i = Studium.return_url_from(i)
1865
+ else
1866
+ i = BeautifulUrl[i]
1867
+ end
1868
+ if i.is_a? Array
1869
+ i = i.first
1870
+ end
1871
+ return i
1872
+ end; alias return_remote_URL beautiful_url # === return_remote_URL
1873
+
1874
+ # ========================================================================= #
1875
+ # === filter_for_all_passed_exams
1876
+ # ========================================================================= #
1877
+ def filter_for_all_passed_exams(i)
1878
+ return i.select {|a, b|
1879
+ b[:already_solved] and
1880
+ (b[:already_solved] == true)
1881
+ }
1882
+ end
1883
+
1884
+ # ========================================================================= #
1885
+ # === etomato
1886
+ # ========================================================================= #
1887
+ def etomato(i)
1888
+ e tomato(i)
1889
+ end
1890
+
1891
+ # ========================================================================= #
1892
+ # === is_a_master_lecture?
1893
+ # ========================================================================= #
1894
+ def is_a_master_lecture?(i)
1895
+ Studium.is_a_master_lecture?(i)
1896
+ end
1897
+
1898
+ # ========================================================================= #
1899
+ # === try_to_require_the_open_gem
1900
+ # ========================================================================= #
1901
+ def try_to_require_the_open_gem
1902
+ begin
1903
+ require 'open'
1904
+ rescue LoadError; end
1905
+ end
1906
+
1907
+ # ========================================================================= #
1908
+ # === roebe_path_to_file_lecture_information?
1909
+ # ========================================================================= #
1910
+ def roebe_path_to_file_lecture_information?
1911
+ '/home/x/programming/ruby/src/studium/lib/studium/yaml/lecture_information/'\
1912
+ 'lecture_information.yml'
1913
+ end
1914
+
1915
+ # ========================================================================= #
1916
+ # === add_proper_year_entry_to_this_line
1917
+ #
1918
+ # This method will add a proper year entry to a line. It will either
1919
+ # append a year entry - or, which may be more useful, try to insert
1920
+ # the year-entry into a position that fits. The latter will make
1921
+ # use of a regex.
1922
+ #
1923
+ # A test string for the latter is the following:
1924
+ #
1925
+ # "Dienstag 02.10. 11:30-13:00 UZA2 Hörsaal 5 Raum 2Z202 2.OG"
1926
+ #
1927
+ # ========================================================================= #
1928
+ def add_proper_year_entry_to_this_line(line)
1929
+ result = line.dup
1930
+ current_year = Time.now.year
1931
+ use_this_regex = # See: https://rubular.com/r/xV0yNSYhWW
1932
+ /^(.+)(\d{2}\.\d{1,2}\.) (\d{1,2}:\d{1,2}(-| )?\d{1,2}:\d{1,2})(.+)$/
1933
+ if result =~ use_this_regex
1934
+ result.sub!(use_this_regex, '\1\2'+current_year.to_s+', \3\5')
1935
+ else # this here is the simpler case
1936
+ result << current_year # This is the variant that will simply append.
1937
+ end
1938
+ result
1939
+ end
1940
+
1941
+ # ========================================================================= #
1942
+ # === parse_this_line_for_date_entry
1943
+ # ========================================================================= #
1944
+ def parse_this_line_for_date_entry(i)
1945
+ use_this_regex = /\d{2}\.\d{2}\.\d{4}/ # See: https://rubular.com/r/ePRbty9Cjo49xv
1946
+ result = i.scan(use_this_regex).flatten
1947
+ result = result.first if result.is_a? Array
1948
+ return result
1949
+ end
1950
+
1951
+ # ========================================================================= #
1952
+ # === german_weekend_for?
1953
+ # ========================================================================= #
1954
+ def german_weekend_for?(
1955
+ i = '22.11.2022'
1956
+ )
1957
+ if Object.const_defined?(:Roebe)
1958
+ return Roebe.return_german_weekday(i)
1959
+ end
1960
+ end
1961
+
1962
+ # ========================================================================= #
1963
+ # === file_passed_exams_per_month
1964
+ # ========================================================================= #
1965
+ def file_passed_exams_per_month
1966
+ Studium.file_passed_exams_per_month
1967
+ end; alias passed_exams_per_month file_passed_exams_per_month # === passed_exams_per_month
1968
+ alias local_csv_file? file_passed_exams_per_month # === local_csv_file?
1969
+
1970
+ # ========================================================================= #
1971
+ # === try_to_require_the_verbose_truth_gem
1972
+ # ========================================================================= #
1973
+ def try_to_require_the_verbose_truth_gem
1974
+ begin
1975
+ require 'verbose_truth'
1976
+ rescue LoadError
1977
+ end
1978
+ end
1979
+
1980
+ # ========================================================================= #
1981
+ # === try_to_require_html_templates
1982
+ # ========================================================================= #
1983
+ def try_to_require_html_templates
1984
+ begin
1985
+ require 'cyberweb/requires/require_the_html_template.rb'
1986
+ rescue LoadError
1987
+ end
1988
+ end
1989
+
1990
+ # ========================================================================= #
1991
+ # === cliner (cliner tag)
1992
+ #
1993
+ # This method can be used such as in the following example, if a specific
1994
+ # colour is wanted:
1995
+ #
1996
+ # cliner('*', :mediumaquamarine)
1997
+ # cliner { :unicode }
1998
+ #
1999
+ # ========================================================================= #
2000
+ def cliner(
2001
+ which_token_to_use = :default_token,
2002
+ use_this_colour = nil,
2003
+ &block
2004
+ )
2005
+ if which_token_to_use.is_a? Hash # Treat Hashes specially.
2006
+ # ===================================================================== #
2007
+ # === :colours
2008
+ # ===================================================================== #
2009
+ if which_token_to_use.has_key? :colours
2010
+ use_this_colour = which_token_to_use.delete(:colours)
2011
+ which_token_to_use = :default_token
2012
+ # ===================================================================== #
2013
+ # === :colour
2014
+ # ===================================================================== #
2015
+ elsif which_token_to_use.has_key? :colour
2016
+ use_this_colour = which_token_to_use.delete(:colour)
2017
+ which_token_to_use = :default_token
2018
+ end
2019
+ end
2020
+ case which_token_to_use
2021
+ # ======================================================================= #
2022
+ # === :default_token
2023
+ # ======================================================================= #
2024
+ when :default_token
2025
+ which_token_to_use = '='
2026
+ end
2027
+ # ======================================================================= #
2028
+ # === Handle blocks given to this method next
2029
+ # ======================================================================= #
2030
+ if block_given?
2031
+ yielded = yield
2032
+ case yielded
2033
+ # ===================================================================== #
2034
+ # === :unicode
2035
+ # ===================================================================== #
2036
+ when :unicode
2037
+ begin
2038
+ require 'roebe/toplevel_methods/unicode/unicode_block_elements.rb'
2039
+ which_token_to_use = Roebe.horizontal_double_bar.dup
2040
+ rescue LoadError; end
2041
+ else
2042
+ use_this_colour = :mediumaquamarine
2043
+ end
2044
+ end
2045
+ result = (which_token_to_use * 80)
2046
+ if use_this_colour.is_a? Symbol
2047
+ if use_this_colour.to_s.include?('konsole_') or
2048
+ is_this_colour_a_html_colour?(use_this_colour)
2049
+ unless use_this_colour.to_s.include? '_colour_'
2050
+ use_this_colour = use_this_colour.to_s
2051
+ use_this_colour.sub!(/_/,'_colour_')
2052
+ end
2053
+ result = COLOURS.send(use_this_colour, result) if COLOURS
2054
+ end
2055
+ end
2056
+ e result
2057
+ end
2058
+
2059
+ # ========================================================================= #
2060
+ # === german_yes_or_no
2061
+ # ========================================================================= #
2062
+ def german_yes_or_no(i)
2063
+ case i
2064
+ when true
2065
+ 'ja'
2066
+ when false
2067
+ 'nein'
2068
+ end
2069
+ end
2070
+
2071
+ # ========================================================================= #
2072
+ # === return_german_weekday_of?
2073
+ # ========================================================================= #
2074
+ def return_german_weekday_of?(i)
2075
+ weekday?(i, :german)
2076
+ end
2077
+
2078
+ # ========================================================================= #
2079
+ # === return_german_name_for_this_english_month
2080
+ # ========================================================================= #
2081
+ def return_german_name_for_this_english_month(i)
2082
+ array = MONTH_NAME_ALIASES_GERMAN_TO_ENGLISH.invert
2083
+ return array[i]
2084
+ end; alias to_german_month return_german_name_for_this_english_month # === to_german_month
2085
+
2086
+ # ========================================================================= #
2087
+ # === rinstall2
2088
+ #
2089
+ # This method can be used to perform an install-process via oldschool
2090
+ # setup.rb.
2091
+ # ========================================================================= #
2092
+ def rinstall2
2093
+ cpruby
2094
+ system 'ruby setup.rb --quiet config'
2095
+ system 'ruby setup.rb --quiet setup'
2096
+ system 'ruby setup.rb --quiet install'
2097
+ delete_file 'setup.rb'
2098
+ delete_file 'InstalledFiles'
2099
+ delete_file '.config'
2100
+ end; alias r2 rinstall2 # === r2
2101
+
2102
+ # ========================================================================= #
2103
+ # === silently_open_in_browser
2104
+ #
2105
+ # This method can accept Strings such as
2106
+ # '/home/x/Temp/studium/html/timetable.html#today'.
2107
+ # ========================================================================= #
2108
+ def silently_open_in_browser(into)
2109
+ try_to_require_the_open_gem unless Object.const_defined?(:Open)
2110
+ ::Open.in_browser(into) { :be_silent }
2111
+ end
2112
+
2113
+ # ========================================================================= #
2114
+ # === read_this_file_with_default_encoding
2115
+ #
2116
+ # This method will read in a file, that should ideally exist, in the
2117
+ # default project-wide encoding.
2118
+ #
2119
+ # A few aliases exist to this method, such as "read_this_file()".
2120
+ # ========================================================================= #
2121
+ def read_this_file_with_default_encoding(
2122
+ this_file
2123
+ )
2124
+ File.read(this_file, encoding: ::Studium.main_encoding?)
2125
+ end; alias read_as_string_with_default_encoding read_this_file_with_default_encoding # === read_as_string_with_default_encoding
2126
+ alias read_file read_this_file_with_default_encoding # === read_file
2127
+ alias read_this_file read_this_file_with_default_encoding # === read_this_file
2128
+ alias read_file_with_default_encoding read_this_file_with_default_encoding # === read_file_with_default_encoding
2129
+ alias read_in_with_default_encoding read_this_file_with_default_encoding # === read_in_with_default_encoding
2130
+
2131
+ # ========================================================================= #
2132
+ # === german_date_notation
2133
+ #
2134
+ # Give a Range as input, and it will give us back a String that
2135
+ # shows german date notation, aka DD.MM.YYYY.
2136
+ # ========================================================================= #
2137
+ def german_date_notation(
2138
+ i, use_this_token_as_separator = '-'
2139
+ )
2140
+ # ======================================================================= #
2141
+ # === Handle Range objects next
2142
+ # ======================================================================= #
2143
+ if i.is_a? Range
2144
+ start_date = i.begin
2145
+ end_date = i.end
2146
+ start_day = start_date.day.to_s.rjust(2, '0')
2147
+ start_month = start_date.month.to_s.rjust(2, '0')
2148
+ start_year = start_date.year.to_s
2149
+ end_day = end_date.day.to_s.rjust(2, '0')
2150
+ end_month = end_date.month.to_s.rjust(2, '0')
2151
+ end_year = end_date.year.to_s
2152
+ i = start_day+'.'+start_month+'.'+start_year+' '+
2153
+ use_this_token_as_separator+' '+
2154
+ end_day+'.'+end_month+'.'+end_year
2155
+ # ======================================================================= #
2156
+ # === Handle Time objects next
2157
+ #
2158
+ # This requires no token.
2159
+ # ======================================================================= #
2160
+ elsif i.is_a? Time
2161
+ i = "#{i.day.to_s.rjust(2, '0')}."\
2162
+ "#{i.month.to_s.rjust(2, '0')}."\
2163
+ "#{i.year.to_s}"
2164
+ end
2165
+ return i
2166
+ end; alias german_notation german_date_notation # === german_notation
2167
+ alias to_german_date german_date_notation # === to_german_date
2168
+ alias german_formatting_for_the_date german_date_notation # === german_formatting_for_the_date
2169
+
2170
+ # ========================================================================= #
2171
+ # === show_todays_date
2172
+ # ========================================================================= #
2173
+ def show_todays_date
2174
+ e "Today is the #{slateblue(today?)} (#{lightgreen(weekday?)})"
2175
+ e
2176
+ end
2177
+
2178
+ # ========================================================================= #
2179
+ # === ensure_that_a_base_directory_exists_for_this_file
2180
+ #
2181
+ # This method expects a file path, such as "/tmp/foo/bar.html".
2182
+ #
2183
+ # If such a file path is passed to this method then this
2184
+ # method will try to ensure that /tmp/foo/ exists (the directory).
2185
+ # ========================================================================= #
2186
+ def ensure_that_a_base_directory_exists_for_this_file(i)
2187
+ _ = File.dirname(i)
2188
+ unless File.directory?(_)
2189
+ FileUtils.mkdir_p(_)
2190
+ end
2191
+ end
2192
+
2193
+ # ========================================================================= #
2194
+ # === does_this_line_include_a_german_weekday?
2195
+ # ========================================================================= #
2196
+ def does_this_line_include_a_german_weekday?(i)
2197
+ ARRAY_GERMAN_WEEKDAYS.any? {|this_german_weekday|
2198
+ i.include? this_german_weekday
2199
+ }
2200
+ end; alias does_this_string_include_a_german_weekday? does_this_line_include_a_german_weekday? # === does_this_string_include_a_german_weekday?
2201
+
2202
+ # ========================================================================= #
2203
+ # === is_german_weekday?
2204
+ # ========================================================================= #
2205
+ def is_german_weekday?(i)
2206
+ ARRAY_GERMAN_WEEKDAYS.include?(i)
2207
+ end
2208
+
2209
+ # ========================================================================= #
2210
+ # === is_a_weekday?
2211
+ #
2212
+ # This method will return true if the input is a String that represents
2213
+ # a weekday, such as "Monday". Otherwise, false will be returned.
2214
+ #
2215
+ # Both german and english variants are allowed here.
2216
+ # ========================================================================= #
2217
+ def is_a_weekday?(i = 'Montag')
2218
+ result = false
2219
+ if ARRAY_GERMAN_WEEKDAYS.include? i
2220
+ result = true
2221
+ elsif ARRAY_ENGLISH_WEEKDAYS.include? i
2222
+ result = true
2223
+ end
2224
+ return result
2225
+ end
2226
+
2227
+ # ========================================================================= #
2228
+ # === german_weekdays?
2229
+ # ========================================================================= #
2230
+ def german_weekdays?
2231
+ ARRAY_GERMAN_WEEKDAYS
2232
+ end
2233
+
2234
+ # ========================================================================= #
2235
+ # === does_this_line_include_an_english_weekday?
2236
+ # ========================================================================= #
2237
+ def does_this_line_include_an_english_weekday?(i)
2238
+ ARRAY_ENGLISH_WEEKDAYS.any? {|this_english_weekday|
2239
+ i.include? this_english_weekday
2240
+ }
2241
+ end
2242
+
2243
+ # ========================================================================= #
2244
+ # === english_to_german_weekday
2245
+ #
2246
+ # This method will simply convert e. g. "Monday" into "Montag". In other
2247
+ # words: it will convert from the english name for a day into the
2248
+ # german name of that day.
2249
+ # ========================================================================= #
2250
+ def english_to_german_weekday(english_day)
2251
+ ENGLISH_TO_GERMAN_WEEKDAYS[english_day]
2252
+ end; alias english_to_german english_to_german_weekday # === english_to_german
2253
+
2254
+ # ========================================================================= #
2255
+ # === n_days_difference_from_today_to_this_day
2256
+ #
2257
+ # This method will return a number, which is the amount of days between
2258
+ # weekdays.
2259
+ #
2260
+ # The days are numbered like this:
2261
+ #
2262
+ # Monday: 1
2263
+ # Tuesday: 2
2264
+ # Wednesday: 3
2265
+ # Thursday: 4
2266
+ # Friday: 5
2267
+ # Saturday: 6
2268
+ # Sunday: 0
2269
+ #
2270
+ # So, how to calculate the time difference to the next day?
2271
+ #
2272
+ # Well, say we have the current day be a Wednesday, and the day that is
2273
+ # to be compared, a Friday. The difference is thus (5 - 3 = 2). If the
2274
+ # current day is a Saturday, and the input-day is a Friday, then
2275
+ # the difference must be 5.
2276
+ #
2277
+ # If we have, for example, "Friday" to "Tuesday", then this method
2278
+ # should return the number 4, because the distance is that: Friday,
2279
+ # Saturday, Sunday and Monday (the start day has to be included, as
2280
+ # lectures can happen on that day still, e. g. if you check early
2281
+ # in the morning, you could still have courses in the evening
2282
+ # slots scheduled).
2283
+ # ========================================================================= #
2284
+ def n_days_difference_from_today_to_this_day(
2285
+ time_now = Time.now,
2286
+ name_of_the_future_day # ← This ought to be a String, such as "Monday".
2287
+ )
2288
+ n_days_difference = 0
2289
+ weekday_as_number = time_now.wday
2290
+ name_of_the_future_day = name_of_the_future_day.dup if name_of_the_future_day.frozen?
2291
+ name_of_the_future_day.strip! # We better strip that input.
2292
+ start_day = Date::DAYNAMES[weekday_as_number]
2293
+ # ======================================================================= #
2294
+ # The next is simply a hardcoded table. We will begin with the
2295
+ # future day.
2296
+ # ======================================================================= #
2297
+ n_days_difference =
2298
+ case start_day
2299
+ when 'Monday'
2300
+ case name_of_the_future_day
2301
+ when 'Tuesday' then 1
2302
+ when 'Wednesday' then 2
2303
+ when 'Thursday' then 3
2304
+ when 'Friday' then 4
2305
+ when 'Saturday' then 5
2306
+ when 'Sunday' then 6
2307
+ end
2308
+ when 'Tuesday'
2309
+ case name_of_the_future_day
2310
+ when 'Wednesday' then 1
2311
+ when 'Thursday' then 2
2312
+ when 'Friday' then 3
2313
+ when 'Saturday' then 4
2314
+ when 'Sunday' then 5
2315
+ when 'Monday' then 6
2316
+ end
2317
+ when 'Wednesday'
2318
+ case name_of_the_future_day
2319
+ when 'Thursday' then 1
2320
+ when 'Friday' then 2
2321
+ when 'Saturday' then 3
2322
+ when 'Sunday' then 4
2323
+ when 'Monday' then 5
2324
+ when 'Tuesday' then 6
2325
+ end
2326
+ when 'Thursday'
2327
+ case name_of_the_future_day
2328
+ when 'Friday' then 1
2329
+ when 'Saturday' then 2
2330
+ when 'Sunday' then 3
2331
+ when 'Monday' then 4
2332
+ when 'Tuesday' then 5
2333
+ when 'Wednesday' then 6
2334
+ end
2335
+ when 'Friday'
2336
+ case name_of_the_future_day
2337
+ when 'Saturday' then 1
2338
+ when 'Sunday' then 2
2339
+ when 'Monday' then 3
2340
+ when 'Tuesday' then 4
2341
+ when 'Wednesday' then 5
2342
+ when 'Thursday' then 6
2343
+ end
2344
+ when 'Saturday'
2345
+ case name_of_the_future_day
2346
+ when 'Sunday' then 1
2347
+ when 'Monday' then 2
2348
+ when 'Tuesday' then 3
2349
+ when 'Wednesday' then 4
2350
+ when 'Thursday' then 5
2351
+ when 'Friday' then 6
2352
+ end
2353
+ when 'Sunday'
2354
+ case name_of_the_future_day
2355
+ when 'Monday' then 1
2356
+ when 'Tuesday' then 2
2357
+ when 'Wednesday' then 3
2358
+ when 'Thursday' then 4
2359
+ when 'Friday' then 5
2360
+ when 'Saturday' then 6
2361
+ end
2362
+ end
2363
+ return n_days_difference
2364
+ end
2365
+
2366
+ # ========================================================================= #
2367
+ # === return_lva_number_of_this_lecture
2368
+ # ========================================================================= #
2369
+ def return_lva_number_of_this_lecture(this_lecture)
2370
+ ::Studium.return_lva_number_of_this_lecture(this_lecture)
2371
+ end
2372
+
2373
+ # ========================================================================= #
2374
+ # === csv_file?
2375
+ #
2376
+ # This method is only useful on my home setup.
2377
+ # ========================================================================= #
2378
+ def csv_file?
2379
+ Studium.file_passed_exams_per_month
2380
+ end
2381
+
2382
+ # ========================================================================= #
2383
+ # === does_this_line_include_a_html_colour?
2384
+ # ========================================================================= #
2385
+ def does_this_line_include_a_html_colour?(i)
2386
+ ::Colours.does_this_line_include_a_html_colour?(i)
2387
+ end
2388
+
2389
+ # ========================================================================= #
2390
+ # === translate_dd_mm_yyyy_to_weekday
2391
+ #
2392
+ # This method will return the weekday of a given dd.mm.yyyy date.
2393
+ #
2394
+ # If the given input is, for example, the String '25.02.2019', then
2395
+ # this method will return the String 'Monday'.
2396
+ # ========================================================================= #
2397
+ def translate_dd_mm_yyyy_to_weekday(
2398
+ i = '25.02.2020'
2399
+ )
2400
+ weekday?(i)
2401
+ end; alias translate_dd_mm_yyy_to_weekday translate_dd_mm_yyyy_to_weekday # === translate_dd_mm_yyy_to_weekday
2402
+
2403
+ # ========================================================================= #
2404
+ # === hh_mm_ss_dd_mm_yyyy
2405
+ # ========================================================================= #
2406
+ def hh_mm_ss_dd_mm_yyyy(i)
2407
+ "#{hh_mm_ss(i)}-#{dd_mm_yyyy(i)}"
2408
+ end
2409
+
2410
+ # ========================================================================= #
2411
+ # === replace_all_html_colours_in_this
2412
+ #
2413
+ # This method will replace all HTML colours, such as <slateblue>, with
2414
+ # the corresponding RGB colour variant for the commandline. Typically
2415
+ # this refers to a terminal such as the KDE konsole, and a shell such
2416
+ # as bash (although other shells are fine too, and many other terminals,
2417
+ # such as the gnome-terminal, most likely will work fine as well - but
2418
+ # it is optimized for the KDE konsole).
2419
+ #
2420
+ # This method should only be called after a prior check was done, to
2421
+ # determine whether the given input String at hand does indeed
2422
+ # include a valid HTML colour. This can be done via a call to
2423
+ # the method called line_contains_a_valid_html_colour?().
2424
+ # ========================================================================= #
2425
+ def replace_all_html_colours_in_this(
2426
+ i,
2427
+ use_this_colour_for_the_default_colour = colour_for_questions?
2428
+ )
2429
+ # ======================================================================= #
2430
+ # bl $RUBY_COLOURS/toplevel_methods/replace_all_html_colours_in_this_line.rb
2431
+ # ======================================================================= #
2432
+ ::Colours.replace_all_html_colours_in_this_line(
2433
+ i, use_this_colour_for_the_default_colour
2434
+ )
2435
+ end
2436
+
2437
+ # ========================================================================= #
2438
+ # === return_local_path_of_this_pwdstud
2439
+ # ========================================================================= #
2440
+ def return_local_path_of_this_pwdstud(i = 1)
2441
+ Studium.return_local_path_of_this_pwdstud(i)
2442
+ end
2443
+
2444
+ # ========================================================================= #
2445
+ # === already_solved_this_lva_number?
2446
+ # ========================================================================= #
2447
+ def already_solved_this_lva_number?(i)
2448
+ Studium.already_solved_this_lva_number?(i)
2449
+ end
2450
+
2451
+ # ========================================================================= #
2452
+ # === debug?
2453
+ # ========================================================================= #
2454
+ def debug?
2455
+ @internal_hash[:debug]
2456
+ end
2457
+
2458
+ # ========================================================================= #
2459
+ # === german_weekday?
2460
+ #
2461
+ # This method will return a german weekday, for the given input. The
2462
+ # input should be the specific wday at hand.
2463
+ # ========================================================================= #
2464
+ def german_weekday?(
2465
+ i = Date.today.wday
2466
+ )
2467
+ weekday?(i, :german)
2468
+ end; alias weekday_at german_weekday? # === weekday_at
2469
+ alias german_weekday german_weekday? # === german_weekday
2470
+
2471
+ # ========================================================================= #
2472
+ # === directory_to_the_exam_topics?
2473
+ #
2474
+ # This method will point to the directory where all exam topics
2475
+ # are normally kept; it is simply a "wrapper-method".
2476
+ # ========================================================================= #
2477
+ def directory_to_the_exam_topics?
2478
+ Studium.directory_to_the_exam_topics?
2479
+ end; alias exam_topics_directory? directory_to_the_exam_topics? # === exam_topics_directory?
2480
+ alias exam_topic_directory? directory_to_the_exam_topics? # === exam_topic_directory?
2481
+
2482
+ # ========================================================================= #
2483
+ # === opnn
2484
+ #
2485
+ # The method also handles blocks.
2486
+ # ========================================================================= #
2487
+ def opnn(
2488
+ i = namespace?,
2489
+ &block
2490
+ )
2491
+ if use_opn?
2492
+ if i.is_a? String # "Turn" it into a Hash here.
2493
+ i = { namespace: i }
2494
+ end
2495
+ Opn.opn(i, &block)
2496
+ end
2497
+ end
2498
+
2499
+ # ========================================================================= #
2500
+ # === is_this_a_valid_html_colour?
2501
+ #
2502
+ # This method will let us know whether the given input is a valid (aka
2503
+ # registered) "html colour". An example for this would be the String
2504
+ # 'slateblue'.
2505
+ # ========================================================================= #
2506
+ def is_this_a_valid_html_colour?(i)
2507
+ ::Studium.is_this_a_valid_html_colour?(i)
2508
+ end; alias is_this_colour_a_html_colour? is_this_a_valid_html_colour? # === is_this_colour_a_html_colour?
2509
+
2510
+ # ========================================================================= #
2511
+ # === remove_weekday_names_from
2512
+ #
2513
+ # This method will remove Strings such as "Monday" or "Montag" from
2514
+ # the given input argument.
2515
+ # ========================================================================= #
2516
+ def remove_weekday_names_from(i)
2517
+ Studium.remove_weekday_names_from(i)
2518
+ end; alias remove_weekname_from remove_weekday_names_from # === remove_weekname_from
2519
+ alias remove_weekdays remove_weekday_names_from # === remove_weekdays
2520
+ alias remove_weekday_names_from remove_weekday_names_from # === remove_weekday_names_from
2521
+ alias remove_weeknames_from remove_weekday_names_from # === remove_weeknames_from
2522
+ alias remove_weeknames remove_weekday_names_from # === remove_weeknames
2523
+ alias remove_weekday_name remove_weekday_names_from # === remove_weekday_name
2524
+
2525
+ # ========================================================================= #
2526
+ # === return_name_of_the_weekday
2527
+ #
2528
+ # This method can be used to return an associated weekday to a specific
2529
+ # date, such as '22.02.2018'. The format has to be in dd.mm.yyyy.
2530
+ #
2531
+ # As mnemonic-helper, Roebe.return_german_weekday "22.11.2022" would
2532
+ # yield the String "Dienstag".
2533
+ # ========================================================================= #
2534
+ def return_name_of_the_weekday(
2535
+ i = :today
2536
+ )
2537
+ begin
2538
+ require 'roebe/constants/time.rb'
2539
+ rescue LoadError; end
2540
+ case i
2541
+ # ======================================================================= #
2542
+ # === :today
2543
+ # ======================================================================= #
2544
+ when :today
2545
+ i = Roebe.return_german_weekday(i) if Object.const_defined? :Roebe
2546
+ end
2547
+ if i.include? ','
2548
+ splitted = i.split(',')
2549
+ first = splitted.first
2550
+ if first.count('.') > 1
2551
+ return Roebe.return_german_weekday(first) if Object.const_defined? :Roebe
2552
+ end
2553
+ else
2554
+ return i
2555
+ end
2556
+ end; alias return_weekday return_name_of_the_weekday # === return_weekday
2557
+
2558
+ # ========================================================================= #
2559
+ # === has_year_entry?
2560
+ #
2561
+ # This method will return a Boolean.
2562
+ #
2563
+ # It will return true if the line has a year entry such as '2018'; and
2564
+ # it will return false, otherwise.
2565
+ # ========================================================================= #
2566
+ def has_year_entry?(this_line)
2567
+ this_line =~ /\d{4}/ # If this line has at the least one entry with 4 numbers.
2568
+ end; alias this_line_has_a_year_entry? has_year_entry? # === has_year_entry?
2569
+
2570
+ # ========================================================================= #
2571
+ # === do_these_curricula_include_both_a_bachelor_and_a_master_curriculum?(i)
2572
+ #
2573
+ # The input to this method should be an Array.
2574
+ # ========================================================================= #
2575
+ def do_these_curricula_include_both_a_bachelor_and_a_master_curriculum?(i)
2576
+ result = false
2577
+ if i.any? {|entry| entry.start_with?('033')} and
2578
+ i.any? {|entry| entry.start_with?('066')}
2579
+ result = true
2580
+ end
2581
+ return result
2582
+ end
2583
+
2584
+ # ========================================================================= #
2585
+ # === bachelor_master_or_diploma
2586
+ #
2587
+ # For a given solved lecture, we will determine whether it belongs
2588
+ # to a Bachelor (B), Master (M) or Diploma (D) curriculum.
2589
+ #
2590
+ # For the line:
2591
+ #
2592
+ # 13.05.2020 | 1.0 | 1.0 | 1 | BOKU | M | SE | 940003 | 2020S | Emerging Topics in RNA Biology (in Eng.)
2593
+ # 0 1 2 3 4 5
2594
+ #
2595
+ # It would be at 5.
2596
+ # ========================================================================= #
2597
+ def bachelor_master_or_diploma(
2598
+ this_lecture, dataset = nil
2599
+ )
2600
+ if dataset.nil? and File.exist? Studium.file_passed_exams_per_month
2601
+ dataset = File.readlines(Studium.file_passed_exams_per_month).reject {|line|
2602
+ line.strip.empty? or
2603
+ line.strip.start_with?('#')
2604
+ }
2605
+ end
2606
+ selection = dataset.select {|line|
2607
+ splitted = this_lecture.split(' ')
2608
+ lecture_id = splitted.first
2609
+ course_name = splitted[1..-1].join(' ').strip
2610
+ line.include?(lecture_id) and
2611
+ line.include?(course_name)
2612
+ }
2613
+ if selection.empty?
2614
+ '(unknown)'
2615
+ else
2616
+ selection = selection.first
2617
+ return selection.split('|')[5].strip
2618
+ end
2619
+ end
2620
+
2621
+ # ========================================================================= #
2622
+ # === return_name_of_this_curriculum
2623
+ #
2624
+ # This method will return the official name of a curriculum. In order
2625
+ # to achieve this, the method will read the file, and grab the second
2626
+ # line, which should contain the name of the curriculum at hand.
2627
+ #
2628
+ # This method will NOT remove strings such as "Bachelorcurriculum"
2629
+ # or "Mastercurriculum", due to the individual vector-curriculum
2630
+ # having the very same name (Bachelor + Master).
2631
+ # ========================================================================= #
2632
+ def return_name_of_this_curriculum(i)
2633
+ file = return_file_for_this_curriculum(i)
2634
+ if file.nil?
2635
+ e "Something went wrong for the input #{steelblue(i)}."
2636
+ e 'No match could be found for it. Are you sure that it must exist?'
2637
+ exit
2638
+ elsif File.exist? file
2639
+ dataset = readlines_with_proper_encoding(file)
2640
+ name = dataset[1].delete('#=').strip
2641
+ return name
2642
+ end
2643
+ end; alias return_long_name_of_this_curriculum return_name_of_this_curriculum # === return_long_name_of_this_curriculum
2644
+
2645
+ # ========================================================================= #
2646
+ # === rds
2647
+ # ========================================================================= #
2648
+ def rds(i)
2649
+ i.squeeze('/')
2650
+ end
2651
+
2652
+ # ========================================================================= #
2653
+ # === return_all_registered_curricula
2654
+ # ========================================================================= #
2655
+ def return_all_registered_curricula
2656
+ Studium.return_registered_standalone_curricula
2657
+ end
2658
+
2659
+ # ========================================================================= #
2660
+ # === return_dataset_from_this_curriculum_file
2661
+ # ========================================================================= #
2662
+ def return_dataset_from_this_curriculum_file(i)
2663
+ return Studium.return_dataset_from_this_curriculum_file(i)
2664
+ end; alias return_dataset_for_this_curriculum_file return_dataset_from_this_curriculum_file # === return_dataset_for_this_curriculum_file
2665
+ alias return_dataset_from_this_curriculum return_dataset_from_this_curriculum_file # === return_dataset_from_this_curriculum
2666
+ alias return_this_curriculum return_dataset_from_this_curriculum_file # === return_this_curriculum
2667
+
2668
+ # ========================================================================= #
2669
+ # === ensure_that_the_log_directory_exists
2670
+ #
2671
+ # This method will try to make sure that the log directory exists.
2672
+ # ========================================================================= #
2673
+ def ensure_that_the_log_directory_exists
2674
+ _ = log_dir?
2675
+ unless File.directory? _
2676
+ mkdir(_)
2677
+ end
2678
+ unless File.directory? "#{_}html/"
2679
+ mkdir("#{_}html/")
2680
+ end
2681
+ end
2682
+
2683
+ # ========================================================================= #
2684
+ # === from_curriculum_id_to_university
2685
+ #
2686
+ # This method will translate from the curriculum-ID to the university.
2687
+ # So it will return a String such as "BOKU".
2688
+ # ========================================================================= #
2689
+ def from_curriculum_id_to_university(id)
2690
+ ::Studium.from_curriculum_id_to_university(id)
2691
+ end; alias from_curriculum_number_to_university from_curriculum_id_to_university # === from_curriculum_number_to_university
2692
+ alias which_university? from_curriculum_id_to_university # === which_university?
2693
+
2694
+ # ========================================================================= #
2695
+ # === return_name_of_this_curriculum_based_on_its_id_number
2696
+ #
2697
+ # The input to this method should be the ID of a curriculum number,
2698
+ # ideally as a String, such as '033290'.
2699
+ # ========================================================================= #
2700
+ def return_name_of_this_curriculum_based_on_its_id_number(i)
2701
+ ::Studium.map_curriculum_number_to_curriculum_name(i)
2702
+ end; alias from_curriculum_id_to_curriculum_name return_name_of_this_curriculum_based_on_its_id_number # === from_curriculum_id_to_curriculum_name
2703
+ alias return_curriculum_name_of_this_curriculum_number return_name_of_this_curriculum_based_on_its_id_number # === return_curriculum_name_of_this_curriculum_number
2704
+ alias curriculum_number_to_curriculum_name return_name_of_this_curriculum_based_on_its_id_number # === curriculum_number_to_curriculum_name
2705
+ alias name_of_this_curriculum? return_name_of_this_curriculum_based_on_its_id_number # === name_of_this_curriculum?
2706
+ alias return_name_of_the_curriculum_based_on_this_curriculum_id return_name_of_this_curriculum_based_on_its_id_number # === return_name_of_the_curriculum_based_on_this_curriculum_id
2707
+ alias return_name_of_the_curriculum return_name_of_this_curriculum_based_on_its_id_number # === return_name_of_the_curriculum
2708
+ alias turn_id_to_curriculum_name return_name_of_this_curriculum_based_on_its_id_number # === turn_id_to_curriculum_name
2709
+
2710
+ # ========================================================================= #
2711
+ # === return_all_bachelor_lectures
2712
+ #
2713
+ # This method will simply return all bachelor-lectures.
2714
+ # ========================================================================= #
2715
+ def return_all_bachelor_lectures(
2716
+ from_this_dataset = ::Studium.main_dataset?
2717
+ )
2718
+ if from_this_dataset.nil?
2719
+ ::Studium.initialize_main_dataset
2720
+ from_this_dataset = ::Studium.main_dataset?
2721
+ end
2722
+ from_this_dataset.select {|name_of_the_lecture, inner_hash|
2723
+ array = inner_hash['curricula']
2724
+ is_a_bachelor_lecture?(array)
2725
+ }
2726
+ end
2727
+
2728
+ # ========================================================================= #
2729
+ # === has_a_bachelor_and_a_master_curriculum?
2730
+ # ========================================================================= #
2731
+ def has_a_bachelor_and_a_master_curriculum?(i)
2732
+ has_a_bachelor_curriculum?(i) and has_a_master_curriculum?(i)
2733
+ end
2734
+
2735
+ # ========================================================================= #
2736
+ # === available_topics_as_short_name
2737
+ # ========================================================================= #
2738
+ def available_topics_as_short_name
2739
+ ::Studium::Exams.all_topics_as_short_name.sort
2740
+ end; alias available_topics? available_topics_as_short_name # === available_topics?
2741
+ alias exam_topics? available_topics_as_short_name # === exam_topics?
2742
+ alias return_all_exam_topics available_topics_as_short_name # === return_all_exam_topics
2743
+ alias available_exam_topics? available_topics_as_short_name # === available_exam_topics?
2744
+
2745
+ # ========================================================================= #
2746
+ # === return_n_exam_questions_in
2747
+ #
2748
+ # This method will return how many exam questions are in the given topic
2749
+ # xyz.
2750
+ # ========================================================================= #
2751
+ def return_n_exam_questions_in(this_topic)
2752
+ Studium::Exams.return_n_questions_in_this_topic(this_topic)
2753
+ end
2754
+
2755
+ # ========================================================================= #
2756
+ # === return_lectures_with_at_the_least_one_upcoming_exam
2757
+ #
2758
+ # This method will return all lectures that have at the least
2759
+ # one upcoming exam entry. In this context "upcoming" refers
2760
+ # to an exam date that comes after today (or any day before
2761
+ # today).
2762
+ # ========================================================================= #
2763
+ def return_lectures_with_at_the_least_one_upcoming_exam
2764
+ today = Time.now
2765
+ return_sanitized_dataset_from_the_file_lecture_information.select {|name_of_the_course, hash_dataset|
2766
+ if hash_dataset.has_key? 'exams'
2767
+ exams = hash_dataset['exams']
2768
+ if exams.is_a? Array
2769
+ exams = exams.first
2770
+ end
2771
+ exams = remove_german_weekdays(exams)
2772
+ exams.delete!(',')
2773
+ if exams.include? 'Ort:'
2774
+ exams = exams.split('Ort:').first.to_s
2775
+ end
2776
+ # =================================================================== #
2777
+ # The next line can be problematic, if the entry is incorrect.
2778
+ # Hence the rescue-clause.
2779
+ # =================================================================== #
2780
+ begin
2781
+ time_parsed = Time.parse(exams)
2782
+ rescue Exception => error
2783
+ pp error
2784
+ e rev+'The original input was: '+
2785
+ tomato(hash_dataset['exams'])
2786
+ e 'The modified input was: '+
2787
+ steelblue(exams)
2788
+ exit
2789
+ end
2790
+ today < time_parsed # Check that the courses are not too old.
2791
+ else
2792
+ false
2793
+ end
2794
+ }
2795
+ end
2796
+
2797
+ # ========================================================================= #
2798
+ # === read_dataset_from_a_curriculum_file
2799
+ # ========================================================================= #
2800
+ def read_dataset_from_a_curriculum_file(
2801
+ i,
2802
+ optional_commands = :remove_comments
2803
+ )
2804
+ Studium.read_dataset_from_a_curriculum_file(i, optional_commands)
2805
+ end
2806
+
2807
+ # ========================================================================= #
2808
+ # === has_a_bachelor_curriculum?
2809
+ #
2810
+ # This method will return true if the given Array has any bachelor
2811
+ # curriculum; and it will return false otherwise.
2812
+ # ========================================================================= #
2813
+ def has_a_bachelor_curriculum?(array)
2814
+ Studium.has_a_bachelor_curriculum?(array)
2815
+ end; alias has_a_bachelor_curriculum_entry? has_a_bachelor_curriculum? # === has_a_bachelor_curriculum_entry?
2816
+ alias is_a_bachelor_lecture? has_a_bachelor_curriculum? # === is_a_bachelor_curriculum?
2817
+ alias is_a_bachelor_curriculum? has_a_bachelor_curriculum? # === is_a_bachelor_curriculum?
2818
+ alias does_this_include_a_bachelor_curriculum? has_a_bachelor_curriculum? # === does_this_include_a_bachelor_curriculum?
2819
+
2820
+ # ========================================================================= #
2821
+ # === map_input_to_this_curriculum_filename
2822
+ # ========================================================================= #
2823
+ def map_input_to_this_curriculum_filename(i)
2824
+ ::Studium.map_input_to_this_curriculum_filename(i)
2825
+ end
2826
+
2827
+ # ========================================================================= #
2828
+ # === chmod
2829
+ #
2830
+ # The second argument can also be an Array.
2831
+ # ========================================================================= #
2832
+ def chmod(
2833
+ new_mode = 0644,
2834
+ which_file = 'LINKS.md'
2835
+ )
2836
+ FileUtils.chmod(new_mode, which_file)
2837
+ end
2838
+
2839
+ # ========================================================================= #
2840
+ # === does_this_line_start_with_a_german_weekday?
2841
+ # ========================================================================= #
2842
+ def does_this_line_start_with_a_german_weekday?(i)
2843
+ result = false
2844
+ if i.include?(' ')
2845
+ i = i.dup
2846
+ if i.start_with?(' - "')
2847
+ i[0, 4] = ''
2848
+ end
2849
+ splitted = i.split(' ')
2850
+ first = splitted.first
2851
+ if is_german_weekday?(first)
2852
+ result = true
2853
+ end
2854
+ end
2855
+ return result
2856
+ end
2857
+
2858
+ # ========================================================================= #
2859
+ # === return_either_grey_or_the_custom_colour_for_answers
2860
+ # ========================================================================= #
2861
+ def return_either_grey_or_the_custom_colour_for_answers
2862
+ _ = grey('').strip
2863
+ if @internal_hash[:custom_colours] and
2864
+ @internal_hash[:custom_colours].has_key?('colour_for_answers')
2865
+ _ = COLOURS.send(@internal_hash[:custom_colours]['colour_for_answers']) { :omit_end }
2866
+ end
2867
+ return _
2868
+ end
2869
+
2870
+ # ========================================================================= #
2871
+ # === studium_log_dir?
2872
+ #
2873
+ # This is the log dir - where we "operate on".
2874
+ # ========================================================================= #
2875
+ def studium_log_dir?
2876
+ Studium.log_dir?
2877
+ end; alias log_dir? studium_log_dir? # === log_dir?
2878
+ alias base_dir? studium_log_dir? # === base_dir?
2879
+
2880
+ # ========================================================================= #
2881
+ # === return_hour_from_this
2882
+ #
2883
+ # This method will extract the time-format from a String,
2884
+ # such as:
2885
+ #
2886
+ # "18.02.2020, 17:00-18:00"
2887
+ # "Dienstag 13.10.2020, 14:30-17:45"
2888
+ #
2889
+ # A String will be returned in this event, holding the start and
2890
+ # stop time - for instance, in the first example it would return
2891
+ # the String "17:00-18:00".
2892
+ #
2893
+ # A String should be given as argument to this method.
2894
+ # ========================================================================= #
2895
+ def return_hour_from_this(i)
2896
+ i.scan(
2897
+ /\d{2}:\d{2}-\d{2}:\d{2}/
2898
+ ).flatten.first.to_s.strip
2899
+ end; alias extract_the_time_from return_hour_from_this # === extract_the_time
2900
+
2901
+ # ========================================================================= #
2902
+ # === sort_these_lecture_names_by_time
2903
+ # ========================================================================= #
2904
+ def sort_these_lecture_names_by_time(
2905
+ array, weekday
2906
+ )
2907
+ _ = main_dataset?
2908
+ array.sort_by {|entry|
2909
+ pointer = _[entry]
2910
+ lva_date = pointer['lva_dates'].select {|inner_entry|
2911
+ inner_entry.include? weekday
2912
+ }
2913
+ lva_date = lva_date.first if lva_date.is_a? Array
2914
+ lva_date = return_hour_from_this(lva_date) # This will be like "08:00-09:45"
2915
+ # ===================================================================== #
2916
+ # However had, we only need the last part, so chop it down.
2917
+ # ===================================================================== #
2918
+ if lva_date.include? '-'
2919
+ lva_date = lva_date.split('-').first
2920
+ end
2921
+ timestamp = Time.parse(lva_date)
2922
+ timestamp # And "return" it here.
2923
+ }
2924
+ end
2925
+
2926
+ # ========================================================================= #
2927
+ # === number_to_month
2928
+ #
2929
+ # This method will convert a number, such as 6, to the corresponding
2930
+ # month entry.
2931
+ # ========================================================================= #
2932
+ def number_to_month(i)
2933
+ array = Date::MONTHNAMES
2934
+ i = i.to_i
2935
+ return array[i]
2936
+ end
2937
+
2938
+ # ========================================================================= #
2939
+ # === return_hh_mm_ss_from
2940
+ #
2941
+ # Input to this method may be like this:
2942
+ #
2943
+ # 2020-03-04 00:00:00 +0000
2944
+ #
2945
+ # It will then return the ss:mm:hh notation.
2946
+ # ========================================================================= #
2947
+ def return_hh_mm_ss_from(i = Time.now)
2948
+ if i.is_a? String
2949
+ i = Time.parse(i)
2950
+ end
2951
+ if i.is_a? Time
2952
+ "#{i.hour.to_s.rjust(2,'0')}:"\
2953
+ "#{i.min.to_s.rjust(2,'0')}:"\
2954
+ "#{i.sec.to_s.rjust(2,'0')}"
2955
+ else
2956
+ e 'Unknown time format.'
2957
+ end
2958
+ end; alias hh_mm_ss return_hh_mm_ss_from # === hh_mm_ss
2959
+
2960
+ # ========================================================================= #
2961
+ # === datum?
2962
+ # ========================================================================= #
2963
+ def datum?
2964
+ Studium.datum? # ← Available in "studium/toplevel_methods/toplevel_methods.rb".
2965
+ end
2966
+
2967
+ # ========================================================================= #
2968
+ # === this_month_has_n_days?
2969
+ #
2970
+ # This method will return the maximum amount of days in the given
2971
+ # month.
2972
+ # ========================================================================= #
2973
+ def this_month_has_n_days?(
2974
+ this_month,
2975
+ this_year = Time.now.year
2976
+ )
2977
+ this_month = this_month.to_i
2978
+ return 29 if this_month == 2 && Date.gregorian_leap?(this_year)
2979
+ COMMON_YEAR_DAYS_IN_MONTH[this_month]
2980
+ end
2981
+
2982
+ # ========================================================================= #
2983
+ # === return_n_days_until_sunday
2984
+ # ========================================================================= #
2985
+ def return_n_days_until_sunday(
2986
+ time_now = Time.now
2987
+ )
2988
+ n_days_difference_from_today_to_this_day(time_now, 'Sunday')
2989
+ end
2990
+
2991
+ # ========================================================================= #
2992
+ # === return_current_year
2993
+ #
2994
+ # This method will simply return the current year, as String.
2995
+ # ========================================================================= #
2996
+ def return_current_year
2997
+ Time.now.year.to_s
2998
+ end; alias current_year? return_current_year # === current_year?
2999
+
3000
+ # ========================================================================= #
3001
+ # === return_dd_mm_yy_and_time_from
3002
+ #
3003
+ # This method will return the day, in dd.mm.yyyy format, and the
3004
+ # time on that date. You have to pass in a special object to this
3005
+ # method, such as an instance of class Time - see methods used
3006
+ # such as .day() or .month() and so forth.
3007
+ # ========================================================================= #
3008
+ def return_dd_mm_yy_and_time_from(i)
3009
+ Studium.return_dd_mm_yy_and_time_from(i)
3010
+ end
3011
+
3012
+ # ========================================================================= #
3013
+ # === current_semester?
3014
+ #
3015
+ # This method will either return the Symbol :summer or it will return
3016
+ # the Symbol :winter. This will be based on the current time (today).
3017
+ # ========================================================================= #
3018
+ def current_semester?
3019
+ today = ::Time.now
3020
+ # ======================================================================= #
3021
+ # Next we must determine whether we have the Range in winter or the
3022
+ # Range in summer.
3023
+ # ======================================================================= #
3024
+ current_year = current_year?.to_i
3025
+ next_year = current_year+1
3026
+ winter_range = ( Date.parse('01.10.'+current_year.to_s) .. Date.parse('28.02.'+next_year.to_s) )
3027
+ min_winter_day = winter_range.min
3028
+ max_winter_day = winter_range.max
3029
+ summer_range = ( Date.parse('01.03.'+current_year.to_s) .. Date.parse('30.09.'+current_year.to_s) )
3030
+ min_summer_day = summer_range.min
3031
+ max_summer_day = summer_range.max
3032
+ # ======================================================================= #
3033
+ # Ok, we have all the required dates. Now we have to check on the variable
3034
+ # today to find out in which range we are in.
3035
+ # ======================================================================= #
3036
+ if min_winter_day <= today.to_datetime and max_winter_day >= today.to_datetime
3037
+ # e 'Yes, the queried date is part of the date-range.'
3038
+ :winter
3039
+ else
3040
+ # e 'No, the queried date is NOT part of the date-range.'
3041
+ if min_summer_day <= today.to_datetime and max_summer_day >= today.to_datetime
3042
+ :summer
3043
+ else
3044
+ :impossible_situation_check_for_flaw_in_the_code
3045
+ end
3046
+ end
3047
+ end
3048
+
3049
+ # ========================================================================= #
3050
+ # === day_month_year
3051
+ #
3052
+ # This method will return a dd.mm.yyyy notation.
3053
+ #
3054
+ # If you need to find out whether the given input-day is today, then
3055
+ # use the method called .is_this_day_today?, defined in this file.
3056
+ #
3057
+ # An example for this will be:
3058
+ #
3059
+ # 03.04.2020
3060
+ #
3061
+ # ========================================================================= #
3062
+ def day_month_year(
3063
+ use_this_time = Time.now
3064
+ )
3065
+ if use_this_time.is_a? Time
3066
+ use_this_time.strftime('%d.%m.%Y')
3067
+ else
3068
+ use_this_time
3069
+ end
3070
+ end; alias today? day_month_year # === today?
3071
+ alias return_day_month_year day_month_year # === return_day_month_year
3072
+ alias dd_mm_yyyy day_month_year # === dd_mm_yyyy
3073
+ alias return_dd_mm_yyyy day_month_year # === return_dd_mm_yyyy
3074
+ alias time_today day_month_year # === time_today
3075
+
3076
+ # ========================================================================= #
3077
+ # === parse_dd_mm_yyyy
3078
+ # ========================================================================= #
3079
+ def parse_dd_mm_yyyy(
3080
+ i = '03.05.2023'
3081
+ )
3082
+ if i.is_a? String
3083
+ if i.include? ' '
3084
+ i = i.split(' ').last.to_s.strip
3085
+ end
3086
+ return ::Time.parse(i)
3087
+ else
3088
+ return i
3089
+ end
3090
+ end
3091
+
3092
+ # ========================================================================= #
3093
+ # === is_this_day_today?
3094
+ #
3095
+ # This method will return true or false, depending on whether the given
3096
+ # input is assumed to be the present day or not.
3097
+ #
3098
+ # The method assumes that the input will be a Time object normally.
3099
+ # ========================================================================= #
3100
+ def is_this_day_today?(
3101
+ i = '18.02.2022'
3102
+ )
3103
+ dd_mm_yyyy(Time.now) == dd_mm_yyyy(i)
3104
+ end
3105
+
3106
+ # ========================================================================= #
3107
+ # === weekday?
3108
+ #
3109
+ # This method will return a String such as "Thursday". Note that the
3110
+ # english name will be returned by default. This can be changed via
3111
+ # the second parameter to this method, which can be either :english
3112
+ # or :german.
3113
+ #
3114
+ # The input to this method should be a number, such as can be obtained
3115
+ # via the method .wday().
3116
+ #
3117
+ # A String can also be passed into this method, in a form like
3118
+ # "dd.mm.yyyy". So, an input String such as "10.03.2018" is
3119
+ # perfectly valid.
3120
+ # ========================================================================= #
3121
+ def weekday?(
3122
+ i = Date.today.wday,
3123
+ use_this_language = :english
3124
+ )
3125
+ if i.is_a?(String) and i.include?('.')
3126
+ # ===================================================================== #
3127
+ # In this case here assume an input-String such as "12.03.2018".
3128
+ # ===================================================================== #
3129
+ begin
3130
+ i = Time.parse(i).wday
3131
+ rescue ArgumentError => error
3132
+ pp error
3133
+ end
3134
+ end
3135
+ result = Date::DAYNAMES[i]
3136
+ case use_this_language
3137
+ # ======================================================================= #
3138
+ # === :german
3139
+ # ======================================================================= #
3140
+ when :german,
3141
+ :use_german
3142
+ # ===================================================================== #
3143
+ # In this case we have to translate to the german name.
3144
+ # ===================================================================== #
3145
+ result = ENGLISH_TO_GERMAN_WEEKDAYS[result]
3146
+ end
3147
+ return result
3148
+ end; alias return_name_for_this_day weekday? # === return_name_for_this_day
3149
+ alias return_weekday_for weekday? # === return_weekday_for
3150
+ alias return_weekday_of weekday? # === return_weekday_of
3151
+ alias return_weekday_from_this_input weekday? # === return_weekday_from_this_input
3152
+ alias english_weekday weekday? # === english_weekday
3153
+ alias english_weekday? weekday? # === english_weekday?
3154
+
3155
+ # ========================================================================= #
3156
+ # === open_in_browser
3157
+ # ========================================================================= #
3158
+ def open_in_browser(i)
3159
+ try_to_require_the_open_gem unless Object.const_defined?(:Open)
3160
+ Open.in_browser(i)
3161
+ end
3162
+
3163
+ # ========================================================================= #
3164
+ # === require_open_uri
3165
+ # ========================================================================= #
3166
+ def require_open_uri
3167
+ require 'open-uri'
3168
+ end
3169
+
3170
+ # ========================================================================= #
3171
+ # === write_what_into
3172
+ #
3173
+ # Use this method to save data into a specific file.
3174
+ # ========================================================================= #
3175
+ def write_what_into(
3176
+ what,
3177
+ into,
3178
+ &block
3179
+ )
3180
+ Studium.write_what_into(what, into, &block)
3181
+ end; alias store_what_into write_what_into # === store_what_into
3182
+
3183
+ # ========================================================================= #
3184
+ # === return_either_grey_or_the_custom_colour_for_questions
3185
+ # ========================================================================= #
3186
+ def return_either_grey_or_the_custom_colour_for_questions(
3187
+ custom_colours = @internal_hash[:custom_colours]
3188
+ )
3189
+ _ = grey('').strip
3190
+ if custom_colours and
3191
+ custom_colours.has_key?('colour_for_questions')
3192
+ _ = COLOURS.send(custom_colours['colour_for_questions']) { :omit_end }
3193
+ end
3194
+ return _
3195
+ end
3196
+
3197
+ # ========================================================================= #
3198
+ # === dataset?
3199
+ #
3200
+ # This query-method won't be valid for all subclasses, but I consider it
3201
+ # useful to have it enabled by default - that way we can avoid having
3202
+ # to define it for those subclasses that make use of it.
3203
+ # ========================================================================= #
3204
+ def dataset?
3205
+ @internal_hash[:dataset]
3206
+ end
3207
+
3208
+ # ========================================================================= #
3209
+ # === course_filter
3210
+ #
3211
+ # This method is a generic filter over the dataset made available in
3212
+ # the file lecture_information.yml.
3213
+ # ========================================================================= #
3214
+ def course_filter(
3215
+ dataset = dataset?,
3216
+ filter_how = :BOKU
3217
+ )
3218
+ act_on_this_entry = :university
3219
+ case filter_how
3220
+ # ======================================================================= #
3221
+ # === :winter
3222
+ # ======================================================================= #
3223
+ when :winter
3224
+ act_on_this_entry = :semester
3225
+ # ======================================================================= #
3226
+ # === :prüfungsimmanent
3227
+ # ======================================================================= #
3228
+ when :prüfungsimmanent
3229
+ act_on_this_entry = :type
3230
+ end
3231
+ return dataset.select {|name_of_the_course, inner_hash|
3232
+ case act_on_this_entry
3233
+ # ===================================================================== #
3234
+ # === :type
3235
+ # ===================================================================== #
3236
+ when :type
3237
+ case filter_how
3238
+ # =================================================================== #
3239
+ # === :prüfungsimmanent
3240
+ # =================================================================== #
3241
+ when :prüfungsimmanent
3242
+ _ = inner_hash[act_on_this_entry]
3243
+ is_prüfungsimmanent?(_)
3244
+ else
3245
+ false
3246
+ end
3247
+ # ===================================================================== #
3248
+ # === :semester
3249
+ # ===================================================================== #
3250
+ when :semester
3251
+ _ = inner_hash[act_on_this_entry]
3252
+ if _
3253
+ _.to_sym == filter_how # e. g. == :winter
3254
+ else
3255
+ e 'nil-entry for '+name_of_the_course+' - please fix this.'
3256
+ end
3257
+ # ===================================================================== #
3258
+ # === :university
3259
+ # ===================================================================== #
3260
+ when :university
3261
+ inner_hash[act_on_this_entry].to_sym == filter_how
3262
+ end
3263
+ }
3264
+ end
3265
+
3266
+ # ========================================================================= #
3267
+ # === return_n_days_until_monday
3268
+ # ========================================================================= #
3269
+ def return_n_days_until_monday(
3270
+ time_now = Time.now
3271
+ )
3272
+ n_days_difference_from_today_to_this_day(time_now, 'Monday')
3273
+ end
3274
+
3275
+ # ========================================================================= #
3276
+ # === n_seconds_to_n_days
3277
+ #
3278
+ # A day has 60 seconds * 60 minutes
3279
+ # ========================================================================= #
3280
+ def n_seconds_to_n_days(i)
3281
+ hour = 60 * 60.0
3282
+ one_day = hour * 24
3283
+ return (i / one_day.to_f)
3284
+ end
3285
+
3286
+ # ========================================================================= #
3287
+ # === readlines_from_this_input_file
3288
+ #
3289
+ # This method is essentially File.readlines(), but we also use the
3290
+ # :encoding symbol to denote which Encoding to use.
3291
+ #
3292
+ # As first argument pass in the file path to the target input file.
3293
+ #
3294
+ # You should ideally use this method in a unified way, that is, whenever
3295
+ # you want to read the content of a file make use of this method here.
3296
+ # This makes it easier to have the functionality all in one place.
3297
+ #
3298
+ # Keep in mind that the file in question has to exist locally; the
3299
+ # file here will NOT check whether the given input file exists.
3300
+ # ========================================================================= #
3301
+ def readlines_from_this_input_file(
3302
+ this_file,
3303
+ use_this_encoding = :default_encoding,
3304
+ &block
3305
+ )
3306
+ yielded = nil
3307
+ if block_given?
3308
+ yielded = yield
3309
+ end
3310
+ case use_this_encoding
3311
+ # ======================================================================= #
3312
+ # === :default
3313
+ #
3314
+ # This refers to the default encoding, which is usually UTF-8 (Unicode).
3315
+ # ======================================================================= #
3316
+ when :default,
3317
+ :default_encoding
3318
+ use_this_encoding = ::Studium.main_encoding?
3319
+ end
3320
+ if use_this_encoding.is_a? Hash
3321
+ # ===================================================================== #
3322
+ # === :encoding
3323
+ # ===================================================================== #
3324
+ if use_this_encoding.has_key? :encoding
3325
+ use_this_encoding = use_this_encoding[:encoding]
3326
+ end
3327
+ end
3328
+ if this_file
3329
+ if this_file.is_a? Array
3330
+ return this_file.map {|inner_entry|
3331
+ if File.exist?(inner_entry)
3332
+ inner_entry = File.readlines(inner_entry, encoding: use_this_encoding)
3333
+ end
3334
+ inner_entry
3335
+ }.flatten
3336
+ elsif File.exist?(this_file)
3337
+ return File.readlines(
3338
+ this_file,
3339
+ encoding: use_this_encoding
3340
+ )
3341
+ end
3342
+ else
3343
+ unless yielded == :be_quiet
3344
+ e "Can not read in the file at #{this_file} as it does not exist."
3345
+ end
3346
+ return false
3347
+ end
3348
+ end; alias readlines_via_default_encoding readlines_from_this_input_file # === readlines_via_default_encoding
3349
+ alias readlines_with_default_encoding readlines_from_this_input_file # === readlines_with_default_encoding
3350
+ alias readlines_with_the_default_encoding readlines_from_this_input_file # === readlines_with_the_default_encoding
3351
+ alias file_readlines_of_this_file readlines_from_this_input_file # === file_readlines_of_this_file
3352
+ alias file_readlines readlines_from_this_input_file # === file_readlines
3353
+ alias readlines_with_proper_encoding readlines_from_this_input_file # === readlines_with_proper_encoding
3354
+ alias proper_readlines readlines_from_this_input_file # === proper_readlines
3355
+ alias default_readlines readlines_from_this_input_file # === default_readlines
3356
+ alias readlines readlines_from_this_input_file # === readlines
3357
+ # alias readlines_with_iso_encoding readlines_from_this_input_file # === readlines_with_iso_encoding
3358
+
3359
+ # ========================================================================= #
3360
+ # === find_corresponding_exam_topic
3361
+ #
3362
+ # This method will try to find the corresponding exam topic, based on a
3363
+ # short given input.
3364
+ #
3365
+ # For instance, 'bem1' will become 'basic biochemistry' and 'amg1'
3366
+ # will become 'allgemeine_genetik'. If no match is found then the
3367
+ # original input will be returned.
3368
+ # ========================================================================= #
3369
+ def find_corresponding_exam_topic(
3370
+ i,
3371
+ be_verbose = be_verbose?
3372
+ )
3373
+ return Studium.find_corresponding_exam_topic(i, be_verbose)
3374
+ end; alias return_file_associated_with_this_exam_topic find_corresponding_exam_topic # === return_file_associated_with_this_exam_topic
3375
+ alias find_corresponding_exam_title find_corresponding_exam_topic # === find_corresponding_exam_title
3376
+ alias expand_topic find_corresponding_exam_topic # === expand_topic
3377
+ alias try_to_find_a_registered_exam_topic find_corresponding_exam_topic # === try_to_find_a_registered_exam_topic
3378
+
3379
+ # ========================================================================= #
3380
+ # === is_this_a_registered_exam_topic?
3381
+ #
3382
+ # This method must return a boolean - true if the given input is a
3383
+ # registere exam topic; and false otherwise.
3384
+ # ========================================================================= #
3385
+ def is_this_a_registered_exam_topic?(i)
3386
+ original_input = i.dup
3387
+ possibly_expanded_input = try_to_find_a_registered_exam_topic(original_input)
3388
+ return original_input == possibly_expanded_input
3389
+ end
3390
+
3391
+ # ========================================================================= #
3392
+ # === project_yaml_directory?
3393
+ # ========================================================================= #
3394
+ def project_yaml_directory?
3395
+ Studium.project_yaml_directory?
3396
+ end
3397
+
3398
+ # ========================================================================= #
3399
+ # === filter_away_already_answered_questions
3400
+ # ========================================================================= #
3401
+ def filter_away_already_answered_questions(i)
3402
+ return i.reject {|entry|
3403
+ entry.end_with?(" []\n")
3404
+ }
3405
+ end; alias filter_away_already_answered_comments filter_away_already_answered_questions # === filter_away_already_answered_questions
3406
+
3407
+ # ========================================================================= #
3408
+ # === lectures_from_the_individual_vektor_curricula
3409
+ #
3410
+ # This method is a convenience method, returning all the lectures that
3411
+ # belong to the individual bachelor+master vektor-curriculum
3412
+ # ========================================================================= #
3413
+ def lectures_from_the_individual_vektor_curricula
3414
+ (
3415
+ obtain_lectures_from_this_curriculum(:bachelor_vektor)+
3416
+ obtain_lectures_from_this_curriculum(:master_vektor)
3417
+ ).flatten
3418
+ end
3419
+
3420
+ # ========================================================================= #
3421
+ # === obtain_lectures_from_this_curriculum
3422
+ #
3423
+ # This method should be used whenever you wish to obtain all lectures
3424
+ # that belong to a specific curriculum, without any comments.
3425
+ #
3426
+ # An Array will be returned by this method.
3427
+ # ========================================================================= #
3428
+ def obtain_lectures_from_this_curriculum(
3429
+ i = :default,
3430
+ do_flatten_the_result = true
3431
+ )
3432
+ Studium.read_dataset_from_a_curriculum_file(i, :remove_comments, do_flatten_the_result).map {|entry|
3433
+ entry.squeeze(' ') # ← We don't want multiple ' ' in succession here.
3434
+ }
3435
+ end; alias return_lectures_from_this_curriculum obtain_lectures_from_this_curriculum # === return_lectures_from_this_curriculum
3436
+ alias return_lectures_of_this_curriculum obtain_lectures_from_this_curriculum # === return_lectures_of_this_curriculum
3437
+ alias return_lectures_from_this_curriculu obtain_lectures_from_this_curriculum # === return_lectures_from_this_curriculu
3438
+ alias return_lectures_from_this_curriculum_file obtain_lectures_from_this_curriculum # === return_lectures_from_this_curriculum_file
3439
+ alias obtain_all_lectures_from_this_curriculum obtain_lectures_from_this_curriculum # === obtain_all_lectures_from_this_curriculum
3440
+
3441
+ # ========================================================================= #
3442
+ # === ecomment
3443
+ # ========================================================================= #
3444
+ def ecomment(
3445
+ i = '',
3446
+ use_colours = use_colours?
3447
+ )
3448
+ if use_colours
3449
+ ::Colours.ecomment(i)
3450
+ else
3451
+ e i
3452
+ end
3453
+ end
3454
+
3455
+ # ========================================================================= #
3456
+ # === read_in_exam_dataset_from_this_file
3457
+ #
3458
+ # This is the method that will read from an existing file. If a symbol
3459
+ # is given then we will expand this to the default exam-topic directory.
3460
+ # ========================================================================= #
3461
+ def read_in_exam_dataset_from_this_file(
3462
+ this_file,
3463
+ shall_we_filter_away_invalid_questions = true,
3464
+ &block
3465
+ )
3466
+ if this_file.is_a? Symbol
3467
+ this_file = "#{exam_topic_directory?}#{this_file}"
3468
+ end
3469
+ # ======================================================================= #
3470
+ # === Handle blocks given to this method next
3471
+ # ======================================================================= #
3472
+ if File.exist? this_file
3473
+ dataset = readlines_via_default_encoding(this_file) # First read in the dataset.
3474
+ if block_given?
3475
+ yielded = yield
3476
+ case yielded
3477
+ # =================================================================== #
3478
+ # === :filter_away_the_comments
3479
+ # =================================================================== #
3480
+ when :filter_away_the_comments
3481
+ shall_we_filter_away_invalid_questions = true
3482
+ # =================================================================== #
3483
+ # === :filter_away_already_answered_comments
3484
+ # =================================================================== #
3485
+ when :filter_away_already_answered_comments
3486
+ dataset.reject! {|entry|
3487
+ entry.rstrip.end_with?(' []')
3488
+ }
3489
+ end
3490
+ end
3491
+ if shall_we_filter_away_invalid_questions
3492
+ dataset = filter_away_invalid_questions(dataset)
3493
+ end
3494
+ return dataset
3495
+ end
3496
+ end; alias obtain_exam_questions_from_this_file read_in_exam_dataset_from_this_file # === obtain_exam_questions_from_this_file
3497
+
3498
+ # ========================================================================= #
3499
+ # === filter_away_invalid_questions
3500
+ #
3501
+ # This method will remove entries that begin with '#' and empty entries.
3502
+ # ========================================================================= #
3503
+ def filter_away_invalid_questions(i)
3504
+ Studium.filter_away_invalid_questions(i)
3505
+ end
3506
+
3507
+ # ========================================================================= #
3508
+ # === word_wrap
3509
+ #
3510
+ # This method can re-arrange a given text (a String) to honour a certain
3511
+ # size limit, such as 80 characters per line.
3512
+ #
3513
+ # Keep in mind that colours that may be used inside of a tag, such as
3514
+ # <tomato>foobar</tomato>, will also count for that limit. This has
3515
+ # to be remembered when doing the calculation for text-wrapping.
3516
+ # ========================================================================= #
3517
+ def word_wrap(
3518
+ text,
3519
+ line_width = N_CHARACTERS_PER_LINE
3520
+ )
3521
+ ::Studium.word_wrap(text, line_width)
3522
+ end
3523
+
3524
+ # ========================================================================= #
3525
+ # === run
3526
+ # ========================================================================= #
3527
+ def run
3528
+ end
3529
+
3530
+ end; end
3531
+
3532
+ if __FILE__ == $PROGRAM_NAME
3533
+ require 'verbose_truth'
3534
+ alias e puts
3535
+ x = Studium::Base.new
3536
+ x.reset
3537
+ # x.current_semester? # This will be :winter or :summer.
3538
+ e x.this_month_has_n_days?('10')
3539
+ e x.this_month_has_n_days?('11')
3540
+ e x.this_month_has_n_days?('12')
3541
+ e x.web_liner
3542
+ e 'Do we have konsole support? '+
3543
+ VerboseTruth[
3544
+ x.konsole_support?.to_s
3545
+ ]
3546
+ e x.web_liner
3547
+ Studium::Base.new.directory_to_the_exam_topics?
3548
+ p x.weekday?
3549
+ p x.today?
3550
+ #p x.select_lectures_with_this_key(:exam_registration_at)
3551
+ e
3552
+ e x.swarn('Hey there!')
3553
+ e
3554
+ end