BeanShell-Filter

Aus TV-Browser Wiki
Version vom 9. März 2015, 14:02 Uhr von Sheldon2012⧼word-separator⧽⧼parentheses⧽ ⧼parentheses⧽
⧼revision-nav⧽
Wechseln zu: Navigation⧼comma-separator⧽Suche

Diese Seite enthält einige Beispiele für die Verwendung von BeanShell-Filtern. Der angegebene Code muss jeweils in das Textfeld einer BeanShell-Filterkomponente kopiert werden.

Sendungen mit Bildern

import devplugin.beanshell.BeanShellProgramFilterIf; 
import devplugin.Program; 
import devplugin.ProgramFieldType; 

accept(Program p) { 
  if(p.getBinaryField(ProgramFieldType.PICTURE_TYPE) != null) 
    return true; 
   
  return false; 
} 

return (BeanShellProgramFilterIf) this;

Temporär alle Premiere-Sendungen ausblenden

import devplugin.beanshell.BeanShellProgramFilterIf; 
import devplugin.Program; 

accept(Program p) { 
    String s=p.getChannel().toString(); 
    return (-1==s.indexOf("Premiere"));  
}

return (BeanShellProgramFilterIf) this;

Sendungen, bei denen der Regisseur auch Schauspieler ist

import devplugin.beanshell.BeanShellProgramFilterIf;
import devplugin.Program;
import devplugin.ProgramFieldType;

accept(Program p) {
  String director = p.getTextField(ProgramFieldType.DIRECTOR_TYPE);
  String actors = p.getTextField(ProgramFieldType.ACTOR_LIST_TYPE);
  if (director != null && actors != null) {
    if (actors.indexOf(director) >= 0) {
      return true;
    }
  }
  return false;
}

return (BeanShellProgramFilterIf) this;

Dynamischer BeanShell-Filter als CSV-File-Interface

Die bislang vorgestellten Skripte führen zu statischen Filterkomponenten vom Typ BeanShell-Filter. Deren Funktionsweise ist ausschließlich durch das Skript und den Datenbestand im TV-Browser bestimmt.

Mit der Filterkomponente BeanShell-Filter kann man auch dynamische Filterkomponenten erstellen. Das hier vorgestellte Skript dient zum Auslesen einer CSV-Datei. Da die Funktionsweise des Filters vom Inhalt der CSV-Datei abhängt und die CSV-Datei jederzeit modifiziert werden kann, ist diese Filterkomponente dynamisch.

In diesem konkreten Beispiel enthält die CSV-Datei episodes.csv Sendungsinformationen in der Form Sendungstitel;Episodentitel. Diese werden mit den korrespondierenden aktuellen Daten im TV-Browser abgeglichen. Der resultierende Filter schließt alle Episoden aus der CSV-Datei ein, die im aktuellen Datenbestand des TV-Browsers enthalten sind.

Hinweis:

Dies ist natürlich nur ein Beispiel für einen dynamischen BeanShell-Filter. Die Daten können auch z. B. in Form eines Excel-Sheets vorliegen oder aus einer SQL-Datenbank ausgelesen werden. Dazu muss dann natürlich ein entsprechendes Skript erstellt werden.

Ebenso können auf diesem Weg auch andere Parameter als Sendungstitel und Episodentitel abgeglichen werden. Auch hierfür ist natürlich eine Anpassung des Skriptes erforderlich.

Die Wahl einer CSV-Datei als Datenschnittstelle erfolgte bewusst, weil sich die meisten Schnittstellenprobleme darauf reduzieren lassen. Die CSV-Datei stellt diesbezüglich also quasi den "kleinsten gemeinsamen Nenner" dar. In diesem Sinne ist die hier vorgestellte Lösung universell verwendbar.


// Beanshell-Filter: CSV file interface  

import devplugin.beanshell.BeanShellProgramFilterIf;
import devplugin.Program;
import devplugin.ProgramFieldType;

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;

accept(Program prog) throws IOException {

   // Reading program data 
   String title = prog.getTextField(ProgramFieldType.TITLE_TYPE);
   String episode = prog.getTextField(ProgramFieldType.EPISODE_TYPE);

   // Program data comparison preparation
   title = prepareForComparison(title);
   episode = prepareForComparison(episode);

   // CSV file settings
   String file = "D:\\Portable Applications\\Platform\\PortableApps\\TV Browser\\custom\\data\\BeanShell\\episodes.csv";
   String separator = ";";
   String line = "";
   
   // Program data check
   if ((title != null) && (title.trim().length() > 0) && (episode != null) && (episode.trim().length() > 0)){

      try{
 
         // Read CSV file
         BufferedReader br = new BufferedReader(new FileReader(file));
         
         line = br.readLine();

         while (line != null){

            line = line.trim();

            String[] lineParts = line.split(separator);

            // CSV data comparison preparation
            String favTitle = prepareForComparison(lineParts[0]);
            String favEpisode = prepareForComparison(lineParts[1]);

            // Data comparison
            if (title.trim().equals(favTitle) && episode.trim().equals(favEpisode)){
     
               // Close reader
               closeReader(br);
               
               return true;
            }
         
            line = br.readLine();
         }

         // Close reader;
         closeReader(br);

         return false;

      }catch (IOException ioe) {

         // Close reader
         closeReader(br); 

         throw ioe;
      }

   }else{
       
       // Program data check failed
       return false;

   }
}

private String prepareForComparison(String unpreparedString){

   String preparedString = "";
   
   preparedString = unpreparedString;

   // Set to lower case
   preparedString = preparedString.toLowerCase();

   // Special alphabetic character handling 
   preparedString = preparedString.replaceAll("\00df", "ss"); // replace ß by ss
   preparedString = preparedString.replaceAll("\00e4", "ae"); // replace ä by ae
   preparedString = preparedString.replaceAll("\00f6", "oe"); // replace ö by oe
   preparedString = preparedString.replaceAll("\00fc", "ue"); // replace ü by ue

   // Non-numeric and non-alphabetic character handling 
   preparedString = preparedString.replaceAll("[^0-9a-z]", "");

   // Trim the string
   preparedString = preparedString.trim();
   
   return preparedString;

}

private void closeReader (BufferedReader br) throws IOException {

   try {
    
      if (br != null) {
     
         br.close();
      }
   
   } catch (IOException e) {

      throw e;
   } 
}

return (BeanShellProgramFilterIf) this;  

Beispiel für eine CSV-Datei:

Dies ist ein Beispiel für eine CSV-Datei episodes.csv, die vom obigen Skript ausgelesen werden kann.


Die Rosenheim-Cops;Ein Abgang mit Blubb
Die Rosenheim-Cops;Zu Tode gesteigert
Die Rosenheim-Cops;Tot im Netz
Um Himmels Willen;Miss Kaltenthal
Um Himmels Willen;Bloßgestellt
Falling Skies;Eine dunkle Nacht
Gotham;Arkham

Anwendung:

Das vorgestellte Beanshell-Skript kann in Kombination mit den Plugins Filter-Info-Icons und SwitchPlugin zur Konfiguration einer offenen bidirektionalen Schnittstelle verwendet werden.


Performance:

Bei der Verwendung von Schnittstellen ist stets auch deren Performance ein sehr wichtiger Aspekt. Diesbezügliche Tests haben für das hier betrachtete BeanShell-Skript für eine CSV-Datei mit 1000 Datensätzen eine zufriedenstellende Performance gezeigt. Daher stellt dieser Ansatz für Datenbestände in dieser Größenordnung eine gute Lösung dar.

Für größere Datenmengen ist dieser Ansatz jedoch ungeeignet. Hierfür steht mit der CSV-Datei-Filterkomponente eine hinsichtlich der Performance weitaus leistungsstärkere Lösung zur Verfügung.


Statiische Variante:

Die Verwendung einer CSV-Datei mit konstantem Inhalt führt zu einer statischen Variante dieser Schnittstelle. Mit dieser Variante lassen sich bei Bedarf sehr komplexe Filter erzeugen.