Fix travel bookmarks
This commit is contained in:
parent
ae9fc3234c
commit
03dc11febe
9 changed files with 217 additions and 127 deletions
|
@ -289,33 +289,39 @@ public class WikiArticleHelper {
|
|||
|
||||
@Nullable
|
||||
public static String getPartialContent(String source) {
|
||||
if (source == null) {
|
||||
if (Algorithms.isEmpty(source)) {
|
||||
return null;
|
||||
}
|
||||
String content = source.replaceAll("\\n", "");
|
||||
int firstParagraphStart = content.indexOf(P_OPENED);
|
||||
int firstParagraphEnd = content.indexOf(P_CLOSED);
|
||||
firstParagraphEnd = firstParagraphEnd < firstParagraphStart ? content.indexOf(P_CLOSED, firstParagraphStart) : firstParagraphEnd;
|
||||
if (firstParagraphStart == -1 || firstParagraphEnd == -1
|
||||
|| firstParagraphEnd < firstParagraphStart) {
|
||||
return null;
|
||||
}
|
||||
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length());
|
||||
while (firstParagraphHtml.substring(P_OPENED.length(), firstParagraphHtml.length() - P_CLOSED.length()).trim().isEmpty()
|
||||
&& (firstParagraphEnd + P_CLOSED.length()) < content.length()) {
|
||||
firstParagraphStart = content.indexOf(P_OPENED, firstParagraphEnd);
|
||||
firstParagraphEnd = firstParagraphStart == -1 ? -1 : content.indexOf(P_CLOSED, firstParagraphStart);
|
||||
if (firstParagraphStart != -1 && firstParagraphEnd != -1) {
|
||||
firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length());
|
||||
} else {
|
||||
break;
|
||||
String firstParagraphHtml = null;
|
||||
if (firstParagraphStart != -1 && firstParagraphEnd != -1
|
||||
&& firstParagraphEnd >= firstParagraphStart) {
|
||||
firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length());
|
||||
while (firstParagraphHtml.substring(P_OPENED.length(), firstParagraphHtml.length() - P_CLOSED.length()).trim().isEmpty()
|
||||
&& (firstParagraphEnd + P_CLOSED.length()) < content.length()) {
|
||||
firstParagraphStart = content.indexOf(P_OPENED, firstParagraphEnd);
|
||||
firstParagraphEnd = firstParagraphStart == -1 ? -1 : content.indexOf(P_CLOSED, firstParagraphStart);
|
||||
if (firstParagraphStart != -1 && firstParagraphEnd != -1) {
|
||||
firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + P_CLOSED.length());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Algorithms.isEmpty(firstParagraphHtml)) {
|
||||
firstParagraphHtml = source;
|
||||
}
|
||||
if (Algorithms.isEmpty(firstParagraphHtml)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String firstParagraphText = Html.fromHtml(firstParagraphHtml.replaceAll("(<(/)(a|img)>)|(<(a|img).+?>)|(<div.+?/div>)", ""))
|
||||
.toString().trim();
|
||||
String[] phrases = firstParagraphText.split("\\. ");
|
||||
|
||||
StringBuilder res = new StringBuilder();
|
||||
int limit = Math.min(phrases.length, PARTIAL_CONTENT_PHRASES);
|
||||
for (int i = 0; i < limit; i++) {
|
||||
|
@ -324,7 +330,6 @@ public class WikiArticleHelper {
|
|||
res.append(". ");
|
||||
}
|
||||
}
|
||||
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -373,7 +373,7 @@ public class WikivoyageArticleDialogFragment extends WikiArticleBaseDialogFragme
|
|||
@NonNull String title,
|
||||
@NonNull String lang) {
|
||||
TravelArticleIdentifier articleId = app.getTravelHelper().getArticleId(title, lang);
|
||||
return showInstance(app, fm, articleId, lang);
|
||||
return articleId != null && showInstance(app, fm, articleId, lang);
|
||||
}
|
||||
|
||||
public static boolean showInstance(@NonNull OsmandApplication app,
|
||||
|
|
|
@ -9,11 +9,9 @@ import androidx.annotation.Nullable;
|
|||
import androidx.annotation.Size;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.aidl.search.SearchResult;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
@ -22,8 +20,6 @@ import java.io.File;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TravelArticle {
|
||||
|
||||
|
@ -40,22 +36,40 @@ public class TravelArticle {
|
|||
String imageTitle;
|
||||
GPXFile gpxFile;
|
||||
String routeId;
|
||||
String routeSource;
|
||||
String routeSource = "";
|
||||
long originalId;
|
||||
String lang;
|
||||
String contentsJson;
|
||||
String aggregatedPartOf;
|
||||
String fullContent;
|
||||
|
||||
long lastModified;
|
||||
|
||||
@NonNull
|
||||
public TravelArticleIdentifier generateIdentifier() {
|
||||
return new TravelArticleIdentifier(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getTravelBook(@NonNull OsmandApplication app, @NonNull File file) {
|
||||
return file.getPath().replace(app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).getPath() + "/", "");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTravelBook(@NonNull OsmandApplication app) {
|
||||
return file != null ? getTravelBook(app, file) : null;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
if (lastModified > 0) {
|
||||
return lastModified;
|
||||
}
|
||||
return file != null ? file.lastModified() : 0;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
|
|
@ -563,6 +563,9 @@ public class TravelDbHelper implements TravelHelper {
|
|||
cursor.close();
|
||||
}
|
||||
}
|
||||
if (res == null) {
|
||||
res = localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -643,13 +646,19 @@ public class TravelDbHelper implements TravelHelper {
|
|||
cursor.close();
|
||||
}
|
||||
}
|
||||
if (res.isEmpty()) {
|
||||
List<TravelArticle> articles = localDataHelper.getSavedArticles(articleId.file, articleId.routeId);
|
||||
for (TravelArticle a : articles) {
|
||||
res.add(a.getLang());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private TravelArticle readArticle(SQLiteCursor cursor) {
|
||||
TravelArticle res = new TravelArticle();
|
||||
|
||||
res.file = selectedTravelBook;
|
||||
res.title = cursor.getString(0);
|
||||
try {
|
||||
res.content = Algorithms.gzipToString(cursor.getBlob(1)).trim();
|
||||
|
@ -671,7 +680,6 @@ public class TravelDbHelper implements TravelHelper {
|
|||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,7 @@ public interface TravelHelper {
|
|||
File createGpxFile(@NonNull final TravelArticle article);
|
||||
|
||||
// TODO: this method should be deleted once TravelDBHelper is deleted
|
||||
// For TravelOBFHelper it could always return "" and should be no problem
|
||||
// Bookmarks should be refactored properly to support multiple files
|
||||
@Nullable
|
||||
String getSelectedTravelBookName();
|
||||
|
||||
String getWikivoyageFileName();
|
||||
|
|
|
@ -4,11 +4,13 @@ package net.osmand.plus.wikivoyage.data;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
|
||||
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
|
||||
import net.osmand.plus.wikipedia.WikiArticleHelper;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -24,12 +26,12 @@ public class TravelLocalDataHelper {
|
|||
|
||||
private static final int HISTORY_ITEMS_LIMIT = 300;
|
||||
|
||||
private WikivoyageLocalDataDbHelper dbHelper;
|
||||
private final WikivoyageLocalDataDbHelper dbHelper;
|
||||
|
||||
private Map<String, WikivoyageSearchHistoryItem> historyMap = new HashMap<>();
|
||||
private List<TravelArticle> savedArticles = new ArrayList<>();
|
||||
|
||||
private Set<Listener> listeners = new HashSet<>();
|
||||
private final Set<Listener> listeners = new HashSet<>();
|
||||
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
|
@ -70,21 +72,21 @@ public class TravelLocalDataHelper {
|
|||
}
|
||||
|
||||
public void addToHistory(@NonNull TravelArticle article) {
|
||||
addToHistory(article.getTitle(), article.getLang(), article.getIsPartOf());
|
||||
}
|
||||
File file = article.getFile();
|
||||
String title = article.getTitle();
|
||||
String lang = article.getLang();
|
||||
String isPartOf = article.getIsPartOf();
|
||||
|
||||
public void addToHistory(String title, String lang, String isPartOf) {
|
||||
String key = getHistoryKey(lang, title);
|
||||
WikivoyageSearchHistoryItem item = historyMap.get(key);
|
||||
boolean newItem = item == null;
|
||||
if (newItem) {
|
||||
item = new WikivoyageSearchHistoryItem();
|
||||
}
|
||||
WikivoyageSearchHistoryItem item = new WikivoyageSearchHistoryItem();
|
||||
item.articleFile = file;
|
||||
item.articleTitle = title;
|
||||
item.lang = lang;
|
||||
item.isPartOf = isPartOf;
|
||||
item.lastAccessed = System.currentTimeMillis();
|
||||
if (newItem) {
|
||||
|
||||
String key = item.getKey();
|
||||
boolean exists = historyMap.containsKey(key);
|
||||
if (!exists) {
|
||||
dbHelper.addHistoryItem(item);
|
||||
historyMap.put(key, item);
|
||||
} else {
|
||||
|
@ -98,10 +100,6 @@ public class TravelLocalDataHelper {
|
|||
}
|
||||
}
|
||||
|
||||
static String getHistoryKey(String lang, String title) {
|
||||
return lang + ":"+title;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<TravelArticle> getSavedArticles() {
|
||||
return new ArrayList<>(savedArticles);
|
||||
|
@ -109,19 +107,8 @@ public class TravelLocalDataHelper {
|
|||
|
||||
public void addArticleToSaved(@NonNull TravelArticle article) {
|
||||
if (!isArticleSaved(article)) {
|
||||
TravelArticle saved = new TravelArticle();
|
||||
saved.title = article.title;
|
||||
saved.lang = article.lang;
|
||||
saved.aggregatedPartOf = article.aggregatedPartOf;
|
||||
saved.imageTitle = article.imageTitle;
|
||||
saved.content = WikiArticleHelper.getPartialContent(article.getContent());
|
||||
saved.lat = article.lat;
|
||||
saved.lon = article.lon;
|
||||
saved.routeId = article.routeId;
|
||||
saved.fullContent = article.getContent();
|
||||
saved.contentsJson = article.contentsJson;
|
||||
savedArticles.add(saved);
|
||||
dbHelper.addSavedArticle(saved);
|
||||
savedArticles.add(article);
|
||||
dbHelper.addSavedArticle(article);
|
||||
notifySavedUpdated();
|
||||
}
|
||||
}
|
||||
|
@ -164,17 +151,29 @@ public class TravelLocalDataHelper {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public TravelArticle getSavedArticle(String routeId, String lang) {
|
||||
public TravelArticle getSavedArticle(File file, String routeId, String lang) {
|
||||
for (TravelArticle article : savedArticles) {
|
||||
if (article.routeId != null && article.routeId.equals(routeId)
|
||||
&& article.lang != null && article.lang.equals(lang)) {
|
||||
article.content = article.fullContent;
|
||||
if (Algorithms.objectEquals(article.file, file)
|
||||
&& Algorithms.stringsEqual(article.routeId, routeId)
|
||||
&& Algorithms.stringsEqual(article.lang, lang)) {
|
||||
return article;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<TravelArticle> getSavedArticles(File file, String routeId) {
|
||||
List<TravelArticle> articles = new ArrayList<>();
|
||||
for (TravelArticle article : savedArticles) {
|
||||
if (Algorithms.objectEquals(article.file, file)
|
||||
&& Algorithms.stringsEqual(article.routeId, routeId)) {
|
||||
articles.add(article);
|
||||
}
|
||||
}
|
||||
return articles;
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
void savedArticlesUpdated();
|
||||
|
@ -182,7 +181,7 @@ public class TravelLocalDataHelper {
|
|||
|
||||
private static class WikivoyageLocalDataDbHelper {
|
||||
|
||||
private static final int DB_VERSION = 6;
|
||||
private static final int DB_VERSION = 7;
|
||||
private static final String DB_NAME = "wikivoyage_local_data";
|
||||
|
||||
private static final String HISTORY_TABLE_NAME = "wikivoyage_search_history";
|
||||
|
@ -219,6 +218,7 @@ public class TravelLocalDataHelper {
|
|||
private static final String BOOKMARKS_COL_ROUTE_ID = "route_id";
|
||||
private static final String BOOKMARKS_COL_CONTENT_JSON = "content_json";
|
||||
private static final String BOOKMARKS_COL_CONTENT = "content";
|
||||
private static final String BOOKMARKS_COL_LAST_MODIFIED = "last_modified";
|
||||
|
||||
private static final String BOOKMARKS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
|
||||
BOOKMARKS_TABLE_NAME + " (" +
|
||||
|
@ -226,25 +226,26 @@ public class TravelLocalDataHelper {
|
|||
BOOKMARKS_COL_LANG + " TEXT, " +
|
||||
BOOKMARKS_COL_IS_PART_OF + " TEXT, " +
|
||||
BOOKMARKS_COL_IMAGE_TITLE + " TEXT, " +
|
||||
BOOKMARKS_COL_PARTIAL_CONTENT + " TEXT, " +
|
||||
BOOKMARKS_COL_TRAVEL_BOOK + " TEXT, " +
|
||||
BOOKMARKS_COL_LAT + " double, " +
|
||||
BOOKMARKS_COL_LON + " double, " +
|
||||
BOOKMARKS_COL_ROUTE_ID + " TEXT, " +
|
||||
BOOKMARKS_COL_CONTENT_JSON + " TEXT, " +
|
||||
BOOKMARKS_COL_CONTENT + " TEXT" + ");";
|
||||
BOOKMARKS_COL_CONTENT + " TEXT, " +
|
||||
BOOKMARKS_COL_LAST_MODIFIED + " long" + ");";
|
||||
|
||||
private static final String BOOKMARKS_TABLE_SELECT = "SELECT " +
|
||||
BOOKMARKS_COL_ARTICLE_TITLE + ", " +
|
||||
BOOKMARKS_COL_LANG + ", " +
|
||||
BOOKMARKS_COL_IS_PART_OF + ", " +
|
||||
BOOKMARKS_COL_IMAGE_TITLE + ", " +
|
||||
BOOKMARKS_COL_PARTIAL_CONTENT + ", " +
|
||||
BOOKMARKS_COL_TRAVEL_BOOK + ", " +
|
||||
BOOKMARKS_COL_LAT + ", " +
|
||||
BOOKMARKS_COL_LON + ", " +
|
||||
BOOKMARKS_COL_ROUTE_ID + ", " +
|
||||
BOOKMARKS_COL_CONTENT_JSON + ", " +
|
||||
BOOKMARKS_COL_CONTENT +
|
||||
BOOKMARKS_COL_CONTENT + ", " +
|
||||
BOOKMARKS_COL_LAST_MODIFIED +
|
||||
" FROM " + BOOKMARKS_TABLE_NAME;
|
||||
|
||||
private final OsmandApplication context;
|
||||
|
@ -253,8 +254,12 @@ public class TravelLocalDataHelper {
|
|||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SQLiteConnection openConnection(boolean readonly) {
|
||||
SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
|
||||
if (conn == null) {
|
||||
return null;
|
||||
}
|
||||
if (conn.getVersion() < DB_VERSION) {
|
||||
if (readonly) {
|
||||
conn.close();
|
||||
|
@ -283,7 +288,7 @@ public class TravelLocalDataHelper {
|
|||
if (oldVersion < 3) {
|
||||
conn.execSQL("ALTER TABLE " + HISTORY_TABLE_NAME + " ADD " + HISTORY_COL_TRAVEL_BOOK + " TEXT");
|
||||
conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_TRAVEL_BOOK + " TEXT");
|
||||
String selectedTravelBookName = getSelectedTravelBookName();
|
||||
String selectedTravelBookName = context.getTravelHelper().getSelectedTravelBookName();
|
||||
if (selectedTravelBookName != null) {
|
||||
Object[] args = new Object[]{selectedTravelBookName};
|
||||
conn.execSQL("UPDATE " + HISTORY_TABLE_NAME + " SET " + HISTORY_COL_TRAVEL_BOOK + " = ?", args);
|
||||
|
@ -301,20 +306,23 @@ public class TravelLocalDataHelper {
|
|||
conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_CONTENT_JSON + " TEXT");
|
||||
conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_CONTENT + " TEXT");
|
||||
}
|
||||
if (oldVersion < 7) {
|
||||
conn.execSQL("ALTER TABLE " + BOOKMARKS_TABLE_NAME + " ADD " + BOOKMARKS_COL_LAST_MODIFIED + " long");
|
||||
conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME +
|
||||
" SET " + BOOKMARKS_COL_CONTENT + " = " + BOOKMARKS_COL_PARTIAL_CONTENT +
|
||||
" WHERE " + BOOKMARKS_COL_CONTENT + " is null");
|
||||
conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME +
|
||||
" SET " + BOOKMARKS_COL_PARTIAL_CONTENT + " = null");
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
Map<String, WikivoyageSearchHistoryItem> getAllHistoryMap() {
|
||||
Map<String, WikivoyageSearchHistoryItem> res = new LinkedHashMap<>();
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
if (travelBook == null) {
|
||||
return res;
|
||||
}
|
||||
SQLiteConnection conn = openConnection(true);
|
||||
if (conn != null) {
|
||||
try {
|
||||
String query = HISTORY_TABLE_SELECT + " WHERE " + HISTORY_COL_TRAVEL_BOOK + " = ?";
|
||||
SQLiteCursor cursor = conn.rawQuery(query, new String[]{travelBook});
|
||||
SQLiteCursor cursor = conn.rawQuery(HISTORY_TABLE_SELECT, null);
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
|
@ -322,8 +330,8 @@ public class TravelLocalDataHelper {
|
|||
res.put(item.getKey(), item);
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
cursor.close();
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
|
@ -331,8 +339,8 @@ public class TravelLocalDataHelper {
|
|||
return res;
|
||||
}
|
||||
|
||||
void addHistoryItem(WikivoyageSearchHistoryItem item) {
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
void addHistoryItem(@NonNull WikivoyageSearchHistoryItem item) {
|
||||
String travelBook = item.getTravelBook(context);
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -349,8 +357,8 @@ public class TravelLocalDataHelper {
|
|||
}
|
||||
}
|
||||
|
||||
void updateHistoryItem(WikivoyageSearchHistoryItem item) {
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
void updateHistoryItem(@NonNull WikivoyageSearchHistoryItem item) {
|
||||
String travelBook = item.getTravelBook(context);
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -371,8 +379,8 @@ public class TravelLocalDataHelper {
|
|||
}
|
||||
}
|
||||
|
||||
void removeHistoryItem(WikivoyageSearchHistoryItem item) {
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
void removeHistoryItem(@NonNull WikivoyageSearchHistoryItem item) {
|
||||
String travelBook = item.getTravelBook(context);
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -391,16 +399,10 @@ public class TravelLocalDataHelper {
|
|||
}
|
||||
|
||||
void clearAllHistory() {
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
SQLiteConnection conn = openConnection(false);
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.execSQL("DELETE FROM " + HISTORY_TABLE_NAME +
|
||||
" WHERE " + HISTORY_COL_TRAVEL_BOOK + " = ?",
|
||||
new Object[]{travelBook});
|
||||
conn.execSQL("DELETE FROM " + HISTORY_TABLE_NAME);
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
|
@ -410,19 +412,21 @@ public class TravelLocalDataHelper {
|
|||
@NonNull
|
||||
List<TravelArticle> readSavedArticles() {
|
||||
List<TravelArticle> res = new ArrayList<>();
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
if (travelBook == null) {
|
||||
return res;
|
||||
}
|
||||
SQLiteConnection conn = openConnection(true);
|
||||
if (conn != null) {
|
||||
try {
|
||||
String query = BOOKMARKS_TABLE_SELECT + " WHERE " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?";
|
||||
SQLiteCursor cursor = conn.rawQuery(query, new String[]{travelBook});
|
||||
SQLiteCursor cursor = conn.rawQuery(BOOKMARKS_TABLE_SELECT, null);
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
res.add(readSavedArticle(cursor));
|
||||
TravelArticle dbArticle = readSavedArticle(cursor);
|
||||
TravelArticle article = context.getTravelHelper().getArticleById(dbArticle.generateIdentifier(), dbArticle.lang);
|
||||
if (article != null && article.getLastModified() > dbArticle.getLastModified()) {
|
||||
updateSavedArticle(dbArticle, article);
|
||||
res.add(article);
|
||||
} else {
|
||||
res.add(dbArticle);
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
cursor.close();
|
||||
|
@ -434,8 +438,8 @@ public class TravelLocalDataHelper {
|
|||
return res;
|
||||
}
|
||||
|
||||
void addSavedArticle(TravelArticle article) {
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
void addSavedArticle(@NonNull TravelArticle article) {
|
||||
String travelBook = article.getTravelBook(context);
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -447,26 +451,26 @@ public class TravelLocalDataHelper {
|
|||
BOOKMARKS_COL_LANG + ", " +
|
||||
BOOKMARKS_COL_IS_PART_OF + ", " +
|
||||
BOOKMARKS_COL_IMAGE_TITLE + ", " +
|
||||
BOOKMARKS_COL_PARTIAL_CONTENT + ", " +
|
||||
BOOKMARKS_COL_TRAVEL_BOOK + ", " +
|
||||
BOOKMARKS_COL_LAT + ", " +
|
||||
BOOKMARKS_COL_LON + ", " +
|
||||
BOOKMARKS_COL_ROUTE_ID + ", " +
|
||||
BOOKMARKS_COL_CONTENT_JSON + ", " +
|
||||
BOOKMARKS_COL_CONTENT +
|
||||
BOOKMARKS_COL_CONTENT + ", " +
|
||||
BOOKMARKS_COL_LAST_MODIFIED +
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
conn.execSQL(query, new Object[]{article.title, article.lang,
|
||||
article.aggregatedPartOf, article.imageTitle, article.content,
|
||||
article.aggregatedPartOf, article.imageTitle,
|
||||
travelBook, article.lat, article.lon, article.routeId, article.contentsJson,
|
||||
article.fullContent});
|
||||
article.content, article.getFile().lastModified()});
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeSavedArticle(TravelArticle article) {
|
||||
String travelBook = getSelectedTravelBookName();
|
||||
void removeSavedArticle(@NonNull TravelArticle article) {
|
||||
String travelBook = article.getTravelBook(context);
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -475,44 +479,78 @@ public class TravelLocalDataHelper {
|
|||
try {
|
||||
conn.execSQL("DELETE FROM " + BOOKMARKS_TABLE_NAME +
|
||||
" WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ?" +
|
||||
" AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" +
|
||||
" AND " + BOOKMARKS_COL_LANG + " = ?" +
|
||||
" AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?",
|
||||
new Object[]{article.title, article.lang, travelBook});
|
||||
new Object[]{article.title, article.routeId, article.lang, travelBook});
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getSelectedTravelBookName() {
|
||||
return context.getTravelHelper().getSelectedTravelBookName();
|
||||
void updateSavedArticle(@NonNull TravelArticle odlArticle, @NonNull TravelArticle newArticle) {
|
||||
String travelBook = odlArticle.getTravelBook(context);
|
||||
if (travelBook == null) {
|
||||
return;
|
||||
}
|
||||
SQLiteConnection conn = openConnection(false);
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.execSQL("UPDATE " + BOOKMARKS_TABLE_NAME + " SET " +
|
||||
BOOKMARKS_COL_ARTICLE_TITLE + " = ?, " +
|
||||
BOOKMARKS_COL_LANG + " = ?, " +
|
||||
BOOKMARKS_COL_IS_PART_OF + " = ?, " +
|
||||
BOOKMARKS_COL_IMAGE_TITLE + " = ?, " +
|
||||
BOOKMARKS_COL_TRAVEL_BOOK + " = ?, " +
|
||||
BOOKMARKS_COL_LAT + " = ?, " +
|
||||
BOOKMARKS_COL_LON + " = ?, " +
|
||||
BOOKMARKS_COL_ROUTE_ID + " = ?, " +
|
||||
BOOKMARKS_COL_CONTENT_JSON + " = ?, " +
|
||||
BOOKMARKS_COL_CONTENT + " = ?, " +
|
||||
BOOKMARKS_COL_LAST_MODIFIED + " = ?, " +
|
||||
"WHERE " + BOOKMARKS_COL_ARTICLE_TITLE + " = ? " +
|
||||
" AND " + BOOKMARKS_COL_ROUTE_ID + " = ?" +
|
||||
" AND " + BOOKMARKS_COL_LANG + " = ?" +
|
||||
" AND " + BOOKMARKS_COL_TRAVEL_BOOK + " = ?",
|
||||
new Object[]{newArticle.title, newArticle.lang, newArticle.aggregatedPartOf,
|
||||
newArticle.imageTitle, travelBook, newArticle.lat, newArticle.lon,
|
||||
newArticle.routeId, newArticle.content, newArticle.contentsJson,
|
||||
odlArticle.title, odlArticle.routeId, odlArticle.lang, travelBook});
|
||||
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private WikivoyageSearchHistoryItem readHistoryItem(SQLiteCursor cursor) {
|
||||
WikivoyageSearchHistoryItem res = new WikivoyageSearchHistoryItem();
|
||||
res.articleTitle = cursor.getString(cursor.getColumnIndex(HISTORY_COL_ARTICLE_TITLE));
|
||||
res.lang = cursor.getString(cursor.getColumnIndex(HISTORY_COL_LANG));
|
||||
res.isPartOf = cursor.getString(cursor.getColumnIndex(HISTORY_COL_IS_PART_OF));
|
||||
res.lastAccessed = cursor.getLong(cursor.getColumnIndex(HISTORY_COL_LAST_ACCESSED));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private TravelArticle readSavedArticle(SQLiteCursor cursor) {
|
||||
TravelArticle res = new TravelArticle();
|
||||
|
||||
res.title = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_ARTICLE_TITLE));
|
||||
res.lang = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_LANG));
|
||||
res.aggregatedPartOf = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_IS_PART_OF));
|
||||
res.imageTitle = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_IMAGE_TITLE));
|
||||
res.content = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_PARTIAL_CONTENT));
|
||||
res.content = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_CONTENT));
|
||||
res.lat = cursor.getDouble(cursor.getColumnIndex(BOOKMARKS_COL_LAT));
|
||||
res.lon = cursor.getDouble(cursor.getColumnIndex(BOOKMARKS_COL_LON));
|
||||
res.routeId = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_ROUTE_ID));
|
||||
res.contentsJson = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_CONTENT_JSON));
|
||||
res.fullContent = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_CONTENT));
|
||||
|
||||
String travelBook = cursor.getString(cursor.getColumnIndex(BOOKMARKS_COL_TRAVEL_BOOK));
|
||||
if (!Algorithms.isEmpty(travelBook)) {
|
||||
res.file = context.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR + travelBook);
|
||||
res.lastModified = cursor.getLong(cursor.getColumnIndex(BOOKMARKS_COL_LAST_MODIFIED));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ public class TravelObfHelper implements TravelHelper {
|
|||
parts = null;
|
||||
}
|
||||
Map<String, List<WikivoyageSearchResult>> navMap = new HashMap<>();
|
||||
Set<String> headers = new LinkedHashSet<String>();
|
||||
Set<String> headers = new LinkedHashSet<>();
|
||||
Map<String, WikivoyageSearchResult> headerObjs = new HashMap<>();
|
||||
Map<File, List<Amenity>> amenityMap = new HashMap<>();
|
||||
for (BinaryMapIndexReader reader : getReaders()) {
|
||||
|
@ -335,7 +335,7 @@ public class TravelObfHelper implements TravelHelper {
|
|||
navMap.put(rs.isPartOf, l);
|
||||
}
|
||||
l.add(rs);
|
||||
if (headers != null && headers.contains(a.getTitle())) {
|
||||
if (headers.contains(a.getTitle())) {
|
||||
headerObjs.put(a.getTitle(), rs);
|
||||
}
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ public class TravelObfHelper implements TravelHelper {
|
|||
@Override
|
||||
public TravelArticle getArticleById(@NonNull TravelArticleIdentifier articleId, @NonNull String lang) {
|
||||
TravelArticle article = getCachedArticle(articleId, lang);
|
||||
return article == null ? findArticleById(articleId, lang) : article;
|
||||
return article == null ? localDataHelper.getSavedArticle(articleId.file, articleId.routeId, lang) : article;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -390,10 +390,11 @@ public class TravelObfHelper implements TravelHelper {
|
|||
|
||||
private TravelArticle findArticleById(@NonNull final TravelArticleIdentifier articleId, final String lang) {
|
||||
TravelArticle article = null;
|
||||
final boolean isDbArticle = articleId.file != null && articleId.file.getName().endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT);
|
||||
final List<Amenity> amenities = new ArrayList<>();
|
||||
for (BinaryMapIndexReader reader : getReaders()) {
|
||||
try {
|
||||
if (articleId.file != null && !articleId.file.equals(reader.getFile())) {
|
||||
if (articleId.file != null && !articleId.file.equals(reader.getFile()) && !isDbArticle) {
|
||||
continue;
|
||||
}
|
||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(0, 0,
|
||||
|
@ -404,7 +405,7 @@ public class TravelObfHelper implements TravelHelper {
|
|||
@Override
|
||||
public boolean publish(Amenity amenity) {
|
||||
if (Algorithms.stringsEqual(articleId.routeId, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_ID, null)))
|
||||
&& Algorithms.stringsEqual(articleId.routeSource, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null)))) {
|
||||
&& Algorithms.stringsEqual(articleId.routeSource, Algorithms.emptyIfNull(amenity.getTagContent(Amenity.ROUTE_SOURCE, null))) || isDbArticle) {
|
||||
amenities.add(amenity);
|
||||
done = true;
|
||||
}
|
||||
|
@ -519,10 +520,15 @@ public class TravelObfHelper implements TravelHelper {
|
|||
ArrayList<String> res = new ArrayList<>();
|
||||
TravelArticle article = getArticleById(articleId, "");
|
||||
if (article != null) {
|
||||
Map<String, TravelArticle> articles = cachedArticles.get(articleId);
|
||||
Map<String, TravelArticle> articles = cachedArticles.get(article.generateIdentifier());
|
||||
if (articles != null) {
|
||||
res.addAll(articles.keySet());
|
||||
}
|
||||
} else {
|
||||
List<TravelArticle> articles = localDataHelper.getSavedArticles(articleId.file, articleId.routeId);
|
||||
for (TravelArticle a : articles) {
|
||||
res.add(a.getLang());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -547,7 +553,7 @@ public class TravelObfHelper implements TravelHelper {
|
|||
|
||||
@Override
|
||||
public String getSelectedTravelBookName() {
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,17 +1,36 @@
|
|||
package net.osmand.plus.wikivoyage.data;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class WikivoyageSearchHistoryItem {
|
||||
|
||||
File articleFile;
|
||||
String articleTitle;
|
||||
String lang;
|
||||
String isPartOf;
|
||||
long lastAccessed;
|
||||
|
||||
|
||||
public String getKey() {
|
||||
return TravelLocalDataHelper.getHistoryKey(lang, articleTitle);
|
||||
public static String getKey(String lang, String title, @Nullable File file) {
|
||||
return lang + ":" + title + (file != null ? ":" + file.getName() : "");
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return getKey(lang, articleTitle, articleFile);
|
||||
}
|
||||
|
||||
public File getArticleFile() {
|
||||
return articleFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTravelBook(@NonNull OsmandApplication app) {
|
||||
return articleFile != null ? TravelArticle.getTravelBook(app, articleFile) : null;
|
||||
}
|
||||
|
||||
public String getArticleTitle() {
|
||||
return articleTitle;
|
||||
|
|
|
@ -22,6 +22,7 @@ import net.osmand.plus.settings.backend.OsmandSettings;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.widgets.tools.CropCircleTransformation;
|
||||
import net.osmand.plus.wikipedia.WikiArticleHelper;
|
||||
import net.osmand.plus.wikivoyage.WikivoyageUtils;
|
||||
import net.osmand.plus.wikivoyage.data.TravelArticle;
|
||||
import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper;
|
||||
|
@ -102,7 +103,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
|||
|
||||
holder.icon.setVisibility(loaded == null || loaded.booleanValue() ? View.VISIBLE : View.GONE);
|
||||
holder.title.setText(article.getTitle());
|
||||
holder.content.setText(article.getContent());
|
||||
holder.content.setText(WikiArticleHelper.getPartialContent(article.getContent()));
|
||||
holder.partOf.setText(article.getGeoDescription());
|
||||
holder.leftButton.setText(app.getString(R.string.shared_string_read));
|
||||
holder.leftButton.setCompoundDrawablesWithIntrinsicBounds(readIcon, null, null, null);
|
||||
|
@ -178,7 +179,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
Object item = getItemByPosition();
|
||||
if (item != null && item instanceof TravelArticle) {
|
||||
if (item instanceof TravelArticle) {
|
||||
if (listener != null) {
|
||||
listener.openArticle((TravelArticle) item);
|
||||
}
|
||||
|
@ -193,7 +194,7 @@ public class SavedArticlesRvAdapter extends RecyclerView.Adapter<RecyclerView.Vi
|
|||
@Override
|
||||
public void onClick(View view) {
|
||||
Object item = getItemByPosition();
|
||||
if (item != null && item instanceof TravelArticle) {
|
||||
if (item instanceof TravelArticle) {
|
||||
final TravelArticle article = (TravelArticle) item;
|
||||
final TravelLocalDataHelper ldh = app.getTravelHelper().getBookmarksHelper();
|
||||
ldh.removeArticleFromSaved(article);
|
||||
|
|
Loading…
Reference in a new issue