diff --git a/tagger.py b/tagger.py index 0299aa1..107f035 100644 --- a/tagger.py +++ b/tagger.py @@ -12,7 +12,7 @@ OUTPUT_FILE = 'tags.json' TAGS_PER_ARTICLE = 5 JSON_INDENT = 2 -UPPER_CHECK = re.compile(r'[A-Z]') +_UPPER_CHECK = re.compile(r'[A-Z]') @dataclass @@ -28,40 +28,60 @@ class FileScanner(HTMLParser): self.texte = [] def scan_file(self): + # Datei einlesen content = read_file(self.file) + # HTMLParser aufrufen um HTML-Syntax-Elemente zu entfernen. self.feed(content) words_with_usage = {} words = [] for text in self.texte: + # Eventuelle URL-codierte Zeichen in die eigentliche Zeichen umwandeln. (z.B. %2F -> /) text = unquote_plus(text) + # Textteile in einzelne Wörter aufteilen words += re.split(r'[ /\-_#\n.?=]', text) print(f'\nFile {self.file.parent.name} contains {len(words)} words') + # Titel in einzelne Wörter aufteilen title_words = set(self.file.parent.name.split('-')) for word in words: + # Verschiedene Zeichen vom Anfang und Ende der Wörter entfernen. tag_name = word.strip(".,:;!\"'<>()") + # Leere Wörter ignorieren if not tag_name: continue + # Alle Buchstaben verkleinern, aber gleichzeitig originales Wort merken word = tag_name.lower() + # Standard Bewertung für jedes Wort ist 10 score = 10 + # Wörter, die in der Liste der ausgeschlossenen Wörter stehen, ignorieren if word in EXCLUDED_WORDS: continue + # Wörter, die nur aus Zahlen bestehen, ignorieren if word.isdigit(): continue + # Die Bewertung von Wörtern, die im Titel vorkommen, deutlich verbessern. if word in title_words: score *= 4 + # Die Bewertung von Wörtern, die kürzer oder gleich lang sind als 3 Buchstaben, + # entsprechend der Länge des Wortes verringern. word_length = len(word) if word_length <= 3: score = int(score * word_length / 4) - upper_letters_count = len(UPPER_CHECK.findall(tag_name)) + # Die Anzahl der Großbuchstaben in dem originalen Wort zählen ... + upper_letters_count = len(_UPPER_CHECK.findall(tag_name)) + # ... und die Bewertung entsprechen der Anzahl verbessern. score += upper_letters_count * 5 + # Die Bewertung für das Wort speichern. + # Wenn das Wort bereits eine Bewertung besitzt werden die beiden Bewertungen zusammen gerechnet. if word not in words_with_usage: words_with_usage[word] = Tag(name=tag_name, score=score) else: words_with_usage[word].score += score + # Die Wörter nach ihrer Bewertung sortieren return sorted(words_with_usage.values(), key=lambda tag: tag.score, reverse=True) def handle_starttag(self, tag, attrs): + # Die Links, die in den 'href' Attributen eines HTML-Elements stehen, mit einbeziehen. if tag != "a": return for attr_name, attr_value in attrs: @@ -70,10 +90,12 @@ class FileScanner(HTMLParser): break def handle_data(self, data): + # Den Text innerhalb eines HTML-Elements mit einbeziehen. self.texte.append(data) def display_tags(tags, min_score): + # Die Ergebnisse auf der Konsole ausgeben. for tag in tags: if tag.score <= min_score: continue @@ -88,27 +110,35 @@ class CustomJsonEncoder(json.JSONEncoder): def write_tags(tags): + # Die Ergebnisse in JSON umwandeln. content = json.dumps(tags, indent=JSON_INDENT, cls=CustomJsonEncoder) + # Das JSON in eine Datei schreiben. with open(OUTPUT_FILE, 'w') as file: file.write(content) def read_file(file: Path) -> str: + # Eine Datei einlesen with open(file, 'r') as file: return file.read() def main(): final_tags = {} - for file in SOURCE_DIR.glob('**/index.txt'): + for file in SOURCE_DIR.glob('**/index.txt'): # Nach allen index.txt Dateien suchen + # Die Dateien, deren Ordner mit 'autosave-' beginnen, ignorieren. title = file.parent.name if title.startswith('autosave-'): continue + # Die Datei analysieren scanner = FileScanner(file) tags = scanner.scan_file() + # Die Ergebnisse auf der Konsole ausgeben display_tags(tags, min_score=20) + # Die eingestellte Anzahl an Tags für die Ausgabedatei übernehmen, sofern vorhanden. final_tags[title] = tags[:TAGS_PER_ARTICLE] if len(tags) > TAGS_PER_ARTICLE else tags - # write_tags(final_tags) + # Die Ausgabedatei schreiben + write_tags(final_tags) if __name__ == '__main__':