From 12b907aee8474b5d8297982d9182ce6021620172 Mon Sep 17 00:00:00 2001 From: Chopper <156493704+choppeh@users.noreply.github.com> Date: Fri, 19 Sep 2025 03:55:05 -0300 Subject: [PATCH] Manhuarm: Fix dialog box empty and add translation support (#10625) Fix dialog box empty and add translation support --- .../assets/fonts/LICENSE_ANIMEACE.txt | 25 ++ .../assets/fonts/LICENSE_COMIC_NEUE.txt | 93 +++++ .../assets/fonts/LICENSE_COMING_SOON.txt | 202 ++++++++++ .../assets/fonts/animeace2_regular.ttf | Bin 0 -> 32756 bytes .../manhuarm/assets/fonts/comic_neue_bold.ttf | Bin 0 -> 53384 bytes .../assets/fonts/comic_neue_regular.ttf | Bin 0 -> 54848 bytes .../assets/fonts/coming_soon_regular.ttf | Bin 0 -> 47128 bytes .../i18n/messages_manhuarm_en.properties | 19 + .../i18n/messages_manhuarm_es.properties | 1 + .../i18n/messages_manhuarm_fr.properties | 1 + .../i18n/messages_manhuarm_id.properties | 1 + .../i18n/messages_manhuarm_it.properties | 1 + .../i18n/messages_manhuarm_pt_br.properties | 19 + src/{en => all}/manhuarm/build.gradle | 4 +- .../manhuarm/res/mipmap-hdpi/ic_launcher.png | Bin .../manhuarm/res/mipmap-mdpi/ic_launcher.png | Bin .../manhuarm/res/mipmap-xhdpi/ic_launcher.png | Bin .../res/mipmap-xxhdpi/ic_launcher.png | Bin .../res/mipmap-xxxhdpi/ic_launcher.png | Bin .../extension/all/manhuarm/Manhuarm.kt | 353 ++++++++++++++++++ .../extension/all/manhuarm/ManhuarmDto.kt | 95 +++++ .../extension/all/manhuarm/ManhuarmFactory.kt | 20 + .../extension/all/manhuarm/ManhuarmUtils.kt | 15 + .../interceptors/ComposedImageInterceptor.kt | 221 +++++++++++ .../interceptors/TranslationInterceptor.kt | 61 +++ .../manhuarm/translator/TranslatorEngine.kt | 6 + .../translator/bing/BingTranslator.kt | 115 ++++++ .../translator/bing/BingTranslatorDto.kt | 28 ++ .../translator/google/GoogleTranslator.kt | 84 +++++ .../translator/google/GoogleTranslatorDto.kt | 15 + .../extension/en/manhuarm/Manhuarm.kt | 11 - 31 files changed, 1377 insertions(+), 13 deletions(-) create mode 100644 src/all/manhuarm/assets/fonts/LICENSE_ANIMEACE.txt create mode 100644 src/all/manhuarm/assets/fonts/LICENSE_COMIC_NEUE.txt create mode 100644 src/all/manhuarm/assets/fonts/LICENSE_COMING_SOON.txt create mode 100644 src/all/manhuarm/assets/fonts/animeace2_regular.ttf create mode 100644 src/all/manhuarm/assets/fonts/comic_neue_bold.ttf create mode 100644 src/all/manhuarm/assets/fonts/comic_neue_regular.ttf create mode 100644 src/all/manhuarm/assets/fonts/coming_soon_regular.ttf create mode 100644 src/all/manhuarm/assets/i18n/messages_manhuarm_en.properties create mode 100644 src/all/manhuarm/assets/i18n/messages_manhuarm_es.properties create mode 100644 src/all/manhuarm/assets/i18n/messages_manhuarm_fr.properties create mode 100644 src/all/manhuarm/assets/i18n/messages_manhuarm_id.properties create mode 100644 src/all/manhuarm/assets/i18n/messages_manhuarm_it.properties create mode 100644 src/all/manhuarm/assets/i18n/messages_manhuarm_pt_br.properties rename src/{en => all}/manhuarm/build.gradle (70%) rename src/{en => all}/manhuarm/res/mipmap-hdpi/ic_launcher.png (100%) rename src/{en => all}/manhuarm/res/mipmap-mdpi/ic_launcher.png (100%) rename src/{en => all}/manhuarm/res/mipmap-xhdpi/ic_launcher.png (100%) rename src/{en => all}/manhuarm/res/mipmap-xxhdpi/ic_launcher.png (100%) rename src/{en => all}/manhuarm/res/mipmap-xxxhdpi/ic_launcher.png (100%) create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/Manhuarm.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmDto.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmFactory.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmUtils.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/ComposedImageInterceptor.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/TranslationInterceptor.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/TranslatorEngine.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslator.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslatorDto.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslator.kt create mode 100644 src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslatorDto.kt delete mode 100644 src/en/manhuarm/src/eu/kanade/tachiyomi/extension/en/manhuarm/Manhuarm.kt diff --git a/src/all/manhuarm/assets/fonts/LICENSE_ANIMEACE.txt b/src/all/manhuarm/assets/fonts/LICENSE_ANIMEACE.txt new file mode 100644 index 000000000..5ba98714a --- /dev/null +++ b/src/all/manhuarm/assets/fonts/LICENSE_ANIMEACE.txt @@ -0,0 +1,25 @@ +This font is © 2006 Nate Piekos. All Rights Reserved. +Created for Blambot Fonts + +This font is freeware for independent comic book creation and +non-profit use ONLY. ( This excludes use by "mainstream" publishers, +(Marvel, DC, Dark Horse, Oni, Image, SLG, Top Cow, Crossgen and their +subsidiaries) without a license fee. Use by a "mainstream" publisher +(or it's employee), and use for commercial non-comic book production +(eg. magazine ads, merchandise lables etc.) incurs a license fee +be paid to the designer, Nate Piekos. +This font may not be redistributed without the author's permission and +never with this text file missing from the .zip, .sit or .hqx. + +Blambot/Nate Piekos makes no guarantees about these font files, + the completeness of character sets, or safety of these files on your +computer. By installing these fonts on your system, you prove that +you have read and understand the above. + +If you have any questions, visit http://www.blambot.com/license.shtml + +For more free and original fonts visit Blambot. +www.blambot.com + +Nate Piekos +studio@blambot.com diff --git a/src/all/manhuarm/assets/fonts/LICENSE_COMIC_NEUE.txt b/src/all/manhuarm/assets/fonts/LICENSE_COMIC_NEUE.txt new file mode 100644 index 000000000..80062cfab --- /dev/null +++ b/src/all/manhuarm/assets/fonts/LICENSE_COMIC_NEUE.txt @@ -0,0 +1,93 @@ +Copyright 2014 The Comic Neue Project Authors (https://github.com/crozynski/comicneue) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/all/manhuarm/assets/fonts/LICENSE_COMING_SOON.txt b/src/all/manhuarm/assets/fonts/LICENSE_COMING_SOON.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/src/all/manhuarm/assets/fonts/LICENSE_COMING_SOON.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/all/manhuarm/assets/fonts/animeace2_regular.ttf b/src/all/manhuarm/assets/fonts/animeace2_regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6521ab5b551926497b1fdc74ed5bba613adf1ad9 GIT binary patch literal 32756 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 adWOCo*$A!DCTfzI&>vKLEQDQq<^KVen%i{% literal 0 HcmV?d00001 diff --git a/src/all/manhuarm/assets/fonts/comic_neue_bold.ttf b/src/all/manhuarm/assets/fonts/comic_neue_bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..dc9a6d5522364181c258abf8b2b074185012d396 GIT binary patch literal 53384 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 literal 0 HcmV?d00001 diff --git a/src/all/manhuarm/assets/fonts/comic_neue_regular.ttf b/src/all/manhuarm/assets/fonts/comic_neue_regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d454f4693a74261051bbfae316e65128034684b5 GIT binary patch literal 54848 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

Y3+Zu@>oR_c!jV<>@rmdf)>CIO#K^m^EXK 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 d&7VINs{9D0 Data and storage > Clear chapter cache". Font changes will not affect downloaded chapters +font_name_message=Font name changed to %s +font_name_device_title=Device +font_size_title=Font size +font_size_summary=Font changes will not be applied to downloaded or cached chapters. The font size will be adjusted according to the size of the dialog box. +font_size_message=Font size changed to %s +default_font_size=Default +default_font_name=Default +disable_word_break_title=Disable word break +disable_word_break_summary=This feature prevents words from being automatically broken in the middle of a line. +disable_translator_title=Disable translator +disable_translator_summary=Disable auto translation and enable source translation. This does not mean that a translation is available. Make sure a translation is available before enabling this option. +translate_dialog_box_title=Translator +translate_dialog_box_summary=Engine used to translate dialog boxes +translate_dialog_box_toast=The translator has been changed to +enable_manga_details_translation_title=Enable translation of manga details +enable_manga_details_translation_summary=This option will slow down the loading of manga details +chapter_unavailable_message=Chapter cannot be translated diff --git a/src/all/manhuarm/assets/i18n/messages_manhuarm_es.properties b/src/all/manhuarm/assets/i18n/messages_manhuarm_es.properties new file mode 100644 index 000000000..48bc523f9 --- /dev/null +++ b/src/all/manhuarm/assets/i18n/messages_manhuarm_es.properties @@ -0,0 +1 @@ +font_size_title=Tamaño de letra diff --git a/src/all/manhuarm/assets/i18n/messages_manhuarm_fr.properties b/src/all/manhuarm/assets/i18n/messages_manhuarm_fr.properties new file mode 100644 index 000000000..1beb3574f --- /dev/null +++ b/src/all/manhuarm/assets/i18n/messages_manhuarm_fr.properties @@ -0,0 +1 @@ +font_size_title=Taille de la police diff --git a/src/all/manhuarm/assets/i18n/messages_manhuarm_id.properties b/src/all/manhuarm/assets/i18n/messages_manhuarm_id.properties new file mode 100644 index 000000000..b129b31a4 --- /dev/null +++ b/src/all/manhuarm/assets/i18n/messages_manhuarm_id.properties @@ -0,0 +1 @@ +font_size_title=Ukuran font diff --git a/src/all/manhuarm/assets/i18n/messages_manhuarm_it.properties b/src/all/manhuarm/assets/i18n/messages_manhuarm_it.properties new file mode 100644 index 000000000..917acd0f9 --- /dev/null +++ b/src/all/manhuarm/assets/i18n/messages_manhuarm_it.properties @@ -0,0 +1 @@ +font_size_title=Dimensione del carattere diff --git a/src/all/manhuarm/assets/i18n/messages_manhuarm_pt_br.properties b/src/all/manhuarm/assets/i18n/messages_manhuarm_pt_br.properties new file mode 100644 index 000000000..b58cd28c0 --- /dev/null +++ b/src/all/manhuarm/assets/i18n/messages_manhuarm_pt_br.properties @@ -0,0 +1,19 @@ +font_name_title=Fonte +font_name_summary=Personalize os diálogos escolhendo a fonte de sua preferência. Para aplicar a alteração em capitulos lidos será necessário limpar o cache de capitulos em "Mais > Dados e armazenamento > Limpar cache de capítulos". As alterações de fonte não serão aplicadas aos capítulos baixados. +font_name_message=Fonte alterada para %s +font_name_device_title=Dispositivo +font_size_title=Tamanho da fonte +font_size_summary=As alterações de fonte não serão aplicadas aos capítulos baixados ou armazenados em cache. O tamanho da fonte será ajustado de acordo com o tamanho da caixa de diálogo. +font_size_message=Tamanho da fonte foi alterada para %s +default_font_size=Padrão +default_font_name=Padrão +disable_word_break_title=Desativar quebra de palavras +disable_word_break_summary=Esse recurso impede que palavras sejam quebradas automaticamente no meio da linha. +disable_translator_title=Desativar tradutor +disable_translator_summary=Desativar tradução automática e ativar tradução da fonte. Isso não significa que há uma tradução disponivel. Certifique-se de que exista uma tradução antes de ativar esta opção no site. +translate_dialog_box_title=Tradutor +translate_dialog_box_summary=Motor utilizado para traduzir caixas de diálogo +translate_dialog_box_toast=O tradutor foi alterado para +enable_manga_details_translation_title=Habilitar tradução dos detalhes do manga +enable_manga_details_translation_summary=Esta opção tornará o carregamento dos detalhes do mangá mais lento +chapter_unavailable_message=O capítulo não pode ser traduzido diff --git a/src/en/manhuarm/build.gradle b/src/all/manhuarm/build.gradle similarity index 70% rename from src/en/manhuarm/build.gradle rename to src/all/manhuarm/build.gradle index 7775dad94..2a7aee99d 100644 --- a/src/en/manhuarm/build.gradle +++ b/src/all/manhuarm/build.gradle @@ -1,9 +1,9 @@ ext { extName = 'Manhuarm' - extClass = '.Manhuarm' + extClass = '.ManhuarmFactory' themePkg = 'madara' baseUrl = 'https://manhuarm.com' - overrideVersionCode = 0 + overrideVersionCode = 1 isNsfw = true } diff --git a/src/en/manhuarm/res/mipmap-hdpi/ic_launcher.png b/src/all/manhuarm/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from src/en/manhuarm/res/mipmap-hdpi/ic_launcher.png rename to src/all/manhuarm/res/mipmap-hdpi/ic_launcher.png diff --git a/src/en/manhuarm/res/mipmap-mdpi/ic_launcher.png b/src/all/manhuarm/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from src/en/manhuarm/res/mipmap-mdpi/ic_launcher.png rename to src/all/manhuarm/res/mipmap-mdpi/ic_launcher.png diff --git a/src/en/manhuarm/res/mipmap-xhdpi/ic_launcher.png b/src/all/manhuarm/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from src/en/manhuarm/res/mipmap-xhdpi/ic_launcher.png rename to src/all/manhuarm/res/mipmap-xhdpi/ic_launcher.png diff --git a/src/en/manhuarm/res/mipmap-xxhdpi/ic_launcher.png b/src/all/manhuarm/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from src/en/manhuarm/res/mipmap-xxhdpi/ic_launcher.png rename to src/all/manhuarm/res/mipmap-xxhdpi/ic_launcher.png diff --git a/src/en/manhuarm/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/manhuarm/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from src/en/manhuarm/res/mipmap-xxxhdpi/ic_launcher.png rename to src/all/manhuarm/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/Manhuarm.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/Manhuarm.kt new file mode 100644 index 000000000..4db837e76 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/Manhuarm.kt @@ -0,0 +1,353 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm + +import android.content.SharedPreferences +import android.os.Build +import android.widget.Toast +import androidx.annotation.RequiresApi +import androidx.preference.ListPreference +import androidx.preference.Preference +import androidx.preference.PreferenceScreen +import androidx.preference.SwitchPreferenceCompat +import eu.kanade.tachiyomi.extension.all.manhuarm.interceptors.ComposedImageInterceptor +import eu.kanade.tachiyomi.extension.all.manhuarm.interceptors.TranslationInterceptor +import eu.kanade.tachiyomi.extension.all.manhuarm.translator.bing.BingTranslator +import eu.kanade.tachiyomi.extension.all.manhuarm.translator.google.GoogleTranslator +import eu.kanade.tachiyomi.lib.i18n.Intl +import eu.kanade.tachiyomi.lib.i18n.Intl.Companion.createDefaultMessageFileName +import eu.kanade.tachiyomi.multisrc.machinetranslations.translator.TranslatorEngine +import eu.kanade.tachiyomi.multisrc.madara.Madara +import eu.kanade.tachiyomi.network.interceptor.rateLimit +import eu.kanade.tachiyomi.source.ConfigurableSource +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import keiyoushi.utils.getPreferencesLazy +import keiyoushi.utils.parseAs +import kotlinx.serialization.encodeToString +import okhttp3.Interceptor +import okhttp3.OkHttpClient +import okhttp3.Response +import org.jsoup.nodes.Document +import java.util.Calendar +import java.util.Date +import java.util.concurrent.TimeUnit + +@RequiresApi(Build.VERSION_CODES.O) +class Manhuarm( + private val language: Language, +) : Madara( + "Manhuarm", + "https://manhuarm.com", + language.lang, +), + ConfigurableSource { + + override val useNewChapterEndpoint: Boolean = true + + private val preferences: SharedPreferences by getPreferencesLazy() + + /** + * A flag that tracks whether the settings have been changed. It is used to indicate if + * any configuration change has occurred. Once the value is accessed, it resets to `false`. + * This is useful for tracking whether a preference has been modified, and ensures that + * the change status is cleared after it has been accessed, to prevent multiple triggers. + */ + private var isSettingsChanged: Boolean = false + get() { + val current = field + field = false + return current + } + + private var fontSize: Int + get() = preferences.getString(FONT_SIZE_PREF, DEFAULT_FONT_SIZE)!!.toInt() + set(value) = preferences.edit().putString(FONT_SIZE_PREF, value.toString()).apply() + + private var fontName: String + get() = preferences.getString(FONT_NAME_PREF, language.fontName)!! + set(value) = preferences.edit().putString(FONT_NAME_PREF, value).apply() + + private var disableWordBreak: Boolean + get() = preferences.getBoolean(DISABLE_WORD_BREAK_PREF, language.disableWordBreak) + set(value) = preferences.edit().putBoolean(DISABLE_WORD_BREAK_PREF, value).apply() + + private var disableTranslator: Boolean + get() = preferences.getBoolean(DISABLE_TRANSLATOR_PREF, language.disableTranslator) + set(value) = preferences.edit().putBoolean(DISABLE_TRANSLATOR_PREF, value).apply() + + private val i18n = Intl( + language = language.lang, + baseLanguage = "en", + availableLanguages = setOf("en", "es", "fr", "id", "it", "pt-BR"), + classLoader = this::class.java.classLoader!!, + createMessageFileName = { createDefaultMessageFileName("${name.lowercase()}_${language.lang}") }, + ) + + private val settings get() = language.copy( + fontSize = this@Manhuarm.fontSize, + fontName = this@Manhuarm.fontName, + disableWordBreak = this@Manhuarm.disableWordBreak, + disableTranslator = this@Manhuarm.disableTranslator, + disableFontSettings = this@Manhuarm.fontName == DEVICE_FONT, + ) + + override val client: OkHttpClient get() = clientInstance!! + + private val translators = arrayOf( + "Bing", + "Google", + ) + + private val provider: String get() = + preferences.getString(TRANSLATOR_PROVIDER_PREF, translators.first())!! + + /** + * This ensures that the `OkHttpClient` instance is only created when required, and it is rebuilt + * when there are configuration changes to ensure that the client uses the most up-to-date settings. + */ + private var clientInstance: OkHttpClient? = null + get() { + if (field == null || isSettingsChanged) { + field = clientBuilder().build() + } + return field + } + private val clientUtils = network.cloudflareClient.newBuilder() + .rateLimit(3, 2, TimeUnit.SECONDS) + .build() + + private lateinit var translator: TranslatorEngine + + private fun clientBuilder(): OkHttpClient.Builder { + translator = when (provider) { + "Google" -> GoogleTranslator(clientUtils, headers) + else -> BingTranslator(clientUtils, headers) + } + + return network.cloudflareClient.newBuilder() + .connectTimeout(1, TimeUnit.MINUTES) + .readTimeout(2, TimeUnit.MINUTES) + .rateLimit(3) + .addInterceptorIf( + !disableTranslator && language.lang != language.origin, + TranslationInterceptor(settings, translator), + ) + .addInterceptor(ComposedImageInterceptor(settings)) + } + + private fun OkHttpClient.Builder.addInterceptorIf(condition: Boolean, interceptor: Interceptor): OkHttpClient.Builder { + return this.takeIf { condition.not() } ?: this.addInterceptor(interceptor) + } + + private val translationAvailability = Calendar.getInstance().apply { + set(2025, Calendar.SEPTEMBER, 9, 0, 0, 0) + set(Calendar.MILLISECOND, 0) + } + + override fun chapterListParse(response: Response): List { + return super.chapterListParse(response).filter { + language.target == language.origin || Date(it.date_upload).after(translationAvailability.time) + } + } + + override fun pageListParse(document: Document): List { + val pages = super.pageListParse(document) + val content = document.selectFirst("meta[name=description]") + ?.attr("content") + ?.fixJsonFormat() + ?: return pages.takeIf { language.target == language.origin } ?: throw Exception(i18n["chapter_unavailable_message"]) + + val dialog = content.parseAs>() + + return dialog.mapIndexed { index, dto -> + val page = pages.first { it.imageUrl?.contains(dto.imageUrl, true)!! } + val fragment = json.encodeToString>( + dto.dialogues.filter { it.getTextBy(language).isNotBlank() }, + ) + if (dto.dialogues.isEmpty()) { + return@mapIndexed page + } + + Page(index, imageUrl = "${page.imageUrl}${fragment.toFragment()}") + } + } + + private fun String.fixJsonFormat(): String { + return JSON_FORMAT_REGEX.replace(this) { matchResult -> + val content = matchResult.groupValues.last() + val modifiedContent = content.replace("\"", "'") + """"text": "${modifiedContent.trimIndent()}", "box"""" + } + } + + // Prevent bad fragments + fun String.toFragment(): String = "#${this.replace("#", "*")}" + + override fun setupPreferenceScreen(screen: PreferenceScreen) { + // Some libreoffice font sizes + val sizes = arrayOf( + "12", "13", "14", + "15", "16", "18", + "20", "21", "22", + "24", "26", "28", + "32", "36", "40", + "42", "44", "48", + "54", "60", "72", + "80", "88", "96", + ) + + val fonts = arrayOf( + i18n["font_name_device_title"] to DEVICE_FONT, + "Anime Ace" to "animeace2_regular", + "Comic Neue" to "comic_neue_bold", + "Coming Soon" to "coming_soon_regular", + ) + + ListPreference(screen.context).apply { + key = FONT_SIZE_PREF + title = i18n["font_size_title"] + entries = sizes.map { + "${it}pt" + if (it == DEFAULT_FONT_SIZE) " - ${i18n["default_font_size"]}" else "" + }.toTypedArray() + entryValues = sizes + + summary = buildString { + appendLine(i18n["font_size_summary"]) + append("\t* %s") + } + + setDefaultValue(fontSize.toString()) + + setOnPreferenceChange { _, newValue -> + val selected = newValue as String + val index = this.findIndexOfValue(selected) + val entry = entries[index] as String + + fontSize = selected.toInt() + + Toast.makeText( + screen.context, + i18n["font_size_message"].format(entry), + Toast.LENGTH_LONG, + ).show() + + true // It's necessary to update the user interface + } + }.also(screen::addPreference) + + if (!language.disableFontSettings) { + ListPreference(screen.context).apply { + key = FONT_NAME_PREF + title = i18n["font_name_title"] + entries = fonts.map { + it.first + if (it.second.isBlank()) " - ${i18n["default_font_name"]}" else "" + }.toTypedArray() + entryValues = fonts.map { it.second }.toTypedArray() + summary = buildString { + appendLine(i18n["font_name_summary"]) + append("\t* %s") + } + + setDefaultValue(fontName) + + setOnPreferenceChange { _, newValue -> + val selected = newValue as String + val index = this.findIndexOfValue(selected) + val entry = entries[index] as String + + fontName = selected + + Toast.makeText( + screen.context, + i18n["font_name_message"].format(entry), + Toast.LENGTH_LONG, + ).show() + + true // It's necessary to update the user interface + } + }.also(screen::addPreference) + } + + SwitchPreferenceCompat(screen.context).apply { + key = DISABLE_WORD_BREAK_PREF + title = "⚠ ${i18n["disable_word_break_title"]}" + summary = i18n["disable_word_break_summary"] + setDefaultValue(language.disableWordBreak) + setOnPreferenceChange { _, newValue -> + disableWordBreak = newValue as Boolean + true + } + }.also(screen::addPreference) + + if (language.target == language.origin) { + return + } + + if (language.supportNativeTranslation) { + SwitchPreferenceCompat(screen.context).apply { + key = DISABLE_TRANSLATOR_PREF + title = "⚠ ${i18n["disable_translator_title"]}" + summary = i18n["disable_translator_summary"] + setDefaultValue(language.disableTranslator) + setOnPreferenceChange { _, newValue -> + disableTranslator = newValue as Boolean + true + } + }.also(screen::addPreference) + } + + if (!disableTranslator) { + ListPreference(screen.context).apply { + key = TRANSLATOR_PROVIDER_PREF + title = i18n["translate_dialog_box_title"] + entries = translators + entryValues = translators + summary = buildString { + appendLine(i18n["translate_dialog_box_summary"]) + append("\t* %s") + } + + setDefaultValue(translators.first()) + + setOnPreferenceChange { _, newValue -> + val selected = newValue as String + val index = this.findIndexOfValue(selected) + val entry = entries[index] as String + + Toast.makeText( + screen.context, + "${i18n["translate_dialog_box_toast"]} '$entry'", + Toast.LENGTH_LONG, + ).show() + + true + } + }.also(screen::addPreference) + } + } + + /** + * Sets an `OnPreferenceChangeListener` for the preference, and before triggering the original listener, + * marks that the configuration has changed by setting `isSettingsChanged` to `true`. + * This behavior is useful for applying runtime configurations in the HTTP client, + * ensuring that the preference change is registered before invoking the original listener. + */ + private fun Preference.setOnPreferenceChange(onPreferenceChangeListener: Preference.OnPreferenceChangeListener) { + setOnPreferenceChangeListener { preference, newValue -> + isSettingsChanged = true + onPreferenceChangeListener.onPreferenceChange(preference, newValue) + } + } + + companion object { + val PAGE_REGEX = Regex(".*?\\.(webp|png|jpg|jpeg)#\\[.*?]", RegexOption.IGNORE_CASE) + val JSON_FORMAT_REGEX = """(?:"text":\s+?".*?)([\s\S]*?)(?:",\s+?"box")""".toRegex() + + const val DEVICE_FONT = "device:" + private const val FONT_SIZE_PREF = "fontSizePref" + private const val FONT_NAME_PREF = "fontNamePref" + private const val DISABLE_WORD_BREAK_PREF = "disableWordBreakPref" + private const val DISABLE_TRANSLATOR_PREF = "disableTranslatorPref" + private const val TRANSLATOR_PROVIDER_PREF = "translatorProviderPref" + private const val DEFAULT_FONT_SIZE = "28" + } +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmDto.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmDto.kt new file mode 100644 index 000000000..9ba189472 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmDto.kt @@ -0,0 +1,95 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm + +import android.os.Build +import androidx.annotation.RequiresApi +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonTransformingSerializer +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import kotlinx.serialization.json.put +import java.io.IOException + +@Serializable +class PageDto( + @SerialName("image") + val imageUrl: String, + + @SerialName("texts") + @Serializable(with = DialogListSerializer::class) + val dialogues: List

= emptyList(), +) + +@Serializable +@RequiresApi(Build.VERSION_CODES.O) +data class Dialog( + val x: Float, + val y: Float, + val width: Float, + val height: Float, + val angle: Float = 0f, + val isBold: Boolean = false, + val isNewApi: Boolean = false, + val textByLanguage: Map = emptyMap(), + val type: String = "normal", + private val fbColor: List = emptyList(), + private val bgColor: List = emptyList(), +) { + val text: String get() = textByLanguage["text"] ?: throw Exception("Dialog not found") + fun getTextBy(language: Language) = when { + !language.disableTranslator -> textByLanguage[language.origin] + else -> textByLanguage[language.target] + } ?: text + val centerY get() = height / 2 + y + val centerX get() = width / 2 + x +} + +private object DialogListSerializer : + JsonTransformingSerializer>(ListSerializer(Dialog.serializer())) { + override fun transformDeserialize(element: JsonElement): JsonElement { + return JsonArray( + element.jsonArray.map { jsonElement -> + val coordinates = getCoordinates(jsonElement) + val textByLanguage = getDialogs(jsonElement) + + buildJsonObject { + put("x", coordinates[0]) + put("y", coordinates[1]) + put("width", coordinates[2]) + put("height", coordinates[3]) + put("textByLanguage", textByLanguage) + } + }, + ) + } + + private fun getCoordinates(element: JsonElement): JsonArray { + return when (element) { + is JsonArray -> element.jsonArray[0].jsonArray + else -> element.jsonObject["box"]?.jsonArray + ?: throw IOException("Dialog box position not found") + } + } + private fun getDialogs(element: JsonElement): JsonObject { + return buildJsonObject { + when (element) { + is JsonArray -> put("text", element.jsonArray[1]) + else -> { + element.jsonObject.entries + .filter { it.value.isString } + .forEach { put(it.key, it.value) } + } + } + } + } + + private val JsonElement.isArray get() = this is JsonArray + private val JsonElement.isObject get() = this is JsonObject + private val JsonElement.isString get() = this.isObject.not() && this.isArray.not() && this.jsonPrimitive.isString +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmFactory.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmFactory.kt new file mode 100644 index 000000000..35f3b88fd --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmFactory.kt @@ -0,0 +1,20 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm + +import android.os.Build +import androidx.annotation.RequiresApi +import eu.kanade.tachiyomi.source.SourceFactory + +@RequiresApi(Build.VERSION_CODES.O) +class ManhuarmFactory : SourceFactory { + override fun createSources() = languageList.map(::Manhuarm) +} + +private val languageList = listOf( + Language("ar", disableFontSettings = true), + Language("en"), + Language("es"), + Language("fr", supportNativeTranslation = true), + Language("id", supportNativeTranslation = true), + Language("it"), + Language("pt-BR", "pt", supportNativeTranslation = true), +) diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmUtils.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmUtils.kt new file mode 100644 index 000000000..aea5af653 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/ManhuarmUtils.kt @@ -0,0 +1,15 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm + +class MachineTranslationsFactoryUtils + +data class Language( + val lang: String, + val target: String = lang, + val origin: String = "en", + val fontSize: Int = 28, + val disableFontSettings: Boolean = false, + val disableWordBreak: Boolean = false, + val disableTranslator: Boolean = false, + val supportNativeTranslation: Boolean = false, + val fontName: String = "comic_neue_bold", +) diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/ComposedImageInterceptor.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/ComposedImageInterceptor.kt new file mode 100644 index 000000000..d12b55c37 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/ComposedImageInterceptor.kt @@ -0,0 +1,221 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm.interceptors + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Typeface +import android.graphics.text.LineBreaker +import android.os.Build +import android.text.Layout +import android.text.StaticLayout +import android.text.TextPaint +import androidx.annotation.RequiresApi +import eu.kanade.tachiyomi.extension.all.manhuarm.Dialog +import eu.kanade.tachiyomi.extension.all.manhuarm.Language +import eu.kanade.tachiyomi.extension.all.manhuarm.Manhuarm.Companion.PAGE_REGEX +import keiyoushi.utils.parseAs +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.Response +import okhttp3.ResponseBody.Companion.toResponseBody +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.FileOutputStream +import java.io.InputStream + +// The Interceptor joins the dialogues and pages of the manga. +@RequiresApi(Build.VERSION_CODES.O) +class ComposedImageInterceptor( + val language: Language, +) : Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + val url = request.url.toString() + + if (PAGE_REGEX.containsMatchIn(url).not()) { + return chain.proceed(request) + } + + val dialogues = request.url.fragment?.parseAs>() + ?: emptyList() + + val imageRequest = request.newBuilder() + .url(url) + .build() + + val response = chain.proceed(imageRequest) + + if (response.isSuccessful.not()) { + return response + } + + val bitmap = BitmapFactory.decodeStream(response.body.byteStream())!! + .copy(Bitmap.Config.ARGB_8888, true) + + val canvas = Canvas(bitmap) + + dialogues.forEach { dialog -> + val textPaint = createTextPaint(selectFontFamily()) + val dialogBox = createDialogBox(dialog, textPaint) + val y = getYAxis(textPaint, dialog, dialogBox) + canvas.draw(textPaint, dialogBox, dialog, dialog.x, y) + } + + val output = ByteArrayOutputStream() + + val ext = url.substringBefore("#") + .substringAfterLast(".") + .lowercase() + val format = when (ext) { + "png" -> Bitmap.CompressFormat.PNG + "jpeg", "jpg" -> Bitmap.CompressFormat.JPEG + else -> Bitmap.CompressFormat.WEBP + } + + bitmap.compress(format, 100, output) + + val responseBody = output.toByteArray().toResponseBody(mediaType) + + return response.newBuilder() + .body(responseBody) + .build() + } + + private fun createTextPaint(font: Typeface?): TextPaint { + val defaultTextSize = language.fontSize.pt + return TextPaint().apply { + color = Color.BLACK + textSize = defaultTextSize + font?.let { + typeface = it + } + isAntiAlias = true + } + } + + private fun selectFontFamily(): Typeface? { + if (language.disableFontSettings) { + return null + } + return loadFont("${language.fontName}.ttf") + } + + /** + * Loads font from the `assets/fonts` directory within the APK + * + * @param fontName The name of the font to load. + * @return A `Typeface` instance of the loaded font or `null` if an error occurs. + * + * Example usage: + *
{@code
+     *   val typeface: TypeFace? = loadFont("filename.ttf")
+     * }
+ */ + private fun loadFont(fontName: String): Typeface? { + return try { + this::class.java.classLoader!! + .getResourceAsStream("assets/fonts/$fontName") + .toTypeface(fontName) + } catch (e: Exception) { + null + } + } + + private fun InputStream.toTypeface(fontName: String): Typeface? { + val fontFile = File.createTempFile(fontName, fontName.substringAfter(".")) + this.copyTo(FileOutputStream(fontFile)) + return Typeface.createFromFile(fontFile) + } + + /** + * Adjust the text to the center of the dialog box when feasible. + */ + private fun getYAxis(textPaint: TextPaint, dialog: Dialog, dialogBox: StaticLayout): Float { + val fontHeight = textPaint.fontMetrics.let { it.bottom - it.top } + + val dialogBoxLineCount = dialog.height / fontHeight + + /** + * Centers text in y for dialogues smaller than the dialog box + */ + return when { + dialogBox.lineCount < dialogBoxLineCount -> dialog.centerY - dialogBox.lineCount / 2f * fontHeight + else -> dialog.y + } + } + + private fun createDialogBox(dialog: Dialog, textPaint: TextPaint): StaticLayout { + var dialogBox = createBoxLayout(dialog, textPaint) + + /** + * The best way I've found to adjust the text in the dialog box (Especially in long dialogues) + */ + while (dialogBox.height > dialog.height) { + textPaint.textSize -= 0.5f + dialogBox = createBoxLayout(dialog, textPaint) + } + + textPaint.color = Color.BLACK + textPaint.bgColor = Color.WHITE + + return dialogBox + } + + private fun createBoxLayout(dialog: Dialog, textPaint: TextPaint): StaticLayout { + val text = dialog.getTextBy(language) + + return StaticLayout.Builder.obtain(text, 0, text.length, textPaint, dialog.width.toInt()).apply { + setAlignment(Layout.Alignment.ALIGN_CENTER) + setIncludePad(language.disableFontSettings) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + if (language.disableWordBreak) { + setBreakStrategy(LineBreaker.BREAK_STRATEGY_SIMPLE) + setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE) + return@apply + } + setBreakStrategy(LineBreaker.BREAK_STRATEGY_BALANCED) + setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL) + } + }.build() + } + + private fun Canvas.draw(textPaint: TextPaint, layout: StaticLayout, dialog: Dialog, x: Float, y: Float) { + save() + translate(x, y) + rotate(dialog.angle) + drawTextOutline(textPaint, layout) + drawText(textPaint, layout) + restore() + } + + private fun Canvas.drawText(textPaint: TextPaint, layout: StaticLayout) { + textPaint.style = Paint.Style.FILL + layout.draw(this) + } + + private fun Canvas.drawTextOutline(textPaint: TextPaint, layout: StaticLayout) { + val foregroundColor = textPaint.color + val style = textPaint.style + + textPaint.strokeWidth = 5F + textPaint.color = textPaint.bgColor + textPaint.style = Paint.Style.FILL_AND_STROKE + + layout.draw(this) + + textPaint.color = foregroundColor + textPaint.style = style + } + + // https://pixelsconverter.com/pt-to-px + private val Int.pt: Float get() = this / SCALED_DENSITY + + companion object { + // w3: Absolute Lengths [...](https://www.w3.org/TR/css3-values/#absolute-lengths) + const val SCALED_DENSITY = 0.75f // 1px = 0.75pt + val mediaType = "image/png".toMediaType() + } +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/TranslationInterceptor.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/TranslationInterceptor.kt new file mode 100644 index 000000000..2c91f1e25 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/interceptors/TranslationInterceptor.kt @@ -0,0 +1,61 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm.interceptors + +import android.os.Build +import androidx.annotation.RequiresApi +import eu.kanade.tachiyomi.extension.all.manhuarm.Dialog +import eu.kanade.tachiyomi.extension.all.manhuarm.Language +import eu.kanade.tachiyomi.extension.all.manhuarm.Manhuarm.Companion.PAGE_REGEX +import eu.kanade.tachiyomi.multisrc.machinetranslations.translator.TranslatorEngine +import keiyoushi.utils.parseAs +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.runBlocking +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import okhttp3.Interceptor +import okhttp3.Response +import uy.kohesive.injekt.injectLazy + +@RequiresApi(Build.VERSION_CODES.O) +class TranslationInterceptor( + val language: Language, + private val translator: TranslatorEngine, +) : Interceptor { + + private val json: Json by injectLazy() + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + val url = request.url.toString() + + if (PAGE_REGEX.containsMatchIn(url).not() || language.target == language.origin) { + return chain.proceed(request) + } + + val dialogues = request.url.fragment?.parseAs>() + ?: return chain.proceed(request) + + val translated = runBlocking(Dispatchers.IO) { + dialogues.map { dialog -> + async { + dialog.replaceText( + translator.translate(language.origin, language.target, dialog.text), + ) + } + }.awaitAll() + } + + val newRequest = request.newBuilder() + .url("${url.substringBeforeLast("#")}#${json.encodeToString(translated)}") + .build() + + return chain.proceed(newRequest) + } + + private fun Dialog.replaceText(value: String) = this.copy( + textByLanguage = mutableMapOf( + "text" to value, + ), + ) +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/TranslatorEngine.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/TranslatorEngine.kt new file mode 100644 index 000000000..d8a420361 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/TranslatorEngine.kt @@ -0,0 +1,6 @@ +package eu.kanade.tachiyomi.multisrc.machinetranslations.translator + +interface TranslatorEngine { + val capacity: Int + fun translate(from: String, to: String, text: String): String +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslator.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslator.kt new file mode 100644 index 000000000..b5dbdbaee --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslator.kt @@ -0,0 +1,115 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm.translator.bing + +import eu.kanade.tachiyomi.multisrc.machinetranslations.translator.TranslatorEngine +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import okhttp3.FormBody +import okhttp3.Headers +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Element +import uy.kohesive.injekt.injectLazy + +class BingTranslator(private val client: OkHttpClient, private val headers: Headers) : TranslatorEngine { + + private val baseUrl = "https://www.bing.com" + + private val translatorUrl = "$baseUrl/translator" + + private val json: Json by injectLazy() + + private var tokens: TokenGroup = TokenGroup() + + override val capacity: Int = 1000 + + private val attempts = 3 + + override fun translate(from: String, to: String, text: String): String { + if (tokens.isNotValid() && refreshTokens().not()) { + return text + } + val request = translatorRequest(from, to, text) + repeat(attempts) { + try { + return fetchTranslatedText(request) + } catch (e: Exception) { + refreshTokens() + } + } + return text + } + + private fun fetchTranslatedText(request: Request): String { + return client.newCall(request).execute().parseAs>() + .firstOrNull()!!.text + } + + private fun refreshTokens(): Boolean { + tokens = loadTokens() + return tokens.isValid() + } + + private fun translatorRequest(from: String, to: String, text: String): Request { + val url = "$baseUrl/ttranslatev3".toHttpUrl().newBuilder() + .addQueryParameter("isVertical", "1") + .addQueryParameter("", "") // Present in Bing URL + .addQueryParameter("IG", tokens.ig) + .addQueryParameter("IID", tokens.iid) + .build() + + val headersApi = headers.newBuilder() + .set("Accept", "*/*") + .set("Origin", baseUrl) + .set("Referer", translatorUrl) + .set("Alt-Used", baseUrl) + .build() + + val payload = FormBody.Builder() + .add("fromLang", from) + .add("to", to) + .add("text", text) + .add("tryFetchingGenderDebiasedTranslations", "true") + .add("token", tokens.token) + .add("key", tokens.key) + .build() + + return POST(url.toString(), headersApi, payload) + } + + private fun loadTokens(): TokenGroup { + val document = client.newCall(GET(translatorUrl, headers)).execute().asJsoup() + + val scripts = document.select("script") + .map(Element::data) + + val scriptOne: String = scripts.firstOrNull(TOKENS_REGEX::containsMatchIn) + ?: return TokenGroup() + + val scriptTwo: String = scripts.firstOrNull(IG_PARAM_REGEX::containsMatchIn) + ?: return TokenGroup() + + val matchOne = TOKENS_REGEX.find(scriptOne)?.groups + val matchTwo = IG_PARAM_REGEX.find(scriptTwo)?.groups + + return TokenGroup( + token = matchOne?.get(4)?.value ?: "", + key = matchOne?.get(3)?.value ?: "", + ig = matchTwo?.get(1)?.value ?: "", + iid = document.selectFirst("div[data-iid]:not([class])")?.attr("data-iid") ?: "", + ) + } + + private inline fun Response.parseAs(): T { + return json.decodeFromStream(body.byteStream()) + } + + companion object { + val TOKENS_REGEX = """params_AbusePreventionHelper(\s+)?=(\s+)?[^\[]\[(\d+),"([^"]+)""".toRegex() + val IG_PARAM_REGEX = """IG:"([^"]+)""".toRegex() + } +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslatorDto.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslatorDto.kt new file mode 100644 index 000000000..6d204464f --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/bing/BingTranslatorDto.kt @@ -0,0 +1,28 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm.translator.bing + +import kotlinx.serialization.Serializable + +class BingTranslatorDto + +class TokenGroup( + val token: String = "", + val key: String = "", + val iid: String = "", + val ig: String = "", +) { + fun isNotValid() = listOf(token, key, iid, ig).any(String::isBlank) + + fun isValid() = isNotValid().not() +} + +@Serializable +class TranslateDto( + val translations: List, +) { + val text = translations.firstOrNull()?.text ?: "" +} + +@Serializable +class TextTranslated( + val text: String, +) diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslator.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslator.kt new file mode 100644 index 000000000..6056cdb67 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslator.kt @@ -0,0 +1,84 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm.translator.google + +import eu.kanade.tachiyomi.multisrc.machinetranslations.translator.TranslatorEngine +import eu.kanade.tachiyomi.network.GET +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonPrimitive +import okhttp3.Headers +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import uy.kohesive.injekt.injectLazy +import java.io.IOException + +/** + * This client is an adaptation of the following python repository: https://github.com/ssut/py-googletrans. + */ +class GoogleTranslator(private val client: OkHttpClient, private val headers: Headers) : TranslatorEngine { + + private val baseUrl: String = "https://translate.googleapis.com" + + private val webpage: String = "https://translate.google.com" + + private val translatorUrl = "$baseUrl/translate_a/single" + + override val capacity: Int = 5000 + + private val json: Json by injectLazy() + + override fun translate(from: String, to: String, text: String): String { + val request = translateRequest(text, from, to) + return try { fetchTranslatedText(request) } catch (_: Exception) { text } + } + + private fun translateRequest(text: String, from: String, to: String): Request { + return GET(clientUrlBuilder(text, from, to).build(), headersBuilder().build()) + } + + private fun headersBuilder(): Headers.Builder = headers.newBuilder() + .set("Origin", webpage) + .set("Alt-Used", webpage.substringAfterLast("/")) + .set("Referer", "$webpage/") + + private fun clientUrlBuilder(text: String, src: String, dest: String, token: String = "xxxx"): HttpUrl.Builder { + return translatorUrl.toHttpUrl().newBuilder() + .setQueryParameter("client", "gtx") + .setQueryParameter("sl", src) + .setQueryParameter("tl", dest) + .setQueryParameter("hl", dest) + .setQueryParameter("ie", Charsets.UTF_8.toString()) + .setQueryParameter("oe", Charsets.UTF_8.toString()) + .setQueryParameter("otf", "1") + .setQueryParameter("ssel", "0") + .setQueryParameter("tsel", "0") + .setQueryParameter("tk", token) + .setQueryParameter("q", text) + .apply { + arrayOf("at", "bd", "ex", "ld", "md", "qca", "rw", "rm", "ss", "t").forEach { + addQueryParameter("dt", it) + } + } + } + + private fun fetchTranslatedText(request: Request): String { + val response = client.newCall(request).execute() + + if (response.isSuccessful.not()) { + throw IOException("Request failed: ${response.code}") + } + + return response.parseJson().let(::extractTranslatedText) + } + + private fun Response.parseJson(): JsonElement = json.parseToJsonElement(this.body.string()) + + private fun extractTranslatedText(data: JsonElement): String { + return data.jsonArray[0].jsonArray.joinToString("") { + it.jsonArray[0].jsonPrimitive.content + } + } +} diff --git a/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslatorDto.kt b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslatorDto.kt new file mode 100644 index 000000000..d6a4dedb9 --- /dev/null +++ b/src/all/manhuarm/src/eu/kanade/tachiyomi/extension/all/manhuarm/translator/google/GoogleTranslatorDto.kt @@ -0,0 +1,15 @@ +package eu.kanade.tachiyomi.extension.all.manhuarm.translator.google + +import okhttp3.Response + +class GoogleTranslatorDto + +data class Translated( + val from: String, + val to: String, + val origin: String, + val text: String, + val pronunciation: String, + val extraData: Map, + val response: Response, +) diff --git a/src/en/manhuarm/src/eu/kanade/tachiyomi/extension/en/manhuarm/Manhuarm.kt b/src/en/manhuarm/src/eu/kanade/tachiyomi/extension/en/manhuarm/Manhuarm.kt deleted file mode 100644 index 33b801810..000000000 --- a/src/en/manhuarm/src/eu/kanade/tachiyomi/extension/en/manhuarm/Manhuarm.kt +++ /dev/null @@ -1,11 +0,0 @@ -package eu.kanade.tachiyomi.extension.en.manhuarm - -import eu.kanade.tachiyomi.multisrc.madara.Madara - -class Manhuarm : Madara( - "Manhuarm", - "https://manhuarm.com", - "en", -) { - override val useNewChapterEndpoint: Boolean = true -}