Archive

Posts Tagged ‘kam’

Using CUPS to print text files in non-UTF8 charset encoding

May 17th, 2012 No comments

At our university department, many people still haven’t migrated to UTF8 and are still happily using ISO-8859-2 – mainly due to the amount of legacy text (TeX, …) documents.
Nowadays, support for non-UTF8 is slowly waning though, and CUPS is a prime example. Most of (shabby anyway) support for non-UTF8 encodings have been removed few years ago. It is still possible to force CUPS to print text files in non-UTF8 encoding if you extract the appropriate files from ancient version (1.2 or some-such) of CUPS to /usr/share/cups/charset/ and print using e.g. lpr -o document-format='text/plain;charset=iso-8859-2'. However, there is simply no support for lpr automatically setting the charset based on your locale.

We decided that the best way to go is to simply auto-detect the encoding using the awesome enca package and convert text files from this encoding to UTF8. This should be actually fairly fool-proof in practice, unless you are dealing with an extremely mixed set of languages. Making own CUPS filter is easy – just change texttops entries in /etc/cups/mime.conv to textautoencps and create a new /usr/lib/cups/filter/textautoencps file:

#!/bin/bash
 
if [ $# == 0 ]; then
  echo >&2 "ERROR: $0 job-id user title copies options [file]"
  exit 1
fi
 
{ if [ $# -ge 6 ]; then
    cat $6
  else
    cat
  fi; } |
    enconv -x utf-8 -L czech |
    /usr/lib/cups/filter/texttops "${@:0:6}"
Categories: linux, software Tags: , , ,

Publicly Killable Computations

March 7th, 2012 No comments

At our university department, people sometimes need to run expensive or long-term computations. We have few servers reserved for computations, but frequently it is useful to run computations on machines in the offices since some of them are fairly powerful and mostly get only very light use CPU-wise.

However, such computations must never impair any interactive or more pressing use of the machine. Therefore, we want to limit scheduling priority of the computations, limit total memory used by the computations and allow *anyone* kill *any* running computation. It turns out that this is not as trivial to achieve as I hoped.

In comes Computations under control: compctl – cgroup-based control of publicly limitable and stopable tasks. It is a tool that allows anyone to execute a command (or start screen) such that it is marked as a computation. Then, it allows anyone else to limit the total amount of memory allocated for all computations and to stop a specific computation or all computations on a machine. It uses cgroups to keep track of computations and limit the total memory usage, and a simple client-server architecture to perform priviledged tasks.

I hope it will be useful for someone else too. :-) Feel free to send in patches, and extra pairs of eyeballs checking the security would be welcome too. Top on my TODO list is simple debian package and a more verbose compctl –list output.

Categories: linux, software Tags: , , , ,

Sticker Generator

February 19th, 2011 3 comments

At KAM MFF CUNI, we have about ~60 to ~70 computers scattered over the department, be them at desks of professors, older ones stocked in the basements or near-identical rack servers. Especially when older machines are shuffled around, it is difficult to track them, and the standard tiny inventory stickers keep falling off (and you have to keep looking up the number).

Therefore, we are making stickers to put on all our computers with some details about them. I used that as a pretense for learning some basic Cairo and I really like the paradigm (though I wish text manipulation was be easier). In case anyone would find this ever useful (or just a good scaffolding for their own Cairo Perl script), the script goes here; the default sticker size is to have height of a 5.25″ drive bay and width so that two rows fit nicely on A4.

#!/usr/bin/perl
# (c) Petr Baudis  2011  MIT licence
# 
# Generate PDF with stickers.
# Expects tab-delimited columns on stdin:
# hostname mac invnumber buydate
 
use strict;
use warnings;
 
 
# -- User configuration --
 
our @paper = (598, 842); # A4, 72dpi
our @margin = (72, 72);
our @sticker = (227, 116);
our $filename = 'nalepky.pdf';
 
our $fontface = 'Arial';
our $ffontface = 'Courier New';
# large, normal, small
our @fontsize = (26, 15, 10);
our @linespacing = (18, 4, 18);
our $topmargin = 2;
 
our $contact = '<contact information>';
 
# -- User configuration end --
 
 
use lib 'perl';
use List::Util qw(min);
use List::MoreUtils qw(pairwise);
use Cairo;
 
our $surface = Cairo::PdfSurface->create ($filename, @paper);
 
# Effective surface area
our @surfsize = pairwise { $a - $b * 2 } @paper, @margin;
# Grid layout on effective surface
our @grid = pairwise { int($a / $b) } @surfsize, @sticker;
# Grid surface area
 
our @gridsurfsize = pairwise { $a * $b } @grid, @sticker;
# Start of grid surface so that it is centered on the paper
our @gridsurfstart = pairwise { ($a - $b) / 2 } @paper, @gridsurfsize;
 
# Produce a context for single sticker, starting at coordinates [0,0]
sub nalepka_cr {
        my ($surface, $cell) = @_;
        my @startM = pairwise { $a * $b } @sticker, @$cell;
        my @start = pairwise { $a + $b } @gridsurfstart, @startM;
 
        my $cr = Cairo::Context->create($surface);
        $cr->translate(@start);
 
        $cr->set_source_rgb(0, 0, 0);
        $cr->set_line_width(1);
        $cr;
}
 
# Centered text with top border at $$y. $size is index in font config above.
sub nalepka_text {
        my ($cr, $y, $face, $slant, $weight, $size, $text) = @_;
        $$y += $linespacing[$size] / 2;
 
        $cr->select_font_face($face, $slant, $weight);
        $cr->set_font_size($fontsize[$size]);
        my $textents = $cr->text_extents($text);
        my $fextents = $cr->font_extents();
        $$y += $fextents->{height};
        $cr->move_to(($sticker[0] - $textents->{width}) / 2, $$y);
        $cr->show_text($text);
 
        $$y += $linespacing[$size] / 2;
}
 
sub nalepka {
        my ($cr, $host, $mac, $inv, $since) = @_;
 
        $cr->rectangle(0, 0, @sticker);
        $cr->stroke;
 
        my $invs = $since ? "$inv      $since" : $inv;
 
 
        my $ypos = $topmargin - $linespacing[0] / 2;
        nalepka_text($cr, \$ypos, $fontface, 'normal', 'bold', 0, $host);
        nalepka_text($cr, \$ypos, $ffontface, 'normal', 'normal', 1, $mac);
        nalepka_text($cr, \$ypos, $fontface, 'normal', 'normal', 1, $invs);
        nalepka_text($cr, \$ypos, $fontface, 'italic', 'normal', 2, $contact);
}
 
 
my @table;
while (<>) {
 chomp;
 my @col = split(/\t/);
 push @table, \@col;
}
 
my ($x, $y) = (0, 0);
 
for my $c (@table) {
        nalepka(nalepka_cr($surface, [$x, $y]), @$c);
 
        $y++;
        if ($y >= $grid[1]) {
                $y = 0; $x++;
                if ($x >= $grid[0]) {
                        my $cr = Cairo::Context->create($surface);
                        $cr->show_page;
                        ($x, $y) = (0, 0);
                }
        }
}
Categories: software Tags: , ,