/**
* Android ownCloud News
*
* @author David Luhmer
* @copyright 2013 David Luhmer david-dev@live.de
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.luhmer.owncloudnewsreader.reader.owncloud;
import android.content.Context;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.model.RssItem;
import de.luhmer.owncloudnewsreader.reader.FeedItemTags;
import de.luhmer.owncloudnewsreader.reader.HttpJsonRequest;
import de.luhmer.owncloudnewsreader.reader.owncloud.apiv1.APIv1;
import de.luhmer.owncloudnewsreader.reader.owncloud.apiv2.APIv2;
import okhttp3.HttpUrl;
public class OwnCloudReaderMethods {
@SuppressWarnings("unused")
private static final String TAG = "OwnCloudReaderMethods";
public static String maxSizePerSync = "300";
public static int[] GetUpdatedItems(FeedItemTags tag, Context cont, long lastSync, API api) throws Exception
{
HttpUrl.Builder getItemUpdatedUrlBuilder = api.getItemUpdatedUrl().newBuilder();
if(tag.equals(FeedItemTags.ALL_STARRED) || tag.equals(FeedItemTags.ALL))
{
getItemUpdatedUrlBuilder.addQueryParameter("type", tag.toString())
.addQueryParameter("id", "0");
}
getItemUpdatedUrlBuilder.addQueryParameter("lastModified", String.valueOf(lastSync));
InputStream is = HttpJsonRequest.getInstance().PerformJsonRequest(getItemUpdatedUrlBuilder.build());
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(cont);
try
{
if(api instanceof APIv1)
return readJsonStreamV1(is, new InsertItemIntoDatabase(dbConn));
else if(api instanceof APIv2)
return readJsonStreamV2(is, new InsertItemIntoDatabase(dbConn));
} finally {
is.close();
}
return new int[] { 0, 0 };
}
//"type": 1, // the type of the query (Feed: 0, Folder: 1, Starred: 2, All: 3)
public static int GetItems(FeedItemTags tag, Context cont, String offset, boolean getRead, String id, String type, API api) throws Exception
{
HttpUrl.Builder getItemsUrlBuilder = api.getItemUrl().newBuilder();
getItemsUrlBuilder.addQueryParameter("batchSize", maxSizePerSync)
.addQueryParameter("offset", offset)
.addQueryParameter("getRead", String.valueOf(getRead));
if(tag.equals(FeedItemTags.ALL_STARRED) ||tag.equals(FeedItemTags.ALL))
{
getItemsUrlBuilder.addQueryParameter("type",type)
.addQueryParameter("id", id);
}
InputStream is = HttpJsonRequest.getInstance().PerformJsonRequest(getItemsUrlBuilder.build());
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(cont);
try
{
if(api instanceof APIv1)
return readJsonStreamV1(is, new InsertItemIntoDatabase(dbConn))[0];
else if(api instanceof APIv2)
return readJsonStreamV2(is, new InsertItemIntoDatabase(dbConn))[0];
} finally {
is.close();
}
return 0;
}
public static int GetFolderTags(Context cont, API api) throws Exception
{
InputStream is = HttpJsonRequest.getInstance().PerformJsonRequest(api.getFolderUrl());
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(cont);
int[] result = new int[2];
try
{
InsertFolderIntoDatabase ifid = new InsertFolderIntoDatabase(dbConn);
if(api instanceof APIv1)
result = readJsonStreamV1(is, ifid);
else if(api instanceof APIv2)
result = readJsonStreamV2(is, ifid);
ifid.WriteAllToDatabaseNow();
} finally {
is.close();
}
return result[0];
}
public static int[] GetFeeds(Context cont, API api) throws Exception
{
InputStream inputStream = HttpJsonRequest.getInstance().PerformJsonRequest(api.getFeedUrl());
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(cont);
int result[] = new int[2];
try {
InsertFeedIntoDatabase ifid = new InsertFeedIntoDatabase(dbConn);
if(api instanceof APIv1)
result = readJsonStreamV1(inputStream, ifid);
else if(api instanceof APIv2)
result = readJsonStreamV2(inputStream, ifid);
ifid.WriteAllToDatabaseNow();
} finally {
inputStream.close();
}
return result;
}
/**
* can parse json like {"items":[{"id":6782}]}
* @param in
* @param iJoBj
* @return count all, count new items
* @throws IOException
*/
public static int[] readJsonStreamV2(InputStream in, IHandleJsonObject iJoBj) throws IOException {
List<String> allowedArrays = Arrays.asList("feeds", "folders", "items");
int count = 0;
int newItemsCount = 0;
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
reader.beginObject();
String currentName;
while(reader.hasNext() && (currentName = reader.nextName()) != null) {
if(allowedArrays.contains(currentName))
break;
else
reader.skipValue();
}
reader.beginArray();
while (reader.hasNext()) {
JSONObject e = getJSONObjectFromReader(reader);
if(iJoBj.performAction(e))
newItemsCount++;
count++;
}
if(iJoBj instanceof InsertItemIntoDatabase)
((InsertItemIntoDatabase) iJoBj).performDatabaseBatchInsert(); //Save pending buffer
//reader.endArray();
//reader.endObject();
reader.close();
return new int[] { count, newItemsCount };
}
/**
* can parse json like {"items":[{"id":6782}]}
* @param in
* @param iJoBj
* @return new int[] { count, newItemsCount }
* @throws IOException
*/
public static int[] readJsonStreamV1(InputStream in, IHandleJsonObject iJoBj) throws IOException {
int count = 0;
int newItemsCount = 0;
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
reader.beginObject();//{
reader.nextName();//"ocs"
reader.beginObject();//{
reader.nextName();//meta
getJSONObjectFromReader(reader);//skip status etc.
reader.nextName();//data
reader.beginObject();//{
reader.nextName();//folders etc..
reader.beginArray();
while (reader.hasNext()) {
//reader.beginObject();
JSONObject e = getJSONObjectFromReader(reader);
if(iJoBj.performAction(e))
newItemsCount++;
//reader.endObject();
count++;
}
if(iJoBj instanceof InsertItemIntoDatabase)
((InsertItemIntoDatabase) iJoBj).performDatabaseBatchInsert(); //Save pending buffer
//reader.endArray();
//reader.endObject();
reader.close();
return new int[] { count, newItemsCount };
}
/**
* can read json like {"version":"1.101"}
* @param in
* @param iJoBj
* @return
* @throws IOException
*/
private static int readJsonStreamSimple(InputStream in, IHandleJsonObject iJoBj) throws IOException {
int count = 0;
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
//reader.setLenient(true);
//JsonToken token = reader.peek();
//while(token.equals(JsonToken.STRING))
// reader.skipValue();
JSONObject e = getJSONObjectFromReader(reader);
iJoBj.performAction(e);
reader.close();
return count;
}
private static JSONObject getJSONObjectFromReader(JsonReader jsonReader) {
JSONObject jObj = new JSONObject();
JsonToken tokenInstance;
try {
tokenInstance = jsonReader.peek();
if(tokenInstance == JsonToken.BEGIN_OBJECT)
jsonReader.beginObject();
else if (tokenInstance == JsonToken.BEGIN_ARRAY)
jsonReader.beginArray();
while(jsonReader.hasNext()) {
JsonToken token;
String name;
try {
name = jsonReader.nextName();
token = jsonReader.peek();
//Log.d(TAG, token.toString());
switch(token) {
case NUMBER:
jObj.put(name, jsonReader.nextLong());
break;
case NULL:
jsonReader.skipValue();
break;
case BOOLEAN:
jObj.put(name, jsonReader.nextBoolean());
break;
case BEGIN_OBJECT:
//jsonReader.beginObject();
jObj.put(name, getJSONObjectFromReader(jsonReader));
//jsonReader.endObject();
break;
case BEGIN_ARRAY:
jsonReader.skipValue();
break;
default:
jObj.put(name, jsonReader.nextString());
}
} catch(Exception ex) {
ex.printStackTrace();
jsonReader.skipValue();
}
}
if(tokenInstance == JsonToken.BEGIN_OBJECT)
jsonReader.endObject();
else if (tokenInstance == JsonToken.BEGIN_ARRAY)
jsonReader.endArray();
return jObj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static boolean PerformTagExecutionAPIv2(List<String> itemIds, FeedItemTags tag, Context context, API api)
{
String jsonIds;
HttpUrl.Builder urlBuilder = api.getTagBaseUrl().newBuilder();
if(tag.equals(FeedItemTags.MARK_ITEM_AS_READ) || tag.equals(FeedItemTags.MARK_ITEM_AS_UNREAD))
{
jsonIds = buildIdsToJSONArray(itemIds);
urlBuilder.addPathSegment(tag.toString());
} else {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(context);
HashMap<String, String> items = new HashMap<>();
for(String idItem : itemIds)
{
RssItem rssItem = dbConn.getRssItemById(Long.parseLong(idItem));
items.put(rssItem.getGuidHash(), String.valueOf(rssItem.getFeedId()));
}
jsonIds = buildIdsToJSONArrayWithGuid(items);
/*
if(jsonIds != null)
{
nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.put("itemIds", jsonIds));
}*/
if(tag.equals(FeedItemTags.MARK_ITEM_AS_STARRED) || tag.equals(FeedItemTags.MARK_ITEM_AS_UNSTARRED))
urlBuilder.addPathSegment(tag.toString());
/*
url += "/" + guidHash;
if(tag.equals(TAGS.MARK_ITEM_AS_STARRED))
url += "/star";
else if(tag.equals(TAGS.MARK_ITEM_AS_UNSTARRED))
url += "/unstar";
*/
}
urlBuilder.addPathSegment("multiple");
try
{
int result = HttpJsonRequest.getInstance().performTagChangeRequest(urlBuilder.build(), jsonIds);
//if(result != -1 || result != 405)
return (result == 200);
}
catch (Exception ex)
{
ex.printStackTrace();
return false;
}
}
public static boolean PerformTagExecutionAPIv1(String itemId, FeedItemTags tag, Context context, API api)
{
HttpUrl.Builder urlBuilder = api.getTagBaseUrl().newBuilder();
if(tag.equals(FeedItemTags.MARK_ITEM_AS_READ) || tag.equals(FeedItemTags.MARK_ITEM_AS_UNREAD)) {
urlBuilder
.addPathSegment(itemId)
.addPathSegment(tag.toString());
} else {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(context);
RssItem rssItem = dbConn.getRssItemById(Long.parseLong(itemId));
urlBuilder.addPathSegment(String.valueOf(rssItem.getFeedId()));
urlBuilder.addPathSegment(rssItem.getGuidHash());
if(tag.equals(FeedItemTags.MARK_ITEM_AS_STARRED) || tag.equals(FeedItemTags.MARK_ITEM_AS_UNSTARRED))
urlBuilder.addPathSegment(tag.toString());
}
try
{
int result = HttpJsonRequest.getInstance().performTagChangeRequest(urlBuilder.build(), null);
return (result == 200);
}
catch (Exception ex)
{
ex.printStackTrace();
return false;
}
}
public static String GetVersionNumber(HttpUrl basePath) throws Exception
{
//Try APIv2
try {
HttpUrl requestUrl = basePath.resolve(OwnCloudConstants.ROOT_PATH_APIv2).newBuilder()
.addPathSegment(OwnCloudConstants.VERSION_PATH)
.build();
InputStream is = HttpJsonRequest.getInstance().PerformJsonRequest(requestUrl);
try {
GetVersion_v2 gv = new GetVersion_v2();
readJsonStreamSimple(is, gv);
return gv.getVersion();
} finally {
is.close();
}
} catch(Exception ex) {
HttpUrl requestUrl = basePath.resolve(OwnCloudConstants.ROOT_PATH_APIv1).newBuilder()
.addPathSegment(OwnCloudConstants.VERSION_PATH)
.addQueryParameter("format", "json")
.build();
InputStream is = HttpJsonRequest.getInstance().PerformJsonRequest(requestUrl);
try {
GetVersion_v1 gv = new GetVersion_v1();
readJsonStreamSimple(is, gv);
return gv.getVersion();
} finally {
is.close();
}
}
}
private static String buildIdsToJSONArray(List<String> ids)
{
try
{
JSONArray jArr = new JSONArray();
for(String id : ids)
jArr.put(Integer.parseInt(id));
JSONObject jObj = new JSONObject();
jObj.put("items", jArr);
return jObj.toString();
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
private static String buildIdsToJSONArrayWithGuid(HashMap<String, String> items)
{
try
{
JSONArray jArr = new JSONArray();
for(Map.Entry<String, String> entry : items.entrySet())
{
JSONObject jOb = new JSONObject();
jOb.put("feedId", Integer.parseInt(entry.getValue()));
jOb.put("guidHash", entry.getKey());
jArr.put(jOb);
}
JSONObject jObj = new JSONObject();
jObj.put("items", jArr);
return jObj.toString();
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
}