Pidgin-Webkit works! (on Linux)

So basically, there’s this other libpurple based client on that other platform, called Adium, which uses webkit as the IM rendering backend and allows for tons of crazy message styles that really make the IM client a more unique and aesthetically appealing program. These days, webkit is being used everwhere, from desktop browsers such as Safari and Chrome to smartphone OSes like iPhone OS X and Android. It seems that webkit is in general easier to embed into other applications than gecko, which is kind of a shame in my opinion, but I suppose if something works better for certain purposes, it makes sense to use it.

Some time ago, one of the pidgin developers, Sean Egan, decided to try and embed webkit into Pidgin and then use Adium’s message styles. He got it into a working state, the results of which can be seen here, but it was kind of left out for the public to see and never got integrated into Pidgin proper, since I assume the code was somewhat hackish. Of course, as this was a very exciting development, eventually someone else picked it up and developed it a bit.

The latest pidgin-webkit source can be found on launchpad, a site run by Canonical that is similar to Sourceforge, Google Code, github, etc. You can check out the source using bzr and after installing the proper development headers for pidgin and webkit, the plugin actually compiles, and you can use it! Under Ubuntu at least the proper headers are found in packages nicely labeled libwebkit-dev and pidgin-dev. After installing the dependencies you just do a make and then make install to get the plugin installed into Pidgin. You can then use it as you would any plugin, and you just put the Adium messagestyles folders into $PURPLEHOME/message_styles.

Unfortunately, I haven’t gotten it to compile on Windows yet, which is my primary OS at the moment, but I’m working on setting up a Pidgin cross-compile environment in a VM so I can try to compile a Windows .dll, which would be the height of awesomeness. I think if I have free time I would love to actually look at the plugin and try to continue development, since the last guy working on it seems to have become too busy.

Oh, this is the homepage for Pidgin-webkit.

How to use git over scp without git on the remote server

This is basically a quick adaptation of this handy tutorial to use scp instead of a usb drive. I find it useful when I have a project I want to track using git across multiple computers, and I don’t want to make it public and use github.

First, make a new directory someplace that will be your local “remote” repository. Essentially, we will use this as the remote repository and use scp to update it when necessary, and then pull from and push to it. Then cd to your working directory, and do

git clone –local –bare . /path/to/remote/repository.git

Then, add it as a remote

git remote add origin file:///path/to/remote/repository.git

Once you’ve done this, you can simply do a git push to push to this repository. Now, when you want to use this repository on another computer, first copy it to a remote server using scp:

scp –r /path/to/remote/repository.git user@host:~/git/repository.git

I like to make a git directory in my home directory both locally and on the server, to store my “remote” repositories. Whenever you update the local “remote” git repository, just use scp to copy it to the server.

When you want to get at this repository from another computer, use scp to pull down the repository, and then do a git clone or git pull to get your updated contents into your working directory.

scp –r user@host:~/git/repository.git /path/to/different/remote/repository.git

and then a git clone or git pull as necessary.
Hope this helps someone, as I was looking for something like this and couldn’t figure it out initially. It’s pretty simple but for a git newbie like me it wasn’t immediately obvious.

Github

I’ve been using SVN for several years now, because revision control is essential to programming pretty much anything slightly complicated. SVN is really straightforward and easy to use, and it has served me well. However, these days people are moving on to distributed version control systems, so I figured I’d check one out (pardon the pun). These days, the most popular thing in the open source world seems to be git, so I decided on that. The learning curve is decidedly sharper than SVN’s, but I’m sort of finding my way through it. The thing I really like about git is github; sort of a social network for git code hosting. I’ve got an account there and I’ll be pushing my random test stuff onto that for the time being. The nice thing about git/github is that it feels cheaper to do things, so you don’t worry too much about experimenting. I’ll probably still put bigger commits on Google Code’s SVN, but unfortunately the native windows port of git, msys-git, lacks git-svn so I have to do it manually. Anyway, my github url is  http://github.com/ibrahima , where you can find my meager progress on wii projects. Unfortunately, school is taking up too much of my time but I might try to make a prototype of a windowing system tomorrow.

WorldWiideWeb – A Wii homebrew web browser

So, I’m starting to develop Wii homebrew, and I felt that one thing the Wii lacks is an easy way to download homebrew that isn’t on the Homebrew Browser. I decided that the best solution for this would be to make a web browser. I had also wanted to make an RSS reader, so I will be including that as well. I decided upon the painfully creative name “WorldWiideWeb” because it seemed somewhat appropriate. I apologize for the name, but it was the best I could come up with.

To date, I have made a simple app that downloads a specified file. Now, I’m going to focus on the presentation aspect, and I’ve decided that I might as well make a general-purpose library type thing for Wii homebrew application GUIs, which easily allows the developer to make windows and such. Unfortunately, I’m now away from my Wii on weekdays so I’ll have to learn SDL/C++ to make some mockups of the windowing system. But hopefully, this should end up being very useful for the Wii homebrew community. I don’t expect anything useful to be completed before summer, though.

How to Write an Auto-Updater System in Java

Occasionally I do things where I spend a large portion of time looking up tidbits of code from various sources to string together something really cool. Usually I wish someone had documented how to do them so I wouldn’t have to jump around from site to site looking for things. This is one such time. I wanted to write an auto-updater for a java program, distributed in a jar file. Although this may sound somewhat complicated, it’s actually fairly simple, especially when your entire program is just one jar file. More programs should implement something like this, but I digress.

Here are the steps necessary for a complete autoupdating system. I will elaborate sometime in the near future, with code examples.

Step 0: Automate your build process

This is optional, but makes things easier. Basically, you can set up a build script using Ant that you can just double click to compile, assign a revision number, jar, and then upload your program to a webserver. Ant is an XML based build system, and since I’m not really familiar with build scripts I was surprised at how powerful and easy to use it is. I won’t go into depth about Ant, but this is a good link for getting started. Basically, you use XML to describe a set of tasks you want it to do. These groups of tasks are called targets. Of course, Eclipse, my editor of choice, has excellent Ant support, so editing is really easy, properties are autocompleted, and running scripts is just a double click on the desired target. There are a couple things that are of specific use for an auto-updater, such as finding the current revision of your code (in my case, from SVN, although you could use anything really).

<target name="find_revision" description="Sets property 'svn.revision' to the head svn revision"> <taskdef resource="org/tigris/subversion/svnant/svnantlib.xml" /> <svn> <status path="src" revisionProperty="svn.revision" /> </svn> <echo>Revision: ${svn.revision}</echo> <echo file="revision.txt" append="false">${svn.revision}</echo> </target>

This code grabs the revision number from SVN, using the SVNAnt plugin, and then stores it in a file called revision.txt, as well as the variable svn.revision.

 

<target name="create_run_jar" depends="build,find_revision"> <jar destfile="foo.jar" filesetmanifest="mergewithoutmain"> <manifest> <attribute name="Built-By" value="${user.name}" /> <attribute name="Main-Class" value="package.MainClass" /> <attribute name="Class-Path" value="." /> <attribute name="Implementation-Vendor" value="The Team" /> <attribute name="Implementation-Title" value="The Program" /> <attribute name="Implementation-Version" value="${version.num}r${svn.revision}" /> </manifest> <fileset dir="classes" /> <fileset file="revision.txt" /> </jar> </target>

This bit packages the code into an executable jar file. It also grabs revision.txt, so the software can figure out what revision it is. I had a similar jar for my updater, since if your program is running you can’t overwrite it, at least on Windows, so you need to use a separate executable to actually download the update.

<target name="copy_to_server" depends="find_revision,create_run_jar,create_updater_jar"> <input message="Please enter username:" addproperty="scpuser" /> <input message="Please enter password:" addproperty="scppw" /> <scp file="foo.jar" trust="yes" remoteToFile="${scpuser}:${scppw}@my.server.com:~/public_html/stuff/foor${svn.revision}.jar"> </scp> <scp file="updater.jar" trust="yes" remoteToFile="${scpuser}:${scppw}@my.server.com:~/public_html/stuff/updater.jar"> </scp> <sshexec host="my.server.com" username="${scpuser}" password="${scppw}" trust="yes" command="chmod 644 ~/public_html/stuff/foor${svn.revision}.jar" /> <sshexec host="my.server.com" username="${scpuser}" password="${scppw}" trust="yes" command="ln -s -f ~/public_html/stuff/foor${svn.revision}.jar ~/public_html/stuff/foo.jar" /> <scp file="revision.txt" trust="yes" todir="${scpuser}:${scppw}@my.server.com:~/public_html/stuff"> </scp> </target>

This part copies the files to the server, using scp. SCP is the secure file copy client, part of SSH. There’s probably a plugin to use FTP too, if that’s your thing. The thing about SCP is that it gives files default permissions of 0600, meaning they aren’t world readable, no matter what your umask is, so you need to follow it up with an ssh command to chmod the file to the proper permissions, probably 644. Just for the sake of keeping old revisions on the server, instead of uploading something to foo.jar I upload to foor${svn.revision} and then create a symlink from the latest file to foo.jar.

Step 1: Store your local version somewhere

In my case, I stored it inside the jar file in a text file called revision.txt using the Ant script. Later, you can get at it by using this little bit of code.

public int currentRevision(){ BufferedReader is; try { is = new BufferedReader( new InputStreamReader(ClassLoader.getSystemResource("revision.txt").openStream())); int rev = Integer.valueOf(is.readLine()); return rev; } catch(NullPointerException e){ }catch (Exception e) { e.printStackTrace(); } return 1<<31-1; }

This checks inside the jar file for a revision.txt, and then parses it to get the current revision. If no file is found, it returns the largest possible value for an int, to avoid problems with trying to update needlessly.

Step 2: Host updates on a server, along with a latest version number

I used a remote revision.txt to check against the local one. You can check the latest revision using this snippet of code:

public int latestRevision(){ URL url; try { url = new URL("http://my.server.com/~me/stuff/revision.txt"); HttpURLConnection hConnection = (HttpURLConnection) url .openConnection(); HttpURLConnection.setFollowRedirects(true); if (HttpURLConnection.HTTP_OK == hConnection.getResponseCode()) { BufferedReader is = new BufferedReader(new InputStreamReader(hConnection.getInputStream())); int rev = Integer.valueOf(is.readLine()); return rev; } }catch(IOException e){ e.printStackTrace(); } return -1; }

This simply downloads a file from the server and returns the int value of the file. All uploading tasks are taken care of by the Ant script, which you would run every time you want to publish a new revision. You would want to compare the latest revision with your revision at some time that makes sense for your program, probably at startup. If you find that there’s a new version, notify the user that there is an update available, and then start the updater and exit yourself (System.exit(0);).

Step 3: Write a downloader stub that downloads the new version

Since you can’t write to an open file (at least on Windows) you need to download the new version in a separate process and close the current one. I used a specialized class just for downloading the file. I also included a general purpose method for downloading files in case other parts need to download anything. This is used in another class to download the updater.jar, in case it doesn’t exist. You might find that you need to update the updater, in which case you can just skip the check for an existing updater, or go through the trouble of versioning the updater too. It’s not that difficult, but probably not really worth it when the updater.jar is around 3kb.

package updater; import java.awt.Dimension; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import javax.swing.JFrame; import javax.swing.JProgressBar; public class Updater extends JFrame{ String updateurl; JProgressBar progress; public static void main(String[] args){ Updater up = new Updater("http://my.server.com/~me/stuff/foo.jar"); up.downloadLatestVersion(); try { Process foo = Runtime.getRuntime().exec("java -jar foo.jar"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.exit(0); } public Updater(String url){ updateurl = url; this.setPreferredSize(new Dimension(300, 80)); this.setSize(new Dimension(300, 80)); this.setTitle("Updater"); progress = new JProgressBar(0,100); progress.setValue(0); progress.setStringPainted(true); this.add(progress); this.setLocationRelativeTo(null); this.setVisible(true); this.requestFocus(true); } void downloadLatestVersion(){ URL url; try { url = new URL(updateurl); HttpURLConnection hConnection = (HttpURLConnection) url .openConnection(); HttpURLConnection.setFollowRedirects(true); if (HttpURLConnection.HTTP_OK == hConnection.getResponseCode()) { InputStream in = hConnection.getInputStream(); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream("foo.jar")); int filesize = hConnection.getContentLength(); progress.setMaximum(filesize); byte[] buffer = new byte[4096]; int numRead; long numWritten = 0; while ((numRead = in.read(buffer)) != -1) { out.write(buffer, 0, numRead); numWritten += numRead; System.out.println((double)numWritten/(double)filesize); progress.setValue((int) numWritten); } if(filesize!=numWritten) System.out.println("Wrote "+numWritten+" bytes, should have been "+filesize); else System.out.println("Downloaded successfully."); out.close(); in.close(); } }catch(IOException e){ e.printStackTrace(); } } public static void downloadFile(String sourceurl, String dest){ URL url; try { url = new URL(sourceurl); HttpURLConnection hConnection = (HttpURLConnection) url .openConnection(); HttpURLConnection.setFollowRedirects(true); if (HttpURLConnection.HTTP_OK == hConnection.getResponseCode()) { InputStream in = hConnection.getInputStream(); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(dest)); int filesize = hConnection.getContentLength(); byte[] buffer = new byte[4096]; int numRead; long numWritten = 0; while ((numRead = in.read(buffer)) != -1) { out.write(buffer, 0, numRead); numWritten += numRead; System.out.println((double)numWritten/(double)filesize); } if(filesize!=numWritten) System.out.println("Wrote "+numWritten+" bytes, should have been "+filesize); else System.out.println("Downloaded successfully."); out.close(); in.close(); } }catch(IOException e){ e.printStackTrace(); } } }

This code is pretty easy to follow, and half of it is essentially the same method duplicated for reuse in other places. In hindsight, I probably could have statically downloaded the update file, but then I wouldn’t be able to use the nice progress bar.

Step 4: Restart with the new version

Once you’ve downloaded the new version, the updater will simply start the new version and quit. And then, you’ve got an automatic updater system that is pretty simple and easy to use. Thanks to jar files, you won’t even have to worry about grabbing a large number of files, although if you really wanted to save bandwidth you could do something where you split up your code and resources between jar files. In my case it wouldn’t really matter since my entire program, including resources, is under 500kb, and if it was just the code by itself it would download before the progress bar even showed up. As for my project, maybe I’ll reveal it in another post once I clear up some issues.

Nintendo DSi

So Nintendo announced the third iteration of the DS this week. Unfortunately, it seems like two or three steps forward and a couple steps back. However, I have a feeling there’s more to the DSi than has been announced as of yet. This is my opinion on the DSi:

Pros:

  • Slightly slimmer, which is kind of nice but the DS Lite is already pretty slim.
  • Bigger screens, although the resolution doesn’t seem to have been upgraded.
  • Internal NVRAM and SD card expandability for downloadable games and content- this is the major improvement in my mind, because it allows the firmware to be upgraded to add new features like other modern consoles and handhelds, although if the Wii is any indication feature additions might not be so forthcoming. Downloadable games are pretty cool to have, and this might be an easily exploited vector for homebrew, depending on how well Nintendo has protected their system- but more on that later.
  • Integrated web browser- this on its own is kind of useful, but the DS had this through homebrew and/or Opera. The more interesting things about this are the implications of a web browser- again, more on that later.
  • Cameras- not that useful to me, but it would be nice to have. The ability to edit photos on the other hand, as well as the webcam-looking one, also have some interesting implications that I’ll speculate on.
  • Matte finish- this is more of an aesthetic thing, but anyone who had a DS Lite, especially the black ones, knows how irritating it is to have something so glossy.

Cons:

  • No GBA slot- this is more annoying for people who had an extensive GBA library, or one of the DS games that use the GBA slot as expansion. Neither of those apply to me, so I don’t care too much.
  • No announced hardware upgrades- this might not be completely accurate, as I’ll speculate on later. But lack of hardware upgrades kind of implies that the real next generation DS is at least two years off, which is fairly annoying.
  • Lower battery life- this is a real WTF, because the projected battery life at highest brightness is a mere 3-4 hours, whereas the DS Lite’s projected life is 5-8 hours on high. This is really frustrating, but I guess you can always just turn the brightness down to get longer life.

The stuff we know about the DSi seems to imply a few things that might not have been announced. This is all speculation on my part, but I’d be surprised if none of these things are true.

  • Since the original Opera browser came with a RAM expansion, and now there’s no GBA slot, I’d be fairly surprised if there wasn’t a RAM upgrade to accommodate the browser. This could have nice implications for games and homebrew as well, and DSLinux might be easier to run. The other alternative is that they use the built in NVRAM as cache like homebrew browsers use SD as cache, but I do remember them saying the new browser would be faster than Opera, and I don’t think it would be possible to do that without the RAM upgrade.
  • The faster browser and the increased connectivity in general could mean that the WiFi chip has been upgraded. The WiFi in the DS/Lite is pretty pathetic, being a cut-down version of 802.11b that works at 2Mbps, and in practice is really slow. Homebrew downloads through DSOrganize’s homebrew database top out around 30kbps, although this might be due to the reverse engineered dswifi libs.
  • This one’s more of a stretch, but image editing might require a beefier processor than that currently in the DS. This might also be the reason the battery life is weaker, although that could also be attributed to the slimming of the case. This would of course be welcome.

I’ll add to this as I think up more wild guesses. Hey, I’m a market analyst!

Text Invaders 0.6

After a bit of work, I’ve released another version of Text Invaders in Java, this time a bit more featureful. The full changelog is on Google Code here, but in summary, I added a HUD, money/score, menus, a rudimentary shop, and waves. The release is available in executable jar format again here. The next release should add a lot of polish and turn what are mostly a bunch of placeholders in this version into actual counterparts of the VB version.