Passed
Push — main ( 853695...d18ab9 )
by Máté
03:41 queued 02:14
created

main.open_article_paste_text()   A

Complexity

Conditions 2

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nop 3
dl 0
loc 16
rs 9.8
c 0
b 0
f 0
1
from argparse import ArgumentParser, Namespace
2
import logging
3
from pathlib import Path
4
from platform import system
5
import time
6
from urllib.parse import quote, urlencode
7
import webbrowser
8
9
# future: delete the comment below when stubs for the package below are available
10
import pyperclip  # type: ignore
11
from send2trash import send2trash  # type: ignore
12
13
from quiz.illustrations.state_of_illustrations import StateOfIllustrations  # type: ignore
14
from quiz.grading_types import GradingType  # type: ignore
15
from quiz.quiz import Quiz  # type: ignore
16
from quiz.quiz_helpers import clear_terminal  # type: ignore
17
18
19
def main() -> None:
20
    args = parse_arguments()
21
    configure_logging(args.verbose)
22
    logging.getLogger(__name__).debug("Program started...")
23
24
    quiz_title = get_desired_name_of_quiz(args.new)
25
    if args.new:
26
        grading = get_grading()
27
    else:
28
        grading = None
29
    quiz = Quiz(
30
        parent_article=get_name_of_parent_article(),
31
        title=quiz_title,
32
        grading=grading,
33
    )
34
    absolute_source_path: Path = args.source_path.resolve()
35
    quiz.import_file_or_files(
36
        path=absolute_source_path,
37
        recursively=args.recursive,
38
    )
39
    wiki_domain = "https://vik.wiki"
40
41
    input(
42
        """Let's log in to the wiki! Please...
43
• if you see the login page, log in
44
• when you see the main page of the wiki, return here.
45
46
Please press Enter to open the login page..."""
47
    )
48
    quiz_wikitext = str(quiz)
49
    webbrowser.open_new_tab(f"{wiki_domain}/index.php?title=Speciális:Belépés")
50
    input("Please press Enter if you've logged in...")
51
    clear_terminal()
52
53
    print("Great!\n")
54
    wikitext_instructions = """
55
<!-- További teendőid (ebben a sorrendben):
56
• e komment feletti sorba illeszd be a vágólapodra másolt tartalmat
57
• kattints az 'Előnézet megtekintése' gombra"""
58
    operating_system = system()
59
    wiki_modifier_keys = {
60
        "Darwin": "Control-Option",
61
        "Linux": "Alt-Shift",
62
    }
63
    wiki_editor_keys = {"Show preview": "P", "Publish page": "S"}
64
    if operating_system == "Darwin" or operating_system == "Linux":
65
        wikitext_instructions += f" ({wiki_modifier_keys[operating_system]}-{wiki_editor_keys["Show preview"]})"
66
    wikitext_instructions += """
67
• javítsd a helyesírást és a formázást (ha szükséges), különös tekintettel a képletekre"""
68
    match quiz.state_of_illustrations:
69
        case StateOfIllustrations.YesAndAvailable:
70
            upload_directory = quiz.get_illustrations_ready_for_upload()
71
            if operating_system == "Darwin":
72
                pyperclip.copy(str(upload_directory))
73
            print(
74
                f"""The batch upload page of the wiki will now be opened. After that, please...
75
• click on 'Fájlok kiválasztása...'"""
76
            )
77
            if operating_system == "Darwin":
78
                print(
79
                    """    • press Command–Shift–G
80
        • paste the content of the clipboard
81
        • press Enter"""
82
                )
83
            else:
84
                print("    • open the following folder: " + str(upload_directory))
85
            print(
86
                """    • select all files in the folder
87
    • click on 'Upload'
88
• return here."""
89
            )
90
            input("Please press Enter then follow these instructions...")
91
            webbrowser.open_new_tab(
92
                f"{wiki_domain}/Speciális:TömegesFeltöltés/moodle-to-vikwikiquiz"
93
            )
94
            input("Please press Enter if you're done with uploading...")
95
            if upload_directory:
96
                remove_uploaded_files(upload_directory)
97
            clear_terminal()
98
99
            print("Great! I've deleted the uploaded files from your disk.\n")
100
        case StateOfIllustrations.YesButUnavailable:
101
            wikitext_instructions += """
102
• töltsd fel kézzel, egyesével a piros linkekkel formázott illusztrációkat
103
    • másold ki a megfelelő "Fájl:" wikitext után található generált fájlnevet
104
    • kattints a szerkesztő eszköztárában található 'Képek és médiafájlok' gombra
105
    • töltsd fel az illusztrációt"""
106
        case StateOfIllustrations.Nil:
107
            pass
108
    wikitext_instructions += """
109
• töröld ezt a kommentet
110
• kattints a 'Lap mentése' gombra"""
111
    if operating_system == "Darwin" or operating_system == "Linux":
112
        wikitext_instructions += f" ({wiki_modifier_keys[operating_system]}-{wiki_editor_keys["Publish page"]})"
113
    wikitext_instructions += """
114
-->"""
115
    parameters_for_opening_edit = {
116
        "action": "edit",
117
        "summary": "Kvíz bővítése "
118
        "a https://github.com/gy-mate/moodle-to-vikwikiquiz segítségével importált Moodle-kvíz(ek)ből",
119
        "preload": "Sablon:Előbetöltés",
120
        "preloadparams[]": wikitext_instructions,
121
    }
122
    clear_terminal()
123
124
    create_article(
125
        args, parameters_for_opening_edit, quiz_title, quiz_wikitext, wiki_domain
126
    )
127
    logging.getLogger(__name__).debug("Program finished!")
128
129
130
def remove_uploaded_files(folder: Path) -> None:
131
    send2trash(folder)
132
133
134
def parse_arguments() -> Namespace:
135
    parser = ArgumentParser()
136
    parser.add_argument(
137
        "-v", "--verbose", action="store_true", help="increase output verbosity"
138
    )
139
    parser.add_argument(
140
        "-n",
141
        "--new",
142
        action="store_true",
143
        help="create a new quiz on vik.wiki by automatically opening an edit page for the new article",
144
    )
145
    parser.add_argument(
146
        "-r",
147
        "--recursive",
148
        action="store_true",
149
        help="import HTML files from the current directory recursively",
150
    )
151
    parser.add_argument(
152
        "source_path",
153
        type=Path,
154
        help="The absolute or relative path of the file or directory where the Moodle quiz HTML files are located. "
155
        "These HTML files should contain the 'Review' page of the quizzes.",
156
    )
157
    return parser.parse_args()
158
159
160
def configure_logging(verbose: bool) -> None:
161
    if verbose:
162
        logging.basicConfig(
163
            encoding="utf-8",
164
            format='%(asctime)s [%(levelname)s] "%(pathname)s:%(lineno)d": %(message)s',
165
            level=logging.DEBUG,
166
        )
167
    else:
168
        logging.basicConfig(
169
            encoding="utf-8",
170
            format="[%(levelname)s]: %(message)s",
171
            level=logging.INFO,
172
        )
173
174
175
def get_name_of_parent_article() -> str:
176
    while True:
177
        try:
178
            input_name = input(
179
                f"\nPlease enter the name of the vik.wiki article of the corresponding course then press Enter:\n"
180
            )
181
            if not input_name:
182
                raise ValueError("Nothing was entered!")
183
            return input_name
184
        except ValueError as error:
185
            print(error)
186
187
188
def get_desired_name_of_quiz(new: bool) -> str:
189
    while True:
190
        try:
191
            print(
192
                "\nPlease enter how the quiz should be named on vik.wiki then press Enter!"
193
                "\nThis is usually in the following form: `[course name] kvíz – [exam name]`. (The ` – [exam name]` can be omitted.)"
194
            )
195
            if not new:
196
                print("This might be an existing article name.")
197
            input_name = input()
198
            if not input_name:
199
                raise ValueError("Nothing was entered!")
200
            return input_name
201
        except ValueError as error:
202
            print(error)
203
204
205
def get_grading() -> GradingType:
206
    while True:
207
        try:
208
            grading_symbol = input(
209
                "\nPlease enter `+` or `-` as the grading type of the quiz then press Enter!"
210
                "\nSee https://vik.wiki/Segítség:Kvíz#Pontozás for further info.\n"
211
            )
212
            return GradingType(grading_symbol)
213
        except ValueError:
214
            print("This is not a valid grading type!")
215
        finally:
216
            clear_terminal()
217
218
219
def create_article(
220
    args: Namespace,
221
    parameters_for_opening_edit: dict,
222
    quiz_title: str,
223
    quiz_wikitext: str,
224
    wiki_domain: str,
225
) -> None:
226
    if args.new:
227
        parameters_for_opening_edit_with_paste = parameters_for_opening_edit.copy()
228
        parameters_for_opening_edit_with_paste.update(
229
            {
230
                "preload": "Sablon:Előbetöltés",
231
                "preloadparams[]": quiz_wikitext,
232
            }
233
        )
234
        parameters_for_opening_edit_with_paste["summary"] = (
235
            parameters_for_opening_edit_with_paste["summary"].replace(
236
                "bővítése", "létrehozása"
237
            )
238
        )
239
        url = f"{wiki_domain}/{quiz_title}?{urlencode(parameters_for_opening_edit_with_paste)}"
240
        if len(url) < 2048:
241
            return open_article_paste_text(args, quiz_wikitext, url)
242
        else:
243
            open_article(args, parameters_for_opening_edit, url)
244
    pyperclip.copy(quiz_wikitext)
245
    print("The wikitext of the quiz has been copied to the clipboard!")
246
    url = f"{wiki_domain}/{quote(quiz_title)}?{urlencode(parameters_for_opening_edit)}"
247
    webbrowser.open_new_tab(url)
248
    print(
249
        "\nThe edit page of the quiz article has been opened in your browser! Please follow the instructions there."
250
    )
251
252
253
def open_article_paste_text(args: Namespace, quiz_wikitext: str, url: str) -> None:
254
    pyperclip.copy(quiz_wikitext)
255
    print(
256
        "\nThe wikitext of the quiz has been copied to the clipboard! "
257
        "This will be overwritten but you may recall it later if you use an app like Pastebot."
258
    )
259
    wait_for_pastebot_to_recognize_copy()
260
    if args.verbose:
261
        pyperclip.copy(url)
262
        print("The URL has been copied to the clipboard!")
263
    webbrowser.open_new_tab(url)
264
    print(
265
        "\nThe edit page of the new quiz article has been opened in your browser with the wikitext pre-filled! "
266
        "Please upload illustrations manually, if there are any."
267
    )
268
    return
269
270
271
def open_article(args: Namespace, parameters_for_opening_edit: dict, url: str) -> None:
272
    logging.getLogger(__name__).warning(
273
        "I can't create the article automatically "
274
        "because the URL would be too long for some browsers (or the server)."
275
    )
276
    if args.verbose:
277
        pyperclip.copy(url)
278
        print(
279
            "\nThis URL has been copied to the clipboard! "
280
            "It will be overwritten but you may recall it later if you use an app like Pastebot."
281
        )
282
        wait_for_pastebot_to_recognize_copy()
283
    parameters_for_opening_edit["summary"] = parameters_for_opening_edit[
284
        "summary"
285
    ].replace("bővítése", "létrehozása")
286
287
288
def wait_for_pastebot_to_recognize_copy() -> None:
289
    print("Waiting 2 seconds for Pastebot to recognize it...")
290
    time.sleep(2)
291
    print("...done!")
292
293
294
if __name__ == "__main__":
295
    main()
296