This is the host object which is created under the WM version 4.x script
Verzia zo dňa
Tento skript by nemal byť nainštalovaný priamo. Je to knižnica pre ďalšie skripty, ktorú by mali používať cez meta príkaz // @require https://update.greasyfork.org/scripts/6898/27563/WM%20Feed%20Manager%20Objects.js
// ==UserScript==
// @name WM Feed Manager Objects
// @namespace MerricksdadWMFeedManagerObjects
// @description This is the host object which is created under the WM version 4.x script
// @license http://creativecommons.org/licenses/by-nc-nd/3.0/us/
// @version 4.0.0.0
// @copyright Charlie Ewing except where noted
// ==/UserScript==
//this script requires some functions in the WM Common Library
//this script needs access to a pre-defined JSON object
(function(){
//***************************************************************************************************************************************
//***** Feed Objects
//***************************************************************************************************************************************
WM.feedManager = {
feeds : [],
init : function(){
var feedsIn=(getOptJSON("feeds3_"+WM.currentUser.profile)||[]);
var feedsInGlobal=(getOptJSON("feeds3_global")||[]);
if (isArrayAndNotEmpty(feedsIn)) {
//import feeds from storage
for (var f=0;f<feedsIn.length;f++){
feed=feedsIn[f];
if (!feed.isGlobal){
WM.feedManager.feeds.push(new WM.Feed(feed));
} else {
var glob=feedsInGlobal[feed.uniqueID]||null;
if (glob){
var merge=mergeJSON(glob,feed);
WM.feedManager.newFeed(merge);
glob.alreadyUsed=true;
} else {
log("WM.feedManager.init: Global feed missing, cannot merge");
}
}
}
} else {
//never been used before, create base feeds
WM.feedManager.feeds.push(new WM.Feed({title:"My Home Feed", url:"https://graph.facebook.com/me/home", isRemoveable:false}));
//WM.feedManager.feeds.push(new WM.Feed({title:"My Profile Wall", url:"https://graph.facebook.com/me/feed", isRemoveable:false}));
//import oldstyle feeds
var feedsOld=getOpt("feeds_"+WM.currentUser.profile);
if (feedsOld){
feedsOld=feedsOld.split("\n");
if (isArrayAndNotEmpty(feedsOld)) for (var f=0;f<feedsOld.length;f++) {
//prevent empties
if (feedsOld[f]) {
//create the new feed
WM.feedManager.newFeed({id:feedsOld[f],title:feedsOld[f]});
}
}
}
WM.feedManager.save();
}
//import all global feeds not already accounted for
for (var t in feedsInGlobal) {
var glob=feedsInGlobal[t];
if (!glob.alreadyUsed){
glob.uniqueID=t;
glob.isGlobal=true;
WM.feedManager.newFeed(glob); //newFeed adds app filters, where New Feed() does not
}
}
},
newFeed : function(params){
params=params||{};
var feed = new WM.Feed(params);
WM.feedManager.feeds.push(feed);
//add filters for each app available
for (var a in WM.apps){
feed.addFilter({id:"app_"+a});
}
},
save :function(){
var retFeeds=[];
var retGlobal={};
if (isArrayAndNotEmpty(WM.feedManager.feeds)) for (var f=0,len=WM.feedManager.feeds.length; f<len; f++){
var feed=WM.feedManager.feeds[f];
if (!feed.isGlobal) {
retFeeds.push(feed.saveableData);
} else {
retFeeds.push({isGlobal:true, uniqueID:feed.uniqueID, enabled:feed.enabled, expanded:feed.expanded});
var glob=feed.saveableData;
glob.uniqueID=feed.uniqueID;
retGlobal[feed.uniqueID]=glob;
}
}
setOptJSON("feeds3_"+WM.currentUser.profile,retFeeds);
setOptJSON("feeds3_global",retGlobal);
},
};
//***************************************************************************************************************************************
//***** FeedFilter Class
//***************************************************************************************************************************************
WM.FeedFilter = function(params){try{
this.objType="feedFilter";
params=params||{};
var self=this;
//set defaults
this.enabled=true;
this.expanded=true;
this._olderLimitReached=false;
//initialize edges to the collector startup time
this.oldedge=Math.round(timeStamp()/1000); //older edge timestamp
this.newedge=Math.round(timeStamp()/1000); //newer edge timestamp
//use passed params
for (var p in params) this[p]=params[p];
this.enable=function(){try{
this.enabled=true;
this.node.className=this.node.className.removeWord("disabled");
WM.feedManager.save();
}catch(e){log("WM.FeedFilter.enable: "+e);}};
this.disable=function(){try{
this.enabled=false;
this.node.className=this.node.className.addWord("disabled");
WM.feedManager.save();
}catch(e){log("WM.FeedFilter.disable: "+e);}};
this.toggle=function(){try{
this.enabled=this.toggleNode.checked;
this.node.className=this.node.className.swapWordB(this.enabled,"enabled","disabled");
WM.feedManager.save();
}catch(e){log("WM.FeedFilter.toggle: "+e);}};
this.toggleContent=function(){try{
this.expanded=!this.expanded;
var btnSize=WM.opts.littleButtonSize;
with (this.contentNode)
className=className.swapWordB(this.expanded,"expanded","collapsed");
with (this.toggleImgNode)
className=className.swapWordB(this.expanded,"treeCollapse"+btnSize,"treeExpand"+btnSize);
WM.feedManager.save();
}catch(e){log("WM.FeedFilter.toggleContent: "+e);}};
//remove this
this.remove=function(){try{
if (this.node) remove(this.node);
if (this.parent) delete this.parent.filters[this.id];
WM.feedManager.save();
}catch(e){log("WM.FeedFilter.remove: "+e);}};
//fetch posts for this
this.fetchNewer=function(){try{
WM.fetch({
newer:true,
apps:WM.apps[this.appID],
feeds:[this.parent],
bypassPause:true,
bypassAppDisabled:true,
bypassFeedDisabled:true,
bypassFilterDisabled:true,
});
}catch(e){log("WM.FeedFilter.fetchNewer: "+e);}};
this.fetchOlder=function(){try{
WM.fetch({
older:true,
apps:WM.apps[this.appID],
feeds:[this.parent],
bypassPause:true,
bypassAppDisabled:true,
bypassFeedDisabled:true,
bypassFilterDisabled:true,
});
}catch(e){log("WM.FeedFilter.fetchOlder: "+e);}};
this.__defineGetter__("olderLimitReached",function(){try{
return this._olderLimitReached;
}catch(e){log("WM.FeedFilter.olderLimitReached: "+e);}});
this.__defineSetter__("olderLimitReached",function(v){try{
this._olderLimitReached=v;
//update the sidekick page button graphics
var node=this.olderLimitNode;
if (node) node.textContent=v;
if (v) {
WM.rulesManager.doEvent("onFeedFilterOlderLimitReached",this);
}
}catch(e){log("WM.FeedFilter.olderLimitReached: "+e);}});
this.__defineGetter__("appID",function(){try{
//this assumes its an app filter because so far thats all we use
return this.id.removePrefix("app_");
}catch(e){log("WM.FeedFilter.appID: "+e);}});
this.__defineGetter__("appName",function(){try{
//this assumes its an app filter because so far thats all we use
//it also assumes app objects are global, which they are
//but that they are also available and already filled in by the sidekick, which they may not be
var a = WM.apps[this.appID];
if (a!=undefined) {
//debug.print([this.appID,a]);
return a.name;
}
return "";
}catch(e){log("WM.FeedFilter.appName: "+e);}});
//draw it
try{
if (this.parent.filtersNode) this.parent.filtersNode.appendChild(
this.node=createElement("div",{className:"listItem "+((this.enabled)?"enabled":"disabled")},[
createElement("div",{className:"line"},[
createElement("div",{className:"littleButton",title:"Toggle Content",onclick:function(){self.toggleContent();}},[
this.toggleImgNode=createElement("img",{className:"resourceIcon "+(this.expanded?"treeCollapse"+WM.opts.littleButtonSize:"treeExpand"+WM.opts.littleButtonSize)}),
]),
this.toggleNode=createElement("input",{type:"checkbox",checked:this.enabled,onchange:function(){
self.enabled=this.checked;
with (self.node) className=className.toggleWordB(!this.checked,"disabled");
WM.feedManager.save();
}}),
createElement("span",{textContent:this.appName + " (" + this.id + ")"}),
//toolbox
createElement("div",{className:"littleButton oddBlue", title:"Fetch Newer"},[
this.fetchNewerButton=createElement("img",{className:"resourceIcon rssUpRight"+WM.opts.littleButtonSize,onclick:function(){self.fetchNewer();} })
]),
createElement("div",{className:"littleButton", title:"Fetch Older"},[
this.fetchOlderButton=createElement("img",{className:"resourceIcon rssDownLeft"+WM.opts.littleButtonSize,onclick:function(){self.fetchOlder();} })
]),
]),
this.contentNode=createElement("div",{className:"subsection "+(this.expanded?"expanded":"collapsed")},[
createElement("div",{className:"line"},[
createElement("label",{textContent:"Older Limit Reached: ",title:"Reports if this filter has reached the user defined oldest post limit."}),
this.olderLimitNode=createElement("span",{textContent:this.olderLimitReached}),
]),
createElement("div",{className:"line"},[
createElement("label",{textContent:"Newer Edge: ",title:"A Unixtime indicator of the newest post-time you have fetched for this filter."}),
this.newedgeNode=createElement("span",{textContent:this.newedge}),
]),
createElement("div",{className:"line"},[
createElement("label",{textContent:"Older Edge: ",title:"A Unixtime indicator of the oldest post-time you have fetched for this filter."}),
this.oldedgeNode=createElement("span",{textContent:this.oldedge}),
]),
]),
])
);
}catch(e){log("WM.FeedFilter.init:addManagerElement: "+e);};
return self;
}catch(e){log("WM.FeedFilter.init: "+e);}};
//***************************************************************************************************************************************
//***** Feed Class
//***************************************************************************************************************************************
WM.Feed = function(params){try{
this.objType="feed";
params=params||{};
var self=this;
//set defaults
this.enabled=true;
this.expanded=true;
this.url="";
this.id="";
this.filters={};
this.feedName="";
this.isRemoveable=true; //set to false on own feeds
this.title="New Feed";
this._isGlobal=false;
//use passed params
var newFilters=params.filters||{};
delete params.filters;
this.__defineGetter__("isGlobal",function(){try{
return this._isGlobal;
}catch(e){log("WM.Feed.isGlobal: "+e);}});
this.__defineSetter__("isGlobal",function(v){try{
if (!v) {
if (!confirm("Disabling profile sharing on this feed will prevent other users on this machine from loading it. Are you sure you wish to make this feed locally available only?")) return;
}
this._isGlobal=v;
//make sure we have a uniqueID
//but don't destroy one that already exists
if (v && !exists(this.uniqueID)) this.uniqueID = unique();
//change the color/icon of the isGlobal button
if (this.toggleGlobalButton) {
var s=WM.opts.littleButtonSize;
with (this.toggleGlobalButton) className=className.swapWordB(v,"removeGlobal"+s,"addGlobal"+s);
with (this.toggleGlobalButton.parentNode) {
className=className.swapWordB(v,"oddOrange","oddGreen");
title=(v)?"Disable Profile Sharing":"Share With Other Profiles";
}
}
}catch(e){log("WM.Feed.isGlobal: "+e);}});
this.__defineGetter__("saveableData",function(){try{
var ret={};
ret.title=this.title;
ret.enabled=this.enabled;
ret.expanded=this.expanded;
ret.isRemoveable=this.isRemoveable;
ret.url=this.url;
if (this.isRemoveable) ret.id=this.id;
//capture filters
ret.filters={};
for (var f in this.filters) {
ret.filters[f]={
enabled:this.filters[f].enabled,
expanded:this.filters[f].expanded,
id:this.filters[f].id,
};
}
return ret;
}catch(e){log("WM.Feed.saveableData: "+e);}});
for (var p in params) this[p]=params[p];
this.enable=function(){try{
this.enabled=true;
this.node.className=this.node.className.removeWord("disabled");
WM.feedManager.save();
}catch(e){log("WM.Feed.enable: "+e);}};
this.disable=function(){try{
this.enabled=false;
this.node.className=this.node.className.addWord("disabled");
WM.feedManager.save();
}catch(e){log("WM.Feed.disable: "+e);}};
this.toggle=function(){try{
this.enabled=this.toggleNode.checked;
this.node.className=this.node.className.swapWordB(this.enabled,"enabled","disabled");
WM.feedManager.save();
}catch(e){log("WM.Feed.toggle: "+e);}};
//create a filter for a specific app
//filter id must be "app_"+appID
//will not add duplicates
this.addFilter=function(params){try{
var isNew=!exists(params);
params=params||{};
params.parent=this;
//prevent duplicates
if (!exists(this.filters[params.id])) {
return (this.filters[params.id]=new WM.FeedFilter(params));
if (isNew) WM.feedManager.save();
} else {
return this.filters[params.id];
}
}catch(e){log("WM.Feed.addFilter: "+e);}};
//get the extents of the feed by merging all feed filter oldedge/newedge values
this.getMergedEdges=function(params){
/*
apps[]: an array of appID's to test against, otherwise read from all filters
*/
//console.log("getMergedEdges: "+JSON.stringify(params));
var retval = {newedge:Math.round(timeStamp()/1000), oldedge:0};
if (params.apps||null){
for (var c=0,l=params.apps.length;c<l;c++){
var filter = this.filters["app_"+params.apps[c]];
if (filter||null){
//get the youngest older edge and oldest newer edge so we don't lose posts because one feed is more active.
//this forces them to run at the same edges after the first pull
retval.newedge = Math.min(retval.newedge, filter.newedge);
retval.oldedge = Math.max(retval.oldedge, filter.oldedge);
} else {
log("getMergedEdges: no filter matching app_"+params.apps[c]+" on feed " + this.id);
}
}
} else {
for (var name in this.filters){
var filter = this.filters[name];
if (filter||null){
//get the youngest older edge and oldest newer edge so we don't lose posts because one feed is more active.
//this forces them to run at the same edges after the first pull
retval.newedge = Math.min(retval.newedge, filter.newedge);
retval.oldedge = Math.max(retval.oldedge, filter.oldedge);
} else {
log("getMergedEdges: no filter matching "+name+" on feed " + this.id);
}
}
}
return retval;
};
//remove this
this.remove=function(noConfirm){try{
if (this.isRemoveable) {
var ask=WM.opts.feedsConfirmDeleteFeed;
if (noConfirm || (this.isGlobal && confirm("This feed is shared with other profiles. Deleting it here will prevent it from loading for other users. Are you sure you wish to delete this feed and its filters.")) || !ask || (!this.isGlobal && ask && confirm("Delete feed and all of its filters?"))){
//remove my data
if (this.node) remove(this.node);
WM.feedManager.feeds.removeByValue(this);
WM.feedManager.save();
}
}
}catch(e){log("WM.Feed.remove: "+e);}};
//fetch posts for this
this.fetchNewer=function(){try{
WM.fetch({
newer:true,
feeds:[self],
bypassPause:true,
bypassAppDisabled:true,
bypassFeedDisabled:true,
});
}catch(e){log("WM.Feed.fetchNewer: "+e);}};
this.fetchOlder=function(){try{
WM.fetch({
older:true,
feeds:[self],
bypassPause:true,
bypassAppDisabled:true,
bypassFeedDisabled:true,
});
}catch(e){log("WM.Feed.fetchOlder: "+e);}};
this.toggleContent=function(){try{
this.expanded=!this.expanded;
var btnSize=WM.opts.littleButtonSize;
with (this.contentNode)
className=className.swapWordB(this.expanded,"expanded","collapsed");
with (this.toggleImgNode)
className=className.swapWordB(this.expanded,"treeCollapse"+btnSize,"treeExpand"+btnSize);
WM.feedManager.save();
}catch(e){log("WM.Feed.toggleContent: "+e);}};
if (this.id && !this.url) this.url="https://graph.facebook.com/"+this.id+"/feed";
//draw it
try{
WM.console.feedManagerNode.appendChild(
this.node=createElement("div",{className:"listItem "+((this.enabled)?"enabled":"disabled")},[
createElement("div",{className:"line"},[
createElement("div",{className:"littleButton",title:"Toggle Content",onclick:function(){self.toggleContent();}},[
this.toggleImgNode=createElement("img",{className:"resourceIcon "+(this.expanded?"treeCollapse"+WM.opts.littleButtonSize:"treeExpand"+WM.opts.littleButtonSize)}),
]),
this.toggleNode=createElement("input",{type:"checkbox",checked:this.enabled,onchange:function(){
self.enabled=this.checked;
with (self.node) className=className.toggleWordB(!this.checked,"disabled");
WM.feedManager.save();
}}),
this.titleNode=createElement("input",{value:(this.title||""), onchange:function(){self.title=this.value; WM.feedManager.save();}}),
//toolbox
createElement("div",{className:"littleButton oddBlue", title:"Fetch Newer"},[
this.fetchNewerButton=createElement("img",{className:"resourceIcon rssUpRight"+WM.opts.littleButtonSize,onclick:function(){self.fetchNewer();} })
]),
createElement("div",{className:"littleButton", title:"Fetch Older"},[
this.fetchOlderButton=createElement("img",{className:"resourceIcon rssDownLeft"+WM.opts.littleButtonSize,onclick:function(){self.fetchOlder();} })
]),
(this.isRemoveable)?createElement("div",{className:"littleButton oddOrange", title:"Remove Feed"},[
this.removeButtonNode=createElement("img",{className:"resourceIcon trash"+WM.opts.littleButtonSize,onclick:function(){self.remove();} })
]):null,
(this.isRemoveable)?createElement("div",{className:"indent littleButton "+((this.isGlobal)?"oddOrange":"oddGreen"), title:((this.isGlobal)?"Disable Profile Sharing":"Share With Other Profiles")},[
this.toggleGlobalButton=createElement("img",{className:"resourceIcon "+((this.isGlobal)?"removeGlobal":"addGlobal")+WM.opts.littleButtonSize,onclick:function(){self.isGlobal=!self.isGlobal; WM.feedManager.save();}})
]):null,
]),
this.contentNode=createElement("div",{className:"subsection "+(this.expanded?"expanded":"collapsed")},[
(this.isRemoveable)?createElement("div",{className:"line"},[
createElement("label",{textContent:"Target FB Entity: ",title:"The request address from where WM gets posts for this fb entity."}),
this.idNode=createElement("input",{value:(this.id||""), onchange:function(){
self.id=this.value;
self.url="https://graph.facebook.com/"+this.value+"/feed";
self.urlNode.textContent=self.url;
WM.feedManager.save();
}}),
createElement("label",{textContent:"URL: ",title:"The request address from where WM gets posts for this fb entity."}),
this.urlNode=createElement("span",{textContent:this.url}),
]):null,
//app filters sub box
createElement("div",{className:"line"},[
createElement("label",{textContent:"App Filters: ",title:"This is a list of filters run on this feed by apps you collect for. Only filters for sidekick-supported apps are used."}),
this.filtersNode=createElement("div",{className:"subsection"}),
]),
]),
])
);
}catch(e){log("WM.Feed.init:addManagerElement: "+e);};
//add any passed filters
for (var f in newFilters){
this.addFilter(newFilters[f]);
}
return self;
}catch(e){log("WM.Feed.init: "+e);}};
})();