Posting Source Code to WordPress.com

2007/09/12 6:07:14

The other day I tried to blog about the vte.terminal, and I had huge problems posting the source code. My problem was that despite how much I searched, and everything I tried, I could not keep the formatting and post the source code. The formatting was wrong when I used the <code> tags (The spaces where removed and in python that’s important).

It turns out that this was the most correct with the exception that befor you make your post you must go to Users then Your Profile and make sure “Use the visual rich editor when writing”
is unselected instead of


you are going to want to have

#This
#is an example
#of what your source code will look like
x = True
if x:
    print 'hello world'

The source for this post can be found here.


Python vte.Terminal example

2007/09/10 19:09:35

About a week ago while working on propensity, I was trying to add an impeded terminal into the program instead of just sending commands to an xterm. I quickly found out about the VTE Terminal Widget, this is the same widget used by the gnome-terminal. Now while I was able to find a great API, I was working in python not C and while I love API’s when I’m using a new feature I also find examples to be one of the best ways for me to learn, but even with all my google searching I found it really hard to find a simple python example of the VTE Terminal Widget. The good news is I now have a simple working example, its a basic gui that lets you enter a command and then that command will be run in a separate terminal window (I’m not exactly sure why I used two windows now that I think of it.)


An so without further ado here is the code (all GPL). Hope this helps someone in the future. You can download the code here, or view it below.

VirtualTerminal.py (This code could be used in your program)

#!/usr/bin/env python
#
#      VirtualTerminal.py
#
#      Copyright 2007 Edward Andrew Robinson <earobinson@gmail>
#
#      This program is free software; you can redistribute it and/or modify
#      it under the terms of the GNU General Public License as published by
#      the Free Software Foundation; either version 2 of the License, or
#      (at your option) any later version.
#
#      This program is distributed in the hope that it will be useful,
#      but WITHOUT ANY WARRANTY; without even the implied warranty of
#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#      GNU General Public License for more details.
#
#      You should have received a copy of the GNU General Public License
#      along with this program; if not, write to the Free Software
#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

# Imports
import os
import vte
import gtk
import time

class VirtualTerminal(vte.Terminal):
    def __init__(self, log_file = None, history_length = 5, prompt_watch = {}, prompt_auto_reply = True, icon = None):
        # Set up terminal
        vte.Terminal.__init__(self)

        self.history = []
        self.history_length = history_length
        self.icon = icon
        self.last_row_logged = 0
        self.log_file = log_file
        self.prompt_auto_reply = prompt_auto_reply
        self.prompt_watch = prompt_watch

        self.connect('eof', self.run_command_done_callback)
        self.connect('child-exited', self.run_command_done_callback)
        self.connect('cursor-moved', self.contents_changed_callback)

        if False:
            self.connect('char-size-changed', self.activate_action, 'char-size-changed')
            #self.connect('child-exited', self.activate_action, 'child-exited')
            self.connect('commit', self.activate_action, 'commit')
            self.connect('contents-changed', self.activate_action, 'contents-changed')
            #self.connect('cursor-moved', self.activate_action, 'cursor-moved')
            self.connect('decrease-font-size', self.activate_action, 'decrease-font-size')
            self.connect('deiconify-window', self.activate_action, 'deiconify-window')
            self.connect('emulation-changed', self.activate_action, 'emulation-changed')
            self.connect('encoding-changed', self.activate_action, 'encoding-changed')
            #self.connect('eof', self.activate_action, 'eof')
            self.connect('icon-title-changed', self.activate_action, 'icon-title-changed')
            self.connect('iconify-window', self.activate_action, 'iconify-window')
            self.connect('increase-font-size', self.activate_action, 'increase-font-size')
            self.connect('lower-window', self.activate_action, 'lower-window')
            self.connect('maximize-window', self.activate_action, 'maximize-window')
            self.connect('move-window', self.activate_action, 'move-window')
            self.connect('raise-window', self.activate_action, 'raise-window')
            self.connect('refresh-window', self.activate_action, 'refresh-window')
            self.connect('resize-window', self.activate_action, 'resize-window')
            self.connect('restore-window', self.activate_action, 'restore-window')
            self.connect('selection-changed', self.activate_action, 'selection-changed')
            self.connect('status-line-changed', self.activate_action, 'status-line-changed')
            self.connect('text-deleted', self.activate_action, 'text-deleted')
            self.connect('text-inserted', self.activate_action, 'text-inserted')
            self.connect('text-modified', self.activate_action, 'text-modified')
            self.connect('text-scrolled', self.activate_action, 'text-scrolled')
            self.connect('window-title-changed', self.activate_action, 'window-title-changed')

    def activate_action(self, action, string):
        print 'Action ' + action.get_name() + ' activated ' + str(string)

    def capture_text(self,text,text2,text3,text4):
        return True

    def contents_changed_callback(self, terminal):
        '''Gets the last line printed to the terminal, it will log
        this line using self.log() (if the logger is on, and it will
        also prompt this line using self.prompt() if the line needs
        prompting'''
        column,row = self.get_cursor_position()
        if self.last_row_logged != row:
            off = row-self.last_row_logged
            text = self.get_text_range(row-off,0,row-1,-1,self.capture_text)
            self.last_row_logged=row
            text = text.strip()

            # Log
            self.log(text)

            # Prompter
            self.prompter()

    def get_last_line(self):
        terminal_text = self.get_text(self.capture_text)
        terminal_text = terminal_text.split('\\\\n')
        ii = len(terminal_text) - 1
        while terminal_text[ii] == '':
            ii = ii - 1
        terminal_text = terminal_text[ii]

        return terminal_text

    def log(self, text):
        '''if self.log_file is not None the the line will be logged to
        self.log_file. This function also stors the info in self.histoy
        if self.history_lenght > 0'''
        if self.log_file != None:
            date_string = time.strftime('[%d %b %Y %H:%M:%S] ', time.localtime())
            file = open(self.log_file, 'a')
            file.write(date_string + text + '\\\\n')
            file.close

        # Append to internal history
        if self.history_length != 0:
            if len(self.history) >= self.history_length:
                self.history.pop(0)
            self.history.append(text)

    def prompter(self):
        last_line = self.get_last_line()
        if last_line in self.prompt_watch:
            if self.prompt_auto_reply == False:
                message = ''
                for ii in self.prompt_watch[last_line]:
                    message = message + self.history[self.history_length - 1 - ii]
                if self.yes_no_question(message):
                    self.feed_child('Yes\\\\n')
                    # TODO not sure why this is needed twice
                    self.feed_child('Yes\\\\n')
                else:
                    self.feed_child('No\\\\n')
            else:
                self.feed_child('Yes\\\\n')

    def run_command(self, command_string):
        '''run_command runs the command_string in the terminal. This
        function will only return when self.thred_running is set to
        True, this is done by run_command_done_callback'''
        self.thread_running = True
        spaces = ''
        for ii in range(80 - len(command_string) - 2):
            spaces = spaces + ' '
        self.feed('$ ' + str(command_string) + spaces)
        self.log('$ ' + str(command_string) + spaces)

        command = command_string.split(' ')
        pid =  self.fork_command(command=command[0], argv=command, directory=os.getcwd())

        while self.thread_running:
            #time.sleep(.01)
            gtk.main_iteration()

    def run_command_done_callback(self, terminal):
        '''When called this function sets the thread as done allowing
        the run_command function to exit'''
        #print 'child done'
        self.thread_running = False

    def yes_no_question(self, message):
        message = message.replace('\\\\n\\\\n', '[NEWLINE][NEWLINE]').replace('\\\\n', '').replace('[NEWLINE]', '\\\\n')

        if message.find('?') == -1:
            message = message + '\\\\n\\\\nDo you want to continue?'

        type=gtk.MESSAGE_QUESTION
        if message.lower().find('warning') != -1:
            type=gtk.MESSAGE_WARNING

        dialog = gtk.MessageDialog(parent=None, flags=0, type=type, buttons=gtk.BUTTONS_YES_NO, message_format=message)
        dialog.set_icon(self.icon)
        dialog.show_all()
        responce = dialog.run()
        dialog.destroy()

        # Responce == yes
        return responce == -8

TestVirtualTerminal.py Used to actually make the GUIs, this is the program you should run.

#!/usr/bin/env python
#
#      TestVirtualTerminal.py
#
#      Copyright 2007 Edward Andrew Robinson <earobinson@gmail>
#
#      This program is free software; you can redistribute it and/or modify
#      it under the terms of the GNU General Public License as published by
#      the Free Software Foundation; either version 2 of the License, or
#      (at your option) any later version.
#
#      This program is distributed in the hope that it will be useful,
#      but WITHOUT ANY WARRANTY; without even the implied warranty of
#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#      GNU General Public License for more details.
#
#      You should have received a copy of the GNU General Public License
#      along with this program; if not, write to the Free Software
#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

import gtk

from VirtualTerminal import VirtualTerminal

class mainWindow(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self)
        self.connect('destroy', lambda w: gtk.main_quit())
        self.set_default_size(400, 400)

        self.button = gtk.Button('press me')
        self.button.connect("clicked", self.pressed_callback)

        self.command_entry = gtk.Entry()
        self.command_entry.set_text('python count.py')
        #self.command_entry.set_text('sudo aptitude install gaim-encryption')

        vbox = gtk.VBox()

        self.r = 0

        self.add(vbox)

        vbox.pack_start(self.command_entry, False)
        vbox.pack_start(self.button, True)

        self.myTerminal = terminal()

        self.show_all()

        gtk.main()

    def pressed_callback(self, button):
        print 'presed'
        column,row = self.myTerminal.terminal.get_cursor_position()
        if self.r != row:
            off = row-self.r
            text = self.myTerminal.terminal.get_text_range(row-off,0,row-1,-1,self.capture_text)
            self.r=row
            text = text.strip()
            print text
        self.button.set_sensitive(False)
        self.myTerminal.terminal.run_command(self.command_entry.get_text())
        self.button.set_sensitive(True)
        print 'done'

    def capture_text(self,text,text2,text3,text4):
        return True

class terminal(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self)
        #self.set_title(self.settings.application_name)
        self.connect('destroy', lambda w: gtk.main_quit())

        self.terminal = VirtualTerminal()

        #self.child_pid = self.terminal.fork_command()

        self.add(self.terminal)
        self.show_all()

mainWindow()

count.py A little test program but you can run any command you want

#!/usr/bin/python

import time

print '0'

for ii in range (10):
    time.sleep(1)
    print ii + 1

A special thanks to Alberto Milone for all the help he provided me with for this.


Propensity – feedback wanted

2007/09/02 4:37:08

I have been using ubuntu for quite some time, and I have ubuntu installed on 20+ computers at one time. I find myself always installing ubuntu on a different computer. One of the things that I always do is install some programs that don’t come stock with ubuntu like geany, or miro. At first I had a simple shell script that I ran that aptituded (lol) all the programs I wanted to install. But soon that was not enough because different computers had different uses and installing miro or gaim guifications on a work computer, or a computer that will be going back to a client is out of the question. Another thing I wanted was to updated the source.list file with new repositories cleanly. And so eventually that shell script involved into a python program.

I have spent a bit of my summer cleaning up that python program and the result is propensity (I looked for synonyms for aptitude) and now I figure its almost ready to be released into the public. I have uploaded both a deb file and the source to my website, and would love some feedback.

Some features that I would like to add before I release it are:

  • I would like propensity to generate a standalone shell script that could be used to standalone install the package
  • Icon
  • Splash screen
  • Ability to add your own programs and save them (so you can load them from a file at a later date) Thanks Ed
  • Documentation

To sum up you can get the deb file here, and the source here. Thanks for any feedback you have.

Update 01: I made a post to the ubuntu forums and posted a screenshot
Update 02: I have been dugg.
Update 03: Propensity has only been tested on feisty.


Linux live CD as a window recovery tool

2007/07/27 13:31:09

As a computer geek one of the first things people say to me when learn that I’m a computer geek is “can you fix my computer”. Now depending on my mood or how exactly they asked, offering beer is always a good idea, I usually respond with “I don’t use windows, and haven’t used it in years”. But if your nice and its convenient for me sure Ill give it a shot.

The other day a friend of mines computer laptop had stopped booting, during the boot it would get the blue screen of death. She had all ready called IBM, she got her laptop before Lenovo bought the thinkpad name, who said the hard drive was most likely dead. Seeing as she had lost all her data I first scolded her for not creating proper backups, and then told her that if she brought her computer to me I would give it a shot at fixing it.

Popping a Ubuntu live cd into her computer and then plugging in an IPod we where able to recover most of the data on her computer. To me it seemed second nature to be able to run an operating system off a live cd in order to recover data, but to her it seemed foreign since windows would not boot she had assumed all was lost.

Is this really still the case for windows, what do you do if windows wont boot (and yes safe mode and the “IBM recovery button” would not boot)?

Disclamer: This is not a windows bash but is there no way to yank your data off the computer if it wont boot other than taking out the hard drive?


There has been a revolution! Democracy is now Miro!

2007/07/19 1:28:53

Democracy is now Miro, today I did my updates and was welcomed with the new Miro player, I must say I haven’t noticed any real changes, In fact they don’t even seem to list any real on there blog (just little things here and there), but the one thing I can say is the update was flawless and its great to see a for profit company coming out with great open source software people getting paid to make open source software.

Long live Miro!


GraphThing and xchm

2007/07/14 17:38:07

On of the best features that linux has in my opinion is synaptic, I have said this before and I will say it again. Why is synaptic so great? You can fire it up and search for any package you like and then with a few clicks install that program. I have recently had two great finds with synaptic, the first came in my algorithms class I was sitting at school doing some homework and one of my buddies asked me if I had a program to find a maximum flow of a graph. Simply by searching for “max flow” in synaptic I was able to find a program called GraphThing that lets you draw graphs and then run all sorts of simple algorithms on them like, max flow, minimum spanning tree, and may more. GraphThing dose have some faults however it is unable to have an edge to a node with capasity of 3 and an edge in the opsit direction with capasity 5 but it is a great application for starters. then a Funny thing is not moments later do we find some notes online but they are stored in chm format, once again I fire up synaptic this time I search for “chm” and moments later Im using xchm a great chm viewer.


What great programs have you found using synaptic?


Ubuntu root access.

2007/06/20 13:51:58

One of the greatest features that Linux has to offer, is the ability to customize your version so that it works the way you like it. Being a computer science student I have many friends that run linux, and many running windows (most dual boot).

With some of my windows friends there is a bit of an on going war about who’s computer is better, IBM vs Dell, Windows vs Linux vs Mac, Ubuntu vs Fedora Firefox vs IE, Vista vs XP. The things to debate are endless, its mostly all in good fun but it can sometimes get heated. The great thing is that usually when someone finds a “flaw” with ubuntu I can fix it on the spot if I so chose. Common arguments are that the brown is ugly (I love the brow), all I need do is fire up beryl or compiz (gl desktop). And the argument is shutdown.

The other day it was pointed out to me that a “flaw” was that if ubuntu was booted into recovery mode that the user was then given root access without the need of a password. I know that /boot/grub/menu.lst controls grub so I open it up “sudo gedit /boot/grub/menu.lst” and search for the word “password” at line 28 I find

## password ['--md5'] passwd
# If used in the first section of a menu file, disable all interactive editing
# control (menu entry editor and command-line) and entries protected by the
# command ‘lock’
# e.g. password topsecret
# password –md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
# password topsecrete

I change it to

## password ['--md5'] passwd
# If used in the first section of a menu file, disable all interactive editing
# control (menu entry editor and command-line) and entries protected by the
# command ‘lock’
# e.g. password topsecret
# password –md5 $1$gLhU0/$aW78kHK1QfV3P2b2znUoe/
password topsecrete

Go down to the bottom of the file and change

## ## End Default Options ##

title Ubuntu, kernel 2.6.20-16-generic
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-16-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro quiet splash
initrd /boot/initrd.img-2.6.20-16-generic
quiet
savedefault

title Ubuntu, kernel 2.6.20-16-generic (recovery mode)
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-16-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro single
initrd /boot/initrd.img-2.6.20-16-generic

title Ubuntu, kernel 2.6.20-15-generic
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-15-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro quiet splash
initrd /boot/initrd.img-2.6.20-15-generic
quiet
savedefault

title Ubuntu, kernel 2.6.20-15-generic (recovery mode)
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-15-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro single
initrd /boot/initrd.img-2.6.20-15-generic

title Ubuntu, memtest86+
root (hd0,0)
kernel /boot/memtest86+.bin
quiet

### END DEBIAN AUTOMAGIC KERNELS LIST

to

## ## End Default Options ##

title Ubuntu, kernel 2.6.20-16-generic
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-16-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro quiet splash
initrd /boot/initrd.img-2.6.20-16-generic
quiet
savedefault

title Ubuntu, kernel 2.6.20-16-generic (recovery mode)
lock
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-16-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro single
initrd /boot/initrd.img-2.6.20-16-generic

title Ubuntu, kernel 2.6.20-15-generic
lock
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-15-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro quiet splash
initrd /boot/initrd.img-2.6.20-15-generic
quiet
savedefault

title Ubuntu, kernel 2.6.20-15-generic (recovery mode)
lock
root (hd0,0)
kernel /boot/vmlinuz-2.6.20-15-generic root=UUID=8fdab1e2-1453-4eb3-a8db-a14dbff447d0 ro single
initrd /boot/initrd.img-2.6.20-15-generic

title Ubuntu, memtest86+
lock
root (hd0,0)
kernel /boot/memtest86+.bin
quiet

### END DEBIAN AUTOMAGIC KERNELS LIST

Now not only can the user not access anything but my default boot option with using the very secure password, lol. While I don’t consider it a bug that the user could have gained access to the root before without a password I love how easy it is in Linux to prevent that kind of thing. Now all I need is to set my BIOS password so that the user cant boot of anything but the hard disk without a password.


Follow

Get every new post delivered to your Inbox.