diff --git a/classes/Video.php b/classes/Video.php
index 5c6f7e4..76a621e 100644
--- a/classes/Video.php
+++ b/classes/Video.php
@@ -39,6 +39,7 @@ class Video {
             SELECT  dirname
             FROM    storagegroup
             WHERE   groupname="Coverart"
+            OR groupname="Fanart"
         ');
 
         $video = $db->query_assoc('
@@ -62,9 +63,16 @@ class Video {
         $this->showlevel    = $video['showlevel'];
         $this->filename     = $video['filename'];
         $this->cover_file   = $video['coverfile'];
+        $this->fanart_file  = $video['fanart'];
         $this->browse       = $video['browse'];
     // And the artwork URL
         $this->cover_url = '';
+        $fanart=false;
+        if (!$this->cover_file && $this->fanart_file) {
+            $foo = explode('/', $this->fanart_file);
+            $this->cover_file = $foo[count($foo) - 1];
+            $fanart=true;
+        }
         if ($this->cover_file && $this->cover_file != 'No Cover') {
             $exists = false;
             foreach ($video_dirs as $dir) {
@@ -75,7 +83,11 @@ class Video {
                 }
             }
             if ($exists) {
-                $this->cover_url = 'pl/coverart/'.$this->cover_file;
+                if ($fanart) {
+                    $this->cover_url = 'pl/fanart/'.$this->cover_file;
+                } else {
+                    $this->cover_url = 'pl/coverart/'.$this->cover_file;
+                }
                 $this->cover_file = $path;
                 list($width, $height) = @getimagesize($this->cover_file);
                 if ($width > 0 && $height > 0) {
diff --git a/modules/fanart/handler.pl b/modules/fanart/handler.pl
new file mode 100644
index 0000000..b149dea
--- /dev/null
+++ b/modules/fanart/handler.pl
@@ -0,0 +1,159 @@
+#!/usr/bin/perl
+#
+# MythWeb Coverart/Download module
+#
+#
+
+# Necessary constants for sysopen
+    use Fcntl;
+
+# Other includes
+    use Sys::Hostname;
+    use HTTP::Date;
+
+# Attempt to use the perl bindings to prevent the backend from shutting down during streaming
+    eval 'use MythTV;';
+
+    if (!$@) {
+        our $mythbackend = new MythTV();
+        $mythbackend->backend_command('ANN Playback '.hostname);
+    }
+
+# Which cover are we displaying
+    our $cover    = url_param('cover');
+    if ($Path[1]) {
+        $cover    = $Path[1];
+    }
+
+# No match?
+    unless ($cover =~ /\w/) {
+        print header(),
+              "Unknown cover requested.\n";
+        exit;
+    }
+
+# Find the local file
+    our $filename;
+    $sh = $dbh->prepare('SELECT dirname FROM storagegroup WHERE groupname = "Fanart"');
+    $sh->execute();
+    while (my ($coverart_dir) = $sh->fetchrow_array()) {
+        next unless (-e "$coverart_dir/$cover");
+        $filename = "$coverart_dir/$cover";
+        last;
+    }
+    $sh->finish;
+
+    1;
+
+    unless ($filename) {
+        print header(),
+              "$cover does not exist in any recognized storage group directories for this host.";
+        exit;
+    }
+
+# File size
+    my $size = -s $filename;
+
+# Zero bytes?
+    if ($size < 1) {
+        print header(),
+              "$cover is an empty file.";
+        exit;
+    }
+
+# File type
+    my $type   = 'text/html';
+    my $suffix = '';
+    if ($cover =~ /\.jpg$/) {
+        $type   = 'image/jpeg';
+        $suffix = '.jpg';
+    }
+    else {
+        print header(),
+              "Unknown image type requested:  $cover\n";
+        exit;
+    }
+
+# Open the file for reading
+    unless (sysopen DATA, $filename, O_RDONLY) {
+        print header(),
+              "Can't read $cover:  $!";
+        exit;
+    }
+
+# Binmode, in case someone is running this from Windows.
+    binmode DATA;
+
+    my $start      = 0;
+    my $end        = $size;
+    my $total_size = $size;
+    my $read_size  = 1024;
+    my $mtime      = (stat($filename))[9];
+
+# Handle cache hits/misses
+    if ( $ENV{'HTTP_IF_MODIFIED_SINCE'}) {
+        my $check_time = str2time($ENV{'HTTP_IF_MODIFIED_SINCE'});
+        if ($mtime <= $check_time) {
+            print header(-Content_type           => $type,
+                         -status                 => "304 Not Modified"
+                        );
+            exit;
+        }
+    }
+
+# Requested a range?
+    if ($ENV{'HTTP_RANGE'}) {
+    # Figure out the size of the requested chunk
+        ($start, $end) = $ENV{'HTTP_RANGE'} =~ /bytes\W+(\d*)-(\d*)\W*$/;
+        if ($end < 1 || $end > $size) {
+            $end = $size;
+        }
+        $size = $end - $start+1;
+        if ($read_size > $size) {
+            $read_size = $size;
+        }
+        print header(-status                => "206 Partial Content",
+                     -type                  => $type,
+                     -Content_length        => $size,
+                     -Accept_Ranges         => 'bytes',
+                     -Content_Range         => "bytes $start-$end/$total_size",
+                     -Last_Modified         => time2str($mtime),
+                     -Content_disposition => " attachment; filename=\"$cover\""
+                 );
+    }
+    else {
+        print header(-type                  => $type,
+                    -Content_length         => $size,
+                    -Accept_Ranges          => 'bytes',
+                    -Last_Modified          => time2str($mtime),
+                    -Content_disposition => " attachment; filename=\"$cover\""
+                 );
+    }
+
+# Seek to the requested position
+    sysseek DATA, $start, 0;
+
+# Print the content to the browser
+    my $buffer;
+    while (sysread DATA, $buffer, $read_size ) {
+        print $buffer;
+        $size -= $read_size;
+        if ($size == 0) {
+            last;
+        }
+        if ($size < $read_size) {
+            $read_size = $size;
+        }
+    }
+    close DATA;
+
+# Escape a parameter for safe use in a commandline call
+    sub shell_escape {
+        $str = shift;
+        $str =~ s/'/'\\''/sg;
+        return "'$str'";
+    }
+
+# Return true
+    1;
+
diff --git a/modules/fanart/init.php b/modules/fanart/init.php
new file mode 100644
index 0000000..ce88ab4
--- /dev/null
+++ b/modules/fanart/init.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Initialization routines for the MythWeb Video Coverart module
+ *
+ * @license     GPL
+ *
+ * @package     MythWeb
+ * @subpackage  Video Coverart
+ *
+/**/
+?>
diff --git a/modules/video/handler.php b/modules/video/handler.php
index 721f186..ff9e3fd 100644
--- a/modules/video/handler.php
+++ b/modules/video/handler.php
@@ -205,9 +205,12 @@
 
 // Get the video categories on the system
     $Category_String = array();
+    $Category_Index = array();
     $sh = $db->query('SELECT * FROM videocategory ORDER BY category');
-    while ($row = $sh->fetch_assoc())
+    while ($row = $sh->fetch_assoc()) {
         $Category_String[$row['intid']] = $row['category'];
+        $Category_Index[$row['category']] = $row['intid'];
+    }
     $sh->finish();
     $Category_String[0] = t('Uncategorized');
 
diff --git a/modules/video/imdb.php b/modules/video/imdb.php
index 1892e54..89ddab6 100644
--- a/modules/video/imdb.php
+++ b/modules/video/imdb.php
@@ -47,21 +47,32 @@
                                   'ALLOCINE' => array( ' -M "%%TITLE%%"')
                                  );
 
-        $dupe = array();
         foreach ($options[$imdbwebtype] as $option) {
             $cmd = $imdb.str_replace('%%TITLE%%', $title, $option);
             exec($cmd, $output, $retval);
             if ($retval == 255)
                 $return['warning'][] = "IMDB Command $cmd exited with return value $retval";
+            if (!count($output)) {
+                $title_parts = explode(' ', $title);
+                $cmd = $imdb.str_replace('%%TITLE%%', $title_parts[0], $option);
+                exec($cmd, $output, $retval);
+                if ($retval == 255)
+                    $return['warning'][] = "IMDB Command $cmd exited with return value $retval";
+            }
             if (!count($output))
                 continue;
+            $single_output='';
             foreach ($output as $line) {
-                list($imdbid, $title) = explode(':', $line, 2);
-                if ($dupe[$imdbid])
-                    continue;
-                $dupe[$imdbid] = true;
-                $return['matches'][] = array('imdbid' => $imdbid,
-                                             'title'  => $title);
+                $single_output=$single_output.$line;
+            }
+            $xml = simplexml_load_string($single_output);
+
+            foreach ($xml as $item) {
+                if (strlen($item->imdb) > 1) {
+                    $imdbid = (string)$item->imdb;
+                    $title = (string)$item->title;
+                    $return['matches'][] = array('imdbid' => $imdbid, 'title' => $title);
+                }
             }
         }
     }
@@ -70,6 +81,29 @@
     {
         global $db;
         global $return;
+
+ //  Get the video genres on the system
+     $Genre_String = array();
+     $Genre_Index = array();
+     $sh = $db->query('SELECT * FROM videogenre ORDER BY genre');
+     while ($row = $sh->fetch_assoc()) {
+         $Genre_String[$row['intid']] = $row['genre'];
+         $Genre_Index[$row['genre']] = $row['intid'];
+     }
+     $sh->finish();
+     $Genre_String[0] = t('No Genre');
+
+
+     $Category_String = array();
+     $Category_Index = array();
+     $sh = $db->query('SELECT * FROM videocategory ORDER BY category');
+     while ($row = $sh->fetch_assoc()) {
+         $Category_String[$row['intid']] = $row['category'];
+         $Category_Index[$row['category']] = $row['intid'];
+     }
+     $sh->finish();
+     $Category_String[0] = t('Uncategorized');
+
         $return['action'] = 'grab';
         $imdb             = setting('web_video_imdb_path', hostname);
         $imdbwebtype      = setting('web_video_imdb_type', hostname);
@@ -94,29 +128,105 @@
             return;
         }
         $posterfile = "$artwork_dir/$imdbnum.jpg";
+
+    # Figure out the fanart directory
+        $fanartwork_dirs = $db->query_list('
+            SELECT  dirname
+            FROM    storagegroup
+            WHERE   groupname="Fanart"
+            ');
+        if (empty($fanartwork_dirs)) {
+            $return['warning'][] = 'MythWeb now requires use of the Fanart Storage Group.';
+            return;
+        }
+        foreach ($fanartwork_dirs as $dir) {
+            if (is_dir($dir) || is_link($dir)) {
+                $fanartwork_dir = $dir;
+                break;
+            }
+        }
+        if (empty($fanartwork_dir)) {
+            $return['warning'][] = 'Could not find a valid Fanart Storage Group directory';
+            return;
+        }
+        $fanartfile = "$fanartwork_dir/$imdbnum.jpg";
+
+
     // Get the imdb data
         $data = array();
         $cmd = "$imdb -D $imdbnum";
-        exec($cmd, $lines, $retval);
+        exec($cmd, $output, $retval);
         if ($retval == 255 || $DEBUG) {
             $return['warning'][] = "IMDB Command $cmd exited with return value $retval";
         }
-        $valid = FALSE;
-        foreach ($lines as $line) {
-            list ($key, $value) = explode(':', $line, 2);
-            $data[strtolower($key)] = trim($value);
-            if (strlen($data[strtolower($key)]) > 0) {
-                $valid = TRUE;
+        $single_output='';
+        foreach ($output as $line) {
+            $single_output=$single_output.$line;
+        }
+        $xml = simplexml_load_string($single_output);
+
+        foreach ($xml as $item) {
+          $data['title'] = (string)$item->title;
+          $data['plot'] = (string)$item->description;
+          $date = date_parse($item->releasedate);
+          $data['year'] = (string)$date['year'];
+          $data['userrating'] = (string)$item->userrating;
+          $data['runtime'] = (string)$item->runtime;
+          if ($item->certifications) {
+            foreach ($item->certifications->certification as $cert) {
+              if (strtoupper($cert->attributes()->locale) == "US" && !$data['movierating']) {
+                $data['movierating'] = (string)$cert->attributes()->name;
+              }
+            }
+          }
+          if ($item->people) {
+            foreach ($item->people->person as $person) {
+              if (strtoupper($person->attributes()->job) == "DIRECTOR" && !$data['director']) {
+                $data['director'] = (string)$person->attributes()->name;
+              }
+            }
+          }
+          $data['coverart']='';
+          $data['fanart']='';
+          foreach ($item->images->image as $image_data) {
+            if ($image_data->attributes()->type == 'coverart' && !$data['coverart']) {
+              $data['coverart'] = (string)$image_data->attributes()->url;
             }
+            if ($image_data->attributes()->type == 'fanart' && !$data['fanart']) {
+              $data['fanart'] = (string)$image_data->attributes()->url;
+            }
+          }
         }
-        if (!$valid) {
-            $return['error'][] = t('Video: Error: IMDB');
-            return;
+        $data['genre'] = array();
+        foreach ($item->categories->category as $cat) {
+          array_push($data['genre'], (string)$cat->attributes()->name);
         }
     // If the file already exists, use it, don't bother regrabbing
         if (!file_exists($posterfile)) {
             $posterurl = $data['coverart'];
-            if (!is_writable($artwork_dir))
+            if (!is_writable($artwork_dir)) {
+                $return['warning'][] = t('Video: Warning: Artwork');
+            } else {
+                if (!ini_get('allow_url_fopen')) {
+                    $return['warning'][] = t('Video: Warning: fopen');
+                } elseif(strlen($posterurl) > 0) {
+                    $posterurl = preg_replace('/,.+$/', '', $posterurl);    // For now, only bother to grab the first poster URL
+                    $posterjpg = @file_get_contents($posterurl);
+                    if ($posterjpg === FALSE)
+                        $return['warning'][] = t('Video: Warning: Artwork: Download');
+                    else {
+                        @file_put_contents( $posterfile, $posterjpg);
+                        if (!file_exists($posterfile))
+                            $return['warning'][] = t('Video: Warning: Artwork');
+                    }
+                }
+            }
+        }
+    // rinse and repeat for fanart
+    // If the file already exists, use it, don't bother regrabbing
+        if (!file_exists($fanartfile)) {
+            $posterurl = $data['fanart'];
+            if (!is_writable($fanartwork_dir))
                 $return['warning'][] = t('Video: Warning: Artwork');
             else {
                 if (!ini_get('allow_url_fopen'))
@@ -127,36 +237,59 @@
                     if ($posterjpg === FALSE)
                         $return['warning'][] = t('Video: Warning: Artwork: Download');
                     else {
-                        @file_put_contents( $posterfile, $posterjpg);
-                        if (!file_exists($posterfile))
+                        @file_put_contents( $fanartfile, $posterjpg);
+                        if (!file_exists($fanartfile))
                             $return['warning'][] = t('Video: Warning: Artwork');
                     }
                 }
             }
         }
+
+        if (!$Category_Index[$data['genre'][0]]) {
+            $db->query('INSERT INTO videocategory SET category = ?', $data['genre'][0]);
+        }
+
     // Update the database
         $sh = $db->query('UPDATE videometadata
                              SET title        = ?,
                                  director     = ?,
                                  plot         = ?,
                                  rating       = ?,
+                                 category     = ?,
                                  inetref      = ?,
                                  year         = ?,
                                  userrating   = ?,
                                  length       = ?,
-                                 coverfile    = ?
+                                 coverfile    = ?,
+                                 fanart       = ?
                            WHERE intid        = ?',
                          $data['title'],
                          $data['director'],
                          $data['plot'],
                          $data['movierating'],
+                         $Category_Index[$data['genre'][0]],
                          $imdbnum,
                          $data['year'],
                          $data['userrating'],
                          $data['runtime'],
                          ( @filesize($posterfile) > 0 ? "$imdbnum.jpg" : 'No Cover' ),
+                         ( @filesize($fanartfile) > 0 ? "$imdbnum.jpg" : 'No Cover' ),
                          $id
                          );
+
+        $db->query('DELETE FROM videometadatagenre
+                     WHERE videometadatagenre.idvideo = ?',
+                     $id
+                     );
+
+        if (count($data['genre']) > 0)
+            foreach ($data['genre'] as $genre)
+                $db->query('INSERT INTO videometadatagenre ( idvideo, idgenre )
+                                                    VALUES (       ?,       ? )',
+                            $id,
+                            $Genre_Index[$genre]
+                            );
+
         $return['update'][] = $id;
     }
 
