v 0.2 adds sparkles a bit everywhere where stats apply and fix the style of the graph
[FlickrHacks.git] / _greasemonkey_ / flickrbuddyinteresting.user.js
blob203e277cca90605703318ab63d2b912481920802
1 // ==UserScript==
2 // @name        Flickr Buddy Interesting
3 // @namespace   http://6v8.gamboni.org/
4 // @description Quick access to user's interesting photos from the Buddy Icon Menu
5 // @version        0.3
6 // @identifier  http://6v8.gamboni.org/IMG/js/flickrbuddyinteresting.user.js
7 // @date           2007-06-26
8 // @creator        Pierre Andrews (mortimer.pa@free.fr)
9 // @contributor    Stephen Fernandez ( http://steeev.freehostia.com )
10 // @include http://*flickr.com*
11 // ==/UserScript==
13 // --------------------------------------------------------------------
15 // This is a Greasemonkey user script.
17 // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
18 // Then restart Firefox and revisit this script.
19 // Under Tools, there will be a new menu item to "Install User Script".
20 // Accept the default configuration and install.
22 // --------------------------------------------------------------------
23 // Copyright (C) 2006 Pierre Andrews
24 // 
25 // This program is free software; you can redistribute it and/or
26 // modify it under the terms of the GNU General Public License
27 // as published by the Free Software Foundation; either version 2
28 // of the License, or (at your option) any later version.
29 // 
30 // This program is distributed in the hope that it will be useful,
31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33 // GNU General Public License for more details.
34 // 
35 // The GNU General Public License is available by visiting
36 //   http://www.gnu.org/copyleft/gpl.html
37 // or by writing to
38 //   Free Software Foundation, Inc.
39 //   51 Franklin Street, Fifth Floor
40 //   Boston, MA  02110-1301
41 //   USA
44 (function () {
46         //update information
47         var SCRIPT = {
48                 name: "Flickr Buddy Interesting",
49                 namespace: "http://6v8.gamboni.org/",
50                 description: "Quick access to user's interesting photos from the Buddy Icon Menu",
51                 identifier: "http://6v8.gamboni.org/IMG/js/flickrbuddyinteresting.user.js",
52                 version: "0.3",                                                         // version
53                 date: (new Date("2007-06-26"))          // update date
54                 .valueOf()
55         };
57         
58         function $x1(xpath) {
59                 return document.evaluate(
60                                                                  xpath,
61                                                                  document,
62                                                                  null,
63                                                                  XPathResult.FIRST_ORDERED_NODE_TYPE, null
64                                                                  ).singleNodeValue;
65         }
68         /***********************************************************************
69          * Flickr Localisation
70          **********************************************************************/
72         var FlickrLocaliser = function(locals) {
73                 this.init(locals);
74         }
75         FlickrLocaliser.prototype = {
76                 selectedLang: undefined,
77                 localisations: undefined,
78                 getLanguage: function() {
79                         if(!this.selectedLang) {
80                                 var langA = $x1("//p[@class='LanguageSelector']//a[contains(@class,'selected')]");
81                                 if(langA) {
82                                         var matches = /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA.href);
83                                         if(matches && matches[1]) {
84                                                 this.selectedLang = matches[1];
85                                                 return this.selectedLang;
86                                         }
87                                 }
88                                 return false;
89                         } else return this.selectedLang;
90                 },
92                 init: function(locals) {
93                         this.localisations = locals;
94                 },
96                 localise: function(string, params) {
97                         if(this.localisations && this.getLanguage()) {
98                                 var currentLang = this.localisations[this.selectedLang];
99                                 if(!currentLang) currentLang = this.localisations[this.localisations.defaultLang];
100                                 var local = currentLang[string];
101                                 if(!local) {
102                                         local = this.localisations[this.localisations.defaultLang][string];
103                                 } 
104                                 if(!local) return string;
105                                 for(arg in params) {
106                                         var rep = new RegExp('@'+arg+'@','g');
107                                         local = local.replace(rep,params[arg]);
108                                 }
109                                 local =local.replace(/@[^@]+@/g,'');
110                                 return local;
111                         } else return undefined;
112                 }
114         }
116         /*****************************Flickr Localisation**********************/
118         
119         var localiser =  new FlickrLocaliser({
120                         'en-us' : {
121                                 'pool_interesting' : 'Pool Interestingness',
122                                 'quick_interesting' : 'Quick Interestingness',
123                                 'close' : 'Close'
124                         },
125                         'fr-fr' : {
126                                 'pool_interesting' : 'Interestingness du Groupe',
127                                 'quick_interesting' : 'Interestingness Rapide',
128                                 'close' : 'Fermer'                              
129                         },
130                         'it-it' : {
131                                 'pool_interesting' : 'Interestingness del Gruppo',
132                                 'quick_interesting' : 'Interestingness Rapida',
133                                 'close' : 'Chiudi'
134                         },
135                         defaultLang: 'en-us'
136                 });
137         
138         function M8_log() {
139                 if(unsafeWindow.console)
140                         unsafeWindow.console.log(arguments);
141                 else
142                         GM_log(arguments);
143         }
145         /*
146           Xpath trickery, from:
147           http://ecmanaut.blogspot.com/2006/07/expressive-user-scripts-with-xpath-and.html
148         */
149         function $x( xpath, root )
150                 {
151                         var doc = root ? root.evaluate?root:root.ownerDocument : document;
152                         var got = doc.evaluate( xpath, root||doc, null, 0, null ), next;
153                         var result = [];
154                         while( next = got.iterateNext() )
155                                 result.push( next );
156                         return result;
157                 }
160         function foreach( xpath, cb, root )
161         {
162                 var nodes = $x( xpath, root ), e = 0;
163                 for( var i=0; i<nodes.length; i++ )
164                         e += cb( nodes[i], i ) || 0;
165                 return e;
166         }
170         function getObjectMethodClosure(object, method) {
171                 return function(arg) {
172                         return object[method](arg); 
173                 }
174         }
176         /*
177           LightWeightBox - Thom Shannon
178           http://www.ts0.com
179           V 1.0 2006
180           BSD License
181         */
183         var LightWeightBoxOn=false;
184         var LightWeightBox = function(ele){
185                 this.ele = ele;
186                 this.backgroundColor = '#CCC';
187                 this.opacity = 0.5;
188         }
189         with (LightWeightBox){
190                 prototype.Render = function(){
191                         if (!LightWeightBoxOn){
192                                 bgDiv = document.createElement('div');
193                                 bgDiv.innerHTML = ''
194                                 bgDiv.style.backgroundColor = this.backgroundColor;
195                                 bgDiv.style.position='fixed';
196                                 bgDiv.style.height='100%';
197                                 bgDiv.style.width='100%';
198                                 bgDiv.style.top=0;
199                                 bgDiv.style.left='0';
200                                 bgDiv.style.opacity=this.opacity;
201                                 this.ele.style.position='fixed';
202                                 this.bgDiv=bgDiv;
203                                 document.body.appendChild(this.bgDiv);
204                                 document.body.appendChild(this.ele);
205                                 this.CheckSize();
206                                 LightWeightBoxOn = true;
207                                 var oSelf=this;
208                                 this.sizeCheck = setInterval(function(){oSelf.CheckSize();},20);
209                         }
210                 }
211                 prototype.CheckSize = function(){
212                         if (this.ele.offsetHeight!=this.currentHeight) {
213                                 this.offsetTop = (self.innerHeight/2)-(this.ele.offsetHeight/2);
214                                 this.ele.style.top = this.offsetTop+'px';
215                                 this.currentHeight=this.ele.offsetHeight;
216                         }
217                         if (this.ele.offsetWidth!=this.currentWidth) {
218                                 this.offsetLeft = (self.innerWidth/2)-(this.ele.offsetWidth/2);
219                                 this.ele.style.left = this.offsetLeft+'px';
220                                 this.currentWidth=this.ele.offsetWidth;
221                         }
222                 }
224                 prototype.Close=function(oSelf){
225                         document.body.removeChild(oSelf.bgDiv);
226                         document.body.removeChild(oSelf.ele);
227                         LightWeightBoxOn = false;
228                 }
229         }
233         var flickrbuddyinteresting = function() {this.init();}
235         flickrbuddyinteresting.prototype = {
236                 init: function() {
237                         var menu = document.getElementById('personmenu_contacts_link');
238                         if(menu) {
239                                 var link =document.createElement('a');
240                                 link.setAttribute('class','block');
241                                 link.setAttribute('id','tag_person_link');
242                                 link.setAttribute('href','javascript:;');
243                                 link.addEventListener('click',getObjectMethodClosure(this,'showInteresting'),true);
244                                 link.textContent=localiser.localise('quick_interesting');
245                           
246                                 menu.parentNode.insertBefore(link,menu.nextSibling);
247                         }
249                         if(document.location.href.match(/\/groups\//) && unsafeWindow.document.getElementById('SubNav')) {
250                                 psi=$x1('//p[@class="Links"]');
251                                 psi.innerHTML+=' <img src="/images/subnavi_dots.gif" alt="" height="11" width="1"> ';
252                                 var link =document.createElement('a');
253                                 link.setAttribute('class','block');;
254                                 link.setAttribute('href','javascript:;');
255                                 link.addEventListener('click',getObjectMethodClosure(this,'showInteresting'),true);
256                                 link.textContent=localiser.localise('pool_interesting');
257                                 psi.appendChild(link);
259                         }
261                 },
262                 
263                 showInteresting: function(ev) {
264                         // create a block element of some kind
265                         var boxEle = document.createElement('div');
266                         var ul = boxEle.appendChild(document.createElement('ul'));      
267                         // style it up with a class or inline
268                         boxEle.className = 'popup';
269                         // create something to act as a close button
270                         btnClose = document.createElement('a');
271                         btnClose.href='javascript:;';
272                         btnClose.innerHTML=localiser.localise('close');
273                         // add close button to block element
274                         boxEle.appendChild(btnClose);
275                         // create box with block element
276                         var lwBox = new LightWeightBox(boxEle);
277                         // optional bg color and opacity
278                         boxEle.style.paddingTop= '20px';
279                         boxEle.style.width= (75*5+20)+'px';
280                         boxEle.style.height= (75*5+40)+'px';
281                         boxEle.style.backgroundColor = '#333';
282                         // attach close event and add your own code
283                         btnClose.addEventListener('click',function(){
284                                         // you have to pass box object into event
285                                         // because of the js event scoping
286                                         lwBox.Close(lwBox);
287                                         // false to cancel link
288                                         return false;
289                                 },true);
290                         btnClose.setAttribute('style','background-color:#CCC;');
291                         
292                         ul.setAttribute('style','margin:0;padding:0;list-style-type:none;');
293                         var self = this;
294                         var listener = {
295                                 flickr_photos_search_onLoad: function(success, responseXML, responseText, params){
296                                         try{
297                                                 var rsp = responseText.replace(/jsonFlickrApi\(/,'');
298                                                 rsp = eval('('+rsp);
299                                                 if(rsp.stat == 'ok') {
300                                                         var i=0;
301                                                         var html = '';
302                                                         for(i=0;i<rsp.photos.photo.length;i++) {
303                                                                 var photo = rsp.photos.photo[i];
304                                                                 html += '<li style="margin:0;padding:0;display:inline;"><a href="http://www.flickr.com/photos/'+photo.owner+'/'+photo.id+'/"><img title="&quot;' + photo.title + '&quot; by ' +  photo.ownername + '" src="http://farm'+photo.farm+'.static.flickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'_s.jpg" width="75" height="75"/></a></li>';
305                                                         }
306                                                         ul.innerHTML = html;
307                                                         // render it!
308                                                         lwBox.Render();
309                                                 } else
310                                                         M8_log("Error2 "+responseText);                                                 
311                                         } catch (e) {
312                                                 M8_log("Error1 "+responseText);
313                                                 M8_log(e);
314                                         }
315                                 }
316                         };
318                         var block = ev.target.parentNode;
319                         var matches = /messages_write\.gne\?to=([^"]*)"/.exec(block.innerHTML);
320                                                                                                          if(matches)
321                                                                                                                  unsafeWindow.F.API.callMethod('flickr.photos.search', {
322                                                                                                                                  user_id: matches[1], sort: 'interestingness-desc', page:1, per_page: 25,
323                                                                                                                                          format: 'json', extras: 'owner_name'
324                                                                                                                                          }, listener);  
326                                                                                                          if(ev.target.textContent==localiser.localise('pool_interesting')) {
327                                                                                                                  thegroupid=unsafeWindow.document.getElementById('SubNav').innerHTML.split('\/buddyicons\/')[1].split('\.jpg')[0];
328                                                                                                                  unsafeWindow.F.API.callMethod('flickr.photos.search', {
329                                                                                                                                  group_id: thegroupid , sort: 'interestingness-desc', page:1, per_page: 25,
330                                                                                                                                          format: 'json', extras: 'owner_name'
331                                                                                                                                          }, listener);  
332                                                                                                          }
333                                                                                                          }
334                                                                                                         }
335                         //======================================================================
336                         // launch
337                         try {
338                                 window.addEventListener("load", function () {
339                                                 try {
340                                                                                 
341                                                         // update automatically (http://userscripts.org/scripts/show/2296)
342                                                         win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
343                                                 } catch (ex) {} 
344                                                                         
345                                                 var flickrgp = new flickrbuddyinteresting();
346                                         }, false);
347                         } catch (ex) {}
348                 })();