Index of categories

Non-technical posts.

My semi serious stand up comedy notes

Video

Disclaimers

“Someone has said that it requires less mental effort to condemn than to think.”

(Emma Goldman, on several things including mailing list flamewars)

Fascinating Aïda's "Dogging" song.

Look for "dogging etiquette" for more examples of code of conducts. Just don't take your computer for repair immediately afterwards™.

Introduction

Every daring attempt to make a great change in existing conditions, every lofty vision of new possibilities for the human race, has been labeled Utopian.

(Emma Goldman, on the Debian Social Contract)

I am going to talk about many topics that we all know have so much in common:

  • Anarchism
  • Poliamory
  • BDSM
  • and Free Software

They are all, after all:

  • People
  • Consensually
  • Doing Things
  • Together

BDSM

A person is no less a slave because they are allowed to choose a new master once in a term of years.

(Lysander Spooner about proprietary cloud service providers)

If you thought you've seen it all with recursive acronyms, here's a chain acronym: Bondage Discipline, Dominance Submission, Sado Masochism.

Why I think BDSM is interesting: not (just) because of whips, but for having a lot of awareness about power releationships. Why should one accept from a coworker a level of abuse that would be considered a hard limit when negotiating with a trusted dom?

The BDSM Free Software definition: "I refuse to be bound by software I cannot negotiate with".

YKINMKBYKIOK (Your Kink Is Not My Kink But Your Kink Is Okay) is a nice example of dealing with diversity, and it also definitely solves the emacs vs vi debate.

Comfort zones, safewords, traffic light flow control, safety.

"No means no", unless there has been a long discussion first, and a safeword is in place, in which case "Fuzzy purple unicorn" means "no"

"No means no", and if someone insists after a "no", it becomes harassment.

"No means no" is a precondition for being able to say "yes": http://pervocracy.blogspot.de/2011/03/no-and-no-and-no-and-yes.html

Aftercare! Aftercare! Release parties! High fives! Solidarity after flamewars or votes!

Poliamory

If love does not know how to give and take without restrictions, it is not love, but a transaction that never fails to lay stress on a plus and a minus.

(Emma Goldman, on volunteer projects)

Polyamory is the practice, desire, or acceptance of intimate relationships that are not exclusive with respect to other sexual or intimate relationships, with knowledge and consent of everyone involved.

Compersion, n: the feeling you get when someone else also takes good care of one of your packages.

We currently allow only one value in the Maintainer field: * takeover is traumatic, because values can only be replaced * if values could be added instead, and removed when they don't make sense anymore...

What is your definition of love? My current one is: my world is better with you in it.

Relationship anarchy is the practice of forming relationships which are not bound by rules aside from what the people involved mutually agree on. How do you call a relationship that is bound by rules that the people involved do not agree on?

From discussions after the talk

New Relationship Energy, the excitement when you start to maintain a new package, and the risk of been carried away by the excitement and neglecting all the other ones.

Consent

Anarchism, to me, means not only the denial of authority, not only a new economy, but a revision of the principles of morality. It means the development of the individual as well as the assertion of the individual. It means self-responsibility, and not leader worship.

(Voltairine de Cleyre about trusting lintian warnings)

You need to know what you are doing, and what situation you're putting yourself into.

You need to know that the person asking a question really is able to accept any answer, and take it seriously.

You need to feel that you have alternatives.

Be selfish when you ask, honest when you reply, and when others reply, take them seriously. If any of this doesn't stand, I find it hard to trust that we are in a consensual situation.

When is one supposed to learn about consent?

  • I see little consensuality in standard education.
  • I see little consensuality at work.

Consent explained with tea.

Practical advice

Anarchism has but one infallible, unchangeable motto, ‘Freedom.’ Freedom to discover any truth, freedom to develop, to live naturally and fully.

(Lucy Parsons about the DFSG)

Relationship advice and work advice have a lot in common:

Relationship advice from 99 ways to ruin an open source project

Online participation advice from How to Screw Up Your Relationship (and make everyone miserable while you’re at it)

Packaging advice from BDSM Basics: 20 Unsolicited Tips for New Dominants

Advice about joining a new community from Advice to a newbie submissive about dominants

♥ ♥ ♥

Dear Debian, and dear everyone contributing to it: my world is better with you in it.

I love you all :* <3

Posted Tue Aug 18 11:48:08 2015 Tags:

Expectations and needs

All people ever say is: "thank you" (a celebration of life) and "please" (an opportunity to make life more wonderful). (Marshall Rosenberg)

Sometimes, when I see the word "expectation" I try to read it as "need" and see how things change.

I noticed that this tends to reframe situations in a way that makes me feel more comfortable.

I noticed that I tend to instinctively perceive "expectations" as "do this or there will be consequences", and I tend to instinctively perceive "needs" as "do this if you want to see me happy".

I noticed that my motivation to care for someone's expectations tend to be something close to fear, and my motivation to care for someone's needs tends to be something close to love.

This might give me a bit more hints on The art of asking: I will not expect you to do something for me, I'll just allow myself to be loved, liked or helped by you, and I'll try to be open about what I need.

I smile realising that since a long time, on the professional side of my life, I learnt to lead interaction with my customers along the same lines: "let's talk about what you need, not about what you expect of me".

Posted Fri Aug 14 12:13:16 2015 Tags:

Random quote

Be selfish when you ask, honest when you reply, and when others reply, take them seriously.

(me, late at night)

Posted Sun Jul 19 18:53:03 2015 Tags:

Love thy neighbor as thyself

‘Love thy neighbor as thyself’, words which astoundingly occur already in the Old Testament.

One can love one’s neighbor less than one loves oneself; one is then the egoist, the racketeer, the capitalist, the bourgeois. and although one may accumulate money and power one does not of necessity have a joyful heart, and the best and most attractive pleasures of the soul are blocked.

Or one can love one’s neighbor more than oneself—then one is a poor devil, full of inferiority complexes, with a longing to love everything and still full of hate and torment towards oneself, living in a hell of which one lays the fire every day anew.

But the equilibrium of love, the capacity to love without being indebted to anyone, is the love of oneself which is not taken away from any other, this love of one’s neighbor which does no harm to the self.

(From Herman Hesse, "My Belief")

I always have a hard time finding this quote on the Internet. Let's fix that.

Posted Wed May 20 11:35:15 2015 Tags:

Free as in Facebook

Yesterday we were in an airport. We tried to connect to the airport "free" wifi. It had a captive portal that asked for a lot of personal information before one could maybe get on the internet, and we gave up. Bologna Airport, no matter what they do to pretend that they like you, it's always clear that they don't.

I looked at the captive portal screen and I said: «ah yes, "free" wifi. Free as in Facebook».

We figured that we had an expression that will want to be reused.

Posted Mon Mar 9 10:58:49 2015 Tags:

<3 Bremen

[[!img Error: Image::Magick is not installed]]

Greedy people exploit our cultural differences to justify fighting wars to seize wealth for themselves, when sharing and enjoying cultural diversity makes us far richer than if we possess material wealth!

From a recursive murales in Bremen Halmerweg.

Posted Sun Jan 11 22:20:11 2015 Tags:

Non importa che mi dai del voi

Dai, non importa che mi dai del voi

In che senso?

Eh, mi dici sempre "voi informatici", "voi tecnici", "voi..."

Posted Fri Dec 19 15:55:20 2014 Tags:

On relationships

Good relationships are like a good video game

with an easy, intuitive interface

and lots of interesting content.

(Lynoure)

Posted Wed Aug 6 16:47:40 2014 Tags:

On love and sexual desire

Soundtrack: Skullcrusher Mountain (with lyrics)

After seeing a review of it, I just watched again the first episode of Lupin III. with an eye on how sex and love are represented. To my eyes, they seem to be shown as mutually exclusive: the evil boss sexual appetites have Fujiko tied up and (childishly) "raped". Lupin's love of Fujiko is shown as self-sacrifice, with him ending up in Zenigata's cuffs, with him enduring her betrayal. In the end, Lupin's sexual desire for Fujiko seems to turn her again into a disadvantaged position, as the instrument of "rape" of the evil boss comes back into play.

In all the literature that I remember as I grew up, there has been love and there has been sexual desire. Love was wishing for the other person to be well, sexual desire was wishing for oneself to be well.

For some reason, in most of the literature there seemed to be an implicit rule saying that two people cannot both be well at the same time. Love meant being soulless and devoting oneself to the other person entirely, and suffering from it. Sexual desire meant reducing the other person as an object of one's own pleasure, and (usually she) would suffer from it.

Sometimes two people loved each other and wished for both to be well at the same time, and were usually torn away by circumstances, or had to suffer and sacrifice a lot so that they could be together, or one of them would die, for extra drama. What being together meant, was usually not covered in the story, and tended to happen during that "happily ever after" that usually starts where the book or film ends.

Yet, I find that sex is a wonderful way for two people to be both happy at the same time, where I can desire my happiness and the other person's happiness, and where each feeling, each desire, each move contributes to both. In pleasing myself I please the other; in pleasing the other I please myself.

Is there a romantic story where the lovers do not just feel love, but also they long for, they desire each other? Where that desire is shown not by hitting the partner in the head with a club and dragging them to wake up tied up in a secret lair, but by inviting their partner to come closer, kissing them, holding them tight to their body, caressing them, discovering what gives them pleasure, opening up for them to play, each person riding their own, the other's, and their shared desire?

I cannot think of one. It sounds like I'll have to write one.

With my own life.

Posted Tue Jul 22 17:40:36 2014 Tags:

Abuse

I've recently spent a lot of effort trying to find, recover, reconnect, embrace, strengthen and grow my inner child, my actual identity, what I'm comfortable being. Now I figure that I feel abused when I perceive an assault against my identity.

I'm ok having had to study a shallow moralistic piece of literature at school. Having been expected to like it and embrace it, that feels like abuse.

I'm ok being told I made a mistake. Being humiliated for it, feels like abuse.

I'm ok being suggested how to avoid making a mistake. But being expected to promptly follow the advice and change my life accordingly, that feels like abuse.

Someone offers help in cleaning my house? Fine. Someone barges in, takes over my personal space and reshapes it as they see fit? That feels like abuse.

If I'm sad, a hug's great. If the hug comes with a surprise grope at my bottom, that feels like abuse. I would not be bothered about the sexual assault, but about the denial of my current state of mind. The denial of feelings. Forget who you are, how you feel, and just be my sexual object. When it begins to deny my identity, then it starts feeling like abuse.

Being taught that "when you love a person, you must..." feels like abuse.

Being expected to have sex and like it at another person's whim, regardless of my real feelings, feels like abuse.

Being expected to like to have sex, or not like to have sex, regardless of my real feelings, feels like abuse.

The concept of "marital duty" feels like abuse. Two people who are expected to demand and provide sex, just because they are married, regardless of what they actually feel or need.

The concept of "training your boyfriend" sounds to me like nonconsensual manipulation. Like Abuse.

A lot of dating advice? Abuse. Abuse. Abuse.

A relationship based on me faking my identity, in order to keep another person close to me who wouldn't be otherwise, sounds to me like a relationship based on mutual abuse.

Why do we even have the concept of love potions in our culture, in our fairy tales?

"For your own good", abuse. Luckily, there are alternatives.

Being called "nice boobies" when you want to be called "Elizabeth", feels to me like abuse.

Being called "geek" when you want to be called "Enrico", feels to me like abuse.

Being called a stereotype when I want to be recognised as an individual, feels like abuse. When I grow up in an environment where that is the accepted way of addressing people, and so I learn to do the same, then I feel abused and I'm taught to abuse.

I think I had some pretty abusive role models when I grew up.

Being asked to do something I don't want to? Fine. Telling me off because I do not like it? Abuse.

Despising me because I like something another person doesn't? Abuse.

Despising me because I don't like something another person likes? Abuse.

As a kid I quickly had to learn to figure out what a person liked or disliked, and pretend accordingly. To this day, I still have a problem answering the simple question "what would you like to do today?"

It feels like abuse when my identity is denied. When I cannot make mistakes. When I cannot be vulnerable. When I have to be happy. When I have to be sad. When I have to care. When I must not care. When it doesn't matter how I feel, who I am, but I just have to feel something, like something, be something.

For my own good. Because someone else knows better. Because "that's the thing you do". Because.

When I was a kid, I felt very uncomfortable when going to a carnival or to a theme park, because I felt an expectation to enjoy it, regardles of what I was really feeling. An effort was made to make me happy so I had to. It was a place where I was not free to have my own mood. Abuse.

The doctor would touch, knock, hit, tell me to do this or that, but would never ask me how I was feeling. He would tell me how I was feeling, and he must have been right. Abuse.

There was lots of abuse against my identity in my growing up. I had to learn to blend in to protect myself. I had to learn to please. I had to pretend I liked it all. I got good at pretending.

In order to be accepted as a person I needed to pretend to be someone else. And the person that ended up being accepted was not me.

In "A Wizard from Earthsea", Ged turns into a falcon to run away, but stays a falcon for too long, and forgets how to be a person again. The wizard Ogion turns him back by recognising him, accepting him, and speaking only one word: Ged's name.

I feel abused when I'm taken away from my identity, my feelings, my needs. I could even do that to myself, out of frustration, out of despair, out of habit.

I have started to recognise the moments when I'm not feeling abused, the people who accept me for what I am, there and then, who allow me to exist without judging me. I have started to accept all other moments as likely abuse attempts, and emotionally deal with them accordingly.

I have started to become conscious of when I'm abusing myself (this has been an interesting read), and stop, and ask myself why.

Posted Sat Jun 21 14:38:12 2014 Tags:

Fear of losing

If I am afraid of breaking my laptop, then I may leave it at home, and it will be as if I didn't have a laptop.

If I am afraid of losing faith, then I may closely follow the dictates of the church. I will be keeping the church's faith, but not mine.

If I am afraid of losing my children, they may have to run away from me to be free to grow into adults.

If I am afraid of losing my inner child, then I might not expose it to the world, and so my inner child will never live. I will just be a box, a mask of what the world expects from me, that shelters and cages the Me that would like to live.

If I am afraid of losing you, then I may get obsessed with preserving the beautiful image I have of you. I may stop seeing, experiencing you as you live, think, grow. I may become afraid of your depth, of your being different each day, of your being alive. I may end up with cherishing a perfect image of you in my head, while you will have become a stranger to me.

I am really asking when I can accept answers.

I am really living when I can accept myself.

I am really loving when I can accept you.

Posted Mon Jun 16 09:21:52 2014 Tags:

Perfection

We like perfection.

Perfection is the ultimate achievement, there is nothing beyond.

Perfection is fully understood. It is not going to change, it is fact, we can rely upon it.

Perfection is final. Perfection is death.

Ideas can be perfect, and perfect ideas are easy to understand.

Perfect ideas are final and unchangeable. Perfect ideas are hard to correct, hard to refute.

Perfect ideas spread easily. They are helpful. They shed light on a little corner of our world, give it shape. They bring stability. They can be relied upon. Perfect ideas make good memes.

Perfect ideas are shared standards through which we act, interact, coordinate, cooperate. They don't change, so they are a solid base for habits, that make a bit of our life a little easier.

That we should not kill, is a perfect idea. So is racism. So are the ten commandments, so, for many, is love.

Thanks Lynoure for saying the right thing at the right time.

Posted Wed Jun 4 22:53:37 2014 Tags:

When I said "I love you"

All people ever say is: thank you (a celebration of life) and please (an opportunity to make life more wonderful). Marshall Rosenberg

I have said "I love you" many times in my life, and many times I have failed to say it, because, for me, it is not an easy thing to say.

It is not easy when I have no idea what the other person will make of it: will they be frightened? Will they feel awkward around me afterwards? Will they disappear from my life?

But do I know what I myself mean when I say it?

I have said "I love you" because I thought you somehow expected it of me. "please, consider me worth of you".

I have said "I love you" to beg for affection. "please, love me back".

I have said "I love you" because I was grateful to you for existing in my life. "thank you".

I now understand why it has not been easy for me to say "I love you" when I was feeling, or imagining, that I had to say it.

I now understand why I have sometimes made myself awkward, as I was begging.

I now understand why, when I said "I love you" out of gratitude, when I said it to celebrate that you exist in my life, that's when I felt no trouble, no fear, and when I felt that my words really were fitting with what I was feeling and what I was wanting to say.

Posted Mon Jun 2 10:18:56 2014 Tags:

Habits

Beware of habits. I've seen them turn into expectations over time, without any kind of negotiation.

Posted Thu Feb 13 01:22:59 2014 Tags:

Original sin

I feel that I was somewhat born innocent, an animal with sound, primal instincts. But if I remained that way, I wouldn't be able to function in a complex society, so I got education. Education taught me what is expected from me in order to be accepted by my peers[1].

Education taught me more than that: it also taught me to enjoy what a complex society can give me: art, science, history, philosophy, adding depth of meaning and correlations to my perceptions and memories.

Education wasn't perfect, though. Some of my educators obsessed about some of the expectations, and gave me rules to follow that aren't really needed to interact with a society. Sit down for hours in silence without complaining. Don't talk back to figures of authority, even when they are abusing me. Don't ever feel that my efforts in a task have been enough, because there is always something more that I could have done. Do what people expect me to do, regardless of what I wish to do. Do what I need to do, not what I want to do.

So I grew up with a set of arbitrary expectations that weren't needed to function in a society, and weren't in any way meeting any of my needs, yet I still felt them as a part of me, putting every effort into meeting them that I would put in making myself happy. I like to call this set of learned arbitrary, unneeded expectations "neurosis".

I like this as an interpretation of the "original sin" myth: in order to go from an innocent animal to a member of a complex society, I acquired a set of neuroses that make me behave in a meaningless way. Or, rephrased going along with the myth, that rob me of my innocence.

In some environments like BDSM, many have a name for an unnegotiated practice forced on a person: they call it "abuse". It made sense to accept that I have been abused many times while being educated, because my educators also had their own baggage of parasite expectations, of neuroses. And since I don't currently know how I can ever be sure that I freed myself from all my neuroses, I feel like I should accept that it is possible that I do and will abuse others; by accepting it as a possibility, I hope at least to be able to realise as soon as possible that I am doing it, and try to stop.

I have now realised that my life is far simpler and more rewarding when expectations are negotiated between all the parties involved. I have recently spent a substantial amount of my energy in recognising and renegotiating many of the expectations and the neuroses that I had learnt while growing up, and, who knows, perhaps this effort will continue throughout my life.

So there you go, an agnostic atheist freeing himself of his original sin, and regaining his paradise lost one step at a time, alive, on earth.

And enjoying every moment of it.

[1] I suspect that is why people educated in a high class society tend to be accepted more easily by a high class society: they conform to the right set of expectations. But I digress.

Posted Sat Feb 8 17:48:27 2014 Tags:

On political correctness

I am reading "Four ways to forgiveness" by Ursula Le Guin. This is how the book begins:

“On the planet 0 there has not been a war for five thousand years,” she read, “and on Gethen there has never been a war.” She stopped reading, to rest her eyes and because she was trying to train herself to read slowly, not gobble words down in chunks the way Tikuli gulped his food. “There has never been a war”: in her mind the words stood clear and bright, surrounded by and sinking into an infinite, dark, soft incredulity.

What would that world be, a world without war? It would be the real world Peace was the true life, the life of working and learning and bringing up children to work and learn. War, which devoured work, learning, and children, was the denial of reality. But my people, she thought, know only how to deny. Born in the dark shadow of power misused, we set peace outside our world, a guiding and unattainable light. All we know to do is fight. Any peace one of us can make in our life is only a denial that the war is going on, a shadow of the shadow, a doubled unbelief.

That made me realise that several times I perceived political correctness as "only a denial that the war is going on".

Last night I watched this video, which I felt was very relevant to this.

Indeed, I have more respect for someone who listens to me and makes a good effort to understand what I said, then rudely disagrees, than for someone who is very politely ignoring everything I am trying to say.

This is how I feel like this experience can be distilled into an actionable item:

Replying to an email is probably going to be useless, unless I am willing to make an effort to understand what the other person is trying to say, from their own point of view.

Posted Wed Jan 29 10:44:14 2014 Tags:

Liberation vs expectations

I feel like I found a key struggle: liberation vs expectations.

Many ideas liberate me, like poliamory, atheism, anarchism, nonviolent communication, sexual liberation, discordianism, free software, nonjudgemental environments, E-prime, sillyness, love, pataphysics, dada, constructivism, rolling naked in the mud, fantasy, bdsm exploration, pansexuality, this very idea that i'm trying to describe, crying, laughing, mindfulness, what have you.

Sometimes however they become an end rather than a mean, they give me expectations and judgements, and take some other freedom away.

I feel like I found where to draw a line: it's the point inbetween freeing myself of my limits and making myself some new ones.

It's one of those epiphany moments. Weeeeeee!

Posted Sun Jan 12 12:17:39 2014 Tags:

Spelling a chilometri zero

Lo spelling internazionale è troppo globalizzato, e volete recuperare un attimo la dimensione del posto dove siete nati e cresciuti?

Da oggi c'è questo script che fa per voi: gli dite dove abitate, e lui vi crea lo spelling a chilometri zero.

$ git clone git@gitorious.org:trespolo/osmspell.git
$ cd osmspell
$ ./osmspell "San Giorgio di Piano"
1: San Giorgio di Piano, BO, EMR, Italia
2: San Giorgio di Piano, Via Codronchi, San Giorgio di Piano, BO, EMR, Italia
3: San Giorgio Di Piano, Via Libertà, San Giorgio di Piano, BO, EMR, Italia
Choose one: 1
Center: 44.6465332, 11.3790398
A Argelato, Altedo
B Bentivoglio, Bologna, Boschi
C Cinquanta, Castagnolo Minore, Castel Maggiore, Cento
D Dosso
E Eremo di Tizzano
F Funo di Argelato, Finale Emilia, Ferrara, Fiesso
G Gherghenzano, Galliera, Gesso
I Il Cucco, Irnerio, Idice
L Località Fortuna, Lovoleto, Lippo
M Malacappa, Massumatico, Minerbio, Marano
N Navile
O Osteriola, Ozzano dell'Emilia, Oca
P Piombino, Padulle, Poggio Renatico, Piave
Q Quarto Inferiore, Quattrina
R Rubizzano, Renazzo, Riale
S San Giorgio di Piano, Saletto
T Torre Verde, Tintoria, Tombe
U Uccellino
V Venezzano Mascarino, Vigarano Mainarda, Veduro
X XII Morelli
Z Zenerigolo, Zola Predosa

I dati vengono da OSM, e lo script è un ottimo esempio di come usarne la API di geolocazione (veloci) e la API di query geografica (lenta).

Posted Sat Jan 4 00:38:16 2014 Tags:

Poesia: "Lavatrice"

Pensavo fosse pail,

invece ora è feltro.

Posted Tue Dec 3 22:32:23 2013 Tags:

Shops

Christmas songs should only ever be played on Christmas day.

In church.

At midnight.

Unless I happen to be there.

Posted Mon Dec 2 14:07:58 2013 Tags:

Explanation of umarell

Umarell /uma'rɛl/ (oo-mah-rell), n; pl. Umarells. People in a community who offer all sorts of comments to those who are trying to get some work done, but who are not doing any work themselves.

Etymology and further details

Umarell is a word that entered Italian slang in Bologna and is spreading to nearby towns, occasionally even across Italy. It comes from the Bolognese for "cute/odd little man".

"Umarells" are those people, usually retired men, who spend time watching construction works, often holding their hands behind their back, occasionally commenting on what is going on, sometimes trying to tell the workers what to do.

It's easy to find examples on the internet; the word was popularised by a blog collecting photos, which has even been published into a book.

With some Italian Debian friends, we realised that umarell is the perfect word to describe those people in a community, who offer all sorts of comments to those who are trying to get some work done, but who are not doing any work themselves.

I think that it is a word that fits perfectly, and since I'm likely going to use it blissfully anywhere, here is a page that temporarily explains what it means until the Oxford English Dictionary picks it up.

Posted Fri Sep 20 13:27:07 2013 Tags:

Random notes from that other lightning talk session

If you can, have dinner with your upstreams at least once a year.

Posted Sat Aug 31 12:35:09 2013 Tags:

On codes of conduct

A criticism of the status quo, with a simple proposal: video and lyrics.

With compassion unyielding to grudge, mother, I learnt how to love.

Posted Sat Aug 24 18:15:31 2013 Tags:

Random notes from that other lightning talk session

YKINMKBYKIOK: "Your Kink Is Not My Kink But Your Kink Is Ok"

As far as I'm concerned, this puts the vim vs emacs quarrel to rest, for good.

Posted Fri Aug 23 18:11:30 2013 Tags:

Random notes from that other lightning talk session

The BDSM Free Software Definition:

I refuse to be bound by software I cannot trust and negotiate with.

Posted Wed Aug 21 08:16:15 2013 Tags:

Random notes from DebConf

Compersion, n: the feeling you get when someone else also takes good care of one of your packages.

Posted Tue Aug 20 17:44:52 2013 Tags:

Components in a system

But what we are discovering is that if we see ourselves as components in a system,

that it is very difficult to change the world.

It is a very good way of organising things, even rebellions,

but it offers no ideas about what comes next.

(from All Watched Over By Machines of Loving Grace)

Posted Wed Mar 13 01:30:34 2013 Tags: tags/quotes

Che coss'è l'amor

Di recente mi sono spesso trovato a chiedermi "che cos'è l'amore", e ogni volta inizia a suonarmi in testa: "♪...chiedilo al vento / che sferza il suo lamento sulla ghiaia del viale del tramonto... ♫"

Socialmente l'amore mi è sempre stato venduto come una cosa indescrivibile ma allo stesso tempo estremamente codificata. L'amore è quella cosa che ti fa sentire così, e poi se non fai così non è vero amore, e l'altra persona la devi trattare così, e devi essere spontaneo mapperò... tv e musica con i quali volente o nolente sono cresciuto hanno spesso propagandato modelli che raramente ho condiviso, e che riassumerei con questo.

Mi è sempre stato difficile capire quando poter dire "ti amo". Il problema non è tanto nell'interpretare i miei sentimenti, quanto nel capire quali significati sto tirando addosso a entrambi nel momento in cui lo faccio. Per questo motivo, finché non sono sicuro di come l'espressione "ti amo" significhi per entrambi, tendo a ragionare usando invece concetti definiti in maniera un po' più chiara (per me), tipo: desiderio, fiducia, intimità, odori, intesa, ridere, contatto fisico, curiosità...

È un peccato: ogni tanto provo quel sentimento di piacevole resa verso l'altra persona che mi porta a voler dire "ti amo!", e finisco per non farlo.

Detto questo, da quando ho visto "Una de zombis", alla domanda "ma sei innamorato?" non può non venirmi in mente questo.

Posted Wed Feb 20 02:02:30 2013 Tags:

On praising people, and on success

This morning I was pointing out to friends how excellent is mako's post on Aaron Swartz, and I thought it'd be nice if we didn't have to wait for people to die before telling the world how awesome and inspirational they are.

Then Russ posted an article about work, success and motivation and I went to tell my friends how awesome and inspirational he is.

I, too, see myself as somehow successful, and I, too, don't identify in the usual stereotype of success. I don't want to stop being a craftsman to become a manager, I don't get a high from having power over other people, I don't define my value in terms of my profits.

At a glance, people don't see me as successful, until they get to know me better. They they realise that I'm not at all unhappy about my life.

I have a job that I like, I write Free Software and it gets used and appreciated, my colleagues are friends, who respect me and my opinion, and I respect them and theirs.

I can work from home. In fact, I can work from everywhere as long as I have my laptop with me. I can sustain a long distance relationship because I can work from the house of my partner when I'm visiting. Two days ago I worked from the bar of a farm on top of a hill, because I was on the road, it was close by, and what the hell, it's a wonderful place to be.

To me success means that I can care about the quality of my life, that I have the luxury of caring about little things that make my day, of trying to make good ideas sustainable, of working a bit more when I'm on fire, and of working a bit less when there's something wonderful in the world to see, or someone interesting in the world to meet.

Russ, the way I read your article, you are questioning what "success" means, and you are spot on. People should be able to define "success" as whatever works for them and pursue it freely. Only then success becomes something that is worth praising when it is achieved. Only then it becomes inspirational.

I like how you managed to put into words something that has been for a long time in some corner of my mind and I hadn't yet managed or bothered to bring into the spotlight.

You have the insight and the confidence of seeing something in an insightful but non-mainstream way, and say "you know what? That actually makes sense."

Sometimes I read your post, nod a lot and realise how important something actually is, how that is actually such an important part of myself. And now that you took it out for me to see it, I can appreciate how valuable it is, and make sure I don't accidentally lose it.

Thanks! That's another one I owe you. It's just the kind of thing I shouldn't wait before letting you know.

Posted Fri Jan 25 12:45:49 2013 Tags:

Yet another Ubuntu anecdote

Some posts on planet made me remember of a little Canonical-related story of mine.

Many years ago I shortly contracted for Canonical. It was interesting and fun.

At the time I didn't have any experience of being temporarily hired by a foreign company, so I rang my labour union to get an appointment, to make sure with them that everything was allright.

The phone call went more or less like this:

Me:

Hello. I have received this contract for temporary employment by a foreign company and I wondered if I could book an appointment to come show it to you to see if it's all ok.

Their answer rather cut me short:

Hi. Be careful! People get temporary employment from obscure companies with the headquarters, like, in the Isle of Man, they do the job, the company disappears and they never get paid. There's bad stuff out there!

I looked at the contract, the heading said something like "Canonical ltd, Douglas, Isle of Man".

I was certain that the union people would have never understood what was going on. I politely thanked them for their time and hung up. However, to this day I still regret that I didn't insist:

Uh, yes, the company is indeed in the Isle of Man. But what if I told you that it's owned by an astronaut?

I just signed the contract and had a good time.

Posted Sat Jan 15 10:35:36 2011 Tags:

La paura e la voglia

Results 1 - 10 of about 5,470 for "la paura e la voglia di essere nudi". (0.34 seconds) 

Results 1 - 10 of about 26,500 for "la paura e la voglia di essere soli". (0.10 seconds) 

Poi non c'è da stupirsi se siamo diventati come siamo diventati.

Posted Wed May 5 13:36:24 2010 Tags:

Se è vero questo...

Se è vero questo...

...allora è vero anche questo!

Posted Thu Apr 22 09:26:08 2010 Tags:

Global trends

For some time I have been trying to pinpoint what it is that is brewing in Italy and risks spreading elsewhere, like it happened in the past.

I don't need to be decent to stay in power

While following a train of thought during a political/philosophical lecture I figured that a current growing trend is to have public figures that are more and more indecent.

In Italy it is very hard to find a public figure you can look up to. It is hard to name a politician that is not involved in some shady exchange of favours or some abues of their powers, and we got used to seeing people in power implicated in major corruption scandals, perverted prostitution affairs, or dealings with international criminal organisations.

They do not normally end up in jail, and in fact they keep being very firmly in power, because they manage to stretch or change the laws to get away, or at least to delay trials in order to trigger some statute of limitations.

Is there a pattern here that, although maybe not as clearly defined as in Italy, can be found more or less globally?

Yesterday I thought that this could be such a pattern:

I don't need to be decent to stay in power

If I think of it like that, then it is most definitely not just an Italian phenomenon. If you tell "one doesn't need to be decent to stay in power" to a British, or to a French, I would not expect them to see anything strange with it. We all find it depressing, but we are all used to it.

It is a pattern with repercussions, though: once that becomes normal in a society, it means that people who get to be in power are free to abuse their power much as they want, as long as they are careful enough not to end up in jail. Because, well, nowadays one doesn't need to be decent to stay in power.

I don't need to follow the law to stay in power

That first pattern is already quite well accepted in Italy. So much well accepted, that I think we are starting to see what comes next.

At the end of March we are going to have elections for some regional governors. Funnily enough, in Lazio, the very important region around Rome, the centre-right coalition failed to submit the paperwork on time, and is out of the elections.

It is not just red tape: at some point someone will have to print out the ballots and dispatch them to the voting booths, so one expects to have the coalition logos and the names of the candidates submitted in time, together with signatures supporting the candidates and whatever else the election process needs.

Well, they missed the deadline, they got there after closing time and the building was, well, closed.

It was a fantastic opportunity for a laugh. Memes blossomed on the Italian intarwebs and we now have 2 or 3 new expressions to mean "stupid".

However, now it's hard to tell what is going to happen. On one hand, you can't exclude one of the two major coalitions because of some bureaucratic detail like an office closing time. But on the other hand, several minor coalitions have been excluded in all sorts of past elections because of similar things, and it really would not be fair to start making exceptions now.

But Lombardia, the region around Milan and Emilia Romagna, the one around Bologna, both very, very important, are having similar kinds of problems.

In both regions the previous governors are running again, for the 3rd time in a row, and most likely they legally can't do it, and if elected one can sue and force them to resign, because they have been in power long enough. Lots of paper is being shuffled at the moment to figure if they can get away with it or not.

Oh, and the lawyers of the candidate for the Milan region also managed to get to the tribunal after closing time, but apparently there was still someone inside and they managed to shout loud enough, or somesuch.

Anyway, the situation is getting hot. The Lazio coalition that has been excluded because of their incompetence is now hard at work pushing their potential voters to mount a fracas. Chances are that eventually they'll get away with it, and manage to take part to the election. If that happens, they will likely get close to winning it.

So this seems to be a new pattern that is emerging:

I don't need to follow the law to stay in power

Which, again, is a pattern with quite some repercussions. It is something much more radical than just an issue with morality: it means feudalism, it means we are culturally ready to accept dictatorship.

So, please do me a favour: do not think for a moment that Italy is just a funny place with lemons and tomatoes, and watch out for these patterns emerging around you.

Posted Fri Mar 5 16:52:31 2010 Tags:

Feedback democratico

Le elezioni sono passate, la frustrazione rimane.

Per la comodità di chi volesse dare un democratico feedback alle deludenti forze politiche in gioco, dallo spiegare pacatamente le proprie ragioni per l'aver votato un altro, al mandarli cortesemente a scoreggiare nella farina, ecco un po' di email:

Non dimenticate di mettere bene in chiaro che la mail di insulti che avete mandato non è da intendere come una richiesta di essere iscritti alle loro newsletter.

Posted Tue Jun 9 10:45:05 2009 Tags:

Igiene pubblica

Stamattina:

  • Andare in via Gramsci 12
  • Andare alla porta 10 piano terra
  • Prendere il numero bianco con bordo blu
  • Aspettare (due ore)
  • Fare vaccino
  • Andare alla porta 22 piano terra
  • Pagare
  • Tornare alla porta 10 piano terra
  • Consegnare la ricevuta
  • Ritirare il certificato

Mi sono sentito come la tartaruga del logo.

Posted Sat Jun 6 00:57:39 2009 Tags:

Edifici

Da una canzone in amarico:

"Il tuo amore è diventato vecchio

come gli edifici costruiti dagli italiani"

Posted Sat Jun 6 00:57:39 2009 Tags:

Altro cazzeggio in letteratura

Dopo il mio talk sul cazzeggio e la versione inglese, il buon godog mi segnala un'altra serie di link di letteratura "futile":

Quoto in toto la facezia LXI:

DI GUGLIELMO CHE AVEVA UN AFFARE ABBONDANTE

Nella città di Terranova eravi un uomo che aveva nome Guglielmo, che facea il falegname ed era assai ben provvisto dalla natura. E la moglie fortunata narrò la cosa alle vicine, e quando questa morì, condusse egli in moglie una giovinetta ingenua, che avea nome Antonia, e che quando fu sposa seppe dai vicini che arma potente possedesse il marito. Nella prima notte che ella fu col marito tremava assai, e voleva sfuggirlo né voleva lasciar fare. E l'uomo capì di che cosa avesse timore la ragazza, e per consolarla le disse che ciò che ella aveva udito dire era vero, ma che egli ne aveva due, uno più grande e uno più piccolo: «E di questo», soggiunse, «per non farti male, mi servirò questa notte; e vedrai che ti farà bene; poi se ti piacerà proveremo col più grande». La ragazza acconsentì e cedette senza pianto e senza dolore all'uomo. E dopo un mese, fattasi più franca e più audace, una notte, mentre accarezzava suo marito: «Amico mio», gli disse, «se ora ti volessi servire di quell'altro ch'è più grande? « E l'uomo, che ne avea quasi quanto un asino, rise dell'appetito della donna; e da lui una volta udii narrare, in compagnia, questa storia.

Posted Sat Jun 6 00:57:39 2009 Tags:

Housing agent in the UK

Yesterday afternoon:

Me: "Where is the gas central heating?"

Agent: "Over there, behind the chimney"

Me: "I see. Beyond that wall is another apartment: where do the fumes go?"

Agent: "Up the chimney"

Me: "Good. And where does it get oxygen from?"

Agent: "It does not need any oxygen, it only needs gas"

Me: "The gas central heater does not have any oxygen or air??"

Agent: "No, it only needs gas"

Me: "I think the laws of physics would have problems with that"

Agent: "You'd have to ask that to British Gas"

Posted Sat Jun 6 00:57:39 2009 Tags:

Etiopia

È interessante, bello e triste allo stesso tempo trovarsi a ridefinire il significato di "Abissinia". E maledire che per i primi 30 anni della tua vita, quella parola l'hai sentita soltanto quando uno stronzo cantava "Faccetta nera".

Posted Sat Jun 6 00:57:39 2009 Tags:
Posted Sat Jun 6 00:57:39 2009 Tags:

Italian weather agencies

Most Italian regions have agencies providing good regional weather forecast. However, I could not find a useful national index of all their weather forecast pages. So I made one, tweaking an image map found on wikipedia.

Abruzzo Basilicata Calabria Campania Emilia-Romagna Friuli-Venezia Giulia Lazio Liguria Lombardia Marche Molise Piemonte Puglia Sardegna Sicilia Toscana Trentino-Alto Adige Umbria Valle d'Aosta Veneto

Italia suddivisa per regioni

I only filled in those regions that I was checking to organise a specific trip. With time, if I'll keep using this map I'll add more regions. Of course, if you now of a weather forecast page of a regional, public funded agency that is missing here, send me an e-mail.

Posted Sat Jun 6 00:57:39 2009 Tags:

Off by one

A few days ago I was around a table having a hot pot and having a small chat with other friends around the table:

X: How old are you?  I was born in 1976
Me: I was born in 1976 as well.  Cool year!

a few minutes pass, I realise something:

Me: So, since you were born in 1976, how old are you?
X: I'm 30
Me: I thought so.  I'm 29 :)

It turns out that in some countries, at the moment you're born you're 1 year old instead of 0: it's just a matter of convention.

And then today it's the first day of 2006. It's also the 95th year since the founding of Republic of China, which is another way of counting years here. The good thing is that if you see that a bottle of milk expires in '95, it means it could still be good.

So, when was Republic of China founded? Of course in 1912, but since when it was founded it was 1 year old, we're now in 95 instead of 94.

Things would be even more interesting if the Lunar Calendar used numbers for the years, but they instead use a "sexagesimal stem-branch cycle" so I cannot say that, according to the lunar calendar, we're still in 2005 until February 29 However, people do have two different birthdays.

And why am I in Taiwan but they count since the founding of Republic of China? I'll tell you if you buy me a glass of wine :)

Anyway, Today is Sweetmorn, the 1st day of Chaos in the YOLD 3172

Posted Sat Jun 6 00:57:39 2009 Tags:

My company

I had an interesting conversation in which I was explaining my current work situation. It might be fun to share:

< mornfall> you are working on a timed contract?
< enrico> I'm probably worse than a timed contract: I had to setup a company
< enrico> The government is restricting them so badly that they couldn't hire
          me even temporarily, and they had to buy software from me
< enrico> so I had to become a company
< enrico> I AM THE COMPANY
< mornfall> oh duh
< enrico> I'm my employer
< enrico> and my employee
< enrico> in all this, the government proudly shows statistics of lots of new
          companies being created in Italy as a sign that our economy is so
          good
< mornfall> be nice to your employee :-)
< mornfall> hmh
< enrico> so last friday there was a general strike and my company sent a
          press release to the major labor union telling them that the CEO
          together with all the employees decided to fully take part in the
          strike
< enrico> Signed: Enrico Zini, directory of the company Enrico Zini;
          Employees of the company Enrico Zini: Enrico Zini
< mornfall> that's getting tough
< enrico> I'm very nice to my employees, hes :)
< enrico> but sometimes I wonder if masturbation could be considered sexual
          harassment from my boss
< mornfall> LOL
< mornfall> you need to appoint a secretary
< enrico> I have one: Enrico Zini.  He's a bit messy, though.
< enrico> The only thing which is not called Enrico Zini is the accountant.
< enrico> Incidentally, he's called Vincenzo Zini, but he's isn't a relative
          of mine :)
< mornfall> in that case i think the boss is harassing the secretary not the
          other employee
< enrico> However, he is member of the local LUG and has a Jabber account :)
< mornfall> fun :)
< enrico> oh, ok.  But the employee might be harassing the secretary, or the
          secretary is harassing the employee and the boss
< enrico> IDEA
< enrico> Tonight I'll propose an orgy with the boss, the secretaries and the
          employees!
< enrico> (but not the accountant)

(blogged with mornfall's permission)

Posted Sat Jun 6 00:57:39 2009 Tags:

Allucinazioni

Bologna, 14 dicembre 2005.

Stamattina andavo a Bologna in macchina (capita raramente, ma odio quando capita).

Al primo maggio tiro dritto per andare in via Colombo e la coda dell'occhio tira su un cartellone dei saldi da un capannone sulla destra.

C'è qualcosa di strano. Guardo meglio.

"Niente piú telefonate! Svendita totale per cambio gestione"

Sorrido: il capannone era "Il Mobile di Castel Maggiore".

Posted Sat Jun 6 00:57:39 2009 Tags:
Posted Sat Aug 1 15:48:47 2015

Entries to also be published on truelite.it

Free as in Facebook

Yesterday we were in an airport. We tried to connect to the airport "free" wifi. It had a captive portal that asked for a lot of personal information before one could maybe get on the internet, and we gave up. Bologna Airport, no matter what they do to pretend that they like you, it's always clear that they don't.

I looked at the captive portal screen and I said: «ah yes, "free" wifi. Free as in Facebook».

We figured that we had an expression that will want to be reused.

Posted Mon Mar 9 10:58:49 2015 Tags:

Setting up Akonadi

Now that I have a CalDAV server that syncs with my phone I would like to use it from my desktop.

It looks like akonadi is able to sync with CalDAV servers, so I'm giving it a try.

First thing first is to give a meaning to the arbitrary name of this thing. Wikipedia says it is the oracle goddess of justice in Ghana. That still does not hint at all at personal information servers, but seems quite nice. Ok. I gave up with software having purpose-related names ages ago.

# apt-get install akonadi-server akonadi-backend-postgresql

Akonadi wants a SQL database as a backend. By default it uses MySQL, but I had enough of MySQL ages ago.

I tried SQLite but the performance with it is terrible. Terrible as in, it takes 2 minutes between adding a calendar entry and having it show up in the calendar. I'm fascinated by how Akonadi manages to use SQLite so badly, but since I currently just want to get a job done, next in line is PostgreSQL:

# su - postgres
$ createuser enrico
$ psql postgres
postgres=# alter user enrico createdb;

Then as enrico:

$ createdb akonadi-enrico
$ cat <<EOT > ~/.config/akonadi/akonadiserverrc
[%General]
Driver=QPSQL

[QPSQL]
Name=akonadi-enrico
StartServer=false
Host=
Options=
ServerPath=
InitDbPath=

I can now use kontact to connect Akonadi to my CalDAV server and it works nicely, both with calendar and with addressbook entries.

KDE has at least two clients for Akonadi: Kontact, which is a kitchen sink application similar to Evolution, and KOrganizer, which is just the calendar and scheduling component of Kontact.

Both work decently, and KOrganizer has a pretty decent startup time. I now have a usable desktop PIM application that is synced with my phone. W00T!

Next step is to port my swift little calendar display tool to use Akonadi as a back-end.

Posted Tue Feb 17 15:34:55 2015 Tags:

seat-inspect

Four months ago I wrote this somewhere:

Seeing a DD saying "this new dbus stuff scares me" would make most debian users scared. Seeing a DD who has an idea of what is going on, and who can explain it, would be an interesting and exciting experience.

So, let's be exemplary, competent and patient. Or at least, competent. Some may like or not like the changes, but do we all understand what is going on? Will we all be able to support our friends and customers running jessie?

I confess that although I understand the need for it, I don't feel competent enough to support systemd-based machines right now.

So, are we maybe in need of help, cheat sheets, arsenals of one-liners, diagnostic tools?

Maybe a round of posts on -planet like "one debian package a day" but with new features that jessie will have, and how to understand them and take advantage of them?

That was four months ago. In the meantime, I did some work, and it got better for me.

Yesterday, however, I've seen an experienced Linux person frustrated because the shutdown function of the desktop was doing nothing whatsoever. Today I found John Goerzen's post on planet.

I felt like some more diagnostic tools were needed, so I spent the day making seat-inspect.

seat-inspect tries to make the status of the login/seat system visible, to help with understanding and troubleshooting.

The intent of running the code is to have an overview of the system status, both to see what the new facilities are about, and to figure out if there is something out of place.

The intent of reading the code is to have an idea of how to use these facilities: the code has been written to be straightforward and is annotated with relevant bits from the logind API documentation.

seat-inspect is not a finished tool, but a starting point. I put it on github hoping that people will fork it and add their own extra sanity checks and warnings, so that it can grow into a standard thing to run if a system acts weird.

As it is now, it should be able to issue warnings if some bits are missing for network-manager or shutdown functions to work correctly. I haven't really tested that, though, because I don't have a system at hand where they are currently not working fine.

Another nice thing of it is that when running seat-inspect -v you get a dump of what logind/consolekit think about your system. I found it an interesting way to explore the new functionalities that we recently grew. The same can be done, and in more details, with loginctl calls, but I lacked a summary.

After writing this I feel a bit more competent, probably enough to sit at somebody's computer and poke into loginctl bits. I highly recommend the experience.

Posted Tue Feb 10 18:06:43 2015 Tags:

Playing with python, terminfo and command output

I am experimenting with showing progress on the terminal for a subcommand that is being run, showing what is happening without scrolling away the output of the main program, and I came out with this little toy. It shows the last X lines of a subcommand output, then gets rid of everything after the command has ended.

Usability-wise, it feels like a tease to me: it looks like I'm being shown all sorts of information then they are taken away from me before I managed to make sense of them. However, I find it cute enough to share:

#!/usr/bin/env python3
#coding: utf-8
# Copyright 2015 Enrico Zini <enrico@enricozini.org>.  Licensed under the terms
# of the GNU General Public License, version 2 or any later version.

import argparse
import fcntl
import select
import curses
import contextlib
import subprocess
import os
import sys
import collections
import shlex
import shutil
import logging

def stream_output(proc):
    """
    Take a subprocess.Popen object and generate its output, line by line,
    annotated with "stdout" or "stderr". At process termination it generates
    one last element: ("result", return_code) with the return code of the
    process.
    """
    fds = [proc.stdout, proc.stderr]
    bufs = [b"", b""]
    types = ["stdout", "stderr"]
    # Set both pipes as non-blocking
    for fd in fds:
        fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK)
    # Multiplex stdout and stderr with different prefixes
    while len(fds) > 0:
        s = select.select(fds, (), ())
        for fd in s[0]:
            idx = fds.index(fd)
            buf = fd.read()
            if len(buf) == 0:
                fds.pop(idx)
                if len(bufs[idx]) != 0:
                    yield types[idx], bufs.pop(idx)
                types.pop(idx)
            else:
                bufs[idx] += buf
                lines = bufs[idx].split(b"\n")
                bufs[idx] = lines.pop()
                for l in lines:
                    yield types[idx], l
    res = proc.wait()
    yield "result", res

@contextlib.contextmanager
def miniscreen(has_fancyterm, name, maxlines=3, silent=False):
    """
    Show the output of a process scrolling in a portion of the screen.

    has_fancyterm: true if the terminal supports fancy features; if false, just
    write lines to standard output

    name: name of the process being run, to use as a header

    maxlines: maximum height of the miniscreen

    silent: do nothing whatsoever, used to disable this without needing to
            change the code structure

    Usage:
        with miniscreen(True, "my process", 5) as print_line:
            for i in range(10):
                print_line(("stdout", "stderr")[i % 2], "Line #{}".format(i))
    """
    if not silent and has_fancyterm:
        # Discover all the terminal control sequences that we need
        output_normal = str(curses.tigetstr("sgr0"), "ascii")
        output_up = str(curses.tigetstr("cuu1"), "ascii")
        output_clreol = str(curses.tigetstr("el"), "ascii")
        cols, lines = shutil.get_terminal_size()
        output_width = cols

        fg_color = (curses.tigetstr("setaf") or
                    curses.tigetstr("setf") or "")
        sys.stdout.write(str(curses.tparm(fg_color, 6), "ascii"))

        output_lines = collections.deque(maxlen=maxlines)

        def print_lines():
            """
            Print the lines in our buffer, then move back to the beginning
            """
            sys.stdout.write("{} progress:".format(name))
            sys.stdout.write(output_clreol)
            for msg in output_lines:
                sys.stdout.write("\n")
                sys.stdout.write(msg)
                sys.stdout.write(output_clreol)
            sys.stdout.write(output_up * len(output_lines))
            sys.stdout.write("\r")

        try:
            print_lines()

            def _progress_line(type, line):
                """
                Print a new line to the miniscreen
                """
                # Add the new line to our output buffer
                msg = "{} {}".format("." if type == "stdout" else "!", line)
                if len(msg) > output_width - 4:
                    msg = msg[:output_width - 4] + "..."
                output_lines.append(msg)
                # Update the miniscreen
                print_lines()

            yield _progress_line

            # Clear the miniscreen by filling our ring buffer with empty lines
            # then printing them out
            for i in range(maxlines):
                output_lines.append("")
            print_lines()
        finally:
            sys.stdout.write(output_normal)
    elif not silent:
        def _progress_line(type, line):
            print("{}: {}".format(type, line))
        yield _progress_line
    else:
        def _progress_line(type, line):
            pass
        yield _progress_line

def run_command_fancy(name, cmd, env=None, logfd=None, fancy=True, debug=False):
    quoted_cmd = " ".join(shlex.quote(x) for x in cmd)
    log.info("%s running command %s", name, quoted_cmd)
    if logfd: print("runcmd:", quoted_cmd, file=logfd)

    # Run the script itself on an empty environment, so that what was
    # documented is exactly what was run
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)

    with miniscreen(fancy, name, silent=debug) as progress:
        stderr = []
        for type, val in stream_output(proc):
            if type == "stdout":
                val = val.decode("utf-8")
                if logfd: print("stdout:", val, file=logfd)
                log.debug("%s stdout: %s", name, val)
                progress(type, val)
            elif type == "stderr":
                val = val.decode("utf-8")
                if logfd: print("stderr:", val, file=logfd)
                stderr.append(val)
                log.debug("%s stderr: %s", name, val)
                progress(type, val)
            elif type == "result":
                if logfd: print("retval:", val, file=logfd)
                log.debug("%s retval: %d", name, val)
                retval = val

    if retval != 0:
        lastlines = min(len(stderr), 5)
        log.error("%s exited with code %s", name, retval)
        log.error("Last %d lines of standard error:", lastlines)
        for line in stderr[-lastlines:]:
            log.error("%s: %s", name, line)

    return retval


parser = argparse.ArgumentParser(description="run a command showing only a portion of its output")
parser.add_argument("--logfile", action="store", help="specify a file where the full execution log will be written")
parser.add_argument("--debug", action="store_true", help="debugging output on the terminal")
parser.add_argument("--verbose", action="store_true", help="verbose output on the terminal")
parser.add_argument("command", nargs="*", help="command to run")
args = parser.parse_args()

if args.debug:
    loglevel = logging.DEBUG
elif args.verbose:
    loglevel = logging.INFO
else:
    loglevel = logging.WARN
logging.basicConfig(level=loglevel, stream=sys.stderr)
log = logging.getLogger()

fancy = False
if not args.debug and sys.stdout.isatty():
    curses.setupterm()
    if curses.tigetnum("colors") > 0:
        fancy = True

if args.logfile:
    logfd = open("output.log", "wt")
else:
    logfd = None

retval = run_command_fancy("miniscreen example", args.command, logfd=logfd)

sys.exit(retval)
Posted Wed Jan 21 11:13:31 2015 Tags:

Upgrade Cyanogenmod with an encrypted phone

Cyanogenmod found an update, it downloaded it, then it rebooted to install it and nothing happened. It turns out that the update procedure cannot work if the zip file to install is in encrypted media, so a workaround is to move the zip into unencrypted external storage.

As far as I know, my Nexus 4 has no unencrypted external storage.

This is how I managed to upgrade it, I write it here so I can find it next time:

  1. enable USB debugging
  2. adb pull /cmupdater/cm-11-20141115-SNAPSHOT-M12-mako.zip
  3. adb reboot recovery
  4. choose "install zip from sideload"
  5. adb sideload cm-11-20141115-SNAPSHOT-M12-mako.zip
Posted Fri Dec 19 10:21:29 2014 Tags:

Radicale and DAVDroid

radicale and DAVdroid appeal to me. Let's try to make the whole thing work.

A self-signed SSL certificate

Update: use this method instead, to avoid apache complaining that server certificate is a CA certificate.

Generating the certificate:

    openssl req -nodes -x509 -newkey rsa:2048 -keyout cal-key.pem -out cal-cert.pem -days 3650
    [...]
    Country Name (2 letter code) [AU]:IT
    State or Province Name (full name) [Some-State]:Bologna
    Locality Name (eg, city) []:
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:enricozini.org
    Organizational Unit Name (eg, section) []:
    Common Name (e.g. server FQDN or YOUR name) []:cal.enricozini.org
    Email Address []:postmaster@enricozini.org

Installing it on my phone:

    openssl x509 -in cal-cert.pem -outform DER -out cal-cert.crt
    adb push cal-cert.crt /mnt/sdcard/
    enrico --follow-instructions http://davdroid.bitfire.at/faq/entry/importing-a-certificate

Installing radicale in my VPS

Update: there is already a new version of radicale available in Debian testing.

An updated radicale package, with this patch to make it work with DAVDroid:

    apt-get source radicale
    # I reviewed 063f7de7a2c7c50de5fe3f8382358f9a1124fbb6
    git clone https://github.com/Kozea/Radicale.git
    Move the python code from git to the Debian source
    dch -v 0.10~enrico-1 "Pulled in the not yet released 0.10 work from upstream"
    debuild -us -uc -rfakeroot

Install the package:

    # dpkg -i python-radicale_0.10~enrico0-1_all.deb
    # dpkg -i radicale_0.10~enrico0-1_all.deb

Create a system user to run it:

    # adduser --system --disabled-password radicale

Configure it (/etc/radicale/config) for mod_wsgi with auth done by Apache:

    # For brevity, this is my config file with comments removed

    [storage]
    # Storage backend
    # Value: filesystem | multifilesystem | database | custom
    type = filesystem

    # Folder for storing local collections, created if not present
    filesystem_folder = /var/lib/radicale/collections

    [logging]
    config = /etc/radicale/logging

Create the wsgi file to run it:

    # mkdir /srv/radicale
    # cat <<EOT > /srv/radicale/radicale.wsgi
    import radicale
    radicale.log.start()
    application = radicale.Application()
    EOT
    # chown radicale.radicale /srv/radicale/radicale.wsgi
    # chmod 0755 /srv/radicale/radicale.wsgi

Make radicale commit to git

    # apt-get install python-dulwich
    # cd /var/lib/radicale/collections
    # git init
    # chown radicale.radicale -R /var/lib/radicale/collections/.git

Apache configuration

Add a new site to apache:

    $ cat /etc/apache2/sites-available/cal.conf
    # For brevity, this is my config file with comments removed
    <IfModule mod_ssl.c>
    <VirtualHost *:443>
            ServerName cal.enricozini.org
            ServerAdmin enrico@enricozini.org

            Alias /robots.txt /srv/radicale/robots.txt
            Alias /favicon.ico /srv/radicale/favicon.ico

            WSGIDaemonProcess radicale user=radicale group=radicale threads=1 umask=0027 display-name=%{GROUP}
            WSGIProcessGroup radicale
            WSGIScriptAlias / /srv/radicale/radicale.wsgi

            <Directory /srv/radicale>
                    # WSGIProcessGroup radicale
                    # WSGIApplicationGroup radicale
                    # WSGIPassAuthorization On
                    AllowOverride None
                    Require all granted
            </Directory>

            <Location />
                    AuthType basic
                    AuthName "Enrico's Calendar"
                    AuthBasicProvider file
                    AuthUserFile /usr/local/etc/radicale/htpasswd
                    Require user enrico
            </Location>

            ErrorLog{APACHE_LOG_DIR}/cal-enricozini-org-error.log
            LogLevel warn

            CustomLog{APACHE_LOG_DIR}/cal-enricozini-org-access.log combined

            SSLEngine on
            SSLCertificateFile    /etc/ssl/certs/cal.pem
            SSLCertificateKeyFile /etc/ssl/private/cal.key
    </VirtualHost>
    </IfModule>

Then enable it:

    # a2ensite cal.conf
    # service apache2 reload

Create collections

DAVdroid seems to want to see existing collections on the server, so we create them:

    $ apt-get install cadaver
    $ cat <<EOT > /tmp/empty.ics
    BEGIN:VCALENDAR
    VERSION:2.0
    END:VCALENDAR
    EOT
    $ cat <<EOT > /tmp/empty.vcf
    BEGIN:VCARD
    VERSION:2.1
    END:VCARD
    EOT
    $ cadaver https://cal.enricozini.org
    WARNING: Untrusted server certificate presented for `cal.enricozini.org':
    [...]
    Do you wish to accept the certificate? (y/n) y
    Authentication required for Enrico's Calendar on server `cal.enricozini.org':
    Username: enrico
    Password: ****
    dav:/> cd enrico/contacts.vcf/
    dav:/> put /tmp/empty.vcf
    dav:/> cd ../calendar.ics/
    dav:/> put /tmp/empty.ics
    dav:/enrico/calendar.ics/> ^D
    Connection to `cal.enricozini.org' closed.

DAVdroid configuration

  1. Add a new DAVdroid sync account
  2. Use server/username configuration
  3. For server, use https:////
  4. Add username and password

It should work.

Related links

Posted Tue Dec 9 16:35:50 2014 Tags:

Alternate rescue boot entry with systemd

Since systemd version 215, adding systemd.debug-shell to the kernel command line activates the debug shell on tty9 alongside the normal boot. I like the idea of that, and I'd like to have it in my standard 'rescue' entry in my grub menu.

Unfortunately, by default update-grub does not allow to customize the rescue menu entry options. I have just filed #766530 hoping for that to change.

After testing the patch I proposed for /etc/grub.d/10_linux, I now have this in my /etc/default/grub, with some satisfaction:

GRUB_CMDLINE_LINUX_RECOVERY="systemd.log_target=kmsg systemd.log_level=debug systemd.debug-shell"

Further information:

Thanks to sjoerd and uau on #debian-systemd for their help.

Posted Thu Oct 23 22:06:30 2014 Tags:

Spelling a chilometri zero

Lo spelling internazionale è troppo globalizzato, e volete recuperare un attimo la dimensione del posto dove siete nati e cresciuti?

Da oggi c'è questo script che fa per voi: gli dite dove abitate, e lui vi crea lo spelling a chilometri zero.

$ git clone git@gitorious.org:trespolo/osmspell.git
$ cd osmspell
$ ./osmspell "San Giorgio di Piano"
1: San Giorgio di Piano, BO, EMR, Italia
2: San Giorgio di Piano, Via Codronchi, San Giorgio di Piano, BO, EMR, Italia
3: San Giorgio Di Piano, Via Libertà, San Giorgio di Piano, BO, EMR, Italia
Choose one: 1
Center: 44.6465332, 11.3790398
A Argelato, Altedo
B Bentivoglio, Bologna, Boschi
C Cinquanta, Castagnolo Minore, Castel Maggiore, Cento
D Dosso
E Eremo di Tizzano
F Funo di Argelato, Finale Emilia, Ferrara, Fiesso
G Gherghenzano, Galliera, Gesso
I Il Cucco, Irnerio, Idice
L Località Fortuna, Lovoleto, Lippo
M Malacappa, Massumatico, Minerbio, Marano
N Navile
O Osteriola, Ozzano dell'Emilia, Oca
P Piombino, Padulle, Poggio Renatico, Piave
Q Quarto Inferiore, Quattrina
R Rubizzano, Renazzo, Riale
S San Giorgio di Piano, Saletto
T Torre Verde, Tintoria, Tombe
U Uccellino
V Venezzano Mascarino, Vigarano Mainarda, Veduro
X XII Morelli
Z Zenerigolo, Zola Predosa

I dati vengono da OSM, e lo script è un ottimo esempio di come usarne la API di geolocazione (veloci) e la API di query geografica (lenta).

Posted Sat Jan 4 00:38:16 2014 Tags:
Posted Tue Apr 7 19:20:12 2015

Pages about OpenMoko.

Released nodm 0.7

I have released version 0.7 of nodm.

It only fixes one silly typo in autotools, which made it fail to build on Fedora.

Posted Sun May 23 21:36:52 2010 Tags:

Released nodm 0.6

I have released version 0.6 of nodm.

It is purely a bug fix release, trying harder to detect a console in order to get rid of a bug introduced with version 0.5

Posted Mon Aug 3 12:34:16 2009 Tags:

Released nodm 0.5

I have released version 0.5 of nodm.

New features:

  • truncate ~/.xsession-errors on startup: finally that file stops growing, and growing, and growing...
  • dynamic VT allocation: it can now avoid opening a virtual terminal if it is already in use.
Posted Fri Jul 24 02:29:55 2009 Tags:

Getting dbus signatures right from Vala

I am trying to play a bit with Vala on the FreeRunner.

The freesmartphone.org stack on the OpenMoko is heavily based on DBus. Using DBus from Vala is rather simple, if mostly undocumented: you get a few examples in the Vala wiki and you make do with those.

All works fine with simple methods. But what with providing callbacks to signals that have complex nested structures in their signatures, like aa{sv}? You try, and then if you don't get the method signature right, the signal is just silently not delivered because it does not match the method signature.

So this is how to provide a callback to org.freesmartphone.Usage.ResourceChanged, with signature sba{sv}:

public void on_resourcechanged(dynamic DBus.Object pos,
                   string name,
                   bool state,
                   HashTable<string, Value?> attributes)
{
    stderr.printf("Resource %s changed\n", name);
}

And this is how to provide a callback to org.freesmartphone.GPS.UBX.DebugPacket, with signature siaa{sv}:

protected void on_ubxdebug_packet(dynamic DBus.Object ubx, string clid, int length,
        HashTable<string, Value?>[] wrongdata)
{
    stderr.printf("Received UBX debug packet");

    // Ugly ugly work-around
    PtrArray< HashTable<string, Value?> >* data = (PtrArray< HashTable<string, Value?> >)wrongdata;

    stderr.printf("%u elements received", data->len);
}

What is happening here is that the only method signature that I found matching the dbus signature is this one. However, the unmarshaller for some reason gets it wrong, and passes a PtrArray instead of a HashTable array. So you need to cast it back to what you've actually been passed.

Figuring all this out took several long hours and was definitely not fun.

Posted Wed Jul 15 12:30:50 2009 Tags:

Mapping using the Openmoko FreeRunner headset

The FreeRunner has a headset which includes a microphone and a button. When doing OpenStreetMap mapping, it would be very useful to be able to keep tangogps on the display and be able to mark waypoints using the headset button, and to record an audio track using the headset microphone.

In this way, I can use tangogps to see where I need to go, where it's already mapped and where it isn't, and then I can use the headset to mark waypoints corresponding to the audio track, so that later I can take advantage of JOSM's audio mapping features.

Enter audiomap:

$ audiomap --help
Usage: audiomap [options]

Create a GPX and audio trackFind the times in the wav file when there is clear
voice among the noise

Options:
  --version      show program's version number and exit
  -h, --help     show this help message and exit
  -v, --verbose  verbose mode
  -m, --monitor  only keep the GPS on and monitor satellite status
  -l, --levels   only show input levels

If called without parameters, or with -v which is suggested, it will:

  1. Fix the mixer settings so that it can record from the headset and detect headset button presses.
  2. Show a monitor of GPS satellite information until it gets a fix.
  3. Synchronize the system time with the GPS time so that the timestamps of the files that are created afterwards are accurate.
  4. Start recording a GPX track.
  5. Start recording audio.
  6. Record a GPX waypoint for every headset button press.

When you are done, you stop audiomap with ^C and it will properly close the .wav file, close the tags in the GPX waypoint and track files and restore the mixer settings.

You can plug the headset out and record using the handset microphone, but then you will not be able to set waypoints until you plug the headset back in.

After you stop audiomap, you will have a track, waypoints and .wav file ready to be loaded in JOSM.

Big thanks go to Luca Capello for finding out how to detect headset button presses.

Posted Sun Jun 7 23:51:37 2009 Tags:

Simple tool to query the GPS using the OpenMoko FSO stack

I was missing a simple command line tool that allows me to perform basic GPS queries in shellscripts.

Enter getgps:

# getgps --help
Usage: getgps [options]

Simple GPS query tool for the FSO stack

Options:
  --version          show program's version number and exit
  -h, --help         show this help message and exit
  -v, --verbose      verbose mode
  -q, --quiet        suppress normal output
  --fix              check if we have a fix
  -s, --sync-time    set system time from GPS time
  --info             get all GPS information
  --info-connection  get GPS connection information
  --info-fix         get GPS fix information
  --info-position    get GPS position information
  --info-accuracy    get GPS accuracy information
  --info-course      get GPS course information
  --info-time        get GPS time information
  --info-satellite   get GPS satellite information

So finally I can write little GPS-aware scripts:

if getgps --fix -q
then
    start_gps_aware_program
else
    start_gps_normal_program
fi

Or this.

Posted Sun Jun 7 17:59:32 2009 Tags:

Voice-controlled waypoints

I have it in my TODO list to implement taking waypoints when pressing the headset button of the openmoko, but that is not done yet.

In the meantime, I did some experiments with audio mapping, and since I did not manage to enter waypoints while recording them, I was looking for a way to make use of them anyway.

Enter findvoice:

$ ./findvoice  --help
Usage: findvoice [options] wavfile

Find the times in the wav file when there is clear voice among the noise

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         verbose mode
  -p NUM, --percentile=NUM
            percentile to use to discriminate noise from voice
            (default: 90)
  -t, --timestamps      print timestamps instead of human readable information

You give it a wav file, and it will output a list of timestamps corresponding to where it things that you were talking clearly and near the FreeRunner / voice recorder instead of leaving the recorder dangling to pick up background noise.

Its algorithm is crude and improvised because I have no background whatsoever in audio processing, but it basically finds those parts of the audio file where the variance of the samples is above a given percentile: the higher the percentile, the less timestamps you get; the lower the percentile, the more likely it is that it picks a period of louder noise.

For example, you can automatically extract waypoints out of an audio file by using it together with gpxinterpolate:

./findvoice -t today.wav | ./gpxinterpolate today.gpx > today-waypoints.gpx

The timestamps it outputs are computed using the modification time of the .wav file: if your system clock was decently synchronised (which you can do with getgps), then the mtime of the wav is the time of the end of the recording, which gives the needed reference to compute timestamps that are absolute in time.

For example:

getgps --sync-time
arecord file.wav
^C
./findvoice -t file.wav | ./gpxinterpolate today.gpx > today-waypoints.gpx
Posted Sun Jun 7 02:48:40 2009 Tags:

Geocoding Unix timestamps

Geocoding EXIF tags in JPEG images is fun, but there is more that can benefit from interpolating timestamps over a GPX track.

Enter gpxinterpolate:

$ ./gpxinterpolate --help
Usage: gpxinterpolate [options] gpxfile [gpxfile...]

Read one or more GPX files and a list of timestamps on standard input. Output
a GPX file with waypoints at the location of the GPX track at the given
timestamps.

Options:
  --version      show program's version number and exit
  -h, --help     show this help message and exit
  -v, --verbose  verbose mode

For example, you can create waypoints interpolating file modification times:

find . -printf "%Ts %p\n" | ./gpxinterpolate ~/tracks/*.gpx > myfiles.gpx

In case you wonder where you were when you modified or accessed a file, now you can find out.

Posted Sun Jun 7 02:07:43 2009 Tags:

Recording audio on the FreeRunner

The FreeRunner can record audio. It is nice to record audio: for example I can run the recording in background while I keep tangogps in the screen, and take audio notes about where I am while I am doing mapping for OpenStreetMap.

Here is the script that I put together to create geocoded audio notes:

#!/bin/sh

WORKDIR=~/rec
TMPINFO=`mktemp $WORKDIR/info.XXXXXXXX`

# Sync system time and get GPS info
echo "Synchronising system time..."
getgps --sync-time --info > $TMPINFO

# Compute an accurate basename for the files we generate
BASENAME=~/rec/rec-$(date +%Y-%m-%d-%H-%M-%S)
# Then give a proper name to the file with saved info
mv $TMPINFO $BASENAME.info

# Proper mixer settings for recording
echo "Recording..."
alsactl -f /usr/share/openmoko/scenarios/voip-handset.state restore
arecord -D hw -f cd -r 8000 -t wav $BASENAME.wav

echo "Done"

It works like this:

  1. It synchronizes the system time from the GPS (if there is a fix) so that the timestamps on the wav files will be as accurate as possible.
  2. It also gets all sort of information from the GPS and stores them into a file, should you want to inspect it later.
  3. It records audio until it gets interrupted.

The file name of the files that it generates corresponds to the beginning of the recording. The mtime of the wav file obviously corresponds to the end of the recording. This can be used to later georeference the start and end point of the recording.

You can use this to check mixer levels and that you're actually getting any input:

arecord -D hw -f cd -r 8000 -t wav -V mono /dev/null

The getgps script is now described in its own post.

You may now want to experiment, in JOSM, with "Preferences / Audio settings / Modified times (time stamps) of audio files".

Posted Sun Jun 7 01:30:37 2009 Tags:

Logging on the Freerunner

By default, the FreeRunner comes without a system log daemon, and rightfully so, because you don't want a daemon filling up /var, and a nightly cron job to rotate logs, on a mobile phone.

However, I do not want to give up logging. If there are bugs I want to investigate, I like to be able to look at the logs.

The solution: remote logging. Configure the phone to send all log info via UDP to my laptop, and configure my laptop to listen for UDP syslog messages from the phone only.

How to do it:

  1. apt-get install rsyslog (see below how other logging daemons fail)
  2. Add a /etc/hosts entry for the laptop on the phone: 192.168.0.200 base
  3. Add a /etc/hosts entry for the phone on the laptop: 192.168.0.202 openmoko
  4. Replace the phone's rsyslog rules to send everything to the laptop:

    ################
    ##### RULES ####
    ################
    
    # Everything goes to the main computer, via UDP, if available
    *.*     @base
    
    #
    # Emergencies are sent to everybody logged in.
    #
    *.emerg                         *
    
  5. Tell the laptop's rsyslog to accept UDP messages from the phone only:

    # provides UDP syslog reception
    $ModLoad imudp
    $UDPServerRun 514
    $UDPServerAddress 192.168.0.200
    

That is all. When the phone is not connected, the UDP packets from the logger will go nowhere. When it gets connected to the laptop, a script is triggered that creates the 192.168.0.200 interface, rsyslogd will listen on that interface and the UDP packets will be logged.

This has the extra potential to be able to get error messages in case of bugs in the SD card driver, which I seem to hit from time to time.

Why rsyslog

sysklogd could receive the messages from the phone, but can only listen on all interfaces, and therefore requires me to set up firewall on my laptop in order to get packets from the phone only.

syslog-ng can and can be told to listen on a given interface, but it will refuse to start if that interface isn't available. Since the phone is on an hotplugged interface that comes and goes, this is totally unacceptable.

And finally, rsyslog is going to replace sysklogd both in Debian and in Fedora, so it's just as well a good excuse to switch.

Posted Sat Jun 6 00:57:39 2009 Tags:
Posted Sat Jun 6 00:57:39 2009
eng

Pages in English.

debtags.debian.org cleaned up

Since the Debtags consolidation announcement there are some more news:

No more anonymous submissions

  • I have disabled anonymous tagging. Anyone is still able to tag via Debian Single Sign-On. SSO-enabling the site was as simple as this.
  • Tags need no review anymore to be sent to ftp-master. I have removed all the distinction in the code between reviwed and unreviewed tags, and all the code for the tag review interface.
  • The site now has an audit log for each user, that any person logged in via SSO can access via the "history" link in the top right of the tag editor page.

Official recognition as Debian Contributors

  • Tag contributions are sent to contributors.debian.org. There is no historical data for them because all submissions until now have been anonymous, but from now on if you tag packages you are finally recognised as a Debian Contributor!

Mailing lists closed

  • I closed the debtags-devel and debtags-commits mailing lists; the archives are still online.
  • I have updated the workflow for suggesting new tags in the FAQ to "submit a bug to debtags and Cc debian-devel"

We can just use debian-devel instead of debtags-devel.

Autotagging of trivial packages

  • I have introduced the concept of "trivial" packages to currently be any package in the libs, oldlibs and debug sections. They are tagged automatically by the site maintenance and are excluded from the site todo lists and tag editor. We do not need to bother about trivial packages anymore, all 13239 of them.

Miscellaneous other changes

  • I have moved the debtags vocabulary from subversion to git
  • I have renamed the tag used to mark packages not yet reviewed by humans from special::not-yet-tagged to special::unreviewed
  • At the end of every nightly maintenance, some statistics are saved into a database table. I have collected 10 years of historical data by crunching big tarballs of site backups, and fed them to the historical stats table.
  • The workflow for getting tags from the site to ftp-master is now far, far simpler. It is almost simple enough that I should manage to explain it without needing to dig through code to see what it is actually doing.
Posted Fri Feb 5 19:18:50 2016 Tags:

Downgrading network-manager

This morning I woke up. Bad idea.

I find in the work mail a compiler error that I cannot reproduce, so I need to log into a machine at work. But #809195.

I decided to downgrade network-manager. I recall there was a tool to download packages from snapshots.debian.org, I discussed it recently on IRC, let's sync the IRC logs from my server. Or not (#810212).

Never mind, I'll log into the server and grep. Ooh, it's debsnap. However, it doesn't quite do what I hoped (#667712).

After some help from #debian-devel (thanks jcristau and LebedevRI), here is how to downgrade network-manager:

# echo "deb http://snapshot.debian.org/archive/debian/20151125T155830Z/ sid main" >> /etc/apt/sources.list.d/tmp-downgrade-nm.list
# apt -o Acquire::Check-Valid-Until=false update
# apt -o Acquire::Check-Valid-Until=false install network-manager=1.0.6-1
# rm /etc/apt/sources.list.d/tmp-downgrade-nm.list
# service network-manager restart

And as user:

$ killall nm-applet
$ nm-applet &

The yak is now nice and shaved, I can now go and see what those compiler errors are all about.

Actually, no, there was still an unshaved patch on the yak, and now we have a debcya script.

Posted Thu Jan 7 11:37:19 2016 Tags:

When Akonadi silently fails to sync your calendar...

Bug severity: seriously ruining my life.

Try to use korganizer to create a calendar entry when the server is not reachable (say, you are offline, or you typed the wrong password), and you may find that you end up with no error messages, an entry that shows up perfectly fine, but that will never be synced to the server, ever again.

I use korganizer, radicale and caldav for important things. The practical ramifications of me inserting entries in korganizer, seeing that everything looks ok, and then not finding them on my phone while on the go, are scary.

Think of things like importing .ics files with flight schedules, entering tax deadlines, time and places for customer meetings, time and places of arrival of loved ones I'm supposed to pick up.

I spent time setting up my own infrastructure for this exactly because I care that all of this works reliably.

And now I urgently took a morning off work to find a way to detect those entries that Akonadi is refusing to update,

The whole thing is cumbersome to run, but if you are using kdepim-based tools to manage your calendars and sync them across devices, you may want to give it a go every once in a while.

You can find the script and the notes I took so far on the issue at https://github.com/spanezz/akonadi-workarounds.

Posted Tue Dec 1 14:01:09 2015 Tags:

Italian Fattura Elettronica with OpenSSL

I have had some success signing an Italian fattura elettronica with OpenSSL.

I am amazed to realise that the software they gave me to do the job is of such bad quality that I felt like spending a few hours trying to do the same thing with OpenSSL instead.

Posted Fri Oct 23 10:35:53 2015 Tags:

Extracting XML payload from Italian Fattura Elettronica zipfiles

This system does not even export to PDF. In order to provide my accountant with something better than a DER-encoded file with a random-looking name stored inside a zipfile, here is a script that at least extracts the unsigned XML payload out of a saved Fattura Elettronica.

If you're giving a python course in Italy, this sounds like a nice early programming assignment.

Posted Fri Oct 9 11:52:04 2015 Tags:

If you happen to know a browser developer...

Do you happen to know a developer of Firefox or Chrome or some other mainstream browser?

If so, can you please talk to them about our experiments with Client Certificate authentication in Debian?

Client Certificate authentication rocks; with just a couple of little tweaks in the interface, it would be pretty close to perfect.

Visiting sites without using a certificate

If I want to browse a site unauthenticated instead of using a certificate, at the moment I can hit "Cancel" on the certificate popup menu, and it works nicely. I feel quite confused when I do that, though, because it's not clear to me if I am canceling use of certificates, or canceling the visit to the site.

Can you please change the wording on the Cancel button to something more descriptive?

See/change current certificate selection

My top wish is, once I choise to use (or not use) a certificate for a site, to be able to see which certificate I'm using and possibly change it.

At the moment I did not find a way to see what certificate I'm using, and the browser will remember the choice until it gets closed and reopened.

At the moment I can use a Private or Incognito window to switch identities or to stop authenticated access and continue anonymously, and that helps me immensely.

I think however that the ultimate solution could be to have the https lockpad popup show an indication of what certificate is currently being used, and offer a way to re-trigger certificate selection. That would be so cool.

Also, once the certificate choice can be seen and changed at any time, it could just get remembered so that sites can be visited again without any prompts, even after the browser has been closed and reopened. That would be, to me, the ultimate convenience.

Thanks! <3

Thank you very much for all the work you have already put into this: I have been told that a few years ago using client certificate was unthinkable, and now it seems to be down to just a couple of papercuts. And SPKAC/keygen seriously rocks!

I have been constantly impressed by how well this all works right now.

Posted Tue Sep 1 17:25:04 2015 Tags:

My semi serious stand up comedy notes

Video

Disclaimers

“Someone has said that it requires less mental effort to condemn than to think.”

(Emma Goldman, on several things including mailing list flamewars)

Fascinating Aïda's "Dogging" song.

Look for "dogging etiquette" for more examples of code of conducts. Just don't take your computer for repair immediately afterwards™.

Introduction

Every daring attempt to make a great change in existing conditions, every lofty vision of new possibilities for the human race, has been labeled Utopian.

(Emma Goldman, on the Debian Social Contract)

I am going to talk about many topics that we all know have so much in common:

  • Anarchism
  • Poliamory
  • BDSM
  • and Free Software

They are all, after all:

  • People
  • Consensually
  • Doing Things
  • Together

BDSM

A person is no less a slave because they are allowed to choose a new master once in a term of years.

(Lysander Spooner about proprietary cloud service providers)

If you thought you've seen it all with recursive acronyms, here's a chain acronym: Bondage Discipline, Dominance Submission, Sado Masochism.

Why I think BDSM is interesting: not (just) because of whips, but for having a lot of awareness about power releationships. Why should one accept from a coworker a level of abuse that would be considered a hard limit when negotiating with a trusted dom?

The BDSM Free Software definition: "I refuse to be bound by software I cannot negotiate with".

YKINMKBYKIOK (Your Kink Is Not My Kink But Your Kink Is Okay) is a nice example of dealing with diversity, and it also definitely solves the emacs vs vi debate.

Comfort zones, safewords, traffic light flow control, safety.

"No means no", unless there has been a long discussion first, and a safeword is in place, in which case "Fuzzy purple unicorn" means "no"

"No means no", and if someone insists after a "no", it becomes harassment.

"No means no" is a precondition for being able to say "yes": http://pervocracy.blogspot.de/2011/03/no-and-no-and-no-and-yes.html

Aftercare! Aftercare! Release parties! High fives! Solidarity after flamewars or votes!

Poliamory

If love does not know how to give and take without restrictions, it is not love, but a transaction that never fails to lay stress on a plus and a minus.

(Emma Goldman, on volunteer projects)

Polyamory is the practice, desire, or acceptance of intimate relationships that are not exclusive with respect to other sexual or intimate relationships, with knowledge and consent of everyone involved.

Compersion, n: the feeling you get when someone else also takes good care of one of your packages.

We currently allow only one value in the Maintainer field: * takeover is traumatic, because values can only be replaced * if values could be added instead, and removed when they don't make sense anymore...

What is your definition of love? My current one is: my world is better with you in it.

Relationship anarchy is the practice of forming relationships which are not bound by rules aside from what the people involved mutually agree on. How do you call a relationship that is bound by rules that the people involved do not agree on?

From discussions after the talk

New Relationship Energy, the excitement when you start to maintain a new package, and the risk of been carried away by the excitement and neglecting all the other ones.

Consent

Anarchism, to me, means not only the denial of authority, not only a new economy, but a revision of the principles of morality. It means the development of the individual as well as the assertion of the individual. It means self-responsibility, and not leader worship.

(Voltairine de Cleyre about trusting lintian warnings)

You need to know what you are doing, and what situation you're putting yourself into.

You need to know that the person asking a question really is able to accept any answer, and take it seriously.

You need to feel that you have alternatives.

Be selfish when you ask, honest when you reply, and when others reply, take them seriously. If any of this doesn't stand, I find it hard to trust that we are in a consensual situation.

When is one supposed to learn about consent?

  • I see little consensuality in standard education.
  • I see little consensuality at work.

Consent explained with tea.

Practical advice

Anarchism has but one infallible, unchangeable motto, ‘Freedom.’ Freedom to discover any truth, freedom to develop, to live naturally and fully.

(Lucy Parsons about the DFSG)

Relationship advice and work advice have a lot in common:

Relationship advice from 99 ways to ruin an open source project

Online participation advice from How to Screw Up Your Relationship (and make everyone miserable while you’re at it)

Packaging advice from BDSM Basics: 20 Unsolicited Tips for New Dominants

Advice about joining a new community from Advice to a newbie submissive about dominants

♥ ♥ ♥

Dear Debian, and dear everyone contributing to it: my world is better with you in it.

I love you all :* <3

Posted Tue Aug 18 11:48:08 2015 Tags:

Expectations and needs

All people ever say is: "thank you" (a celebration of life) and "please" (an opportunity to make life more wonderful). (Marshall Rosenberg)

Sometimes, when I see the word "expectation" I try to read it as "need" and see how things change.

I noticed that this tends to reframe situations in a way that makes me feel more comfortable.

I noticed that I tend to instinctively perceive "expectations" as "do this or there will be consequences", and I tend to instinctively perceive "needs" as "do this if you want to see me happy".

I noticed that my motivation to care for someone's expectations tend to be something close to fear, and my motivation to care for someone's needs tends to be something close to love.

This might give me a bit more hints on The art of asking: I will not expect you to do something for me, I'll just allow myself to be loved, liked or helped by you, and I'll try to be open about what I need.

I smile realising that since a long time, on the professional side of my life, I learnt to lead interaction with my customers along the same lines: "let's talk about what you need, not about what you expect of me".

Posted Fri Aug 14 12:13:16 2015 Tags:

Random quote

Be selfish when you ask, honest when you reply, and when others reply, take them seriously.

(me, late at night)

Posted Sun Jul 19 18:53:03 2015 Tags:

Billing an Italian public administration

Here's a simple guide for how I managed to bill one of my customers as is now mandated by law in Italy.

Create a new virtualbox machine

I would never do any of this to any system I would ever want to use for anything else, so it's virtual machine time.

  • I started virtualbox, created a new machine for Ubuntu 32bit, 8Gb disk, 4Gb RAM, and placed the .vdi image in an encrypted partition. The web services of Infocert's fattura-pa requires "Java (JRE) a 32bit di versione 1.6 o superiore".
  • I installed Ubuntu 12.04 on it: that is what dike declares to support.
  • I booted the VM, installed virtualbox-guest-utils, and de sure I also had virtualbox-guest-x11
  • I restarted the VM so that I could resize the virtualbox window and have Ubuntu resize itself as well. Now I could actually read popup error messages in full.
  • I changed the desktop background to something that gave me the idea that this is an untrusted machine where I need to be very careful of what I type. I went for bright red.

Install smart card software into it

  • apt-get install pcscd pcsc-tools opensc
  • In virtualbox, I went to Devices/USB devices and enabled the smart card reader in the virtual machine.
  • I ran pcsc_scan to see if it could see my smart card.
  • I ran Firefox, went to preferences, advanced, security devices, load. Module name is "CRS PKCS#11", module path is /usr/lib/opensc-pkcs11.so
  • I went to https://fattura-pa.infocamere.it/fpmi/service and I was able to log in. To log in, I had to type the PIN 4 times into popups that offered little explanations about what was going on, enjoying cold shivers because the smart card would lock itself at the 3rd failed attempt.
  • Congratulations to myself! I thought that all was set, but unfortunately, at this stage, I was not able to do anything else except log into the website.

Descent into darkness

Set up things for fattura-pa

  • I got the PDF with the setup instructions from here. Get it too, for a reference, a laugh, and in case you do not believe the instructions below.
  • I went to https://www.firma.infocert.it/installazione/certificato.php, and saved the two certificates.
  • Firefox, preferences, advanced, show certificates, I imported both CA certificates, trusted for everything, all my base are belong to them.
  • apt-get install icedtea-plugin
  • I went to https://fattura-pa.infocamere.it/fpmi/service and tried to sign. I could not: I got an error about invalid UTF8 for something or other in Firefox's stdandard error. Firefox froze and had to be killed.

Set up things for signing locally with dike

  • I removed icedtea so that I could use the site without firefox crashing.
  • I installed DiKe For Ubuntu 12.04 32bit
  • I ran dikeutil to see if it could talk to my smart card
  • When signing with the website, I chose the manual signing options and downloaded the zip file with the xml to be signed.
  • I got a zip file, unzipped it.
  • I loaded the xml into dike.
  • I signed it with dike.
  • I got this error message: "nessun certificato di firma presente sul dispositivo di firma" and then this error message: "Impossibile recuperare il certificato dal dispositivo di firma". No luck.

Set up things for signing locally with ArubaSign

  • I went to https://www.pec.it/Download.aspx
  • I downloaded ArubaSign for Linux 32 bit.
  • Oh! People say that it only works with Oracle's version of Java.
  • sudo add-apt-repository ppa:webupd8team/java
  • apt-get update
  • apt-get install oracle-java7-installer
  • During the installation process I had to agree to also sell my soul to Oracle.
  • tar axf ArubaSign*.tar*
  • cd ArubaSing-*/apps/dist
  • java -jar ArubaSign.jar
  • I let it download its own updates. Another time I did not. It does not seem to matter: I get asked that question every time I start it anyway.
  • I enjoyed the fancy brushed metal theme, and had an interesting time navigating an interface where every label on every icon or input field was truncated.
  • I downloaded https://www.pec.it/documenti/Manuale_ArubaSign2_firma%20Remota_V03_02_07_2012.pdf to get screenshots of that interface with all the labels intact
  • I signed the xml that I got from the website. I got told that I needed to really view carefully what I was signing, because the signature would be legally binding
  • I enjoyed carefully reading a legally binding, raw XML file.
  • I told it to go ahead, and there was now a .p7m file ready for me. I rejoiced, as now I might, just might actually get paid for my work.

Try fattura-pa again

Maybe fattura-pa would work with Oracle's Java plugin?

  • I went to https://fattura-pa.infocamere.it/fpmi/service
  • I got asked to verify java at www.java.com. I did it.
  • I told FireFox to enable java.
  • Suddenly, and while I was still in java.com's tab, I got prompted about allowing Infocert's applet to run: I allowed it to run.
  • I also got prompted several times, still while the current tab was not even Infocert's tab, about running components that could compromise the security of my system. I allowed and unblocked all of them.
  • I entered my PIN.
  • Congratulations! Now I have two ways of generating legally binding signatures with government issued smart cards!

Aftermath

I shut down that virtual machine and I'm making sure I never run anything important on it. Except, of course, generating legally binding signatures as required by the Italian government.

What could possibly go wrong?

Posted Thu Jul 2 23:48:36 2015 Tags:
Posted Sat Jun 6 00:57:39 2009

Bologna.

Pasto criminale

Si era in coda nella circonvallazione di San Giovanni in Persiceto per andare a una visita chirurgica all'USL di Crevalcore, quando si è notato sulla destra questo sbarazzino ristorante con un po' di patacche sulla porta da qualche guida, tra cui pure la Michelin: http://www.ristorantegiardinetto.it/

Tornati a casa, abbiamo googlato e chiesto a un po' di gente di San Giovanni, e nessuno lo conosceva. Una persona sana di mente avrebbe detto: "se la gente di San Giovanni non lo conosce, ci sarà un motivo". Noi ci siamo invece detti "se non lo conosce nessuno, andiamo a vedere".

La verità è: "Se la gente di San Giovanni va invece al Bertoldo, un motivo ci sarà".

Siamo entrati ottimisti. Menú tipico Bolognese, tortellini, passatelli, tortelloni di ricotta, bolliti. Piú "Menú del giorno" dedicato alla Sicilia con Pasta alla Norma e cose cosí. Bello.

Primi ordinati: Pasta alla Norma, Tortellini in Brodo.

Come secondi: Misto di verdure arrosto, Braciola di maiale. Avrei voluto lo zampone dal carrello dei bolliti, ma siccome è ancora troppo caldo i bolliti non li hanno, per cui ho ripiegato sulla braciola.

Dopo che il cameriere è andato via con l'ordine, mi è venuto il terribile dubbio: "ma se non siamo in stagione per i bolliti, con cosa lo fanno il brodo?".

Arrivano i primi. Dopo un'accurata ricerca che ci ha visti coinvolti entrambi abbiamo trovato una minuscola striciolina di melanzana in mezzo agli spaghetti, che ci ha confermato che effettivamente erano gli spaghetti alla Norma che avevamo ordinato e non un ordine sbagliato di spaghetti al sugo con aggiunta di unto.

I tortellini invece erano fatti a mano, pure piccoli (la sfoglina era brava), e se si scolava via con cura il brodo erano anche buoni.

Finiti i primi, il cameriere ha chiesto "tutto bene?" e io, candidamente ho detto "buoni i tortellini, peccato per il brodo". Non l'ha presa bene. Ha malcelatamente represso un attacco d'ira ed è scappato con la scusa di andarlo a dire al cuoco. È tornato poco dopo con una supercazzola che aveva a che fare col fondo della pentola, alla quale non abbiamo dato molto peso. Ha avuto il buon gusto di non chiedere com'erano gli "spaghetti alla Norma".

Arrivano i secondi. Verdure arrostite ustionanti dentro, che solo il microonde le sa scaldare cosí bene, e farcite di pangrattato intriso in sgradevole unto. In compenso, braciola di maiale talmente secca che solo a guardarla mi si sono asciugate anche le lacrime dagli occhi.

La braciola ho provato a campionarla in vari punti ma alla fine l'ho dovuta lasciare nel piatto. Ho poi aiutato a finire le verdure ai grassi saturi, che in confronto con la braciola erano di-vi-ne.

Quando il cameriere è arrivato a portar via i piatti, un po' rassegnato ha chiesto "non andava bene la braciola?". Ho risposto "sta scherzando?". Mi ha detto "se vuole gliela faccio rifare". Ho detto "grazie, ma è meglio di no". Ha insistito. Ho insistito che portasse il conto.

Il conto ci ha messo un po' ad arrivare. Alla fine ci hanno fatto pagare tutto a prezzo pieno nonostante le lamentele e la braciola lasciata lí. Dopo vado a cercare l'email del feedback della guida Michelin.

Il conto:

  • 2 Coperto e pane: 5€ (il costo di una pizza marinara)
  • 2 Minestra: 19€ (8€ spaghetti conditi con pomodoro e unto strizzato delle melanzane al forno; 11€ tortellini buoni devastati da un brodo indegno)
  • 2 Pietanza: 20€ (10€ verdure al gratin di grassi saturi e 10€ braciola di ieri scaldata col fòn)
  • 1/2 Sangiovese della casa: 5€ (stica)
  • 1l Acqua gasata: 2.50€
  • Totale: 51.50€

Bagno senza carta igienica, con l'asse sconnesso.

Fossimo stati in centro a Venezia il mese d'Agosto, uno lo dà per posto truffa per turisti. Ma nella Bassa, non saper cuocere una braciola, è criminale.

Volevo chiamare il 112: "pronto, vorrei la polizia. Buonasera. Sono in un ristorante a San Giovanni, Circ.ne Italia, 20. Si. Per favore venite subito. Si. Stanno insultando il buon nome del MAIALE. Si, nella Bassa. San Giovanni in Persiceto, ha capito bene. Ok, bene, vi aspetto."

Posted Thu Sep 17 23:59:44 2009 Tags:

Igiene pubblica

Stamattina:

  • Andare in via Gramsci 12
  • Andare alla porta 10 piano terra
  • Prendere il numero bianco con bordo blu
  • Aspettare (due ore)
  • Fare vaccino
  • Andare alla porta 22 piano terra
  • Pagare
  • Tornare alla porta 10 piano terra
  • Consegnare la ricevuta
  • Ritirare il certificato

Mi sono sentito come la tartaruga del logo.

Posted Sat Jun 6 00:57:39 2009 Tags:

Linux Day 2006

Fico!

L'anno scorso siamo finiti sui giornali, quest'anno addirittura al TG1, e con un ottimo servizio, pure.

Belli i talk a Bologna, che hanno avuto un taglio meno da programmatori e piú da creativi: è stato molto bello vedere come lavorano con Linux un musicista e un fotografo.

Mezzo fallito invece il LIP (Linux Installation Party), che ha visto pochi partecipanti. La spiegazione che va per la maggiore è che ormai non serve piú un gran aiuto per installare Linux, e salvo in quei computer che richiedono riti voodoo e santini di Sgala, le distribuzioni moderne van su da sole.

Mi piacciono i talk creativi: in Venezuela ho visto un talk fatto da un professionista di Blender del progetto Plumiferos: spettacolare!

Spettacolare allo stesso modo vedere ieri Daniele usare Ardour e un mare di altri sintetizzatori, effetti e periferiche Midi.

Obbligatoria nota cazzeggio: durante la cena abbiamo creato una grammatica polygen per generare nomi di ditte di informatica italiane. Per esempio:

  • Polpicess
  • Storpijet
  • Folpysekk
  • Pomygen
  • Polysperm
  • Polpydent
  • Polyjam

A quando il prossimo talk di sera?

Aggiunta: articolo su Linux.com.

Posted Sat Jun 6 00:57:39 2009 Tags:

Note sul talk del LinuxDay

Strumenti avanzati per il cazzeggio

Dal Linux Day 2005 di Bologna_.

Debian GNU/Linux è un sistema stabile, sicuro, completo e che risolve qualsiasi tipo di esigenza. Ma quando tutte le esigenze sono risolte? Quando tutti i bisogni sono appagati? Quando tutti i nostri sistemi funzionano affidabili e non possiamo neanche sentirci impegnati supervisionando il pirolare di un defrag? Ci servono maniere creative, geniali, totalmente inutili per perdere il nostro tempo. Fortunatamente, in questo talk ne vedremo un bel po'.

Questi sono gli appunti che ho usato per il talk. Frammentari, ma dovrebbero dare l'idea. Alla pagina del Linux Day 2005 di Bologna si trovano le registrazioni audio e anche quelle video quando saranno pronte.

Introduzione

Definizione

Lo definirei come una maniera di impiegare il tempo che sia creativa, ma soprattutto inutile. Inutile almeno secondo i canoni del rituale corrente e di massa della società, che impongono che le uniche cose utili sono quelle che richiedono ansia e fatica.

Il cazzeggio nella storia

Le piramidi.

Il cazzeggio nella letteratura

Il cazzeggio nell'arte

  • I Dadaisti (di nuovo)
  • Piero Manzoni
  • Marti Guixé

Nella scienza

  • I premi Ignobel

Parte 1: Software a linea di comando

Tool di base

  • sl
  • an (e poi sbagliarsi con man)
  • tama
  • vigor
  • an, wordplay
  • sysvbanner
  • dpkg -L bsdgames | grep /usr/games
    • bcd, ppt, morse
    • countmail
    • hangman
    • number
    • pig (man pig)
    • pom
    • quiz
    • random
    • wargames
  • robotfindskitten
  • fortune

Tool avanzati

Comandi:

dpkg -L filters
formail -I "" -s < .mail/debian-legal | dadadodo -
polygen bloccotraffico | lynx -dump -stdin
polygen uforobot | lynx -dump -stdin | grep -v '^$' | cowsay
for i in *.cow; do echo $i | cowsay -f `basename $i .cow`; done | less
polygen pythoniser | fmt | b1ff | cowsay -f eyes
polygen -X 50 unieuro | dadadodo - | festival --tts --language italian
polygen screensaver
randtype
bogosort

Parte 2: Software grafici

Tool di base

  • cappuccino
  • Orologi
    • sunclock, daliclock, xarclock -update 1
    • xearth
    • xplanet con gadgets
  • xteddy
  • kodo
  • xdesktopwaves
  • xlaby
  • xlaby + kodo

Tool avanzati

xscreensaver, xscreensaver-gl, rss-glx:

/usr/lib/xscreensaver/noseguy -program "polygen unieuro"
mkfifo pippo
tail -f pippo | festival --tts --language italian
/usr/lib/xscreensaver/noseguy -program "polygen unieuro|tee /home/enrico/pippo |fmt"
ll /usr/lib/xscreensaver
phosphor -program bash
phosphor -program ’xscreensaver-text | tee /dev/stderr | festival --tts’
(come si velocizza?)
phosphor -program 'polygen -X 50 unieuro | dadadodo - | tee /dev/stderr | festival --tts --language italian'
matrixview

Parte 3: Cazzeggio con strumenti seri

  • Quasi seri
    • debtags search game::toys
    • xtartan -list
    • gdesklets gkrellm
  • Seri
    • mappa caratteri + ctrl-shift
    • guppi
    • LDAP -- GEEZ! Multisync can do LDAP synchronization! I could add a new user in my mobile phone and have a UNIX account automatically created for it! :)
    • graphviz

Conclusione

  • xfs_fsr
Posted Sat Jun 6 00:57:39 2009 Tags:

Cena di alta classe

Interessante cena di alta classe al ristorante Il Sole di Trebbo di Reno:

[...] tra gli chef di nuova generazione, i più apprezzati, hanno mutato nel corso degli anni la cucina abbinando i piatti della tradizione regionale italiana all'elevata aspirazione alla ricerca, alla sperimentazione mai eccessiva, all'intuito per le novità, facendo dell'equilibrio tra storia e innovazione culinaria l'asso nella manica di questa locanda.

Non ho linkato il loro sito perché è un malvagio monoblocco in Flash e per punizione è introvabile in Google. Si può trovare la loro e-mail, a cui ho scritto per chiedere del menú di capodanno, ma non hanno mai risposto.

Ci andai coi miei vari anni fa e ci lasciò un buon ricordo, quindi ci son tornato con morosa a vedere se ne vale ancora la pena.

Abbiamo mangiato (vado a memoria e non sono descrizioni esatte):

Primi

Io: Cappellacci di ricciola al sapore di funghi con gelato di tartufo nero.

Lei: Zuppa di riso con tortelli di spigola, cime di rapa e odore di arancio.

Secondi

Una porzione in due di: Branzino con scampi arrostiti.

Dolce

Millefoglie allo stracchino con sale affumicato e salsa di kaki.

Vini

Pinot di San Michele Appiano, purtroppo non ricordo la cantina.

OLIVARES Dulce Monastrell spagnolo. Abbiamo chiesto al cuoco quale regione della Spagna, ma non è mai tornato indietro a dircelo. Google compensa: Murcia.

Commenti

In attesa del primo

Mini porzione di ricciola cruda con limone caramellato, paté di olive taggiasca e pappa al pomodoro. Buone le varie parti anche se non formavano un insieme: un assaggino non stupefacente, ma interessante.

Cappellacci di ricciola al sapore di funghi con gelato di tartufo nero

La pasta dei cappellacci non era male, anche se il ripieno mancava o di sale o di sapore, e per percepirlo bisognava prestare molta attenzione.

I funghi, erano amari come il veleno.

Il gelato di tartufo nero, in onore al tartufo nero del tartufo aveva l'odore ma non il sapore. Il sapore era un vago dolcino.

Il sapore che è rimasto in bocca era lo spiacevole amaro dei funghi.

Zuppa di riso con tortelli di spigola, cime di rapa e odore di arancio

La zuppa aveva una consistenza vinilica e un sapore assente. Al primo assaggio il pensiero di entrambi è stato: "si offendono se chiedo del sale?".

I tortelli avevano una buona pasta, il ripieno era percettibile ma l'odore di pesce non era contrastato piú di tanto dall'arancio (che ci stava benino) ma dalle cime di rapa, sgradevolmente amare.

Il sapore che è rimasto in bocca era lo sgradevole amaro delle cime di rapa.

Branzino con scampi arrostiti

Al primo assaggio il branzino non era male, ma al secondo assaggio non diceva piú molto: un po' di sale io ce lo avrei messo. Lo scampo era buono, ma era servito in una specie di lana di patata nera fritta che sapeva di patatine fritte e ne copriva quasi interamente il sapore.

In attesa del dolce

Pallina di gelato alla fragola con sopra una fragola.

Il gelato era fatto con fragole buone, cosa che ho apprezzato, ma a parte gli ingredienti la struttura non ci ha stupiti: a Bologna ci si è abituati a standard di gelato molto alti.

In uno dei due piattini abbiamo trovato un corpo estraneo che stiamo ancora cercando di convincerci non fosse un'unghia. Mi pento di non aver chiamato il cameriere per spiegazioni, è l'abitudine da viaggiatore ad avere poche pippe per questo genere di cose.

Millefoglie allo stracchino con sale affumicato e salsa di kaki

Decisamente il top della serata, verrà ricordato per lungo tempo.

La sfoglia del millefoglie era un capolavoro: ottima da tutti i punti di vista: veramente un piacere.

A romperla col cucchiaio e a sentirla sotto i denti la bocca si aspetta, esige di trovarci in mezzo qualcosa di altrettanto grandioso, e ci rimane male quando ci trova, ebbene sí, dello stracchino che sa di stracchino.

Delusione. Ma non è finita, perché poi arriva il sale affumicato, e a quel punto si entra in un nuovo mondo. Giuro, non ho mai provato nulla di cosí creativamente rivoltante. Mi sono sforzato di finirlo per trovargli un senso, ma niente: se ci ripenso mi viene la nausea. È la prima volta che la parola migliore che trovo per descrivere un dessert è offensivo.

La salsa di cachi che decorava il piatto non era male, ma non poteva che assistere impotente alla tragedia.

Lo stomaco si sta ancora lamentando: non per la difficoltà di digestione, ma per la rabbia del vedere varie parti tutte di alta qualità unite nello scempio di una cacofonia cosí disgustosa.

È la prima volta che il mio stomaco non vuol digerire perché si sente preso in giro.

Dopo il dolce

Un assaggio di dolcetti piú o meno interessanti, su cui spiccava una ciotolina di crema che per entrambi aveva una netta dominante di cloro sotto la quale il sapore di uovo non era neanche male.

Servizio

  • Gli altri tavoli hanno avuto piú assaggetti di pane di noi: a noi solo dei grissini che a me sono parsi un po' vecchi e a lei troppo unti.
  • Vorrei vedere l'etichetta sulla bottiglia mentre mi si fa assaggiare il vino: e invece, era girata dall'altra parte.
  • Mi va bene se uno ha il menú in inglese ma non parla inglese, ma almeno voglio che mi si dia il tempo di tradurre. Non tollero di vedere una faccia irritata se chiedo al cameriere una pausa per tradurre.
  • Se ti chiedo da che parte della Spagna viene il vino da dessert e sei il cuoco che me lo ha suggerito, mi aspetto che tu lo sappia. Se mi dici che non lo sai e che vai a vedere, poi torna anche indietro a dirmelo.

Gli altri clienti

Uno dice magari non ci hanno presi sul serio perché venivamo da un pomeriggio a passeggio per il centro ed eravamo in jeans: come stile sarebbe da migliorare.

Però... però noi non andiamo a fumare in bagno (che poi puzza!) e dopo aver usato il mini asciugamanino di tela monouso lo riponiamo nella cesta degli asciugamanini di tela monouso usati, invece di ripiegarlo e rimetterlo bagnato nella pila di quelli puliti.

Prezzo

Cose che si possono fare allo stesso prezzo:

  • Una cena da Buriani o al Dolce e Salato.
  • Una cena a base di tartufo bianco alla trattoria La Rosa a Sant'Agostino.
  • Una signora mangiata di pesce per due persone alla Giara ad Altedo.
  • Pranzo a base di tartufo bianco a Cà Gabrielli al Corno alle Scale e giornata sulla neve, incluso benzina per il viaggio, skipass e nolo sci.

Questa entry di blog è stata scritta per rappacificarmi col mio stomaco, che prima di iniziare la digestione ha richiesto una chiara presa di posizione.

Ergo, chiara presa di posizione: stasera abbiamo mangiato male.

Vediamo se ora il mio stomaco mi permette di dormire.

Posted Sat Jun 6 00:57:39 2009 Tags:

Allucinazioni

Bologna, 14 dicembre 2005.

Stamattina andavo a Bologna in macchina (capita raramente, ma odio quando capita).

Al primo maggio tiro dritto per andare in via Colombo e la coda dell'occhio tira su un cartellone dei saldi da un capannone sulla destra.

C'è qualcosa di strano. Guardo meglio.

"Niente piú telefonate! Svendita totale per cambio gestione"

Sorrido: il capannone era "Il Mobile di Castel Maggiore".

Posted Sat Jun 6 00:57:39 2009 Tags:
Posted Sat Jun 6 00:57:39 2009

Pages about Turbogears.

Custom function decorators with TurboGears 2

I am exposing some library functions using a TurboGears2 controller (see web-api-with-turbogears2). It turns out that some functions return a dict, some a list, some a string, and TurboGears 2 only allows JSON serialisation for dicts.

A simple work-around for this is to wrap the function result into a dict, something like this:

@expose("json")
@validate(validator_dispatcher, error_handler=api_validation_error)
def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
    # Call API
    res = self.engine.list_colours(filter, productID, maxResults)

    # Return result
    return dict(r=res)

It would be nice, however, to have an @webapi() decorator that automatically wraps the function result with the dict:

def webapi(func):
    def dict_wrap(*args, **kw):
        return dict(r=func(*args, **kw))
    return dict_wrap

# ...in the controller...

    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    @webapi
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)

        # Return result
        return res

This works, as long as @webapi appears last in the list of decorators. This is because if it appears last it will be the first to wrap the function, and so it will not interfere with the tg.decorators machinery.

Would it be possible to create a decorator that can be put anywhere among the decorator list? Yes, it is possible but tricky, and it gives me the feeling that it may break in any future version of TurboGears:

class webapi(object):
    def __call__(self, func):
        def dict_wrap(*args, **kw):
            return dict(r=func(*args, **kw))
        # Migrate the decoration attribute to our new function
        if hasattr(func, 'decoration'):
            dict_wrap.decoration = func.decoration
            dict_wrap.decoration.controller = dict_wrap
            delattr(func, 'decoration')
        return dict_wrap

# ...in the controller...

    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    @webapi
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)

        # Return result
        return res

As a convenience, TurboGears 2 offers, in the decorators module, a way to build decorator "hooks":

class before_validate(_hook_decorator):
    '''A list of callables to be run before validation is performed'''
    hook_name = 'before_validate'

class before_call(_hook_decorator):
    '''A list of callables to be run before the controller method is called'''
    hook_name = 'before_call'

class before_render(_hook_decorator):
    '''A list of callables to be run before the template is rendered'''
    hook_name = 'before_render'

class after_render(_hook_decorator):
    '''A list of callables to be run after the template is rendered.

    Will be run before it is returned returned up the WSGI stack'''

    hook_name = 'after_render'

The way these are invoked can be found in the _perform_call function in tg/controllers.py.

To show an example use of those hooks, let's add a some polygen wisdom to every data structure we return:

class wisdom(decorators.before_render):
    def __init__(self, grammar):
        super(wisdom, self).__init__(self.add_wisdom)
        self.grammar = grammar
    def add_wisdom(self, remainder, params, output):
        from subprocess import Popen, PIPE
        output["wisdom"] = Popen(["polyrun", self.grammar], stdout=PIPE).communicate()[0]

# ...in the controller...

    @wisdom("genius")
    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
    
        # Return result
        return res

These hooks cannot however be used for what I need, that is, to wrap the result inside a dict. The reason is because they are called in this way:

        controller.decoration.run_hooks(
                'before_render', remainder, params, output)

and not in this way:

        output = controller.decoration.run_hooks(
                'before_render', remainder, params, output)

So it is possible to modify the output (if it is a mutable structure) but not to exchange it with something else.

Can we do even better? Sure we can. We can assimilate @expose and @validate inside @webapi to avoid repeating those same many decorator lines over and over again:

class webapi(object):
    def __init__(self, error_handler = None):
        self.error_handler = error_handler

    def __call__(self, func):
        def dict_wrap(*args, **kw):
            return dict(r=func(*args, **kw))
        res = expose("json")(dict_wrap)
        res = validate(validator_dispatcher, error_handler=self.error_handler)(res)
        return res

# ...in the controller...

    @expose("json")
    def api_validation_error(self, **kw):
        pylons.response.status = "400 Error"
        return dict(e="validation error on input fields", form_errors=pylons.c.form_errors)

    @webapi(error_handler=api_validation_error)
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)

        # Return result
        return res

This got rid of @expose and @validate, and provides almost all the default values that I need. Unfortunately I could not find out how to access api_validation_error from the decorator so that I can pass it to the validator, therefore I remain with the inconvenience of having to explicitly pass it every time.

Posted Wed Nov 4 17:52:38 2009 Tags:

Building a web-based API with Turbogears2

I am using TurboGears2 to export a python API over the web. Every API method is wrapper by a controller method that validates the parameters and returns the results encoded in JSON.

The basic idea is this:

@expose("json")
def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
    # Call API
    res = self.engine.list_colours(filter, productID, maxResults)

    # Return result
    return res

To validate the parameters we can use forms, it's their job after all:

class ListColoursForm(TableForm):
    fields = [
            # One field per parameter
            twf.TextField("filter", help_text="Please enter the string to use as a filter"),
            twf.TextField("productID", help_text="Please enter the product ID"),
            twf.TextField("maxResults", validator=twfv.Int(min=0), default=200, size=5, help_text="Please enter the maximum number of results"),
    ]
list_colours_form=ListColoursForm()

#...

    @expose("json")
    @validate(list_colours_form, error_handler=list_colours_validation_error)
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Parameter validation is done by the form
    
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
    
        # Return result
        return res

All straightforward so far. However, this means that we need two exposed methods for every API call: one for the API call and one error handler. For every API call, we have to type the name several times, which is error prone and risks to get things mixed up.

We can however have a single error handler for all methonds:

def get_method():
    '''
    The method name is the first url component after the controller name that
    does not start with 'test'
    '''
    found_controller = False
    for name in pylons.c.url.split("/"):
        if not found_controller and name == "controllername":
            found_controller = True
            continue
        if name.startswith("test"):
            continue
        if found_controller:
            return name
    return None

class ValidatorDispatcher:
    '''
    Validate using the right form according to the value of the "method" field
    '''
    def validate(self, args, state):
        method = args.get("method", None)
    # Extract the method from the URL if it is missing
        if method is None:
            method = get_method()
            args["method"] = method
        return forms[method].validate(args, state)

validator_dispatcher = ValidatorDispatcher()

This validator will try to find the method name, either as a form field or by parsing the URL. It will then use the method name to find the form to use for validation, and pass control to the validate method of that form.

We then need to add an extra "method" field to our forms, and arrange the forms inside a dictionary:

class ListColoursForm(TableForm):
    fields = [
            # One hidden field to have a place for the method name
            twf.HiddenField("method")
            # One field per parameter
            twf.TextField("filter", help_text="Please enter the string to use as a filter"),
    #...

forms["list_colours"] = ListColoursForm()

And now our methods become much nicer to write:

    @expose("json")
    def api_validation_error(self, **kw):
        pylons.response.status = "400 Error"
        return dict(form_errors=pylons.c.form_errors)

    @expose("json")
    @validate(validator_dispatcher, error_handler=api_validation_error)
    def list_colours(self, filter=None, productID=None, maxResults=100, **kw):
        # Parameter validation is done by the form
    
        # Call API
        res = self.engine.list_colours(filter, productID, maxResults)
    
        # Return result
        return res

api_validation_error is interesting: it returns a proper HTTP error status, and a JSON body with the details of the error, taken straight from the form validators. It took me a while to find out that the form errors are in pylons.c.form_errors (and for reference, the form values are in pylons.c.form_values). pylons.response is a WebOb Response that we can play with.

So now our client side is able to call the API methods, and get a proper error if it calls them wrong.

But now that we have the forms ready, it doesn't take much to display them in web pages as well:

def _describe(self, method):
    "Return a dict describing an API method"
    ldesc = getattr(self.engine, method).__doc__.strip()
    sdesc = ldesc.split("\n")[0]
    return dict(name=method, sdesc = sdesc, ldesc = ldesc)

@expose("myappserver.templates.myappapi")
def index(self):
    '''
    Show an index of exported API methods
    '''
    methods = dict()
    for m in forms.keys():
        methods[m] = self._describe(m)
    return dict(methods=methods)

@expose('myappserver.templates.testform')
def testform(self, method, **kw):
    '''
    Show a form with the parameters of an API method
    '''
    kw["method"] = method
    return dict(method=method, action="/myapp/test/"+method, value=kw, info=self._describe(method), form=forms[method])

@expose(content_type="text/plain")
@validate(validator_dispatcher, error_handler=testform)
def test(self, method, **kw):
    '''
    Run an API method and show its prettyprinted result
    '''
    res = getattr(self, str(method))(**kw)
    return pprint.pformat(res)

In a few lines, we have all we need: an index of the API methods (including their documentation taken from the docstrings!), and for each method a form to invoke it and a page to see the results.

Make the forms children of AjaxForm, and you can even see the results together with the form.

Posted Thu Oct 15 15:45:39 2009 Tags:

Passing values to turbogears widgets at display time (the general case)

Last time I dug this up I was not clear enough in documenting my findings, so I had to find them again. Here is the second attempt.

In Turbogears, in order to pass parameters to arbitrary widgets in a compound widget, the syntax is:

form.display(PARAMNAME=dict(WIDGETNAME=VALUE))

And if you have more complex nested widgets and would like to know what goes on, this monkey patch is good for inspecting the params lookup functions:

import turbogears.widgets.forms
old_rpbp = turbogears.widgets.forms.retrieve_params_by_path
def inspect_rpbp(params, path):
    print "RPBP", repr(params), repr(path)
    res = old_rpbp(params, path)
    print "RPBP RES", res
    return res
turbogears.widgets.forms.retrieve_params_by_path = inspect_rpbp

The code for the lookup itself is, as the name suggests, in the retrieve_params_by_path function in the file widgets/forms.py in the Turbogears source code.

Posted Sat Jun 6 00:57:39 2009 Tags:

Quirks when overriding SQLObject setters

Let's suppose you have a User that is, optionally, a member of a Company. In SQLObject you model it somehow like this:

    class Company(SQLObject):
        name = UnicodeCol(length=16, alternateID=True, alternateMethodName="by_name")
        display_name = UnicodeCol(length=255)

    class User(InheritableSQLObject):
        company = ForeignKey("Company", notNull=False, cascade='null')

Then you want to implement a user settings interface that uses a Select box to choose the company of the user.

For the Select widget to properly handle the validator for your data, you need to put a number in the first option. As my first option, I want to have the "None" entry, so I decided to use -1 to mean "None".

Now, to make it all blend nicely, I overrode the company setter to accept -1 and silently convert it to a None:

    class User(InheritableSQLObject):
        company = ForeignKey("Company", notNull=False, cascade='null')

        def _set_company(self, id):
            "Set the company id, using None if -1 is given"
            if id == -1: id = None
            self._SO_set_company(id)

In the controller, after parsing and validating all the various keyword arguments, I do something like this:

            user.set(**kw)

Now, the overridden method didn't get called.

After some investigation, and with the help of NandoFlorestan on IRC, we figured out the following things:

  1. That method needs to be rewritten as _set_companyID:

            def _set_companyID(self, id):
                "Set the company id, using None if -1 is given"
                if id == -1: id = None
                self._SO_set_companyID(id)
    
  2. Methods overridden in that way are alsop called by user.set(**kw), but not by the User(**kw) constructor, so using, for example, a similar override to transparently encrypt passwords would give you plaintext passwords for new users and encrypted passwords after they changed it.

Posted Sat Jun 6 00:57:39 2009 Tags:

Turbogears i18n quirks

Collecting strings from .kid files

tg-admin i18n collect won't collect strings from your .kid files: you need the toolbox web interface for that.

Indentation problems in .kid files

The toolbox web interface chokes on intentation errors on your .kid files.

To see the name of the .kid file that causes the error, look at the tg-admin toolbox output in the terminal for lines like Working on app/Foo/templates/bar.kid.

What happens is that the .kid files are converted to python files, and if there are indentation glitches they end up in the python files, and python will complain.

Once you see from the tg-admin toolbox standard error what is the .kid file with the problem, edit it and try to make sure that all closing tags are at the exact indentation level as their coresponding opening tags. Even a single space would matter.

Bad i18n bug in TurboKid versions earlier than 1.0.1

faide on #turbogears also says:

It is of outmost importance that you use TurboKid 1.0.1 because it is the first version that corrects a BIG bug regarding i18n filters ...

The version below had a bug where the filters kept being added at each page load in such a way that after a few hundreds of pages you could have page loading times as long as 5 minutes!

If one has a previous version of TurboKid, one (and only one) of these is needed:

So, in short, all i18n users should upgrade to TurboGears 1.0.2.2 or patch TurboKid using http://trac.turbogears.org/ticket/1301.

Posted Sat Jun 6 00:57:39 2009 Tags:

Turbogears quirks when testing controllers that use SingleSelectField

Suppose you have a User that can be a member of a Company. In SQLObject you model it somehow like this:

    class Company(SQLObject):
        name = UnicodeCol(length=16, alternateID=True, alternateMethodName="by_name")
        display_name = UnicodeCol(length=255)

    class User(InheritableSQLObject):
        company = ForeignKey("Company", notNull=False, cascade='null')

Then you want to make a form that allows to choose what is the company of a user:

def companies():
    return [ [ -1, 'None' ] ] + [ [c.id, c.display_name] for c in Company.select() ]

class NewUserFields(WidgetsList):
    """Fields for editing general settings"""
    user_name = TextField(label="User name")
    companyID = SingleSelectField(label="Company", options=companies)

Ok. Now you want to run tests:

  1. nosetests imports the controller to see if there's any initialisation code.
  2. The NewUserFields class is created.
  3. The SingleSelectField is created.
  4. The SingleSelectField constructor tries to guess the validator and peeks at the first option.
  5. This calls companies.
  6. companies accesses the database.
  7. The testing database has not yet been created because nosetests imported the module before giving the test code a chance to setup the test database.
  8. Bang.

The solution is to add an explicit validator to disable this guessing code that is a source of so many troubles:

class NewUserFields(WidgetsList):
    """Fields for editing general settings"""
    user_name = TextField(label="User name")
    companyID = SingleSelectField(label="Company", options=companies, validator=v.Int(not_empty=True))
Posted Sat Jun 6 00:57:39 2009 Tags:

File downloads with TurboGears

In TurboGears, I had to implement a file download method, but the file required access controls so it was put in a directory not exported by Apache.

In #turbogears I've been pointed at: http://cherrypy.org/wiki/FileDownload and this is everything put together:

from cherrypy.lib.cptools import serveFile
# In cherrypy 3 it should be:
#from cherrypy.lib.static import serve_file

@expose()
def get(self, *args, **kw):
    """Access the file pointed by the given path"""
    pathname = check_auth_and_compute_pathname()
    return serveFile(pathname)

Then I needed to export some CSV:

@expose()
def getcsv(self, *args, **kw):
    """Get the data in CSV format"""
    rows = compute_data_rows()
    headers = compute_headers(rows)
    filename = compute_file_name()

    cherrypy.response.headers['Content-Type'] = "application/x-download"
    cherrypy.response.headers['Content-Disposition'] = 'attachment; filename="'+filename+'"'

    csvdata = StringIO.StringIO()
    writer = csv.writer(csvdata)
    writer.writerow(headers)
    writer.writerows(rows)

    return csvdata.getvalue()

In my case it's not an issue as I can only compute the headers after I computed all the data, but I still have to find out how to serve the CSV file while I'm generating it, instead of storing it all into a big string and returning the big string.

Posted Sat Jun 6 00:57:39 2009 Tags:

Passing values to turbogears widgets at display time

In turbogears, I often need to pass data to widgets at display time. Sometimes it works automatically, but sometimes, in cases like passing option lists to CheckBoxLists or number of repetitions in a RepeatingFieldSet, it doesn't.

All the examples use precomputed lists or pass simple code functions. In most of my cases, I want them computed by the controller every time.

Passing a function hasn't worked, as I did not find any obvious way to have the function know about the controller.

So I need to pass things the display() method of the widgets, but I could not work out how to pass the option list and default list for a CheckBoxList that is part of a WidgetsList in a TableForm.

On IRC came the answer, thanks to Xentac:

you should be able to...
    tableform.display(options=dict(checkboxname=[optionlist]))

And yes, it works. I can pass the default value as one of the normal form values:

    tableform.display(values=dict(checkboxname=[values]), options=dict(checkboxname=[optionlist]))
Posted Sat Jun 6 00:57:39 2009 Tags:

Linking to self in turbogears

I want to put in my master.kid some icons that allow to change the current language for the session.

First, all user-accessible methods need to handle a 'language' parameter:

@expose(template="myapp.templates.foobar")
def index(self, someparam, **kw):
    if 'language' in kw: turbogears.i18n.set_session_locale(kw['language'])

Then, we need a way to edit the current URL so that we can generate modified links to self that preserve the existing path_info and query parameters. In your main controller, add:

def linkself(**kw):
    params = {}
    params.update(cherrypy.request.params)
    params.update(kw)
    url = cherrypy.request.browser_url.split('?', 1)[0]
    return url + '?' + '&'.join(['='.join(x) for x in params.iteritems()])

def add_custom_stdvars(vars):
    return vars.update({"linkself": linkself})

turbogears.view.variable_providers.append(add_custom_stdvars)

(see the turbogears stdvars documentation and the cherrypy request documentation (cherrypy 2 documentation at the bottom of the page))

And finally, in master.kid:

<div id="footer">
  <div id="langselector">
    <span class="language">
      <a href="${tg.linkself(language='it_IT')}">
        <img src="${tg.url('/static/images/it.png')}"/>
      </a>
    </span>

    <span class="language">
      <a href="${tg.linkself(language='C')}">
        <img src="${tg.url('/static/images/en.png')}"/>
      </a>
    </span>
  </div><!-- langselector -->
</div><!-- footer -->
Posted Sat Jun 6 00:57:39 2009 Tags:

TurboGears RemoteForm tip

In case your RemoteForm misteriously behaves like a normal HTTP form, refreshing the page on submit, and the only hint that there's something wrong is this bit in the Iceweasel's error console:

Errore: uncaught exception: [Exception... "Component returned failure
code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIXMLHttpRequest.open]"
nsresult: "0x80070057 (NS_ERROR_ILLEGAL_VALUE)"  location: "JS frame ::
javascript: eval(__firebugTemp__); :: anonymous :: line 1"  data: no]

the problem can just be a missing action= attribute to the form.

I found out after:

  1. reading the TurboGears remoteform wiki: "For some reason, the RemoteForm is acting like a regular html form, serving up a new page instead of performing the replacements we're looking for. I'll update this page as soon as I figure out why this is happening."

  2. finding this page on Google and meditating for a while while staring at it. I don't speak German, but often enough I manage to solve problems after meditating over Google results in all sorts of languages unknown or unreadable to me. I will call this practice Webomancy.

Posted Sat Jun 6 00:57:39 2009 Tags:
Posted Sat Jun 6 00:57:39 2009
sw

Software

debtags.debian.org cleaned up

Since the Debtags consolidation announcement there are some more news:

No more anonymous submissions

  • I have disabled anonymous tagging. Anyone is still able to tag via Debian Single Sign-On. SSO-enabling the site was as simple as this.
  • Tags need no review anymore to be sent to ftp-master. I have removed all the distinction in the code between reviwed and unreviewed tags, and all the code for the tag review interface.
  • The site now has an audit log for each user, that any person logged in via SSO can access via the "history" link in the top right of the tag editor page.

Official recognition as Debian Contributors

  • Tag contributions are sent to contributors.debian.org. There is no historical data for them because all submissions until now have been anonymous, but from now on if you tag packages you are finally recognised as a Debian Contributor!

Mailing lists closed

  • I closed the debtags-devel and debtags-commits mailing lists; the archives are still online.
  • I have updated the workflow for suggesting new tags in the FAQ to "submit a bug to debtags and Cc debian-devel"

We can just use debian-devel instead of debtags-devel.

Autotagging of trivial packages

  • I have introduced the concept of "trivial" packages to currently be any package in the libs, oldlibs and debug sections. They are tagged automatically by the site maintenance and are excluded from the site todo lists and tag editor. We do not need to bother about trivial packages anymore, all 13239 of them.

Miscellaneous other changes

  • I have moved the debtags vocabulary from subversion to git
  • I have renamed the tag used to mark packages not yet reviewed by humans from special::not-yet-tagged to special::unreviewed
  • At the end of every nightly maintenance, some statistics are saved into a database table. I have collected 10 years of historical data by crunching big tarballs of site backups, and fed them to the historical stats table.
  • The workflow for getting tags from the site to ftp-master is now far, far simpler. It is almost simple enough that I should manage to explain it without needing to dig through code to see what it is actually doing.
Posted Fri Feb 5 19:18:50 2016 Tags:

Downgrading network-manager

This morning I woke up. Bad idea.

I find in the work mail a compiler error that I cannot reproduce, so I need to log into a machine at work. But #809195.

I decided to downgrade network-manager. I recall there was a tool to download packages from snapshots.debian.org, I discussed it recently on IRC, let's sync the IRC logs from my server. Or not (#810212).

Never mind, I'll log into the server and grep. Ooh, it's debsnap. However, it doesn't quite do what I hoped (#667712).

After some help from #debian-devel (thanks jcristau and LebedevRI), here is how to downgrade network-manager:

# echo "deb http://snapshot.debian.org/archive/debian/20151125T155830Z/ sid main" >> /etc/apt/sources.list.d/tmp-downgrade-nm.list
# apt -o Acquire::Check-Valid-Until=false update
# apt -o Acquire::Check-Valid-Until=false install network-manager=1.0.6-1
# rm /etc/apt/sources.list.d/tmp-downgrade-nm.list
# service network-manager restart

And as user:

$ killall nm-applet
$ nm-applet &

The yak is now nice and shaved, I can now go and see what those compiler errors are all about.

Actually, no, there was still an unshaved patch on the yak, and now we have a debcya script.

Posted Thu Jan 7 11:37:19 2016 Tags:

When Akonadi silently fails to sync your calendar...

Bug severity: seriously ruining my life.

Try to use korganizer to create a calendar entry when the server is not reachable (say, you are offline, or you typed the wrong password), and you may find that you end up with no error messages, an entry that shows up perfectly fine, but that will never be synced to the server, ever again.

I use korganizer, radicale and caldav for important things. The practical ramifications of me inserting entries in korganizer, seeing that everything looks ok, and then not finding them on my phone while on the go, are scary.

Think of things like importing .ics files with flight schedules, entering tax deadlines, time and places for customer meetings, time and places of arrival of loved ones I'm supposed to pick up.

I spent time setting up my own infrastructure for this exactly because I care that all of this works reliably.

And now I urgently took a morning off work to find a way to detect those entries that Akonadi is refusing to update,

The whole thing is cumbersome to run, but if you are using kdepim-based tools to manage your calendars and sync them across devices, you may want to give it a go every once in a while.

You can find the script and the notes I took so far on the issue at https://github.com/spanezz/akonadi-workarounds.

Posted Tue Dec 1 14:01:09 2015 Tags:

Italian Fattura Elettronica with OpenSSL

I have had some success signing an Italian fattura elettronica with OpenSSL.

I am amazed to realise that the software they gave me to do the job is of such bad quality that I felt like spending a few hours trying to do the same thing with OpenSSL instead.

Posted Fri Oct 23 10:35:53 2015 Tags:

Extracting XML payload from Italian Fattura Elettronica zipfiles

This system does not even export to PDF. In order to provide my accountant with something better than a DER-encoded file with a random-looking name stored inside a zipfile, here is a script that at least extracts the unsigned XML payload out of a saved Fattura Elettronica.

If you're giving a python course in Italy, this sounds like a nice early programming assignment.

Posted Fri Oct 9 11:52:04 2015 Tags:

If you happen to know a browser developer...

Do you happen to know a developer of Firefox or Chrome or some other mainstream browser?

If so, can you please talk to them about our experiments with Client Certificate authentication in Debian?

Client Certificate authentication rocks; with just a couple of little tweaks in the interface, it would be pretty close to perfect.

Visiting sites without using a certificate

If I want to browse a site unauthenticated instead of using a certificate, at the moment I can hit "Cancel" on the certificate popup menu, and it works nicely. I feel quite confused when I do that, though, because it's not clear to me if I am canceling use of certificates, or canceling the visit to the site.

Can you please change the wording on the Cancel button to something more descriptive?

See/change current certificate selection

My top wish is, once I choise to use (or not use) a certificate for a site, to be able to see which certificate I'm using and possibly change it.

At the moment I did not find a way to see what certificate I'm using, and the browser will remember the choice until it gets closed and reopened.

At the moment I can use a Private or Incognito window to switch identities or to stop authenticated access and continue anonymously, and that helps me immensely.

I think however that the ultimate solution could be to have the https lockpad popup show an indication of what certificate is currently being used, and offer a way to re-trigger certificate selection. That would be so cool.

Also, once the certificate choice can be seen and changed at any time, it could just get remembered so that sites can be visited again without any prompts, even after the browser has been closed and reopened. That would be, to me, the ultimate convenience.

Thanks! <3

Thank you very much for all the work you have already put into this: I have been told that a few years ago using client certificate was unthinkable, and now it seems to be down to just a couple of papercuts. And SPKAC/keygen seriously rocks!

I have been constantly impressed by how well this all works right now.

Posted Tue Sep 1 17:25:04 2015 Tags:

Billing an Italian public administration

Here's a simple guide for how I managed to bill one of my customers as is now mandated by law in Italy.

Create a new virtualbox machine

I would never do any of this to any system I would ever want to use for anything else, so it's virtual machine time.

  • I started virtualbox, created a new machine for Ubuntu 32bit, 8Gb disk, 4Gb RAM, and placed the .vdi image in an encrypted partition. The web services of Infocert's fattura-pa requires "Java (JRE) a 32bit di versione 1.6 o superiore".
  • I installed Ubuntu 12.04 on it: that is what dike declares to support.
  • I booted the VM, installed virtualbox-guest-utils, and de sure I also had virtualbox-guest-x11
  • I restarted the VM so that I could resize the virtualbox window and have Ubuntu resize itself as well. Now I could actually read popup error messages in full.
  • I changed the desktop background to something that gave me the idea that this is an untrusted machine where I need to be very careful of what I type. I went for bright red.

Install smart card software into it

  • apt-get install pcscd pcsc-tools opensc
  • In virtualbox, I went to Devices/USB devices and enabled the smart card reader in the virtual machine.
  • I ran pcsc_scan to see if it could see my smart card.
  • I ran Firefox, went to preferences, advanced, security devices, load. Module name is "CRS PKCS#11", module path is /usr/lib/opensc-pkcs11.so
  • I went to https://fattura-pa.infocamere.it/fpmi/service and I was able to log in. To log in, I had to type the PIN 4 times into popups that offered little explanations about what was going on, enjoying cold shivers because the smart card would lock itself at the 3rd failed attempt.
  • Congratulations to myself! I thought that all was set, but unfortunately, at this stage, I was not able to do anything else except log into the website.

Descent into darkness

Set up things for fattura-pa

  • I got the PDF with the setup instructions from here. Get it too, for a reference, a laugh, and in case you do not believe the instructions below.
  • I went to https://www.firma.infocert.it/installazione/certificato.php, and saved the two certificates.
  • Firefox, preferences, advanced, show certificates, I imported both CA certificates, trusted for everything, all my base are belong to them.
  • apt-get install icedtea-plugin
  • I went to https://fattura-pa.infocamere.it/fpmi/service and tried to sign. I could not: I got an error about invalid UTF8 for something or other in Firefox's stdandard error. Firefox froze and had to be killed.

Set up things for signing locally with dike

  • I removed icedtea so that I could use the site without firefox crashing.
  • I installed DiKe For Ubuntu 12.04 32bit
  • I ran dikeutil to see if it could talk to my smart card
  • When signing with the website, I chose the manual signing options and downloaded the zip file with the xml to be signed.
  • I got a zip file, unzipped it.
  • I loaded the xml into dike.
  • I signed it with dike.
  • I got this error message: "nessun certificato di firma presente sul dispositivo di firma" and then this error message: "Impossibile recuperare il certificato dal dispositivo di firma". No luck.

Set up things for signing locally with ArubaSign

  • I went to https://www.pec.it/Download.aspx
  • I downloaded ArubaSign for Linux 32 bit.
  • Oh! People say that it only works with Oracle's version of Java.
  • sudo add-apt-repository ppa:webupd8team/java
  • apt-get update
  • apt-get install oracle-java7-installer
  • During the installation process I had to agree to also sell my soul to Oracle.
  • tar axf ArubaSign*.tar*
  • cd ArubaSing-*/apps/dist
  • java -jar ArubaSign.jar
  • I let it download its own updates. Another time I did not. It does not seem to matter: I get asked that question every time I start it anyway.
  • I enjoyed the fancy brushed metal theme, and had an interesting time navigating an interface where every label on every icon or input field was truncated.
  • I downloaded https://www.pec.it/documenti/Manuale_ArubaSign2_firma%20Remota_V03_02_07_2012.pdf to get screenshots of that interface with all the labels intact
  • I signed the xml that I got from the website. I got told that I needed to really view carefully what I was signing, because the signature would be legally binding
  • I enjoyed carefully reading a legally binding, raw XML file.
  • I told it to go ahead, and there was now a .p7m file ready for me. I rejoiced, as now I might, just might actually get paid for my work.

Try fattura-pa again

Maybe fattura-pa would work with Oracle's Java plugin?

  • I went to https://fattura-pa.infocamere.it/fpmi/service
  • I got asked to verify java at www.java.com. I did it.
  • I told FireFox to enable java.
  • Suddenly, and while I was still in java.com's tab, I got prompted about allowing Infocert's applet to run: I allowed it to run.
  • I also got prompted several times, still while the current tab was not even Infocert's tab, about running components that could compromise the security of my system. I allowed and unblocked all of them.
  • I entered my PIN.
  • Congratulations! Now I have two ways of generating legally binding signatures with government issued smart cards!

Aftermath

I shut down that virtual machine and I'm making sure I never run anything important on it. Except, of course, generating legally binding signatures as required by the Italian government.

What could possibly go wrong?

Posted Thu Jul 2 23:48:36 2015 Tags:

debtags rewritten in python3

In my long quest towards closing #540218, I have uploaded a new libept to experimental. Then I tried to build debtags on a sid+experimental chroot and the result runs but has libc's free() print existential warnings about whatevers.

At a quick glance, there are now things around like a new libapt, gcc 5 with ABI changes, and who knows what else. I figured how much time it'd take me to debug something like that, and I've used that time to rewrite debtags in python3. It took 8 hours, 5 of pleasant programming and the usual tax of another 3 of utter frustration packaging the results. I guess I gained over the risk of spending an unspecified amount of hours of just pure frustration.

So from now on debtags is going to be a pure python3 package, with dependencies on only python3-apt and python3-debian. 700 lines of python instead of several C++ files built on 4 layers of libraries. Hopefully, this is the last of the big headaches I get from hacking on this package. Also, one less package using libept.

Posted Sun Jun 21 18:04:39 2015 Tags:

Work around Google evil .ics feeds

I've happily been using 2015/akonadi-install for my calendars, and yesterday I added an .ics feed export from Google, as a URL file source. It is a link in the form: https://www.google.com/calendar/ical/person%40gmail.com/private-12341234123412341234123412341234/basic.ics

After doing that, I noticed that the fan in my laptop was on more often than usual, and I noticed that akonadi-server and postgres were running very often, and doing quite a lot of processing.

The evil

I investigated and realised that Google seems to be doing everything they can to make their ical feeds hard to sync against efficiently. This is the list of what I have observed Gmail doing to an unchanged ical feed:

  • Date: headers in HTTP replies are always now
  • If-Modified-Since: is not supported
  • DTSTAMP of each element is always now
  • VTIMEZONE entries appear in random order
  • ORGANIZER CN entries randomly change between full name and plus.google.com user ID
  • ATTENDEE entries randomly change between having a CN or not having it
  • TRIGGER entries change spontaneously
  • CREATED entries change spontaneously

This causes akonadi to download and reprocess the entire ical feed at every single poll, and I can't blame akonadi for doing it. In fact, Google is saying that there is a feed with several years worth of daily appointments that all keep being changed all the time.

The work-around

As a work-around, I have configured the akonadi source to point at a local file on disk, and I have written a script to update the file only if the .ics feed has actually changed.

Have a look at the script: I consider it far from trivial, since it needs to do a partial parsing of the .ics feed to throw away all the nondeterminism that Google pollutes it with.

The setup

The script needs to be run periodically, and I used it as an opportunity to try systemd user timers:

    $ cat ~/.config/systemd/user/update-ical-feeds.timer
    [Unit]
    Description=Updates ical feeds every hour
    # Only run when on AC power
    ConditionACPower=yes

    [Timer]
    # Run every hour
    OnActiveSec=1h
    # Run a minute after boot
    OnBootSec=1m
    Unit=update-ical-feeds.service

    $ cat ~/.config/systemd/user/update-ical-feeds.service
    [Unit]
    Description=Update ICal feeds

    [Service]
    # Use oneshot to prevent two updates being run in case the previous one
    # runs for more time than the timer interval
    Type=oneshot
    ExecStart=/home/enrico/tmp/calendars/update

    $ systemctl --user start update-ical-feeds.timer
    $ systemctl --user list-timers
    NEXT                         LEFT       LAST                         PASSED UNIT                    ACTIVATES
    Wed 2015-03-25 22:19:54 CET  59min left Wed 2015-03-25 21:19:54 CET  2s ago update-ical-feeds.timer update-ical-feeds.service

    1 timers listed.
    Pass --all to see loaded but inactive timers, too.

To reload the configuration after editing: systemctl --user daemon-reload.

Further investigation

I wonder if ConditionACPower needs to be in the .timer or in the .service, since there is a [Unit] section is in both. Update: I have been told it can be in the .timer.

I also wonder if there is a way to have the timer trigger only when online. There is a network-online.target and I do not know if it is applicable. I also do not know how to ask systemd if all the preconditions are currently met for a .service/.timer to run.

Finally, I especially wonder if it is worth hoping that Google will ever make their .ics feeds play nicely with calendar clients.

Posted Wed Mar 25 21:50:21 2015 Tags:

Screen-dependent window geometry

I have an external monitor for my laptop in my work desk at home, and when I work I keep a few windows like IRC on my laptop screen, and everything else on the external monitor. Then maybe I transfer on the sofa to watch a movie or in the kitchen to cook, and I unplug from the external monitor to bring the laptop with me. Then maybe I go back to the external monitor to resume working.

The result of this (with openbox) is that when I disconnect the external monitor all the windows on my external monitor get moved to the right edge of the laptop monitor, and when I reconnect the external monitor I need to rearrange them all again.

I would like to implement something that does the following:

  1. it keeps a dictionary mapping screen geometry to window geometries
  2. every time a window geometry and virtual desktop number changes, it gets recorded in the hash for the current screen geometry
  3. every time the screen geometry changes, for each window, if there was a saved window geometry + wirtual desktop number for it for the new screen geometry, it gets restored.

Questions:

  1. Is anything like this already implemented? Where?
  2. If not, what would be a convenient way to implement it myself, ideally in a wmctrl-like way that does not depend on a specific WM?

Note: I am not interested in switching to a different WM unless it is openbox with this feature implemented in it.

Posted Mon Mar 16 21:29:36 2015 Tags:
Posted Sat Jun 6 00:57:39 2009

Pages about Debtags.

Evolution's old odd mail folders to mbox

Something wrong happened in my dad's Evolution. It just would get stuck checking mail forever, with no useful diagnostic that I could find. Fun. Not.

Anyway, I solved by resetting everything to factory defaults, moving away all gconf entries and .evolution/ files. Then it started to work again, of course then I needed to reconfigure it from scratch.

It turned out however that some old mail was only archived locally, and in a kind of weird format that looks like this:

$ ls -la Enrico/
total 336
drwx------ 2 enrico enrico   4096 Jul 23 03:05 .
drwxr-xr-x 7 enrico enrico   4096 Jul 23 03:12 ..
-rw------- 1 enrico enrico   3230 Dec  4  2010 113.HEADER
-rw------- 1 enrico enrico  14521 Dec  4  2010 113.TEXT
-rw------- 1 enrico enrico   3209 Oct 22  2010 134.HEADER
-rw------- 1 enrico enrico   2937 Oct 22  2010 134.TEXT
-rw------- 1 enrico enrico   3116 Jun 27  2011 15.
-rw------- 1 enrico enrico   3678 Jun 27  2011 168.
-rw------- 1 enrico enrico     73 Apr 27  2009 22.1.MIME
-rw------- 1 enrico enrico   3199 Apr 27  2009 22.2
-rw------- 1 enrico enrico     88 Apr 27  2009 22.2.MIME
[...]

I couldn't even find the name of that mail folder layout, let alone conversion tools. So I had to sit down and waste my sunday break writing software to convert that to a mbox file. Here's the tool, may it save you the awful time I had today: http://anonscm.debian.org/gitweb/?p=users/enrico/evo2mbox.git

Note: feel free to fork it, or send patches, but don't bother with feature requests. Evolution isn't and won't be a personal interest of mine. Anything that makes an afternoon at my parents more tiresome than a whole busy month of paid work, doesn't deserve to be.

Luckily they now seem to have changed the local folder format to Maildir.

Posted Mon Jul 23 03:27:50 2012 Tags:

Giving away distromatch

at last year's Fosdem I tried to inject a lot of energy into distromatch but shortly afterwards I've had to urgently rewrite the nm.debian.org website.

After Lars Wirzenius GTDFH talks in Bologna and Varese I wrote a tool which, among other things, is able to scan my home dir and list how many projects I'm working on.

The output was scary. Like, they are too many. Like, I couldn't even recite the list out of memory. And since I couldn't do that, I had no idea there were so many. And I kept being stressful because I couldn't manage to take care of them all properly.

Now that I became conscious of the situation, it's time to deal with it like a grown up, and politely back off from some of my irresponsible responsibilities.

Distromatch is one of them. It had just started as a proof of concept prototype, and I had the vision that it could be the basis for a fantastic culture of sharing and exchange of information across distributions.

I need to distinguish the vision from the responsibility. I still have that vision for distromatch, but I cannot take responsibility for making it happen.

So I am giving it up to anyone who has the time and resources to pick up that responsibility.

Current status

It works well enough as a prototype. I believe it can successfully map a large enough slice of packages, that one can prototype stuff based on it.

I have for example used it to export the Debtags categories for other distros, and the resulting file looked big enough to be used for prototyping category-based features on distributions that don't have them yet.

I think it also works well enough to support a few common use cases, like sharing screenshots, or doing most of the work of converting dependency lists from a distro to another.

And finally, anyone can deploy it, and work on it.

Existing data sources

Everything I index in the Debian distromatch deployment is available at http://dde.debian.net/exports/distromatch/. The rpm-based data in there comes from an export script I wrote that runs on Sophie, but which I cannot maintain properly.

This is an experimental export of Fedora and OpenSUSE data: http://tmp.vuntz.net/misc/distromatch/distromatch-opensuse-fedora.tar

All existing export scripts are found in distromatch git repo on gitorious.

Contacts I gathered at Fosdem

At Fosdem I devoted quite some work to get contacts from all possible distributions and software repositories, so that distromatch could be hooked into them. Here is a dump of what I have collected:

  • Debian: me
  • OpenSuse: Vincent Untz and Adrian Schröter
  • Fedora: Tom "Spot" Callaway
  • Arch: Tasser on IRC
  • CPAN: contact the people of https://metacpan.org/, on irc.perl.org:#metacpan or make an issue on github
  • NetBSD: ask on #netbsd on Freenode
  • FreeBSD: Baptiste Daroussin (bapt)
  • Mageia: Olivier Thauvin

Some of those contacts may have "expired" in the meantime: I wouldn't assume all of them still remember talking with me, although most probably still do.

My commitment for the time being

I am happy to commit, at the moment, to maintaining a working data export for Debian data. I can take responsibility for making it so that the Debian data for it stays up to date, and to fix it asap if it isn't the case.

I hope that now someone can take distromatch over from me, and make it grow to achieve its great potential.

Posted Sat Jul 21 16:54:18 2012 Tags:

More diversity in Debian skills

This blog post has been co-authored with Francesca Ciceri.

In his Debconf talk, zack said:

We need to understand how to invite people with different backgrounds than packaging to join the Debian project [...] I don't know what exactly, but we need to do more to attract those kinds of people.

Francesca and I know what we could do: make other kinds of contributions visible.

Basically, we should track and acknowledge the contributions of webmasters, translators, programmers, sysadmins, event organisers, and so on, at the same level as what we do for packagers: DDPO, minechangelogs, Portfolio...

For any non-packaging activity that we can make visible and credited, we get:

  • to acknowledge the people who do it, and show that they are active contributors in the project;

  • to acknowledge the work that gets done, and show the actual amount of non-packaging work that gets done in Debian every day;

  • to allow non-packagers to have a reputation, too: first of all, they deserve it, and among other things, it would make nm processing trivial.  

Here's an example: who's the lead translator for German? And if you are German, who's the lead translator for Spanish? Czech? Thai? I (Enrico) don't know the answers, not even for Italian, but we all should! Or at least it should be trivial to find out.

To start to change this, is just a matter of programming.

Francesca already worked on a list of trackable data sources, at least for translators.

Here are some more details, related to translation:

  • Translations can be tracked via the i18n robot (and relative statistics). This works only with teams who activated the robot and actively use the pseudo-urls in their messages on localisation mailing lists. Some translators don't bother to do it but it's ok to only support the main workflow. It beats extracting .po files from l10n-tagged BTS bugs at any rate.

  • DPN and website translations: for wml pages there's a specific field to be extracted for each translated page: grep for maintainer="name" on normal wml pages, while for DPN translations we have a specific translator="name" field. The problem is that this field is not mandatory, so sometimes there's no indication of the maintainer. Again, it's ok to only support the main workflow.

    Anyway, this is preferable to the cvs log: often the commit is done by the coordinator of the team and not by the actual translator. See above for the alternative solution of using the statistics provided by the i18n bot.

  • DDTSS: since the new release of DDTSS-Django, done by Martijn van Oosterhout about a year ago, the contributions are by default non-anonymous. This should be easy to track.

  • http://wiki.debian.org: it is more complicated because in the wiki we do not have a proper l10n translation workflow, so the only thing that can be tracked are changelogs $LANG/* pages. A nice idea would be to have translated pages list the version of the page that was translated and who did the translation.

  • translation of debian manuals and release notes: usually in the translation of manuals and long documentation there is a specific translator field.

And here are some notes about other fields:

  • DPN editors: for each issue there's a list of editors at the bottom of the page. In the wml: grep for editor=.

  • Artwork: artwork submitted via debianart are easy to track on the portal. Anyway usually you can find the author in the license and copyright file.

  • Programming: the only thing we have is the list of services which can be expanded if needed.

  • Press and publicity: there seems to be not much besides svn logs.

  • l10n-english: The Smith Review Project page has some tracking links. Other activities can probably only be tracked, at the moment, via mailing list activity.

  • Events: we can use the "main coordinator" field on www.debian.org/events/$year/$date-$eventname.wml: grep for <define-tag coord>; for events not published on the http://www.debian.org, but only on http://wiki.debian.org, the coordinator or the contact for the event is usually present on the page itself.

  • Sysadmins: we haven't asked DSA.

And finally, if you are still wondering who those translation coordinators are, they are listed here, although not all teams keep that page up to date.

Of course, when a data source is too hard to mine, it can make sense to see if the workflow could be improved, rather than spending months writing compicated mining code.

This is a fun project for people at Debconf to get together and try.

If by the end of the conference we had a way to credit some group of non-packaging contributors, even if just one like translators or website contributors, at least we would finally have started having official trackers for the activities of non-packagers.

Posted Thu Jul 12 14:01:54 2012 Tags:

Debtags for derivative distributions

Sometimes I do cool stuff and I forget to announce it.

Ok, so I recently announced a new Debtags website.

I forgot to say in the announcement that the new website does not only know of Debian packages: see for example this page, at the very bottom it says: "Distributions: oneiric, precise, sid, testing".

This means that already, here and now, debtags.debian.net can be used to tag packages from both Debian and Ubuntu, and can easily be extended to cover the entire Debian ecosystem.

If you are a package maintainer, you will notice that your maintainer page shows your packages from everywhere. If you want to filter things a bit, for example hide obsolete packages from an old Debian Stable or Ubuntu LTS, just click on the "Settings" link on the top right to configure the page.

How it works

The magic is in this mergepackages script, which is run daily, and exports merged Packages files at dde.debian.net. The debtags.debian.net concept of Packages and Sources files are just those all-merged.gz and all-merged-sources.gz.

The merging is simple: that rebuild script processes files in order, and the first version of a package that is found is chosen as the base for the one that will go in the merged Packages file. Some fields like "Description" are just taken from this pivot package, others like Architecture or dependencies are merged into it. It's arbitrary, but works for me: the result has all the packages with all their possible architectures and dependencies, and is ready to be indexed with apt-xapian-index.

At the moment I pull data from Debian and Ubuntu, but you can see that the script can easily be extended to pull data from any Debian-style ftp archive, so any Debian derivative can go in. I've already started negotiations with the Derivatives Census on how to add any Debian derivative and keep the list up to date.

How to export tags for your own distribution

I'll use Ubuntu as an example since the data is already available.

The way you add Debtags to the Ubuntu packages file is just this one:

  1. Get the full reviewed tag database
  2. Optionally filter out those packages that you are not interested in
  3. Tweak this script to build an overrides file.
  4. Give the overrides file to your favourite ftp archive building tool.

The make-overrides is a bit rusty: if you improve it, please send me your changes.

That is it, nothing else required, no excuses, it's ready, here, now!

Hitches and gotchas

This merged Packages file is a bit of a hack, and suffers from name conflicts across distributions, where two different softwares are packaged in two different distributions with the same name.

Ideally, name conflicts should not happen: if a derivative decided to package kate and call it gedit, they deserve to have it tagged uitoolkit::gtk. I think it's rather important that the whole Debian ecosystem works as much as possible with a single package namespace.

However, that reasoning fails if you take time into account: packages get renamed, like git and chromium, and may mean completely different things, for example, if you compare Debian Stable with Debian Sid.

This last is a problem caused by debtags only working with package names but not package versions. I have a strategy in mind based on being able to override the stable tag database using headers in debian/control; it still needs some details sorted out, but I'm confident we will be able to address these issues properly soon enough.

Why stop at the Debian ecosystem?

Why indeed. I'm clearly trying to use FOSDEM, and the CrossDistribution devroom as the venue to discuss just that.

Posted Fri Jan 20 15:12:33 2012 Tags:

Deploying distromatch

I have been working on allowing anyone to set up their own distromatch instance.

For Debian and Ubuntu, I can easily generate the distromatch input using UDD and the Contents files found in any mirrors.

For the whole RPM world, thanks to Olivier Thauvin I have been able to set up regular exports from the vast Sophie database.

I have set up distromatch access on DDE, which can also serve as a list of all working distributions so far. If you have access to the full dataset of package names and package contents for a distribution not in that list, please get in touch and we can add it.

I'm also exporting the full raw dataset which enables anyone to set up the same distromatch environment on their own machines.

Here is how:

# Get distromatch
git clone git://gitorious.org/appstream/distromatch.git
cd distromatch

# Fetch distribution information (updated every 2 days)
wget http://dde.debian.net/exports/distromatch-all.tar.gz

# Unpack it
mkdir data
tar -C data -zxf distromatch-all.tar.gz

# Reindex it (use --verbose if you are curious)
./distromatch --datadir=data --reindex --verbose

# Run it
./distromatch --datadir=data debian gedit

What does this mean? For example it means that if another distribution has some data (categories, screenshots...) that your distribution doesn't have, you can use distromatch to translate package names, then go and get it!

My next step is going to be to improve the distromatch functionality in DDE and possibly build a simple user friendly web interface to it. If you have some JQuery experience and would like to help, don't wait to get in touch.

Posted Fri Feb 18 13:46:30 2011 Tags:

update-apt-xapian-index on other distros

I've drafted a little HOWTO on using apt-xapian-index on non-Debian distributions.

The procedure has been tried on Mageia with some success, and there's no reason it wouldn't work everywhere else: the index itself does not depend on anything distro-specific.

Posted Tue Jan 25 23:01:45 2011 Tags:

Cross-distro Meeting on Application Installer

I have been to a Cross-distro Meeting on Application Installer which to the best of our knowledge is also the first one of its kind. Credit goes to Vincent Untz for organising it, to OpenSUSE for hosting it and to the various sponsors for getting us there.

It went surprisingly well. We got along, got stuff done, did as much work as possible to agree on as many formats, protocols and technologies as we possibly could.

The timing of it is very important, as most major distros would like to adopt some of the features that just became popular in the various new app markets and stores, such as screenshots, user comments and ratings. It looks like a lot of new code is about to be written, or a lot of existing code is about to gain quite a bit of popularity.

For my part, I presented the work on Debtags and apt-xapian-index.

With regards to Debtags, other distros seem to be missing a compehensive classification system, and Debtags is, well, it.

With regards to apt-xapian-index, we just noticed that it's the perfect back-end for what everyone would like to do, and the index structure is rather distribution-agnostic, and it's been road-tested with considerable success by at least software-center, so it attracted quite a bit of interest, and will likely attract some more.

Just to prove a point I put together a prototype webby markety appy thing in just a few hours of work.

The meeting was also the ideal place to create a joint effort to match package names across distributions, which means that a lot of things that were hard to share before, such as screenshots, tags and patches, are suddenly not hard to share anymore.

Posted Sat Jan 22 01:40:50 2011 Tags:

Match package names across distributions

What would happen if we had a quick and reliable way to match package names across distributions?

These ideas came up at the appinstaller2011 meeting:

  • it would be easy to lookup screenshots in the local distro, and if there are none then fall back on other distributions;
  • it would be easy to port Debtags to other distributions, and possibly get changes back;
  • it would be trivial to add a [patches in $DISTRO] link to the PTS
  • it would be easy to point to other BTSes

We thought they were good ideas, so we started hacking.

To try it, you need to get the code and build the index first:

git clone git://git.debian.org/users/enrico/distromatch.git
cd distromatch
# Careful: 90Mb
wget http://people.debian.org/~enrico/dist-info.tar.gz
tar zxf dist-info.tar.gz
# Takes a long time to do the indexing
./distromatch --reindex --verbose

Then you can query it this way:

./distromatch $DISTRO $PKGNAME [$PKGNAME1 ...]

This would give you, for the package $PKGNAME in $DISTRO, the corresponding package names in all other distros for which we have data. If you do not provide package names, it automatically shows output for all packages in $DISTRO.

For example:

$ time ./distromatch debian libdigest-sha1-perl
debian:libdigest-sha1-perl fedora:perl-Digest-SHA1
debian:libdigest-sha1-perl mandriva:perl-Digest-SHA1
debian:libdigest-sha1-perl suse:perl-Digest-SHA1

real    0m0.073s
user    0m0.056s
sys 0m0.016s

Yes it's quick. It builds a Xapian index with the information it needs, and then it reuses it. As soon as I find a moment, I intend to deploy an instance of it on DDE.

It is using a range of different heuristics:

  • match packages by name;
  • match packages by desktop files contained within;
  • match packages by pkg-config metadata files contained within;
  • match packages by [/usr]/bin/* files contained within;
  • match packages by shared library files contained within;
  • match packages by devel library files contained within;
  • match packages by man pages contained within;
  • match stemmed form of development library package names;
  • match stemmed form of shared library package names;
  • match stemmed form of perl library package names;
  • match stemmed form of python library package names.

This list may get obsolete soon as more heuristics get implemented.

Euristics will never cover all corner cases we surely have, but the idea is that if we can match a sizable amout of packages, the rest can be somehow fixed by hand as needed.

The data it requires for a distribution should be rather straightforward to generate:

  1. a file which maps binary package names to source package names
  2. a file with the list of files in all the packages

For example:

$ ls -l dist-debian/
total 39688
-rw-r--r--  1 enrico enrico  1688249 Jan 20 17:37 binsrc
drwxr-xr-x  2 enrico enrico     4096 Jan 21 19:12 db
-rw-r--r--  1 enrico enrico 29960406 Jan 21 10:02 files.gz
-rw-r--r--  1 enrico enrico  8914771 Jan 21 18:39 interesting-files

$ head dist-debian/binsrc 
openoffice.org-dev openoffice.org
ext4-modules-2.6.32-5-4kc-malta-di linux-kernel-di-mipsel-2.6
linux-headers-2.6.30-2-common linux-2.6
libnspr4 nspr
ipfm ipfm
libforks-perl libforks-perl
med-physics debian-med
libntfs-3g-dev ntfs-3g
libguppi16 guppi
selinux selinux

$ zcat dist-debian/files.gz | head
memstat etc/memstat.conf
memstat usr/bin/memstat
memstat usr/share/doc/memstat/changelog.gz
memstat usr/share/doc/memstat/copyright
memstat usr/share/doc/memstat/memstat-tutorial.txt.gz
memstat usr/share/man/man1/memstat.1.gz
libdirectfb-dev usr/bin/directfb-config
libdirectfb-dev usr/bin/directfb-csource
libdirectfb-dev usr/include/directfb-internal/core/clipboard.h
libdirectfb-dev usr/include/directfb-internal/core/colorhash.h

interesting-files and db are generated when indexing.

To prove the usefulness of the idea (but does it need proving?), you can find in the same git repo a little example app (it took me 10 minutes to write it), that uses the distromatch engine to export Debtags tags to other distributions:

$ ./exportdebtags fedora | head
memstat: admin::benchmarking, interface::commandline, role::program, use::monitor
libdirectfb-dev: devel::lang:c, devel::library, implemented-in::c, interface::framebuffer, role::devel-lib
libkonqsidebarplugin4a: implemented-in::c++, role::shared-lib, suite::kde, uitoolkit::qt
libemail-simple-perl: devel::lang:perl, devel::library, implemented-in::perl, role::devel-lib, role::shared-lib, works-with::mail
libpoe-component-pluggable-perl: devel::lang:perl, devel::library, implemented-in::perl, role::shared-lib
manpages-ja: culture::japanese, made-of::man, role::documentation
libhippocanvas-dev: devel::library, qa::low-popcon, role::devel-lib
libexpat-ocaml-dev: devel::lang:ocaml, devel::library, implemented-in::c, implemented-in::ocaml, role::devel-lib, works-with-format::xml
libgnutls-dev: devel::library, role::devel-lib, suite::gnu

Just in case this made you itch to play with Debtags in a non-Debian distribution, I've generated the full datasets for Fedora, Mandriva and OpenSUSE.

Others have been working on the same matching problem. After we started writing code we started to become aware of existing work:

I'd like to make use of those efforts, maybe to cross-validate results, maybe even better as yet another heuristics.

Update:

I built a simple distromatch query system into DDE!

Posted Sat Jan 22 01:40:50 2011 Tags:

A prototype webby markety appy thing

What better way to introduce my work at an Application Installer meeting than to come with a prototype package browser modeled after shopping sites developed in just a few hours?

It's a little Flask webapp that just works on any Debian system, using the local apt-xapian-index as a backend. It has fast keyword search, faceted navigation and screenshots, and it runs on your system showing the packages that you have available.

[[!img Error: Image::Magick is not installed]]

To try it:

git clone git://git.debian.org/users/enrico/pkgshelf.git
cd pkgshelf
./web-server.py

Then visit http://localhost:5000

It didn't have much interface polishing, as it's just a quick technology demo. However you can see that:

  • keyword search is fast (fast enought that it could be made to search as you type);
  • relevant tags appear on the left, grouped by facets;
  • the most relevant tags are highlighted;
  • the less relevant tags could be hidden behind a [more] expander;
  • you can choose several strategies to hide packages you may find irrelevant.

Things that need doing:

  • hiding uninteresting facets;
  • making it pretty.

It's essentially JavaScript and CSS work. Anyone wants to play?

Posted Sat Jan 22 01:40:50 2011 Tags:

fuss-launcher: an application launcher built on apt-xapian-index

Long ago I blogged about using apt-xapian-index to write an application launcher.

Now I just added a couple of new apt-xapian-index plugins that look like they have been made just for that.

In fact, they have indeed been made just for that.

After my blog post in 2008, people from Truelite and the FUSS project took up the challenge and wrote a launcher applet around my example engine.

The prototype has been quite successful in FUSS, and as a consequence I've been asked (and paid) to bring in some improvements.

The result, that I have just uploaded to NEW, is a package called fuss-launcher:

* New upstream release
   - Use newer apt-xapian-index: removed need of local index
   - Dragging a file in the launcher shows the applications that can open it
   - Remembers the applications launched more frequently
   - Allow to set a list of favourite applications

To get it:

  • apt-get install fuss-launcher (after it passed NEW);
  • or git clone http://git.fuss.bz.it/git/launcher.git/ and apt-get install python-gtk2 python-xapian python-xdg apt-xapian-index app-install-data

It requires apt-xapian-index >= 0.35.

To try it:

  1. Make sure your index is up to date, especially if you just installed app-install-data: just run update-apt-xapian-index as root.
  2. Run fuss-launcher.
  3. Click on the new tray icon to open the launcher dialog.
  4. Type some keywords and see the list of matching applications come to life as you type.

It's worth mentioning again that all this work was sponsored by Truelite and the Fuss project, which rocks.

Some screenshots:

When you open the launcher, by default it shows the most frequently started applicationss and the favourite applications:

[[!img Error: Image::Magick is not installed]]

When you type some keywords, you get results as you type, and context-sensitive completion:

[[!img Error: Image::Magick is not installed]]

When you drag a file on the launcher you only see the applications that can open that file:

[[!img Error: Image::Magick is not installed]]

Posted Mon May 17 10:41:09 2010 Tags:
Posted Sat Jun 6 00:57:39 2009
ita

Pages in Italian.

Non importa che mi dai del voi

Dai, non importa che mi dai del voi

In che senso?

Eh, mi dici sempre "voi informatici", "voi tecnici", "voi..."

Posted Fri Dec 19 15:55:20 2014 Tags:

Spelling a chilometri zero

Lo spelling internazionale è troppo globalizzato, e volete recuperare un attimo la dimensione del posto dove siete nati e cresciuti?

Da oggi c'è questo script che fa per voi: gli dite dove abitate, e lui vi crea lo spelling a chilometri zero.

$ git clone git@gitorious.org:trespolo/osmspell.git
$ cd osmspell
$ ./osmspell "San Giorgio di Piano"
1: San Giorgio di Piano, BO, EMR, Italia
2: San Giorgio di Piano, Via Codronchi, San Giorgio di Piano, BO, EMR, Italia
3: San Giorgio Di Piano, Via Libertà, San Giorgio di Piano, BO, EMR, Italia
Choose one: 1
Center: 44.6465332, 11.3790398
A Argelato, Altedo
B Bentivoglio, Bologna, Boschi
C Cinquanta, Castagnolo Minore, Castel Maggiore, Cento
D Dosso
E Eremo di Tizzano
F Funo di Argelato, Finale Emilia, Ferrara, Fiesso
G Gherghenzano, Galliera, Gesso
I Il Cucco, Irnerio, Idice
L Località Fortuna, Lovoleto, Lippo
M Malacappa, Massumatico, Minerbio, Marano
N Navile
O Osteriola, Ozzano dell'Emilia, Oca
P Piombino, Padulle, Poggio Renatico, Piave
Q Quarto Inferiore, Quattrina
R Rubizzano, Renazzo, Riale
S San Giorgio di Piano, Saletto
T Torre Verde, Tintoria, Tombe
U Uccellino
V Venezzano Mascarino, Vigarano Mainarda, Veduro
X XII Morelli
Z Zenerigolo, Zola Predosa

I dati vengono da OSM, e lo script è un ottimo esempio di come usarne la API di geolocazione (veloci) e la API di query geografica (lenta).

Posted Sat Jan 4 00:38:16 2014 Tags:

Poesia: "Lavatrice"

Pensavo fosse pail,

invece ora è feltro.

Posted Tue Dec 3 22:32:23 2013 Tags:

Coppone e spinaci all'orientale

Ingredienti:

  • una bistecca di coppone
  • spinaci surgelati
  • olio
  • aglio
  • zenzero
  • peperoncino
  • anice stellato
  • salsa di soia
  • olio di sesamo tostato
  • pepe

Al supermercato hanno spesso delle bistecchine di coppone in sconto. Sono ottime sulla griglia, ma in mancanza di griglia una volta ho improvvisato questo, e ogni tanto lo rifaccio. È una cena velocissima che si può preparare quando non c'è niente in casa con ingredienti presi fuori dal freezer.

Soffriggere nell'olio l'aglio, lo zenzero e l'anice stellato.

Aggiungere il coppone tagliato a pezzetti e farlo rosolare. Mentre sta cuocendo, aggiungere il peperoncino sbriciolato, l'olio di sesamo e un po' di salsa di soia.

Quando la carne ha preso colore, aggiungere gli spinaci scongelati e rosolarli assieme alla carne e al suo sugo.

Regolare di sale con la salsa di soia e spolverare di pepe macinato prima di servire.

Posted Sat Mar 9 18:42:22 2013 Tags:

Besciamella al caffè e acciughe

Ingredienti:

Ispirato da un soufflé di broccoli al caffè mangiato alla meravigliosa trattoria Antichi Sapori a Parma, ho provato anch'io a combinare caffè e broccoli.

L'idea era fare una salsa da versare sui broccoli appena lessati. Lo chef Davide Sensi aveva parlato di caffè e acciughe, quindi ho deciso che il sapore della salsa dovrà venire da caffè e salsa di pesce thai. Per addensarli, ci potrebbe stare anche solo un classico roux.

Il risultato, una besciamella in cui il roux non è allungato con latte, ma con caffè, salsa di pesce thai e acqua di cottura dei broccoli.

La prima prova è venuta un po' troppo carica di caffè. Sui broccoli però ci sta benino.

Posted Fri Mar 8 19:17:04 2013 Tags:

Che coss'è l'amor

Di recente mi sono spesso trovato a chiedermi "che cos'è l'amore", e ogni volta inizia a suonarmi in testa: "♪...chiedilo al vento / che sferza il suo lamento sulla ghiaia del viale del tramonto... ♫"

Socialmente l'amore mi è sempre stato venduto come una cosa indescrivibile ma allo stesso tempo estremamente codificata. L'amore è quella cosa che ti fa sentire così, e poi se non fai così non è vero amore, e l'altra persona la devi trattare così, e devi essere spontaneo mapperò... tv e musica con i quali volente o nolente sono cresciuto hanno spesso propagandato modelli che raramente ho condiviso, e che riassumerei con questo.

Mi è sempre stato difficile capire quando poter dire "ti amo". Il problema non è tanto nell'interpretare i miei sentimenti, quanto nel capire quali significati sto tirando addosso a entrambi nel momento in cui lo faccio. Per questo motivo, finché non sono sicuro di come l'espressione "ti amo" significhi per entrambi, tendo a ragionare usando invece concetti definiti in maniera un po' più chiara (per me), tipo: desiderio, fiducia, intimità, odori, intesa, ridere, contatto fisico, curiosità...

È un peccato: ogni tanto provo quel sentimento di piacevole resa verso l'altra persona che mi porta a voler dire "ti amo!", e finisco per non farlo.

Detto questo, da quando ho visto "Una de zombis", alla domanda "ma sei innamorato?" non può non venirmi in mente questo.

Posted Wed Feb 20 02:02:30 2013 Tags:

Spaghetti con friggitelli e mozzarella

Dosi per 4 persone:

  • 300 gr di spaghetti
  • 300 gr di friggitelli
  • 70 gr di mollica di pane
  • 125 gr di mozzarella
  • parmigiano grattugiato q.b.
  • 4 foglioline di menta
  • olio extra-vergine q.b.
  • sale & pepe

Laviamo i peperoncini, togliamo i semini e il picciolo, asciughiamoli e tagliamoli a striscette.

Tritiamo nel mixer la mollica di pane e doriamola in padella con 3 cucchiai di l'olio, finchè non diventerà croccanate e, mettiamolo da parte.

Tagliamo la mozzarella a dadini e teniamo anch'essa da parte.

Scaldiamo altri 5 cucchiai di olio, uniamo i peperoncini e facciamoli cuocere a fiamma viva per 10 minuti, regolandoli di sale e pepe.

Cuociamo la pasta, scoliamola e ripassiamola in padella con i peperoncini.

Facciamo saltare il tutto a fiamma vivace per qualche minuto.

Aggiungiamo la mozzarella a dadini, il pane croccante e il parmigiano.

Come tocco finale, uniamo la menta spezzettata e serviamo.

(via http://friggitelli.it/)

Fatta oggi, buona. Per le briciole di pane ho usato un avanzo della farcitura dei carciofi alla romana di ieri sera.

Con l'acqua di cottura dei carciofi, stasera risotto.

Posted Mon Apr 30 16:08:55 2012 Tags:

Repubblica vs i traduttori automatici

Vedo questo titolo: "Cieco e senza ali: l'insetto della cava più profonda" e scatta la sensazione di unghie sulla lavagna. Non avran mica tradotto l'inglese "cave" con "cava"?

Si.

E ne sono veramente convinti, ribadendo nell'articoletto che è proprio proprio una cava artificiale, scavata proprio proprio dall'uomo:

…lo hanno trovato durante l'ispezione della cava più profonda scavata
dall'uomo, la Krubera-Voronja, in Abkhazia.

Cara Repubblica, questa è una cava, e questa è una caverna. Vi sembra plausibile una cava fonda piú di 2 chilometri in cui si trovano forme di vita mai scoperte prima? Ah, ma sai, in Abkhazia...

Bastava scrivere Krubera-Voronja su un motore di ricerca; fare 30 secondi di approfondimento prima di pubblicare la roba, ma mi rendo conto che pensare è fatica, soprattutto quando uno ha perso l'abitudine a farlo.

Si apre però una riflessione interessante: un traduttore automatico non fa questo errore. Questo vuol dire che i traduttori automatici hanno superato l'intelligenza di Repubblica. QUESTA è una notizia da pubblicare!

Il prossimo passo è superare l'intelligenza dei moscerini della frutta.

Posted Thu Feb 23 15:07:52 2012 Tags:

Quei simpatici spammer di Aruba

Aruba ha deciso, di punto in bianco, di iscrivermi a tutte le loro newsletter.

Le newsletter non hanno link di deiscrizione. O meglio, forse ce l'hanno, ma si vedono solo decodificando la mail usando programmi che io non ho intenzione di usare. A prescindere dal link di deiscrizione, perché dovrei deiscrivermi da delle newsletter alle quali non mi sono mai iscritto?

Ho mandato questa mail a abuse@staff.aruba.it, e altre 3 segnalazioni dopo di questa, che ovviamente sono state ignorate:

Buon giorno,

vi segnalo questo spam inviato da voi stessi (in allegato la mail con
gli header intatti).

Potreste per favore procedere con provvedimenti disciplinari contro voi
stessi? Il vostro comportamento su internet viola le piú banali regole
di netiquette, ed è vostro interesse, come provider, istruire voi stessi
sulle stesse e farvele rispettare.


Cordiali saluti,

Enrico

Che dire, una nazione del terzo mondo si merita ISP da terzo mondo.

È pur sempre un'ottima scusa per studiarsi gli header_check di postfix: ora le mail delle newsletter di Aruba, che son tra l'altro dei patozzi da 300Kb l'una, incontrano un REJECT direttamente nella sessione SMTP:

550 5.7.1 Criminal third-world ISP spammers not accepted here.

Per farlo, ho aggiunto a /etc/postfix/main.cf:

# Reject aruba spam right away
header_checks = pcre:/etc/postfix/known_idiots.pcre

E poi ho creato il file /etc/postfix/known_idiots.pcre:

/^Received:.+smtpnewsletter[0-9]+.aruba.it/
REJECT Criminal third-world ISP spammers not accepted here.

Nel frattempo ho mandato un'email al Garante Privacy e una all'AGCOM, piú per curiosità che altro. Non mi aspetto nessuna risposta, ma se succede qualcosa lo aggiungo volentieri qui.

Posted Fri Oct 14 16:14:54 2011 Tags:

La paura e la voglia

Results 1 - 10 of about 5,470 for "la paura e la voglia di essere nudi". (0.34 seconds) 

Results 1 - 10 of about 26,500 for "la paura e la voglia di essere soli". (0.10 seconds) 

Poi non c'è da stupirsi se siamo diventati come siamo diventati.

Posted Wed May 5 13:36:24 2010 Tags:
Posted Sat Jun 6 00:57:39 2009
pdo

Pages exported to http://planet.debian.org.

debtags.debian.org cleaned up

Since the Debtags consolidation announcement there are some more news:

No more anonymous submissions

  • I have disabled anonymous tagging. Anyone is still able to tag via Debian Single Sign-On. SSO-enabling the site was as simple as this.
  • Tags need no review anymore to be sent to ftp-master. I have removed all the distinction in the code between reviwed and unreviewed tags, and all the code for the tag review interface.
  • The site now has an audit log for each user, that any person logged in via SSO can access via the "history" link in the top right of the tag editor page.

Official recognition as Debian Contributors

  • Tag contributions are sent to contributors.debian.org. There is no historical data for them because all submissions until now have been anonymous, but from now on if you tag packages you are finally recognised as a Debian Contributor!

Mailing lists closed

  • I closed the debtags-devel and debtags-commits mailing lists; the archives are still online.
  • I have updated the workflow for suggesting new tags in the FAQ to "submit a bug to debtags and Cc debian-devel"

We can just use debian-devel instead of debtags-devel.

Autotagging of trivial packages

  • I have introduced the concept of "trivial" packages to currently be any package in the libs, oldlibs and debug sections. They are tagged automatically by the site maintenance and are excluded from the site todo lists and tag editor. We do not need to bother about trivial packages anymore, all 13239 of them.

Miscellaneous other changes

  • I have moved the debtags vocabulary from subversion to git
  • I have renamed the tag used to mark packages not yet reviewed by humans from special::not-yet-tagged to special::unreviewed
  • At the end of every nightly maintenance, some statistics are saved into a database table. I have collected 10 years of historical data by crunching big tarballs of site backups, and fed them to the historical stats table.
  • The workflow for getting tags from the site to ftp-master is now far, far simpler. It is almost simple enough that I should manage to explain it without needing to dig through code to see what it is actually doing.
Posted Fri Feb 5 19:18:50 2016 Tags:

Downgrading network-manager

This morning I woke up. Bad idea.

I find in the work mail a compiler error that I cannot reproduce, so I need to log into a machine at work. But #809195.

I decided to downgrade network-manager. I recall there was a tool to download packages from snapshots.debian.org, I discussed it recently on IRC, let's sync the IRC logs from my server. Or not (#810212).

Never mind, I'll log into the server and grep. Ooh, it's debsnap. However, it doesn't quite do what I hoped (#667712).

After some help from #debian-devel (thanks jcristau and LebedevRI), here is how to downgrade network-manager:

# echo "deb http://snapshot.debian.org/archive/debian/20151125T155830Z/ sid main" >> /etc/apt/sources.list.d/tmp-downgrade-nm.list
# apt -o Acquire::Check-Valid-Until=false update
# apt -o Acquire::Check-Valid-Until=false install network-manager=1.0.6-1
# rm /etc/apt/sources.list.d/tmp-downgrade-nm.list
# service network-manager restart

And as user:

$ killall nm-applet
$ nm-applet &

The yak is now nice and shaved, I can now go and see what those compiler errors are all about.

Actually, no, there was still an unshaved patch on the yak, and now we have a debcya script.

Posted Thu Jan 7 11:37:19 2016 Tags:

When Akonadi silently fails to sync your calendar...

Bug severity: seriously ruining my life.

Try to use korganizer to create a calendar entry when the server is not reachable (say, you are offline, or you typed the wrong password), and you may find that you end up with no error messages, an entry that shows up perfectly fine, but that will never be synced to the server, ever again.

I use korganizer, radicale and caldav for important things. The practical ramifications of me inserting entries in korganizer, seeing that everything looks ok, and then not finding them on my phone while on the go, are scary.

Think of things like importing .ics files with flight schedules, entering tax deadlines, time and places for customer meetings, time and places of arrival of loved ones I'm supposed to pick up.

I spent time setting up my own infrastructure for this exactly because I care that all of this works reliably.

And now I urgently took a morning off work to find a way to detect those entries that Akonadi is refusing to update,

The whole thing is cumbersome to run, but if you are using kdepim-based tools to manage your calendars and sync them across devices, you may want to give it a go every once in a while.

You can find the script and the notes I took so far on the issue at https://github.com/spanezz/akonadi-workarounds.

Posted Tue Dec 1 14:01:09 2015 Tags:

Italian Fattura Elettronica with OpenSSL

I have had some success signing an Italian fattura elettronica with OpenSSL.

I am amazed to realise that the software they gave me to do the job is of such bad quality that I felt like spending a few hours trying to do the same thing with OpenSSL instead.

Posted Fri Oct 23 10:35:53 2015 Tags:

Extracting XML payload from Italian Fattura Elettronica zipfiles

This system does not even export to PDF. In order to provide my accountant with something better than a DER-encoded file with a random-looking name stored inside a zipfile, here is a script that at least extracts the unsigned XML payload out of a saved Fattura Elettronica.

If you're giving a python course in Italy, this sounds like a nice early programming assignment.

Posted Fri Oct 9 11:52:04 2015 Tags:

If you happen to know a browser developer...

Do you happen to know a developer of Firefox or Chrome or some other mainstream browser?

If so, can you please talk to them about our experiments with Client Certificate authentication in Debian?

Client Certificate authentication rocks; with just a couple of little tweaks in the interface, it would be pretty close to perfect.

Visiting sites without using a certificate

If I want to browse a site unauthenticated instead of using a certificate, at the moment I can hit "Cancel" on the certificate popup menu, and it works nicely. I feel quite confused when I do that, though, because it's not clear to me if I am canceling use of certificates, or canceling the visit to the site.

Can you please change the wording on the Cancel button to something more descriptive?

See/change current certificate selection

My top wish is, once I choise to use (or not use) a certificate for a site, to be able to see which certificate I'm using and possibly change it.

At the moment I did not find a way to see what certificate I'm using, and the browser will remember the choice until it gets closed and reopened.

At the moment I can use a Private or Incognito window to switch identities or to stop authenticated access and continue anonymously, and that helps me immensely.

I think however that the ultimate solution could be to have the https lockpad popup show an indication of what certificate is currently being used, and offer a way to re-trigger certificate selection. That would be so cool.

Also, once the certificate choice can be seen and changed at any time, it could just get remembered so that sites can be visited again without any prompts, even after the browser has been closed and reopened. That would be, to me, the ultimate convenience.

Thanks! <3

Thank you very much for all the work you have already put into this: I have been told that a few years ago using client certificate was unthinkable, and now it seems to be down to just a couple of papercuts. And SPKAC/keygen seriously rocks!

I have been constantly impressed by how well this all works right now.

Posted Tue Sep 1 17:25:04 2015 Tags:

My semi serious stand up comedy notes

Video

Disclaimers

“Someone has said that it requires less mental effort to condemn than to think.”

(Emma Goldman, on several things including mailing list flamewars)

Fascinating Aïda's "Dogging" song.

Look for "dogging etiquette" for more examples of code of conducts. Just don't take your computer for repair immediately afterwards™.

Introduction

Every daring attempt to make a great change in existing conditions, every lofty vision of new possibilities for the human race, has been labeled Utopian.

(Emma Goldman, on the Debian Social Contract)

I am going to talk about many topics that we all know have so much in common:

  • Anarchism
  • Poliamory
  • BDSM
  • and Free Software

They are all, after all:

  • People
  • Consensually
  • Doing Things
  • Together

BDSM

A person is no less a slave because they are allowed to choose a new master once in a term of years.

(Lysander Spooner about proprietary cloud service providers)

If you thought you've seen it all with recursive acronyms, here's a chain acronym: Bondage Discipline, Dominance Submission, Sado Masochism.

Why I think BDSM is interesting: not (just) because of whips, but for having a lot of awareness about power releationships. Why should one accept from a coworker a level of abuse that would be considered a hard limit when negotiating with a trusted dom?

The BDSM Free Software definition: "I refuse to be bound by software I cannot negotiate with".

YKINMKBYKIOK (Your Kink Is Not My Kink But Your Kink Is Okay) is a nice example of dealing with diversity, and it also definitely solves the emacs vs vi debate.

Comfort zones, safewords, traffic light flow control, safety.

"No means no", unless there has been a long discussion first, and a safeword is in place, in which case "Fuzzy purple unicorn" means "no"

"No means no", and if someone insists after a "no", it becomes harassment.

"No means no" is a precondition for being able to say "yes": http://pervocracy.blogspot.de/2011/03/no-and-no-and-no-and-yes.html

Aftercare! Aftercare! Release parties! High fives! Solidarity after flamewars or votes!

Poliamory

If love does not know how to give and take without restrictions, it is not love, but a transaction that never fails to lay stress on a plus and a minus.

(Emma Goldman, on volunteer projects)

Polyamory is the practice, desire, or acceptance of intimate relationships that are not exclusive with respect to other sexual or intimate relationships, with knowledge and consent of everyone involved.

Compersion, n: the feeling you get when someone else also takes good care of one of your packages.

We currently allow only one value in the Maintainer field: * takeover is traumatic, because values can only be replaced * if values could be added instead, and removed when they don't make sense anymore...

What is your definition of love? My current one is: my world is better with you in it.

Relationship anarchy is the practice of forming relationships which are not bound by rules aside from what the people involved mutually agree on. How do you call a relationship that is bound by rules that the people involved do not agree on?

From discussions after the talk

New Relationship Energy, the excitement when you start to maintain a new package, and the risk of been carried away by the excitement and neglecting all the other ones.

Consent

Anarchism, to me, means not only the denial of authority, not only a new economy, but a revision of the principles of morality. It means the development of the individual as well as the assertion of the individual. It means self-responsibility, and not leader worship.

(Voltairine de Cleyre about trusting lintian warnings)

You need to know what you are doing, and what situation you're putting yourself into.

You need to know that the person asking a question really is able to accept any answer, and take it seriously.

You need to feel that you have alternatives.

Be selfish when you ask, honest when you reply, and when others reply, take them seriously. If any of this doesn't stand, I find it hard to trust that we are in a consensual situation.

When is one supposed to learn about consent?

  • I see little consensuality in standard education.
  • I see little consensuality at work.

Consent explained with tea.

Practical advice

Anarchism has but one infallible, unchangeable motto, ‘Freedom.’ Freedom to discover any truth, freedom to develop, to live naturally and fully.

(Lucy Parsons about the DFSG)

Relationship advice and work advice have a lot in common:

Relationship advice from 99 ways to ruin an open source project

Online participation advice from How to Screw Up Your Relationship (and make everyone miserable while you’re at it)

Packaging advice from BDSM Basics: 20 Unsolicited Tips for New Dominants

Advice about joining a new community from Advice to a newbie submissive about dominants

♥ ♥ ♥

Dear Debian, and dear everyone contributing to it: my world is better with you in it.

I love you all :* <3

Posted Tue Aug 18 11:48:08 2015 Tags:

Expectations and needs

All people ever say is: "thank you" (a celebration of life) and "please" (an opportunity to make life more wonderful). (Marshall Rosenberg)

Sometimes, when I see the word "expectation" I try to read it as "need" and see how things change.

I noticed that this tends to reframe situations in a way that makes me feel more comfortable.

I noticed that I tend to instinctively perceive "expectations" as "do this or there will be consequences", and I tend to instinctively perceive "needs" as "do this if you want to see me happy".

I noticed that my motivation to care for someone's expectations tend to be something close to fear, and my motivation to care for someone's needs tends to be something close to love.

This might give me a bit more hints on The art of asking: I will not expect you to do something for me, I'll just allow myself to be loved, liked or helped by you, and I'll try to be open about what I need.

I smile realising that since a long time, on the professional side of my life, I learnt to lead interaction with my customers along the same lines: "let's talk about what you need, not about what you expect of me".

Posted Fri Aug 14 12:13:16 2015 Tags:

Random quote

Be selfish when you ask, honest when you reply, and when others reply, take them seriously.

(me, late at night)

Posted Sun Jul 19 18:53:03 2015 Tags:

Billing an Italian public administration

Here's a simple guide for how I managed to bill one of my customers as is now mandated by law in Italy.

Create a new virtualbox machine

I would never do any of this to any system I would ever want to use for anything else, so it's virtual machine time.

  • I started virtualbox, created a new machine for Ubuntu 32bit, 8Gb disk, 4Gb RAM, and placed the .vdi image in an encrypted partition. The web services of Infocert's fattura-pa requires "Java (JRE) a 32bit di versione 1.6 o superiore".
  • I installed Ubuntu 12.04 on it: that is what dike declares to support.
  • I booted the VM, installed virtualbox-guest-utils, and de sure I also had virtualbox-guest-x11
  • I restarted the VM so that I could resize the virtualbox window and have Ubuntu resize itself as well. Now I could actually read popup error messages in full.
  • I changed the desktop background to something that gave me the idea that this is an untrusted machine where I need to be very careful of what I type. I went for bright red.

Install smart card software into it

  • apt-get install pcscd pcsc-tools opensc
  • In virtualbox, I went to Devices/USB devices and enabled the smart card reader in the virtual machine.
  • I ran pcsc_scan to see if it could see my smart card.
  • I ran Firefox, went to preferences, advanced, security devices, load. Module name is "CRS PKCS#11", module path is /usr/lib/opensc-pkcs11.so
  • I went to https://fattura-pa.infocamere.it/fpmi/service and I was able to log in. To log in, I had to type the PIN 4 times into popups that offered little explanations about what was going on, enjoying cold shivers because the smart card would lock itself at the 3rd failed attempt.
  • Congratulations to myself! I thought that all was set, but unfortunately, at this stage, I was not able to do anything else except log into the website.

Descent into darkness

Set up things for fattura-pa

  • I got the PDF with the setup instructions from here. Get it too, for a reference, a laugh, and in case you do not believe the instructions below.
  • I went to https://www.firma.infocert.it/installazione/certificato.php, and saved the two certificates.
  • Firefox, preferences, advanced, show certificates, I imported both CA certificates, trusted for everything, all my base are belong to them.
  • apt-get install icedtea-plugin
  • I went to https://fattura-pa.infocamere.it/fpmi/service and tried to sign. I could not: I got an error about invalid UTF8 for something or other in Firefox's stdandard error. Firefox froze and had to be killed.

Set up things for signing locally with dike

  • I removed icedtea so that I could use the site without firefox crashing.
  • I installed DiKe For Ubuntu 12.04 32bit
  • I ran dikeutil to see if it could talk to my smart card
  • When signing with the website, I chose the manual signing options and downloaded the zip file with the xml to be signed.
  • I got a zip file, unzipped it.
  • I loaded the xml into dike.
  • I signed it with dike.
  • I got this error message: "nessun certificato di firma presente sul dispositivo di firma" and then this error message: "Impossibile recuperare il certificato dal dispositivo di firma". No luck.

Set up things for signing locally with ArubaSign

  • I went to https://www.pec.it/Download.aspx
  • I downloaded ArubaSign for Linux 32 bit.
  • Oh! People say that it only works with Oracle's version of Java.
  • sudo add-apt-repository ppa:webupd8team/java
  • apt-get update
  • apt-get install oracle-java7-installer
  • During the installation process I had to agree to also sell my soul to Oracle.
  • tar axf ArubaSign*.tar*
  • cd ArubaSing-*/apps/dist
  • java -jar ArubaSign.jar
  • I let it download its own updates. Another time I did not. It does not seem to matter: I get asked that question every time I start it anyway.
  • I enjoyed the fancy brushed metal theme, and had an interesting time navigating an interface where every label on every icon or input field was truncated.
  • I downloaded https://www.pec.it/documenti/Manuale_ArubaSign2_firma%20Remota_V03_02_07_2012.pdf to get screenshots of that interface with all the labels intact
  • I signed the xml that I got from the website. I got told that I needed to really view carefully what I was signing, because the signature would be legally binding
  • I enjoyed carefully reading a legally binding, raw XML file.
  • I told it to go ahead, and there was now a .p7m file ready for me. I rejoiced, as now I might, just might actually get paid for my work.

Try fattura-pa again

Maybe fattura-pa would work with Oracle's Java plugin?

  • I went to https://fattura-pa.infocamere.it/fpmi/service
  • I got asked to verify java at www.java.com. I did it.
  • I told FireFox to enable java.
  • Suddenly, and while I was still in java.com's tab, I got prompted about allowing Infocert's applet to run: I allowed it to run.
  • I also got prompted several times, still while the current tab was not even Infocert's tab, about running components that could compromise the security of my system. I allowed and unblocked all of them.
  • I entered my PIN.
  • Congratulations! Now I have two ways of generating legally binding signatures with government issued smart cards!

Aftermath

I shut down that virtual machine and I'm making sure I never run anything important on it. Except, of course, generating legally binding signatures as required by the Italian government.

What could possibly go wrong?

Posted Thu Jul 2 23:48:36 2015 Tags:
Posted Sat Jun 6 00:57:39 2009