Gravatar module for Roxen

Published 9 December, 2009 in Misc , Roxen - 0 Comments

Although I’m working on some social web related Pike modules where a Gravatar module is included I needed a Gravatar module right now at work so I hacked up a standalone Gravatar Roxen module.

This is how it works

12 lines of RoXen Macro Language
  1. <ul>
  2. <emit source=“sql” host=“mydb”
  3. query=“SELECT name, email, `date`, body FROM my_comments”
  4. >
  5. <li>
  6. <gravatar-img email=“&_.email;” rating=“pg” size=“32”
  7. default-image=“/path/to/icon.png”
  8. /> &_.name; wrote at <date iso-time=“&_.date;” />
  9. <wash-html paragraphify=“”>&_.body;</wash-html>
  10. </li>
  11. </emit>
  12. </ul>

Download the Gravatar Roxen module 14:20, Wed 09 December 2009 :: 7 kB

A change of times

Published 2 December, 2009 in Misc - 0 Comments

old Pripps ad

Times are changing! This old beer ad is in Swedish but in short it says:

Pripps in a new disposable pack, for the sailing tripp. Extra tip: Make a hole in the bottom of the empty pack and it will sink faster.

It feels we at least have come some way regarding recycling.

Click on the image for a full scale version.

Vala – the new programming language for Gnome

Published 25 October, 2009 in Linux , Programming - 0 Comments

This Friday when I read the last issue (in Sweden) of Linux Format there was an article on a new programming language named Vala. The goal for Vala is to provide a modern programming language for, primarily, developing Gnome applications. There is of course Mono, but Vala doesn’t run in a virtual machine but is complied to machine code. But Vala resembles C# syntactically and has borrowed a lot of concepts from C#.

From what I understand Vala code is first translated into plain old C code, and then compiled with the ordinary GCC compiler. The benefit is that you don’t have to get head aches about memory management and so forth.

Vala seems pretty interesting and I downloaded it and compiled it without any difficulties. There are precompiled packages for most Linux distros – it’s available in the Ubuntu repository – but since Vala is new and still under development the distro packages is far behind in version.

There’s also a Vala IDE and plugins for GEdit, Anjuta and Eclipse.

Anyway, just to try Vala out I made a little program – using Val(a)ide – that changes the desktop wallpaper on a per interval basis. Send the program a path to a directory with images and the background will change among those images every *nth minutes.

This program needs libgee which at the moment needs to be added manually.

Compile: valac --pkg gconf-2.0 --pkg gee-1.0 --pkg gio-2.0 main.vala -o wallpaper-iterator

239 lines of Vala
  1. /* main.vala
  2. *
  3. * Copyright (C) 2009 Pontus Östlund <spam@poppa.se>
  4. *
  5. * No license what so ever. Do what ever you like…
  6. *
  7. * Author:
  8. * Pontus Östlund <spam@poppa.se>
  9. */
  10. // GLib isn’t really neccessary since it’s imported automatically
  11. using GLib, Gee, GConf;
  12. /**
  13. * User defined exception types
  14. */
  15. errordomain IOError {
  16. FILE_NOT_FOUND,
  17. NOT_A_DIRECTORY
  18. }
  19. /**
  20. * Main class
  21. */
  22. public class Main
  23. {
  24. /**
  25. * Used as reference in option parser
  26. */
  27. static int arg_delay;
  28. /**
  29. * Application command line options
  30. */
  31. const OptionEntry[] options = {
  32. { “delay”, ‘d’, 0, OptionArg.INT, ref arg_delay,
  33. “Number of minutes to wait before swapping background”, null },
  34. { null }
  35. };
  36. /**
  37. * Main method
  38. *
  39. * @param args
  40. * Command line arguments
  41. */
  42. public static int main (string[] args)
  43. {
  44. try {
  45. var opt = new OptionContext(“\”/path/to/wallpapers\””);
  46. opt.set_help_enabled(true);
  47. opt.add_main_entries(options, null);
  48. opt.parse(ref args);
  49. }
  50. catch (GLib.Error e) {
  51. stderr.printf(“Error: %s\n”, e.message);
  52. stderr.printf(“Run ‘%s –help’ to see a full list of available “+
  53. “options\n”, args[0]);
  54. return 1;
  55. }
  56. if (args.length < 2) {
  57. stderr.printf(“Missing argument!\n”);
  58. stderr.printf(“Run ‘%s –help’ for usage\n”, args[0]);
  59. return 1;
  60. }
  61. // Default time before changing background is 30 minutes
  62. int delay = arg_delay > 0 ? arg_delay*60 : 60*30;
  63. try {
  64. WallpaperIterator bg = new WallpaperIterator(args[1], delay);
  65. bg.run();
  66. bg.stop();
  67. }
  68. catch (IOError e) {
  69. stderr.printf(“Error: %s\n”, e.message);
  70. return 1;
  71. }
  72. finally {
  73. stderr.printf(“Finally block reached!\n”);
  74. }
  75. return 0;
  76. }
  77. }
  78. /**
  79. * Class that handles changeing of desktop wallpapers on a per interval way
  80. */
  81. public class WallpaperIterator : GLib.Object
  82. {
  83. /**
  84. * Number of seconds to wait before changeing wallpaper
  85. */
  86. private int delay = 0;
  87. /**
  88. * Current index in the images list
  89. */
  90. private int index = 0;
  91. /**
  92. * List of images to change between
  93. */
  94. private ArrayList<string> files = new ArrayList<string>();
  95. /**
  96. * List of allowed content types
  97. */
  98. private ArrayList<string> allow = new ArrayList<string>();
  99. /**
  100. * GConf client object
  101. */
  102. private GConf.Client gclient = null;
  103. /**
  104. * GConf registry where the background image is set
  105. */
  106. private string gconf_key = “/desktop/gnome/background/picture_filename”;
  107. /**
  108. * Background being used when the application is started
  109. */
  110. private string default_bg = null;
  111. /**
  112. * Constructor
  113. *
  114. * @param dir
  115. * The directory to collect wallpapers in
  116. * @param delay
  117. * Time to wait – in seconds – before swapping wallpaper
  118. */
  119. public WallpaperIterator(string dir, int delay)
  120. throws IOError
  121. {
  122. assert(delay > 0);
  123. allow.add(“image/jpeg”);
  124. allow.add(“image/png”);
  125. var f = File.new_for_path(dir);
  126. if (!f.query_exists(null))
  127. throw new IOError.FILE_NOT_FOUND(” \”%s\” doesn’t exits!”.printf(dir));
  128. if (f.query_file_type(0, null) != FileType.DIRECTORY) {
  129. throw new IOError.NOT_A_DIRECTORY(” \”%s\” is not a directory!”
  130. .printf(dir));
  131. }
  132. collect(f.get_path());
  133. if (files.size < 2) {
  134. warning(“Not enough images found for this application to be useful!\n”);
  135. return;
  136. }
  137. this.delay = delay;
  138. }
  139. /**
  140. * Run the application. Starts a MainLoop
  141. */
  142. public void run()
  143. {
  144. gclient = GConf.Client.get_default();
  145. default_bg = gclient.get_string(gconf_key);
  146. MainLoop loop = new MainLoop(null, false);
  147. var time = new TimeoutSource(delay*1000);
  148. time.set_callback(() => { swap(); });
  149. time.attach(loop.get_context());
  150. loop.run();
  151. }
  152. /**
  153. * Stop the application. Tries to reset the background
  154. */
  155. public void stop()
  156. {
  157. try {
  158. if (default_bg != null)
  159. gclient.set_string(gconf_key, default_bg);
  160. }
  161. catch (GLib.Error e) {
  162. warning(“Failed to restore background!\n”);
  163. }
  164. }
  165. /**
  166. * Does the actual background swapping
  167. */
  168. private void swap()
  169. {
  170. if (index >= files.size) {
  171. debug(“Restart…\n”);
  172. index = 0;
  173. }
  174. debug(“Callback…%-2d (%s)\n”, index, files[index]);
  175. try {
  176. gclient.set_string(gconf_key, files[index]);
  177. }
  178. catch (GLib.Error e) {
  179. warning(“Failed to set background: %s\n”, e.message);
  180. }
  181. index++;
  182. }
  183. /**
  184. * Collect images
  185. *
  186. * @param path
  187. */
  188. private void collect(string path)
  189. {
  190. try {
  191. var dir = File.new_for_path(path).enumerate_children(
  192. “standard::name,standard::type,standard::content-type”,
  193. 0, null
  194. );
  195. FileInfo fi;
  196. string fp;
  197. while ((fi = dir.next_file(null)) != null) {
  198. fp = path + “/” + fi.get_name();
  199. if (fi.get_file_type() == FileType.DIRECTORY)
  200. collect(fp);
  201. else {
  202. if (fi.get_content_type() in allow)
  203. files.add(fp);
  204. else
  205. warning(“Skipping \”%s\” due to unallowed content type\n”, fp);
  206. }
  207. }
  208. }
  209. catch (GLib.Error e) {
  210. warning(“Error: %s\n”, e.message);
  211. }
  212. }
  213. }

I think Vala looks promising and I will try it out trying to write a more complex application when I find the time.

Useful 404 page

Published 22 October, 2009 in User Science - 0 Comments

I read an article on A List Apart about creating “A More Useful 404”. I also think that it’s important to give better feedback to the visitor who ends up on a missing page. But I think that the customized 404 page should differ remarkably from the original site layout so that there’s no doubt about you’ve ended up on a “missing” page. I’ve seen 404 pages that are impossible to tell apart from the site and it can take quite some time before you realize you’ve reached a dead end.

I’ve used a customized 404 page on our sites at work almost since day one. The feedback to the visitor can be better but I have an email function – like suggested in the article at A List Apart – that sends an email to me, telling which URL the visitor tried to access and which URL the visitor came from, when someone reaches a missing page from a link, internal or external.

And I must say that this function is really, really helpful. If the broken link is on another site I usually send them an email notifying them about the problem and giving them the correct link – sometimes you just need to re-structure your site, even though it should be avoided when possible – and mostly they appreciate it and alter their link immediately. Also, when re-structuring, it’s easy to miss a few of your own internal links and with the little email notification the problem can be fixed right away.

In Roxen (the CMS we use at work) terms, all that needs to be done is adding this little snippet to the 404 page template in the administration site, under the “settings” tab for the site in question.

6 lines of RoXen Macro Language
  1. <email to=“you@your-domain.com” subject=“Error 404”>
  2. Requested URL: &page.virtfile;
  3. Referring URL: &client.referrer;
  4. UA: &client.fullname;
  5. </email>

Merging associative arrays in PHP

Published 20 October, 2009 in Programming - 0 Comments

It’s nice when serendipity is your friend! I was porting my Bitly class from Pike to PHP – I know there’s probably a hundred PHP classes already out there, but mine is better coded ;) – and noted by accident that I had used some Pike syntax in my PHP class but it was working anyway. So what was I doing? In Pike there’s separate data type for associative arrays called mapping. In Pike, in general, when merging two objects you just join them with a + sign. Thus merging two mappings you do like

9 lines of Pike
  1. mapping m1 = ([ “key1” : “Value 1”, “key2” : “Value 2” ]);
  2. mapping m2 = ([ “key3” : “Value 3” ]);
  3. write(“My mapping: %O\n”, m1 + m2);
  4. //> My mapping: ([ /* 3 elements */
  5. //> “key1”: “Value 1”,
  6. //> “key2”: “Value 2”,
  7. //> “key3”: “Value 3”
  8. //> ])

And I noted that I had done the same thing in PHP and the result was perfectly valid:

11 lines of PHP
  1. $a1 = array(“key1” => “Value 1”, “key2” => “Value 2”);
  2. $a2 = array(“key3” => “Value 3”);
  3. echo “My mapping: “;
  4. print_r($a1 + $a2);
  5. //> My mapping: Array
  6. //> (
  7. //> [key1] => Value 1
  8. //> [key2] => Value 2
  9. //> [key3] => Value 3
  10. //> )

This method doesn’t work on flat array though so there you’ll still have to use array_merge(), but pretty nice anyway.

And oh, the PHP Bitly class will be part of the new PLib release once done!

Annoying WordPress thing…

Published 18 October, 2009 in Misc - 0 Comments

It seems WordPress is hard coding the domain name into the database. How smart is that, or have I missed something? When I first set the site up on my local development server I soon noticed that various links were written hard with the domain and everything. Obviously that would f**k thing up once the site was moved to the public server. So I went into the settings and saw that there were two fields – WordPress address and Blog address – containing absolute paths. So I changed them to relative onces, e.g /blog instead of http://strindberg.loc/blog and things seemed to work properly.

Now I just realized that the guids in the RSS feed pointed to my development server. I looked in the database table and saw that there were hard coded references to http://strindberg.loc. So with a little UPDATE wp_posts SET guid = REPLACE(guid, 'strindberg.loc', 'www.poppa.se') I thought I had solved the problem. But then I realized some other guids in the RSS is generated on the fly, and they get f**ked up since the WordPress address now is relative and thus some guids looks like http:///some-url/. Is that good or what?

And try to figure out how to find out where those guids gets generated. My idea was to find where they are generated and there insert the HOST dynamically, but since there’s a zillion apply_filter(...) it’s virtually impossible to find where the shit gets generated (thanks to Netbeans it’s otherwise simple to follow the chain of execution. Just ctrl+click on a function call and the source of that function will be loaded.)

Ok, so now I have to put on my Sherlock hat and see if I can solve this. I find it hard to believe you shouldn’t be able to move a WordPress site from one domain to another without having to work your ass off!

If anyone have a solution – it’s perfectly possible I’m missing out on something here – I’m happy to know!

Finally a new site!

Published 17 October, 2009 in Misc - 0 Comments

New version of poppa.se

It hit me I hadn’t done anything to my site for three years. After all I’m a web developer and some kind of standard must be met and kept!

The previous version of this site was built on my home cooked blog application. But that was written three years ago and you learn, and develop skills, a lot over three years, so I didn’t feel like reusing it and it was kind of limited regarding lots of stuff – like social networkning – that has emerged over the past few years.

Since I’m an open source advocat I decided to live as I learn and went for WordPress. It was really simple to setup and the admin interface is rather uncluttered and easy to use. Although I’m not too fond of how the backbone of WordPress is coded and structured it’s fairly easy to bolt on your own functionality.

Hopefully this new version of the site will make me write more than two posts a year, but I wouldn’t bet on it ;)

Visual C# 2008 Express bug

Published 8 October, 2009 in Misc - 0 Comments

The other day at work I was hacking up a console application that converts an Excel workbook to chosen format. This is to be used in a web application where some people can upload an Excel file that will populate a MySQL database. To make it easier to parse the Excel file the console application will save a copy of the file as a tab separated file that is easier to parse (I will share the code when done).

vs-express-def
Visual C# 2008 default layout

Anyhow! At work I use Visual C# 2008 Express Editon when – very rarely – hacking C# and it annoyed me that the code part was too far to the left for me to feel comfortable. So I though I could displace the right column with class viewer and solution explorer and put that on my right screen, narrowing the main window and put farther to the right on my left screen.

Error message when Visual C# crashes

So I did and it felt alright – until I tried to compile the application. Visual C# just crashed big time! I didn’t have any clue why at that moment so I fired it up again and had to displace the right column again and put everything where I wanted it. I tried to compile again and boom, crash again!

So I thought: What the heck! Fired the thing up again, displaced the right column but this time I thought I’d just close the application so it would remember my settings the next time it was started. So I just hit ALT+F4 and boom, crash again. After repeating this again I came to the conclusion that Visual C# 2008 crashes if you displace the right column and then tries to either compile the current project or close the application it self. There’s probably some other actions that will cause it to crash as well.

vs-expressMy desired layout

The final conclusion is that I will have to use the application layout dear Microsoft has decided I should use. Thank you very much! Okey, I can live with it but it’s a bit annoying!

UTF-8 encoding/decoding in C

Published 27 September, 2009 in Programming - 0 Comments

I was working on a simple database to Excel XML exporter the other day and decided to write it in C. Now, the problem was that since the Swedish language contains non-ascii characters the output needs to be UTF-8 encoded. C doesn’t have a built-in function for this – it seems I should add since I’m a C rookie – and no matter how I searched at Google I couldn’t find anything useful. So I thought…

Look at PHP

…why not look at the source code of PHP and see how the PHP functions utf8_encode and utf8_decode are being done. So I downloaded the source of PHP and with a little find . -name *.c -print | xargs grep "utf8_encode" I found the functions in xml.c. Thankfully they weren’t too complicated – when dug out from the rest of the XML functions – so I didn’t take too long before I had them as standalone functions.

This is how they are used:

12 lines of C/C++
  1. #include “utf8.h”
  2. int main(int argc, char **argv)
  3. {
  4. char *iso_str = “Pontus Östlund”;
  5. char *utf8_str;
  6. utf8_str = utf8_encode(iso_str);
  7. iso_str = utf8_decode(utf8_str);
  8. return 0;
  9. }

And it seems to be working quite OK!

Sources at Github

Firefox Domain-Swapper extension

Published 12 March, 2009 in Misc - 0 Comments
The Domain Swapper extension is hosted here at poppa.se now a days.

Anybody working on a replicated web site (with an edit/backend server and one or more frontend servers) with perhaps lots of sub sites has probably experienced the hassle of switching domains between the backends and frontends.

Say you get an email saying: Can you change … to … on http://some-front-end.com/some/path/to/a/page.html. You click on the link, since you’r lazy, and then have to change the domain in the address bar to your backend domain and 40% of the time you misspell and have to go up there again and…

Anyhow! I got tired of this so I created a domain swapping extension to Firefox. It adds a context menu (right-click on any page) where you can choose to change to another domain – the URL will stay intact.

So if you are working with replicated sites the extension is free to download at:

http://www.tekniskaverken.se/fishnet…pper/index.xml