Exemple #1
0
 def test_later(self):
     from worker import current, later, sleep
     
     a = 0
     b = None
     
     def add(value):
         nonlocal a
         nonlocal b
         b = current()
         a += value
         
     current().later(add, 10, timeout=2)
     
     with self.subTest("not yet"):
         sleep(1)
         self.assertEqual(a, 0)
         self.assertEqual(b, None)
     
     with self.subTest("finished"):
         sleep(2)
         self.assertEqual(a, 10)
         self.assertEqual(b, current())
         
     later(add, 10, timeout=2)
     
     with self.subTest("not yet"):
         sleep(1)
         self.assertEqual(a, 10)
         
     with self.subTest("finished"):
         sleep(2)
         self.assertEqual(a, 20)
         self.assertEqual(b, current())
Exemple #2
0
    def __init__(self):
        """Construct."""

        self.thread = current()

        self.cid_view = {}
        self.cid_library = {}
        self.pre_url = None

        self.create_view()

        self.bindevent()

        self.register_listeners()

        printer.add_listener(self.sp_callback)

        if (setting.getboolean("libraryautocheck")
                and time() - setting.getfloat("lastcheckupdate", 0) >
                24 * 60 * 60):
            download_manager.start_check_update()

        self.tv_refresh("view")
        self.tv_refresh("library")

        self.save()
        self.update()
        self.root.mainloop()
Exemple #3
0
    def __init__(self):
        """Construct."""
        self.create_view()
        self.bind_event()

        self.thread = worker.current()
        self.loop = TkinterLoop(self.root, worker.update)

        self.pool_index = {
            id(mission_manager.view): self.view_table,
            id(mission_manager.library): self.library_table
        }

        self.register_listeners()

        printer.add_listener(self.sp_callback)

        if (setting.getboolean("libraryautocheck")
                and time() - setting.getfloat("lastcheckupdate", 0) >
                setting.getfloat("autocheck_interval") * 60 * 60):
            download_manager.start_check_update()

        self.update_table(mission_manager.view)
        self.update_table(mission_manager.library)

        self.save()
        self.loop.start()
Exemple #4
0
 def test_daemon(self):
     from worker import current, Worker
     
     with self.subTest("main thread is not deamon"):
         self.assertFalse(current().is_daemon())
     
     with self.subTest("thread is not daemon by default"):
         thread = Worker().start()
         self.assertFalse(thread.is_daemon())
         thread.stop().join()
     
     with self.subTest("should inherit parent if not set"):
         a = Worker(daemon=True).start()
         self.assertTrue(a.is_daemon())
         
         b = Worker(parent=a).start()
         self.assertTrue(b.is_daemon())
         
         a.stop().join()
         
     with self.subTest("parent will wait non-daemon child thread"):
         a = Worker().start()
         b = Worker(parent=a).start()
         a.stop().join()
         self.assertFalse(b.is_running())
         
     with self.subTest("parent won't wait daemon child thread"):
         def blocker():
             time.sleep(1)
         a = Worker().start()
         b = Worker(blocker, parent=a, daemon=True).start()
         a.stop().join()
         self.assertTrue(b.is_running())
         b.join()
	def __init__(self):
		"""Construct."""
		self.download_thread = None
		self.analyze_threads = ThreadSafeSet()
		self.library_thread = None
		self.library_err_count = None
		self.batch_analyzer = None
		
		thread = current()
		
		download_ch.sub(thread)
		
		@thread.listen("DOWNLOAD_ERROR")
		def _(event):
			_err, mission = event.data
			mission_manager.drop("view", mission)

		@thread.listen("DOWNLOAD_FINISHED")
		def _(event):
			"""After download, execute command."""
			if event.target is not self.download_thread:
				return
				
			cmd = event.data.module.config.get("runafterdownload")
			default_cmd = setting.get("runafterdownload")
			
			commands = []
			
			if cmd:
				commands.append(cmd)
				
			if default_cmd and default_cmd not in commands:
				commands.append(default_cmd)
			
			for command in commands:
				command += " " + quote(path_join(
					profile(event.data.module.config["savepath"]),
					safefilepath(event.data.title)
				))
				try:
					await_(subprocess.call, command, shell=True) # nosec
				except (OSError, subprocess.SubprocessError):
					traceback.print_exc()
					
		@thread.listen("DOWNLOAD_FINISHED")
		@thread.listen("DOWNLOAD_ERROR")
		def _(event):
			"""After download, continue next mission"""
			if event.target is self.download_thread:
				self.download_thread = None
				self.start_download()
				
		@thread.listen("DOWNLOAD_INVALID")
		def _(event):
			"""Something bad happened"""
			if event.target is self.download_thread:
				self.download_thread = None
				print("停止下載")
    def __init__(self):
        """Construct."""
        self.download_thread = None
        self.analyze_threads = ThreadSafeSet()
        self.library_thread = None
        self.library_err_count = None
        self.batch_analyzer = None

        thread = current()

        download_ch.sub(thread)

        @thread.listen("DOWNLOAD_ERROR")
        def _(event):
            _err, mission = event.data
            mission_manager.drop("view", mission)

        @thread.listen("DOWNLOAD_FINISHED")
        def _(event):
            """After download, execute command."""
            if event.target is not self.download_thread:
                return

            cmd = event.data.module.config.get("runafterdownload")
            default_cmd = setting.get("runafterdownload")

            commands = []

            if cmd:
                commands.append(cmd)

            if default_cmd and default_cmd not in commands:
                commands.append(default_cmd)

            for command in commands:
                command += " " + quote(
                    path_join(profile(event.data.module.config["savepath"]),
                              safefilepath(event.data.title)))
                try:
                    await_(subprocess.call, command, shell=True)  # nosec
                except (OSError, subprocess.SubprocessError):
                    traceback.print_exc()

        @thread.listen("DOWNLOAD_FINISHED")
        @thread.listen("DOWNLOAD_ERROR")
        def _(event):
            """After download, continue next mission"""
            if event.target is self.download_thread:
                self.download_thread = None
                self.start_download()

        @thread.listen("DOWNLOAD_INVALID")
        def _(event):
            """Something bad happened"""
            if event.target is self.download_thread:
                self.download_thread = None
                print("停止下載")
	def __init__(self):
		"""Construct."""
		self.pool = {}
		self.view = OrderedDict()
		self.library = OrderedDict()
		self.edit = False
		self.lock = Lock()
		
		self.load()

		thread = current()
		mission_ch.sub(thread)
		@thread.listen("MISSION_PROPERTY_CHANGED")
		def _(event):
			"""Set the edit flag after mission changed."""
			self.edit = True
	def __init__(self):
		"""Construct."""
		self.pool = {}
		self.view = OrderedDict()
		self.library = OrderedDict()
		self.edit = False
		self.lock = Lock()
		
		self.load()

		thread = current()
		mission_ch.sub(thread)
		@thread.listen("MISSION_PROPERTY_CHANGED")
		def _(event):
			"""Set the edit flag after mission changed."""
			self.edit = True
    def __init__(self):
        """Construct."""
        self.download_thread = None
        self.analyze_threads = ThreadSafeSet()
        self.library_thread = None
        self.library_err_count = None
        self.batch_analyzer = None
        self.continued_failure = 0

        thread = current()

        download_ch.sub(thread)

        @thread.listen("DOWNLOAD_ERROR")
        def _(event):
            _err, mission = event.data
            mission_manager.drop("view", mission)
            self.continued_failure += 1

        @thread.listen("DOWNLOAD_FINISHED")
        def _(event):
            """After download, execute command."""
            self.continued_failure = 0

            if event.target is not self.download_thread:
                return

            cmd = event.data.module.config.get("runafterdownload")
            default_cmd = setting.get("runafterdownload")

            commands = []

            if cmd:
                commands.append(cmd)

            if default_cmd and default_cmd not in commands:
                commands.append(default_cmd)

            def run_command():
                for command in commands:
                    target = quote(
                        path_join(
                            profile(event.data.module.config["savepath"]),
                            safefilepath(event.data.title)))
                    if "{target}" in command:
                        command = command.format(target=target)
                    else:
                        command += " " + target
                    print(f"run command: {command}")
                    try:
                        await_(subprocess.call, command, shell=True)  # nosec
                    except (OSError, subprocess.SubprocessError):
                        traceback.print_exc()

            async_(run_command)

        @thread.listen("DOWNLOAD_FINISHED")
        @thread.listen("DOWNLOAD_ERROR")
        def _(event):
            """After download, continue next mission"""
            if event.target is not self.download_thread:
                return
            self.download_thread = None
            if self.continued_failure >= len(
                    mission_manager.get_all("view",
                                            lambda m: m.state != "FINISHED")):
                print(f"連續失敗 {self.continued_failure} 次,停止下載")
                return
            self.start_download(continued=True)

        @thread.listen("DOWNLOAD_INVALID")
        def _(event):
            """Something bad happened"""
            if event.target is self.download_thread:
                self.download_thread = None
                print("停止下載")
Exemple #10
0
    def __init__(self):
        """Construct."""
        self.download_thread = None
        self.analyze_threads = set()
        self.library_thread = None
        self.library_err_count = None
        self.batch_analyzer = None

        thread = current()

        download_ch.sub(thread)

        @thread.listen("DOWNLOAD_PAUSE")
        @thread.listen("DOWNLOAD_INVALID")
        @thread.listen("DOWNLOAD_ERROR")
        @thread.listen("DOWNLOAD_FINISHED")
        def _(event):
            try:
                _err, mission = event.data
            except TypeError:
                mission = event.data

            if mission.url in mission_manager.pool:
                uninit_episode(mission)

        @thread.listen("DOWNLOAD_ERROR")
        def _(event):
            _err, mission = event.data
            mission_manager.drop("view", mission)

        @thread.listen("DOWNLOAD_FINISHED")
        def _(event):
            """After download, execute command."""
            if event.target is not self.download_thread:
                return

            cmd = event.data.module.config.get("runafterdownload")
            default_cmd = setting.get("runafterdownload")

            commands = []

            if cmd:
                commands.append(cmd)

            if default_cmd and default_cmd not in commands:
                commands.append(default_cmd)

            for command in commands:
                command += " " + quote(
                    path_join(profile(event.data.module.config["savepath"]),
                              safefilepath(event.data.title)))
                try:
                    await_(subprocess.call, command, shell=True)  # nosec
                except (OSError, subprocess.SubprocessError):
                    traceback.print_exc()

        @thread.listen("DOWNLOAD_FINISHED")
        @thread.listen("DOWNLOAD_ERROR")
        def _(event):
            """After download, continue next mission"""
            if event.target is self.download_thread:
                self.download_thread = None
                self.start_download()

        @thread.listen("DOWNLOAD_INVALID")
        def _(event):
            """Something bad happened"""
            if event.target is self.download_thread:
                self.download_thread = None
                print("停止下載")

        @thread.listen("ANALYZE_FAILED")
        @thread.listen("ANALYZE_FINISHED")
        def _(event):
            """After analyze, continue next (library)"""
            try:
                _err, mission = event.data
            except TypeError:
                mission = event.data

            if event.target is self.library_thread:
                uninit_episode(mission)
                if mission.state == "UPDATE":
                    mission_manager.lift("library", mission)

                if mission.state == "ERROR":
                    if self.library_err_count > 10:
                        print("Too many error!")
                        download_ch.pub("LIBRARY_CHECK_UPDATE_FAILED")
                    else:
                        self.library_err_count += 1
                        mission_manager.drop("library", mission)
                        later(self.do_check_update, 5, target=thread)
                    return

                self.do_check_update()

        @thread.listen("ANALYZE_INVALID")
        def _(event):
            """Cleanup library thread with PauseDownloadError"""
            _err, mission = event.data
            if event.target is self.library_thread:
                uninit_episode(mission)
                self.library_thread = None
                print("Failed to check update")

        @thread.listen("ANALYZE_FINISHED")
        def _(event):
            """After analyze, add to view (view analyzer)"""
            if event.target in self.analyze_threads:
                mission = event.data
                uninit_episode(mission)
                mission_manager.add("view", mission)
                download_ch.pub("ANALYZE_NEW_MISSION", mission)

        @thread.listen("ANALYZE_FINISHED")
        @thread.listen("ANALYZE_FAILED")
        def _(event):
            if event.target in self.analyze_threads:
                self.analyze_threads.remove(event.target)

        @thread.listen("BATCH_ANALYZE_END")
        def _(event):
            self.batch_analyzer = None

        @thread.listen("BATCH_ANALYZE_ITEM_FINISHED")
        def _(event):
            _analyzer, mission = event.data
            mission_manager.add("view", mission)
Exemple #11
0
	def __init__(self):
		"""Construct."""
		self.download_thread = None
		self.analyze_threads = set()
		self.library_thread = None
		self.library_err_count = None
		
		thread = current()
		
		download_ch.sub(thread)
		
		@thread.listen("DOWNLOAD_PAUSE")
		@thread.listen("DOWNLOAD_INVALID")
		@thread.listen("DOWNLOAD_ERROR")
		@thread.listen("DOWNLOAD_FINISHED")
		def _(event):
			try:
				err, mission = event.data
			except Exception:
				mission = event.data
			if mission.url in mission_manager.pool:
				uninit_episode(mission)
		
		@thread.listen("DOWNLOAD_ERROR")
		def _(event):
			err, mission = event.data
			mission_manager.drop("view", mission)

		@thread.listen("DOWNLOAD_FINISHED")
		def _(event):
			"""After download, execute command."""
			if event.target is not self.download_thread:
				return
				
			r1 = event.data.module.config.get("runafterdownload")
			r2 = setting.get("runafterdownload")
			
			if r1 == r2 and r1:
				commands = [r1]
			elif r1:
				commands = [r1, r2]
			else:
				commands = []
				
			for command in commands:
				command = command + " " + path_join(
					event.data.module.config["savepath"],
					safefilepath(event.data.title)
				)
				try:
					subprocess.call(command)
				except Exception:
					print("Failed to run process: {}".format(command))
					
		@thread.listen("DOWNLOAD_FINISHED")
		@thread.listen("DOWNLOAD_ERROR")
		def _(event):
			"""After download, continue next mission"""
			if event.target is self.download_thread:
				self.download_thread = None
				self.start_download()
				
		@thread.listen("DOWNLOAD_INVALID")
		def _(event):
			"""Something bad happened"""
			if event.target is self.download_thread:
				self.download_thread = None
				print("停止下載")

		@thread.listen("ANALYZE_FAILED")
		@thread.listen("ANALYZE_FINISHED")
		def _(event):
			"""After analyze, continue next (library)"""
			try:
				err, mission = event.data
			except Exception:
				mission = event.data
				
			if event.target is self.library_thread:
				uninit_episode(mission)
				if mission.state == "UPDATE":
					mission_manager.lift("library", mission)
					
				if mission.state == "ERROR":
					if self.library_err_count > 10:
						print("Too many error!")
						download_ch.pub("LIBRARY_CHECK_UPDATE_FAILED")
					else:
						self.library_err_count += 1
						mission_manager.drop("library", mission)
						later(self.do_check_update, 5)
					return
					
				self.do_check_update()
				
		@thread.listen("ANALYZE_INVALID")
		def _(event):
			"""Cleanup library thread with PauseDownloadError"""
			err, mission = event.data
			if event.target is self.library_thread:
				uninit_episode(mission)
				self.library_thread = None
				print("Failed to check update")

		@thread.listen("ANALYZE_FINISHED")
		def _(event):
			"""After analyze, add to view (view analyzer)"""
			if event.target in self.analyze_threads:
				mission = event.data
				uninit_episode(mission)
				mission_manager.add("view", mission)

		@thread.listen("ANALYZE_FINISHED")
		@thread.listen("ANALYZE_FAILED")
		def _(event):
			if event.target in self.analyze_threads:
				self.analyze_threads.remove(event.target)
Exemple #12
0
 def add(value):
     nonlocal a
     nonlocal b
     b = current()
     a += value