Advertisement
kolesnikoff

diff2po.sh

Feb 17th, 2016
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 5.80 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. display_help() {
  4.   cat <<EOF
  5. Script transforms diff to PO file.
  6. Usage: diff2po [-db|--dbcheck] [-dbro|--dbro]
  7.                [-dbu|--dbuser user] [-dbp|--dbpass pass]
  8.                [-dbn|--dbname name]
  9.                [-dbh|--dbhost host[=localhost]] [-dbpr|--dbport port[=3306]]
  10.                [-h|--help] INPUT_FILE
  11. It may work with usual stdin flow.
  12. If you need to check translation strings in the DB(mysql) use -db param and set access credentials.
  13. If your DB works in read-only mode use -dbro parameter.
  14. EOF
  15. }
  16.  
  17. # Read arguments.
  18. while :
  19.   do
  20.   case "$1" in
  21.     -db|--dbcheck)
  22.       DB_CHECK=1
  23.     ;;
  24.     -dbro|--dbro)
  25.       DB_RO=1
  26.     ;;
  27.     -dbu|--dbuser)
  28.       DB_USER="$2"
  29.       shift
  30.     ;;
  31.     -dbp|--dbpass)
  32.       DB_PASS="$2"
  33.       shift
  34.     ;;
  35.     -dbn|--dbname)
  36.       DB_NAME="$2"
  37.       shift
  38.     ;;
  39.     -dbh|--dbhost)
  40.       DB_HOST="$2"
  41.       shift
  42.     ;;
  43.     -dbpr|--dbport)
  44.       DB_PORT="$2"
  45.       shift
  46.     ;;
  47.     -h|--help)
  48.       display_help
  49.       exit 1;
  50.     ;;
  51.     *)
  52.       INPUT_FILE=$1
  53.       break
  54.     ;;
  55.   esac
  56.   shift
  57. done
  58.  
  59. # Check DB settings.
  60. if [ ! -z "$DB_CHECK" ]; then
  61.   if [ -z "$DB_USER" ] || [ -z "$DB_PASS" ]  || [ -z "$DB_NAME" ]; then
  62.     echo "Please enter proper DB credentials."
  63.     echo
  64.     display_help
  65.     exit 1;
  66.   fi
  67.  
  68.   if [ -z "$DB_SERVER" ]; then
  69.     DB_SERVER="localhost"
  70.   fi
  71.  
  72.   if [ -z "$DB_PORT" ]; then
  73.     DB_PORT="3306"
  74.   fi
  75. fi
  76.  
  77. # Get messages from file of stdin.
  78. if [ ! -z "$INPUT_FILE" -a -f "$INPUT_FILE" ]; then
  79.   messages=$(cat $INPUT_FILE)
  80. else
  81.   messages=$(cat -)
  82. fi
  83.  
  84. if [ -z "$messages" ]; then
  85.   echo "There is nothing to process."
  86.   echo
  87.   exit 1
  88. fi
  89.  
  90.  
  91. # Regex matches all quoted strings.
  92. # Take a look at http://www.metaltoad.com/blog/regex-quoted-string-escapable-quotes
  93. read -r -d '' regex_string <<EOF
  94. (                 # Capturing group 1 for single or double quotes without slash before them
  95.   (?<![\\])       #  No slash before next symbol
  96.   [\x27"]         #  Single or double quote symbols
  97. )                 # End of group 1
  98. (                 # Capturing group 2 for the string
  99.   (?:             #  Non-capturing group needs for
  100.     .(?!          #   continue matching any characters which are not followed by
  101.       (?<![\\])\1 #    the string matched in the first backreference without a slash
  102.     )             #
  103.   )*              #
  104.   .?              # Grab the last symbol before ending quote
  105. )                 # End of group 2
  106. \1                # Ending quote
  107. EOF
  108.  
  109. read -r -d '' regex_t <<EOF
  110. /
  111.   [[:space:]\.=]    # Only space, dot or equal sign should be before function
  112.   t                 # Function name
  113.   \s*\(\s*          # Opening parenthesis of the function
  114.   $regex_string     # Search for quoted strings
  115. /gmx                # global, multi-line, extended
  116. EOF
  117.  
  118. read -r -d '' regex_format_plural <<EOF
  119. /
  120.   [[:space:]\.=]               # Only space, dot or equal sign should be before function
  121.   [format_plural|formatPlural] # Function name
  122.   \s*\(\s*                     # Opening parenthesis of the function
  123.   .*?,\s*                      # Any characters in first parameter of the function
  124.   $regex_string                # Search for quoted strings in second parameter
  125.   \s*,\s*                      # Comma separated parameters
  126.   $regex_string                # Search for quoted strings in third parameter
  127. /gmx                           # global, multi-line, extended
  128. EOF
  129.  
  130. messages=$(
  131.   echo "${messages}" |
  132.   sed '/^[^\+].*/d'
  133. )
  134.  
  135. # Extract messages from t() functions.
  136. messages_t=$(
  137.   echo "${messages}" |
  138.   perl -ne 'while (/[[:space:]\.=]t\s*\(\s*((?<![\\])[\x27"])((?:.(?!(?<![\\])\1))*.?)\1/mgx) {print "$2\n"}'
  139. )
  140.  
  141. # Extract messages from format_plural() functions.
  142. messages_plural=$(
  143.   echo "${messages}" |
  144.   perl -ne 'while (/[[:space:]\.=](format_plural|formatPlural)\s*\(\s*.*?,\s*((?<![\\])[\x27"])((?:.(?!(?<![\\])\2))*.?)\2\s*,\s*((?<![\\])[\x27"])((?:.(?!(?<![\\])\4))*.?)\4/mgx) {print "$3\n$5\n"}'
  145. )
  146.  
  147. # Merge 2 lists and sort them.
  148. messages=$(
  149.   echo "$messages_t
  150. $messages_plural" |
  151.   sort -u
  152. )
  153.  
  154. # Check strings in the database.
  155. if [ ! -z "$DB_CHECK" ]; then
  156.   db_connection="mysql\
  157.    --user=$DB_USER --password=$DB_PASS --database=$DB_NAME\
  158.    --host=$DB_HOST --port=$DB_PORT\
  159.    --skip-column-names --execute"
  160.  
  161.   if [ -z "$DB_RO" ]; then
  162.     # Create temporary table for all strings
  163.     tableName="UntranslatedStrings${RANDOM}"
  164.  
  165.     query="CREATE TEMPORARY TABLE ${tableName}(string TEXT);"
  166.  
  167.     while read message
  168.       do
  169.       # Escape double quotes.
  170.       message=${message//\"/\\\"}
  171.  
  172.       # Insert strings into temporary table.
  173.       query+="INSERT INTO ${tableName} VALUES (\"${message}\");";
  174.     done <<< "$messages"
  175.  
  176.     # Try to find strings, which are not added to the DB.
  177.     query+="SELECT us.string s FROM ${tableName} us WHERE us.string NOT IN (SELECT source FROM locales_source);";
  178.  
  179.     messages=$(${db_connection} "${query}")
  180.   else
  181.    # IF DB works in RO mode, check strings one by one.
  182.    messages_processed=""
  183.    while read message
  184.       do
  185.       # Escape double quotes.
  186.       message=${message//\"/\\\"}
  187.  
  188.       query="SELECT ls.source FROM locales_source ls WHERE ls.source = \"${message}\";";
  189.  
  190.       result=$(${db_connection} "${query}")
  191.       if [ -z "$result" ]; then
  192.         messages_processed+=${message}
  193.         messages_processed+=$IFS
  194.       fi
  195.    done <<< "$messages"
  196.  
  197.    messages=$messages_processed
  198.   fi
  199. fi
  200.  
  201. # Output untranslated string to PO file.
  202. if [ ! -z "$messages" ]; then
  203.   while read message
  204.     do
  205.     if [ -z "$message" ]; then
  206.       continue
  207.     fi
  208.  
  209.     # Escape double quote.
  210.     message=${message//\"/\\\"}
  211.     message=${message//\"/\\\"}
  212.     printf "msgid \"$message\"\nmsgstr \"\"\n\n"
  213.   done <<< "$messages"
  214. else
  215.   echo "Nothing to output."
  216.   exit
  217. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement