Laggy file navigation at startup with xfce Thunar: fix

This applies to the last two or three distributions of Linux that use Thunar as file manager, notably Xubuntu or others using Xfce for the desktop. The problem is that the first time you open the file manager, you have to wait a very long time to see anything. This can persist for several minutes after booting, even with multicore systems with lots of RAM. Some people also get error messages.

The reason seems to be that Thunar is waiting for gvfs-xxx to return with network devices. Rather than allowing the user to breathe by showing them the interface, it does nothing until this process returns (30 seconds to several minutes). Reportedly there is a bug with one of the gvfs modules that I won’t pretend to have analyzed in detail. The Thunar behavior is known to the developers, and I believe they are working on it… but what to do for now?

Well here’s a fix that works for me on Xubuntu 11.10. Do this:

sudo nano /usr/share/gvfs/mounts/network.mount

(with editor of your choice if nano doesn’t do it for you)… This file is only a few lines long. Change this:

Exec=/some/exec
AutoMount=true

to this:

#Exec=/some/exec
Exec=''
AutoMount=false

The next time you reboot, you’ll start off with a usable and responsive GUI. Yay.

One or the other change to network.mount might even be enough. Note that this will disable Thunar’s (ill-fated) search for remote drives — not much of a fix if you need that functionality, I admit. But if you need your file manager to mount remote drives, you can always try another manager.

Posted in Uncategorized | Leave a comment

VirtualBox 4.1.8

VirtualBox is my new best friend. Soooo many 64-bittish problems, not to mention OS X problems (if developing anything other than Cocoa) can be solved simply by installing 32-bit linux in VirtualBox. Now to see if my Py2App distributions actually run on the mac :)

Posted in Uncategorized | Leave a comment

Forcing 32 bit Python in OS X 10.6 +

Lots of python libraries fail to install or fail to work under 64 bit python. Here’s a cheesy non-programmatic hack to make 32-bit python the default.

1. Find the path to the python installation you want to default to 32-bit mode in your .bash_profile

nano .bash_profile

Mine is at /Library/Frameworks/Python.framework/Versions/2.7/bin

2. Go to the python installation in Finder. Observe the aliases (shortcuts / symlinks) to various python configurations. If you’re not sure what you’re looking for, stop and go find out about aliases and symlinks, what they are, and what they look like in OS X (obligatory “don’t proceed if you don’t know what you’re doing”).

3. Rename the alias called “python” to “python-64″. There is no existing alias with that name because “python” defaults to the 64-bit configuration whenever possible.

4. Right click “python-32″ or, if you prefer, “python2.7-32″ (which is not an alias, but is what the alias points to). Select “Make Alias”. Rename the new alias “python”.

5. Now any time you type “python” in the Terminal, 32-bit python will start. Even better, when other programs start python in various ways, or the python launcher starts, they will default to 32-bit python.

6. If you ever want to go back and default to 64-bit again, just delete your python alias and remove “-64″ from “python-64″.

By the way, don’t believe what you read in the man pages about this stuff:

# this doesn't work!
defaults write com.apple.versioner.python Prefer-32-Bit -bool yes
# neither does this!
export VERSIONER_PYTHON_PREFER_32_BIT=yes

The Mac versioner stuff only applies to the Mac pre-installed python. It will not have any effect on your python 2.7 installation!

And one final caveat. If you’ve installed libraries under 64-bit python, you might get a “wrong architecture” error running in 32-bit mode. You can either run those programs under 64-bit, or assuming you can install 32-bit configurations of your libraries, do that.

Posted in Uncategorized | Leave a comment

ndexr – index a directory and output a json file of its contents

New python project at https://sourceforge.net/projects/ndexr/

Currently it indexes a directory specified in interactive mode or by a config file, and writes a json file cataloging the directory’s contents. You can also specify the output file and the files types to index.

It is made to be easy to extend with your own scripts… ie: if you want to recursively index a directory tree you can. If you want to index files on a server and send them once a week to some other server you can. If you want to use it to let clients search a directory without actually having access to it, you certainly can (you’ll have to supply apache or some other web server obviously).

I’ll probably extend it to automatically handle recursive indexing, and optional indexing of directories (as of right now it indexes files only, because that’s what I needed it to do today :)

It’s simple, not much code, and its only job will stay in the domain of indexing files and spitting out json. Check it out if you think it’s useful to you.

Posted in Uncategorized | Leave a comment

Stretching a 1-pixel image to make a resizeable border or shadow

This comes up a lot, so I’m positing an image to illustrate the idea.

Here’s my related stack overflow answer, which uses the technique to make a shadow around a UITableView section of arbitrary size and shape.

Posted in Uncategorized | 2 Comments

Batch plist to JSON conversion

Posted this to sourceforge last night:

plist2json: Batch convert plist files to JSON

Feature list:

  • Convert any number of plist’s to json
  • Command line – type a directory to convert or drag and drop folder to Terminal
  • Works with OS X, should work fine in most Linux distros
  • Compact, easy to modify for your own needs

It’s easier to use than the rough one-at-a-time version I posted before. Enjoy.

Posted in Uncategorized | 1 Comment

Convert plist to JSON

EDIT: see my plist2json post for a better version

Here’s a python program to convert a plist to JSON. You’ll need to type in the input and output filenames in the GUI (ie: /Users/bob/myDirectory/file.plist). It will overwrite the output file if it already exists. If anyone wants a version for batch processing, feel free to modify it or send me a request. Tested in Python 2.7.2.

# By Rab Beverly: http://www.robertbeverly.com
# Author assumes no responsibility for damages.
# Use this code however you wish.
# Attribution is not required.

import json
from plistlib import readPlist
import StringIO
import Tkinter

class Converter:

    def __init__(self):
        """ ... """
        self.root = root = Tkinter.Tk()
        root.title('Converter')
        # inFile
        inLabel = Tkinter.Label(root, text='plist file (in):')
        inLabel.grid(column=0, row=0)
        # grabbable entry field
        self.inFileBox = Tkinter.Entry(root, width=30)
        self.inFileBox.grid(column=1, row=0)
        # outFile
        outLabel = Tkinter.Label(root, text='JSON file (out):')
        outLabel.grid(column=0, row=1)
        # grabbable entry field
        self.outFileBox = Tkinter.Entry(root, width=30)
        self.outFileBox.grid(column=1, row=1)
        # Button to grab fields
        convertButton = Tkinter.Button(root, text='Convert',
                                      command=self.makeConversion)
        convertButton.grid(column=0, row=3)
        # A quit button
        quitButton = Tkinter.Button(root, text='Quit',
                                    command=self.onExit)
        quitButton.grid(column=1, row=3)
        root.mainloop()

    def onExit(self):
        self.root.quit()

    def makeConversion(self):
        """ grab the configuration values, convert, and write """
        inFile = self.inFileBox.get()
        outFile = self.outFileBox.get()

        plist = open(inFile,"r").read()
        theData = StringIO.StringIO(plist)
        plist_dict = readPlist(theData)
        open(outFile,"w").write(json.dumps(plist_dict))

Converter()

Download it:

plist-to-json.py (zip file, ~4KB)

Posted in Uncategorized | 2 Comments

Python 2.7 and XCode 4

Here’s a relevant link for setting up a project (I’m using it for cross-platform development, not PyObj-C): Python + XCode @ SO

For debugging you’ll probably have to go outside XCode, or figure out how to set Python debugging up properly. Supposedly LLDB has support, but in XCode you’ll get SIGTRAP when you run your program. Personally I think I’ll debug outside XCode, then figure out how to set up LLDB+Py+XCode4 if and only if I have so much debugging that running from another environment becomes a chore.

Posted in Uncategorized | 1 Comment

Fast Enumeration of NSDictionary: “for in” loop returns NSCFString

People ask, and I see questions, and… Ok I admit it, this has gotten me too. If you use the for … in syntax in Objective-C to iterate through an NSDictionary, the result is different than if you were iterating through and NSArray. (Yes I know, they totally warn you of this in the documentation). With an array that you knew was filled with NSDictionaries (loaded, say, from a file or JSON) you could write:

for (NSDictionary * thisDict in myArray) {
     NSLog("%@", [thisDict valueForKey:@"testing"]);
}

BUT IF, instead of an array, you were iterating though the contents of a dictionary, you would get something like this from the debugger window:

>> *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x6812fc0

It seems rational to expect the same behavior from the array and the dictionary. The array does not return an index when you enumerate it, it enumerates the objects. In the case of the dictionary, it is the keys that are enumerated. So rather than:

for (NSDictionary * subDict in myDict) {
     NSLog("%@", [subDict class]);
     NSLog("Hmm, nothing bad has happened so far... Let's call
            objectForKey on this and see if it's really a
            dictionary like the code suggests.");
     NSLog("%@", [subDict objectForKey@"yeahCrash"]);
}

… which logs this:

>> NSCFString
>> Hmm, nothing bad has happened so far… Let’s call objectForKey on this and see if \
>> it’s really a dictionary like the code suggests:
>> -[NSCFString objectForKey:]: unrecognized selector sent to instance 0x6812fc0
>> *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x6812fc0
>> *** Call stack at first throw:
(…)

You would write your code more thusly:

for (NSString * key in myDict) {
     NSDictionary * subDict = [myDict objectForKey:key];
     NSLog("%@", [subDict objectForKey@"noCrashThisTime"]);
     // all your other code here.
}

And you would be safe once again.

Posted in Uncategorized | Leave a comment

Moodle: Set a quiz to email teacher when a student completes it

When you want to know each time a student attempts a quiz in moodle: http://docs.moodle.org/20/en/Quiz_submission_email_notification

Posted in Uncategorized | Leave a comment