Installation and setup

Eints is written in Python 3. Its software uses the GPL V2. For stand-alone use (which is useful for development and testing), no other software is needed.

Internally, it uses:

  • Bottle, a Python framework for writing web applications. - Location: webtranslate/bottle.py - Licensed under MIT License
  • Twitter Boostrap, a CSS, JS and glyphicon framework for web application user interfaces. - Locations: static/css static/img static/js - Code licensed under Apache License v2.0, - Documentation licensed under CC BY 3.0. - Glyphicons Free licensed under CC BY 3.0.
  • WooCons #1, an icon library. - Location: static/img/woocons1 - Licensed under GPL v3

The Eints repository includes files of the above projects for your convenience. They are however not part of Eints.

Setup

After downloading and unpacking, Eints needs to be configured:

If the authentication in the config.xml file is set to development, additional configuration file must be set up:

If the authentication in the config.xml file is set to redmine or ldap, the latter information is retrieved from the Redmine data base or LDAP respectively, as explained in Redmine configuration setup and LDAP configuration setup.

Server configuration

The global configuration settings are in config.xml. It has the following entries:

Note that Eints is not thread-safe, trying to use it with multiple threads will fail to work properly.

Server setup

The following configuration fields exist for the general server set up.

server-mode
Mode of the server, must be either development, production or mod_wsgi. The former two will start a bottle web server. In development mode, errors that happen in the server process are copied into the generated html page. The latter allows deployment via apache’s mod_wsgi. See Server setup with apache’s mod_wsgi for an example configuration with mod_wsgi.
server-host
Name of the host that should provides the Eints service.
server-port
Port number of the host that should provide the Eints service.
authentication

Method of authentication. Currently supported forms are:

  • development which uses local files for everything, or
  • redmine which hooks into the Redmine software for roles and users.
  • ldap which queries an LDAP server for authentication and roles.

Eints uses basic authentication to authenticate users. For this reason, the Eints service should be remotely accessible only through a secure connection.

Server setup with apache’s mod_wsgi

Below is an example apache2 configuration assuming eints to reside in the directory /home/eints/eints:

WSGIPythonPath /home/eints/eints
<VirtualHost *:80>
    ServerAdmin webmaster@localhost

    WSGIDaemonProcess eints user=eints group=eints processes=1 threads=1 home=/home/eints/eints
    WSGIScriptAlias / /home/eints/eints/app.wsgi
    WSGIPassAuthorization On

    DocumentRoot /var/www

    <Directory /var/www/>
        WSGIProcessGroup eints
        WSGIApplicationGroup %{GLOBAL}
        Order allow,deny
        allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Project data setup

The following configuration fields exist to define how project data is treated.

stable-languages
Path to the directory with meta-information of ‘stable’ languages (that is, languages with a sufficient number of translators).
unstable-languages
Path to the directory with meta-information of ‘unstable’ languages (that is, languages generally lacking translators). Optional configuration.
project-root
Root directory of the data files for each project, including the backup files.
project-cache
Eints loads project data files when needed. To reduce memory requirements, this setting controls how many data files it may keep in memory.
project-types
Eints understands three types of projects, openttd, game-script, and newgrf. Each has a different set of known string commands. In this configuration field, you can list the project types that should be allowed (separated by white space).
storage-format

This configuration field controls the storage format used for new translation projects.

The one-file format stores all information about a project in a single file. It is simple to handle, having all information at one place. For bigger projects, the format may become too unwieldy to handle. Internally, the file is completely created before storage, and memory requirements can become huge. The split-languages format aims to solve that. Instead of a file, the project data all goes into a directory. Within the directory, there is a project_data.xml file, and one for each language. Files are only written when modified.

data-format

This configuration field controls whether XML or JSON is used for storage. It only affects new projects. The field contains either xml (for XML data format) or json (for JSON data format).

XML format has more features, but tends to grow fast in memory requirements with bigger projects. JSON is better for big projects (needs less memory), but lacks (at the time of writing this) support for sharing text strings. That doesn’t hurt much if you use split-languages for the storage-format field, as normally, there are not many string shared within a single language.

language-file-size
Eints can download NML <http://dev.openttdcoop.org/projects/nml> language files. This setting control the maximum size in bytes of such files.
num-backup-files
When the data of a project is changed, Eints writes a new copy of the project data to disk. This setting controls how many previous versions are kept.
max-num-changes
Eints enables changing of strings in translations. For reference purposes, a number of previous texts for each string (in each language in each project) are kept. This setting controls how many can exist at most. Keep in mind that the last uploaded string is always kept to allow comparing with the next upload.
min-num-changes
Controls the minimum number of texts to keep for each string. Should be at least 2. (One for the last uploaded text, and one for the newest translation.)
change-stable-age
When a string is being changed, the change is considered ‘unstable’, and will be kept for a while. This setting controls when such a change is sufficiently old to consider it ‘stable’, so it may get deleted if the string count is above min-num-changes.

When uploading language files from NML, Eints uses the available strings to detect whether changes occurred in the file. The min-num-changes and change-stable-age values should be chosen such that previously uploaded information is still available when downloading updates.

Redmine configuration setup

If Eints authentication is using redmine, the redmine part of the configuration should also be filled in.

db-type
Type of data base used by Redmine.
db-schema
Postgress sometimes needs a search path to find its schema.
db-user
Accoutn which gives read access to the Redmine data base.
db-password
Password of the db-user entry to get read access to the Redmine data base.
db-host
Name of the host to contact for accessing the data base.
db-port
Port number of the db-host to contact.

Redmine roles setup

Eints uses a project owner and translator roles to provide access to its web pages. These roles are mapped to Redmine roles, so you can setup access control from the Redmine interface.

owner-role
Name of the Redmine role to denote the user(s) which are considered ‘project owner’ for an Eints project.
translator-role

Name of the Redmine role to denote the user(s) which are considered to be a translator for one language.

A translator role must be defined for each language that is used in Eints. Each Eints role may map to the same Redmine role however.

Note that project owner access implies translator access in Eints. Any page accessible to a translator is also accessible by the owner of the project.

LDAP configuration setup

If Eints authentication is using LDAP, the LDAP part of the configuration should also be filled in.

host
URL to LDAP server, optionally including a port number.
basedn-users
Base DN for users in the LDAP tree. User objects are looked up via ‘cn:Username’ directly subordinate to the base DN.
basedn-groups
Base DN for groups in the LDAP tree. Group objects are looked up via ‘cn:Groupname’ directly subordinate to the base DN:

LDAP roles setup

Eints uses a project owner and translator roles to provide access to its web pages. These roles are mapped to posixGroup memberships in LDAP. Note, that the roles are language specific, but not project specific. All translators have access too all projects in Eints. The ‘OWNER’ role is an administrator role, with access to all projects.

owner-group
CN of the posixGroup to denote the user(s) which are considered ‘project owner’ for all Eints project.
translator-group

CN of the posixGroup to denote the user(s) which are considered to be a translator for one language.

A translator group must be defined for each language that is used in Eints. Each Eints role may map to the same posixGroup however.

The groups are not project specific, a translator always has access to all projects.

Note that project owner access implies translator access in Eints. Any page accessible to a translator is also accessible by the owner of the project.

Page access rights

The rights.dat file defines who can access the data. It inspects paths of web pages being accessed, and checks whether the user performing the operation should be allowed to proceed.

The file is a list of access rules, that associates users and paths with the right to access. The general form of a rule is:

<user> +/- <path>

The +/- at the first access rule that matches with the user and the path decides access. The + means to give access, - means deny access. For readability, the file can also have empty lines, and comment lines (a line starting with # in the first column).

A <user> can be

  • A literal username (not recommended),
  • The * wildcard, matching everybody,
  • SOMEONE, matching unauthenticated users,
  • OWNER, a user denoted as owner of the project that is accessed through the path.
  • TRANSLATOR, a user that is registered as translator for a language in a project, for paths that deal with languages. Obviously being an OWNER implies being an TRANSLATOR for all languages in the project.

A <path> looks a lot like the paths used by Eints for the URI of the web-pages. A path in this file however always has four elements, namely action, project, language, and operation. Each of the elements is a name, the value * (to denote its value is not relevant in matching), or the value - (to denote the value does not exist).

The action is the same as the first component in the URI, except that the root page uses root as action. The following actions exist:

  • root, the root page,
  • projects, the overview page containing all projects,
  • project, the overview page of a single project,
  • language, the overview page of a language in a project,
  • string, the edit page of a single string in a single translation language,
  • upload, the page to upload language files into Eints,
  • download, the download page for getting new language files from Eints, and
  • delete, the page to delete a language.

The project and language elements are the name of the project and name of the language respectively. Usually these are not interesting, access control is handled with OWNER and TRANSLATOR users.

The operation element is either read or add.

For reference purposes, below is an example access rights file:

# Root, project overview, and download pages are readable by all
* + /root/-/-/read

# Unauthenticated users don't get any further
SOMEONE - /*/*/*/*

# First pages of project creation can be used by anyone (these pages have no
# project to authenticate against).
* + /newproject/-/-/read
* + /createproject/-/-/add

# Only the owner can create a project.
OWNER + /makeproject/*/-/add

# Authenticated users (of a project) can see the projects, see each project, download a
# language, and get an overview of a language in a project.
* + /projects/-/-/read
* + /project/*/-/read
* + /download-list/*/*/read
* + /download/*/*/read
* + /language/*/*/read

# Strings editing
OWNER      + /string/*/*/*
TRANSLATOR + /string/*/*/*

# Language file uploading, language deletion and creation
OWNER + /upload/*/-/*
OWNER + /delete/*/*/*
OWNER + /newlanguage/*/-/*
OWNER + /projsettings/*/-/*

Project owners and translators

In the above section, user categories OWNER and TRANSLATOR may be used to define who can access certain pages.

If the authentication entry in config.xml is set to redmine or ldap, the Redmine data base or LDAP are queried for membership of the roles. If the authentication entry is set to development, a local file is used, explained below.

Membership of a user in these categories is decided in the projects.dat file. It is a INI file, where the section name is the name of the project, the keys of a section are the languages, and the values are the names of the users separated by spaces or commas. The special ‘language’ owner is used to denote project ownership. An example:

[eints]
owner = alberth, andythenorth
nl_NL = alberth

Here, the eints project is defined (always lowercase), with two owners, and one translator for the Dutch language. (Note that since an owner also has translator access, the final line is not needed in this example.)

Users

Users send authentication information using standard HTTP basic authentication to the web server. As such, it is highly recommended to use the https protocol for the translator service.

If the authentication entry in config.xml is set to redmine or ldap, the Redmine data base or LDAP are queried for user authentication. If the authentication entry is set to development, a local file is used. In the latter case users and their passwords are stored in plain text in users.dat. Obviously, this is not secure in any way. It should never be used to store important authentication information. The editsilly program can add, update, and remove users from the file, for example

./editsilly admin

would create or change the admin account.