Freitag, 12. März 2010
If you encounter a strange error from pdftex saying "cannot open type 1 font file" with a reference to some pfb file, there's a good chance you are missing the appropriate font.

In my case, bchri8a.pfb was missing and a google search revealed that this file belongs to a font called "charter". Installing this font with the MikTeX package manager solved this issue for me.




Mittwoch, 23. September 2009
Today I had the problem that no stacktrace was printed in logs produced by log4j. Here's an important difference between the logging functions with 1 and 2 parameters:

Logger logger = Logger.getLogger(MyClass.class);
try {
  someFunction();
} catch(MyException e) {
  logger.error("someFunction failed", e); //   prints stacktrace
  logger.error("someFunction failed" + e); // one-liner with type of exception
}

So, use 2 parameters with the Throwable object as 2nd parameter to get a full backtrace. If you want to receive a single line in your output can pass the Throwable as the 1st parameter.




Montag, 21. September 2009
A list of handy attributes and functions of gContextMenu for Mozilla Firefox Extension development (posted because google didn't find any documentation on gContextMenu when I looked for it):

gContextMenu.target

The DOM object the user clicked on.

gContextMenu.menu

The internal object representing the popup menu.

gContextMenu.popupURL

Something internal. Yeah, I know, cool explanation =).

gContextMenu.onTextInput

Returns true if target is a text input element.

gContextMenu.onImage

Returns true if target is a image.

gContextMenu.onLoadedImage

Returns true if target is image that's loaded.

gContextMenu.onLink

Returns true if target is a link.

gContextMenu.onMailtoLink

Returns true if target is a mailto link.

gContextMenu.onSaveableLink

I don't know exactly what this is good for. Comment inside the code: "If element is a directory, then you can't save it."
Implementation equivalent to:
onSaveableLink = target.getAttribute( "URL" ) && target.getAttribute( "container" ) != "true"

gContextMenu.onMetaDataItem

I don't know what this is for. Have a look at the link at the bottom, the implementation should help you figure out the exact behaviour.

gContextMenu.onMathML

I don't know what this is for. Have a look at the link at the bottom, the implementation should help you figure out the exact behaviour.

gContextMenu.link

Returns a pseudo link object (like in DOM) with a href attribute and getAttribute function.

gContextMenu.inFrame

Returns true if the user clicked inside of a frame.

gContextMenu.hasBGImage

I don't know what this is for. Have a look at the link at the bottom, the implementation should help you figure out the exact behaviour.

gContextMenu.isTextSelected

Returns true if there is selected text that you can retrieve with content.window.getSelection(). Does not work if the selected text is inside of a text input. Also returns true, if the user didn't click on the selection but somewhere else on the page.

gContextMenu.inDirList

I don't know what this is for. Have a look at the link at the bottom, the implementation should help you figure out the exact behaviour.

gContextMenu.shouldDisplay

I don't know what this is for. Have a look at the link at the bottom, the implementation should help you figure out the exact behaviour.

gContextMenu.initMenu( xulMenu )

Use the parameter xulMenu as new context menu.

Source:
http://www.koders.com/javascript/fidCF90560822BBAC49CF500EEC09210B336E08A656.aspx?s=menu#L42




Freitag, 31. Juli 2009
I like to watch some shows from german TV channel pro7, but unfortunately their site depends on Move Media Player, which only support Windows.

In the windows version of Firefox (started from wine) you can install Move Media Player without problems, you can also start the video but there is only sound, no video (just black).

I found a workaround, though. Go to the site where you want to watch the video. Then, before it has begun playing, go to another tab in your browser. When you hear the sound of the video you want to watch, change back to the first tab and you should have video, too!




Sonntag, 26. Juli 2009
Wow I started to hate my laptop. Often I was unable to watch videos or it was so slow that I didn't want to continue. Yesterday, finally, I found what caused those problems:

I noticed that for some time when booting a message appeared saying
FATAL: Error inserting acpi_cpufreq (.../acpi-cpufreq): No Such Device

This was the culprit, no cpu frequency scaling, it seems my cores have been running on 800 Mhz for a few months. Somehow "CPU frequency scaling" was disabled in my BIOS (perhaps after change of the motherboard by a technician from Dell). Re-enabling that setting solved the issue for me.




Mittwoch, 15. Juli 2009
I don't know how you are using twitter, but I like to follow friends as well as news sites and politicians. Normally, you'll see your friends' timeline sorted by date. This can be annoying if you got some spammy friends that dominate your first page and make it hard to keep up with others that don't tweet that often.

I didn't find a client that is capable of reordering the timeline - taking into account how many tweets a friend is writing - so I decided to write it on my own.

The result is a Ruby on Rails application, which you can run on your computer (i don't plan on hosting it somewhere at the moment). It looks like this if you use Mozilla Prism to convert the website to a local application:
TwitRel: A twitter client that is capable of reordering your friends' timeline based on how often they tweet

The code is available for downloading, forking or anything over at github.

The README file in the Repository can help you get up and running.

If you are interested in how the reordering works, I'll explain it shortly. The following code is taken from app/controllers/timeline_controller.rb:
twitter = Twitter::Client.new(:login => USER, :password => PASSWORD)
timeline = twitter.timeline_for(:friends, :count => 300)
my_id = twitter.my(:info).id
timeline = timeline.select { |entry| entry.user.id != my_id }
numtweets = {}
twitter.my(:friends).each do |friend|
  num = timeline.select { |entry| entry.user.id == friend.id }.size
  numtweets.store(friend.id, num)
end
@tweets = timeline.sort_by { |entry| (numtweets[entry.user.id] ** 0.6) * (Time.now - entry.created_at) }

We're connecting to twitter with the great Twitter4R API and then fetch 300 tweets from your friends' timeline. Next, the number of tweets per friend is calculated (in the current timeline).
Each tweet now gets a relevance score calculated by n0.6 × Δt, with n the number of tweets for the specific user ("tweep" that send the update) and Δt, the time interval passed since the status update.
0.6 is an arbitrary constant, you can test what best matches your taste (try some numbers between 0 and 1 to see the difference).




Montag, 13. Juli 2009
Running one of my test classes using multiparameter attributes (date column in the database) I got a lot of warnings saying:
vendor/rails/activerecord/lib/active_record/attribute_methods.rb:142: warning: Object#type is deprecated; use Object#class

Here's the code where type is called:
def create_time_zone_conversion_attribute?(name, column)
  time_zone_aware_attributes && !skip_time_zone_conversion_for_attributes.include?(name.to_sym) && [:datetime, :timestamp].include?(column.type)
end

Normally, type should be called on a Column object, which provides a type (see vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb), but in my case, column was nil and the method type was called for Object.

I don't fully understand what's going on (why is column nil?), but as a quickfix to silence the annoying warning you can change the method in attribute_methods.rb to handle this as a special case:
def create_time_zone_conversion_attribute?(name, column)
  if column.nil?
    true
  else
    time_zone_aware_attributes && !skip_time_zone_conversion_for_attributes.include?(name.to_sym) && [:datetime, :timestamp].include?(column.type)
  end
end




Today, I had the problem that rcov on one machine produced outputs like 50% or 48% for some files while on some other machine the coverage was 100% or at least >95%. When looking at the rcov output, I noticed that the contents of the files that made problems were duplicated, first the correct results and then again the whole class, this time with every single line marked as being not covered.

The affected files were sessions_controller.rb, user_controller.rb and user_mailer.rb. This made me think of where those files came originally from: The restful authentication plugin. I had a look on the test files for these and their beginning looked like this (test/functional/sessions_controller_test.rb here):
require 'test_helper'
require 'sessions_controller'

# Re-raise errors caught by the controller.
class SessionsController; def rescue_action(e) raise e end; end

Why is sessions_controller included/required there? I don't know why the restful authentication plugin put those instructions there, but you can just remove them from the affected files and you will be fine.

I suspect that this issue only comes up with older rcov versions, because my development machine with current rcov does not have a problem with the require instructions.




Samstag, 11. Juli 2009
Me and my team mates at the university today spent hours on trying to get Vectors from a Web Feature Service correctly placed on a Google Maps Layer in OpenLayers. So here is a description how you can make it work.

Google Maps uses another system of geocoordinates, so a projection is needed. Your map should be created with these options:
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
20037508, 20037508.34)
};
map = new OpenLayers.Map('map', options);

Your layer needs special handling, too (sphericalMercator):
var gmap = new OpenLayers.Layer.Google("Google", {"sphericalMercator": true});
map.addLayers([gmap]);

Also the results from the WFS need to run through the projection. Call it similar to this:
var layer = new OpenLayers.Layer.WFS( "Krankenhaus",
"http://chrifhost.webhop.org:8080/WFS_Server/WFS/",
{typename: "HOSPITAL", maxfeatures: 1000},
{projection: new OpenLayers.Projection("EPSG:4326"),
extractAttributes: true});
map.addLayers([layer]);

Your points are already placed correctly now. If you want to set the center of the map to some specific area that you have in lat/lng coordinates, they need to be changed to match the new system used by the map. An example for Germany:
map.setCenter(OpenLayers.Layer.SphericalMercator.forwardMercator(10.455278, 51.165), 2);




Samstag, 27. Juni 2009
I had an issue with the quickfix functionality in Vim and the Rails Plugin.

In test failures, a path is given to the test file where there was the test failure. This path starts sometimes in my Installation (Rails 2.3.2, Ruby 1.8.7) with a '/' (only happens paths to test cases, I think). I don't now why, it doesn't really make sense and the vim-rails plugin doesn't like this, too and try's to open up a file with an absolute path instead of one relative to the rails project path.

Today I was so annoyed by this (after each 'Rake test' call a new tab opens up with an empty file) that I went for fixing it. The fix is a little change to /usr/share/vim/autoload/rails.vim.

Somewhere in there, there are the following lines: (line 941+ here)
" stack backtrace is in brackets. if multiple lines, it starts on a new line.
let s:efm=s:efm
\.'%Ctest_%.%#(%.%#):%#,'
\.'%C%.%#\ [/\\?%f:%l]:,'
\.'%C\ \ \ \ [/\\?%f:%l:%.%#,'
\.'%C\ \ \ \ %f:%l:%.%#,'
\.'%C\ \ \ \ \ %f:%l:%.%#]:,'
\.'%C\ \ \ \ \ %f:%l:%.%#,'

You need to change Lines 4 and 5 of that section to:
\.'%C%.%#\ [/\\?%f:%l]:,'
\.'%C\ \ \ \ [/\\?%f:%l:%.%#,'

This will test for an optional leading slash and ignore it so that vim opens up a relative path from now on. Perhaps other changes are needed, I'll update this article if I encounter sth.

UPDATE
I noticed there are more problems with the rails plugin here. Most of the time, the error message isn't found. So I spent a few hours figuring out these odd vim error formats. It's now working for the failures I had till now.
How to apply my changes:

Look for the lines containing '" Current directory' and 'function! s:makewithruby(arg,bang,...)' and replace the area in between with the following code:

" Current directory
let s:efm='%D(in\ /\\?%f),'
" Failure and Error headers, start a multiline message
let s:efm=s:efm
\.'%A\ %\\+%\\d%\\+)\ Failure:,'
\.'%A\ %\\+%\\d%\\+)\ Error:,'
\.'%+A'."'".'%.%#'."'".'\ FAILED,'
" Syntax errors in the test itself
let s:efm=s:efm
\.'%.%#.rb:%\\d%\\+:in\ `load%.%#'."'".':\ %f:%l:\ syntax\ error\,\ %m,'
\.'%.%#.rb:%\\d%\\+:in\ `load%.%#'."'".':\ %f:%l:\ %m,'
" And required files
let s:efm=s:efm
\.'%.%#:in\ `%.%#require'."'".':\ %f:%l:\ syntax\ error\,\ %m,'
\.'%.%#:in\ `%.%#require'."'".':\ %f:%l:\ %m,'
" Syntax Errors
let s:efm=s:efm
\.'%A%.%#.rb:\\d%\\+:in\ `%.%#'."'".':\ %m\ (%.%#Error),'
" Exclusions
let s:efm=s:efm
\.'%C%.%#(eval)%.%#,'
\.'%C-e:%.%#,'
\.'%C%.%#/lib/gems/%\\d.%\\d/gems/%.%#,'
\.'%C%.%#/lib/ruby/%\\d.%\\d/%.%#,'
\.'%C%.%#/vendor/rails/%.%#,'
" Specific to template errors
let s:efm=s:efm
\.'%Ctest_%.%#(%.%#Test):%\\?,'
\.'%C%.%#Errors\\?:\ %#%m,'
\.'%C\ %\\+On\ line\ #%l\ of\ %f,'
\.'%C%\\(You\ might\ have\ expected\ an\ instance\ of%.%#%\\)%\\@=%m,'
\.'%C%\\(The\ error\ occurred\ while\ evaluating\ %.%#%\\)%\\@=%m,'
\.'%C%\\(%.%#didn'."'".'t\ change\ by%\\)%\\@=%m,'
\.'%C%\\(%.%#expected\ but\ was%\\)%\\@=%m,'
\.'%Z%\\(<%\\d%#>.\\)%\\@=%m,'
" stack backtrace is in brackets. if multiple lines, it starts on a new line.
let s:efm=s:efm
\.'%C\ %\\{5}/\\?%f:%l:in `test_%.%#'."'".']:,'
\.'%Z\ %\\{4}/\\?%f:%l:in `%.%#'."'".','
\.'%Ctest_%.%#(%.%#)\ [/\\?%f:%l]:,'
\.'%C\ %#[/\\?%f:%l:in `test_%.%#'."'".','
" Catch all
let s:efm=s:efm
\.'%Z\ %\\{4}/\\?%f:%l:%.%#,'
\.'%Z%.%#from\ %f:%l,'
\.'%Z%.%#from\ %f:%l:%.%#,'
let s:efm=s:efm
\.'%Z%m,'
" Another catch for syntax errors in tests
let s:efm=s:efm
\.'%A%f:%l:\ %m\ for\ %.%#(%.%#Error),'
\.'%Z\ %#from %.%#.rb:%\\d%\\+:in\ `load%.%#'."'".','
" Exclusions
let s:efm=s:efm
\.'%-G%.%#/lib/gems/%\\d.%\\d/gems/%.%#,'
\.'%-G%.%#/lib/ruby/%\\d.%\\d/%.%#,'
\.'%-G%.%#/vendor/rails/%.%#,'
\.'%-G%.%#%\\d%\\d:%\\d%\\d:%\\d%\\d%.%#,'
" Final catch all for one line errors
let s:efm=s:efm
\.'%f:%l:\ syntax error\,\ %m,'
\.'%-G%\\s%#from\ %.%#,'
" Drop everything else
let s:efm=s:efm
\.'%-G%.%#'

let s:efm_backtrace='%D(in\ /\\?%f),'
\.'%\\s%#from\ /\\?%f:%l:%m,'
\.'%\\s#{RAILS_ROOT}/%f:%l:\ %#%m,'
\.'%\\s%#[/\\?%f:%l:\ %#%m,'
\.'%\\s%#/\\?%f:%l:\ %#%m'

function! s:makewithruby(arg,bang,...)

Wohooo! This is paradise for a regex lover like me =)




Samstag, 20. Juni 2009
Don't try to achieve this with str.getChars, I never got this working in sth like 2 hours of work. Instead, go for using InputStreamReader if possible. This class includes the required conversion logic.

If 'is' is a InputStream that you want to process, use code like this:

new InputStreamReader(is, "ISO-8859-1");




Montag, 15. Juni 2009
Here's a tip on how to deal with with partial dates like hours with ruby on rails. start_hour in this example is a virtual attribute of the search model. To make the select_hour helper work properly, you need to add the the default value to use (@search.start_hour) as well as a prefix and field_name (this will tell rails how to name the field, 'search[start_hour]' in this case).

So, I assume you got some form declaration like this:
<% form_for(@search) do |f| %>

Now to add a hour select box inside that form, use code similar to this:
<%= select_hour @search.start_hour, :prefix => 'search', :field_name => 'start_hour' %>

This will also work with select_minute / select_second / select_day / select_month / select_year.




Donnerstag, 7. Mai 2009
Argh das war ja mal ein Krampf. Mein Problem war, dass meine UMTS-Karte verschiedene Devices zugewiesen bekommen hatte (/dev/ttyUSB1, /dev/ttyUSB2, /dev/ttyUSB3 oder manchmal /dev/ttyUSB2, /dev/ttyUSB3, /dev/ttyUSB4).

Ich konnte also kein festes Device angeben, über das connected werden soll.
Man kann das ganze sich mit Udev hinbasteln, neue Regel erstellen, z.B. /etc/udev/rules.d/44-my-device.rules

Als Inhalt einfach das folgende eintragen, dann wird beim nächsten Einstecken der Karte ein eindeutiges Device /dev/umts für /dev/ttyUSB1 bzw /dev/ttyUSB2 je nachdem welches die niedrigste Nummer gerade bekommen hat, erstellt.

SUBSYSTEMS=="usb", DRIVERS=="option", ATTRS{bInterfaceNumber}=="00", SYMLINK="umts"




Dienstag, 27. Januar 2009
wtf - schrecklich wie auf diese Art Innovation verhindert und die großen Unternehmen vor den bösen Konkurrenten "geschützt" werden:

http://www.spiegel.de/netzwelt/mobil/0,1518,603726,00.html




Mittwoch, 7. Januar 2009
Hab ein paar sozial engagierte Firmen bei den Crunchies 2008 gefunden, die, finde ich, mehr Aufmerksamkeit verdient hätten:

Kiva ist ein Dienst, er es Leuten erlaubt, anderen private Mikrokredite zu vergeben und somit z.B. die Welt der Leute in Afrika ein Stück besser zu machen. Man kann sich verschiedene Projekte anschauen und so das Leben einer anderen Person (oder mehreren) verbessern.
http://kiva.org

Akoha fällt in eine andere Kategorie: Das wird ein soziales Spiel werden, bei dem es Karten gibt, auf denen eine "sozialfreundliche" ( ;-) ) Aktion steht wie z.B. 'Gib jemandem einen Kaffee aus'. Wenn man diese Aktion ausführt, gibt man die Karte an die andere Person weiter, die diese Aktion wiederum ausführen kann etc. Die web2nullige Komponente dabei ist, dass man den Pfad der Karten online verfolgen und sich mit anderen Spielern austauschen kann.
http://akoha.com/

Das Ziel von Better Place ist es, eine Infrastruktur für Elektroautos aufzubauen und so letztendlich emissionsfreie Autos möglich zu machen. Das ganze ist kein Hirngespinst, sondern ich bin überzeugt, das es funktionieren wird. Vorreiter an Ländern sind u.a. Dänemark, Österreich und Kalifornien, da fragt man sich wo Deutschland bleibt?
Hier ein niedliches (wirklich ;-) ) Video von der sympathischen Firma:
http://www.betterplace.com/press-room/videos-detail/the-davos-question/