001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.demos.sandbox.ml.linear.learner.stream.twitter; 031 032import java.io.IOException; 033import java.util.Scanner; 034 035import org.joda.time.format.DateTimeFormat; 036import org.joda.time.format.DateTimeFormatter; 037import org.openimaj.tools.twitter.modes.preprocessing.TwitterPreprocessingMode; 038import org.openimaj.twitter.GeneralJSON; 039import org.openimaj.twitter.USMFStatus; 040import org.openimaj.twitter.USMFStatus.User; 041 042import twitter4j.GeoLocation; 043import twitter4j.HashtagEntity; 044import twitter4j.MediaEntity; 045import twitter4j.Place; 046import twitter4j.Status; 047import twitter4j.URLEntity; 048import twitter4j.UserMentionEntity; 049 050/** 051 * Turns {@link Status} instances into {@link USMFStatus} instances such that 052 * the statuses can be used in the {@link TwitterPreprocessingMode} and other 053 * twitter preprocessing libraries 054 * 055 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 056 * 057 */ 058public class GeneralJSONTweet4jStatus extends GeneralJSON { 059 060 private Status status; 061 062 /** 063 * @param status 064 */ 065 public GeneralJSONTweet4jStatus(Status status) { 066 this.status = status; 067 } 068 069 @Override 070 public void readASCII(Scanner in) throws IOException { 071 final USMFStatus status = new USMFStatus(this.getClass()); 072 status.readASCII(in); 073 this.fromUSMF(status); 074 } 075 076 @Override 077 public void fillUSMF(USMFStatus status) { 078 // Populate message fields 079 status.application = this.status.getSource(); 080 final DateTimeFormatter parser = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss Z yyyy"); 081 status.date = parser.print(this.status.getCreatedAt().getTime()); 082 ; 083 if (this.status.getGeoLocation() != null) { 084 final GeoLocation geloc = this.status.getGeoLocation(); 085 final double[] coords = new double[2]; 086 087 coords[0] = geloc.getLatitude(); 088 coords[1] = geloc.getLongitude(); 089 status.geo = coords; 090 } 091 final Place place = this.status.getPlace(); 092 if (place != null) { 093 status.location = place.getName(); 094 status.country_code = place.getCountryCode(); 095 } 096 status.id = this.status.getId(); 097 status.text = this.status.getText(); 098 status.service = "Twitter"; 099 100 // Check if user is null, and make invalid if it is 101 if (this.status.getUser() != null) 102 { 103 final twitter4j.User user = this.status.getUser(); 104 // Populate the User 105 106 status.user.avatar = user.getBiggerProfileImageURL(); 107 status.user.description = user.getDescription(); 108 status.user.id = user.getId(); 109 status.user.location = user.getLocation(); 110 status.user.language = user.getLang(); 111 status.user.postings = user.getStatusesCount(); 112 status.user.real_name = user.getName(); 113 status.user.name = user.getScreenName(); 114 status.user.subscribers = user.getFollowersCount(); 115 status.user.utc = user.getUtcOffset(); 116 status.user.website = user.getURL(); 117 } 118 119 // Populate the links 120 121 final MediaEntity[] ents = this.status.getMediaEntities(); 122 for (final URLEntity link : this.status.getURLEntities()) { 123 final USMFStatus.Link l = new USMFStatus.Link(); 124 l.href = link.getExpandedURL(); 125 } 126 127 // Populate the keywords from hashtags 128 for (final HashtagEntity tag : this.status.getHashtagEntities()) { 129 status.keywords.add(tag.getText()); 130 } 131 132 // Populate the to users from user mentions 133 for (final UserMentionEntity user : this.status.getUserMentionEntities()) { 134 final USMFStatus.User u = new USMFStatus.User(); 135 u.name = user.getScreenName(); 136 u.real_name = user.getName(); 137 u.id = user.getId(); 138 status.to_users.add(u); 139 } 140 if (this.status.getInReplyToScreenName() != null) { 141 status.reply_to = new User(); 142 status.reply_to.name = this.status.getInReplyToScreenName(); 143 status.reply_to.id = this.status.getInReplyToUserId(); 144 145 } 146 this.fillAnalysis(status); 147 } 148 149 @Override 150 public void fromUSMF(USMFStatus status) { 151 // TODO Auto-generated method stub 152 153 } 154 155 @Override 156 public GeneralJSON instanceFromString(String line) { 157 GeneralJSONTweet4jStatus jsonInstance = null; 158 try { 159 jsonInstance = gson.fromJson(line, GeneralJSONTweet4jStatus.class); 160 } catch (final Throwable e) { 161 throw new RuntimeException(e); 162 } 163 return jsonInstance; 164 } 165 166}