Add the ability to save wikivoyage articles

This commit is contained in:
Alex Sytnyk 2018-04-06 13:34:11 +03:00
parent a9025bccdb
commit 868d0deb03
2 changed files with 167 additions and 4 deletions

View file

@ -1,7 +1,9 @@
package net.osmand.plus.wikivoyage.data; package net.osmand.plus.wikivoyage.data;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size; import android.support.annotation.Size;
import android.text.Html;
import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.GPXFile;
@ -14,6 +16,8 @@ public class WikivoyageArticle {
private static final String THUMB_PREFIX = "320px-"; private static final String THUMB_PREFIX = "320px-";
private static final String REGULAR_PREFIX = "800px-"; private static final String REGULAR_PREFIX = "800px-";
private static final int PARTIAL_CONTENT_PHRASES = 3;
String id; String id;
String title; String title;
String content; String content;
@ -80,6 +84,35 @@ public class WikivoyageArticle {
return aggregatedPartOf; return aggregatedPartOf;
} }
@Nullable
public String getPartialContent() {
if (content == null) {
return null;
}
int firstParagraphStart = content.indexOf("<p>");
int firstParagraphEnd = content.indexOf("</p>");
if (firstParagraphStart == -1 || firstParagraphEnd == -1) {
return null;
}
// 4 is the length of </p> tag
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + 4);
String firstParagraphText = Html.fromHtml(firstParagraphHtml).toString();
String[] phrases = firstParagraphText.split("\\. ");
StringBuilder res = new StringBuilder();
int limit = Math.min(phrases.length, PARTIAL_CONTENT_PHRASES);
for (int i = 0; i < limit; i++) {
res.append(phrases[i]).append(".");
if (i < limit - 1) {
res.append(" ");
}
}
return res.toString();
}
@NonNull @NonNull
public static String getImageUrl(@NonNull String imageTitle, boolean thumbnail) { public static String getImageUrl(@NonNull String imageTitle, boolean thumbnail) {
String[] hash = getHash(imageTitle); String[] hash = getHash(imageTitle);

View file

@ -1,6 +1,7 @@
package net.osmand.plus.wikivoyage.data; package net.osmand.plus.wikivoyage.data;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
@ -22,10 +23,12 @@ public class WikivoyageLocalDataHelper {
private WikivoyageLocalDataDbHelper dbHelper; private WikivoyageLocalDataDbHelper dbHelper;
private TLongObjectHashMap<WikivoyageSearchHistoryItem> historyMap; private TLongObjectHashMap<WikivoyageSearchHistoryItem> historyMap;
private List<WikivoyageArticle> savedArticles;
private WikivoyageLocalDataHelper(OsmandApplication app) { private WikivoyageLocalDataHelper(OsmandApplication app) {
dbHelper = new WikivoyageLocalDataDbHelper(app); dbHelper = new WikivoyageLocalDataDbHelper(app);
historyMap = dbHelper.getAllHistoryMap(); historyMap = dbHelper.getAllHistoryMap();
savedArticles = dbHelper.getSavedArticles();
} }
public static WikivoyageLocalDataHelper getInstance(OsmandApplication app) { public static WikivoyageLocalDataHelper getInstance(OsmandApplication app) {
@ -51,7 +54,7 @@ public class WikivoyageLocalDataHelper {
return res; return res;
} }
public void addToHistory(WikivoyageArticle article) { public void addToHistory(@NonNull WikivoyageArticle article) {
addToHistory(article.getCityId(), article.getTitle(), article.getLang(), article.getIsPartOf()); addToHistory(article.getCityId(), article.getTitle(), article.getLang(), article.getIsPartOf());
} }
@ -80,9 +83,49 @@ public class WikivoyageLocalDataHelper {
} }
} }
public List<WikivoyageArticle> getSavedArticles() {
return new ArrayList<>(savedArticles);
}
public void addArticleToSaved(@NonNull WikivoyageArticle article) {
if (!isArticleSaved(article)) {
WikivoyageArticle saved = new WikivoyageArticle();
saved.cityId = article.cityId;
saved.title = article.title;
saved.lang = article.lang;
saved.aggregatedPartOf = article.aggregatedPartOf;
saved.imageTitle = article.imageTitle;
saved.content = article.getPartialContent();
savedArticles.add(saved);
dbHelper.addSavedArticle(saved);
}
}
public void removeArticleFromSaved(@NonNull WikivoyageArticle article) {
WikivoyageArticle savedArticle = getArticle(article.cityId, article.lang);
if (savedArticle != null) {
savedArticles.remove(savedArticle);
dbHelper.removeSavedArticle(savedArticle);
}
}
public boolean isArticleSaved(@NonNull WikivoyageArticle article) {
return getArticle(article.cityId, article.lang) != null;
}
@Nullable
private WikivoyageArticle getArticle(long cityId, String lang) {
for (WikivoyageArticle article : savedArticles) {
if (article.cityId == cityId && article.lang != null && article.lang.equals(lang)) {
return article;
}
}
return null;
}
private static class WikivoyageLocalDataDbHelper { private static class WikivoyageLocalDataDbHelper {
private static final int DB_VERSION = 1; private static final int DB_VERSION = 2;
private static final String DB_NAME = "wikivoyage_local_data"; private static final String DB_NAME = "wikivoyage_local_data";
private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history"; private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history";
@ -108,9 +151,35 @@ public class WikivoyageLocalDataHelper {
HISTORY_COL_LAST_ACCESSED + HISTORY_COL_LAST_ACCESSED +
" FROM " + HISTORY_TABLE_NAME; " FROM " + HISTORY_TABLE_NAME;
private static final String BOOKMARKS_TABLE_NAME = "wikivoyage_saved_articles";
private static final String BOOKMARKS_COL_CITY_ID = "city_id";
private static final String BOOKMARKS_COL_ARTICLE_TITLE = "article_title";
private static final String BOOKMARKS_COL_LANG = "lang";
private static final String BOOKMARKS_COL_IS_PART_OF = "is_part_of";
private static final String BOOKMARKS_COL_IMAGE_TITLE = "image_title";
private static final String BOOKMARKS_COL_PARTIAL_CONTENT = "partial_content";
private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
BOOKMARKS_TABLE_NAME + " (" +
BOOKMARKS_COL_CITY_ID + " long, " +
BOOKMARKS_COL_ARTICLE_TITLE + " TEXT, " +
BOOKMARKS_COL_LANG + " TEXT, " +
BOOKMARKS_COL_IS_PART_OF + " TEXT, " +
BOOKMARKS_COL_IMAGE_TITLE + " TEXT, " +
BOOKMARKS_COL_PARTIAL_CONTENT + " TEXT);";
private static final String BOOKMARKS_TABLE_SELECT = "SELECT " +
BOOKMARKS_COL_CITY_ID + ", " +
BOOKMARKS_COL_ARTICLE_TITLE + ", " +
BOOKMARKS_COL_LANG + ", " +
BOOKMARKS_COL_IS_PART_OF + ", " +
BOOKMARKS_COL_IMAGE_TITLE + ", " +
BOOKMARKS_COL_PARTIAL_CONTENT +
" FROM " + BOOKMARKS_TABLE_NAME;
private final OsmandApplication context; private final OsmandApplication context;
private WikivoyageLocalDataDbHelper(OsmandApplication context) { WikivoyageLocalDataDbHelper(OsmandApplication context) {
this.context = context; this.context = context;
} }
@ -139,7 +208,9 @@ public class WikivoyageLocalDataHelper {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void onUpgrade(SQLiteConnection conn, int oldVersion, int newVersion) { private void onUpgrade(SQLiteConnection conn, int oldVersion, int newVersion) {
if (oldVersion < 2) {
conn.execSQL(BOOKMARKS_TABLE_CREATE);
}
} }
@NonNull @NonNull
@ -203,6 +274,52 @@ public class WikivoyageLocalDataHelper {
} }
} }
@NonNull
List<WikivoyageArticle> getSavedArticles() {
List<WikivoyageArticle> res = new ArrayList<>();
SQLiteConnection conn = openConnection(true);
if (conn != null) {
try {
SQLiteCursor cursor = conn.rawQuery(BOOKMARKS_TABLE_SELECT, null);
if (cursor.moveToFirst()) {
do {
res.add(readSavedArticle(cursor));
} while (cursor.moveToNext());
}
} finally {
conn.close();
}
}
return res;
}
void addSavedArticle(WikivoyageArticle article) {
SQLiteConnection conn = openConnection(false);
if (conn != null) {
try {
conn.execSQL("INSERT INTO " + BOOKMARKS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?, ?)",
new Object[]{article.cityId, article.title, article.lang,
article.aggregatedPartOf, article.imageTitle, article.content});
} finally {
conn.close();
}
}
}
void removeSavedArticle(WikivoyageArticle article) {
SQLiteConnection conn = openConnection(false);
if (conn != null) {
try {
conn.execSQL("DELETE FROM " + BOOKMARKS_TABLE_NAME +
" WHERE " + BOOKMARKS_COL_CITY_ID + " = ?" +
" AND " + BOOKMARKS_COL_LANG + " = ?",
new Object[]{article.cityId, article.lang});
} finally {
conn.close();
}
}
}
private WikivoyageSearchHistoryItem readHistoryItem(SQLiteCursor cursor) { private WikivoyageSearchHistoryItem readHistoryItem(SQLiteCursor cursor) {
WikivoyageSearchHistoryItem res = new WikivoyageSearchHistoryItem(); WikivoyageSearchHistoryItem res = new WikivoyageSearchHistoryItem();
@ -214,5 +331,18 @@ public class WikivoyageLocalDataHelper {
return res; return res;
} }
private WikivoyageArticle readSavedArticle(SQLiteCursor cursor) {
WikivoyageArticle res = new WikivoyageArticle();
res.cityId = cursor.getLong(0);
res.title = cursor.getString(1);
res.lang = cursor.getString(2);
res.aggregatedPartOf = cursor.getString(3);
res.imageTitle = cursor.getString(4);
res.content = cursor.getString(5);
return res;
}
} }
} }