new_contents: # -*- coding: utf-8 -*-
  
  """
      This program 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 (at your option) any later version.
  
      This program 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 this program; if not, see <http://www.gnu.org/licenses/>.
  
      @author: hgg
  """
  from os.path import basename
  
  from module.utils import fs_encode
  from module.plugins.Hook import Hook
  from module.PyFile import PyFile
  
  class UnSkipOnFail(Hook):
      __name__ = 'UnSkipOnFail'
      __version__ = '0.01'
      __description__ = 'When a download fails, restart "skipped" duplicates.'
      __config__ = [('activated', 'bool', 'Activated', True),]
      __author_name__ = ('hagg',)
      __author_mail__ = ('')
  
      def downloadFailed(self, pyfile):
          pyfile_name = basename(pyfile.name)
          pid = pyfile.package().id
          msg = 'look for skipped duplicates for %s (pid:%s)...'
          self.logInfo(msg % (pyfile_name, pid))
          dups = self.findDuplicates(pyfile)
          for link in dups:
              # check if link is "skipped"(=4)
              if link.status == 4:
                  lpid = link.packageID
                  self.logInfo('restart "%s" (pid:%s)...' % (pyfile_name, lpid))
                  self.setLinkStatus(link, "queued")
  
      def findDuplicates(self, pyfile):
          """ Search all packages for duplicate links to "pyfile".
              Duplicates are links that would overwrite "pyfile".
              To test on duplicity the package-folder and link-name
              of twolinks are compared (basename(link.name)).
              So this method returns a list of all links with equal
              package-folders and filenames as "pyfile", but except
              the data for "pyfile" iotselöf.
              It does MOT check the link's status.
          """
          dups = []
          pyfile_name = fs_encode(basename(pyfile.name))
          # get packages (w/o files, as most file data is useless here)
          queue = self.core.api.getQueue()
          for package in queue:
              # check if package-folder equals pyfile's package folder
              if fs_encode(package.folder) == fs_encode(pyfile.package().folder):
                  # now get packaged data w/ files/links
                  pdata = self.core.api.getPackageData(package.pid)
                  if pdata.links:
                      for link in pdata.links:
                          link_name = fs_encode(basename(link.name))
                          # check if link name collides with pdata's name
                          if link_name == pyfile_name:
                              # at last check if it is not pyfile itself
                              if link.fid != pyfile.id:
                                  dups.append(link)
          return dups
  
      def setLinkStatus(self, link, new_status):
          """ Change status of "link" to "new_status".
              "link" has to be a valid FileData object,
              "new_status" has to be a valid status name
                (i.e. "queued" for this Plugin)
              It creates a temporary PyFile object using
              "link" data, changes its status, and tells
              the core.files-manager to save its data.
          """
          pyfile = PyFile(self.core.files,
                          link.fid,
                          link.url,
                          link.name,
                          link.size,
                          link.status,
                          link.error,
                          link.plugin,
                          link.packageID,
                          link.order)
          pyfile.setStatus(new_status)
          self.core.files.save()
          pyfile.release()
  
  
subject: add UnSkipOnFail hook