fixed sets... added support for user tags
[FlickrHacks.git] / _greasemonkey_ / flickrupcomingevent.user.js
blob2e7f462d107f899c8bb095fc446af4084a54e8b3
1 // ==UserScript==
2 // @name Flickr Upcoming Event
3 // @namespace http://6v8.gamboni.org/
4 // @description This is a greasemonkey script to enhance flickr pages and be able to easilly associate photos with an upcoming event. When a shot is associated to an event, it can then be tagged and located from the data provided by the event.
5 // @version 0.7
6 // @identifier http://6v8.gamboni.org/IMG/js/flickrupcomingevent.user.js
7 // @date 2007-06-26
8 // @creator Pierre Andrews (mortimer.pa@free.fr) , pt translation by Perla* <http://www.flickr.com/photos/bobnperla/>
9 // @include http://*flickr.com/photos/*/*
10 // @exclude http://*flickr.com/photos/organize*
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
43 var DEBUG = false;
44 var UPCOMING_API_URL = 'http://upcoming.yahooapis.com/services/rest/';
46 (function () {
49 //update information
50 var SCRIPT = {
51 name: "Flickr Upcoming Event",
52 namespace: "http://6v8.gamboni.org/",
53 description: "This is a greasemonkey script to enhance flickr pages and be able to easilly associate photos with an upcoming event. When a shot is associated to an event, it can then be tagged and located from the data provided by the event.",
54 identifier: "http://6v8.gamboni.org/IMG/js/flickrupcomingevent.user.js",
55 version: "0.7", // version
56 date: (new Date("2007-06-28")) // update date
57 .valueOf()
61 Path to wrap descriptions by Johan Sundstr�m
62 http://www.lysator.liu.se/~jhs/
64 function wbr( html ) {
65 return (''+html).replace( /[-\/_.]|\w{20}/g,
66 function( c ){ return c+'<wbr/>'; } );
69 function M8_log() {
70 if(unsafeWindow.console)
71 unsafeWindow.console.log(arguments);
72 else
73 GM_log(arguments);
76 function getObjectMethodClosure01(object, method,arg1) {
77 return function(arg) {
78 return object[method](arg1);
83 function getObjectMethodClosure03(object, method,arg1,arg2,arg3) {
84 return function(arg) {
85 return object[method](arg1,arg2,arg3);
89 function getObjectMethodClosure11(object, method,arg1) {
90 return function(arg) {
91 return object[method](arg,arg1);
94 function getObjectMethodClosure12(object, method,arg1,arg2) {
95 return function(arg) {
96 return object[method](arg,arg1,arg2);
99 function getObjectMethodClosure13(object, method,arg1,arg2,arg3) {
100 return function(arg) {
101 return object[method](arg,arg1,arg2,arg3);
105 function $x1(xpath) {
106 return document.evaluate(
107 xpath,
108 document,
109 null,
110 XPathResult.FIRST_ORDERED_NODE_TYPE, null
111 ).singleNodeValue;
115 /***********************************************************************
116 * Flickr Localisation
117 **********************************************************************/
119 var FlickrLocaliser = function(locals) {
120 this.init(locals);
122 FlickrLocaliser.prototype = {
123 selectedLang: undefined,
124 localisations: undefined,
125 getLanguage: function() {
126 if(!this.selectedLang) {
127 var langA = $x1("//p[@class='LanguageSelector']//a[contains(@class,'selected')]");
128 if(langA) {
129 var matches = /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA.href);
130 if(matches && matches[1]) {
131 this.selectedLang = matches[1];
132 return this.selectedLang;
135 return false;
136 } else return this.selectedLang;
139 init: function(locals) {
140 this.localisations = locals;
143 localise: function(string, params) {
144 if(this.localisations && this.getLanguage()) {
145 var currentLang = this.localisations[this.selectedLang];
146 if(!currentLang) currentLang = this.localisations[this.localisations.defaultLang];
147 var local = currentLang[string];
148 if(!local) {
149 local = this.localisations[this.localisations.defaultLang][string];
151 if(!local) return string;
152 for(arg in params) {
153 var rep = new RegExp('@'+arg+'@','g');
154 local = local.replace(rep,params[arg]);
156 local =local.replace(/@[^@]+@/g,'');
157 return local;
158 } else return undefined;
163 /*****************************Flickr Localisation**********************/
166 var flickrupcomingevent = function() {this.init();}
168 flickrupcomingevent.prototype = {
169 UPCOMING_API_KEY: '684909d568',
170 tagged: false,
171 canTag: false,
172 upcoming_token: GM_getValue('upcoming_token'),
173 upcoming_user_name: GM_getValue('upcoming_user_name'),
174 upcoming_user_username: GM_getValue('upcoming_user_username'),
175 upcoming_user_id: GM_getValue('upcoming_user_id'),
177 event_id: '',
178 events: {},
179 localiser: new FlickrLocaliser({
180 'en-us': {
181 'script_title' : 'Upcoming.org event tool',
182 'auth_1' : 'You first have to authorize the connection with upcoming. First go ',
183 'auth_2' : 'When you are done, come back to this page and',
184 'auth_3' : 'Enter the frob given by upcoming here',
185 'finish_auth' : 'Finish authorization',
186 'loading_details' : 'Getting event details',
187 'fetch_events' : 'Fetching events',
188 'event' : 'Event',
189 'metro' : 'Metro',
190 'searching' : 'searching',
191 'venue' : 'Venue',
192 'description' : 'Description',
193 'see_other' : '<b>See other photos</b> from this event by: @this_user@, @everyone@',
194 'this_user' : 'This User',
195 'everyone' : 'Everyone',
196 'geotag' : 'geotag this photo',
197 'Tag' : 'Tag',
198 'select_event' : 'Select the event this photo was taken at',
199 'error' : 'There was an error, please see the console for details.'
201 'fr-fr': {
202 // T
203 'Tag' : 'Tagger',
204 // A
205 'auth_1' : 'Vous devez d\'abord autoriser la connection avec upcoming.org. Commencez par',
206 'auth_2' : 'Quand vous avez fini, revenez sur cette page et',
207 'auth_3' : 'Entrez le frob donn&eacute; par upcoming.org ici',
208 // D
209 'description' : 'Description',
210 // E
211 'error' : 'Il y a eu une erreur, veillez consulter les logs pour plus de d&eacute;tails.',
212 'event' : '&Eacute;v&egrave;nement',
213 'everyone' : 'Tous le monde',
214 // F
215 'fetch_events' : 'R&eacute;cup&eacute;ration des &eacute;v&egrave;nements',
216 'finish_auth' : 'Finir l\'autorisation',
217 // G
218 'geotag' : 'Geotagger cette photo',
219 // L
220 'loading_details' : 'R&eacute;cup&eacute;ration des d&eacute;tails de l\'&eacute;v&egrave;nement',
221 // M
222 'metro' : 'Metro',
223 // S
224 'script_title' : 'Outil des &eacute;v&egrave;nements Upcoming.org',
225 'searching' : 'En Recherche',
226 'see_other' : '<b>Voir les autres photos</b> de cet &eacute;v&egrave;nement par: @this_user@, @everyone@',
227 'select_event' : 'S&eacute;lectionner l\'&eacute;v&egrave;nement auquel la photo a &eacute;t&eacute; prise',
228 // T
229 'this_user' : 'Cet Utilisateur',
230 // V
231 'venue' : 'Lieu'
233 'pt-br': {// T
234 'Tag' : 'R&oacute;tulo',
235 // A
236 'auth_1' : 'Primeiro voc&ecirc; tem que autorizar a conex&atilde;o com o "upcoming". Primeiro v&aacute;',
237 'auth_2' : 'Quando terminar, volte para esta p&aacute;gina e',
238 'auth_3' : 'Digite aqui o "frob" dado pelo "upcoming"',
239 // D
240 'description' : 'Descri&ccedil;&atilde;o',
241 // E
242 'error' : 'Houve um erro, por favor veja o console para detalhes',
243 'event' : 'Evento',
244 'everyone' : 'Todas as pessoas',
245 // F
246 'fetch_events' : 'Procurando eventos',
247 'finish_auth' : 'Fim da Autoriza&ccedil;&atilde;o',
248 // G
249 'geotag' : '"geotag" esta foto',
250 // L
251 'loading_details' : 'Pegando detalhes do evento',
252 // M
253 'metro' : 'Metro',
254 // S
255 'script_title' : 'Ferramenta do evento "Upcoming.org"',
256 'searching' : 'Buscando',
257 'see_other' : '<b>Veja outras fotos</b> deste evento feitas por: @this_user@, @everyone@',
258 'select_event' : 'Selecione o evento onde esta foto foi tirada',
259 // T
260 'this_user' : 'Este usu&aacute;rio',
261 // V
262 'venue' : 'Local'
265 defaultLang: 'en-us'
268 init: function() {
270 if(unsafeWindow.page_photo_id) {
271 var privacy_and_upcoming = document.evaluate(
272 "//p[@class='Privacy']",
273 document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
274 ).singleNodeValue;
276 var div;
277 var links = privacy_and_upcoming.getElementsByTagName('a');
278 if(links.length > 0) {
279 for(var i = 0; i < links.length; i++) {
280 link = links[i];
281 var matches;
282 if(matches = /http:\/\/upcoming.org\/event\/([0-9]+)/.exec(link.href)) {
283 this.tagged = true;
284 this.event_id = matches[1];
285 break;
288 link.parentNode.appendChild(document.createElement('br'));
289 div = link.parentNode.appendChild(document.createElement('div'));
290 } else {
291 privacy_and_upcoming.appendChild(document.createElement('br'));
292 div = privacy_and_upcoming.appendChild(document.createElement('div'));
294 if(!this.upcoming_token) {
295 var img = div.appendChild(document.createElement('img'));
296 img.align="left";
297 img.alt=this.localiser.localiser("script_title");
298 img.src="/images/icon_upcoming_over.gif";
299 div.appendChild(document.createTextNode(this.localiser.localise('auth_1')));
300 var a = div.appendChild(document.createElement('a'));
301 a.innerHTML = 'here';
302 a.target = 'blank';
303 a.href= 'http://upcoming.org/services/auth/?api_key='+this.UPCOMING_API_KEY;
304 div.appendChild(document.createTextNode('. '+this.localiser.localise('auth_2')+':'));
305 div.appendChild(document.createElement('br'));
306 var label = div.appendChild(document.createElement('label'));
307 label.htmlFor = 'upcoming_frob';
308 label.innerHTML = this.localiser.localise('auth_3');
309 var input = div.appendChild(document.createElement('input'));
310 input.id = 'upcoming_frob';
311 var button = document.createElement('button');
312 button.type = 'button';
313 button.innerHTML = this.localiser.localise('finish_auth');
314 button.addEventListener('click',getObjectMethodClosure01(this,'finishAuth',input),true);
315 button.className = 'SmallButt';
316 div.appendChild(button);
317 } else {
318 this.upcomingAuthenticated(div);
323 finishAuth: function(input) {
324 this.makeUpcomingCall('auth.getToken',{frob: input.value},getObjectMethodClosure11(this,'authDone',input.parentNode),getObjectMethodClosure11(this,'authError',input.parentNode));
327 authDone: function(rsp,div) {
328 this.upcoming_token = ''+rsp.token.@token;
329 this.upcoming_user_username = ''+rsp.token.@user_username;
330 this.upcoming_user_name = ''+rsp.token.@user_name;
331 this.upcoming_user_id = ''+rsp.token.@user_id;
333 GM_setValue('upcoming_token',this.upcoming_token);
334 GM_setValue('upcoming_user_username',this.upcoming_user_username);
335 GM_setValue('upcoming_user_name',this.upcoming_user_name);
336 GM_setValue('upcoming_user_id',this.upcoming_user_id);
338 this.upcomingAuthenticated(div);
341 authError: function(msg,div) {
342 GM_setValue('upcoming_token','');
345 upcomingAuthenticated: function(div) {
346 if(!this.tagged) {
347 for each(tag in unsafeWindow.global_photos[unsafeWindow.page_photo_id].tags_rawA) {
348 if(tag.indexOf('upcoming:') >= 0) {
349 this.tagged = true;
350 this.event_id = tag.replace('upcoming:','').replace(':','=');
354 var tagger = document.getElementById('tagadder');
355 if(tagger) {
356 this.canTag = true;
358 if(this.tagged) {
359 div.innerHTML = '<img id="flickrphotocompass_wait" src="http://www.flickr.com/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" /> '+this.localiser.localise('loading_details')+'.';
360 this.makeUpcomingCall('event.getInfo',{event_id:this.event_id},getObjectMethodClosure11(this,'eventInfoReceived',div),getObjectMethodClosure11(this,'standard_error',div));
361 } else {
362 if(this.canTag) {
363 div.innerHTML = '<img id="flickrphotocompass_wait" src="http://www.flickr.com/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" /> '+this.localiser.localise('fetch_events')+'.';
364 this.makeUpcomingCall('user.getWatchlist',{user_id:this.upcoming_user_id,show:'past'},getObjectMethodClosure11(this,'eventListDetailedReceived',div),getObjectMethodClosure11(this,'standard_error',div));
369 eventInfoReceived: function(rsp,div) {
370 var event = rsp.event;
371 if(event != undefined) {
372 this.events[event.@id] = {id:event.@id,
373 username:event.@username,
374 status:event.@status,
375 name: event.@name,
376 tags: event.@tags,
377 description: event.@description,
378 start_date: event.@start_date,
379 end_date: event.@end_date,
380 start_time: event.@start_time,
381 end_time: event.@end_time,
382 personal: event.@personal,
383 metro_id: event.@metro_id,
384 venue_id: event.@venue_id,
385 user_id: event.@user_id,
386 category_id: event.@category_id,
387 latitude: event.@latitude,
388 longitude: event.@longitude,
389 geocoding_precision: event.@geocoding_precision,
390 geocoding_ambiguous: event.@geocoding_ambiguous
392 this.displayEventInfo(div);
393 } else M8_log(event);
397 autoTag: function(tags) {
398 unsafeWindow.tagrs_addTag(unsafeWindow.page_photo_id,tags);
401 displayEventInfo: function(div) {
402 div.innerHTML = '';
403 div.setAttribute('style','position:relative;left:-18px;');
404 event = this.events[this.event_id];
405 var ul = div.appendChild(document.createElement('ul'));
406 ul.setAttribute('style',"margin: 0 24px;list-style-image:url(/images/icon_upcoming_over.gif);");
408 var li = ul.appendChild(document.createElement('li'));
409 li.className="Stats";
410 li.innerHTML = '<b>'+this.localiser.localise('event')+':</b> <a href="http://www.upcoming.org/event/'+event.id+'">'+event.name+'</a> ';
411 if(this.canTag) {
412 var a = li.appendChild(document.createElement('a'));
413 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
414 a.href="javascript:;";
415 a.innerHTML = '[+]';
416 a.addEventListener('click',getObjectMethodClosure01(this,'autoTag','"'+event.name+'"'),true);
419 var li = ul.appendChild(document.createElement('li'));
420 li.className="Stats";
421 li.innerHTML = '<b>'+this.localiser.localise('metro')+':</b> '+this.localiser.localise('searching')+'...';
422 this.makeUpcomingCall('metro.getInfo',{metro_id:event.metro_id},getObjectMethodClosure11(this,'metroInfoReceived',li),getObjectMethodClosure11(this,'standard_error',li));
425 var li = ul.appendChild(document.createElement('li'));
426 li.className="Stats";
427 li.innerHTML = '<b>'+this.localiser.localise('venue')+':</b> '+this.localiser.localise('searching')+'...';
428 this.makeUpcomingCall('venue.getInfo',{venue_id:event.venue_id},getObjectMethodClosure11(this,'venueInfoReceived',li),getObjectMethodClosure11(this,'standard_error',li));
431 if(event.description+"") {
432 var li = ul.appendChild(document.createElement('li'));
433 li.className="Stats";
434 li.innerHTML = '<b>'+this.localiser.localise('description')+':</b> '+wbr(event.description);
437 var li = ul.appendChild(document.createElement('li'));
438 li.className="Stats";
439 li.innerHTML = this.localiser.localise('see_other',{
440 'this_user':'<a class="Plain" href="'+unsafeWindow.global_photos[unsafeWindow.page_photo_id].ownersUrl+'/tags/upcomingevent'+this.event_id+'">'+this.localiser.localise('this_user')+'</a>', 'everyone':'<a class="Plain" href="http://www.flickr.com/photos/tags/upcomingevent'+this.event_id+'">'+this.localiser.localise('everyone')+'</a>'});
443 metroInfoReceived: function(rsp,li) {
444 var metro = rsp.metro[0];
446 this.makeUpcomingCall('state.getInfo',{state_id:metro.@state_id},getObjectMethodClosure12(this,'stateInfoReceived',li,metro),getObjectMethodClosure11(this,'standard_error',li));
449 stateInfoReceived: function(rsp,li,metro) {
450 var state = rsp.state[0];
452 this.makeUpcomingCall('country.getInfo',{country_id:state.@country_id},getObjectMethodClosure13(this,'countryInfoReceived',li,metro,state),getObjectMethodClosure11(this,'standard_error',li));
455 countryInfoReceived: function(rsp,li,metro,state) {
456 var country = rsp.country[0];
457 li.innerHTML = '<b>'+this.localiser.localise('metro')+':</b> <a href="http://upcoming.org/metro/'+country.@code+'">'+country.@name+'</a> > <a href="http://upcoming.org/metro/'+country.@code+'/'+state.@code+'">'+state.@name+'</a> > <a href="http://upcoming.org/metro/'+country.@code+'/'+state.@code+'/'+metro.@code+'">'+metro.@name+'</a> ';
458 if(this.canTag) {
459 var a = li.appendChild(document.createElement('a'));
460 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
461 a.href="javascript:;";
462 a.innerHTML = '[+]';
463 a.addEventListener('click',getObjectMethodClosure01(this,'autoTag','"'+country.@name+'" "'+state.@name+'" "'+metro.@name+'" "'+country.@name+'>'+state.@name+'>'+metro.@name+'"'),true);
467 venueInfoReceived: function(rsp,li) {
468 var venue = rsp.venue[0];
469 /*<venue id="2142" name="Alex Theatre" address="216 N. Brand Blvd."
470 city="Glendale, CA" zip="91203" phone="818-243-ALEX"
471 url="http://www.alextheatre.org/" description="The 1,450-seat Alex Theatre
472 is a historic, cultural and artistic treasure built in 1925 as the
473 Alexander Theatre, a vaudeville and motion picture house with Greek and
474 Egyptian motifs." user_id="1" private="0"
475 latitude="37.9183" longitude="-122.024" geocoding_precision="zip"
476 geocoding_ambiguous="0"
477 />*/
479 li.innerHTML = '';
480 var b = li.appendChild(document.createElement('b'));
481 b.innerHTML = this.localiser.localise('venue')+': ';
483 var venue_link = li.appendChild(document.createElement('a'));
484 venue_link.href= venue.@url;
485 venue_link.innerHTML = venue.@name+' ';
486 if(this.canTag) {
487 var a = li.appendChild(document.createElement('a'));
488 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
489 a.href="javascript:;";
490 a.innerHTML = '[+]';
491 a.addEventListener('click',getObjectMethodClosure01(this,'autoTag','"'+venue.@name+'"'),true);
494 var ul = li.appendChild(document.createElement('ul'));
495 // ul.setAttribute('style','list-style-type:none;');
497 if(venue.@address+"") {
498 var li2 = ul.appendChild(document.createElement('li'));
499 li2.className = 'Stats';
500 li2.setAttribute('style','list-style-type:none; list-style-image:none;');
501 li2.innerHTML = venue.@address+' ';
502 if(this.canTag) {
503 var a = li2.appendChild(document.createElement('a'));
504 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
505 a.href="javascript:;";
506 a.innerHTML = '[+]';
507 a.addEventListener('click',getObjectMethodClosure01(this,'autoTag','"'+venue.@address+'"'),true);
511 if(venue.@city+"") {
512 var li2 = ul.appendChild(document.createElement('li'));
513 li2.className = 'Stats';
514 li2.setAttribute('style','list-style-type:none; list-style-image:none;');
515 li2.innerHTML = venue.@city+' ';
516 if(this.canTag) {
517 var a = li2.appendChild(document.createElement('a'));
518 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
519 a.href="javascript:;";
520 a.innerHTML = '[+]';
521 a.addEventListener('click',getObjectMethodClosure01(this,'autoTag','"'+venue.@city+'"'),true);
525 if(venue.@zip+"") {
526 var li2 = ul.appendChild(document.createElement('li'));
527 li2.className = 'Stats';
528 li2.setAttribute('style','list-style-type:none; list-style-image:none;');
529 li2.innerHTML = venue.@zip+' ';
530 if(this.canTag) {
531 var a = li2.appendChild(document.createElement('a'));
532 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
533 a.href="javascript:;";
534 a.innerHTML = '[+]';
535 a.addEventListener('click',getObjectMethodClosure01(this,'autoTag','"'+venue.@zip+'"'),true);
539 if(unsafeWindow.global_photos[unsafeWindow.page_photo_id].isOwner && venue.@longitude+"" && venue.@latitude+"" && venue.@geocoding_ambiguous*1 == 0) {
540 var li2 = ul.appendChild(document.createElement('li'));
541 li2.setAttribute('style','list-style-type:none; list-style-image:none;');
542 li2.className = 'Stats';
543 var a = li2.appendChild(document.createElement('a'));
544 a.setAttribute('style',"text-decoration: none; color: rgb(201, 201, 201);");
545 a.innerHTML = this.localiser.localise('geotag');
546 a.href="javascript:;";
547 a.addEventListener('click',getObjectMethodClosure03(this,'setLatLon',venue.@latitude,venue.@longitude,venue.@geocoding_precision),true);
552 setLatLon: function(lat,lon,precision) {
553 var accuracy = 6; //default accuracy is ~region accuracy
554 switch(precision) {
555 case 'zip':
556 accuracy = 11;
557 break;
558 case 'address':
559 accuracy = 16;
560 break;
562 var listener = {
563 flickr_photos_geo_setLocation_onLoad: function(success, responseXML, responseText, params){
564 if(DEBUG) M8_log(responseText);
568 unsafeWindow.F.API.callMethod('flickr.photos.geo.setLocation', {photo_id:unsafeWindow.page_photo_id,lat:lat,lon:lon,accuracy:accuracy}, listener);
571 /* eventListReceived: function(rsp,div) {
572 var event_ids = '';
573 for each(w in rsp..watchlist) {
574 event_ids += ','+w.@event_id;
576 event_ids = event_ids.substr(1);
577 this.makeUpcomingCall('event.getInfo',{event_id:event_ids},getObjectMethodClosure11(this,'eventListDetailedReceived',div),getObjectMethodClosure11(this,'standard_error',div));
579 },*/
581 eventListDetailedReceived: function(rsp, div) {
582 var select = document.createElement("select");
583 select.id = 'upcoming_event_select';
584 select.setAttribute("style","display:block;");
585 for each(event in rsp..event) {
586 var name=""+event.@name;
587 if(name.length > 50) {
588 name = name.substring(0,47)+"...";
591 var option = select.appendChild(document.createElement("option"));
592 option.value = event.@id;
593 option.innerHTML = name+' ('+event.@start_date+')';
594 this.events[event.@id] = {id:event.@id,
595 username:event.@username,
596 status:event.@status,
597 name: event.@name,
598 tags: event.@tags,
599 description: event.@description,
600 start_date: event.@start_date,
601 end_date: event.@end_date,
602 start_time: event.@start_time,
603 end_time: event.@end_time,
604 personal: event.@personal,
605 metro_id: event.@metro_id,
606 venue_id: event.@venue_id,
607 user_id: event.@user_id,
608 category_id: event.@category_id,
609 latitude: event.@latitude,
610 longitude: event.@longitude,
611 geocoding_precision: event.@geocoding_precision,
612 geocoding_ambiguous: event.@geocoding_ambiguous
615 var button = document.createElement('button');
616 button.type = 'button';
617 button.innerHTML = this.localiser.localise('Tag');
618 button.addEventListener('click',getObjectMethodClosure01(this,'tagPhoto',select),true);
619 button.className = 'SmallButt';
620 var label = div.appendChild(document.createElement('label'));
621 label.htmlFor = 'upcoming_event_select';
622 label.innerHTML = this.localiser.localise('select_event')+':';
623 label.setAttribute("style","display:block;");
624 div.innerHTML = '';
625 var img = div.appendChild(document.createElement('img'));
626 img.align="left";
627 img.alt= this.localiser.localise('script_title');
628 img.src="/images/icon_upcoming_over.gif";
629 div.appendChild(label);
630 div.appendChild(select);
631 div.appendChild(button);
634 tagPhoto: function(select) {
635 unsafeWindow.tagrs_addTag(unsafeWindow.page_photo_id,'"upcoming:event='+select.value+'" upcoming');
636 this.event_id = select.value;
637 this.displayEventInfo(select.parentNode);
640 makeUpcomingCall: function(method,params,callback,error) {
641 var url_params = '';
642 for (p in params) {
643 url_params += '&'+encodeURIComponent(p)+'='+encodeURIComponent(params[p]);
645 if(this.upcoming_token) url_params += '&token='+this.upcoming_token;
646 if(DEBUG) M8_log(url_params);
647 GM_xmlhttpRequest({method: "GET",
648 url: UPCOMING_API_URL+"/?api_key="+this.UPCOMING_API_KEY+'&method='+encodeURIComponent(method)+url_params,
649 headers: {
650 "User-agent": "Mozilla/4.0 (compatible) Greasemonkey",
651 "Accept": "application/atom+xml,application/xml,text/xml",
653 onload: function(req) {
654 if(DEBUG) M8_log(req.responseText);
655 var rsp = req.responseText.replace(/<\?xml.*\?>/,'');
656 var rsp = new XML(rsp);
658 if (rsp == null) {
659 error( "Could not understand Upcoming's response. "+req.responseText);
662 var stat = rsp.@stat;
663 if (stat == null) {
664 error( "Could not find status of Upcoming request. "+req.responseText);
667 if (stat != 'ok') {
668 if (stat == 'fail') {
669 error("Upcoming error: "+rsp..error.@msg);
670 } else {
671 error("Uknown Upcoming error. "+req.responseText);
674 callback(rsp);
679 standard_error: function(msg,div) {
680 div.innerHTML = this.localiser.localise('error');
684 //======================================================================
685 // launch
686 try {
687 window.addEventListener("load", function () {
688 try {
689 // update automatically (http://userscripts.org/scripts/show/2296)
690 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
691 } catch (ex) {}
693 var flickrgp = new flickrupcomingevent();
694 }, false);
695 } catch (ex) {}
696 })();