How To Save Artwork from Weavesilk.com
I just discovered weavesilk.com, which I think is pretty cool. However, it looks like they don’t give you a way to save your generated artwork. If you’re running Google Chrome (or, as I am, Chromium), there’s a trick you can use to save what you’ve created. This can probably be done with Firefox using Firebug, and maybe in some other ways, but here’s how I do it with Chromium.
- Create your artwork by dragging around.
- Right-click somewhere on the page and select “Inspect Element.”
- In the new browser pane that comes up, click to the “Console” tab and enter the following:
canvas = document.getElementById('render') img = document.createElement('img'); img.src = canvas.toDataURL()
- The browser will probably freeze for a few seconds (or more than a few), and your CPU usage will shoot up. Be patient.
- Click to the “Resources” tab in the developer pane, and look in the list for something that starts with “data:image/png”. Click it, and you should see your artwork to the right, on a transparent checkerboard background.
- Right-click the image and select “Save Image As.”
The image will save with a transparent background, but you can open it up in an image editor and add a solid background color if you like.
How To Save Artwork from Weavesilk.com
I just discovered weavesilk.com, which I think is pretty cool. However, it looks like they don’t give you a way to save your generated artwork. If you’re running Google Chrome (or, as I am, Chromium), there’s a trick you can use to save what you’ve created. This can probably be done with Firefox using Firebug, and maybe in some other ways, but here’s how I do it with Chromium.
-
Create your artwork by dragging around.
-
Right-click somewhere on the page and select “Inspect Element.”
-
In the new browser pane that comes up, click to the “Console” tab and enter the following:
``canvas = document.getElementById('render') img = document.createElement('img') img.src = canvas.toDataURL()``
-
The browser will probably freeze for a few seconds (or more than a few), and your CPU usage will shoot up. Be patient.
-
Click to the “Resources” tab in the developer pane, and look in the list for something that starts with “data:image/png”. Click it, and you should see your artwork to the right, on a transparent checkerboard background.
-
Right-click the image and select “Save Image As.”
The image will save with a transparent background, but you can open it up in an image editor and add a solid background color if you like.
Gentoo Linux on an 11” MacBook Air (October 2010)
I just posted a page detailing my experience installing Gentoo on one of the new MacBook Air models (in my case the MacBookAir3,1 with 1.6GHz CPU, 128GB SSD, and 4GB RAM). Hopefully it’ll be useful for others.
Gentoo Linux on an 11" MacBook Air (October 2010)
I just posted a page detailing my experience installing Gentoo on one of the new MacBook Air models (in my case the MacBookAir3,1 with 1.6GHz CPU, 128GB SSD, and 4GB RAM). Hopefully it'll be useful for others.
Gentoo Linux on an 11? MacBook Air (October 2010)
I just posted a page detailing my experience installing Gentoo on one of the new MacBook Air models (in my case the MacBookAir3,1 with 1.6GHz CPU, 128GB SSD, and 4GB RAM). Hopefully it’ll be useful for others.
Amazon MP3 Downloader on 64bit Gentoo Linux
(This is going to be a bit of a narrative. If you’re impatient, scroll to the “How-To” section at the bottom of the post.)
Today I decided to download an MP3 album from Amazon. I actually wanted all the songs on the particular album, and noted that you save a couple bucks by downloading the whole album vs. downloading each individual song. So click through, and find that it requires the Amazon Download Manager thingo.
Lame, I think. I click the download link, and it actually gives me some buttons to choose from that have to do with Linux. Huh. Nice work. However, I assume it’s closed-source proprietary crap. But hey, why not give it a try.
My choices are two .deb files, one for Ubuntu Jaunty, and one for Debian 5, or two .rpm files, one for Fedora 11, and one for OpenSuse somethingorother.
So I grab the Ubuntu one. I’m on Gentoo, so I “emerge dpkg”, and then run “dpkg -x amazonmp3.deb .” in an empty directory. I look in usr/bin that it created, and find a binary. But it’s a 32bit binary.
Crap.
I run ‘ldd’ on it, and of course it needs gtk and a bunch of other stuff that I don’t have 32bit libraries for. Like boost.
So I think, ok, I can install a 32bit chroot. So I download the stage3 Gentoo i686 tarball and unpack it in /opt/gentoo32. I also “emerge schroot” in my regular system, and set that up. I recently found schroot while using Ubuntu at work. It’s awesome. Eventually the stage3 tarball finishes up, so I schroot into my new 32bit environment and “emerge libboost”. After it’s finished, I note a problem. Amazon’s binary is expecting some weird version of boost that has “gcc42″ in the filename. Also, I just installed boost 1.35, and it wants 1.34. Out of desperation, I try to make symlinks to the correct file names, assuming it probably won’t work. I was right: it doesn’t work. Balls.
Then I think… well, why not install a chroot of 32bit Ubuntu Jaunty? I “emerge debootstrap” and pray… yep, it’s in portage, excellent. I install it, schroot into it, and apt-get a bunch of the libboost packages, and… holy crap, it works.
How-To
Here’s a step-by-step. This is for Gentoo, but it should work equally well on any system where you can install debootstrap and chroot. The following instructions assume you’ve installed them already.
As root on the “main” system:
# mkdir -p /opt/ubuntu-jaunty-32 # debootstrap --arch i386 jaunty /opt/ubuntu-jaunty-32 http://archive.ubuntu.com/ubuntu/ # cat >/etc/schroot/chroot.d/jaunty32.conf [ubuntu-jaunty-32] type=directory description=Ubuntu Jaunty (32-bit) location=/opt/ubuntu-jaunty-32 priority=3 users=$USER groups=$USER,root root-users=root,$USER root-groups=root,wheel personality=linux32 run-setup-scripts=true run-exec-scripts=true aliases=jaunty [hit ctrl+d] # cat >/etc/schroot/mount-defaults /proc /proc none rw,bind 0 0 /proc/bus/usb /proc/bus/usb none rw,bind 0 0 /sys /sys none rw,bind 0 0 /dev /dev none rw,bind 0 0 /dev/pts /dev/pts none rw,bind 0 0 /dev/shm /dev/shm none rw,bind 0 0 /home /home none rw,bind 0 0 /tmp /tmp none rw,bind 0 0 /var/run/dbus /var/run/dbus none rw,bind 0 0 /usr/portage /usr/portage none rw,bind 0 0 [hit ctrl+d] # schroot -c jaunty (32bit)# groupadd -r staff (32bit)# apt-get update (32bit)# apt-get install sudo curl libglademm-2.4-1c2a xdg-utils libboost-date-time1.34.1 libboost-filesystem1.34.1 libboost-iostreams1.34.1 libboost-regex1.34.1 libboost-signals1.34.1 libboost-thread1.34.1 (32bit)# dpkg -i $DOWNLOAD_DIR/amazonmp3.deb
Note that I didn’t just type all this verbatim… this was just my memory of what I did. So if something’s missing, please leave a note in the comments and I’ll update this.
Next you can try running “amazonmp3″ to test it. If that works, you can go back out to your “real” system (just type “exit” in that shell), and do this:
# mkdir -p /usr/local/bin # cat >/usr/local/bin/amazonmp3 #!/bin/bash schroot -c jaunty -p /usr/bin/amazonmp3 -- "$@" [hit ctrl+d] # chmod +x amazonmp3
This creates a script in your “real” system that will chain to the 32bit amazonmp3 binary in your Jaunty chroot. You can set up your browser of choice to automatically launch this script when you download .amz files. At this point you can try running “amazonmp3″ from your “real” system (outside the chroot) and see if that works.
There are also a few other things:
- If you are running a system that uses GDM to log in, you may need to add /var/run/gdm to the bind mounts in the mount-defaults file or else apps started in your chroot won’t be able to connect to your X server.
- If you’re using non-default gtk2 theme engines on your “real” desktop”, you’ll need to install them in the chroot (via apt-get) as well. Well, ok, you don’t have to, but if you don’t, the Amazon app will look uglier than it should.
- Remember to always pass the “-p” option to schroot. If you don’t, the environment in the chroot will get reset, which means you’ll lose your DISPLAY env var, and you won’t be able to connect to the X server without manually setting it.
- When I first ran the apt-get command in the chroot, I got some weird errors at the end of the process about some packages not being configured because another package (gtk, I think) that it depended on hadn’t been configured yet. Just running the same apt-get command a couple times fixed it, strangely.
- Make sure your “real” system has /usr/local/bin in the PATH.
Anyhow, that’s it. Works like a charm.
Amazon MP3 Downloader on 64bit Gentoo Linux
Update 2010/12/04: A commenter recommended clamz instead. I’ve installed it but not yet tried it, but it’s certainly easier than installing another OS in a chroot.
(This is going to be a bit of a narrative. If you’re impatient, scroll to the “How-To” section at the bottom of the post.)
Today I decided to download an MP3 album from Amazon. I actually wanted all the songs on the particular album, and noted that you save a couple bucks by downloading the whole album vs. downloading each individual song. So click through, and find that it requires the Amazon Download Manager thingo.
Lame, I think. I click the download link, and it actually gives me some buttons to choose from that have to do with Linux. Huh. Nice work. However, I assume it’s closed-source proprietary crap. But hey, why not give it a try.
My choices are two .deb files, one for Ubuntu Jaunty, and one for Debian 5, or two .rpm files, one for Fedora 11, and one for OpenSuse somethingorother.
So I grab the Ubuntu one. I’m on Gentoo, so I “emerge dpkg”, and then run “dpkg -x amazonmp3.deb .” in an empty directory. I look in usr/bin that it created, and find a binary. But it’s a 32bit binary.
Crap.
I run ‘ldd’ on it, and of course it needs gtk and a bunch of other stuff that I don’t have 32bit libraries for. Like boost.
So I think, ok, I can install a 32bit chroot. So I download the stage3 Gentoo i686 tarball and unpack it in /opt/gentoo32. I also “emerge schroot” in my regular system, and set that up. I recently found schroot while using Ubuntu at work. It’s awesome. Eventually the stage3 tarball finishes up, so I schroot into my new 32bit environment and “emerge libboost”. After it’s finished, I note a problem. Amazon’s binary is expecting some weird version of boost that has “gcc42” in the filename. Also, I just installed boost 1.35, and it wants 1.34. Out of desperation, I try to make symlinks to the correct file names, assuming it probably won’t work. I was right: it doesn’t work. Balls.
Then I think… well, why not install a chroot of 32bit Ubuntu Jaunty? I “emerge debootstrap” and pray… yep, it’s in portage, excellent. I install it, schroot into it, and apt-get a bunch of the libboost packages, and… holy crap, it works.
How-To
Here’s a step-by-step. This is for Gentoo, but it should work equally well on any system where you can install debootstrap and chroot. The following instructions assume you’ve installed them already.
As root on the “main” system:
# mkdir -p /opt/ubuntu-jaunty-32 # debootstrap --arch i386 jaunty /opt/ubuntu-jaunty-32 http://archive.ubuntu.com/ubuntu/ # cat >/etc/schroot/chroot.d/jaunty32.conf [ubuntu-jaunty-32] type=directory description=Ubuntu Jaunty (32-bit) location=/opt/ubuntu-jaunty-32 priority=3 users=$USER groups=$USER,root root-users=root,$USER root-groups=root,wheel personality=linux32 run-setup-scripts=true run-exec-scripts=true aliases=jaunty [hit ctrl+d] # cat >/etc/schroot/mount-defaults /proc/procnonerw,bind 00 /proc/bus/usb/proc/bus/usbnonerw,bind00 /sys/sysnone rw,bind00 /dev/devnonerw,bind00 /dev/pts/dev/ptsnonerw,bind00 /dev/shm/dev/shmnonerw,bind00 /home/homenonerw,bind00 /tmp/tmpnonerw,bind00 /var/run/dbus/var/run/dbusnonerw,bind00 /usr/portage/usr/portagenonerw,bind00 [hit ctrl+d] # schroot -c jaunty (32bit)# groupadd -r staff (32bit)# apt-get update (32bit)# apt-get install sudo curl libglademm-2.4-1c2a xdg-utils libboost-date-time1.34.1 libboost-filesystem1.34.1 libboost-iostreams1.34.1 libboost-regex1.34.1 libboost-signals1.34.1 libboost-thread1.34.1 (32bit)# dpkg -i $DOWNLOAD_DIR/amazonmp3.deb
Note that I didn’t just type all this verbatim… this was just my memory of what I did. So if something’s missing, please leave a note in the comments and I’ll update this.
Next you can try running “amazonmp3” to test it. If that works, you can go back out to your “real” system (just type “exit” in that shell), and do this:
# mkdir -p /usr/local/bin # cat >/usr/local/bin/amazonmp3 #!/bin/bash schroot -c jaunty -p /usr/bin/amazonmp3 -- "$@" [hit ctrl+d] # chmod +x amazonmp3
This creates a script in your “real” system that will chain to the 32bit amazonmp3 binary in your Jaunty chroot. You can set up your browser of choice to automatically launch this script when you download .amz files. At this point you can try running “amazonmp3” from your “real” system (outside the chroot) and see if that works.
There are also a few other things:
-
If you are running a system that uses GDM to log in, you may need to add /var/run/gdm to the bind mounts in the mount-defaults file or else apps started in your chroot won’t be able to connect to your X server.
-
If you’re using non-default gtk2 theme engines on your “real” desktop”, you’ll need to install them in the chroot (via apt-get) as well. Well, ok, you don’t have to, but if you don’t, the Amazon app will look uglier than it should.
-
Remember to always pass the “-p” option to schroot. If you don’t, the environment in the chroot will get reset, which means you’ll lose your DISPLAY env var, and you won’t be able to connect to the X server without manually setting it.
-
When I first ran the apt-get command in the chroot, I got some weird errors at the end of the process about some packages not being configured because another package (gtk, I think) that it depended on hadn’t been configured yet. Just running the same apt-get command a couple times fixed it, strangely.
-
Make sure your “real” system has /usr/local/bin in the PATH.
Anyhow, that’s it. Works like a charm.
Amazon MP3 Downloader on 64bit Gentoo Linux
Update 2010/12/04: A commenter recommended clamz instead. I've installed it but not yet tried it, but it's certainly easier than installing another OS in a chroot.
(This is going to be a bit of a narrative. If you're impatient, scroll to the "How-To" section at the bottom of the post.)
Today I decided to download an MP3 album from Amazon. I actually wanted all the songs on the particular album, and noted that you save a couple bucks by downloading the whole album vs. downloading each individual song. So click through, and find that it requires the Amazon Download Manager thingo.
Lame, I think. I click the download link, and it actually gives me some buttons to choose from that have to do with Linux. Huh. Nice work. However, I assume it's closed-source proprietary crap. But hey, why not give it a try.
My choices are two .deb files, one for Ubuntu Jaunty, and one for Debian 5, or two .rpm files, one for Fedora 11, and one for OpenSuse somethingorother.
So I grab the Ubuntu one. I'm on Gentoo, so I "emerge dpkg", and then run "dpkg -x amazonmp3.deb ." in an empty directory. I look in usr/bin that it created, and find a binary. But it's a 32bit binary.
Crap.
I run 'ldd' on it, and of course it needs gtk and a bunch of other stuff that I don't have 32bit libraries for. Like boost.
So I think, ok, I can install a 32bit chroot. So I download the stage3 Gentoo i686 tarball and unpack it in /opt/gentoo32. I also "emerge schroot" in my regular system, and set that up. I recently found schroot while using Ubuntu at work. It's awesome. Eventually the stage3 tarball finishes up, so I schroot into my new 32bit environment and "emerge libboost". After it's finished, I note a problem. Amazon's binary is expecting some weird version of boost that has "gcc42" in the filename. Also, I just installed boost 1.35, and it wants 1.34. Out of desperation, I try to make symlinks to the correct file names, assuming it probably won't work. I was right: it doesn't work. Balls.
Then I think... well, why not install a chroot of 32bit Ubuntu Jaunty? I "emerge debootstrap" and pray... yep, it's in portage, excellent. I install it, schroot into it, and apt-get a bunch of the libboost packages, and... holy crap, it works.
How-To
Here's a step-by-step. This is for Gentoo, but it should work equally well on any system where you can install debootstrap and chroot. The following instructions assume you've installed them already.
As root on the "main" system:
# mkdir -p /opt/ubuntu-jaunty-32 # debootstrap --arch i386 jaunty /opt/ubuntu-jaunty-32 http://archive.ubuntu.com/ubuntu/ # cat >/etc/schroot/chroot.d/jaunty32.conf [ubuntu-jaunty-32] type=directory description=Ubuntu Jaunty (32-bit) location=/opt/ubuntu-jaunty-32 priority=3 users=$USER groups=$USER,root root-users=root,$USER root-groups=root,wheel personality=linux32 run-setup-scripts=true run-exec-scripts=true aliases=jaunty [hit ctrl+d] # cat >/etc/schroot/mount-defaults /proc/procnonerw,bind 00 /proc/bus/usb/proc/bus/usbnonerw,bind00 /sys/sysnone rw,bind00 /dev/devnonerw,bind00 /dev/pts/dev/ptsnonerw,bind00 /dev/shm/dev/shmnonerw,bind00 /home/homenonerw,bind00 /tmp/tmpnonerw,bind00 /var/run/dbus/var/run/dbusnonerw,bind00 /usr/portage/usr/portagenonerw,bind00 [hit ctrl+d] # schroot -c jaunty (32bit)# groupadd -r staff (32bit)# apt-get update (32bit)# apt-get install sudo curl libglademm-2.4-1c2a xdg-utils libboost-date-time1.34.1 libboost-filesystem1.34.1 libboost-iostreams1.34.1 libboost-regex1.34.1 libboost-signals1.34.1 libboost-thread1.34.1 (32bit)# dpkg -i $DOWNLOAD_DIR/amazonmp3.deb
Note that I didn't just type all this verbatim... this was just my memory of what I did. So if something's missing, please leave a note in the comments and I'll update this.
Next you can try running "amazonmp3" to test it. If that works, you can go back out to your "real" system (just type "exit" in that shell), and do this:
# mkdir -p /usr/local/bin # cat >/usr/local/bin/amazonmp3 #!/bin/bash schroot -c jaunty -p /usr/bin/amazonmp3 -- "$@" [hit ctrl+d] # chmod +x amazonmp3
This creates a script in your "real" system that will chain to the 32bit amazonmp3 binary in your Jaunty chroot. You can set up your browser of choice to automatically launch this script when you download .amz files. At this point you can try running "amazonmp3" from your "real" system (outside the chroot) and see if that works.
There are also a few other things: 1. If you are running a system that uses GDM to log in, you may need to add /var/run/gdm to the bind mounts in the mount-defaults file or else apps started in your chroot won't be able to connect to your X server.
If you're using non-default gtk2 theme engines on your "real" desktop", you'll need to install them in the chroot (via apt-get) as well. Well, ok, you don't have to, but if you don't, the Amazon app will look uglier than it should.
Remember to always pass the "-p" option to schroot. If you don't, the environment in the chroot will get reset, which means you'll lose your DISPLAY env var, and you won't be able to connect to the X server without manually setting it.
When I first ran the apt-get command in the chroot, I got some weird errors at the end of the process about some packages not being configured because another package (gtk, I think) that it depended on hadn't been configured yet. Just running the same apt-get command a couple times fixed it, strangely.
Make sure your "real" system has /usr/local/bin in the PATH.
Anyhow, that's it. Works like a charm.
Amazon MP3 Downloader on 64bit Gentoo Linux
(This is going to be a bit of a narrative. If you’re impatient, scroll to the “How-To” section at the bottom of the post.) Today I decided to download an MP3 album from Amazon. I actually wanted all the songs on the particular album, and noted that you save a couple bucks by downloading the [...]Code Comments
I'm a bit of a minimalist when it comes to commenting my code. This is probably in some ways a bad thing; code that is completely obvious to me in its function may be difficult to understand for others, and I'm often not so great at realizing this on the first pass.
So that leads me to the purpose of code comments:
The purpose of commenting your code is to inform readers of that code what a section of nontrivial or non-obvious code does.
At least, this is my definition. Opinions differ, I'm sure. I might also add to that a clarification: "readers" in this case may include yourself. Code you wrote may even be incomprehensible to you if a decent amount of time has passed.
From this definition you can also infer something else, that I believe it's unnecessary to comment obvious code. In fact, I'd argue that it's harmful to comment obvious code, because you're making it harder to follow, and you're adding a barrier in front of the reader being easily able to distinguish between trivial and nontrivial code at a glance. You also increase the length of the code fragment, which may make it more difficult to read and understand in its entirety (if you can't fit the entire fragment on one screen, you'll have to scroll back and forth to see the entire thing).
However, too often -- very often, it turns out -- I see things like the following:
``/* take a reference */ g_object_ref(object);````/* free string */ g_free(str);``
And one of my favorites:
``/* set the label text to "Time Left:" */ gtk_label_set_text(GTK_LABEL(label), "Time Left:");``
(Yes, I actually have seen something very similar to that, though I don't remember what the label text was.)
How do these comments actually add anything useful to the file? Every time I see one of these, a little part of me dies inside.
Now, the last one is just silly. Even someone who has never developed using the gtk+ UI toolkit can figure out what that line of code does without the comment. If you can't, then a code comment there probably isn't going to be enough to help you overall in any case.
The middle one is equally silly, though it's understandable that someone might not know that g_free() is the glib equivalent of free(). However, consider your audience: is an extra line of code for a comment really useful here?
The first one is not quite so easy for me to dismiss. It presupposes a few bits of knowledge:
Understanding of what reference-counted memory management is.
Familiarity with the "ref/unref" pair, as opposed to only being exposed to something like the OpenStep "retain/release" (or even the COM/XPCOM "AddRef/Release") terminology
At least passing knowledge of what a GObject is
Now, for code that makes heavy use of reference counting, I think presupposing #1 is not unreasonable. In this case, it doesn't matter: the comment as presented will not help you if you don't know what reference counting is.
Points #2 and #3 depend on your goals and potential audience. If you think that a decent number of readers may not be familiar with the "ref/unref" terminology, "take a reference" is probably enough to generate an "oh, duh!" moment in the reader's head. As for #3, unless you intend your code to be able to act as a sort of GObject tutorial, that is, something that people aspiring to learn GObject programming might want to read, I think the comment there does not serve people unfamiliar with GObject. Regardless, most GObject-using code will probably be pretty confusing to someone who doesn't know GObject, so whether or not you should comment g_object_ref() is going to be the least of your worries.
Now, I'm not going to claim that my code commenting is perfect... far from it. I could certainly stand to sprinkle comments a bit more liberally throughout my code. I tend to only comment public API (and then just a description of what the function does, not how it does it), and code fragments that are really nontrivial[1] and potentially hard to understand.
But there has to be a happy medium somewhere. While too-infrequent commenting can certainly make code harder to understand, I'd argue that too-frequent commenting is worse. It's sorta like "the boy who cried wolf" in the sense that comments draw my eyes to them as a way of saying, "pay attention! This bit here is important!" (or tricky, or whatever). Overuse of comments just makes me start skipping over all of them, useful or otherwise.
<>[1] It's worth noting here that this point further reduces my volume of comments. I generally prefer clear code over neat hacks, even if the neat hack represents a reduction in lines of code or a moderate increase in performance. If I write a section of code and then look at it again and see that it looks too complex, I'll usually try to immediately rewrite it to be simpler.