Ticket #11344: tmdb_parse-fanart.patch

File tmdb_parse-fanart.patch, 17.2 KB (added by gergnz@…, 8 years ago)
  • classes/Video.php

    diff --git a/classes/Video.php b/classes/Video.php
    index 5c6f7e4..76a621e 100644
    a b class Video { 
    3939            SELECT  dirname
    4040            FROM    storagegroup
    4141            WHERE   groupname="Coverart"
     42            OR groupname="Fanart"
    4243        ');
    4344
    4445        $video = $db->query_assoc('
    class Video { 
    6263        $this->showlevel    = $video['showlevel'];
    6364        $this->filename     = $video['filename'];
    6465        $this->cover_file   = $video['coverfile'];
     66        $this->fanart_file  = $video['fanart'];
    6567        $this->browse       = $video['browse'];
    6668    // And the artwork URL
    6769        $this->cover_url = '';
     70        $fanart=false;
     71        if (!$this->cover_file && $this->fanart_file) {
     72            $foo = explode('/', $this->fanart_file);
     73            $this->cover_file = $foo[count($foo) - 1];
     74            $fanart=true;
     75        }
    6876        if ($this->cover_file && $this->cover_file != 'No Cover') {
    6977            $exists = false;
    7078            foreach ($video_dirs as $dir) {
    class Video { 
    7583                }
    7684            }
    7785            if ($exists) {
    78                 $this->cover_url = 'pl/coverart/'.$this->cover_file;
     86                if ($fanart) {
     87                    $this->cover_url = 'pl/fanart/'.$this->cover_file;
     88                } else {
     89                    $this->cover_url = 'pl/coverart/'.$this->cover_file;
     90                }
    7991                $this->cover_file = $path;
    8092                list($width, $height) = @getimagesize($this->cover_file);
    8193                if ($width > 0 && $height > 0) {
  • new file modules/fanart/handler.pl

    diff --git a/modules/fanart/handler.pl b/modules/fanart/handler.pl
    new file mode 100644
    index 0000000..b149dea
    - +  
     1#!/usr/bin/perl
     2#
     3# MythWeb Coverart/Download module
     4#
     5#
     6
     7# Necessary constants for sysopen
     8    use Fcntl;
     9
     10# Other includes
     11    use Sys::Hostname;
     12    use HTTP::Date;
     13
     14# Attempt to use the perl bindings to prevent the backend from shutting down during streaming
     15    eval 'use MythTV;';
     16
     17    if (!$@) {
     18        our $mythbackend = new MythTV();
     19        $mythbackend->backend_command('ANN Playback '.hostname);
     20    }
     21
     22# Which cover are we displaying
     23    our $cover    = url_param('cover');
     24    if ($Path[1]) {
     25        $cover    = $Path[1];
     26    }
     27
     28# No match?
     29    unless ($cover =~ /\w/) {
     30        print header(),
     31              "Unknown cover requested.\n";
     32        exit;
     33    }
     34
     35# Find the local file
     36    our $filename;
     37    $sh = $dbh->prepare('SELECT dirname FROM storagegroup WHERE groupname = "Fanart"');
     38    $sh->execute();
     39    while (my ($coverart_dir) = $sh->fetchrow_array()) {
     40        next unless (-e "$coverart_dir/$cover");
     41        $filename = "$coverart_dir/$cover";
     42        last;
     43    }
     44    $sh->finish;
     45
     46    1;
     47
     48    unless ($filename) {
     49        print header(),
     50              "$cover does not exist in any recognized storage group directories for this host.";
     51        exit;
     52    }
     53
     54# File size
     55    my $size = -s $filename;
     56
     57# Zero bytes?
     58    if ($size < 1) {
     59        print header(),
     60              "$cover is an empty file.";
     61        exit;
     62    }
     63
     64# File type
     65    my $type   = 'text/html';
     66    my $suffix = '';
     67    if ($cover =~ /\.jpg$/) {
     68        $type   = 'image/jpeg';
     69        $suffix = '.jpg';
     70    }
     71    else {
     72        print header(),
     73              "Unknown image type requested:  $cover\n";
     74        exit;
     75    }
     76
     77# Open the file for reading
     78    unless (sysopen DATA, $filename, O_RDONLY) {
     79        print header(),
     80              "Can't read $cover:  $!";
     81        exit;
     82    }
     83
     84# Binmode, in case someone is running this from Windows.
     85    binmode DATA;
     86
     87    my $start      = 0;
     88    my $end        = $size;
     89    my $total_size = $size;
     90    my $read_size  = 1024;
     91    my $mtime      = (stat($filename))[9];
     92
     93# Handle cache hits/misses
     94    if ( $ENV{'HTTP_IF_MODIFIED_SINCE'}) {
     95        my $check_time = str2time($ENV{'HTTP_IF_MODIFIED_SINCE'});
     96        if ($mtime <= $check_time) {
     97            print header(-Content_type           => $type,
     98                         -status                 => "304 Not Modified"
     99                        );
     100            exit;
     101        }
     102    }
     103
     104# Requested a range?
     105    if ($ENV{'HTTP_RANGE'}) {
     106    # Figure out the size of the requested chunk
     107        ($start, $end) = $ENV{'HTTP_RANGE'} =~ /bytes\W+(\d*)-(\d*)\W*$/;
     108        if ($end < 1 || $end > $size) {
     109            $end = $size;
     110        }
     111        $size = $end - $start+1;
     112        if ($read_size > $size) {
     113            $read_size = $size;
     114        }
     115        print header(-status                => "206 Partial Content",
     116                     -type                  => $type,
     117                     -Content_length        => $size,
     118                     -Accept_Ranges         => 'bytes',
     119                     -Content_Range         => "bytes $start-$end/$total_size",
     120                     -Last_Modified         => time2str($mtime),
     121                     -Content_disposition => " attachment; filename=\"$cover\""
     122                 );
     123    }
     124    else {
     125        print header(-type                  => $type,
     126                    -Content_length         => $size,
     127                    -Accept_Ranges          => 'bytes',
     128                    -Last_Modified          => time2str($mtime),
     129                    -Content_disposition => " attachment; filename=\"$cover\""
     130                 );
     131    }
     132
     133# Seek to the requested position
     134    sysseek DATA, $start, 0;
     135
     136# Print the content to the browser
     137    my $buffer;
     138    while (sysread DATA, $buffer, $read_size ) {
     139        print $buffer;
     140        $size -= $read_size;
     141        if ($size == 0) {
     142            last;
     143        }
     144        if ($size < $read_size) {
     145            $read_size = $size;
     146        }
     147    }
     148    close DATA;
     149
     150# Escape a parameter for safe use in a commandline call
     151    sub shell_escape {
     152        $str = shift;
     153        $str =~ s/'/'\\''/sg;
     154        return "'$str'";
     155    }
     156
     157# Return true
     158    1;
     159
  • new file modules/fanart/init.php

    diff --git a/modules/fanart/init.php b/modules/fanart/init.php
    new file mode 100644
    index 0000000..ce88ab4
    - +  
     1<?php
     2/**
     3 * Initialization routines for the MythWeb Video Coverart module
     4 *
     5 * @license     GPL
     6 *
     7 * @package     MythWeb
     8 * @subpackage  Video Coverart
     9 *
     10/**/
     11?>
  • modules/video/handler.php

    diff --git a/modules/video/handler.php b/modules/video/handler.php
    index 721f186..ff9e3fd 100644
    a b  
    205205
    206206// Get the video categories on the system
    207207    $Category_String = array();
     208    $Category_Index = array();
    208209    $sh = $db->query('SELECT * FROM videocategory ORDER BY category');
    209     while ($row = $sh->fetch_assoc())
     210    while ($row = $sh->fetch_assoc()) {
    210211        $Category_String[$row['intid']] = $row['category'];
     212        $Category_Index[$row['category']] = $row['intid'];
     213    }
    211214    $sh->finish();
    212215    $Category_String[0] = t('Uncategorized');
    213216
  • modules/video/imdb.php

    diff --git a/modules/video/imdb.php b/modules/video/imdb.php
    index 1892e54..89ddab6 100644
    a b  
    4747                                  'ALLOCINE' => array( ' -M "%%TITLE%%"')
    4848                                 );
    4949
    50         $dupe = array();
    5150        foreach ($options[$imdbwebtype] as $option) {
    5251            $cmd = $imdb.str_replace('%%TITLE%%', $title, $option);
    5352            exec($cmd, $output, $retval);
    5453            if ($retval == 255)
    5554                $return['warning'][] = "IMDB Command $cmd exited with return value $retval";
     55            if (!count($output)) {
     56                $title_parts = explode(' ', $title);
     57                $cmd = $imdb.str_replace('%%TITLE%%', $title_parts[0], $option);
     58                exec($cmd, $output, $retval);
     59                if ($retval == 255)
     60                    $return['warning'][] = "IMDB Command $cmd exited with return value $retval";
     61            }
    5662            if (!count($output))
    5763                continue;
     64            $single_output='';
    5865            foreach ($output as $line) {
    59                 list($imdbid, $title) = explode(':', $line, 2);
    60                 if ($dupe[$imdbid])
    61                     continue;
    62                 $dupe[$imdbid] = true;
    63                 $return['matches'][] = array('imdbid' => $imdbid,
    64                                              'title'  => $title);
     66                $single_output=$single_output.$line;
     67            }
     68            $xml = simplexml_load_string($single_output);
     69
     70            foreach ($xml as $item) {
     71                if (strlen($item->imdb) > 1) {
     72                    $imdbid = (string)$item->imdb;
     73                    $title = (string)$item->title;
     74                    $return['matches'][] = array('imdbid' => $imdbid, 'title' => $title);
     75                }
    6576            }
    6677        }
    6778    }
     
    7081    {
    7182        global $db;
    7283        global $return;
     84
     85 //  Get the video genres on the system
     86     $Genre_String = array();
     87     $Genre_Index = array();
     88     $sh = $db->query('SELECT * FROM videogenre ORDER BY genre');
     89     while ($row = $sh->fetch_assoc()) {
     90         $Genre_String[$row['intid']] = $row['genre'];
     91         $Genre_Index[$row['genre']] = $row['intid'];
     92     }
     93     $sh->finish();
     94     $Genre_String[0] = t('No Genre');
     95
     96
     97     $Category_String = array();
     98     $Category_Index = array();
     99     $sh = $db->query('SELECT * FROM videocategory ORDER BY category');
     100     while ($row = $sh->fetch_assoc()) {
     101         $Category_String[$row['intid']] = $row['category'];
     102         $Category_Index[$row['category']] = $row['intid'];
     103     }
     104     $sh->finish();
     105     $Category_String[0] = t('Uncategorized');
     106
    73107        $return['action'] = 'grab';
    74108        $imdb             = setting('web_video_imdb_path', hostname);
    75109        $imdbwebtype      = setting('web_video_imdb_type', hostname);
     
    94128            return;
    95129        }
    96130        $posterfile = "$artwork_dir/$imdbnum.jpg";
     131
     132    # Figure out the fanart directory
     133        $fanartwork_dirs = $db->query_list('
     134            SELECT  dirname
     135            FROM    storagegroup
     136            WHERE   groupname="Fanart"
     137            ');
     138        if (empty($fanartwork_dirs)) {
     139            $return['warning'][] = 'MythWeb now requires use of the Fanart Storage Group.';
     140            return;
     141        }
     142        foreach ($fanartwork_dirs as $dir) {
     143            if (is_dir($dir) || is_link($dir)) {
     144                $fanartwork_dir = $dir;
     145                break;
     146            }
     147        }
     148        if (empty($fanartwork_dir)) {
     149            $return['warning'][] = 'Could not find a valid Fanart Storage Group directory';
     150            return;
     151        }
     152        $fanartfile = "$fanartwork_dir/$imdbnum.jpg";
     153
     154
    97155    // Get the imdb data
    98156        $data = array();
    99157        $cmd = "$imdb -D $imdbnum";
    100         exec($cmd, $lines, $retval);
     158        exec($cmd, $output, $retval);
    101159        if ($retval == 255 || $DEBUG) {
    102160            $return['warning'][] = "IMDB Command $cmd exited with return value $retval";
    103161        }
    104         $valid = FALSE;
    105         foreach ($lines as $line) {
    106             list ($key, $value) = explode(':', $line, 2);
    107             $data[strtolower($key)] = trim($value);
    108             if (strlen($data[strtolower($key)]) > 0) {
    109                 $valid = TRUE;
     162        $single_output='';
     163        foreach ($output as $line) {
     164            $single_output=$single_output.$line;
     165        }
     166        $xml = simplexml_load_string($single_output);
     167
     168        foreach ($xml as $item) {
     169          $data['title'] = (string)$item->title;
     170          $data['plot'] = (string)$item->description;
     171          $date = date_parse($item->releasedate);
     172          $data['year'] = (string)$date['year'];
     173          $data['userrating'] = (string)$item->userrating;
     174          $data['runtime'] = (string)$item->runtime;
     175          if ($item->certifications) {
     176            foreach ($item->certifications->certification as $cert) {
     177              if (strtoupper($cert->attributes()->locale) == "US" && !$data['movierating']) {
     178                $data['movierating'] = (string)$cert->attributes()->name;
     179              }
     180            }
     181          }
     182          if ($item->people) {
     183            foreach ($item->people->person as $person) {
     184              if (strtoupper($person->attributes()->job) == "DIRECTOR" && !$data['director']) {
     185                $data['director'] = (string)$person->attributes()->name;
     186              }
     187            }
     188          }
     189          $data['coverart']='';
     190          $data['fanart']='';
     191          foreach ($item->images->image as $image_data) {
     192            if ($image_data->attributes()->type == 'coverart' && !$data['coverart']) {
     193              $data['coverart'] = (string)$image_data->attributes()->url;
    110194            }
     195            if ($image_data->attributes()->type == 'fanart' && !$data['fanart']) {
     196              $data['fanart'] = (string)$image_data->attributes()->url;
     197            }
     198          }
    111199        }
    112         if (!$valid) {
    113             $return['error'][] = t('Video: Error: IMDB');
    114             return;
     200        $data['genre'] = array();
     201        foreach ($item->categories->category as $cat) {
     202          array_push($data['genre'], (string)$cat->attributes()->name);
    115203        }
    116204    // If the file already exists, use it, don't bother regrabbing
    117205        if (!file_exists($posterfile)) {
    118206            $posterurl = $data['coverart'];
    119             if (!is_writable($artwork_dir))
     207            if (!is_writable($artwork_dir)) {
     208                $return['warning'][] = t('Video: Warning: Artwork');
     209            } else {
     210                if (!ini_get('allow_url_fopen')) {
     211                    $return['warning'][] = t('Video: Warning: fopen');
     212                } elseif(strlen($posterurl) > 0) {
     213                    $posterurl = preg_replace('/,.+$/', '', $posterurl);    // For now, only bother to grab the first poster URL
     214                    $posterjpg = @file_get_contents($posterurl);
     215                    if ($posterjpg === FALSE)
     216                        $return['warning'][] = t('Video: Warning: Artwork: Download');
     217                    else {
     218                        @file_put_contents( $posterfile, $posterjpg);
     219                        if (!file_exists($posterfile))
     220                            $return['warning'][] = t('Video: Warning: Artwork');
     221                    }
     222                }
     223            }
     224        }
     225    // rinse and repeat for fanart
     226    // If the file already exists, use it, don't bother regrabbing
     227        if (!file_exists($fanartfile)) {
     228            $posterurl = $data['fanart'];
     229            if (!is_writable($fanartwork_dir))
    120230                $return['warning'][] = t('Video: Warning: Artwork');
    121231            else {
    122232                if (!ini_get('allow_url_fopen'))
     
    127237                    if ($posterjpg === FALSE)
    128238                        $return['warning'][] = t('Video: Warning: Artwork: Download');
    129239                    else {
    130                         @file_put_contents( $posterfile, $posterjpg);
    131                         if (!file_exists($posterfile))
     240                        @file_put_contents( $fanartfile, $posterjpg);
     241                        if (!file_exists($fanartfile))
    132242                            $return['warning'][] = t('Video: Warning: Artwork');
    133243                    }
    134244                }
    135245            }
    136246        }
     247
     248        if (!$Category_Index[$data['genre'][0]]) {
     249            $db->query('INSERT INTO videocategory SET category = ?', $data['genre'][0]);
     250        }
     251
    137252    // Update the database
    138253        $sh = $db->query('UPDATE videometadata
    139254                             SET title        = ?,
    140255                                 director     = ?,
    141256                                 plot         = ?,
    142257                                 rating       = ?,
     258                                 category     = ?,
    143259                                 inetref      = ?,
    144260                                 year         = ?,
    145261                                 userrating   = ?,
    146262                                 length       = ?,
    147                                  coverfile    = ?
     263                                 coverfile    = ?,
     264                                 fanart       = ?
    148265                           WHERE intid        = ?',
    149266                         $data['title'],
    150267                         $data['director'],
    151268                         $data['plot'],
    152269                         $data['movierating'],
     270                         $Category_Index[$data['genre'][0]],
    153271                         $imdbnum,
    154272                         $data['year'],
    155273                         $data['userrating'],
    156274                         $data['runtime'],
    157275                         ( @filesize($posterfile) > 0 ? "$imdbnum.jpg" : 'No Cover' ),
     276                         ( @filesize($fanartfile) > 0 ? "$imdbnum.jpg" : 'No Cover' ),
    158277                         $id
    159278                         );
     279
     280        $db->query('DELETE FROM videometadatagenre
     281                     WHERE videometadatagenre.idvideo = ?',
     282                     $id
     283                     );
     284
     285        if (count($data['genre']) > 0)
     286            foreach ($data['genre'] as $genre)
     287                $db->query('INSERT INTO videometadatagenre ( idvideo, idgenre )
     288                                                    VALUES (       ?,       ? )',
     289                            $id,
     290                            $Genre_Index[$genre]
     291                            );
     292
    160293        $return['update'][] = $id;
    161294    }
    162295