class Configure: conf = None pixiv = None notice = None core = None def __init__(self, conf): self.conf = conf if conf is None: raise Exception("Conf缺失。") if isinstance(conf, str): try: self.conf = json.loads(conf) except Exception: raise Exception("Conf不是合法的JSON结构。") self.initialize_notice() self.initialize_core() self.initialize_pixiv() def initialize_notice(self): log_file = self.conf.get("log", None) if log_file is not None: log_notice = OutputToFile(log_file) self.notice = Notice(log_notice, log_notice) else: self.notice = Notice() def initialize_core(self): proxy = self.conf.get("proxy", True) is True self.core = Core(use_proxy=proxy) def initialize_pixiv(self): self.pixiv = Pixiv(core=self.core, notice=self.notice) if "account" in self.conf: username = self.conf["account"].get("username", None) password = self.conf["account"].get("password", None) if username is None: raise Exception("Conf JSON缺失结构'account.username'。") if password is None: raise Exception("Conf JSON缺失结构'account.password'。") self.pixiv.login(username, password) else: raise Exception("Conf JSON缺失结构'account'。") def run(self): content = self.conf.get("content", []) for c in content: if c.get("enabled", True): if "save" not in c: raise Exception("无法找到启动配置的存储路径配置(save)。") if "uid" in c: self.run_uid(c) elif "pid" in c: self.run_pid(c) else: raise Exception("无法找到启动配置的特征码(pid/uid/etc.)。") def run_uid(self, content): uids = content["uid"] replace = content.get("replace", False) save = content.get("save") multi_save = content.get("multi_save", None) if isinstance(uids, str) or isinstance(uids, int): uids = [uids] elif not isinstance(uids, list): raise Exception("启动配置的uid不是合法的User ID或其表达式。") for uid in uids: if isinstance(uid, str): u, begin, end = Configure.get_uid_and_range(uid) if u is None: raise Exception("启动配置的uid不是合法的User ID或其表达式。") self.run_uid_source(u, begin, end, save, multi_save, replace) elif isinstance(uid, int): self.run_uid_source(uid, None, None, save, multi_save, replace) else: raise Exception("启动配置的uid不是合法的User ID或其表达式。") def run_pid(self, content): pids = content["pid"] replace = content.get("replace", False) save = content.get("save") multi_save = content.get("multi_save", None) if isinstance(pids, str) or isinstance(pids, int): pids = [pids] elif not isinstance(pids, list): raise Exception("启动配置的pid不是合法的Pixiv ID或其表达式。") for pid in pids: if isinstance(pid, str): matched = re.match(r'([0-9]*)[-: ]([0-9]*)', pid) if matched is not None: min_pid, max_pid = matched.groups() for i in range(int(min_pid), int(max_pid) + 1): self.run_pid_source(i, save, multi_save, replace) else: try: p = int(pid) except ValueError: raise Exception("启动配置的pid不是合法的Pixiv ID或其表达式。") self.run_pid_source(p, save, multi_save, replace) elif isinstance(pid, int): self.run_pid_source(pid, save, multi_save, replace) else: raise Exception("启动配置的pid不是合法的Pixiv ID或其表达式。") def run_uid_source(self, uid, begin, end, save, multi_save, replace=False): ret = self.pixiv.get_member_image_list(uid=uid, max_count=end) if ret is None: return self.notice.log("||==处理Member ID %s==||" % (uid,)) head = begin - 1 if begin is not None else 0 tail = end if end is not None else len(ret) for i in range(head, tail): pid, title = ret[i] self.run_pid_source(pid, save, multi_save, replace, uid=uid) def run_pid_source(self, pid, save, multi_save, replace=False, uid=None): ret = self.pixiv.get_image_source(pid) if ret is None: return self.notice.log("|==处理Pixiv ID %s==|" % (pid,)) if len(ret["content"]) == 1 or (len(ret["content"]) > 1 and multi_save is None): content, pg_index, extension = ret["content"][0] file_path = save.format(title=ret["title"], pid=ret["pid"], user=ret["user"], uid=uid if uid is not None else ret["user_id"]) + "." + extension if not os.path.exists(file_path) or replace: Configure.make_dir(file_path) with open(file_path, 'wb') as f: f.write(content) elif not replace: self.notice.log("[%s]已存在,跳过。" % (pid,)) else: for content, pg_index, extension in ret["content"]: file_path = multi_save.format(title=ret["title"], pid=ret["pid"], user=ret["user"], uid=uid if uid is not None else ret["user_id"], index=pg_index) + "." + extension if not os.path.exists(file_path) or replace: Configure.make_dir(file_path) with open(file_path, 'wb') as f: f.write(content) elif not replace: self.notice.log("[%s]已存在,跳过。" % (pid,)) @staticmethod def get_uid_and_range(uid_str): matched = re.match(r'([0-9]*)\[([0-9]*)[-: ]([0-9]*)\]', uid_str) if matched is not None: u, begin, end = matched.groups() return int(u), int(begin), int(end) else: matched = re.match(r'([0-9]*)\[([0-9]*)\]', uid_str) if matched is not None: u, num = matched.groups() return int(u), 1, int(num) else: try: u = int(uid_str) except ValueError: return None, None, None return int(u), None, None @staticmethod def make_dir(filepath): split_index = filepath.rfind('/') if split_index >= 0: dir_path = filepath[:split_index] os.makedirs(dir_path, exist_ok=True) @staticmethod def help(): return help_text