1/* 2 * Eventbrite API client (jQuery required) - https://github.com/ryanjarvinen/Eventbrite.jquery.js 3 */ 4 5//Constructor 6var Eventbrite = function () { 7 "use strict"; 8 var auth_tokens = {}, 9 args = Array.prototype.slice.call(arguments), 10 // the last argument is the callback 11 callback = args.pop(); 12 13 if(typeof args[0] === 'object'){ 14 auth_tokens = args[0]; 15 }else if(typeof args[0] === 'function' || args[0] === undefined ){ 16 auth_tokens.access_token = Eventbrite.prototype.data.getAccessToken(); 17 }else{ 18 auth_tokens.app_key = args[0]; 19 if(typeof args[1] !== 'function'){ 20 if(typeof args[2] !== 'function'){ 21 auth_tokens.user = args[1]; 22 auth_tokens.password = args[1]; 23 }else{ 24 auth_tokens.user_key = args[1]; 25 } 26 } 27 } 28 29 // make sure the function is called as a constructor 30 if (!(this instanceof Eventbrite)) { 31 return new Eventbrite(auth_tokens, callback); 32 } 33 this.auth_tokens = auth_tokens; 34 35 // call callback 36 callback(this); 37}; 38 39Eventbrite.prototype = { 40 'api_host': "https://www.eventbrite.com/json/", 41 'api_methods': ['discount_new', 'discount_update', 'event_copy', 'event_get', 'event_list_attendees', 'event_list_discounts', 'event_new', 'event_search', 'event_update', 'organizer_list_events', 'organizer_new', 'organizer_update', 'organizer_get', 'payment_update', 'ticket_new', 'ticket_update', 'user_get', 'user_list_events', 'user_list_organizers', 'user_list_tickets', 'user_list_venues', 'user_new', 'user_update', 'venue_new', 'venue_get', 'venue_update'], 42 'request': function ( method, params, cb ) { 43 var auth_headers = {}; 44 if(typeof params === 'function'){ cb = params; params = {};} 45 else if( params === undefined){ params = {}; } 46 if( this.auth_tokens.access_token === undefined ){ 47 if(this.auth_tokens.app_key){ params.app_key = this.auth_tokens.app_key;} 48 if(this.auth_tokens.user_key){ params.user_key = this.auth_tokens.user_key;} 49 if(this.auth_tokens.user){ params.user = this.auth_tokens.user;} 50 if(this.auth_tokens.password){ params.password = this.auth_tokens.password;} 51 }else{ 52 auth_headers = {'Authorization': 'Bearer ' + this.auth_tokens.access_token}; 53 params.access_token = this.auth_tokens.access_token; 54 } 55 56 $.ajax({ 57 url: this.api_host + method, 58 data: params, 59 type: 'GET', 60 dataType: 'jsonp', 61 headers: auth_headers, 62 beforeSend: function(xhrObj){ 63 xhrObj.setRequestHeader("Content-Type","application/javascript"); 64 xhrObj.setRequestHeader("Accept","application/javascript"); 65 if(params.access_token !== undefined){ 66 xhrObj.setRequestHeader("Authorization","Bearer "+params.access_token); 67 } 68 }, 69 success: function (resp) { 70 if(resp.contents !== undefined){ 71 cb(resp.contents); 72 }else{ 73 cb(resp); 74 } 75 }, 76 failure: function (err) { 77 console.log("Error connecting to Eventbrite API"); 78 } 79 }); 80 }, 81 82 // various API client utility functions 83 'utils': { 84 'eventList': function( evnts, callback, options){ 85 var html = ['<div class="eb_event_list">']; 86 if( evnts.events !== undefined ){ 87 var len = evnts.events.length; 88 for( var i = 0; i < len; i++ ){ 89 if(evnts.events[i].event !== undefined ){ 90 html.push( callback( evnts.events[i].event, options )); 91 92 } 93 } 94 }else{ 95 html.push('No events are available at this time.'); 96 } 97 html.push('</div>'); 98 return html.join('\n'); 99 }, 100 'eventListRow': function( evnt ){ 101 var not_iso_8601 = /\d\d-\d\d-\d\d \d\d:\d\d:\d\d/; 102 var date_string = not_iso_8601.test( evnt.start_date ) ? evnt.start_date.replace(' ', 'T') : evnt.start_date; 103 var start_date = new Date( Date.parse( date_string )); 104 var venue_name = 'Online'; //default location name 105 var time_string = Eventbrite.prototype.utils.formatTime( start_date ); 106 var html = ''; 107 date_string = start_date.toDateString(); 108 if( evnt.venue !== undefined && evnt.venue.name !== undefined && evnt.venue.name !== ''){ 109 venue_name = evnt.venue.name; 110 } 111 112 html = "<div class='eb_event_list_item' id='evnt_div_" + evnt.id + "'>" + 113 "<span class='eb_event_list_title'><a href='" + evnt.url + "'>" + evnt.title + "</a></span>" + 114 "<span class='eb_event_list_date'>" + date_string + "</span><span class='eb_event_list_time'>" + time_string + "</span>" + 115 "<span class='eb_event_list_location'>" + venue_name + "</span></div>"; 116 return html; 117 }, 118 'formatTime': function( time ){ 119 var time_string = ''; 120 var minutes = time.getMinutes(); 121 var hours = time.getHours(); 122 var ampm = 'am'; 123 if( minutes < 10 ){ 124 minutes = '0' + minutes; 125 } 126 if( hours === 0 ){ 127 hours = 12; 128 } else if ( hours >= 12 ){ 129 ampm = 'pm'; 130 if( hours !== 12){ 131 hours = hours - 12; 132 } 133 } 134 return time_string += hours + ':' + minutes + ampm; 135 }, 136 'login': function( options, cb ) { 137 var response = {}; 138 if( options.error_message !== undefined ){
139 if( options.error_message === 'access_denied' ){ 140 response.login_error = "Account access denied."; 141 }else if( options.error_message !== 'disabled' ){ 142 response.login_error = options.error_message; 143 } 144 } 145 // auto lookup of access_token from data-store 146 if( options.access_token === undefined ){ 147 if( typeof options.get_token == 'function' ){ 148 options.access_token = options.get_token(); 149 }else if( options.get_token !== 'disabled' ){ 150 options.access_token = Eventbrite.prototype.data.getAccessToken(); 151 } 152 } 153 try{ 154 // Example using an access_token to initialize the API client: 155 Eventbrite({'access_token': options.access_token}, function(eb){ 156 var resp = eb.user_get(function(resp){ 157 if( resp !== undefined && resp.user !== undefined){ 158 response.user_email = resp.user.email; 159 response.user_name = resp.user.first_name + ' ' + resp.user.last_name; 160 } 161 return cb(response); 162 }); 163 }); 164 }catch(error){ 165 // This token may no longer be valid 166 response.login_error = error; 167 if( typeof options.delete_token === 'function' ){ 168 options.delete_token( options.access_token ); 169 }else if( options.delete_token !== 'disabled' ){ 170 Eventbrite.prototype.data.deleteAccessToken( options.access_token ); 171 } 172 return cb(response); 173 } 174 }, 175 'logoutLink': function( ) { 176 return Eventbrite.prototype.utils.logout; 177 }, 178 'logout': function( app_key ) { 179 // delete token and do other cleanup work 180 Eventbrite.prototype.data.deleteAccessToken(); 181 Eventbrite.prototype.widget.login({'app_key': app_key }, function(widget_html){ 182 $('.eb_login_widget').replaceWith(widget_html); 183 }); 184 }, 185 'oauthLink': function( key ) { 186 return 'https://www.eventbrite.com/oauth/authorize?response_type=token&client_id=' + key; 187 }, 188 'isLoggedIn': function() { 189 var token = Eventbrite.prototype.data.getAccessToken(); 190 var isLogged = ( token !== undefined && token !== 'undefined' ); 191 return isLogged; 192 } 193 }, 194 'data': { 195 'getAccessToken': function ( ){ 196 return localStorage.eb_access_token; 197 }, 198 'saveAccessToken': function ( token ){ 199 localStorage.eb_access_token = token; 200 }, 201 'deleteAccessToken': function ( token ){ 202 localStorage.eb_access_token = undefined; 203 } 204 }, 205 'widget': { 206 'login': function( options, cb ){ 207 // automatically grab the access_token from the request fragment? 208 if( window.location.hash.indexOf("token_type=Bearer") !== -1 && 209 window.location.hash.indexOf("access_token=") !== -1 && 210 options.access_token === undefined ){ 211 212 // if we have a new access_token: add it to "options", and save it 213 if( window.location.hash.slice( window.location.hash.indexOf("access_token=") + 13 ).indexOf("&") !== -1){ 214 //partial fragment slice 215 access_token = window.location.hash.slice( 216 window.location.hash.indexOf("access_token=") + 13, 217 window.location.hash.indexOf("access_token=") + 13 + window.location.hash.slice( window.location.hash.indexOf("access_token=") + 13 ).indexOf("&") 218 ); 219 }else{ 220 //the rest of the string contains the access_token value 221 access_token = window.location.hash.slice( window.location.hash.indexOf("access_token=") + 13 ); 222 } 223 if( access_token !== -1 && access_token !== '' && options.save_token !== 'disabled'){ 224 if(typeof options.save_token == 'function'){ 225 options.save_token( access_token ); 226 }else{ 227 Eventbrite.prototype.data.saveAccessToken( access_token ); 228 } 229 options.access_token = access_token; 230 window.location.hash = '#'; 231 } 232 } 233 234 // automatically grab the access_token from storage? 235 if( options.access_token === undefined && options.get_token !== 'disabled'){ 236 if(typeof options.get_token == 'function'){ 237 options.access_token = options.get_token(); 238 }else{ 239 options.access_token = Eventbrite.prototype.data.getAccessToken(); 240 } 241 } 242 243 // automatically grab errors from the querystring? 244 if( options.error_message !== undefined && options.error_message == "disabled"){ 245 delete(options.error_message); 246 }else if( options.error_message !== 'disabled' && window.location.search.indexOf("error=") !== -1 ){ 247 if( window.location.search.slice( window.location.search.indexOf("error=") + 6 ).indexOf("&") !== -1){ 248 options.error_message = window.location.search.slice( 249 window.location.search.indexOf("error=") + 6, 250 window.location.search.indexOf("error=") + 6 + window.location.search.slice( window.location.search.indexOf("error=") + 6 ).indexOf("&") 251 ); 252 }else{ 253 options.error_message = window.location.search.slice( window.location.search.indexOf("error=") + 6 ); 254 } 255 } 256 257 // Check to see if we have a valid user account 258 // and Proccess any data-related work: 259 Eventbrite.prototype.utils.login( options, function(response){ 260 // package up the data for our view / template: 261 var login_params = {}; 262 if(options.logout_link !== 'disabled'){ 263 login_params.logout_link = options.logout_link; 264 } 265 login_params.oauth_link = options.oauth_link; 266 if( login_params.oauth_link === undefined ){ 267 login_params.oauth_link = Eventbrite.prototype.utils.oauthLink(options.app_key); 268 } 269 if( login_params.logout_link === undefined ){
270 login_params.logout_link = "Eventbrite.prototype.utils.logout('" + options.app_key + "');"; 271 } 272 if( response !== undefined && typeof response == 'object'){ 273 if( response.user_email !== undefined ){ 274 login_params.user_name = response.user_name, 275 login_params.user_email = response.user_email; 276 } 277 if( response.login_error !== undefined ){ 278 login_params.login_error = response.login_error; 279 } 280 } 281 282 // view related work: 283 // render your "template" 284 if( typeof options.renderer == 'function' ){ 285 return cb(options.renderer( login_params )); 286 }else if(options.renderer == 'disabled' ){ 287 //return the raw data for use with an external template 288 return cb(login_params); 289 }else{ 290 //use our default renderer: 291 return cb(Eventbrite.prototype.widget.loginHTML( login_params )); 292 } 293 }); 294 }, 295 'loginHTML': function( strings ) { 296 // Replace this example with something that works with your Application's templating engine 297 html = ["<div class='eb_login_widget'>"]; 298 html.push("<style type='text/css'>.eb_login_btn{width:162px;height:24px;display:block;text-indent: -99999px;background: url('http://evbdn.eventbrite.com/s3-s3/static/images/developer/oauth2/oauth-connect-btns.png') top;}\n.eb_login_btn:hover{background-position: 0px 24px;} .eb_logout{text-align:right;}</style>"); 299 if( strings.user_name !== undefined && 300 strings.user_email !== undefined && 301 strings.logout_link !== undefined ){ 302 html.push("<div><p><b>Welcome Back!</b></p>"); 303 html.push("<p>You are logged in as:<br/>"+ strings.user_name + "<br/><i>(" + strings.user_email + ")</i></p>"); 304 if(strings.logout_link !== 'disabled'){ 305 html.push("<p class='eb_logout'><a class='button' href='#' onclick=\"" + strings.logout_link + "\">Logout</a></p>"); 306 } 307 html.push("</div>"); 308 }else if( strings.oauth_link !== undefined ){ 309 if(strings.login_error !== undefined){ 310 html.push("<p class='error'>" + strings.login_error + "</p>"); 311 } 312 html.push("<p><a class='eb_login_btn' target='_top' href='" + strings.oauth_link + "'>Connect to Eventbrite</a></p>"); 313 }else{ 314 html.push("<div><b>Eventbrite widgetHTML template example fail :(</b></div>"); 315 } 316 html.push("</div>"); 317 return html.join("\n"); 318 }, 319 'ticket': function( evnt ) { 320 return '<div style="width:100%; text-align:left;"><iframe src="http://www.eventbrite.com/tickets-external?eid=' + evnt.id + '&ref=etckt" frameborder="0" height="192" width="100%" vspace="0" hspace="0" marginheight="5" marginwidth="5" scrolling="auto" allowtransparency="true"></iframe><div style="font-family:Helvetica, Arial; font-size:10px; padding:5px 0 5px; margin:2px; width:100%; text-align:left;"><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/r/etckt">Online Ticketing</a><span style="color:#ddd;"> for </span><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/event/' + evnt.id + '?ref=etckt">' + evnt.title + '</a><span style="color:#ddd;"> powered by </span><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com?ref=etckt">Eventbrite</a></div></div>'; 321 }, 322 'registration': function( evnt ) { 323 return '<div style="width:100%; text-align:left;"><iframe src="http://www.eventbrite.com/event/' + evnt.id + '?ref=eweb" frameborder="0" height="1000" width="100%" vspace="0" hspace="0" marginheight="5" marginwidth="5" scrolling="auto" allowtransparency="true"></iframe><div style="font-family:Helvetica, Arial; font-size:10px; padding:5px 0 5px; margin:2px; width:100%; text-align:left;"><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/r/eweb">Online Ticketing</a><span style="color:#ddd;"> for </span><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/event/' + evnt.id + '?ref=eweb">' + evnt.title + '</a><span style="color:#ddd;"> powered by </span><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com?ref=eweb">Eventbrite</a></div></div>'; 324 }, 325 'calendar': function ( evnt ) { 326 return '<div style="width:195px; text-align:center;"><iframe src="http://www.eventbrite.com/calendar-widget?eid=' + evnt.id + '" frameborder="0" height="382" width="195" marginheight="0" marginwidth="0" scrolling="no" allowtransparency="true"></iframe><div style="font-family:Helvetica, Arial; font-size:10px; padding:5px 0 5px; margin:2px; width:195px; text-align:center;"><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/r/ecal">Online event registration</a><span style="color:#ddd;"> powered by </span><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com?ref=ecal">Eventbrite</a></div></div>'; 327 }, 328 'countdown': function ( evnt ) { 329 return '<div style="width:195px; text-align:center;"><iframe src="http://www.eventbrite.com/countdown-widget?eid=' + evnt.id + '" frameborder="0" height="479" width="195" marginheight="0" marginwidth="0" scrolling="no" allowtransparency="true"></iframe><div style="font-family:Helvetica, Arial; font-size:10px; padding:5px 0 5px; margin:2px; width:195px; text-align:center;"><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/r/ecount">Online event registration</a><span style="color:#ddd;"> for </span><a style="color:#ddd; text-decoration:none;" target="_blank" href="http://www.eventbrite.com/event/' + evnt.id + '?ref=ecount">' + evnt.title + '</a></div></div>'; 330 }, 331 'button': function ( evnt ) { 332 return '<a href="http://www.eventbrite.com/event/' + evnt.id + '?ref=ebtn" target="_blank"><img border="0" src="http://www.eventbrite.com/custombutton?eid=' + evnt.id + '" alt="Register for ' + evnt.title + ' on Eventbrite" /></a>'; 333 }, 334 'link': function ( evnt, text, color ) { 335 return '<a href="http://www.eventbrite.com/event/' + evnt.id + '?ref=elink" target="_blank" style="color:' + ( color || "#000000" ) + ';">' + ( text || evnt.title ) + '</a>'; 336 } 337 } 338}; 339 340(function(){ 341 var len = Eventbrite.prototype.api_methods.length; 342 function addMethod ( method ) { 343 Eventbrite.prototype[method] = function( params, callback) { 344 this.request( method, params, callback ); 345 }; 346 } 347 for ( var i = 0; i < len ; i += 1 ){ 348 addMethod( Eventbrite.prototype.api_methods[i] ); 349 } 350}()); 351 352 353// including the following progressive enhancement for ISO 8601 dates - Thanks Colin Snover! 354/** 355 * Date.parse with progressive enhancement for ISO 8601 <https://github.com/csnover/js-iso8601> 356 * © 2011 Colin Snover <http://zetafleet.com> 357 * Released under MIT license. 358 */ 359(function (Date, undefined) { 360 var origParse = Date.parse, numericKeys = [ 1, 4, 5, 6, 7, 10, 11 ]; 361 Date.parse = function (date) { 362 var timestamp, struct, minutesOffset = 0; 363 // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format str
363ing 364 // before falling back to any implementation-specific date parsing, so thatâs what we do, even if native 365 // implementations could be faster 366 // 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm 367 if ((struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date))) { 368 // avoid NaN timestamps caused by âundefinedâ values being passed to Date.UTC 369 for (var i = 0, k; (k = numericKeys[i]); ++i) { 370 struct[k] = +struct[k] || 0; 371 } 372 // allow undefined days and months 373 struct[2] = (+struct[2] || 1) - 1; 374 struct[3] = +struct[3] || 1; 375 if (struct[8] !== 'Z' && struct[9] !== undefined) { 376 minutesOffset = struct[10] * 60 + struct[11]; 377 if (struct[9] === '+') { 378 minutesOffset = 0 - minutesOffset; 379 } 380 } 381 timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]); 382 } else { 383 timestamp = origParse ? origParse(date) : NaN; 384 } 385 return timestamp; 386 }; 387}(Date));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.