001/* 002 * Copyright (c) 2012, the Last.fm Java Project and Committers 003 * All rights reserved. 004 * 005 * Redistribution and use of this software in source and binary forms, with or without modification, are 006 * permitted provided that the following conditions are met: 007 * 008 * - Redistributions of source code must retain the above 009 * copyright notice, this list of conditions and the 010 * following disclaimer. 011 * 012 * - Redistributions in binary form must reproduce the above 013 * copyright notice, this list of conditions and the 014 * following disclaimer in the documentation and/or other 015 * materials provided with the distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 018 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 019 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 020 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 021 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 023 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 024 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 025 */ 026 027package de.umass.lastfm; 028 029import java.text.DateFormat; 030import java.text.ParseException; 031import java.text.SimpleDateFormat; 032import java.util.*; 033 034import de.umass.util.MapUtilities; 035import de.umass.xml.DomElement; 036 037/** 038 * Bean for Events. 039 * 040 * @author Janni Kovacs 041 */ 042public class Event extends ImageHolder { 043 044 static final ItemFactory<Event> FACTORY = new EventFactory(); 045 046 private static final DateFormat DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH); 047 048 private int id; 049 private String title; 050 private Collection<String> artists; 051 private String headliner; 052 private Collection<TicketSupplier> tickets; 053 054 private Date startDate; 055 private Date endDate; 056 057 private String description; 058 private String url; 059 private String website; 060 private int attendance; 061 private int reviews; 062 063 private Venue venue; 064 private AttendanceStatus userAttendanceStatus; 065 066 private Event() { 067 } 068 069 public Collection<String> getArtists() { 070 return artists; 071 } 072 073 public int getAttendance() { 074 return attendance; 075 } 076 077 public String getDescription() { 078 return description; 079 } 080 081 public String getHeadliner() { 082 return headliner; 083 } 084 085 public int getId() { 086 return id; 087 } 088 089 public int getReviews() { 090 return reviews; 091 } 092 093 /** 094 * Returns the start date and time of this event. Note that the time might not be correct, but instead a random time, if not set to a 095 * proper value on last.fm (happens often). 096 * 097 * @return start date 098 */ 099 public Date getStartDate() { 100 return startDate; 101 } 102 103 /** 104 * Returns the event's end date, or <code>null</code> if not available. End dates are only supplied for events such as festivals, which 105 * last longer than one day. 106 * 107 * @return end date 108 */ 109 public Date getEndDate() { 110 return endDate; 111 } 112 113 public String getTitle() { 114 return title; 115 } 116 117 /** 118 * Returns the last.fm event url, i.e. https://www.last.fm/event/event-id 119 * 120 * @return last.fm url 121 */ 122 public String getUrl() { 123 return url; 124 } 125 126 /** 127 * Returns the event website url, if available. 128 * 129 * @return event website url 130 */ 131 public String getWebsite() { 132 return website; 133 } 134 135 public Collection<TicketSupplier> getTicketSuppliers() { 136 return tickets; 137 } 138 139 public Venue getVenue() { 140 return venue; 141 } 142 143 public AttendanceStatus getAttendanceStatus() { 144 return this.userAttendanceStatus; 145 } 146 147 /** 148 * Get the metadata for an event on Last.fm. Includes attendance and lineup information. 149 * 150 * @param eventId The numeric last.fm event id 151 * @param apiKey A Last.fm API key. 152 * @return Event metadata 153 */ 154 public static Event getInfo(String eventId, String apiKey) { 155 Result result = Caller.getInstance().call("event.getInfo", apiKey, "event", eventId); 156 return ResponseBuilder.buildItem(result, Event.class); 157 } 158 159 /** 160 * Set a user's attendance status for an event. 161 * 162 * @param eventId The numeric last.fm event id 163 * @param status The attendance status 164 * @param session A Session instance 165 * @return the Result of the operation. 166 * @see de.umass.lastfm.Event.AttendanceStatus 167 * @see de.umass.lastfm.Authenticator 168 */ 169 public static Result attend(String eventId, AttendanceStatus status, Session session) { 170 return Caller.getInstance().call("event.attend", session, "event", eventId, "status", String.valueOf(status.getId())); 171 } 172 173 /** 174 * Share an event with one or more Last.fm users or other friends. 175 * 176 * @param eventId An event ID 177 * @param recipients A comma delimited list of email addresses or Last.fm usernames. Maximum is 10. 178 * @param message An optional message to send with the recommendation. 179 * @param session A Session instance 180 * @return the Result of the operation 181 */ 182 public static Result share(String eventId, String recipients, String message, Session session) { 183 return Caller.getInstance().call("event.share", session, "event", eventId, "recipient", recipients, "message", message); 184 } 185 186 /** 187 * Get a list of attendees for an event. 188 * 189 * @param eventId The numeric last.fm event id 190 * @param apiKey A Last.fm API key 191 * @return a list of users who attended the given event 192 */ 193 public static Collection<User> getAttendees(String eventId, String apiKey) { 194 Result result = Caller.getInstance().call("event.getAttendees", apiKey, "event", eventId); 195 return ResponseBuilder.buildCollection(result, User.class); 196 } 197 198 /** 199 * Get shouts for an event. 200 * 201 * @param eventId The numeric last.fm event id 202 * @param apiKey A Last.fm API key. 203 * @return a page of <code>Shout</code>s 204 */ 205 public static PaginatedResult<Shout> getShouts(String eventId, String apiKey) { 206 return getShouts(eventId, -1, -1, apiKey); 207 } 208 209 /** 210 * Get shouts for an event. 211 * 212 * @param eventId The numeric last.fm event id 213 * @param page The page number to fetch 214 * @param apiKey A Last.fm API key. 215 * @return a page of <code>Shout</code>s 216 */ 217 public static PaginatedResult<Shout> getShouts(String eventId, int page, String apiKey) { 218 return getShouts(eventId, page, -1, apiKey); 219 } 220 221 /** 222 * Get shouts for an event. 223 * 224 * @param eventId The numeric last.fm event id 225 * @param page The page number to fetch 226 * @param limit An integer used to limit the number of shouts returned per page or -1 for default 227 * @param apiKey A Last.fm API key. 228 * @return a page of <code>Shout</code>s 229 */ 230 public static PaginatedResult<Shout> getShouts(String eventId, int page, int limit, String apiKey) { 231 Map<String, String> params = new HashMap<String, String>(); 232 params.put("event", eventId); 233 MapUtilities.nullSafePut(params, "limit", limit); 234 MapUtilities.nullSafePut(params, "page", page); 235 Result result = Caller.getInstance().call("event.getShouts", apiKey, params); 236 return ResponseBuilder.buildPaginatedResult(result, Shout.class); 237 } 238 239 /** 240 * Enumeration for the attendance status parameter of the <code>attend</code> operation. 241 */ 242 public static enum AttendanceStatus { 243 244 ATTENDING(0), 245 MAYBE_ATTENDING(1), 246 NOT_ATTENDING(2); 247 248 private int id; 249 250 private AttendanceStatus(int id) { 251 this.id = id; 252 } 253 254 public int getId() { 255 return id; 256 } 257 258 public static AttendanceStatus getByID(int statusId) { 259 for (AttendanceStatus status : AttendanceStatus.values()) { 260 if(status.id == statusId) 261 return status; 262 } 263 return null; 264 } 265 } 266 267 public static class TicketSupplier { 268 private String name; 269 private String website; 270 271 public TicketSupplier(String name, String website) { 272 this.name = name; 273 this.website = website; 274 } 275 276 public String getName() { 277 return name; 278 } 279 280 public String getWebsite() { 281 return website; 282 } 283 } 284 285 private static class EventFactory implements ItemFactory<Event> { 286 public Event createItemFromElement(DomElement element) { 287// if (element == null) 288// return null; 289 Event event = new Event(); 290 ImageHolder.loadImages(event, element); 291 event.id = Integer.parseInt(element.getChildText("id")); 292 event.title = element.getChildText("title"); 293 event.description = element.getChildText("description"); 294 event.url = element.getChildText("url"); 295 if (element.hasChild("attendance")) 296 event.attendance = Integer.parseInt(element.getChildText("attendance")); 297 if (element.hasChild("reviews")) 298 event.reviews = Integer.parseInt(element.getChildText("reviews")); 299 try { 300 event.startDate = DATE_FORMAT.parse(element.getChildText("startDate")); 301 if (element.hasChild("endDate")) { 302 event.endDate = DATE_FORMAT.parse(element.getChildText("endDate")); 303 } 304 } catch (ParseException e1) { 305 // Date format not valid !?, should definitely not happen. 306 } 307 event.headliner = element.getChild("artists").getChildText("headliner"); 308 event.artists = new ArrayList<String>(); 309 for (DomElement artist : element.getChild("artists").getChildren("artist")) { 310 event.artists.add(artist.getText()); 311 } 312 event.website = element.getChildText("website"); 313 event.tickets = new ArrayList<TicketSupplier>(); 314 if (element.hasChild("tickets")) { 315 for (DomElement ticket : element.getChild("tickets").getChildren("ticket")) { 316 event.tickets.add(new TicketSupplier(ticket.getAttribute("supplier"), ticket.getText())); 317 } 318 } 319 if(element.hasAttribute("status")) 320 event.userAttendanceStatus = AttendanceStatus.getByID(Integer.parseInt(element.getAttribute("status"))); 321 if(element.hasChild("venue")) 322 event.venue = ResponseBuilder.buildItem(element.getChild("venue"), Venue.class); 323 return event; 324 } 325 } 326}