-
-
Save saitamanodoruji/2944470 to your computer and use it in GitHub Desktop.
Endless Summer on Tumblr Dashboard with Logger
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Endless Summer on dsbd with Logger | |
// @namespace http://www.tumblr.com/ | |
// @description random next link on tumblr dashboard | |
// @include http://www.tumblr.com/dashboard/1* | |
// @include http://www.tumblr.com/show/*/1* | |
// @require https://raw.github.com/gist/3242 | |
// @require https://raw.github.com/gist/198443 | |
// @require https://raw.github.com/gist/34615 | |
// @version 0.0.4.0.17 | |
// @update 2013-09-06 | |
// ==/UserScript== | |
// shuffles dashboard with Exponential Endless Summer method | |
// http://tumblr.g.hatena.ne.jp/saitamanodoruji/20130831/1377961157 | |
// scrapes dashboard and logs data to Firefox preference | |
// under the name "log" as JSON array | |
// [{"drawnNo": 1234567899, "utime": 1234567890000, "postNo": 1234567890, "type": 1}, ...] | |
// requires sharedObject fix to Greaesemonkey (or Scriptish) | |
// http://exe.tyo.ro/2011/11/greasemonkey0912minibufferldrize.html by tyoro | |
// requires AutoPagerize http://userscripts.org/scripts/show/8551 by swdyh | |
// requires fix of AutoPagerize http://d.hatena.ne.jp/t_f_m/20111121/1321886246a by t_f_m | |
// using $X() https://gist.github.com/3242 by os0x | |
// using createDocumentFromString https://gist.github.com/198443 by os0x | |
// using wedata utility for GM https://gist.github.com/34615 by youpy | |
(function(){ | |
var dsbd = 'http://www.tumblr.com/dashboard'; | |
var DATABASE_URL = 'http://wedata.net/items/54652.json'; | |
var database = new Wedata.Database(DATABASE_URL); | |
var data = JSON.parse(GM_getValue('log', '[{"drawnNo": 1}]')); | |
var data_ = []; | |
data.forEach(function(d){ | |
if (d.utime && d.postNo < d.drawnNo) data_.push(d); | |
}); | |
data = data_; | |
GM_log('logged data loaded from Firefox preference.\nN = ' + data.length); | |
var getId = function(info){ | |
var opt = { | |
method: 'GET', | |
url: dsbd, | |
headers : { | |
}, | |
onload: function(res) { | |
var i = $X(info.nextLink, createDocumentFromString(res.responseText)); | |
if(i.length){ | |
i = i[0]; | |
}else{ | |
return; | |
} | |
var cacheInfo = { | |
postNo : i.href.match(/.*\/\d+\/(\d+)/)[1], | |
nextLink : info.nextLink | |
}; | |
GM_setValue('cacheInfo', JSON.stringify(cacheInfo)); | |
} | |
}; | |
GM_xmlhttpRequest(opt); | |
}; | |
var endlessSummer = function(doc, url, info){ | |
var cacheInfo = JSON.parse(GM_getValue('cacheInfo')); | |
if (!cacheInfo){ | |
return; | |
} | |
var a = $X(cacheInfo.nextLink, doc); | |
if (a.length) { | |
a = a[0]; | |
}else{ | |
return; | |
} | |
var range = {min: 72997, max: cacheInfo.postNo}; | |
var drawnNo = draw(range.min, range.max); | |
a.href = location.pathname.replace(/(\/[^\/]+\/\d+)(\/\d+)/,'$1') + '?offset=' + drawnNo; | |
a.textContent = 'Searching for The Endless Summer \u2192 '; | |
a.style.background='none repeat scroll 0 0 #4AADF0'; | |
// log | |
if (data.length) { | |
var d = data[data.length - 1]; | |
if (d.drawnNo && !d.postNo && !d.utime && !d.type) { | |
var dData = {}; // data scraped from dashboard | |
var anchor = $X('//a[contains(concat(" ", @class, " "), " post_permalink ")]', doc)[0]; | |
dData.postNo = anchor.href.replace(/^http:\/\/[^\/]+\/(?:post\/)?(\d+)\/?[^\/]*$/, '$1'); | |
if (dData.postNo > d.drawnNo) { | |
// when AutoPagerize.filter didn't work before loading next page | |
data.pop(); | |
GM_log('AutoPagerize.filter didn\'t work before loading this page.\n' | |
+ 'drawnNo = ' + d.drawnNo + '\n' | |
+ 'postNo = ' + dData.postNo + '\n' | |
+ 'discarded the data.\n' | |
+ 'N = ' + data.length); | |
} else { | |
dData.mesTime = new Date().getTime(); | |
dData.utime = getUnixTimeFromDsbdDateString(anchor.title, dData.postNo); | |
dData.type = anchor.title.replace('View post - ', '').split(' ').length; | |
dData.minPID = range.min; | |
dData.maxPID = range.max; | |
d = update(d, dData); | |
GM_log('got data. N = ' + data.length + '\n' + [ | |
dData.type, | |
(new Date(dData.utime)).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'), | |
dData.utime, | |
(new Date(dData.mesTime)).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'), | |
dData.mesTime, | |
dData.postNo, | |
d.drawnNo, | |
dData.minPID, | |
dData.maxPID].join(',')) | |
} | |
} | |
} | |
data.push({drawnNo: drawnNo}); | |
GM_setValue('log', JSON.stringify(data)); | |
}; | |
// Exponential Endless Summer 2013.08 | |
var draw = function(oldestID, newestID) { | |
var oldestUTime = getUnixTimeFromPostID(oldestID); | |
var newestUTime = getUnixTimeFromPostID(newestID); | |
var drawnUTime = oldestUTime + Math.floor((newestUTime - oldestUTime) * Math.random()); | |
return getPostIDFromUnixTime(drawnUTime); | |
} | |
var getPostIDFromUnixTime = function(utime) { | |
if (utime < 1149465600000) { | |
return; | |
} else if (utime === Number.POSITIVE_INFINITY) { | |
return Number.POSITIVE_INFINITY; | |
} | |
for (var i = 0; i < params.length; i++) { | |
if (utime <= params[i].upperBound) { | |
return Math.ceil(params[i].coefAlpha * Math.exp(params[i].coefBeta * (utime - 1136073600000))); | |
} | |
} | |
} | |
var getUnixTimeFromPostID = function(postID) { | |
if (postID < 1) { return; } | |
for (var i = 0; i < params.length; i++) { | |
if (postID <= getPostIDFromUnixTime(params[i].upperBound)) { | |
return Math.floor(Math.log(postID/params[i].coefAlpha)/params[i].coefBeta) + 1136073600000; | |
} | |
} | |
} | |
var params = [ | |
// f_i(t) = Alpha_i * exp[Beta_i * (t - t_0)] | |
// t: Unix time [msec] | |
// t_0 = 1136073600000 [msec] (2006-01-01T00:00:00+09:00) | |
{coefAlpha: 1.211 * Math.pow(10, -1), coefBeta: 1.571 * Math.pow(10, -10), upperBound: 1160012789359}, | |
{coefAlpha: 3.619 * Math.pow(10, -13), coefBeta: 1.266 * Math.pow(10, -9), upperBound: 1163269541924}, | |
{coefAlpha: 2.120 * Math.pow(10, 0), coefBeta: 1.846 * Math.pow(10, -10), upperBound: 1172120791893}, | |
{coefAlpha: 1.179 * Math.pow(10, -49), coefBeta: 3.331 * Math.pow(10, -9), upperBound: 1173392561265}, | |
{coefAlpha: 4.702 * Math.pow(10, -7), coefBeta: 7.024 * Math.pow(10, -10), upperBound: 1176405323219}, | |
{coefAlpha: 5.338 * Math.pow(10, 1), coefBeta: 2.425 * Math.pow(10, -10), upperBound: 1182930300850}, | |
{coefAlpha: 8.255 * Math.pow(10, 3), coefBeta: 1.349 * Math.pow(10, -10), upperBound: 1193299359828}, | |
{coefAlpha: 2.496 * Math.pow(10, 6), coefBeta: 3.509 * Math.pow(10, -11), upperBound: 1241622616806}, | |
{coefAlpha: 2.907 * Math.pow(10, 5), coefBeta: 5.546 * Math.pow(10, -11), upperBound: 1283088065116}, | |
{coefAlpha: 5.206 * Math.pow(10, 4), coefBeta: 6.716 * Math.pow(10, -11), upperBound: 1291075200000}, | |
{coefAlpha: 8.329 * Math.pow(10, 4), coefBeta: 6.521 * Math.pow(10, -11), upperBound: 1292241600000}, | |
{coefAlpha: 8.396 * Math.pow(10, 4), coefBeta: 6.541 * Math.pow(10, -11), upperBound: 1307576237376}, | |
{coefAlpha: 7.746 * Math.pow(10, 4), coefBeta: 6.588 * Math.pow(10, -11), upperBound: 1313586050187}, | |
{coefAlpha: 8.798 * Math.pow(10, 6), coefBeta: 3.922 * Math.pow(10, -11), upperBound: 1340572542928}, | |
{coefAlpha: 2.693 * Math.pow(10, 8), coefBeta: 2.249 * Math.pow(10, -11), upperBound: Number.POSITIVE_INFINITY}, | |
] | |
// utilities for date correction | |
// a.post_permalink の title に入っている日付文字列と Post ID を元に | |
// ポストが作られた Unix time を求める | |
var getUnixTimeFromDsbdDateString = function(dsbdDateStr, dsbdPostNo) { | |
var utime; | |
var dateArr = dsbdDateStr.replace('View post - ', '').split(' '); | |
var type = dateArr.length; | |
var curDate = new Date(); | |
if (type == 1) { | |
// View post - 5:17am | |
var formattedTime = getFormattedTime(dsbdDateStr.replace('View post - ', '')); | |
var timestamp = curDate.toString().replace(/\d\d:\d\d:\d\d/, formattedTime); | |
utime = new Date(timestamp).getTime(); | |
} else if (type == 2) { | |
// View post - Thursday, 11:53pm | |
var diffInWeek; | |
var day = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; | |
day.forEach(function(e, i) { | |
if( e == dateArr[0].replace(',', '') ) { | |
diffInWeek = curDate.getDay() - i > 0 ? | |
curDate.getDay() - i : | |
curDate.getDay() - i + 7; | |
} | |
}); | |
var formattedTime = getFormattedTime(dsbdDateStr.replace(/^[^,]+, /, '')); | |
var timestamp = curDate.toString().replace(/\d\d:\d\d:\d\d/, formattedTime); | |
utime = new Date(timestamp).getTime() - diffInWeek * 86400000; | |
} else if (type == 3) { | |
// View post - June 8th, 8:46pm | |
var formattedDateStr = [ | |
curDate.getFullYear(), | |
dateArr[0], | |
dateArr[1].replace(/(?:st|nd|rd|th)/, ''), | |
getFormattedTime(dateArr[2]) | |
].join(' '); | |
utime = new Date(formattedDateStr).getTime(); | |
} else if (type == 4) { | |
// View post - March 29th 2007, 8:38pm | |
var formattedDateStr = [ | |
dateArr[0], | |
dateArr[1].replace(/(?:st|nd|rd|th)/, ''), | |
dateArr[2], | |
getFormattedTime(dateArr[3]) | |
].join(' '); | |
utime = new Date(formattedDateStr).getTime(); | |
} | |
return correctDsbdUTime(utime, type, dsbdPostNo); | |
} | |
// いくつかの日付で日付文字列が間違っているので校正する | |
var correctDsbdUTime = function(utime, type, dsbdPostNo) { | |
var cUTime; //corrected Unix time | |
var timestamp = new Date(utime).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'); | |
if (1230649200000 <= utime && utime < 1230735600000 | |
&& dsbdPostNo < 31818629) { | |
// 2007-12-31 is displayed as 2008 by mistake | |
cUTime = new Date(timestamp.replace(/^2008/, '2007')).getTime(); | |
} else if (1262012400000 <= utime && utime < 1262271600000 | |
&& dsbdPostNo < 175958681) { | |
// 2008-12-29, 2008-12-30, 2008-12-31 are displayed as 2009 by mistake | |
cUTime = new Date(timestamp.replace(/^2009/, '2008')).getTime(); | |
} else if (1230735600000 <= utime && utime < 1230994800000 | |
&& dsbdPostNo > 175958681) { | |
// 2010-01-01, 2010-01-02, 2010-01-03 are displayed as 2009 by mistake | |
cUTime = new Date(timestamp.replace(/^2009/, '2010')).getTime(); | |
} else if (1262271600000 <= utime && utime < 1262444400000 | |
&& dsbdPostNo > 973060715) { | |
// 2011-01-01, 2011-01-02 are displayed as 2010 by mistake | |
cUTime = new Date(timestamp.replace(/^2010/, '2011')).getTime(); | |
} else if (1293807600000 <= utime && utime < 1293894000000 | |
&& dsbdPostNo > 5381076679) { | |
// 2012-01-01 is displayed as 2011 by mistake | |
cUTime = new Date(timestamp.replace(/^2011/, '2012')).getTime(); | |
} | |
// same day of previous years displayed as current year | |
if (type == 1) { | |
var currentYear = new Date().getFullYear(); | |
if (dsbdPostNo < 22717143) { | |
// to 2007 | |
cUTime = rewindYear(utime, currentYear - 2007); | |
} else if (dsbdPostNo < 67667869) { | |
// to 2008 | |
cUTime = rewindYear(utime, currentYear - 2008); | |
} else if (dsbdPostNo < 309781747) { | |
// to 2009 | |
cUTime = rewindYear(utime, currentYear - 2009); | |
} else if (dsbdPostNo < 2542286951) { | |
// to 2010 | |
cUTime = rewindYear(utime, currentYear - 2010); | |
} else if (dsbdPostNo < 15082228675) { | |
// to 2011 | |
cUTime = rewindYear(utime, currentYear - 2011); | |
} else if (dsbdPostNo < 39306789337) { | |
// to 2012 | |
cUTime = rewindYear(utime, currentYear - 2012); | |
} | |
} | |
// for 2012-12-31 | |
if (type == 2 && 39217020996 < dsbdPostNo && dsbdPostNo < 39306789337) { | |
cUTime = new Date(timestamp.replace(/\d{4}-\d{2}-\d{2}/, '2012-12-31')).getTime(); | |
} | |
return cUTime || utime; | |
} | |
// n 年前の同日の Unix time を求める | |
var rewindYear = function(utime, n) { | |
var utimeDateStr = new Date(utime).toISOString(); | |
var utimeYear = Number(utimeDateStr.match(/^\d{4}/)[0]); | |
var rewindedYear = utimeYear - n; | |
var rewindedDateStr = utimeDateStr.replace(/^\d{4}/, rewindedYear); | |
var rewindedUTime = new Date(rewindedDateStr).getTime(); | |
return rewindedUTime; | |
} | |
// 時刻文字列を 24 h 形式にする | |
// ex. 1) '9:17am' -> '09:17' | |
// ex. 2) '5:36pm' -> '17:36' | |
var getFormattedTime = function(timeStr) { | |
var timeArr = timeStr.split(':'); | |
timeArr[0] = Number(timeArr[0]); | |
if (/pm/.test(timeArr[1])) { | |
timeArr[0] = (timeArr[0] + 12).toString(); | |
} else if (timeArr[0].toString().length == 1) { | |
timeArr[0] = '0' + timeArr[0]; | |
} else { | |
timeArr[0] = timeArr[0].toString().replace('12', '00'); | |
} | |
timeArr[1] = timeArr[1].replace(/(?:am|pm)/, ''); | |
return timeArr.join(':'); | |
} | |
function update(t, s){ | |
for(var p in s) | |
t[p] = s[p] | |
return t | |
} | |
// end of utilities for date correction | |
GM_registerMenuCommand('endless summer - clear cache', function() { | |
GM_setValue('cacheInfo', ''); | |
database.clearCache(); | |
}); | |
GM_registerMenuCommand('endless summer - dump log', function() { | |
var data = JSON.parse(GM_getValue('log', '[]')); | |
if (data.length) { | |
data.pop(); | |
} else { | |
GM_log('no log'); | |
return; | |
} | |
var labels = [ | |
'dsbdDateStringType', | |
'dsbdDate', | |
'dsbdUnixtime', | |
'mesDate', | |
'mesUnixTime', | |
'calcDate', | |
'calcUnixTime', | |
'postNo', | |
'drawnNo', | |
'residual[day]', | |
'minPID', | |
'maxPID' | |
].join(','); | |
var msg = data.map(function(e){ | |
var calcUTime = getUnixTimeFromPostNo(e.drawnNo); | |
var ret = [ | |
e.type, | |
(new Date(e.utime)).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'), | |
e.utime, | |
(new Date(e.mesTime)).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'), | |
e.mesTime, | |
(new Date(calcUTime)).toLocaleFormat('%Y-%m-%dT%H:%M:%S+09:00'), | |
calcUTime, | |
e.postNo, | |
e.drawnNo, | |
((e.utime - calcUTime) / (1000 * 60 * 60 * 24)).toFixed(1), | |
e.minPID, | |
e.maxPID | |
].join(','); | |
return ret; | |
}).join('\n'); | |
GM_log(['','N = ' + data.length, labels, msg].join('\n')); | |
}); | |
GM_registerMenuCommand('endless summer - clear log', function() { | |
if(confirm('Endless Summer: Are you sure you want to clear log?')) { | |
GM_deleteValue('log'); | |
data = []; | |
} | |
}); | |
database.get(function(items) { | |
getId(items.data); | |
}); | |
endlessSummer(document, '', ''); | |
setTimeout(function(){ | |
if (sharedObject.AutoPagerize && sharedObject.AutoPagerize.addDocumentFilter){ | |
sharedObject.AutoPagerize.addDocumentFilter(endlessSummer); | |
} | |
},0); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment