WM Friend Tracker Objects

This is the friend tracker system which is created under the WM version 4.x script

Ovu skriptu ne treba izravno instalirati. To je biblioteka za druge skripte koje se uključuju u meta direktivu // @require https://update.greatest.deepsurf.us/scripts/6897/27562/WM%20Friend%20Tracker%20Objects.js

  1. // ==UserScript==
  2. // @name WM Friend Tracker Objects
  3. // @namespace MerricksdadWMFriendTrackerObjects
  4. // @description This is the friend tracker system which is created under the WM version 4.x script
  5. // @license http://creativecommons.org/licenses/by-nc-nd/3.0/us/
  6. // @version 4.0.0.0
  7. // @copyright Charlie Ewing except where noted
  8. // ==/UserScript==
  9.  
  10. //this script requires some functions in the WM Common Library
  11. //this script needs access to a pre-defined JSON object
  12.  
  13.  
  14. (function(){
  15.  
  16. //***************************************************************************************************************************************
  17. //***** Friend Objects
  18. //***************************************************************************************************************************************
  19. WM.friendTracker = {
  20. friends: {},
  21. init : function(){
  22. //import friends tracker data
  23. var friendsIn=getOptJSON('friends_'+WM.currentUser.profile)||[];
  24. if (isArrayAndNotEmpty(friendsIn)) for (var f=0,len=friendsIn.length;f<len;f++) {
  25. WM.friendTracker.newFriend(friendsIn[f],true);
  26. }
  27. WM.friendTracker.sort();
  28. },
  29. clean : function(){
  30. //clean friend tracker data
  31. var len=0;
  32. if (WM.opts.useFriendTracker && (len=WM.friendTracker.friends.length)) {
  33. var ageDays=WM.opts.trackDays*day;
  34. var timeNow=timeStamp();
  35. for (var f=0; f<len; f++){
  36. var friend=WM.friendTracker.friends[f];
  37. if (friend.data && friend.data.posts){
  38. for (var p in friend.data.posts){
  39. var post=friend.data.posts[p];
  40. if ((timeNow-(post.date*1000)) > ageDays) {
  41. delete friend.data.posts[p];
  42. }
  43. }
  44. }
  45. }
  46. }
  47. },
  48. clearAll : function(noConfirm){
  49. var ask=WM.opts.trackConfirmClearUser;
  50. if (noConfirm || !ask || (ask && confirm("Clear tracker history for all users?"))){
  51. for (var f in WM.friendTracker.friends){
  52. WM.friendTracker.friends[f].remove(true);
  53. }
  54. }
  55. },
  56. newFriend : function(params,preventSort){
  57. params=params||{};
  58. var friend = new WM.Friend(params);
  59. WM.friendTracker.friends[friend.id]=friend;
  60. if (!preventSort) WM.friendTracker.sort();
  61. return friend;
  62. },
  63.  
  64. save :function(){
  65. var ret=[];
  66. for (var f in WM.friendTracker.friends){
  67. ret.push(WM.friendTracker.friends[f].saveableData);
  68. }
  69. setOptJSON("friends_"+WM.currentUser.profile,ret);
  70. },
  71. sort : function(params){
  72. params=params||{};
  73. if (exists(params.sortBy)) WM.quickOpts.sortFriendsBy=params.sortBy;
  74. if (exists(params.sortOrder)) WM.quickOpts.sortFriendsOrder=params.sortOrder;
  75. WM.saveQuickOpts();
  76.  
  77. var sortBy=params.sortBy||WM.quickOpts.sortFriendsBy||"name"
  78. var sortOrder=params.sortOrd||WM.quickOpts.sortFriendsOrder||"asc"
  79. var friendArray=[];
  80. for (var f in WM.friendTracker.friends) {
  81. friend=WM.friendTracker.friends[f];
  82. friendArray.push({id:friend[sortBy],node:friend.node});
  83. }
  84. if (["asc","ascending"].inArray(sortOrder)) friendArray.sort(function(a,b){return a.id>b.id;});
  85. else if (["desc","descending"].inArray(sortOrder)) friendArray.sort(function(a,b){return a.id<b.id;});
  86. for (var f=0,len=friendArray.length; f<len; f++) {
  87. WM.console.friendBuild.appendChild(friendArray[f].node);
  88. }
  89. },
  90. track : function(post){
  91. //dont track stuff older than our older tracking limit
  92. var limit=WM.opts.trackTime*day;
  93. if ( ( timeStamp()-(post.date*1000) ) < limit ) {
  94. //get/create the friend record
  95. var friend=WM.friendTracker.friends[post.fromID]||null;
  96. if (!friend) {
  97. friend=WM.friendTracker.newFriend({id:post.fromID,name:post.fromNameLastFirst});
  98. }
  99. //check if this is newer than last known post
  100. if (WM.opts.trackLastKnownPost) {
  101. var data=friend.lastKnownPost;
  102. if (data) {
  103. if (data.date<post.date){
  104. data.date=post.date;
  105. //data.id=post.id.removePrefix(post.fromID+"_");
  106. }
  107. } else {
  108. friend.data.lastKnownPost={date:post.date};
  109. }
  110. }
  111. //add it to history
  112. if (WM.opts.trackCreated){
  113. var data={date:post.date};
  114. if (WM.opts.trackFailed){
  115. data.failed=(post.status<0 && post.status !=-4 && post.status !=-6);
  116. }
  117. if (WM.opts.trackAccepted){
  118. data.accepted=(post.status>0 || post.status ==-4 || post.status ==-6);
  119. }
  120. friend.data.posts[post.id.removePrefix(post.fromID+"_")]=data;
  121. }
  122. //save it
  123. friend.updateStats();
  124. WM.friendTracker.save();
  125. //push events
  126. WM.rulesManager.doEvent("onFriendDataChanged",friend);
  127. }
  128. },
  129. trackStatus : function(post,acceptOrFail){
  130. var friend=WM.friendTracker.friends[post.fromID]||null;
  131. if (friend) {
  132. var data=friend.data.posts[post.id.removePrefix(post.fromID+"_")]||null;
  133. if (data){
  134. if (acceptOrFail) {
  135. data.accepted=true;
  136. delete data.failed;
  137. } else {
  138. data.failed=true;
  139. delete data.accepted;
  140. }
  141. friend.updateStats();
  142. WM.rulesManager.doEvent("onFriendDataChanged",friend);
  143. } else {
  144. debug.print("post does not exist under friend");
  145. //if post does not exists, we had more errors elsewhere
  146. //or post id not fit our history range
  147. }
  148. } else {
  149. debug.print("friend does not exist for this post");
  150. //if friend does not exist, we had errors elsewhere
  151. //don't bother fixing it here
  152. }
  153. },
  154. };
  155.  
  156. //***************************************************************************************************************************************
  157. //***** Friend Class
  158. //***************************************************************************************************************************************
  159. WM.Friend = function(params){try{
  160. this.objType="friend";
  161. params=params||{};
  162. var self=this;
  163.  
  164. //set defaults
  165. this.expanded=false;
  166. this.id="";
  167. this.name="";
  168. this.data={
  169. lastKnownPost:{date:0},
  170. posts:{},
  171. };
  172.  
  173. this.__defineGetter__("saveableData",function(){try{
  174. var ret={};
  175. ret.id=this.id;
  176. ret.name=this.name;
  177. ret.enabled=this.enabled;
  178. ret.expanded=this.expanded;
  179. //capture posts data
  180. ret.data=this.data;
  181. return ret;
  182. }catch(e){log("WM.Friend.saveableData: "+e);}});
  183. for (var p in params) this[p]=params[p];
  184.  
  185. //remove this
  186. this.remove=function(noConfirm){try{
  187. var ask=WM.opts.trackConfirmClearUser;
  188. if (noConfirm || !ask || (ask && confirm("Clear history for this user?"))){
  189. //remove my data
  190. if (this.node) remove(this.node);
  191. delete WM.friendTracker.friends[this.id];
  192. WM.friendTracker.save();
  193. }
  194. }catch(e){log("WM.Friend.remove: "+e);}};
  195.  
  196. this.toggleContent=function(){try{
  197. this.expanded=!this.expanded;
  198. var btnSize=WM.opts.littleButtonSize;
  199. with (this.contentNode)
  200. className=className.swapWordB(this.expanded,"expanded","collapsed");
  201. with (this.toggleImgNode)
  202. className=className.swapWordB(this.expanded,"treeCollapse"+btnSize,"treeExpand"+btnSize);
  203. WM.friendTracker.save();
  204. }catch(e){log("WM.Friend.toggleContent: "+e);}};
  205. this.addToFeeds=function(){try{
  206. WM.feedManager.newFeed({id:this.id, title:this.name});
  207. WM.feedManager.save();
  208. }catch(e){log("WM.Friend.addToFeeds: "+e);}};
  209. this.countAccepted=function(){try{
  210. var c=0;
  211. if (this.data.posts) for (var p in this.data.posts) {
  212. var post=this.data.posts[p];
  213. if (post.accepted) c++;
  214. }
  215. return c;
  216. }catch(e){log("WM.Friend.countAccepted: "+e);}};
  217.  
  218. this.countFailed=function(){try{
  219. var c=0;
  220. if (this.data.posts) for (var p in this.data.posts) {
  221. var post=this.data.posts[p];
  222. if (post.failed) c++;
  223. }
  224. return c;
  225. }catch(e){log("WM.Friend.countFailed: "+e);}};
  226.  
  227. this.countCreated=function(){try{
  228. var c=0;
  229. if (this.data.posts) for (var p in this.data.posts) {
  230. c++
  231. }
  232. return c;
  233. }catch(e){log("WM.Friend.countFailed: "+e);}};
  234.  
  235. this.__defineGetter__("lastKnownPost",function(){try{
  236. if (this.data && (this.data.lastKnownPost||null)){
  237. return this.data.lastKnownPost;
  238. }
  239. return {id:null,date:0};
  240. }catch(e){log("WM.Friend.lastKnownPost: "+e);}});
  241. this.__defineGetter__("lastKnownPostDate",function(){try{
  242. if (this.data && (this.data.lastKnownPost||null)){
  243. return this.data.lastKnownPost.date;
  244. }
  245. return 0;
  246. }catch(e){log("WM.Friend.lastKnownPostDate: "+e);}});
  247. this.__defineGetter__("acceptCount",function(){try{
  248. return this.countAccepted();
  249. }catch(e){log("WM.Friend.acceptCount: "+e);}});
  250. this.__defineGetter__("failCount",function(){try{
  251. return this.countFailed();
  252. }catch(e){log("WM.Friend.failCount: "+e);}});
  253. this.__defineGetter__("postCount",function(){try{
  254. return this.countCreated();
  255. }catch(e){log("WM.Friend.postCount: "+e);}});
  256. this.__defineGetter__("totalCount",function(){try{
  257. return this.failCount+this.acceptCount;
  258. }catch(e){log("WM.Friend.totalCount: "+e);}});
  259. this.updateStats=function(){try{
  260. var n=this.statsNode;
  261. if (n) {
  262. if (WM.opts.trackLastKnownPost){
  263. d=new Date(((this.lastKnownPost.date*1000)||0)).toLocaleString();
  264. if (!this.lastPostNode) {
  265. n.appendChild(createElement("div",{className:"line"},[
  266. createElement("label",{textContent:"Last Known Post Date: "}),
  267. this.lastPostNode=createElement("span",{textContent:d})
  268. ]));
  269. } else {
  270. this.lastPostNode.textContent=d;
  271. }
  272. }
  273.  
  274. if (WM.opts.trackCreated){
  275. if (!this.countCreatedNode) {
  276. n.appendChild(createElement("div",{className:"line"},[
  277. createElement("label",{textContent:"Posts Created: "}),
  278. this.countCreatedNode=createElement("span",{textContent:this.countCreated()})
  279. ]));
  280. } else {
  281. this.countCreatedNode.textContent=this.countCreated();
  282. }
  283. }
  284. if (WM.opts.trackAccepted){
  285. if (!this.countAcceptedNode){
  286. n.appendChild(createElement("div",{className:"line"},[
  287. createElement("label",{textContent:"Posts Accepted: "}),
  288. this.countAcceptedNode=createElement("span",{textContent:this.countAccepted()})
  289. ]));
  290. } else {
  291. this.countAcceptedNode.textContent=this.countAccepted();
  292. }
  293. }
  294. if (WM.opts.trackFailed){
  295. if (!this.countFailedNode){
  296. n.appendChild(createElement("div",{className:"line"},[
  297. createElement("label",{textContent:"Posts Failed: "}),
  298. this.countFailedNode=createElement("span",{textContent:this.countFailed()})
  299. ]));
  300. } else {
  301. this.countFailedNode.textContent=this.countFailed();
  302. }
  303. }
  304. }
  305. }catch(e){log("WM.Friend.updateStats: "+e);}};
  306. //draw it
  307. try{
  308. WM.console.friendBuild.appendChild(
  309. this.node=createElement("div",{className:"listItem"},[
  310. createElement("div",{className:"line"},[
  311. createElement("div",{className:"littleButton",title:"Toggle Content",onclick:function(){self.toggleContent();}},[
  312. this.toggleImgNode=createElement("img",{className:"resourceIcon "+(this.expanded?"treeCollapse"+WM.opts.littleButtonSize:"treeExpand"+WM.opts.littleButtonSize)}),
  313. ]),
  314. this.titleNode=createElement("input",{value:(this.name||""), onchange:function(){self.name=this.value; WM.friendTracker.save();}}),
  315. //toolbox
  316. createElement("div",{className:"littleButton", title:"Add To Feeds"},[
  317. createElement("img",{className:"resourceIcon addFeed"+WM.opts.littleButtonSize,onclick:function(){self.addToFeeds();} })
  318. ]),
  319. createElement("div",{className:"littleButton oddOrange", title:"Clear Data"},[
  320. createElement("img",{className:"resourceIcon trash"+WM.opts.littleButtonSize,onclick:function(){self.remove();} })
  321. ]),
  322. createElement("div",{onclick:function(){window.open("http://www.facebook.com/profile.php?id="+self.id,"_blank");},title:"Visit Wall",className:"littleButton oddBlue"},[
  323. createElement("img",{className:"resourceIcon openInNewWindow"+WM.opts.littleButtonSize})
  324. ]),
  325. ]),
  326. this.contentNode=createElement("div",{className:"subsection "+(this.expanded?"expanded":"collapsed")},[
  327. createElement("div",{className:"line"},[
  328. createElement("label",{textContent:"ID: ",title:"The facebook id of this user."}),
  329. createElement("span",{textContent:self.id}),
  330. ]),
  331. //post data sub box
  332. createElement("div",{className:"line"},[
  333. createElement("label",{textContent:"Statistics: ",title:"Statistics you selected to track."}),
  334. this.statsNode=createElement("div",{className:"subsection"}),
  335. ]),
  336. ]),
  337. ])
  338. );
  339. }catch(e){log("WM.Friend.init:addManagerElement: "+e);};
  340.  
  341. this.updateStats();
  342. return self;
  343. }catch(e){log("WM.Friend.init: "+e);}};
  344.  
  345. })();