summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2012-10-15 17:01:08 +0400
committerAndrew Dolgov <[email protected]>2012-10-15 17:01:08 +0400
commit60b1b4234a2da1826c2b4a6ddcd22f480185e696 (patch)
treedb6e28e35038b5c138964f6950639afb3af0496a /src
parentcf5ed38aa2476051908030fc210faede5d60567a (diff)
implement sync lastread position sharing
Diffstat (limited to 'src')
-rw-r--r--src/org/fox/ttcomics/CommonActivity.java47
-rw-r--r--src/org/fox/ttcomics/MainActivity.java21
-rw-r--r--src/org/fox/ttcomics/SyncClient.java123
-rw-r--r--src/org/fox/ttcomics/ViewComicActivity.java40
4 files changed, 225 insertions, 6 deletions
diff --git a/src/org/fox/ttcomics/CommonActivity.java b/src/org/fox/ttcomics/CommonActivity.java
index 0a368b5..f4aa04d 100644
--- a/src/org/fox/ttcomics/CommonActivity.java
+++ b/src/org/fox/ttcomics/CommonActivity.java
@@ -5,6 +5,8 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
+import android.accounts.Account;
+import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -25,7 +27,11 @@ public class CommonActivity extends FragmentActivity {
protected static final String FRAG_COMICS_PAGER = "comic_pager";
protected static final String FRAG_COMICS_LIST = "comics_list";
+ protected final static int REQUEST_SHARE = 1;
+ protected static final int REQUEST_VIEWCOMIC = 2;
+
protected SharedPreferences m_prefs;
+ protected SyncClient m_syncClient = new SyncClient();
private boolean m_smallScreenMode = true;
@@ -34,7 +40,15 @@ public class CommonActivity extends FragmentActivity {
super.onCreate(savedInstanceState);
m_prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-
+
+ String googleAccount = getGoogleAccount();
+
+ if (googleAccount != null) {
+ m_syncClient.setOwner(googleAccount);
+ } else {
+ //toast("No Google account found, sync disabled.");
+ m_syncClient.setOwner("TEST-ACCOUNT");
+ }
}
public static boolean isCompatMode() {
@@ -159,6 +173,25 @@ public class CommonActivity extends FragmentActivity {
return null;
}
+ protected static String sha1(String s) {
+ try {
+ MessageDigest digest = java.security.MessageDigest.getInstance("SHA1");
+ digest.update(s.getBytes());
+ byte messageDigest[] = digest.digest();
+
+ StringBuffer hexString = new StringBuffer();
+ for (int i=0; i<messageDigest.length; i++)
+ hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
+
+ return hexString.toString();
+
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
public String getCacheFileName(String fileName) {
String hash = md5(fileName);
@@ -167,6 +200,18 @@ public class CommonActivity extends FragmentActivity {
return file.getAbsolutePath();
}
+ public String getGoogleAccount() {
+ AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+ Account[] list = manager.getAccounts();
+
+ for (Account account: list) {
+ if (account.type.equalsIgnoreCase("com.google")) {
+ return account.name;
+ }
+ }
+ return null;
+ }
+
public void toast(int msgId) {
Toast toast = Toast.makeText(CommonActivity.this, msgId, Toast.LENGTH_SHORT);
toast.show();
diff --git a/src/org/fox/ttcomics/MainActivity.java b/src/org/fox/ttcomics/MainActivity.java
index f34ccb5..4252955 100644
--- a/src/org/fox/ttcomics/MainActivity.java
+++ b/src/org/fox/ttcomics/MainActivity.java
@@ -24,6 +24,7 @@ public class MainActivity extends CommonActivity {
private TabListener m_tabListener;
private int m_selectedTab;
private String m_baseDirectory = "";
+ private String m_fileName = "";
@SuppressLint("NewApi")
private class TabListener implements ActionBar.TabListener {
@@ -88,6 +89,7 @@ public class MainActivity extends CommonActivity {
} else {
m_selectedTab = -1;
m_baseDirectory = savedInstanceState.getString("baseDir");
+ m_fileName = savedInstanceState.getString("fileName");
}
if (!isCompatMode()) {
@@ -163,6 +165,7 @@ public class MainActivity extends CommonActivity {
out.putInt("selectedTab", m_selectedTab);
out.putString("baseDir", m_baseDirectory);
+ out.putString("fileName", m_fileName);
}
public boolean onOptionsItemSelected(MenuItem item) {
@@ -201,10 +204,24 @@ public class MainActivity extends CommonActivity {
ViewComicActivity.class);
intent.putExtra("fileName", fileName);
-
- startActivityForResult(intent, 0);
+ m_fileName = fileName;
+
+ startActivityForResult(intent, REQUEST_VIEWCOMIC);
}
}
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (requestCode == REQUEST_VIEWCOMIC) {
+ //Log.d(TAG, "finished viewing comic: " + m_fileName);
+
+ if (m_prefs.getBoolean("use_position_sync", false)) {
+ toast("Uploading sync data...");
+ m_syncClient.setPosition(sha1(new File(m_fileName).getName()), getLastPosition(m_fileName));
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, intent);
+ }
+
}
diff --git a/src/org/fox/ttcomics/SyncClient.java b/src/org/fox/ttcomics/SyncClient.java
new file mode 100644
index 0000000..377a3fc
--- /dev/null
+++ b/src/org/fox/ttcomics/SyncClient.java
@@ -0,0 +1,123 @@
+package org.fox.ttcomics;
+
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class SyncClient {
+ public interface PositionReceivedListener {
+ void onPositionReceived(int position);
+ }
+
+ private class HttpTask extends AsyncTask<String, Integer, Boolean> {
+ protected String m_response = null;
+ protected int m_responseCode = -1;
+
+ @Override
+ protected Boolean doInBackground(String... params) {
+
+ String requestStr = "set".equals(params[0]) ? String.format("op=set&owner=%1$s&hash=%2$s&position=%3$s", m_owner, params[1], params[2]) :
+ String.format("op=get&owner=%1$s&hash=%2$s", m_owner, params[1]);
+
+ try {
+ byte[] postData = requestStr.getBytes("UTF-8");
+
+ URL url = new URL(SYNC_ENDPOINT);
+
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setUseCaches(false);
+ conn.setRequestMethod("POST");
+
+ OutputStream out = conn.getOutputStream();
+ out.write(postData);
+ out.close();
+
+ m_responseCode = conn.getResponseCode();
+
+ if (m_responseCode == HttpURLConnection.HTTP_OK) {
+ StringBuffer response = new StringBuffer();
+ InputStreamReader in = new InputStreamReader(conn.getInputStream(), "UTF-8");
+
+ char[] buf = new char[1024];
+ int read = 0;
+
+ while ((read = in.read(buf)) >= 0) {
+ response.append(buf, 0, read);
+ }
+
+ //Log.d(TAG, "<<< " + response);
+
+ m_response = response.toString();
+
+ if (response.indexOf("ERROR") == -1) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ Log.d(TAG, "HTTP error, code: " + m_responseCode);
+ }
+
+ conn.disconnect();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ }
+
+ private final String TAG = this.getClass().getSimpleName();
+ private static final String SYNC_ENDPOINT = "http://tt-rss.org/tcrsync/";
+ private String m_owner = null;
+
+ public void setOwner(String owner) {
+ m_owner = CommonActivity.sha1(owner);
+ }
+
+ public int getPosition(String hash, final PositionReceivedListener listener) {
+ if (m_owner != null) {
+ Log.d(TAG, "Requesting sync data...");
+
+ HttpTask task = new HttpTask() {
+ @Override
+ protected void onPostExecute(Boolean result) {
+ if (result) {
+ try {
+ listener.onPositionReceived(Integer.valueOf(m_response));
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ task.execute("get", hash);
+
+ }
+ return -1;
+ }
+
+ public void setPosition(String hash, int position) {
+ if (m_owner != null) {
+ Log.d(TAG, "Uploading sync data...");
+
+ HttpTask task = new HttpTask();
+
+ task.execute("set", hash, String.valueOf(position));
+ }
+ }
+
+ public boolean hasOwner() {
+ return m_owner != null;
+ }
+
+}
diff --git a/src/org/fox/ttcomics/ViewComicActivity.java b/src/org/fox/ttcomics/ViewComicActivity.java
index 1bd47b5..8693048 100644
--- a/src/org/fox/ttcomics/ViewComicActivity.java
+++ b/src/org/fox/ttcomics/ViewComicActivity.java
@@ -28,8 +28,6 @@ import android.widget.TextView;
public class ViewComicActivity extends CommonActivity {
private final String TAG = this.getClass().getSimpleName();
-
- private final static int REQUEST_SHARE = 1;
private String m_fileName;
private String m_tmpFileName;
@@ -66,11 +64,15 @@ public class ViewComicActivity extends CommonActivity {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
+
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_view_comic, menu);
+
+ menu.findItem(R.id.menu_sync_location).setVisible(m_prefs.getBoolean("use_position_sync", false) && m_syncClient.hasOwner());
+
return true;
}
@@ -118,7 +120,7 @@ public class ViewComicActivity extends CommonActivity {
m_tmpFileName = tmpFile.getAbsolutePath();
- startActivityForResult(Intent.createChooser(shareIntent, "Share comic"), REQUEST_SHARE);
+ startActivityForResult(Intent.createChooser(shareIntent, getString(R.string.share_comic)), REQUEST_SHARE);
} catch (IOException e) {
toast(getString(R.string.error_could_not_prepare_file_for_sharing));
@@ -146,6 +148,38 @@ public class ViewComicActivity extends CommonActivity {
case R.id.menu_share:
shareComic();
return true;
+ case R.id.menu_sync_location:
+ m_syncClient.getPosition(sha1(new File(m_fileName).getName()), new SyncClient.PositionReceivedListener() {
+ @Override
+ public void onPositionReceived(final int position) {
+ final ComicPager pager = (ComicPager) getSupportFragmentManager().findFragmentByTag(FRAG_COMICS_PAGER);
+
+ if (pager != null && pager.isAdded()) {
+ int localPosition = pager.getPosition();
+
+ if (position > localPosition) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(ViewComicActivity.this);
+ builder.setMessage(getString(R.string.sync_server_has_further_page, localPosition+1, position+1))
+ .setCancelable(false)
+ .setPositiveButton(R.string.dialog_open_page, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ pager.setCurrentItem(position);
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+ AlertDialog alert = builder.create();
+ alert.show();
+
+ }
+
+ }
+ }
+ });
+ return true;
case R.id.menu_go_location:
Dialog dialog = new Dialog(ViewComicActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(ViewComicActivity.this)