Adapting Twitter4J java code to run as MXJ

chope1's icon

Hi All,

I am trying to create an MXJ object from Twitter4J to make a list of daily trending topics on twitter.

I have seen something similar on the max forum already that is also based on twitter4J: https://cycling74.com/tools/searchtweet-design-patches-that-respond-to-twitter-posts/

This is the 'GetDailyTrends' code from Twiter4J to get a trending list from twitter: https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/trends/GetDailyTrends.java

What i have tried so far:

I have made some test MXJ objects successfully already. This one using an eclipse tutorial: (http://compusition.com/web/articles/maxmsp-eclipse) and also this from the MXJ tutorials (file:///Applications/Max5/java-doc/tutorial/html/Tutorial01.html)

Following this i tried compiling the GetDailyTrends .java code in Eclipse. this seems to work ok; it compiles and i get a returned list of trending topics in the eclipse console window.

When i add my extra code to this to turn it into a MXJ object i run into trouble. i got the error messages:

Error
Mon Aug 06 16:56:06 BST 2012
The Class File Viewer cannot handle the given input ('org.eclipse.ui.ide.FileStoreEditorInput').

There does seem to be a .class file generated though which i tried to open in max but when i send it a bang the max window reads:
GetDailyTrends doesn't understand bang

Max Patch
Copy patch and select New From Clipboard in Max.

here is the object in Max:

Does anyone have an idea of what i should be doing to adapt this code to run as an MXJ? Without any other knowledge of writing Java i dont know from looking at the code exactly how it functions (ie. what do info do its inlets and outlets need/produce etc.) to construct the right code around it.

I have attached the .java MXJ file i created.

The code i added to the original file is this:

import com.cycling74.max.Atom;
import com.cycling74.max.MaxObject;

And this:

private static final String[] INLET_ASSIST
    = { "bang to generate daily trends list" };
private static final String[] OUTLET_ASSIST
    = { "output daily trends list", };

public GetDailyTrends(Atom[] atoms) {
    declareInlets(new int[] { 15 });
    declareOutlets(new int[] { 15 });
    setInletAssist(INLET_ASSIST);
    setOutletAssist(OUTLET_ASSIST);
}

Any Help is much appreciated, Cheers.

I am running Max5 on OSX 10.6.8

4285.GetDailyTrends.java
java
lfxyz's icon

I used Twitter4J in my Individual Project for the Streaming API, so it's slightly different. I did everything in Eclipse, following these instructions to get Eclipse set up correctly: http://compusition.com/web/articles/maxmsp-eclipse

After this, I mainly let Eclipse check for errors, and corrected things until it seemed happy to compile. Then I crashed Max lots, until I finally got my external working properly.

Hope this helps a little!

The top of my file ended up like this:

package twitter4j.examples.stream;

import twitter4j.FilterQuery;
import twitter4j.Status;
import twitter4j.StatusDeletionNotice;
import twitter4j.StatusListener;
import twitter4j.TwitterException;
import twitter4j.TwitterStream;
import twitter4j.TwitterStreamFactory;
import twitter4j.conf.ConfigurationBuilder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

import com.cycling74.max.Atom;
import com.cycling74.max.MaxObject;

/**
*

This is a code example of Twitter4J Streaming API - filter method support.
* Usage: java twitter4j.examples.stream.PrintFilterStream [follow(comma separated numerical user ids)] [track(comma separated filter terms)]
*

*
* @author Yusuke Yamamoto - yusuke at mac.com
*/
public class getFilterStream extends MaxObject {
private TwitterStream twitterStream;
/**
* Main entry of this application.
*
* @param args follow(comma separated user ids) track(comma separated filter terms)
* @throws twitter4j.TwitterException
*/
    public getFilterStream() {
            declareIO(1,3);
        }

[Rest of my code went here]

chope1's icon

OK thanks for the pointers. Here's where I've got to.

I tried compiling the searchtweet.class file in eclipse because i knew it worked already in max. it had the same error as the code in the console as i got when trying to run my GetDailyTrends code. So... i checked the code i again in eclipse and compiled it (would it even compile if there was an error at this point?)

Next going into max i sent a bang into the object i get 'GetDailyTrends doesn't understand bang' in the max window - its in white text, not highlighted red. does this mean that the mxj object might work but that it just needs the right combination of other max objects around it to give it specific information (not just a bang in the inlet) to make it function?? The mxj searchtweet object needed text in a specific way to work. Can anyone suggest how i could use a few max objects to get this to work.

Max Patch
Copy patch and select New From Clipboard in Max.

mxj searchtweet and max objects:

chope1's icon

Update... I think i was looking at it from the wrong angle before I just dont know enough about java!. what i need to know to make this work:
- the kind of information coming in from twitter - a json file
- how the GetDailyTrends patch functions and what it is likely to output to max
- how to add to the existing patch to get it to function as an MXJ with in/outputs

I've found out some more about the Java patch and how it works, also an example of the json file it receives from twitter.

The json file from twitter has a whole load of info i dont need; url, query, promoted_content, events... i only need the text part that comes after "name". Here;s a snippet of that code:

"url": "http://twitter.com/search/%23ThoughtsDuringSchool",
"query": "%23ThoughtsDuringSchool",
"name": "#ThoughtsDuringSchool",
"promoted_content": null,
"events": null

Looking at the code in GetDailyTrends.java it looks like it prints out the list of names with this line of code: System.out.println(" " + trend.getName());

here is the code around it:

System.out.println("Showing daily trends");
            for (Trends trends : trendsList) {
                System.out.println("As of : " + trends.getAsOf());
                for (Trend trend : trends.getTrends()) {
                    System.out.println(" " + trend.getName());
                }
            }
            System.out.println("done.");
            System.exit(0);

I think what I need to do is find a way to output all the text that is being send out of the 'System.out.println' function in to an output of the mxj object as text.

lfxyz's icon

Okay, I've got all this stuff working. Twitter4j has built-in JSON parsing, so you don't need to worry about that. Also, you definitely need to delete the line 'System.exit(0);'

After you've got the code below compiled, you should be able to initiate the object in Max - send it a 'main' message, and it will print the trends out of the console, and also out of the first outlet.

If any of this doesn't make sense, then it's probably because I'm an idiot/amateur. Enjoy!
Assuming you've added all the correct .jars to your 'lib' folder (I just chucked them all in), then this code should compile:

/*
 * Copyright 2007 Yusuke Yamamoto
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package twitter4j.examples.trends;

import twitter4j.Trend;
import twitter4j.Trends;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

import com.cycling74.max.Atom;
import com.cycling74.max.MaxObject;

/**
 * Shows daily trends.
 *
 * @author Yusuke Yamamoto - yusuke at mac.com
 */
public final class GetDailyTrends extends MaxObject {
    /**
     * Usage: java twitter4j.examples.trends.GetDailyTrends [yyyy-mm-dd]
     *
     * @param args message
     */
    public GetDailyTrends(){
        declareIO(1,1);
    }

    public void main(String[] args) {
        try {
            Twitter twitter = new TwitterFactory().getInstance();
            List trendsList;
            if (args.length > 0) {
                trendsList = twitter.getDailyTrends(new SimpleDateFormat("yyyy-MM-dd").parse(args[0]), false);

            } else {
                trendsList = twitter.getDailyTrends();
            }
            outlet(0, "Showing daily trends");
            System.out.println("Showing daily trends");
            for (Trends trends : trendsList) {
                outlet(0, "As of : " + trends.getAsOf());
                System.out.println("As of : " + trends.getAsOf());
                for (Trend trend : trends.getTrends()) {
                    outlet(0, " " + trend.getName());
                    System.out.println(" " + trend.getName());
                }
            }
            System.out.println("done.");

        } catch (ParseException pe) {
            System.out.println("Usage: java twitter4j.examples.trends.GetDailyTrends [yyyy-mm-dd]");
            System.exit(-1);
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to get trends: " + te.getMessage());
            System.exit(-1);
        }
    }
}

chope1's icon

Hey Thanks so much. I just tried the code and it compiles and runs in eclipse. Only thing is I cant get it to print out in max!!. looking at the max window it seems to load fine.... What did you mean about sending it a 'main' message. i tried a few different things into the inlet but no results. sorry if i'm being dumb.

And thanks again for your help i really appreciate it.

lfxyz's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Something like this?

chope1's icon

Uh-ohh too simple. I think i tried that first and it did nothing. think maybe i hadn't updated the class file at that point- doh.

Cheers for the help, I owe you a beer!

lfxyz's icon

No problem :) I banged my head against the wall for a while getting twitter4j working in my dissertation. Enjoy!