package org.mots.haxsync.services;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONObject;
import org.mots.haxsync.R;
import org.mots.haxsync.provider.FacebookStatus;
import org.mots.haxsync.provider.Status;
import org.mots.haxsync.utilities.DeviceUtil;
import org.mots.haxsync.utilities.FacebookUtil;
import org.mots.haxsync.utilities.WebUtil;
import org.mots.haxsync.utilities.intents.Stream;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
import android.app.IntentService;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.StreamItemPhotos;
import android.provider.ContactsContract.StreamItems;
import android.util.Log;
/**
* Service to handle view notifications. This allows the sample sync adapter to update the
* information when the contact is being looked at
*/
@SuppressLint("NewApi")
public class NotifierService extends IntentService {
private static final String TAG = "NotifierService";
private static ContentResolver mContentResolver;
private long addContactStreamItem(long rawContactId, String uid, FacebookStatus status, Account account){
//get timestamp of latest saved streamItem
Cursor c = mContentResolver.query(Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
RawContacts.StreamItems.CONTENT_DIRECTORY),
new String[] {StreamItems.TIMESTAMP}, null, null, StreamItems.TIMESTAMP+" DESC");
long oldTimestamp = -2;
if (c.getCount() > 0){
c.moveToFirst();
oldTimestamp = c.getLong(c.getColumnIndex("timestamp"));
}
c.close();
long timestamp = status.getTimestamp();
//only add item if newer then latest saved one
if(oldTimestamp >= timestamp){
return -2;
}
String message = status.getMessage();
String picLink = findPicLink(message);
message = message.replace(picLink, "");
Youtube yt = findYoutube(message);
if (yt != null)
message = message.replace(yt.link, "");
ContentValues values = new ContentValues();
values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
values.put(StreamItems.RES_PACKAGE, "org.mots.haxsync");
values.put(StreamItems.RES_LABEL, R.string.app_name);
values.put(StreamItems.TEXT, message);
values.put(StreamItems.TIMESTAMP, timestamp);
String commentString = status.getCommentHtml();
if (!commentString.equals("")){
values.put(StreamItems.COMMENTS, commentString);
}
values.put(StreamItems.SYNC1, status.getID());
values.put(StreamItems.SYNC2, uid);
values.put(StreamItems.SYNC3, status.getPermalink());
values.put(StreamItems.ACCOUNT_NAME, account.name);
values.put(StreamItems.ACCOUNT_TYPE, account.type);
Uri streamItemUri = mContentResolver.insert(StreamItems.CONTENT_URI, values);
long streamItemId = ContentUris.parseId(streamItemUri);
if (status.getType() == 247)
addFBPhoto(streamItemId, account, status.getAppData());
if (yt != null)
addYoutubeThumb(streamItemId, account, yt);
if (!picLink.equals(""))
addPicThumb(streamItemId, account, picLink);
return streamItemId;
}
private void addStreamPhoto(long itemID, byte[] photo, Account account, String type, String sync2){
ContentValues values = new ContentValues();
values.put(StreamItemPhotos.STREAM_ITEM_ID, itemID);
values.put(StreamItemPhotos.SORT_INDEX, 1);
values.put(StreamItemPhotos.PHOTO, photo);
values.put(StreamItems.ACCOUNT_NAME, account.name);
values.put(StreamItems.ACCOUNT_TYPE, account.type);
values.put(StreamItemPhotos.SYNC1, type);
values.put(StreamItemPhotos.SYNC2, sync2);
mContentResolver.insert(StreamItems.CONTENT_PHOTO_URI, values);
}
private String findPicLink(String message){
String picLink = "";
Pattern picPattern = Pattern.compile("https?:\\/\\/[a-z0-9\\-\\.]+\\.[a-z]{2,3}/.+\\.(jpg|png|gif|bmp)", Pattern.CASE_INSENSITIVE);
Matcher picMatcher = picPattern.matcher(message);
while (picMatcher.find()){
picLink = picMatcher.group();
//Log.i("picLink", picLink);
}
return picLink;
}
public static class Youtube{
public String ID;
public String link;
}
private Youtube findYoutube(String message){
Youtube yt = null;
Pattern ytPattern = Pattern.compile ("https?:\\/\\/(?:[0-9A-Z-]+\\.)?(?:youtu\\.be\\/|youtube\\.com\\S*[^\\w\\-\\s])([\\w\\-]{11})(?=[^\\w\\-]|$)(?![?=&+%\\w]*(?:['\"][^<>]*>|<\\/a>))[?=&+%\\w]*", Pattern.CASE_INSENSITIVE);
Matcher ytMatcher = ytPattern.matcher(message);
while (ytMatcher.find()){
yt = new Youtube();
yt.link = ytMatcher.group();
yt.ID = ytMatcher.group(1);
}
return yt;
}
private void addFBPhoto(long streamID, Account account, JSONObject appData){
long picID = 0;
try {
picID = appData.getJSONArray("photo_ids").getLong(0);
} catch (Exception e) {
Log.e("ERROR", e.toString());
}
if (picID != 0){
JSONObject picinfo = FacebookUtil.getPicInfo(picID);
if (picinfo != null){
String src = null;
try {
src = picinfo.getString("src_big");
} catch (Exception e) {
Log.e("ERROR", e.toString());
}
if (src != null){
byte[] pic = WebUtil.download(src);
if (pic != null){
addStreamPhoto(streamID, pic, account, "fbphoto", String.valueOf(picID));
}
}
}
}
}
private void addYoutubeThumb(long streamID, Account account, Youtube yt){
byte[] pic = WebUtil.download("http://img.youtube.com/vi/"+yt.ID+"/0.jpg");
if (pic != null){
addStreamPhoto(streamID, pic, account, "youtube", yt.link);
}
}
private void addPicThumb(long streamID, Account account, String picLink){
byte[] pic = WebUtil.download(picLink);
if (pic != null){
addStreamPhoto(streamID, pic, account, "link", picLink);
}
}
public NotifierService() {
super(TAG);
}
@SuppressWarnings("unused")
@Override
protected void onHandleIntent(Intent intent) {
if (!FacebookUtil.RESPECT_FACEBOOK_POLICY && DeviceUtil.isOnline(this)){
Log.i(TAG, "is online");
SharedPreferences prefs = this.getSharedPreferences(this.getPackageName() + "_preferences", MODE_MULTI_PROCESS);
boolean sync = prefs.getBoolean("sync_status", true);
boolean syncNew = prefs.getBoolean("status_new", true);
boolean timelineAll = prefs.getBoolean("timeline_all", false);
if (Build.VERSION.SDK_INT >= 15 && sync && syncNew){
mContentResolver = this.getContentResolver();
AccountManager am = AccountManager.get(this);
Account account = am.getAccountsByType("org.mots.haxsync.account")[0];
if (FacebookUtil.authorize(this, account)){
String[] projection = new String[] {RawContacts._ID, RawContacts.SYNC1};
Cursor c = mContentResolver.query(intent.getData(), projection, null, null, null);
c.moveToFirst();
long id = c.getLong(c.getColumnIndex(RawContacts._ID));
String uid = c.getString(c.getColumnIndex(RawContacts.SYNC1));
c.close();
ArrayList<Status> statuses = FacebookUtil.getStatuses(uid, timelineAll);
if (statuses != null) {
Log.i(TAG, statuses.toString());
for (Status status : statuses) {
FacebookStatus fbstatus = (FacebookStatus) status;
if (timelineAll || fbstatus.getActorID().equals(uid)){
if (fbstatus != null && !fbstatus.getMessage().equals(""))
addContactStreamItem(id, uid, fbstatus, account);
}
}
}
}
}
}
}
}