Skip to content

Commit

Permalink
Import tools from old SVN repository for gettext strings and the like.
Browse files Browse the repository at this point in the history
  • Loading branch information
George Stephanis committed Jan 23, 2014
1 parent fc124a1 commit 470fb21
Show file tree
Hide file tree
Showing 76 changed files with 7,436 additions and 0 deletions.
1 change: 1 addition & 0 deletions tools/.svn/entries
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12
1 change: 1 addition & 0 deletions tools/.svn/format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
1. Add 'jetpack' textdomain to all i18n strings: SANDBOX
1. path/to/tools/add-textdomain.sh path/to/trunk
2. Make sure everything looks right
3. Commit
2. Generate the POT file: OS X (ignore warnings) or SANDBOX
1. php path/to/tools/make-pot.php path/to/trunk path/to/trunk/languages/jetpack.pot
2. Commit
3. Import POT file into https://translate.wordpress.com/projects/jetpack/
1. Find or create the correct subproject for this version of Jetpack: https://translate.wordpress.com/projects/jetpack/1.3, for example
2. If you created a new subproject, go to the previoulsy active project and approve all pending strings that can be approved.
3. In the new subproject, mass-create Translation Sets from the most recent subproject.
4. If you get an error, try doing Mass-creating Translations from the HTTP URL instead of the HTTPS URL.
5. Go to https://translate.wordpress.com/projects/jetpack/$subproject and click Project Actions -> Import Originals
6. Upload the latest POT file generated above.
4. Import translations from WordPress.com and/or previous versionsn of Jetpack into the latest Jetpack subproject: OS X (Proxied == Annoying)
*. php path/to/tools/import-translations.php DESTINATION_URL SOURCE_URL [SOURCE_URL ...]
*. Must be proxied.
*. E.g., tsocks php path/to/tools/import-translations.php https://translate.wordpress.com/projects/jetpack/$subproject https://translate.wordpress.com/projects/wpcom
5. Export translations from GlotPress to Jetpack plugin: OS X (ignore warnings) or SANDBOX
*. php path/to/tools/export-translations.php DIRECTORY SOURCE_URL
*. E.g., php path/to/tools/export-translations.php path/to/trunk/ https://translate.wordpress.com/projects/jetpack/1.3
* Commit
6. Test :)
1. Make a list of all of the changes and new features in this release.
2. Write testing steps for each of the above items.
3. Follow the testing steps and test on multiple hosts/environments.
7. Update readme.txt changelog
8. Update Jetpack version number in two places:
1. Plugin header
2. JETPACK__VERSION
9. Tag new release
1. E.g., svn cp path/to/trunk path/to/tags/1.3
2. Commit
10. Update stable tag in two places:
1. trunk/readme.txt
2. tags/$new/readme.txt
3. Commit *both* at the same time in one commit
11. Create or update the legacy branch for this version
1. E.g. (To create the branch) svn cp path/to/trunk path/to/branches/1.3
OR
(To update the branch) svn merge -r CURRENT_BRANCH_REVISION:CURRENT_TRUNK_REVISION path/to/trunk path/to/branches/1.3
* Note: Find current revision numbers by running "svn info" from within the branch or trunk.
2. Commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php

/*
* Imports translations from one or multiple WordPress.com GlotPress project to another
*
* php import-translations.php DESTINATION_URL SOURCE_URL [SOURCE_URL ...]
*/

/**
* Terminates script. Prints help and message to STDERR
*
* @param string $message
*/
function die_error( $message ) {
global $argv;

fwrite( STDERR, "php $argv[0] DESTINATION_URL SOURCE_URL [SOURCE_URL ...]\n" );
fwrite( STDERR, "$message\n" );
exit( 1 );
}

/**
* Converts GlotPress URL into a GlotPress API URL
*
* @param sring $url URL
* @return sstring API URL
*/
function apize_url( $url ) {
if ( false !== strpos( $url, '/api' ) ) {
return $url;
}

$host = preg_quote( parse_url( $url, PHP_URL_HOST ) );

return preg_replace( "#^https?://$host#", '\\0/api', $url );
}

if ( empty( $argv[1] ) ) {
die_error( 'No DESTINATION_URL specified' );
}

$destination_url = apize_url( rtrim( $argv[1], '/' ) );
$destination = json_decode( file_get_contents( $destination_url ) );

$destination_locales = array();
foreach ( $destination->translation_sets as $translation_set ) {
$destination_locales[$translation_set->locale] = sprintf( '%s/%s', $translation_set->locale, $translation_set->slug );
}

if ( isset( $argv[2] ) ) {
$origin_urls = array_map( 'apize_url', array_slice( $argv, 2 ) );
} else {
/*
// Imports all siblings into destination
$origin_urls = array();
$destination_parent_url = rtrim( dirname( $destination_url ), '/' );
$destination_parent = json_decode( file_get_contents( $destination_parent_url ) );
foreach ( $destination_parent->sub_projects as $sub_project ) {
$origin_url = sprintf( '%s/%s', $destination_parent_url, $sub_project->slug );
if ( $origin_url == $destination_url ) {
continue;
}
$origin_urls[] = $origin_url;
}

$origin_urls[] = 'http://translate.wordpress.com/api/projects/wpcom';
*/
die_error( 'No SOURCE_URLs specified' );
}

sort( $origin_urls );

// Log in
echo "WordPress.com Username: ";
$user_login = trim( fgets( STDIN ) );

echo "WordPress.com Password: ";
$user_pass = shell_exec( 'read -rs secret_password && echo $secret_password' );
$user_pass = substr( $user_pass, 0, -1 );
echo "\n";

$cookie_jar = tmpfile(); // handle
$cookie_jar_meta = stream_get_meta_data( $cookie_jar ); // file meta data
$cookie_jar_file = $cookie_jar_meta['uri']; // file

$login = curl_init( 'https://translate.wordpress.com/login' );
$login_error = false;

curl_setopt_array( $login, array(
CURLOPT_POSTFIELDS => compact( 'user_login', 'user_pass' ),
CURLOPT_COOKIEJAR => $cookie_jar_file, // write cookies
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_HEADERFUNCTION => function( $curl, $header_line ) use ( &$login_error ) {
if ( preg_match( '/_gp_notice_error=/', $header_line, $matches ) ) {
$login_error = true;
}
return strlen( $header_line );
},
) );

curl_exec( $login );
curl_close( $login ); // Now our cookies are stored in $cookie_jar_file

if ( $login_error ) {
die_error( 'Invalid username/password' );
}

foreach ( $destination_locales as $locale => $locale_url_suffix ) {
echo "$locale: ";

$destination_locale_url = sprintf( '%s/%s', $destination_url, $locale_url_suffix );
$destination_locale_export_url = sprintf( '%s/%s/%s', $destination_url, $locale_url_suffix, 'export-translations?format=po' );
$destination_locale_import_url = sprintf( '%s/%s/%s', $destination_url, $locale_url_suffix, 'import-translations' );

$destination_locale_po = tmpfile(); // handle
$destination_locale_po_meta = stream_get_meta_data( $destination_locale_po ); // file meta data
$destination_locale_po_file = $destination_locale_po_meta['uri']; // file
$destination_locale_po_data = @file_get_contents( $destination_locale_export_url ); // file contents
fwrite( $destination_locale_po, $destination_locale_po_data );

$total_strings = preg_match_all( '/^msgstr/m', $destination_locale_po_data, $m );
$untranslated_strings = preg_match_all( '/^msgstr(\[\d+\])? ""/m', $destination_locale_po_data, $m );

echo "TOTAL: $total_strings; UNTRANSLATED: $untranslated_strings\n";

foreach ( $origin_urls as $origin_url ) {
$origin_locale_url = sprintf( '%s/%s', $origin_url, $locale_url_suffix );
$origin_locale_export_url = sprintf( '%s/%s/%s', $origin_url, $locale_url_suffix, 'export-translations?format=po' );

$origin_locale_po = tmpfile(); // handle
$origin_locale_po_meta = stream_get_meta_data( $origin_locale_po ); // file meta data
$origin_locale_po_file = $origin_locale_po_meta['uri']; // file
$origin_locale_po_data = @file_get_contents( $origin_locale_export_url ); // file contents

$translations_added = 0;

if ( $origin_locale_po_data ) {
fwrite( $origin_locale_po, $origin_locale_po_data );

$translations_added = upload_translation( $destination_locale_import_url, $origin_locale_po_file );
}

fclose( $origin_locale_po );

printf( "%s: %d\n", $origin_locale_url, $translations_added );
}

$translations_added = upload_translation( $destination_locale_import_url, $destination_locale_po_file );
printf( "%s: %d\n", $destination_locale_url, $translations_added );

fclose( $destination_locale_po );

echo "\n";
}

/**
* Upload file to URL using Cookie Authentication
*
* @param string $import_url
* @param string $file
*/
function upload_translation( $import_url, $file ) {
global $cookie_jar_file;

$import = curl_init( $import_url );

$translations_added = 0;

curl_setopt_array( $import, array(
CURLOPT_COOKIEFILE => $cookie_jar_file, // read cookies
CURLOPT_POSTFIELDS => array(
'format' => 'po',
'import-file' => sprintf( '@%s', $file ),
),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_HEADERFUNCTION => function( $curl, $header_line ) use ( &$translations_added ) {
if ( preg_match( '/_gp_notice_notice=(\d+)/', $header_line, $matches ) ) {
$translations_added = (int) $matches[1];
}
return strlen( $header_line );
},
) );

curl_exec( $import );

return $translations_added;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

/**
* Generates POT File for Jetpack
*
* php makepot DIRECTORY [OUTPUT=jetpack.pot]
*/

function jetpack_makepot_usage() {
global $argv;

die( "$argv[0] DIRECTORY [OUTPUT=jetpack.pot]\n" );
}

defined( 'WORDPRESS_I18N__MAKEPOT_PATH' ) or define( 'WORDPRESS_I18N__MAKEPOT_PATH', dirname( __FILE__ ) . '/wordpress-i18n/makepot.php' );

if ( !WORDPRESS_I18N__MAKEPOT_PATH || !is_file( WORDPRESS_I18N__MAKEPOT_PATH ) ) {
jetpack_make_pot_usage();
}

require WORDPRESS_I18N__MAKEPOT_PATH;

class Jetpack_MakePOT extends MakePOT {
function __construct() {
$this->projects[] = 'jetpack';
parent::__construct();
}

function jetpack( $dir, $output ) {
$main_file = "$dir/jetpack.php";
$source = $this->get_first_lines( $main_file, $this->max_header_lines );

$placeholders = array(
'version' => $this->get_addon_header( 'Version', $source ),
'author' => $this->get_addon_header( 'Author', $source ),
'name' => $this->get_addon_header( 'Plugin Name', $source ),
'slug' => 'jetpack',
);

if ( !$res = $this->xgettext( 'wp-plugin', $dir, $output, $placeholders ) ) {
return false;
}

$potextmeta = new PotExtMeta;
$res = $potextmeta->append( $main_file, $output );

$modules = glob( "$dir/modules/*.php" ); /* */
foreach ( $modules as $module ) {
$potextmeta = new Jetpack_PotExtMeta;
$potextmeta->append( $module, $output );
}

/* Adding non-gettexted strings can repeat some phrases */
$output_shell = escapeshellarg($output);
system( "msguniq $output_shell -o $output_shell" );
return $res;
}
}

class Jetpack_PotExtMeta extends PotExtMeta {
var $headers = array(
'Module Name',
'Module Description',
);
}


// run the CLI only if the file
// wasn't included
$included_files = get_included_files();
if ( __FILE__ == $included_files[0] ) {
$makepot = new Jetpack_MakePOT;
if ( empty( $argv[1] ) ) {
jetpack_makepot_usage();
}

if ( ( !$realpath = realpath( $argv[1] ) ) || !is_dir( $realpath ) ) {
jetpack_makepot_usage();
}

$res = $makepot->jetpack( $realpath, isset( $argv[2] )? $argv[2] : 'jetpack.pot' );
if ( false === $res ) {
fwrite(STDERR, "Couldn't generate POT file!\n");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

# add-textdomain.sh DIRECTORY

DIRECTORY=${1?"Usage: $0 DIRECTORY"}

while IFS= read -r -d '' file; do
php $(dirname $(readlink -f $0))/wordpress-i18n/add-textdomain.php -i jetpack "$file"
done < <(find $DIRECTORY -type f -name '*.php' \! -path '*.svn*' -print0)
Loading

2 comments on commit 470fb21

@nb
Copy link
Member

@nb nb commented on 470fb21 Jan 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@georgestephanis, why do you need the .svn directories?

@georgestephanis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nb I left them in because in the original svn tools, it was set as a svn:external -- I figured by leaving them in, it could be more easily svn up'd by anyone with a checkout.

@cathyjf mentioned it may be better to use a git submodule -- which I'd be completely fine switching to, I just tossed it in this way for the time being.

Please sign in to comment.