linkToPDF2.py 17 KB
Newer Older
Dominik Woiwode's avatar
Dominik Woiwode committed
1
2
3
import datetime
import hashlib
import os
Dominik Woiwode's avatar
Dominik Woiwode committed
4
from dataclasses import dataclass
Dominik Woiwode's avatar
Dominik Woiwode committed
5
from pathlib import Path
6
from typing import Optional, Dict, List, Iterator, Tuple
Dominik Woiwode's avatar
Dominik Woiwode committed
7
8
9

import requests

10
11
import config
from pterClasses import Gremium, GREMIUM_FR, GREMIUM_FSR, MailParticipant, sendFRMail, SemesterPart
Dominik Woiwode's avatar
Dominik Woiwode committed
12

13
opt = config.Config()
Jakob Marten's avatar
Jakob Marten committed
14
15


Dominik Woiwode's avatar
Dominik Woiwode committed
16
17
18
19
@dataclass(unsafe_hash=True)
class Semester:
    year: int
    part: SemesterPart
Jakob Marten's avatar
Jakob Marten committed
20

Dominik Woiwode's avatar
Dominik Woiwode committed
21
22
    def __post_init__(self):
        self.displayName = f"{self.part.value} {self.year}"
23
        self.gravPath = os.path.join(opt.GIT_REPO_PATH, opt.GRAV_PROTOCOL_PATH,
Dominik Woiwode's avatar
Dominik Woiwode committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
                                     self._gravName(), "protocol_semester.de.md")

    def _gravName(self):
        return f"{self.year - 2000}{self.part.short()}"

    @classmethod
    def fromDate(cls, date: datetime.datetime) -> "Semester":
        if 4 <= date.month < 10:
            # Summer
            return Semester(date.year, SemesterPart.Summer)
        elif date.month >= 10:
            # Winter
            return Semester(date.year, SemesterPart.Winter)
        else:
            # Winter
            return Semester(date.year - 1, SemesterPart.Winter)
Jakob Marten's avatar
Jakob Marten committed
40
41
42

    def uploadToGrav(self):
        if os.path.exists(self.gravPath):
43
            return
Jakob Marten's avatar
Jakob Marten committed
44

Dominik Woiwode's avatar
Dominik Woiwode committed
45
46
47
        os.makedirs(str(Path(self.gravPath).parent), exist_ok=True)
        with open(self.gravPath, "w") as d:
            d.write(f"---\ntitle: {self.displayName}\n---")
Jakob Marten's avatar
Jakob Marten committed
48

49
50
        git = opt.git
        git.add(opt.GRAV_PROTOCOL_PATH)
Dominik Woiwode's avatar
Dominik Woiwode committed
51
52
        git.commit(f"Added {self.part.value} {self.year}")
        git.push()
Jakob Marten's avatar
Jakob Marten committed
53
54


Dominik Woiwode's avatar
Dominik Woiwode committed
55
# === Source Types ===
Dominik Woiwode's avatar
Dominik Woiwode committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class SourceTypes:
    def __init__(self, url: str):
        self.url: str = url

    def __repr__(self):
        return f"{self.__class__.__name__}({self.url})"

    def retrieveContent(self):
        raise NotImplementedError()


class Etherpad(SourceTypes):
    def retrieveContent(self):
        url = f"{self.url}.txt"
        response = requests.get(url)
        return response.content.decode("utf-8")

73
74
75
76
77
    @classmethod
    def fitUrl(cls, url: str) -> bool:
        # TODO: Maybe improve filter
        return "/p/" in url

Dominik Woiwode's avatar
Dominik Woiwode committed
78
79
80
81
82
83
84

class CodiMD(SourceTypes):
    def retrieveContent(self):
        url = f"{self.url}/download"
        response = requests.get(url)
        return response.content.decode("utf-8")

85
86
87
88
89
    @classmethod
    def fitUrl(cls, url: str) -> bool:
        # TODO: Maybe improve filter
        return "/p/" not in url

Dominik Woiwode's avatar
Dominik Woiwode committed
90
91

class LocalCache(SourceTypes):
92
93
94
95
    def __init__(self, url: str, localPath: str = None):
        super().__init__(url)
        self.localPath = localPath or hashlib.md5(url.encode("utf-8"))

Dominik Woiwode's avatar
Dominik Woiwode committed
96
    def retrieveContent(self):
97
        with open(self.localPath, "r", encoding="utf-8") as d:
Dominik Woiwode's avatar
Dominik Woiwode committed
98
99
            return d.read()

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    def asOnlinePad(self) -> SourceTypes:
        if Etherpad.fitUrl(self.url):
            return Etherpad(self.url)
        if CodiMD.fitUrl(self.url):
            return CodiMD(self.url)


class CachedEtherPad(Etherpad):
    def __init__(self, url: str):
        super().__init__(url)
        self._cache = None

    def retrieveContent(self):
        if self._cache is None:
            self._cache = super().retrieveContent()
        return self._cache


class CachedCodiMD(CodiMD):
    def __init__(self, url: str):
        super().__init__(url)
        self._cache = None

    def retrieveContent(self):
        if self._cache is None:
            self._cache = super().retrieveContent()
        return self._cache

Dominik Woiwode's avatar
Dominik Woiwode committed
128
129
130

# === Pad Types ===
class BasePad:
131
132
    def __init__(self, source: SourceTypes, *_, displayName: str = None, date: datetime.datetime, isApproved: bool,
                 **kwargs):
Dominik Woiwode's avatar
Dominik Woiwode committed
133
134
        self.source = source
        self.metadata = kwargs
Jakob Marten's avatar
Jakob Marten committed
135
        self.folder = ""
136
137
138
139
        self.date = date
        self.isApproved = isApproved

        self.displayName = displayName or self.DEFAULT_DISPLAY_NAME()
Dominik Woiwode's avatar
Dominik Woiwode committed
140
141
142
143

    def __repr__(self):
        return f"{self.__class__.__name__}({self.source})"

Dominik Woiwode's avatar
Dominik Woiwode committed
144
145
146
    def DEFAULT_DISPLAY_NAME(self):
        return self.source.url

147
148
149
    @property
    def rawPath(self) -> Path:
        return Path(os.path.join(opt.DATA_FOLDER, "raw", f"{self.displayName}.md")).absolute()
Dominik Woiwode's avatar
Dominik Woiwode committed
150

151
152
153
    @property
    def compiledPath(self) -> Path:
        return Path(os.path.join(opt.DATA_FOLDER, "result", f"{self.displayName}.pdf")).absolute()
Dominik Woiwode's avatar
Dominik Woiwode committed
154

155
156
    def download(self, override=True):
        path = self.rawPath
Dominik Woiwode's avatar
Dominik Woiwode committed
157
        content = self.source.retrieveContent()
158
        if not override and os.path.exists(str(path)):
Dominik Woiwode's avatar
Dominik Woiwode committed
159
            raise FileExistsError(f"{path} already exists!")
160
161
        os.makedirs(str(path.parent), exist_ok=True)
        with open(str(path), "w", encoding="utf-8") as d:
Dominik Woiwode's avatar
Dominik Woiwode committed
162
            d.write(content)
163
164
165
166
167
168
        self.source = LocalCache(self.source.url, str(path))

    def compile(self, template: str = None) -> int:
        os.makedirs(str(self.compiledPath.parent), exist_ok=True)
        metadataStr = (" " +
                       " ".join([f'-M {key}="{val}"' for key, val in self.metadata.items()]))
Dominik Woiwode's avatar
Dominik Woiwode committed
169
        templateStr = ""
Dominik Woiwode's avatar
Dominik Woiwode committed
170
171
172
173
        if template is None and hasattr(self, "gremium"):
            templateStr = f' --template="{getattr(self, "gremium").fullTemplate()}" '
        elif template != "":
            templateStr = f' --template="{template}" '
174
        cmd = f'pandoc "{self.rawPath}" {metadataStr}{templateStr}-o "{str(self.compiledPath)}"'
Dominik Woiwode's avatar
Dominik Woiwode committed
175
        ret = os.system(cmd)
176
177
        if ret != 0:
            raise RuntimeWarning(f"Non-Zero Returncode ({ret})")
Dominik Woiwode's avatar
Dominik Woiwode committed
178
        return ret
Dominik Woiwode's avatar
Dominik Woiwode committed
179
180
181


class ProtocolPad(BasePad):
Dominik Woiwode's avatar
Dominik Woiwode committed
182
    def __init__(self, source: SourceTypes, *_, date: datetime.datetime = None,
Dominik Woiwode's avatar
Dominik Woiwode committed
183
                 isFachgruppenvollversammlung: bool = False, isApproved: bool = False, gremium: Gremium = None):
184
        self.gremium = gremium or opt.GREMIUM
Dominik Woiwode's avatar
Dominik Woiwode committed
185
        self.isFachgruppenvollversammlung = isFachgruppenvollversammlung
Jakob Marten's avatar
Jakob Marten committed
186
        self.semester = None
187
188

        super().__init__(source, date=date, isApproved=isApproved)
Dominik Woiwode's avatar
Dominik Woiwode committed
189
190
191
192

    def __repr__(self):
        return super(ProtocolPad, self).__repr__()[:-1] + f", {self.date})"

Dominik Woiwode's avatar
Dominik Woiwode committed
193
    def DEFAULT_DISPLAY_NAME(self):
Dominik Woiwode's avatar
Dominik Woiwode committed
194
        return f"Protokoll {self.gremium.name} {self.date.strftime('%Y-%m-%d')}" + " - Fachgruppenvollversammlung" * self.isFachgruppenvollversammlung
Dominik Woiwode's avatar
Dominik Woiwode committed
195

196
197
198
199
200
201
    @property
    def gravPath(self) -> Path:
        return Path(os.path.join(opt.GIT_REPO_PATH, opt.GRAV_PROTOCOL_PATH,
                                 self.semester._gravName(),
                                 self.date.strftime("%Y-%m-%d") + "-fgvv" * self.isFachgruppenvollversammlung,
                                 "default.de.md")).absolute()
Dominik Woiwode's avatar
Dominik Woiwode committed
202
203
204
205
206
207

    def parseTops(self):
        # TODO: better top filter?
        lines = self.source.retrieveContent().split("\n")
        tops = []
        for l in lines:
208
            # TODO: Change to regex?
Dominik Woiwode's avatar
Dominik Woiwode committed
209
210
211
212
213
214
215
            # import re
            # res = re.match("^## ([\w\d &!\"'§$%/\-+äöüß]+)\w*(\(\d\d:\d\d Uhr\))?", l)
            # if res is not None:
            #     top = res.group(1)

            if l.startswith("## "):
                top = l.strip("#").rsplit("(")[0].strip()
216
                if any(top in t or t in top for t in opt.IGNORED_TOPS):
Dominik Woiwode's avatar
Dominik Woiwode committed
217
218
219
                    continue
                tops.append(top)
        return tops
Jakob Marten's avatar
Jakob Marten committed
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
    def cleanedRaw(self):
        linesNew = []
        ignore = False
        for l in self.source.retrieveContent().split("\n"):
            if l.startswith("######"):  # tags 'fr'
                continue
            if l == "---":
                ignore = True
                continue
            if l == "...":
                ignore = False
                continue
            if ignore:
                continue
            linesNew.append(l)
        "\n".join(linesNew)
        return

    def sendMailAsPreliminary(self) -> bool:
        sender = MailParticipant(opt.LDAP_MAIL, opt.MAIL_DISPLAY_NAME)
        receivers = opt.PRELIMINARY_MAIL_RECEIVER
Dominik Woiwode's avatar
Dominik Woiwode committed
242
243
244
        text = (f"Hallo zusammen,\n\n"
                f"anbei das vorläufige Protokoll der Fachrats-Sitzung vom {self.date.strftime('%d.%m.%Y')}.\n\n"
                f"Änderungswünsche bitte direkt an mich, bzw. mir kurz Bescheid geben, wenn ihr was im Pad geändert habt.\n\n"
245
                f"Falls es Probleme mit dieser Mail gibt, meldet euch bitte bei mir. Diese Mail wurde automatisch erstellt.\n\n"
Dominik Woiwode's avatar
Dominik Woiwode committed
246
                f"Viele Grüße\n"
247
                f"{opt.MAIL_DISPLAY_NAME}\n")
Dominik Woiwode's avatar
Dominik Woiwode committed
248
249
        subject = f"Vorläufiges Protokoll der FR-Sitzung vom {self.date.strftime('%d.%m.%Y')}"
        try:
250
            sendFRMail(text, subject, sender, receivers, attachment=self, ldapPassword=opt.LDAP_PASSWORD)
Dominik Woiwode's avatar
Dominik Woiwode committed
251
252
253
254
255
256
257
258
        except Exception:
            return False
        return True

    def sendMailAsApproved(self) -> bool:
        if not self.isApproved:
            print("Protocol is not approved yet!")
            raise PermissionError("Protocol is not approved yet!")
259
260
        sender = MailParticipant(opt.LDAP_MAIL, opt.MAIL_DISPLAY_NAME)
        receivers = opt.APPROVED_MAIL_RECEIVER
Dominik Woiwode's avatar
Dominik Woiwode committed
261
262
263
264
265
        text = (f"Hallo zusammen,\n\n"
                f"anbei das Protokoll der Fachrats-Sitzung vom {self.date.strftime('%d.%m.%Y')}.\n\n"
                f"Alle Protokolle sind zu finden unter:\n"
                f"https://cloud.finf.uni-hannover.de/index.php/s/Erw9Cbta0PruqZI\n\n"
                f"Viele Grüße\n"
266
                f"{opt.MAIL_DISPLAY_NAME}\n")
Dominik Woiwode's avatar
Dominik Woiwode committed
267
268
        subject = f"Protokoll der FR-Sitzung vom {self.date.strftime('%d.%m.%Y')}"
        try:
269
            sendFRMail(text, subject, sender, receivers, attachment=self, ldapPassword=opt.LDAP_PASSWORD)
Dominik Woiwode's avatar
Dominik Woiwode committed
270
271
272
        except Exception:
            return False
        return True
Dominik Woiwode's avatar
Dominik Woiwode committed
273

Jakob Marten's avatar
Jakob Marten committed
274
    def uploadToCloud(self):
Dominik Woiwode's avatar
Dominik Woiwode committed
275
276
        pass

Jakob Marten's avatar
Jakob Marten committed
277
    def uploadToGrav(self):
Dominik Woiwode's avatar
Dominik Woiwode committed
278
        # Init semester
Jakob Marten's avatar
Jakob Marten committed
279
        # TODO: better file management
Jakob Marten's avatar
Jakob Marten committed
280
        self.semester.uploadToGrav()
281
        if not os.path.exists(str(self.rawPath)):
Dominik Woiwode's avatar
Dominik Woiwode committed
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
            raise FileNotFoundError(f"{self.rawPath} doesn't exist")

        # TODO: move conversion to another method?
        # Tops
        tops = self.parseTops()
        tops_text = ", ".join(tops)

        # Header
        if self.isFachgruppenvollversammlung:
            name = "der Fachgruppenvollversammlung"
        else:
            name = f"des {self.gremium.fullName}"
        header = ("---\n"
                  f"title: Protokoll {name} am {self.date.strftime('%d.%m.%Y')}\n"
                  f"date: {self.date.strftime('%d.%m.%Y')}\n"
                  f"tops: {tops_text}\n"
                  "---\n\n"
                  "[MINITOC]\n\n")
        # Upload
301
302
303
        os.makedirs(str(self.gravPath.parent), exist_ok=True)
        with open(str(self.gravPath), "w", encoding="utf-8") as f:
            f.write(header + self.cleanedRaw())
Dominik Woiwode's avatar
Dominik Woiwode committed
304

305
306
        git = opt.git
        git.add(opt.GRAV_PROTOCOL_PATH)
Dominik Woiwode's avatar
Dominik Woiwode committed
307
308
        git.commit(f"Added protocol {self.displayName}")
        git.push()
Dominik Woiwode's avatar
Dominik Woiwode committed
309
310
311


class AttachementPad(BasePad):
Dominik Woiwode's avatar
Dominik Woiwode committed
312
    def __init__(self, source: SourceTypes, name: str, date: datetime.datetime = None, version=0, isApproved=False):
313
        super().__init__(source, date=date, isApproved=isApproved)
Dominik Woiwode's avatar
Dominik Woiwode committed
314
315
        self.name = name
        self.version = version
Dominik Woiwode's avatar
Dominik Woiwode committed
316
317
318
319


class PadCollection(BasePad):
    def __init__(self, source: SourceTypes):
320
321
322
323
324
325
326
327
328
329
        super().__init__(source, isApproved=False, date=datetime.datetime.now())
        self._pads: Dict[str, List[BasePad]] = dict()
        self.__retrieved = False

    def __iter__(self) -> Iterator[Tuple[str, BasePad]]:
        """ Iter (folder, pad) """
        pads = self.pads
        for folder in pads:
            for pad in pads[folder]:
                yield folder, pad
Dominik Woiwode's avatar
Dominik Woiwode committed
330

Dominik Woiwode's avatar
Dominik Woiwode committed
331
332
333
    def DEFAULT_DISPLAY_NAME(self):
        return f"PadCollection"

334
335
336
337
338
339
340
341
342
343
344
345
346
347
    def addPads(self, folder: str, pads: List[BasePad]):
        self._pads[folder] = pads

    def clearAllPads(self):
        self._pads = dict()

    @property
    def pads(self):
        if not self.__retrieved:
            self._pads.update(self.getPads())
            self.__retrieved = True

        return self._pads

Dominik Woiwode's avatar
Dominik Woiwode committed
348
    def getPads(self) -> Dict[str, List[BasePad]]:
Dominik Woiwode's avatar
Dominik Woiwode committed
349
350
351
        """
        Parsing the protocollink-Pad for urls.
        """
Dominik Woiwode's avatar
Dominik Woiwode committed
352
        pads = dict()
Jakob Marten's avatar
Jakob Marten committed
353
        semesters = dict()
Dominik Woiwode's avatar
Dominik Woiwode committed
354
        currentFolder = ""
Dominik Woiwode's avatar
Dominik Woiwode committed
355
        for line in self.source.retrieveContent().split("\n"):
Dominik Woiwode's avatar
Dominik Woiwode committed
356
357
358
            if line.startswith("# "):
                currentFolder = line.split("#")[1].strip()
                continue
Dominik Woiwode's avatar
Dominik Woiwode committed
359
360
361
            pad = self.parsePad(line)
            if pad is None:
                continue
Dominik Woiwode's avatar
Dominik Woiwode committed
362
363
            if currentFolder not in pads:
                pads[currentFolder] = list()
Dominik Woiwode's avatar
Dominik Woiwode committed
364
365
366
367
368
            if isinstance(pad, ProtocolPad) and pad.date is not None:
                semester = Semester.fromDate(pad.date)
                if semester not in semesters:
                    semesters[semester] = semester
                pad.semester = semester
Jakob Marten's avatar
Jakob Marten committed
369
            pad.folder = currentFolder
Dominik Woiwode's avatar
Dominik Woiwode committed
370
            pads[currentFolder].append(pad)
Dominik Woiwode's avatar
Dominik Woiwode committed
371
372
373

        return pads

374
375
    @classmethod
    def parsePad(cls, line: str, prefixes=None) -> Optional[BasePad]:
Dominik Woiwode's avatar
Dominik Woiwode committed
376
        url, *comment = line.split("#")
377
        if not url.strip():  # Only whitespace
Dominik Woiwode's avatar
Dominik Woiwode committed
378
            return None
379
380
381
382
383
384
385
386
387
        allPrefixes, url = url.split("https://")
        if prefixes is not None:
            allPrefixes += prefixes
        url = f"https://{url}".strip()

        if Etherpad.fitUrl(url):
            retrieveClass = CachedEtherPad
        elif CodiMD.fitUrl(url):
            retrieveClass = CachedCodiMD
Dominik Woiwode's avatar
Dominik Woiwode committed
388
        else:
389
390
            raise ValueError("Cannot retrieve SourceType class")
        src = retrieveClass(url)
Dominik Woiwode's avatar
Dominik Woiwode committed
391

392
393
394
        isAttachement = opt.ATTACHMENT_SIGN in allPrefixes
        isFachgrupenvollversammlung = opt.FACHGRUPPENVOLLVERSAMMLUNG_SIGN in allPrefixes
        isApproved = opt.NOT_APPROVED_SIGN not in allPrefixes
Dominik Woiwode's avatar
Dominik Woiwode committed
395
396
397
398
399
400
401
402
403
404
405
406

        kwargs = dict()
        if isAttachement:
            padType = AttachementPad
            kwargs["date"] = None
            kwargs["name"] = None
            kwargs["version"] = None
            kwargs["isApproved"] = isApproved
        else:
            padType = ProtocolPad
            kwargs["isApproved"] = isApproved
            try:
407
                date = datetime.datetime.strptime(comment[0].strip(), "%d.%m.%Y")
Dominik Woiwode's avatar
Dominik Woiwode committed
408
409
410
411
412
413
414
415
416
            except Exception:
                dateStr = url.split("protokoll")[-1][:8]
                date = datetime.datetime.strptime(dateStr, "%Y%m%d")

            kwargs["date"] = date
            kwargs["isFachgruppenvollversammlung"] = isFachgrupenvollversammlung

        return padType(src, **kwargs)

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    def removeApproved(self):
        oldPads = self.pads
        self.clearAllPads()
        for folder in oldPads:
            folderPads = list()
            for pad in oldPads[folder]:
                if not pad.isApproved:
                    folderPads.append(pad)
            if folderPads:
                self.addPads(folder, folderPads)

    def removeOld(self):
        oldPads = self.pads
        self.clearAllPads()
        for folder in oldPads:
            folderPads = list()
            for pad in oldPads[folder]:
                if not isinstance(pad, Etherpad):
                    folderPads.append(pad)
            if folderPads:
                self.addPads(folder, folderPads)
        return self.pads

    def downloadPads(self, forceDownload=False):
        for folder, pad in self:
            pad.download(forceDownload)

    def compilePads(self, template: str = None):
        for folder, pad in self:
            pad.compile(template)

    def createTopics(self):
        raise NotImplementedError()
Jakob Marten's avatar
Jakob Marten committed
450
451


Dominik Woiwode's avatar
Dominik Woiwode committed
452
453
454
if __name__ == '__main__':
    import argparse

455
456
457
    opt = config.Config()
    parser = argparse.ArgumentParser(description="Download and convert finf/fsr-protocols using pandoc")

Dominik Woiwode's avatar
Dominik Woiwode committed
458
459
460
461
462
463
    parser.add_argument("-urls", nargs="+", type=str, default=[])
    parser.add_argument("-pad", type=str, default=None)
    # parser.add_argument("--prefixes", type=str, default="",
    #                     help=f"Add additional information to pad:\n"
    #                          f"Not approved: {NOT_APPROVED_SIGN}\n"
    #                          f"Fachschaftenvollversammlung: {FACHSCHAFTENVERSAMMLUNG_SIGN}\n"
464
    #                          f"Attachement: {ATTACHMENT_SIGN}\n")
Dominik Woiwode's avatar
Dominik Woiwode committed
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
    parser.add_argument("--finf", action="store_true")
    parser.add_argument("--topics", action="store_true")
    parser.add_argument("--fsr", action="store_true")
    parser.add_argument("--download", action="store_true")
    parser.add_argument("--ignoreOld", action="store_true")
    parser.add_argument("--compile", action="store_true")
    parser.add_argument("--newOnly", action="store_true")
    parser.add_argument("--override", action="store_true")
    parser.add_argument("--mail", action="store_true")

    parsed = parser.parse_args()

    urls = parsed.urls
    if not urls and parsed.pad is None:
        parser.print_usage()
        exit()

    if parsed.finf and parsed.fsr:
        raise AttributeError("Cannot have --finf AND --fsr")

    if parsed.finf:
486
        opt.GREMIUM = GREMIUM_FR
Dominik Woiwode's avatar
Dominik Woiwode committed
487
    if parsed.fsr:
488
        opt.GREMIUM = GREMIUM_FSR
Dominik Woiwode's avatar
Dominik Woiwode committed
489
490

    if parsed.override:
491
        opt.OVERRIDE_ACCEPTED = True
Dominik Woiwode's avatar
Dominik Woiwode committed
492

493
494
    pads = PadCollection(CodiMD(parsed.pad))
    pads.addPads("unsorted", [PadCollection.parsePad(url, prefixes=parsed.prefixes) for url in urls])
Dominik Woiwode's avatar
Dominik Woiwode committed
495
496

    if parsed.newOnly:
497
        pads.removeApproved()
Dominik Woiwode's avatar
Dominik Woiwode committed
498
    if parsed.ignoreOld:
499
        pads.removeOld()
Dominik Woiwode's avatar
Dominik Woiwode committed
500
501

    if parsed.download:
502
        pads.downloadPads(opt.OVERRIDE_ACCEPTED)
Dominik Woiwode's avatar
Dominik Woiwode committed
503

504
505
    if parsed.topics:
        pads.createTopics()
Dominik Woiwode's avatar
Dominik Woiwode committed
506
507

    if parsed.compile:
508
        pads.compilePads()