mirror of
https://github.com/LibreTranslate/LibreTranslate.git
synced 2024-11-21 07:30:58 +00:00
Add pre-commit to automatically run formatting when committing
This commit is contained in:
parent
7d07967574
commit
25168ba6e1
14 changed files with 74 additions and 34 deletions
28
.pre-commit-config.yaml
Normal file
28
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# See https://pre-commit.com for more information
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.4.0
|
||||||
|
hooks:
|
||||||
|
- id: check-added-large-files
|
||||||
|
name: " 🐘 Check for added large files"
|
||||||
|
- id: check-toml
|
||||||
|
name: " ✔️ Check TOML"
|
||||||
|
- id: check-yaml
|
||||||
|
name: " ✔️ Check YAML"
|
||||||
|
args:
|
||||||
|
- --unsafe
|
||||||
|
- id: check-json
|
||||||
|
name: " ✔️ Check JSON"
|
||||||
|
- id: trailing-whitespace
|
||||||
|
name: " ✂️ Trim trailing whitespaces"
|
||||||
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
|
rev: v0.0.277
|
||||||
|
hooks:
|
||||||
|
- id: ruff
|
||||||
|
name: " ⚡️ Formatting code with Ruff"
|
||||||
|
args:
|
||||||
|
- --fix
|
||||||
|
|
||||||
|
ci:
|
||||||
|
autofix_commit_msg: 🎨 [pre-commit] Auto format
|
||||||
|
autoupdate_commit_msg: ⬆ [pre-commit] pre-commit auto update
|
|
@ -33,6 +33,8 @@ git clone https://github.com/LibreTranslate/LibreTranslate.git
|
||||||
cd LibreTranslate
|
cd LibreTranslate
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Hatch will automatically install the required dependencies in a virtual environment, and enable [`pre-commit`](https://pre-commit.com/), which will run before each commit to run formatting.
|
||||||
|
|
||||||
Run in development:
|
Run in development:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -72,6 +74,12 @@ You can also run the tests on multiple python versions:
|
||||||
hatch run all:test
|
hatch run all:test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can clean the virtual environment with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hatch env prune
|
||||||
|
```
|
||||||
|
|
||||||
## Run with Docker
|
## Run with Docker
|
||||||
|
|
||||||
Linux/macOS: `./run.sh [args]`
|
Linux/macOS: `./run.sh [args]`
|
||||||
|
@ -125,4 +133,4 @@ This occurs when your operating system depends on and manages Python for core fu
|
||||||
This prevents pip packages from being installed system-wide. This way, there are no risks of pip packages conflicting between multiple projects or the operating system.
|
This prevents pip packages from being installed system-wide. This way, there are no risks of pip packages conflicting between multiple projects or the operating system.
|
||||||
|
|
||||||
References:
|
References:
|
||||||
* [Python venv documentation](https://docs.python.org/library/venv.html)
|
* [Python venv documentation](https://docs.python.org/library/venv.html)
|
||||||
|
|
4
k8s.yaml
4
k8s.yaml
|
@ -1,4 +1,4 @@
|
||||||
# kubernetes deployment template
|
# kubernetes deployment template
|
||||||
# prepare a namespace on your cluster first like libretranslate-prod
|
# prepare a namespace on your cluster first like libretranslate-prod
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
|
@ -41,7 +41,7 @@ spec:
|
||||||
valueFrom:
|
valueFrom:
|
||||||
configMapKeyRef:
|
configMapKeyRef:
|
||||||
name: libretranslate-config
|
name: libretranslate-config
|
||||||
key: ltapikey
|
key: ltapikey
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|
|
@ -170,7 +170,7 @@ _default_options_objects = [
|
||||||
'name': 'UPDATE_MODELS',
|
'name': 'UPDATE_MODELS',
|
||||||
'default_value': False,
|
'default_value': False,
|
||||||
'value_type': 'bool'
|
'value_type': 'bool'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'METRICS',
|
'name': 'METRICS',
|
||||||
'default_value': False,
|
'default_value': False,
|
||||||
|
|
|
@ -44,7 +44,7 @@ def get_alternate_locale_links():
|
||||||
tmpl = os.environ.get("LT_LOCALE_LINK_TEMPLATE")
|
tmpl = os.environ.get("LT_LOCALE_LINK_TEMPLATE")
|
||||||
if tmpl is None:
|
if tmpl is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
locales = get_available_locale_codes()
|
locales = get_available_locale_codes()
|
||||||
result = []
|
result = []
|
||||||
for l in locales:
|
for l in locales:
|
||||||
|
|
|
@ -8,6 +8,6 @@ class Limiter:
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def init_app(self, app):
|
def init_app(self, app):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -18,7 +18,7 @@ def setup(args):
|
||||||
|
|
||||||
if args.api_keys and args.require_api_key_secret:
|
if args.api_keys and args.require_api_key_secret:
|
||||||
scheduler.add_job(func=rotate_secrets, trigger="interval", minutes=30)
|
scheduler.add_job(func=rotate_secrets, trigger="interval", minutes=30)
|
||||||
|
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
|
|
||||||
# Shut down the scheduler when exiting the app
|
# Shut down the scheduler when exiting the app
|
||||||
|
|
|
@ -12,7 +12,7 @@ def rotate_secrets():
|
||||||
secret_1 = s.get_str("secret_1")
|
secret_1 = s.get_str("secret_1")
|
||||||
s.set_str("secret_0", secret_1)
|
s.set_str("secret_0", secret_1)
|
||||||
s.set_str("secret_1", generate_secret())
|
s.set_str("secret_1", generate_secret())
|
||||||
|
|
||||||
|
|
||||||
def secret_match(secret):
|
def secret_match(secret):
|
||||||
s = get_storage()
|
s = get_storage()
|
||||||
|
|
|
@ -31,22 +31,22 @@ class Storage:
|
||||||
raise Exception("not implemented")
|
raise Exception("not implemented")
|
||||||
def dec_hash_int(self, ns, key):
|
def dec_hash_int(self, ns, key):
|
||||||
raise Exception("not implemented")
|
raise Exception("not implemented")
|
||||||
|
|
||||||
def get_hash_keys(self, ns):
|
def get_hash_keys(self, ns):
|
||||||
raise Exception("not implemented")
|
raise Exception("not implemented")
|
||||||
def del_hash(self, ns, key):
|
def del_hash(self, ns, key):
|
||||||
raise Exception("not implemented")
|
raise Exception("not implemented")
|
||||||
|
|
||||||
class MemoryStorage(Storage):
|
class MemoryStorage(Storage):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.store = {}
|
self.store = {}
|
||||||
|
|
||||||
def exists(self, key):
|
def exists(self, key):
|
||||||
return key in self.store
|
return key in self.store
|
||||||
|
|
||||||
def set_bool(self, key, value):
|
def set_bool(self, key, value):
|
||||||
self.store[key] = bool(value)
|
self.store[key] = bool(value)
|
||||||
|
|
||||||
def get_bool(self, key):
|
def get_bool(self, key):
|
||||||
return bool(self.store[key])
|
return bool(self.store[key])
|
||||||
|
|
||||||
|
@ -55,10 +55,10 @@ class MemoryStorage(Storage):
|
||||||
|
|
||||||
def get_int(self, key):
|
def get_int(self, key):
|
||||||
return int(self.store.get(key, 0))
|
return int(self.store.get(key, 0))
|
||||||
|
|
||||||
def set_str(self, key, value):
|
def set_str(self, key, value):
|
||||||
self.store[key] = value
|
self.store[key] = value
|
||||||
|
|
||||||
def get_str(self, key):
|
def get_str(self, key):
|
||||||
return str(self.store.get(key, ""))
|
return str(self.store.get(key, ""))
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class MemoryStorage(Storage):
|
||||||
def inc_hash_int(self, ns, key):
|
def inc_hash_int(self, ns, key):
|
||||||
if ns not in self.store:
|
if ns not in self.store:
|
||||||
self.store[ns] = {}
|
self.store[ns] = {}
|
||||||
|
|
||||||
if key not in self.store[ns]:
|
if key not in self.store[ns]:
|
||||||
self.store[ns][key] = 0
|
self.store[ns][key] = 0
|
||||||
else:
|
else:
|
||||||
|
@ -83,7 +83,7 @@ class MemoryStorage(Storage):
|
||||||
def dec_hash_int(self, ns, key):
|
def dec_hash_int(self, ns, key):
|
||||||
if ns not in self.store:
|
if ns not in self.store:
|
||||||
self.store[ns] = {}
|
self.store[ns] = {}
|
||||||
|
|
||||||
if key not in self.store[ns]:
|
if key not in self.store[ns]:
|
||||||
self.store[ns][key] = 0
|
self.store[ns][key] = 0
|
||||||
else:
|
else:
|
||||||
|
@ -103,13 +103,13 @@ class RedisStorage(Storage):
|
||||||
def __init__(self, redis_uri):
|
def __init__(self, redis_uri):
|
||||||
self.conn = redis.from_url(redis_uri)
|
self.conn = redis.from_url(redis_uri)
|
||||||
self.conn.ping()
|
self.conn.ping()
|
||||||
|
|
||||||
def exists(self, key):
|
def exists(self, key):
|
||||||
return bool(self.conn.exists(key))
|
return bool(self.conn.exists(key))
|
||||||
|
|
||||||
def set_bool(self, key, value):
|
def set_bool(self, key, value):
|
||||||
self.conn.set(key, "1" if value else "0")
|
self.conn.set(key, "1" if value else "0")
|
||||||
|
|
||||||
def get_bool(self, key):
|
def get_bool(self, key):
|
||||||
return bool(self.conn.get(key))
|
return bool(self.conn.get(key))
|
||||||
|
|
||||||
|
@ -122,24 +122,24 @@ class RedisStorage(Storage):
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def set_str(self, key, value):
|
def set_str(self, key, value):
|
||||||
self.conn.set(key, value)
|
self.conn.set(key, value)
|
||||||
|
|
||||||
def get_str(self, key):
|
def get_str(self, key):
|
||||||
v = self.conn.get(key)
|
v = self.conn.get(key)
|
||||||
if v is None:
|
if v is None:
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
return v.decode('utf-8')
|
return v.decode('utf-8')
|
||||||
|
|
||||||
def get_hash_int(self, ns, key):
|
def get_hash_int(self, ns, key):
|
||||||
v = self.conn.hget(ns, key)
|
v = self.conn.hget(ns, key)
|
||||||
if v is None:
|
if v is None:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return int(v)
|
return int(v)
|
||||||
|
|
||||||
def set_hash_int(self, ns, key, value):
|
def set_hash_int(self, ns, key, value):
|
||||||
self.conn.hset(ns, key, value)
|
self.conn.hset(ns, key, value)
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ ltmanage = "libretranslate.manage:manage"
|
||||||
test = [
|
test = [
|
||||||
"pytest >=7.2.0",
|
"pytest >=7.2.0",
|
||||||
"pytest-cov",
|
"pytest-cov",
|
||||||
"ruff ==0.0.277",
|
"pre-commit >=3.0.0",
|
||||||
"types-requests",
|
"types-requests",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -83,13 +83,16 @@ History = "https://github.com/LibreTranslate/LibreTranslate/releases"
|
||||||
features = [
|
features = [
|
||||||
"test",
|
"test",
|
||||||
]
|
]
|
||||||
|
post-install-commands = [
|
||||||
|
"pre-commit install",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
[tool.hatch.envs.default.scripts]
|
[tool.hatch.envs.default.scripts]
|
||||||
dev = "python main.py {args}"
|
dev = "python main.py {args}"
|
||||||
locales = "python scripts/compile_locales.py"
|
locales = "python scripts/compile_locales.py"
|
||||||
fmt = [
|
fmt = [
|
||||||
"ruff libretranslate scripts --fix",
|
"pre-commit run --all --all-files",
|
||||||
]
|
]
|
||||||
test = [
|
test = [
|
||||||
"fmt",
|
"fmt",
|
||||||
|
|
|
@ -36,7 +36,7 @@ def on_starting(server):
|
||||||
sys.argv.append(kwargs[k])
|
sys.argv.append(kwargs[k])
|
||||||
|
|
||||||
args = get_args()
|
args = get_args()
|
||||||
|
|
||||||
from libretranslate import flood, scheduler, secret, storage
|
from libretranslate import flood, scheduler, secret, storage
|
||||||
storage.setup(args.shared_storage)
|
storage.setup(args.shared_storage)
|
||||||
scheduler.setup(args)
|
scheduler.setup(args)
|
||||||
|
|
|
@ -25,19 +25,19 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
con = sqlite3.connect(args.db, check_same_thread=False)
|
con = sqlite3.connect(args.db, check_same_thread=False)
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
|
|
||||||
with open(output_file, 'w', encoding="utf-8") as f:
|
with open(output_file, 'w', encoding="utf-8") as f:
|
||||||
for row in cur.execute('SELECT q, s, source, target FROM suggestions WHERE source != "auto" ORDER BY source'):
|
for row in cur.execute('SELECT q, s, source, target FROM suggestions WHERE source != "auto" ORDER BY source'):
|
||||||
q, s, source, target = row
|
q, s, source, target = row
|
||||||
obj = {
|
obj = {
|
||||||
'q': q,
|
'q': q,
|
||||||
's': s,
|
's': s,
|
||||||
'source': source,
|
'source': source,
|
||||||
'target': target
|
'target': target
|
||||||
}
|
}
|
||||||
json.dump(obj, f, ensure_ascii=False)
|
json.dump(obj, f, ensure_ascii=False)
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
|
||||||
print("Wrote %s" % output_file)
|
print("Wrote %s" % output_file)
|
||||||
|
|
||||||
if args.clear:
|
if args.clear:
|
||||||
|
|
|
@ -54,7 +54,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
messagespot = os.path.join(locales_dir, "messages.pot")
|
messagespot = os.path.join(locales_dir, "messages.pot")
|
||||||
print("Updating %s" % messagespot)
|
print("Updating %s" % messagespot)
|
||||||
sys.argv = ["", "extract", "-F", "babel.cfg", "-k", "_e _h",
|
sys.argv = ["", "extract", "-F", "babel.cfg", "-k", "_e _h",
|
||||||
"--copyright-holder", "LibreTranslate Authors",
|
"--copyright-holder", "LibreTranslate Authors",
|
||||||
"--project", "LibreTranslate",
|
"--project", "LibreTranslate",
|
||||||
"--version", get_version(),
|
"--version", get_version(),
|
||||||
|
@ -80,7 +80,7 @@ if __name__ == "__main__":
|
||||||
'reviewed': False
|
'reviewed': False
|
||||||
}, indent=4))
|
}, indent=4))
|
||||||
print("Wrote %s" % meta_file)
|
print("Wrote %s" % meta_file)
|
||||||
|
|
||||||
# Automatically translate strings with libretranslate
|
# Automatically translate strings with libretranslate
|
||||||
# when a language model is available and a string is empty
|
# when a language model is available and a string is empty
|
||||||
|
|
||||||
|
@ -103,10 +103,10 @@ if __name__ == "__main__":
|
||||||
print("Translating '%s'" % locale)
|
print("Translating '%s'" % locale)
|
||||||
pofile = polib.pofile(messages_file)
|
pofile = polib.pofile(messages_file)
|
||||||
c = 0
|
c = 0
|
||||||
|
|
||||||
for entry in pofile.untranslated_entries():
|
for entry in pofile.untranslated_entries():
|
||||||
text = entry.msgid
|
text = entry.msgid
|
||||||
|
|
||||||
# Extract placeholders
|
# Extract placeholders
|
||||||
placeholders = re.findall(r'%\(?[^\)]*\)?s', text)
|
placeholders = re.findall(r'%\(?[^\)]*\)?s', text)
|
||||||
|
|
||||||
|
@ -126,11 +126,11 @@ if __name__ == "__main__":
|
||||||
else:
|
else:
|
||||||
# Meh, append
|
# Meh, append
|
||||||
translated += " " + placeholders[p]
|
translated += " " + placeholders[p]
|
||||||
|
|
||||||
print(entry.msgid, " --> ", translated)
|
print(entry.msgid, " --> ", translated)
|
||||||
entry.msgstr = translated
|
entry.msgstr = translated
|
||||||
c += 1
|
c += 1
|
||||||
|
|
||||||
if c > 0:
|
if c > 0:
|
||||||
pofile.save(messages_file)
|
pofile.save(messages_file)
|
||||||
print("Saved %s" % messages_file)
|
print("Saved %s" % messages_file)
|
||||||
|
|
1
wsgi.py
1
wsgi.py
|
@ -1,5 +1,6 @@
|
||||||
from libretranslate import main
|
from libretranslate import main
|
||||||
|
|
||||||
|
|
||||||
def app(*args, **kwargs):
|
def app(*args, **kwargs):
|
||||||
import sys
|
import sys
|
||||||
sys.argv = ['--wsgi']
|
sys.argv = ['--wsgi']
|
||||||
|
|
Loading…
Reference in a new issue