def __init__(self, log, status, databaseObj):
        """
        log: modules.nicoLoad_base.Log()
        """
        self.log = log
        self.status = status
        self.db = databaseObj

        if not(self.db.extMovieTable() and self.db.extMylistTable() and self.db.extMylistHasMovieTable()):
            self.db.ctTable()
        self.queue = Queue()

        self.__loading = False
        self.waitTime = 1
    def __init__(self, log, status, ):#databaseObj):
        """
        log: modules.nicoLoad_base.Log()
        """
        self.log = log
        self.status = status
        self.db = Database()#databaseObj

        if not(self.db.extMovieTable() and self.db.extMylistTable() and self.db.extMylistHasMovieTable()):
            self.db.ctTable()
        self.queue = Queue()

        self.__loading = False  # 動画を保存しているか is storing movie or not
        self.waitTime = 1

         # self.movieLoadLoop()  # 保存用の無限ループ
        movieLoadThread = threading.Thread(target=self.movieLoadLoop)
        movieLoadThread.daemon = True
        movieLoadThread.start()
    def __init__(self, databasePath, systemDatabasePath, logging):
        """
        databasePath: database file path
        systemDatabasePath: system database file path
        logging: log function
        """
        self.databasePath = databasePath
        self.systemDatabasePath = systemDatabasePath
        #self.logging = logging

        self._wtime_load = 60 * 60 * 12  # wait times
        self._wtime_scan = 60 * 60 * 12
        self._wtime_rss = 60 * 60 * 12
        self.__flag_mainLoop = True  # mainLoop
        self.__flag_loading = False  # load
        self.__flag_scanning = False  # scan
        self.__flag_rssing = False  # rss
        self.sysenc = sys.getfilesystemencoding()

        self.queue = NQueue()
        self.saveMovie = SaveMovie(1024)
class NicoLoad_Load():
    def __init__(self, log, status, databaseObj):
        """
        log: modules.nicoLoad_base.Log()
        """
        self.log = log
        self.status = status
        self.db = databaseObj

        if not(self.db.extMovieTable() and self.db.extMylistTable() and self.db.extMylistHasMovieTable()):
            self.db.ctTable()
        self.queue = Queue()

        self.__loading = False
        self.waitTime = 1

    # まとめ系
    def nicoLoad_Load(self, *args):
        """
        load全般まとめ関数
        General Summary of load function
        コマンドから実行する関数を振り分ける
        Distributes the function to be executed from the command
        """
        option = args[1]
        if option.has_key(args[0]):
            url = option[args[0]]
            self.movieLoad(url)
        else:
            self.movieLoadAll()

    def rss(self, *args):
        """
        rss
         -id mylistid_1, mylistid_2, ...
        """
        option = args[1]
        del option[args[0]]
        if len(args) == 0:
            rssAll()
        else:
            for mylistid in option["-id"]:
                rssOne(mylistid)
    def regNicoInfo(self, *args):
        """
        ニコニコID,PW保存
        save niconico ID & PW
        """
        nicoid = raw_input(u"ニコニコ動画のIDを入力してください\n>>> ")
        nicopw = raw_input(u"ニコニコ動画のパスワードを入力してください\n>>> ")
        self.db.svNicoid(nicoid)
        self.db.svNicopw(nicopw)
        return True
    def regGmailInfo(self, *args):
        """
        GmailID,PWを保存
        save Gmail ID & PW
        """
        gmailid = raw_input(u"GmailのIDを入力してください\n>>> ")
        gmailpw = raw_input(u"GmailのPWを入力してください\n>>> ")
        self.db.svGmailid(gmailid)
        self.db.svGmailpw(gmailpw)
    def regSavedir(self, *args):
        """
        保存フォルダを保存
        save the folder for saving
        """
        flag = False
        while True:
            savedir = raw_input(u"保存フォルダを入力してください\n>>> ")
            flag = os.path.exists(os.path.abspath(savedir))
            if flag:
                break
            else:
                print u"入力されたフォルダは存在しません"

        self.db.svSavedir(savedir)
        return True

    def getNicoInfo(self):
        """return (nicoid, nicopw)"""
        return (self.db.getNicoid(), self.db.getNicopw())
    def getGmailInfo(self):
        """return (gmailid, gmailpw)"""
        return (self.db.getGmailid(), self.db.getGmailpw())
    def getSavedir(self):
        """return savedir"""
        return self.db.getSavedir()

    def movieQueueAdd(self, movieid):
        """
        保存キューに追加
        add to the queue for string
        """
        print "addQueue: %s" % movieid
        self.queue.add(movieid)
    def movieQueueAddFront(self, movieid):
        """
        保存キューの先頭に追加
        added to the top of the queue for string
        """
        print "addQueue: %s" % movieid
        self.queue.addFromnt(movieid)
    def movieQueueaddNext(self, movieid):
        """
        保存キューの次に追加
        added to the queue for string the second
        """
        print "addQueue: %s" % movieid
        self.queue.addNext(movieid)
    def movieQueueGet(self):
        """
        キューから取得
        retrived from the queue
        """
        return self.queue.get()
    def movieLoadDone(self):
        """
        タスクの終了を伝える 
        convey the completetion of the task
        タスクを実行したら呼び出す
        call to perform the task
        
        """
        self.queue.done()
        self.status.chLoadingMovie()

    def movieLoadLoop(self):
        """
        保存用ループ
        loop for strage
        """
        # 既に動いていたら I was already running
        if self.__loading: return False
        else: self.__loading = True
        while True:
            try:
                movieid = self.movieQueueGet()
                self.status.setLoadingMovieid(movieid)
                self.movieLoad()
            except QueueEmptyError():
                self.status.setLoadingMovieid(u"waiting")
                time.sleep(self.waitTime)

    def movieLoadAll(self):
        """
        すべての動画を保存
        save all videos
        """
        for movieid in self.db.getMovieState0():
            self.movieQueueAdd(movieid)
        self.movieLoadLoop()

    def movieLoad(self, movieid):
        """
        動画を保存
        save videos
        """
        if not self.db.addMovie(movieid):  # DB登録
            # 登録済みの時
            self.db.setMovieState(movieid, 0)
        api = NicovideoAPI(movie_id=movieid)
        title = api.get_movie_title()
        # ext = api.get_movie_type()
        nicoid = self.db.getNicoid()
        nicopw = self.db.getNicopw()
        savedir = getSavedir()
        self.status.chLoadingMovie()
        self.db.setMovieTitle(movieid, title)
        self.db.setMovieDescription(movieid, api.get_movie_description())
        self.db.setMovieLength(movieid, api.get_movie_length())
        self.db.setMoviePath(movieid, moviePath)
        self.status.setLoadingMovieid(movieid)
        moviePath = api.save_movie(nicoid, nicopw, savedir)
        self.db.setMovieThumbnail(movieid, api.save_thumbnail(savedir))
        self.db.setMovieComment(movieid, api.save_comment(nicoid, nicopw, savedir, title))
        self.db.setMovieState(movieid, 1)
        self.movieLoadDone()
        return True

    def rssOne(self, mylistid):
        """
        マイリスRSS
        RSS for mylist
        """
        various = Various(self.database)
        for movieid in  various.rsscheck(mylistid):
            self.movieQueueAdd(movieid)

    def rssAll(self):
        """
        マイリスRSS
        RSS for mylist
        """
        various = Various(self.databse)
        for mylistid in self.DB.getMylistAll():
            for movieid in various.rsscheck(mylistid):
                self.movieQueueAdd(movieid)

    def exit(self):
        """
        Exit
        """
        self.db.close()
class NicoMovieLoadMain():
    def __init__(self, databasePath, systemDatabasePath, logging):
        """
        databasePath: database file path
        systemDatabasePath: system database file path
        logging: log function
        """
        self.databasePath = databasePath
        self.systemDatabasePath = systemDatabasePath
        #self.logging = logging

        self._wtime_load = 60 * 60 * 12  # wait times
        self._wtime_scan = 60 * 60 * 12
        self._wtime_rss = 60 * 60 * 12
        self.__flag_mainLoop = True  # mainLoop
        self.__flag_loading = False  # load
        self.__flag_scanning = False  # scan
        self.__flag_rssing = False  # rss
        self.sysenc = sys.getfilesystemencoding()

        self.queue = NQueue()
        self.saveMovie = SaveMovie(1024)

    def logging(self, text):
        print text

    def main(self):
        """
        call each daemons
        """
        db = Database(self.databasePath)
        db.ctTable()
        db.close()

        daemon = (self.daemonRss,
                  self.daemonScan,
                  self.daemonLoad,
                  )
        for func in daemon:
            th = threading.Thread(target=func)
            th.daemon = True
            th.start()
            time.sleep(3)

    def load(self, movieid):
        """
        load movieid
        """
        movieid = movieid
        self.logging("load: %s" % movieid)
        # 各データの取得
        db = Database(self.databasePath)
        sdb = SystemDatabase(self.systemDatabasePath)
        nicoid = sdb.getNicoid()
        nicopw = sdb.getNicopw()
        savedir = sdb.getSavedir()
        sdb.close()
        api = NicovideoAPI(movie_id=movieid)
        title = api.get_movie_title()
        moviePath = api.save_movie(nicoid, nicopw, savedir)  # 保存専用のクラスを定義する。一時停止可能なもの
        # 登録
        db.setMoviePath(movieid, moviePath)
        db.setMovieState(movieid, 1)
        self.queue.done()
        db.close()
        return True

    def cancel(self):
        self.saveMovie.cancel()


    def find(self, text):
        """
        find movieid/mylistid from text
        """
        various = NVarious(None, self.logging)
        return various.find(text)

    def _scanning(self):
        """
        scanning the database
        add to queue videos id unloaded
        should be called at regular intervals

        retunrn: added movieid num in queue
        """
        num = 0
        self.logging("scanning")
        db = Database(self.databasePath)
        for movieid in db.getMovieState0():
            self.queue.add(movieid)
            self.logging("AddQueue: %s" % movieid)
            num += 1
        db.close()
        return num

    def _rss(self):
        """
        check new movieid from include mylistid
        register in database to the new movieid
        """
        self.logging("rss")
        db = Database(self.databasePath)
        for mylistid in db.getMylistAll():
            if db.getMylistRss(mylistid):
                self.logging("RSS: %s" % mylistid)
                hitNum = 0
                apiMylist = NicovideoAPI.Nicovideo(mylistid=mylistid)
                for movieid in apiMylist.get_mylist_movies():
                    if not(movieid in db.getMylistHasMovieFromMylistId(mylistid)):
                        self.logging("RSS: Hit: %s" % movieTitle)
                        db.addMylistHasMovie(mylistid, movieid)
                        self.register(movieid)
                        db.setMovieTitle(movieid, movieTitle)
                        hitNum += 1
                self.logging("RSS: %s: %2dhit" % (mylistid, hitNum))
        db.close()

    def register(self, mid):
        """
        register in database mid
        if mid is already registered, it marks unload

        mid: mylistid or movieid
        return: bool
        """
        db = Database(self.databasePath)
        if mid[0:2] == "sm":
            if db.extMovieidInTable(mid):
                db.setMovieState(mid, 0)
            else:
                apiMovie = NicovideoAPI(movie_id=mid)
                movieTitle = apiMovie.get_movie_title()
                db.addMovie(mid)
                db.setMovieTitle(mid, movieTitle)
        else:
            if db.extMylistInTable(mid):
                db.setMylistRss(mid, 1)
            else:
                api = NicovideoAPI(mylist_id=mid)
                mylistTitle = api.get_mylist_title().decode(self.sysenc)
                db.addMylist(mid)
                db.setMylistTitle(mylistTitle)
        db.close()

    def daemonLoad(self):
        """
        daemon with self.load

        interval: interval function is called
        """
        """
        一定時間(interval)ごとにself.load()を呼ぶ
        重複呼び出しをしないようにフラグ管理
        このフラグはself.doneで戻す
        """
        while True:
            self.logging("daemon load")
            if self.__flag_loading == False:
                if not self.queue.empty():
                    self.__flag_loading = True
                    mid = self.queue.get()
                    print "mid:", mid
                    self.load(mid)
                    #self.load(self.queue.get())
                    self.queue.done()
                else:
                    for i in xrange(self._wtime_load):
                        time.sleep(1)
                        # 中断処理 #

    def daemonScan(self):
        """
        daemon with self.scanning

        interval: interval function is called
        """
        while True:
            self.logging("daemon scan")
            if self.__flag_scanning == False:
                self.__flag_scanning = True
                self._scanning()
            for i in xrange(self._wtime_scan):
                time.sleep(1)
                # 中断処理 #

    def daemonRss(self):
        """
        daemon with self.rss
        
        interval: interval function is called
        """
        while True:
            self.logging("daemon rss")
            if self.__flag_rssing == False:
                self.__flag_rssing = True
                self._rss()
            for i in xrange(self._wtime_rss):
                time.sleep(1)
                # 中断処理 #

    # flag setter
    #def setFlagMain(self, flag):
    #    self.__flag_ing = flag
    def setFlagLoad(self, flag):
        self.__flag_loading = flag
    def setFlagScan(self, flag):
        self.__flag_scanning = flag
    def setFlagRss(self, flag):
        self.__flag_rssing = flag
    # flag getter
    def getFlagLoad(self):
        self.__flag_loading
    def getFlagScan(self):
        self.__flag_scaning
    def getFlagRss(self):
        self.__flag_rssing
    # wait time setter
    def setWtimeLoad(self, interval):
        self._wtime_load = interval
    def setWtimeScan(self, interval):
        self._wtime_scan = interval
    def setWtimeRss(self, interval):
        self._wtime_rss = interval
    # wait time getter
    def getWtimeLoad(self):
        return self._wtime_load
    def getWtimeScan(self):
        return self._wtime_scan
    def getWtimeRss(self):
        return self._wtime_rss

    def getQueueObj(self):
        return self.queue