From 8b6af3fdb905fd1762bf0378bc6d79c8c02ff825 Mon Sep 17 00:00:00 2001 From: Eric House Date: Tue, 14 Aug 2012 07:13:03 -0700 Subject: [PATCH] add md5sum calculator for dicts and use to send POST that checks if they're current. --- .../org/eehouse/android/xw4/DictUtils.java | 63 +++++++++++++++- .../src/org/eehouse/android/xw4/NetUtils.java | 75 ++++++++++++++----- xwords4/android/scripts/info.py | 52 ++++++++++++- 3 files changed, 166 insertions(+), 24 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java index 7b63e10cb..aa6de8c11 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java @@ -23,21 +23,22 @@ package org.eehouse.android.xw4; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.res.AssetManager; import android.net.Uri; import android.os.Environment; +import android.text.Html; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; +import java.security.MessageDigest; import java.util.ArrayList; import java.util.Arrays; -import android.content.res.AssetManager; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.locks.Lock; import java.util.HashMap; import java.util.HashSet; import java.util.Random; -import android.text.Html; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import junit.framework.Assert; @@ -525,6 +526,60 @@ public class DictUtils { // want this later? Environment.MEDIA_MOUNTED_READ_ONLY } + private static String figureMD5Sum( Context context, DictAndLoc dandl ) + { + byte[] digest = null; + String result = null; + String name = dandl.name; + File path = getDictFile( context, addDictExtn( name ), dandl.loc ); + try { + InputStream fis = new FileInputStream( path ); + byte[] buffer = new byte[1024]; + MessageDigest md = MessageDigest.getInstance("MD5"); + for ( ; ; ) { + int nRead = fis.read( buffer ); + if ( 0 > nRead ) { + break; + } + md.update( buffer, 0, nRead ); + } + fis.close(); + + digest = md.digest(); + } catch ( java.io.FileNotFoundException fnfe ) { + DbgUtils.logf( "figureMD5Sum: %s", fnfe.toString() ); + } catch( java.security.NoSuchAlgorithmException nsae ) { + DbgUtils.logf( "figureMD5Sum: %s", nsae.toString() ); + } catch( java.io.IOException ioe ) { + DbgUtils.logf( "figureMD5Sum: %s", ioe.toString() ); + } + + if ( null != digest ) { + final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9', + 'a','b','c','d','e','f'}; + char[] chars = new char[digest.length * 2]; + for ( int ii = 0; ii < digest.length; ii++ ) { + int byt = digest[ii] & 0xFF; + chars[ii * 2] = hexArray[byt >> 4]; + chars[ii * 2 + 1] = hexArray[byt & 0x0F]; + } + result = new String(chars); + } + return result; + } // figureMD5Sum + + public static String getMD5SumFor( Context context, DictAndLoc dandl ) + { + String sum = null; // DBUtils.getDictMD5Sum( context, dandl.name, + // dandl.loc.ordinal() ); + if ( null == sum ) { + sum = figureMD5Sum( context, dandl ); + // DBUtils.setDictMD5Sum( context, dandl.name, + // dandl.loc.ordinal(), sum ); + } + return sum; + } + private static File getSDDir( Context context ) { File result = null; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java index a9936f3e1..4f03c5ea2 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NetUtils.java @@ -282,6 +282,46 @@ public class NetUtils { } } // sendToRelay + private static HttpPost makePost( String proc ) + { + return new HttpPost("http://www.eehouse.org/xw4/info.py/" + proc); + } + + private static String runPost( HttpPost post, List nvp ) + { + String result = null; + try { + post.setEntity( new UrlEncodedFormEntity(nvp) ); + + // Execute HTTP Post Request + HttpClient httpclient = new DefaultHttpClient(); + HttpResponse response = httpclient.execute(post); + HttpEntity entity = response.getEntity(); + if ( null != entity ) { + result = EntityUtils.toString( entity ); + } + } catch ( java.io.UnsupportedEncodingException uee ) { + DbgUtils.logf( "runPost: %s", uee.toString() ); + } catch ( java.io.IOException ioe ) { + DbgUtils.logf( "runPost: %s", ioe.toString() ); + } + return result; + } + + private static String checkDictVersion( Context context, + DictUtils.DictAndLoc dal, + String sum ) + { + int lang = DictLangCache.getDictLangCode( context, dal ); + HttpPost post = makePost( "dictVersion" ); + List nvp = new ArrayList(); + nvp.add( new BasicNameValuePair( "name", dal.name ) ); + nvp.add( new BasicNameValuePair( "lang", + String.format( "%d", + lang ) ) ); + nvp.add( new BasicNameValuePair( "md5sum", sum ) ); + return runPost( post, nvp ); + } public static void checkVersions( Context context ) { @@ -290,32 +330,31 @@ public class NetUtils { try { int versionCode = pm.getPackageInfo( packageName, 0 ).versionCode; - // Create a new HttpClient and Post Header - HttpPost post = - new HttpPost("http://www.eehouse.org/xw4/info.py/curVersion"); + HttpPost post = makePost( "curVersion" ); - // Add your data List nvp = new ArrayList(); nvp.add(new BasicNameValuePair( "name", packageName ) ); nvp.add( new BasicNameValuePair( "version", String.format( "%d", versionCode ) ) ); - post.setEntity( new UrlEncodedFormEntity(nvp) ); - - // Execute HTTP Post Request - HttpClient httpclient = new DefaultHttpClient(); - HttpResponse response = httpclient.execute(post); - HttpEntity entity = response.getEntity(); - if (entity != null) { - String result = EntityUtils.toString( entity ); - DbgUtils.logf( "checkVersions: received: \"%s\"", result ); - } + String result = runPost( post, nvp ); + DbgUtils.logf( "checkVersions: received: \"%s\"", result ); } catch ( PackageManager.NameNotFoundException nnfe ) { DbgUtils.logf( "checkVersions: %s", nnfe.toString() ); - } catch (ClientProtocolException cpe) { - DbgUtils.logf( "checkVersions: %s", cpe.toString() ); - } catch (java.io.IOException ioe) { - DbgUtils.logf( "checkVersions: %s", ioe.toString() ); + } + + DictUtils.DictAndLoc[] list = DictUtils.dictList( context ); + for ( DictUtils.DictAndLoc dal : list ) { + inner: + switch ( dal.loc ) { + case DOWNLOAD: + case EXTERNAL: + case INTERNAL: + String sum = DictUtils.getMD5SumFor( context, dal ); + String url = checkDictVersion( context, dal, sum ); + DbgUtils.logf( "checkVersions(%s)=>%s", dal.name, url ); + break inner; // switch + } } } diff --git a/xwords4/android/scripts/info.py b/xwords4/android/scripts/info.py index c400562ce..97fbbdc85 100755 --- a/xwords4/android/scripts/info.py +++ b/xwords4/android/scripts/info.py @@ -9,19 +9,67 @@ s_versions = { 'org.eehouse.android.xw4' : '42' ,'org.eehouse.android.xw4sms' : '41' } +s_dictSums = { 'Catalan/DISC2_2to9' : 'd02349fd4021f7a5a5dfd834dc4f2491' + ,'English/CSW12_2to8': '2314a99c1a6af2900db3aefcd2186060' + ,'English/CSW12_2to9': '0b4b1c49d58fb8149535a29b786b8638_x' + } + logging.basicConfig(level=logging.DEBUG ,format='%(asctime)s [[%(levelname)s]] %(message)s' ,datefmt='%d %b %y %H:%M' - ,filename='/tmp/info.py.log' - ,filemode='a') + ,filename='/tmp/info_py.log') +# ,filemode='w') +# This seems to be required to prime the pump somehow. +logging.debug( "loaded...." ) + +# public def curVersion( req, name, version ): global s_versions + logging.debug( "version: " + version ) if name in s_versions: if s_versions[name] == version: logging.debug(name + " is up-to-date") return "" else: + logging.debug( name + " is old" ) return s_versions[name] else: logging.debug( 'Error: bad name ' + name ) + +# Order determined by language_names in +# android/XWords4/res/values/common_rsrc.xml +def langStr( lang ): + langs = ( '' + ,'English' + ,'French' + ,'German' + ,'Turkish' + ,'Arabic' + ,'Spanish' + ,'Swedish' + ,'Polish' + ,'Danish' + ,'Italian' + ,'Dutch' + ,'Catalan' + ,'Portuguese' + ,'' + ,'Russian' + ,'' + ,'Czech' + ,'Greek' + ,'Slovak' ) + return langs[int(lang)] + +# public +def dictVersion( req, name, lang, md5sum ): + global s_dictSums + result = '' + path = langStr(lang) + "/" + name + if path in s_dictSums: + if s_dictSums[path] != md5sum: + result = "http://eehouse.org/and_wordlists/" + path + ".xwd" + else: + logging.debug( path + " not known" ) + return result