Merge branch 'develop' into exo-player
This commit is contained in:
commit
83a9df2657
|
@ -21,7 +21,7 @@ jobs:
|
|||
- v1-android-
|
||||
|
||||
- run:
|
||||
command: ./gradlew assembleDebug -PdisablePreDex
|
||||
command: ./gradlew assembleDebug :core:testPlayDebugUnitTest -PdisablePreDex
|
||||
no_output_timeout: 1800
|
||||
|
||||
- store_artifacts:
|
||||
|
|
|
@ -17,7 +17,6 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.syndication.handler.FeedHandler;
|
||||
|
@ -82,15 +81,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
|
|||
assertEquals(feed.getLink(), parsedFeed.getLink());
|
||||
assertEquals(feed.getDescription(), parsedFeed.getDescription());
|
||||
assertEquals(feed.getPaymentLink(), parsedFeed.getPaymentLink());
|
||||
|
||||
if (feed.getImage() != null) {
|
||||
FeedImage image = feed.getImage();
|
||||
FeedImage parsedImage = parsedFeed.getImage();
|
||||
assertNotNull(parsedImage);
|
||||
|
||||
assertEquals(image.getTitle(), parsedImage.getTitle());
|
||||
assertEquals(image.getDownload_url(), parsedImage.getDownload_url());
|
||||
}
|
||||
assertEquals(feed.getImageUrl(), parsedFeed.getImageUrl());
|
||||
|
||||
if (feed.getItems() != null) {
|
||||
assertNotNull(parsedFeed.getItems());
|
||||
|
@ -119,14 +110,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
|
|||
assertEquals(media.getMime_type(), parsedMedia.getMime_type());
|
||||
}
|
||||
|
||||
if (item.hasItemImage()) {
|
||||
assertTrue(parsedItem.hasItemImage());
|
||||
FeedImage image = item.getImage();
|
||||
FeedImage parsedImage = parsedItem.getImage();
|
||||
|
||||
assertEquals(image.getTitle(), parsedImage.getTitle());
|
||||
assertEquals(image.getDownload_url(), parsedImage.getDownload_url());
|
||||
}
|
||||
assertEquals(item.getImageUrl(), parsedFeed.getImageUrl());
|
||||
|
||||
if (item.getChapters() != null) {
|
||||
assertNotNull(parsedItem.getChapters());
|
||||
|
@ -158,12 +142,8 @@ public class FeedHandlerTest extends InstrumentationTestCase {
|
|||
}
|
||||
|
||||
private Feed createTestFeed(int numItems, boolean withImage, boolean withFeedMedia, boolean withChapters) {
|
||||
FeedImage image = null;
|
||||
if (withImage) {
|
||||
image = new FeedImage(0, "image", null, "http://example.com/picture", false);
|
||||
}
|
||||
Feed feed = new Feed(0, null, "title", "http://example.com", "This is the description",
|
||||
"http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image, file.getAbsolutePath(),
|
||||
"http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", "http://example.com/picture", file.getAbsolutePath(),
|
||||
"http://example.com/feed", true);
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
|
|
|
@ -15,9 +15,7 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.SimpleChapter;
|
||||
|
@ -124,89 +122,13 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
assertNull(media.getFile_url());
|
||||
}
|
||||
|
||||
public void testDeleteFeed() throws IOException, ExecutionException, InterruptedException, TimeoutException {
|
||||
public void testDeleteFeed() throws ExecutionException, InterruptedException, IOException, TimeoutException {
|
||||
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
||||
assertNotNull(destFolder);
|
||||
|
||||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
// create Feed image
|
||||
File imgFile = new File(destFolder, "image");
|
||||
assertTrue(imgFile.createNewFile());
|
||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
||||
image.setOwner(feed);
|
||||
feed.setImage(image);
|
||||
|
||||
List<File> itemFiles = new ArrayList<>();
|
||||
// create items with downloaded media files
|
||||
for (int i = 0; i < 10; i++) {
|
||||
FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed, true);
|
||||
feed.getItems().add(item);
|
||||
|
||||
File enc = new File(destFolder, "file " + i);
|
||||
assertTrue(enc.createNewFile());
|
||||
itemFiles.add(enc);
|
||||
|
||||
FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0, 0);
|
||||
item.setMedia(media);
|
||||
|
||||
item.setChapters(new ArrayList<>());
|
||||
item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com"));
|
||||
}
|
||||
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
adapter.setCompleteFeed(feed);
|
||||
adapter.close();
|
||||
|
||||
assertTrue(feed.getId() != 0);
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
assertTrue(item.getId() != 0);
|
||||
assertTrue(item.getMedia().getId() != 0);
|
||||
assertTrue(item.getChapters().get(0).getId() != 0);
|
||||
}
|
||||
|
||||
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
||||
|
||||
// check if files still exist
|
||||
assertFalse(imgFile.exists());
|
||||
for (File f : itemFiles) {
|
||||
assertFalse(f.exists());
|
||||
}
|
||||
|
||||
adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
c = adapter.getSimpleChaptersOfFeedItemCursor(item);
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
}
|
||||
adapter.close();
|
||||
}
|
||||
|
||||
public void testDeleteFeedNoImage() throws ExecutionException, InterruptedException, IOException, TimeoutException {
|
||||
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
||||
assertNotNull(destFolder);
|
||||
|
||||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
feed.setImage(null);
|
||||
|
||||
List<File> itemFiles = new ArrayList<>();
|
||||
// create items with downloaded media files
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
@ -261,13 +183,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
|
||||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(null);
|
||||
|
||||
// create Feed image
|
||||
File imgFile = new File(destFolder, "image");
|
||||
assertTrue(imgFile.createNewFile());
|
||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
||||
image.setOwner(feed);
|
||||
feed.setImage(image);
|
||||
feed.setImageUrl("url");
|
||||
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
|
@ -275,21 +191,14 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
adapter.close();
|
||||
|
||||
assertTrue(feed.getId() != 0);
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
|
||||
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
||||
|
||||
// check if files still exist
|
||||
assertFalse(imgFile.exists());
|
||||
|
||||
adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
adapter.close();
|
||||
}
|
||||
|
||||
|
@ -300,12 +209,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
// create Feed image
|
||||
File imgFile = new File(destFolder, "image");
|
||||
assertTrue(imgFile.createNewFile());
|
||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
||||
image.setOwner(feed);
|
||||
feed.setImage(image);
|
||||
feed.setImageUrl("url");
|
||||
|
||||
// create items
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
@ -320,24 +224,18 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
adapter.close();
|
||||
|
||||
assertTrue(feed.getId() != 0);
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
assertTrue(item.getId() != 0);
|
||||
}
|
||||
|
||||
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
||||
|
||||
// check if files still exist
|
||||
assertFalse(imgFile.exists());
|
||||
|
||||
adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
|
@ -346,65 +244,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
adapter.close();
|
||||
}
|
||||
|
||||
public void testDeleteFeedWithItemImages() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
||||
assertNotNull(destFolder);
|
||||
|
||||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
// create Feed image
|
||||
File imgFile = new File(destFolder, "image");
|
||||
assertTrue(imgFile.createNewFile());
|
||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
||||
image.setOwner(feed);
|
||||
feed.setImage(image);
|
||||
|
||||
// create items with images
|
||||
for (int i = 0; i < 10; i++) {
|
||||
FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed);
|
||||
feed.getItems().add(item);
|
||||
File itemImageFile = new File(destFolder, "item-image-" + i);
|
||||
FeedImage itemImage = new FeedImage(0, "item-image" + i, itemImageFile.getAbsolutePath(), "url", true);
|
||||
item.setImage(itemImage);
|
||||
}
|
||||
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
adapter.setCompleteFeed(feed);
|
||||
adapter.close();
|
||||
|
||||
assertTrue(feed.getId() != 0);
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
assertTrue(item.getId() != 0);
|
||||
assertTrue(item.getImage().getId() != 0);
|
||||
}
|
||||
|
||||
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
|
||||
|
||||
// check if files still exist
|
||||
assertFalse(imgFile.exists());
|
||||
|
||||
adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(item.getImage().getId()));
|
||||
assertEquals(0, c.getCount());
|
||||
c.close();
|
||||
}
|
||||
adapter.close();
|
||||
}
|
||||
|
||||
public void testDeleteFeedWithQueueItems() throws ExecutionException, InterruptedException, TimeoutException {
|
||||
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
|
||||
assertNotNull(destFolder);
|
||||
|
@ -412,11 +251,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
// create Feed image
|
||||
File imgFile = new File(destFolder, "image");
|
||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
||||
image.setOwner(feed);
|
||||
feed.setImage(image);
|
||||
feed.setImageUrl("url");
|
||||
|
||||
List<File> itemFiles = new ArrayList<>();
|
||||
// create items with downloaded media files
|
||||
|
@ -437,7 +272,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
adapter.close();
|
||||
|
||||
assertTrue(feed.getId() != 0);
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
assertTrue(item.getId() != 0);
|
||||
assertTrue(item.getMedia().getId() != 0);
|
||||
|
@ -460,9 +294,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
|
@ -484,11 +315,7 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
Feed feed = new Feed("url", null, "title");
|
||||
feed.setItems(new ArrayList<>());
|
||||
|
||||
// create Feed image
|
||||
File imgFile = new File(destFolder, "image");
|
||||
FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
|
||||
image.setOwner(feed);
|
||||
feed.setImage(image);
|
||||
feed.setImageUrl("url");
|
||||
|
||||
List<File> itemFiles = new ArrayList<>();
|
||||
// create items with downloaded media files
|
||||
|
@ -509,7 +336,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
adapter.close();
|
||||
|
||||
assertTrue(feed.getId() != 0);
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
assertTrue(item.getId() != 0);
|
||||
assertTrue(item.getMedia().getId() != 0);
|
||||
|
@ -522,9 +348,6 @@ public class DBWriterTest extends InstrumentationTestCase {
|
|||
Cursor c = adapter.getFeedCursor(feed.getId());
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
c = adapter.getImageCursor(String.valueOf(image.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
c.close();
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
|
||||
assertTrue(c.getCount() == 0);
|
||||
|
|
|
@ -55,6 +55,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
} else {
|
||||
otherTheme = R.string.pref_theme_title_light;
|
||||
}
|
||||
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||
solo.clickOnText(solo.getString(R.string.pref_set_theme_title));
|
||||
solo.waitForDialogToOpen();
|
||||
solo.clickOnText(solo.getString(otherTheme));
|
||||
|
@ -69,6 +70,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
} else {
|
||||
otherTheme = R.string.pref_theme_title_light;
|
||||
}
|
||||
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||
solo.clickOnText(solo.getString(R.string.pref_set_theme_title));
|
||||
solo.waitForDialogToOpen(1000);
|
||||
solo.clickOnText(solo.getString(otherTheme));
|
||||
|
@ -76,6 +78,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testExpandNotification() {
|
||||
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||
final int priority = UserPreferences.getNotifyPriority();
|
||||
solo.clickOnText(solo.getString(R.string.pref_expandNotify_title));
|
||||
assertTrue(solo.waitForCondition(() -> priority != UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout()));
|
||||
|
@ -84,7 +87,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testEnablePersistentPlaybackControls() {
|
||||
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||
final boolean persistNotify = UserPreferences.isPersistNotify();
|
||||
solo.scrollDown();
|
||||
solo.scrollDown();
|
||||
solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
|
||||
assertTrue(solo.waitForCondition(() -> persistNotify != UserPreferences.isPersistNotify(), Timeout.getLargeTimeout()));
|
||||
solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
|
||||
|
@ -92,6 +98,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testSetLockscreenButtons() {
|
||||
solo.clickOnText(solo.getString(R.string.user_interface_label));
|
||||
solo.scrollDown();
|
||||
String[] buttons = res.getStringArray(R.array.compact_notification_buttons_options);
|
||||
solo.clickOnText(solo.getString(R.string.pref_compact_notification_buttons_title));
|
||||
solo.waitForDialogToOpen(1000);
|
||||
|
@ -116,7 +124,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testEnqueueAtFront() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
final boolean enqueueAtFront = UserPreferences.enqueueAtFront();
|
||||
solo.scrollDown();
|
||||
solo.scrollDown();
|
||||
solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title));
|
||||
assertTrue(solo.waitForCondition(() -> enqueueAtFront != UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout()));
|
||||
solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title));
|
||||
|
@ -124,6 +135,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testHeadPhonesDisconnect() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect();
|
||||
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
||||
assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect != UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout()));
|
||||
|
@ -132,6 +144,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testHeadPhonesReconnect() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
|
||||
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
||||
assertTrue(solo.waitForCondition(UserPreferences::isPauseOnHeadsetDisconnect, Timeout.getLargeTimeout()));
|
||||
|
@ -144,6 +157,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testBluetoothReconnect() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
|
||||
solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title));
|
||||
assertTrue(solo.waitForCondition(UserPreferences::isPauseOnHeadsetDisconnect, Timeout.getLargeTimeout()));
|
||||
|
@ -156,7 +170,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testContinuousPlayback() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
final boolean continuousPlayback = UserPreferences.isFollowQueue();
|
||||
solo.scrollDown();
|
||||
solo.scrollDown();
|
||||
solo.clickOnText(solo.getString(R.string.pref_followQueue_title));
|
||||
assertTrue(solo.waitForCondition(() -> continuousPlayback != UserPreferences.isFollowQueue(), Timeout.getLargeTimeout()));
|
||||
solo.clickOnText(solo.getString(R.string.pref_followQueue_title));
|
||||
|
@ -164,6 +181,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testAutoDelete() {
|
||||
solo.clickOnText(solo.getString(R.string.storage_pref));
|
||||
final boolean autoDelete = UserPreferences.isAutoDelete();
|
||||
solo.clickOnText(solo.getString(R.string.pref_auto_delete_title));
|
||||
assertTrue(solo.waitForCondition(() -> autoDelete != UserPreferences.isAutoDelete(), Timeout.getLargeTimeout()));
|
||||
|
@ -172,6 +190,9 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testPlaybackSpeeds() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
solo.scrollDown();
|
||||
solo.scrollDown();
|
||||
solo.clickOnText(solo.getString(R.string.pref_playback_speed_title));
|
||||
solo.waitForDialogToOpen(1000);
|
||||
assertTrue(solo.searchText(res.getStringArray(R.array.playback_speed_values)[0]));
|
||||
|
@ -180,6 +201,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testPauseForInterruptions() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss();
|
||||
solo.clickOnText(solo.getString(R.string.pref_pausePlaybackForFocusLoss_title));
|
||||
assertTrue(solo.waitForCondition(() -> pauseForFocusLoss != UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout()));
|
||||
|
@ -188,6 +210,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testDisableUpdateInterval() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_sum));
|
||||
solo.waitForDialogToOpen();
|
||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Disable));
|
||||
|
@ -195,6 +218,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testSetUpdateInterval() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_title));
|
||||
solo.waitForDialogToOpen();
|
||||
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
|
||||
|
@ -207,6 +231,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testMobileUpdates() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
final boolean mobileUpdates = UserPreferences.isAllowMobileUpdate();
|
||||
solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title));
|
||||
assertTrue(solo.waitForCondition(() -> mobileUpdates != UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout()));
|
||||
|
@ -215,6 +240,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testSetSequentialDownload() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
||||
solo.waitForDialogToOpen();
|
||||
solo.clearEditText(0);
|
||||
|
@ -224,6 +250,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testSetParallelDownloads() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
||||
solo.waitForDialogToOpen();
|
||||
solo.clearEditText(0);
|
||||
|
@ -233,6 +260,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testSetParallelDownloadsInvalidInput() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
|
||||
solo.waitForDialogToOpen();
|
||||
solo.clearEditText(0);
|
||||
|
@ -248,6 +276,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
||||
String entry = entries[entries.length/2];
|
||||
final int value = Integer.valueOf(values[values.length/2]);
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.clickOnText(solo.getString(R.string.pref_episode_cache_title));
|
||||
|
@ -261,6 +290,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
||||
String minEntry = entries[0];
|
||||
final int minValue = Integer.valueOf(values[0]);
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
||||
if(!UserPreferences.isEnableAutodownload()) {
|
||||
|
@ -278,6 +308,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
String[] values = res.getStringArray(R.array.episode_cache_size_values);
|
||||
String maxEntry = entries[entries.length-1];
|
||||
final int maxValue = Integer.valueOf(values[values.length-1]);
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
||||
if(!UserPreferences.isEnableAutodownload()) {
|
||||
|
@ -291,6 +322,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
|
||||
public void testAutomaticDownload() {
|
||||
final boolean automaticDownload = UserPreferences.isEnableAutodownload();
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
|
@ -312,6 +344,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testEpisodeCleanupQueueOnly() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||
solo.waitForText(solo.getString(R.string.episode_cleanup_queue_removal));
|
||||
solo.clickOnText(solo.getString(R.string.episode_cleanup_queue_removal));
|
||||
|
@ -323,6 +357,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testEpisodeCleanupNeverAlg() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||
solo.waitForText(solo.getString(R.string.episode_cleanup_never));
|
||||
solo.clickOnText(solo.getString(R.string.episode_cleanup_never));
|
||||
|
@ -334,6 +370,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testEpisodeCleanupClassic() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||
solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
|
||||
solo.clickOnText(solo.getString(R.string.episode_cleanup_after_listening));
|
||||
|
@ -349,6 +387,8 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testEpisodeCleanupNumDays() {
|
||||
solo.clickOnText(solo.getString(R.string.network_pref));
|
||||
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
|
||||
solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
|
||||
solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
|
||||
solo.clickOnText("5");
|
||||
|
@ -368,6 +408,9 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
int seconds = UserPreferences.getRewindSecs();
|
||||
int deltas[] = res.getIntArray(R.array.seek_delta_values);
|
||||
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
solo.scrollDown();
|
||||
solo.scrollDown();
|
||||
solo.clickOnText(solo.getString(R.string.pref_rewind));
|
||||
solo.waitForDialogToOpen();
|
||||
|
||||
|
@ -386,6 +429,9 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
|
|||
}
|
||||
|
||||
public void testFastForwardChange() {
|
||||
solo.clickOnText(solo.getString(R.string.playback_pref));
|
||||
solo.scrollDown();
|
||||
solo.scrollDown();
|
||||
for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind
|
||||
int seconds = UserPreferences.getFastForwardSecs();
|
||||
int deltas[] = res.getIntArray(R.array.seek_delta_values);
|
||||
|
|
|
@ -22,7 +22,6 @@ import de.danoeh.antennapod.activity.MainActivity;
|
|||
import de.danoeh.antennapod.core.event.QueueEvent;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
|
@ -136,12 +135,9 @@ class UITestUtils {
|
|||
public void addHostedFeedData() throws IOException {
|
||||
if (feedDataHosted) throw new IllegalStateException("addHostedFeedData was called twice on the same instance");
|
||||
for (int i = 0; i < NUM_FEEDS; i++) {
|
||||
File bitmapFile = newBitmapFile("image" + i);
|
||||
FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false);
|
||||
Feed feed = new Feed(0, null, "Title " + i, "http://example.com/" + i, "Description of feed " + i,
|
||||
"http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, image, null,
|
||||
"http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, null, null,
|
||||
"http://example.com/feed/src/" + i, false);
|
||||
image.setOwner(feed);
|
||||
|
||||
// create items
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
|
@ -187,12 +183,6 @@ class UITestUtils {
|
|||
List<FeedItem> queue = new ArrayList<>();
|
||||
for (Feed feed : hostedFeeds) {
|
||||
feed.setDownloaded(true);
|
||||
if (feed.getImage() != null) {
|
||||
FeedImage image = feed.getImage();
|
||||
int fileId = Integer.parseInt(StringUtils.substringAfter(image.getDownload_url(), "files/"));
|
||||
image.setFile_url(server.accessFile(fileId).getAbsolutePath());
|
||||
image.setDownloaded(true);
|
||||
}
|
||||
if (downloadEpisodes) {
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
if (item.hasMedia()) {
|
||||
|
|
|
@ -38,9 +38,6 @@ public class UITestUtilsTest extends InstrumentationTestCase {
|
|||
|
||||
for (Feed feed : feeds) {
|
||||
testUrlReachable(feed.getDownload_url());
|
||||
if (feed.getImage() != null) {
|
||||
testUrlReachable(feed.getImage().getDownload_url());
|
||||
}
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
if (item.hasMedia()) {
|
||||
testUrlReachable(item.getMedia().getDownload_url());
|
||||
|
@ -66,9 +63,6 @@ public class UITestUtilsTest extends InstrumentationTestCase {
|
|||
|
||||
for (Feed feed : uiTestUtils.hostedFeeds) {
|
||||
assertTrue(feed.getId() != 0);
|
||||
if (feed.getImage() != null) {
|
||||
assertTrue(feed.getImage().getId() != 0);
|
||||
}
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
assertTrue(item.getId() != 0);
|
||||
if (item.hasMedia()) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="de.danoeh.antennapod"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="1060595"
|
||||
android:versionCode="1060596"
|
||||
android:versionName="1.6.5">
|
||||
<!--
|
||||
Version code schema:
|
||||
|
|
|
@ -393,9 +393,9 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
|||
|
||||
subscribeButton = (Button) header.findViewById(R.id.butSubscribe);
|
||||
|
||||
if (feed.getImage() != null && StringUtils.isNotBlank(feed.getImage().getDownload_url())) {
|
||||
if (StringUtils.isNotBlank(feed.getImageUrl())) {
|
||||
Glide.with(this)
|
||||
.load(feed.getImage().getDownload_url())
|
||||
.load(feed.getImageUrl())
|
||||
.placeholder(R.color.light_gray)
|
||||
.error(R.color.light_gray)
|
||||
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
|
||||
|
|
|
@ -29,12 +29,12 @@ import de.danoeh.antennapod.activity.MainActivity;
|
|||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.fragment.ItemFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
|
||||
|
@ -67,11 +67,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||
this.actionButtonCallback = actionButtonCallback;
|
||||
this.showOnlyNewEpisodes = showOnlyNewEpisodes;
|
||||
|
||||
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark);
|
||||
} else {
|
||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light);
|
||||
}
|
||||
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
|
||||
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ import android.widget.TextView;
|
|||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.util.ChapterUtils;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import de.danoeh.antennapod.core.util.playback.Playable;
|
||||
|
||||
public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
||||
|
@ -143,9 +143,7 @@ public class ChaptersListAdapter extends ArrayAdapter<Chapter> {
|
|||
|
||||
Chapter current = ChapterUtils.getCurrentChapter(media);
|
||||
if (current == sc) {
|
||||
boolean darkTheme = UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark;
|
||||
int highlight = darkTheme ? R.color.highlight_dark : R.color.highlight_light;
|
||||
int playingBackGroundColor = ContextCompat.getColor(getContext(), highlight);
|
||||
int playingBackGroundColor = ThemeUtils.getColorFromAttr(getContext(), R.attr.currently_playing_background);
|
||||
holder.view.setBackgroundColor(playingBackGroundColor);
|
||||
} else {
|
||||
holder.view.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
|
||||
|
|
|
@ -19,7 +19,6 @@ import com.joanzapata.iconify.widget.IconTextView;
|
|||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
|
@ -67,8 +66,6 @@ public class DownloadLogAdapter extends BaseAdapter {
|
|||
holder.type.setText(R.string.download_type_feed);
|
||||
} else if (status.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
holder.type.setText(R.string.download_type_media);
|
||||
} else if (status.getFeedfileType() == FeedImage.FEEDFILETYPE_FEEDIMAGE) {
|
||||
holder.type.setText(R.string.download_type_image);
|
||||
}
|
||||
if (status.getTitle() != null) {
|
||||
holder.title.setText(status.getTitle());
|
||||
|
@ -94,8 +91,7 @@ public class DownloadLogAdapter extends BaseAdapter {
|
|||
}
|
||||
holder.reason.setText(reasonText);
|
||||
holder.reason.setVisibility(View.VISIBLE);
|
||||
if(status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE &&
|
||||
!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
||||
if(!newerWasSuccessful(position, status.getFeedfileType(), status.getFeedfileId())) {
|
||||
holder.retry.setVisibility(View.VISIBLE);
|
||||
holder.retry.setOnClickListener(clickListener);
|
||||
ButtonHolder btnHolder;
|
||||
|
|
|
@ -21,7 +21,6 @@ import de.danoeh.antennapod.R;
|
|||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.MediaType;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
|
@ -60,11 +59,7 @@ public class FeedItemlistAdapter extends BaseAdapter {
|
|||
this.actionButtonUtils = new ActionButtonUtils(context);
|
||||
this.makePlayedItemsTransparent = makePlayedItemsTransparent;
|
||||
|
||||
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
||||
playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_dark);
|
||||
} else {
|
||||
playingBackGroundColor = ContextCompat.getColor(context, R.color.highlight_light);
|
||||
}
|
||||
playingBackGroundColor = ThemeUtils.getColorFromAttr(context, R.attr.currently_playing_background);
|
||||
normalBackGroundColor = ContextCompat.getColor(context, android.R.color.transparent);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.widget.TextView;
|
|||
import com.bumptech.glide.Glide;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
|
||||
import de.danoeh.antennapod.core.util.ThemeUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
@ -75,11 +76,7 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
this.itemTouchHelper = itemTouchHelper;
|
||||
locked = UserPreferences.isQueueLocked();
|
||||
|
||||
if(UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_dark);
|
||||
} else {
|
||||
playingBackGroundColor = ContextCompat.getColor(mainActivity, R.color.highlight_light);
|
||||
}
|
||||
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
|
||||
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
|
||||
}
|
||||
|
||||
|
|
|
@ -113,10 +113,13 @@ public class ItemDescriptionFragment extends Fragment implements MediaplayerInfo
|
|||
Log.d(TAG, "Creating view");
|
||||
webvDescription = new WebView(getActivity().getApplicationContext());
|
||||
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
|
||||
TypedArray ta = getActivity().getTheme().obtainStyledAttributes(new int[]
|
||||
{android.R.attr.colorBackground});
|
||||
int backgroundColor = ta.getColor(0, UserPreferences.getTheme() ==
|
||||
R.style.Theme_AntennaPod_Dark ? Color.BLACK : Color.WHITE);
|
||||
boolean black = UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark
|
||||
|| UserPreferences.getTheme() == R.style.Theme_AntennaPod_TrueBlack;
|
||||
int backgroundColor = ta.getColor(0, black ? Color.BLACK : Color.WHITE);
|
||||
|
||||
ta.recycle();
|
||||
webvDescription.setBackgroundColor(backgroundColor);
|
||||
if (!NetworkUtils.networkAvailable()) {
|
||||
|
|
|
@ -185,7 +185,8 @@ public class ItemFragment extends Fragment implements OnSwipeGesture {
|
|||
txtvTitle.setEllipsize(TextUtils.TruncateAt.END);
|
||||
}
|
||||
webvDescription = (WebView) layout.findViewById(R.id.webvDescription);
|
||||
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
|
||||
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark ||
|
||||
UserPreferences.getTheme() == R.style.Theme_AntennaPod_TrueBlack) {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
|
|||
public static void adjustTextColor(Context context, SearchView sv) {
|
||||
if(Build.VERSION.SDK_INT < 14) {
|
||||
EditText searchEditText = (EditText) sv.findViewById(R.id.search_src_text);
|
||||
if(UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark) {
|
||||
if (UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark
|
||||
|| UserPreferences.getTheme() == R.style.Theme_AntennaPod_TrueBlack) {
|
||||
searchEditText.setTextColor(Color.WHITE);
|
||||
} else {
|
||||
searchEditText.setTextColor(Color.BLACK);
|
||||
|
|
|
@ -10,7 +10,7 @@ android {
|
|||
versionCode 1
|
||||
versionName "1.0"
|
||||
testApplicationId "de.danoeh.antennapod.core.tests"
|
||||
testInstrumentationRunner "de.danoeh.antennapod.core.tests.AntennaPodTestRunner"
|
||||
testInstrumentationRunner "de.danoeh.antennapod.core.AntennaPodTestRunner"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
@ -80,6 +80,18 @@ dependencies {
|
|||
} else {
|
||||
System.out.println("core: free build hack, skipping some dependencies")
|
||||
}
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
testLogging {
|
||||
exceptionFormat "full"
|
||||
events "skipped", "passed", "failed"
|
||||
showStandardStreams true
|
||||
displayGranularity 2
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package de.danoeh.antennapod.core.tests;
|
||||
package de.danoeh.antennapod.core;
|
||||
|
||||
import android.test.InstrumentationTestRunner;
|
||||
import android.test.suitebuilder.TestSuiteBuilder;
|
|
@ -1,9 +0,0 @@
|
|||
package de.danoeh.antennapod.core.feed;
|
||||
|
||||
class FeedImageMother {
|
||||
|
||||
public static FeedImage anyFeedImage() {
|
||||
return new FeedImage(0, "image", null, "http://example.com/picture", false);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package de.danoeh.antennapod.core.tests.util.service.download;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
|
||||
public class DownloadServiceTest extends AndroidTestCase {
|
||||
|
||||
public void testRemoveDuplicateImages() {
|
||||
List<FeedItem> items = new ArrayList<>();
|
||||
for (int i = 0; i < 50; i++) {
|
||||
FeedItem item = new FeedItem();
|
||||
String url = (i % 5 == 0) ? "dupe_url" : String.format("url_%d", i);
|
||||
item.setImage(new FeedImage(null, url, ""));
|
||||
items.add(item);
|
||||
}
|
||||
Feed feed = new Feed();
|
||||
feed.setItems(items);
|
||||
|
||||
DownloadService.removeDuplicateImages(feed);
|
||||
|
||||
assertEquals(50, items.size());
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
FeedItem item = items.get(i);
|
||||
String want = (i == 0) ? "dupe_url" : (i % 5 == 0) ? null : String.format("url_%d", i);
|
||||
assertEquals(want, item.getImageLocation());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package de.danoeh.antennapod.core.tests.util;
|
||||
package de.danoeh.antennapod.core.util;
|
||||
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
@ -7,8 +7,14 @@ import java.util.Date;
|
|||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
|
||||
/**
|
||||
* Unit test for {@link DateUtils}.
|
||||
*
|
||||
* Note: It NEEDS to be run in android devices, i.e., it cannot be run in standard JDK, because
|
||||
* the test invokes some android platform-specific behavior in the underlying
|
||||
* {@link java.text.SimpleDateFormat} used by {@link DateUtils}.
|
||||
*
|
||||
*/
|
||||
public class DateUtilsTest extends AndroidTestCase {
|
||||
|
||||
public void testParseDateWithMicroseconds() throws Exception {
|
||||
|
@ -101,6 +107,12 @@ public class DateUtilsTest extends AndroidTestCase {
|
|||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires Android platform.
|
||||
*
|
||||
* Reason: Standard JDK cannot parse timezone <code>-08:00</code> (ISO 8601 format). It only accepts
|
||||
* <code>-0800</code> (RFC 822 format)
|
||||
*/
|
||||
public void testParseDateWithNoTimezonePadding() throws Exception {
|
||||
GregorianCalendar exp = new GregorianCalendar(2017, 1, 22, 22, 28, 0);
|
||||
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
@ -109,6 +121,12 @@ public class DateUtilsTest extends AndroidTestCase {
|
|||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires Android platform. Root cause: {@link DateUtils} implementation makes
|
||||
* use of ISO 8601 time zone, which does not work on standard JDK.
|
||||
*
|
||||
* @see #testParseDateWithNoTimezonePadding()
|
||||
*/
|
||||
public void testParseDateWithForCest() throws Exception {
|
||||
GregorianCalendar exp1 = new GregorianCalendar(2017, 0, 28, 22, 0, 0);
|
||||
exp1.setTimeZone(TimeZone.getTimeZone("UTC"));
|
|
@ -14,7 +14,6 @@ import java.io.File;
|
|||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
|
@ -64,29 +63,6 @@ class UpdateManager {
|
|||
}
|
||||
|
||||
private static void onUpgrade(final int oldVersionCode, final int newVersionCode) {
|
||||
if(oldVersionCode < 1030099) {
|
||||
// delete the now obsolete image cache
|
||||
// from now on, Glide will handle caching images
|
||||
new Thread() {
|
||||
public void run() {
|
||||
List<Feed> feeds = DBReader.getFeedList();
|
||||
for (Feed podcast : feeds) {
|
||||
List<FeedItem> episodes = DBReader.getFeedItemList(podcast);
|
||||
for (FeedItem episode : episodes) {
|
||||
FeedImage image = episode.getImage();
|
||||
if (image != null && image.isDownloaded() && image.getFile_url() != null) {
|
||||
File imageFile = new File(image.getFile_url());
|
||||
if (imageFile.exists()) {
|
||||
imageFile.delete();
|
||||
}
|
||||
image.setFile_url(null); // calls setDownloaded(false)
|
||||
DBWriter.setFeedImage(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
if(oldVersionCode < 1050004) {
|
||||
if(MediaPlayer.isPrestoLibraryInstalled(context) && Build.VERSION.SDK_INT >= 16) {
|
||||
UserPreferences.enableSonic();
|
||||
|
|
|
@ -44,7 +44,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
* Name of the author
|
||||
*/
|
||||
private String author;
|
||||
private FeedImage image;
|
||||
private String imageUrl;
|
||||
private List<FeedItem> items;
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
* This constructor is used for restoring a feed from the database.
|
||||
*/
|
||||
public Feed(long id, String lastUpdate, String title, String customTitle, String link, String description, String paymentLink,
|
||||
String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
|
||||
String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl,
|
||||
String downloadUrl, boolean downloaded, FlattrStatus status, boolean paged, String nextPageLink,
|
||||
String filter, boolean lastUpdateFailed) {
|
||||
super(fileUrl, downloadUrl, downloaded);
|
||||
|
@ -111,7 +111,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
this.language = language;
|
||||
this.type = type;
|
||||
this.feedIdentifier = feedIdentifier;
|
||||
this.image = image;
|
||||
this.imageUrl = imageUrl;
|
||||
this.flattrStatus = status;
|
||||
this.paged = paged;
|
||||
this.nextPageLink = nextPageLink;
|
||||
|
@ -128,9 +128,9 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
* This constructor is used for test purposes and uses a default flattr status object.
|
||||
*/
|
||||
public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink,
|
||||
String author, String language, String type, String feedIdentifier, FeedImage image, String fileUrl,
|
||||
String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl,
|
||||
String downloadUrl, boolean downloaded) {
|
||||
this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, image,
|
||||
this(id, lastUpdate, title, null, link, description, paymentLink, author, language, type, feedIdentifier, imageUrl,
|
||||
fileUrl, downloadUrl, downloaded, new FlattrStatus(), false, null, null, false);
|
||||
}
|
||||
|
||||
|
@ -191,6 +191,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
int indexNextPageLink = cursor.getColumnIndex(PodDBAdapter.KEY_NEXT_PAGE_LINK);
|
||||
int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE);
|
||||
int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED);
|
||||
int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL);
|
||||
|
||||
Feed feed = new Feed(
|
||||
cursor.getLong(indexId),
|
||||
|
@ -204,7 +205,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
cursor.getString(indexLanguage),
|
||||
cursor.getString(indexType),
|
||||
cursor.getString(indexFeedIdentifier),
|
||||
null,
|
||||
cursor.getString(indexImageUrl),
|
||||
cursor.getString(indexFileUrl),
|
||||
cursor.getString(indexDownloadUrl),
|
||||
cursor.getInt(indexDownloaded) > 0,
|
||||
|
@ -266,8 +267,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
public void updateFromOther(Feed other) {
|
||||
// don't update feed's download_url, we do that manually if redirected
|
||||
// see AntennapodHttpClient
|
||||
if (other.image != null) {
|
||||
this.image = other.image;
|
||||
if (other.imageUrl != null) {
|
||||
this.imageUrl = other.imageUrl;
|
||||
}
|
||||
if (other.feedTitle != null) {
|
||||
feedTitle = other.feedTitle;
|
||||
|
@ -305,8 +306,8 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
if (super.compareWithOther(other)) {
|
||||
return true;
|
||||
}
|
||||
if (other.image != null) {
|
||||
if (image == null || !TextUtils.equals(image.download_url, other.image.download_url)) {
|
||||
if (other.imageUrl != null) {
|
||||
if (imageUrl == null || !TextUtils.equals(imageUrl, other.imageUrl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -411,12 +412,12 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
public FeedImage getImage() {
|
||||
return image;
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImage(FeedImage image) {
|
||||
this.image = image;
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public List<FeedItem> getItems() {
|
||||
|
@ -505,11 +506,7 @@ public class Feed extends FeedFile implements FlattrThing, ImageResource {
|
|||
|
||||
@Override
|
||||
public String getImageLocation() {
|
||||
if (image != null) {
|
||||
return image.getImageLocation();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public int getPageNr() {
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
package de.danoeh.antennapod.core.feed;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import de.danoeh.antennapod.core.asynctask.ImageResource;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
|
||||
|
||||
public class FeedImage extends FeedFile implements ImageResource {
|
||||
public static final int FEEDFILETYPE_FEEDIMAGE = 1;
|
||||
|
||||
private String title;
|
||||
private FeedComponent owner;
|
||||
|
||||
public FeedImage(FeedComponent owner, String download_url, String title) {
|
||||
super(null, download_url, false);
|
||||
this.download_url = download_url;
|
||||
this.title = title;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public FeedImage(long id, String title, String file_url,
|
||||
String download_url, boolean downloaded) {
|
||||
super(file_url, download_url, downloaded);
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public FeedImage() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static FeedImage fromCursor(Cursor cursor) {
|
||||
int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
|
||||
int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
|
||||
int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
|
||||
int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
|
||||
int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
|
||||
|
||||
return new FeedImage(
|
||||
cursor.getLong(indexId),
|
||||
cursor.getString(indexTitle),
|
||||
cursor.getString(indexFileUrl),
|
||||
cursor.getString(indexDownloadUrl),
|
||||
cursor.getInt(indexDownloaded) > 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHumanReadableIdentifier() {
|
||||
if (owner != null && owner.getHumanReadableIdentifier() != null) {
|
||||
return owner.getHumanReadableIdentifier();
|
||||
} else {
|
||||
return download_url;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeAsInt() {
|
||||
return FEEDFILETYPE_FEEDIMAGE;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public FeedComponent getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(FeedComponent owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageLocation() {
|
||||
if (file_url != null && downloaded) {
|
||||
return new File(file_url).getAbsolutePath();
|
||||
} else if(download_url != null) {
|
||||
return download_url;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import android.database.Cursor;
|
|||
import android.support.annotation.Nullable;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import de.danoeh.antennapod.core.asynctask.ImageResource;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
|
@ -14,7 +15,6 @@ import java.util.Set;
|
|||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import de.danoeh.antennapod.core.asynctask.ImageResource;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
import de.danoeh.antennapod.core.util.ShownotesProvider;
|
||||
|
@ -75,7 +75,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
* in the database. The 'hasChapters' attribute should be used to check if this item has any chapters.
|
||||
* */
|
||||
private List<Chapter> chapters;
|
||||
private FeedImage image;
|
||||
private String imageUrl;
|
||||
|
||||
/*
|
||||
* 0: auto download disabled
|
||||
|
@ -100,7 +100,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
* This constructor is used by DBReader.
|
||||
* */
|
||||
public FeedItem(long id, String title, String link, Date pubDate, String paymentLink, long feedId,
|
||||
FlattrStatus flattrStatus, boolean hasChapters, FeedImage image, int state,
|
||||
FlattrStatus flattrStatus, boolean hasChapters, String imageUrl, int state,
|
||||
String itemIdentifier, long autoDownload) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
|
@ -110,7 +110,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
this.feedId = feedId;
|
||||
this.flattrStatus = flattrStatus;
|
||||
this.hasChapters = hasChapters;
|
||||
this.image = image;
|
||||
this.imageUrl = imageUrl;
|
||||
this.state = state;
|
||||
this.itemIdentifier = itemIdentifier;
|
||||
this.autoDownload = autoDownload;
|
||||
|
@ -158,6 +158,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
int indexRead = cursor.getColumnIndex(PodDBAdapter.KEY_READ);
|
||||
int indexItemIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_ITEM_IDENTIFIER);
|
||||
int indexAutoDownload = cursor.getColumnIndex(PodDBAdapter.KEY_AUTO_DOWNLOAD);
|
||||
int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL);
|
||||
|
||||
long id = cursor.getInt(indexId);
|
||||
String title = cursor.getString(indexTitle);
|
||||
|
@ -170,15 +171,16 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
int state = cursor.getInt(indexRead);
|
||||
String itemIdentifier = cursor.getString(indexItemIdentifier);
|
||||
long autoDownload = cursor.getLong(indexAutoDownload);
|
||||
String imageUrl = cursor.getString(indexImageUrl);
|
||||
|
||||
return new FeedItem(id, title, link, pubDate, paymentLink, feedId, flattrStatus,
|
||||
hasChapters, null, state, itemIdentifier, autoDownload);
|
||||
hasChapters, imageUrl, state, itemIdentifier, autoDownload);
|
||||
}
|
||||
|
||||
public void updateFromOther(FeedItem other) {
|
||||
super.updateFromOther(other);
|
||||
if (other.image != null) {
|
||||
this.image = other.image;
|
||||
if (other.imageUrl != null) {
|
||||
this.imageUrl = other.imageUrl;
|
||||
}
|
||||
if (other.title != null) {
|
||||
title = other.title;
|
||||
|
@ -212,9 +214,6 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
chapters = other.chapters;
|
||||
}
|
||||
}
|
||||
if (image == null) {
|
||||
image = other.image;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -389,8 +388,8 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
public String getImageLocation() {
|
||||
if(media != null && media.hasEmbeddedPicture()) {
|
||||
return media.getImageLocation();
|
||||
} else if (image != null) {
|
||||
return image.getImageLocation();
|
||||
} else if (imageUrl != null) {
|
||||
return imageUrl;
|
||||
} else if (feed != null) {
|
||||
return feed.getImageLocation();
|
||||
} else {
|
||||
|
@ -426,29 +425,12 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr
|
|||
* Returns the image of this item or the image of the feed if this item does
|
||||
* not have its own image.
|
||||
*/
|
||||
public FeedImage getImage() {
|
||||
return (hasItemImage()) ? image : feed.getImage();
|
||||
public String getImageUrl() {
|
||||
return (imageUrl != null) ? imageUrl : feed.getImageUrl();
|
||||
}
|
||||
|
||||
public void setImage(FeedImage image) {
|
||||
this.image = image;
|
||||
if (image != null) {
|
||||
image.setOwner(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this FeedItem has its own image, false otherwise.
|
||||
*/
|
||||
public boolean hasItemImage() {
|
||||
return image != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this FeedItem has its own image and the image has been downloaded.
|
||||
*/
|
||||
public boolean hasItemImageDownloaded() {
|
||||
return image != null && image.isDownloaded();
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -161,6 +161,8 @@ public class UserPreferences {
|
|||
int theme = getTheme();
|
||||
if (theme == R.style.Theme_AntennaPod_Dark) {
|
||||
return R.style.Theme_AntennaPod_Dark_NoTitle;
|
||||
} else if (theme == R.style.Theme_AntennaPod_TrueBlack) {
|
||||
return R.style.Theme_AntennaPod_TrueBlack_NoTitle;
|
||||
} else {
|
||||
return R.style.Theme_AntennaPod_Light_NoTitle;
|
||||
}
|
||||
|
@ -597,6 +599,8 @@ public class UserPreferences {
|
|||
return R.style.Theme_AntennaPod_Light;
|
||||
case 1:
|
||||
return R.style.Theme_AntennaPod_Dark;
|
||||
case 2:
|
||||
return R.style.Theme_AntennaPod_TrueBlack;
|
||||
default:
|
||||
return R.style.Theme_AntennaPod_Light;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ import de.danoeh.antennapod.core.R;
|
|||
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||
import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
|
@ -489,9 +488,7 @@ public class DownloadService extends Service {
|
|||
if (status.isSuccessful()) {
|
||||
successfulDownloads++;
|
||||
} else if (!status.isCancelled()) {
|
||||
if (status.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) {
|
||||
createReport = true;
|
||||
}
|
||||
createReport = true;
|
||||
failedDownloads++;
|
||||
}
|
||||
}
|
||||
|
@ -688,10 +685,6 @@ public class DownloadService extends Service {
|
|||
|
||||
Log.d(TAG, "Bundling " + results.size() + " feeds");
|
||||
|
||||
for (Pair<DownloadRequest, FeedHandlerResult> result : results) {
|
||||
removeDuplicateImages(result.second.feed); // duplicate images have to removed because the DownloadRequester does not accept two downloads with the same download URL yet.
|
||||
}
|
||||
|
||||
// Save information of feed in DB
|
||||
if (dbUpdateFuture != null) {
|
||||
try {
|
||||
|
@ -1101,26 +1094,6 @@ public class DownloadService extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the FeedItems of this feed have images that point to the same URL. If two FeedItems
|
||||
* have an image that points to the same URL, the reference of the second item is removed, so
|
||||
* that every image reference is unique.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static void removeDuplicateImages(Feed feed) {
|
||||
Set<String> known = new HashSet<>();
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
String url = item.hasItemImage() ? item.getImage().getDownload_url() : null;
|
||||
if (url != null) {
|
||||
if (known.contains(url)) {
|
||||
item.setImage(null);
|
||||
} else {
|
||||
known.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String compileNotificationString(List<Downloader> downloads) {
|
||||
List<String> lines = new ArrayList<>(downloads.size());
|
||||
for (Downloader downloader : downloads) {
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.Date;
|
|||
|
||||
import de.danoeh.antennapod.core.ClientConfig;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.util.DateUtils;
|
||||
import de.danoeh.antennapod.core.util.DownloadError;
|
||||
|
@ -50,13 +49,8 @@ public class HttpDownloader extends Downloader {
|
|||
|
||||
if (request.isDeleteOnFailure() && fileExists) {
|
||||
Log.w(TAG, "File already exists");
|
||||
if (request.getFeedfileType() != FeedImage.FEEDFILETYPE_FEEDIMAGE) {
|
||||
onFail(DownloadError.ERROR_FILE_EXISTS, null);
|
||||
return;
|
||||
} else {
|
||||
onSuccess();
|
||||
return;
|
||||
}
|
||||
onSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
OkHttpClient.Builder httpClientBuilder = AntennapodHttpClient.newBuilder();
|
||||
|
|
|
@ -13,7 +13,6 @@ import java.util.Map;
|
|||
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
|
@ -201,25 +200,15 @@ public final class DBReader {
|
|||
private static List<FeedItem> extractItemlistFromCursor(PodDBAdapter adapter, Cursor cursor) {
|
||||
List<FeedItem> result = new ArrayList<>(cursor.getCount());
|
||||
|
||||
LongList imageIds = new LongList(cursor.getCount());
|
||||
LongList itemIds = new LongList(cursor.getCount());
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE);
|
||||
long imageId = cursor.getLong(indexImage);
|
||||
imageIds.add(imageId);
|
||||
|
||||
FeedItem item = FeedItem.fromCursor(cursor);
|
||||
result.add(item);
|
||||
itemIds.add(item.getId());
|
||||
} while (cursor.moveToNext());
|
||||
Map<Long, FeedImage> images = getFeedImages(adapter, imageIds.toArray());
|
||||
Map<Long, FeedMedia> medias = getFeedMedia(adapter, itemIds);
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
FeedItem item = result.get(i);
|
||||
long imageId = imageIds.get(i);
|
||||
FeedImage image = images.get(imageId);
|
||||
item.setImage(image);
|
||||
for (FeedItem item : result) {
|
||||
FeedMedia media = medias.get(item.getId());
|
||||
item.setMedia(media);
|
||||
if (media != null) {
|
||||
|
@ -254,24 +243,9 @@ public final class DBReader {
|
|||
}
|
||||
|
||||
private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, Cursor cursor) {
|
||||
final FeedImage image;
|
||||
int indexImage = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE);
|
||||
long imageId = cursor.getLong(indexImage);
|
||||
if (imageId != 0) {
|
||||
image = getFeedImage(adapter, imageId);
|
||||
} else {
|
||||
image = null;
|
||||
}
|
||||
|
||||
Feed feed = Feed.fromCursor(cursor);
|
||||
if (image != null) {
|
||||
feed.setImage(image);
|
||||
image.setOwner(feed);
|
||||
}
|
||||
|
||||
FeedPreferences preferences = FeedPreferences.fromCursor(cursor);
|
||||
feed.setPreferences(preferences);
|
||||
|
||||
return feed;
|
||||
}
|
||||
|
||||
|
@ -838,62 +812,6 @@ public final class DBReader {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the DB for a FeedImage of the given id.
|
||||
*
|
||||
* @param imageId The id of the object
|
||||
* @return The found object
|
||||
*/
|
||||
public static FeedImage getFeedImage(final long imageId) {
|
||||
Log.d(TAG, "getFeedImage() called with: " + "imageId = [" + imageId + "]");
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
try {
|
||||
return getFeedImage(adapter, imageId);
|
||||
} finally {
|
||||
adapter.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the DB for a FeedImage of the given id.
|
||||
*
|
||||
* @param imageId The id of the object
|
||||
* @return The found object
|
||||
*/
|
||||
private static FeedImage getFeedImage(PodDBAdapter adapter, final long imageId) {
|
||||
return getFeedImages(adapter, imageId).get(imageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the DB for a FeedImage of the given id.
|
||||
*
|
||||
* @param imageIds The ids of the images
|
||||
* @return Map that associates the id of an image with the image itself
|
||||
*/
|
||||
private static Map<Long, FeedImage> getFeedImages(PodDBAdapter adapter, final long... imageIds) {
|
||||
String[] ids = new String[imageIds.length];
|
||||
for (int i = 0, len = imageIds.length; i < len; i++) {
|
||||
ids[i] = String.valueOf(imageIds[i]);
|
||||
}
|
||||
Cursor cursor = adapter.getImageCursor(ids);
|
||||
int imageCount = cursor.getCount();
|
||||
if (imageCount == 0) {
|
||||
cursor.close();
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<Long, FeedImage> result = new ArrayMap<>(imageCount);
|
||||
try {
|
||||
while (cursor.moveToNext()) {
|
||||
FeedImage image = FeedImage.fromCursor(cursor);
|
||||
result.put(image.getId(), image);
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the DB for a FeedMedia of the given id.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
package de.danoeh.antennapod.core.storage;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.util.Log;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
|
||||
class DBUpgrader {
|
||||
/**
|
||||
* Upgrades the given database to a new schema version
|
||||
*/
|
||||
static void upgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||
if (oldVersion <= 1) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ PodDBAdapter.KEY_TYPE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 2) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 3) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_ITEM_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 4) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ PodDBAdapter.KEY_FEED_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 5) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_REASON_DETAILED + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_DOWNLOADSTATUS_TITLE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 6) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_CHAPTER_TYPE + " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 7) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 8) {
|
||||
final int KEY_ID_POSITION = 0;
|
||||
final int KEY_MEDIA_POSITION = 1;
|
||||
|
||||
// Add feeditem column to feedmedia table
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FEEDITEM
|
||||
+ " INTEGER");
|
||||
Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS,
|
||||
new String[]{PodDBAdapter.KEY_ID, PodDBAdapter.KEY_MEDIA}, "? > 0",
|
||||
new String[]{PodDBAdapter.KEY_MEDIA}, null, null, null);
|
||||
if (feeditemCursor.moveToFirst()) {
|
||||
db.beginTransaction();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
do {
|
||||
long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION);
|
||||
contentValues.put(PodDBAdapter.KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION));
|
||||
db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, PodDBAdapter.KEY_ID + "=?", new String[]{String.valueOf(mediaId)});
|
||||
contentValues.clear();
|
||||
} while (feeditemCursor.moveToNext());
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
feeditemCursor.close();
|
||||
}
|
||||
if (oldVersion <= 9) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD
|
||||
+ " INTEGER DEFAULT 1");
|
||||
}
|
||||
if (oldVersion <= 10) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_PLAYED_DURATION
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 11) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_USERNAME
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_PASSWORD
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_IMAGE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 12) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_IS_PAGED + " INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_NEXT_PAGE_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 13) {
|
||||
// remove duplicate rows in "Chapters" table that were created because of a bug.
|
||||
db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " +
|
||||
"(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)",
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
PodDBAdapter.KEY_ID,
|
||||
PodDBAdapter.KEY_ID,
|
||||
PodDBAdapter.KEY_ID,
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
PodDBAdapter.KEY_TITLE,
|
||||
PodDBAdapter.KEY_START,
|
||||
PodDBAdapter.KEY_FEEDITEM,
|
||||
PodDBAdapter.KEY_LINK,
|
||||
PodDBAdapter.KEY_CHAPTER_TYPE));
|
||||
}
|
||||
if (oldVersion <= 14) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " INTEGER");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + PodDBAdapter.KEY_AUTO_DOWNLOAD + " = "
|
||||
+ "(SELECT " + PodDBAdapter.KEY_AUTO_DOWNLOAD
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_ID
|
||||
+ " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_FEED + ")");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_HIDE + " TEXT");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0");
|
||||
|
||||
// create indexes
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
|
||||
}
|
||||
if (oldVersion <= 15) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=0");
|
||||
Cursor c = db.rawQuery("SELECT " + PodDBAdapter.KEY_FILE_URL
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " WHERE " + PodDBAdapter.KEY_DOWNLOADED + "=1 "
|
||||
+ " AND " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=-1", null);
|
||||
if (c.moveToFirst()) {
|
||||
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
|
||||
do {
|
||||
String fileUrl = c.getString(0);
|
||||
try {
|
||||
mmr.setDataSource(fileUrl);
|
||||
byte[] image = mmr.getEmbeddedPicture();
|
||||
if (image != null) {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=1"
|
||||
+ " WHERE " + PodDBAdapter.KEY_FILE_URL + "='" + fileUrl + "'");
|
||||
} else {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + PodDBAdapter.KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + PodDBAdapter.KEY_FILE_URL + "='" + fileUrl + "'");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} while (c.moveToNext());
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
if (oldVersion <= 16) {
|
||||
String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_FEEDITEM
|
||||
+ " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_FEEDITEM
|
||||
+ " WHERE "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_READ + " = 0 AND " // unplayed
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_DOWNLOADED + " = 0 AND " // undownloaded
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_POSITION + " = 0 AND " // not partially played
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + PodDBAdapter.KEY_ID + " IS NULL"; // not in queue
|
||||
String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + PodDBAdapter.KEY_READ + "=" + FeedItem.NEW
|
||||
+ " WHERE " + PodDBAdapter.KEY_ID + " IN (" + selectNew + ")";
|
||||
Log.d("Migration", "SQL: " + sql);
|
||||
db.execSQL(sql);
|
||||
}
|
||||
if (oldVersion <= 17) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0");
|
||||
}
|
||||
if (oldVersion < 1030005) {
|
||||
db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " +
|
||||
"(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " +
|
||||
"AND id NOT IN (SELECT feeditem FROM Queue)");
|
||||
}
|
||||
if (oldVersion < 1040001) {
|
||||
db.execSQL(PodDBAdapter.CREATE_TABLE_FAVORITES);
|
||||
}
|
||||
if (oldVersion < 1040002) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0");
|
||||
}
|
||||
if (oldVersion < 1040013) {
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ);
|
||||
}
|
||||
if (oldVersion < 1050003) {
|
||||
// Migrates feed list filter data
|
||||
|
||||
db.beginTransaction();
|
||||
|
||||
// Change to intermediate values to avoid overwriting in the following find/replace
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'unplayed', 'noplay')");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'not_queued', 'noqueue')");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'not_downloaded', 'nodl')");
|
||||
|
||||
// Replace played, queued, and downloaded with their opposites
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'played', 'unplayed')");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'queued', 'not_queued')");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'downloaded', 'not_downloaded')");
|
||||
|
||||
// Now replace intermediates for unplayed, not queued, etc. with their opposites
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'noplay', 'played')");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'noqueue', 'queued')");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'nodl', 'downloaded')");
|
||||
|
||||
// Paused doesn't have an opposite, so unplayed is the next best option
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + PodDBAdapter.KEY_HIDE + " = replace(" + PodDBAdapter.KEY_HIDE + ", 'paused', 'unplayed')");
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
|
||||
// and now get ready for autodownload filters
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_INCLUDE_FILTER + " TEXT DEFAULT ''");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_EXCLUDE_FILTER + " TEXT DEFAULT ''");
|
||||
|
||||
// and now auto refresh
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1");
|
||||
}
|
||||
if (oldVersion < 1050004) {
|
||||
// prevent old timestamps to be misinterpreted as ETags
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL");
|
||||
}
|
||||
if (oldVersion < 1060200) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT");
|
||||
}
|
||||
if (oldVersion < 1060596) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_IMAGE_URL + " TEXT");
|
||||
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + " SET " + PodDBAdapter.KEY_IMAGE_URL + " = ("
|
||||
+ " SELECT " + PodDBAdapter.KEY_DOWNLOAD_URL
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_IMAGES
|
||||
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + "." + PodDBAdapter.KEY_ID
|
||||
+ " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + PodDBAdapter.KEY_IMAGE + ")");
|
||||
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS + " SET " + PodDBAdapter.KEY_IMAGE_URL + " = ("
|
||||
+ " SELECT " + PodDBAdapter.KEY_DOWNLOAD_URL
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_IMAGES
|
||||
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES + "." + PodDBAdapter.KEY_ID
|
||||
+ " = " + PodDBAdapter.TABLE_NAME_FEEDS + "." + PodDBAdapter.KEY_IMAGE + ")");
|
||||
|
||||
db.execSQL("DROP TABLE " + PodDBAdapter.TABLE_NAME_FEED_IMAGES);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,6 @@ import de.danoeh.antennapod.core.event.QueueEvent;
|
|||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedEvent;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
|
@ -166,17 +165,6 @@ public class DBWriter {
|
|||
editor.commit();
|
||||
}
|
||||
|
||||
// delete image file
|
||||
if (feed.getImage() != null) {
|
||||
if (feed.getImage().isDownloaded()
|
||||
&& feed.getImage().getFile_url() != null) {
|
||||
File imageFile = new File(feed.getImage()
|
||||
.getFile_url());
|
||||
imageFile.delete();
|
||||
} else if (requester.isDownloadingFile(feed.getImage())) {
|
||||
requester.cancelDownload(context, feed.getImage());
|
||||
}
|
||||
}
|
||||
// delete stored media files and mark them as read
|
||||
List<FeedItem> queue = DBReader.getQueue();
|
||||
List<FeedItem> removed = new ArrayList<>();
|
||||
|
@ -200,16 +188,6 @@ public class DBWriter {
|
|||
&& requester.isDownloadingFile(item.getMedia())) {
|
||||
requester.cancelDownload(context, item.getMedia());
|
||||
}
|
||||
|
||||
if (item.hasItemImage()) {
|
||||
FeedImage image = item.getImage();
|
||||
if (image.isDownloaded() && image.getFile_url() != null) {
|
||||
File imgFile = new File(image.getFile_url());
|
||||
imgFile.delete();
|
||||
} else if (requester.isDownloadingFile(image)) {
|
||||
requester.cancelDownload(context, item.getImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
|
@ -785,21 +763,6 @@ public class DBWriter {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a FeedImage object in the database. This method will save all attributes of the FeedImage object. The
|
||||
* contents of FeedComponent-attributes (e.g. the FeedImages's 'feed'-attribute) will not be saved.
|
||||
*
|
||||
* @param image The FeedImage object.
|
||||
*/
|
||||
public static Future<?> setFeedImage(final FeedImage image) {
|
||||
return dbExec.submit(() -> {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
adapter.setImage(image);
|
||||
adapter.close();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates download URL of a feed
|
||||
*/
|
||||
|
|
|
@ -14,20 +14,10 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||
import android.media.MediaMetadataRetriever;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.event.ProgressEvent;
|
||||
import de.danoeh.antennapod.core.feed.Chapter;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedComponent;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.feed.FeedPreferences;
|
||||
|
@ -38,6 +28,13 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
|
|||
import de.greenrobot.event.EventBus;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO Remove media column from feeditem table
|
||||
|
||||
/**
|
||||
|
@ -74,8 +71,9 @@ public class PodDBAdapter {
|
|||
public static final String KEY_SIZE = "filesize";
|
||||
public static final String KEY_MIME_TYPE = "mime_type";
|
||||
public static final String KEY_IMAGE = "image";
|
||||
public static final String KEY_IMAGE_URL = "image_url";
|
||||
public static final String KEY_FEED = "feed";
|
||||
private static final String KEY_MEDIA = "media";
|
||||
public static final String KEY_MEDIA = "media";
|
||||
public static final String KEY_DOWNLOADED = "downloaded";
|
||||
public static final String KEY_LASTUPDATE = "last_update";
|
||||
public static final String KEY_FEEDFILE = "feedfile";
|
||||
|
@ -114,14 +112,14 @@ public class PodDBAdapter {
|
|||
public static final String KEY_EXCLUDE_FILTER = "exclude_filter";
|
||||
|
||||
// Table names
|
||||
private static final String TABLE_NAME_FEEDS = "Feeds";
|
||||
private static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
|
||||
private static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
|
||||
private static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
|
||||
private static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
|
||||
private static final String TABLE_NAME_QUEUE = "Queue";
|
||||
private static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
|
||||
private static final String TABLE_NAME_FAVORITES = "Favorites";
|
||||
static final String TABLE_NAME_FEEDS = "Feeds";
|
||||
static final String TABLE_NAME_FEED_ITEMS = "FeedItems";
|
||||
static final String TABLE_NAME_FEED_IMAGES = "FeedImages";
|
||||
static final String TABLE_NAME_FEED_MEDIA = "FeedMedia";
|
||||
static final String TABLE_NAME_DOWNLOAD_LOG = "DownloadLog";
|
||||
static final String TABLE_NAME_QUEUE = "Queue";
|
||||
static final String TABLE_NAME_SIMPLECHAPTERS = "SimpleChapters";
|
||||
static final String TABLE_NAME_FAVORITES = "Favorites";
|
||||
|
||||
// SQL Statements for creating new tables
|
||||
private static final String TABLE_PRIMARY_KEY = KEY_ID
|
||||
|
@ -133,7 +131,7 @@ public class PodDBAdapter {
|
|||
+ KEY_DOWNLOADED + " INTEGER," + KEY_LINK + " TEXT,"
|
||||
+ KEY_DESCRIPTION + " TEXT," + KEY_PAYMENT_LINK + " TEXT,"
|
||||
+ KEY_LASTUPDATE + " TEXT," + KEY_LANGUAGE + " TEXT," + KEY_AUTHOR
|
||||
+ " TEXT," + KEY_IMAGE + " INTEGER," + KEY_TYPE + " TEXT,"
|
||||
+ " TEXT," + KEY_IMAGE_URL + " TEXT," + KEY_TYPE + " TEXT,"
|
||||
+ KEY_FEED_IDENTIFIER + " TEXT," + KEY_AUTO_DOWNLOAD + " INTEGER DEFAULT 1,"
|
||||
+ KEY_FLATTR_STATUS + " INTEGER,"
|
||||
+ KEY_USERNAME + " TEXT,"
|
||||
|
@ -155,14 +153,9 @@ public class PodDBAdapter {
|
|||
+ KEY_MEDIA + " INTEGER," + KEY_FEED + " INTEGER,"
|
||||
+ KEY_HAS_CHAPTERS + " INTEGER," + KEY_ITEM_IDENTIFIER + " TEXT,"
|
||||
+ KEY_FLATTR_STATUS + " INTEGER,"
|
||||
+ KEY_IMAGE + " INTEGER,"
|
||||
+ KEY_IMAGE_URL + " TEXT,"
|
||||
+ KEY_AUTO_DOWNLOAD + " INTEGER)";
|
||||
|
||||
private static final String CREATE_TABLE_FEED_IMAGES = "CREATE TABLE "
|
||||
+ TABLE_NAME_FEED_IMAGES + " (" + TABLE_PRIMARY_KEY + KEY_TITLE
|
||||
+ " TEXT," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL + " TEXT,"
|
||||
+ KEY_DOWNLOADED + " INTEGER)";
|
||||
|
||||
private static final String CREATE_TABLE_FEED_MEDIA = "CREATE TABLE "
|
||||
+ TABLE_NAME_FEED_MEDIA + " (" + TABLE_PRIMARY_KEY + KEY_DURATION
|
||||
+ " INTEGER," + KEY_FILE_URL + " TEXT," + KEY_DOWNLOAD_URL
|
||||
|
@ -191,36 +184,31 @@ public class PodDBAdapter {
|
|||
+ KEY_LINK + " TEXT," + KEY_CHAPTER_TYPE + " INTEGER)";
|
||||
|
||||
// SQL Statements for creating indexes
|
||||
private static final String CREATE_INDEX_FEEDITEMS_FEED = "CREATE INDEX "
|
||||
static final String CREATE_INDEX_FEEDITEMS_FEED = "CREATE INDEX "
|
||||
+ TABLE_NAME_FEED_ITEMS + "_" + KEY_FEED + " ON " + TABLE_NAME_FEED_ITEMS + " ("
|
||||
+ KEY_FEED + ")";
|
||||
|
||||
private static final String CREATE_INDEX_FEEDITEMS_IMAGE = "CREATE INDEX "
|
||||
+ TABLE_NAME_FEED_ITEMS + "_" + KEY_IMAGE + " ON " + TABLE_NAME_FEED_ITEMS + " ("
|
||||
+ KEY_IMAGE + ")";
|
||||
|
||||
private static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS "
|
||||
static final String CREATE_INDEX_FEEDITEMS_PUBDATE = "CREATE INDEX IF NOT EXISTS "
|
||||
+ TABLE_NAME_FEED_ITEMS + "_" + KEY_PUBDATE + " ON " + TABLE_NAME_FEED_ITEMS + " ("
|
||||
+ KEY_PUBDATE + ")";
|
||||
|
||||
private static final String CREATE_INDEX_FEEDITEMS_READ = "CREATE INDEX IF NOT EXISTS "
|
||||
static final String CREATE_INDEX_FEEDITEMS_READ = "CREATE INDEX IF NOT EXISTS "
|
||||
+ TABLE_NAME_FEED_ITEMS + "_" + KEY_READ + " ON " + TABLE_NAME_FEED_ITEMS + " ("
|
||||
+ KEY_READ + ")";
|
||||
|
||||
|
||||
private static final String CREATE_INDEX_QUEUE_FEEDITEM = "CREATE INDEX "
|
||||
static final String CREATE_INDEX_QUEUE_FEEDITEM = "CREATE INDEX "
|
||||
+ TABLE_NAME_QUEUE + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_QUEUE + " ("
|
||||
+ KEY_FEEDITEM + ")";
|
||||
|
||||
private static final String CREATE_INDEX_FEEDMEDIA_FEEDITEM = "CREATE INDEX "
|
||||
static final String CREATE_INDEX_FEEDMEDIA_FEEDITEM = "CREATE INDEX "
|
||||
+ TABLE_NAME_FEED_MEDIA + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_FEED_MEDIA + " ("
|
||||
+ KEY_FEEDITEM + ")";
|
||||
|
||||
private static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX "
|
||||
static final String CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM = "CREATE INDEX "
|
||||
+ TABLE_NAME_SIMPLECHAPTERS + "_" + KEY_FEEDITEM + " ON " + TABLE_NAME_SIMPLECHAPTERS + " ("
|
||||
+ KEY_FEEDITEM + ")";
|
||||
|
||||
private static final String CREATE_TABLE_FAVORITES = "CREATE TABLE "
|
||||
static final String CREATE_TABLE_FAVORITES = "CREATE TABLE "
|
||||
+ TABLE_NAME_FAVORITES + "(" + KEY_ID + " INTEGER PRIMARY KEY,"
|
||||
+ KEY_FEEDITEM + " INTEGER," + KEY_FEED + " INTEGER)";
|
||||
|
||||
|
@ -240,7 +228,7 @@ public class PodDBAdapter {
|
|||
TABLE_NAME_FEEDS + "." + KEY_LASTUPDATE,
|
||||
TABLE_NAME_FEEDS + "." + KEY_LANGUAGE,
|
||||
TABLE_NAME_FEEDS + "." + KEY_AUTHOR,
|
||||
TABLE_NAME_FEEDS + "." + KEY_IMAGE,
|
||||
TABLE_NAME_FEEDS + "." + KEY_IMAGE_URL,
|
||||
TABLE_NAME_FEEDS + "." + KEY_TYPE,
|
||||
TABLE_NAME_FEEDS + "." + KEY_FEED_IDENTIFIER,
|
||||
TABLE_NAME_FEEDS + "." + KEY_AUTO_DOWNLOAD,
|
||||
|
@ -273,7 +261,7 @@ public class PodDBAdapter {
|
|||
TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS,
|
||||
TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER,
|
||||
TABLE_NAME_FEED_ITEMS + "." + KEY_FLATTR_STATUS,
|
||||
TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE,
|
||||
TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL,
|
||||
TABLE_NAME_FEED_ITEMS + "." + KEY_AUTO_DOWNLOAD
|
||||
};
|
||||
|
||||
|
@ -283,7 +271,6 @@ public class PodDBAdapter {
|
|||
private static final String[] ALL_TABLES = {
|
||||
TABLE_NAME_FEEDS,
|
||||
TABLE_NAME_FEED_ITEMS,
|
||||
TABLE_NAME_FEED_IMAGES,
|
||||
TABLE_NAME_FEED_MEDIA,
|
||||
TABLE_NAME_DOWNLOAD_LOG,
|
||||
TABLE_NAME_QUEUE,
|
||||
|
@ -388,12 +375,7 @@ public class PodDBAdapter {
|
|||
values.put(KEY_PAYMENT_LINK, feed.getPaymentLink());
|
||||
values.put(KEY_AUTHOR, feed.getAuthor());
|
||||
values.put(KEY_LANGUAGE, feed.getLanguage());
|
||||
if (feed.getImage() != null) {
|
||||
if (feed.getImage().getId() == 0) {
|
||||
setImage(feed.getImage());
|
||||
}
|
||||
values.put(KEY_IMAGE, feed.getImage().getId());
|
||||
}
|
||||
values.put(KEY_IMAGE_URL, feed.getImageUrl());
|
||||
|
||||
values.put(KEY_FILE_URL, feed.getFile_url());
|
||||
values.put(KEY_DOWNLOAD_URL, feed.getDownload_url());
|
||||
|
@ -450,54 +432,7 @@ public class PodDBAdapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates an image entry
|
||||
*
|
||||
* @return the id of the entry
|
||||
*/
|
||||
public long setImage(FeedImage image) {
|
||||
boolean startedTransaction = false;
|
||||
|
||||
try {
|
||||
if (!db.inTransaction()) {
|
||||
db.beginTransactionNonExclusive();
|
||||
startedTransaction = true;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(KEY_TITLE, image.getTitle());
|
||||
values.put(KEY_DOWNLOAD_URL, image.getDownload_url());
|
||||
values.put(KEY_DOWNLOADED, image.isDownloaded());
|
||||
values.put(KEY_FILE_URL, image.getFile_url());
|
||||
if (image.getId() == 0) {
|
||||
image.setId(db.insert(TABLE_NAME_FEED_IMAGES, null, values));
|
||||
} else {
|
||||
db.update(TABLE_NAME_FEED_IMAGES, values, KEY_ID + "=?",
|
||||
new String[]{String.valueOf(image.getId())});
|
||||
}
|
||||
|
||||
final FeedComponent owner = image.getOwner();
|
||||
if (owner != null && owner.getId() != 0) {
|
||||
values.clear();
|
||||
values.put(KEY_IMAGE, image.getId());
|
||||
if (owner instanceof Feed) {
|
||||
db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(image.getOwner().getId())});
|
||||
}
|
||||
}
|
||||
if (startedTransaction) {
|
||||
db.setTransactionSuccessful();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.e(TAG, Log.getStackTraceString(e));
|
||||
} finally {
|
||||
if (startedTransaction) {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
return image.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts or updates an image entry
|
||||
* Inserts or updates a media entry
|
||||
*
|
||||
* @return the id of the entry
|
||||
*/
|
||||
|
@ -759,12 +694,7 @@ public class PodDBAdapter {
|
|||
values.put(KEY_ITEM_IDENTIFIER, item.getItemIdentifier());
|
||||
values.put(KEY_FLATTR_STATUS, item.getFlattrStatus().toLong());
|
||||
values.put(KEY_AUTO_DOWNLOAD, item.getAutoDownload());
|
||||
if (item.hasItemImage()) {
|
||||
if (item.getImage().getId() == 0) {
|
||||
setImage(item.getImage());
|
||||
}
|
||||
values.put(KEY_IMAGE, item.getImage().getId());
|
||||
}
|
||||
values.put(KEY_IMAGE_URL, item.getImageUrl());
|
||||
|
||||
if (item.getId() == 0) {
|
||||
item.setId(db.insert(TABLE_NAME_FEED_ITEMS, null, values));
|
||||
|
@ -993,11 +923,6 @@ public class PodDBAdapter {
|
|||
new String[]{String.valueOf(item.getId())});
|
||||
}
|
||||
|
||||
private void removeFeedImage(FeedImage image) {
|
||||
db.delete(TABLE_NAME_FEED_IMAGES, KEY_ID + "=?",
|
||||
new String[]{String.valueOf(image.getId())});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a FeedItem and its FeedMedia entry.
|
||||
*/
|
||||
|
@ -1008,9 +933,6 @@ public class PodDBAdapter {
|
|||
if (item.hasChapters() || item.getChapters() != null) {
|
||||
removeChaptersOfItem(item);
|
||||
}
|
||||
if (item.hasItemImage()) {
|
||||
removeFeedImage(item.getImage());
|
||||
}
|
||||
db.delete(TABLE_NAME_FEED_ITEMS, KEY_ID + "=?",
|
||||
new String[]{String.valueOf(item.getId())});
|
||||
}
|
||||
|
@ -1021,9 +943,6 @@ public class PodDBAdapter {
|
|||
public void removeFeed(Feed feed) {
|
||||
try {
|
||||
db.beginTransactionNonExclusive();
|
||||
if (feed.getImage() != null) {
|
||||
removeFeedImage(feed.getImage());
|
||||
}
|
||||
if (feed.getItems() != null) {
|
||||
for (FeedItem item : feed.getItems()) {
|
||||
removeFeedItem(item);
|
||||
|
@ -1363,17 +1282,12 @@ public class PodDBAdapter {
|
|||
public Cursor getImageAuthenticationCursor(final String imageUrl) {
|
||||
String downloadUrl = DatabaseUtils.sqlEscapeString(imageUrl);
|
||||
final String query = ""
|
||||
+ "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_IMAGES
|
||||
+ "SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEED_ITEMS
|
||||
+ " INNER JOIN " + TABLE_NAME_FEEDS
|
||||
+ " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEEDS + "." + KEY_IMAGE
|
||||
+ " WHERE " + TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "=" + downloadUrl
|
||||
+ " UNION SELECT " + KEY_USERNAME + "," + KEY_PASSWORD
|
||||
+ " FROM " + TABLE_NAME_FEED_IMAGES
|
||||
+ " INNER JOIN " + TABLE_NAME_FEED_ITEMS
|
||||
+ " ON " + TABLE_NAME_FEED_IMAGES + "." + KEY_ID + "=" + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE
|
||||
+ " INNER JOIN " + TABLE_NAME_FEEDS
|
||||
+ " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
|
||||
+ " WHERE " + TABLE_NAME_FEED_IMAGES + "." + KEY_DOWNLOAD_URL + "=" + downloadUrl;
|
||||
+ " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + " = " + TABLE_NAME_FEEDS + "." + KEY_ID
|
||||
+ " WHERE " + TABLE_NAME_FEED_ITEMS + "." + KEY_IMAGE_URL + "=" + downloadUrl
|
||||
+ " UNION SELECT " + KEY_USERNAME + "," + KEY_PASSWORD + " FROM " + TABLE_NAME_FEEDS
|
||||
+ " WHERE " + TABLE_NAME_FEEDS + "." + KEY_IMAGE_URL + "=" + downloadUrl;
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
|
@ -1672,7 +1586,7 @@ public class PodDBAdapter {
|
|||
*/
|
||||
private static class PodDBHelper extends SQLiteOpenHelper {
|
||||
|
||||
private static final int VERSION = 1060200;
|
||||
private static final int VERSION = 1060596;
|
||||
|
||||
private final Context context;
|
||||
|
||||
|
@ -1693,7 +1607,6 @@ public class PodDBAdapter {
|
|||
public void onCreate(final SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_FEEDS);
|
||||
db.execSQL(CREATE_TABLE_FEED_ITEMS);
|
||||
db.execSQL(CREATE_TABLE_FEED_IMAGES);
|
||||
db.execSQL(CREATE_TABLE_FEED_MEDIA);
|
||||
db.execSQL(CREATE_TABLE_DOWNLOAD_LOG);
|
||||
db.execSQL(CREATE_TABLE_QUEUE);
|
||||
|
@ -1701,7 +1614,6 @@ public class PodDBAdapter {
|
|||
db.execSQL(CREATE_TABLE_FAVORITES);
|
||||
|
||||
db.execSQL(CREATE_INDEX_FEEDITEMS_FEED);
|
||||
db.execSQL(CREATE_INDEX_FEEDITEMS_IMAGE);
|
||||
db.execSQL(CREATE_INDEX_FEEDITEMS_PUBDATE);
|
||||
db.execSQL(CREATE_INDEX_FEEDITEMS_READ);
|
||||
db.execSQL(CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
||||
|
@ -1716,263 +1628,7 @@ public class PodDBAdapter {
|
|||
EventBus.getDefault().post(ProgressEvent.start(context.getString(R.string.progress_upgrading_database)));
|
||||
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
|
||||
+ newVersion + ".");
|
||||
if (oldVersion <= 1) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ KEY_TYPE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 2) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + KEY_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 3) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_ITEM_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 4) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS + " ADD COLUMN "
|
||||
+ KEY_FEED_IDENTIFIER + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 5) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + KEY_REASON_DETAILED + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_DOWNLOAD_LOG
|
||||
+ " ADD COLUMN " + KEY_DOWNLOADSTATUS_TITLE + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 6) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS
|
||||
+ " ADD COLUMN " + KEY_CHAPTER_TYPE + " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 7) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_PLAYBACK_COMPLETION_DATE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 8) {
|
||||
final int KEY_ID_POSITION = 0;
|
||||
final int KEY_MEDIA_POSITION = 1;
|
||||
|
||||
// Add feeditem column to feedmedia table
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_FEEDITEM
|
||||
+ " INTEGER");
|
||||
Cursor feeditemCursor = db.query(PodDBAdapter.TABLE_NAME_FEED_ITEMS,
|
||||
new String[]{KEY_ID, KEY_MEDIA}, "? > 0",
|
||||
new String[]{KEY_MEDIA}, null, null, null);
|
||||
if (feeditemCursor.moveToFirst()) {
|
||||
db.beginTransaction();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
do {
|
||||
long mediaId = feeditemCursor.getLong(KEY_MEDIA_POSITION);
|
||||
contentValues.put(KEY_FEEDITEM, feeditemCursor.getLong(KEY_ID_POSITION));
|
||||
db.update(PodDBAdapter.TABLE_NAME_FEED_MEDIA, contentValues, KEY_ID + "=?", new String[]{String.valueOf(mediaId)});
|
||||
contentValues.clear();
|
||||
} while (feeditemCursor.moveToNext());
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
feeditemCursor.close();
|
||||
}
|
||||
if (oldVersion <= 9) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_AUTO_DOWNLOAD
|
||||
+ " INTEGER DEFAULT 1");
|
||||
}
|
||||
if (oldVersion <= 10) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_FLATTR_STATUS
|
||||
+ " INTEGER");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_PLAYED_DURATION
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 11) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_USERNAME
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_PASSWORD
|
||||
+ " TEXT");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_IMAGE
|
||||
+ " INTEGER");
|
||||
}
|
||||
if (oldVersion <= 12) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_IS_PAGED + " INTEGER DEFAULT 0");
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_NEXT_PAGE_LINK + " TEXT");
|
||||
}
|
||||
if (oldVersion <= 13) {
|
||||
// remove duplicate rows in "Chapters" table that were created because of a bug.
|
||||
db.execSQL(String.format("DELETE FROM %s WHERE %s NOT IN " +
|
||||
"(SELECT MIN(%s) as %s FROM %s GROUP BY %s,%s,%s,%s,%s)",
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
KEY_ID,
|
||||
KEY_ID,
|
||||
KEY_ID,
|
||||
PodDBAdapter.TABLE_NAME_SIMPLECHAPTERS,
|
||||
KEY_TITLE,
|
||||
KEY_START,
|
||||
KEY_FEEDITEM,
|
||||
KEY_LINK,
|
||||
KEY_CHAPTER_TYPE));
|
||||
}
|
||||
if (oldVersion <= 14) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " ADD COLUMN " + KEY_AUTO_DOWNLOAD + " INTEGER");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + KEY_AUTO_DOWNLOAD + " = "
|
||||
+ "(SELECT " + KEY_AUTO_DOWNLOAD
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " WHERE " + PodDBAdapter.TABLE_NAME_FEEDS + "." + KEY_ID
|
||||
+ " = " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + ")");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_HIDE + " TEXT");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + KEY_LAST_UPDATE_FAILED + " INTEGER DEFAULT 0");
|
||||
|
||||
// create indexes
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_FEED);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_IMAGE);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDMEDIA_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_QUEUE_FEEDITEM);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_SIMPLECHAPTERS_FEEDITEM);
|
||||
}
|
||||
if (oldVersion <= 15) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + KEY_HAS_EMBEDDED_PICTURE + " INTEGER DEFAULT -1");
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + KEY_DOWNLOADED + "=0");
|
||||
Cursor c = db.rawQuery("SELECT " + KEY_FILE_URL
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " WHERE " + KEY_DOWNLOADED + "=1 "
|
||||
+ " AND " + KEY_HAS_EMBEDDED_PICTURE + "=-1", null);
|
||||
if (c.moveToFirst()) {
|
||||
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
|
||||
do {
|
||||
String fileUrl = c.getString(0);
|
||||
try {
|
||||
mmr.setDataSource(fileUrl);
|
||||
byte[] image = mmr.getEmbeddedPicture();
|
||||
if (image != null) {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=1"
|
||||
+ " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'");
|
||||
} else {
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " SET " + KEY_HAS_EMBEDDED_PICTURE + "=0"
|
||||
+ " WHERE " + KEY_FILE_URL + "='" + fileUrl + "'");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} while (c.moveToNext());
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
if (oldVersion <= 16) {
|
||||
String selectNew = "SELECT " + PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID
|
||||
+ " FROM " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " INNER JOIN " + PodDBAdapter.TABLE_NAME_FEED_MEDIA + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_FEEDITEM
|
||||
+ " LEFT OUTER JOIN " + PodDBAdapter.TABLE_NAME_QUEUE + " ON "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "="
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_FEEDITEM
|
||||
+ " WHERE "
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_ITEMS + "." + KEY_READ + " = 0 AND " // unplayed
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + " = 0 AND " // undownloaded
|
||||
+ PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + KEY_POSITION + " = 0 AND " // not partially played
|
||||
+ PodDBAdapter.TABLE_NAME_QUEUE + "." + KEY_ID + " IS NULL"; // not in queue
|
||||
String sql = "UPDATE " + PodDBAdapter.TABLE_NAME_FEED_ITEMS
|
||||
+ " SET " + KEY_READ + "=" + FeedItem.NEW
|
||||
+ " WHERE " + KEY_ID + " IN (" + selectNew + ")";
|
||||
Log.d("Migration", "SQL: " + sql);
|
||||
db.execSQL(sql);
|
||||
}
|
||||
if (oldVersion <= 17) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_AUTO_DELETE_ACTION + " INTEGER DEFAULT 0");
|
||||
}
|
||||
if (oldVersion < 1030005) {
|
||||
db.execSQL("UPDATE FeedItems SET auto_download=0 WHERE " +
|
||||
"(read=1 OR id IN (SELECT feeditem FROM FeedMedia WHERE position>0 OR downloaded=1)) " +
|
||||
"AND id NOT IN (SELECT feeditem FROM Queue)");
|
||||
}
|
||||
if (oldVersion < 1040001) {
|
||||
db.execSQL(CREATE_TABLE_FAVORITES);
|
||||
}
|
||||
if (oldVersion < 1040002) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEED_MEDIA
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_LAST_PLAYED_TIME + " INTEGER DEFAULT 0");
|
||||
}
|
||||
if (oldVersion < 1040013) {
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_PUBDATE);
|
||||
db.execSQL(PodDBAdapter.CREATE_INDEX_FEEDITEMS_READ);
|
||||
}
|
||||
if (oldVersion < 1050003) {
|
||||
// Migrates feed list filter data
|
||||
|
||||
db.beginTransaction();
|
||||
|
||||
// Change to intermediate values to avoid overwriting in the following find/replace
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'unplayed', 'noplay')");
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'not_queued', 'noqueue')");
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'not_downloaded', 'nodl')");
|
||||
|
||||
// Replace played, queued, and downloaded with their opposites
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'played', 'unplayed')");
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'queued', 'not_queued')");
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'downloaded', 'not_downloaded')");
|
||||
|
||||
// Now replace intermediates for unplayed, not queued, etc. with their opposites
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'noplay', 'played')");
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'noqueue', 'queued')");
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'nodl', 'downloaded')");
|
||||
|
||||
// Paused doesn't have an opposite, so unplayed is the next best option
|
||||
db.execSQL("UPDATE " + TABLE_NAME_FEEDS + "\n" +
|
||||
"SET " + KEY_HIDE + " = replace(" + KEY_HIDE + ", 'paused', 'unplayed')");
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
|
||||
// and now get ready for autodownload filters
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_INCLUDE_FILTER + " TEXT DEFAULT ''");
|
||||
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_EXCLUDE_FILTER + " TEXT DEFAULT ''");
|
||||
|
||||
// and now auto refresh
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_KEEP_UPDATED + " INTEGER DEFAULT 1");
|
||||
}
|
||||
if (oldVersion < 1050004) {
|
||||
// prevent old timestamps to be misinterpreted as ETags
|
||||
db.execSQL("UPDATE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " SET " + PodDBAdapter.KEY_LASTUPDATE + "=NULL");
|
||||
}
|
||||
if (oldVersion < 1060200) {
|
||||
db.execSQL("ALTER TABLE " + PodDBAdapter.TABLE_NAME_FEEDS
|
||||
+ " ADD COLUMN " + PodDBAdapter.KEY_CUSTOM_TITLE + " TEXT");
|
||||
}
|
||||
|
||||
DBUpgrader.upgrade(db, oldVersion, newVersion);
|
||||
EventBus.getDefault().post(ProgressEvent.end());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.xml.sax.Attributes;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.syndication.handler.HandlerState;
|
||||
|
||||
public class NSITunes extends Namespace {
|
||||
|
@ -16,7 +15,6 @@ public class NSITunes extends Namespace {
|
|||
public static final String NSURI = "http://www.itunes.com/dtds/podcast-1.0.dtd";
|
||||
|
||||
private static final String IMAGE = "image";
|
||||
private static final String IMAGE_TITLE = "image";
|
||||
private static final String IMAGE_HREF = "href";
|
||||
|
||||
private static final String AUTHOR = "author";
|
||||
|
@ -29,21 +27,15 @@ public class NSITunes extends Namespace {
|
|||
public SyndElement handleElementStart(String localName, HandlerState state,
|
||||
Attributes attributes) {
|
||||
if (IMAGE.equals(localName)) {
|
||||
FeedImage image = new FeedImage();
|
||||
image.setTitle(IMAGE_TITLE);
|
||||
image.setDownload_url(attributes.getValue(IMAGE_HREF));
|
||||
String url = attributes.getValue(IMAGE_HREF);
|
||||
|
||||
if (state.getCurrentItem() != null) {
|
||||
// this is an items image
|
||||
image.setTitle(state.getCurrentItem().getTitle() + IMAGE_TITLE);
|
||||
image.setOwner(state.getCurrentItem());
|
||||
state.getCurrentItem().setImage(image);
|
||||
state.getCurrentItem().setImageUrl(url);
|
||||
} else {
|
||||
// this is the feed image
|
||||
// prefer to all other images
|
||||
if (!TextUtils.isEmpty(image.getDownload_url())) {
|
||||
image.setOwner(state.getFeed());
|
||||
state.getFeed().setImage(image);
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
state.getFeed().setImageUrl(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.xml.sax.Attributes;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.syndication.handler.HandlerState;
|
||||
import de.danoeh.antennapod.core.syndication.namespace.atom.AtomText;
|
||||
|
@ -94,25 +93,16 @@ public class NSMedia extends Namespace {
|
|||
}
|
||||
state.getCurrentItem().setMedia(media);
|
||||
} else if (state.getCurrentItem() != null && url != null && validTypeImage) {
|
||||
FeedImage image = new FeedImage();
|
||||
image.setDownload_url(url);
|
||||
image.setOwner(state.getCurrentItem());
|
||||
|
||||
state.getCurrentItem().setImage(image);
|
||||
state.getCurrentItem().setImageUrl(url);
|
||||
}
|
||||
} else if (IMAGE.equals(localName)) {
|
||||
String url = attributes.getValue(IMAGE_URL);
|
||||
if (url != null) {
|
||||
FeedImage image = new FeedImage();
|
||||
image.setDownload_url(url);
|
||||
|
||||
if (state.getCurrentItem() != null) {
|
||||
image.setOwner(state.getCurrentItem());
|
||||
state.getCurrentItem().setImage(image);
|
||||
state.getCurrentItem().setImageUrl(url);
|
||||
} else {
|
||||
if (state.getFeed().getImage() == null) {
|
||||
image.setOwner(state.getFeed());
|
||||
state.getFeed().setImage(image);
|
||||
if (state.getFeed().getImageUrl() == null) {
|
||||
state.getFeed().setImageUrl(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.util.Log;
|
|||
import org.xml.sax.Attributes;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.syndication.handler.HandlerState;
|
||||
|
@ -77,17 +76,6 @@ public class NSRSS20 extends Namespace {
|
|||
state.getCurrentItem().setMedia(media);
|
||||
}
|
||||
|
||||
} else if (IMAGE.equals(localName)) {
|
||||
if (state.getTagstack().size() >= 1) {
|
||||
String parent = state.getTagstack().peek().getName();
|
||||
if (CHANNEL.equals(parent)) {
|
||||
Feed feed = state.getFeed();
|
||||
if(feed != null && feed.getImage() == null) {
|
||||
feed.setImage(new FeedImage());
|
||||
feed.getImage().setOwner(state.getFeed());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new SyndElement(localName, this);
|
||||
}
|
||||
|
@ -134,11 +122,6 @@ public class NSRSS20 extends Namespace {
|
|||
state.getCurrentItem().setTitle(title);
|
||||
} else if (CHANNEL.equals(second) && state.getFeed() != null) {
|
||||
state.getFeed().setTitle(title);
|
||||
} else if (IMAGE.equals(second) && CHANNEL.equals(third)) {
|
||||
if(state.getFeed() != null && state.getFeed().getImage() != null &&
|
||||
state.getFeed().getImage().getTitle() == null) {
|
||||
state.getFeed().getImage().setTitle(title);
|
||||
}
|
||||
}
|
||||
} else if (LINK.equals(top)) {
|
||||
if (CHANNEL.equals(second) && state.getFeed() != null) {
|
||||
|
@ -150,9 +133,8 @@ public class NSRSS20 extends Namespace {
|
|||
state.getCurrentItem().setPubDate(DateUtils.parse(content));
|
||||
} else if (URL.equals(top) && IMAGE.equals(second) && CHANNEL.equals(third)) {
|
||||
// prefer itunes:image
|
||||
if(state.getFeed() != null && state.getFeed().getImage() != null &&
|
||||
state.getFeed().getImage().getDownload_url() == null) {
|
||||
state.getFeed().getImage().setDownload_url(content);
|
||||
if (state.getFeed() != null) {
|
||||
state.getFeed().setImageUrl(content);
|
||||
}
|
||||
} else if (DESCR.equals(localName)) {
|
||||
if (CHANNEL.equals(second) && state.getFeed() != null) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.util.Log;
|
|||
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.syndication.handler.HandlerState;
|
||||
|
@ -210,10 +209,10 @@ public class NSAtom extends Namespace {
|
|||
state.getCurrentItem().setPubDate(DateUtils.parse(content));
|
||||
} else if (PUBLISHED.equals(top) && ENTRY.equals(second) && state.getCurrentItem() != null) {
|
||||
state.getCurrentItem().setPubDate(DateUtils.parse(content));
|
||||
} else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImage() == null) {
|
||||
state.getFeed().setImage(new FeedImage(state.getFeed(), content, null));
|
||||
} else if (IMAGE_LOGO.equals(top) && state.getFeed() != null && state.getFeed().getImageUrl() == null) {
|
||||
state.getFeed().setImageUrl(content);
|
||||
} else if (IMAGE_ICON.equals(top) && state.getFeed() != null) {
|
||||
state.getFeed().setImage(new FeedImage(state.getFeed(), content, null));
|
||||
state.getFeed().setImageUrl(content);
|
||||
} else if (AUTHOR_NAME.equals(top) && AUTHOR.equals(second) &&
|
||||
state.getFeed() != null && state.getCurrentItem() == null) {
|
||||
String currentName = state.getFeed().getAuthor();
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package de.danoeh.antennapod.core.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.AttrRes;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.util.Log;
|
||||
|
||||
import android.util.TypedValue;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
|
||||
|
@ -12,6 +17,8 @@ public class ThemeUtils {
|
|||
int theme = UserPreferences.getTheme();
|
||||
if (theme == R.style.Theme_AntennaPod_Dark) {
|
||||
return R.color.selection_background_color_dark;
|
||||
} else if (theme == R.style.Theme_AntennaPod_TrueBlack){
|
||||
return R.color.selection_background_color_trueblack;
|
||||
} else if (theme == R.style.Theme_AntennaPod_Light) {
|
||||
return R.color.selection_background_color_light;
|
||||
} else {
|
||||
|
@ -20,4 +27,10 @@ public class ThemeUtils {
|
|||
return R.color.selection_background_color_light;
|
||||
}
|
||||
}
|
||||
|
||||
public static @ColorInt int getColorFromAttr(Context context, @AttrRes int attr) {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
context.getTheme().resolveAttribute(attr, typedValue, true);
|
||||
return typedValue.data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="#000000"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="@color/holo_blue_dark"/>
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -6,6 +6,19 @@
|
|||
<style name="Theme.AntennaPod.Dark" parent="Theme.Base.AntennaPod.Dark">
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
</style>
|
||||
<style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack">
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
<item name="android:navigationBarColor">@color/black</item>
|
||||
<item name="android:colorAccent">@color/white</item>
|
||||
<item name="android:colorPrimary">@color/black</item>
|
||||
<item name="android:colorPrimaryDark">@color/black</item>
|
||||
</style>
|
||||
<style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack.NoTitle">
|
||||
<item name="android:navigationBarColor">@color/black</item>
|
||||
<item name="android:colorAccent">@color/white</item>
|
||||
<item name="android:colorPrimary">@color/black</item>
|
||||
<item name="android:colorPrimaryDark">@color/black</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.AntennaPod.Button" parent="Widget.AppCompat.Button">
|
||||
<item name="textAllCaps">true</item>
|
||||
|
|
|
@ -137,10 +137,12 @@
|
|||
<string-array name="theme_options">
|
||||
<item>@string/pref_theme_title_light</item>
|
||||
<item>@string/pref_theme_title_dark</item>
|
||||
<item>@string/pref_theme_title_trueblack</item>
|
||||
</string-array>
|
||||
<string-array name="theme_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="nav_drawer_titles">
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<attr name="ic_cast_disconnect" format="reference"/>
|
||||
<attr name="ic_swap" format="reference"/>
|
||||
<attr name="master_switch_background" format="color"/>
|
||||
<attr name="currently_playing_background" format="color"/>
|
||||
|
||||
<!-- Used in itemdescription -->
|
||||
<attr name="non_transparent_background" format="reference"/>
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
<color name="image_readability_tint">#80000000</color>
|
||||
<color name="feed_image_bg">#50000000</color>
|
||||
|
||||
<color name="selection_background_color_trueblack">#286E8A</color>
|
||||
<color name="selection_background_color_dark">#286E8A</color>
|
||||
<color name="selection_background_color_light">#81CFEA</color>
|
||||
|
||||
|
@ -30,6 +31,7 @@
|
|||
|
||||
<color name="highlight_light">#DDDDDD</color>
|
||||
<color name="highlight_dark">#414141</color>
|
||||
<color name="highlight_trueblack">#000000</color>
|
||||
|
||||
<color name="antennapod_blue">#147BAF</color>
|
||||
|
||||
|
|
|
@ -395,6 +395,7 @@
|
|||
<string name="pref_episode_cache_title">Episode Cache</string>
|
||||
<string name="pref_theme_title_light">Light</string>
|
||||
<string name="pref_theme_title_dark">Dark</string>
|
||||
<string name="pref_theme_title_trueblack">True Black</string>
|
||||
<string name="pref_episode_cache_unlimited">Unlimited</string>
|
||||
<string name="pref_update_interval_hours_plural">hours</string>
|
||||
<string name="pref_update_interval_hours_singular">hour</string>
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item>
|
||||
<item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item>
|
||||
<item type="attr" name="master_switch_background">@color/master_switch_background_light</item>
|
||||
<item type="attr" name="currently_playing_background">@color/highlight_light</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
</style>
|
||||
|
||||
|
@ -136,9 +137,31 @@
|
|||
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item>
|
||||
<item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item>
|
||||
<item type="attr" name="master_switch_background">@color/master_switch_background_dark</item>
|
||||
<item type="attr" name="currently_playing_background">@color/highlight_dark</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.TrueBlack">
|
||||
<!-- Room for API dependent attributes -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.Base.AntennaPod.TrueBlack" parent="Theme.Base.AntennaPod.Dark">
|
||||
<item name="progressBarTheme">@style/ProgressBarTrueBlack</item>
|
||||
<item type="attr" name="non_transparent_background">@color/black</item>
|
||||
<item type="attr" name="overlay_background">@color/overlay_dark</item>
|
||||
<item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark</item>
|
||||
<item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item>
|
||||
<item type="attr" name="dragview_float_background">@color/black</item>
|
||||
<item type="attr" name="nav_drawer_background">@color/black</item>
|
||||
<item name="android:textColorPrimary">@color/white</item>
|
||||
<item name="android:color">@color/white</item>
|
||||
<item name="android:windowBackground">@color/black</item>
|
||||
<item name="android:actionBarStyle">@color/black</item>
|
||||
<item name="colorPrimary">@color/black</item>
|
||||
<item name="colorPrimaryDark">@color/black</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Theme.AntennaPod.Light.NoTitle" parent="Theme.Base.AntennaPod.Light.NoTitle">
|
||||
<!-- Room for API dependent attributes -->
|
||||
</style>
|
||||
|
@ -206,6 +229,7 @@
|
|||
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item>
|
||||
<item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_grey600_36dp</item>
|
||||
<item type="attr" name="master_switch_background">@color/master_switch_background_light</item>
|
||||
<item type="attr" name="currently_playing_background">@color/highlight_light</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
</style>
|
||||
|
||||
|
@ -276,9 +300,32 @@
|
|||
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item>
|
||||
<item type="attr" name="ic_cast_disconnect">@drawable/ic_cast_disconnect_white_36dp</item>
|
||||
<item type="attr" name="master_switch_background">@color/master_switch_background_dark</item>
|
||||
<item type="attr" name="currently_playing_background">@color/highlight_dark</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.TrueBlack.NoTitle">
|
||||
<!-- Room for API dependent attributes -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.Base.AntennaPod.TrueBlack.NoTitle" parent="Theme.Base.AntennaPod.Dark.NoTitle">
|
||||
<item name="progressBarTheme">@style/ProgressBarTrueBlack</item>
|
||||
<item type="attr" name="non_transparent_background">@color/black</item>
|
||||
<item type="attr" name="overlay_background">@color/black</item>
|
||||
<item type="attr" name="overlay_drawable">@drawable/overlay_drawable_dark</item>
|
||||
<item type="attr" name="dragview_background">@drawable/ic_drag_vertical_white_48dp</item>
|
||||
<item type="attr" name="dragview_float_background">@color/black</item>
|
||||
<item type="attr" name="nav_drawer_background">@color/black</item>
|
||||
<item type="attr" name="currently_playing_background">@color/highlight_trueblack</item>
|
||||
<item name="android:textColorPrimary">@color/white</item>
|
||||
<item name="android:color">@color/white</item>
|
||||
<item name="android:windowBackground">@color/black</item>
|
||||
<item name="android:actionBarStyle">@color/black</item>
|
||||
<item name="colorPrimary">@color/black</item>
|
||||
<item name="colorPrimaryDark">@color/black</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="Theme.AntennaPod.Dark.Splash" parent="Theme.AppCompat.NoActionBar">
|
||||
<item name="android:windowBackground">@drawable/bg_splash</item>
|
||||
</style>
|
||||
|
@ -366,4 +413,9 @@
|
|||
<item name="android:progressDrawable">@drawable/progress_bar_horizontal_dark</item>
|
||||
</style>
|
||||
|
||||
<style name="ProgressBarTrueBlack">
|
||||
<item name="android:indeterminateOnly">false</item>
|
||||
<item name="android:progressDrawable">@drawable/progress_bar_horizontal_trueblack</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -13,7 +13,6 @@ import java.util.Calendar;
|
|||
import java.util.List;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedImage;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
|
@ -97,9 +96,9 @@ public class CastUtils {
|
|||
if (subtitle != null) {
|
||||
metadata.putString(MediaMetadata.KEY_SUBTITLE, subtitle);
|
||||
}
|
||||
FeedImage image = feedItem.getImage();
|
||||
if (image != null && !TextUtils.isEmpty(image.getDownload_url())) {
|
||||
metadata.addImage(new WebImage(Uri.parse(image.getDownload_url())));
|
||||
|
||||
if (!TextUtils.isEmpty(feedItem.getImageUrl())) {
|
||||
metadata.addImage(new WebImage(Uri.parse(feedItem.getImageUrl())));
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(media.getItem().getPubDate());
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package android.text;
|
||||
|
||||
/**
|
||||
* A slim-down version of standard {@link android.text.TextUtils} to be used in unit tests.
|
||||
*/
|
||||
public class TextUtils {
|
||||
|
||||
/**
|
||||
* Returns true if a and b are equal, including if they are both null.
|
||||
* <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if
|
||||
* both the arguments were instances of String.</i></p>
|
||||
* @param a first CharSequence to check
|
||||
* @param b second CharSequence to check
|
||||
* @return true if a and b are equal
|
||||
*/
|
||||
public static boolean equals(CharSequence a, CharSequence b) {
|
||||
if (a == b) return true;
|
||||
int length;
|
||||
if (a != null && b != null && (length = a.length()) == b.length()) {
|
||||
if (a instanceof String && b instanceof String) {
|
||||
return a.equals(b);
|
||||
} else {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (a.charAt(i) != b.charAt(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
package android.util;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* A stub for {@link android.util.Log} to be used in unit tests.
|
||||
*
|
||||
* It outputs the log statements to standard error.
|
||||
*/
|
||||
public final class Log {
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.v.
|
||||
*/
|
||||
public static final int VERBOSE = 2;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.d.
|
||||
*/
|
||||
public static final int DEBUG = 3;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.i.
|
||||
*/
|
||||
public static final int INFO = 4;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.w.
|
||||
*/
|
||||
public static final int WARN = 5;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method; use Log.e.
|
||||
*/
|
||||
public static final int ERROR = 6;
|
||||
|
||||
/**
|
||||
* Priority constant for the println method.
|
||||
*/
|
||||
public static final int ASSERT = 7;
|
||||
|
||||
private Log() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #VERBOSE} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int v(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #VERBOSE} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int v(String tag, String msg, Throwable tr) {
|
||||
return printlns(LOG_ID_MAIN, VERBOSE, tag, msg, tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #DEBUG} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int d(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #DEBUG} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int d(String tag, String msg, Throwable tr) {
|
||||
return printlns(LOG_ID_MAIN, DEBUG, tag, msg, tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an {@link #INFO} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int i(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, INFO, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #INFO} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int i(String tag, String msg, Throwable tr) {
|
||||
return printlns(LOG_ID_MAIN, INFO, tag, msg, tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #WARN} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int w(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, WARN, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #WARN} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int w(String tag, String msg, Throwable tr) {
|
||||
return printlns(LOG_ID_MAIN, WARN, tag, msg, tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see whether or not a log for the specified tag is loggable at the specified level.
|
||||
*
|
||||
* @return true in all cases (for unit test environment)
|
||||
*/
|
||||
public static boolean isLoggable(String tag, int level) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a {@link #WARN} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int w(String tag, Throwable tr) {
|
||||
return printlns(LOG_ID_MAIN, WARN, tag, "", tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an {@link #ERROR} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int e(String tag, String msg) {
|
||||
return println_native(LOG_ID_MAIN, ERROR, tag, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #ERROR} log message and log the exception.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log
|
||||
*/
|
||||
public static int e(String tag, String msg, Throwable tr) {
|
||||
return printlns(LOG_ID_MAIN, ERROR, tag, msg, tr);
|
||||
}
|
||||
|
||||
/**
|
||||
* What a Terrible Failure: Report a condition that should never happen.
|
||||
* The error will always be logged at level ASSERT with the call stack.
|
||||
* Depending on system configuration, a report may be added to the
|
||||
* {@link android.os.DropBoxManager} and/or the process may be terminated
|
||||
* immediately with an error dialog.
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static int wtf(String tag, String msg) {
|
||||
return wtf(LOG_ID_MAIN, tag, msg, null, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #wtf(String, String)}, but also writes to the log the full
|
||||
* call stack.
|
||||
* @hide
|
||||
*/
|
||||
public static int wtfStack(String tag, String msg) {
|
||||
return wtf(LOG_ID_MAIN, tag, msg, null, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* What a Terrible Failure: Report an exception that should never happen.
|
||||
* Similar to {@link #wtf(String, String)}, with an exception to log.
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tr An exception to log.
|
||||
*/
|
||||
public static int wtf(String tag, Throwable tr) {
|
||||
return wtf(LOG_ID_MAIN, tag, tr.getMessage(), tr, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* What a Terrible Failure: Report an exception that should never happen.
|
||||
* Similar to {@link #wtf(String, Throwable)}, with a message as well.
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param msg The message you would like logged.
|
||||
* @param tr An exception to log. May be null.
|
||||
*/
|
||||
public static int wtf(String tag, String msg, Throwable tr) {
|
||||
return wtf(LOG_ID_MAIN, tag, msg, tr, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Priority Constant for wtf.
|
||||
* Added for this custom Log implementation, not in android sources.
|
||||
*/
|
||||
private static final int WTF = 8;
|
||||
static int wtf(int logId, String tag, String msg, Throwable tr, boolean localStack,
|
||||
boolean system) {
|
||||
return printlns(LOG_ID_MAIN, WTF, tag, msg, tr);
|
||||
}
|
||||
|
||||
private static final int LOG_ID_MAIN = 0;
|
||||
|
||||
private static final String[] PRIORITY_ABBREV = { "0", "1", "V", "D", "I", "W", "E", "A", "WTF" };
|
||||
|
||||
private static int println_native(int bufID, int priority, String tag, String msg) {
|
||||
String res = PRIORITY_ABBREV[priority] + "/" + tag + " " + msg + System.lineSeparator();
|
||||
System.err.print(res);
|
||||
return res.length();
|
||||
}
|
||||
|
||||
private static int printlns(int bufID, int priority, String tag, String msg,
|
||||
Throwable tr) {
|
||||
StringWriter trSW = new StringWriter();
|
||||
if (tr != null) {
|
||||
trSW.append(" , Exception: ");
|
||||
PrintWriter trPW = new PrintWriter(trSW);
|
||||
tr.printStackTrace(trPW);
|
||||
trPW.flush();
|
||||
}
|
||||
return println_native(bufID, priority, tag, msg + trSW.toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -2,14 +2,14 @@ package de.danoeh.antennapod.core.feed;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage;
|
||||
import static de.danoeh.antennapod.core.feed.FeedMother.anyFeed;
|
||||
|
||||
class FeedItemMother {
|
||||
private static final String IMAGE_URL = "http://example.com/image";
|
||||
|
||||
static FeedItem anyFeedItemWithImage() {
|
||||
FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.PLAYED, anyFeed());
|
||||
item.setImage(anyFeedImage());
|
||||
item.setImageUrl(IMAGE_URL);
|
||||
return item;
|
||||
}
|
||||
|
|
@ -1,65 +1,60 @@
|
|||
package de.danoeh.antennapod.core.feed;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static de.danoeh.antennapod.core.feed.FeedItemMother.anyFeedItemWithImage;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class FeedItemTest extends AndroidTestCase {
|
||||
public class FeedItemTest {
|
||||
|
||||
private FeedItem original;
|
||||
private FeedImage originalImage;
|
||||
private FeedItem changedFeedItem;
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
@Before
|
||||
public void setUp() {
|
||||
original = anyFeedItemWithImage();
|
||||
originalImage = original.getImage();
|
||||
changedFeedItem = anyFeedItemWithImage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFromOther_feedItemImageDownloadUrlChanged() throws Exception {
|
||||
setNewFeedItemImageDownloadUrl();
|
||||
|
||||
original.updateFromOther(changedFeedItem);
|
||||
|
||||
feedItemImageWasUpdated();
|
||||
assertFeedItemImageWasUpdated();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFromOther_feedItemImageRemoved() throws Exception {
|
||||
feedItemImageRemoved();
|
||||
|
||||
original.updateFromOther(changedFeedItem);
|
||||
|
||||
feedItemImageWasNotUpdated();
|
||||
assertFeedItemImageWasNotUpdated();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFromOther_feedItemImageAdded() throws Exception {
|
||||
feedItemHadNoImage();
|
||||
original.setImageUrl(null);
|
||||
setNewFeedItemImageDownloadUrl();
|
||||
|
||||
original.updateFromOther(changedFeedItem);
|
||||
|
||||
feedItemImageWasUpdated();
|
||||
}
|
||||
|
||||
private void feedItemHadNoImage() {
|
||||
original.setImage(null);
|
||||
assertFeedItemImageWasUpdated();
|
||||
}
|
||||
|
||||
private void setNewFeedItemImageDownloadUrl() {
|
||||
changedFeedItem.getImage().setDownload_url("http://example.com/new_picture");
|
||||
changedFeedItem.setImageUrl("http://example.com/new_picture");
|
||||
}
|
||||
|
||||
private void feedItemImageRemoved() {
|
||||
changedFeedItem.setImage(null);
|
||||
changedFeedItem.setImageUrl(null);
|
||||
}
|
||||
|
||||
private void feedItemImageWasUpdated() {
|
||||
assertEquals(original.getImage().getDownload_url(), changedFeedItem.getImage().getDownload_url());
|
||||
private void assertFeedItemImageWasUpdated() {
|
||||
assertEquals(original.getImageUrl(), changedFeedItem.getImageUrl());
|
||||
}
|
||||
|
||||
private void feedItemImageWasNotUpdated() {
|
||||
assertTrue(originalImage == original.getImage());
|
||||
private void assertFeedItemImageWasNotUpdated() {
|
||||
assertEquals(anyFeedItemWithImage().getImageUrl(), original.getImageUrl());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package de.danoeh.antennapod.core.feed;
|
||||
|
||||
import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage;
|
||||
|
||||
class FeedMother {
|
||||
public static final String IMAGE_URL = "http://example.com/image";
|
||||
|
||||
public static Feed anyFeed() {
|
||||
FeedImage image = anyFeedImage();
|
||||
return new Feed(0, null, "title", "http://example.com", "This is the description",
|
||||
"http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image,
|
||||
"http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", IMAGE_URL,
|
||||
null, "http://example.com/feed", true);
|
||||
}
|
||||
|
|
@ -1,63 +1,61 @@
|
|||
package de.danoeh.antennapod.core.feed;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static de.danoeh.antennapod.core.feed.FeedImageMother.anyFeedImage;
|
||||
import static de.danoeh.antennapod.core.feed.FeedMother.anyFeed;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class FeedTest extends AndroidTestCase {
|
||||
public class FeedTest {
|
||||
|
||||
private Feed original;
|
||||
private FeedImage originalImage;
|
||||
private Feed changedFeed;
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
@Before
|
||||
public void setUp() {
|
||||
original = anyFeed();
|
||||
originalImage = original.getImage();
|
||||
changedFeed = anyFeed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareWithOther_feedImageDownloadUrlChanged() throws Exception {
|
||||
setNewFeedImageDownloadUrl();
|
||||
|
||||
feedHasChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareWithOther_sameFeedImage() throws Exception {
|
||||
changedFeed.setImage(anyFeedImage());
|
||||
|
||||
changedFeed.setImageUrl(FeedMother.IMAGE_URL);
|
||||
feedHasNotChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareWithOther_feedImageRemoved() throws Exception {
|
||||
feedImageRemoved();
|
||||
|
||||
feedHasNotChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFromOther_feedImageDownloadUrlChanged() throws Exception {
|
||||
setNewFeedImageDownloadUrl();
|
||||
|
||||
original.updateFromOther(changedFeed);
|
||||
|
||||
feedImageWasUpdated();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFromOther_feedImageRemoved() throws Exception {
|
||||
feedImageRemoved();
|
||||
|
||||
original.updateFromOther(changedFeed);
|
||||
|
||||
feedImageWasNotUpdated();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateFromOther_feedImageAdded() throws Exception {
|
||||
feedHadNoImage();
|
||||
setNewFeedImageDownloadUrl();
|
||||
|
||||
original.updateFromOther(changedFeed);
|
||||
|
||||
feedImageWasUpdated();
|
||||
}
|
||||
|
||||
|
@ -66,11 +64,11 @@ public class FeedTest extends AndroidTestCase {
|
|||
}
|
||||
|
||||
private void feedHadNoImage() {
|
||||
original.setImage(null);
|
||||
original.setImageUrl(null);
|
||||
}
|
||||
|
||||
private void setNewFeedImageDownloadUrl() {
|
||||
changedFeed.getImage().setDownload_url("http://example.com/new_picture");
|
||||
changedFeed.setImageUrl("http://example.com/new_picture");
|
||||
}
|
||||
|
||||
private void feedHasChanged() {
|
||||
|
@ -78,15 +76,15 @@ public class FeedTest extends AndroidTestCase {
|
|||
}
|
||||
|
||||
private void feedImageRemoved() {
|
||||
changedFeed.setImage(null);
|
||||
changedFeed.setImageUrl(null);
|
||||
}
|
||||
|
||||
private void feedImageWasUpdated() {
|
||||
assertEquals(original.getImage().getDownload_url(), changedFeed.getImage().getDownload_url());
|
||||
assertEquals(original.getImageUrl(), changedFeed.getImageUrl());
|
||||
}
|
||||
|
||||
private void feedImageWasNotUpdated() {
|
||||
assertTrue(originalImage == original.getImage());
|
||||
assertEquals(anyFeed().getImageUrl(), original.getImageUrl());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
package de.danoeh.antennapod.core.tests.util;
|
||||
package de.danoeh.antennapod.core.util;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.danoeh.antennapod.core.util.LongIntMap;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class LongLongMapTest extends AndroidTestCase {
|
||||
public class LongLongMapTest {
|
||||
|
||||
@Test
|
||||
public void testEmptyMap() {
|
||||
LongIntMap map = new LongIntMap();
|
||||
assertEquals(0, map.size());
|
||||
|
@ -18,6 +19,7 @@ public class LongLongMapTest extends AndroidTestCase {
|
|||
assertEquals(1, map.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleElement() {
|
||||
LongIntMap map = new LongIntMap();
|
||||
map.put(17, 42);
|
||||
|
@ -30,6 +32,7 @@ public class LongLongMapTest extends AndroidTestCase {
|
|||
assertEquals(true, map.delete(17));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAndDelete() {
|
||||
LongIntMap map = new LongIntMap();
|
||||
for(int i=0; i < 100; i++) {
|
||||
|
@ -46,6 +49,7 @@ public class LongLongMapTest extends AndroidTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverwrite() {
|
||||
LongIntMap map = new LongIntMap();
|
||||
map.put(17, 42);
|
Loading…
Reference in New Issue