Skip to content

Commit

Permalink
feat(jellyfin): Timezone trickery to sus out weird timezone reporting…
Browse files Browse the repository at this point in the history
… from jellyfin #87
  • Loading branch information
FoxxMD committed Aug 10, 2023
1 parent af4ac98 commit cde6046
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import utc from 'dayjs/plugin/utc.js';
import isBetween from 'dayjs/plugin/isBetween.js';
import relativeTime from 'dayjs/plugin/relativeTime.js';
import duration from 'dayjs/plugin/duration.js';
import timezone from 'dayjs/plugin/timezone.js';
import passport from 'passport';
import session from 'express-session';

Expand Down Expand Up @@ -45,6 +46,7 @@ dayjs.extend(utc)
dayjs.extend(isBetween);
dayjs.extend(relativeTime);
dayjs.extend(duration);
dayjs.extend(timezone);

const app = addAsync(express());
const router = Router();
Expand Down
23 changes: 15 additions & 8 deletions src/sources/JellyfinSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default class JellyfinSource extends MemorySource {
// JELLYFIN WEB -> LastPlayedDate = time when track stopped being played
if(NotificationType === 'UserDataSaved' && SaveReason === 'PlaybackFinished' && LastPlayedDate !== undefined) {
nfs = false;

playDate = dayjs(LastPlayedDate);
if(Played !== true) {
eventReason = 'PlaybackFinished-NOTPLAYED'
Expand Down Expand Up @@ -257,16 +258,22 @@ export default class JellyfinSource extends MemorySource {
const trackId = buildTrackString(playObj, {include: ['artist', 'track']});

// sometimes jellyfin sends UserDataSaved payload with a LastPlayedDate that uses local time but accidentally includes a UTC offset (Z)
// we need to check if playDate with local offset is the same (to within a second or two)?
// we need to check if playDate with local offset is the same (to within 10 seconds to allow symphonium to report)
const now = dayjs();
let offsetDate: Dayjs = undefined;
const localOffset = dayjs().utcOffset();
const offsetBackDate = playObj.data.playDate.add(localOffset * -1, 'minutes');
const offsetForwardDate = playObj.data.playDate.add(localOffset * -1, 'minutes');
let offsetDate: Dayjs;
if(Math.abs(now.diff(offsetBackDate, 'seconds')) < 5) {
offsetDate = offsetBackDate;
} else if (Math.abs(now.diff(offsetForwardDate, 'seconds')) < 5) {
offsetDate = offsetForwardDate;
if(localOffset < 0) {
const offsetBackDate = playObj.data.playDate.subtract(Math.abs(localOffset), 'minutes');
if(Math.abs(now.diff(offsetBackDate, 'seconds')) < 5) {
offsetDate = offsetBackDate;
}
}
if(offsetDate === undefined) {
const tz = dayjs.tz.guess();
const normalizedDate = dayjs(playObj.data.playDate.utc().tz('Etc/UTC').tz(tz, true).toISOString())
if(Math.abs(now.diff(normalizedDate, 'seconds')) < 12) {
offsetDate = normalizedDate;
}
}
if(offsetDate !== undefined) {
this.logger.warn(`Play with event UserDataSaved-PlaybackFinished has a playDate that is likely local time with incorrect UTC offset. It has been corrected. => ${trackId}`);
Expand Down

0 comments on commit cde6046

Please sign in to comment.