class MovieWindow(xbmcgui.Window):
    class widget(object):
        label = None
        button = None
        wlist = None
        mlist = None
        path = None

    def __init__(self):

        self.scalex = self.getWidth() / float(100)
        self.scaley = self.getHeight() / float(100)

        labelp = place()
        labelp.xpos = int(35 * self.scalex)
        labelp.ypos = int(5 * self.scaley)
        labelp.xsize = int(60 * self.scalex)
        labelp.ysize = int(5 * self.scaley)

        buttonp = place()
        buttonp.xpos = int(5 * self.scalex)
        buttonp.ypos = int(5 * self.scaley)
        buttonp.xsize = int(25 * self.scalex)
        buttonp.ysize = int(5 * self.scaley)

        listp = place()
        listp.xpos = int(5 * self.scalex)
        listp.ypos = int(20 * self.scaley)
        listp.xsize = int(90 * self.scalex)
        listp.ysize = int(60 * self.scaley)

        # Source widgets
        basey = 0
        self.src = self.widget()
        self.src.label = xbmcgui.ControlLabel(
            labelp.xpos, basey + labelp.ypos, labelp.xsize, labelp.ysize, getLS(16), "font14", "0xFFBBBBFF"
        )
        self.addControl(self.src.label)
        self.src.button = xbmcgui.ControlButton(
            buttonp.xpos, basey + buttonp.ypos, buttonp.xsize, buttonp.ysize, getLS(10)
        )
        self.addControl(self.src.button)
        self.src.wlist = xbmcgui.ControlList(
            listp.xpos,
            basey + listp.ypos,
            listp.xsize,
            listp.ysize,
            buttonFocusTexture="MenuItemFO.png",
            selectedColor="0xFFBBBBFF",
        )
        self.addControl(self.src.wlist)
        self.src.wlist.addItem(INIT_LIST_ITEM)

        # Destination widgets
        basey = int(5 * self.scaley)
        self.dst = self.widget()
        self.dst.label = xbmcgui.ControlLabel(
            labelp.xpos, basey + labelp.ypos, labelp.xsize, labelp.ysize, getLS(16), "font14", "0xFFBBBBFF"
        )
        self.addControl(self.dst.label)
        self.dst.button = xbmcgui.ControlButton(
            buttonp.xpos, basey + buttonp.ypos, buttonp.xsize, buttonp.ysize, getLS(11)
        )
        self.addControl(self.dst.button)
        # self.dst.wlist = xbmcgui.ControlList( basex + listp.xpos, listp.ypos,
        #        listp.xsize, listp.ysize, buttonFocusTexture="MenuItemFO.png",
        #        selectedColor='0xFFBBBBFF')
        # self.addControl(self.dst.wlist)
        # self.dst.wlist.addItem( INIT_LIST_ITEM )

        # Ok and Cancel
        okp = place()
        okp.xpos = int(85 * self.scalex)
        okp.ypos = int(85 * self.scaley)
        okp.xsize = int(10 * self.scalex)
        okp.ysize = int(10 * self.scaley)
        self.okButton = xbmcgui.ControlButton(okp.xpos, okp.ypos, okp.xsize, okp.ysize, getLS(12))
        self.addControl(self.okButton)
        cancelp = place()
        cancelp.xpos = int(70 * self.scalex)
        cancelp.ypos = int(85 * self.scaley)
        cancelp.xsize = int(10 * self.scalex)
        cancelp.ysize = int(10 * self.scaley)
        self.cancelButton = xbmcgui.ControlButton(cancelp.xpos, cancelp.ypos, cancelp.xsize, cancelp.ysize, getLS(13))
        self.addControl(self.cancelButton)

        # Options buttion
        optionp = place()
        optionp.xpos = int(5 * self.scalex)
        optionp.ypos = int(85 * self.scaley)
        optionp.xsize = int(15 * self.scalex)
        optionp.ysize = int(10 * self.scaley)
        self.optionButton = xbmcgui.ControlButton(
            optionp.xpos, optionp.ypos, optionp.xsize, optionp.ysize, getLS(14) + "..."
        )
        self.addControl(self.optionButton)

        # Set widgets order navigation
        self.src.button.controlUp(self.okButton)
        self.src.button.controlDown(self.dst.button)
        self.dst.button.controlUp(self.src.button)
        self.dst.button.controlDown(self.src.wlist)
        self.src.wlist.controlUp(self.dst.button)
        self.src.wlist.controlDown(self.okButton)
        self.src.wlist.controlLeft(self.okButton)
        self.src.wlist.controlRight(self.okButton)
        self.okButton.controlUp(self.src.wlist)
        self.okButton.controlDown(self.src.button)
        self.okButton.controlLeft(self.cancelButton)
        self.cancelButton.controlUp(self.src.wlist)
        self.cancelButton.controlDown(self.src.button)
        self.cancelButton.controlRight(self.okButton)
        self.cancelButton.controlLeft(self.optionButton)
        self.optionButton.controlUp(self.src.wlist)
        self.optionButton.controlDown(self.src.button)
        self.optionButton.controlRight(self.cancelButton)

        # Set focus
        self.setFocus(self.src.button)

        # Set default options
        self.options = OptionClass.getDefOptions()
        self.optionsWindow = OptionClass(options=self.options)

        # DB mng
        self.db = dbMng()

    def doModal(self):
        # Open DB
        self.db.open_conn()
        return super(MovieWindow, self).doModal()

    def onAction(self, action):
        if action == ACTION_PREVIOUS_MENU:
            # Close DB
            self.db.close_conn()
            self.close()

    def onControl(self, control):
        if control == self.src.button:
            self.on_widget_button(self.src)
            self.update_list(self.src)
        if control == self.dst.button:
            self.on_widget_button(self.dst)

        if control == self.src.wlist or control == self.dst.wlist:
            # Get selected item
            item = control.getSelectedItem()
            # Updated item state
            item.select(not item.isSelected())

        if control == self.okButton:
            self.on_ok_button()

        if control == self.cancelButton:
            self.on_cancel_button()

        if control == self.optionButton:
            self.optionsWindow.doModal()
            self.options = self.optionsWindow.getOptions()
            if self.src.mlist:
                self.update_list(self.src)

    def on_cancel_button(self):
        # Close DB
        self.db.close_conn()
        self.close()

    def on_widget_button(self, widget):
        dialog = xbmcgui.Dialog()
        # Get path lists
        paths = self.get_path_list()
        # Get selected option
        option_idx = dialog.select(getLS(23), paths)
        if option_idx < 0:
            return
        # Check path availability
        if not os.path.exists(paths[option_idx]):
            dialog.ok(getLS(20), getLS(21), getLS(22))
            return
            # Save option
        widget.path = paths[option_idx]
        # Set source lable properly
        widget.label.setLabel(paths[option_idx])
        # Update list

    # self.update_list( widget )
    # self.setFocus( widget.wlist )

    def on_ok_button(self):
        # Check values
        dialog = xbmcgui.Dialog()
        if self.src.path is None:
            dialog.ok(getLS(30), getLS(31))
            return
        if self.dst.path is None:
            dialog.ok(getLS(32), getLS(33))
            return
        if self.src.path == self.dst.path:
            dialog.ok(getLS(34), getLS(35))
            return
        sel_items = []
        for i in range(self.src.wlist.size()):
            if self.src.wlist.getListItem(i).isSelected():
                sel_items.append(i)
        if len(sel_items) > 0:
            if not dialog.yesno(getLS(36), "%d " % len(sel_items) + getLS(37), getLS(38)):
                return
        else:
            dialog.ok(getLS(39), getLS(40))
            return
        # Move Movies
        progress = xbmcgui.DialogProgress()
        progress.create(getLS(36))
        for i in sel_items:
            progress.update(
                sel_items.index(i) * 100 / len(sel_items), "", getLS(41) + " %s" % self.src.mlist[i].encode("utf-8")
            )
            self.move_movie(self.src.mlist[i], self.src.path, self.dst.path)
            if progress.iscanceled():
                break
        progress.close()
        # Update lists
        self.update_list(self.src)

    # self.update_list( self.dst )

    def update_list(self, widget):
        if widget.path:
            # Reset list
            widget.wlist.reset()
            # Popullate file list
            widget.mlist = self.get_movie_list(widget.path.meta)
            widget.wlist.addItems(widget.mlist)

    def get_path_list(self):
        # Create empty list
        res = []
        # Create query
        query = 'SELECT idPath, strPath \
                 FROM   path \
                 WHERE  strContent = "movies"'
        # Create a cursor
        c = self.db.create_cursor()
        # Launch query
        c.execute(query)
        # Build result
        for idp, strp in c:
            res.append(metaStr(strp, idp))
        # Close cursor
        c.close()
        # Return result
        return res

    def get_movie_list(self, id_path):
        # Create empty list
        res = []
        # Create query
        query = "SELECT f.idFile, m.c00 \
                 FROM   movie m, files f \
                 WHERE  m.idFile = f.idFile AND f.idPath = ?"
        if self.options["watched"]:
            query += "  AND f.playcount > 0 "
        query += "ORDER BY m.c00"
        # Create values
        value = (id_path,)
        # Create a cursor
        c = self.db.create_cursor()
        # Launch query
        c.execute(query, value)
        # Build result
        for idf, mov in c:
            res.append(metaStr(mov, idf))
        # Close cursor
        c.close()
        # Return result
        return res

    def move_movie(self, movie, old_path, new_path):
        ## Update file with new id
        # Create query
        query = "UPDATE files \
                 SET    idPath=? \
                 WHERE  idFile=?"
        # Create values
        value = new_path.meta, movie.meta
        # Create a cursor
        c = self.db.create_cursor()
        # Launch query
        c.execute(query, value)

        ### Move file
        ## Get filename
        # Create query
        query = "SELECT f.strFilename \
                 FROM   files f \
                 WHERE  f.idFile = ?"
        # Create values
        value = (movie.meta,)
        # Launch query
        c.execute(query, value)
        # Build result
        mfile = unicode(c.fetchone()[0])
        # mfile = unicode( c.fetchone()[0] )

        ## Deal with stacked files
        if mfile.startswith("stack://"):
            logging.dbg("Dealing with stacked files")
            # Update db file with new values
            query = "UPDATE files \
                     SET    strFilename=? WHERE idFile=?"
            # Create values
            strfn = mfile.replace(old_path, new_path)
            value = strfn, movie.meta
            # Launch query
            c.execute(query, value)
            # Get fanart cache filename and move it
            srcfn = xbmc.translatePath("special://thumbnails/Video") + "/Fanart/" + xbmc.getCacheThumbName(mfile)
            dstfn = xbmc.translatePath("special://thumbnails/Video") + "/Fanart/" + xbmc.getCacheThumbName(strfn)
            try:
                shutil.move(srcfn, dstfn)
                logging.dbg("move %s %s" % (srcfn, dstfn))
            except IOError, e:
                logging.err("Error moving %s %s: %s" % (srcfn, dstfn, e))
                pass
            # Create file list with removed whites spaces arround names
            mfiles = map(lambda x: x.strip(), mfile[8:].split(","))
        else:
class TVshowWindow(xbmcgui.Window):

    class widget( object ):
        label = None
        button = None
        w1list = None
        w2list = None
        tslist = None
        eplist = None
	path = None
        show = None
    
    def __init__(self):

        self.scalex = self.getWidth() / float( 100 ) 
        self.scaley = self.getHeight() / float( 100 )

	labelp = place()
	labelp.xpos = int( 35*self.scalex )
	labelp.ypos = int( 5*self.scaley )
	labelp.xsize = int( 60*self.scalex )
	labelp.ysize = int( 5*self.scaley )

	buttonp = place()
	buttonp.xpos = int( 5*self.scalex )
	buttonp.ypos = int( 5*self.scaley )
	buttonp.xsize = int( 25*self.scalex ) 
	buttonp.ysize = int( 5*self.scaley )

	listp = place()
	listp.xpos = int( 5*self.scalex )
	listp.ypos = int( 20*self.scaley )
	listp.xsize = int( 40*self.scalex )
	listp.ysize = int( 60*self.scaley )
	
        # Source widgets 
	basey = 0
        basex = 0
        self.src = self.widget()
        self.src.label = xbmcgui.ControlLabel( basex + labelp.xpos, basey + labelp.ypos,
                labelp.xsize, labelp.ysize, getLS(16), 'font14', '0xFFBBBBFF')
        self.addControl( self.src.label )
        self.src.button = xbmcgui.ControlButton( basex + buttonp.xpos, basey +
                buttonp.ypos, buttonp.xsize, buttonp.ysize, getLS(10) )
        self.addControl(self.src.button)
        self.src.w1list = xbmcgui.ControlList( basex + listp.xpos, basey + listp.ypos,
                listp.xsize, listp.ysize, buttonFocusTexture="MenuItemFO.png",
                selectedColor='0xFFBBBBFF')
        self.addControl(self.src.w1list)
        self.src.w1list.addItem( INIT_LIST_ITEM )
        basex = int( 50*self.scalex )
        self.src.w2list = xbmcgui.ControlList( basex + listp.xpos, basey + listp.ypos,
                listp.xsize, listp.ysize, buttonFocusTexture="MenuItemFO.png",
                selectedColor='0xFFBBBBFF')
        self.addControl(self.src.w2list)
        self.src.w2list.addItem( INIT_LIST_ITEM )

        # Destination widgets 
	basey = int( 5*self.scaley )
        self.dst = self.widget()
        self.dst.label = xbmcgui.ControlLabel( labelp.xpos, basey + labelp.ypos,
                labelp.xsize, labelp.ysize, getLS(16), 'font14', '0xFFBBBBFF')
        self.addControl( self.dst.label )
        self.dst.button = xbmcgui.ControlButton( buttonp.xpos, basey +
                buttonp.ypos, buttonp.xsize, buttonp.ysize, getLS(11) )
        self.addControl(self.dst.button)
	
        # Ok and Cancel
       	okp = place()
	okp.xpos = int( 85*self.scalex )
	okp.ypos = int( 85*self.scaley )
	okp.xsize = int( 10*self.scalex )
	okp.ysize = int( 10*self.scaley )
	self.okButton = xbmcgui.ControlButton( okp.xpos, okp.ypos,
	     okp.xsize, okp.ysize, getLS(12) )
        self.addControl(self.okButton)
       	cancelp = place()
	cancelp.xpos = int( 70*self.scalex )
	cancelp.ypos = int( 85*self.scaley )
	cancelp.xsize = int( 10*self.scalex )
	cancelp.ysize = int( 10*self.scaley )
	self.cancelButton = xbmcgui.ControlButton( cancelp.xpos, cancelp.ypos,
	     cancelp.xsize, cancelp.ysize, getLS(13) )
        self.addControl(self.cancelButton)

        # Options buttion 
       	optionp = place()
	optionp.xpos = int( 5*self.scalex )
	optionp.ypos = int( 85*self.scaley )
	optionp.xsize = int( 15*self.scalex )
	optionp.ysize = int( 10*self.scaley )
	self.optionButton = xbmcgui.ControlButton( optionp.xpos, optionp.ypos,
	     optionp.xsize, optionp.ysize, getLS(14)+"..." )
        self.addControl(self.optionButton)

        # Set widgets order navigation 
        self.src.button.controlUp( self.okButton )
        self.src.button.controlDown( self.dst.button )
        self.dst.button.controlUp( self.src.button )
        self.dst.button.controlDown( self.src.w1list )
        self.src.w1list.controlUp( self.dst.button )
        self.src.w1list.controlDown( self.okButton )
        self.src.w1list.controlLeft( self.okButton )
        self.src.w1list.controlRight( self.src.w2list )
        self.src.w2list.controlUp( self.dst.button )
        self.src.w2list.controlDown( self.okButton )
        self.src.w2list.controlLeft( self.src.w1list )
        self.src.w2list.controlRight( self.okButton )
        self.okButton.controlUp( self.src.w1list )
        self.okButton.controlDown( self.src.button )
        self.okButton.controlLeft( self.cancelButton )
        self.cancelButton.controlUp( self.src.w1list )
        self.cancelButton.controlDown( self.src.button )
        self.cancelButton.controlRight( self.okButton )
        self.cancelButton.controlLeft( self.optionButton )
        self.optionButton.controlUp( self.src.w1list )
        self.optionButton.controlDown( self.src.button )
        self.optionButton.controlRight( self.cancelButton )

        # Set focus 
        self.setFocus( self.src.button )

        # Set default options 
        self.options = OptionClass.getDefOptions() 
        self.optionsWindow = OptionClass( options=self.options )

        # DB mng
        self.db = dbMng()

    def doModal( self ):
        # Open DB 
        self.db.open_conn()
        return super( TVshowWindow, self ).doModal()

    def onAction(self, action):
        if action == ACTION_PREVIOUS_MENU:
            # Close DB 
            self.db.close_conn()
            self.close()

    def onControl(self, control):
        if control == self.src.button:
            self.on_widget_button( self.src )
	    self.update_tvshow_list( self.src )
        if control == self.dst.button:
            self.on_widget_button( self.dst )

        if control == self.src.w1list:
            if self.src.path:
                self.src.show = self.src.tslist[control.getSelectedPosition()] 
                self.update_episode_list( self.src )
                # Set focus on ep. list
                self.setFocus( self.src.w2list )

        if control == self.src.w2list:
            # Get selected item 
            item = control.getSelectedItem()
            # Updated item state 
            item.select( not item.isSelected() )

        if control == self.okButton:
            self.on_ok_button()

	if control == self.cancelButton:
            self.on_cancel_button()

	if control == self.optionButton:
            self.optionsWindow.doModal()
            self.options = self.optionsWindow.getOptions()
            if self.src.eplist:
	        self.update_episode_list( self.src )

    def on_cancel_button( self ):
        # Close DB 
	self.db.close_conn()
        self.close()

    def on_widget_button( self, widget ):
        dialog = xbmcgui.Dialog()
        # Get path lists 
        paths = self.get_path_list( )
        # Get selected option 
        option_idx = dialog.select( getLS(23), paths )
        if option_idx < 0:
            return 
	# Check path availability  
	if not os.path.exists( paths[option_idx] ):
	  dialog.ok( getLS(20), getLS(21), getLS(22) )
	  return
        # Save option 
        widget.path = paths[option_idx]
        # Set source lable properly 
        widget.label.setLabel( paths[option_idx] )

    def on_ok_button( self ):
        # Check values 
        dialog = xbmcgui.Dialog()
        if self.src.path is None:
            dialog.ok( getLS(30), getLS(31) )
            return
        if self.dst.path is None:
            dialog.ok( getLS(32), getLS(33) )
            return
        if self.src.path == self.dst.path:
            dialog.ok( getLS(34), getLS(35) )
            return
        sel_items = []
        for i in range( self.src.w2list.size() ):
            if self.src.w2list.getListItem( i ).isSelected(): 
                sel_items.append( i )
        if len( sel_items ) > 0:
            if not dialog.yesno( getLS(60), "%d " % len( sel_items ) 
                    + getLS(61)  , getLS(38) ):
                return 
        else:
            dialog.ok( getLS(62), getLS(63) )
            return
        # Move TV shows
        progress = xbmcgui.DialogProgress() 
        progress.create( getLS(60) )
        for i in sel_items:
            progress.update( sel_items.index( i ) * 100 / len( sel_items ),
                    "", getLS(41)+" %s" % self.src.eplist[i].encode('utf-8') )
            self.move_episode( self.src.eplist[i], self.src.path,
                    self.dst.path )
            if progress.iscanceled():
                break
        progress.close()
        # Update lists 
        self.update_episode_list( self.src )

    def update_tvshow_list( self, widget ):
        if widget.path:
            # Reset list 
            widget.w1list.reset()
            # Popullate file list 
            widget.tslist = self.get_tvshow_list( widget.path )
            widget.w1list.addItems( widget.tslist )

    def update_episode_list( self, widget ):
        if widget.show:
            # Reset list 
            widget.w2list.reset()
            # Popullate file list 
            widget.eplist = self.get_episode_list( widget.show ) 
            widget.w2list.addItems( widget.eplist ) 
 
    def get_path_list( self ):
        # Create empty list
        res = []
        # Create query 
        query = "SELECT idPath, strPath \
                 FROM   path \
                 WHERE  strContent = \"tvshows\""
        # Create a cursor
        c = self.db.create_cursor()
        # Launch query 
        c.execute( query )
        # Build result 
        for idp, strp in c:
            res.append( metaStr( strp, idp ) )
        # Close cursor 
        c.close()
        # Return result 
        return res

    def get_tvshow_list( self, path ):
        # Create empty list 
        res = []
        # Create query 
        query = "SELECT ts.idShow, ts.c00  \
                 FROM   tvshowlinkpath tslp, tvshow ts \
                 WHERE  tslp.idShow = ts.idShow AND idPath IN \
                        ( SELECT idPath \
                          FROM   path \
                          WHERE  strPath LIKE ? ) \
	         ORDER BY ts.c00"
        # Create values 
        value = path+"%", 
        # Create a cursor
        c = self.db.create_cursor()
        # Launch query 
        c.execute( query, value )
        # Build result 
        for ids, tvs in c:
            res.append( metaStr( tvs, ids ) )
        # Close cursor 
        c.close()
        # Return result 
        return res

    def get_episode_list( self, show ):
        # Create empty list 
        res = []
        # Create query 
        query = "SELECT e.c12, e.c13, e.c00, e.idFile \
                 FROM   tvshowlinkepisode tsle, episode e, files f \
                 WHERE  tsle.idEpisode = e.idEpisode AND e.idFile = f.idFile \
                        AND tsle.idShow = ?"
        if self.options["watched"]:
            query += "  AND f.playcount > 0 "
        # Create values 
        value = show.meta, 
        # Create a cursor
        c = self.db.create_cursor()
        # Launch query 
        c.execute( query, value )
        # Build result 
        for s, e, name, eid in c:
            res.append( metaStr( "%02dx%02d - %s" % ( int(s), int(e), name ), 
                eid ) )
        # Close cursor 
        c.close()
        # Return result 
        return sorted( res )

    def move_episode( self, episode, old_path, new_path ):
        logging.dbg( "moving episode '%s' from '%s' to '%s'" % ( episode,
            old_path, new_path ) ) 

	# Create a cursor
        c = self.db.create_cursor()

	## Get filename, path, show and episode id and season number
	# Create query 
        query = "SELECT e.idEpisode, f.strFilename, p.strPath, p.idPath, \
                        tsle.idShow, e.c12 \
                 FROM   episode e, files f, path p, tvshowlinkepisode tsle \
                 WHERE  e.idFile = f.idFile AND f.idPath = p.idPath \
                        AND tsle.idEpisode = e.idEpisode AND f.idFile = ?"
        # Create values 
        value = episode.meta, 
        # Launch query 
	c.execute( query, value )
        # Build result 
        res = c.fetchone()
	eid   = res[0]
	efile = unicode( res[1] )
	epath = unicode( res[2] )
	eidpath = res[3]
        eidshow = res[4]
        season = int( res[5] )
        logging.dbg( "filename: '%s'" % ( epath+efile ) )

        # Compute new path
        new_epath = epath.replace( old_path, new_path )

        ## Check if new path exists on DB 
        # Create query 
        query = "SELECT p.idPath \
                 FROM   path p \
                 WHERE  p.strPath = ?"
        # Create values 
        value = new_epath, 
        # Launch query 
	c.execute( query, value )
        # Build result 
	res = c.fetchone()
        if res:
            new_eidpath = res[0]
        else:
            logging.dbg( "Path does not exist on db" )
            ## Insert new path on DB
            # Create query 
            query = "INSERT INTO path \
                            ( strPath, strContent, strScraper) \
                     VALUES ( ?, '', '')"
            # Create values 
            value = new_epath,
            # Launch query 
            c.execute( query, value )
            # Get new id
            new_eidpath = c.lastrowid
            logging.dbg( "New path id: %d" %( new_eidpath ) )

        # Try to Create new path on system
        try:
            os.makedirs( new_epath )
            logging.dbg( "Creating directory '%s'" % ( new_epath ) )
        except OSError, e:
            if e.errno == errno.EEXIST:
                pass
            else:
                logging.err( "Error Creating directory '%s': %s" % (
                    new_epath, e.strerror ) )
                return

        ## Get new show id and path 
        # Create query 
        query = "SELECT p.strPath, tslp.idShow \
                 FROM   tvshowlinkpath tslp, path p \
                 WHERE  tslp.idPath = p.idPath"
        # Launch query 
        c.execute( query )
        # check result
        for new_tspath, new_idshow in c:
            if unicode( new_tspath ) in new_epath:
                break
        else:
            # Create a new TV show on DB
            logging.dbg( "Cannot find a proper TV show for this path '%s'.\
 Creating a new one." % ( new_epath) )
            new_tspath, new_idshow = self.create_new_tvshow( eidshow, old_path,
                    new_path, c )
            if new_idshow is None:
                return

        ## Update file with new path id 
        # Create query 
        query = "UPDATE files \
                 SET    idPath = ? \
                 WHERE  idFile = ?"  
        # Create values 
        value = new_eidpath, episode.meta
        # Launch query 
        c.execute( query, value )

        ## Update episode link with new show id 
        # Create query 
        query = "UPDATE tvshowlinkepisode \
                 SET    idShow = ? \
                 WHERE  idEpisode = ?"  
        # Create values 
        value = new_idshow, eid
        # Launch query 
        c.execute( query, value )

        ## Copy season fanart cache
        # http://forum.xbmc.org/showthread.php?p=324453#post324453
        dst = "season" + unicode( new_tspath ) + xbmc.getLocalizedString( 20358 )
        dst = dst % season
        src = dst.replace( new_path, old_path ) 
        logging.dbg( "src season fanart: %s" % src )
        logging.dbg( "dst season fanart: %s" % dst )
        # Get cache file names
        thsrc = xbmc.getCacheThumbName( src )
        thdst = xbmc.getCacheThumbName( dst )
        # Get thumbnail fname
        srcfn = xbmc.translatePath( 'special://thumbnails/Video' ) + "/" + thsrc[0] + "/" + thsrc 
        dstfn =  xbmc.translatePath( 'special://thumbnails/Video' ) + "/" + thdst[0] + "/" + thdst 
        # Copy files
        try:
            shutil.copy( srcfn, dstfn )
            logging.dbg( "copy %s %s" % ( srcfn, dstfn ) )
        except IOError, e:
            logging.err( "Error copying '%s' to '%s': %s" % ( srcfn, dstfn, e ) )
            pass