Commit 7b97d4cc authored by Julien Lepiller's avatar Julien Lepiller

Initial commit

parents
.guix-profile*
__pycache__
dist
*.egg-info
_build
build
This diff is collapsed.
Transmon
========
Transmon (Translation Monitor) is a translation monitor. It uses a manifest
that lists projects you are interested in. It will get the latest release or
development version (e.g. latest git commit) and try to find localisation
information in the project.
The result of the tool is a json representation of the localisation state of the
different projects. The output is a list of projects. Each project has attributes
"name", "home-page" and "state". The state attribute contains an object whose
attributes are the name of languages (en, fr, de, …) and values are a couple
composed of the number of translated strings in that language and the number of
available strings in the project.
Example
-------
projects.manifest:
```json
[
{"name": "dns66",
"fetcher": "git",
"analyzer": "android",
"uri": "https://github.com/julian-klode/dns66",
"home-page": "https://github.com/julian-klode/dns66"}
]
```
Then, run:
```bash
$ transmon projects.manifest
```
Finally, you will get the result on the standard output:
```json
[{"name": "dns66",
"state": {"fr": [93, 102], "ru": [92, 102], "zh": [92, 102], "nl": [94, 102],
"es": [94, 102], "et": [94, 102], "pl": [93, 102], "tr": [93, 102],
"de": [102, 102], "it": [94, 102], "ja": [93, 102], "nb": [94, 102]},
"home-page": "https://github.com/julian-klode/dns66"}]
```
from setuptools import setup, find_packages
setup (
name="transmon",
version="0.1",
packages=find_packages(exclude=['.guix-profile*']),
python_requires = '>=3',
install_requires=['android-stringslib', 'polib', 'pygit2'],
entry_points={
'console_scripts': [
'transmon=transmon:main',
],
},
author="Julien Lepiller",
author_email="julien@lepiller.eu",
description="Translation monitor",
long_description="Transmon is a translation monitor. It uses a manifest \
that lists projects you are interested in. It will get the latest release or \
development version (e.g. latest git commit) and try to find localisation \
information in the project.",
license="AGPLv3+",
keywords="translation monitor",
url="https://framagit.org/tyreunom/transmon",
classifiers=[
# How mature is this project? Common values are
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',
# Indicate who your project is intended for
'Intended Audience :: Developers',
'Topic :: Software Development :: Localization',
# Pick your license as you wish (should match "license" above)
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python :: 3',
],
)
# Copyright (c) 2018 Julien Lepiller <julien@lepiller.eu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
####
import sys
import json
from .project import Project
from .fetcher import GitFetcher
from .analyzer import AndroidAnalyzer
def main():
if(len(sys.argv) < 2):
print('Usage: ' + sys.argv[0] + ' projects-file')
sys.exit(1)
with open(sys.argv[1]) as f:
conf = json.load(f)
res = []
for proj in conf:
if proj['fetcher'] == 'git':
f = GitFetcher()
else:
raise Exception('No such fetcher: ' + proj['fetcher'])
if proj['analyzer'] == 'android':
a = AndroidAnalyzer()
else:
raise Exception('No such analyzer: ' + proj['analyzer'])
p = Project(proj['name'], f, proj['uri'], a, proj['home-page'])
p.fetch()
res.append({"name": proj['name'], 'home-page': proj['home-page'],
'state': p.analyze()})
p.cleanup()
print(json.dumps(res))
# Copyright (c) 2018 Julien Lepiller <julien@lepiller.eu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
####
import os
import polib
from androidstringslib import android
class Analyzer(object):
def __init__(self):
return
def analyze(self, path):
raise Exception('Not implemented')
class AndroidAnalyzer(Analyzer):
def __init__(self):
Analyzer.__init__(self)
def analyze(self, path):
respath = path + '/app/src/main/res'
dirs = os.listdir(respath)
dirs = [(respath + "/" + x) for x in dirs if 'strings.xml' in os.listdir(respath + "/" + x)]
res = {}
for p in dirs:
if p.endswith('values'):
continue
an = android(respath + '/values/strings.xml', p + '/strings.xml')
translated = 0
number = len(an)
for entry in an:
if entry.dst != '':
translated = translated + 1
res[p[-2:]] = (translated, number)
return res
# Copyright (c) 2018 Julien Lepiller <julien@lepiller.eu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
####
import tempfile
import pygit2
class Fetcher(object):
def __init__(self):
self.path = None
return
def fetch(self, project):
raise Exception('Not implemented')
def getDirectory(self):
if self.path == None:
return None
return self.path.name
class GitFetcher(Fetcher):
def __init__(self):
Fetcher.__init__(self)
def fetch(self, uri):
path = tempfile.TemporaryDirectory()
self.path = path
pygit2.clone_repository(uri, path.name)
return path.name
def cleanup(self):
self.path.cleanup()
self.path = None
# Copyright (c) 2018 Julien Lepiller <julien@lepiller.eu>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
####
class Project(object):
def __init__(self, name, fetcher, uri, analyzer, homepage):
self.name = name
self.fetcher = fetcher
self.uri = uri
self.analyzer = analyzer
self.homepage = homepage
self.dir = None
def fetch(self):
self.fetcher.fetch(self.uri)
def analyze(self):
return self.analyzer.analyze(self.fetcher.getDirectory())
def cleanup(self):
self.fetcher.cleanup()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment