Search Results: "andy"

8 July 2008

Jonny Lamb: debexpo

debexpo (Debian package exposition) is a web application that allows one to run a user-friendly public Debian package repository with social interaction that one may be used to from social networking sites. debexpo will be the basis for the mentors.debian.net site but will be useful for others as well. debexpo is the project I am working on for this year’s Summer of Code for Debian under the watch of Christoph Haas debexpo is more than just a web application though. It was based on suggestions by you, and therefore it has some nifty features: Development can be tracked through its Trac instance: http://debexpo.workaround.org/, where I invite you to submit tickets or even submit patches! Its Git repository is public: http://debexpo.workaround.org/debexpo.git (and mirrored here). Last but not least, the there is also a low-traffic mailing list. I invite you to try it out, and report bugs. Posting to the list is a great way to get in contact. There is little visible eye-candy in your browser to show for the work so far as nearly all the work so far has gone into the backend. A sneak peek at what it looks like at the moment is available though: As you can see, the theme is somewhat familiar. Hopefully, as the SoC program nears an end, this will be fixed. Oh, and hello: this is my first post to Planet Debian.

6 July 2008

John Goerzen: Look out Nebraska, Here Comes Jacob!

img_5195.jpg

This weekend, the three of us got in the car and drove up to Tekamah, NE for Blogstock 08 at Cliff's. That's Jacob when we were stopped at a park halfway there. Sure looks like he's about to do something ornery, doesn't it? I think he looks even more ornery than the photo of Cliff. That's saying something.

We all really enjoyed Blogstock. Ralph, Cliff, and the rest of the Morrows sure know how to have an event. Ralph said that Cliff's BBQ smoked chicken is the best we'll ever have, and he may just have been right.

I'm going to include a few of my photos in this post; you can see all of my 200+ Blogstock photos on Flickr. (In case anyone else uploads Blogstock photos, you might tag them blogstock08).

Jacob had a blast, and I think he took special pleasure in keeping Terah and me busy. I recall saying something like this, all strung together:

"Jacob, please stop throwing dirt at the cat. That cat doesn't like to have dirt thrown on it. Jacob, stop throwing grass on the cat. Jacob, stop hitting the cat. The cat doesn't like to be hit. Can you pet the cat gently like this? Good job! Jacob, stop sitting on the cat. That hurts the cat. Stop throwing dirt at the cat. Would you like to go play in the corn?"

The Morrow cat was the most tolerant cat I've ever seen, and didn't really seem to mind having a toddler sit on its head. However, we noticed this morning that Jacob's legs mysteriously have some scratches that look very much like cat scratches. We didn't see anything happen, and Jacob didn't come crying to us or anything. I suspect the cat found a way to communicate that it doesn't very much like to have someone sit on it. I also suspect that Jacob understood the message.

img_4996.jpg

As for corn -- Jacob loves corn. He first noticed it within the past week or two, and always gets excited when we drove past some. He calls it "koh!", and particularly tall corn is "koh-koh" or "ah-koh". Cliff has tall corn, and when I first asked Jacob if he wanted to see it, he immediately stopped pestering the cat, yelled "KOOHHHHH!!! KOH KOH KOH KOH!!!" and started running towards it. He started by carefully inspecting the corn from the edge of the field. (I can't help but thinking he looks a bit like is great-grandpa Yoder in this picture.) I can almost hear him saying "yep, this corn looks pretty good" in a couple of years.

img_5051.jpg

The real fun begins when you get into the corn, apparently. With a little bit of holding my hand to balance while walking over the rows of dirt, he'd get between the rows of corn and have a blast. That means mainly picking up a full handful of dirt, running to another random corn plant somewhere, throwing the dirt in the general direction of the corn, and cackling like this was the best thing ever. I had to watch out with the camera, because I didn't really care for it to be hit by dirt, and well, I was in the general direction of corn, too.

img_5062.jpg

And, in case you didn't know, having fun in the corn is serious business.

Now, what can a toddler possibly do after playing in the corn, eating some cherries off a tree, and smearing some dirt on his face with cherry juice?

img_5088.jpg

Well, plan his next activity, of course! From the look on his face, it will be another one to keep Terah and me busy.

Jacob seemed to get along really well with everyone. But Ralph said that everytime he came close, Jacob would give him a nasty glare. Here's Ralph holding Jacob. Was this the look, Ralph?

img_5078.jpg

Or maybe it was this:

img_5116.jpg

Friday evening, Cliff and Ralph made up some great hamburgers, hot dogs, and sausages. We all ate under the big tent, and had a nice time visiting. It was sort of an unusual thing -- meeting people you already know for the first time -- but very nice. We left somewhere around 8. Jacob enjoyed the hotel room, too.

img_5027r.jpg

That's Jacob talking on the telephone. Well, I would normally use it as a TV remote, but to Jacob it looks like a phone, so a phone it is. (I can see his point.) This is Jacob answering the phone by saying Hi! Jacob's word for a phone, by the way, is "hi." He'll find a remote by the TV in the room, point to it, and yell "hi!"

Jacob's usual bedtime is 6:30PM. He normally falls asleep fairly easily and sleeps soundly until 6:30AM. Well, we got him in bed well after 6:30PM. Then he made the discovery that the hotel crib/playpen has a mattress that is not attached to the bottom like our mattresses at home are. This was good for at least an hour of excited playing. As Terah and I were trying to sleep, we'd hear these cackles from Jacob's crib, and the noises of a very active boy. I'd peek around and see him using the mattress as a tent, as a peek-a-boo toy, or just as something to throw. I think he fell asleep at about 11.

And woke up promptly at 6:30 on Saturday, just like clockwork, ready to make some phone calls and start the day.

Now, just a tidbit for anyone that doesn't have kids: a toddler, low on sleep, and endless excitement all combine to make for busy parents. Jacob did pretty well, and got in a good long nap in the afternoon. We did take several trips to the corn field.

For most of us, Saturday was a day for brunch, for sitting around and visiting under the tent, for horse rides, and maybe a massage for those that wanted it. Terah got to ride a horse, and Jacob got to ride a pony, too.

For Jacob, it was a day to make new friends, too.

img_5095.jpg

I took this picture just a second after she had given him a hug. I was just a little too slow whipping out the camera.

But when it comes to cherry picking, it's all serious business once again.

img_5098.jpg

Jacob loved eating these sour cherries. At first, he would pick one cherry off the tree, run over to the tent, give it to Terah for her to get the pit out, eat it, then go back to the tree for another one. He must have decided this was inefficient not long after I did. After a few roundtrips, he started trying to get the closest adult, whoever that might be, to pit the cherry for him. When he found one that would do it, he'd keep bringing cherries back to that person.

And then he was under the tree for a long time. Terah and I noticed, and had a conversation about just how many cherry pits it's OK to swallow. But when I checked it out, I found out that Jacob had figured out how to pit cherries himself. He did lose about half a cherry each time he did it, but I guess that was more efficient than pestering adults to do it for him. Though it may have also worked to carry two cherries to the tent at a time.

img_5123.jpg

Late in the afternoon, Cliff started up the smoker for the chicken. He had rented a big smoker for the occasion, but it wasn't working, so he made do with his regular smoker, ovens for the corn, and an array of dutch ovens or side grills for everything else. I couldn't keep track of it all, and I was just watching, but somehow it all turned out perfect.

img_5140.jpg

While the chicken was cooking, Ralph and son-of-Ralph (SOR) were having a conversation and patting their bellies. I couldn't hear, and didn't ask questions, so I'm choosing to believe that they were discussing how many pieces of chicken they could eat. When they heard my camera click, Ralph said, "He didn't just take a photo, did he?" Thereby guaranteeing a spot on my blog.

I had the distinction, I think, of being the least-read blogger at Blogstock. I can't quite remember how many times I'd meet someone, and they'd say, "Oh, you're the computer guy, right? I tried reading your blog, but I didn't understand it, sorry!" Completely understandable, I assure you!

After dinner Saturday, we talked about how we got started blogging (hi, Marty and Andy if you're reading), why we were there. Cliff said some very kind things about Terah and me, which really meant a lot.

Later, Cliff told me how Terah showed up in the kitchen with her tray of deviled eggs. Cliff saw them, and said, "Terah, I love you." Later, Cliff said "I love you" to someone else. From the next room, Terah piped up, "What food did she bring?"

Saturday evening, Terah took her horse ride. Jacob was quite tired by that point, and threw a tantrum about not being able to go with mom and ride a horse, too. We were talking about it when Rachel came over. Jacob asked her to pick him up, she did, and he instantly stopped fussing. Maybe it was a "so there" to me, since I had been holding him a minute before, and he took the opportunity to scream in my ear. But in any case, Jacob loved Rachel. She let him sit on a pony, carried him all around the yard, and he managed to hold it together until Terah came back at 9:30.

Saturday evening it was time for goodbyes. We all had a blast and I'm sure we'll do this again. If you weren't there, here's what Blogstock looks like:

img_4991.jpg

A bunch of friends sitting around chatting under a tent pretty well sums it up.

(There was a full tent of people; some were just elsewhere when this particular photo was taken.)

Jacob shared his thoughts on the whole trip on the way home, too. Well put, Jacob.

img_5202.jpg

4 July 2008

Daniel Burrows: CWidget tutoral 1: 'Hello, world!'

Late last year, I spent some time disentangling aptitude's internal UI library and packaging it as a separate library, which I named cwidget. This article is the first in what will hopefully become a series describing the basic concepts and APIs of cwidget. It applies to the versions of cwidget currently available in Debian sid and lenny, 0.5.11-1 and 0.5.12-1. Autogenerated documentation of cwidget can be found here (but beware that as of this writing it is somewhat incomplete).
In this tutorial, I will walk through a simple program (hello.cc) that initializes cwidget, displays a simple message box, and then terminates the program when the user confirms the message. I assume a basic familiarity with C++. Screenshot of the 'Hello, World' program The first thing to do is to include the portions of cwidget that our program will use. Most importantly, we need the top level cwidget routines. These are the global routines that initialize cwidget, shut it down, and control its main loop (among other things).
#include <cwidget/toplevel.h>
cwidget comes with a collection of stock dialog boxes for things like displaying messages to the user. To access the routines that build these dialogs, we write:
#include <cwidget/dialogs.h>
All the symbols provided by the cwidget library are in the cwidget namespace. Using the full library name means that there's a reasonable chance that its names will not conflict with the names provided by other libraries; however, it's a real pain to type cwidget over and over. Since this is the only namespaced library we are using in this program, it's handy to define cw as an alias for cwidget:
namespace cw = cwidget;
Now we're ready to write the main routine. The first interaction of client code with the cwidget library is to initialize it. This will initialize the ncurses library and put the terminal into a mode suitable for a full-screen curses program.
cw::toplevel::init();
Next, we create a dialog box that will be displayed to the user. There are two things to note about this code:
  1. cwidget is Unicode-aware and the ok() routine expects the message string to be a wide-character string. In this case, that means that we need to pass in a wide-character string (indicated by typing L in front of the string).
  2. The second argument tells cwidget what to do when the ok button is pressed. The expression
      sigc::ptr_fun(cw::toplevel::exitmain);
    
    creates a slot using libsigc++. Briefly, a slot is a reference to a function or to a method of a class instance. When invoked, this particular slot will call cwidget::toplevel::exitmain(), which causes the main cwidget loop to exit. The slot is wrapped in cwidget::util::arg, a utility function that handles passing slots as optional arguments.
cw::widgets::widget_ref dialog =
    cw::dialogs::ok(L"Hello, world!",
                    cw::util::arg(sigc::ptr_fun(cw::toplevel::exitmain)));
Now that we have a widget, the next step is to arrange for it to appear on the terminal. In cwidget, control of the terminal is assigned to a single top-level widget: whatever it displays is what gets displayed on the terminal, and all user input is passed directly to it. In a real program this widget will typically manage a collection of sub-widgets and assign each one a screen region, but for now let's just display the dialog box we created:
cw::toplevel::settoplevel(dialog);
With everything initialized, we're ready to start the main loop. mainloop() will keep the display up-to-date and dispatch incoming events (for instance, keystrokes and mouse presses) until exitmain() is invoked.
cw::toplevel::mainloop();
When the user presses Enter or clicks on the Ok button in the dialog, exitmain() will be invoked by the binding that we set up earlier. Once this happens, we need to shut down cwidget in order to restore the terminal to its original state. If you skip this step, the terminal will be garbled and will not work properly when your program exits.
cw::toplevel::shutdown();
And that's it! To compile the program, change to the directory containing hello.cc and run:
$ g++ -o hello hello.cc $(pkg-config --cflags --libs cwidget)
Of course, you'll need to have the g++ and libcwidget-dev packages installed for this to work!

30 June 2008

Marc 'Zugschlus' Haber: Serial Console Server for the Poor III

This is the third installment of my article about the Serial Console Server for the Poor. First installment here, Second installment here. The first part of the article having covered the hardware and the udev part creating the device nodes, and the second part explaining how to solve the software part using ser2net, this part explains why ser2net was ditched in favor of cereal and how the console server operates with cereal now. Cereal (which I was pointed to on IRC as a reaction to article II) is a nifty combination of runit’s runsv and screen. One of the less-known features of screen is that screen can also connect to a serial port instead of a “real” console. cereal makes use of this feature, putting up with the fact that screen can only set a baud rate. I have not seen a serial application with other parameters than 8n1 (8 data bits, no parity, 1 stop bit) in a decade, so I cannot comment whether this is a real disadvantage. I guess that it might be possible to set the serial port to the desired set of parameters before starting up screen, but I didn’t actually try it since I do not need it. Cereal uses a set of configuration parameters and processes called a “session” to associate a serial port with a baud rate and a set of user/group settings to control who is able to start, stop, attach or detach a session. It doesn’t have a “real” configuration file. Instead, it has an admin program, cereal_admin, which takes the parameters associated with a session and writes them to an (intentionally? undocumented?) set of config files in /var/lib/cereal. Only a single user is able to attach to a session read/write, while an entire group can attach to a session read-only and can thus access the logs. A session is automatically started when the sysem boots and can be stopped and started using cereal_admin as well. Once a session is running, a specially configured screen process runs attached to the serial port, and users simply attach and detach to and from it as one would to a normally running screen. That way, one can scroll back and examine what was shown on the serial port while nobody was attached. This is quite handy when the device connected to the port prints out warnings, errors and status information to its serial port. The screen configuration that is used is rather sophisticated. So, a permanent log file is written, which is also used for read-only access to the serial session. Also, a very informative status line is configured. Unfortunately, one of screen’s biggest disadvantages applies here as well: User X cannot attach to a session started by User Y unless Y has access privileges for X’s pty (or vice versa, I never can remember), which can be a security risk. Additionally, it is not possible to su or sudo to X and then to attach to the session - one needs to have the original pty opened by the correct user, which usually means that one needs to do a “real” log in with the correct account (via /bin/login or sshing in to the box). If one has the privileges necessary, one can use the cereal executeable to attach to the screen (which gives read-write access) or to tail -F the log file (giving timestamped read-only access). That way, one never knows that one is actually working with an appropriately configured screen that is kept running by runit. The restrictions coming with cereal suggest a setup similiar to what I did with ser2net previously: Each session has its own user account, which forces an attach to the appropriately named cereal shell on login:
my-device-name:x:1801:1801:my-device-name,,,:/home/my-device-name:/usr/local/sbin/cerealshell
$ cat /usr/local/sbin/cerealshell
#!/bin/bash
set -eu
cereal attach $(id --user --name)
$
You can see that I decided to name the sessions after the actual device name, allowing the unterlying ttyUSB device name to change without change in the user interface. The actual users and sessions were created with a small shell script:
#!/bin/bash
createconsole()  
  NAME=“$1”
  PORT=“$2”
  BAUD=“$3”
  MUID=“$ PORT/USBserial/180 ”
  echo sudo addgroup --force-badname --gid $MUID $NAME
  echo sudo adduser --force-badname --gecos “$NAME,,,” --ingroup $NAME --uid $MUID --disabled-password
$NAME
  echo sudo adduser $NAME dialout
  echo sudo mkdir -p /home/$NAME/.ssh
  echo sudo chmod 755 /home/$NAME/.ssh
  echo sudo touch /home/$NAME/.ssh/authorized_keys
  echo sudo chmod 644 /home/$NAME/.ssh/authorized_keys
  echo sudo chown $NAME:$NAME /home/$NAME/.ssh /home/$NAME/.ssh/authorized_keys
  echo sudo cereal-admin create $1 /dev/$2 $3 $1 $1
  echo sleep 2
    echo sudo cereal-admin start $1
  echo echo -----
 
createconsole my-device-1 USBserial1 9600
createconsole my-device-2 USBserial3 115200
Note that the script also uses a hardcoded UID range which might need adaption to your local needs (and breaks for more than ten serial ports), and that it also takes care of creating an empty authorized_keys file with correct permissions. That way one can simply ssh to my-devlce-1@consoleserver and find oneself immediately connected to the serial console, seeing the last things that happened on the serial port, and immediately being able to work with the device. That’s fine, comfortable and useable. I actually like that better than what I built with ser2net previously.

26 June 2008

Stefano Zacchiroli: firefox 3 un-ranting

Gunnar, have a look at this: iceweasel-ssl.png. So your example using the Penta website was just a bad one, and I personally agree with the "INVALID" resolution of your bug report. In fact, showing a partially encrypted connection as an insecure one is an overall advantage for (l)user securities, as with the browser interfaces we are used to use, we don't know which parts are actually sent encrypted and which are not. As you can see in the example above a fully encrypted connection is properly reported as such by Firefox 3.0. FWIW: I'm overall satisfied with Firefox 3.0, especially about the new URL bar Wouther is disliking. Yes it is a bit slower than before, but even on my 4-year old laptop it is perfectly usable. The HTML title shown there? Well, it is rather handy when I start typing bugs.debian.org and then I've to discriminate among tons of almost identical bug report URLs ... Is the about:config hand-holding dialog worst than the pop-up the first time you "have provided unencrypted information" in a random form? It is not, we have probably just forgot about the first time we unchecked the corresponding checkbox. All in all, the only "feature" of the new Firefox I found incredibly stupid is the SSL certificate exception mechanism. Installing the untrusted certificate is what? ... 5 click-away from the initial page? That is just dumb. (And as it is well-known that habits form anyhow, getting the habits harder to form is just a way to piss-off users.)

25 June 2008

David Moreno Garza: YAPC::NA 2008

So I attended the conference last week in Chicago, IL. I was just been procrastinating to write about this.

As a (almost) complete outsider of the Perl community, I have countered thoughts about the whole event:

After all, it was quite a nice and new experience. I'm not totally sure I'll attend YAPC::NA 2009 in Pittsburgh, PA, we'll see.

Clint Adams: Relaxation

I was misled. That much is probably true. I certainly had no idea what I was getting myself into. Enough of that though; there's narrative fading away. The part I should take responsibility for is the decision I made to stray off the map. Perhaps it was not so much a decision as a compulsion. I looked at the map. I saw the suspicious unmarked area at the edge, and concluded immediately that there was something good there, something the people wanted to keep hidden from me. I was correct, but I presumed far too much about the terrain. I thought I would make a quick exploration of the secret place, then backtrack to the more mapped area and get back with the program. Enough of that though; I've nearly forgotten the story. First I should point out that, had the map been to scale, it should have taken me an leisurely fifteen minutes to get to my first destination. It should have, assuming the land would be as flat as the map that represented it. Instead, it turned out to be something one could cover in fifteen minutes if one had, say, a jetpack and spring boots. I'm probably wrong; I'd probably injure myself in the process and take longer. Anyway, the average incline was close to 45 , and luckily was mostly uphill. Luckily. When I got to a resting place, I was able to conclude that my supply of fluids was almost certainly insufficient for me to continue. On the other hand, there was probably no way I would return if I went back for more drink. I told myself that there would likely be a beverage-selling shack out in the middle of nowhere around the next bend or so. Having solved this probability problem, I pressed on into the blazing sun. I came to a path leading down to the sea. It was unclear what was down there, but it was clear that it seemed to be a million miles down, and that that path might be the only way back. Given my current state of exhaustion and hydration, I decided to pass on this opportunity. After continuing for a while, the features at the bottom of that path became visible. A very pretty cove was down there, and almost certainly no shack o' drinks. I then came upon a fork. A wide path led downward: to what, I could not see. To its left, a narrow and rough path led straight. Knowing that a descent probably meant climbing four to eight times the altitude back somehow, and assuming the less pleasant-looking path led somewhere better, I went left. After a while, the land began to slope down, ever so slightly. Little clusters of bottles and newspapers were left on the rocks here and there. Then came a sofa under a tent. I began to wonder what hippies were traveling this path. The slope grew greater, and I passed a bench in a tent. Then I came to a giant staircase, almost straight down. It was covered in weeds and insects. Some were vegan, some wanted my flesh. As I got toward the bottom I thought about how glad I was that I had come that way from the top and not the other way around. Oh, I was very glad. At the bottom was something resembling a plastic bottle graveyard and barrels among barrels filled with water. Rubber hoses seemed to run randomly between certain barrels. A kitchen stood at the edge of some barrels. I suddenly got the feeling that I was not supposed to be here. After discovering that a couple of escape routes were actually dead ends, I proceeded to descend a small staircase to a terraced garden. Hoses lay about the rows, presumably for watering the plants. A cot under a tent lay empty, and I hurried past hoping I would not encounter the owner. Then I was at the ocean. The coast was lined with huge boulders, and a wooden bridge led me to the first one, and another wooden bridge took me to the second. Then the bridges stopped. In the distance, I could see that pretty little cove from before. I took stock. I could either return whence I came, up that horrifying staircase, or I could try to traverse the rocky coast over to the cove, then maybe do a faceplant on the beach and let the tide drown me rather than climbing back up. It seemed like a no-brainer, so I began making my way toward the cove. It got harder. Several times I became very afraid, either of falling and smashing my head against a rock or falling into the water below, or some sequential combination thereof. In the end I turned out to be more afraid of going back, at least until I got to what I judged the point of no return. I was reasonably close to where I imagined the sandy beach started, but there was a huge and impassable boulder in the way. Also, if I went further there was no way I would be able to climb back up in case I needed to retreat. I was thinking I would need to retreat, because unless there was some magical hidden toehold, I would be forced to jump into the water and swim around. I did not want to jump into the water. I wanted my phone to stay unfried in the event that I would need to use it to get rescued. I also did not want to call anyone to get rescued, especially since I didn't really know how to explain where I was. With a heavy sigh, I gave up, turned, and went back. This time I moved more quickly, though incurring more damage to my hands and feet. No humans were visible at the crazy farm/garden and makeshift reservoir, but plenty of bugs were visible on the staircase. I made the mistake of trying to lean against the railing to catch my breath. When I finally got to the bench in the tent, I understood exactly what it was for. I sat down, took a sip of my remaining water, ate an apple, and kept going up. When I got to the couch, I sat again. This time I sat and tried to figure out a plan. I still clung to the belief that once I got back to somewhere less wild I'd be able to buy a drink. I noted that I only had a little bit of water left, that I was dehydrated, that I was sunburned, that my pulse was about 180, and that there were no dogs or Russian people wandering past me. I ate a pear and drank my last few drops of water. I kept sitting until my pulse was down to around 150, then I figured I needed to keep moving. I was experiencing most of the effects of caffeine, and for free. Oddly, I passed a dog a few steps later. It was just standing by a rock, looking at me. I decided not to converse. When I had nearly reached the fork again, a couple came my way. I thought about begging them for water. I decided not to be rude. I have no idea what happened to them. I'm betting they wisely decided not to go down the steps. Resolving that the only sane option was to go back all the way to where I absolutely knew I could buy something potable, I headed in that direction. Still, I took two risks. Instead of going up the exact way I had come, or taking a well-travelled path down, I took a narrow and flat dirt path. It was actually a bit of a dilemma. I started down the latter two more than once each. Finally I saw that the down path was rather V shaped, and I concluded correctly that the straight path would bypass that angular-half-pipe-like construct. When I finally got to a point I recognized, it was smooth sailing the rest of the way down. I bought water and a snack, since I had had almost nothing to eat that day. At this point it would have been prudent to call it quits and go off and gorge myself on seafood or something, but no, I was now in the mapped area and surely it would all be roses and manna. Finishing one bottle, I bought two more. Five minutes later I bought another. I had now overcompensated, but I was playing it safe. I continued my explorations. Bicyclists kept nearly running into me, and, aside from the obvious, I viewed this as a good sign. Bicyclists, especially those that can't seem to steer straight for some reason, avoid difficult terrain. This is why they take their bikes on subways, trains, and buses. I don't like bike-riding, but if I had my druthers, I would always go downhill. No up, no flat, just down. Like downhill skiing, just down. It is a good thing I don't ride a bike. Once I got to the point where the bicycles thinned out to nonexistence, I was at an intersection. The way I wanted to go was up. The way I didn't want to go, but was a reasonable option, was only very slightly up. Additional factors complicated this decision point. [elision] This passage has been marked friends-only and you will not be able to view it without logging in. Moving hurriedly away from there, I headed upward. After a couple of turns, I ran into Catholics. First there were dead Catholics. Then there were Catholics pre-occupied with dead Catholics. Then there were Catholics waiting to die. Then there were seminarians. Then there were teens with prayer books. When I reached the next pinnacle, there were more teens with prayer books. There were benches, and there were no teens on them, for the teens were standing or sitting on the ground, quietly contemplating the Word. Unfortunately, they had decided that the benches were more suitable for holding all their bags, so there was nowhere for me to sit. I considered interrupting their reverie, but decided it wouldn't be very Christian of me to disturb them, so I just placed an ancient Drasnian curse on them and plodded down the hill toward a small beach. I really didn't need any more sun, but at least there probably wouldn't be anyone praying there. The water was tempting, but I'm always paranoid about my belongings when swimming alone, and if my phone were taken I wouldn't be able to call anybody to come rescue me at the next crisis point, sure to come. So I skirted the coastline and arrived at a much larger beach, one with facilities and services. Opting to save money but complicate things by using the public changing rooms and showers, I made a discovery. [elision] This passage has been marked friends-only and you will not be able to view it without logging in. Nonetheless, I changed into my swimming trunks, stuffed everything else but my towel, sunglasses, and a disgusting sugary drink I never should have bought into my bag, and went barefoot a few buildings down to rent a locker. The locker was ridiculously large for a single person, which is good to know should I ever want to kidnap a family and torture them at this place. The proprietor informed me that they were closing at some specific time, about an hour from then. I had no timekeeping device outside of the locker, so I had to wing it, and erring heavily on the side of caution, I had a short beach diversion. Given that large swathes of my epidermis were turning bright red, it's probably for the best. Handling the shower, locker, and changing in the other direction was slightly more complicated, but I did it and then I headed inland, figuring I should have a substantial meal for once that day. On my way to find dinner is when things got really crazy. [elision] This passage has been marked friends-only and you will not be able to view it without logging in. I wandered over to a bench to eat my newly-acquired snack, and did not exercise enough caution, because the flimsy paper bag ripped and I got sauce all over my pants and a little on my shirt. Unfortunately I had used my napkin in that earlier episode, and I'm not sure how much it would have helped anyway. Thus I continued on, looking like a slobby retard. Then I made an obviously-poor decision and ended up having a subpar dinner. What happened after that is a story for another time.

23 June 2008

Jonathan McDowell: BarCamp Belfast 2008

I spent Saturday at BarCamp Belfast. There were more people than I expected; I'm no good at judging exact numbers but the wiki lists 62. As it turned out not everyone ended up talking; this worked out well for me because I don't think I'm Web2.0 enough (is that a bit ironic given I'm writing this on a blog?). I don't really do user interfaces or website stuff and that seemed to be the primary focus of a lot of the attendees. Nice to know there's a fairly active crowd in
Belfast though; I discovered the existence of Belfast Open Coffee which I'll have to try and make at some point.

I went to at least the following talks::

Gerard McBreen on Digital Circle & Adobe Flex: Quite a cute demonstration of the Flex framework for Flash. I'd have been more convinced if Flash could be considered truly cross platform; Adobe can't even manage a 64 bit client yet and Gnash is far from ready.

Daniel McLaughlin on Nagios: Not really anything I didn't already know, but always interesting to see how other people are using these things to see if there's any nice tricks you've missed.

Andrew Gribbon from Exile Coffee on speciality coffee: This was really interesting. A complete tangent from IT but enjoyable and I must buy some roasted beans from him (I've been meaning to place a Roast and Post order for ages anyway).

Brian O'Neill on freelancing: Tailored towards the web market in my opinion, which is fair enough but things like aiming to never employ anyone and stay a one man operation doesn't really work if you're doing something that a customer wants supported around the clock. Or even just during the working day if you're crossing time zones. Interesting to hear that Brian had run an agency in the past but preferred working on his own these days. I kinda feel I've gone a bit the other way. :)

Linux Hardware workshop: Not really a lot of interest here; a clutch of EEEs, an N800 and a Debian box or two. However I had a chat with David Newman about his MythTV setup which convinced me I really should give it another try. After I get someone to install a bigger aerial in the hope of stabilising our Freeview reception.

Brian Cleland on Linux Trends: Talking about lots of Linux takeup by big names and general market adoption eg the recent selection of cheap subnotebooks. Main thing of interest was OpenPandora which I hadn't heard of before; OMAP3 based handheld device running Linux with a 800x480 4.3" screen. Aimed as a gaming device, but has a keyboard and bluetooth/wifi so has potential as a PDA as well. Hopefully the build quality will be better than the GP2X I saw.

Andy McMillan on coffee shop working: I've thought about this in the past myself; I worked from Cafe Java in Norwich a few times while doing Black Cat, but in general didn't find it as conducive to work as I'd hoped. He mentioned Coworking Belfast which is an idea Tristam has talked about in the past, in terms of people who work from home getting to have some form of social contact with like minded individuals, without having to go to the expense of a whole office. It'll be interesting to see if it takes off.

Darragh Doyle and Grannymar on blogging: I think everyone in the audience already had a blog of some description. I don't really consider my blog a social forum; it's not something I expect to have a long conversation on, just ask a quick question or discuss something
I've done that I think might interest people or give a general "this is what's happening at present" post. Blog commenting systems are all a bit crap to keep up anything sustained. Someone needs to write a blog<>nntp gateway that correctly cross posts comments as well. I suppose the issue with that is then everyone needs to run a news server, or all agree on
using the same one. Fine for groups of people who know each other but not if you want to read a dozen blogs from different areas in a single client that'll let you properly follow conversations. Mind you, people seem to cope with forums and I don't really understand how. Supporters of news and mailing lists seem to be dwindling. :(

Anyway, that was my first BarCamp. I wasn't quite sure what to expect, it was a bit more Web2.0 than I'd have liked (which is fair enough, but I'd have liked to have seen some talks about low level bits really) but I'd go again and will keep an eye out for the next one. And hopefully I'll see some of the people I met there at the BLUG meeting this Wednesday (Tap House in Lower Crescent from 6pm for anyone who's not on the mailing list).

17 June 2008

Daniel Silverstone: Scary licence questions follow

I have, at several points over the past few years, been interested in finding out quite how the GPL applies when one has runtime dynamic linking in the mix. As such, I would like to set a little scenario up and then solicit responses from you as to how things might go. I have yet to receive any useful answers which consider all the aspects. Several people have basically said oooh, hard.. erm therefore you can t do it , and the FSF have told someone I know who asked essentially this question, erm consult your lawyer ; and it took them four months to say that. So, with all that in mind, here we go Setting the scene
  1. There exists a company SuperMegaCorp...
  2. ...who have a software product called FantasticUsefulApp...
  3. ...which is released to the public in a proprietary/pay-for kind of way...
  4. ...but has a BSD licenced set of header files for third parties to write plugins distributed with it.
  5. There exists a useful GPLv2+ed library HandyStuffs...
  6. ...which is authored by a freedom loving software engineer called Fred.
  7. A pragmatic, yet freedom loving software engineer called Pete...
  8. ...who does not know Fred...
  9. ...writes a plugin for FantasticUsefulApp which we shall call IncrediblyCoolPlugin...
  10. ...which incorporates parts of the HandyStuffs codebase...
  11. ...and is GPLv2+ed by Pete...
  12. ...who then releases it to the wider world on his website.
Next, the following happens
  1. Seeing that Pete has written IncrediblyCoolPlugin for their FantasticUsefulApp...
  2. ...a user of the app called Uhura downloads it in binary form and drops it straight into the plugin folder.
  3. Uhura then starts FantasticUsefulApp which proceeds to dynamically link itself to IncrediblyCoolPlugin for the duration of Uhura's use of the app.
So here is question one Is anyone violating any of the GPLv2 s terms (or the GPLv3 s terms) by doing this at any point? If so, who is violating which terms, and how can that be fixed without losing functionality? Extending the scenario
  1. Uhura loves FantasticUsefulApp a lot. She also really loves IncrediblyCoolPlugin and wishes that each time she made a new installation of the app it would come with the plugin.
  2. Uhura writes to SuperMegaCorp and asks them to include IncrediblyCoolPlugin with FantasticUsefulApp.
  3. Liking the idea, and mindful to place the source code to IncrediblyCoolPlugin on their distribution media, SuperMegaCorp proceed to distribute the plugin along with their app in one easy to install bundle.
Here is question two Is anyone violating any of the GPLv2 s terms (or the GPLv3 s terms) by doing the above? If so, who is violating which terms, and how can that be fixed without losing functionality? (For this question, consider the bundling of the plugin and the app together as functionality it is preferable to retain.) An alternative way to extend the scenario
  1. Concerned about the possibilities of upsetting freedom lovers, SuperMegaCorp decline to distribute IncrediblyCoolPlugin with their app...
  2. ...however instead they distribute a plugin which connects to Pete's website and downloads IncrediblyCoolPlugin the first time FantasticUsefulApp loads, installing it for the user automatically.
And question three Is anyone violating any of the GPLv2 s terms (or the GPLv3 s terms) by doing the above? If so, who is violating which terms, and how can that be fixed without losing functionality? If anyone has any useful ideas on this, please either email them to me, or blog about it and email me a link. I intend to post a precis of the answers in a future entry.

24 May 2008

John Goerzen: How to Start Bicycling to Work

Yesterday, I wrote about bicycling to work, pointing out that it's a safe, inexpensive, way for many people (including office workers without access to showers) to get to work. There were a lot of thoughtful comments there too.

Today I'd like to provide some tips for getting started commuting on a bicycle. As I'm just getting started on this, these are mainly things I've learned from poking around online, so I'll be including lots of links.

The Bicycle

This varies from person to person, but as a general rule: if you have a very short ride -- say a mile or less -- you can probably just use any old bike and a bicycling helmet. Don't try to use a motorcycle helmet. It won't vent your head, so you could overheat. Also, it won't be comfortable.

Most people will have a longer ride and will want to get a bike that works specifically for them. Each model of bicycle comes in different frame sizes. It's important to get a bicycle that is the right size for you. Also, you'll want to get a quality bicycle that will let you be fast and won't break down along the way.

For all these reasons, I -- and every single other person I've ever seen talk about this -- highly recommend that you buy your bicycle from a bicycle shop. Don't buy a bicycle from a "big box" store like Walmart or Target. They may be cheaper up front, but you'll pay for it in the long run because they won't last as long, won't fit you as well, and may even be unsafe. Bike shop staff will help you find a bike that fits you, which is important for avoiding aches and pains and even injury. They'll be able to help you find appropriate accessories for your bike, as well as repair it. Here is a helpful article on this topic, written by a bike shop.

Generally speaking, bike shops can repair bikes bought at any other bike shops. However, they can instantly recognize bikes bought at big box stores. Many will repair those too, but some refuse to work on some of those bikes on the grounds that it is impossible to bring them to the level of service they expect their mechanics to do.

Aches and Pains

With any sport, when you start it, you can expect a little bit of aches and pains at first, as you start using muscles that you may not have really used at first. Bicycling is no exception, but it's easy to deal with.

Your first stop if you have aches and pains might be the where does it hurt page. It provides detailed, helpful advice. There are also some common things that go wrong for people.

First on the list is wrong size of bike or improper adjustment of your bike. You want a bike frame that is the right size for you, and you want the seat and handlebars adjusted properly for you. A bike shop can help you get this done easily. If your feet can reach the ground while you're on the seat, you almost certainly have the seat too low, which is a common mistake.

Sometimes the way you position yourself on the bike, or your technique, could be to blame.

Also, clothing can be a problem. A good place to start here is with some cycling shorts. Another common complaint from new cyclists appears to be blisters on the feet. This can be caused by improper positioning on the pedals, or by using the wrong type of sock. Typical socks absorb moisture and trap it next to the skin; bicycling socks will wick it away and let it evaporate. In fact, cycling clothes: socks, shorts, and jerseys (shirts) are all designed to wick moisture away from you and let it evaporate, which keeps you cooler and more comfortable. Bicycling gloves are cheap and can help your hands stay comfortable.

Expense

You can easily save thousands of dollars by riding a bicycle instead of driving a car. Bicycles do need periodic maintenance, just like a car. Usually you can do a lot of that yourself. It probably will pay off to take your bike in to the shop for an annual tuneup. If you have no bicycling equipment at all, and buy your equipment at a bike shop new, you can probably get started for around $500. Even that will probably pay for itself in less than a year if you average riding your bike at least a few times a week.

Safety

Safety on a bicycle can usually be summed up with three rules: be visible, be predictable, and ride with traffic.

Unless there are dedicated bicycle-only lanes or paths, the safest way (in the United States) to ride your bike is on the road, riding with traffic (acting like a car). Don't ride on a sidewalk, and never ride against traffic. This may sound counter-intuitive, but it is backed up by solid research. It all has to do with being predictable. Nobody is looking for something the speed of a bicycle to emerge from a sidewalk to cross a road or driveway. Sidewalks often aren't that visible and frequently don't provide enough room to pass. Sidewalk-riding cyclists get into accidents all the time with cars backing pulling out of driveways, making turns, or even just driving down a road where the cyclist cuts in front of them to cross a street.

A great book for learning how to ride in traffic can be viewed free online: the Bicycling Street Smarts book. There are also some safety videos online that are helpful.

Staying visible is certainly important. In some places, like cities where cyclists are common, drivers are going to be on the lookout for you already. In my case, I'm riding on rural roads that have some hills, where cyclists are rare, so I'm putting extra effort into this.

Staying visible in the day or at night starts with high-visibility clothing. A "screaming yellow" jersey or an ANSI safety reflective vest (less than $10) are good ways to do that. Several people recommend a Cateye TL-LD1100 flashing tail light for use at night, or even for daytime use when visibility is critical (such as my situation). If you will ever ride at night, laws require you to have the proper reflectors on your bike. And, you must also have a white headlight that does not cover up your front reflector (in some locations, you may also be required to have a red tail light that doesn't cover up your reflector). Companies like Cateye carry those products as well.

Other tips: avoid drainage covers; they sometimes have slats that a bicycle tire could fall into.

Accessories

Here are some suggestions you might consider as a commuter.

Start with pannier bags. They mount over your rear tire and are cooler for you than a backpack because your back can still breathe. They're more aerodynamic than a front basket. You can get bags suitable for carrying papers, laptops, a change of clothes, etc.

Next on your list might be a bicycle lock, to help keep it from being stolen. Your local bike shop can make suggestions here.

You might want to consider a spare inner tube (about $5) and tire-changing tools (also about $5) to carry with you in your bag. You wouldn't want to have to walk 5 miles if you get a flat.

Along with that goes an air pump. I suggest a frame pump -- it's a small pump that can clip on to your bicycle's frame, so you always have it handy. Obviously you will need this if you have to change a tube, but it could be handy even if you don't.

You can find some more suggestions from bicycling.about.com and from Mike or your local bike shop.

Where to buy

Besides your local bike shop, you can buy a lot of accessories online. I wouldn't suggest buying a bicycle online, because you really want to get a good fit at a bike shop.

When I asked at bikeforums.net, readers suggested three online stores:

www.pricepoint.com
www.bikenashbar.com
www.performancebike.com

You can also find some bicycling accessories at general-purpose stores like Amazon or sporting goods stores like REI. I personally wouldn't recommend local "big box" sporting goods stores any more than I would Walmart or Target for this stuff, though.

More info

For more information, check out my bicycling links at del.icio.us.

6 May 2008

Ond&#345;ej &#268;ert&iacute;k: snapshot.debian.net saved me again

On one computer I am taking care of, I suddenly started getting:

$ ps2pdf fa_808.ps fa_808.pdf
/usr/bin/ps2pdfwr: line 45: exec: gs: not found

What's wrong?

$ ls /usr/bin/gs
ls: cannot access /usr/bin/gs: No such file or directory
$ wajig find-file /usr/bin/gs
ghostscript: /usr/bin/gs
$ wajig list ghostscript
ii ghostscript 8.61.dfsg.1-1 The GPL Ghostscript PostScript/PDF interpret
ii ghostscript-x 8.61.dfsg.1-1 The GPL Ghostscript PostScript/PDF interpret

That is really weird, the file /usr/bin/gs is simply missing, even though I have the ghostscript package installed. Ok, let's reinstall it:

$ wajig reinstall ghostscript
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libwine-capi libstdc++5 libopenal0a xgnokii libglut3 libcapi20-3
libggi-target-x lib64gfortran2 libsvg1 lib64gomp1 libggi2 libgii1
libgii1-target-x libxine1-gnome cups-pdf lib64objc2
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
akregator gs kaddressbook kaddressbook-plugins kalarm kandy kappfinder karm
kate kcontrol kdebase-bin kdebase-data kdelibs-data kdelibs4c2a
kdepim-kfile-plugins kdepim-kio-plugins kdepim-kresources kdepim-wizards
kdesktop kghostview kicker kitchensync kleopatra kmplayer kmplayer-common
kpersonalizer ksplash libarts1c2a libgnutls26 libgs8 libilmbase6 libkcal2b
libkdepim1a libkleopatra1 libkmime2 libkonq4 libkpimidentities1 libktnef1
libopenexr6
Suggested packages:
kdeaddons-doc-html ntpdate ntp-simple perl-suid egroupware ffmpeg xawtv
gnutls-bin
The following packages will be REMOVED:
digikam kde-amusements kde-core kdeaddons kdebase kdebase-kio-plugins kdepim
kmail kmailcvt kmplayer-plugin knights konq-plugins konqueror
konqueror-nsplugins korn smb4k
The following NEW packages will be installed:
gs libgnutls26 libilmbase6 libopenexr6
The following packages will be upgraded:
akregator ghostscript kaddressbook kaddressbook-plugins kalarm kandy
kappfinder karm kate kcontrol kdebase-bin kdebase-data kdelibs-data
kdelibs4c2a kdepim-kfile-plugins kdepim-kio-plugins kdepim-kresources
kdepim-wizards kdesktop kghostview kicker kitchensync kleopatra kmplayer
kmplayer-common kpersonalizer ksplash libarts1c2a libgs8 libkcal2b
libkdepim1a libkleopatra1 libkmime2 libkonq4 libkpimidentities1 libktnef1
36 upgraded, 4 newly installed, 16 to remove and 683 not upgraded.
Need to get 53.1MB of archives.
After this operation, 42.9MB disk space will be freed.
Do you want to continue [Y/n]? n
Abort.

Oops, unstable is broken at the moment. Ok, what now? Well, snapshot.debian.net comes to rescue again. Find "ghostcript", version "8.61.dfsg.1-1" and here we are:

$ wget http://snapshot.debian.net/archive/2008/03/02/debian/pool/main/g/ghostscript/ghostscript_8.61.dfsg.1-1_i386.deb
$ wajig install ./ghostscript_8.61.dfsg.1-1_i386.deb

And all is fine now:

$ ls /usr/bin/gs
/usr/bin/gs

2 May 2008

Russell Coker: The Future of Xen

I’m currently in Xen hell. My Thinkpad (which I won’t replace any time soon) has a Pentium-M CPU without PAE support. I think that Debian might re-introduce Xen support for CPUs without PAE in Lenny, but at the moment I have the choice of running without Xen or running an ancient kernel on my laptop. Due to this I’ve removed Xen from my laptop (I’m doing most of my development which needs Xen on servers anyway). Now I’ve just replaced my main home server. It was a Pentium-D 2.8GHz machine with 1.5G of RAM and a couple of 300G SATA disks in a RAID-1. Now it’s a Pentium E2160 1.8Ghz machine with 3G of RAM with the same disks. Incidentally Intel suck badly, they are producing CPUs with names that have no meaning, and most of their chipsets don’t support more than 4G of physical address space [1]. I wanted 4G of RAM but the machine I was offered only supported addressing 4G and 700M of that was used for PCI devices. For computation tasks it’s about the same speed as the old Pentium-D, but it has faster RAM access, more RAM, uses less power, and makes less noise. If I was going to a shop to buy something I probably would have chosen something different to get support for more than 4G of RAM, but as I got the replacement machine for free as a favor I’m not complaining! I expected that I could just install the new server and have things just work. There were some minor issues such as configuring X for the different video hardware (and installing the 915resolution package (which is only needed in Etch) to get the desired 1650×1400 resolution. But for the core server tasks I expected that I could just move the hard drives across and have it work. After the initial install the system crashed whenever I did any serious hard drive access from Dom0, the Dom0 kernel Oopsed and network access was cut off from the DomU’s (I’m not sure whether the DomU’s died but without any way of accessing them it doesn’t really matter much). As a test I installed the version of the Xen hypervisor from Unstable and it worked. But the Xen hypervisor from Unstable required the Xen tools from Unstable which also required the latest libc6, and therefore the entire Dom0 had to be upgraded. Then in an unfortunate accident unrelated to Xen (cryptsetup in Debian/Unstable warns you if you try to use a non-LUKS option on a device which has been used for LUKS and would have saved me) I lost the root filesystem before I finished the upgrade. So I did a fresh install of Debian/Unstable, this time it didn’t crash on heavy disk IO, instead it would lock up randomly when under no load. I’ve now booted a non-Xen kernel and it’s working well. But this situation is not acceptable long-term, a large part of the purpose of the machine is to run virtualisation so that I can test various programs under multiple distributions. I think that I will have to try some other virtualisation technologies. The idea of running KVM on real servers (ones that serve data to the Internet) doesn’t thrill me, Tavis Ormandy’s paper about potential ways of exploiting virtual machine technologies [2] is a compelling argument for para-virtualisation. Fortunately however my old Pentium-3 machines running Xen seem quite reliable (replacing both software and hardware is a lot of pain that I don’t want). In the near future I will rename the Xen category on my blog to Virtualisation. For older machines Xen is still working reasonably well, but for all new machines I expect that I will have to use something else - and I’ll be blogging about the new machines not the old. I expect that an increasing number of people will be moving away from Xen in the near future. It doesn’t seem to have the potential to give systems that are reliable when running on common hardware. Ulrich Drepper doesn’t have a high opinion of Xen [3], the more I learn about it the more I agree with Ulrich.

24 April 2008

Joachim Breitner: Pausable IO actions for better GUI responsiveness

For a university seminar I m currently writing a GUI program to view fractals based on simple iterated function systems (only similaritudes allowed). It supports three different drawing algorithms and you can edit the IFS by dragging squares around on the screen. But this post is not about this program (I might present it later), but how Haskell allowed me to solve a problem very nicely:The first instances of the code had a problem that a lot of GUI programmers know: The drawing of the fractal took quite some time, and during that time the gtk main loop is blocked and the program becomes unresponsive. At first I avoided this problem by manually splitting the drawing function (e.g. by repeatedly increasing the resolution) and kept re-drawing it at higher resolutions in an idle handler, so at least I could interact whenever one resolution has finished drawing. It worked somewhat but it was not easily done for the other, not pixel based, algorithms and it was ugly.So I wanted a way to (a) pause the drawing at any convenient point, to resume it later, and (b) safely abort the drawing if what I m drawing has changed and I need to restart.A common solution to this would be to do the drawing in a separate thread, so (a) is actually not needed, but I did not know if I can safely do (b), and I have heard that threads cause problems with gtk.So I tried to dig deeper for the hidden treasures of advanced haskell programming: I need a monad transformer! I expected the infamous ContT monad transformer to help, but I couldn t figure out how, and I started to create my own monad transformer, called CoroutineT.I tried to figure out what an action of type (CoroutineT IO a) should do, and I came up with this type signature:
pausingAction :: IO (Either (CoroutineT IO a) a)
which means that after the pausingAction is done, it is Either paused (and I get back another pausingAction to run when I want it), or it is done (and I get the result). Note that I m writing IO here, but it can be any monad.The definition of the datatype and the monad instance came mostly from trying to make this type work (yay to haskell s type system, less thinking required), and looks like this:
data CoroutineT m a = CoroutineT  unCoroutineT :: (m (Either (CoroutineT m a) a))  

instance (Monad m) => Monad (CoroutineT m) where
return v = CoroutineT (return (Right v))
a >>= b = CoroutineT $ do
r <- unCoroutineT a
case r of
Left paused -> return $ Left (paused >>= b)
Right unpaused -> unCoroutineT (b unpaused)
This translates to english like this: A call to return is not paused. When an action is already paused, further actions should be run after the paused action is resumed. When an action is not paused, further actions can happen now.Like every well behaving monad transfomer, I also need a "runCoroutineT" function to start the coroutine. I probably could have used unCoroutineT directly, but for my use case (GUI drawing) I did not need a return value, so this function is more handy:
runCoroutineT :: Monad m => CoroutineT m () -> m (Maybe (CoroutineT m ()))
runCoroutineT a = either (Just) (const Nothing) liftM unCoroutineT a
Nothing surprising here, basically just turning the Either into a Maybe. So it becomes clear how to do (b): We can just throw away the resume action returned by runCoroutineT (if any). The more interesting thing is how we do (a): We need a pause action of type (Coroutine m ()). But how should it work? I did not really try to understand why it works, but by looking at the types, I came up with this:
pause :: Monad m => CoroutineT m ()
pause = CoroutineT (return (Left (CoroutineT (return (Right ())))))
Yes, it sounds like some dance step instructions (read the second line out aloud!), but it works somehow.So here is some example code: I have a pausable IO action that counts from one to ten, pausing after each number. I also have function that resumes an pausable action up to n times:
example n = keepGoingFor n $ do
        liftIO $ putStrLn "This is the coroutine"
        forM_ [1..10] $ \i -> do
            liftIO $ putStrLn $ "Counting to "++ show i ++" while you keep calling it"
            pause
  where --keepGoing :: Monad m => CoroutineT m () -> m ()
      keepGoingFor 0 _   = putStrLn "Here I just abort the run"
      keepGoingFor n cor = do
        resume <- runCoroutineT cor
        case resume of
            Just runAgain -> keepGoingFor (n-1) runAgain
            Nothing       -> putStrLn "Finally stopped"
And here is the output of two different runs:
*CouroutineT> example 5
This is the coroutine
Counting to 1 while you keep calling it
Counting to 2 while you keep calling it
Counting to 3 while you keep calling it
Counting to 4 while you keep calling it
Counting to 5 while you keep calling it
Here I just abort the run
*CouroutineT> example 14
This is the coroutine
Counting to 1 while you keep calling it
Counting to 2 while you keep calling it
Counting to 3 while you keep calling it
Counting to 4 while you keep calling it
Counting to 5 while you keep calling it
Counting to 6 while you keep calling it
Counting to 7 while you keep calling it
Counting to 8 while you keep calling it
Counting to 9 while you keep calling it
Counting to 10 while you keep calling it
Finally stopped
So it does really works fine, and it proved very useful in my GUI drawing problem. For that, I created this nice control structure which works like mapM_, but calls pause every n iterations, and therefore hides the pausing stuff almost completely:
pausingForM_ :: Monad m => Int -> [a] -> (a -> CoroutineT m ()) -> CoroutineT m ()
pausingForM_ period list action = pausing' 0 list
where pausing' _ [] = return ()
pausing' n (x:xs) = do action x
if n==period then pause >> pausing' 0 xs
else pausing' (n+1) xs
I have put the complete module (including instances omitted here) in the darcs repository that might later also contain the fractal drawing program.

17 April 2008

Jaldhar Vyas: Bitter New Maintainers Cling to Guns and Religion

For the second year in a row, I didn't vote in the DPL election. Not because I have lost interest in Debian affairs but because nothing is really going on that demands my attention. All three of the candidates who ran this year were eminently capable of representing of Debian and its ideals, all three had more or less the same vision for the role of DPL (IMO. See here for platforms,) and all three are, as far as I know, nice people. Organizational and social problems that previously existed have been fixed. The only problem I have with Debian these days is a lack of time but I can hardly expect the DPL to do anything about that. However, a recent post from Lucas reminded me that there is one group for which all is not fine and dandy. Given that this is the same complaint that has been made for atleast five years nows, one has to wonder why it remains singularly unfixable? Well I don't know but this delegation makes me confident that we will finally see the end of this last bottleneck too. Joerg is the one who sped up NEW package processing and I am sure he will have account creation humming along in no time. I sympathize with the frustration people stuck in NM feel, but I would like to remind them that Debian acts the way Winston Churchill observed the United States does:
"Americans can always be depended upon to do the right thing—after they've tried everything else."

13 April 2008

Jeff Bailey: Update of the moment

So here's the latest update on how I'm doing:

* Got the stomach flu this week. After 3 days of being ill, went to the doctors and got anti-nausea, anti-diarrhea medication, and 400ccs of Saline by IV for the dehydration. Joy. I'm going to try to go off the anti-nausea drugs tomorrow to see if I'm keeping things down now.

* Leif swam for the first time. I didn't get video, but opted for some nice stills. I *will* actually upload the last 5 months of pictures sometime soon. Really.

* Found an accountant who knows what to do for Canadians who just moved here. Yay! US Taxes will get done!

* The incision has no redness around it at all anymore, which is way cool. On Tuesday, I go in for my 6-week checkup. I asked at the 4-week mark whether I could go in the hottub, and was told that they'd probably OK it at the 6-week mark. I start 6 weeks of physiotherapy the day after that.

* My stamina for walking seems largely back. I can walk to Safeway at a decent pace (I still have to rest when I'm there). I can get to the mailbox and back without a break now. The part that causes me grief still is the muscles on my left shoulders. I'll ask Angie which one it is. It's been more sore than the others since the beginning, but hopefully it's something the physio can help me sort out. If it weren't for that, I'd be cutting back the pain killers already. I still might do that when I know I have a 6-hour stretch of low activity.

* For lack of anything better to do, I've been playing with Eclipse. I rediscovered eclipse a year ago when I was working on the ConnectUU site. The PHP mode was surprisingly good and helpful, and I was quite productive in it. I tried shortly after that to use PyDev, and it did horrible things to eclipse. I've tried it again, and I'm enjoying doing a bit of Java coding (homework), and Python coding in it now. I may finally have found an environment in which I can be more productive than I was in vi.

* Ernie (Angie's dad) and Janet (his wife / one of Leif's Grandmothers) have been here for the weekend helping us clean up. Janet is an absolute whiz at organising things, and the kitchen is way more usable then it has been since we got here in November. I need to make sure that I send out thank-you cards to everyone who's come and helped us. Kit was here a couple of weekends ago. Heather was here last weekend. Leslie, Grant, Jim/Sarah, and Andrew/Sarah have each brought us food. Jamu and Sandy each came for longer periods right after the surgery. Having people come and help has made a huge difference to us keeping things together. Without outside help, I don't know how we would've managed.

I'm a day and a bit off of 6-weeks post-surgery. I'm feeling good.

7 April 2008

Jeff Bailey: Titanium cage

During the surgery, the surgeons replaced two vertebrae with titanium cages. I hadn't a clue what that was, and they didn't have one handy to show me. I've managed to find a picture of one on the Internet, though:

http://www.medscape.com/content/2003/00/46/53/465370/art-nf465370.fig1.jpg

Cool, eh? On the next visit I'm going to ask them how they get the spinal cord to go through that, since I don't see any gaps to slide it through in the picture.

In other news, I can finally lift my laptop now, so chatting with people on jaber can be done at a reasonable speed without trashing by wrists from typing on the blackberry. Yay!

Also, Leif is definitely walking now. Craziness. I'll try to get some video soon.

5 April 2008

Mark Brown: ARM Linux git tree

It’s surprisingly poorly advertised but there is an ARM Linux git tree available from http://ftp.arm.linux.org.uk/pub/armlinux/kernel/git-cur/ and ftp://ftp.arm.linux.org.uk/pub/armlinux/kernel/git-cur/ with currently accepted patches queued up in it. Very handy, especially for offline use.

29 March 2008

Enrico Zini: OpenStreetMap party at Kaohsiung, Taiwan

OpenStreetMap party at Kaohsiung, Taiwan Apparently, yesterday we had the first OpenStreetMap event in Taiwan! We met in a caf /restaurant equipped with power plug, wireless network and overhead projector and we had a bit of an introduction, chat and lunch. Then we split in groups and exploited the fact that the newly built underground (KMRT) system is still free of charge, to spread around and map around the stations. Finally, we reconvened at someone's house to see how to put the data together, draw roads, tag and upload. Highlights of the day: Technical bits: Issues to address:

28 March 2008

Vincent Fourmond: Thoughts about statsvn

Some time ago, I packaged statsvn, a pretty neat SVN repository analysis tool based on statcvs. To be truthful, I was quite amazed that no one had packaged it before, as I find it quite handy. It is currently in contrib, as it depends on statcvs that depends on libjfreechart-java that currently only works with Sun's java on AMD64 machines (at least, see the bug report). A few comments about it: though it can work fine with remote repositories, it is highly recommended that you either take down the number of -threads, as many repositories out there do not like too many concurrent ssh accesses, or you rsync the whole repository to your local hard drive and work from a checkout of the local copy, as it will burn much less bandwidth and server time. Of course, statistics of this kind are not to be taken too seriously, as they can be seriously biased by commit mistakes for instance, but they give the impression that work is being done, and that is pleasant ;-)...

26 March 2008

Jeff Bailey: Update of the moment

Hey - here's an update:

* I'm off the steroids. Last one was last Friday, spent the weekend enjoying the withdrawal symptoms, and already enjoying the benefits, like my skin is clearing up even more, I'm starting to get my voice back, and I'm less inclined to be angry at the vacuum cleaner when it runs into me. Angie tells me I'm a lot more fun to have around. Which is encouraging when one is totally dependent on another person for food. =)

* I seem to have gotten sick. It took me a bit to figure this one out, but the withdrawal symptoms seemed to be going on longer than expected. Then Angie started showing signs of them, after Leif was fussy for a day. Blech. =( Which explains why I can be cold under covers when the thermostat claims that it's 74 F (No idea in civilised measurements, sorry). Hopefully this passes quickly. Time for lots of breathing and napping. Like I could be sleeping any more during the day.

* My energy levels are getting better. I saw Andrew Pollock at noon today when he returned a CD to me, and he commented that from my walking you can barely tell I had surgery 3 weeks ago. Except for how slowly I'm going. And the full body turn in order to look to see if cars are coming when I cross the road. And the huge production to step up onto the sidewalk. A 5 minute walk no long requires me to sleep for 2 hours. Can't say the same for a 10 minute walk yet, though.

* Staples are out! I have two more days of antibiotics because the incision is still red and giving off more heat than they'd like so I'm back in next Tuesday for another checkup. Last week, the surgeon wasn't surprised by the healing rate given that the steroids are an immunosuppressant, though. So hopefully next Tuesday I get a clean bill of health and then just have to wait 2 weeks before getting some movement restrictions lifted and starting PT. And tomorrow I'll have a shower without fetish^WPlastic Wrap all over the incision. I can't shower unassisted yet, though, since getting most of my body would count as "reaching"

* Short-term disability finally approved my claim. For 6 weeks anyway. Then they want me to return to work or get better justification from my surgeon. I'm sure he'll be all professional, but I'd love it if the letter read "My client takes 10 minutes to get out of bed. He takes vicodin every 4 hours, and my nurse just recommended Oxycodone so that he can sleep more than 2.5 hours at a stretch. What do you think?"

* We have the biopsy results. And like every other biopsy result, we have... Inconclusive! Whee! At least they're no longer using the word "Sarcoma", but instead have settled on Osteoblastoma. But there's a catch - there are two types of Osteoblastoma, Aggressive and not. (I'm sure there's technical terms, but I'm tired and didn't catch them). The inconclusive bit is whether it's aggressive or not. During surgery, however, they treated it as aggressive because they didn't have the information and did what they'd do to minimize the chance of it coming back by taking out lots of extra tissue. I still get to see an Oncologist, in case there's something interesting through all of this still to learn.

* Otherwise, schoolwork extensions are all approved, our new bank likes us and is doing good things. Coworkers are popping in and saying hi, so I'm not feeling totally isolated. Heinlein is less good the fewer drugs I'm on. Or maybe it's because I'm reading "Friday".

Things are still getting better every day, even through all the sickness and such. I'm trying to catch up with people on Jabber. I still can't lift the laptop, so IRCs out until I figure out where I put the charger to the N810. It's somewhere out of reach, so as far away as the moon as far as I'm concerned.

I also want to take a moment to say thanks to Sandy and Jamu for their visits here - We're trying to arrange for people to visit us on the weekends and help us return the place to a clean state, with Kit starting the visits this coming weekend. Angie's got her hands full with Leif, and I get the joy of sitting in the corner wishing I could be useful. The result is that the house slowly falls apart over the course of a week, and hopefully weekend visitors will help us keep some measure of sanity here.

Peace and love, all.

Tks,
Jeff Bailey

Next.

Previous.