Today I was trying to use the Google Closure compiler to build a single .js file out of several source files and their closure library dependencies:
closure-library-read-only/closure/bin/calcdeps.py -p closure-library-read-only -i bar.js -i foo.js -o compiled -c closure-compiler/compiler.jar > compiled.js
I kept getting errors like this:
Exception: Missing provider for (foo.Foo)
That sucked, since foo.js with its goog.Provide("foo.Foo") was right in the same directory with bar.js, and I even specified it explicitly on the command line.
Turns out I needed to specify "-p ." so that it'd look in the current directory for the dependency. So with a command line of:
closure-library-read-only/closure/bin/calcdeps.py -p . -p closure-library-read-only -i bar.js -i foo.js -o compiled -c closure-compiler/compiler.jar > compiled.js
I got:
Exception: Duplicate provide (goog.async.DeferredList) in ...
That seemed even weirder. Turns out calcdeps doesn't like having the same subdirectory show up twice in -p arguments. That is, "-p ." and "-p closure-library-read-only" was causing it to find the closure library twice. Okay, so we take out the second -p:
closure-library-read-only/closure/bin/calcdeps.py -p . -i bar.js -i foo.js -o compiled -c closure-compiler/compiler.jar > compiled.js
Now I get:
ERROR - namespace "foo.Foo" cannot be provided twice
Almost there: it doesn't like having foo.js explicitly provided. This actually worked:
closure-library-read-only/closure/bin/calcdeps.py -p . -i bar.js -o compiled -c closure-compiler/compiler.jar > compiled.js
Tuesday, March 16, 2010
Sunday, March 14, 2010
Universal Muses
The universe halted. This would have been traumatic for its inhabitants, had they been able to notice. But their brains had halted along with everything else, so they didn't mind.
"More elevator music. I'm telling you, happiness doesn't make for good art," said Cyn.
"I suppose you're right. I guess I just have a soft spot for them." Fob sighed, twiddling the values in the configuration file.
He pressed a button and erased the 10e80 particle simulation. 175 billion galaxies ceased to be simulated.
Cyn softened. "Look at it this way:the suffering is what gives their lives meaning. No suffering means no art, and no art means there's no point wasting computer time on them." Cyn and Fob shared time on a supercomputer with 10^73 gigabytes of memory, or about 100 times the number of particles in our universe. It had been respectable when it was built, but was starting to show its age.
"Yeah, I guess," said Fob, distracted. "How about this? I'm going to restore the water planet from the pre-life checkpoint, but turn up the resource saturation and sunlight, so they'll really eat each other alive."
"If you really think that'll help. At least turn up the quantum granularity so it doesn't take forever to run."
Fob laughed. "Okay, okay. The poor physicists. Maybe they'll start writing requiems."
Life bloomed and ended. Then bloomed again, and ended. On the third try it caught.
"Giant lizards. Cute."
Cyn and Fob searched the history books, as soon as there were history books. "Hey, some of this architecture is pretty good."
Fob checked another result. "And check out the music. There's a whole cluster of them right around 1800."
"Meh, it's okay. Make this one go deaf and see what happens."
"More elevator music. I'm telling you, happiness doesn't make for good art," said Cyn.
"I suppose you're right. I guess I just have a soft spot for them." Fob sighed, twiddling the values in the configuration file.
He pressed a button and erased the 10e80 particle simulation. 175 billion galaxies ceased to be simulated.
Cyn softened. "Look at it this way:the suffering is what gives their lives meaning. No suffering means no art, and no art means there's no point wasting computer time on them." Cyn and Fob shared time on a supercomputer with 10^73 gigabytes of memory, or about 100 times the number of particles in our universe. It had been respectable when it was built, but was starting to show its age.
"Yeah, I guess," said Fob, distracted. "How about this? I'm going to restore the water planet from the pre-life checkpoint, but turn up the resource saturation and sunlight, so they'll really eat each other alive."
"If you really think that'll help. At least turn up the quantum granularity so it doesn't take forever to run."
Fob laughed. "Okay, okay. The poor physicists. Maybe they'll start writing requiems."
Life bloomed and ended. Then bloomed again, and ended. On the third try it caught.
"Giant lizards. Cute."
Cyn and Fob searched the history books, as soon as there were history books. "Hey, some of this architecture is pretty good."
Fob checked another result. "And check out the music. There's a whole cluster of them right around 1800."
"Meh, it's okay. Make this one go deaf and see what happens."
Monday, March 01, 2010
XMPP / asmack / android / Google Talk
OK, I finally figured out how to send and receive XMPP instant messages from my gmail account using asmack with an Android 2.1 AVD. For some reason, the event-driven message receive code doesn't work, but this polling example code does. Here's my latest source:
// DON'T FORGET TO INCLUDE THE INTERNET PERMISSION IN YOUR MANIFEST.XML
package com.example.HelloFormStuff;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromContainsFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
public class HelloFormStuffActivity extends Activity {
public int state = 0;
private static final String TAG = "HelloFormStuffActivity";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(new Runnable() {
public void run() {
//XMPPConnection xmpp = new XMPPConnection("jabber.iitsp.com");
XMPPConnection xmpp = new XMPPConnection("gmail.com");
try {
xmpp.connect();
// for other jabber accounts, truncate after the @
//xmpp.login("username", "password");
// for gtalk / gmail, include the @
xmpp.login("your-gmail-account@gmail.com", "your-gmail-password");
} catch (XMPPException e) {
Log.v(TAG, "Failed to connect to " + xmpp.getHost());
e.printStackTrace();
}
ChatManager chatmanager = xmpp.getChatManager();
Chat newChat = chatmanager.createChat("friend@gmail.com", new MessageListener() {
// THIS CODE NEVER GETS CALLED FOR SOME REASON
public void processMessage(Chat chat, Message message) {
try {
Log.v(TAG, "Got:" + message.getBody());
chat.sendMessage(message.getBody());
} catch (XMPPException e) {
Log.v(TAG, "Couldn't respond:" + e);
}
Log.v(TAG, message.toString());
}
});
// Send something to friend@gmail.com
try {
newChat.sendMessage("OMNOMNOM");
} catch (XMPPException e) {
Log.v(TAG, "couldn't send:" + e.toString());
}
// Accept only messages from friend@gmail.com
PacketFilter filter
= new AndFilter(new PacketTypeFilter(Message.class),
new FromContainsFilter("friend@gmail.com"));
// Collect these messages
PacketCollector collector = xmpp.createPacketCollector(filter);
while(true) {
Packet packet = collector.nextResult();
if (packet instanceof Message) {
Message msg = (Message) packet;
// Process message
Log.v(TAG, "Got message:" + msg.getBody());
}
}
}
}).start();
//setContentView(this);
}
}
Friday, February 26, 2010
Android XMPP
Update: working code for send/receive over XMPP from gtalk / non-gtalk accounts
So, apparently XMPP support was briefly part of the official android SDK, but they took it out again.
There's a respected library called "smack", but it doesn't work with android out of the box.
There's a hack of smack for android called asmack, and that seems to work for me, at least for sending messages.
I haven't figured out how to make it work with talk.google.com, but I created an account at jabber.iitsp.com and was successful in sending an IM from my android.
Don't forget to add the INTERNET permission to the manifest.xml, or you'll get "not connected" exceptions.
So, apparently XMPP support was briefly part of the official android SDK, but they took it out again.
There's a respected library called "smack", but it doesn't work with android out of the box.
There's a hack of smack for android called asmack, and that seems to work for me, at least for sending messages.
I haven't figured out how to make it work with talk.google.com, but I created an account at jabber.iitsp.com and was successful in sending an IM from my android.
package com.example.HelloFormStuff;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
public class HelloFormStuffActivity extends Activity {
public int state = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
XMPPConnection xmpp = new XMPPConnection("jabber.iitsp.com");
try {
xmpp.connect();
xmpp.login("username","password"); // just username, no @ sign
} catch (XMPPException e) {
// TODO Auto-generated catch block
System.out.println("Failed to connect to " + xmpp.getHost());
e.printStackTrace();
}
ChatManager chatmanager = xmpp.getChatManager();
Chat newChat = chatmanager.createChat("destination@example.com", new MessageListener() {
public void processMessage(Chat chat, Message message) {
Toast.makeText(HelloFormStuffActivity.this, message.toString(), Toast.LENGTH_SHORT).show();
}
});
try {
newChat.sendMessage("IMing from my android");
} catch (XMPPException e) {
Toast.makeText(HelloFormStuffActivity.this, "ERROR", Toast.LENGTH_SHORT).show();
}
...
Don't forget to add the INTERNET permission to the manifest.xml, or you'll get "not connected" exceptions.
Wednesday, February 17, 2010
picasa gdata API and face recognition
Tonight I wanted to download a list of photos from picasaweb with a particular person in them, using the "subjectids" field. I don't see any official way to do this, but here's how I managed it:
In picasaweb (in my web browser), I loaded up the page showing all the photos my friend was in. At the bottom, there was a little "RSS" link. That link looked like this:
http://picasaweb.google.com/data/feed/base/user/credentiality?alt=rss&kind=photo&subjectids=SOME_BIG_LONG_STRING_OF_CHARACTERS&authkey=A_SHORTER_STRING&hl=en_US
I loaded that link in my browser, and it gave me the option to keep it as a live bookmark.
Instead, I trimmed the URL down and plunked it in this little python gdata script:
That printed out a list of URLs to the images I wanted.
In picasaweb (in my web browser), I loaded up the page showing all the photos my friend was in. At the bottom, there was a little "RSS" link. That link looked like this:
http://picasaweb.google.com/data/feed/base/user/credentiality?alt=rss&kind=photo&subjectids=SOME_BIG_LONG_STRING_OF_CHARACTERS&authkey=A_SHORTER_STRING&hl=en_US
I loaded that link in my browser, and it gave me the option to keep it as a live bookmark.
Instead, I trimmed the URL down and plunked it in this little python gdata script:
#!/usr/bin/python
import gdata.photos.service
import gdata.media
import gdata.geo
gd_client = gdata.photos.service.PhotosService()
gd_client.email = 'MY_EMAIL_ADDRESS'
gd_client.password = 'MY_PASSWORD'
gd_client.source = 'exampleCo-exampleApp-1'
gd_client.ProgrammaticLogin()
print "logged in"
photos = gd_client.GetFeed('/data/feed/base/user/credentiality?kind=photo&subjectids=THE_SAME_BIG_LONG_STRING')
for photo in photos.entry:
print photo.content.src
That printed out a list of URLs to the images I wanted.
Thursday, February 11, 2010
TED2010 Jane McGonigal on gamers
Jane puts a really positive spin on the time people spend gaming. Games give us much more positive reinforcement than we get from real life, and people are consequently spending HUGE amounts of time gaming. 500 million gamers worldwide spend at least an hour a day gaming. Serious gamers spend 10,000 hours gaming by the time they turn 21 -- the same time they spent in K-12 education. People have spent 6 million man-years playing World of Warcraft.
I have long felt that we need to find a way to give people in real life the kind of positive stimulus they get in games, and she puts it in a much more optimistic way than I could. I'm really glad she's working on it.
I have long felt that we need to find a way to give people in real life the kind of positive stimulus they get in games, and she puts it in a much more optimistic way than I could. I'm really glad she's working on it.
Wednesday, February 10, 2010
#TED Wednesday morning session
Very welcome scientific results on fighting poverty in Africa: handing out a kilogram of lentils with immunizations drasticaly increases rate of child innoculation. Deworming, iron supplements vastly more effective at keeping kids in school than hiring more teachers or other more conventional approaches.
Ukelele flamenco ftw.
And some worthwhile arguments about why our race is evolved to believe things and find patters where there isn't anything, since it's safer to be think there's a lion in the bush and be wrong than to think there isn't and be wrong.
Ukelele flamenco ftw.
And some worthwhile arguments about why our race is evolved to believe things and find patters where there isn't anything, since it's safer to be think there's a lion in the bush and be wrong than to think there isn't and be wrong.
Subscribe to:
Posts (Atom)