From 3fb2f1804198b4a2f7c473acc2edaf9bac270233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Fern=C3=A1ndez?= <975883+pazos@users.noreply.github.com> Date: Sun, 26 May 2024 20:10:12 +0200 Subject: [PATCH] update tool to generate metadata translations (#11869) * updated: - strings to translate - english metadata * added: - appstream: metadata generator - appstream: translation of screenshot captions, if they're present. - appstream: link to gh release notes --- make/appimage.mk | 2 +- make/linux.mk | 3 +- metadata/en-US/full_description.txt | 25 +- metadata/en-US/short_description.txt | 2 +- .../koreader.metainfo.xml} | 100 +++-- platform/linux/do_debian_package.sh | 2 +- tools/update-metadata.lua | 390 +++++++++++++++--- 7 files changed, 403 insertions(+), 121 deletions(-) rename platform/{appimage/koreader.appdata.xml => common/koreader.metainfo.xml} (76%) diff --git a/make/appimage.mk b/make/appimage.mk index 4c632d431..fdf0e7059 100644 --- a/make/appimage.mk +++ b/make/appimage.mk @@ -9,7 +9,7 @@ update: all $(SYMLINK) $(abspath $(APPIMAGE_DIR)/AppRun) $(INSTALL_DIR)/koreader/ $(SYMLINK) $(abspath $(APPIMAGE_DIR)/koreader.desktop) $(INSTALL_DIR)/koreader/ $(SYMLINK) $(abspath resources/koreader.png) $(INSTALL_DIR)/koreader/ - sed -e 's/%%VERSION%%/$(VERSION)/' -e 's/%%DATE%%/$(RELEASE_DATE)/' $(APPIMAGE_DIR)/koreader.appdata.xml >$(INSTALL_DIR)/koreader/koreader.appdata.xml + sed -e 's/%%VERSION%%/$(VERSION)/' -e 's/%%DATE%%/$(RELEASE_DATE)/' $(PLATFORM_DIR)/common/koreader.metainfo.xml >$(INSTALL_DIR)/koreader/koreader.appdata.xml # TODO at best this is DebUbuntu specific $(SYMLINK) /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 $(INSTALL_DIR)/koreader/libs/libSDL2.so # required for our stock Ubuntu SDL even though we don't use sound diff --git a/make/linux.mk b/make/linux.mk index b2c614fb1..d3a92576a 100644 --- a/make/linux.mk +++ b/make/linux.mk @@ -8,10 +8,11 @@ update: all $(INSTALL_DIR)/linux/bin \ $(INSTALL_DIR)/linux/lib \ $(INSTALL_DIR)/linux/share/pixmaps \ + $(INSTALL_DIR)/linux/share/metainfo \ $(INSTALL_DIR)/linux/share/applications \ $(INSTALL_DIR)/linux/share/doc/koreader \ $(INSTALL_DIR)/linux/share/man/man1 - sed -e 's/%%VERSION%%/$(VERSION)/' -e 's/%%DATE%%/$(RELEASE_DATE)/' $(PLATFORM_DIR)/appimage/koreader.appdata.xml >$(INSTALL_DIR)/linux/koreader.appdata.xml + sed -e 's/%%VERSION%%/$(VERSION)/g' -e 's/%%DATE%%/$(RELEASE_DATE)/' $(PLATFORM_DIR)/common/koreader.metainfo.xml >$(INSTALL_DIR)/linux/share/metainfo/koreader.metainfo.xml cp -pv resources/koreader.png $(INSTALL_DIR)/linux/share/pixmaps cp -pv $(LINUX_DIR)/koreader.desktop $(INSTALL_DIR)/linux/share/applications cp -pv $(LINUX_DIR)/copyright COPYING $(INSTALL_DIR)/linux/share/doc/koreader diff --git a/metadata/en-US/full_description.txt b/metadata/en-US/full_description.txt index 2f93b2715..cd261b425 100644 --- a/metadata/en-US/full_description.txt +++ b/metadata/en-US/full_description.txt @@ -1,14 +1,11 @@ -* portable: runs on embedded devices (Cervantes, Kindle, Kobo, PocketBook), Android and Linux computers. Developers can run a KOReader emulator in Linux and MacOS. - -* multi-format documents: supports fixed page formats (PDF, DjVu, CBT, CBZ) and reflowable e-book formats (EPUB, FB2, Mobi, DOC, CHM, TXT). Scanned PDF/DjVu documents can also be reflowed with the built-in K2pdfopt library. - -* full-featured reading: multi-lingual user interface with a highly customizable reader view and many typesetting options. You can set arbitrary page margins, override line spacing and choose external fonts and styles. It has multi-lingual hyphenation dictionaries bundled into the application. - -* integrated with calibre (search metadata, receive ebooks wirelessly, browse library via OPDS), Wallabag, Wikipedia, Google Translate and other content providers. - -* optimized for e-ink devices: custom UI without animation, with paginated menus, adjustable text contrast, and easy zoom to fit content or page in paged media. - -* extensible via plugins - -* and much more: look up words with StarDict dictionaries / Wikipedia, add your own online OPDS catalogs and RSS feeds, online over-the-air software updates, an FTP client, an SSH server, … - +

KOReader is an ebook reader optimized for e-ink screens. It can open many formats and provides advanced text adjustments.

+

See below for a selection of its many features:

+ diff --git a/metadata/en-US/short_description.txt b/metadata/en-US/short_description.txt index 535be5201..0a1b60d6b 100644 --- a/metadata/en-US/short_description.txt +++ b/metadata/en-US/short_description.txt @@ -1 +1 @@ -Ebook reader with support for many formats like PDF, DjVu, EPUB, FB2, CBZ. +Ebook reader diff --git a/platform/appimage/koreader.appdata.xml b/platform/common/koreader.metainfo.xml similarity index 76% rename from platform/appimage/koreader.appdata.xml rename to platform/common/koreader.metainfo.xml index 3ae788580..97c221e76 100644 --- a/platform/appimage/koreader.appdata.xml +++ b/platform/common/koreader.metainfo.xml @@ -1,55 +1,22 @@ + rocks.koreader.KOReader KOReader - Ebook reader - - -

KOReader is an ebook reader optimized for e-ink screens. It can open many formats and provides advanced text adjustments.

-

See below for a selection of its many features:

- -
- - - - - https://github.com/koreader/koreader-artwork/raw/master/koreader-menu-framed.png - - - - https://github.com/koreader/koreader-artwork/raw/master/koreader-footnotes-framed.png - - - - https://github.com/koreader/koreader-artwork/raw/master/koreader-dictionary-framed.png - - - - - Viewer - Literature - - - KOReader Community + + KOReader Community + CC0-1.0 AGPL-3.0-only https://koreader.rocks/ https://github.com/koreader/koreader/issues - https://github.com/koreader/koreader/wiki + https://koreader.rocks/user_guide https://hosted.weblate.org/engage/koreader/ https://github.com/koreader/koreader - https://koreader.rocks/doc/ + https://github.com/koreader/koreader #ffffff @@ -57,7 +24,6 @@ - 128 360 @@ -117,9 +83,57 @@ rocks.koreader.KOReader.desktop - - - + + Office + Viewer + Literature + + + Ebook reader + +

KOReader is an ebook reader optimized for e-ink screens. It can open many formats and provides advanced text adjustments.

+

See below for a selection of its many features:

+
    +
  • Supports both fixed page formats (PDF, DjVu, CBT, CBZ) and reflowable e-book formats (EPUB, FB2, Mobi, DOC, CHM, TXT, HTML). Scanned PDF/DjVu documents can be reflowed. Special flow directions for reading double column PDFs and manga.
  • +
  • Multi-lingual user interface optimized for e-ink screens. Highly customizable reader view with complete typesetting options. Multi-lingual hyphenation dictionaries are bundled in.
  • +
  • Non-Latin script support for books, including the Hebrew, Arabic, Persian, Russian, Chinese, Japanese and Korean languages.
  • +
  • Unique Book Map and Page Browser features to navigate your book.
  • +
  • Special multi-page highlight mode with many local and online export options.
  • +
  • Can synchronize your reading progress across all your KOReader running devices.
  • +
  • Integrated with Calibre, Wallabag, Wikipedia, Google translate and other content providers.
  • +
+
+ + + https://github.com/koreader/koreader-artwork/raw/master/koreader-menu-framed.png + + + https://github.com/koreader/koreader-artwork/raw/master/koreader-footnotes-framed.png + + + https://github.com/koreader/koreader-artwork/raw/master/koreader-dictionary-framed.png + + + + reader + viewer + dictionary + wikipedia + wallabag + annotations + epub + fb2 + pdf + djvu + + + + +

Release notes available on the link below

+
+ https://github.com/koreader/koreader/releases/tag/%%VERSION%% +
+
diff --git a/platform/linux/do_debian_package.sh b/platform/linux/do_debian_package.sh index ea47b583f..194f53c9e 100755 --- a/platform/linux/do_debian_package.sh +++ b/platform/linux/do_debian_package.sh @@ -65,7 +65,7 @@ fi mkdir -p tmp-debian/usr chmod 0755 tmp-debian/usr tar -xf "${1}" -C tmp-debian/usr -rm -f tmp-debian/usr/koreader.appdata.xml tmp-debian/usr/README.md +rm -f tmp-debian/usr/README.md ARCH="$(echo "${1}" | cut -d '-' -f3)" VERSION="$(cut -f2 -dv "tmp-debian/usr/lib/koreader/git-rev" | cut -f1,2 -d-)" DEB_ARCH="$(uname_to_debian "${ARCH}")" diff --git a/tools/update-metadata.lua b/tools/update-metadata.lua index 7239c4fe0..4df14284c 100755 --- a/tools/update-metadata.lua +++ b/tools/update-metadata.lua @@ -1,46 +1,168 @@ #!/usr/bin/env luajit --- tool to generate localized metadata --- --- metadata is fetched by F-Droid on each tagged release and used to update --- https://f-droid.org/packages/org.koreader.launcher.fdroid/ --- --- usage: ./tools/update_metadata.lua --- --- NOTE: title and screenshots are not translated. These resources are located in metadata/en-US +--[[ + tool to generate localized metadata for application stores. + We currently support F-Droid(fastlane) and Flathub(appstream). + + usage: ./tools/update_metadata.lua +]]-- package.path = "frontend/?.lua;base/" .. package.path local _ = require("gettext") -local metadata = { - ["short_description.txt"] = _("Ebook reader with support for many formats like PDF, DjVu, EPUB, FB2, CBZ."), - ["full_description.txt"] = _([[* portable: runs on embedded devices (Cervantes, Kindle, Kobo, PocketBook), Android and Linux computers. Developers can run a KOReader emulator in Linux and MacOS. - -* multi-format documents: supports fixed page formats (PDF, DjVu, CBT, CBZ) and reflowable e-book formats (EPUB, FB2, Mobi, DOC, CHM, TXT). Scanned PDF/DjVu documents can also be reflowed with the built-in K2pdfopt library. - -* full-featured reading: multi-lingual user interface with a highly customizable reader view and many typesetting options. You can set arbitrary page margins, override line spacing and choose external fonts and styles. It has multi-lingual hyphenation dictionaries bundled into the application. - -* integrated with calibre (search metadata, receive ebooks wirelessly, browse library via OPDS), Wallabag, Wikipedia, Google Translate and other content providers. - -* optimized for e-ink devices: custom UI without animation, with paginated menus, adjustable text contrast, and easy zoom to fit content or page in paged media. - -* extensible via plugins - -* and much more: look up words with StarDict dictionaries / Wikipedia, add your own online OPDS catalogs and RSS feeds, online over-the-air software updates, an FTP client, an SSH server, … -]]), -} - -local function isFile(str) - local f = io.open(str, "r") - if f then - f:close() - return true - end - return false +-- we can't require util here, some C libraries might not be available +local function htmlEscape(text) + return text:gsub("[}{\">/<'&]", { + ["&"] = "&", + ["<"] = "<", + [">"] = ">", + ['"'] = """, + ["'"] = "'", + ["/"] = "/", + }) end +local metadata = { + summary = _("Ebook reader"), + desc = { + paragraphs = { + _("KOReader is an ebook reader optimized for e-ink screens. It can open many formats and provides advanced text adjustments."), + _("See below for a selection of its many features:"), + }, + highlights = { + _("Supports both fixed page formats (PDF, DjVu, CBT, CBZ) and reflowable e-book formats (EPUB, FB2, Mobi, DOC, CHM, TXT, HTML). Scanned PDF/DjVu documents can be reflowed. Special flow directions for reading double column PDFs and manga."), + _("Multi-lingual user interface optimized for e-ink screens. Highly customizable reader view with complete typesetting options. Multi-lingual hyphenation dictionaries are bundled in."), + _("Non-Latin script support for books, including the Hebrew, Arabic, Persian, Russian, Chinese, Japanese and Korean languages."), + _("Unique Book Map and Page Browser features to navigate your book."), + _("Special multi-page highlight mode with many local and online export options."), + _("Can synchronize your reading progress across all your KOReader running devices."), + _("Integrated with Calibre, Wallabag, Wikipedia, Google translate and other content providers."), + }, + }, + notes = { + _ ("Release notes available on the link below"), + }, + screenshots = { + { image = "https://github.com/koreader/koreader-artwork/raw/master/koreader-menu-framed.png", + default = true, + }, + { image = "https://github.com/koreader/koreader-artwork/raw/master/koreader-footnotes-framed.png", + }, + { image = "https://github.com/koreader/koreader-artwork/raw/master/koreader-dictionary-framed.png", + } + }, + keywords = { + _("reader"), + _("viewer"), + _("dictionary"), + _("wikipedia"), + _("wallabag"), + _("annotations"), + -- don't translate formats + "epub", + "fb2", + "pdf", + "djvu", + }, + + -- appstream metadata that needs no translation + component = [[ + rocks.koreader.KOReader + + KOReader + + KOReader Community + + + CC0-1.0 + AGPL-3.0-only + + https://koreader.rocks/ + https://github.com/koreader/koreader/issues + https://koreader.rocks/user_guide + https://hosted.weblate.org/engage/koreader/ + https://github.com/koreader/koreader + https://github.com/koreader/koreader + + + #ffffff + #303030 + + + + 360 + + + + pointing + keyboard + gamepad + + + + 1024 + 600 + always + touch + + + + application/epub+zip + application/fb2 + application/fb3 + application/msword + application/oxps + application/pdf + application/rtf + application/tcr + application/vnd.amazon.mobi8-ebook + application/vnd.comicbook+tar + application/vnd.comicbook+zip + application/vnd.ms-htmlhelp + application/vnd.openxmlformats-officedocument.wordprocessingml.document + application/vnd.palm + application/x-cbz + application/x-chm + application/x-fb2 + application/x-fb3 + application/x-mobipocket-ebook + application/x-tar + application/xhtml+xml + application/xml + application/zip + image/djvu + image/gif + image/jp2 + image/jpeg + image/jxr + image/png + image/svg+xml + image/tiff + image/vnd.djvu + image/vnd.ms-photo + image/x-djvu + image/x-portable-arbitrarymap + image/x-portable-bitmap + text/html + text/plain + + + rocks.koreader.KOReader.desktop + + + Office + Viewer + Literature + + + +]], +} + +local updated_files = {} local function writeFile(str, path) local f = io.open(path, "w") + table.insert(updated_files, path) if f then f:write(str) f:write("\n") @@ -65,38 +187,186 @@ local function getLocales() end end output:close() + table.insert(locales, 1, "en") return locales end ----------------------------------------------------------------- -print("updating metadata for " .. #getLocales() .. " languages") -for file, str in pairs(metadata) do - local count = { new = 0, updated = 0, not_translated = 0 } +local locales = getLocales() - -- update english - _.changeLang("en") - local source = _(str) - local metadata_file = "metadata/en-US/" .. file - writeFile(source, metadata_file) +local function htmlDescription(lang) + local lang = lang or "en" + local desc = metadata.desc + local t = {} + _.changeLang(lang) + for i, v in ipairs (desc.paragraphs) do + table.insert(t, "

" .. htmlEscape(_(v)) .. "

") + end + table.insert(t, "") + return table.concat(t, "\n") +end - -- update translations - for __, lang in ipairs(getLocales()) do - _.changeLang(lang) - local translation = _(str) - if source ~= translation then - local metadata_dir = "metadata/" .. lang - metadata_file = metadata_dir .. "/" .. file - os.execute('mkdir -p ' .. metadata_dir) - if isFile(metadata_file) then - count.updated = count.updated + 1 - else - count.new = count.new + 1 - end - writeFile(translation, metadata_file) - else - count.not_translated = count.not_translated + 1 +local function tag(element, lang, str, pad) + local offset = "" + local pad = pad or 0 + if pad >= 1 then + for i = 1, pad do + offset = offset .. " " end end - print(string.format("%s: %d new | %d updated | %d not translated", - file, count.new, count.updated, count.not_translated)) + if lang == "en" then + return string.format("%s<%s>%s", + offset, element, str, element) + else + return string.format('%s<%s xml:lang="%s">%s', + offset, element, lang, str, element) + end end + +local function genAppstream() + local metadata_file = "platform/common/koreader.metainfo.xml" + print("Building appstream metadata, this might take a while...") + local t = {} + local desc = metadata.desc + table.insert(t, '') + table.insert(t, '') + table.insert(t, '') + table.insert(t, metadata.component) + local orig, translated + _.changeLang("en") + orig = metadata.summary + for __, lang in ipairs(locales) do + _.changeLang(lang) + translated = _(metadata.summary) + if orig ~= translated or lang == "en" then + table.insert(t, tag("summary", lang, htmlEscape(translated), 2)) + end + end + table.insert(t, ' ') + for i, v in ipairs (desc.paragraphs) do + _.changeLang("en") + orig = v + for __, lang in ipairs(locales) do + _.changeLang(lang) + translated = _(v) + if orig ~= translated or lang == "en" then + table.insert(t, tag("p", lang, htmlEscape(translated), 4)) + end + end + end + table.insert(t, '
    ') + for i, v in ipairs(desc.highlights) do + _.changeLang("en") + orig = v + for __, lang in ipairs(locales) do + _.changeLang(lang) + translated = _(v) + if orig ~= translated or lang == "en" then + table.insert(t, tag("li", lang, htmlEscape(translated), 6)) + end + end + end + table.insert(t, '
') + table.insert(t, '
') + table.insert(t, ' ') + for i, v in ipairs(metadata.screenshots) do + if v.default then + table.insert(t, ' ') + else + table.insert(t, ' ') + end + table.insert(t, tag("image", "en", v.image, 6)) + if v.caption then + _.changeLang(en) + orig = v.caption + for __, lang in ipairs(locales) do + _.changeLang(lang) + translated = _(v.caption) + if orig ~= translated or lang == "en" then + table.insert(t, tag("caption", lang, htmlEscape(translated), 6)) + end + end + end + table.insert(t, ' ') + end + table.insert(t, ' ') + + table.insert(t, ' ') + for i, v in ipairs(metadata.keywords) do + _.changeLang(en) + orig = v + for __, lang in ipairs(locales) do + _.changeLang(lang) + translated = _(v) + if orig ~= translated or lang == "en" then + table.insert(t, tag("keyword", lang, htmlEscape(translated), 4)) + end + end + end + table.insert(t, ' ') + table.insert(t, [[ + + ]]) + for i, v in ipairs(metadata.notes) do + _.changeLang(en) + orig = v + for __, lang in ipairs(locales) do + _.changeLang(lang) + translated = _(v) + if orig ~= translated or lang == "en" then + table.insert(t, tag("p", lang, htmlEscape(translated), 8)) + end + end + end + table.insert(t, [[ + https://github.com/koreader/koreader/releases/tag/%%VERSION%% + + ]]) + table.insert(t, '
') + writeFile(table.concat(t, "\n"), metadata_file) +end + + +local function genFastlane() + print("Building fastlane metadata") + + + local short, full = "short_description.txt", "full_description.txt" + local short_orig = metadata.summary + local full_orig = htmlDescription() + local short_translated, full_translated + + for __, lang in ipairs(locales) do + _.changeLang(lang) + if lang == "en" then + metadata_dir = "metadata/en-US/" + metadata_file = metadata_dir .. short + writeFile(short_orig, metadata_file) + metadata_file = metadata_dir .. full + writeFile(full_orig, metadata_file) + else + metadata_dir = "metadata/" .. lang .. "/" + short_translated = _(metadata.summary) + full_translated = htmlDescription(lang) + if short_orig ~= short_translated or full_orig ~= full_translated then + os.execute('mkdir -p ' .. metadata_dir) + end + if short_orig ~= short_translated then + metadata_file = metadata_dir .. short + writeFile(short_translated, metadata_file) + end + if full_orig ~= full_translated then + metadata_file = metadata_dir .. full + writeFile(full_translated, metadata_file) + end + end + end +end + +genAppstream() +genFastlane() +print("All done! Updated files:") +print(table.concat(updated_files, "\n"))