How to open mms:// links from Chrome under Ubuntu

December 7th, 2011 rei No comments

By default, Chrome will not launch mms:// (Windows Media streaming) links under Linux. It invokes xdg-open to “launch the user’s preferred application.” Under Ubuntu, xdg-open doesn’t handle mms:// links either.

Three steps:
1. Install mplayer and your choice of frontend (smplayer, gnome-mplayer)
2. Create a desktop entry for mms links.
3. Edit a configuration file to tie it all together.

Create a file named mms.desktop in ~/.local/share/applications/:

[Desktop Entry]
Name=Mplayer
Exec=smplayer %u
Type=Application
Icon=gnome-mplayer-icon
Terminal=false
MimeType=x-scheme-handler/mms;

Edit the mimeapps.list file in the same directory and add the following to the bottom of the [Default Applications] section:

x-scheme-handler/mms=mms.desktop

After this is done, you should be able to open mms:// links from Chrome. The link will open in the application you specified in the Exec entry in the desktop file.

Categories: Uncategorized Tags:

New blog: agnos.is

December 7th, 2011 rei No comments

I have created a new blog, agnos.is. The name is a domain hack for the word “agnosis.” If gnosis means “knowledge,” then agnosis means “no knowledge.” The word “agnostic” derives from agnosis. In this case, the name is a nod to the idea that this new blog is about discovering new things and learning new technologies. It focuses mostly on NodeJS, but will also focus on other programming languages and technologies.

agnos.is is built on a bunch of new and exciting technologies: Node, Redis, markdown, and cloud computing. The site is written entirely in server-side Javascript, using Express and a bunch of other NPM packages. It is hosted on the Rackspace Cloud, which allows far more control over the environment than a “traditional” web host, like the one this site runs on. It’s also a lot faster. Thermetics’ web host has always been slow for some reason.

agnos.is won’t replace thermetics.net, at least not yet. Thermetics has been around for many years, and though I never really did much with the domain except use it as personal storage, it is still high up in Google’s rankings, and has even been linked to by a few other websites. Thermetics will be a random useful tips blog for awhile longer. I may mirror posts between the two. I haven’t decided.

Categories: Uncategorized Tags:

Fixing Nexenta Zones: Update

October 25th, 2010 rei No comments

According to Comment #10 on Nexenta bug 203, some of the more glaring problems with Zones in Nexenta have been fixed in version 3.0.1. The most tedious fixes have been put in place. The only thing necessary to do now is simply dpkg-reconfigure sunwcsd once the zone is installed. I also did a reimport of sysevent.xml. It seems to be necessary (at least on my dist-upgraded system). In order to do the reconfiguring, you will need to be in maintenance mode. The zone should already have dropped into maintenance mode to begin with, so just zlogin and do the reconfigure. After that you will need to reboot the zone. Everything should then be working correctly. To get Nexenta 3.0.1, either dist-upgrade your existing system, or download the ISO from here.

Categories: Nexenta, OpenSolaris Tags:

Fixing Nexenta Zones

August 19th, 2010 rei 6 comments

Update: Some of the bugs in this post have been fixed, rendering a lot of the steps unnecessary. If you are running the latest version of Nexenta (3.0.1), you should only need to perform the last steps, where you dpkg-reconfigure sunwcsd and reimport the sysevent.xml file. See the new post for more details.

There is a nasty bug in Nexenta 3.0 that causes zones to function improperly. Services such as SSH are broken, packages may not install properly, etc. This is caused by a missing sysidtool, and a missing sysevent service. Two fix this problem, a few steps are required. First, in the global zone, you must edit /usr/bin/createzone and make the following changes:

1. Replace elatte-unstable with hardy-unstable. This should be found around line 41, in the default_config() subroutine.
2. Update the @source_files array as follows:

my @source_files = qw(
        /lib/svc/method/nexenta-sysidtool-system
        /var/svc/manifest/system/nexenta-sysidtool.xml
        /lib/svc/method/nexenta-sysidtool-net
        );

You are simply changing “elatte” to “nexenta” here.

Now, go through the normal zone creation process. If you don’t know how to do that, see here for a decent tutorial. The zone creation process should go off without a hitch, and sysidtool should install properly. Without our fixes, you would probably see an error that looks something like this.

There are still two more steps to be done. We must log in to the zone, but regular zlogin will not work until we fix another small bug. Boot the zone with “zoneadm -z yourZone boot”, then log in with “zlogin -S yourZone” instead of the normal zlogin. This will bring us to maintenance mode. Run pwconv:

zoneadm -z yourZone boot
zlogin -S yourZone

[In yourZone]
pwconv
exit

After this, regular zlogin should work. Now, we need to get the sysevent service working. Many services depend on this service. Without it, all of them will fail to start. To fix this, edit (from within the zone) the /lib/svc/method/svc-syseventd.

After the line . /lib/svc/share/smf_include.sh put
add [ `zonename` = global ] || sleep 3600 & exit 0

When finished, your zone’s /lib/svc/method/svc-syseventd file should look something like this. The bolded line is the one you added.

# CDDL Header
# ...

. /lib/svc/share/smf_include.sh
[ `zonename` = global ] || sleep 3600 & exit 0

case "$1" in
'start')
	/usr/lib/sysevent/syseventd >/dev/msglog 2>&1
	rc=$?
	if [ $rc -ne 0 ]; then
		echo "WARNING: /usr/lib/sysevent/syseventd failed: exit status $rc"
		exit $SMF_EXIT_ERR_FATAL
	fi
	;;

#
# devfsadmd and syseventconfd are started on-demand
# by syseventd. syseventd should be stopped before devfsadm and syseventconfd.
#
'stop')
	zone=`smf_zonename`
	/usr/bin/pkill -x -u 0 -P 1 -z $zone rcm_daemon
	/usr/bin/pkill -x -u 0 -P 1 -z $zone syseventd
	/usr/bin/pkill -x -u 0 -P 1 -z $zone devfsadm
	/usr/bin/pkill -x -u 0 -P 1 -z $zone syseventconfd

	#
	# Since pkill is not atomic (may miss forking processes), also
	# kill entire service contract.
	#
	smf_kill_contract $2 TERM 1
	[ $? -ne 0 ] && exit 1
	;;	

*)
	echo "Usage: $0 { start | stop }"
	exit 1
	;;

esac
exit 0

Finally, you will need to enter two more commands as the super-user:

dpkg-reconfigure sunwcsd
svccfg import /var/svc/manifest/system/sysevent.xml

Exit the zone and reboot it. Log in again, and everything should be magically working!

This information was compiled from several Nexenta bug reports (203, 173, LP #347937) after I ran into problems getting SSH working in my new zone. Apparently, the problems are bigger than SSH. I can’t take credit for discovering these fixes.

jyn: Simple Native Code Access in Jython

July 14th, 2010 rei No comments
I had been wanting to mess around with native code access in Java for awhile. I’ve also been delving fairly deep into Jython, mostly out of necessity for RingMUD. So, I decided to combine these two ideas, and started work on a simple library similar to ctypes. Jython does not have a working ctypes implementation yet, but it is coming along. This was mostly for my own experimentation to learn a bit more Python as well as experiment with JNA (Java Native Access).

JNA is the much simpler alternative to JNI. In normal Java, you define an interface that corresponds to the function prototypes of the native library you want to access. You then create a new “instance” of the library by calling JNA’s special gateway method. From that point on, you can call the defined functions of the library.

The nice thing about Python is that it is a dynamic language. By overriding __getattr__ and friends, and using JNA’s reflection API, it becomes possible to have Jython lazily load the function references and call them in a much more intuitive way. The name of this simple library is jyn (No, no alcohol was involved in the creation of this library).

An example:

import jyn
lib = jyn.libc() #Load libc for Windows or Unix
printf = lib.printf
printf("Hello world! I am printing from Jython!\n")

jyn is not really suitable for production environments yet. The most glaring problem at the moment is that there is no argument checking. This means that passing wrong arguments to a native function will usually crash the JVM. I am definitely open to more experienced Python developers willing to improve the library.

jyn is intended mainly as a demonstration of what is possible with Java and Jython. The Java platform brings with it a large selection of powerful libraries, and Jython brings the dynamic power of Python. Combined, they are an unbeatable team.

Grab jyn from GitHub.

Categories: Java Programming, Jython, Python Tags:

Mutliple Events with Jython Event Properties

June 10th, 2010 rei No comments

At first glance, Jython event properties seem magical–almost too magical. They allow you to bypass the massive Java boilerplate required to set up event listeners. What is normally something along these lines:

public class Test extends JFrame {
    private JButton button;

    public Test() {
         super("A Frame");
         setSize(200, 200);
         setupEvents();
         setVisible(true);
    }

    public void setupEvents() {
          button = new JButton("Click me");
          button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                      System.out.println("Button pressed");
                }
          });

         this.add(button);
    }
}

Instead becomes something like this, when using Jython:

class Test(JFrame):
    def __init__(self):
        JFrame.__init__(self, "A Frame")
        button = JButton("Hello", actionPerformed=self.buttonPress)

        self.add(button)
        self.setSize(200, 200)
        self.visible = true

    def buttonPress(self, event):
        print "Button pressed"

if __name__=="__main__":
    Test()

The Python version of this is far briefer and much more compact than its Java counterpart. That’s all well and good, you say, but what if you want to add multiple event handlers? At first glance, it does not look like Jython’s event properties would allow for such a thing. Luckily, it is possible. However, it is not documented. Indeed, documentation of Jython’s Java API and specialized features is a bit … lacking.

This undocumented feature was discovered after some chatting in the Jython IRC channel, and a bit of experimentation. It turns out that the event properties are actually an object type called CompoundCallable. These objects, as their name implies, store a set of functions that are executed one after another in sequence when called. Observe:

class Test(JFrame):
    def __init__(self):
        JFrame.__init__(self, "Hello Jython")
        button = JButton("Hello")
        button.actionPerformed = self.hello
        button.actionPerformed.append(self.otherEvent)
        self.add(button)

        self.setSize(200, 200)
        self.visible = true

    def hello(self, event):
        print "Hello, world!"

    def otherEvent(self, event):
        print "this is the other event"

if __name__=="__main__":
      Test()

When the button is clicked, both the “hello” and “otherEvent” functions will execute. Any Jython event property (including ones you create yourself) has two useful methods: append() and clear(). They do what their names say. The append method takes a function as a parameter, and adds it to the list of functions to be executed. The clear() methods clears all the functions out of the property.

Unfortunately, there do not appear to be ways to iterate over the functions contained within the CompoundCallable, or access specific event handlers directly. In a similar vein, you cannot delete individual event handlers out of the CompoundCallable. Your only option is the clear() method.

The source code for the PyCompoundCallable object is very simple. It doesn’t look like it would be too hard to add some more methods for getting and deleting specific event handlers. (Scroll way down to the bottom of that page to view the code.)

Categories: Jython, Python Tags:

Internet Explorer 6 Disappearing Images and Text

March 12th, 2010 rei No comments

There is a strange bug in Internet Explorer 6 that causes images or text to disappear. This generally happens if there are floated elements within the element that is disappearing. This website (see #3) shows that by putting position: relative into the CSS style for the element that is disappearing, it will once again cause everything inside it to show up. Very strange.

Install Greasemonkey Scripts in Chromium the Easy Way

February 3rd, 2010 rei No comments

Simple tip: You want to install a Greasemonkey user script that isn’t hosted on www.userscripts.org. Or, you have the script residing on your hard drive and you want to install it from there. If you open the .js file directly in the browser, Chromium (I’m assuming Chrome will do the same) will pick it up as a script and install it.

MiXer Library: mixins in JavaScript

January 16th, 2010 rei No comments

Mixins in JavaScript certainly aren’t a new idea. However, I noticed a lack of libraries for implementing this pattern. JavaScript libraries like Dojo allow the developer to create something akin to traditional classes. Such a thing is an unnatural pattern for the language. It doesn’t have any base support for classical OOP, so the libraries have to implement tricky functions to mimic inheritance. Even these functions have their limits though.

Mixins are another way to do inheritance in JavaScript. It can be a radical departure from the “regular” inheritance model that many developers are used to. However, once one wraps their brain around it, one may find that it’s a good pattern, and perhaps even a better one for JavaScript. As always, the nature of the system should determine what kind of development patterns are used. This is just one more way of doing it. Check out MiXer to learn more.

Categories: Web Development Tags:

Google Wave’s Java Bot API: Part 1

November 29th, 2009 rei No comments

Google’s Wave has also come with a host of new development APIs for creating bots and embeddable gadgets. I have not had the chance to mess around with gadgets yet. However, I have been working on a simple bot for Google Wave (see below), written in Java. This project was started to create group management for the Fortress Forever community on Google Wave. Currently the community is extremely small; only seven people. Some of those people may not even remain active on Wave; they just wanted to see it and mess around with it. Anyway, that has not stopped this small project. It started out with simple group management, but is progressing to something bigger, badder, and better.

This is the first in a small series of small reviews about Google’s bot API. As I discover new things about the API, I will review them here. This first article will focus on the basics of the API overall. Subsequent articles will delve into more specific things. This particular article will also be focusing on the Java API, as I have not experimented with the Python version of the client library yet.

The Basics: Pros

Overall, the API is very straightforward for a platform that is as complicated as Wave. All of the complications of the Wave protocol are hidden inside a nice client library (currently Python and Java versions exist). Bots written in Java are J2EE web applications that build on the foundational concepts of servlets. The Java bot API provides a servlet class named AbstractRobotServlet.

You must extend this class and implement its processEvents(RobotMessageBundle bundle) method. This is the entry point for the bot, and will be called every time an event is raised by the Wave platform. From the RobotMessageBundle, you can get the wavelet that raised the event, as well as check some event types. Once you have the wavelet, you can do more things such as create new wavelets, append blips, edit text, and more.

The Basics: Cons

The most annoying thing I’ve found so far is that certain bits of information you may want use in order to process an event tend to be spread across the RobotMessageBundle, the Wavelet, and the Blip objects. This leads to one passing around the three different objects to fully process different events. This problem mostly arises as a design issue in the software, though. With proper design practices, passing around all three objects as parameters to methods can be avoided. However, I don’t see it being completely impossible that a framework built on the Wave robot library will arise.

The other thing I have found to be of minor annoyance is having to increment “version numbers” in the capabilities.xml file when a new event is added to the bot. This forces Wave to update its list of known capabilities on the bot. It seems a bit obtuse, rather than just having a forced capabilites.xml update whenever a new version of the bot is deployed to Google’s App Engine, or allowing the user to manually trigger an update the next time the bot is hit from Wave. I suppose the forced update on every new deployment would eat up more of Google’s resources than necessary, but the manual trigger for an update wouldn’t be that bad.

Perhaps the versioning stuff could be abstracted by the Google Plugin for Eclipse with a checkbox on the deploy screen that gives the option to force the Wave to update the bot’s capabilities cache. It’s a small change (and definitely of low priority given everything else that needs to be finished first), but would make things even easier/straightforward.