Skip to content

Commit

Permalink
Merge pull request #68 from wallabag/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
tcitworld committed Jan 14, 2015
2 parents 6f12cc9 + 78f0317 commit c46b697
Show file tree
Hide file tree
Showing 19 changed files with 662 additions and 683 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ android:
- tools

# The BuildTools version used by your project
- build-tools-21.0.0
- build-tools-21.1.2

# The SDK version used to compile your project
- android-21
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# wallabag - Android App [![Build Status](https://travis-ci.org/wallabag/android-app.svg?branch=rss-feed)](https://travis-ci.org/wallabag/android-app)
# wallabag - Android App [![Build Status](https://travis-ci.org/wallabag/android-app.svg?branch=dev)](https://travis-ci.org/wallabag/android-app)

wallabag app for Android, originally written by Jonathan GAULUPEAU <jo.gaulupeau-at-gmail.com>

Expand Down
4 changes: 3 additions & 1 deletion android-app.iml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/main" />
<output-test url="file://$MODULE_DIR$/build/classes/test" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
Expand Down
11 changes: 7 additions & 4 deletions app/app.iml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
Expand All @@ -31,11 +31,13 @@
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
Expand Down Expand Up @@ -77,12 +79,13 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-annotations-21.0.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-21.0.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-21.0.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-21.0.2" level="project" />
<orderEntry type="library" exported="" name="support-v4-21.0.2" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-21.0.2" level="project" />
</component>
</module>

6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.android.application'

android {
compileSdkVersion 21
buildToolsVersion '21'
buildToolsVersion '21.1.2'

defaultConfig {
applicationId "fr.gaulupeau.apps.InThePoche"
Expand All @@ -13,12 +13,12 @@ android {
}
buildTypes {
release {
runProguard false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'com.android.support:appcompat-v7:21.+'
}
4 changes: 3 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
</activity>
<activity android:name="fr.gaulupeau.apps.Poche.ReadArticle" />
<activity android:name="fr.gaulupeau.apps.Poche.ListArticles" />
<activity android:name="fr.gaulupeau.apps.Poche.Settings" />
<activity
android:name="fr.gaulupeau.apps.Poche.Settings"
android:label="@string/btnSettings" />

</application>
</manifest>
278 changes: 278 additions & 0 deletions app/src/main/java/fr/gaulupeau/apps/Poche/FeedUpdater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
package fr.gaulupeau.apps.Poche;

import android.content.ContentValues;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.AsyncTask;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import fr.gaulupeau.apps.InThePoche.R;

import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARCHIVE;
import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARTICLE_CONTENT;
import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARTICLE_DATE;
import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARTICLE_SYNC;
import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARTICLE_TABLE;
import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARTICLE_TITLE;
import static fr.gaulupeau.apps.Poche.ArticlesSQLiteOpenHelper.ARTICLE_URL;

/**
* Created by kevinmeyer on 13/12/14.
*/

interface FeedUpdaterInterface {
void feedUpdaterFinishedWithError(String errorMessage);
void feedUpdatedFinishedSuccessfully();
}

public class FeedUpdater extends AsyncTask<Void, Void, Void> {

private SQLiteDatabase database;
private String wallabagUrl;
private String apiUserId;
private String apiToken;
private FeedUpdaterInterface callback;
private String errorMessage;

public FeedUpdater(String wallabagUrl, String apiUserId, String apiToken, SQLiteDatabase writableDatabase, FeedUpdaterInterface callback) {
this.wallabagUrl = wallabagUrl;
this.apiUserId = apiUserId;
this.apiToken = apiToken;
this.database = writableDatabase;
this.callback = callback;
}

@Override
protected Void doInBackground(Void... params) {
parseRSS();
return null;
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (callback == null)
return;

if (errorMessage == null) {
callback.feedUpdatedFinishedSuccessfully();
} else {
callback.feedUpdaterFinishedWithError(errorMessage);
}
}

private void trustEveryone() {
try {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(
context.getSocketFactory());
} catch (Exception e) { // should never happen
e.printStackTrace();
}
}


public void parseRSS() {

URL url;
try {
// Set the url (you will need to change this to your RSS URL
url = new URL(wallabagUrl + "/?feed&type=home&user_id=" + apiUserId + "&token=" + apiToken);
if (wallabagUrl.startsWith("https")) {
trustEveryone();
}

// Setup the connection
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) url.openConnection();

if ((urlConnection != null) && (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK)) {

// Retreive the XML from the URL
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = null;

InputSource is;

try {
is = new InputSource(
new InputStreamReader(
urlConnection.getInputStream()));
doc = db.parse(is);
doc.getDocumentElement().normalize();
} catch (SAXException e) {
e.printStackTrace();

InputStream inputStream = url.openStream();
int ch;
StringBuffer stringBuffer = new StringBuffer();
while ((ch = inputStream.read()) != -1) {
stringBuffer.append((char) ch);
}
errorMessage = ":\nGot invalid response:\n\"" + stringBuffer.toString() + "\"";
return;
}

// This is the root node of each section you want to parse
NodeList itemLst = doc.getElementsByTagName("item");

// This sets up some arrays to hold the data parsed
arrays.PodcastTitle = new String[itemLst.getLength()];
arrays.PodcastURL = new String[itemLst.getLength()];
arrays.PodcastContent = new String[itemLst.getLength()];
arrays.PodcastMedia = new String[itemLst.getLength()];
arrays.PodcastDate = new String[itemLst.getLength()];

// Loop through the XML passing the data to the arrays
for (int i = 0; i < itemLst.getLength(); i++) {

Node item = itemLst.item(i);
if (item.getNodeType() == Node.ELEMENT_NODE) {
Element ielem = (Element) item;

// This section gets the elements from the XML
// that we want to use you will need to add
// and remove elements that you want / don't want
NodeList title = ielem.getElementsByTagName("title");
NodeList link = ielem.getElementsByTagName("link");
NodeList date = ielem.getElementsByTagName("pubDate");
NodeList content = ielem
.getElementsByTagName("description");
//NodeList media = ielem
// .getElementsByTagName("media:content");

// This is an attribute of an element so I create
// a string to make it easier to use
//String mediaurl = media.item(0).getAttributes()
// .getNamedItem("url").getNodeValue();

// This section adds an entry to the arrays with the
// data retrieved from above. I have surrounded each
// with try/catch just incase the element does not
// exist
try {
arrays.PodcastTitle[i] = cleanString(title.item(0).getChildNodes().item(0).getNodeValue());
} catch (NullPointerException e) {
e.printStackTrace();
arrays.PodcastTitle[i] = "Echec";
}
try {
arrays.PodcastDate[i] = date.item(0).getChildNodes().item(0).getNodeValue();
} catch (NullPointerException e) {
e.printStackTrace();
arrays.PodcastDate[i] = null;
}
try {
arrays.PodcastURL[i] = link.item(0).getChildNodes()
.item(0).getNodeValue();
} catch (NullPointerException e) {
e.printStackTrace();
arrays.PodcastURL[i] = "Echec";
}
try {
arrays.PodcastContent[i] = content.item(0)
.getChildNodes().item(0).getNodeValue();
} catch (NullPointerException e) {
e.printStackTrace();
arrays.PodcastContent[i] = "Echec";
}

ContentValues values = new ContentValues();
values.put(ARTICLE_TITLE, arrays.PodcastTitle[i]);
values.put(ARTICLE_CONTENT, arrays.PodcastContent[i]);
//values.put(ARTICLE_ID, Html.fromHtml(article.getString("id")).toString());
values.put(ARTICLE_URL, arrays.PodcastURL[i]);
values.put(ARTICLE_DATE, arrays.PodcastDate[i]);
values.put(ARCHIVE, 0);
values.put(ARTICLE_SYNC, 0);
try {
database.insertOrThrow(ARTICLE_TABLE, null, values);
} catch (SQLiteConstraintException e) {
continue;
} catch (SQLiteException e) {
database.execSQL("ALTER TABLE " + ARTICLE_TABLE + " ADD COLUMN " + ARTICLE_DATE + " datetime;");
database.insertOrThrow(ARTICLE_TABLE, null, values);
}
}
}

} else {
// HTTP Connection not successful
if (urlConnection == null) {
errorMessage = "";
} else {
errorMessage = ":\n" + urlConnection.getResponseCode() + " " + urlConnection.getResponseMessage();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

public String cleanString(String s) {
s = s.replace("&Atilde;&copy;", "&eacute;");
s = s.replace("&Atilde;&uml;", "&egrave;");
s = s.replace("&Atilde;&ordf;", "&ecirc;");
s = s.replace("&Atilde;&laquo;", "&euml;");
s = s.replace("&Atilde;&nbsp;", "&agrave;");
s = s.replace("&Atilde;&curren;", "&auml;");
s = s.replace("&Atilde;&cent;", "&acirc;");
s = s.replace("&Atilde;&sup1;", "&ugrave;");
s = s.replace("&Atilde;&raquo;", "&ucirc;");
s = s.replace("&Atilde;&frac14;", "&uuml;");
s = s.replace("&Atilde;&acute;", "&ocirc;");
s = s.replace("&Atilde;&para;", "&ouml;");
s = s.replace("&Atilde;&reg;", "&icirc;");
s = s.replace("&Atilde;&macr;", "&iuml;");
s = s.replace("&Atilde;&sect;", "&ccedil;");
s = s.replace("&amp;", "&amp;");

// Replace multiple whitespaces with single space
s = s.replaceAll("\\s+", " ");
s = s.trim();

return s;
}
}
Loading

0 comments on commit c46b697

Please sign in to comment.