Posts about programming (old posts, page 29)

2010-02-04 19:58

Marave 0.1 released, please test!

The first "good" version of Marave my relaxing text editor is out!

What is Marave?

Marave is an editor that doesn't distract you. It has a fullscreen interface, and most of the time, while you write, you will only see your text, and maybe a background:

marave1

Of course it is also quite configurable:

marave2

Some of the features:

  • Custom backgrounds (images or colors)
  • Font and font size are configurable
  • Resizeable editor of configurable opacity
  • "Vanishing" UI, when you tipe, it all goes away
  • Optional media player (right now aimed at streaming audio, maybe soundscapes someday)
  • Optional audio feedback for the keyboard (just in case you miss the old typewriter)
  • Theme support
  • Multilingual spellchecking (requires pyenchant)

Marave is implemented using PyQt, so it should work in all major platforms, Windows, Linux and Mac OSX, as long as you have PyQt installed.

In the future, easy to use binaries will be provided for Windows and Mac.

This version is not feature complete. Specifically:

  • Search+Replace is not done
  • There may be some customizations not implemented

Download Marave 0.1

UPDATE 0.2 is out, at http://code.google.com/p/marave/downloads/list

2010-02-03 12:31

Apple's iPad is a sad, sad thing.

What the Ipad means

Everything I will say here was probably better said by Mark Pilgrim but what the heck, let's give it a shot.

Here's what's wrong with the iPad: it sucks for me.

Before anyone says "don't buy it then!" I'll say it first: I don't intend to buy one.

I think there is a place for iPads and it would go agains most of my beliefs to say it shouldn't exist, but I also expect it to make our world poorer, if it's popular enough.

Yes it's hostile to tinkering. Yes, to read about that, see Mark Pilgrim's article, he's a much better writer than I.

I once posted the README file for a piece of software called Atlast. It said things like "make everything programmable" and "[It is] far better to invest the effort up front to create a product flexible enough to be adapted at will, by its users, to their immediate needs."

The iPad and most other Apple products are the antithesis of that. They are products meant to be exactly as they are, and that's all they are goint to be. If you want to change the way it acts, you need to pay and be subject of Apple's whim, or "break into" your own device.

That hurts me. I see people give up even the possibility of changing what a (let's say it) pretty, useful, powerful device is capable of, just because they don't what that freedom. I can understand that from, say, a used car salesman, or whatever, someone without any inclination for that craft.

But I see freaking programmers buying apple kit. And I see them happy with their iPhones and iPods and (soon, surely) iPads, buying apps from the only source enabled to sell them, buying the apps that are allowed by a single party, that decides, hey, this app? you won't need it!

I see them and I say to myself, dude, that thing you hold in your hand is more powerful than anything we had 10 years ago, there must be something cool you could do with it that noone else is doing.

What's the vision a programmer has of his future if he endorses Apple's closed kit? A future where he can program something only if Apple approves? A future where a "real" computer is a SDK for the things "real people" use in their everyday lifes?

What is wrong with you? What happened to you? Are you now the kind of guy that's just happy with what he's given? Are you now a freaking utilitarian? Are you old now?

Have you noticed the trend in Apple's new products is towards less control by the user? First it was just handhelds, now there's a tablet. What was the last new interesting Apple product that wasn't locked up?

Here they had a device which could have OSX or Iphone OS, and they went with Iphone OS. There is a reason for that: it makes them more money.

For OSX, they make money of the hardware, the OS upgrades, and some apps. On the iPad, they make money every time you buy any app, every time you buy a book to read in it, every time you use 3G with the prepaid plan, and I am sure they are going to find other ways too.

And what's the key to making money that way? Control. If they had no exclusive control of the App store, they lose a source of revenue. If they allowed for easy development of hobby apps, they would lose revenue. If they could let you replace the freaking battery, they would lose revenue.

And if there's one thing companies hate is losing revenue. Apple saw two paths ahead, one leading to huge money, the other to just big money. They have taken the huge money path, and it's working for them. They are not going back.

If everyone goes along for the ride, it will be a sad thing.

2010-01-28 20:05

New project: marave, a relaxed text editor

Announcement:

Marave (nothing, in guaraní) is a relaxed text editor. Its goal is to let you focus in your writing, free of visual distractions and clutter.

It is written using PyQt, so it should work in all major platforms, and it is licensed under the GPLv2 so it is free software.

You can find the current SVN (no release yet) at http://marave.googlecode.com

Screenshots:

snapshot10snapshot9snapshot8

Status:

It's not finished yet, but it has the following features:

  • You can edit text
  • Minimalistic, "vanishing" user interface
  • (Optional) audio feedback for the keyboard
  • (Optional) relaxing music (requires internet access)
  • You can customize the background, font, colours, and sounds
  • Live spell checking (requires pyenchant)

There are also some major missing features:

  • Search and Search/Replace is not implemented
  • UI customizations are not stored
  • UI has to be cleaned up a lot more
  • It doesn't ask to save when closing
  • Autosave not implemented

And at least one known bug:

  • In windows the widgets are not well placed Fixed in SVN

A litte history:

A few days ago, I saw ommwriter mentioned in a tweet or something similar.

I was thinking "nice thing", but in the back of my mind I was also thinking "that can't be too hard to do". After all, the hard part of creating a program is making it do things, right?

Well, yes and no. I did manage to create a somewhat reasonable facsimile in a day, but tweaking the looks of it is driving me nuts :-)

2010-01-19 14:12

Happy 10th blogiversary to me!

Since yesterday this blog is ten years old so, time for some history.

It all started in advogato where you could still read it today! (Please read it here instead ;-)

Then it moved to PyDS an early python desktop blog platform with a web interface, and was hosted in PyCS, a free service.

Then PyCS kinda died, and I started generating a static blog and hosting it in my ISP's free hosting. That sucked bad.

Then I started my own company, and I had my own servers, so I started hosting it there (even today this blog is completely static HTML!)

Then PyDS started acting weird, so I wrote my own blogging software, which is a real mess, perhaps 25% finished, but it does things exactly the way I like them.

Currently, this blog is syndicated in Planeta PyAr, Planet Python, Planet Qt, Planeta LUGLI, and a couple other places.

This year, I decided to make the blog completely bilingual (English and Spanish), but I hate translating it.

According to the stats I have available, the blog is in average more popular now than ever (but yes, my most popular posts were years ago ;-)

stats

These are the most popular pages in the last year:

Lessons:

  1. I need to write more about Qt and/or start flamewars with clueless IT writers
  2. I need to search for ancient material and deprecate it
  3. Having your own hosting and blogging software is neat
  4. 10 years is a lot of time: 860 posts (or 913, depending on how you count)

2009-12-23 15:32

With iterpipes, python is ready to replace bash for scripting. Really.

This has been a pet peeve of mine for years: programming shell scripts suck. They are ugly and error prone. The only reason why we still do it? There is no real replacement.

Or at least that was the case, until today I met iterpipes at python.reddit.com

Iterpipes is "A library for running shell pipelines using shell-like syntax" and guess what? It's brilliant.

Here's an example from its PYPI page:

# Total lines in *.py files under /path/to/dir,
# use safe shell parameters formatting:

>>> total = cmd(
...     'find {} -name {} -print0 | xargs -0 wc -l | tail -1 | awk {}',
...     '/path/to/dir', '\*.py', '{print $1}')
>>> run(total | strip() | join | int)
315

Here's how that would look in shell:

find /path/to/dir -name '*.py' -print0 | xargs -0 wc -l | tail -1 | awk '{print $1}'

You may say the shell version looks better. That's an illusion caused by the evil that is shell scripting: the shell version is buggy.

Why is it buggy? Because if I control what's inside /path/to/dir I can make that neat little shell command fail [1], but at least in python I can handle errors!

Also, in most versions you could attempt to write, this command would be unsafe because quoting and escaping in shell is insane!

The iterpipes version uses the equivalent of SQL prepared statements which are much safer.

It's nearly impossible to do such a command in pure shell and be sure it's safe.

Also, the shell version produces a string instead of an integer, which sucks if you intend to do anything with it.

And the most important benefit is, of course, not when you try to make python act like a shell, but when you can stop pretending shell is a real programming language.

Consider this gem from Arch Linux's /etc/rc.shutdown script. Here, DAEMONS is a list of things that started on boot, and this script is trying to shut them down in reverse order, unless the daemon name starts with "!":

# Shutdown daemons in reverse order
let i=${#DAEMONS[@]}-1
while [ $i -ge 0 ]; do
        if [ "${DAEMONS[$i]:0:1}" != '!' ]; then
                ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@}
        fi
        let i=i-1
done

Nice uh?

Now, how would that look in python (I may have inverted the meaning of ck_daemon)?

# Shutdown daemons in reverse order
for daemon in reversed(DAEMONS):
    if daemon[0]=='!':
        continue
    if ck_daemon(daemon):
        stop_daemon(daemon)

Where stop_daemon used to be this:

stop_daemon() {
    /etc/rc.d/$1 stop
}

And will now be this:

def stop_daemon(daemon):
    run(cmd('/etc/rc.d/{} stop',daemon))

So, come on, people, we are in the 21st century, and shell scripting sucked in the 20th already.

[1] I leave that as exercise for the reader.

2009-12-22 09:38

What I do for a living

So, what do you do for a living?

—Hardest question ever

Whenever I am speaking with people who don't know me [1] that's the question I dread.

If someone asks my wife what she does, all she has to do is say "I'm a lawyer". If someone asks my mother, she'd say "I am a retired teacher". Everyone understands what a lawyer does, or what a retired teacher did.

If someone asks me... oh, boy, that's hard. I usually weasel out by saying "I work with computers" but that has several problems:

  • They assume I repair PCs
  • They start telling me how their windows box was slow until they installed some kropotkina which supergarbled their frobnozzles [4], then ask me my opinion on frobnozzle garbling. For or against?

It's really hard to explain that yes, I work with computers every day, but I almost never open one (in fact, I have a policy of not touching my customers computers), and I have no idea what a frobnozzle is.

I have tried saying "I work on server side things, like mail servers and such. I install them, support them and also consulting work, explaining companies what the best ways to improve their services are.".

That one usually gets glassy eyes and a general "what?" look.

I could lie and say I program for a living, but that's not true. While I program a lot, it's usually not for money, and what little I do for money is just using programming as a sysadmin tool.

I could say "I'm a sysadmin" but most people have no idea what that is. It does tend to end conversations, though, so it has one thing going for it.

Nowadays I could say "I have a company", which is true (we are awesome, you should hire us to do whatever it is we do, more details at http://www.netmanagers.com.ar )

So, I usually manage to work around this question, but I have a problem: I'm not telling the truth, or if I am, I am not telling the truth in spirit because I am not conveying what my work is, but only what I do.

So, this post is about trying to explain what the hell I do for a living, in another way, which is more ... internally true, so to speak. This is really hard to do, so I am trying to just let the writing flow, maybe you can understand what I do even if it's not clearly explained.

I work with computers. I make them do what I want them to do. Whenever a regular user sits before his keyboard, he tries to make his computer follow his orders, which variable rates of success. I always succeed.

Sometimes, I am logged into a computer that manages data for thousands of people. They all are on my care. No, it's not their lives at stake, but a little part of their fun, or work is under my care. I help them. I care about them, and I want their fun, their work to be smooth and pleasant.

Often the computer will not do what they need. I will try with my craft to make it happen. I will write little programs, search for others on the Internet, carefully piece together a puzzle and make their needs be fulfilled.

I will write or install and configure those programs and do it well, because I am skilled, I have literally decades of training and experience, but I will mostly do it because I like order and function. I like when things flow unimpeded, I like when serendipitous accidents make things just click together.

I do those things for a living, yes, because I need to make a living. And later, when I'm off the clock and my boy is asleep and I have my own time, you know what I do? I do the same things because they are fun. And I will bother writing a 1300 word post about how I migrated my blog's comments from one site to another because it was fun.

Yes, I know, to most people that would not be fun at all, it would be a boring job, and they would hate doing it. And that's one of the many reasons I am a lucky man [5]: I have fun doing unusual things. That's really lucky, because if my idea of fun was watching "Gossip Girl" I would never have found anyone to pay me to do that!

But going back to what I do for a living, I create things. I don't create large, impressive things, I am not a bridge builder, an architect, I create small, useful things and try to do it with a certain taste or elegance. I am more like a silversmith doing cutlery. Sure, I'll try to make it nice to look at, but it must cut a chunk of beef first.

Yes, I work with computers, but how does that convey what I feel when after a solid day of work I can see that what was a lot of stupid computers and cables are now a working machine that can make 50000 phone calls a day?

How can I make anyone see the beauty in 3 hard lines of code that do nothing but print a bunch of numbers?

How can someone who makes a living any other way understand that I think things and they become real? No, not real as in a puff of smoke and there they are, but they become real through work and effort and thinking and cursing, which is what makes them really real.

I know most of this will sound like mysticism, but it's not, it's my honest truth, I really feel all these things as I work, all these things are my work. Sometimes when I crack a hard problem I want to fucking sing [7] that's how awesome it feels.

So, that's what I do for a living. I work with computers.

[1] Given my shyness problem, that's not too often [2]
[2] To those who only know me from public speaking [3]: I am painfully shy.
[3] Yes, it's perfectly possible to be a decent public speaker and be shy.
[4] At least that's how windows users sound to me half the time
[5] The others are of course y wife and boy, and if they ever read this: kisses for both. [6]
[6] He's just 2.9 years old but you know, the Internet keeps things forever.
[7] If you know my voice, you know why I don't. My own son says "no, don't sing, daddy", except for his good night song, which is the only one he lets me sing. Oh, and sorry for the cursing, but no other word fits.

2009-12-21 14:39

python-keyring is seriously nice

Many programs require passwords from the user.

It's nice when a program can remember the password you give it.

It's nicer when it stores said password safely. However, it's not trivial to do that if you care for cross-platform support.

Or at least it wasn't until Kang Zhang wrote python keyring, a module that abstracts the password storage mechanisms for KDE, GNOME, OSX and windows (and adds a couple of file-based backends just in case).

So, how does it work?

Install it in the usual way. If it's not packaged for your distro/operating system, just use easy_install:

easy_install keyring

You could also get it from mercurial:

hg clone http://bitbucket.org/kang/python-keyring-lib/

The API is simplicity itself. This is how you save a secret:

import keyring
keyring.set_password('keyring_demo','username','thisisabadpassword')

You may get this dialog (or some analog on other platforms):

keyring1

And here's the proof that it was saved correctly (this is KDE's password manager):

keyring2

And how do you get the secret back?

import keyring
print keyring.get_password('keyring_demo','username')

This is how it runs:

$ python load.py
thisisabadpassword

As you can see, the API is as easy as it could possible get. It even chose the KWallet backend automatically because I am in KDE!

Python-keyring is a module that fixes a big problem, so a big thank you to Kang Zhang and Tarek Ziadé (who had the idea)

2009-12-18 11:50

The smartest thing I ever wrote

When I was migrating the comments I noticed a page looked wrong in the site, and started fixing it.

While I was reading, I noticed a couple of things:

  • It was published almost exactly 5 years ago
  • It may be the smartest thing I ever wrote

Sometimes, you get an idea, and you can give it shape. Since I really think it's not completely stupid, I translated it to spnish (there was only an english version) y "reprint" it today.

It's about programming, it's about evolution, and I hope you like Being a good Lamarckian froggie!.

2009-12-18 00:37

Migrating from Haloscan to Disqus (if you can comment on it, it worked ;-)

Introduction

If you are a Haloscan user, and are starting to wonder what can you do... this page will explain you a way to take your comments to Disqus, another free comment service.

A few days ago, Haloscan announced they were stopping their free comment service for blogs. Guess what service has in it the comments of the last 9 years of this blog? Yes, Haloscan.

They offered a simple migration to their Echo platform, which you have to pay for. While Echo looks like a perfectly nice comment platform, I am not going to spend any money on this blog if I can help it, since it already eats a lot of my time.

Luckily, the guys at Haloscan allow exporting the comments (that used to be only for their premium accounts), so thanks Haloscan, it has been nice!

So, I started researching where I could run to. There seems to be two large free comment systems:

Keep in mind that my main interest lays in not losing almost ten years of comments, not on how great the service is. That being said, they both seem to offer roughly the same features.

Let's consider how you can import comments to each service:

  • Disqus: It can import from blogger and some other hosted blog service. Not from Haloscan.
  • Intense Debate: Can import from some hosted services, and from some files. Not from the file Haloscan gave me.

So, what is a guy to do? Write a python program, of course! Here's where Disqus won: they have a public API for posting comments.

So, all I have to do then is:

  1. Grok the Disqus API
  2. Grok the Haloscan comments file (it's XML)
  3. Create the necessary threads and whatever in Disqus
  4. Post the comments from Haloscan to Disqus
  5. Hack the blog so the links to Haloscan now work for Disqus

Piece of cake. It only took me half a day, which at my current rates is what 3 years of Echo would have costed me, but where's the fun in paying?

So, let's go step by step.

1. Grok the Disqus API

Luckily, there is a reasonable Disqus Python Client library and docs for the API so, this was not hard.

Just get the library and install it:

hg clone https://[email protected]/IanLewis/disqus-python-client/
cd disqus-python-client
python setup.py install

The API usage we need is really simple, so study the API docs for 15 minutes if you want. I got almost all the tips I needed from this pybloxsom import script

Basically:

  1. Get your API Key
  2. You login
  3. You get the right "forum" (you can use a disqus account for more than one blog)
  4. Post to the right thread

2. Grok the Haloscan comments file

Not only is it XML, it's pretty simple XML!

Here's a taste:

<?xml version="1.0" encoding="iso-8859-1" ?>
<comments>
    <thread id="BB546">
      <comment>
        <datetime>2007-04-07T10:21:54-05:00</datetime>
        <name>superstoned</name>
        <email>[email protected]</email>
        <uri></uri>
        <ip>86.92.111.236</ip>
        <text><![CDATA[that is one hell of a cool website ;-)]]></text>
      </comment>
      <comment>
        <datetime>2007-04-07T16:14:53-05:00</datetime>
        <name>Remi Villatel</name>
        <email>[email protected]</email>
        <uri></uri>
        <ip>77.216.206.65</ip>
        <text><![CDATA[Thank you for these rare minutes of sweetness in this rough world...]]></text>
      </comment>
    </thread>
</comments>

So, a comments tag that contains one or more thread tags, which contain one or more comment tags. Piece of cake to traverse using ElementTree!

There is an obvious match between comments and threads in Haloscan and Disqus. Good.

3. Create the necessary threads and whatever in Disqus

This is the tricky part, really, because it requires some things from your blog.

  • You must have a permalink for each post
  • Each permalink should be a separate page. You can't have permalinks with # in the URL
  • You need to know what haloscan id you used for each post's comments, and what the permalink for each post is.

For example, suppose you have a post at //ralsina.me/weblog/posts/ADV0.html and it has a Haloscan comments link like this:

<a href="javascript:HaloScan('ADV0');" target="_self"> <script type="text/javascript">postCount('ADV0');</script></a>

You know where else that 'ADV0' appears? In Haloscan's XML file, of course! It's the "id" attribute of a thread.

Also, the title of this post is "Advogato post for 2000-01-17 17:19:57" (hey, it's my blog ;-)

Got that?

Then we want to create a thread in Disqus with that exact same data:

  • URL
  • Thread ID
  • Title

The bad news is... you need to gather this information for your entire blog and store it somewhere. If you are lucky, you may be able to get it from a database, as I did. If not... well, it's going to be a lot of work :-(

For the purpose of this explanation, I will assume you got that data nicely in a dictionary indexed by thread id:

{
  id1: (url, title),
  id2: (url, title)
}

4. Post the comments from Haloscan to Disqus

Here's the code. It's not really tested, because I had to do several attempts and fixes, but it should be close to ok (download).

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Read all comments from a CAIF file, the XML haloscan exports

from disqus import DisqusService
from xml.etree import ElementTree
from datetime import datetime
import time


# Obviously these should be YOUR comment threads ;-)
threads={
    'ADV0': ('//ralsina.me/weblog/posts/ADV0.html','My first post'),
    'ADV1': ('//ralsina.me/weblog/posts/ADV1.html','My second post'),
    }

key='USE YOUR API KEY HERE'
ds=DisqusService()
ds.login(key)
forum=ds.get_forum_list()[0]

def importThread(node):
    t_id=node.attrib['id']

    # Your haloscan thread data
    thr_data=threads[t_id]

    # A Disqus thread: it will be created if needed
    thread=ds.thread_by_identifier(forum,t_id,t_id)['thread']

    # Set the disqus thread data to match your blog
    ds.update_thread(forum, thread, url=thr_data[0], title=thr_data[1])


    # Now post all the comments in this thread
    for node in node.findall('comment'):
        dt=datetime.strptime(node.find('datetime').text[:19],'%Y-%m-%dT%H:%M:%S')
        name=node.find('name').text or 'Anonymous'
        email=node.find('email').text or ''
        uri=node.find('uri').text or ''
        text=node.find('text').text or 'No text'

        print '-'*80
        print 'Name:', name
        print 'Email:', email
        print 'Date:', dt
        print 'URL:', uri
        print
        print 'Text:'
        print text

        print ds.create_post(forum, thread, text, name, email,
                                   created_at=dt, author_url=uri)
        time.sleep(1)

def importComments(fname):
    tree=ElementTree.parse(fname)
    for node in tree.findall('thread'):
        importThread(node)


# Replace comments.xml with the file you downloaded from Haloscan
importComments('comments.xml')

Now, if we are lucky, you already have a nice and fully functioning collection of comments in your Disqus account, and you should be calm knowing you have not lost your data. Ready for the final step?

2009-12-16 17:12

New 24-hour app coming (not so) soon: foley

First a short explanation:

24-hour apps are small, self-contained projects where I intend to create a decent, useful application in 24 hours. The concept is that:

  1. I will think about this app a lot for a while
  2. I will design it in my head or in written notes
  3. I will code, from scratch, for 24 hours.
  4. That's not one day, really, but 24 hours of work. I can't work 24 hours straight anymore.

The last time around this didn't quite work as I intended, but it was fun and educational (for me at least ;-) and the resulting app is really not bad!

So, what's foley going to be? A note-taking app aimed at students and conference public.

In your last geeky conference, did you notice everyone is using a computer?

And what are they taking notes on? Vi? Kwrite? OpenOffice? Whatever it is they use, it's not meant to be used for this purpose.

So, what will foley do different? I don't quite know yet, but I have some ideas:

  1. A strong timeline orientation. Every paragraph will be dated.
  2. Twitter/Identica support. Want to liveblog your notes? Just click.
  3. Multimedia incorporated in the timeline.
    • Webcam/Audio recording synced to your notes?
    • Images imported and added in the timeline?
    • Attach files to the timeline? (Useful for slides?)
  4. If provided with a PDF of slides, attach each slide to the right moment in the timeline
  5. Easy web publishing: find a way to put this on a webpage easy and quick (single-click publishing is the goal)

I have only thought about this for about 10 minutes, but I see potential here.

The bad news is... I have a ton of paying work to do. So this will probably only happen in January. However, I wanted to post it so I can take input while in this planning phase.

So, any ideas?

Contents © 2000-2019 Roberto Alsina