diff --git a/.gitignore b/.gitignore index 216927c6..fec2ba57 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ workbench.xmi .settings .checkstyle twitter4j.properties +riskingh/twitter4j.properties +riskingh/src/main/resources/googleMaps.properties diff --git a/pom.xml b/pom.xml index a2fdfbd2..d48c78d8 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,5 @@ - + + 4.0.0 ru.fizteh.fivt.students @@ -19,7 +19,7 @@ UTF-8 - + egiby akormushin @@ -46,6 +46,7 @@ ladyae nikitarykov duha666 + riskingh diff --git a/riskingh/pom.xml b/riskingh/pom.xml new file mode 100644 index 00000000..27cf292b --- /dev/null +++ b/riskingh/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + ru.fizteh.fivt.students + parent + 1.0-SNAPSHOT + + ru.fizteh.fivt.students + riskingh + 1.0-SNAPSHOT + riskingh + http://maven.apache.org + + UTF-8 + + + + junit + junit + 3.8.1 + test + + + org.twitter4j + twitter4j-core + [4.0,) + + + org.twitter4j + twitter4j-stream + 4.0.4 + + + com.beust + jcommander + 1.48 + + + org.json + json + 20151123 + + + diff --git a/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/GeoUtils.java b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/GeoUtils.java new file mode 100644 index 00000000..5a0cf979 --- /dev/null +++ b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/GeoUtils.java @@ -0,0 +1,32 @@ +package ru.fizteh.fivt.students.riskingh.TwitterStream; + +/** + * Created by max on 18/12/15. + */ + +import twitter4j.*; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Properties; + +public class GeoUtils { + public static GeoLocation getLocationByPlace(String placeString) throws IOException, + URISyntaxException, org.json.JSONException { + Properties properties = new Properties(); + try (InputStream inputStream = GeoLocation.class.getResourceAsStream("/googleMaps.properties")) { + properties.load(inputStream); + } + String googleMapsKey = properties.getProperty("google"); + String urlString = "https://maps.googleapis.com/maps/api/geocode/json?key=" + + googleMapsKey + "&address=" + URLEncoder.encode(placeString, "UTF-8"); + URL url = new URL(urlString); + org.json.JSONObject jsonObject = JSONReader.readJSONFromUrl(url.toString()); + jsonObject = jsonObject.getJSONArray("results").getJSONObject(0) + .getJSONObject("geometry").getJSONObject("location"); + return new GeoLocation(jsonObject.getDouble("lat"), jsonObject.getDouble("lng")); + } +} diff --git a/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/JSONReader.java b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/JSONReader.java new file mode 100644 index 00000000..c4601314 --- /dev/null +++ b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/JSONReader.java @@ -0,0 +1,36 @@ +package ru.fizteh.fivt.students.riskingh.TwitterStream; + +/** + * Created by max on 18/12/15. + */ + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.nio.charset.Charset; + +import org.json.JSONException; +import org.json.JSONObject; + +public class JSONReader { + + private static String readAll(Reader rd) throws IOException { + StringBuilder sb = new StringBuilder(); + int cp; + while ((cp = rd.read()) != -1) { + sb.append((char) cp); + } + return sb.toString(); + } + + public static JSONObject readJSONFromUrl(String url) throws IOException, JSONException { + try (InputStream is = new URL(url).openStream()) { + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + String jsonText = readAll(rd); + return new JSONObject(jsonText); + } + } +} diff --git a/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/Settings.java b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/Settings.java new file mode 100644 index 00000000..ba9aad0e --- /dev/null +++ b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/Settings.java @@ -0,0 +1,54 @@ +package ru.fizteh.fivt.students.riskingh.TwitterStream; + +/** + * Created by max on 18/12/15. + */ +import com.beust.jcommander.*; + +public class Settings { + + private static final int DEFAULT_TWEET_LIMIT = 10; + + @Parameter(names = {"-q", "--query"}, description = "Query or keywords for stream") + private String query = ""; + + @Parameter(names = {"-p", "--place"}, description = "Location") + private String place = "nearby"; + + @Parameter(names = {"-s", "--stream"}, description = "Stream") + private boolean stream = false; + + @Parameter(names = {"--hideRetweets"}, description = "Hide retweets") + private boolean hideRetweets = false; + + @Parameter(names = {"-l", "--limit"}, description = "Tweets limit") + private Integer limit = DEFAULT_TWEET_LIMIT; + + @Parameter(names = {"-h", "--help"}, description = "Show this help") + private boolean printHelp = false; + + public String getQuery() { + return query; + } + + public String getPlace() { + return place; + } + + public boolean stream() { + return stream; + } + + public boolean hideRetweets() { + return hideRetweets; + } + + public Integer getLimitNumber() { + return limit; + } + + public boolean printHelp() { + return printHelp; + } +} + diff --git a/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/StatusPrinter.java b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/StatusPrinter.java new file mode 100644 index 00000000..d0f8489b --- /dev/null +++ b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/StatusPrinter.java @@ -0,0 +1,68 @@ +package ru.fizteh.fivt.students.riskingh.TwitterStream; + +/** + * Created by max on 18/12/15. + */ + +import twitter4j.*; +import twitter4j.TwitterStream; + +import java.util.List; + +public class StatusPrinter { + public static final int SEARCH_DISTANCE_IN_KM = 5; + public static final int MILLISECONDS_IN_SECOND = 1000; + + private static void printTweet(Status tweet) { + System.out.print("[" + TimeUtils.formatTime(tweet.getCreatedAt()) + "]"); + System.out.print("@" + tweet.getUser().getScreenName() + ": "); + if (tweet.isRetweet()) { + System.out.print("ретвитнул "); + System.out.print(tweet.getRetweetedStatus().getUser().getScreenName() + ":"); + System.out.print(tweet.getRetweetedStatus().getText()); + } else { + System.out.print(tweet.getText()); + int retweetsCount = tweet.getRetweetCount(); + if (retweetsCount > 0) { + System.out.print("(" + retweetsCount + " ретвитов)"); + } + } + System.out.println(); + } + + public static void print(Settings settings, GeoLocation location) throws TwitterException { + Twitter twitter = new TwitterFactory().getInstance(); + Query query = new Query(settings.getQuery()).geoCode(location, SEARCH_DISTANCE_IN_KM, "km"); + query.setCount(settings.getLimitNumber()); + QueryResult queryResult = twitter.search(query); + List statuses = queryResult.getTweets(); + statuses.stream(). + filter(status -> !settings.hideRetweets() || !status.isRetweet()). + forEach(ru.fizteh.fivt.students.riskingh.TwitterStream.StatusPrinter::printTweet); + } + + public static void stream(Settings settings, GeoLocation location) throws TwitterException { + TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); + twitterStream.addListener(new StatusAdapter() { + @Override + public void onStatus(Status status) { + if (settings.hideRetweets() && status.isRetweet()) { + return; + } + printTweet(status); + try { + Thread.sleep(MILLISECONDS_IN_SECOND); + } catch (Exception e) { + System.err.print("ERROR!"); + } + } + }); + FilterQuery filterQuery = new FilterQuery(); + double[][] locations = { + {location.getLongitude() - SEARCH_DISTANCE_IN_KM, location.getLatitude() - SEARCH_DISTANCE_IN_KM}, + {location.getLongitude() + SEARCH_DISTANCE_IN_KM, location.getLatitude() + SEARCH_DISTANCE_IN_KM} + }; + filterQuery.track(settings.getQuery()).locations(locations); + twitterStream.filter(filterQuery); + } +} diff --git a/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/TimeUtils.java b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/TimeUtils.java new file mode 100644 index 00000000..22b85918 --- /dev/null +++ b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/TimeUtils.java @@ -0,0 +1,42 @@ +package ru.fizteh.fivt.students.riskingh.TwitterStream; + +/** + * Created by max on 18/12/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +public class TimeUtils { + public static String formatTime(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Calendar today = Calendar.getInstance(); + + Calendar yesterday = Calendar.getInstance(); + yesterday.add(Calendar.DAY_OF_YEAR, -1); + + Date current = new Date(); + long difference = current.getTime() - date.getTime(); + + long differenceInMinutes = TimeUnit.MILLISECONDS.toMinutes(difference); + long differenceInHours = TimeUnit.MILLISECONDS.toHours(difference); + long differenceInDays = TimeUnit.MILLISECONDS.toDays(difference); + + if (differenceInMinutes < 2) { + return "только что"; + } else if (differenceInHours < 1) { + return Long.toString(differenceInMinutes) + " минут назад"; + } else if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR) + && calendar.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) { + return Long.toString(differenceInHours) + " часов назад"; + } else if (calendar.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR) + && calendar.get(Calendar.DAY_OF_YEAR) == yesterday.get(Calendar.DAY_OF_YEAR)) { + return "вчера"; + } else { + return Long.toString(differenceInDays) + " дней назад"; + } + } +} diff --git a/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/TwitterStream.java b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/TwitterStream.java new file mode 100644 index 00000000..735b702a --- /dev/null +++ b/riskingh/src/main/java/ru/fizteh/fivt/students/riskingh/TwitterStream/TwitterStream.java @@ -0,0 +1,40 @@ +package ru.fizteh.fivt.students.riskingh.TwitterStream; + +/** + * Created by max on 18/12/15. + */ + +import com.beust.jcommander.JCommander; +import twitter4j.GeoLocation; +import twitter4j.TwitterException; + +public class TwitterStream { + public static void main(String[] args) throws TwitterException { + Settings settings = new Settings(); + try { + JCommander jcommander = new JCommander(settings, args); + if (settings.printHelp()) { + jcommander.usage(); + return; + } + } catch (Exception e) { + JCommander jcommander = new JCommander(settings); + jcommander.usage(); + return; + } + + System.out.print("Твиты по запросу " + settings.getQuery() + " для " + settings.getPlace() + ":"); + System.out.println(); + try { + GeoLocation location = GeoUtils.getLocationByPlace(settings.getPlace()); + if (settings.stream()) { + StatusPrinter.stream(settings, location); + } else { + StatusPrinter.print(settings, location); + } + } catch (Exception e) { + System.err.print("ERROR: " + e.toString()); + e.printStackTrace(); + } + } +} diff --git a/riskingh/src/test/java/ru/fizteh/fivt/students/riskingh/f b/riskingh/src/test/java/ru/fizteh/fivt/students/riskingh/f new file mode 100644 index 00000000..e69de29b