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}