#!/usr/bin/perl -w # # # rhimport # # Copyright (C) 2009 Christian Pointner <equinox@helsinki.at> # # This file is part of rhimport. # # rhimport is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # # rhimport is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with rhimport. If not, see <http://www.gnu.org/licenses/>. # use strict; use Getopt::Long; use DBI; use Gtk2; use Gtk2::GladeXML; use lib '/usr/local/share/rhimport/'; use rhimport; my $glade_file = '/usr/local/share/rhimport/rhimport.glade'; my $DBHOST = "airplay"; my $DBUSER = "rivendell"; my $DBPW = "lldriven"; my $DB = "rivendell"; my $HELP = 0; my $FILE = ""; my $POOL = 0; my $KEEPCARTS = 0; my $DROPBOX = ""; my $LISTALLOWED = 0; GetOptions ("help!" => \$HELP, "file=s" => \$FILE, "pool!" => \$POOL, "keep-carts!" => \$KEEPCARTS, "dropbox=s" => \$DROPBOX, "list-allowed!" => \$LISTALLOWED, ) or die(); if($HELP) { print << "EOF"; usage: $0 --file <audio or playlist file> --pool --keep-carts --dropbox <path to dropbox> --list-allowed When called with no file and/or no dropbox the GUI gets started to select the missing parameters options: -f | --file the media file or playlist to import -p | --pool pool mode, import media files referneced by playlist -k | --keep-carts in pool mode keep existing carts instead of clearing them before import -d | --dropbox the path to the dropbox to use -l | --list-allowed list allowed dropboxes and exit EOF exit 0; } my $user = `/usr/bin/id -un`; $user =~ s/\n//; my $dbh = DBI->connect("DBI:mysql:$DB:$DBHOST","$DBUSER","$DBPW") or die "Database Error: $DBI::errstr"; my @allowed_dbs = rhimport::get_dropboxes($dbh, $user); if($LISTALLOWED) { for my $href ( @allowed_dbs ) { print "$href->{'NAME'} \t-> $href->{'PATH'}\n"; } $dbh->disconnect(); exit 0; } ########################################### ## GUI mode my $guixml; sub set_mode_playlist_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } $POOL = 1; my $l_mode = $guixml->get_widget('l_mode'); $l_mode->set_label("<b>Musik Pool</b>"); my $cb_clear_carts = $guixml->get_widget('cb_clear_carts'); $cb_clear_carts->set_sensitive(1); my $l_file_playlist = $guixml->get_widget('l_file_playlist'); $l_file_playlist->set_label("<b>Playlist</b>"); my $filter = Gtk2::FileFilter->new; $filter->add_pattern("*.m3u"); my $filechooser = $guixml->get_widget('filechooser'); $filechooser->set_filter($filter); } sub set_mode_file_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } $POOL = 0; my $l_mode = $guixml->get_widget('l_mode'); $l_mode->set_label("<b>Sendung</b>"); my $cb_clear_carts = $guixml->get_widget('cb_clear_carts'); $cb_clear_carts->set_sensitive(0); my $l_file_playlist = $guixml->get_widget('l_file_playlist'); $l_file_playlist->set_label("<b>Datei</b>"); my $filter = Gtk2::FileFilter->new; $filter->add_pattern("*.wav"); $filter->add_pattern("*.WAV"); $filter->add_pattern("*.ogg"); $filter->add_pattern("*.OGG"); $filter->add_pattern("*.flac"); $filter->add_pattern("*.FLAC"); $filter->add_pattern("*.fla"); $filter->add_pattern("*.FLA"); $filter->add_pattern("*.mp*"); $filter->add_pattern("*.MP*"); my $filechooser = $guixml->get_widget('filechooser'); $filechooser->set_filter($filter); } sub set_mode_disabled_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my @widgets = ('b_mode', 'cb_clear_carts', 'b_showcarts', 'b_apply', 'filechooser'); for my $w ( @widgets ) { my $widget = $guixml->get_widget($w); $widget->set_sensitive(0) if($widget); } } sub toggle_mode_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my $co_dropbox = $guixml->get_widget('co_dropbox'); my $to_cart = $allowed_dbs[$co_dropbox->get_active]->{'TO_CART'} if($allowed_dbs[$co_dropbox->get_active]); my $response = 'no'; if(($to_cart == 0 && $POOL) || ($to_cart != 0 && !$POOL)) { my $question = "Diese Sendung hat "; if($to_cart != 0) { $question .= "nur ein Cart"; } else { $question .= "mehrere Carts"; } $question .= ". Soll der Modus trotzdem gewechselt werden?"; my $parent_window = $guixml->get_widget('appwin'); my $dialog = Gtk2::MessageDialog->new ($parent_window, 'destroy-with-parent', 'question', 'yes-no', $question); $dialog->set_default_response ('no'); $response = $dialog->run; $dialog->destroy; } else { $response = 'yes'; } if($response eq 'yes') { if($POOL) { set_mode_file_gui(); } else { set_mode_playlist_gui(); } } } my $gui_progress_cb = sub { my ($elapsed, $max, $text) = @_; if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my $progressbar = $guixml->get_widget('progressbar'); $progressbar->set_text("($elapsed/$max) $text"); $progressbar->set_fraction($elapsed/$max); while (Gtk2->events_pending) { Gtk2->main_iteration; } Gtk2::Gdk->flush; }; my $gui_error_cb = sub { my ($text) = @_; if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } $text .= "\n\nVorgang abbrechen?"; my $parent_window = $guixml->get_widget('appwin'); my $dialog = Gtk2::MessageDialog->new ($parent_window, 'destroy-with-parent', 'error', 'yes-no', $text); $dialog->set_default_response ('no'); my $response = $dialog->run; $dialog->destroy; return 0 if($response eq 'yes'); return 1; }; sub start_import_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my $b_apply = $guixml->get_widget('b_apply'); my $b_close = $guixml->get_widget('b_close'); $b_apply->set_sensitive(0); $b_close->set_sensitive(0); if(!rhimport::check_key_file()) { my $parent_window = $guixml->get_widget('appwin'); my $dialog = Gtk2::MessageDialog->new ($parent_window, 'destroy-with-parent', 'error', 'ok', "Es wurde kein Import Key gefunden."); $dialog->run; $dialog->destroy; $b_apply->set_sensitive(1); $b_close->set_sensitive(1); return 0; } my $l_status = $guixml->get_widget('l_status'); my $filechooser = $guixml->get_widget('filechooser'); my $file = $filechooser->get_filename; if(!$file || -d $file) { if($POOL) { $l_status->set_label("Keine Playlist ausgew�hlt!"); } else { $l_status->set_label("Keine Audio Datei ausgew�hlt!"); } $b_apply->set_sensitive(1); $b_close->set_sensitive(1); return 0; } $filechooser->unselect_all; my $co_dropbox = $guixml->get_widget('co_dropbox'); my $dropbox = $allowed_dbs[$co_dropbox->get_active]->{'PATH'} if ($allowed_dbs[$co_dropbox->get_active]); my $group = $allowed_dbs[$co_dropbox->get_active]->{'GROUP'} if ($allowed_dbs[$co_dropbox->get_active]); my $to_cart = $allowed_dbs[$co_dropbox->get_active]->{'TO_CART'} if($allowed_dbs[$co_dropbox->get_active]); $l_status->set_label("importiere von $file"); my $ret; my $log; if($POOL) { my $cb_clear_carts = $guixml->get_widget('cb_clear_carts'); if($cb_clear_carts->get_active) { $log = rhimport::clear_carts($dbh, $group, $to_cart, $gui_progress_cb); } my $import_log; ($ret, $import_log) = rhimport::import_playlist($file, $dropbox, $user, rhimport::get_num_carts($dbh, $group) ,$gui_progress_cb, $gui_error_cb); $log .= $import_log; } else { $log = rhimport::clear_carts($dbh, $group, $to_cart, $gui_progress_cb); my $import_log; ($ret, $import_log) = rhimport::import_single($file, $dropbox, $user, $gui_progress_cb, $gui_error_cb); $log .= $import_log; } my $parent_window = $guixml->get_widget('appwin'); my $dialog; if(!$ret) { $l_status->set_label("Fehler beim Importieren"); $dialog = Gtk2::MessageDialog->new ($parent_window, 'destroy-with-parent', 'error', 'ok', "Fehler beim Importieren."); # $dialog->add_button("Log anzeigen", 1); } else { $l_status->set_label(""); $dialog = Gtk2::MessageDialog->new ($parent_window, 'destroy-with-parent', 'info', 'ok', "Der Import wurde erfolgreich abgeschlossen!"); # $dialog->add_button("Log anzeigen", 1); } my $response = $dialog->run; $dialog->destroy; # if($response == 1) { # $dialog = Gtk2::MessageDialog->new ($parent_window, 'destroy-with-parent', # 'info', 'ok', $log); # $dialog->run; # $dialog->destroy; # } $b_apply->set_sensitive(1); $b_close->set_sensitive(1); return $ret; } sub show_used_carts_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my $co_dropbox = $guixml->get_widget('co_dropbox'); my $group = $allowed_dbs[$co_dropbox->get_active]->{'GROUP'} if($allowed_dbs[$co_dropbox->get_active]); my $l_status = $guixml->get_widget('l_status'); my ($low_cart, $high_cart) = rhimport::get_cart_range($dbh, $group); if($low_cart eq $high_cart) { $l_status->set_label("Cart: $low_cart"); } else { $l_status->set_label("Carts: $low_cart - $high_cart"); } # my $usedcartswin = $guixml->get_widget('usedcartswin'); # $usedcartswin or die "can't find Widget"; # $usedcartswin->resize(640,480); # $usedcartswin->show; } sub clear_status_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my $l_status = $guixml->get_widget('l_status'); $l_status->set_label(""); my $progressbar = $guixml->get_widget('progressbar'); $progressbar->set_text(""); $progressbar->set_fraction(0); } sub dropbox_updated_gui() { if(!$guixml) { print STDERR "no GUI definition found!\n"; exit 2; } my $co_dropbox = $guixml->get_widget('co_dropbox'); if($allowed_dbs[$co_dropbox->get_active]) { my $to_cart = $allowed_dbs[$co_dropbox->get_active]->{'TO_CART'}; my $group = $allowed_dbs[$co_dropbox->get_active]->{'GROUP'}; my ($low_cart, $high_cart) = rhimport::get_cart_range($dbh, $group); if($to_cart == 0) { set_mode_playlist_gui(); } else { set_mode_file_gui(); } } else { set_mode_disabled_gui(); } } if(!$FILE || !$DROPBOX) { Gtk2->init; $guixml = Gtk2::GladeXML->new($glade_file); $guixml or die "can't load glade xml file"; require gui_callbacks; my $model = Gtk2::ListStore->new('Glib::String', 'Glib::String', 'Glib::String', 'Glib::String'); for my $href ( @allowed_dbs ) { $model->set ($model->append, 0, $href->{'PATH'}, 1, $href->{'GROUP'}, 2, $href->{'TO_CART'}, 3, $href->{'NAME'}); } my $co_dropbox = $guixml->get_widget('co_dropbox'); $co_dropbox->set_model($model); my $renderer = Gtk2::CellRendererText->new; $co_dropbox->pack_start($renderer, 1); $co_dropbox->add_attribute($renderer, text => 3); $co_dropbox->set_active(0); dropbox_updated_gui(); my $cb_clear_carts = $guixml->get_widget('cb_clear_carts'); if($KEEPCARTS) { $cb_clear_carts->set_active(0); } else { $cb_clear_carts->set_active(1); } $guixml->signal_autoconnect_from_package('gui_callbacks'); my $appwin = $guixml->get_widget('appwin'); $appwin or die "can't find Main Window"; $appwin->resize(800,600); $appwin->show; Gtk2->main; $dbh->disconnect(); exit 0; } ########################################### ## command line mode my $cl_error_cb = sub { my ($text) = @_; print "\n$text .. cancel operation [Y/n]? "; my $x = scalar(<STDIN>); $x =~ /^n/i; }; rhimport::check_key_file() or die "Import Key not found, use rhimport-create-id to create one\n"; (-e "$FILE") or die "file '$FILE' not found\n"; if($POOL) { print "will import from playlist $FILE, with user $user\n\n"; } else { print "will import $FILE, with user $user\n\n"; } my $group = ''; my $to_cart = 0; for my $href (@allowed_dbs) { if($href->{'PATH'} eq $DROPBOX) { $group = $href->{'GROUP'}; $to_cart = $href->{'TO_CART'}; last; } } if($group eq '') { print "Dropbox not found or not allowed\n"; exit 1 } my $ret; my $log; if($POOL) { if(!$KEEPCARTS) { $log = rhimport::clear_carts($dbh, $group, $to_cart); } my $import_log; ($ret, $import_log) = rhimport::import_playlist($FILE, $DROPBOX, $user, rhimport::get_num_carts($dbh, $group), 0, $cl_error_cb); $log .= $import_log; } else { $log = rhimport::clear_carts($dbh, $group, $to_cart); my $import_log; ($ret, $import_log) = rhimport::import_single($FILE, $DROPBOX, $user, 0, $cl_error_cb); $log .= $import_log; } $dbh->disconnect(); if(!$ret) { exit 1; } exit 0;