Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import scala.actors.Actor;
- import scala.collection.mutable.{HashMap, HashSet};
- import scala.actors.Actor._;
- import org.jivesoftware.smack._;
- import org.jivesoftware.smackx._;
- import org.jivesoftware.smack.packet._;
- import java.util.regex._;
- case class Connected();
- case class Connect(user : String, password: String, server: String);
- case class Say(user : String, message: String);
- case class Said(user : String, message: String);
- case class Present(kind : Presence.Type, status : String);
- case class Listener(listener : Actor);
- case class Track(word : String);
- case class UnTrack(word : String);
- case class Tweet(tweet : String);
- case class Tweets();
- case class TweetDump(word : String, tweets : List[String]);
- case class Tracked(nick : String, tweet : String);
- case class TrackWords(trackwords : List[String]);
- case class UnTrackWords(trackwords : List[String]);
- class Jabber extends Actor {
- def act = {
- loop {
- react {
- case Connect(user, password, server) => {
- val conn = new XMPPConnection(server);
- conn.connect()
- conn.login(user,password);
- reply(Connected());
- val jabber = self;
- conn.getChatManager().addChatListener(new ChatManagerListener() {
- def chatCreated(chat : Chat, createdLocally: boolean) {
- if(!createdLocally) {
- chat.addMessageListener(new MessageListener() {
- def processMessage(chat : Chat, message : Message) {
- jabber ! Said(chat.getParticipant(), message.getBody());
- }
- });
- }
- }
- })
- connectedLoop(conn, Nil)
- }
- }
- }
- }
- def connectedLoop(conn : XMPPConnection, listeners : List[Actor]) {
- loop {
- react {
- case Listener(listener) => {
- connectedLoop(conn, listener :: listeners);
- }
- case Said(user, message) => {
- if(message != null) {
- listeners.foreach(_ ! Said(user, message));
- }
- }
- case Say(user, message) => {
- val jabber = self;
- conn.getChatManager().createChat(user, new MessageListener() {
- def processMessage(chat : Chat, message : Message) {
- jabber ! Said(chat.getParticipant(), message.getBody());
- }
- }
- ).sendMessage(message);
- }
- case Present(kind, status) => {
- val presence = new Presence(kind);
- presence.setStatus(status);
- conn.sendPacket(presence);
- }
- }
- }
- }
- }
- class TwitterWord(word : String) extends Actor {
- def act = {
- println("Starting up store for " + word);
- trackTweets(Nil);
- }
- def trackTweets(tweets : List[String]) {
- loop {
- react {
- case Tweet(tweet) => {
- trackTweets(tweet :: tweets);
- }
- case Tweets() => {
- reply(TweetDump(word, tweets));
- }
- }
- }
- }
- }
- class TwitterTracker extends Actor {
- val track = Pattern.compile("\\(([^)]+)\\): (.*)", Pattern.MULTILINE | Pattern.DOTALL);
- val trackinglist = Pattern.compile("You are tracking: (.*)\\.", Pattern.MULTILINE | Pattern.DOTALL);
- val trackingnotify = Pattern.compile("You'll now receive updates matching '([^']+)'.*", Pattern.MULTILINE | Pattern.DOTALL);
- val trackingunnotify = Pattern.compile("You'll no longer receive updates that match '([^']+)'.*", Pattern.MULTILINE | Pattern.DOTALL);
- val stores = new HashMap[String, Actor];
- def act = {
- val j = new Jabber().start
- j ! Listener(self);
- j ! Connect("trackingfeeds","biddulph","hackdiary.com")
- j ! Present(Presence.Type.available, "Scala");
- j ! Say("twitter@twitter.com", "track");
- react {
- case Connected() => {
- connectedAndWaitingForTrack(j);
- }
- }
- }
- def connectedAndWaitingForTrack(jabber : Actor) {
- loop {
- react {
- case Said(user, message) => {
- processSaid(user, message);
- }
- case TrackWords(trackwords) => {
- trackWords(trackwords);
- connected(jabber);
- }
- }
- }
- }
- def trackWords(trackwords : List[String]) {
- trackwords.foreach {
- word => {
- if(!stores.contains(word.toLowerCase)) {
- val store = new TwitterWord(word.toLowerCase).start
- stores += word.toLowerCase -> store;
- }
- }
- }
- }
- def unTrackWords(trackwords : List[String]) {
- trackwords.foreach {
- word => {
- stores -= word.toLowerCase;
- }
- }
- }
- def connected(jabber : Actor) {
- loop {
- react {
- case TrackWords(trackwords) => {
- trackWords(trackwords);
- }
- case UnTrackWords(trackwords) => {
- unTrackWords(trackwords);
- }
- case Tracked(nick, tweet) => {
- stores.keySet.foreach {
- word => {
- if(tweet.toLowerCase.contains(word)) {
- stores(word) ! Tweet(nick + ": " + tweet);
- }
- }
- }
- }
- case Tweets() => {
- stores.keySet.foreach {
- store => stores(store) ! Tweets();
- }
- }
- case TweetDump(word, tweets) => {
- if(tweets.length > 0) {
- println(word + ": " + tweets);
- }
- }
- case UnTrack(word) => {
- if(stores.contains(word.toLowerCase)) {
- jabber ! Say("twitter@twitter.com", "track " + word.toLowerCase);
- println("Stopping tracking " + word);
- } else {
- println("Not tracking " + word);
- }
- }
- case Track(word) => {
- if(!stores.contains(word.toLowerCase)) {
- jabber ! Say("twitter@twitter.com", "track " + word.toLowerCase);
- println("Starting tracking " + word);
- } else {
- println("Already tracking " + word);
- }
- }
- case Said(user, message) => {
- processSaid(user, message);
- }
- }
- }
- }
- def processSaid(user: String, message: String) {
- val trackedmatch = track.matcher(message);
- val trackinglistmatch = trackinglist.matcher(message);
- val trackingnotifymatch = trackingnotify.matcher(message);
- val trackingunnotifymatch = trackingunnotify.matcher(message);
- if(trackedmatch.matches()) {
- self ! Tracked(trackedmatch.group(1), trackedmatch.group(2));
- } else if(trackinglistmatch.matches()) {
- self ! TrackWords(trackinglistmatch.group(1).split(", ").map { x => x.substring(1,x.length-1) }.toList)
- } else if(trackingnotifymatch.matches()) {
- self ! TrackWords(List(trackingnotifymatch.group(1)));
- } else if(trackingunnotifymatch.matches()) {
- self ! UnTrackWords(List(trackingunnotifymatch.group(1)));
- }
- }
- }
- val t = new TwitterTracker().start
- while(true) {
- Thread.sleep(5000)
- t ! Tweets()
- }
Add Comment
Please, Sign In to add comment