package esl.cuenet.source.accessors; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.ontology.OntModel; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.util.JSON; import esl.cuenet.query.IResultIterator; import esl.cuenet.query.IResultSet; import esl.cuenet.query.ResultIterator; import esl.cuenet.query.drivers.webjson.HttpDownloader; import esl.cuenet.source.AccesorInitializationException; import esl.cuenet.source.Attribute; import esl.cuenet.source.IAccessor; import esl.cuenet.source.SourceQueryException; import esl.datastructures.Location; import esl.datastructures.TimeInterval; import org.apache.log4j.Logger; import java.io.IOException; import java.util.Calendar; import java.util.List; public class UpcomingEventsAPI implements IAccessor { private Logger logger = Logger.getLogger(UpcomingEventsAPI.class); private HttpDownloader downloader = new HttpDownloader(); private Attribute[] attributes = null; private boolean[] setFlags = new boolean[6]; //lat, lon, start-date, end-date, name, description private double lat, lon; private String startDate, endDate; private String nameSubstring, descriptionSubstring; private OntModel model = null; public UpcomingEventsAPI() {} public UpcomingEventsAPI(OntModel model) { this.model = model; } // startDate, endDate format: YYYY-MM-DD public BasicDBList searchUpcoming() throws IOException { int radius = 5; StringBuilder url = new StringBuilder("http://upcoming.yahooapis.com/services/rest/?method=event.search"); url.append("&api_key=123157aeb5"); if (setFlags[0] && setFlags[1]) url.append("&location=").append(lat).append(',').append(lon); url.append("&radius=").append(radius); if (setFlags[2]) url.append("&min_date=").append(startDate); if (setFlags[3]) url.append("&max_date=").append(endDate); url.append("&category_id=").append("1,2"); url.append("&format=json"); logger.info("url: " + url.substring(0)); byte[] contents = downloader.get(url.substring(0)); if (contents == null) return null; if (contents.length < 5) return null; BasicDBObject object = (BasicDBObject) JSON.parse(new String(contents)); if (!object.containsField("rsp")) return null; BasicDBObject response = (BasicDBObject) object.get("rsp"); if (response.getString("stat").compareTo("ok") != 0) { logger.info("No events on UpcomingEventsAPI"); return null; } int rc = response.getInt("resultcount"); if (rc < 1) return null; if (!response.containsField("event")) return null; BasicDBList events = (BasicDBList) response.get("event"); BasicDBList filteredEvents = new BasicDBList(); for (Object e: events) { BasicDBObject event = (BasicDBObject) e; if (setFlags[4]) if ( !event.getString("name").contains(nameSubstring) ) continue; if (setFlags[5]) if ( !event.getString("description").contains(descriptionSubstring) ) continue; filteredEvents.add(event); } return filteredEvents; } @Override public void setAttributeNames(Attribute[] attributes) throws AccesorInitializationException { if (attributes.length != 6) throw new AccesorInitializationException("Invalid number of attributes for " + UpcomingEventsAPI.class.getName()); this.attributes = attributes; } @Override public void start() { for (int i = 0; i < setFlags.length; i++) setFlags[i] = false; } @Override public void associateTimeInterval(Attribute attribute, TimeInterval timeInterval) throws AccesorInitializationException { throw new AccesorInitializationException("Incorrect Assignment: No time interval attributes in " + YahooPlaceFinderAPI.class.getName()); } @Override public void associateLocation(Attribute attribute, Location timeInterval) throws AccesorInitializationException { throw new AccesorInitializationException("Incorrect Assignment: No location attributes in " + YahooPlaceFinderAPI.class.getName()); } @Override public void associateLong(Attribute attribute, long value) throws AccesorInitializationException { if (attribute.compareTo(attributes[2]) == 0) { setFlags[2] = true; Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(value); startDate = String.format("%d-%02d-%02d", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)+1, calendar.get(Calendar.DAY_OF_MONTH)); } else if (attribute.compareTo(attributes[3]) == 0) { setFlags[3] = true; Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(value); endDate = String.format("%d-%02d-%02d", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)+1, calendar.get(Calendar.DAY_OF_MONTH)); } else throw new AccesorInitializationException("Long value being initialized for wrong attribute " + YahooPlaceFinderAPI.class.getName()); } @Override public void associateString(Attribute attribute, String value) throws AccesorInitializationException { if (attribute.compareTo(attributes[4]) == 0) { setFlags[4] = true; nameSubstring = value; } else if (attribute.compareTo(attributes[5]) == 0) { setFlags[5] = true; descriptionSubstring = value; } else throw new AccesorInitializationException("String value being initialized for wrong attribute " + YahooPlaceFinderAPI.class.getName()); } @Override public void associateDouble(Attribute attribute, double value) throws AccesorInitializationException { if (attribute.compareTo(attributes[0]) == 0) { setFlags[0] = true; this.lat = value; } else if (attribute.compareTo(attributes[1])==0) { setFlags[1] = true; this.lon = value; } else throw new AccesorInitializationException("Double value being initialized for wrong attribute " + YahooPlaceFinderAPI.class.getName()); } @Override public IResultSet executeQuery() throws SourceQueryException { boolean areParamsAvailable = false; for (boolean b : setFlags) if (b) areParamsAvailable = true; if (!areParamsAvailable) throw new SourceQueryException("No parameters set"); BasicDBList result; try { result = searchUpcoming(); } catch (IOException e) { throw new SourceQueryException("Internal IOException: " + e.getMessage()); } if (result != null) return new ResultSetImpl(result.toString(), model); return null; } public BasicDBList searchUpcoming(double lat, double lon, String startDate, String endDate) throws IOException { this.lat = lat; setFlags[0] = true; this.lon = lon; setFlags[1] = true; this.startDate = startDate; setFlags[2] = true; this.endDate = endDate; setFlags[3] = true; return searchUpcoming(); } }