WM Friend Tracker Objects

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

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/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. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址