Archive for the ‘Code’ Category

Licensing your libraries

Tuesday, February 8th, 2011

For most spare time projects, licensing can be an afterthought. Personally, I hardly put licences on anything I write. Most of the time this is just because I expect people to use it anyway. I treat licences more as a restriction than a freedom.

Really, if you don’t put a licence on your code then people can’t use it but if anyone asked I would probably let them. A licence should let them know whether they can use it without having to ask you.

However, anything serious that you release needs a licence. Choosing the right licence for your project can be time consuming and involve reading and completely understanding legal documents, which isn’t what most of us want to do. It is very common for people to release code under the GNU General Public Licence (GPL) or Lesser General Public Licence (LGPL).

Terms such as “derived works” and what constitutes these are even more of a problem.

There are a few key points around releasing under these licences. Please bear in mind that I do not have a legal background.

  1. Anyone is free to distribute your work, even if you have sold it to them.
  2. You must provide source code for anything you release.
  3. Anyone is free to modify your work.
  4. If you use code licensed under the GPL in your project, your project must also be licensed under the GPL. This means that for people not releasing under the GPL, your code is essentially useless and to all intents and purposes does not exist.

The first point here makes selling your work difficult. Even if you successfully sell it, anyone who has bought it can just give it away for free.

The second point here makes releasing closed source binaries a problem. Anything you release must be released with accompanying source code. This causes further problems for commercial software, as attempts to safeguard it against piracy can be easily removed, which is also legal by the third point here.

The third point means that people can effectively take what you have done, make slight changes to it and pass it off as their own work.

However, the fourth point here is the biggest problem. When you licence under the GPL, you are not only causing the above problems for yourself (which may be ideal for you), you are also forcing anyone who uses your code to have all the same problems (which probably won’t be ideal for them). If they don’t want these problems in their own work, they can’t use yours. Fortunately there is a solution for this. The LGPL varies from the GPL in that projects don’t have to use the same licence as you in order to use your code. This makes it ideal for freely releasing libraries that anyone can use.

Somewhat worryingly, FSF and GNU are trying to trying to get people to use GPL instead of LGPL and, it seems, the only reason they are doing this is to give “free” software an advantage. I don’t agree with this ethically. For free software to be free, everyone should be able to use it and that includes people who want to use it in commercial projects.

I’ve lost count of how many times I’ve found a nice little snippet of code that does exactly what I want and the author seems to want to release it to the public for everyone, but has released it under the GPL making it unusable in a non-GPL project.

There are many other licences out there to choose from, such as the MIT and BSD licences. So, please choose the licence for your project carefully and think of the consequences for your target audience before blindly slapping a GPL sticker on it.

Printer friendly Fudzilla RSS

Wednesday, September 29th, 2010

Fudzilla is a nice site for catching up with daily tech news. I prefer to set up my email client Thunderbird to aggregate the RSS, but when you have a 1920×1200 monitor and Fudzilla still puts so much crap at the top of the article that it ends up looking like this and you have to scroll down before you can even read a few lines of text, its becomes a terrible user experience.

Wouldn’t it be better to get the text at a reasonable size, taking 100% of the width available, with no crap at the top that you have to scroll past?

Well, you can. The printer friendly view does all of this, and all you have to do is change the link in the RSS to use the printer friendly URL instead of the standard one. Here is some php do do just that! Just put this on a server somewhere and subscribe to that URL instead of the normal fudzilla feed.

<?php
header("Content-Type: application/rss+xml; charset=utf-8");
 
$url = "http://www.fudzilla.com/?format=feed";
 
$rss = fopen($url, "rb");
$contents = stream_get_contents($rss);
fclose($rss);
 
$contents = str_replace("?</guid>", "%3f</guid>", $contents);
$contents = str_replace("</guid>", "?tmpl=component&amp;print=1</guid>", $contents);
echo($contents);
?>

You may be able to just view the description in your RSS aggregator, but it tends not to show the whole article. In the past, fudzilla has put just the subtitle in there, for example.


Update: This has been broken by fudzilla using a HTTP 302 redirect and a cookie but anything that will take the cookie from the first request and use it for the second request should be able to handle this easily. Here’s a function for it that uses cURL.

function download_string_curl($url)
{
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_AUTOREFERER, true);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
  curl_setopt($ch, CURLOPT_COOKIEFILE, "THIS_FILE_DOES_NOT_EXIST");
  $contents = curl_exec($ch);
  curl_close($ch);
  return $contents;
}

As a note to Fudzilla: This is only necessary because of the sheer amount of crap you put at the top of your page. You shouldn’t have to scroll down an entire screen height before you can even see the content of that page. That’s just poor design. If adding cookies and a redirect was an attempt to stop screen scraping, it didn’t work. You can disable that now and save yourself some bandwidth.

Compiling zlib.lib on Windows

Thursday, August 26th, 2010

Update: see comments section for a more up to date method of doing this. Don’t forget to run contrib\masmx86\bld_ml32.bat from the Visual Studio Command Prompt before compiling this way though.

This article still applies if you want to compile on older versions e.g. MSVC 6.0, for older projects or if you have problems with the new method.


zlib is the standard for lossless data compression. The DEFLATE compression algorithm is the basis for just about every lossless compression format out there, including “zip” and “gzip”, which is itself part of zlib.

There are two ways that it can be used from C/C++ projects in Windows.

Firstly, it can be used by dynamic linking (dll). This means using zdll.lib and shipping the appropriate version of zlib1.dll with your project. This is not a problem, as Windows versions of both of these files are provided.

The second way is to use static linking. That is, having all of the code in one .lib file and compiling it into your exe so that you do not have to distribute zlib1.dll. This means compiling zlib.lib.

In version 1.2.4 of zlib, a “projects” directory was provided, with a Microsoft Visual C++ 6.0 project. However, it seems that version 1.2.5 has not included this project. This means that the best solution is to go and get the 1.2.4 source and compile it yourself. However, the zlib project seems to be kept inside the libpng project on sourceforge.net, so it is not immediately obvious where to find older versions of the zlib source code.

zlib 1.2.4 source (zip)

Extract the zip, open projects\visualc6\zlib.dsp in Visual Studio (I used 2005) and compile “LIB Release” (and optionally “LIB Debug”)

Copy zlib.h and zconf.h from “include” to your Visual Studio “include” directory, and zlib.lib (and zlibd.lib if you made it) to your Visual Studio “lib” directory.

On 64 bit Windows, with Visual Studio 2005, this is “C:\Program Files (x86)\Microsoft Visual Studio 8\VC\” so adjust for your version of Visual Studio.

You now just need to add “zlib.lib” to your “Linker -> Input -> Additional Dependencies” line in your C++ project configuration to use it (and optionally zlibd.lib for the debug version).

Remote recursive sha1sum with php

Wednesday, June 2nd, 2010

To calculate the SHA-1 sums, display them and make them available for download in a sums.gz file:

<?php echo(`find ./some_directory/ -type f | grep -v sums.gz | xargs sha1sum | gzip -c | tee sums.gz | zcat`); ?>

To check the sums:

<?php echo(`zcat sums.gz | sha1sum -c -`); ?>

Get external IP address with Python

Wednesday, May 26th, 2010

Here’s a quick snippet of Python code (tested in 3.0) to quickly look up your external IP address over HTTP and display it:

import urllib.request
print(str(urllib.request.urlopen("http://automation.whatismyip.com/n09230945.asp").read(), "utf8"))

wp-syntax to look like Visual Studio

Tuesday, March 23rd, 2010

wp-syntax is a nice plugin for WordPress using GeSHi to produce syntax highlighted blocks of code.

The default colours aren’t very nice though, and there is no way to easily change them. wp-syntax-colorizer (horrible name) makes it easier to set the colours, but defaults to even worse colours.

Most of us want readable colours that we are used to from IDEs, and most of us will be using either Visual Studio or Eclipse. I mainly use the former. To get it to use the visual studio colours I edit wp-syntax-colorizer as follows:

function my_custom_geshi_styles(&$geshi)
{
  $overall = "black";
  $keyword = "blue";
  $literal = "maroon";
  $comment = "green";
 
  $geshi->set_overall_style("color: $overall;", true);
 
  $geshi->set_keyword_group_style(1, "color: $keyword;", true);
  $geshi->set_keyword_group_style(2, "color: $keyword;", true);
  $geshi->set_keyword_group_style(3, "color: $keyword;", true);
  $geshi->set_keyword_group_style(4, "color: $keyword;", true);
 
  $geshi->set_symbols_style("color: $overall;", true);
  $geshi->set_methods_style(1, "color: $overall;", true);
  $geshi->set_regexps_style(1, "color: $overall;", true);
 
  $geshi->set_strings_style("color: $literal;", true);
  $geshi->set_numbers_style("color: $literal;", true);
 
  $geshi->set_comments_style(1, "color: $comment;", true);
  $geshi->set_comments_style('MULTI',"color: $comment;", true);
}

Remove Size bbcode from phpbb

Thursday, March 4th, 2010

One of the most annoying things about phpBB is the ability for people to randomly use [size="200"]Huge[/size] BB code, with no easy way to remove it and every time you update between versions it comes back.

To disable it:
in /include/bbcode.php remove the whole

case 5:
...
break;

section.

To remove it from the posting page:
in /styles/prosilver/template/posting_buttons.html remove the whole

<select>
...
</select>

section.

After that, delete your “cache” directory so that it uses the new copy.

Remember that you have to repeat this process after every update to phpBB3.

Moving comments in WordPress

Sunday, February 7th, 2010

In MySQL, first move the comment:

UPDATE wp_comments SET comment_post_ID = P_TO_ID WHERE comment_ID = C_ID;

P_TO_ID is the ID of the post you are moving it to. C_ID is the ID of the comment you are moving. You can find both of these IDs easily from the dashboard.

Then correct the comment counts for the posts:

UPDATE wp_posts SET comment_count = (SELECT COUNT(*) FROM wp_comments WHERE comment_post_id = id AND comment_approved = 1)
WHERE comment_count != (SELECT COUNT(*) FROM wp_comments WHERE comment_post_id = id AND comment_approved = 1);

The second line in this query is not strictly necessary but it lets you know how many posts were affected.

Convert any audio/video files to mp3 for free

Tuesday, November 24th, 2009

It seems that there is some confusion about audio conversion tools and some people even pay for them.

The truth is that most encoders, even ones you pay for, use ffmpeg internally to do all of the actual work and ffmpeg is free and open source.

You can even get it pre-compiled for Windows, though the version isn’t great.

The only problem with using ffmpeg directly is that it has a command line interface and most novices find it hard to use.

Here’s a batch file for use on Windows which will convert anything you drop onto the file into a 320kbps mp3:

ffmpeg -i %1 -ab 320k -y %1.mp3
@if errorlevel 1 @pause

To create this file, open notepad. Copy and paste the above 2 lines in. Save it as “convert.bat” or something similar (the .bat is important) and select “All files” from the drop down list.

Put the bat file in the same directory as ffmpeg.exe and simply drag anything you want converted on top of the bat file.

You can use almost anything. wav, m4a, m4v, mov, mpg, avi, etc. If you use a file with both audio and video, such as a movie, it will just extract the audio and save that as an mp3 file.

ffmpeg target file sizes (again)

Friday, July 17th, 2009

This script is now available as an ongoing project that can be downloaded. Please see the Video Encoding Project.


As a bit of a revision to a previous entry, I have converted the combination bash/python scripts I gave earlier into a single large python script.

This can now be used without editing any files to set sizes. An example of use is:
$ ./enc.py -s 700 -a 192 -o '-deinterlace' da_*.VOB
All of these flags are optional except the file list, where at least 1 file must be specified.

enc.tar.gz:

#!/usr/bin/python
 
from getopt import getopt, GetoptError
from sys import argv, exit
from subprocess import Popen, PIPE
from re import search
 
def secs(h, m, s):
  return (((h*60)+m)*60)+s
 
def calc_video_bitrate(target_bytes, ab, time):
  audio_bytes = (ab * 1000 / 8) * time
  return (target_bytes - audio_bytes) / time * 8
 
def get_duration(file):
  ffmpeg = Popen(("ffmpeg", "-i", file), stderr=PIPE)
  match = search("(\\d+):(\\d+):(\\d+)\\.\\d+", ffmpeg.communicate()[1])
  ffmpeg.stderr.close()
 
  if match == None: return 0
  dur = match.groups()
  return secs(int(dur[0]), int(dur[1]), int(dur[2]))
 
def encode(source, dest, opts, vbr, abr=128):
  command1 = "ffmpeg -i %s -pass 1 -an -vcodec libx264 -vpre fastfirstpass -b %d -bt %d -threads 0 %s -y pass1.mp4" % (source, vbr, vbr, opts)
  command2 = "ffmpeg -i %s -pass 2 -acodec libfaac -ac 2 -ab %dk -vcodec libx264 -vpre hq -b %d -bt %d -threads 0 %s -y %s" % (source, abr, vbr, vbr, opts, dest)
 
  pass1 = Popen(command1.split())
  pass1.wait()
 
  pass2 = Popen(command2.split())
  pass2.wait()
 
 
target_size = 350 #MiB
ab = 128 #kbps
extra_options = ""
 
# Parse args
try:
  opts, args = getopt(argv[1:], "s:a:o:", ["size=", "ab=", "opts="])
except GetoptError, err:
  print str(err)
  exit(2)
 
for o, a in opts:
  if o in ("-s", "--size"):
    target_size = int(a) * 1024 * 1024
  elif o in ("-a", "--ab"):
    ab = int(a)
  elif o in ("-o", "--opts"):
    extra_options = a
 
if len(args) < 1:
  print "Usage: " + argv[0] + \
    " [-s <size (MiB)>] [-a <audio bit rate (kbps)>] [-o <additional options>] <file list>"
  exit(2)
 
# Loop through files
for file in args:
  duration = get_duration(file)
  if duration <= 0:
    print "Unable to get length of", file
    continue
 
  bitrate = calc_video_bitrate(target_size, ab, duration)
 
  encode(file, file + ".mp4", extra_options, bitrate, ab)