Older blog entries for ralsina (starting at number 595)

Nikola: Filters & Bundles

Two upcoming features for the next release of Nikola, my static site generator, due sometime in August.

Filters

Filters let you postprocess your output. Think of it like instagram for websites, but useful. You can configure per file extension a series of python functions or shell commands, which will be applied in place to the output file.

For example, suppose you want to apply yui-compressor to your CSS and JS files:

FILTERS = {
    ".css": [filters.yui_compressor],
    ".js": [filters.yui_compressor],
}

There, filters.yui_compressor is a simple wrapper around the command so that it applies in-place to the output files.

If you use strings there (untested), they are taken as commands. The "%s" will be replaced by the filename, the usual crazy shell quoting rules apply:

FILTERS = {
    ".jpg": ["jpegoptim '%s'"],
    ".png": ["pngoptim '%s'"],
}

Keep in mind that the filters modify the output of Nikola, not the input, so your images, CSS, and JS files will not be touched in any way. And of course changing the filters applied to a file will force a rebuild, so you can experiment freely.

Bundles

Having many separate CSS or JS files is usually a nono for performance reasons because each one may involve a separate HTTP transaction. The solution is to "bundle" those files in a single, larger file.

The reason not to do that is that usually it means having a huge, uncomfortable thing to handle. So Nikola tries to give you the best of both worlds, by letting you have separate files, and bundling them (or not) on build.

There is a new option, USE_BUNDLES that defaults to False, and there are some changes in the theme templates so that it uses the bundled version when needed.

This was only possible thanks to Webassets. However, if you don't have Webassets installed, or you don't enable USE_BUNDLES, this should cause no changes in the output.

Conclusion

These new features will allow Nikola users to improve their site's performance with minimal tweaking, which is always a good thing.


Syndicated 2012-08-10 20:06:54 from Lateral Opinion

The Minimal Server

I was a sysadmin for a long time. I did that for money, so I never really wanted to spend time doing the same thing in my own time, which lead to a severe case of cobbler's children walking barefoot in my private server.

So, today at lunch, I decided to clean up my garbage. So this is what I ended up with, which is the minimal server that is good enough to be generally useful for me.

Hosting

This is a cheap VPS provided by the nice folks at burst.net who are not giving me anything to speak nice things about their service. However, I will do it anyway:

  • Crazy cheap ($5.50 but I have a 20% discount for life)
  • Good amount of monthly bandwidth
  • Lots of disk space
  • Good uptime
  • Fast network
  • Very cheap
  • Decent performance

Distribution

I had CentOS 5 installed, and it stays. If burst ever starts offering Ubuntu Precise, I may switch. Or, since this works, I may not.

What's good about CentOS? It's stable and boring.

What's bad about CentOS? It's too boring. Lots of cool stuff just isn't packaged.

Web Server

I need to serve a bunch of domains, but I have a peculiarity: they are all static sites. I want:

  • Low resource usage
  • Decent performance (that mostly involves supporting ranges and content negotiation)
  • Stable
  • Support directory indexes
  • Easy configuration
  • Virtual domains by name

Almost any server works well for this. Even Apache, except for the easy configuration bit. I ended up with gatling because it fits those criteria fairly well.

  • It uses about 1.4MB of RAM , which is always nice in a VPS
  • It's pretty fast
  • Has not crashed in 2 hours?
  • Supports indexes
  • Here's the configuration: "-c /srv/www -P 2M -d -v -p 80 -F -S" (yes, there is no config file at all)
  • Virtual domains are just folders and symlinks inside /srv/www which is the easiest possilble way to do it.
  • It supports reverse proxying for when I want to try a python web app I am working on.

Mail Server

No, I don't want a mail server. I have gmail and/or a real mail server for that. I want to get the mails from cron. For this, I used ssmtp and an extra gmail account. It works, and here's the whole config:

root=roberto.alsina@gmail.com
mailhub=smtp.gmail.com:587
UseTLS=YES
UseSTARTTLS=YES
AuthMethod=LOGIN
AuthUser=roberto.alsina.3@gmail.com
AuthPass=notputtingthetrueoneheredude

The best I can say about this configuration is that it works, and doesn't involve running a daemon.

Misc

For when I need to be in two places at the same time: OpenVPN rules, and there is no argument. I have a squid running occasionally, and there is a Quassel core for IRC stuff. I installed mosh to make ssh less painful, rsync handles file deployment and backup storage, cron schedules stuff, and that's it.

Status

Plenty of free RAM and CPU (yes, that's the full process list):

[root@burst1 ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1   2156   664 ?        Ss   22:01   0:00 init [3]
root      1135  0.0  0.1   2260   576 ?        S<s  22:01   0:00 /sbin/udevd -d
root      1518  0.0  0.1   1812   572 ?        Ss   22:01   0:00 syslogd -m 0
root      1594  0.0  0.1   7240  1032 ?        Ss   22:01   0:00 /usr/sbin/sshd
root      1602  0.0  0.2   4492  1112 ?        Ss   22:01   0:00 crond
root      1630  0.0  0.1   5684   716 ?        Ss   22:01   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a pam -n 2
root      1631  0.0  0.0   5684   444 ?        S    22:01   0:00 /usr/sbin/saslauthd -m /var/run/saslauthd -a pam -n 2
root      1636  0.0  0.2   3852  1372 ?        S    22:01   0:01 /opt/diet/bin/gatling -c /srv/www -P 2M -d -v -p 80 -F -S
root      1677  0.0  0.2   4284  1232 ?        Ss   22:02   0:00 SCREEN /root/quasselcore-static-0.7.1
root      1678  0.0  2.1  36688 11148 pts/0    Ssl+ 22:02   0:03 /root/quasselcore-static-0.7.1
root      3228  1.0  0.7  12916  4196 ?        Ss   23:28   0:13 mosh-server new -s -c 8
root      3229  0.0  0.3   3848  1588 pts/2    Ss   23:28   0:00 -bash
root      3275  0.0  0.1   2532   908 pts/2    R+   23:48   0:00 ps aux
[root@burst1 ~]# w
 23:49:03 up  1:47,  1 user,  load average: 0.00, 0.01, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/2    186.153.52.253   23:28    0.00s  0.01s  0.00s w
[root@burst1 ~]# free
             total       used       free     shared    buffers     cached
Mem:        524800      49100     475700          0          0          0
-/+ buffers/cache:      49100     475700
Swap:            0          0          0

All things considered, fairly happy with the result.


Syndicated 2012-08-07 16:17:40 from Lateral Opinion

Christians say the funniest things!

This is a response to a response to this webcomic titled "How to suck at your religion". While Oatmeal's comic is crass and paints things in broad terms, it's a freaking webcomic. So it's supposed to do that. Butthe response is so full of phallacies (and lacking in webcomic-ness) that it may deserve a response.

I have promised not to be a troll (anymore) so I will try to answer in a sensible manner.

Here's the article I am replying to go read it if you want. I will not reply to all of it, but will instead cherrypick a couple of paragraphs.

In response to the "forcing dogma" panel:

So... religion is fine, unless you actually believe in it? Should parents not pass their political, ethical or moral views on to their children as well? What parts of parenting would be left if parents were to avoid passing their views on to their kids? The irony here is that silence is itself a statement. Avoiding any mention of God to your kids sends as clear a message as talking about God: specifically, it tells your kids that God's existence is either untrue, unknown, or unimportant. Because if you knew Him to exist, surely you'd share that knowledge, right?

Let's start from the top: you don't know god exists. You have faith that he exists, but you don't know it for a fact. If you knew for a fact that he exists, you could not possibly have faith because faith excludes certainty. As your bible says, faith is "the substance of things hoped for, the evidence of things not seen."

So, do I tell my son god doesn't exist? Nope. I tell him I think he doesn't exist, and that I have never seen r heard of any reliable evidence or datum that points towards his existence, but also that some people do believe he does exist. I told him that because I feel that's a honest answer. If your honest answer is "god exists", then bully for you, but from the point of view of a non-believer you are telling your son a lie, or at best a half-truth. And if you really don't know he exists for a fact then you are just lying.

Now, are you sayin that you know god exists factually? Based on what? That's the usual slippery slope for this argument. The religious are the ones making statements of fact based on tradition. To the rest of us, they just seem to be playing loose with what "fact" means, or what "god" means or what "know" means.

So, no, don't avoid mentions of god, just avoid lying to your kids if you can.

This next section is probably the worst, because it's just an incoherent argument. A kid asks, “Dad, what happens to us after we die?” The author compares providing the Christian answer to this question with correcting your kid for having green as a favorite color. What?? That just isn’t a coherent argument. In what world are those two ideas parallel, or even comparable?

According to the webcomic, good parenting is to pretend to be agnostic, and say that “no one really knows for sure.” Of course, if the Resurrection is true, that claim is false. So to be a good parent, you apparently have to deny the Resurrection and embrace agnosticism, treating beliefs about the afterlife as mere matters of personal preference like having a favorite color. This is just… stupid. There’s just no other way of describing it. Imagine if we treated everything that way. “Dad, what’s 3 x 3?” “No one really knows for sure. What do YOU think 3 x 3 is?”

So, comparing life after death with color preference is stupid and incoherent, but comparing it the christian belief of resurrection with basic arithmethics is a-ok? That must have taken some effort to write with a straight face, I'm sure.

So, let's go slowly on this one. Beliefs about the afterlife are, like most other beliefs, probably not a personal preference, but just something you have, because of, in most cases, indoctrination early in life, peer pressure, and just because you live in a society where that belief is normal and approved of.

But what is it your belief in the afterlife is not?

  • It's not inherent to "you". If you were born in another place or time, you would probably believe something else.
  • It's not undisputed. Because there exists a majority of people who don't believe the same thing, either by details or entirely.
  • It's not unique. Because other religions have had similar resurrection beliefs.
  • It's not reliable. Even if we were to accept everything the bible says as true that would not mean we know what will happen to you or to me after we die. We would have a testimony about what happened in a few days in the afterlife of a specific person, at a point in the past, as told to someone by someone. Is that the same as knowing what will happen? No it's not.

Let's compare that to 3x3 as the author attempted:

  • If I was a chinese in the 12th century: 3x3 is 9.
  • There is no group of people that believes 3x3 is 8 or 10.
  • There has not been in the past any real disagreement about the value of 3x3. We have not achieved that result via a gradual improvement.
  • We rely on 3x3 being 9 every day in our lives. If you drive a car, use a phone, or zip your pants, you are agreeing 3x3 is 9.
  • We don't expect 3x3 not to be 9 in the future.

Notice any differences? Yes, me too.

Personally, I consider your faith in god more akin my liking Queen (the band, not the ruler). I was exposed to Queen at the right time, it was approved by my peers, and I like it. On the other hand, I understand that Queen is not everyone's cup of tea, and I don't claim Queen to be the "right" band.

The whole "if the Resurrection is true, that claim is false" line of thought is not logical. If my cat had wings, then the claim that winged cats are awesome is false. But my cat doesn't have wings. Does it make the winged cats less or more awesome that he doesn't? It's not that it's not right, it's that it's not even wrong.

Also, Oatmeal, shame on you about Galileo, really, look it up ;-)


Syndicated 2012-07-26 16:57:42 from Lateral Opinion

Driving a Nail With a Shoe I: Do-Sheet

I had proposed a talk for PyCon Argentina called "Driving 3 Nails with a Shoe". I know, the title is silly, but the idea was showing how to do things using the wrong tool, intentionally. Why? Because:

  1. It makes you think different
  2. It's fun

The bad side is, of course, that this talk's contents have to be a secret, or else the fun is spoiled for everyone. Since the review process for PyConAr talks is public, there was no way to explain what this was about.

And since that means the reviewers basically have to take my word for this being a good thing to have at a conference, which is unfair, I deleted the proposal. The good (maybe) news is that now everyone will see what those ideas I had were about. And here is nail number 1: Writing a spreadsheet using doit.

This is not my first "spreadsheet". It all started a long, long time ago with a famous recipe by Raymond Hettinger which I used again and again and again (I may even be missing some post there).

Since I have been using doit for Nikola I am impressed by the power it gives you. In short, doit lets you create tasks, and those tasks can depend on other tasks, and operate on data, and provide results for other tasks, etc.

See where this is going?

So, here's the code, with explanations:

cells is our spreadsheet. You can put anything there, just always use "cellname=formula" format, and the formula must be valid Python, ok?

from tokenize import generate_tokens

cells = ["A1=A3+A2", "A2=2", "A3=4"]
values = {}

task_calculate creates a task for each cell, called calculate:CELLNAME. The "action" to be performed by that task is evaluating the formula. But in order to do that successfully, we need to know what other cells have to be evaluated first!

This is implemented using doit's calculated dependencies by asking doit to run the task "get_dep:FORMULA" for this cell's formula.

def evaluate(name, formula):
    value = eval(formula, values)
    values[name] = value
    print "%s = %s" % (name, value)

def task_calculate():
    for cell in cells:
        name, formula = cell.split('=')
        yield {
            'name':name,
            'calc_dep': ['get_dep:%s' % formula],
            'actions': [(evaluate, (name, formula))],
            }

For example, in our test sheet, A1 depends on A3 and A2 but those depend on no other cells. To figure this out, I will use the tokenize module, and just remember what things are "names". More sophisticated approaches exist.

The task_get_dep function is a doit task that will create a task called "get_dep:CELLNAME" for every cell name in cells.

What get_dep returns is a list of doit tasks. For our A1 cell, that would be ["calculate:A2", "calculate:A3"] meaning that to calculate A1 you need to perform those tasks first.

def get_dep(formula):
    """Given a formula, return the names of the cells referenced."""
    deps = {}
    try:
        for token in generate_tokens([formula].pop):
            if token[0] == 1:  # A variable
                deps[token[1]] = None
    except IndexError:
        # It's ok
        pass
    return {
        'result_dep': ['calculate:%s' % key for key in deps.keys()]
        }

def task_get_dep():
    for cell in cells:
        name, formula = cell.split('=')
        yield {
            'name': formula,
            'actions': [(get_dep, (formula,))],
            }

And that's it. Let's see it in action. You can get your own copy here and try it out by installing doit, editing cells and then running it like this:

ralsina@perdido:~/dosheet$ doit -v2 calculate:A3
.  get_dep:4
{}
.  calculate:A3
A3 = 4
ralsina@perdido:~/dosheet$ doit -v2 calculate:A2
.  get_dep:2
{}
.  calculate:A2
A2 = 2
ralsina@perdido:~/dosheet$ doit -v2 calculate:A1
.  get_dep:A3+A2
{'A3': None, 'A2': None}
.  get_dep:4
{}
.  calculate:A3
A3 = 4
.  get_dep:2
{}
.  calculate:A2
A2 = 2
.  calculate:A1
A1 = 6

As you can see, it always does the minimum amount of effort to calculate the desired result. If you are so inclined, there are some things that could be improved, and I am leaving as exercise for the reader, for example:

  1. Use uptodate to avoid recalculating dependencies.
  2. Get rid of the global values and use doit's computed values instead.

Here is the full listing, enjoy!


Syndicated 2012-07-25 22:25:22 from Lateral Opinion

Apple uses skeuomorphism, but it's not because they are idiots.

Every day there is a new post decrying Apple's tasteless use of skeuomorphism (you know, making calculator programs look like calculators and note-taking apps look like notepads?).

I totally agree that skeuomorphic apps are ugly and stupid. I said that in 2-thousand-freaking-four. But just looking at the latest abomination (it seems to be a sound recorder that looks like a ree-to-reel, of all things) and sneering is worse, because that means you don't have any ideas of where design comes from, and I say this being a person with as much taste as a walrus.

Design comes from people. There is a grander design behind that specific design, which you could call a guideline, or a philosophy, or in some cases a zeitgeist. For 50 years, there has existed a consensus about cleanliness of design being a good thing. It started in some specific niches while others went in other directions (car fins!) and later each area of design has moved, like a pendulum, towards cleanliness or "specialness".

Once you go "clean", and everyone goes "clean" there is very little you can do to make your product distinctive, and a tension is created to make it less clean and more "special".

Google's entry page used to be absolutely clean. A place to enter text, and two buttons. Now it has a menu with 11+ items, 3 buttons, and an icon. Apple's OS9 was ascetic, and now OSX is a sea of bouncy colorful things shouting at you.

The skeuomorphism and other indications of overdesign, of complication, in apple's apps is not unintentional, it's an intentional attempt at making the applications special, appealing, and distinctive. It is ugly and awful, but it is so intentionally, because the very concepts of ugliness and awfulness are just a vague consensus among the users, and Apple surely felt confidence that users, accostumed to Apple's role as kings of taste, would change their taste to fit. And as far as I can see that is exactly what has happened.

Users are not the ones complaining about Apple's design style, other designers are complaining. That signals, to me, a disconnect between the taste of designers and the taste of users. And honestly, the taste of designers is only of vague academic interest to companies trying to sell product.

Apple's hardware stays minimalistic because they have successfully branded it. If you see a squarish slab of black glass with a button, you think iPad or iPhone depending on size, not "generic minimalistic touch device". On software, that did not work. There was nothing interesting or innovative, or distinctive in minimalistic design for applications.

So they started with colorful gumdrops, moved onto brushed metal, and then into fake stitched leather, because they are trying to find something that can be as successfully and powerfully branded as "silvery slim wedge with black keys" is now.

Designers apparently seem to believe there is certain specific "cleanliness" that is the hallmark of "good" design, and that ripped paper and other skeuomorphic affectations are signs of bad taste. That is silly and ahistoric. Cleanliness is just a fashion, reel-to-reel digital recorders are an attempt at creating a taste. It's ambitious, and respectable.

On the other hand, it is ugly as hell.


Syndicated 2012-07-22 19:29:04 from Lateral Opinion

Year Zero

It starts with these two aliens:

And a lawyer called Nick Carter, who is not this Nick Carter:

If I were to describe the plot, it would make me sound insane, which is a good thing. So, I will just let the book trailer do the work:

Have you ever read Douglas Adams and wished the plot started making some sense? Have you ever read Terry Pratchett and wished there was more than one excruciatingly stretched joke per book? [1]

Well, if you have, I recommend you give Year Zero a try. It's hilarious, it has a plot of sorts, and has at least three different jokes in it. A working knowledge of lame 80s (and 70s) music helps but is not horribly necessary.

So, I give this five stars [2] and recommend it to every one.

[1] And yes, I know that's practically the point of Terry Pratchett's style.
[2] It's the second 5-star book for me this year, after A Naked Singularity. I didn't even give those to The Mongoliad even though I am a hopeless Neal Stephenson fanboy.


Syndicated 2012-07-21 13:37:16 from Lateral Opinion

Tus Amigos

Sorry, spanish only.


http://www.pescadopodrido.com/imagenes/politica/principal/DICTADOR%20costa%20pobre.jpg

Miren la banda.

No tengo muchos amigos. Tengo tres o cuatro, ponéle. Seguro no más de 10. Tengo muchos conocidos, tengo mucha gente que me cae bien, habrá alguno que le caigo bien, habrá otros que me conocen. He tenido amigos que nunca ví, tengo amigos que nunca veo, tengo amigos que nunca voy a ver porque tuvieron la mala idea de morirse antes que los vea.

Tengo amigos que quiero mucho, tengo amigos que me cagan de risa, tengo amigos y tengo amigas, tengo alguna hermana postiza que la quiero como si fuera mi hígado, tengo mi esposa que es más amiga, tengo amigos que quisiera ver más.

Hay amigos que no me conocen, pero si alguien te regala un libro que te cambia la vida, o una canción que te levanta a la mañana, o un programa de radio que te hace olvidar todas las noches la bosta que fué el día, esos son amigos míos, aunque yo no sea amigo suyo.

Hay gente que no conozco que me ha agradecido alguna cosa que hice y supongo que yo seré amigo suyo aunque no sean amigos míos. A ellos les digo que son amigos míos también.

No tengo amigos de la infancia, no tengo amigos de la adolescencia, tengo algún amigo de mis veintipico, tengo más de mis treintas, todavía no tengo uno de los cuarentaypico. Tengo amigos en otros países, tengo amigos acá al lado. Tengo pocos pero son variados. Tengo pocos pero son los mejores.

Y cuando me muera, si me hacen la gauchada de no morirse antes ellos, ojalá tenga una corona que diga: Tus Amigos. Y se la destapen y se la tomen, los putos.


Syndicated 2012-07-20 22:49:29 from Lateral Opinion

Y U So Serious?

http://farm8.staticflickr.com/7047/6823423920_94a9682eea.jpg

Hello? I am the guy that posts about twin bananas!

Since I decided to stop being a troll (I am trying!) I noticed that people take what I write waaaaay too seriously. This post is a gentle reminder that I have posted more about silly stuff than about serious stuff. MUCH more.

So, if you ever find yourself thinking "Hey, Roberto seems to be making an interesting point", first think about the twin bananas. If what I wrote still looks interesting, proceed.


Syndicated 2012-07-16 22:47:35 from Lateral Opinion

Your Editor is Not the Bottleneck

This may cause some palpitations in some friends of mine who laugh at me for using kwrite, but it really is not. Any time you spend configuring, choosing, adjusting, tweaking, changing, improving, patching or getting used to your editor is time invested, for which you need to show a benefit, or else it's time wasted.

Let's look at SLOC, which while discredited as a measure of programmer's productivity, surely does work as a measure of how much a programmer types, right?

Well, estimates of total code production across the lifetime of a product vary (just take the SLOC of the product, divide by men/days spent), but they are usually something between 10 and 100 SLOC per programmer per day. Let's be generous and say 200.

So, 200 lines in eight hours. That's roughly one line every two minutes, and the average line of code is about 45 characters. Since I assume you are a competent typist (if you are not, shame on you!), it takes less than 20 seconds to type that.

So, typing, which is what you often tweak in your editor, takes less than 15% of your time. And how much faster can it get? Can you get a line written in 10 seconds? Then you just saved 8% of your day. And really, does your editor isave you half the typing time?

How much time do you lose having your eyes wonder over the sidebars, buttons, toolbars, etc?

So while yes, typing faster and more efficiently is an optimization, it may also be premature, in that, what the hell are we doing the other 80% of the time? Isn't there something we can do to make that huge chunck of time more efficient instead of the smaller chunk?

Well, I think we spent most of that time doing three things:

  1. Reading code
  2. Thinking about what code to write
  3. Fixing what we wrote in that other 20%

The first is easy: we need better code readers not editors. It's a pity that the main interface we get for looking at code is an editor, with its constant lure towards just changing stuff. I think there is a lost opportunity there somewhere, for an app where you can look at the code in original or interesting ways, so that you understand the code better.

The second is harder, because it's personal. I walk. If you see me walking while my editor is open, I am thinking. After I think, I write. Your mileage may vary.

The third is by far the hardest of the three. For example, autocomplete helps there, because you won't mistype things, which is interesting, but more powerful approaches exist, like constant running of tests suites while you edit. Every time you leave a line, trigger the affected parts of the suite.

That's much harder than it sounds, since it means your tools need to correlate your test suite to your code very tightly, so that you will see you are breaking stuff the second you break it, not minutes later.

Also, it should enable you to jump to the test with a keystroke, so that you can fix those tests if you are changing behaviour in your code. And of course it will mean you need tests ;-)

Which brings me to a pet peeve of mine, that editors still treat the file as the unit of work, which makes no sense at all. You never want to edit a file, you want to edit a function, or a class, or a method, or a constant but never a file. Knowing this was the sheer genius of ancient Visual Basic, which was completely ignored by all the snobs looking down at it.

So, instead of tweaking your editor, get me a tool that does what I need please. I have been waiting for it since VB 1.0. And a sandwich.

warning

This post is 99% lies, but I want to hear the arguments against it. If I tell you now it doesn't count as a real lie, I have learned from financial press ;-)


Syndicated 2012-07-15 22:22:12 from Lateral Opinion

Quick Hack to Catalog your Books

If you have actual, paper books and want to catalog their info quickly, this bookdata.py script may be handy:

import sys
import time
import gdata.books.service
import json

def get_book_info(isbn):
    print "Looking for ISBN:", isbn
    google_books = gdata.books.service.BookService()
    result = google_books.search('ISBN %s '%isbn)
    data = [x.to_dict() for x in result.entry]
    if not data:
        print "No results"
        return
    title = data[0]['title']
    with open(title+'.json','w') as f:
        f.write(json.dumps(data))
    print "Guardada info de '%s' en '%s.json'" %(isbn, title])

if __name__ == "__main__":
    while True:
        isbn = sys.stdin.readline().strip()
        if isbn:
            get_book_info(isbn)
        time.sleep(1)

What does it do? It reads ISBN numbers from standard input and saves the book's info in a title.json file for later processing and formatting.

If you want to edit that information, you can just do it or you can try doing a little script using jsonwidget like this:

python -c 'import jsonwidget; jsonwidget.run_editor("abook.json", schemafile="gbooks.schema")'

Where abook.json is a file generated by the previous script and gbooks.schema is this file.

Oh, and if your books have barcodes, you can just do:

zbarcam --raw | python bookdata.py

Show your computer your books and let it do the rest :-)

PS: I would love if someone gathered all this and made a nice personal book cataloguing thing.


Syndicated 2012-07-13 12:22:00 from Lateral Opinion

586 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!