add code comments

This commit is contained in:
OneNewDev 2022-05-28 19:22:30 +02:00
parent e1e0669fca
commit 2802b83649

View file

@ -12,7 +12,7 @@ OUTPUT_FILE = 'tags.json'
TAGS_PER_ARTICLE = 5 TAGS_PER_ARTICLE = 5
JSON_INDENT = 2 JSON_INDENT = 2
UPPER_CHECK = re.compile(r'[A-Z]') _UPPER_CHECK = re.compile(r'[A-Z]')
@dataclass @dataclass
@ -28,40 +28,60 @@ class FileScanner(HTMLParser):
self.texte = [] self.texte = []
def scan_file(self): def scan_file(self):
# Datei einlesen
content = read_file(self.file) content = read_file(self.file)
# HTMLParser aufrufen um HTML-Syntax-Elemente zu entfernen.
self.feed(content) self.feed(content)
words_with_usage = {} words_with_usage = {}
words = [] words = []
for text in self.texte: for text in self.texte:
# Eventuelle URL-codierte Zeichen in die eigentliche Zeichen umwandeln. (z.B. %2F -> /)
text = unquote_plus(text) text = unquote_plus(text)
# Textteile in einzelne Wörter aufteilen
words += re.split(r'[ /\-_#\n.?=]', text) words += re.split(r'[ /\-_#\n.?=]', text)
print(f'\nFile {self.file.parent.name} contains {len(words)} words') 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('-')) title_words = set(self.file.parent.name.split('-'))
for word in words: for word in words:
# Verschiedene Zeichen vom Anfang und Ende der Wörter entfernen.
tag_name = word.strip(".,:;!\"'<>()") tag_name = word.strip(".,:;!\"'<>()")
# Leere Wörter ignorieren
if not tag_name: if not tag_name:
continue continue
# Alle Buchstaben verkleinern, aber gleichzeitig originales Wort merken
word = tag_name.lower() word = tag_name.lower()
# Standard Bewertung für jedes Wort ist 10
score = 10 score = 10
# Wörter, die in der Liste der ausgeschlossenen Wörter stehen, ignorieren
if word in EXCLUDED_WORDS: if word in EXCLUDED_WORDS:
continue continue
# Wörter, die nur aus Zahlen bestehen, ignorieren
if word.isdigit(): if word.isdigit():
continue continue
# Die Bewertung von Wörtern, die im Titel vorkommen, deutlich verbessern.
if word in title_words: if word in title_words:
score *= 4 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) word_length = len(word)
if word_length <= 3: if word_length <= 3:
score = int(score * word_length / 4) 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 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: if word not in words_with_usage:
words_with_usage[word] = Tag(name=tag_name, score=score) words_with_usage[word] = Tag(name=tag_name, score=score)
else: else:
words_with_usage[word].score += score 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) return sorted(words_with_usage.values(), key=lambda tag: tag.score, reverse=True)
def handle_starttag(self, tag, attrs): def handle_starttag(self, tag, attrs):
# Die Links, die in den 'href' Attributen eines <a> HTML-Elements stehen, mit einbeziehen.
if tag != "a": if tag != "a":
return return
for attr_name, attr_value in attrs: for attr_name, attr_value in attrs:
@ -70,10 +90,12 @@ class FileScanner(HTMLParser):
break break
def handle_data(self, data): def handle_data(self, data):
# Den Text innerhalb eines HTML-Elements mit einbeziehen.
self.texte.append(data) self.texte.append(data)
def display_tags(tags, min_score): def display_tags(tags, min_score):
# Die Ergebnisse auf der Konsole ausgeben.
for tag in tags: for tag in tags:
if tag.score <= min_score: if tag.score <= min_score:
continue continue
@ -88,27 +110,35 @@ class CustomJsonEncoder(json.JSONEncoder):
def write_tags(tags): def write_tags(tags):
# Die Ergebnisse in JSON umwandeln.
content = json.dumps(tags, indent=JSON_INDENT, cls=CustomJsonEncoder) content = json.dumps(tags, indent=JSON_INDENT, cls=CustomJsonEncoder)
# Das JSON in eine Datei schreiben.
with open(OUTPUT_FILE, 'w') as file: with open(OUTPUT_FILE, 'w') as file:
file.write(content) file.write(content)
def read_file(file: Path) -> str: def read_file(file: Path) -> str:
# Eine Datei einlesen
with open(file, 'r') as file: with open(file, 'r') as file:
return file.read() return file.read()
def main(): def main():
final_tags = {} 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 title = file.parent.name
if title.startswith('autosave-'): if title.startswith('autosave-'):
continue continue
# Die Datei analysieren
scanner = FileScanner(file) scanner = FileScanner(file)
tags = scanner.scan_file() tags = scanner.scan_file()
# Die Ergebnisse auf der Konsole ausgeben
display_tags(tags, min_score=20) 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 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__': if __name__ == '__main__':