Brion VIBBER has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/145708

Change subject: Update storyboard strings, qqq files when master files change
......................................................................

Update storyboard strings, qqq files when master files change

en.lproj/Main_iPhone.strings now updates automatically when
new things appear in Main_iPhone.storyboard.

qqq.lproj/*.strings files now have stub entries added for any new
entries in en.lproj/*.strings files. These should be very visible
in code review if they don't get caught before committing. :)

Change-Id: Ibd01ba5eb754ec9aaafddf0391496c8c527273cc
---
M Wikipedia.xcodeproj/project.pbxproj
A scripts/update-qqq.php
M wikipedia/qqq.lproj/Localizable.strings
M wikipedia/qqq.lproj/Main_iPhone.strings
4 files changed, 281 insertions(+), 66 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/ios/wikipedia 
refs/changes/08/145708/1

diff --git a/Wikipedia.xcodeproj/project.pbxproj 
b/Wikipedia.xcodeproj/project.pbxproj
index be38747..ad6ceb2 100644
--- a/Wikipedia.xcodeproj/project.pbxproj
+++ b/Wikipedia.xcodeproj/project.pbxproj
@@ -1573,9 +1573,11 @@
                        buildPhases = (
                                D4991431181D51DE00E6073C /* Sources */,
                                D4991432181D51DE00E6073C /* Frameworks */,
-                               D4991433181D51DE00E6073C /* Resources */,
                                04272E7619404CDF00CC682F /* ShellScript */,
                                04272E75193FF7F000CC682F /* ShellScript */,
+                               D4C16A621970946900CD91AD /* ShellScript */,
+                               D4C16A631970949A00CD91AD /* ShellScript */,
+                               D4991433181D51DE00E6073C /* Resources */,
                        );
                        buildRules = (
                        );
@@ -1753,6 +1755,37 @@
                        shellPath = /bin/sh;
                        shellScript = "scripts/run-grunt.sh";
                };
+               D4C16A621970946900CD91AD /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                               
"$(SRCROOT)/wikipedia/Base.lproj/Main_iPhone.storyboard",
+                       );
+                       outputPaths = (
+                               
"$(SRCROOT)/wikipedia/en.lproj/Main_iPhone.strings",
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "scripts/update-storyboard-strings.php";
+               };
+               D4C16A631970949A00CD91AD /* ShellScript */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                               
"$(SRCROOT)/wikipedia/en.lproj/Main_iPhone.strings",
+                               
"$(SRCROOT)/wikipedia/en.lproj/InfoPlist.strings",
+                               
"$(SRCROOT)/wikipedia/en.lproj/Localizable.strings",
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "scripts/update-qqq.php";
+               };
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
diff --git a/scripts/update-qqq.php b/scripts/update-qqq.php
new file mode 100755
index 0000000..c192a6d
--- /dev/null
+++ b/scripts/update-qqq.php
@@ -0,0 +1,239 @@
+#!/usr/bin/php -q
+<?php
+
+/**
+ * AppleFFS class implements support for Apple .strings files.
+ * This class reads and writes only UTF-8 files.
+ *
+ * @author Brion Vibber <bvib...@wikimedia.org>
+ *
+ * derived from the AppleFFS in Translate extension, but hacked down
+ */
+class AppleStringsFile {
+       // READ
+
+       public function readFromFile( $path ) {
+               $data = file_get_contents( $path );
+               return $this->readFromVariable( $data );
+       }
+       
+       public function write( $data ) {
+               return $this->writeReal( $data );
+       }
+       
+       /**
+        * @param array $data
+        * @return array Parsed data.
+        * @throws Exception
+        */
+       public function readFromVariable( $data ) {
+               $lines = explode( "\n", $data );
+               $authors = $messages = array();
+               $linecontinuation = false;
+
+               $value = '';
+               foreach ( $lines as $line ) {
+                       if ( $linecontinuation ) {
+                               $linecontinuation = false;
+                               $valuecont = $line;
+                               $value .= $valuecont;
+                       } else {
+                               if ( $line === '' ) {
+                                       continue;
+                               }
+
+                               if ( substr( $line, 0, 2 ) === '//' ) {
+                                       // Single-line comment
+                                       $match = array();
+                                       $ok = preg_match( 
'~//\s*Author:\s*(.*)~', $line, $match );
+                                       if ( $ok ) {
+                                               $authors[] = $match[1];
+                                       }
+                                       continue;
+                               }
+
+                               if ( substr( $line, 0, 2 ) === '/*' ) {
+                                       if ( strpos( $line, '*/', 2 ) === false 
) {
+                                               $linecontinuation = true;
+                                       }
+                                       continue;
+                               }
+
+                               list( $key, $value ) = self::readRow( $line );
+                               $messages[$key] = $value;
+                       }
+               }
+
+               return array(
+                       'AUTHORS' => $authors,
+                       'MESSAGES' => $messages,
+               );
+       }
+
+       /**
+        * Parses non-empty strings file row to key and value.
+        * @param string $line
+        * @throws Exception
+        * @return array( string $key, string $val )
+        */
+       public static function readRow( $line ) {
+               $match = array();
+               if ( preg_match( 
'/^"((?:\\\"|[^"])*)"\s*=\s*"((?:\\\"|[^"])*)"\s*;\s*$/', $line, $match ) ) {
+                       $key = self::unescapeString( $match[1] );
+                       $value = self::unescapeString( $match[2] );
+                       if ( $key === '' ) {
+                               throw new Exception( "Empty key in line $line" 
);
+                       }
+                       return array( $key, $value );
+               } else {
+                       throw new Exception( "Unrecognized line format: $line" 
);
+               }
+       }
+
+       // Write
+
+       /**
+        * @param MessageCollection $collection
+        * @return string
+        */
+       protected function writeReal( array $collection ) {
+               $header = $this->doHeader( $collection );
+               $header .= $this->doAuthors( $collection );
+               $header .= "\n";
+
+               $output = '';
+
+               /**
+                * @var TMessage $m
+                */
+               foreach ( $collection['MESSAGES'] as $key => $m ) {
+                       $value = $m;
+
+                       if ( $value === '' ) {
+                               continue;
+                       }
+
+                       $output .= self::writeRow( $key, $value );
+               }
+
+               if ( $output ) {
+                       $data = $header . $output;
+               } else {
+                       $data = $header;
+               }
+
+               return $data;
+       }
+
+       /**
+        * Writes well-formed properties file row with key and value.
+        * @param string $key
+        * @param string $value
+        * @return string
+        */
+       public static function writeRow( $key, $value ) {
+               return self::quoteString( $key ) . ' = ' . self::quoteString( 
$value ) . ';' . "\n";
+       }
+
+       /**
+        * Quote and escape Obj-C-style strings for .strings format
+        */
+       protected static function quoteString( $str ) {
+               return '"' . self::escapeString( $str ) . '"';
+       }
+
+       /**
+        * Escape Obj-C-style strings; use backslash-escapes etc.
+        *
+        * @param string $str
+        * @return string
+        */
+       protected static function escapeString( $str ) {
+               $str = addcslashes( $str, '\\"' );
+               $str = str_replace( "\n", '\\n', $str );
+               return $str;
+       }
+
+       /**
+        * Unescape Obj-C-style strings; can include backslash-escapes
+        *
+        * @todo support \UXXXX
+        *
+        * @param string $str
+        * @return string
+        */
+       protected static function unescapeString( $str ) {
+               return stripcslashes( $str );
+       }
+
+       /**
+        * @param MessageCollection $collection
+        * @return string
+        */
+       protected function doHeader( array $collection ) {
+               if ( isset( $this->extra['header'] ) ) {
+                       $output = $this->extra['header'];
+               } else {
+                       $wgSitename = 'translatewiki.net';
+
+                       $name = 'Message documentation';
+                       $native = 'Message documentation';
+                       $output = "// Messages for $name ($native)\n";
+                       $output .= "// Exported from $wgSitename\n";
+               }
+
+               return $output;
+       }
+
+       /**
+        * @param MessageCollection $collection
+        * @return string
+        */
+       protected function doAuthors( array $collection ) {
+               $output = '';
+               $authors = $collection['AUTHORS'];
+
+               foreach ( $authors as $author ) {
+                       $output .= "// Author: $author\n";
+               }
+
+               return $output;
+       }
+}
+
+function fillStubs( &$en, &$qqq ) {
+       $enKeys = array_keys( $en['MESSAGES'] );
+       $qqqKeys = array_keys( $qqq['MESSAGES'] );
+       $missing = array_diff( $enKeys, $qqqKeys );
+       
+       if (count( $missing ) > 0) {
+               foreach( $missing as $key ) {
+                       $qqq['MESSAGES'][$key] = 'MISSING DESCRIPTION; DO NOT 
COMMIT FILE YET';
+               }
+               return true;
+       } else {
+               return false;
+       }
+}
+
+function processStubs( $filename ) {
+       $base = realpath( dirname( __DIR__ ) ) . "/wikipedia";
+
+       $parser = new AppleStringsFile();
+
+       $file_en = "$base/en.lproj/$filename.strings";
+       $file_qqq = "$base/qqq.lproj/$filename.strings";
+       
+       $data_en = $parser->readFromFile( $file_en );
+       $data_qqq = $parser->readFromFile( $file_qqq );
+
+       if (fillStubs( $data_en, $data_qqq )) {
+               $out = $parser->write( $data_qqq );     
+               file_put_contents( $file_qqq, $out );
+               echo "Updated qqq.lproj/$filename.strings\n";
+       }
+}
+
+processStubs('InfoPlist');
+processStubs('Main_iPhone');
+processStubs('Localizable');
diff --git a/wikipedia/qqq.lproj/Localizable.strings 
b/wikipedia/qqq.lproj/Localizable.strings
index aee3ca4..badb85c 100644
--- a/wikipedia/qqq.lproj/Localizable.strings
+++ b/wikipedia/qqq.lproj/Localizable.strings
@@ -149,3 +149,9 @@
 "license-footer-text" = "Brief footer text linking to CC-BY-SA license. '$1' 
is placeholder for the license-footer-name message";
 "license-footer-name" = "License short name; usually leave untranslated as 
CC-BY-SA 3.0";
 "table-of-contents-heading" = "Header text appearing above the first section 
in the table of contents";
+"wikitext-upload-save-terms-name" = "Formal name of Wikipedia 'Terms of Use' 
in local language, used as a link";
+"page_protected_autoconfirmed" = "Brief description of Wikipedia 
'autoconfirmed' protection level, shown when editing a page that is protected.";
+"page_protected_sysop" = "Brief description of Wikipedia 'sysop' protection 
level, shown when editing a page that is protected.";
+"page_protected_other" = "Brief description of Wikipedia unknown protection 
level, shown when editing a page that is protected.";
+"page_protected_can_not_edit" = "Text of alert dialog shown when trying to 
edit a page that is protected beyond what the user can edit.";
+"page_protected_can_not_edit_title" = "Title of alert dialog shown when trying 
to edit a page that is protected beyond what the user can edit.";
diff --git a/wikipedia/qqq.lproj/Main_iPhone.strings 
b/wikipedia/qqq.lproj/Main_iPhone.strings
index 342b360..1ef24b8 100644
--- a/wikipedia/qqq.lproj/Main_iPhone.strings
+++ b/wikipedia/qqq.lproj/Main_iPhone.strings
@@ -1,99 +1,36 @@
+// Messages for Message documentation (Message documentation)
+// Exported from translatewiki.net
 
-/* Class = "IBUIButton"; normalTitle = "Show another captcha"; ObjectID = 
"21c-U6-yfo"; */
 "21c-U6-yfo.normalTitle" = "Label for button on captcha screen to fetch and 
show another captcha image";
-
-/* Class = "IBUILabel"; text = "github repo"; ObjectID = "3gs-D6-glW"; */
 "3gs-D6-glW.text" = "label for link to project source on github";
-
-/* Class = "IBUILabel"; text = "wikimedia"; ObjectID = "5KU-bp-5Fs"; */
 "5KU-bp-5Fs.text" = "label for links to project source";
-
-/* Class = "IBUITextField"; placeholder = "User name"; ObjectID = 
"5cT-2Y-0Ie"; */
 "5cT-2Y-0Ie.placeholder" = "Label on login screen ";
-
-/* Class = "IBUILabel"; text = "NSDate-Extensions"; ObjectID = "6O2-5x-h41"; */
 "6O2-5x-h41.text" = "Name of an open-source library used in the project; 
usually do not translate.";
-
-/* Class = "IBUILabel"; text = "Saved pages are pretty awesome. Think of them 
as bookmarks that you can access when you are offline."; ObjectID = 
"GiD-Rj-wb7"; */
 "GiD-Rj-wb7.text" = "Explanatory text shown on saved pages list when no saved 
pages are present.";
-
-/* Class = "IBUILabel"; text = "Preview"; ObjectID = "LfM-01-aCF"; */
 "LfM-01-aCF.text" = "Button text for 'Preview' button on edit screen";
-
-/* Class = "IBUILabel"; text = "Skip"; ObjectID = "P6J-IE-CiO"; */
 "P6J-IE-CiO.text" = "Button text for 'Skip' button on onboarding screen that 
offers to log in or sign up";
-
-/* Class = "IBUITextField"; placeholder = "Password"; ObjectID = "PCr-0J-fBj"; 
*/
 "PCr-0J-fBj.placeholder" = "Placeholder label text for password field on 
create-account screen";
-
-/* Class = "IBUILabel"; text = "Canonical Language"; ObjectID = "SER-n4-DZC"; 
*/
 "SER-n4-DZC.text" = "Unused; do not translate";
-
-/* Class = "IBUITextField"; placeholder = "Re-type password"; ObjectID = 
"UgH-77-lyp"; */
 "UgH-77-lyp.placeholder" = "Placeholder label text for second password field 
on create-account screen";
-
-/* Class = "IBUILabel"; text = "No saved pages yet."; ObjectID = "W1c-wQ-1pa"; 
*/
 "W1c-wQ-1pa.text" = "Label text shown on saved pages list when there are no 
saved pages.";
-
-/* Class = "IBUILabel"; text = "Log in"; ObjectID = "Wff-o9-AdH"; */
 "Wff-o9-AdH.text" = "Button text for 'Log in' button";
-
-/* Class = "IBUILabel"; text = "Label"; ObjectID = "XkB-Xo-Xq0"; */
 "XkB-Xo-Xq0.text" = "Unused; do not translate";
-
-/* Class = "IBUILabel"; text = "Test Zero Label Text"; ObjectID = 
"aCV-ih-PXn"; */
 "aCV-ih-PXn.text" = "Unused; do not translate";
-
-/* Class = "IBUILabel"; text = "No recent pages yet."; ObjectID = 
"aUp-0e-F6i"; */
 "aUp-0e-F6i.text" = "Label text shown on 'recent pages' list when there are no 
recent pages.";
-
-/* Class = "IBUILabel"; text = "Create Account"; ObjectID = "c3c-PU-Exz"; */
 "c3c-PU-Exz.text" = "Button to Create Account on the onboarding screen";
-
-/* Class = "IBUILabel"; text = "Label"; ObjectID = "cbH-8H-z54"; */
 "cbH-8H-z54.text" = "Unused; do not translate";
-
-/* Class = "IBUILabel"; text = "Hpple"; ObjectID = "eSk-uQ-Ran"; */
 "eSk-uQ-Ran.text" = "Name of an open-source library used in the project; 
usually do not translate.";
-
-/* Class = "IBUITextField"; placeholder = "Enter CAPTCHA text from image 
above"; ObjectID = "gPg-cg-Yjy"; */
 "gPg-cg-Yjy.placeholder" = "Placeholder for input text on captcha input 
screen";
-
-/* Class = "IBUILabel"; text = "main repo"; ObjectID = "gzT-kN-7kp"; */
 "gzT-kN-7kp.text" = "label for link to project source on Wikimedia Gerrit";
-
-/* Class = "IBUILabel"; text = "Already have an account? Log in"; ObjectID = 
"heA-3K-nhS"; */
 "heA-3K-nhS.text" = "Button label on onboarding screen offering to log in 
instead of creating account";
-
-/* Class = "IBUILabel"; text = "Recent pages are not as awesome as Saved 
pages. They are not available for Offline Reading."; ObjectID = "huU-kO-aYI"; */
 "huU-kO-aYI.text" = "Explanatory text shown on recent pages list when there 
are no recent pages";
-
-/* Class = "IBUILabel"; text = "credits"; ObjectID = "ieH-d1-Ds7"; */
 "ieH-d1-Ds7.text" = "placeholder text; do not translate";
-
-/* Class = "IBUILabel"; text = "Create Account"; ObjectID = "jiW-Cg-oL3"; */
 "jiW-Cg-oL3.text" = "Button label to create account";
-
-/* Class = "IBUILabel"; text = "Language"; ObjectID = "jxY-ej-I9e"; */
 "jxY-ej-I9e.text" = "placeholder text; do not translate";
-
-/* Class = "IBUITextField"; placeholder = "Password"; ObjectID = "kVb-lx-d6C"; 
*/
 "kVb-lx-d6C.placeholder" = "Placeholder label for login password field";
-
-/* Class = "IBUITextField"; placeholder = "User name"; ObjectID = 
"mAk-1N-jPC"; */
 "mAk-1N-jPC.placeholder" = "Placeholder label for login username field";
-
-/* Class = "IBUILabel"; text = "Label"; ObjectID = "nI1-bn-0Ii"; */
 "nI1-bn-0Ii.text" = "placeholder text; do not translate";
-
-/* Class = "IBUILabel"; text = "WikiFont"; ObjectID = "qQl-8k-ux4"; */
 "qQl-8k-ux4.text" = "Name of open-source font project on about screen. Usually 
do not translate.";
-
-/* Class = "IBUITextField"; placeholder = "Email address (optional)"; ObjectID 
= "rKI-nq-3p7"; */
 "rKI-nq-3p7.placeholder" = "Placeholder text for email field on create account 
form";
-
-/* Class = "IBUILabel"; text = "external"; ObjectID = "ven-ec-xzg"; */
 "ven-ec-xzg.text" = "placeholder text; do not translate";
-
-/* Class = "IBUILabel"; text = "Create account"; ObjectID = "wkl-j8-wLX"; */
 "wkl-j8-wLX.text" = "Button label to go to Create Account form from Login 
form";

-- 
To view, visit https://gerrit.wikimedia.org/r/145708
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibd01ba5eb754ec9aaafddf0391496c8c527273cc
Gerrit-PatchSet: 1
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Brion VIBBER <br...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to