C# export for Gaphor

Gaphor is the best free UML tool for X I've seen yet. It's far from finished but at least it produces pretty graphs. I started writing a C# export plugin for it. The first somewhat working version is available. This has been developed with 0.10.4, no guarantees of it working with any other version. No guarantees of it working with that version either, to be exact, but at least it works for me.

Extract it inside Gaphor's source directory, in gaphor/data/plugins.

Python, Queue, Pygame and the GLib mainloop

The GLib mainloop is what you're probably running in your Python program when you are using PyGTK or GStreamer.

Sometimes you want to integrate other event sources to it. The documentation for this is a bit thin; all I've seen is GLib's page on the main event loop, GSourceFuncs section and test-source.py in pygobject. Here I'm presenting two snippets displaying how to do it with two systems I've needed to work with. No guarantees on their correctness, but they do seem to work. Both are parts of larger modules, so they aren't usable by themselves and aren't really tidied up to look like proper examples. However, they should give you the general idea.

Here's how to do it with Python's Queue:

class QueueSource(gobject.Source):
    def __init__(self, queue):
        gobject.Source.__init__(self)
        self._queue = queue
        self.logger = loghelper.get_logger(self)

    def prepare(self):
        return False

    def check(self):
        return not self._queue.empty()

    def dispatch(self, callback, args):
        self.logger.debug("dispatch called, callback: " + str(callback))
        if callback is not None:
            self.logger.debug("dispatch calling callback: " + str(callback))
            v = callback(self._queue.get(), *args)
            self.logger.debug("dispatch returned " + str(v))
        return True

    def finalize(self):
        self.logger.debug("finalize called")


m = QueueSource(self._queue)
def my_callback(command, *args):
    self.logger.debug("my_callback: args: " + str(command) + ", " + str(args))
    self.logger.debug("my_callback: thread: " + str(threading.currentThread()))
    if command == self.PLAY:
        self._player.play()
    elif command == self.STOP:
        self._player.stop()
    elif command == self.SKIP:
        self._player.skip()

m.set_callback(my_callback, mainloop)
m.attach()

And here's Pygame:

class PygameEventSource(gobject.Source):
    def __init__(self):
        gobject.Source.__init__(self)
        self.logger = loghelper.get_logger(self)

    def prepare(self):
        return False

    def check(self):
        try:
            pygame.event.pump()
            p = pygame.event.peek(
                [KEYUP, KEYDOWN, VIDEOEXPOSE, VIDEORESIZE, NUMEVENTS, QUIT,
                 ACTIVEEVENT, USEREVENT])
            return p
        except Exception, ex:
            self.logger.error("Caught an exception while checking for events",
                              exc_info=True)

    def dispatch(self, callback, args):
        if callback is not None:
            try:
                e = pygame.event.poll()
                v = callback(e, *args)
                return v
            except (KeyboardInterrupt, SystemExit):
                self.logger.warn(
                    "Caught a terminating exception while dispatching to the "
                    "callback, re-raising", exc_info=True)
                pygame.display.quit()
                raise
            except Exception, ex:
                self.logger.error(
                    "Caught an exception while dispatching to the callback",
                    exc_info=True)
        return True

    def finalize(self):
        pass

def my_callback(self, event, *args):
    if event.type == QUIT:
        sys.exit()
    if event.type == KEYDOWN:
        self.logger.debug("my_callback: keydown: event.key: " + str(event.key))
        if event.key in (K_q,):
            sys.exit()
        elif event.key in (K_n, K_SPACE):
            self._player.skip()
        elif event.key in (K_p,):
            if self._player.playing:
                self._player.stop()
            else:
                self._player.play()
    
    return True


def start_mainloop(self, mainloop):
    self.logger.debug("Starting mainloop")
    if not self._started:
        s = PygameEventSource()
        s.set_callback(self.my_callback, mainloop)
        s.attach()
    return

One of Those Things You Don't Know If You Should Post in Your Blog Or on TheDailyWTF

From Rails, or more specifically, ActiveSupport's json.rb:

# When +true+, Hash#to_json will omit quoting string or symbol keys
# if the keys are valid JavaScript identifiers.  Note that this is
# technically improper JSON (all object keys must be quoted), so if
# you need strict JSON compliance, set this option to +false+.
mattr_accessor :unquote_hash_key_identifiers
@@unquote_hash_key_identifiers = true

© Juri Pakaste 2023