software

First thoughts about Django-CMS

I just set up a site using Django-CMS over at Pomme d'Api Preschool. Overall, I am pretty impressed. I really like the Django admin interface enhancements as well as the site overlay editing feature. One of the best things it he use of django-filer, a file management tool to manage all the uploads to the site. It's awesome and it makes me want to throw out this home page completely and switch over to Django-CMS. Image handling in Drupal has always sucked and still does. The fact that there was no official media/image handling in Drupal 6 sucks, and it's made worse by the fact that there is no real upgrade path to Drupal 7 for media/images, especially if you're like me and you used the "Image" and "image-assist" modules, two of the most popular modules dealing with images.

Django-CMS is pretty powerful and so far it has allowed me to do pretty much anything I have wanted to do.

I Just Tried Windows 8

I just tried Windows 8, and to be honest it's pretty awful. It looks like it's meant for running on a touch screen but if you are a desktop user it's horribly awkward to use. I'm not sure if it's a bug but getting the task bar thingy (what's it called?) to show up on the left-hand side of the screen is very difficult. I seem to have to hover on the top-left corner and wait for an icon to appear, then move downward, then the whole task bar thingy will appear. Now that I am in the Maps App, I have to go to the bottom-left corner and a "Start" thingy appears but I have to move very fast to it before it disappears (and for some reason, clicking on it right now doesn't do anything, so I seem to be stuck in the Maps app). Ok, I seem to be able to get the Start menu button to appear at the bottom-left but clicking on it doesn't always work.

There does seem to be an app called "Desktop" but it doesn't seem possible to launch any apps from it. It just has a Windows Explorer and an Internet Explorer icon. The menu in Windows Explorer also seems horribly complicated (I guess this is the whole "ribbon" thing). Shudder. It's just awful.

All the apps seem to be full-screen, at least all the apps accessible from the "Start screen" (is that called "Metro"?). Not really sure what the deal is with that. How are we supposed to work with two applications at the same time? I can't seem to launch apps from the "Desktop" I have to launch them from the "Start screen".

I didn't think it was possibly to make something worse than Ubuntu's Unity, but it seems that Microsoft has managed to do that. BTW, I am starting to like Unity more and more (although at the moment I am taking a short break and using KDE4 instead).

NoMachine NX is awesome

Short-version:
Use NX. VNC sucks.

I love Remote Desktop for connecting to Windows machines remotely. I worked from home many times while at Kodak and if it weren't for Remote Desktop, it would have been impossible to enjoy a full-screen connection to my work desktop while at home. I didn't think there was anything for Linux besides VNC until now (I had used remote X a long time ago though, to connect to the Solaris machines at UBC). Then I discovered NoMachine NX (NoMachine is the company's name and NX is the product name). I downloaded the Free Edition for Linux and then grabbed the Windows Client (which apparently is also free?). It's ridiculously fast, as fast as Remote Desktop. Google is also working on neatx an open-source NX server implementation and there is the freenx project, a GPL-licensed implementation of the server and client components. If you are trying to connect to a Linux desktop remotely, don't even think about using any of the VNC derivatives. Use NX.

Tags: 

Using XML for Code Documentation is Just Plain Wrong

I was just looking at some C# code at work today and it had XML Documentation (like javadoc or python docstrings, only with XML). Who was the idiot that came up with that idea? It's the most insane thing I've ever seen. Let's look at the predecessors to C#'s XML documentation:

Javadoc:

/**
 * Returns an Image object that can then be painted on the screen. 
 * The url argument must specify an absolute {@link URL}. The name
 * argument is a specifier that is relative to the url argument. 
 * <p>
 * This method always returns immediately, whether or not the 
 * image exists. When this applet attempts to draw the image on
 * the screen, the data will be loaded. The graphics primitives 
 * that draw the image will incrementally paint on the screen. 
 *
 * @param  url  an absolute URL giving the base location of the image
 * @param  name the location of the image, relative to the url argument
 * @return      the image at the specified URL
 * @see         Image
 */
 public Image getImage(URL url, String name) {
	try {
	    return getImage(new URL(url, name));
	} catch (MalformedURLException e) {
	    return null;
	}
 }

Then, doxygen, which looks a lot like javadoc:

      /**
       * a normal member taking two arguments and returning an integer value.
       * @param a an integer argument.
       * @param s a constant character pointer.
       * @see Test()
       * @see ~Test()
       * @see testMeToo()
       * @see publicVar()
       * @return The test results
       */
       int testMe(int a,const char *s);

Unfortunately Genshi doesn't syntax highlight the javadoc comments. But it looks fairly readable. Let's try a python docstring example. There is no one standard. One of the documentation generators for Python, Epydoc understands plaintext, javadoc, epydoc, and reStructuredText.

Python code with epydoc style docstrings:

def x_intercept(m, b):
    """
    Return the x intercept of the line M{y=m*x+b}.  The X{x intercept}
    of a line is the point at which it crosses the x axis (M{y=0}).
 
    This function can be used in conjuction with L{z_transform} to
    find an arbitrary function's zeros.
 
    @type  m: number
    @param m: The slope of the line.
    @type  b: number
    @param b: The y intercept of the line.  The X{y intercept} of a
              line is the point at which it crosses the y axis (M{x=0}).
    @rtype:   number
    @return:  the x intercept of the line M{y=m*x+b}.
    """
    return -b/m

Python code with one example of reStructuredText docstrings (this one includes the types of the parameters but they aren't necessary):

def fox_speed(size, weight, age):
    """
    Return the maximum speed for a fox.
 
    :Parameters:
      size
        The size of the fox (in meters)
      weight : float
        The weight of the fox (in stones)
      age : int
        The age of the fox (in years)
    """
    #[...]

I couldn't find any nice examples for C# XML Documentation. The C# XML Documentation Tutorial has some examples, but conveniently, none that include all the tags that I would need to replicate the javadoc example I showed above. So I'll convert the Java example to C#:

   /// <summary>
   /// Returns an Image object that can then be painted on the screen. 
   /// The url argument must specify an absolute {@link URL}. The name
   /// argument is a specifier that is relative to the url argument. 
   /// 
   /// This method always returns immediately, whether or not the 
   /// image exists. When this applet attempts to draw the image on
   /// the screen, the data will be loaded. The graphics primitives 
   /// that draw the image will incrementally paint on the screen.</summary>
   /// 
   /// <param name="url">an absolute URL giving the base location of the image</param>
   /// <param name="name">the location of the image, relative to the url argument</param>
   /// <returns>
   /// the image at the specified URL</returns>
   /// <seealso cref="Image">
   /// Read more about the Image class</seealso>
 */
 public Image getImage(URL url, String name) {
	try {
	    return getImage(new URL(url, name));
	} catch (MalformedURLException e) {
	    return null;
	}
 }

I followed Microsoft's convention (because they know best) of putting the opening tags on a line on their own.

The javadoc sucks because you have to put a <p> (or <br />?) to make a new line which is stupid. Otherwise it's pretty readable, and same goes for doxygen. Especially the @param and @return tags. The Epydoc-style python docstrings suck. You have to specify the type using a @type tag and the return type using an @rtype tag. The reStructuredText example looks the best to me. No tags at all, except for the :Parameters: heading which should be there anyways. The C# comments are an eyesore. Even if Visual Studio had syntax highlighting for the comments it would suck. Did Microsoft look at the two major previous implementations (doxygen and javadoc) and decide that XML was a better way to document code?

I recently saw an interesting comment in scipy's source about one of scipy's guiding principles in designing the docstring standard for their codebase:

A guiding principle is that human readers of the text are given precedence over contorting docstrings so our tools produce nice output. Rather than sacrificing the readability of the docstrings, we have written pre-processors to assist tools like epydoc_ and sphinx_ in their task.

Microsoft clearly took the opposite route and decided to make code documentation readability by human readers a low priority.

mp3 Sample Clip Creator With Fade-In/Out

This script will create mp3 sample clips. I created it to automatically create sample mp3 clips for a friend of mine's (Will Stroet) website. You can tweak the length of the clip and the fadeout. Unfortunately it can only create samples that start at the beginning, however, it could be easily modified to start anywhere. It depends on the quelcom library, lame, and mpg123.

Topic: 

Limit Size of Subversion Commits With this Hook

We have experienced some abuse of our subversion repository at work recently. Someone committed 400 MB of data all at once including many object files, libraries, and executables. I did not get very harsh with the person who did this. Because a) I have no objection to binaries in subversion in the first place, b) I don't really know what he's working on, c) disk space is cheap and we are no where near capacity, and d) his commit was still smaller than a few commits we had a long time ago (which were legit). Still, if you just allow people to commit whatever they want to your subversion repository, in the worst case, you could run out of disk space, necessitating an svn dump-and-load onto a new larger drive (pain). It would suck to have to do that just because some people were committing large binaries (without any legitimate reason to). There are other annoying consequences. Our tarball backups of svn currently fit on a DVD, which is cheap and easy, if we allowed this abuse to continue it would complicate our backup process.

What I wanted was a way to limit the commit size for certain users automatically. There did not seem to be any hooks out there to do this, so I wrote one.

Just paste the following into your pre-commit hook:

/svn/repos/hooks/check_txn_size.py "$REPOS" "$TXN" || exit 1

and paste the following into a check_txn_size.py file in your hooks directory and make it executable.

#!/usr/bin/env python
import sys,os,popen2
 
MAX_BYTES = 1024000
DEBUG = False
SVNLOOK = '/usr/bin/svnlook'
ALLOWED_USERS = ['david', 'ctang', 'vjain', 'mike', 'sbridges', 'tcirip']
ADMIN_EMAIL = '<a href="mailto:admin@company.com">admin@company.com</a>'
 
def printUsage():
  sys.stderr.write('Usage: %s "$REPOS" "$TXN" ' % sys.argv[0])
 
def getTransactionSize(repos, txn):
  txnRevPath = repos+'/db/transactions'+'/'+txn+'.txn'+'/rev'
  return os.stat(txnRevPath)[6]
 
def printDebugInfo(repos, txn):
  for root, dirs, files in os.walk(repos+'/db/transactions', topdown=False):
    sys.stderr.write(root+", filesize="+str(os.stat(root)[6])+"\n\n")
    for name in files:
      sys.stderr.write(name+", filesize="+str(os.stat(root+'/'+name)[6])+"\n")
 
def checkTransactionSize(repos, txn):
  size = getTransactionSize(repos, txn)
  if (size > MAX_BYTES):
    sys.stderr.write("Sorry, you are trying to commit %d bytes, which is larger than the limit of %d.\n" % (size, MAX_BYTES))
    sys.stderr.write("If you think you have a good reason to, email %s and ask for permission." % (ADMIN_EMAIL))
    sys.exit(1)
 
def getUser(repos, txn):
  cmd = SVNLOOK + " author " + repos + " -t " + txn
  out, x, y = popen2.popen3(cmd)
  cmd_out = out.readlines()
  return cmd_out[0][:-1]
 
if __name__ == "__main__":
  #Check that we got a repos and transaction with this script
  if len(sys.argv) != 3:
    printUsage()
    sys.exit(2)
  else:
    repos = sys.argv[1]
    txn = sys.argv[2]
 
  if DEBUG: printDebugInfo(repos, txn)
  user=getUser(repos, txn)
  if DEBUG: sys.stderr.write("User:"+user)
  if DEBUG:
    if (user in ALLOWED_USERS):
      sys.stderr.write(user+" in allowed users")
    else:
      sys.stderr.write(user+" not in allowed users")
  if (user not in ALLOWED_USERS):
    checkTransactionSize(repos, txn)

Maven is Amazing

After 2 senior developers recommended maven over ant and another told me he was planning on switching to it (from ant) for his next major project, I knew I would eventually try it when I had the chance. Today I was forced to try it because building my project with ant started becoming a total nightmare. I had added a dependency to my project and now the ant script failed. Time to modify the ant script. Said dependency had some dependencies of it's own. Not only that but one of the dependencies was an internal project and did not have an ant build of it's own so no Jar. So it looked like I was going to have to write an ant build for the dependency or put a hard link to it's output class path (created by Intellij IDEA) or use IDEA's jar maker utility. All of those are crappy workarounds. I like automated one like calls like "ant deploy" that will build, test, package and deploy my app to a tomcat server. I was fed up; there has got to be a better way.

So I tried Maven and it is amazing. I just converted a bunch of projects to use maven and it is so much better than ant. It follows the "convention over configuration" and DRY (don't repeat yourself) philosophies very nicely. It just works. No need to tell Maven where your source is and where you want it to build to. Just use the standard maven directory structure. No need to tell Maven what your classpath is for unit tests or compilation. Deploying builds to a remote or local repository is easy. Running unit tests and generating reports is easy, with no extra code in the build file required.The best part is that it fetches dependencies from a server (or the local repository cache) and fetches dependencies recursively. Building projects will be so much easier now and will save so much time. No more writing ant builds and no more copies of junit or log4j all over the place. In fact, never download any jars, ever again. Another bonus: it can generate an IDEA module file or modify an existing one. I've tried this for all the projects and it works perfectly.

So Maven is awesome, and Ant, well...Ant is dead to me.

Firefox/Opera Shootout

I've been getting really pissed off lately at how much memory Firefox is using up. I decided to give Opera a try. I opened up the exact same tabs in Opera (about 10 of them) and I got about the same memory consumption. I disabled all the Firefox extensions except for the del.icio.us one (because last time I disabled it and re-enabled it, it totally screwed up the bookmarks menu, and I had to create a new profile from scratch to get it back to normal).

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 9152 david     15   0  214m 105m  19m S  1.7 10.4   0:24.86 opera
 9057 david     15   0  211m 100m  24m R  3.7  9.9   0:32.72 firefox-bin

This is a big improvement for Firefox by the way, after disabling the extensions. One of the extensions much be leaking memory big time because the memory usage usually climbs to 250MB. Looks like I will have to go and buy some more RAM. I only have 1 Gig right now. with tw 512MB modules. Looks like there is a third slot. Maybe a new 1G module then.

Switched from Portage to Paludis

I switched to Paludis yesterday. For those who don't know what Paludis is, it's an alternative Gentoo package manager, or a Portage/emerge replacement. It has not all been smooth. I had to fight with it for a while, re-installing a bunch of packages that thought they depended on an installed package that no longer existed. I think this was because Portage left some cruft around that made it think that. The problems were mainly to do with kdelibs-3.4* (which a lot of installed packages thought they had a block on) and with guile (which moved to a new category but some packages weren't aware of the switch). Re-installing worked in most cases.

The other wrinkle was that the portage2paludis.bash script that I used according to the migration instructions didn't bring all my repositories over, including my /usr/local/portage and a few others. The second annoyance was that a few repositories didn't have profiles/repo_name and profiles/categories files in them (which paludis requires) and this causes a bunch of warnings about how paludis is "faking it." I finally got it to the point where I could do "paludis -ip world" and I got no warnings and no errors.

The only remaining problem is that the gentoo java packages are mostly unusable with paludis because none of the hooks in the java gentoo eclasses get installed into paludis' hooks system (and paludis doesn't call the hooks in the java eclasses). Apparently the Gentoo Java team was "abusing the [portage] hooks in [their] eclasses." They should be installing the hooks into the paludis hooks directories. Paludis hooks are similar to subversion's hooks system. They allow you to do a lot of fancy things.

Overall I am impressed with Paludis. Running "paludis -ip world" is a lot faster than "emerge -uva world" or "emerge -uvaDNt world" but more important than speed is that it was designed from scratch, without all of portage's warts and messy hard-to-change code. In a way, paludis is to portage what svn is to cvs. You can read all about the differences between Paludis and portage here.

One more thing happened yesterday, that was a little bit scary. I tried to reboot to try out a new kernel and I noticed the "reboot" and "shutdown" commands were no longer there. I rebooted anyways but hitting the reset button but the system wouldn't load, it stopped right after the kernel was done starting up. It turned out Paludis had uninstalled sysvinit when I ran "paludis --uninstall-unused" and I didn't notice. Reinstalling it fixed everything but I got really scared that the reboot and shutdown binaries were missing due to dataloss.

Drag & Drop from Linux (KDE, Gnome) File Managers (Konqueror, Nautilus) to Java Applications

I tried a few months ago to get drag & drop working from Konqueror to a Java application but it didn't work. Two programmers (myself and another) each had a crack at it and couldn't get it to work. I found one link through Google that seemed to be promising (see reply 23 or 23) but that didn't work. Then finally today by using slightly different keywords in my Google searching, I managed to find this link, which led me to this bug report. It turns out the "workaround" works great and I got it working. Works with Konqueror as well as Nautilus. Haven't tried any other Qt/KDE or GTK applications. Should work with Windows as well of course. I am attaching a trimmed down version of the workaround version with only the essentials to get this working. It it a lot nicer looking than the forum.sun.com link above. I had such a tough time finding the solution to this online, I hope others find this blog post and thus have an easier time at it than I did.

AttachmentSize
Plain text icon TestDragDropLinux.java_.txt3.46 KB

Small Gotcha When Copying Paths With Subversion

I was trying to do an svn copy from a specific server path into a local working copy. I basically wanted to copy over the vanilla mediawiki-1.8.1 sources from my repository into a local directory (called trunk). Here is what I did:

svn copy svn+<a href="ssh://david@server/svn/repos/Projects/wiki/mediawiki/1.8.1">ssh://david@server/svn/repos/Projects/wiki/mediawiki/1.8.1</a> ./trunk

You would think that this would copy the contents of the 1.8.1 directory into the trunk directory. Wrong; it copies the 1.8.1 directory and its contents into the trunk directory, thus creating a 1.8.1 directory inside trunk. It took me forever to figure out why it was doing this instead of what I wanted it to do (which is to copy the contents of 1.8.1, not the 1.8.1 directory itself).

The problem was that the trunk directory already existed. If I removed the trunk directory, then it creates the trunk directory and copies the contents of the 1.8.1 directory into trunk.

In case anyone is curious, what I am doing is following the instructions from the svn book on how to maintain vendor branches.

Backing up MySQL Databases With AutoMySQLBackup

I just discovered a very useful bash script tonight, AutoMySQLBackup. It is a nice and easy way to backup your mysql databases daily, weekly, and monthly. It was very easy to set up and works great. A great suggestion to prevent having to put the username and password for a database user with read/write access in the script is to do the following:

mysql -u root -p -e "GRANT SELECT, LOCK TABLES ON *.* TO 'backup'@'localhost' IDENTIFIED BY 'backupPW';"

That creates a database called backup with password backupPW with only SELECT and LOCK TABLES access to the database. This tip came from this gentoo-wiki.com article on MySQL backup.

MythTV 0.20 Released

MythTV 0.20 was released today. I can't wait to install it and check out the new features. I completely rebuilt my MythTV box last week and it is totally kick-ass now. It has a new 250GB hard drive which allows me to record 100 hours of TV. Some other improvments I made were, setting up XvMC which allows my video card's GPU to help out with some of the MPEG-2 decoding (bringing my CPU usage from 20% to 10% during video playback). Thanks to the Hauppauge PVR-350 card my CPU usage during recording is nil. I also got a new video card with composite out rather than s-video. That fixed a problem with the flaky s-video connector I had (whereby it would slip out and cause the screen to go all fuzzy) and also fixed a problem I had with 3 vertical lines on the TV during playback. We also bought and expensive composite cable to make sure that there are no problems. Finally stuck everything in an Antec Sonata II case for maximum silencing and cooling (not to mention how cool the black case looks).

Now that I have 100 hours of recording space (compared to 3 hours before) I set up a whole bunch of movies to record using the movie list view. It is amazing how many great movies are playing on TV at 3 am. I've also got the CBC National, Simpsons, Seinfeld, and the Colbert Report recorded daily (at any time on any channel, excluding already seen episodes), countless documentary programs and other miscellaneous things like Saturday Night Live. I love watching the TV shows I want, when I want, without commercials, and at faster speed if I want without the audio pitch getting screwed up. For example, I often watch the National at 1.4x speed without commercials. This means I can watch the entire hour-long news in about 32 minutes. Pretty sweet eh?

An X-Ray Pixel Sensor for Large-Area Imaging in VHDL-AMS

Class: ECE 741
Professor: Dr. Jim Barby
Year: Fall 2002

An X-Ray pixel sensor is modelled using the VHDL-AMS mixed-signal modelling language. The components of the model include: the x-ray source, a selenium detection layer and charging capacitor, and the switching and amplifying TFTs. A passive pixel and active pixel configuration are both investigated.

Pages

Subscribe to RSS - software