use of org.joda.time.LocalTime in project SeriesGuide by UweTrottmann.
the class TimeToolsTest method test_parseEpisodeReleaseTime_HourPastMidnight.
@Test
public void test_parseEpisodeReleaseTime_HourPastMidnight() {
// ensure episodes releasing in the hour past midnight are moved to the next day
// e.g. if 00:35, the episode date is typically (wrongly) that of the previous day
// this is common for late night shows, e.g. "Monday night" is technically "early Tuesday"
DateTimeZone showTimeZone = DateTimeZone.forID(AMERICA_NEW_YORK);
String deviceTimeZone = AMERICA_LOS_ANGELES;
long episodeReleaseTime = TimeTools.parseEpisodeReleaseDate(null, showTimeZone, "2013-05-31", // 00:35
new LocalTime(0, 35), UNITED_STATES, null, deviceTimeZone);
System.out.println("Release time: " + episodeReleaseTime + " " + new Date(episodeReleaseTime));
assertThat(episodeReleaseTime).isEqualTo(1370072100000L);
}
use of org.joda.time.LocalTime in project SeriesGuide by UweTrottmann.
the class TimeToolsTest method test_parseEpisodeReleaseTime_NoHourPastMidnight.
@Test
public void test_parseEpisodeReleaseTime_NoHourPastMidnight() {
// ensure episodes releasing in the hour past midnight are NOT moved to the next day
// if it is a Netflix show
DateTimeZone showTimeZone = DateTimeZone.forID(AMERICA_NEW_YORK);
String deviceTimeZone = AMERICA_LOS_ANGELES;
long episodeReleaseTime = TimeTools.parseEpisodeReleaseDate(null, showTimeZone, // +one day here
"2013-06-01", // 00:35
new LocalTime(0, 35), UNITED_STATES, "Netflix", deviceTimeZone);
System.out.println("Release time: " + episodeReleaseTime + " " + new Date(episodeReleaseTime));
assertThat(episodeReleaseTime).isEqualTo(1370072100000L);
}
use of org.joda.time.LocalTime in project SeriesGuide by UweTrottmann.
the class TimeToolsTest method test_parseEpisodeReleaseTime.
@Test
public void test_parseEpisodeReleaseTime() {
// ensure a US show has its local release time correctly converted to UTC time
// (we can be sure that in May there is always DST in effect in America/New_York
// so this test will likely not break if DST rules change)
DateTimeZone showTimeZone = DateTimeZone.forID(AMERICA_NEW_YORK);
String deviceTimeZone = AMERICA_LOS_ANGELES;
long episodeReleaseTime = TimeTools.parseEpisodeReleaseDate(null, showTimeZone, "2013-05-31", // 20:00
new LocalTime(20, 0), UNITED_STATES, null, deviceTimeZone);
System.out.println("Release time: " + episodeReleaseTime + " " + new Date(episodeReleaseTime));
assertThat(episodeReleaseTime).isEqualTo(1370055600000L);
}
use of org.joda.time.LocalTime in project SeriesGuide by UweTrottmann.
the class SeriesGuideDatabase method upgradeToTwentyFour.
/**
* Adds a column to the {@link Tables#EPISODES} table to store the airdate and possibly time in
* milliseconds.
*/
private static void upgradeToTwentyFour(SQLiteDatabase db) {
db.execSQL("ALTER TABLE " + Tables.EPISODES + " ADD COLUMN " + EpisodesColumns.FIRSTAIREDMS + " INTEGER DEFAULT -1;");
// populate the new column from existing data
final Cursor shows = db.query(Tables.SHOWS, new String[] { Shows._ID }, null, null, null, null, null);
while (shows.moveToNext()) {
final String showId = shows.getString(0);
//noinspection deprecation
final Cursor episodes = db.query(Tables.EPISODES, new String[] { Episodes._ID, Episodes.FIRSTAIRED }, Shows.REF_SHOW_ID + "=?", new String[] { showId }, null, null, null);
db.beginTransaction();
try {
ContentValues values = new ContentValues();
DateTimeZone defaultShowTimeZone = TimeTools.getDateTimeZone(null);
LocalTime defaultShowReleaseTime = TimeTools.getShowReleaseTime(-1);
String deviceTimeZone = TimeZone.getDefault().getID();
while (episodes.moveToNext()) {
String firstAired = episodes.getString(1);
long episodeAirtime = TimeTools.parseEpisodeReleaseDate(null, defaultShowTimeZone, firstAired, defaultShowReleaseTime, null, null, deviceTimeZone);
values.put(Episodes.FIRSTAIREDMS, episodeAirtime);
db.update(Tables.EPISODES, values, Episodes._ID + "=?", new String[] { episodes.getString(0) });
values.clear();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
episodes.close();
}
shows.close();
}
use of org.joda.time.LocalTime in project SeriesGuide by UweTrottmann.
the class TvdbTools method parseEpisodes.
/**
* Loads the given zipped XML and parses containing episodes to create an array of {@link
* ContentValues} for new episodes.<br> Adds update ops for updated episodes and delete ops for
* local orphaned episodes to the given {@link ContentProviderOperation} batch.
*/
private ArrayList<ContentValues> parseEpisodes(final ArrayList<ContentProviderOperation> batch, final Show show, String url) throws TvdbException {
final long dateLastMonthEpoch = (System.currentTimeMillis() - (DateUtils.DAY_IN_MILLIS * 30)) / 1000;
final DateTimeZone showTimeZone = TimeTools.getDateTimeZone(show.release_timezone);
final LocalTime showReleaseTime = TimeTools.getShowReleaseTime(show.release_time);
final String deviceTimeZone = TimeZone.getDefault().getID();
RootElement root = new RootElement("Data");
Element episode = root.getChild("Episode");
final ArrayList<ContentValues> newEpisodesValues = new ArrayList<>();
final HashMap<Integer, Long> localEpisodeIds = DBUtils.getEpisodeMapForShow(app, show.tvdb_id);
final HashMap<Integer, Long> removableEpisodeIds = new HashMap<>(// just copy episodes list, then remove valid ones
localEpisodeIds);
final HashSet<Integer> localSeasonIds = DBUtils.getSeasonIdsOfShow(app, show.tvdb_id);
// store updated seasons to avoid duplicate ops
final HashSet<Integer> seasonIdsToUpdate = new HashSet<>();
final ContentValues values = new ContentValues();
// set handlers for elements we want to react to
episode.setEndElementListener(new EndElementListener() {
public void end() {
Integer episodeId = values.getAsInteger(Episodes._ID);
if (episodeId == null || episodeId <= 0) {
// invalid id, skip
return;
}
// don't clean up this episode
removableEpisodeIds.remove(episodeId);
// decide whether to insert or update
if (localEpisodeIds.containsKey(episodeId)) {
/*
* Update uses provider ops which take a long time. Only
* update if episode was edited on TVDb or is not older than
* a month (ensures show air time changes get stored).
*/
Long lastEditEpoch = localEpisodeIds.get(episodeId);
Long lastEditEpochNew = values.getAsLong(Episodes.LAST_EDITED);
if (lastEditEpoch != null && lastEditEpochNew != null && (lastEditEpoch < lastEditEpochNew || dateLastMonthEpoch < lastEditEpoch)) {
// complete update op for episode
batch.add(DBUtils.buildEpisodeUpdateOp(values));
}
} else {
// episode does not exist, yet
newEpisodesValues.add(new ContentValues(values));
}
Integer seasonId = values.getAsInteger(Seasons.REF_SEASON_ID);
if (seasonId != null && !seasonIdsToUpdate.contains(seasonId)) {
// add insert/update op for season
batch.add(DBUtils.buildSeasonOp(values, !localSeasonIds.contains(seasonId)));
seasonIdsToUpdate.add(values.getAsInteger(Seasons.REF_SEASON_ID));
}
values.clear();
}
});
episode.getChild("id").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes._ID, body.trim());
}
});
episode.getChild("EpisodeNumber").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.NUMBER, body.trim());
}
});
episode.getChild("absolute_number").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.ABSOLUTE_NUMBER, body.trim());
}
});
episode.getChild("SeasonNumber").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.SEASON, body.trim());
}
});
episode.getChild("DVD_episodenumber").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.DVDNUMBER, body.trim());
}
});
episode.getChild("FirstAired").setEndTextElementListener(new EndTextElementListener() {
public void end(String releaseDate) {
long releaseDateTime = TimeTools.parseEpisodeReleaseDate(app, showTimeZone, releaseDate, showReleaseTime, show.country, show.network, deviceTimeZone);
values.put(Episodes.FIRSTAIREDMS, releaseDateTime);
}
});
episode.getChild("EpisodeName").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.TITLE, body.trim());
}
});
episode.getChild("Overview").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.OVERVIEW, body.trim());
}
});
episode.getChild("seasonid").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Seasons.REF_SEASON_ID, body.trim());
}
});
episode.getChild("seriesid").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Shows.REF_SHOW_ID, body.trim());
}
});
episode.getChild("Director").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.DIRECTORS, body.trim());
}
});
episode.getChild("GuestStars").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.GUESTSTARS, body.trim());
}
});
episode.getChild("Writer").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.WRITERS, body.trim());
}
});
episode.getChild("filename").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.IMAGE, body.trim());
}
});
episode.getChild("IMDB_ID").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
values.put(Episodes.IMDBID, body.trim());
}
});
episode.getChild("lastupdated").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
// system populated field, trimming not necessary
try {
values.put(Episodes.LAST_EDITED, Long.valueOf(body));
} catch (NumberFormatException e) {
values.put(Episodes.LAST_EDITED, 0);
}
}
});
downloadAndParse(root.getContentHandler(), url, true, "parseEpisodes: ");
// add delete ops for leftover episodeIds in our db
for (Integer episodeId : removableEpisodeIds.keySet()) {
batch.add(ContentProviderOperation.newDelete(Episodes.buildEpisodeUri(episodeId)).build());
}
return newEpisodesValues;
}
Aggregations