Merge lp:~emmanuel-florent/financisto/enhance_from_167 into lp:~financisto-dev/financisto/trunk

Proposed by Emmanuel Florent
Status: Merged
Merged at revision: 525
Proposed branch: lp:~emmanuel-florent/financisto/enhance_from_167
Merge into: lp:~financisto-dev/financisto/trunk
Diff against target: 2744 lines (+1056/-798)
17 files modified
.classpath (+0/-2)
.project (+1/-1)
project.properties (+1/-1)
src/ru/orangesoftware/financisto/activity/FlowzrSyncActivity.java (+69/-87)
src/ru/orangesoftware/financisto/activity/MainActivity.java (+20/-2)
src/ru/orangesoftware/financisto/export/docs/DriveBackupTask.java (+2/-1)
src/ru/orangesoftware/financisto/export/docs/DriveListFilesTask.java (+2/-2)
src/ru/orangesoftware/financisto/export/docs/DriveRestoreTask.java (+10/-7)
src/ru/orangesoftware/financisto/export/docs/GoogleDriveClient.java (+1/-2)
src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncEngine.java (+352/-544)
src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncOptions.java (+1/-1)
src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncTask.java (+179/-94)
src/ru/orangesoftware/financisto/export/flowzr/GCMIntentService.java (+27/-25)
src/ru/orangesoftware/financisto/export/flowzr/GoogleDrivePictureClient.java (+94/-0)
src/ru/orangesoftware/financisto/export/flowzr/PictureDriveTask.java (+234/-0)
src/ru/orangesoftware/financisto/service/FinancistoService.java (+26/-26)
src/ru/orangesoftware/financisto/utils/MyPreferences.java (+37/-3)
To merge this branch: bzr merge lp:~emmanuel-florent/financisto/enhance_from_167
Reviewer Review Type Date Requested Status
Denis Solonenko Pending
Review via email: mp+219828@code.launchpad.net

Description of the change

[.] Merged, in branch, from 1.6.7, lp:financisto
[+] Backup/Restore Online > Upload picture
[*] Fix on recurring budget sync (critical)

To post a comment you must log in.
522. By emmanuel-florent

Fix on Auto-sync checkbox

523. By emmanuel-florent

Cleanup logcat

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.classpath'
2--- .classpath 2013-09-25 22:50:49 +0000
3+++ .classpath 2014-05-17 07:00:19 +0000
4@@ -1,9 +1,7 @@
5 <?xml version="1.0" encoding="UTF-8"?>
6 <classpath>
7 <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
8- <classpathentry kind="lib" path="libs/trace-0.2.0.jar"/>
9 <classpathentry exported="true" kind="lib" path="libs/rfc2445-no-joda.jar" sourcepath="H:/Work/Java/Android/google-rfc-2445-read-only/src"/>
10- <classpathentry kind="lib" path="libs/GDocsAPI.jar"/>
11 <classpathentry kind="lib" path="libs/CWAC-WakefulIntentService.jar"/>
12 <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Android 2.2 Google APIs"/>
13 <classpathentry kind="src" path="src"/>
14
15=== modified file '.project'
16--- .project 2011-09-05 15:09:03 +0000
17+++ .project 2014-05-17 07:00:19 +0000
18@@ -1,6 +1,6 @@
19 <?xml version="1.0" encoding="UTF-8"?>
20 <projectDescription>
21- <name>Financisto</name>
22+ <name>financisto167</name>
23 <comment></comment>
24 <projects>
25 </projects>
26
27=== modified file 'project.properties'
28--- project.properties 2014-01-11 06:52:17 +0000
29+++ project.properties 2014-05-17 07:00:19 +0000
30@@ -24,6 +24,6 @@
31 # Project target.
32 target=Google Inc.:Google APIs:8
33 apk-configurations=
34-android.library.reference.1=google-play-services_lib
35+android.library.reference.1=../../project/google-play-services_lib
36
37
38
39=== modified file 'src/ru/orangesoftware/financisto/activity/FlowzrSyncActivity.java'
40--- src/ru/orangesoftware/financisto/activity/FlowzrSyncActivity.java 2014-01-22 16:22:19 +0000
41+++ src/ru/orangesoftware/financisto/activity/FlowzrSyncActivity.java 2014-05-17 07:00:19 +0000
42@@ -8,18 +8,15 @@
43 package ru.orangesoftware.financisto.activity;
44
45
46+
47 import static ru.orangesoftware.financisto.utils.NetworkUtils.isOnline;
48
49-
50 import java.io.IOException;
51 import java.util.Date;
52 import java.util.List;
53
54 import org.apache.http.impl.client.DefaultHttpClient;
55
56-import com.google.android.gms.common.ConnectionResult;
57-import com.google.android.gms.common.GooglePlayServicesUtil;
58-import com.google.android.gms.gcm.GoogleCloudMessaging;
59 import ru.orangesoftware.financisto.R;
60 import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
61 import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncOptions;
62@@ -54,6 +51,11 @@
63 import android.widget.RadioButton;
64 import android.widget.RadioGroup;
65 import android.widget.TextView;
66+import android.widget.Toast;
67+
68+import com.google.android.gms.common.ConnectionResult;
69+import com.google.android.gms.common.GooglePlayServicesUtil;
70+import com.google.android.gms.gcm.GoogleCloudMessaging;
71
72
73 public class FlowzrSyncActivity extends Activity {
74@@ -102,29 +104,31 @@
75
76 public void setIsFinished() {
77 setReady();
78- ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE);
79- List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
80- ComponentName componentInfo = taskInfo.get(0).topActivity;
81- if (taskInfo.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
82- startActivity(new Intent(getApplicationContext(), MainActivity.class));
83- } else if (taskInfo.get(0).topActivity.getShortClassName().equals(".BudgetListActivity.class")) {
84- startActivity(new Intent(getApplicationContext(), BudgetListActivity.class));
85- }
86+ if (MainActivity.activity !=null) {
87+ runOnUiThread(new Runnable() {
88+ public void run() {
89+ ((MainActivity)MainActivity.activity).refreshCurrentTab();
90+ }
91+ });
92+
93+ }
94 }
95
96 public void setReady() {
97 runOnUiThread(new Runnable() {
98 public void run() {
99 TextView tv = (TextView) findViewById(R.id.sync_was);
100- if (flowzrSyncEngine!=null && flowzrSyncEngine.options!=null) {
101- tv.setText(getString(R.string.flowzr_sync_was) + " " + new Date(flowzrSyncEngine.options.last_sync_ts).toLocaleString());
102- }
103+ //SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
104+ //lastSyncLocalTimestamp=preferences.getLong(FlowzrSyncOptions.PROPERTY_LAST_SYNC_TIMESTAMP,0);
105+ lastSyncLocalTimestamp=MyPreferences.getFlowzrLastSync(FlowzrSyncActivity.this)+ 1400236028;
106+
107+ tv.setText(getString(R.string.flowzr_sync_was) + " " + new Date(lastSyncLocalTimestamp).toLocaleString());
108+
109 bOk.setText(R.string.ok);
110 bOk.setEnabled(true);
111 CheckBox chk=(CheckBox)findViewById(R.id.chk_sync_from_zero);
112 chk.setChecked(false);
113 setProgressBarIndeterminateVisibility(false);
114-
115 }
116 });
117 }
118@@ -134,42 +138,13 @@
119 tv.setText(getString(R.string.flowzr_sync_was) + " " + new Date(lastTime).toLocaleString());
120 }
121
122- public void notifyUser(final String msg, final int pct) {
123- mNotifyBuilder.setContentText(msg);
124- if (pct!=0) {
125- mNotifyBuilder.setProgress(100, pct,false);
126- }
127- nm.notify(NOTIFICATION_ID, mNotifyBuilder.build());
128
129- if (flowzrSyncTask.mProgress!=null) {
130- runOnUiThread(new Runnable() {
131- @Override
132- public void run() {
133- if (pct!=0) {
134- flowzrSyncTask.mProgress.setProgress(pct);
135- }
136- flowzrSyncTask.mProgress.setMessage(msg);
137- }
138- });
139- }
140- }
141-
142-// @Override
143-// public void onBackPressed() {
144-// startActivity(new Intent(this, MainActivity.class));
145-// }
146
147 public static FlowzrSyncActivity getMySelf() {
148 return FlowzrSyncActivity.me;
149 }
150
151- @Override
152- public void onDestroy(){
153- super.onDestroy();
154- if ( flowzrSyncTask!=null && flowzrSyncTask.mProgress!=null && flowzrSyncTask.mProgress.isShowing() ){
155- flowzrSyncTask.mProgress.cancel();
156- }
157- }
158+
159
160 public void initProgressDialog() {
161 Intent notificationIntent = new Intent(getApplicationContext(),FlowzrSyncActivity.class);
162@@ -190,15 +165,12 @@
163 protected void onCreate(Bundle savedInstanceState) {
164 super.onCreate(savedInstanceState);
165 FlowzrSyncActivity.me=this;
166+
167 mNotifyBuilder = new NotificationCompat.Builder(getApplicationContext());
168 nm = (NotificationManager) getApplicationContext()
169 .getSystemService(Context.NOTIFICATION_SERVICE);
170 setContentView(R.layout.flowzr_sync);
171 restoreUIFromPref();
172- if (useCredential!=null) {
173-
174- }
175-
176
177 AccountManager accountManager = AccountManager.get(getApplicationContext());
178 final Account[] accounts = accountManager.getAccountsByType("com.google");
179@@ -233,8 +205,10 @@
180 radioGroupCredentials.addView(rb); //, 0, lp);
181 rb.setOnClickListener(radio_listener);
182 rb.setText(((Account) accounts[i]).name);
183- if (useCredential!=null) {
184- if ( accounts[i].name.equals(useCredential.name)) {
185+ String prefAccount=MyPreferences.getFlowzrAccount(this);
186+ if (prefAccount!=null) {
187+ if ( accounts[i].name.equals(prefAccount)) {
188+ useCredential=accounts[i];
189 rb.toggle(); //.setChecked(true);
190 }
191 }
192@@ -243,29 +217,8 @@
193 bOk = (Button) findViewById(R.id.bOK);
194 bOk.setOnClickListener(new View.OnClickListener() {
195 public void onClick(View view) {
196-
197- setRunning();
198- initProgressDialog();
199-// if (useCredential!=null) {
200-// flowzrBilling=new FlowzrBilling(FlowzrSyncActivity.this, getApplicationContext(), http_client, useCredential.toString());
201-// }
202- if (useCredential==null) {
203- showErrorPopup(FlowzrSyncActivity.this, R.string.flowzr_choose_account);
204- notifyUser(getString(R.string.flowzr_choose_account), 100);
205- setReady();
206- } else if (!isOnline(FlowzrSyncActivity.this)) {
207- showErrorPopup(FlowzrSyncActivity.this, R.string.flowzr_sync_error_no_network);
208- notifyUser(getString(R.string.flowzr_sync_error_no_network), 100);
209- setReady();
210- } else {
211- saveOptionsFromUI();
212- //Play Service Billing
213- //FlowzrBilling flowzrBilling = new FlowzrBilling(FlowzrSyncActivity.this, getApplicationContext(), http_client, useCredential.toString());
214- //if (flowzrSyncTask.checkSubscription()) {
215- flowzrSyncEngine=new FlowzrSyncEngine(FlowzrSyncActivity.this);
216- //}
217-
218- }
219+ startSync();
220+
221 }
222 });
223
224@@ -323,6 +276,42 @@
225 }
226 }
227
228+
229+ public void startSync () {
230+ if (FlowzrSyncEngine.isRunning) {
231+ Toast.makeText(this, R.string.flowzr_sync_inprogress, Toast.LENGTH_SHORT).show();
232+ return;
233+ }
234+ String accountName=useCredential.name;
235+ MyPreferences.setFlowzrAccount(getApplicationContext(), accountName);
236+ if (accountName == null) {
237+ Toast.makeText(this, R.string.flowzr_choose_account, Toast.LENGTH_SHORT).show();
238+ return;
239+ }
240+ if (isOnline(FlowzrSyncActivity.this)) {
241+ //checkPlayServices();
242+ } else {
243+ showErrorPopup(FlowzrSyncActivity.this, R.string.flowzr_sync_error_no_network);
244+ return;
245+ }
246+
247+ if (FlowzrSyncEngine.isRunning) {
248+ showErrorPopup(FlowzrSyncActivity.this, R.string.flowzr_sync_auth_inprogress);
249+ return;
250+ }
251+
252+ Thread myThread = new Thread(new Runnable(){
253+ @Override
254+ public void run()
255+ {
256+ Object o = new FlowzrSyncTask(FlowzrSyncActivity.this).execute();
257+ }
258+ });
259+ myThread.start();
260+ Toast.makeText(this, R.string.flowzr_sync_inprogress, Toast.LENGTH_SHORT).show();
261+ finish();
262+ }
263+
264 private String getRegistrationId(Context context) {
265 final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
266 String registrationId = prefs.getString(PROPERTY_REG_ID, "");
267@@ -439,11 +428,7 @@
268 super.onResume();
269 if (this.isRunning) {
270 setRunning();
271- try {
272- flowzrSyncTask.mProgress.show();
273- } catch(Exception e) {
274- Log.e(TAG,"avoid a leaked window (2)");
275- }
276+
277 } else {
278 setReady();
279 }
280@@ -461,12 +446,7 @@
281 .setCancelable(true)
282 .create().show();
283 }
284-
285-
286- protected void updateResultIntentFromUi(Intent data) {
287- data.putExtra(FlowzrSyncOptions.PROPERTY_LAST_SYNC_TIMESTAMP, lastSyncLocalTimestamp);
288- data.putExtra(FlowzrSyncOptions.PROPERTY_USE_CREDENTIAL, useCredential.name);
289- }
290+
291
292 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
293 if (requestCode == FLOWZR_SYNC_REQUEST_CODE) {
294@@ -491,7 +471,8 @@
295
296 protected void restoreUIFromPref() {
297 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
298- lastSyncLocalTimestamp=preferences.getLong(FlowzrSyncOptions.PROPERTY_LAST_SYNC_TIMESTAMP,0);
299+ lastSyncLocalTimestamp=MyPreferences.getFlowzrLastSync(getApplicationContext());
300+ preferences.getLong(FlowzrSyncOptions.PROPERTY_LAST_SYNC_TIMESTAMP,0);
301 AccountManager accountManager = AccountManager.get(getApplicationContext());
302 Account[] accounts = accountManager.getAccountsByType("com.google");
303 for (Account account : accounts) {
304@@ -501,6 +482,7 @@
305 }
306 TextView tv = (TextView) findViewById(R.id.sync_was);
307 tv.setText(getString(R.string.flowzr_sync_was) + " " + new Date(lastSyncLocalTimestamp).toLocaleString());
308+
309 }
310
311 private boolean checkPlayServices() {
312
313=== modified file 'src/ru/orangesoftware/financisto/activity/MainActivity.java'
314--- src/ru/orangesoftware/financisto/activity/MainActivity.java 2014-01-27 17:08:36 +0000
315+++ src/ru/orangesoftware/financisto/activity/MainActivity.java 2014-05-17 07:00:19 +0000
316@@ -10,6 +10,7 @@
317 ******************************************************************************/
318 package ru.orangesoftware.financisto.activity;
319
320+import android.app.Activity;
321 import android.app.AlertDialog;
322 import android.app.ProgressDialog;
323 import android.app.TabActivity;
324@@ -48,6 +49,7 @@
325 import ru.orangesoftware.financisto.export.dropbox.DropboxBackupTask;
326 import ru.orangesoftware.financisto.export.dropbox.DropboxListFilesTask;
327 import ru.orangesoftware.financisto.export.dropbox.DropboxRestoreTask;
328+import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
329 import ru.orangesoftware.financisto.export.qif.QifExportOptions;
330 import ru.orangesoftware.financisto.export.qif.QifExportTask;
331 import ru.orangesoftware.financisto.export.qif.QifImportOptions;
332@@ -84,9 +86,14 @@
333 private static final int MENU_CLOUD_SYNC = Menu.FIRST + 15;
334 private static final int MENU_BACKUP_RESTORE_ONLINE = Menu.FIRST + 16;
335
336+ public static Activity activity ;
337+
338 @Override
339 protected void onCreate(Bundle savedInstanceState) {
340 super.onCreate(savedInstanceState);
341+
342+ activity=this;
343+
344 requestWindowFeature(Window.FEATURE_NO_TITLE);
345
346 initialLoad();
347@@ -203,7 +210,7 @@
348 Log.d("Financisto", "Tab " + tabId + " updated in " + (t1 - t0) + "ms");
349 }
350
351- private void refreshCurrentTab() {
352+ public void refreshCurrentTab() {
353 Context c = getTabHost().getCurrentView().getContext();
354 if (c instanceof RefreshSupportedActivity) {
355 RefreshSupportedActivity activity = (RefreshSupportedActivity) c;
356@@ -474,6 +481,10 @@
357 new DriveListFilesTask(this, d).execute();
358 }
359
360+ private void doBackupPicture() {
361+ FlowzrSyncEngine.pushAllBlobs();
362+ }
363+
364 public void doImportFromGoogleDrive(final com.google.api.services.drive.model.File[] backupFiles) {
365 if (backupFiles != null) {
366 String[] backupFilesNames = getBackupFilesTitles(backupFiles);
367@@ -653,8 +664,15 @@
368 public void execute(MainActivity mainActivity) {
369 mainActivity.doRestoreFromDropbox();
370 }
371+ },
372+ PICTURE_BACKUP(R.string.googledrive_upload, R.drawable.ic_menu_forward) {
373+ @Override
374+ public void execute(MainActivity mainActivity) {
375+ mainActivity.doBackupPicture();
376+ }
377 };
378-
379+
380+
381 private final int titleId;
382 private final int iconId;
383
384
385=== modified file 'src/ru/orangesoftware/financisto/export/docs/DriveBackupTask.java'
386--- src/ru/orangesoftware/financisto/export/docs/DriveBackupTask.java 2014-01-27 15:52:09 +0000
387+++ src/ru/orangesoftware/financisto/export/docs/DriveBackupTask.java 2014-05-17 07:00:19 +0000
388@@ -42,7 +42,8 @@
389 if (folder == null || folder.equals("")) {
390 throw new ImportExportException(R.string.gdocs_folder_not_configured);
391 }
392- Drive drive = GoogleDriveClient.create(context);
393+ String googleDriveAccount = MyPreferences.getGoogleDriveAccount(context);
394+ Drive drive = GoogleDriveClient.create(context, googleDriveAccount);
395 return export.exportOnline(drive, folder);
396 } catch (ImportExportException e) {
397 throw e;
398
399=== modified file 'src/ru/orangesoftware/financisto/export/docs/DriveListFilesTask.java'
400--- src/ru/orangesoftware/financisto/export/docs/DriveListFilesTask.java 2014-01-27 15:52:09 +0000
401+++ src/ru/orangesoftware/financisto/export/docs/DriveListFilesTask.java 2014-05-17 07:00:19 +0000
402@@ -45,8 +45,8 @@
403 @Override
404 protected File[] doInBackground(Void... contexts) {
405 try {
406- Drive drive = GoogleDriveClient.create(context);
407-
408+ String googleDriveAccount = MyPreferences.getGoogleDriveAccount(context);
409+ Drive drive = GoogleDriveClient.create(context,googleDriveAccount);
410 String targetFolder = MyPreferences.getBackupFolder(context);
411
412 if (targetFolder == null || targetFolder.equals("")) {
413
414=== modified file 'src/ru/orangesoftware/financisto/export/docs/DriveRestoreTask.java'
415--- src/ru/orangesoftware/financisto/export/docs/DriveRestoreTask.java 2014-01-27 17:08:36 +0000
416+++ src/ru/orangesoftware/financisto/export/docs/DriveRestoreTask.java 2014-05-17 07:00:19 +0000
417@@ -8,11 +8,8 @@
418
419 package ru.orangesoftware.financisto.export.docs;
420
421-import android.app.ProgressDialog;
422-import android.content.Context;
423-import com.google.android.gms.auth.GoogleAuthException;
424-import com.google.api.services.drive.Drive;
425-import com.google.api.services.drive.model.File;
426+import java.io.IOException;
427+
428 import ru.orangesoftware.financisto.R;
429 import ru.orangesoftware.financisto.activity.MainActivity;
430 import ru.orangesoftware.financisto.backup.DatabaseImport;
431@@ -20,8 +17,13 @@
432 import ru.orangesoftware.financisto.export.ImportExportAsyncTask;
433 import ru.orangesoftware.financisto.export.ImportExportAsyncTaskListener;
434 import ru.orangesoftware.financisto.export.ImportExportException;
435+import ru.orangesoftware.financisto.utils.MyPreferences;
436+import android.app.ProgressDialog;
437+import android.content.Context;
438
439-import java.io.IOException;
440+import com.google.android.gms.auth.GoogleAuthException;
441+import com.google.api.services.drive.Drive;
442+import com.google.api.services.drive.model.File;
443
444 /**
445 * Created by IntelliJ IDEA.
446@@ -46,7 +48,8 @@
447 @Override
448 protected Object work(Context context, DatabaseAdapter db, String... params) throws Exception {
449 try {
450- Drive drive = GoogleDriveClient.create(context);
451+ String googleDriveAccount = MyPreferences.getGoogleDriveAccount(context);
452+ Drive drive = GoogleDriveClient.create(context,googleDriveAccount);
453 DatabaseImport.createFromGoogleDriveBackup(context, db, drive, entry).importDatabase();
454 } catch (ImportExportException e) {
455 throw e;
456
457=== modified file 'src/ru/orangesoftware/financisto/export/docs/GoogleDriveClient.java'
458--- src/ru/orangesoftware/financisto/export/docs/GoogleDriveClient.java 2014-01-27 15:52:09 +0000
459+++ src/ru/orangesoftware/financisto/export/docs/GoogleDriveClient.java 2014-05-17 07:00:19 +0000
460@@ -37,8 +37,7 @@
461 */
462 public class GoogleDriveClient {
463
464- public static Drive create(Context context) throws IOException, GoogleAuthException, ImportExportException {
465- String googleDriveAccount = MyPreferences.getGoogleDriveAccount(context);
466+ public static Drive create(Context context, String googleDriveAccount) throws IOException, GoogleAuthException, ImportExportException {
467 if (googleDriveAccount == null) {
468 throw new ImportExportException(R.string.google_drive_account_required);
469 }
470
471=== modified file 'src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncEngine.java'
472--- src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncEngine.java 2014-01-21 12:29:20 +0000
473+++ src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncEngine.java 2014-05-17 07:00:19 +0000
474@@ -9,19 +9,14 @@
475 */
476
477
478-import java.io.BufferedInputStream;
479 import java.io.BufferedReader;
480-import java.io.FileInputStream;
481 import java.io.IOException;
482 import java.io.InputStream;
483 import java.io.InputStreamReader;
484 import java.io.PrintWriter;
485 import java.io.StringWriter;
486 import java.io.UnsupportedEncodingException;
487-import java.net.URLEncoder;
488 import java.util.ArrayList;
489-import java.util.Arrays;
490-import java.util.Calendar;
491 import java.util.Collection;
492 import java.util.Date;
493 import java.util.LinkedList;
494@@ -36,8 +31,6 @@
495 import org.apache.http.client.entity.UrlEncodedFormEntity;
496 import org.apache.http.client.methods.HttpGet;
497 import org.apache.http.client.methods.HttpPost;
498-import org.apache.http.client.params.ClientPNames;
499-import org.apache.http.cookie.Cookie;
500 import org.apache.http.entity.StringEntity;
501 import org.apache.http.impl.client.DefaultHttpClient;
502 import org.apache.http.message.BasicNameValuePair;
503@@ -46,37 +39,14 @@
504 import org.json.JSONException;
505 import org.json.JSONObject;
506
507-import android.accounts.AccountManager;
508-import android.accounts.AccountManagerCallback;
509-import android.accounts.AccountManagerFuture;
510-import android.accounts.AuthenticatorException;
511-import android.accounts.OperationCanceledException;
512-import android.app.NotificationManager;
513-import android.app.PendingIntent;
514-import android.content.ContentValues;
515-import android.content.Context;
516-import android.content.Intent;
517-import android.content.SharedPreferences;
518-import android.content.pm.PackageManager.NameNotFoundException;
519-import android.database.Cursor;
520-import android.database.sqlite.SQLiteDatabase;
521-import android.net.Uri;
522-import android.os.AsyncTask;
523-import android.os.Bundle;
524-import android.os.Environment;
525-
526-import android.preference.PreferenceManager;
527-import android.support.v4.app.NotificationCompat;
528-import android.support.v4.app.NotificationCompat.Builder;
529-import android.text.Html;
530-import android.util.Log;
531-
532 import ru.orangesoftware.financisto.R;
533 import ru.orangesoftware.financisto.activity.AccountWidget;
534 import ru.orangesoftware.financisto.activity.FlowzrSyncActivity;
535+import ru.orangesoftware.financisto.activity.MainActivity;
536 import ru.orangesoftware.financisto.db.DatabaseAdapter;
537 import ru.orangesoftware.financisto.db.DatabaseHelper;
538 import ru.orangesoftware.financisto.db.MyEntityManager;
539+import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncTask.GetAuthTokenCallback;
540 import ru.orangesoftware.financisto.model.Account;
541 import ru.orangesoftware.financisto.model.Attribute;
542 import ru.orangesoftware.financisto.model.Budget;
543@@ -93,164 +63,142 @@
544 import ru.orangesoftware.financisto.utils.CurrencyCache;
545 import ru.orangesoftware.financisto.utils.IntegrityFix;
546 import ru.orangesoftware.financisto.utils.MyPreferences;
547+import android.app.Notification;
548+import android.app.NotificationManager;
549+import android.app.PendingIntent;
550+import android.content.ContentValues;
551+import android.content.Context;
552+import android.content.Intent;
553+import android.content.SharedPreferences;
554+import android.database.Cursor;
555+import android.database.sqlite.SQLiteDatabase;
556+import android.net.Uri;
557+import android.os.Environment;
558+import android.os.Handler;
559+import android.os.Looper;
560+import android.preference.PreferenceManager;
561+import android.support.v4.app.NotificationCompat;
562+import android.text.Html;
563+import android.util.Log;
564
565-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
566-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncOptions;
567-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncTask;
568-import com.google.api.client.extensions.android.http.AndroidHttp;
569-import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
570-import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
571-import com.google.api.client.http.InputStreamContent;
572-import com.google.api.client.json.gson.GsonFactory;
573-import com.google.api.services.drive.Drive;
574-import com.google.api.services.drive.DriveScopes;
575-import com.google.api.services.drive.model.File;
576-import com.google.api.services.drive.model.FileList;
577-import com.google.api.services.drive.model.ParentReference;
578 import com.google.gson.stream.JsonReader;
579 import com.google.gson.stream.JsonToken;
580
581 public class FlowzrSyncEngine {
582 private static String TAG="flowzr";
583- private final String FLOWZR_MSG_NET_ERROR="FLOWZR_MSG_NET_ERROR";
584+ private final static String FLOWZR_MSG_NET_ERROR="FLOWZR_MSG_NET_ERROR";
585
586- private final SQLiteDatabase db;
587- private final DatabaseAdapter dba;
588- private final MyEntityManager em;
589- private DefaultHttpClient http_client;
590+ private static SQLiteDatabase db;
591+ private static DatabaseAdapter dba;
592+
593+ private static MyEntityManager em;
594 static InputStream isHttpcontent = null;
595 static JSONObject jObj = null;
596 static String json = "";
597- private final long KEY_CREATE=-1;
598+ private final static long KEY_CREATE=-1;
599
600- private Context context;
601- private FlowzrSyncActivity flowzrSyncActivity;
602-
603- private String[] tableNames= {"attributes","currency","project","payee","account","LOCATIONS","category","transactions",DatabaseHelper.BUDGET_TABLE};
604- private Class[] clazzArray = {Attribute.class,Currency.class,Project.class,Payee.class,Account.class,MyLocation.class,Category.class,Transaction.class,Budget.class};
605+ private static Context context;
606+
607+ private static String[] tableNames= {"attributes","currency","project","payee","account","LOCATIONS","category","transactions",DatabaseHelper.BUDGET_TABLE, "currency_exchange_rate"};
608+ private static Class[] clazzArray = {Attribute.class,Currency.class,Project.class,Payee.class,Account.class,MyLocation.class,Category.class,Transaction.class,Budget.class,ExchangeRate.class};
609
610- private int MAX_PULL_SIZE=50;
611- private int MAX_PUSH_SIZE=20;
612+ private static int MAX_PULL_SIZE=50;
613+ private static int MAX_PUSH_SIZE=20;
614 static JsonReader reader = null;
615 static InputStream is = null;
616 static final int REQUEST_AUTHORIZATION = 2;
617
618- public String rootFolderId=null;
619+ public static String rootFolderId=null;
620 static final int REQUEST_ACCOUNT_PICKER = 8;
621- private static Drive driveService;
622- private GoogleAccountCredential credential;
623+
624 public static final java.io.File PICTURES_DIR = new java.io.File(Environment.getExternalStorageDirectory(), "financisto/pictures");
625- private static final int SYNC_NOTIFICATION_ID = 0;
626-
627- public FlowzrSyncTask flowzrSyncTask;
628- public FlowzrSyncOptions options;
629- public boolean isCanceled=false;
630-
631-
632- public FlowzrSyncEngine(FlowzrSyncActivity a) {
633- android.accounts.Account useCredential = null;
634- if (a==null) {
635- a=(FlowzrSyncActivity) FlowzrSyncActivity.getMySelf();
636- }
637- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(a);
638- this.options = FlowzrSyncOptions.fromPrefs(preferences);
639- this.context=a;
640- this.flowzrSyncActivity=a;
641- FlowzrSyncActivity.isRunning=true;
642- this.dba = new DatabaseAdapter(context);
643- dba.open();
644- this.em=dba.em();
645- this.db = dba.db();
646-
647- if (flowzrSyncActivity==null) {
648- Log.i(TAG,"No activity found, creating.");
649- Intent intent = new Intent(context, FlowzrSyncActivity.class);
650- context.startActivity(intent);
651- return;
652- }
653-
654- http_client=new DefaultHttpClient();
655-
656- if (options.appVersion==null) {
657- try {
658- options.appVersion=context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
659- } catch (NameNotFoundException e) {
660- options.appVersion="undef";
661- e.printStackTrace();
662- }
663- }
664- Log.i(TAG,"init sync engine, last sync was " + new Date(FlowzrSyncOptions.last_sync_ts).toLocaleString());
665-
666- AccountManager accountManager = AccountManager.get(context);
667- android.accounts.Account[] accounts = accountManager.getAccountsByType("com.google");
668- for (int i = 0; i < accounts.length; i++) {
669- if (preferences.getString(FlowzrSyncOptions.PROPERTY_USE_CREDENTIAL,"").equals(((android.accounts.Account) accounts[i]).name)) {
670- useCredential=accounts[i];
671- }
672- }
673- if (useCredential!=null) {
674- AccountManager.get(context).getAuthToken(useCredential, "ah" , null,
675- flowzrSyncActivity, new GetAuthTokenCallback(), null);
676- } else {
677- Log.e(TAG,"No account selected");
678+ public static boolean isCanceled=false;
679+ public static boolean isRunning=false;
680+
681+ public static NotificationManager mNotificationManager;
682+ public static NotificationCompat.Builder mNotifyBuilder;
683+ public static final int NOTIFICATION_ID=666;
684+ public static final int NOTIFICATION_ID2=667;
685+ public static DefaultHttpClient http_client;
686+ public static long last_sync_ts;
687+ public static long startTimestamp;
688+ public static String nsString; // used to identify a book on Flowzr
689+
690+ public static String FLOWZR_BASE_URL="https://flowzr-hrd.appspot.com/";
691+ public static String FLOWZR_API_URL="https://flowzr-hrd.appspot.com/financisto3/";
692+
693+ public static MainActivity currentActivity = null;
694+
695+ public synchronized static void setUpdatable(MainActivity updatable) {
696+ currentActivity = updatable;
697+ }
698+
699+ public static String create(Context p_context,DatabaseAdapter p_dba, DefaultHttpClient p_http) {
700+ startTimestamp=System.currentTimeMillis();
701+
702+ if (isRunning==true) {
703+ isCanceled=true;
704+ isRunning=false;
705 }
706- }
707-
708- static String getStackTrace(Throwable t) {
709- StringWriter sw = new StringWriter();
710- PrintWriter pw = new PrintWriter(sw, true);
711- t.printStackTrace(pw);
712- pw.flush();
713- sw.flush();
714- return sw.toString();
715- }
716-
717- public void sendBackTrace(Exception result) {
718- final String msg=getStackTrace((Exception)result);
719- ((Exception)result).printStackTrace();
720-
721- Thread trd = new Thread(new Runnable(){
722- @Override
723- public void run(){
724- ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
725- nameValuePairs.add(new BasicNameValuePair("action","error"));
726- nameValuePairs.add(new BasicNameValuePair("stack",msg));
727- HttpPost httppost = new HttpPost(FlowzrSyncOptions.FLOWZR_API_URL + options.getNamespace() + "/error/");
728- try {
729- httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
730- } catch (UnsupportedEncodingException e) {
731- e.printStackTrace();
732- }
733- try {
734- http_client.execute(httppost);
735- } catch (ClientProtocolException e1) {
736- e1.printStackTrace();
737- } catch (IOException e1) {
738- e1.printStackTrace();
739- } catch (Exception e) {
740- e.printStackTrace();
741- }
742- }
743- });
744- trd.start();
745- return;
746- }
747-
748- public void doSync() {
749- FlowzrSyncOptions.startTimestamp=System.currentTimeMillis();
750- FlowzrSyncActivity.isRunning=true;
751+ isRunning=true;
752 boolean recordSyncTime=true;
753+
754+ dba=p_dba;
755+ db=dba.db();
756+ em=dba.em();
757+ http_client=p_http;
758+ context=p_context;
759+
760+ last_sync_ts=MyPreferences.getFlowzrLastSync(context);
761+ FLOWZR_BASE_URL="https://" + MyPreferences.getSyncApiUrl(context);
762+ FLOWZR_API_URL=FLOWZR_BASE_URL + "/financisto3/";
763+
764+ nsString=MyPreferences.getFlowzrAccount(context).replace("@", "_"); //urlsafe
765+
766+ Log.i(TAG,"init sync engine, last sync was " + new Date(last_sync_ts).toLocaleString());
767+ //if (true) {
768+ if (!checkSubscriptionFromWeb()) {
769+ Intent notificationIntent = new Intent(context,
770+ FlowzrSyncActivity.class);
771+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
772+ notificationIntent, 0);
773+
774+ NotificationManager notificationManager = (NotificationManager) context
775+ .getSystemService(Context.NOTIFICATION_SERVICE);
776+ Notification notification = new NotificationCompat.Builder(context)
777+ .setSmallIcon(R.drawable.icon)
778+ .setTicker(context.getString(R.string.flowzr_subscription_required))
779+ .setContentTitle(context.getString(R.string.flowzr_sync_error))
780+ .setContentText(context.getString(R.string.flowzr_subscription_required, MyPreferences.getFlowzrAccount(context)))
781+ .setContentIntent(pendingIntent).setAutoCancel(true).build();
782+ notificationManager.notify(0, notification);
783+
784+ Log.w("flowzr","subscription rejected from web");
785+ isCanceled=true;
786+ MyPreferences.unsetAutoSync(context);
787+ return null;
788+ } else {
789+ mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
790+ // Sets an ID for the notification, so it can be updated
791+
792+ mNotifyBuilder = new NotificationCompat.Builder(context)
793+ .setAutoCancel(true)
794+ .setContentTitle(context.getString(R.string.flowzr_sync))
795+ .setContentText(context.getString(R.string.flowzr_sync_inprogress))
796+ .setSmallIcon(R.drawable.icon);
797+ }
798+
799 if (!isCanceled) {
800- flowzrSyncActivity.notifyUser("fix created entities",5);
801+ notifyUser("fix created entities",5);
802 fixCreatedEntities();
803 }
804 /**
805 * pull delete
806 */
807 if (!isCanceled) {
808- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_receiving) + " ...",10);
809+ notifyUser(context.getString(R.string.flowzr_sync_receiving) + " ...",10);
810 try {
811- pullDelete(FlowzrSyncOptions.last_sync_ts);
812+ pullDelete(last_sync_ts);
813 } catch (Exception e) {
814 sendBackTrace(e);
815 recordSyncTime=false;
816@@ -260,7 +208,7 @@
817 * push delete
818 */
819 if (!isCanceled) {
820- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_sending) + " ...",15);
821+ notifyUser(context.getString(R.string.flowzr_sync_sending) + " ...",15);
822 try {
823 pushDelete();
824 } catch (Exception e) {
825@@ -271,8 +219,8 @@
826 /**
827 * pull update
828 */
829- if (!isCanceled && FlowzrSyncOptions.last_sync_ts==0) {
830- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_receiving) + " ...",20);
831+ if (!isCanceled && last_sync_ts==0) {
832+ notifyUser(context.getString(R.string.flowzr_sync_receiving) + " ...",20);
833 try {
834 pullUpdate();
835 } catch (IOException e) {
836@@ -290,7 +238,7 @@
837 * push update
838 */
839 if (!isCanceled) {
840- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_sending) + " ...",35);
841+ notifyUser(context.getString(R.string.flowzr_sync_sending) + " ...",35);
842 try {
843 pushUpdate();
844 } catch (ClientProtocolException e) {
845@@ -309,8 +257,8 @@
846 /**
847 * pull update
848 */
849- if (!isCanceled && FlowzrSyncOptions.last_sync_ts>0) {
850- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_receiving) + " ...",20);
851+ if (!isCanceled && last_sync_ts>0) {
852+ notifyUser(context.getString(R.string.flowzr_sync_receiving) + " ...",20);
853 try {
854 pullUpdate();
855 } catch (IOException e) {
856@@ -330,62 +278,158 @@
857 */
858 if (!isCanceled) {
859 //if (true) { //will generate a Cloud Messaging request if prev. aborted
860- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_sending) + "..." ,80);
861+ notifyUser(context.getString(R.string.flowzr_sync_sending) + "..." ,80);
862 //nm.notify(NOTIFICATION_ID, mNotifyBuilder.build());
863 ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
864 nameValuePairs.add(new BasicNameValuePair("action","balancesRecalc"));
865- nameValuePairs.add(new BasicNameValuePair("last_sync_ts",String.valueOf(FlowzrSyncOptions.last_sync_ts)));
866+ nameValuePairs.add(new BasicNameValuePair("last_sync_ts",String.valueOf(last_sync_ts)));
867 try {
868 httpPush(nameValuePairs,"balances");
869 } catch (Exception e) {
870 sendBackTrace(e);
871 }
872 }
873- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.integrity_fix),85);
874+ notifyUser(context.getString(R.string.integrity_fix),85);
875 new IntegrityFix(dba).fix();
876- flowzrSyncActivity.notifyUser("Widgets ...",90);
877+
878+ notifyUser("Widgets ...",90);
879 AccountWidget.updateWidgets(context);
880+
881+
882+ Handler refresh = new Handler(Looper.getMainLooper());
883+ refresh.post(new Runnable() {
884+ public void run()
885+ {
886+ if (currentActivity !=null) {
887+ //currentActivity.refreshCurrentTab();
888+ }
889+ }
890+ });
891+
892+
893 if (!isCanceled && MyPreferences.doGoogleDriveUpload(context)) {
894- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_sending) + " Google Drive",95);
895+ notifyUser(context.getString(R.string.flowzr_sync_sending) + " Google Drive",95);
896 pushAllBlobs();
897- }
898+ } else {
899+ Log.i("flowzr","picture upload desactivated in prefs");
900+ }
901+ notifyUser(context.getString(R.string.flowzr_sync_success),100);
902 if (isCanceled==false) {
903 if (recordSyncTime==true) {
904- FlowzrSyncOptions.last_sync_ts=FlowzrSyncOptions.startTimestamp;
905+ last_sync_ts=System.currentTimeMillis();
906 SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
907- editor.putLong(FlowzrSyncOptions.PROPERTY_LAST_SYNC_TIMESTAMP, System.currentTimeMillis());
908+ editor.putLong("PROPERTY_LAST_SYNC_TIMESTAMP", last_sync_ts);
909 editor.commit();
910- }
911+ }
912 }
913- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_success),100);
914- FlowzrSyncActivity.isRunning=false;
915- flowzrSyncActivity.setIsFinished();
916- flowzrSyncActivity.renderLastTime(FlowzrSyncOptions.last_sync_ts);
917+ //
918+ mNotificationManager.cancel(NOTIFICATION_ID);
919+ isRunning=false;
920+ isCanceled=false;
921+ if (context instanceof FlowzrSyncActivity) {
922+ ((FlowzrSyncActivity)context).setIsFinished();
923+ }
924+ return FLOWZR_BASE_URL;
925+
926 }
927
928+ public static void resetLastTime () {
929+ SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
930+ if (editor!=null) {
931+ editor.putLong("PROPERTY_LAST_SYNC_TIMESTAMP", 0);
932+ editor.commit();
933+ }
934+ }
935+
936+ public static void notifyUser(final String msg, final int pct) {
937+ Intent notificationIntent = new Intent(context,
938+ FlowzrSyncActivity.class);
939+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
940+ notificationIntent, 0);
941+ if (mNotifyBuilder==null) {
942+ mNotifyBuilder = new NotificationCompat.Builder(context)
943+ .setAutoCancel(true)
944+ .setContentTitle(context.getString(R.string.app_name))
945+ .setContentText(context.getString(R.string.flowzr_sync_inprogress))
946+ .setSmallIcon(R.drawable.icon);
947+
948+ mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
949+ // Sets an ID for the notification, so it can be updated
950+ }
951+ mNotifyBuilder.setContentText(msg);
952+ mNotifyBuilder.setContentIntent(pendingIntent);
953+ mNotifyBuilder.setAutoCancel(true).build();
954+ if (pct!=0) {
955+ mNotifyBuilder.setProgress(100, pct,false);
956+ }
957+ mNotificationManager.notify(
958+ NOTIFICATION_ID,
959+ mNotifyBuilder.build());
960+ }
961+
962+ static String getStackTrace(Throwable t) {
963+ StringWriter sw = new StringWriter();
964+ PrintWriter pw = new PrintWriter(sw, true);
965+ t.printStackTrace(pw);
966+ pw.flush();
967+ sw.flush();
968+ return sw.toString();
969+ }
970+
971+ public static void sendBackTrace(Exception result) {
972+ final String msg=getStackTrace((Exception)result);
973+ ((Exception)result).printStackTrace();
974+
975+ Thread trd = new Thread(new Runnable(){
976+ @Override
977+ public void run(){
978+ ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
979+ nameValuePairs.add(new BasicNameValuePair("action","error"));
980+ nameValuePairs.add(new BasicNameValuePair("stack",msg));
981+ HttpPost httppost = new HttpPost(FLOWZR_API_URL + nsString + "/error/");
982+ try {
983+ httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
984+ } catch (UnsupportedEncodingException e) {
985+ e.printStackTrace();
986+ }
987+ try {
988+ http_client.execute(httppost);
989+ } catch (ClientProtocolException e1) {
990+ e1.printStackTrace();
991+ } catch (IOException e1) {
992+ e1.printStackTrace();
993+ } catch (Exception e) {
994+ e.printStackTrace();
995+ }
996+ }
997+ });
998+ trd.start();
999+ return;
1000+ }
1001+
1002 /*
1003 * Push job
1004 */
1005- private void pushUpdate() throws ClientProtocolException, IOException, JSONException, Exception {
1006+ private static void pushUpdate() throws ClientProtocolException, IOException, JSONException, Exception {
1007 int i=0;
1008 for (String t : tableNames) {
1009- flowzrSyncActivity.notifyUser("pushing " + t, 0);
1010+ notifyUser("pushing " + t, 0);
1011 pushUpdate(t,clazzArray[i]);
1012 i++;
1013 }
1014 }
1015
1016- private <T extends MyEntity> void pushUpdate(String tableName,Class<T> clazz) throws ClientProtocolException, IOException, JSONException, Exception {
1017+ private static <T extends MyEntity> void pushUpdate(String tableName,Class<T> clazz) throws ClientProtocolException, IOException, JSONException, Exception {
1018 SQLiteDatabase db2=dba.db();
1019 Cursor cursorCursor;
1020 String sql;
1021 long total;
1022
1023- sql="select count(*) from " + tableName + " where updated_on<0 or (updated_on > " + FlowzrSyncOptions.last_sync_ts + " and updated_on<" + options.startTimestamp + ")" ;
1024+ sql="select count(*) from " + tableName + " where updated_on<0 or (updated_on > " + last_sync_ts + " and updated_on<" + startTimestamp + ")" ;
1025 cursorCursor=db.rawQuery(sql, null);
1026 cursorCursor.moveToFirst();
1027 total=cursorCursor.getLong(0);
1028- sql="select * from " + tableName + " where updated_on<0 or (updated_on > " + FlowzrSyncOptions.last_sync_ts + " and updated_on<" + options.startTimestamp + ")";
1029+ sql="select * from " + tableName + " where updated_on<0 or (updated_on > " + last_sync_ts + " and updated_on<" + startTimestamp + ")";
1030
1031 if (tableName.equals(DatabaseHelper.TRANSACTION_TABLE)) {
1032 sql+= " order by parent_id asc,_id asc";
1033@@ -402,7 +446,7 @@
1034 if (cursorCursor.moveToFirst() && isCanceled!=true) {
1035 do {
1036 if (i%10==0) {
1037- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_sending) + " " + tableName, (int)(Math.round(i*100/total)));
1038+ notifyUser(context.getString(R.string.flowzr_sync_sending) + " " + tableName, (int)(Math.round(i*100/total)));
1039 }
1040 resultSet.put(cursorToDict(tableName,cursorCursor));
1041 i++;
1042@@ -430,11 +474,12 @@
1043 }
1044 }
1045
1046- public String makeRequest(String tableName, String json) throws ClientProtocolException, IOException, JSONException,Exception {
1047+ public static String makeRequest(String tableName, String json) throws ClientProtocolException, IOException, JSONException,Exception {
1048 if (isCanceled) {
1049 return FLOWZR_MSG_NET_ERROR;
1050 }
1051- String uri=FlowzrSyncOptions.FLOWZR_API_URL + options.getNamespace() + "/" + tableName + "/";
1052+
1053+ String uri=FLOWZR_API_URL + nsString + "/" + tableName + "/";
1054 String strResponse;
1055
1056 HttpPost httpPost = new HttpPost(uri);
1057@@ -445,18 +490,19 @@
1058 int code = response.getStatusLine().getStatusCode();
1059 BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
1060 strResponse = reader.readLine();
1061- JSONArray arr=new JSONArray();
1062- arr = new JSONArray(strResponse);
1063- for(int i = 0; i < arr.length(); i++){
1064- JSONObject o = arr.getJSONObject(i);
1065- String key=o.getString("key");
1066- int id=o.getInt("id");
1067- ContentValues args = new ContentValues();
1068- args.put("remote_key", key);
1069- db.update(tableName, args, String.format("%s = ?", "_id"),
1070- new String[]{String.valueOf(id)});
1071- }
1072-
1073+ if (!tableName.equals("currency_exchange_rate")) {
1074+ JSONArray arr=new JSONArray();
1075+ arr = new JSONArray(strResponse);
1076+ for(int i = 0; i < arr.length(); i++){
1077+ JSONObject o = arr.getJSONObject(i);
1078+ String key=o.getString("key");
1079+ int id=o.getInt("id");
1080+ ContentValues args = new ContentValues();
1081+ args.put("remote_key", key);
1082+ db.update(tableName, args, String.format("%s = ?", "_id"),
1083+ new String[]{String.valueOf(id)});
1084+ }
1085+ }
1086 entity.consumeContent();
1087 if (code!=200) {
1088 throw new Exception(Html.fromHtml(strResponse).toString());
1089@@ -465,7 +511,7 @@
1090 }
1091
1092
1093- private JSONObject cursorToDict(String tableName,Cursor c) {
1094+ private static JSONObject cursorToDict(String tableName,Cursor c) {
1095 int totalColumn = c.getColumnCount();
1096 JSONObject rowObject = new JSONObject();
1097 if (c.getColumnIndex("_id")!=-1) {
1098@@ -553,7 +599,7 @@
1099 return rowObject;
1100 }
1101
1102- public String getRemoteKey(String tableName,String localKey) {
1103+ public static String getRemoteKey(String tableName,String localKey) {
1104 if (localKey.equals("-1") || tableName==null) {
1105 return null;
1106 }
1107@@ -570,8 +616,8 @@
1108
1109
1110
1111- private String httpPush (ArrayList<NameValuePair> nameValuePairs,String action) throws Exception {
1112- HttpPost httppost = new HttpPost(FlowzrSyncOptions.FLOWZR_API_URL + options.getNamespace() + "/" + action + "/");
1113+ private static String httpPush (ArrayList<NameValuePair> nameValuePairs,String action) throws Exception {
1114+ HttpPost httppost = new HttpPost(FLOWZR_API_URL + nsString + "/" + action + "/");
1115 httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
1116 HttpResponse response;
1117 String strResponse;
1118@@ -593,18 +639,24 @@
1119 * it is not possible to make alter table add column updated with a default timestamp at current_timestamp
1120 * so default is set as zero and this pre-sync function make all 0 at last_sync_ts + 1
1121 */
1122- private void fixCreatedEntities() {
1123- long ctime=FlowzrSyncOptions.last_sync_ts + 1;
1124+ private static void fixCreatedEntities() {
1125+ long ctime=last_sync_ts + 1;
1126 for (String t : tableNames) {
1127 db.execSQL("update " + t + " set updated_on=" + ctime + " where updated_on=0");
1128 }
1129 }
1130
1131
1132- private String getTableForColName(String colName) {
1133+ private static String getTableForColName(String colName) {
1134 if (colName.equals("currency_id")) {
1135 return DatabaseHelper.CURRENCY_TABLE;
1136 }
1137+ if (colName.equals("from_currency_id")) {
1138+ return DatabaseHelper.CURRENCY_TABLE;
1139+ }
1140+ if (colName.equals("to_currency_id")) {
1141+ return DatabaseHelper.CURRENCY_TABLE;
1142+ }
1143 if (colName.equals("last_location_id")) {
1144 return DatabaseHelper.LOCATIONS_TABLE;
1145 }
1146@@ -712,7 +764,7 @@
1147 return null;
1148 }
1149
1150- private Object pushDelete() throws Exception {
1151+ private static Object pushDelete() throws Exception {
1152 String sql="select count(*) from " + DatabaseHelper.DELETE_LOG_TABLE ;
1153 Cursor cursorCursor=db.rawQuery(sql, null);
1154 cursorCursor.moveToFirst();
1155@@ -723,7 +775,7 @@
1156 String del_list="";
1157 if (cursor.moveToFirst()) {
1158 do {
1159- flowzrSyncActivity.notifyUser("push delete",(int)(Math.round(i*100/total)));
1160+ notifyUser("push delete",(int)(Math.round(i*100/total)));
1161 del_list+=cursor.getString(1) + ";";
1162 i++;
1163 } while (cursor.moveToNext());
1164@@ -744,7 +796,7 @@
1165 /**
1166 * Pull Job
1167 */
1168- private Object saveOrUpdateAttributeFromJSON(long localKey,
1169+ private static Object saveOrUpdateAttributeFromJSON(long localKey,
1170 JSONObject jsonObjectEntity) {
1171 if (!jsonObjectEntity.has("name")) {
1172 return null;
1173@@ -772,7 +824,7 @@
1174 }
1175 }
1176
1177- public <T> Object saveOrUpdateEntityFromJSON(Class<T> clazz,long id,JSONObject jsonObjectEntity) {
1178+ public static <T> Object saveOrUpdateEntityFromJSON(Class<T> clazz,long id,JSONObject jsonObjectEntity) {
1179 if (!jsonObjectEntity.has("name")) {
1180 return null;
1181 }
1182@@ -806,7 +858,7 @@
1183 }
1184 }
1185
1186- public <T> Object saveOrUpdateCategoryFromJSON(long id,JSONObject jsonObjectEntity) {
1187+ public static <T> Object saveOrUpdateCategoryFromJSON(long id,JSONObject jsonObjectEntity) {
1188 if (!jsonObjectEntity.has("name")) {
1189 return null;
1190 }
1191@@ -853,9 +905,10 @@
1192 }
1193 }
1194
1195- public Object saveOrUpdateCurrencyRateFromJSON(JSONObject jsonObjectEntity) {
1196+ public static Object saveOrUpdateCurrencyRateFromJSON(JSONObject jsonObjectEntity) {
1197+
1198 if (!jsonObjectEntity.has("effective_date")) {
1199- return null;
1200+ //return null;
1201 }
1202 try {
1203 long toCurrencyId= getLocalKey(DatabaseHelper.CURRENCY_TABLE, jsonObjectEntity.getString("to_currency"));
1204@@ -880,7 +933,7 @@
1205 return null;
1206 }
1207
1208- public Object saveOrUpdateBudgetFromJSON(long id,JSONObject jsonObjectEntity) throws JSONException {
1209+ public static Object saveOrUpdateBudgetFromJSON(long id,JSONObject jsonObjectEntity) throws JSONException {
1210 Budget tEntity=em.get(Budget.class, id);
1211 if (tEntity==null) {
1212 tEntity = new Budget();
1213@@ -1004,9 +1057,9 @@
1214 e.printStackTrace();
1215 }
1216 }
1217- if (jsonObjectEntity.has("parent_budget_id")) {
1218+ if (jsonObjectEntity.has("parentBudgetId")) {
1219 try {
1220- tEntity.parentBudgetId=getLocalKey(DatabaseHelper.BUDGET_TABLE, jsonObjectEntity.getString("parent_budget_id"));
1221+ tEntity.parentBudgetId=getLocalKey(DatabaseHelper.BUDGET_TABLE, jsonObjectEntity.getString("parentBudgetId"));
1222 } catch (Exception e) {
1223 Log.e(TAG,"Error parsing Budget.parentBudgetId ");
1224 e.printStackTrace();
1225@@ -1020,11 +1073,11 @@
1226 e.printStackTrace();
1227 }
1228 }
1229- em.insertBudget(tEntity);
1230+ em.saveOrUpdate(tEntity);
1231 return tEntity;
1232 }
1233
1234- public Object saveOrUpdateLocationFromJSON(long id,JSONObject jsonObjectEntity) {
1235+ public static Object saveOrUpdateLocationFromJSON(long id,JSONObject jsonObjectEntity) {
1236 MyLocation tEntity=em.get(MyLocation.class, id);
1237 if (tEntity==null) {
1238 tEntity=new MyLocation();
1239@@ -1085,7 +1138,7 @@
1240 }
1241
1242
1243- public Object saveOrUpdateCurrencyFromJSON(long id,JSONObject jsonObjectEntity) {
1244+ public static Object saveOrUpdateCurrencyFromJSON(long id,JSONObject jsonObjectEntity) {
1245 Currency tEntity=em.get(Currency.class, id);
1246 if (tEntity==null) {
1247 tEntity = Currency.EMPTY;
1248@@ -1149,7 +1202,7 @@
1249 }
1250 }
1251
1252- public Object saveOrUpdateAccountFromJSON(long id,JSONObject jsonObjectAccount) {
1253+ public static Object saveOrUpdateAccountFromJSON(long id,JSONObject jsonObjectAccount) {
1254
1255 Account tEntity=em.get(Account.class, id);
1256
1257@@ -1226,8 +1279,8 @@
1258 c=Currency.EMPTY;
1259 c.isDefault=true;
1260 tEntity.currency=c;
1261- c.id=-1; //db put!
1262- em.saveOrUpdate(c);
1263+ //c.id=-1; //db put!
1264+ //em.saveOrUpdate(c);
1265 }
1266 }
1267 CurrencyCache.initialize(em);
1268@@ -1287,7 +1340,7 @@
1269 }
1270 }
1271
1272- public Object saveOrUpdateTransactionFromJSON(long id,JSONObject jsonObjectResponse) throws JSONException,Exception {
1273+ public static Object saveOrUpdateTransactionFromJSON(long id,JSONObject jsonObjectResponse) throws JSONException,Exception {
1274 Transaction tEntity=em.get(Transaction.class, id);
1275 if (tEntity==null) {
1276 tEntity= new Transaction();
1277@@ -1297,7 +1350,7 @@
1278 try {
1279 tEntity.fromAccountId=getLocalKey(DatabaseHelper.ACCOUNT_TABLE, jsonObjectResponse.getString("account"));
1280 } catch (Exception e1) {
1281- Log.e("financisto","Error parsing Transaction.fromAccount");
1282+ Log.e("flowzr","Error parsing Transaction.fromAccount");
1283 return null; //REQUIRED
1284 }
1285 if (jsonObjectResponse.has("dateTime")) {
1286@@ -1331,7 +1384,6 @@
1287 e.printStackTrace();
1288 //throw new Exception("Got key " + jsonObjectResponse.getString("parent_tr") + " but couldn't find related parent tr");
1289 }
1290- Log.i(TAG,"Done.");
1291
1292 }
1293 }
1294@@ -1340,7 +1392,7 @@
1295 try {
1296 tEntity.toAccountId=getLocalKey(DatabaseHelper.ACCOUNT_TABLE, jsonObjectResponse.getString("to_account"));
1297 } catch (Exception e1) {
1298- Log.e("financisto","Error parsing Transaction.toAccount with : " + jsonObjectResponse.getString("to_account"));
1299+ Log.e("flowzr","Error parsing Transaction.toAccount with : " + jsonObjectResponse.getString("to_account"));
1300 }
1301 }
1302 if (jsonObjectResponse.has("key")) {
1303@@ -1356,7 +1408,7 @@
1304 try {
1305 tEntity.originalCurrencyId=getLocalKey(DatabaseHelper.CURRENCY_TABLE, jsonObjectResponse.getString("original_currency_id"));
1306 } catch (Exception e) {
1307- Log.e("financisto","Error parsing Transaction.original_currency_id with : " + jsonObjectResponse.getString("original_currency_id"));
1308+ Log.e("flowzr","Error parsing Transaction.original_currency_id with : " + jsonObjectResponse.getString("original_currency_id"));
1309 }
1310 }
1311 if (jsonObjectResponse.has("original_from_amount")) {
1312@@ -1376,7 +1428,7 @@
1313 } catch (Exception e1) {
1314 tEntity.categoryId=Category.NO_CATEGORY_ID;
1315 e1.printStackTrace();
1316- Log.e("financisto","Error parsing Transaction.categoryId with : " + jsonObjectResponse.getString("cat"));
1317+ Log.e("flowzr","Error parsing Transaction.categoryId with : " + jsonObjectResponse.getString("cat"));
1318 }
1319 } else {
1320 tEntity.categoryId=Category.NO_CATEGORY_ID;
1321@@ -1386,7 +1438,7 @@
1322 try {
1323 tEntity.projectId=getLocalKey(DatabaseHelper.PROJECT_TABLE, jsonObjectResponse.getString("project"));
1324 } catch (Exception e1) {
1325- Log.e("financisto","Error parsing Transaction.ProjectId with : " + jsonObjectResponse.getString("project"));
1326+ Log.e("flowzr","Error parsing Transaction.ProjectId with : " + jsonObjectResponse.getString("project"));
1327 }
1328 }
1329 //payee_id,
1330@@ -1394,7 +1446,7 @@
1331 try {
1332 tEntity.payeeId=getLocalKey(DatabaseHelper.PAYEE_TABLE, jsonObjectResponse.getString("payee_id"));
1333 } catch (Exception e1) {
1334- Log.e("financisto","Error parsing Transaction.PayeeId with : " + jsonObjectResponse.getString("payee_id"));
1335+ Log.e("flowzr","Error parsing Transaction.PayeeId with : " + jsonObjectResponse.getString("payee_id"));
1336 }
1337 }
1338 //location_id
1339@@ -1405,7 +1457,7 @@
1340 tEntity.locationId=lid;
1341 }
1342 } catch (Exception e1) {
1343- Log.e("financisto","Error parsing Transaction.location_id with : " + jsonObjectResponse.getString("location_id"));
1344+ Log.e("flowzr","Error parsing Transaction.location_id with : " + jsonObjectResponse.getString("location_id"));
1345 }
1346 }
1347 //accuracy,provider,latitude,longitude
1348@@ -1416,7 +1468,7 @@
1349 try {
1350 tEntity.accuracy=jsonObjectResponse.getLong("accuracy");
1351 } catch (Exception e) {
1352- Log.e("financisto","Error getting accuracy value for transaction with:" + jsonObjectResponse.getString("accuracy"));
1353+ Log.e("flowzr","Error getting accuracy value for transaction with:" + jsonObjectResponse.getString("accuracy"));
1354 }
1355 }
1356 if (jsonObjectResponse.has("lat") && jsonObjectResponse.has("lon")) {
1357@@ -1424,7 +1476,7 @@
1358 tEntity.latitude=jsonObjectResponse.getDouble("lat");
1359 tEntity.longitude=jsonObjectResponse.getDouble("lon");
1360 } catch (Exception e) {
1361- Log.e("financisto","Error getting geo_point value for transaction with:" + jsonObjectResponse.getString("lat") + " " + jsonObjectResponse.getDouble("lon"));
1362+ Log.e("flowzr","Error getting geo_point value for transaction with:" + jsonObjectResponse.getString("lat") + " " + jsonObjectResponse.getDouble("lon"));
1363 }
1364 }
1365 tEntity.status=TransactionStatus.UR;
1366@@ -1474,9 +1526,9 @@
1367 return tEntity;
1368 }
1369
1370- public void requery(String tableName,Class clazz,String key) throws ClientProtocolException, IOException, JSONException,Exception {
1371+ public static void requery(String tableName,Class clazz,String key) throws ClientProtocolException, IOException, JSONException,Exception {
1372 Log.i(TAG,"Got key " + key + " but couldn't find related parent tr, requerying ...");
1373- String url=FlowzrSyncOptions.FLOWZR_API_URL + options.getNamespace() + "/key/?tableName=" + DatabaseHelper.TRANSACTION_TABLE + "&key=" + key;
1374+ String url=FLOWZR_API_URL + nsString + "/key/?tableName=" + DatabaseHelper.TRANSACTION_TABLE + "&key=" + key;
1375 StringBuilder builder = new StringBuilder();
1376 DefaultHttpClient http_client2= new DefaultHttpClient();
1377 http_client2.setCookieStore(http_client.getCookieStore());
1378@@ -1493,7 +1545,7 @@
1379 saveEntityFromJson(o, tableName, clazz,1);
1380 }
1381
1382- public long getLocalKey(String tableName,String remoteKey) {
1383+ public static long getLocalKey(String tableName,String remoteKey) {
1384 Cursor c = db.query(tableName, new String[] { "_id" }, "remote_key = ?",
1385 new String[]{ remoteKey }, null, null, null, null);
1386 if (c.moveToFirst()) {
1387@@ -1510,22 +1562,24 @@
1388 }
1389 }
1390
1391- private void pullUpdate() throws IOException, JSONException, Exception {
1392+ private static void pullUpdate() throws IOException, JSONException, Exception {
1393 int i=0;
1394 for (String tableName : tableNames) {
1395- if (tableName.equals(DatabaseHelper.TRANSACTION_TABLE)) {
1396- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_receiving) + " " + tableName + ". " + flowzrSyncActivity.getString(R.string.hint_run_background), (int)(Math.round(i*100/tableNames.length)));
1397+ Log.i("flowzr", context.getString(R.string.flowzr_sync_receiving) + " " + tableName );
1398+
1399+ if (tableName.equals(DatabaseHelper.TRANSACTION_TABLE)) {
1400+ notifyUser(context.getString(R.string.flowzr_sync_receiving) + " " + tableName + ". " + context.getString(R.string.hint_run_background), (int)(Math.round(i*100/tableNames.length)));
1401 } else {
1402- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_receiving) + " " + tableName, (int)(Math.round(i*100/tableNames.length)));
1403+ notifyUser(context.getString(R.string.flowzr_sync_receiving) + " " + tableName, (int)(Math.round(i*100/tableNames.length)));
1404 }
1405 if (!isCanceled) {
1406- pullUpdate(tableName,clazzArray[i],FlowzrSyncOptions.last_sync_ts);
1407+ pullUpdate(tableName,clazzArray[i],last_sync_ts);
1408 }
1409 i++;
1410 }
1411 }
1412
1413- private <T> void pullUpdate(String tableName,Class<T> clazz,long last_sync_ts) throws IOException, JSONException, Exception {
1414+ private static <T> void pullUpdate(String tableName,Class<T> clazz,long last_sync_ts) throws IOException, JSONException, Exception {
1415
1416 if (tableName.equals(DatabaseHelper.TRANSACTION_TABLE)) {
1417 //pull all remote accounts, accounts by accounts
1418@@ -1535,19 +1589,19 @@
1419 do {
1420 String account_key=c.getString(c.getColumnIndex("remote_key"));
1421 if (account_key!=null) {
1422- String url=options.FLOWZR_API_URL + options.getNamespace() + "/" + tableName + "/?last_sync_ts=" + last_sync_ts + "&account=" + account_key;
1423+ String url=FLOWZR_API_URL + nsString + "/" + tableName + "/?last_sync_ts=" + last_sync_ts + "&account=" + account_key;
1424 getJSONFromUrl2(url,tableName,c.getString(c.getColumnIndex("remote_key")),clazz,last_sync_ts);
1425 }
1426 } while (c.moveToNext() && !isCanceled); //
1427 }
1428 c.close();
1429 } else {
1430- String url=options.FLOWZR_API_URL + options.getNamespace() + "/" + tableName + "/?last_sync_ts=" + last_sync_ts;
1431+ String url=FLOWZR_API_URL + nsString + "/" + tableName + "/?last_sync_ts=" + last_sync_ts;
1432 getJSONFromUrl(url,tableName,clazz,last_sync_ts);
1433 }
1434 }
1435
1436- public <T> int getJSONFromUrl(String url,String tableName, Class<T> clazz,long last_sync_ts) throws IOException, JSONException, Exception {
1437+ public static <T> int getJSONFromUrl(String url,String tableName, Class<T> clazz,long last_sync_ts) throws IOException, JSONException, Exception {
1438 if (url==null) {
1439 return 0;
1440 }
1441@@ -1562,14 +1616,14 @@
1442 return i;
1443 }
1444
1445- public <T> void getJSONFromUrl2(String url,String tableName,String account_key, Class<T> clazz,long last_sync_ts) throws IOException, JSONException, Exception {
1446+ public static <T> void getJSONFromUrl2(String url,String tableName,String account_key, Class<T> clazz,long last_sync_ts) throws IOException, JSONException, Exception {
1447 int i=MAX_PULL_SIZE;
1448 while (i!=0) {
1449 i=getJSONFromUrl(url, tableName,clazz,last_sync_ts);
1450 }
1451 }
1452
1453- public <T> int readMessage(JsonReader reader,String tableName,Class<T> clazz,long last_sync_ts) throws IOException, JSONException,Exception {
1454+ public static <T> int readMessage(JsonReader reader,String tableName,Class<T> clazz,long last_sync_ts) throws IOException, JSONException,Exception {
1455 String n = null;
1456 int i=0;
1457 while (reader.hasNext()) {
1458@@ -1608,7 +1662,7 @@
1459 return i;
1460 }
1461
1462- public <T> int readJsnArr(JsonReader reader, String tableName, Class<T> clazz) throws IOException, JSONException,Exception {
1463+ public static <T> int readJsnArr(JsonReader reader, String tableName, Class<T> clazz) throws IOException, JSONException,Exception {
1464 JSONObject o = new JSONObject();
1465 JsonToken peek = reader.peek();
1466 String n = null;
1467@@ -1665,7 +1719,7 @@
1468 }
1469 saveEntityFromJson(o, tableName, clazz,i);
1470 if (i%10==0) {
1471- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_receiving) + " " + tableName + ". " + flowzrSyncActivity.getString(R.string.hint_run_background), (int)(Math.round(j)));
1472+ notifyUser(context.getString(R.string.flowzr_sync_receiving) + " " + tableName + ". " + context.getString(R.string.hint_run_background), (int)(Math.round(j)));
1473 }
1474 }
1475 }
1476@@ -1673,7 +1727,7 @@
1477 return i;
1478 }
1479
1480- public <T> void saveEntityFromJson(JSONObject o, String tableName, Class<T> clazz, int i) throws JSONException,Exception {
1481+ public static <T> void saveEntityFromJson(JSONObject o, String tableName, Class<T> clazz, int i) throws JSONException,Exception {
1482 String remoteKey = o.getString("key");
1483 if (clazz==Transaction.class) {
1484 saveOrUpdateTransactionFromJSON(getLocalKey(tableName,remoteKey),o);
1485@@ -1697,8 +1751,8 @@
1486
1487 }
1488
1489- public void pullDelete(long last_sync_ts) throws Exception {
1490- String url=options.FLOWZR_API_URL + options.getNamespace() + "/delete/?last_sync_ts=" + last_sync_ts ;
1491+ public static void pullDelete(long last_sync_ts) throws Exception {
1492+ String url=FLOWZR_API_URL + nsString + "/delete/?last_sync_ts=" + last_sync_ts ;
1493 HttpGet httpGet = new HttpGet(url);
1494 HttpResponse httpResponse = http_client.execute(httpGet);
1495 HttpEntity httpEntity = httpResponse.getEntity();
1496@@ -1709,7 +1763,7 @@
1497 httpEntity.consumeContent();
1498 }
1499
1500- public void readDelete(JsonReader reader) throws IOException {
1501+ public static void readDelete(JsonReader reader) throws IOException {
1502 reader.nextName();
1503 reader.beginArray();
1504 while (reader.hasNext()) {
1505@@ -1723,7 +1777,7 @@
1506 reader.endArray();
1507 }
1508
1509- public void execDelete(String tableName,String remoteKey) {
1510+ public static void execDelete(String tableName,String remoteKey) {
1511 long id=getLocalKey(tableName,remoteKey);
1512
1513 if (id>0) {
1514@@ -1747,18 +1801,24 @@
1515 }
1516 }
1517
1518- public void pushAllBlobs() {
1519+ public static void pushAllBlobs() {
1520+ if (db==null) {
1521+ if (context==null) {
1522+ context=MainActivity.activity;
1523+ }
1524+ db=new DatabaseAdapter(context).db();
1525+ }
1526 String sql="select attached_picture,datetime,remote_key,blob_key " +
1527 "from transactions " +
1528 "where attached_picture is not null " +
1529- "and blob_key is null limit 3";
1530+ "and blob_key is null";
1531
1532 Cursor cursorCursor=db.rawQuery(sql, null);
1533 int i=0;
1534 if (cursorCursor.moveToFirst()) {
1535 do {
1536 i=i+10;
1537- flowzrSyncActivity.notifyUser(cursorCursor.getString(0) + " >> Google Drive. " + flowzrSyncActivity.getString(R.string.hint_run_background),i);
1538+ notifyUser(cursorCursor.getString(0) + " >> Google Drive. " + context.getString(R.string.hint_run_background),i);
1539 if (i==100) {
1540 i=10;
1541 }
1542@@ -1766,292 +1826,40 @@
1543 } while (cursorCursor.moveToNext());
1544 }
1545 cursorCursor.close();
1546+ notifyUser(context.getString(R.string.googledrive_upload) + " " + context.getString(R.string.ok), 100);
1547 }
1548
1549
1550- public void saveFileToDrive(String pictureFileName,long l,String remoteKey) {
1551+ public static void saveFileToDrive(String pictureFileName,long l,String remoteKey) {
1552 java.io.File pictureFile = new java.io.File(PICTURES_DIR, pictureFileName);
1553- Uri fileUri=Uri.fromFile(pictureFile);
1554- RunUpload runUpload = new RunUpload(fileUri,l,remoteKey);
1555- runUpload.run();
1556- }
1557-
1558- public class RunUpload implements Runnable {
1559-
1560- private Uri fileUri;
1561- private long trDate;
1562- private String remote_key;
1563-
1564- public RunUpload(Uri _fileUri,long l,String _remote_key) {
1565- this.fileUri = _fileUri;
1566- this.trDate = l;
1567- this.remote_key=_remote_key;
1568- }
1569-
1570- public void run() {
1571- String targetFolderId=null;
1572- try {
1573- if (driveService==null) {
1574- driveService=getDriveService();
1575- }
1576- String ROOT_FOLDER=MyPreferences.getGoogleDriveFolder(flowzrSyncActivity);
1577- // ensure to have the app root folder in drive ...
1578- if (rootFolderId==null) {
1579- //search root folder ...
1580- FileList folders=driveService.files().list().setQ("mimeType='application/vnd.google-apps.folder'").execute();
1581- for(File fl: folders.getItems()){
1582- if (fl.getTitle().equals(ROOT_FOLDER)) {
1583- rootFolderId=fl.getId();
1584- }
1585- }
1586- //if not found create it
1587- if (rootFolderId==null) {
1588- File body = new File();
1589- body.setTitle(ROOT_FOLDER);
1590- body.setMimeType("application/vnd.google-apps.folder");
1591- File file = driveService.files().insert(body).execute();
1592- rootFolderId=file.getId();
1593- }
1594- }
1595- //search for the target folder (depending of the date)
1596- Calendar cal = Calendar.getInstance();
1597- cal.setTime(new Date(trDate));
1598- int month=cal.get(Calendar.MONTH) + 1;
1599- String targetFolder=String.valueOf(cal.get(Calendar.YEAR)) + "-" + (month<10?("0"+month):(month));
1600-
1601- FileList subfolders=driveService.files().list().setQ("mimeType='application/vnd.google-apps.folder' and '" + rootFolderId + "' in parents").execute();
1602- for(File fl: subfolders.getItems()){
1603- if (fl.getTitle().equals(targetFolder)) {
1604- targetFolderId=fl.getId();
1605- }
1606- }
1607- //create the target folder if not exist
1608- if (targetFolderId==null) {
1609- //create folder
1610- File body = new File();
1611- body.setTitle(targetFolder);
1612- ArrayList<ParentReference> pList=new ArrayList<ParentReference>();
1613- pList.add(new ParentReference().setId(rootFolderId)) ;
1614- body.setParents(pList);
1615- body.setMimeType("application/vnd.google-apps.folder");
1616- File file = driveService.files().insert(body).execute();
1617- targetFolder=file.getId();
1618- }
1619- // File's binary content
1620- java.io.File fileContent = new java.io.File(fileUri.getPath());
1621- InputStreamContent mediaContent = new InputStreamContent("image/jpeg", new BufferedInputStream(
1622- new FileInputStream(fileContent)));
1623- mediaContent.setLength(fileContent.length());
1624- // File's metadata.
1625- File body = new File();
1626- body.setTitle(fileContent.getName());
1627- body.setMimeType("image/jpeg");
1628- body.setFileSize(fileContent.length());
1629- ArrayList<ParentReference> pList2=new ArrayList<ParentReference>();
1630- pList2.add(new ParentReference().setId(targetFolderId)) ;
1631- body.setParents(pList2);
1632- File file = driveService.files().insert(body, mediaContent).execute();
1633- } catch (UserRecoverableAuthIOException e) {
1634- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_account_setup), 100);
1635- e.getIntent().setClass(context, FlowzrSyncActivity.class);
1636- flowzrSyncActivity.startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
1637- flowzrSyncActivity.setReady();
1638- e.printStackTrace();
1639- } catch (Exception e) {
1640- flowzrSyncActivity.notifyUser(e.getMessage(), 0);
1641- }
1642-
1643- Thread thread= new Thread(){
1644- @Override
1645- public void run(){
1646- try {
1647- synchronized(this){
1648- wait(3000);
1649- }
1650- }
1651- catch(InterruptedException ex){
1652- }
1653- }
1654- };
1655- thread.start();
1656-
1657- String uploadedId=null;
1658- FileList files;
1659- try {
1660- files = driveService.files().list().setQ("mimeType='image/jpeg' and '" + targetFolderId + "' in parents").execute();
1661- String file_url="";
1662- String thumbnail_url="";
1663- for(File fl: files.getItems()){
1664- if (fl.getTitle().equals(fileUri.getLastPathSegment())) {
1665- uploadedId=fl.getId();
1666- try {
1667- file_url=fl.getAlternateLink();
1668- thumbnail_url=fl.getIconLink();
1669- } catch (Exception e) {
1670- file_url="https://drive.google.com/#folders/" + targetFolderId +"/";
1671- }
1672- }
1673- }
1674- if (!uploadedId.equals("null")) {
1675- String sql="update transactions set blob_key='" + uploadedId + "' where remote_key='" + remote_key+"'";
1676- db.execSQL(sql);
1677- sql="select from_account_id,attached_picture from " + DatabaseHelper.TRANSACTION_TABLE + " where remote_key='" + remote_key+"'";
1678- Cursor c=db.rawQuery(sql, null);
1679- if (c.moveToFirst()) {
1680- String account_key=getRemoteKey(DatabaseHelper.ACCOUNT_TABLE, String.valueOf(c.getLong(0)));
1681- String file_type="image/jpeg";
1682- String file_name=c.getString(1);
1683- if (file_url==null) {
1684- file_url="";
1685- }
1686- if (thumbnail_url==null) {
1687- thumbnail_url="";
1688- }
1689- String url=options.FLOWZR_API_URL + options.getNamespace() +"/blob/?url=" + URLEncoder.encode(file_url, "UTF-8") + "&thumbnail_url=" + URLEncoder.encode(thumbnail_url, "UTF-8") + "&account="+account_key+"&crebit="+ remote_key + "&name="+ file_name + "&blob_key=" + uploadedId + "type=" + file_type;
1690- try {
1691- HttpGet httpGet = new HttpGet(url);
1692- http_client.execute(httpGet);
1693- Log.i(TAG,"linked to :" + file_url);
1694- } catch (Exception e) {
1695- e.printStackTrace();
1696- }
1697- }
1698- }
1699- } catch (Exception e) {
1700- e.printStackTrace();
1701- }
1702- }
1703- }
1704-
1705- private Drive getDriveService() {
1706- credential = GoogleAccountCredential.usingOAuth2(flowzrSyncActivity.getApplicationContext(), Arrays.asList(DriveScopes.DRIVE_FILE));
1707- credential.setSelectedAccountName(options.useCredential);
1708- return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();
1709- }
1710-
1711- public class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
1712- public void run(AccountManagerFuture<Bundle> result) {
1713- Bundle bundle;
1714-
1715- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
1716- FlowzrSyncOptions options = FlowzrSyncOptions.fromPrefs(preferences);
1717- flowzrSyncTask= new FlowzrSyncTask(flowzrSyncActivity,FlowzrSyncEngine.this, options,http_client);
1718- flowzrSyncActivity.flowzrSyncTask=flowzrSyncTask;
1719-
1720- try {
1721- bundle = result.getResult();
1722- Intent intent = (Intent)bundle.get(AccountManager.KEY_INTENT);
1723- if(intent != null) {
1724- // User input required
1725- flowzrSyncActivity.startActivity(intent);
1726- } else {
1727- AccountManager.get(context).invalidateAuthToken(bundle.getString(AccountManager.KEY_ACCOUNT_TYPE), bundle.getString(AccountManager.KEY_AUTHTOKEN));
1728- AccountManager.get(context).invalidateAuthToken("ah", bundle.getString(AccountManager.KEY_AUTHTOKEN));
1729- onGetAuthToken(bundle);
1730- }
1731- } catch (OperationCanceledException e) {
1732- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_error_no_network), 100);
1733- //showErrorPopup(FlowzrSyncActivity.this, R.string.flowzr_sync_error_no_network);
1734- flowzrSyncActivity.setReady();
1735- e.printStackTrace();
1736- } catch (AuthenticatorException e) {
1737- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_error_no_network), 100);
1738- flowzrSyncActivity.setReady();
1739- e.printStackTrace();
1740- } catch (IOException e) {
1741- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_error_no_network), 100);
1742- flowzrSyncActivity.setReady();
1743- e.printStackTrace();
1744- }
1745- }
1746- }
1747-
1748- protected void onGetAuthToken(Bundle bundle) {
1749- String auth_token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
1750- new GetCookieTask().execute(auth_token);
1751- }
1752-
1753- private class GetCookieTask extends AsyncTask<String, Void, Boolean> {
1754- protected Boolean doInBackground(String... tokens) {
1755- flowzrSyncActivity.notifyUser(context.getString(R.string.flowzr_sync_auth_inprogress), 15);
1756- try {
1757- http_client.getParams().setParameter("http.protocol.content-charset","UTF-8");
1758- // Don't follow redirects
1759- http_client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
1760- HttpGet http_get = new HttpGet(options.FLOWZR_BASE_URL + "/_ah/login?continue=" + options.FLOWZR_BASE_URL +"/&auth=" + tokens[0]);
1761- HttpResponse response;
1762- flowzrSyncActivity.notifyUser(context.getString(R.string.flowzr_sync_auth_inprogress), 20);
1763- response = http_client.execute(http_get);
1764- response.getEntity().consumeContent();
1765- if(response.getStatusLine().getStatusCode() != 302) {
1766- // Response should be a redirect
1767- return false;
1768- }
1769- for(Cookie cookie : http_client.getCookieStore().getCookies()) {
1770- if(cookie.getName().equals("ACSID")) {
1771- flowzrSyncActivity.notifyUser(context.getString(R.string.flowzr_sync_receiving), 25);
1772- return true;
1773- }
1774- }
1775- } catch (ClientProtocolException e) {
1776- Log.e("financisto",e.getMessage());
1777- return false;
1778- } catch (IOException e) {
1779- Log.e("financisto",e.getMessage());
1780- return false;
1781- } finally {
1782- http_client.getParams().setParameter("http.protocol.content-charset","UTF-8");
1783- http_client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true);
1784- }
1785- return false;
1786- }
1787-
1788- protected void onPostExecute(Boolean result) {
1789- flowzrSyncActivity.notifyUser(context.getString(R.string.flowzr_sync_auth_inprogress), 30);
1790- flowzrSyncTask.execute();
1791- }
1792- }
1793-
1794- public static void builAndRun(Context context) {
1795- final FlowzrSyncActivity fa = FlowzrSyncActivity.getMySelf();
1796- if (fa == null) {
1797- NotificationManager nm = (NotificationManager) context
1798- .getSystemService(Context.NOTIFICATION_SERVICE);
1799-
1800- Intent notificationIntent = new Intent(context,
1801- FlowzrSyncActivity.class);
1802- PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
1803- notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
1804-
1805- Builder mNotifyBuilder = new NotificationCompat.Builder(context);
1806- mNotifyBuilder
1807- .setContentIntent(contentIntent)
1808- .setSmallIcon(R.drawable.icon)
1809- .setWhen(System.currentTimeMillis())
1810- .setAutoCancel(true)
1811- .setContentTitle(context.getString(R.string.flowzr_sync))
1812- .setContentText(
1813- context.getString(R.string.flowzr_sync_require_tap));
1814- nm.notify(SYNC_NOTIFICATION_ID, mNotifyBuilder.build());
1815- Log.e(TAG, "Sync unactive: the required activity is missing.");
1816- return;
1817- } else {
1818- if (FlowzrSyncActivity.isRunning) {
1819- Log.i(TAG, "Sync already in progress");
1820- } else {
1821- if ((System.currentTimeMillis() - FlowzrSyncOptions.last_sync_ts )>30*1000) {
1822- Log.i(TAG, "Starting Auto-Sync Task");
1823- fa.runOnUiThread(new Runnable() {
1824- public void run() {
1825- fa.setRunning();
1826- }
1827- });
1828- fa.initProgressDialog();
1829- new FlowzrSyncEngine(fa);
1830- } else {
1831- Log.i(TAG, "Sync have just been done");
1832- }
1833- }
1834- }
1835- }
1836-}
1837+ Uri fileUri=Uri.fromFile(pictureFile);
1838+ new PictureDriveTask(context, http_client, fileUri, l, remoteKey).execute();
1839+ }
1840+
1841+
1842+
1843+ public static boolean checkSubscriptionFromWeb() {
1844+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
1845+ String registrationId = prefs.getString(FlowzrSyncOptions.PROPERTY_REG_ID, "");
1846+ if (registrationId=="") {
1847+ Log.i(TAG, "Registration not found.");
1848+ }
1849+
1850+ String url=FLOWZR_API_URL + "?action=checkSubscription&regid=" + registrationId;
1851+
1852+ try {
1853+ HttpGet httpGet = new HttpGet(url);
1854+ HttpResponse httpResponse = http_client.execute(httpGet);
1855+ int code = httpResponse.getStatusLine().getStatusCode();
1856+ Log.i("flowzr","Subscription status code is : " + String.valueOf(code));
1857+ if (code==402) {
1858+ httpResponse.getEntity().consumeContent();
1859+ return false;
1860+ }
1861+ httpResponse.getEntity().consumeContent();
1862+ } catch (Exception e) {
1863+ e.printStackTrace();
1864+ }
1865+ return true;
1866+ }
1867+}
1868\ No newline at end of file
1869
1870=== modified file 'src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncOptions.java'
1871--- src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncOptions.java 2014-01-21 12:29:20 +0000
1872+++ src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncOptions.java 2014-05-17 07:00:19 +0000
1873@@ -28,7 +28,7 @@
1874 public static final String FLOWZR_BASE_URL="https://flowzr-hrd.appspot.com";
1875 public static final String GCM_SENDER_ID = "98966630416";
1876 public static final String PROPERTY_REG_ID = "registration_id";
1877- public static String FLOWZR_API_URL=FLOWZR_BASE_URL + "/financisto2/";
1878+ public static String FLOWZR_API_URL=FLOWZR_BASE_URL + "/financisto3/";
1879 public String appVersion="";
1880
1881 public FlowzrSyncOptions(String strUseCredential, long lastSyncLocalTimestamp, DefaultHttpClient pHttp_client,String pRootFolderId,String _appVersion) {
1882
1883=== modified file 'src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncTask.java'
1884--- src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncTask.java 2014-01-02 18:41:51 +0000
1885+++ src/ru/orangesoftware/financisto/export/flowzr/FlowzrSyncTask.java 2014-05-17 07:00:19 +0000
1886@@ -9,106 +9,102 @@
1887 package ru.orangesoftware.financisto.export.flowzr;
1888
1889
1890+import java.io.IOException;
1891+
1892 import org.apache.http.HttpResponse;
1893+import org.apache.http.client.ClientProtocolException;
1894 import org.apache.http.client.methods.HttpGet;
1895+import org.apache.http.client.params.ClientPNames;
1896+import org.apache.http.conn.ClientConnectionManager;
1897+import org.apache.http.conn.scheme.PlainSocketFactory;
1898+import org.apache.http.conn.scheme.Scheme;
1899+import org.apache.http.conn.scheme.SchemeRegistry;
1900+import org.apache.http.conn.scheme.SocketFactory;
1901+import org.apache.http.conn.ssl.SSLSocketFactory;
1902+import org.apache.http.cookie.Cookie;
1903 import org.apache.http.impl.client.DefaultHttpClient;
1904-
1905-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
1906-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncOptions;
1907+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
1908+import org.apache.http.params.BasicHttpParams;
1909
1910 import ru.orangesoftware.financisto.R;
1911 import ru.orangesoftware.financisto.activity.FlowzrSyncActivity;
1912 import ru.orangesoftware.financisto.db.DatabaseAdapter;
1913-import android.app.ProgressDialog;
1914+import ru.orangesoftware.financisto.export.ImportExportException;
1915+import ru.orangesoftware.financisto.utils.MyPreferences;
1916+import android.accounts.Account;
1917+import android.accounts.AccountManager;
1918+import android.accounts.AccountManagerCallback;
1919+import android.accounts.AccountManagerFuture;
1920+import android.accounts.AuthenticatorException;
1921+import android.accounts.OperationCanceledException;
1922+import android.app.NotificationManager;
1923+import android.app.PendingIntent;
1924 import android.content.Context;
1925-import android.content.SharedPreferences;
1926+import android.content.Intent;
1927 import android.os.AsyncTask;
1928-import android.preference.PreferenceManager;
1929+import android.os.Bundle;
1930+import android.support.v4.app.NotificationCompat;
1931+import android.support.v4.app.NotificationCompat.Builder;
1932 import android.util.Log;
1933
1934 public class FlowzrSyncTask extends AsyncTask<String, String, Object> {
1935+
1936 protected final Context context;
1937- private final FlowzrSyncOptions options;
1938- private final DefaultHttpClient http_client;
1939- private final FlowzrSyncActivity flowzrSyncActivity;
1940- FlowzrSyncEngine flowzrSync;
1941- public static ProgressDialog mProgress;
1942 public static final String TAG = "flowzr";
1943-
1944+ public static DefaultHttpClient http_client;
1945+ private static DatabaseAdapter dba;
1946
1947- public FlowzrSyncTask(FlowzrSyncActivity flowzrSyncActivity, FlowzrSyncEngine _flowzrSyncEngine, FlowzrSyncOptions options, DefaultHttpClient pHttp_client) {
1948- this.options = options;
1949- this.http_client=pHttp_client;
1950- this.context=flowzrSyncActivity;
1951- this.flowzrSyncActivity=flowzrSyncActivity;
1952- this.flowzrSync=_flowzrSyncEngine;
1953- mProgress = new ProgressDialog(this.flowzrSyncActivity);
1954- mProgress.setIcon(R.drawable.icon);
1955- mProgress.setTitle(flowzrSyncActivity.getString(R.string.flowzr_sync));
1956- mProgress.setMessage(flowzrSyncActivity.getString(R.string.flowzr_sync_inprogress));
1957- mProgress.setCancelable(true);
1958- mProgress.setCanceledOnTouchOutside(false);
1959- mProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
1960- try {
1961- mProgress.show();
1962- } catch(Exception e) {
1963- Log.e(TAG,"avoid a leaked window");
1964+ public FlowzrSyncTask(Context context) {
1965+ this.context=context;
1966+
1967+ BasicHttpParams params = new BasicHttpParams();
1968+ SchemeRegistry schemeRegistry = new SchemeRegistry();
1969+ schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
1970+ final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
1971+ schemeRegistry.register(new Scheme("https", (SocketFactory) sslSocketFactory, 443));
1972+ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
1973+ this.http_client = new DefaultHttpClient(cm, params);
1974+ this.dba=new DatabaseAdapter(context);
1975+ }
1976+
1977+ protected Object work(Context context, DatabaseAdapter dba, String... params) throws ImportExportException {
1978+
1979+ AccountManager accountManager = AccountManager.get(context);
1980+ android.accounts.Account[] accounts = accountManager.getAccountsByType("com.google");
1981+
1982+ String accountName=MyPreferences.getFlowzrAccount(context);
1983+ if (accountName == null) {
1984+ NotificationManager nm = (NotificationManager) context
1985+ .getSystemService(Context.NOTIFICATION_SERVICE);
1986+
1987+ Intent notificationIntent = new Intent(context,
1988+ FlowzrSyncActivity.class);
1989+ PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
1990+ notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
1991+
1992+ Builder mNotifyBuilder = new NotificationCompat.Builder(context);
1993+ mNotifyBuilder
1994+ .setContentIntent(contentIntent)
1995+ .setSmallIcon(R.drawable.icon)
1996+ .setWhen(System.currentTimeMillis())
1997+ .setAutoCancel(true)
1998+ .setContentTitle(context.getString(R.string.flowzr_sync))
1999+ .setContentText(
2000+ context.getString(R.string.flowzr_choose_account));
2001+ nm.notify(0, mNotifyBuilder.build());
2002+ Log.i("Financisto","account name is null");
2003+ throw new ImportExportException(R.string.flowzr_choose_account);
2004 }
2005-
2006- }
2007-
2008-
2009-
2010- protected Object work(Context context, DatabaseAdapter db, String... params) {
2011-
2012- try {
2013- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_auth_inprogress), 30);
2014- //FlowzrBilling flowzrBilling = new FlowzrBilling(flowzrSyncActivity, flowzrSyncActivity.getApplicationContext(), http_client, options.useCredential);
2015- //if (flowzrBilling.checkSubscription()) {
2016- // Boolean sync=false;
2017- // if (flowzrBilling!=null) {
2018- // sync=flowzrBilling.checkSubscription();
2019- // } else {
2020- // sync=false;
2021- // return new Exception(context.getString(R.string.flowzr_account_setup));
2022- // }
2023- if (this.checkSubscriptionFromWeb()) {
2024- flowzrSync.doSync();
2025- return null;
2026- } else {
2027- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_subscription_required), 100);
2028- flowzrSyncActivity.setRunning();
2029- return new Exception(context.getString(R.string.flowzr_subscription_required));
2030- }
2031- } catch (Exception e) {
2032- return e;
2033- }
2034- }
2035-
2036- public boolean checkSubscriptionFromWeb() {
2037- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
2038- String registrationId = prefs.getString(FlowzrSyncOptions.PROPERTY_REG_ID, "");
2039- if (registrationId=="") {
2040- Log.i(TAG, "Registration not found.");
2041- }
2042-
2043- String url=FlowzrSyncOptions.FLOWZR_API_URL + "?action=checkSubscription&regid=" + registrationId;
2044-
2045- try {
2046- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_auth_inprogress), 40);
2047- HttpGet httpGet = new HttpGet(url);
2048- HttpResponse httpResponse = http_client.execute(httpGet);
2049- flowzrSyncActivity.notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_inprogress), 50);
2050- int code = httpResponse.getStatusLine().getStatusCode();
2051- if (code==402) {
2052- return false;
2053- }
2054- httpResponse.getEntity().consumeContent();
2055- } catch (Exception e) {
2056- e.printStackTrace();
2057- }
2058- return true;
2059- }
2060+ Account useCredential = null;
2061+ for (int i = 0; i < accounts.length; i++) {
2062+ if (accountName.equals(((android.accounts.Account) accounts[i]).name)) {
2063+ useCredential=accounts[i];
2064+ }
2065+ }
2066+ accountManager.getAuthToken(useCredential, "ah", false, new GetAuthTokenCallback(), null);
2067+ return null;
2068+ }
2069+
2070
2071 @Override
2072 protected Object doInBackground(String... params) {
2073@@ -116,7 +112,12 @@
2074 DatabaseAdapter db = new DatabaseAdapter(context);
2075 db.open();
2076 try {
2077- return work(context, db, params);
2078+ try {
2079+ return work(context, db, params);
2080+ } catch (ImportExportException e) {
2081+ e.printStackTrace();
2082+ return e;
2083+ }
2084 } finally {
2085 db.close();
2086 }
2087@@ -126,17 +127,101 @@
2088 @Override
2089 protected void onProgressUpdate(String... values) {
2090 super.onProgressUpdate(values);
2091- mProgress.setProgress(Integer.parseInt(values[0]));
2092 }
2093
2094
2095
2096 @Override
2097- protected void onPostExecute(Object result) {
2098- flowzrSync.finishDelete();
2099- flowzrSyncActivity.setReady();
2100- flowzrSyncActivity.nm.cancel(FlowzrSyncActivity.NOTIFICATION_ID);
2101- mProgress.hide();
2102- }
2103-}
2104-
2105+ protected void onPostExecute(Object result) {
2106+ if (!(result instanceof Exception)) {
2107+
2108+
2109+ }
2110+ }
2111+
2112+
2113+public class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
2114+ public void run(AccountManagerFuture<Bundle> result) {
2115+ Bundle bundle;
2116+ try {
2117+ bundle = result.getResult();
2118+ Intent intent = (Intent)bundle.get(AccountManager.KEY_INTENT);
2119+ if(intent != null) {
2120+ // User input required
2121+ context.startActivity(intent);
2122+ } else {
2123+ AccountManager.get(context).invalidateAuthToken(bundle.getString(AccountManager.KEY_ACCOUNT_TYPE), bundle.getString(AccountManager.KEY_AUTHTOKEN));
2124+ AccountManager.get(context).invalidateAuthToken("ah", bundle.getString(AccountManager.KEY_AUTHTOKEN));
2125+ onGetAuthToken(bundle);
2126+ }
2127+ } catch (OperationCanceledException e) {
2128+ //notifyUser(context.getString(R.string.flowzr_sync_error_no_network), 100);
2129+ //showErrorPopup(FlowzrSyncActivity.this, R.string.flowzr_sync_error_no_network);
2130+ //context.setReady();
2131+ e.printStackTrace();
2132+ } catch (AuthenticatorException e) {
2133+ //notifyUser(context.getString(R.string.flowzr_sync_error_no_network), 100);
2134+ //flowzrSyncActivity.setReady();
2135+ e.printStackTrace();
2136+ } catch (IOException e) {
2137+ //notifyUser(flowzrSyncActivity.getString(R.string.flowzr_sync_error_no_network), 100);
2138+ //flowzrSyncActivity.setReady();
2139+ e.printStackTrace();
2140+ }
2141+ }
2142+ }
2143+
2144+ protected void onGetAuthToken(Bundle bundle) {
2145+ String auth_token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
2146+ new GetCookieTask().execute(auth_token);
2147+ }
2148+
2149+ private class GetCookieTask extends AsyncTask<String, Void, Boolean> {
2150+ protected Boolean doInBackground(String... tokens) {
2151+ //notifyUser(context.getString(R.string.flowzr_sync_auth_inprogress), 15);
2152+ try {
2153+ http_client.getParams().setParameter("http.protocol.content-charset","UTF-8");
2154+ // Don't follow redirects
2155+ http_client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
2156+ HttpGet http_get = new HttpGet(FlowzrSyncEngine.FLOWZR_BASE_URL + "/_ah/login?continue="
2157+ + FlowzrSyncEngine.FLOWZR_BASE_URL +"/&auth=" + tokens[0]);
2158+ HttpResponse response;
2159+ response = http_client.execute(http_get);
2160+ response.getEntity().consumeContent();
2161+ if(response.getStatusLine().getStatusCode() != 302) {
2162+ // Response should be a redirect
2163+ return false;
2164+ }
2165+ for(Cookie cookie : http_client.getCookieStore().getCookies()) {
2166+ if(cookie.getName().equals("ACSID")) {
2167+ return true;
2168+ }
2169+ }
2170+ } catch (ClientProtocolException e) {
2171+ Log.e("flowzr",e.getMessage());
2172+ return false;
2173+ } catch (IOException e) {
2174+ Log.e("flowzr",e.getMessage());
2175+ return false;
2176+ } finally {
2177+ http_client.getParams().setParameter("http.protocol.content-charset","UTF-8");
2178+ http_client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true);
2179+ }
2180+ return false;
2181+ }
2182+
2183+ protected void onPostExecute(Boolean result) {
2184+
2185+ Thread myThread = new Thread(new Runnable(){
2186+ @Override
2187+ public void run()
2188+ {
2189+ FlowzrSyncEngine.create(context,dba,http_client);
2190+ }
2191+ });
2192+
2193+ myThread.start();
2194+
2195+ }
2196+ }
2197+}
2198\ No newline at end of file
2199
2200=== modified file 'src/ru/orangesoftware/financisto/export/flowzr/GCMIntentService.java'
2201--- src/ru/orangesoftware/financisto/export/flowzr/GCMIntentService.java 2013-10-06 12:06:19 +0000
2202+++ src/ru/orangesoftware/financisto/export/flowzr/GCMIntentService.java 2014-05-17 07:00:19 +0000
2203@@ -7,36 +7,38 @@
2204 import android.support.v4.app.NotificationCompat;
2205 import android.util.Log;
2206
2207-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
2208 import com.google.android.gms.gcm.GoogleCloudMessaging;
2209
2210 /**
2211 * IntentService responsible for handling GCM messages.
2212 */
2213
2214- public class GCMIntentService extends IntentService {
2215-
2216- static String TAG="flowzr";
2217-
2218- public static final int NOTIFICATION_ID = 1;
2219- NotificationCompat.Builder builder;
2220-
2221- public GCMIntentService() {
2222- super("GCMIntentService");
2223- }
2224-
2225- @Override
2226- protected void onHandleIntent(Intent intent) {
2227- Bundle extras = intent.getExtras();
2228- GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
2229- String messageType = gcm.getMessageType(intent);
2230- if (!extras.isEmpty()) {
2231- if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
2232- Log.i(TAG,"starting sync from GCM");
2233- FlowzrSyncEngine.builAndRun(getApplicationContext());
2234- }
2235- }
2236- }
2237- }
2238+public class GCMIntentService extends IntentService {
2239+
2240+ static String TAG="flowzr";
2241
2242+ public static final int NOTIFICATION_ID = 1;
2243+ NotificationCompat.Builder builder;
2244+
2245+ public GCMIntentService() {
2246+ super("GCMIntentService");
2247+ }
2248+
2249+ @Override
2250+ protected void onHandleIntent(Intent intent) {
2251+ Bundle extras = intent.getExtras();
2252+ GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
2253+ String messageType = gcm.getMessageType(intent);
2254+ if (!extras.isEmpty()) {
2255+ if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
2256+ if (FlowzrSyncEngine.isRunning) {
2257+ Log.i(TAG,"sync already in progess");
2258+ return;
2259+ }
2260+ Log.i(TAG,"starting sync from GCM");
2261+ new FlowzrSyncTask(getApplicationContext()).execute();
2262+ }
2263+ }
2264+ }
2265+}
2266
2267
2268=== added file 'src/ru/orangesoftware/financisto/export/flowzr/GoogleDrivePictureClient.java'
2269--- src/ru/orangesoftware/financisto/export/flowzr/GoogleDrivePictureClient.java 1970-01-01 00:00:00 +0000
2270+++ src/ru/orangesoftware/financisto/export/flowzr/GoogleDrivePictureClient.java 2014-05-17 07:00:19 +0000
2271@@ -0,0 +1,94 @@
2272+/*
2273+ * Copyright (c) 2011 Denis Solonenko.
2274+ * All rights reserved. This program and the accompanying materials
2275+ * are made available under the terms of the GNU Public License v2.0
2276+ * which accompanies this distribution, and is available at
2277+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
2278+ */
2279+
2280+package ru.orangesoftware.financisto.export.flowzr;
2281+
2282+import java.io.IOException;
2283+import java.util.ArrayList;
2284+import java.util.List;
2285+
2286+import ru.orangesoftware.financisto.R;
2287+import ru.orangesoftware.financisto.export.ImportExportException;
2288+import ru.orangesoftware.financisto.utils.MyPreferences;
2289+import android.app.Notification;
2290+import android.app.NotificationManager;
2291+import android.app.PendingIntent;
2292+import android.content.Context;
2293+import android.content.Intent;
2294+import android.support.v4.app.NotificationCompat;
2295+
2296+import com.google.android.gms.auth.GoogleAuthException;
2297+import com.google.android.gms.auth.UserRecoverableAuthException;
2298+import com.google.api.client.extensions.android.http.AndroidHttp;
2299+import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
2300+import com.google.api.client.json.gson.GsonFactory;
2301+import com.google.api.services.drive.Drive;
2302+import com.google.api.services.drive.DriveScopes;
2303+import com.google.api.services.drive.model.FileList;
2304+
2305+/**
2306+ * Created by IntelliJ IDEA.
2307+ * User: Denis Solonenko
2308+ * Date: 11/9/11 2:19 AM
2309+ */
2310+public class GoogleDrivePictureClient {
2311+
2312+ public static Drive create(Context context) throws IOException, GoogleAuthException, ImportExportException {
2313+ String googleDriveAccount = MyPreferences.getGoogleDriveAccount(context);
2314+ if (googleDriveAccount == null) {
2315+ throw new ImportExportException(R.string.google_drive_account_required);
2316+ }
2317+ try {
2318+ List<String> scope = new ArrayList<String>();
2319+ scope.add(DriveScopes.DRIVE_FILE);
2320+ if (MyPreferences.isGoogleDriveFullReadonly(context)) {
2321+ scope.add(DriveScopes.DRIVE_READONLY);
2322+ }
2323+ GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context, scope);
2324+ credential.setSelectedAccountName(googleDriveAccount);
2325+ credential.getToken();
2326+ return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential).build();
2327+ } catch (UserRecoverableAuthException e) {
2328+ NotificationManager notificationManager = (NotificationManager) context
2329+ .getSystemService(Context.NOTIFICATION_SERVICE);
2330+ Intent authorizationIntent = e.getIntent();
2331+ authorizationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).addFlags(
2332+ Intent.FLAG_FROM_BACKGROUND);
2333+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
2334+ authorizationIntent, 0);
2335+ Notification notification = new NotificationCompat.Builder(context)
2336+ .setSmallIcon(android.R.drawable.ic_dialog_alert)
2337+ .setTicker(context.getString(R.string.google_drive_permission_requested))
2338+ .setContentTitle(context.getString(R.string.google_drive_permission_requested))
2339+ .setContentText(context.getString(R.string.google_drive_permission_requested_for_account, googleDriveAccount))
2340+ .setContentIntent(pendingIntent).setAutoCancel(true).build();
2341+ notificationManager.notify(0, notification);
2342+ throw new ImportExportException(R.string.google_drive_permission_required);
2343+ }
2344+ }
2345+
2346+ public static String getOrCreateDriveFolder(Drive drive, String targetFolder) throws IOException {
2347+ String folderId = null;
2348+ FileList folders = drive.files().list().setQ("mimeType='application/vnd.google-apps.folder'").execute();
2349+ for (com.google.api.services.drive.model.File f : folders.getItems()) {
2350+ if (f.getTitle().equals(targetFolder)) {
2351+ folderId = f.getId();
2352+ }
2353+ }
2354+ //if not found create it
2355+ if (folderId == null) {
2356+ com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
2357+ body.setTitle(targetFolder);
2358+ body.setMimeType("application/vnd.google-apps.folder");
2359+ com.google.api.services.drive.model.File file = drive.files().insert(body).execute();
2360+ folderId = file.getId();
2361+ }
2362+ return folderId;
2363+ }
2364+
2365+}
2366
2367=== added file 'src/ru/orangesoftware/financisto/export/flowzr/PictureDriveTask.java'
2368--- src/ru/orangesoftware/financisto/export/flowzr/PictureDriveTask.java 1970-01-01 00:00:00 +0000
2369+++ src/ru/orangesoftware/financisto/export/flowzr/PictureDriveTask.java 2014-05-17 07:00:19 +0000
2370@@ -0,0 +1,234 @@
2371+/*
2372+ * Copyright (c) 2012 Emmanuel Florent.
2373+ * All rights reserved. This program and the accompanying materials
2374+ * are made available under the terms of the GNU Public License v2.0
2375+ * which accompanies this distribution, and is available at
2376+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
2377+ */
2378+
2379+package ru.orangesoftware.financisto.export.flowzr;
2380+
2381+
2382+import java.io.BufferedInputStream;
2383+import java.io.FileInputStream;
2384+import java.io.IOException;
2385+import java.net.URLEncoder;
2386+import java.util.ArrayList;
2387+import java.util.Calendar;
2388+import java.util.Date;
2389+
2390+import org.apache.http.client.methods.HttpGet;
2391+import org.apache.http.impl.client.DefaultHttpClient;
2392+
2393+import ru.orangesoftware.financisto.R;
2394+import ru.orangesoftware.financisto.backup.DatabaseExport;
2395+import ru.orangesoftware.financisto.db.DatabaseAdapter;
2396+import ru.orangesoftware.financisto.db.DatabaseHelper;
2397+import ru.orangesoftware.financisto.export.ImportExportException;
2398+import ru.orangesoftware.financisto.export.docs.GoogleDriveClient;
2399+import ru.orangesoftware.financisto.utils.MyPreferences;
2400+import android.content.Context;
2401+import android.database.Cursor;
2402+import android.net.Uri;
2403+import android.os.AsyncTask;
2404+import android.util.Log;
2405+
2406+import com.google.android.gms.auth.GoogleAuthException;
2407+import com.google.api.client.http.InputStreamContent;
2408+import com.google.api.services.drive.Drive;
2409+import com.google.api.services.drive.model.File;
2410+import com.google.api.services.drive.model.FileList;
2411+import com.google.api.services.drive.model.ParentReference;
2412+
2413+public class PictureDriveTask extends AsyncTask<String, String, Object> {
2414+
2415+ private String rootFolderId;
2416+ private Uri fileUri;
2417+ private long trDate;
2418+ private String remote_key;
2419+ private Context context;
2420+ private DefaultHttpClient http_client;
2421+ private DatabaseAdapter dba;
2422+
2423+ public PictureDriveTask(Context context, DefaultHttpClient http_client,Uri _fileUri,long l,String _remote_key) {
2424+ this.http_client=http_client; //-(FlowzrSyncEngine) context)
2425+ this.context=context;
2426+ this.fileUri = _fileUri;
2427+ this.trDate = l;
2428+ this.remote_key=_remote_key;
2429+ dba = new DatabaseAdapter(context);
2430+ dba.open();
2431+ }
2432+
2433+
2434+ protected Object work(Context context, DatabaseAdapter db, String... params) throws Exception {
2435+ DatabaseExport export = new DatabaseExport(context, db.db(), true);
2436+ try {
2437+ String folder = MyPreferences.getGoogleDriveFolder(context);
2438+ // check the backup folder registered on preferences
2439+ if (folder == null || folder.equals("")) {
2440+ throw new ImportExportException(R.string.gdocs_folder_not_configured);
2441+ }
2442+ String googleDriveAccount = MyPreferences.getFlowzrAccount(context);
2443+ Drive drive = GoogleDriveClient.create(context,googleDriveAccount);
2444+ runUpload(drive);
2445+ return true;
2446+ } catch (ImportExportException e) {
2447+ throw e;
2448+ } catch (GoogleAuthException e) {
2449+ throw new ImportExportException(R.string.gdocs_connection_failed);
2450+ } catch (IOException e) {
2451+ e.printStackTrace();
2452+ throw new ImportExportException(R.string.gdocs_io_error);
2453+ } catch (Exception e) {
2454+ e.printStackTrace();
2455+ throw new ImportExportException(R.string.gdocs_service_error, e);
2456+ }
2457+ }
2458+
2459+ protected boolean runUpload (Drive driveService) throws IOException {
2460+ String targetFolderId=null;
2461+
2462+
2463+ String ROOT_FOLDER=MyPreferences.getGoogleDriveFolder(context);
2464+ // ensure to have the app root folder in drive ...
2465+ if (rootFolderId==null) {
2466+ //search root folder ...
2467+ FileList folders=driveService.files().list().setQ("mimeType='application/vnd.google-apps.folder'").execute();
2468+ for(File fl: folders.getItems()){
2469+ if (fl.getTitle().equals(ROOT_FOLDER)) {
2470+ rootFolderId=fl.getId();
2471+ }
2472+ }
2473+ //if not found create it
2474+ if (rootFolderId==null) {
2475+ File body = new File();
2476+ body.setTitle(ROOT_FOLDER);
2477+ body.setMimeType("application/vnd.google-apps.folder");
2478+ File file = driveService.files().insert(body).execute();
2479+ rootFolderId=file.getId();
2480+ }
2481+ }
2482+ //search for the target folder (depending of the date)
2483+ Calendar cal = Calendar.getInstance();
2484+ cal.setTime(new Date(trDate));
2485+ int month=cal.get(Calendar.MONTH) + 1;
2486+ String targetFolder=String.valueOf(cal.get(Calendar.YEAR)) + "-" + (month<10?("0"+month):(month));
2487+
2488+ FileList subfolders=driveService.files().list().setQ("mimeType='application/vnd.google-apps.folder' and '" + rootFolderId + "' in parents").execute();
2489+ for(File fl: subfolders.getItems()){
2490+ if (fl.getTitle().equals(targetFolder)) {
2491+ targetFolderId=fl.getId();
2492+ }
2493+ }
2494+ //create the target folder if not exist
2495+ if (targetFolderId==null) {
2496+ //create folder
2497+ File body = new File();
2498+ body.setTitle(targetFolder);
2499+ ArrayList<ParentReference> pList=new ArrayList<ParentReference>();
2500+ pList.add(new ParentReference().setId(rootFolderId)) ;
2501+ body.setParents(pList);
2502+ body.setMimeType("application/vnd.google-apps.folder");
2503+ File file = driveService.files().insert(body).execute();
2504+ targetFolder=file.getId();
2505+ }
2506+ // File's binary content
2507+ java.io.File fileContent = new java.io.File(fileUri.getPath());
2508+ InputStreamContent mediaContent = new InputStreamContent("image/jpeg", new BufferedInputStream(
2509+ new FileInputStream(fileContent)));
2510+ mediaContent.setLength(fileContent.length());
2511+ // File's metadata.
2512+ File body = new File();
2513+ body.setTitle(fileContent.getName());
2514+ body.setMimeType("image/jpeg");
2515+ body.setFileSize(fileContent.length());
2516+ ArrayList<ParentReference> pList2=new ArrayList<ParentReference>();
2517+ pList2.add(new ParentReference().setId(targetFolderId)) ;
2518+ body.setParents(pList2);
2519+ File file = driveService.files().insert(body, mediaContent).execute();
2520+
2521+
2522+ Thread thread= new Thread(){
2523+ @Override
2524+ public void run(){
2525+ try {
2526+ synchronized(this){
2527+ wait(3000);
2528+ }
2529+ }
2530+ catch(InterruptedException ex){
2531+ }
2532+ }
2533+ };
2534+ thread.start();
2535+
2536+ String uploadedId=null;
2537+ FileList files;
2538+
2539+ files = driveService.files().list().setQ("mimeType='image/jpeg' and '" + targetFolderId + "' in parents").execute();
2540+ String file_url="";
2541+ String thumbnail_url="";
2542+ for(File fl: files.getItems()){
2543+ if (fl.getTitle().equals(fileUri.getLastPathSegment())) {
2544+ uploadedId=fl.getId();
2545+ try {
2546+ file_url=fl.getAlternateLink();
2547+ thumbnail_url=fl.getIconLink();
2548+ } catch (Exception e) {
2549+ file_url="https://drive.google.com/#folders/" + targetFolderId +"/";
2550+ }
2551+ }
2552+ }
2553+ if (!uploadedId.equals("null")) {
2554+ String sql="update transactions set blob_key='" + uploadedId + "' where remote_key='" + remote_key+"'";
2555+ dba.db().execSQL(sql);
2556+ sql="select from_account_id,attached_picture from " + DatabaseHelper.TRANSACTION_TABLE + " where remote_key='" + remote_key+"'";
2557+ Cursor c=dba.db().rawQuery(sql, null);
2558+ if (c.moveToFirst()) {
2559+ String account_key=FlowzrSyncEngine.getRemoteKey(DatabaseHelper.ACCOUNT_TABLE, String.valueOf(c.getLong(0)));
2560+ String file_type="image/jpeg";
2561+ String file_name=c.getString(1);
2562+ if (file_url==null) {
2563+ file_url="";
2564+ }
2565+ if (thumbnail_url==null) {
2566+ thumbnail_url="";
2567+ }
2568+ if (http_client!=null) {
2569+ //make html link beetwen Flowzr.com & Drive
2570+ String url=FlowzrSyncEngine.FLOWZR_API_URL +"/clear/blob/?url=" + URLEncoder.encode(file_url, "UTF-8") + "&thumbnail_url=" + URLEncoder.encode(thumbnail_url, "UTF-8") + "&account="+account_key+"&crebit="+ remote_key + "&name="+ file_name + "&blob_key=" + uploadedId + "type=" + file_type;
2571+ try {
2572+ HttpGet httpGet = new HttpGet(url);
2573+ http_client.execute(httpGet);
2574+ Log.i("flowzr","linked to :" + file_url);
2575+ } catch (Exception e) {
2576+ e.printStackTrace();
2577+ }
2578+ }
2579+ }
2580+ }
2581+
2582+ return true;
2583+ }
2584+
2585+ protected String getSuccessMessage(Object result) {
2586+ return String.valueOf(result);
2587+ }
2588+
2589+
2590+ @Override
2591+ protected Object doInBackground(String... arg0) {
2592+ DatabaseAdapter db = new DatabaseAdapter(context);
2593+ db.open();
2594+ try {
2595+ return work(context, db);
2596+ } catch(Exception ex){
2597+ Log.e("Financisto", "Unable to do import/export", ex);
2598+ return ex;
2599+ } finally {
2600+ db.close();
2601+ }
2602+ }
2603+
2604+}
2605\ No newline at end of file
2606
2607=== modified file 'src/ru/orangesoftware/financisto/service/FinancistoService.java'
2608--- src/ru/orangesoftware/financisto/service/FinancistoService.java 2014-01-27 15:52:09 +0000
2609+++ src/ru/orangesoftware/financisto/service/FinancistoService.java 2014-05-17 07:00:19 +0000
2610@@ -10,19 +10,10 @@
2611 ******************************************************************************/
2612 package ru.orangesoftware.financisto.service;
2613
2614-import android.app.Notification;
2615-import android.app.NotificationManager;
2616-import android.app.PendingIntent;
2617-import android.content.Context;
2618-import android.content.Intent;
2619-import android.content.SharedPreferences;
2620-import android.database.Cursor;
2621-import android.os.IBinder;
2622-import android.preference.PreferenceManager;
2623-import android.util.Log;
2624-import com.commonsware.cwac.wakeful.WakefulIntentService;
2625-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
2626-import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncOptions;
2627+import static ru.orangesoftware.financisto.service.DailyAutoBackupScheduler.scheduleNextAutoBackup;
2628+import static ru.orangesoftware.financisto.service.FlowzrAutoSyncScheduler.scheduleNextAutoSync;
2629+
2630+import java.util.Date;
2631
2632 import ru.orangesoftware.financisto.R;
2633 import ru.orangesoftware.financisto.activity.AbstractTransactionActivity;
2634@@ -30,18 +21,25 @@
2635 import ru.orangesoftware.financisto.activity.MassOpActivity;
2636 import ru.orangesoftware.financisto.backup.DatabaseExport;
2637 import ru.orangesoftware.financisto.blotter.BlotterFilter;
2638-import ru.orangesoftware.financisto.filter.WhereFilter;
2639 import ru.orangesoftware.financisto.db.DatabaseAdapter;
2640 import ru.orangesoftware.financisto.export.Export;
2641+import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncEngine;
2642+import ru.orangesoftware.financisto.export.flowzr.FlowzrSyncTask;
2643+import ru.orangesoftware.financisto.filter.WhereFilter;
2644+import ru.orangesoftware.financisto.model.TransactionInfo;
2645 import ru.orangesoftware.financisto.model.TransactionStatus;
2646-import ru.orangesoftware.financisto.model.TransactionInfo;
2647 import ru.orangesoftware.financisto.recur.NotificationOptions;
2648 import ru.orangesoftware.financisto.utils.MyPreferences;
2649-
2650-import java.util.Date;
2651-
2652-import static ru.orangesoftware.financisto.service.DailyAutoBackupScheduler.scheduleNextAutoBackup;
2653-import static ru.orangesoftware.financisto.service.FlowzrAutoSyncScheduler.scheduleNextAutoSync;
2654+import android.app.Notification;
2655+import android.app.NotificationManager;
2656+import android.app.PendingIntent;
2657+import android.content.Context;
2658+import android.content.Intent;
2659+import android.database.Cursor;
2660+import android.os.IBinder;
2661+import android.util.Log;
2662+
2663+import com.commonsware.cwac.wakeful.WakefulIntentService;
2664
2665 public class FinancistoService extends WakefulIntentService {
2666
2667@@ -118,13 +116,15 @@
2668
2669 private void doAutoSync() {
2670 try {
2671- Log.i(TAG, "Auto-sync started at " + new Date());
2672- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
2673- FlowzrSyncOptions o =FlowzrSyncOptions.fromPrefs(preferences);
2674- if (isPushSyncNeed(o.last_sync_ts)) {
2675- FlowzrSyncEngine.builAndRun(getApplicationContext());
2676+ Log.i(TAG, "Auto-sync started at " + new Date());
2677+ if (isPushSyncNeed(MyPreferences.getFlowzrLastSync(getApplicationContext()))) {
2678+ if (FlowzrSyncEngine.isRunning) {
2679+ Log.i(TAG,"sync already in progess");
2680+ return;
2681+ }
2682+ new FlowzrSyncTask(getApplicationContext()).execute();
2683 } else {
2684- Log.i(TAG,"no changes to push since " + new Date(o.last_sync_ts).toString());
2685+ Log.i(TAG,"no changes to push since " + new Date(MyPreferences.getFlowzrLastSync(getApplicationContext())).toString());
2686 }
2687 } finally {
2688 scheduleNextAutoSync(this);
2689
2690=== modified file 'src/ru/orangesoftware/financisto/utils/MyPreferences.java'
2691--- src/ru/orangesoftware/financisto/utils/MyPreferences.java 2014-01-27 15:52:09 +0000
2692+++ src/ru/orangesoftware/financisto/utils/MyPreferences.java 2014-05-17 07:00:19 +0000
2693@@ -606,9 +606,6 @@
2694 return getBoolean(context, "googledrive_upload", false);
2695 }
2696
2697- public static boolean isAutoSync(Context context) {
2698- return getBoolean(context, "auto_sync_enabled", false);
2699- }
2700
2701 public static String getGoogleDriveAccount(Context context) {
2702 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2703@@ -624,4 +621,41 @@
2704 return getBoolean(context, "google_drive_backup_full_readonly", false);
2705 }
2706
2707+ public static void setFlowzrAccount(Context context, String accountName) {
2708+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2709+ sharedPreferences.edit().putString("flowzr_account", accountName).commit();
2710+ }
2711+
2712+ public static void unsetAutoSync(Context context) {
2713+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2714+ sharedPreferences.edit().putBoolean("auto_sync_enabled", false).commit();
2715+ }
2716+
2717+
2718+ public static String getFlowzrAccount(Context context) {
2719+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2720+ return sharedPreferences.getString("flowzr_account", null);
2721+ }
2722+
2723+ public static String getSyncApiUrl(Context context) {
2724+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2725+ return sharedPreferences.getString("sync_api_url", "flowzr-hrd.appspot.com");
2726+ }
2727+
2728+ public static void setSyncApiUrl(Context context, String serverName) {
2729+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2730+ sharedPreferences.edit().putString("sync_api_url", serverName).commit();
2731+ }
2732+
2733+
2734+ public static long getFlowzrLastSync(Context context) {
2735+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
2736+ return sharedPreferences.getLong("PROPERTY_LAST_SYNC_TIMESTAMP",0);
2737+ }
2738+
2739+ public static boolean isAutoSync(Context context) {
2740+ return getBoolean(context, "auto_sync_enabled", false);
2741+ }
2742+
2743+
2744 }