CapturePlugin - Kaffeine

Aus TV-Browser Wiki
Wechseln zu: Navigation⧼comma-separator⧽Suche

Falls man den DVB-Empfang in Kaffeine eingerichtet hat, kann man mittels dieser Anleitung per CapturePlugin aufnehmen.

Zu Leerzeichen im Sendernamen / Titel gibt es folgende Diskussion: Diskussion

kaffeine-Version <= 0.8.x

Installation

  1. DCOP-Bindings für Python installieren (Paket python-dcop bei Debian/Ubuntu).
    Ab Ubuntu 9.04, Jaunty Jackalope, aufwärts ist das Paket python-dcop nur noch über launchpad.net-Quellen verfügbar. Falls eine Installation von dort, bzw. eine Änderung der Paketquellen, nicht erwünscht ist, sollte man das alternative Shell-Script benutzen. Das verwendete Programm dcop befindet sich im Paket kdelibs4c2a.
    Installation des Paketes python-dcop. Unter Ubuntu/Gnome: Anwendungen --> Zubehör --> Terminal.
    Eingabe:
    sudo apt-get install python-dcop
    Installation des Paketes kdelibs4c2a:
    sudo apt-get install kdelibs4c2a
  2. Das unten angegebene Script mit dem Namen kaffeine-tvbrowser-wrapper erstellen und abspeichern.
  3. Script lesbar und ausführbar machen (chmod a+rx kaffeine-tvbrowser-wrapper)
  4. Das Script in den CapturePlugin-Einstellungen als "Applikation" angeben.
    In der deutschen Version von TV-Browser findet man dies unter: Plugins --> Aufnahmesteuerung, hier Tab. Geräte.
  5. Als Parameter folgendes für »Aufnahme« eintragen: {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}"
    Die Anführungszeichen beim Kanalnamen und Titel sorgen dafür, dass diese Parameter auch korrekt mit Leerzeichen an die Scripte übergeben werden. Diese Anführungszeichen sollten für das Shellscript für Kaffeine >= 1.2.1 weggelassen werden!
  6. Als Parameter bei »Löschen« irgend etwas eintragen. Z.Bsp. ein einzelnes Wort: remove

Script kaffeine-tvbrowser-wrapper

#!/usr/bin/env python
import sys
import math
import pcop
import pydcop

if sys.argv.count < 9:
        print 'zu wenig Parameter'
        exit

def dd(num):
        if int(num) < 10:
                return "0" + str(num)
        else:
                return str(num)

year    = dd(sys.argv[1])
month   = dd(sys.argv[2])
day     = dd(sys.argv[3])
hour    = dd(sys.argv[4])
minute  = dd(sys.argv[5])

length  = int(sys.argv[6])

title   = sys.argv[8]
channel = sys.argv[7]

name     = year + "-" + month + "-" + day + "_" + hour + "-" + minute + "_" + title
datetime = year + "-" + month + "-" + day + "T" + hour + ":" + minute + ":00"
duration = dd(int(math.floor(length // 60))) + ":" + dd(length % 60) + ":00"

pydcop.anyAppCalled("kaffeine").KaffeineIface.dvbNewTimer(name, channel, datetime, duration)


Kaffeine >=1.2.1

Alternatives Shell-Skript kaffeine-tvbrowser-wrapper

Leerzeichen im Sendernamen und Titel werden korrekt zu kaffeine übertragen.

#!/bin/bash
#
# Dieses Script überträgt Aufnahmedaten vom
# TV-Browser zu Kaffeine
# Changes by Hartmut Krummrei April/2011

# Konfiguration
kaffeine
lArgumente=8

# Wenn zu wenig Parameter angegeben werden abbrechen
if (( $# < $lArgumente )) ; then
        echo "Nicht genügend Parameter übergeben."
   exit 3
fi

# Wenn genau 8 Parameter übergeben werden ist der 9. der Name
if (( $# == $lArgumente )) ; then
   strJahr=$1
   strMonat=$2
   strTag=$3
   strStunde=$4
   strMinute=$5
   strLaenge=$6
   strKanal=$7
   strTitle=$8
fi

# Wenn mehr als 8 Parameter, gehören die Überschüssigen zum Namen
if (( $# > $lArgumente )) ; then
   strJahr=$1
   shift
   strMonat=$1
   shift
   strTag=$1
   shift
   strStunde=$1
   shift
   strMinute=$1
   shift
   strLaenge=$1
   shift
   strKanal=$1
   shift
   while [ ! -z "$1" ]
   do
      strTitle=$strTitle"_"$1
      shift
   done
fi

# Monatszahl nur einstellig?

if (( ${#strMonat} < 2 )) ; then
   strMonat="0"$strMonat
fi

# Tagzahl nur einstellig?

if (( ${#strTag} < 2 )) ; then
   strTag="0"$strTag
fi

# StartStunde nur einstellig?

if (( ${#strStunde} < 2 )) ; then
   strStunde="0"$strStunde
fi

# Startminute nur einstellig?

if (( ${#strMinute} < 2 )) ; then
   strMinute="0"$strMinute
fi

# Teile für Befehl bauen
strName=$strJahr"-"$strMonat"-"$strTag"_"$strStunde"-"$strMinute"_"$strTitle
strZeitpunkt=$strJahr"-"$strMonat"-"$strTag"T"$strStunde":"$strMinute":00"
strDauerStunden=$(($strLaenge/60))
if (( ${#strDauerStunden} < 2 )) ; then
   strDauerStunden="0"$strDauerStunden
fi
strDauerMinuten=$(($strLaenge%60))
if (( ${#strDauerMinuten} < 2 )) ; then
   strDauerMinuten="0"$strDauerMinuten
fi
strDauer=$strDauerStunden":"$strDauerMinuten":00"

# Aufruf des Kaffeine-Interface

# alt für dcop und Kaffeine 0.8.x
#dcop kaffeine KaffeineIface dvbNewTimer "$strName" "$strKanal" "$strZeitpunkt" "$strDauer"

# neu für qdbus und Kaffeine >= 1.2.1
qdbus org.kde.kaffeine /Television ScheduleProgram "$strName" "$strKanal" "$strZeitpunkt" "$strDauer" 0
# die Null am Ende der vorhergehenden Zeile steht für "einmalig"

# Rückgabe an den TV-Browser
echo "Name:"$strName";Kanal:"$strKanal";Zeit:"$strZeitpunkt";Dauer:"$strDauer


kaffeine-Version >= 1.x

Vorbemerkungen

Ab Version 1 stehen in die Kanäle und Aufnahmezeiten in der sqlite-Datenbank $HOME/.kde/share/apps/kaffeine/sqlite.db. Diese Datenbank lässt sich durch Programme direkt bearbeiten, dadurch ist jetzt auch ein Löschen von Aufnahmezeiten möglich.
Allerdings muss kaffeine nach einer Änderung in dieser Datenbank neu gestartet werden, damit Änderungen an der Datenbank in kaffeine aktualisiert werden!
Dies betrifft das Eintragen und das Löschen von Sendungen vom TV-Browser aus.
Dass heißt, es ist immer die folgende Reihenfolge einzuhalten:

  1. Aufnahmen im TV-Browser eintragen oder löschen.
  2. kaffeine neu starten.

Anmerkung November 2016:

In der Annahme ich brauche eine Senderliste wie sie w_scan ermittelt, habe ich eine solche bereitgelegt.

mit cut -d"(" -f1 sendelistedvbc161122.txt > nursender.txt habe ich inklusive Klammer "(" bis Zeilenende verworfen und nur den Sendernamen behalten.

mit sed -e '1,63s/^/+|/' nursender.txt > nursenderohnehdmitplus.txt habe ich das für untenstehende Datei beschrieben einfügeformat erzeugt. Also vor dem Sendernamen "+|" eingefügt.

Leider wurden über das Script die Programmnamen nicht in die entsprechende Tabelle im CapturePlugin eingespielt oder ich habe es nicht gekonnt.

Also habe ich sie manuell eingetippt. Namen mit Leerzeichen müssen im TV-Browser in "" gesetzt werden "Pro7 MAXX"

Installation

Das Interface für kaffeine-Version >= 1.x wurde in Ruby mit der Sqlite3-Schnittstelle von Ruby realisiert.

Die Software (ruby & ruby-sqlite-Schnittstelle) ist entsprechend auf Ihrem Betriebssystem zu installieren.

  1. Das unten angegebene Script mit dem Namen kaffeine-tvbrowser-wrapper.rb erstellen und abspeichern.
  2. Script lesbar und ausführbar machen (chmod a+rx kaffeine-tvbrowser-wrapper.rb)
  3. Das Script in den CapturePlugin-Einstellungen als "Applikation" angeben.
    In der deutschen Version von TV-Browser findet man dies unter: Plugins --> Aufnahmesteuerung, hier Tab. Geräte.
  4. Als Parameter folgendes für »Aufnahme« eintragen: {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}"
    Die Anführungszeichen beim Kanalnamen und Titel sorgen dafür, dass diese Parameter auch korrekt mit Leerzeichen an die Scripte übergeben werden.
  5. Als Parameter bei »Löschen« folgendes eintragen: remove {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}"

Ruby-Script kaffeine-tvbrowser-wrapper.rb

#!/usr/bin/ruby

require 'rubygems'
require 'sqlite3'

# Version, die unter Ubuntu >= 9.10 und S.U.S.E. 11.3, KDE4 laufen sollte.
db_path = ENV['HOME'] + '/.kde/share/apps/kaffeine/sqlite.db'
db_path = ENV['HOME'] + '/.kde4/share/apps/kaffeine/sqlite.db' \
  if File.readable?(ENV['HOME'] + '/.kde4/share/apps/kaffeine/sqlite.db') \
 and not File.readable?(db_path)

unless File.readable?(db_path) then
  puts "Kaffeine-DB-Datei ist nicht lesbar: '#{db_path}'"
  exit 1
end

# Wenn zu wenig Parameter, < 8, angegeben werden, dann auf Wiedersehen.
if ARGV.length < 8 then
  puts "Zu wenig Parameter! Bitte TV-Browser-Einstellungen ändern!"
  exit 1
elsif ARGV.length == 9 and ARGV[0] == 'remove' then
  # Lies die Parameter in Variablen.
  operation, sJahr, sMonat, sTag, sStunde, sMinute, sLaenge, sKanal, sTitel = ARGV
else
  # Vorgabeoperation ist die Aufnahme.
  operation = 'record'
  # Lies die Parameter in Variablen.
  sJahr, sMonat, sTag, sStunde, sMinute, sLaenge, sKanal, sTitel = ARGV
end

if md = sKanal.match(/^"(.*)"$/) then
  sKanal = md[1]
end
if md = sTitel.match(/^"(.*)"$/) then
  sTitel = md[1]
end
nDauerStunden = sLaenge.to_i / 60
nDauerMinuten = sLaenge.to_i % 60

sBegin = "#{"%04d" % sJahr}-#{"%02d" % sMonat}-#{"%02d" % sTag}T#{"%02d" % sStunde}:#{"%02d" % sMinute}:00"
sDuration = "#{"%02d" % nDauerStunden}:#{"%02d" % nDauerMinuten}:00"

begin
  db = SQLite3::Database.open(db_path)
  id = nil
  # new_id = 0 wird zwar in die Datenbank eingetragen, aber von Kaffeine nicht in der
  # Aufnahme-Liste aufgeführt hierzu muss die id anscheinend > 0 sein. 
  new_id = 1
  db.execute("select Id from RecordingSchedule where Name = ? and Channel = ? and Begin = ? and Duration = ? and Repeat = ?",
    sTitel, sKanal, sBegin, sDuration, 0) do |row|
    id = row[0].to_i unless row[0].nil?
  end
  if id.nil? then
    if operation == 'record' then
      db.execute("select max(Id) from RecordingSchedule") do |row|
        new_id = row[0].to_i + 1 unless row[0].nil?
      end
      nKanal = 0
      db.execute("select count(*) from Channels where Name = ?", sKanal) do |row|
        nKanal = row[0].to_i unless row[0].nil?
      end
      if nKanal == 0 then
        puts "Sender '#{sKanal}' ist in kaffeine nicht vorhanden!"
        db.close
        exit 1
      end
      begin
        # Id, Name, Channel, Begin, Duration, Repeat
        db.execute('insert into RecordingSchedule values (?, ?, ?, ?, ?, ?)',
          new_id, sTitel, sKanal, sBegin, sDuration, 0)
        rc = "OK"
      rescue
        rc = "Fehler beim INSERT: #{$!}"
      end
      # Rückgabe an den TV-Browser.
      puts "Die Sendung wurde mit folgenden Daten bei kaffeine eingetragen:"
      puts "Titel: #{sTitel}"
      puts "Kanal: #{sKanal}"
      puts "Beginn: #{sBegin}"
      puts "Dauer: #{sDuration}"
      puts "Rückgabewert: #{rc}"
      if rc == "OK" then
        puts "Falls kaffeine gerade läuft, müssen Sie es beenden und neu starten um die neuen Aufnahmezeiten zu aktivieren!"
      end
    elsif operation == 'remove' then
      puts "Sendezeit ist in kaffeine nicht vorhanden!"
      db.close
      exit 1
    end
  else
    if operation == 'remove' then
      db.execute("delete from RecordingSchedule where Name = ? and Channel = ? and Begin = ? and Duration = ? and Repeat = ?",
        sTitel, sKanal, sBegin, sDuration, 0)
      puts "Sendung wurde gelöscht."
      puts "Falls kaffeine gerade läuft, müssen Sie es beenden und neu starten um die geänderten Aufnahmezeiten zu aktualisieren!"
    else
      puts "Aufnahmezeit bereits vorhanden!"
      db.close
      exit 1
    end
  end
  db.close
rescue
  db.close unless db.closed?
  puts "Fehler mit der Kaffeine-DB!"
  # raise
  exit 1
end

exit 0

In Abwandlung des oben stehenden Listings (vielen Dank an dieser Stelle!) gibt es auch eine Version, die auf die Verbindung mit qdbus org.kde.kaffeine /Television zurückgreift. Der Vorteil hierbei ist, dass zum Aktualisieren der Daten kaffeine nicht beendet und dann wieder gestartet werden muss. Dieses ist insbesondere von Vorteil, wenn eine Aufnahme läuft. Der Nachteil ist, dass kaffeine laufen muss, damit Daten eingetragen werden können. Daher wird am Anfang des Skripts kaffeine gestartet, falls es nicht schon läuft. Die Installation ist wie oben, nur

  1. muss das Programm pidof und sqlite3 (z.B. in den Paketquellen von Ubuntu vorhanden) installiert sein;
  2. ist bei Aufnahme abweichend folgendes einzutragen: record {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}"

Hinweis: Zwischen Eintragen einer Aufnahme und dem Löschen derselben sollte man ein paar Sekunden warten, da Kaffeine etwas Zeit braucht, um die Datenbank zu aktualisieren. Wenn man nicht lange genug wartet, dann wird der Eintrag nicht gefunden.

Ruby-Script kaffeine-tvbrowser-qdebus.rb

#!/usr/bin/ruby
#

require 'rubygems'
require 'sqlite3'
require "time" 

# Konfiguration
lArgumente=9

# Wenn kaffeine nicht läuft muss es gestartet werden
# gibt es den Prozess? Dann ist ret = true
ret = system("pidof kaffeine")

if ret then
	puts "kaffeine laeuft"
else
	puts "kaffeine laeuft nicht"
	ret = system("kaffeine")

	# Falls es etwas dauert, bis kaffeine gestartet ist
	# bis zu 10 Warteschleifen
	$i = 0
	$num = 10
	begin
		ret = system("pidof kaffeine")
		puts "id = '#{ret}'"
		puts("Inside the loop i = #$i" )
		$i +=1
	end until ($i>$num or ret)
end

# Version, die unter Ubuntu >= 9.10 und S.U.S.E. 11.3, KDE4 laufen sollte.
db_path = ENV['HOME'] + '/.kde/share/apps/kaffeine/sqlite.db'
db_path = ENV['HOME'] + '/.kde4/share/apps/kaffeine/sqlite.db' \
  if File.readable?(ENV['HOME'] + '/.kde4/share/apps/kaffeine/sqlite.db') \
 and not File.readable?(db_path)

unless File.readable?(db_path) then
  puts "Kaffeine-DB-Datei ist nicht lesbar: '#{db_path}'"
  exit 1
end

# Wenn zu wenig Parameter, < 9, angegeben werden, dann auf Wiedersehen.
if ARGV.length < lArgumente then
  puts "Zu wenig Parameter. Bitte TV-Browser-Einstellungen aendern."
  exit 2
#elsif ARGV.length == lArgumente and ARGV[0] == 'remove' then
elsif ARGV[0] == "remove" then
  # Lies die Parameter in Variablen.
  operation, sJahr, sMonat, sTag, sStunde, sMinute, sLaenge, sKanal, sTitel = ARGV
elsif ARGV.length == lArgumente and ARGV[0] == "record" then
  # Vorgabeoperation ist die Aufnahme.
  # Lies die Parameter in Variablen.
  operation, sJahr, sMonat, sTag, sStunde, sMinute, sLaenge, sKanal, sTitel = ARGV
else
  puts "weder record noch remove; Zahl der Argumente '#{ARGV.length}', Operation '#{ARGV[0]}'"
  exit 3
end

if md = sKanal.match(/^"(.*)"$/) then
  sKanal = md[1]
end
if md = sTitel.match(/^"(.*)"$/) then
  sTitel = md[1]
end

# Umrechnung der Aufzeichnungsdauer von Minuten (tv-browser) nach Stunden und Minuten (kaffeine)
nDauerStunden = sLaenge.to_i / 60
nDauerMinuten = sLaenge.to_i % 60

# Zeitumrechnung auf GMT
# Dies ist notwendig, weil bei der Benutzung von qdbus die Anfangszeiten eine Stunde spaeter sind, als in den Parametern uebergeben
	tBegin=Time.mktime(sJahr, sMonat, sTag, sStunde, sMinute)
	puts "EingabeZeit", tBegin 

	# Differenz zu GMT ermitteln
	zeitstr=tBegin.to_s
	iGMTdiff=zeitstr[20,5].to_i/100

	# Zeit in Datenbank errechnen
	#in Ruby muss man die Zeit in Sekunden abziehen
	#
	tBegin = tBegin-iGMTdiff*3600

# sZeit ist der StartZeitString für die Übergabe an die Datenbank mit qdbus org.kde.kaffeine
# sBegin ist der StartZeitString für die Übergabe an die Datenbank mit sqlite
sBegin = "#{"%04d" % sJahr}-#{"%02d" % sMonat}-#{"%02d" % sTag}T#{"%02d" % sStunde}:#{"%02d" % sMinute}:00ZZ"
sZeit="#{"%04d" % tBegin.year}-#{"%02d" % tBegin.month}-#{"%02d" % tBegin.day}T#{"%02d" % tBegin.hour}:#{"%02d" % tBegin.min}:00ZZ"

# Aufnahmedauer
sDuration = "#{"%02d" % nDauerStunden}:#{"%02d" % nDauerMinuten}:00"

begin
	# Datenbank oeffnen
	db = SQLite3::Database.open(db_path)

	# Initialisierung
	id = nil
	rc = false

	# Gibt es den Eintrag in der Datenbank schon?
	# Falls id nicht nil, dann wird sie beim Loeschen verwendet
	db.execute("select Id from RecordingSchedule where Name = ? and Channel = ? and Begin = ? and Duration = ? and Repeat = ?",
		sTitel, sKanal, sZeit, sDuration, 0) do |row|
		id = row[0].to_i unless row[0].nil?
	end

	if id.nil? then
		if operation == 'record' then
			db.execute("select max(Id) from RecordingSchedule") do |row|
				new_id = row[0].to_i + 1 unless row[0].nil?
			end # select max(id)
			nKanal = 0
			db.execute("select count(*) from Channels where Name = ?", sKanal) do |row|
				nKanal = row[0].to_i unless row[0].nil?
			end # select count(*)  Kanälemit eingegebenem Namen

			if nKanal == 0 then
				puts "Sender '#{sKanal}' ist in kaffeine nicht vorhanden!"
				db.close
				exit 5
			end

		begin # Beginn Verarbeitung 
			db.close
			db = SQLite3::Database.open(db_path)

			# Film eintragen, Aufruf in externer shell   Wenn erfolgreich, dann ist ret = TRUE
			ret = system(%Q<bash -c "qdbus org.kde.kaffeine /Television ScheduleProgram '#{sTitel}' '#{sKanal}' #{sZeit} #{sDuration} 0">)
		
			if ret then 
				rc = "OK"
			else
				rc = "Fehler beim Insert"
				db.close
				exit 6
			end

			rescue
			rc = "Fehler beim INSERT: #{$!}"
			puts "Fehler beim INSERT: #{$!}"
			db.close
			exit 7
			end

			# Rueckgabe an den TV-Browser.
			puts "Die Sendung wurde mit folgenden Daten bei kaffeine eingetragen:"
			puts "Titel: #{sTitel}"
			puts "Kanal: #{sKanal}"
			puts "Beginn: #{sBegin}"
			puts "Dauer: #{sDuration}"
			puts "Rueckgabewert: #{rc}"

		elsif operation == 'remove' then # id.nil = TRUE (=nicht gefunden), Sendung soll aber entfernt werden
			puts "Sendezeit ist in kaffeine nicht vorhanden!"
			db.close
			exit 8
		end

	else	# id.nil = FALSE (=Sendung gefunden)
		if operation == 'remove' then
			ret=system(%Q<bash -c "qdbus org.kde.kaffeine /Television RemoveProgram #{id}">)

			if ret then
				puts "Sendung wurde geloescht."
			else
				puts "Fehler! Sendung wurde nicht geloescht."
				db.closed
				exit 9
			end
		else  # if id.nil?  Sendung gefunden, soll noch einmal hinzugefügt werden
			puts "Aufnahmezeit bereits vorhanden!"
			db.close
			exit 10
		end
end
db.close
rescue
	db.close unless db.closed?
	puts "Fehler mit der Kaffeine-DB!"
	exit 20
end




Kaffeine >= 2.0.4

Das Script baut auf den vorherigen Sripten auf. Vielen Dank an alle Vorgänger!

(Version 2017.02)

Installation

Benötigt werden die Pakete ruby-sqlite3 und rubygems.

Das Script erstellen und mit dem Namen (tvbrowser2kaffeine.rb) abspeichern und mit (chmod a+rx tvbrowser2kaffeine.rb) ausführbar machen.

Im Tv-Browser im Menu Extras > Aufnahmesteuerung > Geräte > Gerät-hinzufügen den Standardtreiber auswählen und dem Gerät einen beliebigen Namen geben.

Das Script (tvbrowser2kaffeine.rb) hier als "Applikation" angeben.

Parameter für die Aufnahme:
record {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}" {production_year} "{episode}" {episode_number}

Parameter für das Löschen:
remove {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}" {production_year} "{episode}" {episode_number}

Anmerkung: ruby in der Version 2.4.0-1 kann leider nicht verwendet werden. Bei Archlinux kann man mit dem Befehl [sudo pacman -U /var/cache/pacman/pkg/ruby-2.3.3-1-x86_64.pkg.tar.xz] ein downgrade durchgefühen.


Konfiguration

Im Script den Path zur Kaffeine Datenbank evtl. anpassen.

Das Script enthält mehrere Optionen die auf Wunsch mit # de/aktiviert werden können:

1. Wiederholungen einer Sendung werden nicht erneut zur Aufnahmen vorgemerkt.

2. Titel die schon auf Festplatte gespeichert sind, werden nicht erneut zur Aufnahme gestellt.


Bemerkung

In diesem Script wird sowohl die qdbus als auch die sql Methode genutzt Sendungen in die sqlite.db von Kaffeine einzutragen.

Somit ist es egal ob Kaffeine gerade läuft oder nicht.


Ruby-Script: tvbrowser2kaffeine.rb


#!/usr/bin/ruby
#
# Für Kaffeine > 2.0.4
#
#
# Parameter für TV-Brauser Aufnahmesteuerung:
# record {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}" {production_year} "{episode}" {episode_number}
# remove {start_year} {start_month} {start_day} {start_hour} {start_minute} {length_minutes} "{isset(channel_name_external_quiet,channel_name)}" "{title}" {production_year} "{episode}" {episode_number}
#
# Bitte anpassen falls nötig:
# Zeile 27 Path der kaffeine_db
#
# Zeile 127ff Optionen: Wiederholungen können aufgenommen werden. / Der selbe Titel wird nur ein mal aufgenommen.
#
# Zeile 149ff Hier wird überprüft ob sich der Titel schon auf der Festplatte befindet. Falls gewünscht, bitte Pfad anpassen!

 
require 'rubygems'
require 'sqlite3'
require 'time'

# Path zur db muß evt. angepasst werden
db_path = ENV['HOME'] + '/.local/share/kaffeine/sqlite.db'

unless File.readable?(db_path) then
  puts "Kaffeine-DB-Datei ist nicht lesbar: '#{db_path}'"
  exit 1
end


# Parameter prüfen
if ARGV.length < 8 then
  puts "Zu wenig Parameter. Bitte im TV-Browser die Aufnahmesteuerung anpassen."
  exit 2

elsif ARGV[0] == "remove" then
  # Lies die Parameter in Variablen.
  operation, sJahr, sMonat, sTag, sStunde, sMinute, sLaenge, sKanal, sTitel, sProdYear, sEpisode, sEpisode_number= ARGV
 
elsif ARGV[0] == "record" then
  # Vorgabeoperation ist die Aufnahme.
  # Lies die Parameter in Variablen.
  operation, sJahr, sMonat, sTag, sStunde, sMinute, sLaenge, sKanal, sTitel, sProdYear, sEpisode, sEpisode_number= ARGV
 
else
  puts "Die Parameter in der Aufnahmesteuerung müssen angepasst werden!"
  puts ""
  puts " 1. Operation '#{ARGV[0]}'"
  puts " 2. Jahr '#{ARGV[1]}'"
  puts " 3. Monat '#{ARGV[2]}'"
  puts " 4. Tag '#{ARGV[3]}'"
  puts " 5. Stunde '#{ARGV[4]}'"
  puts " 6. Minute '#{ARGV[5]}'"
  puts " 7. Länge '#{ARGV[6]}'"
  puts " 8. Kanal '#{ARGV[7]}'"
  puts " 9. Titel '#{ARGV[8]}'"
  puts "10. ProdJahr '#{ARGV[9]}'" 
  puts "11. Episode '#{ARGV[10]}'"
  puts "12. Epi-Nr. '#{ARGV[11]}'"
  puts ""
  puts "Anzahl der Parameter '#{ARGV.length}'"
  exit 3
end

if md = sKanal.match(/^"(.*)"$/) then
  sKanal = md[1]
 
end

# Titelergänzung
if ARGV[11] and ARGV[10] and ARGV[9] then
   
    sTitel="#{sTitel} No_#{sEpisode_number} #{sEpisode} (#{sProdYear})"
   
elsif ARGV[10] and ARGV[9] then
   
    sTitel="#{sTitel} #{sEpisode} (#{sProdYear})"
   
elsif ARGV[9] then
   
    sTitel="#{sTitel} (#{sProdYear})"
   
else
   
    sTitel="#{sTitel}"
   
end

#Zeichen aus dem Titel entfernen
sTitel=sTitel.gsub(/[':\"]/, "")
sTitel=sTitel.gsub("()", "")
sTitel=sTitel.gsub("\ \ ", "\ ")

# Umrechnung der Aufzeichnungsdauer von Minuten (tv-browser) nach Stunden und Minuten (kaffeine)
nDauerStunden = sLaenge.to_i / 60
nDauerMinuten = sLaenge.to_i % 60

# Zeitumrechnung auf GMT
# Dies ist notwendig, weil bei der Benutzung von qdbus die Anfangszeiten eine Stunde spaeter sind, als in den Parametern uebergeben
    tBegin=Time.mktime(sJahr, sMonat, sTag, sStunde, sMinute)
    #puts "EingabeZeit", tBegin

    # Differenz zu GMT ermitteln
    zeitstr=tBegin.to_s
    iGMTdiff=zeitstr[20,5].to_i/100

    # Zeit in Datenbank errechnen
    #in Ruby muss man die Zeit in Sekunden abziehen
    tBegin = tBegin-iGMTdiff*3600

# sBegin ist der StartZeitString für die Übergabe an die Datenbank mit sqlite
# sZeit ist der StartZeitString für die Übergabe an die Datenbank mit qdbus org.kde.kaffeine
sBegin = "#{"%04d" % sJahr}-#{"%02d" % sMonat}-#{"%02d" % sTag}T#{"%02d" % sStunde}:#{"%02d" % sMinute}:00ZZ"
sZeit="#{"%04d" % tBegin.year}-#{"%02d" % tBegin.month}-#{"%02d" % tBegin.day}T#{"%02d" % tBegin.hour}:#{"%02d" % tBegin.min}:00ZZ"

# Aufnahmedauer
sDuration = "#{"%02d" % nDauerStunden}:#{"%02d" % nDauerMinuten}:00"

begin
    # Datenbank öffnen
    db = SQLite3::Database.open(db_path)

    # Initialisierung
    id = nil
    rc = false

    # Gibt es den Eintrag der Kaffeine Datenbank schon? (Optional: alle Parameter oder nur den Titel vergleichen)
    # db.execute("select Id from RecordingSchedule where Name = ? and Channel = ? and Begin = ? and Duration = ? and Repeat = ?", sTitel, sKanal, sZeit, sDuration, 0) do |row|
      db.execute("select Id from RecordingSchedule where Name = ?", sTitel) do |row|
        id = row[0].to_i unless row[0].nil?
end

    if id.nil? then
        if operation == 'record' then
            db.execute("select max(Id) from RecordingSchedule") do |row|
                id = row[0].to_i + 1 unless row[0].nil?
            end # select max(id)
            nKanal = 0
            db.execute("select count(*) from Channels where Name = ?", sKanal) do |row|
                nKanal = row[0].to_i unless row[0].nil?
            end # select count(*)  Kanäle mit eingegebenem Namen

            if nKanal == 0 then
                puts "Der Sender '#{sKanal}' ist in kaffeine nicht vorhanden!"
                db.close
                exit 4
            end

# Ist die Aufnahme schon auf Fettplatte?
if File.readable?("/home/erika/MEDIEN/Videos/#{sTitel}.m2t") or
            File.readable?("/home/erika/MEDIEN/Videos/#{sTitel}[remux].mpg") then
        puts ""
        puts "Keine erneute Aufnahme!"
      puts "Der Titel '#{sTitel}' befindet sich schon auf der Festplatte."
      puts ""
      exit 5
end


        begin # Beginn Verarbeitung
                   
                    kaf = system("pidof kaffeine")

                    if kaf then #kaffeine läuft
                       
                        rec=system(%Q<bash -c "qdbus org.kde.kaffeine /Television ScheduleProgram '#{sTitel}' '#{sKanal}' #{sZeit} #{sDuration} 0">)
                       
                    else
                       
            rec=db.execute "INSERT INTO RecordingSchedule(Name, Channel, Begin, Duration, Repeat, Priority, Disabled) VALUES('#{sTitel}', '#{sKanal}', '#{sZeit}', '#{sDuration}', 0, 0, 0)"
                       
                    end

            if rec then
                rc = "OK"
               
            else
                rc = "Fehler beim Insert"
                db.close
                exit 6
            end


            rescue
            rc = "Fehler beim INSERT: #{$!}"
            puts "Fehler beim INSERT: #{$!}"
            db.close
            exit 7
        end

            # Rueckgabe an den TV-Browser.
                        puts ""
            puts "Die Sendung wird aufgenommen:"
                        puts ""
                        puts "Titel: #{sTitel}"
            puts "Kanal: #{sKanal}"
            puts "Beginn: #{sBegin}"
            puts "Dauer: #{sDuration}"
            #puts "Rueckgabewert: #{rc}"

        elsif operation == 'remove' then # id.nil = TRUE (=nicht gefunden), Sendung soll aber entfernt werden
                        puts ""
            puts "Der Eintrag '#{sTitel}' ist in Kaffeine nicht vorhanden!"
            db.close
            exit 8
        end

    else    # id.nil = FALSE (=Sendung gefunden)
                   
        if operation == 'remove' then #(Entferne Eintrag aus db)
                   
                    kaf = system("pidof kaffeine")
                   
                    if kaf then
                       
                        del = system(%Q<bash -c "qdbus org.kde.kaffeine /Television RemoveProgram #{id}">)
                       
                    else
                       
                        del = db.execute("delete from RecordingSchedule where Name = ? and Channel = ? and Begin = ? and Duration = ? and Repeat = ?", sTitel, sKanal, sZeit, sDuration, 0)
                       
                    end

            if del then
                               
                                puts ""
                puts "Die Sendung '#{sTitel}' wurde gelöscht."                                                               
                       
                        else
                                puts ""
                puts "Fehler! Sendung wurde nicht gelöscht."
                db.closed
                exit 9
            end    
                               
                               
        else  # if id.nil?  Sendung gefunden, soll noch einmal hinzugefügt werden
                   
                        puts ""
                        puts "Keine erneute Aufnahme"
            puts "Die Sendung '#{sTitel}' steht bereits auf der Aufnahmeliste"
            db.close
            exit 10
        end
end
db.close
rescue
    db.close unless db.closed?
    puts "Fehler mit der Kaffeine-DB!"
    exit 20
end




Sendernamen

Es ist wichtig, die Sendernamen im TV-Browser und in Kaffeine anzugleichen. D.h. sie müssen identisch sein.
Ein Entfernen der Leerzeichen im Sendernamen ist nicht notwendig. Groß- und Kleinschreibung muss übereinstimmen.

Eine Änderung der Sendernamen kann in kaffeine oder im TV-Browser erfolgen.

Scriptgesteuertes Umsortieren und Umbenennen von Kanälen in kaffeine >= 1.x

Mit diesen Scripten werden die Kanalnamen in kaffeine an TV-Browser angepasst. D.h. sie werden in kaffeine umbenannt.



Als Neuling habe ich das ausgeführt, allerdings wurden keine Sendernamen in TV-Browser eingetragen. Manuell abgeschrieben aus kaffeine seit geht es.



Achtung: Unten angegebene Konfigurationsdatei reorder_kaffeine_channels.conf erhebt keinen Anspruch auf Vollständigkeit!

Installation

Das Interface für kaffeine-Version >= 1.x wurde in Ruby mit der Sqlite3-Schnittstelle von Ruby realisiert.

Die Software (ruby & ruby-sqlite-Schnittstelle) ist entsprechend auf Ihrem Betriebssystem zu installieren.

  1. Das unten angegebene Script mit dem Namen reorder_kaffeine_channels.rb erstellen und abspeichern.
  2. Script lesbar und ausführbar machen (chmod a+rx reorder_kaffeine_channels.rb)
  3. Die unten angegebene Konfigurationsdatei reorder_kaffeine_channels.conf im selben Verzeichnis wie das Script reorder_kaffeine_channels.rb speichern. Gegebenenfalls anpassen.
  4. Das Script ausführen: ./reorder_kaffeine_channels.rb bzw. ruby reorder_kaffeine_channels.rb

Bei jeder Ausführung des Scriptes wird eine Backup-Datei der Kanal-Datenbank angelegt. Diese hat den Namen sqlite.db~DATUM-UHRZEIT. Bei Bedarf, wenn es nicht gefällt oder etwas schief geht, bitte die Backup-Datei zurück kopieren.

Bsp.: cp sqlite.db~20101226-185433 "$HOME/.kde/share/apps/kaffeine/sqlite.db"

Unter S.U.S.E 11.3, KDE4: cp sqlite.db~20101226-185433 "$HOME/.kde4/share/apps/kaffeine/sqlite.db"

Den Namen der verwendeten Datenbank erhält man mit dem Befehl: ruby reorder_kaffeine_channels.rb --help

Ruby-Script reorder_kaffeine_channels.rb

#!/usr/bin/ruby

require 'optparse'
require 'rubygems'
require 'sqlite3'
require "ftools"  #wurde nicht gefunden und ubuntu 16.04

#require "fileutils"  # gefunden auf stackoverflow, das lief dann



g_myname = $0.to_s

g_options = Hash.new
g_optparse = OptionParser.new do |opts|
  opts.banner = "Usage: #{File.basename($0)} [-f config-file] [database-file ...]"
  g_options[:database_file] = ENV['HOME'] + '/.kde/share/apps/kaffeine/sqlite.db'
  g_options[:database_file] = ENV['HOME'] + '/.kde4/share/apps/kaffeine/sqlite.db' \
    if File.readable?(ENV['HOME'] + '/.kde4/share/apps/kaffeine/sqlite.db') \
   and not File.readable?(g_options[:database_file])
  g_options[:config_file] = g_myname.sub(/\.[^.]*$/, '') + ".conf"
  opts.on('-f config-file', String, "Uses the directives in this file.") do |cfg_file|
    g_options[:config_file] = cfg_file
  end
  opts.on_tail('-h', '--help', 'Display this screen') do
    puts opts
    puts "  config-file defaults to: #{g_options[:config_file]} [#{File.readable?(g_options[:config_file]) ? "OK" : "Not readable"}]"
    puts "database-file defaults to: #{g_options[:database_file]} [#{File.readable?(g_options[:database_file]) ? "OK" : "Not readable"}]"
    exit 0
  end
end

begin
  g_optparse.parse!(ARGV)
rescue OptionParser::ParseError
  $stderr.print "Error: #{$!}\n"
  puts g_optparse.to_s
  exit 3
end


# Define a class to hold a channel, with some extra information.
class Channel
  attr_accessor :id, :number, :name, :db_row

  def tv?
    @flags == 1
  end

  def stored?
    @stored
  end

  def name_changed?
    @b_name_set
  end

  def number_changed?
    @b_number_set
  end

  def set_stored
    @stored = true
  end

  def set_number(number)
    if @number != number then
      @number = number
      @db_row[2] = number
      @b_number_set = true
    end
  end

  def set_name(name)
    if @name != name then
      @name = name
      @db_row[1] = name
      @b_name_set = true
    end
  end

  def initialize(db_row)
    @db_row = db_row
    @id = db_row[0].to_i
    @name = db_row[1].to_s
    @number = db_row[2].to_i
    @flags = db_row[10].to_i
    @stored = false
    @b_number_set = false
    @b_name_set = false
  end
end


g_channels = Array.new
g_channels_to_remove = Array.new
g_regex_removal_expressions = Array.new
g_rename_expressions = Hash.new
g_rename_expressions_reverse = Hash.new

g_radio_channels = Array.new
g_radio_channels_to_remove = Array.new
g_radio_regex_removal_expressions = Array.new
g_radio_rename_expressions = Hash.new
g_radio_rename_expressions_reverse = Hash.new

puts "1. Read config-file ..."
if File.readable?(g_options[:config_file]) then
  puts "  Open config-file: #{g_options[:config_file]}"
  File.open(g_options[:config_file], "r") do |cfg_file|
    cfg_file.each_line do |line|
      line.chomp!
      unless line.empty? then
        case line
          when /^\+\|(.+)/
            g_channels.push($1)
          when /^-\|(.+)/
            g_channels_to_remove.push($1)
          when /^R\|(.+)/
            g_regex_removal_expressions.push($1)
          when /^r\|(.+)\|(.+)/
            g_rename_expressions[$1] = $2
            g_rename_expressions_reverse[$2] = $1
          when /^!\+\|(.+)/
            g_radio_channels.push($1)
          when /^!-\|(.+)/
            g_radio_channels_to_remove.push($1)
          when /^!R\|(.+)/
            g_radio_regex_removal_expressions.push($1)
          when /^!r\|(.+)\|(.+)/
            g_radio_rename_expressions[$1] = $2
            g_radio_rename_expressions_reverse[$2] = $1
        end
      end
    end
  end
  puts "  Number of TV-channels to store: #{g_channels.length}"
  puts "  Number of TV-channels to remove: #{g_channels_to_remove.length}"
  puts "  Number regexp removeal expressions (TV): #{g_regex_removal_expressions.length}"
  puts "  Number rename expressions (TV): #{g_rename_expressions.length}"
  puts "  Number of radio-channels to store: #{g_radio_channels.length}"
  puts "  Number of radio-channels to remove: #{g_radio_channels_to_remove.length}"
  puts "  Number regexp removeal expressions (Radio): #{g_radio_regex_removal_expressions.length}"
else
  $stderr.print "Error: Cannot read config-file: #{g_options[:config_file]}\n"
  exit 1
end

ARGV.push(g_options[:database_file]) if ARGV.empty?
ARGV.each do |db_file|
  puts "2. Read database-file ..."
  backup_file = File.basename(db_file) + "~" + Time.now.strftime('%Y%m%d-%H%M%S')
  puts "  Backup database to: #{backup_file}"
  File.copy(db_file, backup_file)
  puts "  Open database: #{db_file}"
  begin
    db = SQLite3::Database.open(db_file)
    tv_channels = 0
    other_channels = 0
    n_removed_by_name = 0
    n_removed_by_regexp = 0
    n_radio_removed_by_name = 0
    n_radio_removed_by_regexp = 0
    a_channels = Array.new
    a_channels_to_remove = Array.new
    db.execute("select Id, Name, Number, Source, Transponder, NetworkId, \
                       TransportStreamId, PmtPid, PmtSection, AudioPid, Flags \
                  from Channels") do |row|
      b_add_flag = true
      channel = Channel.new(row)
      if channel.tv? then
        tv_channels += 1
        # Handle removal of TV-channels.
        if g_channels_to_remove.index(channel.name) then
          b_add_flag = false
          n_removed_by_name += 1
        end
        if b_add_flag then
          g_regex_removal_expressions.each do |regexp|
            if channel.name =~ /#{regexp}/ then
              b_add_flag = false
              n_removed_by_regexp += 1
              break
            end
          end
        end
      else
        other_channels += 1
        # Handle removal of other (radio) channels.
        if g_radio_channels_to_remove.index(channel.name) then
          b_add_flag = false
          n_radio_removed_by_name += 1
        end
        if b_add_flag then
          g_radio_regex_removal_expressions.each do |regexp|
            if channel.name =~ /#{regexp}/ then
              b_add_flag = false
              n_radio_removed_by_regexp += 1
              break
            end
          end
        end
      end
      if b_add_flag then
        a_channels.push(channel)
      else
        # Collect channels to remove.
        a_channels_to_remove.push(channel)
      end
    end
    # Create new channel-list.
    a_new_channel_list = Array.new
    # 1. Handle all wanted TV-channels.
    g_channels.each do |wanted_channel_name|
      a_channels.each do |channel|
        if (channel.name == wanted_channel_name \
            or g_rename_expressions_reverse[channel.name] == wanted_channel_name) \
       and channel.tv? and not channel.stored? then
          a_new_channel_list.push(channel)
          channel.set_stored
        end
      end
    end
    # 2. Handle all wanted radio-channels.
    g_radio_channels.each do |wanted_channel_name|
      a_channels.each do |channel|
        if (channel.name == wanted_channel_name \
            or g_radio_rename_expressions_reverse[channel.name] == wanted_channel_name) \
       and not channel.tv? and not channel.stored? then
          a_new_channel_list.push(channel)
          channel.set_stored
        end
      end
    end
    # 3. Handle all remaining TV-channels.
    a_channels.each do |channel|
      if channel.tv? and not channel.stored? then
        a_new_channel_list.push(channel)
        channel.set_stored
      end
    end
    # 4. Handle all remaining channels (radio).
    a_channels.each do |channel|
      if not channel.stored? then
        a_new_channel_list.push(channel)
        channel.set_stored
      end
    end
    # 5. Rename and renumber all new channels.
    n_renamed_channels = 0
    n_renamed_radio_channels = 0
    n_id = 0
    a_new_channel_list.each do |channel|
      n_id += 1
      channel.set_number(n_id)
      if channel.tv? then
        g_rename_expressions.each do |s_from, s_to|
          if channel.name == s_from then
            puts "  > Rename [TV] '#{s_from}' to '#{s_to}'"
            a_new_channel_list.each do |channel2|
              if channel2.name == s_to then
                channel2.set_name(channel2.name + ' (renamed)')
              end
            end
            channel.set_name(s_to)
            n_renamed_channels += 1
            break
          end
        end
      else
        g_radio_rename_expressions.each do |s_from, s_to|
          if channel.name == s_from then
            puts "  > Rename [Radio] '#{s_from}' to '#{s_to}'"
            a_new_channel_list.each do |channel2|
              if channel2.name == s_to then
                channel2.set_name(channel2.name + ' (renamed)')
              end
            end
            channel.set_name(s_to)
            n_renamed_radio_channels += 1
            break
          end
        end
      end
    end
    puts "  Total number of TV-channels: #{tv_channels}"
    puts "  Total number of Radio-channels: #{other_channels}"
    # Write data back to database.
    puts "3. Write database file ..."
    # puts "  Remove all channels from DB ..."
    # db.execute("delete from Channels")
    puts "  Delete all unwanted channels ..."
    n_id = 0
    a_channels_to_remove.each do |channel|
      n_id += 1
      db.execute("delete from Channels where Number = ?", channel.number)
      $stdout.print "  Delete channel #{n_id}/#{a_channels_to_remove.length}\r"
      $stdout.flush
    end
    puts if a_channels_to_remove.length > 0
    puts "  Update database file ..."
    n_new_tv_channels = 0
    n_new_radio_channels = 0
    n_id = 0
    n_updates = 0
    a_new_channel_list.each do |channel|
      b_update_flag = false
      n_id += 1
      if channel.number_changed? and channel.name_changed? then
        db.execute("update Channels set Number = ?, Name = ? where Id = ?",
          channel.number, channel.name, channel.id)
        b_update_flag = true
      elsif channel.name_changed? then
        db.execute("update Channels set Name = ? where Id = ?",
          channel.name, channel.id)
        b_update_flag = true
      elsif channel.number_changed? then
        db.execute("update Channels set Number = ? where Id = ?",
          channel.number, channel.id)
        b_update_flag = true
      end
      if b_update_flag then
        n_updates += 1
        $stdout.print "  Update channel #{n_id}/#{a_new_channel_list.length}\r"
        $stdout.flush
      end
      if channel.tv? then
        n_new_tv_channels += 1
      else
        n_new_radio_channels += 1
      end
    end
    puts if n_updates > 0
    #
    puts "  Number of written channels: #{a_new_channel_list.length}"
    puts "  Number of written TV-channels: #{n_new_tv_channels}"
    puts "  Number of removed TV-channels (by name): #{n_removed_by_name}"
    puts "  Number of removed TV-channels (by regexp): #{n_removed_by_regexp}"
    puts "  Number of renamed TV-channels: #{n_renamed_channels}"
    puts "  Number of written radio-channels: #{n_new_radio_channels}"
    puts "  Number of removed radio-channels (by name): #{n_radio_removed_by_name}"
    puts "  Number of removed radio-channels (by regexp): #{n_radio_removed_by_regexp}"
    puts "  Number of renamed radio-channels: #{n_renamed_radio_channels}"
    # Close database.
    db.close unless db.closed?
  rescue => e
    db.close unless db.closed?
    $stderr.print "Error: #{e.to_s}\n"
    exit 1
  end
end

Konfigurationsdatei für obiges Script reorder_kaffeine_channels.conf

# +| = TV-Sender wird übernommen, Reihenfolge wird beachtet.
# -| = TV-Sender wird gelöscht.
# R| = TV-Sender wird gelöscht, regulärer Ausdruck.
# r| = TV-Sender wird umbenannt.
# !+| = Radio-Sender wird übernommen, Reihenfolge wird beachtet.
# !-| = Radio-Sender wird gelöscht.
# !R| = Radio-Sender wird gelöscht, regulärer Ausdruck.
# !r| = Radio-Sender wird umbenannt.
#
# --- TV-Hauptsender (Reihenfolge wird beachtet!) ----------
+|Das Erste
+|ZDF
+|RTL Television
+|SAT.1
+|ProSieben
+|kabel eins
+|RTL2
+|Super RTL
+|VOX
+|arte
+|3sat
+|KiKa
+|NICK/COMEDY
+|TELE 5
+|DAS VIERTE
+|SIXX
+|Bayerisches FS Süd
+|hr-fernsehen
+|MDR S-Anhalt
+|NDR FS NDS
+|rbb Berlin
+|SWR Fernsehen BW
+|WDR Bielefeld
+|BR-alpha
+|Phoenix
+|N24
+|n-tv
+|EuroNews
+|ZDFinfokanal
+|ZDFtheaterkanal
+|ZDFdokukanal
+|zdf_neo
+|Einsfestival
+|EinsExtra
+|EinsPlus
+|COMEDY CENTRAL Germany
+|GoTV
+|DSF
+|DMAX
+|Eurosport
+|ANIXE SD
+|ORF2E
+|Bloomberg TV Germany
+|Bayerisches FS Nord
+|Franken SAT
+|LokalSAT
+|ONTV Regional
+|RTL Tele Letzebuerg
+|Radio Bremen TV
+|S-TV
+|münchen.tv/RFO
+|rhein main tv
+|SR Fernsehen
+|MDR Sachsen
+|MDR Thüringen
+|NDR FS HH
+|NDR FS MV
+|NDR FS SH
+|SWR Fernsehen RP
+|WDR Aachen
+|WDR Bonn
+|WDR Dortmund
+|WDR Duisburg
+|WDR Düsseldorf
+|WDR Essen
+|WDR Köln
+|WDR Münster
+|WDR Siegen
+|WDR Wuppertal
+|rbb Brandenburg
+|DELUXE MUSIC
+|MTV Germany
+|VIVA Germany
+|LT1-OOE
+|YAVIDO CLIPS
+|imusic TV
+|TW1
+|tv.gusto
# --- Ausländische TV-Sender (Reihenfolge wird beachtet!) ----------
+|2M Maroc
+|2M Monde
+|Al Jazeera
+|Al Jazeera English
+|Al Jazeera International
+|Al Masriya
+|ANDALUCÍA TV
+|Aragon TV
+|Arirang TV
+|ARTE
+|BBC World
+|Belsat TV
+|BFM TV
+|Budapest TV
+|BVN
+|CANAL ALGERIE
+|CCTV F
+|CNBC Europe
+|CNN Int.
+|CT24
+|Cubavision Internacional
+|Daystar Television Network
+|Demain
+|Direct 8
+|CANAL CLUB
+|CANAL+
+|CCTV 9
+|DW-TV
+|EUSKADI TV
+|Extremadura TV
+|France 24 (in English)
+|France 24 (en Francais)
+|Kabel 1 Austria
+|Kabel 1 Schweiz
+|LCP
+|LibertyTV FR
+|MTV AUSTRIA
+|Medi1 Sat
+|NHK World TV
+|NICK AUSTRIA
+|NRJ Paris
+|Popular TV
+|Press TV
+|ProSieben Austria
+|ProSieben Schweiz
+|RAI 1
+|RTL Austria
+|RTL FS
+|RTL HB NDS
+|RTL HH SH
+|RTL2 Austria
+|RTPI
+|Russia Today
+|SAT.1 A
+|SAT.1 Bayern
+|SAT.1 CH
+|Sky News Intl
+|Super RTL A
+|Super RTL CH
+|TMADRID SAT
+|TRT International
+|TV CANARIA
+|TV GALICIA
+|TV Polonia
+|TV TRWAM
+|TV3CAT
+|TV5MONDE
+|TV5MONDE EUROPE
+|TV7
+|TVEi
+|TVP Historia
+|TVP INFO
+|TVP Kultura
+|TVV INT.
+|Telesur
+|VOX Austria
+|VOX CH
+|Yes Italia
# --- Unerwünschte TV-Sender (werden gelöscht) ----------
-|123Damenwahl
-|2255live
-|666 Girls.TV
-|.6live
-|A1 Teleshop
-|.Ab18
-|AbsoluteSexy.TV
-|AbsolutSexy.TV
-|ACHTUNG Erotik.TV
-|ACHTUNG Singles.TV
-|AKTIV DIREKT TV
-|ALL FUN TV
-|Alpenglühen TVX
-|Amore TV
-|Beate Uhse Sexy Sat
-|Bizarr24
-|Blitzkontakt.TV
-|BunnyClub24
-|Bunny X
-|Camshots TV
-|Clipmobile
-|Club1.TV
-|Das Erotische TV
-|Dateline
-|Date Line
-|Deusches Erotik.TV
-|Deutsche Girls 2
-|Deutsches Erotik.TV
-|dhd24 plus
-|Dreamgirls.TV
-|Eros TV
-|EroticDome
-|Erotik 24
-|EROTIKA TV - NEU!
-|Erotik Sat
-|eUrotic
-|eUrotic NEU
-|!flirtline.tv
-|GayBoys LIVE
-|Guter Sex.TV
-|Herzschlag69
-|Hot Girls TV
-|jeden Tag x
-|Kamasutra TV
-|Liebesglück.TV
-|Liebestraum.TV
-|Lustkanal.TV
-|Maennersache TV
-|maennerwelt.tv
-|Mobile Sex
-|Partnersuche.TV
-|Piep Show
-|PLAYBOY TV
-|Playboy TV (a)
-|Po6
-|P*rnMe.TV
-|Pro Erotik TV
-|Rundum Sex TV
-|S3X Girls
-|SAT Erotiktreff.TV
-|SEX-Kontakte
-|Sexy Amateure
-|SexyGirls.TV
-|SexySat
-|Spass im TV
-|Super Sexy.TV
-|Tele6.tv
-|Telefonsex.TV
-|Traumgirls.TV
-|Traumkontakt.tv
-|Venusclub.TV
-|Visit-X.TV
-|Voyeur TV
-|Weiber TV
-|XXHOME
-|Zack Erotik TV
-|.
-|1-2-3.tv
-|3A TV
-|9Live
-|ABONO FOTBOL+
-|A LA CARTE 5
-|A LA CARTE 9
-|A LA DEMANDE
-|AllesfürsHandy
-|ARD-TEST-1
-|ARD-TEST-2
-|arenaSAT Home
-|ARTE-1
-|Astra Vision
-|AstroTV
-|Beauty TV
-|Best of shopping
-|BFM TV-1
-|Bibel TV
-|Bibel TV ALT
-|BR-alpha*
-|C+ A LA DEMANDE
-|C+ LIGA HD
-|C+ DCINE HD
-|C+ DEPORT HD
-|CANAL+
-|CANAL+-1
-|CANAL+-2
-|CANAL CLUB
-|CANAL+ SPORT
-|CANAL+ HD
-|CANAL+ 3D
-|CASH TV
-|Chamber TV
-|Channel 21
-|Channel 21-1
-|Channel 21-2
-|CINE+
-|CINE+-1
-|CODE DOWN
-|COMPRA SMS
-|DAF-AnlegerTV
-|Der Schmuckkanal
-|Deutsches Gesundheitsfernsehen
-|dhd24.tv
-|Die Neue Zeit TV
-|DIE NEUE ZEIT TV
-|Direct 8
-|Direct 8-1
-|DrDish Television
-|DT16
-|DT16-1
-|DT16-2
-|DT4
-|DT4-1
-|DT4-2
-|DT4
-|DT5
-|DT6
-|DT8
-|DT9
-|EHS
-|equi8
-|ERF
-|EWTN Europe
-|FERIA BILBAO
-|Fotohandy
-|glück TV
-|glþck TV
-|GOD Channel
-|GUÍA DIGITAL+
-|GUÍA DIGITAL+-1
-|HOPE Channel deutsch
-|HSE24
-|HSE24 extra
-|JAMBA! TV
-|JML Shop
-|Juwelo TV
-|Kosmica TV
-|KTO
-|K-TV
-|Kuren und Wellness
-|LCP-1
-|LUXE.TV SD
-|M6 BOUTIQUE LA CHAINE
-|Mallorca.TV
-|Medi1SAT
-|MediaShop- Meine Einkaufswelt
-|MediaShop- Neuheiten
-|MehrGeld.TV
-|meinTVshop
-|MOSA 2
-|MOSA 2-1
-|MOSA 3
-|MOSA 3-1
-|MOSA 4
-|MOSA 4-1
-|MOSA 5
-|MOSA 5-1
-|MOSAIQUE
-|MOSAIQUE-1
-|MOSAIQUE-2
-|MOSAIQUE-3
-|MULTIPANT.1
-|MULTIPANT.2
-|MULTIPANT.3
-|MULTIPANT.4
-|MULTI-X
-|MULTI-X (1)
-|MULTI-X (2)
-|MULTI-X (3)
-|PORTADA
-|Preisfuchs TV
-|Q TV SHOP
-|QVC Deutschland
-|QVC PLUS
-|RADIOS
-|RedeRecord
-|REGIO TV
-|Renault TV
-|RNF
-|Sky News Intl-1
-|Sky Select
-|Sonnenklar TV
-|SpiritON.TV
-|Supreme Master TV
-|TAQUILLA
-|TAQUILLA-1
-|TAQUILLA HD
-|TAQUILLA X
-|TAQUILLA X-1
-|TEST CDN 8
-|TEST_CSD1
-|TEST_CSD2
-|TEST_CSD3
-|TEST_CSD4
-|TEST_CSD5
-|Test-R
-|TIMM
-|tirol tv
-|TVM/WWTV
-|WDR Test A
# --- Unerwünschte TV-Sender REGULÄRER Ausdruck (werden gelöscht) ----------
R|TSID
R|Unknown
R|#0
# --- Umbenennungen TV-Sender (von|nach) ----------
r|Das Erste|Das Erste (ARD)
r|RTL Television|RTL
r|SAT.1|Sat.1
r|KiKa|KI.KA
r|NICK/COMEDY|Nick
r|TELE 5|Tele 5
r|Bayerisches FS Süd|BR
r|hr-fernsehen|HR
r|MDR S-Anhalt|MDR Sachsen-Anhalt
r|NDR FS NDS|NDR Niedersachsen
r|rbb Berlin|RBB Berlin
r|SWR Fernsehen BW|SWR BW
r|WDR Bielefeld|WDR
r|Phoenix|PHOENIX
r|COMEDY CENTRAL Germany|Comedy Central
r|GoTV|gotv
r|SIXX|sixx
r|zdf_neo|ZDFneo
r|Einsfestival|einsfestival
r|Einsfestival HD|einsfestival HD
#
# --- Radio-Hauptsender (Reihenfolge wird beachtet!) ----------
!+|1LIVE
!+|1LIVE diggi
!+|WDR 2
!+|WDR 3
!+|WDR 5
!+|KIRAKA
!+|WDR Event
!+|WDR Funkhaus Europa
!+|DLF
!+|DKULTUR
!+|DRadio Wissen
!+|HIT RADIO FFH
!+|ROCK ANTENNE
!+|SKYROCK
!+|ANTENNE BAYERN
!+|Bayern 1
!+|Bayern 2
!+|BAYERN 3
!+|BR-KLASSIK
!+|B5 aktuell
!+|BAYERN plus
!+|hr1
!+|hr2
!+|hr3
!+|hr4
!+|hr-iNFO
!+|MDR1 THÜRINGEN
!+|MDR FIGARO
!+|MDR SPUTNIK
!+|MDR INFO
!+|MDR KLASSIK
!+|NDR 1 Nieders.
!+|NDR 2
!+|NDR Kultur
!+|NDR Info
!+|NDR 90,3
!+|NDR1WelleNord
!+|NDR 1 Radio MV
!+|NDR Info Spez.
!+|Nordwestradio
!+|Bremen Eins
!+|Bremen Vier
!+|SR1 Europawelle
!+|SR2 KulturRadio
!+|SR3 Saarlandwelle
!+|SWR 1 RP
!+|SWR 2
!+|SWR 3
!+|Inforadio
!+|Kulturradio
!+|MDR1 SACHSEN
!+|MDR1 SA-ANHALT
!+|SWR 4 RP
!+|SWR 1 BW
!+|SWR 4 BW
# --- Unerwünschte Radio-Sender (werden gelöscht) ----------
!-|DT13
!-|DT13-1
!-|DT13-2
!-|DT20
!-|DT20-1
!-|DT2
!-|DT2-1
!-|DT2-2
# --- Unerwünschte Radio-Sender REGULÄRER Ausdruck (werden gelöscht) ----------
!R|TSID
!R|Unknown
!R|#0
# --- Umbenennungen Radio-Sender (von|nach) ----------
!r|MDR1 THÜRINGEN|MDR 1
!r|NDR 1 Nieders.|NDR 1
!r|SWR 1 RP|SWR 1
!r|SWR 4 RP|SWR 4

To Do

  1. Lösch-Funktion in kaffeine-Version <= 0.8.x.
    Diese Funktionalität gibt es in kaffeine bis Version 0.8.8 nicht.
    D.h. für kaffeine-Version <= 0.8.x sind alle Aufnahmedaten separat im TV-Browser und kaffeine zu löschen.