Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

History Import Timestamps (import date, vs watched date) #13

Open
metal450 opened this issue Jul 28, 2018 · 9 comments
Open

History Import Timestamps (import date, vs watched date) #13

metal450 opened this issue Jul 28, 2018 · 9 comments

Comments

@metal450
Copy link

When first installing this extension & importing previous watch history, it seems to set the watch timestamps to the current time (aka the import time), rather than the actual watch time.

@sniklaus
Copy link
Owner

Thank you for bringing this up! When synchronizing with the browser history, it will use the time at which you have last visited the page of the video according to your browser. When synchronizing with the Youtube history, it will use the current time for newly discovered videos. There unfortunately no easy solution to using the actual timestamp when syncing with the Youtube history since this is information that they do not expose. I am hence closing this issue for now but will post an update in case I ever find a better solution.

@metal450
Copy link
Author

metal450 commented Apr 1, 2020

There unfortunately no easy solution to using the actual timestamp when syncing with the Youtube history since this is information that they do not expose.

Isn't that information visible (and thus parsable) when vising the 'history' page on YouTube.com? I do see it listed above each group of videos.

@sniklaus
Copy link
Owner

sniklaus commented Apr 1, 2020

But that categorization is only on a per-day basis, so it is not sufficient to pinpoint the actual time when a video has been watched.

@metal450
Copy link
Author

metal450 commented Apr 1, 2020

True. But still significantly more informative than having no idea when it was viewed at all ;)

@sniklaus
Copy link
Owner

sniklaus commented Apr 1, 2020

Are the categories consistent though? Or does it switch to "last month" or "last year" once you go back sufficiently far? It is also a little tedious to implement this so I am afraid that I am holding off from implementing it based on incomplete information.

@metal450
Copy link
Author

metal450 commented Apr 1, 2020

The naming convention is well-defined. There are exactly 4 formats, so 4 pattern matches needed:
Today|Yesterday (this style is for 2 days)
DayOfTheWeek (this style is for the next 5 days)
Mar 25 (this style is through the beginning of the current year)
Dec 25, 2019 (ongoing)

The other reason this would be much better is because, as I understand it, it would cause multiple PCs to have consistent histories. As it is currently implemented, importing from 2 different PCs would cause them to have different histories (because each would show the watch date whenever that PC happened to sync last). If it was based on the parsed info actually shown, they would always be the same, regardless of when that PC last imported.

@sniklaus
Copy link
Owner

sniklaus commented Apr 1, 2020

That is good to know, but I am afraid that I am unfortunately unable to invest my spare time into adding this feature at the moment, my apologies. I would be happy to review a pull request that adds this feature though.

@metal450
Copy link
Author

metal450 commented Apr 1, 2020

Understood. I've never seen even a line of browser addon code, so I'm afraid it would require some studying on my part too, which I'm unfortunately not in place to do at this particular moment. Still, I'd propose not closing this issue, as it's not actually solved, & perhaps one of us (or someone else looking at these issues in the future) might come along & agree with the idea ;)

@sniklaus
Copy link
Owner

sniklaus commented Apr 1, 2020

Fair enough, reopening. Anyone who wants to give it a shot, the part that would need to be updated is quoted below.

synchronize: function(objRequest, funcResponse, funcProgress) {
Node.series({
'objVideos': function(objArguments, funcCallback) {
if (objArguments.objYtcfg === undefined) {
objArguments.objYtcfg = null
objArguments.strContinuation = 'https://www.youtube.com/feed/history';
}
var objAjax = new XMLHttpRequest();
objAjax.open('GET', objArguments.strContinuation);
if (objArguments.strContinuation !== null) {
objArguments.strContinuation = null;
}
if (objArguments.objYtcfg !== null) {
objAjax.setRequestHeader('X-YouTube-Client-Name', objArguments.objYtcfg['INNERTUBE_CONTEXT_CLIENT_NAME']);
objAjax.setRequestHeader('X-YouTube-Client-Version', objArguments.objYtcfg['INNERTUBE_CONTEXT_CLIENT_VERSION']);
objAjax.setRequestHeader('X-Youtube-Identity-Token', objArguments.objYtcfg['ID_TOKEN']);
}
objAjax.onload = function() {
if (objArguments.objYtcfg === null) {
objArguments.objYtcfg = JSON.parse(objAjax.responseText.split('ytcfg.set(').find(function(strData) { return strData.indexOf('INNERTUBE_CONTEXT_CLIENT_VERSION') !== -1; }).slice(0, -2));
}
var strRegex = null;
var objContinuation = new RegExp('("nextContinuationData":{"continuation":")([^"]+)(")(.*?)("clickTrackingParams":")([^"]+)(")', 'g');
var objVideo = new RegExp('("videoRenderer":{"videoId":")([^"]{11})(")(.*?)("text":")([^"]*)(")', 'g');
var strUnescaped = objAjax.responseText.split('\\"').join('\\u0022');
if ((strRegex = objContinuation.exec(strUnescaped)) !== null) {
objArguments.strContinuation = 'https://www.youtube.com/browse_ajax?ctoken=' + strRegex[2] + '&continuation=' + strRegex[2] + '&itct=' + strRegex[6];
}
var objVideos = [];
while ((strRegex = objVideo.exec(strUnescaped)) !== null) {
var strIdent = strRegex[2];
var strTitle = strRegex[6];
strTitle = strTitle.split('\\u0022').join('"');
strTitle = strTitle.split('\\u0026').join('&');
strTitle = strTitle.split('\\u003C').join('<');
strTitle = strTitle.split('\\u003C').join('=');
strTitle = strTitle.split('\\u003E').join('>');
strTitle = strTitle.split('\\u003E').join('>');
objVideos.push({
'strIdent': strIdent,
'intTimestamp': null,
'strTitle': strTitle,
'intCount': null
});
}
return funcCallback(objVideos);
};
objAjax.send();
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants