diff --git a/twittertopiccount/NOTICE.txt b/twittertopiccount/NOTICE.txt new file mode 100644 index 0000000..d31a1d2 --- /dev/null +++ b/twittertopiccount/NOTICE.txt @@ -0,0 +1,11 @@ +======================================================================= +NOTICE file for use with, and corresponding to Section 4 of, +the Apache License, Version 2.0, in this case for the S4 project. +========================================================================= + + This product includes software developed by + Yahoo! Inc. (www.yahoo.com) + Copyright (c) 2010 Yahoo! Inc. All rights reserved. + + This product includes software developed by + The Apache Software Foundation (http://www.apache.org/). diff --git a/twittertopiccount/assembly.xml b/twittertopiccount/assembly.xml index c9ed2ca..c636a88 100644 --- a/twittertopiccount/assembly.xml +++ b/twittertopiccount/assembly.xml @@ -17,6 +17,13 @@ + + + ${project.basedir}/NOTICE.txt + + NOTICE.txt + + ${project.basedir}/target @@ -25,6 +32,21 @@ *.jar + + ${project.basedir} + 0755 + bin + + *.sh + + + + ${project.basedir} + resources + + *.png + + ${project.basedir}/src/main/resources diff --git a/twittertopiccount/launch_twittertopiccount_application.sh b/twittertopiccount/launch_twittertopiccount_application.sh new file mode 100755 index 0000000..cbf0024 --- /dev/null +++ b/twittertopiccount/launch_twittertopiccount_application.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +osx=false +case "`uname`" in +Darwin*) osx=true;; +esac + +if $osx; then + READLINK="stat" +else + READLINK="readlink" +fi + +export S4_APPS=$IMAGE_BASE/s4_apps + +BASE_DIR=`dirname $($READLINK -f $0)` +echo $BASE_DIR + +rm $S4_APPS/twittertopiccount-*.tar.gz +rm -r $S4_APPS/twittertopiccount +cp $BASE_DIR/../../twittertopiccount-*.tar.gz $S4_APPS +cd $S4_APPS +pwd +tar zxf $S4_APPS/twittertopiccount-*.tar.gz +cd twittertopiccount +cd bin +chmod 755 twitter_topic_count.sh +cd $IMAGE_BASE/bin +./s4_start.sh & +./run_adapter.sh -x -u $S4_APPS/twittertopiccount/lib/twittertopiccount-*.jar -d $S4_APPS/twittertopiccount/adapter_conf.xml & +cd /tmp +touch top_n_hashtags +cd $S4_APPS/twittertopiccount/bin +sleep 4 +./twitter_topic_count.sh diff --git a/twittertopiccount/pom.xml b/twittertopiccount/pom.xml index b52dac0..39b6559 100644 --- a/twittertopiccount/pom.xml +++ b/twittertopiccount/pom.xml @@ -4,7 +4,7 @@ io.s4.examples.twittertopiccount twittertopiccount jar - 0.0.0.1 + 0.0.0.3 twittertopiccount http://maven.apache.org @@ -31,10 +31,15 @@ + + org.json + json + 20090211 + io.s4 s4_core - 0.2.0.0 + 0.3.0.0 provided diff --git a/twittertopiccount/s4.png b/twittertopiccount/s4.png new file mode 100644 index 0000000..bec4a2d Binary files /dev/null and b/twittertopiccount/s4.png differ diff --git a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/DirectToFilePersister.java b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/DirectToFilePersister.java index 02dc809..99c5ec7 100644 --- a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/DirectToFilePersister.java +++ b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/DirectToFilePersister.java @@ -33,6 +33,10 @@ public class DirectToFilePersister implements Persister { public void setOutputFilename(String outputFilename) { this.outputFilename = outputFilename; } + + public String getOutputFilename() { + return outputFilename; + } @Override public int cleanOutGarbage() throws InterruptedException { diff --git a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TopicCountAndReportPE.java b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TopicCountAndReportPE.java index 1263ff9..8c06561 100644 --- a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TopicCountAndReportPE.java +++ b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TopicCountAndReportPE.java @@ -59,9 +59,6 @@ public void processEvent(TopicSeen topicSeen) { @Override public void output() { - if (count < threshold) { - return; - } TopicSeen topicSeen = new TopicSeen((String) this.getKeyValue().get(0), count); topicSeen.setReportKey("1"); diff --git a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TwitterFeedListener.java b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TwitterFeedListener.java index 7881365..3c59291 100644 --- a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TwitterFeedListener.java +++ b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/TwitterFeedListener.java @@ -31,9 +31,9 @@ import io.s4.collector.EventWrapper; import io.s4.listener.EventHandler; -import io.s4.listener.EventListener; +import io.s4.listener.EventProducer; -public class TwitterFeedListener implements EventListener, Runnable { +public class TwitterFeedListener implements EventProducer, Runnable { private String userid; private String password; private String urlString; diff --git a/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/ui/TwitterUI.java b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/ui/TwitterUI.java new file mode 100644 index 0000000..4b7d5eb --- /dev/null +++ b/twittertopiccount/src/main/java/io/s4/example/twittertopiccount/ui/TwitterUI.java @@ -0,0 +1,253 @@ +package io.s4.example.twittertopiccount.ui; + +import java.awt.Color; +import java.awt.Desktop; +import java.awt.Font; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.net.URI; +import java.net.URLEncoder; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Scanner; + +import javax.swing.JLabel; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class TwitterUI extends javax.swing.JFrame { + + /** Creates new form TwitterUI */ + public TwitterUI() { + initComponents(); + } + + int count = 0; + long timestamp = 1L; + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JButton(); + jLabel3 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + getContentPane().setLayout(null); + this.setSize(569, 580); + this.setBackground(Color.white); + + getContentPane().setVisible(true); + } + + public void drawComponents(Object[][] tweets, long maxCount) { + + int y = 110; + int x1 = 74; + int x2 = 290; + + getContentPane().removeAll(); + + jLabel1.setText("Top Twitter Topics"); + jLabel1.setFont(new Font("Times New Roman", Font.BOLD, 18)); + getContentPane().add(jLabel1); + jLabel1.setBounds(193, 40, 200, 25); + jLabel4.setText("Timestamp: " + Long.toString(timestamp)); + jLabel4.setFont(new Font("Times New Roman", Font.ITALIC, 9)); + getContentPane().add(jLabel4); + jLabel4.setBounds(427,40,139,13); + String path = System.getProperty("user.dir"); + String[] splitPath; + splitPath = path.split("/bin"); + jLabel2.setIcon(new javax.swing.ImageIcon(splitPath[0] + + "/resources/s4.png")); + jLabel2.setBounds(164, 529, 124, 19); + if (Desktop.isDesktopSupported()) { + jLabel2.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + if (evt.getClickCount() > count) { + try { + Desktop desktop = Desktop.getDesktop(); + desktop.browse(new URI("http://s4.io/")); + count++; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + count = 0; + } + getContentPane().add(jLabel2); + jLabel3.setText("Get Started"); + jLabel3.setFont(new Font("Times New Roman", Font.ITALIC, 11)); + jLabel3.setBounds(299, 529, 124, 19); + if (Desktop.isDesktopSupported()) { + jLabel3.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + if (evt.getClickCount() > count) { + try { + Desktop desktop = Desktop.getDesktop(); + desktop.browse(new URI( + "http://wiki.s4.io/Tutorials/GettingStarted")); + count++; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + count = 0; + } + getContentPane().add(jLabel3); + + for (int i = 0; i < 10; i++) { + javax.swing.JLabel jLabelTweet = new javax.swing.JLabel(); + javax.swing.JLabel jLabelFrequency = new javax.swing.JLabel(); + final String tweet = (String) tweets[i][0]; + jLabelTweet.setText("" + tweet + ""); + long count = ((Long) tweets[i][1]); + jLabelFrequency.setText(Long.toString((Long) tweets[i][1])); + jLabelTweet.setBounds(x1, y + (i * 40), 200, 13); + if (Desktop.isDesktopSupported()) { + jLabelTweet.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent evt) { + if (evt.getClickCount() > 0) { + try { + Desktop desktop = Desktop.getDesktop(); + URLEncoder.encode(tweet, "UTF-8"); + desktop.browse(new URI( + "http://twitter.com/search?q=" + tweet)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }); + } + getContentPane().add(jLabelTweet); + if (maxCount != 0) { + int size = (int) ((250 / maxCount) * count); + if (size > countDigits(count) * 18) { + jLabelFrequency.setBounds(x2, y + (i * 40), + size, 13); + } + else { + jLabelFrequency.setBounds(x2, y + (i * 40), + countDigits(count) * 18, 13); + } + } + else { + jLabelFrequency.setBounds(x2, y + (i * 40), + 20, 13); + } + jLabelFrequency.setBackground(new java.awt.Color(246, 232, 252)); + jLabelFrequency.setForeground(new java.awt.Color(51, 0, 51)); + jLabelFrequency.setOpaque(true); + getContentPane().add(jLabelFrequency); + } + getContentPane().repaint(); + getContentPane().setVisible(true); + } + + public int countDigits(long count) { + int width = 0; + while (count > 1) { + count /= 10; + width++; + } + return width; + } + + public Object[][] readTopNTweets() { + Object[][] tweets = new Object [][] {{"", 0L}, {"", 0L},{"", 0L}, {"", 0L},{"", 0L}, {"", 0L},{"", 0L}, {"", 0L},{"", 0L}, {"", 0L},{"", 0L}, {"", 0L}}; + long maxCount = 0; + int size = 0; + Scanner scanner = null; + try { + File file = new File(fileName); + if (timestamp < file.lastModified()/1000) { + timestamp = file.lastModified()/1000; + } + scanner = new Scanner(file); + if (scanner.hasNext()) { + String line = scanner.nextLine(); + if ((line != null) && (line != "")) { + JSONObject jsonObject = new JSONObject(line); + JSONArray jsonArray = jsonObject.getJSONArray("topN"); + int numberOfTweets = jsonArray.length(); + for (int i = 0; i < numberOfTweets; i++) { + JSONObject record = (JSONObject) jsonArray.get(i); + tweets[i][0] = record.getString("topic"); + long count = record.getLong("count"); + if (count > maxCount) { + maxCount = count; + } + String countString = Long.toString(record.getLong("count")); + JLabel countLabel = new JLabel(countString); + if (maxCount == 0) { + size =400; + } + else { + size = (int) ((400 / maxCount) * count); + } + countLabel.setSize(size, 29); + countLabel.setBackground(new java.awt.Color(183, 123, 213)); + tweets[i][1] = record.getLong("count"); + } + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } finally { + scanner.close(); + } + drawComponents(tweets, maxCount); + return tweets; + } + + /** + * @param args + * the command line arguments + */ + public static void main(String args[]) { + final TwitterUI twitterUI = new TwitterUI(); + twitterUI.fileName = args[0]; + + while (true) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + twitterUI.readTopNTweets(); + twitterUI.setVisible(true); + } + }); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private javax.swing.JLabel jLabel1; + private javax.swing.JButton jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private String fileName; + +} diff --git a/twittertopiccount/src/main/resources/adapter_conf.xml b/twittertopiccount/src/main/resources/adapter_conf.xml index c8b8219..befe115 100644 --- a/twittertopiccount/src/main/resources/adapter_conf.xml +++ b/twittertopiccount/src/main/resources/adapter_conf.xml @@ -5,11 +5,10 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> - - - + + diff --git a/twittertopiccount/twitter_topic_count.sh b/twittertopiccount/twitter_topic_count.sh new file mode 100755 index 0000000..2bbbad2 --- /dev/null +++ b/twittertopiccount/twitter_topic_count.sh @@ -0,0 +1,25 @@ +#! /bin/bash + +osx=false +case "`uname`" in +Darwin*) osx=true;; +esac + +if $osx; then + READLINK="stat" +else + READLINK="readlink" +fi + +CP_SEP=":" + +BASE_DIR=`dirname $($READLINK -f $0)` +echo $BASE_DIR + +CLASSPATH=$CLASSPATH$CP_SEP`find $BASE_DIR/../lib -name "*.jar" | awk '{p=$0"'$CP_SEP'"p;} END {print p}'` +echo $CLASSPATH + +CMD="java -classpath $CLASSPATH io.s4.example.twittertopiccount.ui.TwitterUI /tmp/top_n_hashtags" +echo "RUNNING $CMD" + +exec ${CMD}