[!!!][TASK] Provision Pootle using Ansible 48/41148/9
authorXavier Perseguers <xavier@typo3.org>
Mon, 13 Jul 2015 19:54:32 +0000 (21:54 +0200)
committerXavier Perseguers <xavier@typo3.org>
Wed, 15 Jul 2015 19:17:18 +0000 (21:17 +0200)
A complete Pootle server may be provisioned using Ansible. This includes
basic scripts to migrate from Pootle v1.9 to v2.5 and new scripts to
synchronize changes in TYPO3 system extensions with Pootle.

The major new feature is the support of removal of outdated labels,
renaming (and move) of localization files within a system extension and,
last but not least, basic support for moving localization file from one
system extension to another one (by copying existing translations to the
new locations when this is detected).

Packaging scripts will be adapted in further patches.

Please refer to README.rst for installation instructions.

Note: The jump into Ansible and the provided setup was inspired by
      https://serversforhackers.com/an-ansible-tutorial

Change-Id: I386e7177c5d72dc5d361d8ab29d2237e95a7be25
Reviewed-on: http://review.typo3.org/41148
Reviewed-by: Xavier Perseguers <xavier@typo3.org>
Tested-by: Xavier Perseguers <xavier@typo3.org>
99 files changed:
.gitignore
LEGACY/bin/build-language-pack [new file with mode: 0755]
LEGACY/bin/pootle-batch-check-project [new file with mode: 0755]
LEGACY/bin/pootle-batch-import-projects [new file with mode: 0755]
LEGACY/bin/pootle-check-project [new file with mode: 0755]
LEGACY/bin/pootle-create-project [new file with mode: 0755]
LEGACY/bin/pootle-notify-hassuggestion [new file with mode: 0755]
LEGACY/bin/pootle-refresh-project [new file with mode: 0755]
LEGACY/bin/pootle-snapshot [new file with mode: 0755]
LEGACY/bin/pootle-upgrade-all-extensions [new file with mode: 0755]
LEGACY/bin/pootle-upgrade-extension [new file with mode: 0755]
LEGACY/bin/pootle-upgrade-extension-git [new file with mode: 0755]
LEGACY/bin/t3xutils.phar [new file with mode: 0755]
LEGACY/etc/typo3-prefix.conf [new file with mode: 0644]
README.rst [new file with mode: 0644]
bin/build-language-pack [deleted file]
bin/pootle-batch-check-project [deleted file]
bin/pootle-batch-import-projects [deleted file]
bin/pootle-check-project [deleted file]
bin/pootle-create-project [deleted file]
bin/pootle-manage [deleted file]
bin/pootle-notify-hassuggestion [deleted file]
bin/pootle-refresh-project [deleted file]
bin/pootle-snapshot [deleted file]
bin/pootle-upgrade-all-extensions [deleted file]
bin/pootle-upgrade-extension [deleted file]
bin/pootle-upgrade-extension-git [deleted file]
bin/t3xutils.phar [deleted file]
bin/update-typo3-core-template [deleted file]
etc/functions [deleted file]
etc/lang-compat.conf [deleted file]
etc/pootle.conf [deleted file]
etc/typo3-prefix.conf [deleted file]
etc/xsl/llxml2template.xsl [deleted file]
etc/xsl/xliff2llxml-source.xsl [deleted file]
etc/xsl/xliff2llxml-target.xsl [deleted file]
geerlingguy.memcached/README.md [new file with mode: 0644]
geerlingguy.memcached/defaults/main.yml [new file with mode: 0644]
geerlingguy.memcached/handlers/main.yml [new file with mode: 0644]
geerlingguy.memcached/meta/main.yml [new file with mode: 0644]
geerlingguy.memcached/tasks/main.yml [new file with mode: 0644]
geerlingguy.memcached/tasks/setup-Debian.yml [new file with mode: 0644]
geerlingguy.memcached/tasks/setup-RedHat.yml [new file with mode: 0644]
geerlingguy.memcached/templates/memcached.conf.j2 [new file with mode: 0644]
geerlingguy.memcached/tests/inventory [new file with mode: 0644]
geerlingguy.memcached/tests/test.yml [new file with mode: 0644]
geerlingguy.mysql/.travis.yml [new file with mode: 0644]
geerlingguy.mysql/README.md [new file with mode: 0644]
geerlingguy.mysql/defaults/main.yml [new file with mode: 0644]
geerlingguy.mysql/handlers/main.yml [new file with mode: 0644]
geerlingguy.mysql/meta/main.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/configure.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/databases.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/main.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/replication.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/secure-installation.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/setup-Debian.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/setup-RedHat.yml [new file with mode: 0644]
geerlingguy.mysql/tasks/users.yml [new file with mode: 0644]
geerlingguy.mysql/templates/my.cnf.j2 [new file with mode: 0644]
geerlingguy.mysql/templates/user-my.cnf.j2 [new file with mode: 0644]
geerlingguy.mysql/tests/inventory [new file with mode: 0644]
geerlingguy.mysql/tests/test.yml [new file with mode: 0644]
geerlingguy.mysql/vars/Debian.yml [new file with mode: 0644]
geerlingguy.mysql/vars/RedHat.yml [new file with mode: 0644]
install.yml [new file with mode: 0644]
nginx/files/h5bp/README.md [new file with mode: 0644]
nginx/files/h5bp/basic.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/cache-file-descriptors.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/cross-domain-insecure.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/extra-security.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/no-transform.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/spdy.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/ssl-stapling.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/ssl.conf [new file with mode: 0644]
nginx/files/h5bp/directive-only/x-ua-compatible.conf [new file with mode: 0644]
nginx/files/h5bp/location/cache-busting.conf [new file with mode: 0644]
nginx/files/h5bp/location/cross-domain-fonts.conf [new file with mode: 0644]
nginx/files/h5bp/location/expires.conf [new file with mode: 0644]
nginx/files/h5bp/location/protect-system-files.conf [new file with mode: 0644]
nginx/handlers/main.yml [new file with mode: 0644]
nginx/tasks/main.yml [new file with mode: 0644]
nginx/templates/virtualhost.conf.j2 [new file with mode: 0644]
pootle/tasks/main.yml [new file with mode: 0644]
pootle/templates/pootle.conf.j2 [new file with mode: 0755]
pootle/templates/pootle.j2 [new file with mode: 0755]
typo3/files/bash_profile.txt [new file with mode: 0644]
typo3/files/scripts/bin/migration/migrate-typo3-xliff [new file with mode: 0755]
typo3/files/scripts/bin/pootle-manage [new file with mode: 0755]
typo3/files/scripts/bin/update-typo3-core-template [new file with mode: 0755]
typo3/files/scripts/etc/functions [new file with mode: 0644]
typo3/files/scripts/etc/lang-compat.conf [new file with mode: 0644]
typo3/files/scripts/etc/xsl/llxml2template.xsl [new file with mode: 0644]
typo3/files/scripts/etc/xsl/xliff2llxml-source.xsl [new file with mode: 0644]
typo3/files/scripts/etc/xsl/xliff2llxml-target.xsl [new file with mode: 0644]
typo3/files/templates/languages.txt [new file with mode: 0644]
typo3/tasks/main.yml [new file with mode: 0644]
typo3/templates/scripts/etc/pootle.conf.j2 [new file with mode: 0644]
vars/main.yml [new file with mode: 0644]

index d7535d2..78efb2a 100644 (file)
@@ -1,3 +1,8 @@
-.build-language-pack-lastbuild
-.build-language-pack-state
-tmp/*
+# Sphinx-related files (local rendering)
+index.rst
+Makefile
+conf.py
+warnings.txt
+_build
+_static
+_templates
diff --git a/LEGACY/bin/build-language-pack b/LEGACY/bin/build-language-pack
new file mode 100755 (executable)
index 0000000..eebcddc
--- /dev/null
@@ -0,0 +1,203 @@
+#!/bin/bash
+
+BASE_DIR=/var/www/vhosts/pootle.typo3.org/pootle/po
+EXPORT_DIR=/var/www/vhosts/pootle.typo3.org/l10n_ter
+STATE_DIR=/var/www/vhosts/pootle.typo3.org/home/scripts/.build-language-pack-state
+POOTLE_CONFIG=/var/www/vhosts/pootle.typo3.org/pootle/localsettings.py
+
+# -- no need to modify anything below
+
+FORCE_EXTENSION=$1
+EXT_PREFIX=TYPO3.TYPO3
+EXTENSIONS=$(ls $BASE_DIR | grep $EXT_PREFIX | cut -b13-)
+DATABASE_NAME=$(grep ^DATABASE_NAME $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+DATABASE_USER=$(grep ^DATABASE_USER $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+DATABASE_PASSWORD=$(grep ^DATABASE_PASSWORD $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+DATABASE_HOST=$(grep ^DATABASE_HOST $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+
+if [ ! -z "$FORCE_EXTENSION" ]; then
+       EXTENSIONS=$FORCE_EXTENSION
+fi
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+# Usage: mysqlpipe "sql-query"
+function mysqlpipe() {
+       echo $@ | mysql -u $DATABASE_USER -p"$DATABASE_PASSWORD" -h $DATABASE_HOST $DATABASE_NAME | sed '1d'
+}
+
+# Usage: lastedit "project" "language"
+function lastedit() {
+       local PROJECT="$1"
+       local LANGUAGE="$2"
+
+       # XP/19.06.2013: Using filesystem instead of database
+       #timestamp=$(mysqlpipe "SELECT p.id, p.code, l.code AS lang, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp
+       #       FROM pootle_app_project AS p
+       #       LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
+       #       LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
+       #       LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
+       #       INNER JOIN pootle_app_language l ON l.id = tp.language_id
+       #       WHERE ( u.state = 50 OR u.state = 200 )
+       #       AND p.code = '$PROJECT'
+       #       AND l.code = '$LANGUAGE'
+       #       GROUP BY p.id, l.code;" \
+       #| awk '{ print $6 }')
+
+       LANGUAGE_DIR=$BASE_DIR/$PROJECT/$LANGUAGE
+       if [ -d $LANGUAGE_DIR ]; then
+               timestamp=$(find $LANGUAGE_DIR -type f -printf '%T@ %p\n' \
+                       | grep -v "./.translation_index" \
+                       | sort -n \
+                       | tail -n 1 \
+                       | cut -f1 -d.
+               )
+       fi
+
+       if [ -z "$timestamp" ]; then
+               echo 0
+       else
+               echo $timestamp
+       fi
+}
+
+cd $(dirname $0)
+if [ -z "$FORCE_EXTENSION" ]; then
+       # Sync whole stores, --project seems not totally reliable
+       echo "Synchronizing all stores ... "
+       ./pootle-manage sync_stores 2>&1
+fi
+
+for EXT in $EXTENSIONS; do
+       EXTNAME=$(echo $EXT | sed -r 's/^[^.]+\.//')
+       echo "Packaging $EXTNAME"
+       if [ ! -z "$FORCE_EXTENSION" ]; then
+               echo -n "   synchronizing store ... "
+               ./pootle-manage sync_stores --project=$EXT_PREFIX.$EXT >/dev/null 2>&1
+               echo "done."
+       fi
+       echo -n "   updating statistics ... "
+       ./pootle-manage refresh_stats --project="$EXT_PREFIX.$EXT" >/dev/null 2>&1
+       echo "done."
+       pushd $BASE_DIR/$EXT_PREFIX.$EXT >/dev/null
+       rm -rf $EXPORT_DIR/_$EXTNAME
+
+       _LANGUAGE_PACK_PATH=${EXPORT_DIR}/${EXTNAME:0:1}/${EXTNAME:1:1}/${EXTNAME}-l10n
+       mkdir -p $_LANGUAGE_PACK_PATH
+       mkdir -p $STATE_DIR/$EXT_PREFIX.$EXT
+
+       LANGUAGES="$(ls | grep -v templates) ba br ch cz dk si se gr hk kr ua jp qc vn ge ga"
+       for LANG in $LANGUAGES; do
+               ORIG_LANG=$LANG
+               case "$LANG" in
+                       'ba')
+                               ORIG_LANG=bs ;;
+                       'br')
+                               ORIG_LANG=pt_BR ;;
+                       'ch')
+                               ORIG_LANG=zh_CN ;;
+                       'cz')
+                               ORIG_LANG=cs ;;
+                       'dk')
+                               ORIG_LANG=da ;;
+                       'si')
+                               ORIG_LANG=sl ;;
+                       'se')
+                               ORIG_LANG=sv ;;
+                       'gr')
+                               ORIG_LANG=el ;;
+                       'hk')
+                               ORIG_LANG=zh_HK ;;
+                       'kr')
+                               ORIG_LANG=ko ;;
+                       'ua')
+                               ORIG_LANG=uk ;;
+                       'jp')
+                               ORIG_LANG=ja ;;
+                       'qc')
+                               ORIG_LANG=fr_CA ;;
+                       'vn')
+                               ORIG_LANG=vi ;;
+                       'ge')
+                               ORIG_LANG=ka ;;
+                       'ga')
+                               ORIG_LANG=gl ;;
+               esac
+
+               echo -n "   processing $LANG ... "
+               #/home/pootle/scripts/pootle-manage sync_stores --project="$EXT_PREFIX.$EXT" --language=$ORIG_LANG >/dev/null 2>&1
+
+               # Compute current state
+               STATUS_FILE=$STATE_DIR/$EXT_PREFIX.$EXT/$LANG.time
+               if [[ -f $STATUS_FILE && -z "$FORCE_EXTENSION" ]]; then
+                       LAST_GENERATION=$(cat $STATE_DIR/$EXT_PREFIX.$EXT/$LANG.time)
+               else
+                       LAST_GENERATION=0
+               fi
+               LAST_EDIT=$(lastedit "$EXT_PREFIX.$EXT" $ORIG_LANG)
+               if [[ $LAST_EDIT -gt 0 && $LAST_EDIT -ne $LAST_GENERATION ]]; then
+                       mkdir -p $EXPORT_DIR/_$EXTNAME/$LANG/$EXTNAME
+                       cp -r $ORIG_LANG/* $EXPORT_DIR/_$EXTNAME/$LANG/$EXTNAME
+                       pushd $EXPORT_DIR/_$EXTNAME/$LANG/$EXTNAME >/dev/null
+                       for XLF in $(find . -type f); do
+                               DIR=$(dirname $XLF)
+                               FILE=$(basename $XLF)
+                               mv $XLF $DIR/$LANG.$FILE
+
+                               # Convert XLIFF to LLXML
+                               _SOURCE_XLIFF_FILE=$BASE_DIR/$EXT_PREFIX.$EXT/templates/$DIR/$FILE
+                               LLXML=$DIR/$LANG.$(echo $FILE | sed s/\.xlf$/\.xml/)
+                               llxml2xliff $EXTNAME \
+                                       $LANG \
+                                       $_SOURCE_XLIFF_FILE \
+                                       $DIR/$LANG.$FILE > $LLXML
+                       done
+                       find . -name \*.xlf -exec chmod 644 {} \;
+                       find . -name \*.xml -exec chmod 644 {} \;
+                       rm -f $_LANGUAGE_PACK_PATH/$EXTNAME-l10n-$LANG.zip
+                       # ../ to include $EXTNAME directory
+                       cd ../
+                       zip -9 $_LANGUAGE_PACK_PATH/$EXTNAME-l10n-$LANG.zip -r . >/dev/null
+
+                       popd >/dev/null
+
+                       # Save current state
+                       echo $LAST_EDIT > $STATUS_FILE
+                       echo "done."
+               else
+                       echo "skipped."
+               fi
+       done
+
+       # Create language pack index
+       pushd $_LANGUAGE_PACK_PATH >/dev/null
+
+       _LANGUAGE_PACK_NAME=${EXTNAME}-l10n
+       _LANGUAGE_INDEX_FILE=${_LANGUAGE_PACK_NAME}.xml
+       rm -f $_LANGUAGE_INDEX_FILE
+        touch $_LANGUAGE_INDEX_FILE
+
+       echo -e "<?xml version=\"1.0\" standalone=\"yes\" ?>"                   >> $_LANGUAGE_INDEX_FILE
+       echo -e "<TERlanguagePackIndex>"                                        >> $_LANGUAGE_INDEX_FILE
+       echo -e "\t<meta>"                                                      >> $_LANGUAGE_INDEX_FILE
+       echo -e "\t\t<timestamp>$(date +"%s")</timestamp>"                      >> $_LANGUAGE_INDEX_FILE
+       echo -e "\t\t<date>$(date +"%F %T")</date>"                             >> $_LANGUAGE_INDEX_FILE
+       echo -e "\t</meta>"                                                     >> $_LANGUAGE_INDEX_FILE
+       echo -e "\t<languagePackIndex>"                                         >> $_LANGUAGE_INDEX_FILE
+
+       for p in $(find . -name \*.zip | sort);
+       do
+               _LANGUAGE_KEY=$(echo $p | sed -r "s/.*${_LANGUAGE_PACK_NAME}-(.*)\.zip\$/\1/")
+               echo -e "\t\t<languagepack language=\"$_LANGUAGE_KEY\">"        >> $_LANGUAGE_INDEX_FILE
+               echo -e "\t\t\t<md5>$(md5sum $p | cut -d" " -f1)</md5>"         >> $_LANGUAGE_INDEX_FILE
+               echo -e "\t\t</languagepack>"                                   >> $_LANGUAGE_INDEX_FILE
+       done
+
+       echo -e "\t</languagePackIndex>"                                        >> $_LANGUAGE_INDEX_FILE
+       echo -e "</TERlanguagePackIndex>"                                       >> $_LANGUAGE_INDEX_FILE
+
+       popd >/dev/null
+
+       rm -rf $EXPORT_DIR/_$EXTNAME
+       popd >/dev/null
+done
diff --git a/LEGACY/bin/pootle-batch-check-project b/LEGACY/bin/pootle-batch-check-project
new file mode 100755 (executable)
index 0000000..5799acd
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+set -e
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+for PROJECT in $(list_all_typo3_project); do
+       pootle-check-project $PROJECT
+done
diff --git a/LEGACY/bin/pootle-batch-import-projects b/LEGACY/bin/pootle-batch-import-projects
new file mode 100755 (executable)
index 0000000..05cf769
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+for PROJECT in $(ls --ignore=po --ignore=terminology --ignore=tutorial $POOTLE_PO); do
+       pootle-create-project $PROJECT >/dev/null 2>/dev/null
+       if [ $? = 0 ]; then
+               echo
+               echo "Refresh project $PROJECT"
+               pootle-refresh-project $PROJECT
+       fi
+done
diff --git a/LEGACY/bin/pootle-check-project b/LEGACY/bin/pootle-check-project
new file mode 100755 (executable)
index 0000000..e0117fa
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+set -e
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+PROJECT=$1
+UPDATE_PROJECT=0
+if [ "$PROJECT" == "" ]; then
+       echo "Missing project name"
+       exit 1
+fi
+
+echo
+echo "Check project $PROJECT ..."
+
+PROJECT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT/"
+
+if [ ! -d $PROJECT_DIRECTORY ]; then
+       echo "Project not found"
+       exit 1
+fi
+
+#
+# Check missing template project
+if [ ! -d $PROJECT_DIRECTORY/templates ]; then
+       echo "[WARNING] Missing templates ..."
+       # TODO Generate template based on english
+else
+       echo "[INFO] Templates exist"
+       # TODO Check if new file exist in english or deleted file in english
+fi
+
+#
+# Create missing language
+check_available_languages $PROJECT
+
diff --git a/LEGACY/bin/pootle-create-project b/LEGACY/bin/pootle-create-project
new file mode 100755 (executable)
index 0000000..d54684c
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+set -e
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+PROJECT=$1
+if [ "$PROJECT" = "" ]; then
+       echo
+       msg "Please provide a project name"
+       echo "Usage: pootle-create-project project-name"
+       echo
+       exit 1
+fi
+
+# Check if the project exist in the database
+_PROJECT_COUNTER=$(mysqlpipe "SELECT id FROM pootle_app_project WHERE code = '${PROJECT}' LIMIT 1\g" | wc -l)
+if [ "$_PROJECT_COUNTER" -gt 0 ]; then
+       echo
+       msg "the current project $PROJECT exist in the database, unable to add a new one with the same name"
+       echo
+       exit 1
+fi
+
+echo
+echo "Create new project in the database ..."
+
+# Create directory record
+_DIRECTORY_COUNTER=$(mysqlpipe "SELECT id FROM pootle_app_directory WHERE pootle_path = '/projects/${PROJECT}/' LIMIT 1\g" | wc -l)
+if [ "$_DIRECTORY_COUNTER" -gt 0 ]; then
+        echo
+        msg "the current directory /projects/${PROJECT}/ exist in the database, unable to add a new one with the same name"
+        echo
+        exit 1
+fi
+mysqlpipe "INSERT INTO pootle_app_directory (name, parent_id, pootle_path) VALUES ('${PROJECT}', 2, '/projects/${PROJECT}/')\g" || exit 1
+
+# Get directory record id
+_POOTLE_DIRECTORY_ID=$(mysqlpipe "SELECT id FROM pootle_app_directory WHERE pootle_path = '/projects/${PROJECT}/' LIMIT 1\g" | tail -n1 | cut -f1)
+
+if [ "$_POOTLE_DIRECTORY_ID" = "" ]; then
+       echo
+       msg "Unable to create directory record"
+       echo
+       exit 1
+fi
+
+if [ ! -d $POOTLE_PO/$PROJECT ]; then
+        # Create the project directory
+        mkdir -p $POOTLE_PO/$PROJECT
+fi
+
+# Create project record
+mysqlpipe "INSERT INTO pootle_app_project (code, fullname, description, checkstyle, localfiletype, treestyle, source_language_id, directory_id) VALUES ('$PROJECT', '$PROJECT', '', 'standard', 'xlf', 'auto', 2, $_POOTLE_DIRECTORY_ID)\g"
+
+exit 0
diff --git a/LEGACY/bin/pootle-notify-hassuggestion b/LEGACY/bin/pootle-notify-hassuggestion
new file mode 100755 (executable)
index 0000000..08cf0e7
--- /dev/null
@@ -0,0 +1,128 @@
+#!/bin/bash
+
+POOTLE_CONFIG=/var/www/vhosts/pootle.typo3.org/pootle/localsettings.py
+
+# -- no need to modify anything below
+
+set -o errtrace
+set -o nounset
+
+#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
+trap onexit 1 2 3 15
+
+#--- onexit() -----------------------------------------------------
+#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
+function onexit() {
+       local exit_status=${1:-$?}
+       if [ $exit_status -gt 0 ]; then
+               echo Exiting $0 with $exit_status
+       fi
+       exit $exit_status
+}
+
+DATABASE_NAME=$(grep ^DATABASE_NAME $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+DATABASE_USER=$(grep ^DATABASE_USER $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+DATABASE_PASSWORD=$(grep ^DATABASE_PASSWORD $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+DATABASE_HOST=$(grep ^DATABASE_HOST $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+# Usage: mysqlpipe "sql-query"
+function mysqlpipe() {
+       echo $@ | mysql -u $DATABASE_USER -p"$DATABASE_PASSWORD" -h $DATABASE_HOST $DATABASE_NAME | sed '1d'
+}
+
+SAVEIFS=$IFS
+
+ROWS=$(mysqlpipe "
+       SELECT l.fullname AS language, l.code AS language_code, l.directory_id AS language_directory_id,
+               p.fullname AS project, p.code AS project_code, p.directory_id AS project_directory_id,
+               COUNT(*) AS suggestions
+       FROM pootle_app_suggestion s
+               INNER JOIN pootle_app_translationproject tp ON tp.id=s.translation_project_id
+               INNER JOIN pootle_app_language l ON l.id=tp.language_id
+               INNER JOIN pootle_app_project p ON p.id=tp.project_id
+               INNER JOIN pootle_store_unit su ON su.id=s.unit
+       WHERE s.state='pending' AND p.id>2
+       GROUP BY s.translation_project_id
+       ORDER BY project, language
+")
+
+IFS=$(echo -en "\n\b")
+
+for ROW in $ROWS;
+do
+       LANGUAGE=$(echo $ROW | awk -F "\t" '{ print $1 }')
+       LANGUAGE_CODE=$(echo $ROW | awk -F "\t" '{ print $2 }')
+       LANGUAGE_DIR_ID=$(echo $ROW | awk -F "\t" '{ print $3 }')
+       PROJECT=$(echo $ROW | awk -F "\t" '{ print $4 }')
+       PROJECT_CODE=$(echo $ROW | awk -F "\t" '{ print $5 }')
+       PROJECT_DIR_ID=$(echo $ROW | awk -F "\t" '{ print $6 }')
+       SUGGESTIONS=$(echo $ROW | awk -F "\t" '{print $7 }')
+
+       echo "[INFO] Found suggestions for project $PROJECT ($PROJECT_CODE) in $LANGUAGE"
+
+       # Look for translators for current project (either project itself or corresponding language)
+       TRANSLATORS=$(mysqlpipe "
+               SELECT DISTINCT u.username, u.first_name, u.last_name, u.email
+               FROM pootle_app_permissionset_positive_permissions pspp
+                       INNER JOIN pootle_app_permissionset ps ON ps.id=pspp.permissionset_id
+                       INNER JOIN pootle_app_pootleprofile pp ON pp.id=ps.profile_id
+                       INNER JOIN auth_user u ON u.id=pp.user_id
+                       INNER JOIN pootle_app_directory d ON d.id=ps.directory_id
+                       INNER JOIN auth_permission p ON p.id=pspp.permission_id
+               WHERE p.codename IN ('administrate', 'translate', 'review') AND u.is_active=1 AND u.email<>''
+                       AND d.id IN ($PROJECT_DIR_ID, $LANGUAGE_DIR_ID)
+               ORDER BY last_name
+       ")
+
+       #if [ -z "$TRANSLATORS" ]; then
+       #       echo "[WARNING] No translators found, falling back to superusers"
+       #       TRANSLATORS=$(mysqlpipe "
+       #               SELECT username, first_name, last_name, email
+       #               FROM auth_user
+       #               WHERE is_active=1 AND is_superuser=1
+       #       ")
+       #fi
+
+       for TRANSLATOR in $TRANSLATORS;
+       do
+               USERNAME=$(echo $TRANSLATOR | awk -F "\t" '{ print $1 }')
+               FIRST_NAME=$(echo $TRANSLATOR | awk -F "\t" '{ print $2 }')
+               LAST_NAME=$(echo $TRANSLATOR | awk -F "\t" '{ print $3 }')
+               EMAIL=$(echo $TRANSLATOR | awk -F "\t" '{ print $4 }')
+
+               echo "[INFO]    - Notifying $USERNAME"
+
+               mail -a"From: TYPO3 Translation Server <no-reply@typo3.org>" \
+                       -s "TYPO3 Pootle: $PROJECT ($LANGUAGE)" \
+                       "$EMAIL" <<EOM
+Dear $FIRST_NAME $LAST_NAME ($USERNAME),
+
+There are currently $SUGGESTIONS suggestions pending for approval for project $PROJECT ($LANGUAGE),
+please review them on:
+
+http://translation.typo3.org/${LANGUAGE_CODE}/${PROJECT_CODE}/translate.html?matchnames=hassuggestion
+
+
+Thanks for contributing to open-source software,
+
+Pootle
+
+
+PS: This is a weekly automated message that you received since you are registered as a
+translator either for project "$PROJECT" or language "$LANGUAGE".
+
+-- 
+TYPO3 translation server (Pootle)
+http://translation.typo3.org/
+EOM
+       done
+
+       # wait a bit before handling next project/language pair
+       sleep 10
+done
+
+IFS=$SAVEIFS
+
+onexit
diff --git a/LEGACY/bin/pootle-refresh-project b/LEGACY/bin/pootle-refresh-project
new file mode 100755 (executable)
index 0000000..31572e8
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -e
+
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
+. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
+
+PROJECT=$1
+if [ ! -d $POOTLE_PO/$PROJECT ]; then
+       echo
+       msg "$PROJECT is not a valid projet"
+       echo
+       exit 1
+fi
+
+echo
+echo -n "1/3 Update translation projects "
+pootle-manage update_translation_projects --project=$PROJECT 2>/dev/null && echo "DONE" || exit 1
+
+echo
+echo -n "2/3 Update database from XLIFF file "
+pootle-manage update_stores --project=$PROJECT 2>/dev/null && echo DONE || exit 1
+
+echo
+echo -n "3/3 Refresh statistics "
+pootle-manage refresh_stats --project=$PROJECT 2>/dev/null && echo DONE || exit 1
diff --git a/LEGACY/bin/pootle-snapshot b/LEGACY/bin/pootle-snapshot
new file mode 100755 (executable)
index 0000000..7b5c885
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+SNAPSHOT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/archives/snapshot"
+
+DESTIONATION_DIRECTORY="$SNAPSHOT_DIRECTORY/$(date +%Y%m%d)"
+mkdir -p $DESTIONATION_DIRECTORY
+mysqldump -ac pootle | gzip > $DESTIONATION_DIRECTORY/pootle.sql.gz
+tar cfpz $DESTIONATION_DIRECTORY/po.tar.gz /var/www/vhosts/pootle.typo3.org/pootle/po
diff --git a/LEGACY/bin/pootle-upgrade-all-extensions b/LEGACY/bin/pootle-upgrade-all-extensions
new file mode 100755 (executable)
index 0000000..9ad8bf0
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+set -o errtrace
+set -o nounset
+
+#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
+trap onexit 1 2 3 15
+
+#--- onexit() -----------------------------------------------------
+#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
+function onexit() {
+       local exit_status=${1:-$?}
+       if [ $exit_status -gt 0 ]; then
+               echo Exiting $0 with $exit_status
+       fi
+       exit $exit_status
+}
+
+BASE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po"
+T3XUTILS=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/t3xutils.phar
+UPGRADE_EXTENSION=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/pootle-upgrade-extension
+
+echo "[INFO] Fetch and cache TER extension metadata"
+$T3XUTILS updateinfo >/dev/null
+
+cd $BASE_DIRECTORY
+PROJECTS=$(find . -maxdepth 1 -type d | egrep 'TYPO3\.TYPO3\.ext\.' | sort)
+
+for PROJECT in $PROJECTS;
+do
+       EXTENSION=$(echo $PROJECT | cut -b19-)
+
+       echo -n "[INFO] Looking for latest version of $EXTENSION on TER: "
+       LASTLINE=$($T3XUTILS info $EXTENSION 2>/dev/null | grep -v "Available versions:" | tail -n 1)
+       if [ -z "$LASTLINE" ]; then
+               echo "n/a"
+               echo "[ERROR] Extension $EXTENSION does not exist on TER"
+       else
+               LASTVERSION=$(echo $LASTLINE | awk '{ print $1 }' | egrep '^[0-9.]+$')
+               if [ -n "$LASTVERSION" ]; then
+                       echo $LASTVERSION
+                       LOCALVERSION=""
+                       if [ -f $BASE_DIRECTORY/$PROJECT/.ter-version ]; then
+                               LOCALVERSION=$(cat $BASE_DIRECTORY/$PROJECT/.ter-version)
+                       fi
+                       if [ -z "$LOCALVERSION" ] || [ "$LOCALVERSION" != "$LASTVERSION" ]; then
+                               echo "[INFO] Updating extension $EXTENSION to version $LASTVERSION"
+                               $UPGRADE_EXTENSION $EXTENSION $LASTVERSION
+                       fi
+               fi
+       fi
+done
+
+onexit
diff --git a/LEGACY/bin/pootle-upgrade-extension b/LEGACY/bin/pootle-upgrade-extension
new file mode 100755 (executable)
index 0000000..b493d22
--- /dev/null
@@ -0,0 +1,161 @@
+#!/bin/bash
+
+set -o errtrace
+set -o nounset
+
+#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
+trap onexit 1 2 3 15
+
+#--- onexit() -----------------------------------------------------
+#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
+function onexit() {
+       local exit_status=${1:-$?}
+       if [ $exit_status -gt 0 ]; then
+               echo Exiting $0 with $exit_status
+       fi
+       exit $exit_status
+}
+
+T3XUTILS=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/t3xutils.phar
+POOTLE_MANAGE=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/pootle-manage
+
+# --- check_available_languages() ---------------------------------
+# @param $1 string               Pootle Project Name
+function check_available_languages() {
+       local NEED_UPDATE=0
+       local PROJECT_NAME=$1
+        for LANGUAGE_KEY in $(ls /var/www/vhosts/pootle.typo3.org/home/templates); do
+               local LANGUAGE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME/$LANGUAGE_KEY"
+                if [ "$PROJECT_NAME" != "" ] && [ -d /var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME ] && [ ! -d $LANGUAGE_DIRECTORY ]; then
+                        mkdir -p $LANGUAGE_DIRECTORY
+                        echo "[NOTICE] Add project language \"$LANGUAGE_KEY\""
+                       NEED_UPDATE=1
+                fi
+        done
+       if [ $NEED_UPDATE == 1 ]; then
+               echo "[NOTICE] Update translation project"
+               $POOTLE_MANAGE update_translation_projects --project=$1 1>/dev/null 2>/dev/null
+       fi
+}
+
+SAVEIFS=$IFS
+
+XSL_LLXML2TEMPLATE="/var/www/vhosts/pootle.typo3.org/home/scripts/etc/xsl/llxml2template.xsl"
+TEMP_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/tmp"
+
+EXTENSION=$1
+VERSION=$2
+
+PROJECT_NAME="TYPO3.TYPO3.ext.$EXTENSION"
+PROJECT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME"
+#
+# Check if the project exist
+if [ ! -d $PROJECT_DIRECTORY ]; then
+       echo
+       echo "[ERROR] Project $PROJECT_NAME doesn't exist in Pootle, please create it before using this script"
+       echo "[ERROR] Please create directory: $PROJECT_DIRECTORY"
+       onexit 1
+fi
+
+#
+# Check if the templates directory exist
+TEMPLATE_DIRECTORY="$PROJECT_DIRECTORY/templates"
+if [ ! -d $TEMPLATE_DIRECTORY ]; then
+        echo
+        echo "[INFO] Templates directory for project $PROJECT_NAME doesn't exist in Pootle"
+       echo "[NOTICE] Create the templates directory"
+       mkdir -p $TEMPLATE_DIRECTORY
+fi
+
+cd $TEMP_DIRECTORY >/dev/null
+
+echo "[INFO] Downloading $EXTENSION $VERSION from TER"
+
+EXTENSION_T3X=$(echo "${EXTENSION}_${VERSION}.t3x" | tr '[:upper:]' '[:lower:]')
+
+#
+# Download t3x
+rm -f $EXTENSION_T3X
+wget -q http://typo3.org/fileadmin/ter/${EXTENSION_T3X:0:1}/${EXTENSION_T3X:1:1}/$EXTENSION_T3X
+
+#
+# Extract t3x
+#extract-t3x $EXTENSION_T3X $EXTENSION > /dev/null
+$T3XUTILS extract $EXTENSION_T3X $EXTENSION >/dev/null
+
+IFS=$(echo -en "\n\b")
+
+#
+# Create directory structure for templates
+for FILE in $(find $EXTENSION/ -name \*.xml); do
+       grep "T3locallang" "$FILE" 1> /dev/null
+       if [ $? == 0 ]; then
+               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
+               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
+       fi
+done
+for FILE in $(find $EXTENSION/ -name \*.xlf); do
+       # Count number of dots in filename to skip e.g., de.locallang.xlf
+       DOTS=$(echo -n $(basename $FILE) | sed 's/[^.]//g' | wc -c)
+       if [ $DOTS -eq 1 ]; then
+               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
+               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
+       fi
+done
+
+cd $TEMP_DIRECTORY
+for FILE in $(find TYPO3.TYPO3.ext.$EXTENSION -name \*.xml); do
+       grep "T3locallang" "$FILE" 1> /dev/null
+       if [ $? == 0 ]; then
+               XLF_FILE=$(echo $FILE | sed s/.xml$/.xlf/)
+               if [ ! -f $XLF_FILE ]; then
+                       echo "[INFO] Convert LLXML to XLIFF for file $FILE"
+                       if [ ! -f $XLF_FILE ]; then
+                               xsltproc --stringparam lang en \
+                                       --stringparam extension $EXTENSION \
+                                       --stringparam date "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" $XSL_LLXML2TEMPLATE $FILE | \
+                                       xmlstarlet ed --insert "/xliff/file/body/trans-unit" --type attr -n xml:space -v preserve > $XLF_FILE
+                       fi
+               fi
+       fi
+       rm -f $FILE
+done
+
+#
+# Deploy new templates files
+echo "[INFO] Deploy new templates to $TEMPLATE_DIRECTORY"
+cd $TEMPLATE_DIRECTORY/../../ && \
+       tar cfzp $TEMP_DIRECTORY/backup/$PROJECT_NAME-$(date +%Y%m%d).tar.gz $PROJECT_NAME && \
+       cd - && \
+       rm -Rf $TEMPLATE_DIRECTORY && \
+       mkdir -p $TEMPLATE_DIRECTORY && \
+       cp -a $TEMP_DIRECTORY/$PROJECT_NAME/* $TEMPLATE_DIRECTORY || \
+               onexit 5
+
+#
+# Check project available language
+check_available_languages $PROJECT_NAME
+
+#
+# Update project from templates
+echo "[INFO] Update from templates"
+$POOTLE_MANAGE update_from_templates --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
+
+echo "[INFO] Refresh statistics"
+$POOTLE_MANAGE refresh_stats --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
+
+echo "[NOTICE] Register version $VERSION for EXT:$EXTENSION"
+echo -n $VERSION > $PROJECT_DIRECTORY/.ter-version
+
+#
+# Cleanup
+cd $TEMP_DIRECTORY
+rm -f $EXTENSION_T3X
+if [ -d $EXTENSION ]; then
+       rm -rf $EXTENSION
+       rm -rf TYPO3.TYPO3.ext.$EXTENSION
+fi
+
+IFS=$SAVEIFS
+
+onexit
diff --git a/LEGACY/bin/pootle-upgrade-extension-git b/LEGACY/bin/pootle-upgrade-extension-git
new file mode 100755 (executable)
index 0000000..78e98a1
--- /dev/null
@@ -0,0 +1,149 @@
+#!/bin/bash
+
+set -o errtrace
+set -o nounset
+
+#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
+trap onexit 1 2 3 15
+
+#--- onexit() -----------------------------------------------------
+#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
+function onexit() {
+       local exit_status=${1:-$?}
+       if [ $exit_status -gt 0 ]; then
+               echo Exiting $0 with $exit_status
+       fi
+       exit $exit_status
+}
+
+# --- check_available_languages() ---------------------------------
+# @param $1 string               Pootle Project Name
+function check_available_languages() {
+       local NEED_UPDATE=0
+       local PROJECT_NAME=$1
+        for LANGUAGE_KEY in $(ls /var/www/vhosts/pootle.typo3.org/home/templates); do
+               local LANGUAGE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME/$LANGUAGE_KEY"
+                if [ "$PROJECT_NAME" != "" ] && [ -d /var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME ] && [ ! -d $LANGUAGE_DIRECTORY ]; then
+                        mkdir -p $LANGUAGE_DIRECTORY
+                        echo "[NOTICE] Add project language \"$LANGUAGE_KEY\""
+                       NEED_UPDATE=1
+                fi
+        done
+       if [ $NEED_UPDATE == 1 ]; then
+               echo "[NOTICE] Update translation project"
+               pootle-manage update_translation_projects --project=$1 1>/dev/null 2>/dev/null
+       fi
+}
+
+SAVEIFS=$IFS
+
+XSL_LLXML2TEMPLATE="/var/www/vhosts/pootle.typo3.org/home/scripts/etc/xsl/llxml2template.xsl"
+TEMP_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/tmp"
+
+EXTENSION=$1
+GIT=$2
+
+PROJECT_NAME="TYPO3.TYPO3.ext.$EXTENSION"
+PROJECT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME"
+#
+# Check if the project exist
+if [ ! -d $PROJECT_DIRECTORY ]; then
+       echo
+       echo "[ERROR] Project $PROJECT_NAME doesn't exist in Pootle, please create it before using this script"
+       echo "[ERROR] Please create directory: $PROJECT_DIRECTORY"
+       onexit 1
+fi
+
+#
+# Check if the templates directory exist
+TEMPLATE_DIRECTORY="$PROJECT_DIRECTORY/templates"
+if [ ! -d $TEMPLATE_DIRECTORY ]; then
+        echo
+        echo "[INFO] Templates directory for project $PROJECT_NAME doesn't exist in Pootle"
+       echo "[NOTICE] Create the templates directory"
+       mkdir -p $TEMPLATE_DIRECTORY
+fi
+
+cd $TEMP_DIRECTORY >/dev/null
+
+echo "[INFO] Cloning $EXTENSION from $GIT"
+
+EXTENSION_DIR=$(echo "${EXTENSION}" | tr '[:upper:]' '[:lower:]')
+
+#
+# Download t3x
+rm -rf $EXTENSION
+git clone $GIT $EXTENSION
+
+IFS=$(echo -en "\n\b")
+
+#
+# Create directory structure for templates
+for FILE in $(find $EXTENSION/ -name \*.xml); do
+       grep "T3locallang" "$FILE" 1> /dev/null
+       if [ $? == 0 ]; then
+               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
+               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
+       fi
+done
+for FILE in $(find $EXTENSION/ -name \*.xlf); do
+       # Count number of dots in filename to skip e.g., de.locallang.xlf
+       DOTS=$(echo -n $(basename $FILE) | sed 's/[^.]//g' | wc -c)
+       if [ $DOTS -eq 1 ]; then
+               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
+               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
+       fi
+done
+
+cd $TEMP_DIRECTORY
+for FILE in $(find TYPO3.TYPO3.ext.$EXTENSION -name \*.xml); do
+       grep "T3locallang" "$FILE" 1> /dev/null
+       if [ $? == 0 ]; then
+               XLF_FILE=$(echo $FILE | sed s/.xml$/.xlf/)
+               if [ ! -f $XLF_FILE ]; then
+                       echo "[INFO] Convert LLXML to XLIFF for file $FILE"
+                       if [ ! -f $XLF_FILE ]; then
+                               xsltproc --stringparam lang en \
+                                       --stringparam extension $EXTENSION \
+                                       --stringparam date "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" $XSL_LLXML2TEMPLATE $FILE | \
+                                       xmlstarlet ed --insert "/xliff/file/body/trans-unit" --type attr -n xml:space -v preserve > $XLF_FILE
+                       fi
+               fi
+       fi
+       rm -f $FILE
+done
+
+#
+# Deploy new templates files
+echo "[INFO] Deploy new templates to $TEMPLATE_DIRECTORY"
+cd $TEMPLATE_DIRECTORY/../../ && \
+       tar cfzp $TEMP_DIRECTORY/backup/$PROJECT_NAME-$(date +%Y%m%d).tar.gz $PROJECT_NAME && \
+       cd - && \
+       rm -Rf $TEMPLATE_DIRECTORY && \
+       mkdir -p $TEMPLATE_DIRECTORY && \
+       cp -a $TEMP_DIRECTORY/$PROJECT_NAME/* $TEMPLATE_DIRECTORY || \
+               onexit 5
+
+#
+# Check project available language
+check_available_languages $PROJECT_NAME
+
+#
+# Update project from templates
+echo "[INFO] Update from templates"
+pootle-manage update_from_templates --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
+
+echo "[INFO] Refresh statistics"
+pootle-manage refresh_stats --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
+
+#
+# Cleanup
+cd $TEMP_DIRECTORY
+if [ -d $EXTENSION ]; then
+       rm -rf $EXTENSION
+       rm -rf TYPO3.TYPO3.ext.$EXTENSION
+fi
+
+IFS=$SAVEIFS
+
+onexit
diff --git a/LEGACY/bin/t3xutils.phar b/LEGACY/bin/t3xutils.phar
new file mode 100755 (executable)
index 0000000..e6b1b30
Binary files /dev/null and b/LEGACY/bin/t3xutils.phar differ
diff --git a/LEGACY/etc/typo3-prefix.conf b/LEGACY/etc/typo3-prefix.conf
new file mode 100644 (file)
index 0000000..15b504e
--- /dev/null
@@ -0,0 +1,2 @@
+core:TYPO3.core
+ext:TYPO3.ext
diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..7ca2ec6
--- /dev/null
@@ -0,0 +1,80 @@
+=========================
+Pootle Translation Server
+=========================
+
+This document describes how to install a personal Pootle translation server.
+
+Requirements
+============
+
+* `Ansible <http://docs.ansible.com/>`_. We use Ansible to easily deploy Pootle and scripts to the server. The deployment receipes and scripts are found in this Git project.
+* Linux server. We will use a blank `Debian AMD64 <https://www.debian.org/CD/netinst/>`_ virtual machine to start with. Installation was done with only a SSH server running and command :command:`sudo` being available.
+
+
+Installing Ansible
+------------------
+
+Ansible is needed on a so-called "Control Machine"; that is, a computer that will control the Pootle server. This is typically your personal computer.
+
+We will install Ansible from source since this is the recommended method. Just pick your preferred user directory and:
+
+::
+
+    $ sudo easy_install pip
+    $ sudo pip install paramiko PyYAML Jinja2 httplib2 six
+    $ git clone git://github.com/ansible/ansible.git --recursive
+    $ cd ./ansible
+    $ source ./hacking/env-setup
+
+Configuring Ansible
+-------------------
+
+Edit or create file :file:`/etc/ansible/hosts` and put a reference to your (blank) server::
+
+    [pootle]
+    192.168.81.128
+
+Provisioning Pootle server
+--------------------------
+
+Run::
+
+    $ ansible-playbook -s install.yml
+
+Administrating Pootle
+---------------------
+
+In default Pootle installations, an admin account (the password matches the username) is created with superuser privileges which can be used to administer the whole site.
+
+.. note::
+    It's highly recommended that you change the password for the default admin account on your first login, or even delete the account
+    and assign superuser rights to another user.
+
+When logging onto your server, you are encouraged to work as user "pootle" and follow the guide::
+
+    $ sudo su - pootle
+
+Migrating data from production
+------------------------------
+
+- Copy po files from production and deploy to new server
+- Dump the production database
+- Remove every database table from new Pootle server
+- Import production database dump
+- Run::
+
+      $ sudo -u pootle /opt/local/pootle/bin/pootle --config=/etc/pootle/pootle.conf setup
+
+- Migrate XLIFF to global space with unique id::
+
+      $ sudo su - pootle
+         $ ~/scripts/bin/migration/migrate-typo3-xliff
+
+- Create Pootle projects:
+  - TYPO3.TYPO3.core.frontend
+  - TYPO3.TYPO3.core.compatibility6
+
+- Update your password to be "password"::
+
+      UPDATE auth_user SET password='sha1$b5711$bb690a5a16cff60ae3b01fa285bcb2e68cd244f7' WHERE username='admin';
+
diff --git a/bin/build-language-pack b/bin/build-language-pack
deleted file mode 100755 (executable)
index eebcddc..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/bin/bash
-
-BASE_DIR=/var/www/vhosts/pootle.typo3.org/pootle/po
-EXPORT_DIR=/var/www/vhosts/pootle.typo3.org/l10n_ter
-STATE_DIR=/var/www/vhosts/pootle.typo3.org/home/scripts/.build-language-pack-state
-POOTLE_CONFIG=/var/www/vhosts/pootle.typo3.org/pootle/localsettings.py
-
-# -- no need to modify anything below
-
-FORCE_EXTENSION=$1
-EXT_PREFIX=TYPO3.TYPO3
-EXTENSIONS=$(ls $BASE_DIR | grep $EXT_PREFIX | cut -b13-)
-DATABASE_NAME=$(grep ^DATABASE_NAME $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-DATABASE_USER=$(grep ^DATABASE_USER $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-DATABASE_PASSWORD=$(grep ^DATABASE_PASSWORD $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-DATABASE_HOST=$(grep ^DATABASE_HOST $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-
-if [ ! -z "$FORCE_EXTENSION" ]; then
-       EXTENSIONS=$FORCE_EXTENSION
-fi
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-# Usage: mysqlpipe "sql-query"
-function mysqlpipe() {
-       echo $@ | mysql -u $DATABASE_USER -p"$DATABASE_PASSWORD" -h $DATABASE_HOST $DATABASE_NAME | sed '1d'
-}
-
-# Usage: lastedit "project" "language"
-function lastedit() {
-       local PROJECT="$1"
-       local LANGUAGE="$2"
-
-       # XP/19.06.2013: Using filesystem instead of database
-       #timestamp=$(mysqlpipe "SELECT p.id, p.code, l.code AS lang, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp
-       #       FROM pootle_app_project AS p
-       #       LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
-       #       LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
-       #       LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
-       #       INNER JOIN pootle_app_language l ON l.id = tp.language_id
-       #       WHERE ( u.state = 50 OR u.state = 200 )
-       #       AND p.code = '$PROJECT'
-       #       AND l.code = '$LANGUAGE'
-       #       GROUP BY p.id, l.code;" \
-       #| awk '{ print $6 }')
-
-       LANGUAGE_DIR=$BASE_DIR/$PROJECT/$LANGUAGE
-       if [ -d $LANGUAGE_DIR ]; then
-               timestamp=$(find $LANGUAGE_DIR -type f -printf '%T@ %p\n' \
-                       | grep -v "./.translation_index" \
-                       | sort -n \
-                       | tail -n 1 \
-                       | cut -f1 -d.
-               )
-       fi
-
-       if [ -z "$timestamp" ]; then
-               echo 0
-       else
-               echo $timestamp
-       fi
-}
-
-cd $(dirname $0)
-if [ -z "$FORCE_EXTENSION" ]; then
-       # Sync whole stores, --project seems not totally reliable
-       echo "Synchronizing all stores ... "
-       ./pootle-manage sync_stores 2>&1
-fi
-
-for EXT in $EXTENSIONS; do
-       EXTNAME=$(echo $EXT | sed -r 's/^[^.]+\.//')
-       echo "Packaging $EXTNAME"
-       if [ ! -z "$FORCE_EXTENSION" ]; then
-               echo -n "   synchronizing store ... "
-               ./pootle-manage sync_stores --project=$EXT_PREFIX.$EXT >/dev/null 2>&1
-               echo "done."
-       fi
-       echo -n "   updating statistics ... "
-       ./pootle-manage refresh_stats --project="$EXT_PREFIX.$EXT" >/dev/null 2>&1
-       echo "done."
-       pushd $BASE_DIR/$EXT_PREFIX.$EXT >/dev/null
-       rm -rf $EXPORT_DIR/_$EXTNAME
-
-       _LANGUAGE_PACK_PATH=${EXPORT_DIR}/${EXTNAME:0:1}/${EXTNAME:1:1}/${EXTNAME}-l10n
-       mkdir -p $_LANGUAGE_PACK_PATH
-       mkdir -p $STATE_DIR/$EXT_PREFIX.$EXT
-
-       LANGUAGES="$(ls | grep -v templates) ba br ch cz dk si se gr hk kr ua jp qc vn ge ga"
-       for LANG in $LANGUAGES; do
-               ORIG_LANG=$LANG
-               case "$LANG" in
-                       'ba')
-                               ORIG_LANG=bs ;;
-                       'br')
-                               ORIG_LANG=pt_BR ;;
-                       'ch')
-                               ORIG_LANG=zh_CN ;;
-                       'cz')
-                               ORIG_LANG=cs ;;
-                       'dk')
-                               ORIG_LANG=da ;;
-                       'si')
-                               ORIG_LANG=sl ;;
-                       'se')
-                               ORIG_LANG=sv ;;
-                       'gr')
-                               ORIG_LANG=el ;;
-                       'hk')
-                               ORIG_LANG=zh_HK ;;
-                       'kr')
-                               ORIG_LANG=ko ;;
-                       'ua')
-                               ORIG_LANG=uk ;;
-                       'jp')
-                               ORIG_LANG=ja ;;
-                       'qc')
-                               ORIG_LANG=fr_CA ;;
-                       'vn')
-                               ORIG_LANG=vi ;;
-                       'ge')
-                               ORIG_LANG=ka ;;
-                       'ga')
-                               ORIG_LANG=gl ;;
-               esac
-
-               echo -n "   processing $LANG ... "
-               #/home/pootle/scripts/pootle-manage sync_stores --project="$EXT_PREFIX.$EXT" --language=$ORIG_LANG >/dev/null 2>&1
-
-               # Compute current state
-               STATUS_FILE=$STATE_DIR/$EXT_PREFIX.$EXT/$LANG.time
-               if [[ -f $STATUS_FILE && -z "$FORCE_EXTENSION" ]]; then
-                       LAST_GENERATION=$(cat $STATE_DIR/$EXT_PREFIX.$EXT/$LANG.time)
-               else
-                       LAST_GENERATION=0
-               fi
-               LAST_EDIT=$(lastedit "$EXT_PREFIX.$EXT" $ORIG_LANG)
-               if [[ $LAST_EDIT -gt 0 && $LAST_EDIT -ne $LAST_GENERATION ]]; then
-                       mkdir -p $EXPORT_DIR/_$EXTNAME/$LANG/$EXTNAME
-                       cp -r $ORIG_LANG/* $EXPORT_DIR/_$EXTNAME/$LANG/$EXTNAME
-                       pushd $EXPORT_DIR/_$EXTNAME/$LANG/$EXTNAME >/dev/null
-                       for XLF in $(find . -type f); do
-                               DIR=$(dirname $XLF)
-                               FILE=$(basename $XLF)
-                               mv $XLF $DIR/$LANG.$FILE
-
-                               # Convert XLIFF to LLXML
-                               _SOURCE_XLIFF_FILE=$BASE_DIR/$EXT_PREFIX.$EXT/templates/$DIR/$FILE
-                               LLXML=$DIR/$LANG.$(echo $FILE | sed s/\.xlf$/\.xml/)
-                               llxml2xliff $EXTNAME \
-                                       $LANG \
-                                       $_SOURCE_XLIFF_FILE \
-                                       $DIR/$LANG.$FILE > $LLXML
-                       done
-                       find . -name \*.xlf -exec chmod 644 {} \;
-                       find . -name \*.xml -exec chmod 644 {} \;
-                       rm -f $_LANGUAGE_PACK_PATH/$EXTNAME-l10n-$LANG.zip
-                       # ../ to include $EXTNAME directory
-                       cd ../
-                       zip -9 $_LANGUAGE_PACK_PATH/$EXTNAME-l10n-$LANG.zip -r . >/dev/null
-
-                       popd >/dev/null
-
-                       # Save current state
-                       echo $LAST_EDIT > $STATUS_FILE
-                       echo "done."
-               else
-                       echo "skipped."
-               fi
-       done
-
-       # Create language pack index
-       pushd $_LANGUAGE_PACK_PATH >/dev/null
-
-       _LANGUAGE_PACK_NAME=${EXTNAME}-l10n
-       _LANGUAGE_INDEX_FILE=${_LANGUAGE_PACK_NAME}.xml
-       rm -f $_LANGUAGE_INDEX_FILE
-        touch $_LANGUAGE_INDEX_FILE
-
-       echo -e "<?xml version=\"1.0\" standalone=\"yes\" ?>"                   >> $_LANGUAGE_INDEX_FILE
-       echo -e "<TERlanguagePackIndex>"                                        >> $_LANGUAGE_INDEX_FILE
-       echo -e "\t<meta>"                                                      >> $_LANGUAGE_INDEX_FILE
-       echo -e "\t\t<timestamp>$(date +"%s")</timestamp>"                      >> $_LANGUAGE_INDEX_FILE
-       echo -e "\t\t<date>$(date +"%F %T")</date>"                             >> $_LANGUAGE_INDEX_FILE
-       echo -e "\t</meta>"                                                     >> $_LANGUAGE_INDEX_FILE
-       echo -e "\t<languagePackIndex>"                                         >> $_LANGUAGE_INDEX_FILE
-
-       for p in $(find . -name \*.zip | sort);
-       do
-               _LANGUAGE_KEY=$(echo $p | sed -r "s/.*${_LANGUAGE_PACK_NAME}-(.*)\.zip\$/\1/")
-               echo -e "\t\t<languagepack language=\"$_LANGUAGE_KEY\">"        >> $_LANGUAGE_INDEX_FILE
-               echo -e "\t\t\t<md5>$(md5sum $p | cut -d" " -f1)</md5>"         >> $_LANGUAGE_INDEX_FILE
-               echo -e "\t\t</languagepack>"                                   >> $_LANGUAGE_INDEX_FILE
-       done
-
-       echo -e "\t</languagePackIndex>"                                        >> $_LANGUAGE_INDEX_FILE
-       echo -e "</TERlanguagePackIndex>"                                       >> $_LANGUAGE_INDEX_FILE
-
-       popd >/dev/null
-
-       rm -rf $EXPORT_DIR/_$EXTNAME
-       popd >/dev/null
-done
diff --git a/bin/pootle-batch-check-project b/bin/pootle-batch-check-project
deleted file mode 100755 (executable)
index 5799acd..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-set -e
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-for PROJECT in $(list_all_typo3_project); do
-       pootle-check-project $PROJECT
-done
diff --git a/bin/pootle-batch-import-projects b/bin/pootle-batch-import-projects
deleted file mode 100755 (executable)
index 05cf769..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-for PROJECT in $(ls --ignore=po --ignore=terminology --ignore=tutorial $POOTLE_PO); do
-       pootle-create-project $PROJECT >/dev/null 2>/dev/null
-       if [ $? = 0 ]; then
-               echo
-               echo "Refresh project $PROJECT"
-               pootle-refresh-project $PROJECT
-       fi
-done
diff --git a/bin/pootle-check-project b/bin/pootle-check-project
deleted file mode 100755 (executable)
index e0117fa..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-
-set -e
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-PROJECT=$1
-UPDATE_PROJECT=0
-if [ "$PROJECT" == "" ]; then
-       echo "Missing project name"
-       exit 1
-fi
-
-echo
-echo "Check project $PROJECT ..."
-
-PROJECT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT/"
-
-if [ ! -d $PROJECT_DIRECTORY ]; then
-       echo "Project not found"
-       exit 1
-fi
-
-#
-# Check missing template project
-if [ ! -d $PROJECT_DIRECTORY/templates ]; then
-       echo "[WARNING] Missing templates ..."
-       # TODO Generate template based on english
-else
-       echo "[INFO] Templates exist"
-       # TODO Check if new file exist in english or deleted file in english
-fi
-
-#
-# Create missing language
-check_available_languages $PROJECT
-
diff --git a/bin/pootle-create-project b/bin/pootle-create-project
deleted file mode 100755 (executable)
index d54684c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-
-set -e
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-PROJECT=$1
-if [ "$PROJECT" = "" ]; then
-       echo
-       msg "Please provide a project name"
-       echo "Usage: pootle-create-project project-name"
-       echo
-       exit 1
-fi
-
-# Check if the project exist in the database
-_PROJECT_COUNTER=$(mysqlpipe "SELECT id FROM pootle_app_project WHERE code = '${PROJECT}' LIMIT 1\g" | wc -l)
-if [ "$_PROJECT_COUNTER" -gt 0 ]; then
-       echo
-       msg "the current project $PROJECT exist in the database, unable to add a new one with the same name"
-       echo
-       exit 1
-fi
-
-echo
-echo "Create new project in the database ..."
-
-# Create directory record
-_DIRECTORY_COUNTER=$(mysqlpipe "SELECT id FROM pootle_app_directory WHERE pootle_path = '/projects/${PROJECT}/' LIMIT 1\g" | wc -l)
-if [ "$_DIRECTORY_COUNTER" -gt 0 ]; then
-        echo
-        msg "the current directory /projects/${PROJECT}/ exist in the database, unable to add a new one with the same name"
-        echo
-        exit 1
-fi
-mysqlpipe "INSERT INTO pootle_app_directory (name, parent_id, pootle_path) VALUES ('${PROJECT}', 2, '/projects/${PROJECT}/')\g" || exit 1
-
-# Get directory record id
-_POOTLE_DIRECTORY_ID=$(mysqlpipe "SELECT id FROM pootle_app_directory WHERE pootle_path = '/projects/${PROJECT}/' LIMIT 1\g" | tail -n1 | cut -f1)
-
-if [ "$_POOTLE_DIRECTORY_ID" = "" ]; then
-       echo
-       msg "Unable to create directory record"
-       echo
-       exit 1
-fi
-
-if [ ! -d $POOTLE_PO/$PROJECT ]; then
-        # Create the project directory
-        mkdir -p $POOTLE_PO/$PROJECT
-fi
-
-# Create project record
-mysqlpipe "INSERT INTO pootle_app_project (code, fullname, description, checkstyle, localfiletype, treestyle, source_language_id, directory_id) VALUES ('$PROJECT', '$PROJECT', '', 'standard', 'xlf', 'auto', 2, $_POOTLE_DIRECTORY_ID)\g"
-
-exit 0
diff --git a/bin/pootle-manage b/bin/pootle-manage
deleted file mode 100755 (executable)
index 183a562..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-set -e
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-python /var/www/vhosts/pootle.typo3.org/pootle/manage.py $@
diff --git a/bin/pootle-notify-hassuggestion b/bin/pootle-notify-hassuggestion
deleted file mode 100755 (executable)
index 08cf0e7..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/bash
-
-POOTLE_CONFIG=/var/www/vhosts/pootle.typo3.org/pootle/localsettings.py
-
-# -- no need to modify anything below
-
-set -o errtrace
-set -o nounset
-
-#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
-trap onexit 1 2 3 15
-
-#--- onexit() -----------------------------------------------------
-#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
-function onexit() {
-       local exit_status=${1:-$?}
-       if [ $exit_status -gt 0 ]; then
-               echo Exiting $0 with $exit_status
-       fi
-       exit $exit_status
-}
-
-DATABASE_NAME=$(grep ^DATABASE_NAME $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-DATABASE_USER=$(grep ^DATABASE_USER $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-DATABASE_PASSWORD=$(grep ^DATABASE_PASSWORD $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-DATABASE_HOST=$(grep ^DATABASE_HOST $POOTLE_CONFIG | sed -r "s/.* = '([^']+)'.*/\1/")
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-# Usage: mysqlpipe "sql-query"
-function mysqlpipe() {
-       echo $@ | mysql -u $DATABASE_USER -p"$DATABASE_PASSWORD" -h $DATABASE_HOST $DATABASE_NAME | sed '1d'
-}
-
-SAVEIFS=$IFS
-
-ROWS=$(mysqlpipe "
-       SELECT l.fullname AS language, l.code AS language_code, l.directory_id AS language_directory_id,
-               p.fullname AS project, p.code AS project_code, p.directory_id AS project_directory_id,
-               COUNT(*) AS suggestions
-       FROM pootle_app_suggestion s
-               INNER JOIN pootle_app_translationproject tp ON tp.id=s.translation_project_id
-               INNER JOIN pootle_app_language l ON l.id=tp.language_id
-               INNER JOIN pootle_app_project p ON p.id=tp.project_id
-               INNER JOIN pootle_store_unit su ON su.id=s.unit
-       WHERE s.state='pending' AND p.id>2
-       GROUP BY s.translation_project_id
-       ORDER BY project, language
-")
-
-IFS=$(echo -en "\n\b")
-
-for ROW in $ROWS;
-do
-       LANGUAGE=$(echo $ROW | awk -F "\t" '{ print $1 }')
-       LANGUAGE_CODE=$(echo $ROW | awk -F "\t" '{ print $2 }')
-       LANGUAGE_DIR_ID=$(echo $ROW | awk -F "\t" '{ print $3 }')
-       PROJECT=$(echo $ROW | awk -F "\t" '{ print $4 }')
-       PROJECT_CODE=$(echo $ROW | awk -F "\t" '{ print $5 }')
-       PROJECT_DIR_ID=$(echo $ROW | awk -F "\t" '{ print $6 }')
-       SUGGESTIONS=$(echo $ROW | awk -F "\t" '{print $7 }')
-
-       echo "[INFO] Found suggestions for project $PROJECT ($PROJECT_CODE) in $LANGUAGE"
-
-       # Look for translators for current project (either project itself or corresponding language)
-       TRANSLATORS=$(mysqlpipe "
-               SELECT DISTINCT u.username, u.first_name, u.last_name, u.email
-               FROM pootle_app_permissionset_positive_permissions pspp
-                       INNER JOIN pootle_app_permissionset ps ON ps.id=pspp.permissionset_id
-                       INNER JOIN pootle_app_pootleprofile pp ON pp.id=ps.profile_id
-                       INNER JOIN auth_user u ON u.id=pp.user_id
-                       INNER JOIN pootle_app_directory d ON d.id=ps.directory_id
-                       INNER JOIN auth_permission p ON p.id=pspp.permission_id
-               WHERE p.codename IN ('administrate', 'translate', 'review') AND u.is_active=1 AND u.email<>''
-                       AND d.id IN ($PROJECT_DIR_ID, $LANGUAGE_DIR_ID)
-               ORDER BY last_name
-       ")
-
-       #if [ -z "$TRANSLATORS" ]; then
-       #       echo "[WARNING] No translators found, falling back to superusers"
-       #       TRANSLATORS=$(mysqlpipe "
-       #               SELECT username, first_name, last_name, email
-       #               FROM auth_user
-       #               WHERE is_active=1 AND is_superuser=1
-       #       ")
-       #fi
-
-       for TRANSLATOR in $TRANSLATORS;
-       do
-               USERNAME=$(echo $TRANSLATOR | awk -F "\t" '{ print $1 }')
-               FIRST_NAME=$(echo $TRANSLATOR | awk -F "\t" '{ print $2 }')
-               LAST_NAME=$(echo $TRANSLATOR | awk -F "\t" '{ print $3 }')
-               EMAIL=$(echo $TRANSLATOR | awk -F "\t" '{ print $4 }')
-
-               echo "[INFO]    - Notifying $USERNAME"
-
-               mail -a"From: TYPO3 Translation Server <no-reply@typo3.org>" \
-                       -s "TYPO3 Pootle: $PROJECT ($LANGUAGE)" \
-                       "$EMAIL" <<EOM
-Dear $FIRST_NAME $LAST_NAME ($USERNAME),
-
-There are currently $SUGGESTIONS suggestions pending for approval for project $PROJECT ($LANGUAGE),
-please review them on:
-
-http://translation.typo3.org/${LANGUAGE_CODE}/${PROJECT_CODE}/translate.html?matchnames=hassuggestion
-
-
-Thanks for contributing to open-source software,
-
-Pootle
-
-
-PS: This is a weekly automated message that you received since you are registered as a
-translator either for project "$PROJECT" or language "$LANGUAGE".
-
--- 
-TYPO3 translation server (Pootle)
-http://translation.typo3.org/
-EOM
-       done
-
-       # wait a bit before handling next project/language pair
-       sleep 10
-done
-
-IFS=$SAVEIFS
-
-onexit
diff --git a/bin/pootle-refresh-project b/bin/pootle-refresh-project
deleted file mode 100755 (executable)
index 31572e8..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-set -e
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/functions
-
-PROJECT=$1
-if [ ! -d $POOTLE_PO/$PROJECT ]; then
-       echo
-       msg "$PROJECT is not a valid projet"
-       echo
-       exit 1
-fi
-
-echo
-echo -n "1/3 Update translation projects "
-pootle-manage update_translation_projects --project=$PROJECT 2>/dev/null && echo "DONE" || exit 1
-
-echo
-echo -n "2/3 Update database from XLIFF file "
-pootle-manage update_stores --project=$PROJECT 2>/dev/null && echo DONE || exit 1
-
-echo
-echo -n "3/3 Refresh statistics "
-pootle-manage refresh_stats --project=$PROJECT 2>/dev/null && echo DONE || exit 1
diff --git a/bin/pootle-snapshot b/bin/pootle-snapshot
deleted file mode 100755 (executable)
index 7b5c885..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-SNAPSHOT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/archives/snapshot"
-
-DESTIONATION_DIRECTORY="$SNAPSHOT_DIRECTORY/$(date +%Y%m%d)"
-mkdir -p $DESTIONATION_DIRECTORY
-mysqldump -ac pootle | gzip > $DESTIONATION_DIRECTORY/pootle.sql.gz
-tar cfpz $DESTIONATION_DIRECTORY/po.tar.gz /var/www/vhosts/pootle.typo3.org/pootle/po
diff --git a/bin/pootle-upgrade-all-extensions b/bin/pootle-upgrade-all-extensions
deleted file mode 100755 (executable)
index 9ad8bf0..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-set -o errtrace
-set -o nounset
-
-#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
-trap onexit 1 2 3 15
-
-#--- onexit() -----------------------------------------------------
-#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
-function onexit() {
-       local exit_status=${1:-$?}
-       if [ $exit_status -gt 0 ]; then
-               echo Exiting $0 with $exit_status
-       fi
-       exit $exit_status
-}
-
-BASE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po"
-T3XUTILS=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/t3xutils.phar
-UPGRADE_EXTENSION=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/pootle-upgrade-extension
-
-echo "[INFO] Fetch and cache TER extension metadata"
-$T3XUTILS updateinfo >/dev/null
-
-cd $BASE_DIRECTORY
-PROJECTS=$(find . -maxdepth 1 -type d | egrep 'TYPO3\.TYPO3\.ext\.' | sort)
-
-for PROJECT in $PROJECTS;
-do
-       EXTENSION=$(echo $PROJECT | cut -b19-)
-
-       echo -n "[INFO] Looking for latest version of $EXTENSION on TER: "
-       LASTLINE=$($T3XUTILS info $EXTENSION 2>/dev/null | grep -v "Available versions:" | tail -n 1)
-       if [ -z "$LASTLINE" ]; then
-               echo "n/a"
-               echo "[ERROR] Extension $EXTENSION does not exist on TER"
-       else
-               LASTVERSION=$(echo $LASTLINE | awk '{ print $1 }' | egrep '^[0-9.]+$')
-               if [ -n "$LASTVERSION" ]; then
-                       echo $LASTVERSION
-                       LOCALVERSION=""
-                       if [ -f $BASE_DIRECTORY/$PROJECT/.ter-version ]; then
-                               LOCALVERSION=$(cat $BASE_DIRECTORY/$PROJECT/.ter-version)
-                       fi
-                       if [ -z "$LOCALVERSION" ] || [ "$LOCALVERSION" != "$LASTVERSION" ]; then
-                               echo "[INFO] Updating extension $EXTENSION to version $LASTVERSION"
-                               $UPGRADE_EXTENSION $EXTENSION $LASTVERSION
-                       fi
-               fi
-       fi
-done
-
-onexit
diff --git a/bin/pootle-upgrade-extension b/bin/pootle-upgrade-extension
deleted file mode 100755 (executable)
index b493d22..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/bin/bash
-
-set -o errtrace
-set -o nounset
-
-#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
-trap onexit 1 2 3 15
-
-#--- onexit() -----------------------------------------------------
-#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
-function onexit() {
-       local exit_status=${1:-$?}
-       if [ $exit_status -gt 0 ]; then
-               echo Exiting $0 with $exit_status
-       fi
-       exit $exit_status
-}
-
-T3XUTILS=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/t3xutils.phar
-POOTLE_MANAGE=/var/www/vhosts/pootle.typo3.org/home/scripts/bin/pootle-manage
-
-# --- check_available_languages() ---------------------------------
-# @param $1 string               Pootle Project Name
-function check_available_languages() {
-       local NEED_UPDATE=0
-       local PROJECT_NAME=$1
-        for LANGUAGE_KEY in $(ls /var/www/vhosts/pootle.typo3.org/home/templates); do
-               local LANGUAGE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME/$LANGUAGE_KEY"
-                if [ "$PROJECT_NAME" != "" ] && [ -d /var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME ] && [ ! -d $LANGUAGE_DIRECTORY ]; then
-                        mkdir -p $LANGUAGE_DIRECTORY
-                        echo "[NOTICE] Add project language \"$LANGUAGE_KEY\""
-                       NEED_UPDATE=1
-                fi
-        done
-       if [ $NEED_UPDATE == 1 ]; then
-               echo "[NOTICE] Update translation project"
-               $POOTLE_MANAGE update_translation_projects --project=$1 1>/dev/null 2>/dev/null
-       fi
-}
-
-SAVEIFS=$IFS
-
-XSL_LLXML2TEMPLATE="/var/www/vhosts/pootle.typo3.org/home/scripts/etc/xsl/llxml2template.xsl"
-TEMP_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/tmp"
-
-EXTENSION=$1
-VERSION=$2
-
-PROJECT_NAME="TYPO3.TYPO3.ext.$EXTENSION"
-PROJECT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME"
-#
-# Check if the project exist
-if [ ! -d $PROJECT_DIRECTORY ]; then
-       echo
-       echo "[ERROR] Project $PROJECT_NAME doesn't exist in Pootle, please create it before using this script"
-       echo "[ERROR] Please create directory: $PROJECT_DIRECTORY"
-       onexit 1
-fi
-
-#
-# Check if the templates directory exist
-TEMPLATE_DIRECTORY="$PROJECT_DIRECTORY/templates"
-if [ ! -d $TEMPLATE_DIRECTORY ]; then
-        echo
-        echo "[INFO] Templates directory for project $PROJECT_NAME doesn't exist in Pootle"
-       echo "[NOTICE] Create the templates directory"
-       mkdir -p $TEMPLATE_DIRECTORY
-fi
-
-cd $TEMP_DIRECTORY >/dev/null
-
-echo "[INFO] Downloading $EXTENSION $VERSION from TER"
-
-EXTENSION_T3X=$(echo "${EXTENSION}_${VERSION}.t3x" | tr '[:upper:]' '[:lower:]')
-
-#
-# Download t3x
-rm -f $EXTENSION_T3X
-wget -q http://typo3.org/fileadmin/ter/${EXTENSION_T3X:0:1}/${EXTENSION_T3X:1:1}/$EXTENSION_T3X
-
-#
-# Extract t3x
-#extract-t3x $EXTENSION_T3X $EXTENSION > /dev/null
-$T3XUTILS extract $EXTENSION_T3X $EXTENSION >/dev/null
-
-IFS=$(echo -en "\n\b")
-
-#
-# Create directory structure for templates
-for FILE in $(find $EXTENSION/ -name \*.xml); do
-       grep "T3locallang" "$FILE" 1> /dev/null
-       if [ $? == 0 ]; then
-               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
-               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
-       fi
-done
-for FILE in $(find $EXTENSION/ -name \*.xlf); do
-       # Count number of dots in filename to skip e.g., de.locallang.xlf
-       DOTS=$(echo -n $(basename $FILE) | sed 's/[^.]//g' | wc -c)
-       if [ $DOTS -eq 1 ]; then
-               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
-               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
-       fi
-done
-
-cd $TEMP_DIRECTORY
-for FILE in $(find TYPO3.TYPO3.ext.$EXTENSION -name \*.xml); do
-       grep "T3locallang" "$FILE" 1> /dev/null
-       if [ $? == 0 ]; then
-               XLF_FILE=$(echo $FILE | sed s/.xml$/.xlf/)
-               if [ ! -f $XLF_FILE ]; then
-                       echo "[INFO] Convert LLXML to XLIFF for file $FILE"
-                       if [ ! -f $XLF_FILE ]; then
-                               xsltproc --stringparam lang en \
-                                       --stringparam extension $EXTENSION \
-                                       --stringparam date "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" $XSL_LLXML2TEMPLATE $FILE | \
-                                       xmlstarlet ed --insert "/xliff/file/body/trans-unit" --type attr -n xml:space -v preserve > $XLF_FILE
-                       fi
-               fi
-       fi
-       rm -f $FILE
-done
-
-#
-# Deploy new templates files
-echo "[INFO] Deploy new templates to $TEMPLATE_DIRECTORY"
-cd $TEMPLATE_DIRECTORY/../../ && \
-       tar cfzp $TEMP_DIRECTORY/backup/$PROJECT_NAME-$(date +%Y%m%d).tar.gz $PROJECT_NAME && \
-       cd - && \
-       rm -Rf $TEMPLATE_DIRECTORY && \
-       mkdir -p $TEMPLATE_DIRECTORY && \
-       cp -a $TEMP_DIRECTORY/$PROJECT_NAME/* $TEMPLATE_DIRECTORY || \
-               onexit 5
-
-#
-# Check project available language
-check_available_languages $PROJECT_NAME
-
-#
-# Update project from templates
-echo "[INFO] Update from templates"
-$POOTLE_MANAGE update_from_templates --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
-
-echo "[INFO] Refresh statistics"
-$POOTLE_MANAGE refresh_stats --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
-
-echo "[NOTICE] Register version $VERSION for EXT:$EXTENSION"
-echo -n $VERSION > $PROJECT_DIRECTORY/.ter-version
-
-#
-# Cleanup
-cd $TEMP_DIRECTORY
-rm -f $EXTENSION_T3X
-if [ -d $EXTENSION ]; then
-       rm -rf $EXTENSION
-       rm -rf TYPO3.TYPO3.ext.$EXTENSION
-fi
-
-IFS=$SAVEIFS
-
-onexit
diff --git a/bin/pootle-upgrade-extension-git b/bin/pootle-upgrade-extension-git
deleted file mode 100755 (executable)
index 78e98a1..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/bin/bash
-
-set -o errtrace
-set -o nounset
-
-#  Trap non-normal exit signals: 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
-trap onexit 1 2 3 15
-
-#--- onexit() -----------------------------------------------------
-#  @param $1 integer  (optional) Exit status.  If not set, use `$?'
-function onexit() {
-       local exit_status=${1:-$?}
-       if [ $exit_status -gt 0 ]; then
-               echo Exiting $0 with $exit_status
-       fi
-       exit $exit_status
-}
-
-# --- check_available_languages() ---------------------------------
-# @param $1 string               Pootle Project Name
-function check_available_languages() {
-       local NEED_UPDATE=0
-       local PROJECT_NAME=$1
-        for LANGUAGE_KEY in $(ls /var/www/vhosts/pootle.typo3.org/home/templates); do
-               local LANGUAGE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME/$LANGUAGE_KEY"
-                if [ "$PROJECT_NAME" != "" ] && [ -d /var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME ] && [ ! -d $LANGUAGE_DIRECTORY ]; then
-                        mkdir -p $LANGUAGE_DIRECTORY
-                        echo "[NOTICE] Add project language \"$LANGUAGE_KEY\""
-                       NEED_UPDATE=1
-                fi
-        done
-       if [ $NEED_UPDATE == 1 ]; then
-               echo "[NOTICE] Update translation project"
-               pootle-manage update_translation_projects --project=$1 1>/dev/null 2>/dev/null
-       fi
-}
-
-SAVEIFS=$IFS
-
-XSL_LLXML2TEMPLATE="/var/www/vhosts/pootle.typo3.org/home/scripts/etc/xsl/llxml2template.xsl"
-TEMP_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/tmp"
-
-EXTENSION=$1
-GIT=$2
-
-PROJECT_NAME="TYPO3.TYPO3.ext.$EXTENSION"
-PROJECT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po/$PROJECT_NAME"
-#
-# Check if the project exist
-if [ ! -d $PROJECT_DIRECTORY ]; then
-       echo
-       echo "[ERROR] Project $PROJECT_NAME doesn't exist in Pootle, please create it before using this script"
-       echo "[ERROR] Please create directory: $PROJECT_DIRECTORY"
-       onexit 1
-fi
-
-#
-# Check if the templates directory exist
-TEMPLATE_DIRECTORY="$PROJECT_DIRECTORY/templates"
-if [ ! -d $TEMPLATE_DIRECTORY ]; then
-        echo
-        echo "[INFO] Templates directory for project $PROJECT_NAME doesn't exist in Pootle"
-       echo "[NOTICE] Create the templates directory"
-       mkdir -p $TEMPLATE_DIRECTORY
-fi
-
-cd $TEMP_DIRECTORY >/dev/null
-
-echo "[INFO] Cloning $EXTENSION from $GIT"
-
-EXTENSION_DIR=$(echo "${EXTENSION}" | tr '[:upper:]' '[:lower:]')
-
-#
-# Download t3x
-rm -rf $EXTENSION
-git clone $GIT $EXTENSION
-
-IFS=$(echo -en "\n\b")
-
-#
-# Create directory structure for templates
-for FILE in $(find $EXTENSION/ -name \*.xml); do
-       grep "T3locallang" "$FILE" 1> /dev/null
-       if [ $? == 0 ]; then
-               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
-               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
-       fi
-done
-for FILE in $(find $EXTENSION/ -name \*.xlf); do
-       # Count number of dots in filename to skip e.g., de.locallang.xlf
-       DOTS=$(echo -n $(basename $FILE) | sed 's/[^.]//g' | wc -c)
-       if [ $DOTS -eq 1 ]; then
-               mkdir -p $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$(dirname $FILE);
-               cp $FILE $TEMP_DIRECTORY/TYPO3.TYPO3.ext.$FILE;
-       fi
-done
-
-cd $TEMP_DIRECTORY
-for FILE in $(find TYPO3.TYPO3.ext.$EXTENSION -name \*.xml); do
-       grep "T3locallang" "$FILE" 1> /dev/null
-       if [ $? == 0 ]; then
-               XLF_FILE=$(echo $FILE | sed s/.xml$/.xlf/)
-               if [ ! -f $XLF_FILE ]; then
-                       echo "[INFO] Convert LLXML to XLIFF for file $FILE"
-                       if [ ! -f $XLF_FILE ]; then
-                               xsltproc --stringparam lang en \
-                                       --stringparam extension $EXTENSION \
-                                       --stringparam date "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" $XSL_LLXML2TEMPLATE $FILE | \
-                                       xmlstarlet ed --insert "/xliff/file/body/trans-unit" --type attr -n xml:space -v preserve > $XLF_FILE
-                       fi
-               fi
-       fi
-       rm -f $FILE
-done
-
-#
-# Deploy new templates files
-echo "[INFO] Deploy new templates to $TEMPLATE_DIRECTORY"
-cd $TEMPLATE_DIRECTORY/../../ && \
-       tar cfzp $TEMP_DIRECTORY/backup/$PROJECT_NAME-$(date +%Y%m%d).tar.gz $PROJECT_NAME && \
-       cd - && \
-       rm -Rf $TEMPLATE_DIRECTORY && \
-       mkdir -p $TEMPLATE_DIRECTORY && \
-       cp -a $TEMP_DIRECTORY/$PROJECT_NAME/* $TEMPLATE_DIRECTORY || \
-               onexit 5
-
-#
-# Check project available language
-check_available_languages $PROJECT_NAME
-
-#
-# Update project from templates
-echo "[INFO] Update from templates"
-pootle-manage update_from_templates --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
-
-echo "[INFO] Refresh statistics"
-pootle-manage refresh_stats --project=$PROJECT_NAME 1>/dev/null 2>/dev/null
-
-#
-# Cleanup
-cd $TEMP_DIRECTORY
-if [ -d $EXTENSION ]; then
-       rm -rf $EXTENSION
-       rm -rf TYPO3.TYPO3.ext.$EXTENSION
-fi
-
-IFS=$SAVEIFS
-
-onexit
diff --git a/bin/t3xutils.phar b/bin/t3xutils.phar
deleted file mode 100755 (executable)
index e6b1b30..0000000
Binary files a/bin/t3xutils.phar and /dev/null differ
diff --git a/bin/update-typo3-core-template b/bin/update-typo3-core-template
deleted file mode 100755 (executable)
index 97d93e2..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/bin/bash
-
-set -e
-
-GIT_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/git/Core"
-PO_DIRECTORY="/var/www/vhosts/pootle.typo3.org/pootle/po"
-TEMPLATE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/templates"
-
-# Usage: project_exist project.name
-function project_exist() {
-       echo -n "Check if project exist: "
-       if [ "$1" != "" ] && [ -d $PO_DIRECTORY/$1 ]; then
-               echo "OK"
-               if [ ! -d $PO_DIRECTORY/$1/templates ]; then
-                       mkdir -p $PO_DIRECTORY/$1/templates
-                       echo "Check if the templates exist: CREATED"
-                       return 1
-               fi
-       else
-               echo "FAILED"
-               return 1
-       fi
-}
-
-# Usage: check_available_languages project.name
-function check_available_languages() {
-       for LANGUAGE_KEY in $(ls /var/www/vhosts/pootle.typo3.org/home/templates); do
-               if [ "$1" != "" ] && [ ! -d $PO_DIRECTORY/$1/$LANGUAGE_KEY ]; then
-                       mkdir -p $PO_DIRECTORY/$1/$LANGUAGE_KEY
-                       echo "[NOTICE] Create project language \"$LANGUAGE_KEY\""
-               fi
-       done
-}
-
-# Usage: sanitize_template_file /path/to/file.xlf
-function sanitize_template_file() {
-       if [ "$1" != "" ] && [ -f "$1" ]; then
-               xmlstarlet ed -d "/xliff/file[@xml:space]/@xml:space" $1 | \
-                       xmlstarlet ed -d "/xliff/file/body/trans-unit/target" | \
-                       xmlstarlet ed -d "/xliff/file[@target-language]/@target-language" | \
-                       xmlstarlet ed -d "/xliff/file/body/trans-unit[@approved]/@approved" | \
-                       xmlstarlet ed -u "/xliff/file[@source-language]/@source-language" -v en
-       fi
-}
-
-# Usage: list_typo3_typo3_core_projects
-function list_typo3_typo3_core_projects() {
-       ls $PO_DIRECTORY | grep TYPO3.TYPO3.core
-}
-
-# Usage; check_typo3_typo3_core_projects_languages
-function check_typo3_typo3_core_projects_languages() {
-       echo
-       echo "Check available language ,,,"
-        for CORE_PROJECT in $(list_typo3_typo3_core_projects); do
-               check_available_languages $CORE_PROJECT
-        done
-}
-
-# Usage: update_typo3_typo3_core_projects
-function update_typo3_typo3_core_projects() {
-       echo
-       echo "Update TYPO3.TYPO3.core projects ..."
-       for CORE_PROJECT in $(list_typo3_typo3_core_projects); do
-               pootle-manage update_translation_projects --project=$CORE_PROJECT
-               pootle-manage update_from_templates --project=$CORE_PROJECT
-       done
-}
-
-function git_typo3_typo3_core_pull() {
-       echo
-       echo "TYPO3 Core GIT Pull from $1"
-       cd $GIT_DIRECTORY
-       git checkout master
-       git reset --hard origin/master
-       git fetch
-       git checkout $1
-       git pull
-}
-
-# We successively fetch from old to newer branches to get back files which
-# may have been moved around. BEWARE: labels should not get deleted (well,
-# possible if file is moved as well) and "templates" language MUST be
-# manually updated (in GUI) to discover new files before they are mirrored
-# to other locales
-#for BRANCH in 'TYPO3_4-5' 'TYPO3_6-2'; do
-for BRANCH in 'TYPO3_6-2'; do
-       # GIT pull
-       git_typo3_typo3_core_pull $BRANCH
-
-       # Check project language configuration
-       check_typo3_typo3_core_projects_languages
-
-       echo
-       echo "Update templates projects ..."
-       for FILE in $(find $GIT_DIRECTORY/ -name *.xlf | grep sysext); do
-               RELATIVE_FILE_PATH=$(echo $FILE | sed s#$GIT_DIRECTORY/## | cut -d/ -f4-)
-               PROJECT=$(echo TYPO3.TYPO3.core.$(echo $FILE | sed s#$GIT_DIRECTORY/## | cut -d/ -f3))
-               echo "$PROJECT/$RELATIVE_FILE_PATH"
-
-               # Check project configuration
-               project_exist $PROJECT || exit 0
-
-               # Update project templates
-               if [ $? = 0 ]; then
-                       # Check if directory exist
-                       RELATIVE_FILE_DIRECTORY=$(dirname $PO_DIRECTORY/$PROJECT/templates/$RELATIVE_FILE_PATH);
-                       if [ ! -d $RELATIVE_FILE_DIRECTORY ]; then
-                               echo "Create directory: $RELATIVE_FILE_DIRECTORY"
-                               mkdir -p $RELATIVE_FILE_DIRECTORY
-                       fi
-
-                       # Deploy file from GIT
-                       sanitize_template_file $FILE > \
-                               $PO_DIRECTORY/$PROJECT/templates/$RELATIVE_FILE_PATH
-               fi
-       done
-done
-
-# Update all core project
-update_typo3_typo3_core_projects
-
-echo "====== UPDATE FINISHED ======"
diff --git a/etc/functions b/etc/functions
deleted file mode 100644 (file)
index 6817ba6..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-
-. /var/www/vhosts/pootle.typo3.org/home/scripts/etc/pootle.conf
-
-#
-# Log
-
-# Usage: msg "message"
-function msg() {
-       local MSG="$@"
-       logger -s -t POOTLE "$MSG"
-}
-
-# Usage: log_notice "message"
-function log_notice() {
-        local MSG="$@"
-        logger -p local0.notice -t POOTLE "$MSG"
-}
-
-#
-# MySQL
-
-# Usage: mysqlpipe "sql-query"
-function mysqlpipe() {
-       echo $@ | mysql pootle | sed '1d'
-}
-
-#
-# XSLT
-
-# Usage: llxml2xliff extension-key language-key sourcexliff targetxliff
-function llxml2xliff() {
-       local EXTENSION=$1
-       local LANG=$2
-       local SOURCE=$3
-       local TARGET=$4
-
-       if [ "$EXTENSION" = "" ] || [ "$LANG" = "" ] || [ "$SOURCE" = "" ] || [ "$TARGET" = "" ]; then
-               echo
-               msg "Please provide source and target XLIFF. Unable to convert XLIFF to LLXML."
-               echo
-               exit 1
-       fi
-       
-       xsltproc --stringparam source $SOURCE \
-               --stringparam lang $LANG \
-               --stringparam extension $EXTENSION \
-               --stringparam date "$(date -u)" \
-               $XSL_LLXML2XLIFF_TARGET $TARGET
-}
-
-#
-# Pootle
-
-# Usage: list_all_typo3_project
-function list_all_typo3_project() {
-       ls $POOTLE_PO | grep ^TYPO3.TYPO3
-}
-
-# Usage: list_all_flow3_project
-function list_all_flow3_project() {
-        ls $POOTLE_PO | grep ^TYPO3.FLOW3
-}
-
-# Usage: check_available_languages project.name
-function check_available_languages() {
-        for LANGUAGE_KEY in $(ls /var/www/vhosts/pootle.typo3.org/home/templates); do
-                if [ "$1" != "" ] && [ ! -d $POOTLE_PO/$1/$LANGUAGE_KEY ]; then
-                        mkdir -p $POOTLE_PO/$1/$LANGUAGE_KEY
-                        echo "[NOTICE] Create project language \"$LANGUAGE_KEY\""
-                       pootle-manage update_translation_projects --project=$1 --language=$LANGUAGE_KEY
-                       pootle-manage update_from_templates --project=$1 --language=$LANGUAGE_KEY
-                       pootle-manage refresh_stats --project=$1 --language=$LANGUAGE_KEY
-                fi
-        done
-}
-
-# Usage: getProjectUpdatedSince 2011-07-14
-function getProjectUpdatedSince() {
-        local SINCE=$1
-        local PROJECT_ONLY=$2
-        if [ "$SINCE" = "" ]; then
-                echo "Empty date, unable to select updated project"
-                exit 1
-        fi
-
-       if [ "$PROJECT_ONLY" = "" ]; then
-               mysqlpipe "SELECT p.id, p.code, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp
-                       FROM pootle_app_project AS p
-                       LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
-                       LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
-                       LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
-                       WHERE ( u.state = 50 OR u.state = 200 ) AND u.mtime > '$SINCE'
-                       AND p.code != 'terminology' AND p.code != 'tutorial'
-                       GROUP BY p.id
-                       ORDER BY u.mtime DESC;"
-       else
-               mysqlpipe "SELECT p.id, p.code, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp
-                        FROM pootle_app_project AS p
-                        LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
-                        LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
-                        LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
-                        WHERE ( u.state = 50 OR u.state = 200 )
-                        AND p.code = '$PROJECT_ONLY'
-                        GROUP BY p.id
-                        ORDER BY u.mtime DESC;"
-       fi
-}
-
-# Usage: getLanguageProjectUpdatedSince project-id 2011-07-14
-function getLanguageProjectUpdatedSince() {
-        local PROJECT_ID=$1
-        if [ "$PROJECT_ID" = "" ]; then
-                echo "Empty project id, unable to select updated language project"
-                exit 1
-        fi
-        local SINCE=$2
-        if [ "$SINCE" = "" ]; then
-                echo "Empty date, unable to select updated language project"
-                exit 1
-        fi
-
-        mysqlpipe "SELECT tp.real_path, p.id, p.code, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp, l.code AS language
-                FROM pootle_app_project AS p
-                LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
-                LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
-                LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
-                LEFT JOIN pootle_app_language AS l ON l.id = tp.language_id
-                WHERE ( u.state = 50 OR u.state = 200 ) AND u.mtime > '$SINCE' AND p.id = $PROJECT_ID
-                GROUP BY tp.id
-                ORDER BY u.mtime DESC;"
-}
-
-# Usage: validProjectName project.name
-function validProjectName() {
-       local PROJECT_NAME=$1
-       if [ "$PROJECT_NAME" == "" ]; then
-               echo "Missing project name"
-               exit 1
-       fi
-
-       if [ -d $POOTLE_PO/$PROJECT_NAME ]; then
-               return 0
-       else
-               exit 1
-       fi
-}
diff --git a/etc/lang-compat.conf b/etc/lang-compat.conf
deleted file mode 100644 (file)
index ac5dfb9..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-ar:ar
-bs:ba
-bg:bg
-pt_BR:br
-ca:ca
-ch:ch
-cs:cz
-de:de
-da:dk
-eo:eo
-es:es
-et:et
-eu:eu
-fa:fa
-fi:fi
-fo:fo
-fr:fr
-gl:ga
-ka:ge
-kl:gl
-el:gr
-he:he
-hi:hi
-zh:hk
-hr:hr
-hu:hu
-is:is
-it:it
-ja:jp
-km:km
-ko:kr
-lt:lt
-lv:lv
-ms:my
-nl:nl
-no:no
-pl:pl
-pt:pt
-fr_CA:qc
-ro:ro
-ru:ru
-sv:se
-sl:si
-sk:sk
-sr:sr
-th:th
-tr:tr
-uk:ua
-vi:vn
diff --git a/etc/pootle.conf b/etc/pootle.conf
deleted file mode 100644 (file)
index 88f2b63..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-
-POOTLE_SCRIPT_HOME=/var/www/vhosts/pootle.typo3.org/home/scripts
-
-POOTLE_PID=$POOTLE_SCRIPT_HOME/tmp/fcgi-t3-pootle.pid
-POOTLE_FCGI_SOCK=/tmp/fcgi-t3-pootle.sock
-POOTLE_LOG=/var/log/pootle/pootle.log
-POOTLE_ERR=/var/log/pootle/pootle.err
-POOTLE_PO=/var/www/vhosts/pootle.typo3.org/pootle/po/
-
-CONF_LANG_COMPAT=$POOTLE_SCRIPT_HOME/etc/lang-compat.conf
-
-LOCAL_GIT_CLONE_DIRECTORY="/var/www/vhosts/pootle.typo3.org/home/git"
-
-XSL_LLXML2XLIFF_SOURCE=$POOTLE_SCRIPT_HOME/etc/xsl/xliff2llxml-source.xsl
-XSL_LLXML2XLIFF_TARGET=$POOTLE_SCRIPT_HOME/etc/xsl/xliff2llxml-target.xsl
-
-_LAST_BUILD_FILE="$POOTLE_SCRIPT_HOME/.build-language-pack-lastbuild"
-
-TER_L10N_PATH=/var/www/vhosts/pootle.typo3.org/l10n_ter/
diff --git a/etc/typo3-prefix.conf b/etc/typo3-prefix.conf
deleted file mode 100644 (file)
index 15b504e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-core:TYPO3.core
-ext:TYPO3.ext
diff --git a/etc/xsl/llxml2template.xsl b/etc/xsl/llxml2template.xsl
deleted file mode 100644 (file)
index dd27b43..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xsl:stylesheet
-       version="1.0"
-       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
-
-       <xsl:output method='xml'
-               version='1.0'
-               encoding='UTF-8'
-               indent='no' />
-
-       <xsl:template match="/T3locallang">
-               <xliff version="1.0">
-                       <file source-language="EN" datatype="plaintext" original="messages" date="{$date}" product-name="{$extension}">
-                               <header/>
-                               <body>
-                                       <xsl:apply-templates select="data[@type='array']/languageKey[@index='default']/label" />
-                               </body>
-                       </file>
-               </xliff>
-       </xsl:template>
-
-       <xsl:template match="label">
-               <xsl:variable name="index" select="@index"/>
-               <trans-unit id="{@index}">
-                       <source><xsl:value-of select="." /></source>
-               </trans-unit>
-       </xsl:template>
-
-</xsl:stylesheet>
diff --git a/etc/xsl/xliff2llxml-source.xsl b/etc/xsl/xliff2llxml-source.xsl
deleted file mode 100644 (file)
index 5955f67..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xsl:stylesheet 
-  version="1.0" 
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
-  
-  <xsl:output method='xml' 
-    version='1.0' 
-    encoding='UTF-8' 
-    indent='yes' />
-  
-  <xsl:template match="/xliff">
-    <T3locallang>
-      <data type="array">
-        <languageKey index="{$lang}" type="array">
-          <xsl:apply-templates select="file/body" />
-        </languageKey>
-      </data>
-    </T3locallang>
-  </xsl:template>
-  
-  <xsl:template match="trans-unit">
-    <xsl:variable name="index" select="@id"/>
-    <label index="{$index}"><xsl:value-of select="source" /></label>
-  </xsl:template>
-  
-</xsl:stylesheet>
diff --git a/etc/xsl/xliff2llxml-target.xsl b/etc/xsl/xliff2llxml-target.xsl
deleted file mode 100644 (file)
index f1ce7c8..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xsl:stylesheet 
-  version="1.0" 
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
-  
-  <xsl:output method='xml' 
-    version='1.0' 
-    encoding='UTF-8' 
-    indent='yes' />
-  
-  <xsl:template match="/xliff">
-    <T3locallangExt>
-      <data type="array">
-        <languageKey index="{$lang}" type="array">
-          <xsl:apply-templates select="file/body" />
-        </languageKey>
-      </data>
-    </T3locallangExt>
-  </xsl:template>
-  
-  <xsl:template match="trans-unit">
-    <xsl:variable name="index" select="@id"/>
-    <label index="{$index}"><xsl:value-of select="target" /></label>
-  </xsl:template>
-  
-</xsl:stylesheet>
diff --git a/geerlingguy.memcached/README.md b/geerlingguy.memcached/README.md
new file mode 100644 (file)
index 0000000..4352e8e
--- /dev/null
@@ -0,0 +1,49 @@
+# Ansible Role: Memcached
+
+[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-memcached.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-memcached)
+
+An Ansible Role that installs Memcached on RedHat/CentOS or Debian/Ubuntu Linux.
+
+## Requirements
+
+None.
+
+## Role Variables
+
+Available variables are listed below, along with default values (see `defaults/main.yml`):
+
+    memcached_user: memcache
+
+The user under which the Memcached daemon will run.
+
+    memcached_port: 11211
+    memcached_listen_ip: 127.0.0.1
+
+The port and IP address (127.0.0.1 for localhost) on which Memcached will listen for requests.
+
+    memcached_memory_limit: 64
+    memcached_connections: 1024
+
+Memcached limits. The maximum amount of RAM `memcached` will consume (64MB is the default), and the maximum number of simultaneous connections memcached will handle.
+
+    memcached_log_file: /var/log/memcached.log
+
+The location of the memcached log file.
+
+## Dependencies
+
+None.
+
+## Example Playbook
+
+    - hosts: cache
+      roles:
+        - { role: geerlingguy.memcached }
+
+## License
+
+MIT / BSD
+
+## Author Information
+
+This role was created in 2014 by [Jeff Geerling](http://jeffgeerling.com/), author of [Ansible for DevOps](http://ansiblefordevops.com/).
diff --git a/geerlingguy.memcached/defaults/main.yml b/geerlingguy.memcached/defaults/main.yml
new file mode 100644 (file)
index 0000000..f7ff622
--- /dev/null
@@ -0,0 +1,10 @@
+---
+memcached_user: memcache
+
+memcached_port: 11211
+memcached_listen_ip: 127.0.0.1
+
+memcached_memory_limit: 64
+memcached_connections: 1024
+
+memcached_log_file: /var/log/memcached.log
diff --git a/geerlingguy.memcached/handlers/main.yml b/geerlingguy.memcached/handlers/main.yml
new file mode 100644 (file)
index 0000000..9aaea02
--- /dev/null
@@ -0,0 +1,3 @@
+---
+- name: restart memcached
+  service: name=memcached state=restarted
diff --git a/geerlingguy.memcached/meta/main.yml b/geerlingguy.memcached/meta/main.yml
new file mode 100644 (file)
index 0000000..876bbbc
--- /dev/null
@@ -0,0 +1,24 @@
+---
+dependencies: []
+
+galaxy_info:
+  author: geerlingguy
+  description: Memcached for Linux
+  company: "Midwestern Mac, LLC"
+  license: "license (BSD, MIT)"
+  min_ansible_version: 1.4
+  platforms:
+  - name: EL
+    versions:
+    - 6
+    - 7
+  - name: Ubuntu
+    versions:
+    - precise
+    - trusty
+  - name: Debian
+    versions:
+    - all
+  categories:
+    - web
+    - database
diff --git a/geerlingguy.memcached/tasks/main.yml b/geerlingguy.memcached/tasks/main.yml
new file mode 100644 (file)
index 0000000..581b265
--- /dev/null
@@ -0,0 +1,18 @@
+---
+- include: setup-RedHat.yml
+  when: ansible_os_family == 'RedHat'
+
+- include: setup-Debian.yml
+  when: ansible_os_family == 'Debian'
+
+- name: Copy Memcached configuration.
+  template:
+    src: memcached.conf.j2
+    dest: /etc/memcached.conf
+    owner: root
+    group: root
+    mode: 0644
+  notify: restart memcached
+
+- name: Ensure Memcached is started and set to run on startup.
+  service: name=memcached state=started enabled=yes
diff --git a/geerlingguy.memcached/tasks/setup-Debian.yml b/geerlingguy.memcached/tasks/setup-Debian.yml
new file mode 100644 (file)
index 0000000..2a5b414
--- /dev/null
@@ -0,0 +1,6 @@
+---
+- name: Update apt cache.
+  apt: update_cache=yes cache_valid_time=86400
+
+- name: Install Memcached.
+  apt: name=memcached state=installed
diff --git a/geerlingguy.memcached/tasks/setup-RedHat.yml b/geerlingguy.memcached/tasks/setup-RedHat.yml
new file mode 100644 (file)
index 0000000..461cc35
--- /dev/null
@@ -0,0 +1,3 @@
+---
+- name: Install Memcached.
+  yum: name=memcached state=installed
diff --git a/geerlingguy.memcached/templates/memcached.conf.j2 b/geerlingguy.memcached/templates/memcached.conf.j2
new file mode 100644 (file)
index 0000000..cdc5b81
--- /dev/null
@@ -0,0 +1,26 @@
+# Run memcached as a daemon. This command is implied, and is not needed for the
+# daemon to run.
+-d
+
+# Log memcached's output to /var/log/memcached
+logfile {{ memcached_log_file }}
+
+# Start with a cap of 64 megs of memory. It's reasonable, and the daemon default
+# Note that the daemon will grow to this size, but does not start out holding this much
+# memory
+-m {{ memcached_memory_limit }}
+
+# Default connection port is 11211
+-p {{ memcached_port }}
+
+# Run the daemon as root. The start-memcached will default to running as root if no
+# -u command is present in this config file
+-u {{ memcached_user }}
+
+# Specify which IP address to listen on. The default is to listen on all IP addresses
+# This parameter is one of the only security measures that memcached has, so make sure
+# it's listening on a firewalled interface.
+-l {{ memcached_listen_ip }}
+
+# Limit the number of simultaneous incoming connections. The daemon default is 1024
+-c {{ memcached_connections }}
diff --git a/geerlingguy.memcached/tests/inventory b/geerlingguy.memcached/tests/inventory
new file mode 100644 (file)
index 0000000..2fbb50c
--- /dev/null
@@ -0,0 +1 @@
+localhost
diff --git a/geerlingguy.memcached/tests/test.yml b/geerlingguy.memcached/tests/test.yml
new file mode 100644 (file)
index 0000000..cc7aee2
--- /dev/null
@@ -0,0 +1,5 @@
+---
+- hosts: localhost
+  remote_user: root
+  roles:
+    - ansible-role-memcached
diff --git a/geerlingguy.mysql/.travis.yml b/geerlingguy.mysql/.travis.yml
new file mode 100644 (file)
index 0000000..f794fb4
--- /dev/null
@@ -0,0 +1,55 @@
+---
+language: python
+python: "2.7"
+
+env:
+  - SITE=test.yml
+
+before_install:
+  - sudo apt-get update -qq
+
+  # Remove MySQL. Completely and totally.
+  - sudo apt-get remove --purge 'mysql*'
+  - sudo apt-get autoremove
+  - sudo apt-get autoclean
+  - sudo rm -rf /var/lib/mysql
+  - sudo truncate -s 0 /var/log/mysql/error.log
+
+install:
+  # Install Ansible.
+  - pip install ansible
+
+  # Add ansible.cfg to pick up roles path.
+  - "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg"
+
+script:
+  # Check the role/playbook's syntax.
+  - "ansible-playbook -i tests/inventory tests/$SITE --syntax-check"
+
+  # Run the role/playbook with ansible-playbook.
+  - "ansible-playbook -i tests/inventory tests/$SITE --connection=local --sudo"
+
+  # Run the role/playbook again, checking to make sure it's idempotent.
+  - >
+    ansible-playbook -i tests/inventory tests/$SITE --connection=local --sudo
+    | grep -q 'changed=0.*failed=0'
+    && (echo 'Idempotence test: pass' && exit 0)
+    || (echo 'Idempotence test: fail' && exit 1)
+
+  # Some MySQL debugging (show all the logs).
+  - "sudo ls -lah /var/log"
+  - "sudo cat /var/log/mysql/error.log"
+
+  # Check to make sure we can connect to MySQL via Unix socket.
+  - >
+    mysql -u root -proot -e 'show databases;'
+    | grep -q 'performance_schema'
+    && (echo 'MySQL running normally' && exit 0)
+    || (echo 'MySQL not running' && exit 1)
+
+  # Check to make sure we can connect to MySQL via TCP.
+  - >
+    mysql -u root -proot -h 127.0.0.1 -e 'show databases;'
+    | grep -q 'performance_schema'
+    && (echo 'MySQL running normally' && exit 0)
+    || (echo 'MySQL not running' && exit 1)
diff --git a/geerlingguy.mysql/README.md b/geerlingguy.mysql/README.md
new file mode 100644 (file)
index 0000000..17b9f91
--- /dev/null
@@ -0,0 +1,143 @@
+# Ansible Role: MySQL
+
+[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-mysql.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-mysql)
+
+Installs and configures MySQL or MariaDB server on RHEL/CentOS or Debian/Ubuntu servers.
+
+## Requirements
+
+None.
+
+## Role Variables
+
+Available variables are listed below, along with default values (see `vars/main.yml`):
+
+    mysql_user_home: /root
+
+The home directory inside which Python MySQL settings will be stored, which Ansible will use when connecting to MySQL. This should be the home directory of the user which runs this Ansible role.
+
+    mysql_root_password: root
+
+The MySQL root user account password.
+
+    mysql_enabled_on_startup: yes
+
+Whether MySQL should be enabled on startup.
+
+    overwrite_global_mycnf: yes
+
+Whether the global my.cnf should be overwritten each time this role is run. Setting this to `no` tells Ansible to only create the `my.cnf` file if it doesn't exist. This should be left at its default value (`yes`) if you'd like to use this role's variables to configure MySQL.
+
+    mysql_databases: []
+
+The MySQL databases to create. A database has the values `name`, `encoding` (defaults to `utf8`), `collation` (defaults to `utf8_general_ci`) and `replicate` (defaults to `1`, only used if replication is configured). The formats of these are the same as in the `mysql_db` module.
+
+    mysql_users: []
+
+The MySQL users and their privileges. A user has the values `name`, `host` (defaults to `localhost`), `password` and `priv` (defaults to `*.*:USAGE`). The formats of these are the same as in the `mysql_user` module.
+
+    mysql_packages:
+      - mysql
+      - mysql-server
+      - MySQL-python
+
+(OS-specific, RedHat/CentOS defaults listed here) Packages to be installed. In some situations, you may need to add additional packages, like `mysql-devel`.
+
+    mysql_enablerepo: ""
+
+(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can be handy, as an example, if you want to install later versions of MySQL.
+
+    mysql_port: "3306"
+    mysql_bind_address: '0.0.0.0'
+    mysql_datadir: /var/lib/mysql
+
+Default MySQL connection configuration.
+
+    mysql_log: ""
+    mysql_log_error: /var/log/mysqld.log
+    mysql_syslog_tag: mysqld
+
+MySQL logging configuration. Setting `mysql_log` (the general query log) or `mysql_log_error` to `syslog` will make MySQL log to syslog using the `mysql_syslog_tag`.
+
+    mysql_slow_query_log_enabled: no
+    mysql_slow_query_log_file: /var/log/mysql-slow.log
+    mysql_slow_query_time: 2
+
+Slow query log settings. Note that the log file will be created by this role, but if you're running on a server with SELinux or AppArmor, you may need to add this path to the allowed paths for MySQL, or disable the mysql profile. For example, on Debian/Ubuntu, you can run `sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/usr.sbin.mysqld && sudo service apparmor restart`.
+
+    mysql_key_buffer_size: "256M"
+    mysql_max_allowed_packet: "64M"
+    mysql_table_open_cache: "256"
+    [...]
+
+The rest of the settings in `defaults/main.yml` control MySQL's memory usage. The default values are tuned for a server where MySQL can consume ~512 MB RAM, so you should consider adjusting them to suit your particular server better.
+
+    mysql_server_id: "1"
+    mysql_max_binlog_size: "100M"
+    mysql_expire_logs_days: "10"
+    mysql_replication_role: ''
+    mysql_replication_master: ''
+    mysql_replication_user: []
+
+Replication settings. Set `mysql_server_id` and `mysql_replication_role` by server (e.g. the master would be ID `1`, with the `mysql_replication_role` of `master`, and the slave would be ID `2`, with the `mysql_replication_role` of `slave`). The `mysql_replication_user` uses the same keys as `mysql_users`, and is created on master servers, and used to replicate on all the slaves.
+
+### MariaDB usage
+
+This role works with either MySQL or a compatible version of MariaDB. On RHEL/CentOS 7+, the mariadb database engine was substituted as the default MySQL replacement package, so you should override the `mysql_packages` variable with the below configuration to make sure MariaDB is installed correctly.
+
+#### RHEL/CentOS 7 MariaDB configuration
+
+Set the following variables (at a minimum):
+
+    mysql_packages:
+      - mariadb
+      - mariadb-server
+      - mariadb-libs
+      - MySQL-python
+      - perl-DBD-MySQL
+    mysql_daemon: mariadb
+    mysql_log_error: /var/log/mariadb/mariadb.log
+    mysql_syslog_tag: mariadb
+    mysql_pid_file: /var/run/mariadb/mariadb.pid
+
+#### Ubuntu 14.04 MariaDB configuration
+
+Set the following variables (at a minimum):
+
+    mysql_packages:
+      - mariadb-client
+      - mariadb-server
+      - python-mysqldb
+
+## Dependencies
+
+None.
+
+## Example Playbook
+
+    - hosts: db-servers
+      vars_files:
+        - vars/main.yml
+      roles:
+        - { role: geerlingguy.mysql }
+
+*Inside `vars/main.yml`*:
+
+    mysql_root_password: super-secure-password
+    mysql_databases:
+      - name: example_db
+        encoding: latin1
+        collation: latin1_general_ci
+    mysql_users:
+      - name: example_user
+        host: "%"
+        password: similarly-secure-password
+        priv: "example_db.*:ALL"
+
+## License
+
+MIT / BSD
+
+## Author Information
+
+This role was created in 2014 by [Jeff Geerling](http://jeffgeerling.com/), author of [Ansible for DevOps](http://ansiblefordevops.com/).
diff --git a/geerlingguy.mysql/defaults/main.yml b/geerlingguy.mysql/defaults/main.yml
new file mode 100644 (file)
index 0000000..c966bcb
--- /dev/null
@@ -0,0 +1,88 @@
+---
+mysql_user_home: /root
+mysql_root_username: root
+mysql_root_password: root
+
+mysql_enabled_on_startup: yes
+
+# update my.cnf. each time role is run? yes | no
+overwrite_global_mycnf: yes
+
+# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). Used only
+# for RedHat systems (and derivatives).
+mysql_enablerepo: ""
+
+# Define a custom list of packages to install; if none provided, the default
+# package list from vars/[OS-family].yml will be used.
+# mysql_packages:
+#   - mysql
+#   - mysql-server
+#   - MySQL-python
+
+# MySQL connection settings.
+mysql_port: "3306"
+mysql_bind_address: '0.0.0.0'
+mysql_datadir: /var/lib/mysql
+mysql_pid_file: /var/run/mysqld/mysqld.pid
+
+# Slow query log settings.
+mysql_slow_query_log_enabled: no
+mysql_slow_query_log_file: /var/log/mysql-slow.log
+mysql_slow_query_time: 2
+
+# Memory settings (default values optimized ~512MB RAM).
+mysql_key_buffer_size: "256M"
+mysql_max_allowed_packet: "64M"
+mysql_table_open_cache: "256"
+mysql_sort_buffer_size: "1M"
+mysql_read_buffer_size: "1M"
+mysql_read_rnd_buffer_size: "4M"
+mysql_myisam_sort_buffer_size: "64M"
+mysql_thread_cache_size: "8"
+mysql_query_cache_size: "16M"
+
+# Other settings.
+mysql_wait_timeout: 28800
+
+# Try number of CPU's * 2 for thread_concurrency.
+mysql_thread_concurrency: 2
+
+# InnoDB settings.
+# Set .._buffer_pool_size up to 80% of RAM but beware of setting too high.
+mysql_innodb_file_per_table: "1"
+mysql_innodb_buffer_pool_size: "256M"
+mysql_innodb_additional_mem_pool_size: "20M"
+# Set .._log_file_size to 25% of buffer pool size.
+mysql_innodb_log_file_size: "64M"
+mysql_innodb_log_buffer_size: "8M"
+mysql_innodb_flush_log_at_trx_commit: "1"
+mysql_innodb_lock_wait_timeout: 50
+
+# mysqldump settings.
+mysql_mysqldump_max_allowed_packet: "64M"
+
+# Logging settings.
+mysql_log: ""
+mysql_log_error: /var/log/mysql.err
+mysql_syslog_tag: mysql
+
+# Databases.
+mysql_databases: []
+# Full example:
+# mysql_databases:
+#   - { name: example, collation: utf8_general_ci, encoding: utf8, replicate: 1 }
+
+# Users
+mysql_users: []
+# Full Example:
+# mysql_users:
+#   - { name: example, host: 127.0.0.1, password: secret, priv: *.*:USAGE }
+
+# Replication settings (replication is only enabled if master/user have values).
+mysql_server_id: "1"
+mysql_max_binlog_size: "100M"
+mysql_expire_logs_days: "10"
+mysql_replication_role: ''
+mysql_replication_master: ''
+# Same keys as `mysql_users` above.
+mysql_replication_user: []
diff --git a/geerlingguy.mysql/handlers/main.yml b/geerlingguy.mysql/handlers/main.yml
new file mode 100644 (file)
index 0000000..429abe3
--- /dev/null
@@ -0,0 +1,3 @@
+---
+- name: restart mysql
+  service: "name={{ mysql_daemon }} state=restarted sleep=5"
diff --git a/geerlingguy.mysql/meta/main.yml b/geerlingguy.mysql/meta/main.yml
new file mode 100644 (file)
index 0000000..3690a17
--- /dev/null
@@ -0,0 +1,22 @@
+---
+dependencies: []
+
+galaxy_info:
+  author: geerlingguy
+  description: MySQL server for RHEL/CentOS and Debian/Ubuntu
+  company: "Midwestern Mac, LLC"
+  license: "license (BSD, MIT)"
+  min_ansible_version: 1.4
+  platforms:
+  - name: EL
+    versions:
+    - 6
+    - 7
+  - name: Ubuntu
+    versions:
+    - all
+  - name: Debian
+    versions:
+    - all
+  categories:
+    - database
diff --git a/geerlingguy.mysql/tasks/configure.yml b/geerlingguy.mysql/tasks/configure.yml
new file mode 100644 (file)
index 0000000..01206a5
--- /dev/null
@@ -0,0 +1,26 @@
+---
+- name: Copy my.cnf global MySQL configuration.
+  template:
+    src: my.cnf.j2
+    dest: "{{ mysql_config_file }}"
+    owner: root
+    group: root
+    mode: 0644
+    force: "{{ overwrite_global_mycnf }}"
+  notify: restart mysql
+
+- name: Create slow query log file (if configured).
+  shell: "touch {{ mysql_slow_query_log_file }} creates={{ mysql_slow_query_log_file }}"
+  when: mysql_slow_query_log_enabled
+
+- name: Set ownership on slow query log file (if configured).
+  file:
+    path: "{{ mysql_slow_query_log_file }}"
+    state: file
+    owner: mysql
+    group: mysql
+    mode: 0644
+  when: mysql_slow_query_log_enabled
+
+- name: Ensure MySQL is started and enabled on boot.
+  service: "name={{ mysql_daemon }} state=started enabled={{ mysql_enabled_on_startup }}"
diff --git a/geerlingguy.mysql/tasks/databases.yml b/geerlingguy.mysql/tasks/databases.yml
new file mode 100644 (file)
index 0000000..39ee42f
--- /dev/null
@@ -0,0 +1,8 @@
+---
+- name: Ensure MySQL databases are present.
+  mysql_db:
+    name: "{{ item.name }}"
+    collation: "{{ item.collation | default('utf8_general_ci') }}"
+    encoding: "{{ item.encoding | default('utf8') }}"
+    state: present
+  with_items: mysql_databases
diff --git a/geerlingguy.mysql/tasks/main.yml b/geerlingguy.mysql/tasks/main.yml
new file mode 100644 (file)
index 0000000..d8ad3a8
--- /dev/null
@@ -0,0 +1,28 @@
+---
+# Include variables and define needed variables.
+- name: Include OS-specific variables.
+  include_vars: "{{ ansible_os_family }}.yml"
+
+- name: Define mysql_packages.
+  set_fact:
+    mysql_packages: "{{ __mysql_packages | list }}"
+  when: mysql_packages is not defined
+
+- name: Define mysql_daemon.
+  set_fact:
+    mysql_daemon: "{{ __mysql_daemon }} "
+  when: mysql_daemon is not defined
+
+# Setup/install tasks.
+- include: setup-RedHat.yml
+  when: ansible_os_family == 'RedHat'
+
+- include: setup-Debian.yml
+  when: ansible_os_family == 'Debian'
+
+# Configure MySQL.
+- include: configure.yml
+- include: secure-installation.yml
+- include: databases.yml
+- include: users.yml
+- include: replication.yml
diff --git a/geerlingguy.mysql/tasks/replication.yml b/geerlingguy.mysql/tasks/replication.yml
new file mode 100644 (file)
index 0000000..ec56dfc
--- /dev/null
@@ -0,0 +1,51 @@
+---
+- name: Ensure replication user exists on master.
+  mysql_user:
+    name: "{{ mysql_replication_user.name }}"
+    host: "{{ mysql_replication_user.host | default('%') }}"
+    password: "{{ mysql_replication_user.password }}"
+    priv: "{{ mysql_replication_user.priv | default('*.*:REPLICATION SLAVE') }}"
+    state: present
+  when: >
+    (mysql_replication_role == 'master')
+    and mysql_replication_user
+    and (mysql_replication_master != '')
+
+- name: Check slave replication status.
+  mysql_replication: mode=getslave
+  ignore_errors: true
+  register: slave
+  when: >
+    mysql_replication_role == 'slave'
+    and (mysql_replication_master != '')
+
+- name: Check master replication status.
+  mysql_replication: mode=getmaster
+  delegate_to: "{{ mysql_replication_master }}"
+  register: master
+  when: >
+    slave|failed
+    and (mysql_replication_role == 'slave')
+    and (mysql_replication_master != '')
+
+- name: Configure replication on the slave.
+  mysql_replication:
+    mode: changemaster
+    master_host: "{{ mysql_replication_master }}"
+    master_user: "{{ mysql_replication_user.name }}"
+    master_password: "{{ mysql_replication_user.password }}"
+    master_log_file: "{{ master.File }}"
+    master_log_pos: "{{ master.Position }}"
+  ignore_errors: True
+  when: >
+    slave|failed
+    and (mysql_replication_role == 'slave')
+    and (mysql_replication_master != '')
+    and mysql_replication_user
+
+- name: Start replication.
+  mysql_replication: mode=startslave
+  when: >
+    slave|failed
+    and (mysql_replication_role == 'slave')
+    and (mysql_replication_master != '')
diff --git a/geerlingguy.mysql/tasks/secure-installation.yml b/geerlingguy.mysql/tasks/secure-installation.yml
new file mode 100644 (file)
index 0000000..f02af77
--- /dev/null
@@ -0,0 +1,37 @@
+---
+- name: Get list of hosts for the root user.
+  command: mysql -NBe 'SELECT Host FROM mysql.user WHERE User = "root" ORDER BY (Host="localhost") ASC'
+  register: mysql_root_hosts
+  changed_when: false
+
+# 'localhost' needs to be last for idempotency.
+- name: Update MySQL root password for localhost root account.
+  mysql_user:
+    name: "root"
+    host: "{{ item }}"
+    password: "{{ mysql_root_password }}"
+  with_items: mysql_root_hosts.stdout_lines
+
+# Has to be after the root password assignment, for idempotency.
+- name: Copy .my.cnf file with root password credentials.
+  template:
+    src: "user-my.cnf.j2"
+    dest: "{{ mysql_user_home }}/.my.cnf"
+    owner: root
+    group: root
+    mode: 0600
+
+- name: Get list of hosts for the anonymous user.
+  command: mysql -NBe 'SELECT Host FROM mysql.user WHERE User = ""'
+  register: mysql_anonymous_hosts
+  changed_when: false
+
+- name: Remove anonymous MySQL users.
+  mysql_user:
+     name: ""
+     host: "{{ item }}"
+     state: absent
+  with_items: mysql_anonymous_hosts.stdout_lines
+
+- name: Remove MySQL test database.
+  mysql_db: "name='test' state=absent"
\ No newline at end of file
diff --git a/geerlingguy.mysql/tasks/setup-Debian.yml b/geerlingguy.mysql/tasks/setup-Debian.yml
new file mode 100644 (file)
index 0000000..8b07af9
--- /dev/null
@@ -0,0 +1,22 @@
+---
+- name: Check if MySQL is already installed.
+  stat: path=/etc/init.d/mysql
+  register: mysql_installed
+
+- name: Update apt cache if MySQL is not yet installed.
+  apt: update_cache=yes
+  when: mysql_installed.stat.exists == false
+
+- name: Ensure MySQL packages are installed.
+  apt: "name={{ item }} state=installed"
+  with_items: mysql_packages
+
+# Because Ubuntu starts MySQL as part of the install process, we need to stop
+# mysql and remove the logfiles in case the user set a custom log file size.
+- name: Ensure MySQL is stopped after initial install.
+  service: name=mysql state=stopped
+  when: mysql_installed.stat.exists == false
+
+- name: Delete innodb log files created by apt package after initial install.
+  shell: "rm -f {{ mysql_datadir }}/ib_logfile[01]"
+  when: mysql_installed.stat.exists == false
diff --git a/geerlingguy.mysql/tasks/setup-RedHat.yml b/geerlingguy.mysql/tasks/setup-RedHat.yml
new file mode 100644 (file)
index 0000000..dc71e2f
--- /dev/null
@@ -0,0 +1,8 @@
+---
+- name: Update postfix to the latest version (if extra repositories enabled).
+  yum: "name=postfix state=latest enablerepo={{ mysql_enablerepo }}"
+  when: mysql_enablerepo != ""
+
+- name: Ensure MySQL packages are installed.
+  yum: "name={{ item }} state=installed enablerepo={{ mysql_enablerepo }}"
+  with_items: mysql_packages
diff --git a/geerlingguy.mysql/tasks/users.yml b/geerlingguy.mysql/tasks/users.yml
new file mode 100644 (file)
index 0000000..b44d649
--- /dev/null
@@ -0,0 +1,9 @@
+---
+- name: Ensure MySQL users are present.
+  mysql_user:
+    name: "{{ item.name }}"
+    host: "{{ item.host | default('localhost') }}"
+    password: "{{ item.password }}"
+    priv: "{{ item.priv | default('*.*:USAGE') }}"
+    state: present
+  with_items: mysql_users
diff --git a/geerlingguy.mysql/templates/my.cnf.j2 b/geerlingguy.mysql/templates/my.cnf.j2
new file mode 100644 (file)
index 0000000..12c1564
--- /dev/null
@@ -0,0 +1,97 @@
+[client]
+#password = your_password
+port = {{ mysql_port }}
+socket = {{ mysql_socket }}
+
+[mysqld]
+port = {{ mysql_port }}
+bind-address = {{ mysql_bind_address }}
+datadir = {{ mysql_datadir }}
+socket = {{ mysql_socket }}
+
+# Logging configuration.
+{% if mysql_log_error == 'syslog' or mysql_log == 'syslog' %}
+syslog
+syslog-tag = {{ mysql_syslog_tag }}
+{% else %}
+{% if mysql_log %}
+log = {{ mysql_log }}
+{% endif %}
+log-error = {{ mysql_log_error }}
+{% endif %}
+
+{% if mysql_slow_query_log_enabled %}
+# Slow query log configuration.
+log_slow_queries = 1
+slow_query_log = 1
+slow_query_log_file = {{ mysql_slow_query_log_file }}
+long_query_time = {{ mysql_slow_query_time }}
+{% endif %}
+
+{% if mysql_replication_master %}
+# Replication
+server-id = {{ mysql_server_id }}
+
+{% if mysql_replication_role == 'master' %}
+log_bin = mysql-bin
+log-bin-index = mysql-bin.index
+expire_logs_days = {{ mysql_expire_logs_days }}
+max_binlog_size = {{ mysql_max_binlog_size }}
+
+{% for db in mysql_databases %}
+{% if db.replicate|default(1) %}
+binlog_do_db = {{ db.name }}
+{% else %}
+binlog_ignore_db = {{ db.name }}
+{% endif %}
+{% endfor %}
+{% endif %}
+
+{% if mysql_replication_role == 'slave' %}
+read_only
+relay-log = relay-bin
+relay-log-index = relay-bin.index
+{% endif %}
+{% endif %}
+
+# Disabling symbolic-links is recommended to prevent assorted security risks
+symbolic-links = 0
+
+# User is ignored when systemd is used (fedora >= 15).
+user = mysql
+
+# http://dev.mysql.com/doc/refman/5.5/en/performance-schema.html
+;performance_schema
+
+# Memory settings.
+key_buffer_size = {{ mysql_key_buffer_size }}
+max_allowed_packet = {{ mysql_max_allowed_packet }}
+table_open_cache = {{ mysql_table_open_cache }}
+sort_buffer_size = {{ mysql_sort_buffer_size }}
+read_buffer_size = {{ mysql_read_buffer_size }}
+read_rnd_buffer_size = {{ mysql_read_rnd_buffer_size }}
+myisam_sort_buffer_size = {{ mysql_myisam_sort_buffer_size }}
+thread_cache_size = {{ mysql_thread_cache_size }}
+query_cache_size = {{ mysql_query_cache_size }}
+
+# Other settings.
+wait_timeout = {{ mysql_wait_timeout }}
+
+# Try number of CPU's * 2 for thread_concurrency.
+thread_concurrency = {{ mysql_thread_concurrency }}
+
+# InnoDB settings.
+innodb_file_per_table = {{ mysql_innodb_file_per_table }}
+innodb_buffer_pool_size = {{ mysql_innodb_buffer_pool_size }}
+innodb_additional_mem_pool_size = {{ mysql_innodb_additional_mem_pool_size }}
+innodb_log_file_size = {{ mysql_innodb_log_file_size }}
+innodb_log_buffer_size = {{ mysql_innodb_log_buffer_size }}
+innodb_flush_log_at_trx_commit = {{ mysql_innodb_flush_log_at_trx_commit }}
+innodb_lock_wait_timeout = {{ mysql_innodb_lock_wait_timeout }}
+
+[mysqldump]
+quick
+max_allowed_packet = {{ mysql_mysqldump_max_allowed_packet }}
+
+[mysqld_safe]
+pid-file = {{ mysql_pid_file }}
diff --git a/geerlingguy.mysql/templates/user-my.cnf.j2 b/geerlingguy.mysql/templates/user-my.cnf.j2
new file mode 100644 (file)
index 0000000..43de06a
--- /dev/null
@@ -0,0 +1,3 @@
+[client]
+user={{ mysql_root_username }}
+password={{ mysql_root_password }}
diff --git a/geerlingguy.mysql/tests/inventory b/geerlingguy.mysql/tests/inventory
new file mode 100644 (file)
index 0000000..2fbb50c
--- /dev/null
@@ -0,0 +1 @@
+localhost
diff --git a/geerlingguy.mysql/tests/test.yml b/geerlingguy.mysql/tests/test.yml
new file mode 100644 (file)
index 0000000..bfe6c6c
--- /dev/null
@@ -0,0 +1,5 @@
+---
+- hosts: localhost
+  remote_user: root
+  roles:
+    - ansible-role-mysql
diff --git a/geerlingguy.mysql/vars/Debian.yml b/geerlingguy.mysql/vars/Debian.yml
new file mode 100644 (file)
index 0000000..292d71a
--- /dev/null
@@ -0,0 +1,8 @@
+---
+__mysql_daemon: mysql
+__mysql_packages:
+  - mysql-common
+  - mysql-server
+  - python-mysqldb
+mysql_config_file: /etc/mysql/my.cnf
+mysql_socket: /var/run/mysqld/mysqld.sock
diff --git a/geerlingguy.mysql/vars/RedHat.yml b/geerlingguy.mysql/vars/RedHat.yml
new file mode 100644 (file)
index 0000000..088ca4f
--- /dev/null
@@ -0,0 +1,8 @@
+---
+__mysql_daemon: mysqld
+__mysql_packages:
+  - mysql
+  - mysql-server
+  - MySQL-python
+mysql_config_file: /etc/my.cnf
+mysql_socket: /var/lib/mysql/mysql.sock
diff --git a/install.yml b/install.yml
new file mode 100644 (file)
index 0000000..4ecf171
--- /dev/null
@@ -0,0 +1,10 @@
+---
+- hosts: pootle
+  vars_files:
+    - vars/main.yml
+  roles:
+    - geerlingguy.mysql
+    - geerlingguy.memcached
+    - pootle
+    - nginx
+    - typo3
diff --git a/nginx/files/h5bp/README.md b/nginx/files/h5bp/README.md
new file mode 100644 (file)
index 0000000..7975311
--- /dev/null
@@ -0,0 +1,9 @@
+Component-config files
+----------------------
+
+Each of these files is intended to be included in a server block. Not all of
+the files here are used - they are available to be included as required. The
+`basic.conf` file includes the rules which are recommended to always be
+defined.
+
+Files imported from https://github.com/h5bp/server-configs-nginx/tree/master/h5bp
diff --git a/nginx/files/h5bp/basic.conf b/nginx/files/h5bp/basic.conf
new file mode 100644 (file)
index 0000000..2b85ad4
--- /dev/null
@@ -0,0 +1,6 @@
+# Basic h5bp rules
+
+include h5bp/directive-only/x-ua-compatible.conf;
+include h5bp/location/expires.conf;
+include h5bp/location/cross-domain-fonts.conf;
+include h5bp/location/protect-system-files.conf;
diff --git a/nginx/files/h5bp/directive-only/cache-file-descriptors.conf b/nginx/files/h5bp/directive-only/cache-file-descriptors.conf
new file mode 100644 (file)
index 0000000..ed312c0
--- /dev/null
@@ -0,0 +1,19 @@
+# This tells Nginx to cache open file handles, "not found" errors, metadata about files and their permissions, etc.
+#
+# The upside of this is that Nginx can immediately begin sending data when a popular file is requested,
+# and will also know to immediately send a 404 if a file is missing on disk, and so on.
+#
+# However, it also means that the server won't react immediately to changes on disk, which may be undesirable.
+#
+# In the below configuration, inactive files are released from the cache after 20 seconds, whereas
+# active (recently requested) files are re-validated every 30 seconds.
+#
+# Descriptors will not be cached unless they are used at least 2 times within 20 seconds (the inactive time).
+#
+# A maximum of the 1000 most recently used file descriptors can be cached at any time.
+#
+# Production servers with stable file collections will definitely want to enable the cache.
+open_file_cache          max=1000 inactive=20s;
+open_file_cache_valid    30s;
+open_file_cache_min_uses 2;
+open_file_cache_errors   on;
diff --git a/nginx/files/h5bp/directive-only/cross-domain-insecure.conf b/nginx/files/h5bp/directive-only/cross-domain-insecure.conf
new file mode 100644 (file)
index 0000000..e9373ad
--- /dev/null
@@ -0,0 +1,14 @@
+# Cross domain AJAX requests
+
+# http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
+
+# **Security Warning**
+# Do not use this without understanding the consequences.
+# This will permit access from any other website.
+#
+add_header "Access-Control-Allow-Origin" "*";
+
+# Instead of using this file, consider using a specific rule such as:
+#
+# Allow access based on [sub]domain:
+#    add_header "Access-Control-Allow-Origin" "subdomain.example.com";
diff --git a/nginx/files/h5bp/directive-only/extra-security.conf b/nginx/files/h5bp/directive-only/extra-security.conf
new file mode 100644 (file)
index 0000000..dcc5fba
--- /dev/null
@@ -0,0 +1,17 @@
+# The X-Frame-Options header indicates whether a browser should be allowed
+# to render a page within a frame or iframe.
+add_header X-Frame-Options SAMEORIGIN;
+# MIME type sniffing security protection
+#      There are very few edge cases where you wouldn't want this enabled.
+add_header X-Content-Type-Options nosniff;
+# The X-XSS-Protection header is used by Internet Explorer version 8+
+# The header instructs IE to enable its inbuilt anti-cross-site scripting filter.
+add_header X-XSS-Protection "1; mode=block";
+# with Content Security Policy (CSP) enabled (and a browser that supports it (http://caniuse.com/#feat=contentsecuritypolicy),
+# you can tell the browser that it can only download content from the domains you explicitly allow
+# CSP can be quite difficult to configure, and cause real issues if you get it wrong
+# There is website that helps you generate a policy here http://cspisawesome.com/
+# add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.google-analytics.com;";
diff --git a/nginx/files/h5bp/directive-only/no-transform.conf b/nginx/files/h5bp/directive-only/no-transform.conf
new file mode 100644 (file)
index 0000000..eda5464
--- /dev/null
@@ -0,0 +1,11 @@
+# Prevent mobile network providers from modifying your site
+#
+# (!) If you are using `ngx_pagespeed`, please note that setting
+# the `Cache-Control: no-transform` response header will prevent
+# `PageSpeed` from rewriting `HTML` files, and, if
+# `pagespeed DisableRewriteOnNoTransform off` is not used, also
+# from rewriting other resources.
+#
+# https://developers.google.com/speed/pagespeed/module/configuration#notransform
+
+add_header "Cache-Control" "no-transform";
diff --git a/nginx/files/h5bp/directive-only/spdy.conf b/nginx/files/h5bp/directive-only/spdy.conf
new file mode 100644 (file)
index 0000000..f65912b
--- /dev/null
@@ -0,0 +1,11 @@
+# Nginx's spdy module is compiled by default from 1.6
+# SPDY only works on HTTPS connections
+
+# Inform browser of SPDY availability 
+add_header Alternate-Protocol  443:npn-spdy/3;
+
+# Adjust connection keepalive for SPDY clients:
+spdy_keepalive_timeout 300; # up from 180 secs default
+
+# enable SPDY header compression
+spdy_headers_comp 6;
diff --git a/nginx/files/h5bp/directive-only/ssl-stapling.conf b/nginx/files/h5bp/directive-only/ssl-stapling.conf
new file mode 100644 (file)
index 0000000..0c65fc9
--- /dev/null
@@ -0,0 +1,9 @@
+# OCSP stapling...
+ssl_stapling on;
+ssl_stapling_verify on;
+
+#trusted cert must be made up of your intermediate certificate followed by root certificate
+#ssl_trusted_certificate /path/to/ca.crt; 
+
+resolver 8.8.8.8 8.8.4.4 216.146.35.35 216.146.36.36 valid=60s;
+resolver_timeout 2s;
diff --git a/nginx/files/h5bp/directive-only/ssl.conf b/nginx/files/h5bp/directive-only/ssl.conf
new file mode 100644 (file)
index 0000000..5a58ec7
--- /dev/null
@@ -0,0 +1,44 @@
+# Protect against the BEAST and POODLE attacks by not using SSLv3 at all. If you need to support older browsers (IE6) you may need to add
+# SSLv3 to the list of protocols below.
+ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
+
+# Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla (Intermediate Set) - https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx
+ssl_ciphers                ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
+ssl_prefer_server_ciphers  on;
+
+# Optimize SSL by caching session parameters for 10 minutes. This cuts down on the number of expensive SSL handshakes.
+# The handshake is the most CPU-intensive operation, and by default it is re-negotiated on every new/parallel connection.
+# By enabling a cache (of type "shared between all Nginx workers"), we tell the client to re-use the already negotiated state.
+# Further optimization can be achieved by raising keepalive_timeout, but that shouldn't be done unless you serve primarily HTTPS.
+ssl_session_cache    shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
+ssl_session_timeout  24h;
+
+# SSL buffer size was added in 1.5.9
+#ssl_buffer_size      1400; # 1400 bytes to fit in one MTU
+
+# Session tickets appeared in version 1.5.9
+#
+# nginx does not auto-rotate session ticket keys: only a HUP / restart will do so and
+# when a restart is performed the previous key is lost, which resets all previous
+# sessions. The fix for this is to setup a manual rotation mechanism:
+# http://trac.nginx.org/nginx/changeset/1356a3b9692441e163b4e78be4e9f5a46c7479e9/nginx
+#
+# Note that you'll have to define and rotate the keys securely by yourself. In absence
+# of such infrastructure, consider turning off session tickets:
+#ssl_session_tickets off;
+
+# Use a higher keepalive timeout to reduce the need for repeated handshakes
+keepalive_timeout 300; # up from 75 secs default
+
+# HSTS (HTTP Strict Transport Security)
+# This header tells browsers to cache the certificate for a year and to connect exclusively via HTTPS.
+#add_header Strict-Transport-Security "max-age=31536000;";
+# This version tells browsers to treat all subdomains the same as this site and to load exclusively over HTTPS
+#add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
+
+# This default SSL certificate will be served whenever the client lacks support for SNI (Server Name Indication).
+# Make it a symlink to the most important certificate you have, so that users of IE 8 and below on WinXP can see your main site without SSL errors.
+#ssl_certificate      /etc/nginx/default_ssl.crt;
+#ssl_certificate_key  /etc/nginx/default_ssl.key;
+
+# Consider using OCSP Stapling as shown in ssl-stapling.conf
diff --git a/nginx/files/h5bp/directive-only/x-ua-compatible.conf b/nginx/files/h5bp/directive-only/x-ua-compatible.conf
new file mode 100644 (file)
index 0000000..a51bb31
--- /dev/null
@@ -0,0 +1,2 @@
+# Force the latest IE version
+add_header "X-UA-Compatible" "IE=Edge";
diff --git a/nginx/files/h5bp/location/cache-busting.conf b/nginx/files/h5bp/location/cache-busting.conf
new file mode 100644 (file)
index 0000000..72e7bc1
--- /dev/null
@@ -0,0 +1,10 @@
+# Built-in filename-based cache busting
+
+# https://github.com/h5bp/html5-boilerplate/blob/5370479476dceae7cc3ea105946536d6bc0ee468/.htaccess#L403
+# This will route all requests for /css/style.20120716.css to /css/style.css
+# Read also this: github.com/h5bp/html5-boilerplate/wiki/cachebusting
+# This is not included by default, because it'd be better if you use the build
+# script to manage the file names.
+location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif)$ {
+   try_files $uri $1.$2;
+}
diff --git a/nginx/files/h5bp/location/cross-domain-fonts.conf b/nginx/files/h5bp/location/cross-domain-fonts.conf
new file mode 100644 (file)
index 0000000..9e6df0c
--- /dev/null
@@ -0,0 +1,13 @@
+# Cross domain webfont access
+location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
+    include h5bp/directive-only/cross-domain-insecure.conf;
+
+    # Also, set cache rules for webfonts.
+    #
+    # See http://wiki.nginx.org/HttpCoreModule#location
+    # And https://github.com/h5bp/server-configs/issues/85
+    # And https://github.com/h5bp/server-configs/issues/86
+    expires 1M;
+    access_log off;
+    add_header Cache-Control "public";
+}
diff --git a/nginx/files/h5bp/location/expires.conf b/nginx/files/h5bp/location/expires.conf
new file mode 100644 (file)
index 0000000..cebd044
--- /dev/null
@@ -0,0 +1,44 @@
+# Expire rules for static content
+
+# No default expire rule. This config mirrors that of apache as outlined in the
+# html5-boilerplate .htaccess file. However, nginx applies rules by location,
+# the apache rules are defined by type. A consequence of this difference is that
+# if you use no file extension in the url and serve html, with apache you get an
+# expire time of 0s, with nginx you'd get an expire header of one month in the
+# future (if the default expire rule is 1 month). Therefore, do not use a
+# default expire rule with nginx unless your site is completely static
+
+# cache.appcache, your document html and data
+# BEWARE TYPO3: html has been removed here since Pootle is using this file extension for dynamic content
+location ~* \.(?:manifest|appcache|xml|json)$ {
+  expires -1;
+  access_log /var/log/nginx/static.log;
+}
+
+# Feed
+location ~* \.(?:rss|atom)$ {
+  expires 1h;
+  add_header Cache-Control "public";
+}
+
+# Media: images, icons, video, audio, HTC
+location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
+  expires 1M;
+  access_log off;
+  add_header Cache-Control "public";
+}
+
+# CSS and Javascript
+location ~* \.(?:css|js)$ {
+  expires 1y;
+  access_log off;
+  add_header Cache-Control "public";
+}
+
+# WebFonts
+# If you are NOT using cross-domain-fonts.conf, uncomment the following directive
+# location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
+#  expires 1M;
+#  access_log off;
+#  add_header Cache-Control "public";
+# }
diff --git a/nginx/files/h5bp/location/protect-system-files.conf b/nginx/files/h5bp/location/protect-system-files.conf
new file mode 100644 (file)
index 0000000..ece9410
--- /dev/null
@@ -0,0 +1,10 @@
+# Prevent clients from accessing hidden files (starting with a dot)
+# This is particularly important if you store .htpasswd files in the site hierarchy
+location ~* (?:^|/)\. {
+    deny all;
+}
+
+# Prevent clients from accessing to backup/config/source files
+location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
+    deny all;
+}
diff --git a/nginx/handlers/main.yml b/nginx/handlers/main.yml
new file mode 100644 (file)
index 0000000..9b7fce2
--- /dev/null
@@ -0,0 +1,6 @@
+---
+- name: Start Nginx
+  service: name=nginx state=started
+
+- name: Reload Nginx
+  service: name=nginx state=reloaded
diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml
new file mode 100644 (file)
index 0000000..8d37392
--- /dev/null
@@ -0,0 +1,35 @@
+---
+- name: Install Nginx
+  apt: pkg=nginx state=installed update_cache=true
+  register: nginxinstalled
+  notify:
+    - Start Nginx
+
+- name: Add H5BP config
+  when: nginxinstalled|success
+  copy: src=h5bp dest=/etc/nginx owner=root group=root
+
+- name: Disable default site
+  when: nginxinstalled|success
+  file: dest=/etc/nginx/sites-enabled/default state=absent
+
+- name: Add translation server site config
+  when: nginxinstalled|success
+  register: typo3config
+  template: src=virtualhost.conf.j2 dest=/etc/nginx/sites-available/{{ domain }}.conf owner=root group=root
+
+- name: Enable translation server site config
+  when: typo3config|success
+  file: src=/etc/nginx/sites-available/{{ domain }}.conf dest=/etc/nginx/sites-enabled/{{ domain }}.conf state=link
+
+- name: Create web root
+  when: nginxinstalled|success
+  file: dest=/var/www/{{ domain }}/public mode=755 state=directory owner=www-data group=www-data
+  notify:
+    - Reload Nginx
+
+- name: Web root permissions
+  when: nginxinstalled|success
+  file: dest=/var/www/{{ domain }} mode=755 state=directory owner=www-data group=www-data recurse=yes
+  notify:
+    - Reload Nginx
diff --git a/nginx/templates/virtualhost.conf.j2 b/nginx/templates/virtualhost.conf.j2
new file mode 100644 (file)
index 0000000..3e27357
--- /dev/null
@@ -0,0 +1,44 @@
+server {
+    listen 80 default_server;
+    server_name {{ domain }};
+
+    # Enable gzip compression
+    gzip on;
+
+    #root /var/www/{{ domain }}/public;
+    #index index.html;
+
+    access_log /var/log/nginx/{{ domain }}.log;
+    error_log /var/log/nginx/{{ domain }}-error.log error;
+
+    charset utf-8;
+
+    include h5bp/basic.conf;
+
+    location = /favicon.ico { log_not_found off; access_log off; }
+    location = /robots.txt  { log_not_found off; access_log off; }
+
+    location ^~ /assets/ {
+        root {{ pootle_virtualenv }}/lib/python2.7/site-packages/pootle/;
+    }
+
+    location / {
+        fastcgi_pass 127.0.0.1:8080;
+        fastcgi_param QUERY_STRING $query_string;
+        fastcgi_param REQUEST_METHOD $request_method;
+        fastcgi_param CONTENT_TYPE $content_type;
+        fastcgi_param CONTENT_LENGTH $content_length;
+        fastcgi_param REQUEST_URI $request_uri;
+        fastcgi_param DOCUMENT_URI $document_uri;
+        fastcgi_param DOCUMENT_ROOT $document_root;
+        fastcgi_param SERVER_PROTOCOL $server_protocol;
+        fastcgi_param REMOTE_ADDR $remote_addr;
+        fastcgi_param REMOTE_PORT $remote_port;
+        fastcgi_param SERVER_ADDR $server_addr;
+        fastcgi_param SERVER_PORT $server_port;
+        fastcgi_param SERVER_NAME $server_name;
+        fastcgi_pass_header Authorization;
+        fastcgi_intercept_errors off;
+        fastcgi_read_timeout 600;
+    }
+}
diff --git a/pootle/tasks/main.yml b/pootle/tasks/main.yml
new file mode 100644 (file)
index 0000000..ce21f3a
--- /dev/null
@@ -0,0 +1,97 @@
+---
+- name: Create directory for Pootle
+  file: path={{ pootle_virtualenv }} state=directory
+
+- name: Create configuration directory for Pootle
+  file: path=/etc/pootle state=directory
+
+- name: Install zip command
+  apt: pkg=zip state=installed update_cache=true
+
+- name: Install unzip command
+  apt: pkg=unzip state=installed
+
+- name: Install development package of python
+  apt: pkg=python-dev state=installed
+  register: pythondevinstalled
+
+- name: Install development package of libxml2
+  apt: pkg=libxml2-dev state=installed
+  register: libxml2devinstalled
+
+- name: Install development package of libxslt
+  apt: pkg=libxslt1-dev state=installed
+  register: libxslt1devinstalled
+
+- name: Install development package of zlib1g
+  apt: pkg=zlib1g-dev state=installed
+  register: zlib1gdevinstalled
+
+- name: Install development package of MySQL client
+  apt: pkg=libmysqlclient-dev state=installed
+  register: libmysqlclientdevinstalled
+
+- name: Install pip
+  apt: pkg=python-pip state=installed
+  register: pipinstalled
+
+- name: Set up the virtual environment
+  pip: name=virtualenv
+  when: pipinstalled|success
+  register: virtualenvinstalled
+
+- name: Install MySQL for Python
+  pip: name=MySQL-python virtualenv={{ pootle_virtualenv }}
+  when: virtualenvinstalled
+  when: libmysqlclientdevinstalled
+
+- name: Install Flup for Python
+  pip: name=flup virtualenv={{ pootle_virtualenv }}
+  when: virtualenvinstalled
+
+- name: Install Memcached support for Python
+  pip: name=python-memcached virtualenv={{ pootle_virtualenv }}
+  when: virtualenvinstalled
+
+- name: Install python-Levenshtein
+  pip: name=python-Levenshtein virtualenv={{ pootle_virtualenv }}
+  when: virtualenvinstalled
+
+- name: Install Xapian support for Python
+  apt: pkg=python-xapian state=installed
+
+- name: Install Xapian tools
+  apt: pkg=xapian-tools state=installed
+
+- name: Make Xapian available inside virtual environment
+  file: src=/usr/lib/python2.7/dist-packages/xapian dest={{ pootle_virtualenv }}/lib/python2.7/site-packages/xapian state=link
+
+- name: Install Pootle v{{ pootle_version }}
+  pip: name=Pootle version={{ pootle_version }} virtualenv={{ pootle_virtualenv }}
+  when: pythondevinstalled
+  when: libxml2devinstalled
+  when: libxslt1devinstalled
+  when: zlib1gdevinstalled
+  when: libmysqlclientdevinstalled
+  when: virtualenvinstalled
+
+- name: Create a pootle user
+  user: name=pootle comment="Pootle server daemon" system=no state=present home=/home/pootle createhome=yes shell=/bin/bash
+
+- name: Create log directory for Pootle
+  file: path=/var/log/pootle state=directory owner=pootle group=pootle
+
+- name: Create directory for PO files
+  file: path={{ pootle_po_directory }} state=directory owner=pootle
+
+- name: Set up init.d scripts for Pootle
+  template: src=pootle.j2 dest=/etc/init.d/pootle owner=root group=root mode=755
+
+- name: Configure Pootle
+  template: src=pootle.conf.j2 dest=/etc/pootle/pootle.conf owner=pootle group=root
+
+- name: Initialize Pootle
+  command: sudo -u pootle {{ pootle_virtualenv }}/bin/pootle --config=/etc/pootle/pootle.conf setup
+
+- name: Start Pootle
+  service: name=pootle enabled=yes state=started
diff --git a/pootle/templates/pootle.conf.j2 b/pootle/templates/pootle.conf.j2
new file mode 100755 (executable)
index 0000000..26e4273
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+# 10-base.conf
+TITLE = "{{ title }}"
+DESCRIPTION = _("""<div dir="ltr" lang="en">
+<h2>Official {{ title }}</h2>
+<p>Official Forge Project, please report any issue on <a href="http://forge.typo3.org/projects/team-translation">Translation Team Forge Project</a>. You can found useful documentation on the forge wiki. Feel free to contribute.</p>
+</div>
+""")
+
+# 20-backends.conf
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': '{{ mysql_databases[0].name }}',
+        'USER': '{{ mysql_users[0].name }}',
+        'PASSWORD': '{{ mysql_users[0].password }}',
+        'HOST': '{{ mysql_users[0].host }}',
+        'PORT': '',
+    }
+}
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+        'LOCATION': '127.0.0.1:11211',
+    }
+}
+
+# 30-site.conf
+ADMINS = (
+       ("{{ admin_name }}", "{{ admin_email }}"),
+)
+CAN_REGISTER = False
+CAN_CONTACT = False
+DEFAULT_FROM_EMAIL = "{{ from_email }}"
+
+# 60-translation.conf
+PODIRECTORY = "{{ pootle_po_directory }}"
diff --git a/pootle/templates/pootle.j2 b/pootle/templates/pootle.j2
new file mode 100755 (executable)
index 0000000..efb1df2
--- /dev/null
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+### BEGIN INIT INFO
+# Provides:          pootle
+# Required-Start:    $local_fs $remote_fs $network $syslog $named
+# Required-Stop:     $local_fs $remote_fs $network $syslog $named
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: starts and stops the Pootle server
+# Description:       starts and stops the Pootle server
+### END INIT INFO
+
+DAEMON_DIR={{ pootle_virtualenv }}/bin
+DAEMON_BIN=pootle
+DAEMON_OPTS="--config=/etc/pootle/pootle.conf runfcgi host=127.0.0.1 port=8080 daemonize=false"
+DAEMON_USER=pootle
+
+# The process ID of the script when it runs is stored here
+PIDFILE=/var/run/$DAEMON_BIN.pid
+
+test -x $DAEMON_DIR/$DAEMON_BIN || exit 0
+
+. /lib/lsb/init-functions
+
+do_start () {
+       log_daemon_msg "Starting system $DAEMON_BIN daemon"
+       start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --exec $DAEMON_DIR/$DAEMON_BIN -- $DAEMON_OPTS
+       log_end_msg $?
+}
+
+do_stop () {
+       log_daemon_msg "Stopping system $DAEMON_BIN daemon"
+       start-stop-daemon --stop --pidfile $PIDFILE --retry 5
+       log_end_msg $?
+}
+
+case "$1" in
+       start|stop)
+               do_${1}
+               ;;
+
+       restart|reload|force-reload)
+               do_stop
+               do_start
+               ;;
+
+       force-stop)
+               do_stop
+               killall -q $DAEMON_BIN || true
+               sleep 2
+               killall -q -9 $DAEMON_BIN || true
+               ;;
+
+       status)
+               status_of_proc "$DAEMON_BIN" "$DAEMON" && exit 0 || exit $?
+               ;;
+
+       *)
+               log_success_msg "Usage: /etc/init.d/$DAEMON_BIN {start|stop|force-stop|restart|reload|force-reload|status}"
+               exit 1
+
+esac
+exit 0
diff --git a/typo3/files/bash_profile.txt b/typo3/files/bash_profile.txt
new file mode 100644 (file)
index 0000000..b9120b1
--- /dev/null
@@ -0,0 +1,10 @@
+PATH="/home/pootle/scripts/bin:$PATH"
+export PATH
+
+echo
+echo "Welcome TYPO3 Pootle Manager"
+echo "============================"
+echo 
+echo "Administration command:"
+find ~/scripts/bin -maxdepth 1 -type f -perm +111 -exec basename {} \; | awk '{ print "\t"$1 }'
+echo
\ No newline at end of file
diff --git a/typo3/files/scripts/bin/migration/migrate-typo3-xliff b/typo3/files/scripts/bin/migration/migrate-typo3-xliff
new file mode 100755 (executable)
index 0000000..d1e2323
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+
+. ~/scripts/etc/pootle.conf
+
+pushd ${POOTLE_PO} >/dev/null
+
+PROJECTS=$(find . -maxdepth 1 -name TYPO3.TYPO3.core.\* -type d | cut -b3- | sort)
+
+for PROJECT in ${PROJECTS}; do
+       pushd ${PROJECT} >/dev/null
+
+       echo "[INFO]    Migrating ${PROJECT}"
+       pootle-manage sync_stores --overwrite --project=${PROJECT}
+
+       LANGUAGES=$(find . -maxdepth 1 -type d | cut -b3-)
+       for LANGUAGE in ${LANGUAGES}; do
+               pushd ${LANGUAGE} >/dev/null
+               rm -rf .converted
+               mkdir .converted
+
+               FILES=$(find . -name \*.xlf)
+               for FILE in ${FILES}; do
+                       T3ID=$(xmlstarlet sel -t -m "//xliff/file" -v "@t3:id" ${FILE} 2>/dev/null)
+                       if [ -z "${T3ID}" ]; then
+                               # Legacy file: keep it as-is
+                               continue
+                       fi
+                       TARGET_NAME=.converted/locallang.${T3ID}.xlf
+                       if [ -f ${TARGET_NAME} ]; then
+                               echo "[ERROR]   OOOPS! Duplicate T3ID ${T3ID} with $FILE" >&2
+                               exit 1
+                       fi
+                       mv $FILE ${TARGET_NAME}
+               done
+
+               mv .converted/*.xlf . >/dev/null 2>&1
+               rmdir .converted
+
+               # Remove empty directories
+               find . -type d | sort -r | xargs rmdir >/dev/null 2>&1
+                                       
+               popd >/dev/null
+       done
+
+       echo "[INFO]    Updating Pootle stores for ${PROJECT}"
+       pootle-manage update_stores --project=${PROJECT}
+
+       popd >/dev/null
+done
+
+popd >/dev/null
diff --git a/typo3/files/scripts/bin/pootle-manage b/typo3/files/scripts/bin/pootle-manage
new file mode 100755 (executable)
index 0000000..c28ff9e
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+set -e
+
+. /home/pootle/scripts/etc/pootle.conf
+
+if [ $# -lt 1 ]; then
+       echo "Usage: $0 <command>" >&2
+       echo >&2
+       echo "Just try this:" >&2
+       echo "    $0 help" >&2
+       echo >&2
+       exit 1
+fi
+
+${POOTLE_BIN} --config=${POOTLE_CONF} $@
diff --git a/typo3/files/scripts/bin/update-typo3-core-template b/typo3/files/scripts/bin/update-typo3-core-template
new file mode 100755 (executable)
index 0000000..f7b674a
--- /dev/null
@@ -0,0 +1,253 @@
+#!/usr/bin/env bash
+
+. ~/scripts/etc/pootle.conf
+. ~/scripts/etc/functions
+
+# Clone of the TYPO3 CMS sources
+SOURCES=${LOCAL_GIT_CLONE_DIRECTORY}/TYPO3.CMS
+
+# Usage; check_typo3_typo3_core_projects_languages
+function check_typo3_typo3_core_projects_languages() {
+       echo
+       echo "[INFO]    Check available languages"
+       for CORE_PROJECT in $(list_typo3_typo3_core_projects); do
+               check_available_languages $CORE_PROJECT
+       done
+}
+
+# Allow to abort whole script on Ctrl+C
+trap "exit" INT
+
+# Check project language configuration
+check_typo3_typo3_core_projects_languages
+
+if [ ! -d ${SOURCES}/.git ]; then
+       echo "[INIT]    Cloning TYPO3 CMS sources into ${SOURCES}"
+       rm -rf ${SOURCES}
+       mkdir -p ${SOURCES}
+       pushd ${SOURCES} >/dev/null
+       git clone ${TYPO3_GIT} . >/dev/null 2>&1
+       popd >/dev/null
+fi
+
+# Update TYPO3 sources
+echo "[INFO]    Fetching latest changes from TYPO3 CMS sources"
+pushd ${SOURCES} >/dev/null
+git checkout master >/dev/null 2>&1
+git reset --hard origin/master >/dev/null 2>&1
+git fetch >/dev/null 2>&1
+popd >/dev/null
+
+BRANCHES_INDEXES=( ${!TYPO3_BRANCHES[@]} )
+IFS=$'\n' VERSIONS=$(echo -e "${BRANCHES_INDEXES[@]/%/\\n}" | sed -e 's/^ *//' -e '/^$/d' | sort)
+PREVIOUS_GLOBAL_MAPPING=""
+for VERSION in ${VERSIONS}; do
+       # Switch to corresponding TYPO3 branch
+       echo "[INFO]    ------------------------------------------------------"
+       echo "[INFO]    Switching to ${VERSION}"
+       echo "[INFO]    ------------------------------------------------------"
+       pushd ${SOURCES} >/dev/null
+       git checkout ${TYPO3_BRANCHES[$VERSION]} >/dev/null 2>&1
+       git pull >/dev/null 2>&1
+       popd >/dev/null
+
+       GLOBAL_MAPPING=${POOTLE_PO}/.typo3/${VERSION}.filemapping
+
+       mkdir -p $(dirname ${GLOBAL_MAPPING})
+       rm -f ${GLOBAL_MAPPING}
+       touch ${GLOBAL_MAPPING}
+
+       pushd ${SOURCES}/typo3/sysext/ >/dev/null
+
+       SYSTEM_EXTENSIONS=$(find . -maxdepth 1 -type d | cut -b3- | sort)
+       for EXTENSION in ${SYSTEM_EXTENSIONS}; do
+               PROJECT="TYPO3.TYPO3.core.${EXTENSION}"
+
+               if [ $(find ${EXTENSION} -name \*.xlf | wc -l) -eq 0 ]; then
+                       continue
+               fi
+
+               echo "[INFO]    Updating XLIFF for EXT:${EXTENSION}"
+
+               # Check project configuration
+               project_exist ${PROJECT} || exit 1
+
+               pushd ${EXTENSION} >/dev/null
+               EXTENSION_TARGET=${POOTLE_PO}/${PROJECT}
+               MAPPING=${EXTENSION_TARGET}/.typo3/${VERSION}.filemapping
+
+               mkdir -p $(dirname ${MAPPING})
+               rm -f ${MAPPING}
+               touch ${MAPPING}
+
+               FILES=$(find . -name \*.xlf | cut -b3-);
+               for FILE in ${FILES}; do
+                       T3ID=$(xmlstarlet sel -t -m "//xliff/file" -v "@t3:id" ${FILE} 2>/dev/null)
+                       if [ -z "${T3ID}" ]; then
+                               continue
+                       fi
+
+                       TARGET_NAME=${EXTENSION_TARGET}/templates/locallang.${T3ID}.xlf
+                       echo "locallang.${T3ID}.xlf ${PROJECT}:${FILE}" >> ${GLOBAL_MAPPING}
+                       echo "locallang.${T3ID}.xlf ${FILE}" >> ${MAPPING}
+
+                       KEYS=${EXTENSION_TARGET}/.typo3/${VERSION}.${T3ID}.keys
+                       xmlstarlet sel -t -m "//trans-unit" -v "@id" -n ${FILE} | sort > ${KEYS}
+
+                       if [ -f "${TARGET_NAME}" ]; then
+                               DIRTY=0
+
+                               # Extract existing keys
+                               xmlstarlet sel -t -m "//trans-unit" -v "@id" -n ${TARGET_NAME} | sort > /tmp/existing.keys
+
+                               diff -q ${KEYS} /tmp/existing.keys >/dev/null
+                               if [ $? -eq 1 ]; then
+                                       # START: Preparing new XLIFF
+                                       cat ${TARGET_NAME} | grep -v "</xliff>" | grep -v "</file>" | grep -v "</body>" > ${TARGET_NAME}.tmp
+
+                                       NEW_KEYS=$(diff /tmp/existing.keys ${KEYS} | grep '^> ' | cut -b3-)
+                                       for NEW_KEY in ${NEW_KEYS}; do
+                                               echo -en "\t\t\t" >> ${TARGET_NAME}.tmp
+                                               xmlstarlet sel -t -c "//trans-unit[@id='${NEW_KEY}']" ${FILE} | sed -e 's/ xmlns:t3="[^"]*"//g' >> ${TARGET_NAME}.tmp
+                                       done
+
+                                       echo -e "\t\t</body>" >> ${TARGET_NAME}.tmp
+                                       echo -e "\t</file>" >> ${TARGET_NAME}.tmp
+                                       echo '</xliff>' >> ${TARGET_NAME}.tmp
+
+                                       mv ${TARGET_NAME}.tmp ${TARGET_NAME}
+                                       # END: Preparing new XLIFF
+
+                                       REMOVED_KEYS=$(diff /tmp/existing.keys ${KEYS} | grep '^< ' | cut -b3-)
+                                       for REMOVED_KEY in ${REMOVED_KEYS}; do
+                                               # Look for existing deprecation note
+                                               NOTE=$(xmlstarlet sel -t -m "//trans-unit[@id='${REMOVED_KEY}']" -v "note[@from='developer']" ${TARGET_NAME})
+                                               if [ -z "${NOTE}" ]; then
+                                                       # The label is not yet marked as "deprecated", do it now!
+                                                       xmlstarlet ed \
+                                                               -s "//trans-unit[@id='${REMOVED_KEY}']" \
+                                                               -t elem -n note -v "This label is deprecated (not used anymore) since ${VERSION}" \
+                                                               -i "//trans-unit[@id='${REMOVED_KEY}']/note" -t attr -n from -v developer ${TARGET_NAME} > ${TARGET_NAME}.tmp
+                                                       mv ${TARGET_NAME}.tmp ${TARGET_NAME}
+                                               fi
+                                       done
+
+                                       DIRTY=1
+                               fi
+
+                               # Remove temporary file
+                               rm -f /tmp/existing.keys
+
+                               # Loop over all keys in file and update source element if needed (this is tolerated with some restrictions)
+                               for KEY in $(cat ${KEYS}); do
+                                       CURRENT_VALUE=$(xmlstarlet sel -t -c "//trans-unit[@id='${KEY}']" ${TARGET_NAME} | sed -e 's/ xmlns:t3="[^"]*"//g')
+                                       NEW_VALUE=$(xmlstarlet sel -t -c "//trans-unit[@id='${KEY}']" ${FILE} | sed -e 's/ xmlns:t3="[^"]*"//g')
+                                       if [ "${CURRENT_VALUE}" != "${NEW_VALUE}" ]; then
+                                               # No double quotes here around ${CURRENT_VALUE} since we don't want to keep the internal line breaks!
+                                               # Using quotemeta make it safe for use in a regular expression
+                                               ELEMENT=$(echo -n ${CURRENT_VALUE} | perl -pe 's|^(<trans-unit .*?>).*$|\1|' | perl -e 'print quotemeta(<STDIN>)')
+                                               # New lines should be escaped in replacement string
+                                               # Beware of special characters changing string to UPPER CASE and breaking the generated XLIFF:
+                                               # see: http://perldoc.perl.org/perlre.html#Escape-sequences
+                                               REPLACEMENT=$(echo -n "${NEW_VALUE}" | sed 's/\\/\\\\/g' | sed 's/|/\\|/g' | perl -pe 'BEGIN{undef $/;} s|\n|\\n|smg')
+
+                                               perl -pe "BEGIN{undef $/;} s|${ELEMENT}.*?</trans-unit>|${REPLACEMENT}|smg" ${TARGET_NAME} > ${TARGET_NAME}.tmp
+                                               if [ $? -ne 0 ]; then
+                                                       # THIS SHOULD NEVER HAPPEN BUT WHO KNOWS?
+                                                       echo "Real trouble happened with file ${TARGET_NAME} and key '${KEY}'" >&2
+                                                       exit 1
+                                               fi
+
+                                               # Check the correctness of the generated XLIFF
+                                               xmlstarlet -q val ${TARGET_NAME}.tmp
+                                               if [ $? -ne 0 ]; then
+                                                       echo "This is really bad! ${TARGET_NAME} is about to get broken!" >&2
+                                                       echo "Key: ${KEY}" >&2
+                                                       exit 2
+                                               fi
+
+                                               NUMBER_OF_KEYS_OLD=$(xmlstarlet sel -t -m "//trans-unit" -v "@id" -n ${TARGET_NAME} | wc -l)
+                                               NUMBER_OF_KEYS_NEW=$(xmlstarlet sel -t -m "//trans-unit" -v "@id" -n ${TARGET_NAME}.tmp | wc -l)
+                                               if [ ${NUMBER_OF_KEYS_OLD} -ne ${NUMBER_OF_KEYS_NEW} ]; then
+                                                       echo "This is really bad! ${TARGET_NAME}.tmp has now another amount of keys than ${TARGET_NAME}" >&2
+                                                       echo "Key: ${KEY}" >&2
+                                                       exit 3
+                                               fi
+
+                                               # Everything's fine: replace original file
+                                               mv ${TARGET_NAME}.tmp ${TARGET_NAME}
+
+                                               DIRTY=1
+                                       fi
+                               done
+
+                               if [ $DIRTY -eq 1 ]; then
+                                       # Reset the date of last modification
+                                       xmlstarlet ed -u "xliff/file/@date" -v "$(date '+%Y-%m-%dT%H:%M:%SZ')" ${TARGET_NAME} > ${TARGET_NAME}.tmp
+                                       mv ${TARGET_NAME}.tmp ${TARGET_NAME}
+
+                                       # Reformat XLF with proper indent
+                                       xmlstarlet fo -t ${TARGET_NAME} > ${TARGET_NAME}.tmp
+                                       mv ${TARGET_NAME}.tmp ${TARGET_NAME}
+                               fi
+                       else
+                               # File did not exist
+                               echo "[INFO]    New file detected: ${FILE}"
+
+                               # Take the file as-this for the templates
+                               # since templates' labels will possibly override labels in copied translations hereafter
+                               sanitize_template_file ${FILE} > ${TARGET_NAME}
+
+                               if [ -n "${PREVIOUS_GLOBAL_MAPPING}" ]; then
+                                       echo "[INFO]    Searching for previous translations"
+                                       ORIGINAL_FILE=$(grep $(basename ${TARGET_NAME}) ${PREVIOUS_GLOBAL_MAPPING} | cut -d ' ' -f2)
+                                       if [ -n "${ORIGINAL_FILE}" ]; then
+                                               ORIGINAL_PROJECT=$(echo ${ORIGINAL_FILE} | cut -d: -f1)
+                                               ORIGINAL_FILE=$(basename ${TARGET_NAME})
+                                               echo "[INFO]    Original file found in project ${ORIGINAL_PROJECT}"
+
+                                               for LANGUAGE_KEY in $(cat ~/templates/languages.txt); do
+                                                       TRANSLATED_FILE=${POOTLE_PO}/${ORIGINAL_PROJECT}/${LANGUAGE_KEY}/${ORIGINAL_FILE}
+                                                       echo -n "[INFO]    - Looking for language ${LANGUAGE_KEY} ... "
+                                                       if [ -f ${TRANSLATED_FILE} ]; then
+                                                               echo "found"
+                                                               TRANSLATED_TARGET=${EXTENSION_TARGET}/${LANGUAGE_KEY}/${ORIGINAL_FILE}
+                                                               cp ${TRANSLATED_FILE} ${TRANSLATED_TARGET}
+                                                       else
+                                                               echo "not found"
+                                                       fi
+                                               done
+                                       fi
+                               fi
+                       fi
+               done
+
+               popd >/dev/null
+       done
+
+       popd >/dev/null
+
+       PREVIOUS_GLOBAL_MAPPING=${GLOBAL_MAPPING}
+done
+
+pushd ${POOTLE_PO} >/dev/null
+
+PROJECTS=$(find . -maxdepth 1 -name TYPO3.TYPO3.core.\* -type d | cut -b3- | sort)
+
+for PROJECT in ${PROJECTS}; do
+       echo "[INFO]    Refreshing Pootle for project ${PROJECT}"
+
+       # Find new files automatically
+       pootle-manage update_stores --project=${PROJECT} --language=templates
+
+       # Add new languages if needed
+       pootle-manage update_translation_projects --project=${PROJECT}
+
+       # Update translations with labels from templates (source language)
+       pootle-manage update_against_templates --project=${PROJECT}
+       pootle-manage refresh_stats --project=${PROJECT}
+done
+
+popd >/dev/null
+
+echo "[INFO]    ====== UPDATE FINISHED ======"
diff --git a/typo3/files/scripts/etc/functions b/typo3/files/scripts/etc/functions
new file mode 100644 (file)
index 0000000..d402bab
--- /dev/null
@@ -0,0 +1,174 @@
+
+. ~/scripts/etc/pootle.conf
+
+#
+# Log
+
+# Usage: msg "message"
+function msg() {
+       local MSG="$@"
+       logger -s -t POOTLE "$MSG"
+}
+
+# Usage: log_notice "message"
+function log_notice() {
+       local MSG="$@"
+       logger -p local0.notice -t POOTLE "$MSG"
+}
+
+#
+# MySQL
+
+# Usage: mysqlpipe "sql-query"
+function mysqlpipe() {
+       echo $@ | mysql pootle | sed '1d'
+}
+
+#
+# XSLT
+
+# Usage: llxml2xliff extension-key language-key sourcexliff targetxliff
+function llxml2xliff() {
+       local EXTENSION=$1
+       local LANG=$2
+       local SOURCE=$3
+       local TARGET=$4
+
+       if [ "$EXTENSION" = "" ] || [ "$LANG" = "" ] || [ "$SOURCE" = "" ] || [ "$TARGET" = "" ]; then
+               echo
+               msg "Please provide source and target XLIFF. Unable to convert XLIFF to LLXML."
+               echo
+               exit 1
+       fi
+       
+       xsltproc --stringparam source $SOURCE \
+               --stringparam lang $LANG \
+               --stringparam extension $EXTENSION \
+               --stringparam date "$(date -u)" \
+               $XSL_LLXML2XLIFF_TARGET $TARGET
+}
+
+#
+# Pootle
+
+# Usage: list_all_typo3_project
+function list_all_typo3_project() {
+       ls ${POOTLE_PO} | grep ^TYPO3.TYPO3
+}
+
+# Usage: list_typo3_typo3_core_projects
+function list_typo3_typo3_core_projects() {
+       ls ${POOTLE_PO} | grep ^TYPO3.TYPO3.core
+}
+
+# Usage: project_exist project.name
+function project_exist() {
+       echo -n "[INFO]    Check if project \"$1\" exists: "
+       if [ "$1" != "" ] && [ -d ${POOTLE_PO}/$1 ]; then
+               echo "OK"
+               if [ ! -d ${POOTLE_PO}/$1/templates ]; then
+                       mkdir -p ${POOTLE_PO}/$1/templates
+                       echo "[INFO]    Check if the templates exist: CREATED"
+                       return 1
+               fi
+       else
+               echo "FAILED"
+               return 1
+       fi
+}
+
+# Usage: check_available_languages project.name
+function check_available_languages() {
+       for LANGUAGE_KEY in $(cat ~/templates/languages.txt); do
+               if [ "$1" != "" ] && [ ! -d ${POOTLE_PO}/$1/$LANGUAGE_KEY ]; then
+                       mkdir -p $POOTLE_PO/$1/$LANGUAGE_KEY
+                       echo "[NOTICE]  Create project language \"$LANGUAGE_KEY\" for \"$1\""
+                       pootle-manage update_translation_projects --project=$1 --language=$LANGUAGE_KEY
+                       pootle-manage update_against_templates --project=$1 --language=$LANGUAGE_KEY
+                       pootle-manage refresh_stats --project=$1 --language=$LANGUAGE_KEY
+               fi
+       done
+}
+
+# Usage: getProjectUpdatedSince 2011-07-14
+function getProjectUpdatedSince() {
+       local SINCE=$1
+       local PROJECT_ONLY=$2
+
+       if [ "$SINCE" = "" ]; then
+               echo "[ERROR]   Empty date, unable to select updated project" >&2
+               exit 1
+       fi
+
+       if [ "$PROJECT_ONLY" = "" ]; then
+               mysqlpipe "SELECT p.id, p.code, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp
+                       FROM pootle_app_project AS p
+                       LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
+                       LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
+                       LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
+                       WHERE ( u.state = 50 OR u.state = 200 ) AND u.mtime > '$SINCE'
+                       AND p.code != 'terminology' AND p.code != 'tutorial'
+                       GROUP BY p.id
+                       ORDER BY u.mtime DESC;"
+       else
+               mysqlpipe "SELECT p.id, p.code, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp
+                       FROM pootle_app_project AS p
+                       LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
+                       LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
+                       LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
+                       WHERE ( u.state = 50 OR u.state = 200 )
+                       AND p.code = '$PROJECT_ONLY'
+                       GROUP BY p.id
+                       ORDER BY u.mtime DESC;"
+       fi
+}
+
+# Usage: getLanguageProjectUpdatedSince project-id 2011-07-14
+function getLanguageProjectUpdatedSince() {
+       local PROJECT_ID=$1
+       if [ "$PROJECT_ID" = "" ]; then
+               echo "[ERROR]   Empty project id, unable to select updated language project" >&2
+               exit 1
+       fi
+       local SINCE=$2
+       if [ "$SINCE" = "" ]; then
+               echo "[ERROR]   Empty date, unable to select updated language project" >&2
+               exit 1
+       fi
+
+       mysqlpipe "SELECT tp.real_path, p.id, p.code, u.mtime, UNIX_TIMESTAMP(u.mtime) AS tstamp, l.code AS language
+               FROM pootle_app_project AS p
+               LEFT JOIN pootle_app_translationproject as tp ON p.id = tp.project_id
+               LEFT JOIN pootle_store_store AS s ON tp.id = s.translation_project_id
+               LEFT JOIN pootle_store_unit AS u ON s.id = u.store_id
+               LEFT JOIN pootle_app_language AS l ON l.id = tp.language_id
+               WHERE ( u.state = 50 OR u.state = 200 ) AND u.mtime > '$SINCE' AND p.id = $PROJECT_ID
+               GROUP BY tp.id
+               ORDER BY u.mtime DESC;"
+}
+
+# Usage: validProjectName project.name
+function validProjectName() {
+       local PROJECT_NAME=$1
+       if [ "$PROJECT_NAME" == "" ]; then
+               echo "[ERROR]   Missing project name" >&2
+               exit 1
+       fi
+
+       if [ -d $POOTLE_PO/$PROJECT_NAME ]; then
+               return 0
+       else
+               exit 1
+       fi
+}
+
+# Usage: sanitize_template_file /path/to/file.xlf
+function sanitize_template_file() {
+       if [ "$1" != "" ] && [ -f "$1" ]; then
+               xmlstarlet ed -d "/xliff/file[@xml:space]/@xml:space" $1 | \
+                       xmlstarlet ed -d "/xliff/file/body/trans-unit/target" | \
+                       xmlstarlet ed -d "/xliff/file[@target-language]/@target-language" | \
+                       xmlstarlet ed -d "/xliff/file/body/trans-unit[@approved]/@approved" | \
+                       xmlstarlet ed -u "/xliff/file[@source-language]/@source-language" -v en
+       fi
+}
diff --git a/typo3/files/scripts/etc/lang-compat.conf b/typo3/files/scripts/etc/lang-compat.conf
new file mode 100644 (file)
index 0000000..ac5dfb9
--- /dev/null
@@ -0,0 +1,49 @@
+ar:ar
+bs:ba
+bg:bg
+pt_BR:br
+ca:ca
+ch:ch
+cs:cz
+de:de
+da:dk
+eo:eo
+es:es
+et:et
+eu:eu
+fa:fa
+fi:fi
+fo:fo
+fr:fr
+gl:ga
+ka:ge
+kl:gl
+el:gr
+he:he
+hi:hi
+zh:hk
+hr:hr
+hu:hu
+is:is
+it:it
+ja:jp
+km:km
+ko:kr
+lt:lt
+lv:lv
+ms:my
+nl:nl
+no:no
+pl:pl
+pt:pt
+fr_CA:qc
+ro:ro
+ru:ru
+sv:se
+sl:si
+sk:sk
+sr:sr
+th:th
+tr:tr
+uk:ua
+vi:vn
diff --git a/typo3/files/scripts/etc/xsl/llxml2template.xsl b/typo3/files/scripts/etc/xsl/llxml2template.xsl
new file mode 100644 (file)
index 0000000..dd27b43
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet
+       version="1.0"
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+
+       <xsl:output method='xml'
+               version='1.0'
+               encoding='UTF-8'
+               indent='no' />
+
+       <xsl:template match="/T3locallang">
+               <xliff version="1.0">
+                       <file source-language="EN" datatype="plaintext" original="messages" date="{$date}" product-name="{$extension}">
+                               <header/>
+                               <body>
+                                       <xsl:apply-templates select="data[@type='array']/languageKey[@index='default']/label" />
+                               </body>
+                       </file>
+               </xliff>
+       </xsl:template>
+
+       <xsl:template match="label">
+               <xsl:variable name="index" select="@index"/>
+               <trans-unit id="{@index}">
+                       <source><xsl:value-of select="." /></source>
+               </trans-unit>
+       </xsl:template>
+
+</xsl:stylesheet>
diff --git a/typo3/files/scripts/etc/xsl/xliff2llxml-source.xsl b/typo3/files/scripts/etc/xsl/xliff2llxml-source.xsl
new file mode 100644 (file)
index 0000000..5955f67
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet 
+  version="1.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+  
+  <xsl:output method='xml' 
+    version='1.0' 
+    encoding='UTF-8' 
+    indent='yes' />
+  
+  <xsl:template match="/xliff">
+    <T3locallang>
+      <data type="array">
+        <languageKey index="{$lang}" type="array">
+          <xsl:apply-templates select="file/body" />
+        </languageKey>
+      </data>
+    </T3locallang>
+  </xsl:template>
+  
+  <xsl:template match="trans-unit">
+    <xsl:variable name="index" select="@id"/>
+    <label index="{$index}"><xsl:value-of select="source" /></label>
+  </xsl:template>
+  
+</xsl:stylesheet>
diff --git a/typo3/files/scripts/etc/xsl/xliff2llxml-target.xsl b/typo3/files/scripts/etc/xsl/xliff2llxml-target.xsl
new file mode 100644 (file)
index 0000000..f1ce7c8
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet 
+  version="1.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+  
+  <xsl:output method='xml' 
+    version='1.0' 
+    encoding='UTF-8' 
+    indent='yes' />
+  
+  <xsl:template match="/xliff">
+    <T3locallangExt>
+      <data type="array">
+        <languageKey index="{$lang}" type="array">
+          <xsl:apply-templates select="file/body" />
+        </languageKey>
+      </data>
+    </T3locallangExt>
+  </xsl:template>
+  
+  <xsl:template match="trans-unit">
+    <xsl:variable name="index" select="@id"/>
+    <label index="{$index}"><xsl:value-of select="target" /></label>
+  </xsl:template>
+  
+</xsl:stylesheet>
diff --git a/typo3/files/templates/languages.txt b/typo3/files/templates/languages.txt
new file mode 100644 (file)
index 0000000..f82784f
--- /dev/null
@@ -0,0 +1,52 @@
+af
+ar
+bg
+bs
+ca
+ch
+cs
+da
+de
+el
+eo
+es
+et
+eu
+fa
+fi
+fo
+fr
+fr_CA
+gl
+he
+hi
+hr
+hu
+id
+is
+it
+ja
+ka
+kl
+km
+ko
+lt
+lv
+ms
+nl
+no
+pl
+pt
+pt_BR
+qc
+ro
+ru
+sk
+sl
+sr
+sv
+th
+tr
+uk
+vi
+zh
\ No newline at end of file
diff --git a/typo3/tasks/main.yml b/typo3/tasks/main.yml
new file mode 100644 (file)
index 0000000..52f3318
--- /dev/null
@@ -0,0 +1,24 @@
+---
+- name: Install git
+  apt: pkg=git state=installed update_cache=true
+
+- name: Install xmlstarlet
+  apt: pkg=xmlstarlet state=installed
+
+- name: Install xsltproc
+  apt: pkg=xsltproc state=installed
+
+- name: Install Pootle user profile
+  copy: src=bash_profile.txt dest=/home/pootle/.bash_profile owner=pootle group=pootle
+
+- name: Install TYPO3 management scripts
+  copy: src=scripts dest=/home/pootle owner=pootle group=pootle mode=750
+
+- name: Install Pootle templates
+  copy: src=templates dest=/home/pootle owner=pootle group=pootle
+
+- name: Register Pootle server configuration
+  template: src=scripts/etc/pootle.conf.j2 dest=/home/pootle/scripts/etc/pootle.conf owner=pootle group=pootle
+
+- name: Create directory for Git clones ({{ pootle_git_directory }})
+  file: path={{ pootle_git_directory }} state=directory owner=pootle group=pootle
\ No newline at end of file
diff --git a/typo3/templates/scripts/etc/pootle.conf.j2 b/typo3/templates/scripts/etc/pootle.conf.j2
new file mode 100644 (file)
index 0000000..1255b86
--- /dev/null
@@ -0,0 +1,32 @@
+POOTLE_BIN={{ pootle_virtualenv }}/bin/pootle
+POOTLE_CONF=/etc/pootle/pootle.conf
+POOTLE_SCRIPT_HOME=/home/pootle/scripts
+
+#POOTLE_PID=$POOTLE_SCRIPT_HOME/tmp/fcgi-t3-pootle.pid
+#POOTLE_FCGI_SOCK=/tmp/fcgi-t3-pootle.sock
+POOTLE_LOG=/var/log/pootle/pootle.log
+POOTLE_ERR=/var/log/pootle/pootle.err
+POOTLE_PO={{ pootle_po_directory }}
+
+CONF_LANG_COMPAT=${POOTLE_SCRIPT_HOME}/etc/lang-compat.conf
+
+LOCAL_GIT_CLONE_DIRECTORY="{{ pootle_git_directory }}"
+
+XSL_LLXML2XLIFF_SOURCE=${POOTLE_SCRIPT_HOME}/etc/xsl/xliff2llxml-source.xsl
+XSL_LLXML2XLIFF_TARGET=${POOTLE_SCRIPT_HOME}/etc/xsl/xliff2llxml-target.xsl
+
+_LAST_BUILD_FILE="${POOTLE_SCRIPT_HOME}/.build-language-pack-lastbuild"
+
+TER_L10N_PATH=/var/www/{{ domain }}/l10n_ter
+
+# Requires bash >= v4.x
+# These are the supported Git branches. Once an older branch
+# is no more supported, it should simply be removed from the
+# list since the corresponding labels will not evolve anymore;
+# they will however be kept available for translation
+declare -A TYPO3_BRANCHES=(
+       [TYPO3v6]=TYPO3_6-2
+       [TYPO3v7]=master
+)
+
+TYPO3_GIT=git://git.typo3.org/Packages/TYPO3.CMS.git
\ No newline at end of file
diff --git a/vars/main.yml b/vars/main.yml
new file mode 100644 (file)
index 0000000..ab2e435
--- /dev/null
@@ -0,0 +1,23 @@
+---
+title: "TYPO3 Translation Server"
+admin_name: "Xavier Perseguers"
+admin_email: "xavier@typo3.org"
+
+domain: "pootle.typo3.loc"
+from_email: "no-reply@typo3.loc"
+
+pootle_virtualenv: "/opt/local/pootle"
+pootle_po_directory: "/srv/pootle/po"
+pootle_git_directory: "/srv/pootle/git-clones"
+pootle_version: 2.5.1.3
+
+mysql_root_password: "super-secure-password"
+mysql_databases:
+  - name: pootle_db
+    encoding: utf8
+    collation: utf8_general_ci
+mysql_users:
+  - name: pootle
+    host: "localhost"
+    password: "{{ lookup('password', '/tmp/password.mysql.pootle chars=ascii_letters,digits,hexdigits,punctuation') }}"
+    priv: "pootle_db.*:ALL"