From 868d0deb03effc4b2f8e6f13eeaaff3a2ba7321b Mon Sep 17 00:00:00 2001 From: Alex Sytnyk Date: Fri, 6 Apr 2018 13:34:11 +0300 Subject: [PATCH] Add the ability to save wikivoyage articles --- .../wikivoyage/data/WikivoyageArticle.java | 33 +++++ .../data/WikivoyageLocalDataHelper.java | 138 +++++++++++++++++- 2 files changed, 167 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java index 8334b9bf2f..7e00ba73fd 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticle.java @@ -1,7 +1,9 @@ package net.osmand.plus.wikivoyage.data; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.annotation.Size; +import android.text.Html; import net.osmand.plus.GPXUtilities.GPXFile; @@ -14,6 +16,8 @@ public class WikivoyageArticle { private static final String THUMB_PREFIX = "320px-"; private static final String REGULAR_PREFIX = "800px-"; + private static final int PARTIAL_CONTENT_PHRASES = 3; + String id; String title; String content; @@ -80,6 +84,35 @@ public class WikivoyageArticle { return aggregatedPartOf; } + @Nullable + public String getPartialContent() { + if (content == null) { + return null; + } + + int firstParagraphStart = content.indexOf("

"); + int firstParagraphEnd = content.indexOf("

"); + if (firstParagraphStart == -1 || firstParagraphEnd == -1) { + return null; + } + + // 4 is the length of

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 public static String getImageUrl(@NonNull String imageTitle, boolean thumbnail) { String[] hash = getHash(imageTitle); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageLocalDataHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageLocalDataHelper.java index a6924dd2b4..05d996961b 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageLocalDataHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageLocalDataHelper.java @@ -1,6 +1,7 @@ package net.osmand.plus.wikivoyage.data; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import net.osmand.plus.OsmandApplication; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; @@ -22,10 +23,12 @@ public class WikivoyageLocalDataHelper { private WikivoyageLocalDataDbHelper dbHelper; private TLongObjectHashMap historyMap; + private List savedArticles; private WikivoyageLocalDataHelper(OsmandApplication app) { dbHelper = new WikivoyageLocalDataDbHelper(app); historyMap = dbHelper.getAllHistoryMap(); + savedArticles = dbHelper.getSavedArticles(); } public static WikivoyageLocalDataHelper getInstance(OsmandApplication app) { @@ -51,7 +54,7 @@ public class WikivoyageLocalDataHelper { return res; } - public void addToHistory(WikivoyageArticle article) { + public void addToHistory(@NonNull WikivoyageArticle article) { addToHistory(article.getCityId(), article.getTitle(), article.getLang(), article.getIsPartOf()); } @@ -80,9 +83,49 @@ public class WikivoyageLocalDataHelper { } } + public List 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 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 HISTORY_TABLE_NAME = "wikivoyage_search_history"; @@ -108,9 +151,35 @@ public class WikivoyageLocalDataHelper { HISTORY_COL_LAST_ACCESSED + " 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 WikivoyageLocalDataDbHelper(OsmandApplication context) { + WikivoyageLocalDataDbHelper(OsmandApplication context) { this.context = context; } @@ -139,7 +208,9 @@ public class WikivoyageLocalDataHelper { @SuppressWarnings("unused") private void onUpgrade(SQLiteConnection conn, int oldVersion, int newVersion) { - + if (oldVersion < 2) { + conn.execSQL(BOOKMARKS_TABLE_CREATE); + } } @NonNull @@ -203,6 +274,52 @@ public class WikivoyageLocalDataHelper { } } + @NonNull + List getSavedArticles() { + List 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) { WikivoyageSearchHistoryItem res = new WikivoyageSearchHistoryItem(); @@ -214,5 +331,18 @@ public class WikivoyageLocalDataHelper { 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; + } } }