Пример #1
0
 def __init__(self, id=None ):
   self.addon   = xbmcaddon.Addon() if id == None else xbmcaddon.Addon(id=id)
   self.name    = Text.xbmcFrom( self.addon.getAddonInfo("name"   ) )
   self.version = Text.xbmcFrom( self.addon.getAddonInfo("version") )
   self.id      = Text.xbmcFrom( self.addon.getAddonInfo("id"     ) )
   self.path    = Text.xbmcFrom( self.addon.getAddonInfo("path"   ) )
   self.data    = Text.xbmcFrom( xbmc.translatePath('special://profile/addon_data/%s' % (self.id)) )
   self.config  = Config(self.addon)
   self.tracker = GaTracker()
   sm.addon     = self.addon
   self.initPaths()
Пример #2
0
class Addon:
  #============================================================================
  # Create a new addon
  #============================================================================
  def __init__(self, id=None ):
    self.addon   = xbmcaddon.Addon() if id == None else xbmcaddon.Addon(id=id)
    self.name    = Text.xbmcFrom( self.addon.getAddonInfo("name"   ) )
    self.version = Text.xbmcFrom( self.addon.getAddonInfo("version") )
    self.id      = Text.xbmcFrom( self.addon.getAddonInfo("id"     ) )
    self.path    = Text.xbmcFrom( self.addon.getAddonInfo("path"   ) )
    self.data    = Text.xbmcFrom( xbmc.translatePath('special://profile/addon_data/%s' % (self.id)) )
    self.config  = Config(self.addon)
    self.tracker = GaTracker()
    sm.addon     = self.addon
    self.initPaths()
  #============================================================================
  # Run the addon
  #============================================================================
  def run(self):
    self.tracker.trackPage('run')
    dt = self.diffLastUpdate(1)
    items = dt.days * 2
    items = 100 if items >= 100 else items
    self.log(u'fetching {0}'.format(items))
    self.runItems(items)
  #============================================================================
  # Run the addon
  #============================================================================
  def runItems(self,items):
    self.notify( sm.str(sm.seriesStart) )
    feeder = ImdbFeeder()
    loadInfo = self.loadSeries(feeder,items)
    self.notify( sm.str(sm.seriesEnd).format(loadInfo.added, loadInfo.episodes))
  #============================================================================
  # add series
  #============================================================================
  def addSeries(self):
    self.tracker.trackPage('addSeries')
    self.runItems( self.config.getInt("refresh_size") )
  #============================================================================
  # add episodes
  #============================================================================
  def addEpisode(self):
    self.tracker.trackPage('addEpisode')
    self.notify( sm.str(sm.episodeStart) )
    feeder = ImdbFeeder()
    loadInfo =self.loadEpisodes(feeder,0)
    self.notify( sm.str(sm.episodeEnd).format(loadInfo.added, loadInfo.episodes) )
  #============================================================================
  # Run the addon as service
  #============================================================================
  def service(self):
    self.log('Service Start')
    addS = ServiceAction(1, self.addSeries  , self.config)
    addE = ServiceAction(2, self.addEpisode , self.config)
    while (not xbmc.abortRequested):
      try:
        #self.log('addS {0:2} {1:3} {2}, addE {3:2} {4:3} {5}'.format(addS.count, addS.left(), addS.isDone(),addE.count, addE.left(), addE.isDone()))
        if addS.isDone() and addE.isDone():
          break
        addS.run()
        addE.run()
        time.sleep(60)
      except:
        break
    self.log('Service End')
  #============================================================================
  # Run the and fetch number of items as refresh_size
  #============================================================================
  def updateNow(self):
    self.tracker.trackPage('updateNow')
    refreshSize = self.config.getInt("refresh_size")
    self.runItems(refreshSize)
  #============================================================================
  # Load Bundle from source
  #   Params: source - the source directory
  #============================================================================
  def loadBundles(self):
    self.tracker.trackPage('loadBundles')
    self.notify( sm.str(sm.bundlesStart) )
    feeder = ImdbBundleFeeder()
    feeder.source = self.translatePath( self.config.getStr('bundle_source') )
    loadInfo = self.loadSeries(feeder,0)
    self.notify( sm.str(sm.bundlesEnd).format(loadInfo.added, loadInfo.episodes) )
  #============================================================================
  # Load Bundle from source
  #   Params: source - the key for the source
  #============================================================================
  def loadPackage(self,configKey):
    self.tracker.trackPage('loadPackage')
    self.notify( sm.str(sm.packageStart) )
    feeder = ImdbBundleFeeder()
    feeder.cache = self.cache
    feeder.package = self.translatePath( self.config.getStr(configKey) )
    loadInfo = self.loadSeries(feeder,0)
    self.notify( sm.str(sm.packageEnd).format(loadInfo.added, loadInfo.episodes) )
  #============================================================================
  # Load Bundle from source
  #   Params: source - the key for the source
  #============================================================================  
  def loadImdbIdList(self):
    self.tracker.trackPage('loadImdbIdList')
    feeder = ImdbBundleFeeder()
    feeder.cache = self.cache
    feeder.imdbIdList = [ ss.strip() for ss in self.config.getStr('package_text').split(',') ]
    loadInfo = self.loadSeries(feeder,0)
    self.notify( sm.str(sm.packageEnd).format(loadInfo.added, loadInfo.episodes) )
  #============================================================================
  # Load filters
  #============================================================================
  def loadFilters(self):
    return FilterInfo(self.addon)
  #============================================================================
  # Display message dialog
  #   Params : title   = the title text
  #            message = the message text
  #============================================================================
  def message(self,title,message):
    xbmcgui.Dialog().ok( Text.xbmcTo(title), Text.xbmcTo(message) )
  #============================================================================
  # Display notify message
  #   Params : message = the message text
  #============================================================================
  def notify(self,message):
    if self.config.getBool('notify'):
      xbmc.executebuiltin(Text.xbmcTo(u'XBMC.Notification({0},{1},{2},{3})'.format(self.name, message , 5 , os.path.join( self.path ,"icon.png" ))) )
  #============================================================================
  # Init the paths
  #============================================================================
  def initPaths(self):
    self.dirRoot    = self.path
    self.cache      = os.path.join( self.data   , "Cache"   )
    self.dirLogs    = os.path.join( self.data   , "Logs"    )

    File.ensureFolder(self.cache  )
    File.ensureFolder(self.dirLogs)

    FileLoader.dirCache = os.path.join( self.data, "Cache" )

    SeriesInfo.tvdbMoldDir = os.path.join( self.dirRoot   , "html" )
    Log.log = self.log
  #============================================================================
  # Add source directory
  #   Params : name = the name of the source
  #            path = the path of the source
  #============================================================================
  def addSource(self,name,path):
    sources_filename = xbmc.translatePath("special://userdata/sources.xml")
    ndRoot =  None
    if os.path.exists(sources_filename):
      tree = et.parse(sources_filename)
    else:
      root = et.fromstring('<sources> <programs> <default pathversion="1"></default> </programs> <video>    <default pathversion="1"></default> </video> <music>    <default pathversion="1"></default> </music> <pictures> <default pathversion="1"></default> </pictures> <files>    <default pathversion="1"></default> </files> </sources>')
      tree = et.ElementTree(root)
    ndVideo = tree.find("./video")
    for ndSource in ndVideo:
      if ndSource.tag == "source":
        ndName = ndSource.find("name")
        if ndName.text == name:
          return
    ndSource = et.Element("source")
    et.SubElement(ndSource, "name").text = name
    et.SubElement(ndSource, "path").text = path
    ndVideo.append(ndSource)
    tree.write(sources_filename)
  #============================================================================
  # Scan the source
  #   Params : path = the path of the source
  #============================================================================
  def scanSource(self,path=None):
    time.sleep(1)
    while xbmc.getCondVisibility('Library.IsScanning') or xbmc.getCondVisibility('Window.IsActive(10101)'):
      time.sleep(1)
    xbmc.executebuiltin('UpdateLibrary({0})'.format('video'))
  #============================================================================
  # Clean the source
  #   Params : path = the path of the source
  #============================================================================
  def cleanSource(self,path=None):
    time.sleep(1)
    while xbmc.getCondVisibility('Library.IsScanning') or xbmc.getCondVisibility('Window.IsActive(10101)'):
      time.sleep(1)
    xbmc.executebuiltin("CleanLibrary({0})".format('video'))
  #============================================================================
  # log a message
  #   Params : message = The message
  #============================================================================
  def log(self,message, filename="main.log"):
    now = datetime.datetime.now()
    try :
      logFile = os.path.join(self.dirLogs,filename)
      with codecs.open(logFile, mode='a+') as ff:
        ff.write( '{2:02}/{1:02}|{3:02}:{4:02}:{5:02} : {6}'.format(
          now.year,
          now.month,
          now.day,
          now.hour,
          now.minute,
          now.second,
          message
        ))
        ff.write('\n')
    except:
      pass
  #============================================================================
  # Translate path special places
  #   Params: path - the path
  #   Return: The translated path
  #============================================================================
  def translatePath(self,path):
    path = path.replace('{home}',self.path)
    path = path.replace('{data}',self.data)
    return path
  #============================================================================
  # Save current time as last update time
  #============================================================================
  def saveLastUpdate(self,id):
    self.config.setStr( 'last_update{0}'.format(id), datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') )
  #============================================================================
  # Save current time as last update time
  #============================================================================
  def diffLastUpdate(self,id):
    date = self.config.getStr('last_update{0}'.format(id))
    lastUpdate = datetime.datetime(2000,1,1,0,0,0)
    try:
      lastUpdate = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
    except:
      pass
    return datetime.datetime.now() - lastUpdate
  #============================================================================
  # Clean the library
  #============================================================================
  def cleanLibrary(self):
    File.delFiles(self.library)
    self.cleanSource()
    self.notify( sm.str(sm.cleanLibrary) )
  #============================================================================
  # Clean the cache
  #============================================================================
  def cleanCache(self):
    File.delFiles(self.cache)
    self.notify( sm.str(sm.cleanCache) )
  #============================================================================
  # Clean the logs
  #============================================================================
  def cleanLogs(self):
    File.delFiles(self.dirLogs)
    self.notify( sm.str(sm.cleanLogs) )
  #============================================================================
  # library
  #============================================================================
  @property
  def library(self):
    library = self.config.getStr('library')
    if library == '':
      library = os.path.join( self.data   , "Library" )
    SeriesInfo.tvdbDataDir = os.path.join( library   , ".tvdb" )
    SeriesInfo.tvdbHtmlDir = os.path.join( library   , ".html" )

    File.ensureFolder(library)
    File.ensureFolder(SeriesInfo.tvdbDataDir)
    File.ensureFolder(SeriesInfo.tvdbHtmlDir)
    return library
  #============================================================================
  def loadSeries(self,feeder,items):
    loadInfo = LoadInfo( FilterInfo(self.config) , items )
    self.addSource(self.name,self.library)
    feeder.withThumb = self.config.getBool('with_thumb')
    feeder.streamMode= self.config.getInt('stream_mode')
    feeder.dirTarget = self.library
    feeder.addSeries(loadInfo)
    self.scanSource(self.library)
    self.saveLastUpdate(1)
    return loadInfo
  #============================================================================
  def loadEpisodes(self,feeder,items):
    loadInfo = LoadInfo(FilterInfo(self.config) , items)
    self.addSource(self.name,self.library)
    feeder.withThumb = self.config.getBool('with_thumb')
    feeder.streamMode= self.config.getInt('stream_mode')
    feeder.dirTarget = self.library
    feeder.addEpisode(loadInfo)
    self.scanSource(self.library)
    self.saveLastUpdate(2)
    return loadInfo
Пример #3
0
class Addon:
  #============================================================================
  # Create a new addon
  #============================================================================
  def __init__(self, id=None ):
    self.addon   = xbmcaddon.Addon() if id == None else xbmcaddon.Addon(id=id)
    self.name    = Text.xbmcFrom( self.addon.getAddonInfo("name"   ) )
    self.version = Text.xbmcFrom( self.addon.getAddonInfo("version") )
    self.id      = Text.xbmcFrom( self.addon.getAddonInfo("id"     ) )
    self.path    = Text.xbmcFrom( self.addon.getAddonInfo("path"   ) )
    self.data    = xbmc.translatePath('special://profile/addon_data/%s' % (self.id))
    self.config  = Config(self.addon)
    self.tracker = GaTracker()
    sm.addon     = self.addon
    self.initPaths()
  #============================================================================
  # Run the addon
  #============================================================================
  def run(self):
    self.tracker.trackPage('run')
    lastUpdate = self.config.getStr('last_update')
    dt = self.diffLastUpdate()
    items = dt.days * 2
    items =  32 if items <= 32  else items
    items = 320 if items >= 320 else items
    self.log("fetching {0}".format(items))
    self.runItems(items)
  #============================================================================
  # Run the addon
  #============================================================================
  def runItems(self,items):
    self.notify( sm.str(sm.refreshStart) )
    feeder = HebsubsFeeder()
    loadInfo = self.load( feeder , items)
    self.notify( sm.str(sm.refreshEnd).format(loadInfo.added))
  #============================================================================
  # Run the addon as service
  #============================================================================
  def service(self):
    def isMode(mode):
      return self.config.getInt('refresh_mode') == mode
    maxTime = [
           6 * 60 * 60, #0
          12 * 60 * 60, #1
      1 * 24 * 60 * 60, #2
      2 * 24 * 60 * 60, #3
      3 * 24 * 60 * 60, #4
    ]
    modeNone = 0
    modeOnce = 1
    modeMany = 2

    self.log('Service Start')
    if isMode(modeNone):
      self.log('Service End : Refresh None')
      return

    maxDelay = self.config.getInt('refresh_first') * 60
    if maxDelay > 0 :
      start = time.time()
      while True:
        time.sleep(60)
        startDelay = time.time() - start
        if startDelay > maxDelay:
          break
        #self.log('WaitFirst {0}'.format(startDelay))


    while (not xbmc.abortRequested):
      try:
        self.tracker.trackPage('refresh')
        self.run()
        if isMode(modeOnce):
          self.log('Service End : Refresh Once')
          return
      except:
        pass
      lastRun = time.time()
      while True:
        time.sleep(60)
        iTime = self.config.getInt('refresh_interval')
        if xbmc.abortRequested or iTime >= len(maxTime) :
          break
        passRun = time.time() - lastRun
        if passRun > maxTime[iTime]:
          break
        #self.log('WaitOther {0}'.format(passRun))
  #============================================================================
  # Run the and fetch number of items as refresh_size
  #============================================================================
  def updateNow(self):
    self.tracker.trackPage('updateNow')
    iRefreshSize = self.config.getInt("refresh_size")
    if iRefreshSize == 0:
      self.runItems(160)
    if iRefreshSize == 1:
      self.runItems(320)
    if iRefreshSize == 2:
      self.run()
  #============================================================================
  # Load Bundle from source
  #   Params: source - the source directory
  #============================================================================
  def loadBundles(self):
    self.tracker.trackPage('loadBundle')
    self.notify( sm.str(sm.bundlesStart) )
    feeder = ImdbBundleFeeder()
    feeder.source = self.translatePath( self.config.getStr('bundle_source') )
    loadInfo = self.load(feeder,0)
    self.notify( sm.str(sm.bundlesEnd).format(loadInfo.added) )

  def loadPackage(self,configKey):
    self.tracker.trackPage('loadPackage')
    self.notify( sm.str(sm.packageStart) )
    feeder = ImdbBundleFeeder()
    feeder.cache = self.cache
    feeder.package = self.translatePath( self.config.getStr(configKey) )
    loadInfo = self.load(feeder,0)
    self.notify( sm.str(sm.packageEnd).format(loadInfo.added) )
  #============================================================================
  # Load filters
  #============================================================================
  def loadFilters(self):
    return FilterInfo(self.addon)
  #============================================================================
  # Display message dialog
  #   Params : title   = the title text
  #            message = the message text
  #============================================================================
  def message(self,title,message):
    xbmcgui.Dialog().ok( Text.xbmcTo(title), Text.xbmcTo(message) )
  #============================================================================
  # Display notify message
  #   Params : message = the message text
  #============================================================================
  def notify(self,message):
    if self.config.getBool('notify'):
      xbmc.executebuiltin(Text.xbmcTo(u'XBMC.Notification({0},{1},{2},{3})'.format(self.name, message , 5 , os.path.join( self.path ,"icon.png" ))) )
  #============================================================================
  # Init the paths
  #============================================================================
  def initPaths(self):
    self.dirRoot    = self.path
    self.dirSource  = os.path.join( self.dirRoot, 'Feeder'  )
    self.cache      = os.path.join( self.data   , "Cache"   )
    self.dirLogs    = os.path.join( self.data   , "Logs"    )
    File.ensureFolder(self.cache  )
    File.ensureFolder(self.dirLogs)
    Log.log = self.log
    FileLoader.dirCache = os.path.join( self.data, "Cache" )
  #============================================================================
  # Add source directory
  #   Params : name = the name of the source
  #            path = the path of the source
  #============================================================================
  def addSource(self,name,path):
    sources_filename = xbmc.translatePath("special://userdata/sources.xml")
    ndRoot =  None
    if os.path.exists(sources_filename):
      tree = et.parse(sources_filename)
    else:
      root = et.fromstring('<sources> <programs> <default pathversion="1"></default> </programs> <video>    <default pathversion="1"></default> </video> <music>    <default pathversion="1"></default> </music> <pictures> <default pathversion="1"></default> </pictures> <files>    <default pathversion="1"></default> </files> </sources>')
      tree = et.ElementTree(root)
    ndVideo = tree.find("./video")
    for ndSource in ndVideo:
      if ndSource.tag == "source":
        ndName = ndSource.find("name")
        if ndName.text == name:
          return
    ndSource = et.Element("source")
    et.SubElement(ndSource, "name").text = name
    et.SubElement(ndSource, "path").text = path
    ndVideo.append(ndSource)
    tree.write(sources_filename)
  #============================================================================
  # Scan the source
  #   Params : path = the path of the source
  #============================================================================
  def scanSource(self,path=None):
    time.sleep(1)
    while xbmc.getCondVisibility('Library.IsScanning') or xbmc.getCondVisibility('Window.IsActive(10101)'):
      time.sleep(1)
    xbmc.executebuiltin('UpdateLibrary({0})'.format('video'))
  #============================================================================
  # Clean the source
  #   Params : path = the path of the source
  #============================================================================
  def cleanSource(self,path=None):
    time.sleep(1)
    while xbmc.getCondVisibility('Library.IsScanning') or xbmc.getCondVisibility('Window.IsActive(10101)'):
      time.sleep(1)
    xbmc.executebuiltin("CleanLibrary({0})".format('video'))
  #============================================================================
  # log a message
  #   Params : message = The message
  #============================================================================
  def log(self,message, filename="main.log"):
    now = datetime.datetime.now()
    try :
      logFile = os.path.join(self.dirLogs,filename)
      with codecs.open(logFile, mode='a+') as ff:
        ff.write( '{2:02}/{1:02}|{3:02}:{4:02}:{5:02} : {6}'.format(
          now.year,
          now.month,
          now.day,
          now.hour,
          now.minute,
          now.second,
          message
        ))
        ff.write('\n')
    except:
      pass
  #============================================================================
  # Translate path special places
  #   Params: path - the path
  #   Return: The translated path
  #============================================================================
  def translatePath(self,path):
    path = path.replace('{home}',self.path)
    path = path.replace('{data}',self.data)
    return path
  #============================================================================
  # Save current time as last update time
  #============================================================================
  def saveLastUpdate(self):
    self.config.setStr( 'last_update', datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') )
  #============================================================================
  # Save current time as last update time
  #============================================================================
  def diffLastUpdate(self):
    date = self.config.getStr('last_update')
    lastUpdate = datetime.datetime(2000,1,1,0,0,0)
    try:
      lastUpdate = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
    except:
      pass
    return datetime.datetime.now() - lastUpdate
  #============================================================================
  # Clean the library
  #============================================================================
  def cleanLibrary(self):
    File.delFiles(self.library)
    self.cleanSource()
    self.notify( sm.str(sm.cleanLibrary) )
  #============================================================================
  # Clean the cache
  #============================================================================
  def cleanCache(self):
    File.delFiles(self.cache)
    self.notify( sm.str(sm.cleanCache) )
  #============================================================================
  # Clean the logs
  #============================================================================
  def cleanLogs(self):
    File.delFiles(self.dirLogs)
    self.notify( sm.str(sm.cleanLogs) )
  #============================================================================
  # library
  #============================================================================
  @property
  def library(self):
    library = self.config.getStr('library')
    if library == '':
      library = os.path.join( self.data   , "Library" )
    File.ensureFolder(library)
    return library
  #============================================================================
  #
  #============================================================================
  def load(self, feeder, items):
    loadInfo = LoadInfo( FilterInfo(self.config) , items )
    self.addSource(self.name,self.library)
    feeder.withThumb = self.config.getBool('with_thumb')
    feeder.streamMode= self.config.getInt('stream_mode')
    feeder.dirTarget = self.library
    feeder.load(loadInfo)
    self.scanSource(self.library)
    self.saveLastUpdate()
    return loadInfo