-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding translation/translate submodule,
Updating submodules. TranslationLoader to check if extracted translator's JS code needs to be updated and updates it. bundle_translation.py zips translator's JS code and puts it into project's assets folder. Updating android.yml to support bundling of translation during CI build. Upping versionCode to 59
- Loading branch information
1 parent
9219fdc
commit 44382a5
Showing
22 changed files
with
1,447 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
[submodule "translators"] | ||
path = translators | ||
url = https://github.com/zotero/translators.git | ||
[submodule "translation/translate"] | ||
path = translation/translate | ||
url = https://github.com/zotero/translate.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1713182643 | ||
1714480514 |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
171 changes: 171 additions & 0 deletions
171
app/src/main/java/org/zotero/android/translator/loader/TranslationLoader.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
package org.zotero.android.translator.loader | ||
|
||
import android.content.Context | ||
import org.apache.commons.io.IOUtils | ||
import org.zotero.android.architecture.Defaults | ||
import org.zotero.android.files.FileStore | ||
import org.zotero.android.helpers.Unzipper | ||
import timber.log.Timber | ||
import javax.inject.Inject | ||
import javax.inject.Singleton | ||
|
||
@Singleton | ||
class TranslationLoader @Inject constructor( | ||
private val context: Context, | ||
private val defaults: Defaults, | ||
private val unzipper: Unzipper, | ||
private val fileStore: FileStore, | ||
) { | ||
enum class UpdateType(val i: Int) { | ||
manual(1), | ||
initial(2), | ||
startup(3), | ||
notification(4), | ||
shareExtension(5); | ||
} | ||
|
||
sealed class Error : Exception() { | ||
data class bundleLoading(val exception: Exception) : Error() | ||
object bundleMissing : Error() | ||
|
||
val isBundleLoadingError: Boolean | ||
get() { | ||
return when (this) { | ||
is bundleLoading -> { | ||
true | ||
} | ||
|
||
else -> { | ||
false | ||
} | ||
} | ||
} | ||
} | ||
|
||
fun updateTranslationIfNeeded() { | ||
_update() | ||
} | ||
|
||
private fun _update() { | ||
val type: UpdateType = | ||
if (defaults.getLastTimestamp() == 0L) { | ||
UpdateType.initial | ||
} else { | ||
UpdateType.startup | ||
} | ||
|
||
Timber.i("TranslationLoader: update translation JS") | ||
try { | ||
checkFolderIntegrity(type = type) | ||
updateFromBundle() | ||
defaults.setLastTimestamp(System.currentTimeMillis() / 1000) | ||
} catch (error: Exception) { | ||
process(error = error, updateType = type) | ||
} | ||
} | ||
|
||
private fun _updateTranslationFromBundle(forceUpdate: Boolean) { | ||
val hash = loadLastTranslationCommitHash() | ||
Timber.i("TranslationLoader: should update translation from bundle, forceUpdate=$forceUpdate; oldHash=${defaults.getLastTranslationCommitHash()}; newHash=$hash") | ||
if (!forceUpdate && defaults.getLastTranslationCommitHash() == hash) { | ||
return | ||
} | ||
Timber.i("TranslationLoader: update translation from bundle") | ||
updateTranslation() | ||
|
||
defaults.setLastTranslationCommitHash(hash) | ||
} | ||
|
||
private fun updateTranslation() { | ||
unzipper.unzipStream( | ||
zipInputStream = context.assets.open("translator.zip"), | ||
location = fileStore.translatorDirectory().absolutePath | ||
) | ||
} | ||
|
||
private fun loadLastTranslationCommitHash(): String { | ||
return loadFromBundle(resource = "translation_commit_hash.txt", map = { it }) | ||
} | ||
|
||
|
||
private inline fun <reified Result> loadFromBundle( | ||
resource: String, | ||
map: (String) -> Result | ||
): Result { | ||
try { | ||
val inputStream = context.assets.open(resource) | ||
val rawValue = IOUtils.toString(inputStream) | ||
return map(rawValue.trim().trim { it == '\n' }) | ||
} catch (e: Exception) { | ||
Timber.e(e) | ||
throw Error.bundleMissing | ||
} | ||
} | ||
|
||
private fun updateFromBundle() { | ||
try { | ||
_updateTranslationFromBundle(forceUpdate = false) | ||
val timestamp = loadLastTimestamp() | ||
if (timestamp > defaults.getLastTimestamp()) { | ||
defaults.setLastTimestamp(timestamp) | ||
return | ||
} else { | ||
return | ||
} | ||
|
||
} catch (error: Exception) { | ||
Timber.e(error, "TranslatorsLoader: can't update from bundle") | ||
throw Error.bundleLoading(error) | ||
} | ||
} | ||
|
||
private fun loadLastTimestamp(): Long { | ||
return loadFromBundle(resource = "timestamp.txt", map = { | ||
try { | ||
return it.toLong() | ||
} catch (e: Exception) { | ||
Timber.e(e) | ||
throw Error.bundleMissing | ||
} | ||
}) | ||
} | ||
|
||
private fun checkFolderIntegrity(type: UpdateType) { | ||
try { | ||
if (!fileStore.translatorDirectory().exists()) { | ||
if (type != UpdateType.initial) { | ||
Timber.e("TranslationLoader: translation directory was missing!") | ||
} | ||
fileStore.translatorDirectory().mkdirs() | ||
} | ||
|
||
if (type == UpdateType.initial) { | ||
return | ||
} | ||
|
||
val fileCount = fileStore.translatorDirectory().listFiles()?.size ?: 0 | ||
|
||
if (fileCount != 0) { | ||
return | ||
} | ||
|
||
defaults.setLastTimestamp(0L) | ||
defaults.setLastTranslationCommitHash("") | ||
} catch (error: Exception) { | ||
Timber.e(error, "TranslationLoader: unable to restore folder integrity") | ||
throw error | ||
} | ||
|
||
} | ||
|
||
private fun process(error: Exception, updateType: UpdateType) { | ||
Timber.e(error, "TranslatorsLoader: error") | ||
|
||
val isBundleLoadingError = (error as? Error)?.isBundleLoadingError == true | ||
if (!isBundleLoadingError) { | ||
return | ||
} | ||
//TODO show bundle load error dialog | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import json | ||
import os | ||
import re | ||
import shutil | ||
import subprocess | ||
import time | ||
|
||
def commit_hash_from_submodules(array): | ||
for line in array: | ||
if line.startswith("translation/translate"): | ||
return line.split()[1] | ||
|
||
# Get bundle directory | ||
bundle_dir = os.path.join(os.path.abspath("."), "app" + os.sep + "src" + os.sep + "main" + os.sep + "assets") | ||
|
||
if not os.path.isdir(bundle_dir): | ||
os.mkdir(bundle_dir) | ||
|
||
# Get translation directory | ||
translators_dir = os.path.join(os.path.abspath("."), "translation") | ||
|
||
if not os.path.isdir(translators_dir): | ||
raise Exception(translators_dir + " is not a directory. Call update_bundled_data.py first.") | ||
|
||
# Store last commit hash from translation submodule | ||
submodules = subprocess.check_output(["git", "submodule", "foreach", "--recursive", "echo $path `git rev-parse HEAD`"]).decode("utf-8").splitlines() | ||
commit_hash = commit_hash_from_submodules(submodules) | ||
|
||
with open(os.path.join(bundle_dir, "translation_commit_hash.txt"), "w") as f: | ||
f.write(str(commit_hash)) | ||
|
||
# Zip translator | ||
os.chdir(translators_dir) | ||
subprocess.check_call(['zip', '-r', os.path.join(bundle_dir, "translator.zip"), "."]) |
Oops, something went wrong.