diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbd2e83 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +GTSv* \ No newline at end of file diff --git a/README.md b/README.md index cd2b918..4639b46 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,38 @@ # Nedir? -https://github.com/ogun/guncel-turkce-sozluk reposunda bulunan TDK Güncel Türkçe Sözlük gts.json.tar.gz dosyasını -PyGlossary aracılığıyla StarDict, Kobo ve Kindle formatlarına çeviren bir Python betiği. +TDK Güncel Türkçe Sözlük gts.json.tar.gz dosyasını PyGlossary aracılığıyla StarDict, Kobo ve Kindle formatlarına çeviren bir Python betiği. # Kullanımı `python gts_convert.py --help` ``` -usage: gts_convert.py [-h] [--json-tar-gz-path JSON_TAR_GZ_PATH] [--stardict] [--kobo] [--kindle] [--dictzip] - [--dictgen DICTGEN] +usage: gts_convert.py [-h] [--json-tar-gz-path JSON_TAR_GZ_PATH] [--cekim-sozlukler CEKIM_SOZLUKLER] [--stardict] + [--kobo] [--kindle] [--dictzip] [--dictgen DICTGEN] -https://github.com/ogun/guncel-turkce-sozluk reposunda bulunan TDK Güncel Türkçe Sözlük gts.json.tar.gz dosyasını -PyGlossary aracılığıyla StarDict, Kobo ve Kindle formatlarına çeviren bir Python betiği. +TDK Güncel Türkçe Sözlük gts.json.tar.gz dosyasını PyGlossary aracılığıyla StarDict, Kobo ve Kindle formatlarına çeviren bir Python betiği. options: -h, --help show this help message and exit --json-tar-gz-path JSON_TAR_GZ_PATH gts.json.tar.gz konumu. + --cekim-sozlukler CEKIM_SOZLUKLER + Sözcük çekimleri için ek Stardict sözlüklerinin dosya yolları. Birden fazla kaynağı noktalı + virgül (;) ile ayırın --stardict StarDict çıktı formatı oluşturulsun. --kobo Kobo dicthtml.zip çıktı formatı oluşturulsun. --kindle Kindle MOBI çıktı formatı oluşturulsun. --dictzip StarDict .dict dosyasını sıkıştıracak dictzip aracı PATH'de mi? --dictgen DICTGEN Kobo dicthtml-tr.zip dosyasını oluşturacak aracın (dictgen-*.exe) konumu. ``` -Yukarıda belirtilen repodan gts.json.tar.gz dosyasını gts_convert.py betiğinin yanına indirin. Sözcüklerin çekim bilgilerinin yer aldığı tr_TR.json.gz dosyasının betik ile aynı konumda olduğundan emin olun. (Bu dosyanın nasıl oluşturulduğunu merak ediyorsanız [bağlantıyı](https://github.com/anezih/HunspellWordForms) takip edin. Üretilen json dosyasının [kaynak Hunspell dosyaları](https://github.com/titoBouzout/Dictionaries/blob/master/Turkish.txt).) +gts.json.tar.gz dosyasının ve sözcüklerin çekim bilgilerinin yer aldığı tr_TR.json.gz dosyasının betik ile aynı konumda olduğundan emin olun. (Bu dosyanın nasıl oluşturulduğunu merak ediyorsanız [bağlantıyı](https://github.com/anezih/HunspellWordForms) takip edin. Üretilen json dosyasının [kaynak Hunspell dosyaları](https://github.com/titoBouzout/Dictionaries/blob/master/Turkish.txt).) (NOT: 2.4 versiyonu öncesinde kaynak olarak kullanılan gts.json.tar.gz dosyasına [buradan](https://github.com/ogun/guncel-turkce-sozluk) ulaşabilirsiniz) Tüm formatları üretmek için betiği şu şekilde çağırın: `python gts_convert.py --stardict --kobo --kindle --dictzip --dictgen "dictgen-windows.exe"` +`--cekim-sozlukler` parametresi, var olan sözcük çekim bilgilerini hazırlanan sözlüğe ekleyebilmenizi sağlar. Bu parametreye çekim bilgileri olan StarDict sözlüklerinin yollarını gösterin. Birden fazla sözlük kullanılacaksa bunları noktalı virgül (;) ile ayırın. Örnek: +``` +python gts_convert.py --cekim-sozlukler "D:\sozlukler\kaynak_1.ifo;D:\sozlukler\kaynak_2.ifo" --stardict --kobo --kindle --dictzip --dictgen "dictgen-windows.exe" +``` + `--dictzip` anahtarı, kullanıldığında dictzip çalıştırılabilir dosyasının PATH'de olduğunu belirtir. (Windows'a yüklemek için: https://github.com/Tvangeste/dictzip-win32) `--dictgen` parametresi Dictfile dosyasını Kobo dicthtml.zip formatına dönüştüren çalıştırılabilir dosyanın konumunu gösterir. Sisteminiz için uygun dictgen-* programını https://github.com/pgaskin/dictutil adresinden edinebilirsiniz. @@ -39,6 +45,7 @@ pip install requests # Kobo sözlüğünü yükleme * Sözlüğü `KOBOeReader/.kobo/dict` konumuna kopyalayın. * `KOBOeReader/.kobo/Kobo/Kobo eReader.conf` dosyasında `ApplicationPreferences` kısmının altına `ExtraLocales=tr` seçeneğini ekleyin. +* Veya sözlüğü doğrudan `KOBOeReader/.kobo/custom-dict` konumuna kopyalayın. * Kaynak ve detaylı açıklama için [buraya](https://pgaskin.net/dictutil/dicthtml/install.html) başvurun. diff --git a/src/gts.json.tar.gz b/src/gts.json.tar.gz new file mode 100644 index 0000000..dc3f5a8 Binary files /dev/null and b/src/gts.json.tar.gz differ diff --git a/src/gts_convert.py b/src/gts_convert.py index 3fc142f..f444d88 100644 --- a/src/gts_convert.py +++ b/src/gts_convert.py @@ -7,24 +7,46 @@ import sys import tarfile from copy import deepcopy -from time import sleep +from datetime import datetime import requests from pyglossary.glossary_v2 import Glossary from pyglossary.sort_keys import namedSortKeyList -VERSION = (2, 3) -LAST_ID = 92411 +VERSION = (2, 4) +LAST_ID = 99501 +DUZELTME_IMLERI_DICT = { + "Â" : "A", "â" : "a", + "Û" : "U", "û" : "u", + "Î" : "İ", "î" : "i" +} +normalize = str.maketrans(DUZELTME_IMLERI_DICT) -class INFL: - # https://github.com/anezih/HunspellWordForms - def __init__(self, unmunched: str) -> None: - try: - with gzip.open(unmunched, "rt", encoding="utf-8") as infl: - temp = json.load(infl) - except: - sys.exit("Sözcük çekimlerinin bulunduğu gzip dosyası açılamadı.\ntr_TR.json.gz dosyasının betikle aynı konumda olduğundan emin olun.") +class INFL(): + def __init__(self, source: str) -> None: self.j = {} + self.populate_dict(source=source) + + def populate_dict(self, source: str, glos_format: str = "") -> None: + raise NotImplementedError + + def get_infl(self, word: str) -> list[str]: + raise NotImplementedError + +class Unmunched(INFL): + def populate_dict(self, source: str) -> None: + if source.endswith(".gz"): + try: + with gzip.open(source, "rt", encoding="utf-8") as f: + temp = json.load(f) + except: + sys.exit("[!] Gzip ile sıkıştırılmış tr_TR.json.gz dosyası açılamadı.\n Dosya ismini/yolunu kontrol edin.") + else: + try: + with open(source, "r", encoding="utf-8") as f: + temp = json.load(f) + except: + sys.exit("[!] tr_TR.json dosyası açılamadı.\n Dosya ismini/yolunu kontrol edin.") for it in temp: for key, val in it.items(): if key in self.j.keys(): @@ -32,12 +54,30 @@ def __init__(self, unmunched: str) -> None: else: self.j[key] = val - def get_sfx(self, word: str) -> list: - word_dict = self.j.get(word) - if word_dict: - return word_dict["SFX"] - else: - return [] + def get_infl(self, word: str) -> list[str]: + afx = [] + afx_lst = self.j.get(word) + if afx_lst: + afx += afx_lst["SFX"] + return afx + +class GlosSource(INFL): + def populate_dict(self, source: str) -> None: + if not os.path.exists(source): + sys.exit("[!] Çekimler için kaynak olarak kullanılacak sözlük bulunamadı.\n Dosya ismini/yolunu kontrol edin.") + glos = Glossary() + glos.directRead(filename=source) + for entry in glos: + if len(entry.l_word) < 2: + continue + hw = entry.l_word[0] + if hw in self.j.keys(): + self.j[hw] += entry.l_word[1:] + else: + self.j[hw] = entry.l_word[1:] + + def get_infl(self, word: str) -> list[str]: + return self.j.get(word, []) def out_dir(name: str, format: str) -> str: folder_name = f"{name}_{format}" @@ -66,19 +106,20 @@ def fix_quotes(text: str) -> str: def fix_df_hws(fname: str) -> None: with open(fname, "r", encoding="utf-8") as df: - _in = df.readlines() - _out = [] - for line in _in: - if line.startswith("@"): - line = line.replace("\"", "'") - _out.append(line) - else: - _out.append(line) - with open(fname, "w", encoding="utf-8") as df_out: - for out_line in _out: - df_out.write(out_line) + with open(f"{fname}_fixed", "w", encoding="utf-8") as df_out: + for line in df.readlines(): + if line.startswith("@"): + line = line.replace("\"", "'") + df_out.write(line) + df_out.flush() + else: + df_out.write(line) + df_out.flush() -def dl_new_entries(num: int) -> list[dict]: +def dl_new_entries(num: int, ignore_cache: bool = False) -> list[dict]: + if os.path.exists(cache_fname := f"{num+1}_{LAST_ID}.json") and not ignore_cache: + with open(cache_fname, "r", encoding="utf-8") as cache_in: + return json.load(cache_in) extra_arr = [] s = requests.Session() headers = { @@ -89,34 +130,46 @@ def dl_new_entries(num: int) -> list[dict]: try: res = s.get(url, params={"id": i}, headers=headers) if res.status_code == 200: + if res.json().get("error"): + continue extra_arr.append(res.json()[0]) + print(f"Yeni girdilerden {i}/{LAST_ID} indirildi.", end="\r") except: pass - sleep(1.5) + print("\n") + if extra_arr: + extra_arr.sort(key=lambda x: int(x["madde_id"])) + with open(cache_fname, "w", encoding="utf-8") as cache_out: + json.dump(extra_arr, cache_out, ensure_ascii=False, indent=2) return extra_arr def local_json(fname: str) -> list[dict]: arr = [] with tarfile.open(fname, "r:gz") as f: - _json = f.extractfile("gts.json").readlines() - for i in _json: - arr.append(json.loads(i)) - if (num := len(arr)) < LAST_ID: + _json = f.extractfile("gts.json") + if _json.read(1).decode() == "[": + _json.seek(0,0) + arr = json.load(_json) + else: + for i in _json.readlines(): + arr.append(json.loads(i)) + arr.sort(key=lambda x: int(x["madde_id"])) + if (num := int(arr[-1]["madde_id"])) < LAST_ID: arr += dl_new_entries(num=num) return arr - -def create_dictionaries(dictionary: list[dict], infl: INFL, stardict: bool = False, kobo: bool = False, kindle: bool = False, dictzip: bool = False, dictgen: str = ""): - Glossary.init() + +def create_dictionaries(dictionary: list[dict], infl_dicts: list[INFL], stardict: bool = False, kobo: bool = False, kindle: bool = False, dictzip: bool = False, dictgen: str = ""): glos = Glossary() glos.setInfo("title", "Güncel Türkçe Sözlük") glos.setInfo("author", "https://github.com/anezih") - glos.setInfo("description", "TDK Güncel Türkçe Sözlük") + glos.setInfo("description", f"TDK Güncel Türkçe Sözlük | Sürüm: {VERSION[0]}.{VERSION[1]}") + glos.setInfo("date", f"{datetime.today().strftime('%d/%m/%Y')}") glos.sourceLangName = "tr" glos.targetLangName = "tr" for it in dictionary: if not it.get("anlamlarListe"): - continue + continue entry = f'
'
features = f''
if it["telaffuz"]:
@@ -124,7 +177,7 @@ def create_dictionaries(dictionary: list[dict], infl: INFL, stardict: bool = Fal
if it["lisan"]:
features += f'{"
" if len(features) > 1 else ""} Orijin: {it["lisan"]}'
if it["cogul_mu"] == "1":
- features += f'{"
" if len(features) > 1 else ""}[ÇOĞUL]'
+ features += f'{"
" if len(features) > 1 else ""}[ÇOĞUL]'
if it["ozel_mi"] == "1":
features += f'{"
" if "[ÇOĞUL]" not in features else ""}[ÖZEL]'
if len(features) > 1:
@@ -136,7 +189,7 @@ def create_dictionaries(dictionary: list[dict], infl: INFL, stardict: bool = Fal
on_taki = f'{it["on_taki"]} '
if it["taki"]:
taki = f', -{it["taki"]}'
- if on_taki or taki:
+ if on_taki or taki:
anlamlar += f'{on_taki}{it["madde"]}{taki}
'
for idx, a in enumerate(it["anlamlarListe"], start=1):
anlam = f''
@@ -168,9 +221,21 @@ def create_dictionaries(dictionary: list[dict], infl: INFL, stardict: bool = Fal
birlesikler = [f'{i}' for i in birlesikler_temp]
entry += f'{", ".join(birlesikler)}
'
entry += f"