Das Nerdlabor

erste Tests DVB-T per UDP ins Netzwerk zu streamen (IP-TV)

1
gst-launch dvbsrc modulation="QAM 64" trans-mode=8k bandwidth=8 frequency=498000000 code-rate-lp=AUTO code-rate-hp=2/3 guard=4  hierarchy=0 ! mpegtsdemux name=demux ! queue max-size-buffers=0 max-size-time=0 ! mpeg2dec ! mpeg2enc ! mpegtsmux ! udpsink

Hier gibt es die Dokumentation für das Modul von Gstreamer: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-plugins/html/gst-plugins-bad-plugins-dvbsrc.html

Mit Ruby Primzahlen erzeugen

Hier ein kleines Beispiel, wie man mit Ruby Primzahlen erzeugen kann.

1
2
3
4
5
6
7
require 'prime'

p = Prime.new
(1..100).each do |n|
  q = p.next()
  puts "#{n}: #{q}"
end

MySQL Dump speichern und emailen mit Shellscript

Hier ist ein Quick&Dirty Shellskript um von einer oder mehreren MySQL-Datenbanken ein Backup zu erstellen, es zu komprimieren und per Mail zu verschicken. Kann z.B. einfach von einem Cron-Job jede Nacht ausgeführt werden. Eventuell müssen einige Programme (z.B. “mutt”) installiert werden.

1
2
3
4
5
6
7
8
9
logger "Database Backup Script: Dumping databases..."
mysqldump -B meine_wichtige_db_name anderer_db_name -u backupboy --password='backuppassword' > database_backup.sql
logger "Database Backup Script: Compressing the dump..."
tar -cjf database_backups/`date '+%Y-%m-%d'`_database_backup.tar.bz2 database_backup.sql
logger "Database Backup Script: Mailing the archive..."
mutt -s "Database Backup `date '+%Y-%m-%d'`" -a database_backups/`date '+%Y-%m-%d'`_database_backup.tar.bz2 admin@adminemail.de < /dev/null
rm database_backup.sql
logger "Database Backup Script: finished!"
exit 0

Wordpress url-rewrite mit lighttpd 1.5

Seit dem Update auf lighttpd 1.5 gab es Problem mit den alten rewrite rules. [1]

Hier sind welche für lighttpd 1.5.

rewrite rules for wordpress link
1
2
3
4
5
6
7
url.rewrite-once = (
"^/(wp-.+).*/?" => "$0",
"^/(sitemap.xml)" => "$0",
"^/(xmlrpc.php)" => "$0",
"^/keyword/([A-Za-z_0-9\-]+)/?$" => "/index.php?keyword=$1",
"^/.*?(\?.*)?$" => "/index.php$1"
)

Pdf generieren mit rails 3, dragonfly und wicked_pdf

Hier möchte ich die wichtigsten Schritte festhalten, um mit dem sehr tollen wicked_pdf plugin PDF Dateien zu erstellen. Dabei soll vor allem die Integrierung von Bilddateien beschrieben werden, die ich mit dem on-the-fly processing/encoding framework dragonfly erzeuge.

Plugin installieren

1
2
cd /path/to/rails_app
rails plugin install git://github.com/mileszs/wicked_pdf.git

Statische Version von wkhtmltopdf herunterladen und in neu angelegten Rails Ordner “bin” legen

1
2
3
cd /path/to/rails_app
mkdir bin
# passende statische Version für wkhtmltopdf in diesem Ordner abspeichern

Neuen Initializer in der config für wicked_pdf erstellen mit folgendem Inhalt:

1
2
3
4
5
6
#Datei /path/to/rails_app/config/initializers/wicked_pdf.rb
WickedPdf.config = {
  #:wkhtmltopdf => '/usr/local/bin/wkhtmltopdf',
  #:layout => "pdf.html"
  :exe_path => Rails.root.join('bin', 'wkhtmltopdf-i386').to_s,
}

Den exe_path müsst ihr auf den Namen eurer geladenen wkhtmltopdf-Datei anpassen. Bei mir ist es “wkhtmltopdf-i386”.

In eurem Controller gibt ihr dann an, welche Action auf PDF antworten soll. Die möglichen Optionen findet ihr hier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyController < ApplicationController
def show
#...     
respond_to do |format|
      format.html # show.html.erb 
      format.xml  { render :xml => @my }
      format.pdf do
        render :pdf => "my",
        :layout => "pdf.html",
        :disposition => "inline",
        :show_as_html => params[:debug].present?
      end
    end
 end
end

View show.pdf.erb anlegen

1
2
#view
<h1>Hallo show von MyController</h1>

In diesem View könnt ihr jetzt ganz normales HTML schreiben, das mit dem entsprechenden Styling für die PDF formatiert wird.

GANZ wichtig:

  • Alle Resourcen, auf die innerhalb des Views verwiesen wird, müssen eine absolute url aufweisen. Dafür könnt ihr die von wicked_pdf zur Verfügung gestellten Helper verwenden. Sie setzen ein “file://” und den Hauptpfad der Railsapp vor jede Url
  • Bei generierten Dateien (generiertes Javascript, Css oder Bilder ) könnnen diese Helper natürlich nicht verwendet werden
  • Hier muss im View selbstständig die eine absolute Url erzeugt werden: Wie dies geht, erfahrt ihr jetzt

Absolute URL’s erzeugen

Es gibt zwei Möglichkeiten, die Urls der verwendeten AssetHelper von Rails absolut zu gestalten:

1

In eurer Enviromentkonfiguration (development.rb, production.rb, test.rb) könnt ihr asset hosts festlegen

1
ActionController::Base.asset_host = "assets.example.com"

Dies kann aber bei größeren Projekten leicht zu Problemen führen, wenn man mehrere asset hosts verwendet (ist aber mit entsprechendem Aufwand möglich).

2

Ich lasse mir im entsprechenden View alle Angaben zum Request ausgeben und erzeuge daraus die absoluten Url’s. Dies funktioniert vor allem in Verbindung mit Dragonfly perfekt:

1
2
3
4
#Ermittlung des request, ergibt z.B. http://localhost:3000 bei einer Standard-Rails-Anwendung
<% prefix=request.protocol+request.env['HTTP_HOST'] %> # => http://localhost:3000
# project mit Draognfly macro "cover_image"
<%= image_tag prefix+project.cover_image.url  %>

Alternativ kann auch eine Option von Dragonfly genutzt werden, bei dem der Host festgelegt werden kann:

1
2
<% prefix=request.protocol+request.env['HTTP_HOST'] %>
<%= image_tag project.cover_image.url(:host => prefix) %>

Wenn ihr in eurer Testumgebung aber immer noch keine generierten Bilder in der PDF vorfindet oder die PDF Generierung von wkhtmltopdf endlos weiterläuft, müsst ihr in eurer “development.rb” Datei noch folgendes setzen.

1
config.consider_all_requests_local = false

Ich hoffe, ich konnte euch weiterhelfen

Bis zum nächsten Mal

Auf lighttpd trunk updaten

Lighttpd Trunk besorgen [1] und kompilieren.

1
2
3
4
5
6
7
apt-get install subversion pkg-config libtool automake libglib2.0-dev
svn checkout svn://svn.lighttpd.net/lighttpd/trunk/
cd trunk
./autogen.sh
./configure --prefix=/usr
make
make install

Statt ‘make install’ kann man auch ein ‘checkinstall’ versuchen.

Für PHP mit FCGI spawn-fcgi besorgen und kompilieren. [2]

1
2
3
4
5
6
svn co svn://svn.lighttpd.net/spawn-fcgi/trunk spawn-fcgi
cd spawn-fcgi
./autogen.sh
./configure --prefix=/usr
make
make install

Statt ‘make install’ kann man auch ein ‘checkinstall’ versuchen.

spawn-fcgi starten. [3]

1
/usr/bin/spawn-fcgi -s /tmp/php-fastcgi.sock -f /usr/bin/php-cgi -u www-data -g www-data -C 5 -P /var/run/spawn-fcgi.pid

lighttpd.conf anpassen

1
2
3
4
5
6
7
8
9
10
  $PHYSICAL["existing-path"] =~ "\.php$" {
    proxy-core.balancer = "round-robin"
    proxy-core.protocol = "fastcgi"
    proxy-core.allow-x-sendfile = "enable"
    proxy-core.backends = ( "unix:/tmp/php-fastcgi.sock" )
    proxy-core.max-pool-size = 16
    proxy-core.rewrite-request = (
      "_pathinfo" => ( "\.php(/.*)" => "$1" )
    )
  }

lighttpd neustarten

1
/etc/init.d/lighttpd restart

Fertig.

Umgang mit Images in RefineryCMS Nachtrag

RefineryCMS in der Rails 3 Version lieferte einige Änderungen betreffend des Umgangs mit Bildern und Dateien. Es wurde nun auf die Verwendung von Dragonfly gesetzt, die als Rack Middleware in der Railsanwendungen betrieben wird.

Folgend eine kleine Gedankenstütze für die Verwendung in den Active Record Models, um Verbindungen mit den neuen Image und Resource Plugins zu erreichen:

Refinery Engine benutzt eine Bilddatei: z.B: eine Galerie hat ein Titelbild

Model:

1
2
3
4
5
class Gallery < ActiveRecord::Base
 belongs_to :image
 #Galerie-Migration muss eine Spalte image_id (Rubykonvention) besitzen oder kann mit :foreign_key => :eigener_name angepasst werden
 #belongs_to image, :foreign_key => :title_image
end

View:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 <%= form_for([:admin, @gallery]) do |f| %>
 ....................
 #andere Modelattribute z.B. Titel
 <div class='field'>
    <%= f.label :image_id -%>
   <%= render :partial => "/shared/admin/image_picker", :locals => {
      :f => f,
      :field => :image_id,
      :image => @gallery.image,
      :toggle_image_display => false
    } %>
   #image_picker speichert die id des ausgewählten Bildes im Feld image_id
 </div>
<% end %>

Refinery Engine benutzt mehrere Bilddateien: z.B: ein Projekt hat ein Titelbild und ein Statusbild

Model:

1
2
3
4
5
class Project < ActiveRecord::Base
 belongs_to :title_image, :class_name => "Image"
 belongs_to :status_image, :class_name => "Image"
 #Projekt-Migration muss die Spalten title_image_id und status_image_id (Rubykonvention) besitzen oder kann mit :foreign_key => :eigener_name angepasst werden siehe Beispiel zuvor
end

View:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 <%= form_for([:admin, @project]) do |f| %>
 ........... 
 #andere Modelattribute z.B. Titel
 <div class='field'>
    <%= f.label :title_image_id -%>
   <%= render :partial => "/shared/admin/image_picker", :locals => {
      :f => f,
      :field => :title_image_id,
      :image => @project.title_image,
      :toggle_image_display => false
    } %>
   # image_picker speichert die id des ausgewählten Titelbildes im Feld title_image_id
 </div>

  <div class='field'>
    <%= f.label :status_image_id -%>
   <%= render :partial => "/shared/admin/image_picker", :locals => {
      :f => f,
      :field => :status_image_id,
      :image => @project.status_image,
      :toggle_image_display => false
    } %>
   # image_picker speichert die id des ausgewählten Statusbildes im Feld status_image_id
 </div>
<% end %>

Will man eine Galerie mit vielen Bildern abbilden, muss man eine has_many Relation erzeugen

Model:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#gallery.rb
class Gallery < ActiveRecord::Base
  #Verknüpfungstabelle zur Join-Tabelle
  has_many :galleryitems, :dependent => :destroy, :order => "galleryitems.position ASC"
  #Verknüpfungstabelle zur Image Engine von RefineryCMS
  has_many :images :through => :galleryitems
end

#galleryitem.rb
class Galleryitem < ActiveRecord::Base
  belongs_to :image
  belongs_to :gallery
  #Galleryitem-Migration muss die Spalten image_id und gallery_id (Rubykonvention) besitzen oder kann mit :foreign_key => :eigener_name angepasst werden 
end

Generell finde ich die gesamte Logik, die Bilder- und Datei-Uploads in RefineryCMS in einer Datenbank abzuspeichern nicht sehr komfortabel. Es führt zu Problemen bei Änderung von Dateinamen und lässt das Hochladen von Bildern zu einer sehr langwierigen Angelegenheit werden (Refinery 0.9.9 wird bereits HTML5 Multiupload ermöglichen). Ich muss noch einige Recherchen beenden (Rails Metal, Rack und vor allem Dragonfly) und vielleicht kann ich bald ein neues Filebrowser-Plugin für RefineryCMS vorstellen, bei dem ich mich konzeptionell an den Filebrowser von Typo3 orientiert habe.

Ich will nicht zu viel versprechen, aber demnächst mehr von mir

Gruß skeller1

Rails 3 lib Ordner bei jeder Änderung des Quellcodes neu laden

Bei Code-Änderungen im Rails lib Ordner muss zwingenderweise immer der Server neugestartet werden. Dies ist bei der aktiven Entwicklung natürlich sehr störend. Mit folgender initializer-Datei kannst du dieses Verhalten unterdrücken und es werden bei jedem Request die Dateien im lib-Ordner neu eingelesen. Lege dafür eine neue Initializer-Datei unter config/initalizers an. Der Dateinamen kann beliebig gewählt werden.

1
2
3
4
5
6
7
8
9
if Rails.env == "development"
  lib_reloader = ActiveSupport::FileUpdateChecker.new(Dir["lib/**/*"], true) do
    Rails.application.reload_routes!
  end

  ActionDispatch::Callbacks.to_prepare do
    lib_reloader.execute_if_updated
  end
end

Das sieht zwar jetzt alles gut aus, doch wir müssen in der config/application.rb noch das automatische Laden der Libs aktivieren.

1
 config.autoload_paths += %W( #{config.root}/lib )

Ein Dank geht an den User pbhogan, der auf StackOverflow die Lösung veröffentlicht hat (Link Original Beitrag).

Anmerkung:

Diese Lösung funktioniert leider nicht im lib Ordner von Rails Engines. Dort müssen sich die Entwickler noch etwas einfallen lassen.

Viel Spaß

Ein mehrspaltiges Ergebnis aus einer Spalte generieren (MySQL)

Das Problem:

Eine Datenbank, in der die Daten alle 5 Minuten mit Datum/Zeit gespeichert werden. Die Daten sollen in einem SQL-Ergebnis so dargestellt werden, dass von allen bis jetzt vorhandenen Jahren eine Spalte erzeugt wird um (aufsummierte) Monatswerte vergleichen zu können.

Die Lösung:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SELECT * FROM
(
  SELECT
    Extract(month from `date`) as monat,
    max(`E-Total`) - min(`E-Total`) as diff2009
  FROM
    archiv
  WHERE
    Extract(year from `date`) = 2009
  GROUP BY monat
  ORDER BY monat
) as t2009
NATURAL LEFT JOIN
(
  SELECT
    Extract(month from `date`) as monat,
    max(`E-Total`) - min(`E-Total`) as diff2010
  FROM
    archiv
  WHERE
    Extract(year from `date`) = 2010
  GROUP BY monat
  ORDER BY monat
) as t2010
NATURAL LEFT JOIN
(
  SELECT
    Extract(month from `date`) as monat,
    max(`E-Total`) - min(`E-Total`) as diff2011
  FROM
    archiv
  WHERE
    Extract(year from `date`) = 2011
  GROUP BY monat
  ORDER BY monat
) as t2011

Das Ergebnis:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
+-------+----------+----------+----------+
| monat | diff2009 | diff2010 | diff2011 |
+-------+----------+----------+----------+
|     1 |   180.00 |    23.66 |     2.27 |
|     2 |   136.00 |   146.99 |     NULL |
|     3 |   279.00 |   355.02 |     NULL |
|     4 |   475.00 |   476.27 |     NULL |
|     5 |   477.00 |   309.44 |     NULL |
|     6 |   389.48 |   522.26 |     NULL |
|     7 |   478.42 |   519.05 |     NULL |
|     8 |   510.60 |   365.10 |     NULL |
|     9 |   342.67 |   340.95 |     NULL |
|    10 |   203.37 |   313.64 |     NULL |
|    11 |   130.66 |    73.19 |     NULL |
|    12 |    94.42 |     6.50 |     NULL |
+-------+----------+----------+----------+

Instiki mit Gems benutzen anstatt mit den Vendor-Plugins

Ich wollte gerne alle Gems, die ich habe, zentral mit Rubygems verwalten. Deswegen hier eine kleine Anleitung wie man Instiki dazu bekommt, diese Gems zu benutzen.

1
cd /path/to/instiki/vendor/
1
rm -r rails
1
cd plugins/

Es können nur die Plugins gelöscht werden, die es auch als Gems gibt.

1
rm -r abstract_1.0.0/ diff/ maruku/ rails_xss/ syntax/ xhtmldiff/
1
cd ../../

Jetzt noch die Gemfile mit folgenden Zeilen ergänzen. (Gilt für Instiki 0.19.1)

1
2
3
4
5
6
7
gem "rails", "2.3.10"
gem "abstract", "1.0.0"
gem "diff-lcs", "1.1.2"
gem "maruku", "0.6.0"
gem "rails_xss", "0.1.3"
gem "syntax", "1.0.0"
gem "xhtmldiff", "1.0.0"

Speichern und ein

1
bundle

Fertig.