def main(props=_libssw.Summary(), p_args=_argparse.Namespace, dmmparser=None): # モジュール呼び出しの場合継承したコマンドライン引数は無視 argv = [props.url] if __name__ != '__main__' else _sys.argv[1:] args = _get_args(argv, p_args) # 作品情報 summ = _libssw.Summary() if __name__ == '__main__': _verbose('args: ', args) if not args.url: # URLが渡されなかったときは標準入力から _verbose('Input from stdin...') data = _sys.stdin.readline().rstrip('\n') if not data: _emsg('E', 'URLを指定してください。') for key, data in zip(('url', 'title', 'pid', 'actress', 'number', 'director', 'director', 'note'), data.split('\t')): if key == 'url': summ[key] = data.split('?')[0] elif key == 'actess': summ[key] = list(_libssw.parse_names(data)) elif key == 'number': summ[key] = int(data) if data else 0 elif key == 'director': summ[key] = _libssw.re_delim.split(data) elif key == 'note': summ[key].append(data) else: summ[key] = data _verbose('summ from stdin: ', summ.items()) for attr in ('url', 'number', 'pid', 'subtitle'): if not summ[attr]: summ[attr] = getattr(args, attr) if not summ['actress'] and args.actress: actiter = _chain.from_iterable( map(_libssw.re_delim.split, args.actress)) summ['actress'] = list(_libssw.parse_names(actiter)) else: _verbose('props: ', props.items()) _verbose('p_args: ', vars(p_args)) summ.update(props) summ['link_label'] = getattr(args, 'label') summ['link_series'] = getattr(args, 'series') retrieval = getattr(p_args, 'retrieval', 'series' if args.as_series else 'find') service = getattr(p_args, 'service', None) series_guide = getattr(p_args, 'series_guide', True) if args.actress and args.actress[0].startswith('@@'): # ウィキテキストで直接指定 rawpfmrs = args.actress[0][2:] else: rawpfmrs = '' # サービス未指定時の自動決定 if not service: service = _libssw.resolve_service(summ['url']) _verbose('service resolved: ', service) if service == 'ama': # 動画(素人)の場合監督欄は出力しない。 args.dir_col = False join_d = dict() _libssw.ret_joindata(join_d, args) if (args.join_tsv or args.join_wiki or args.join_html) and not len(join_d): _emsg('E', '--join-* オプションで読み込んだデータが0件でした。') # URLを開いて読み込む resp, he = _libssw.open_url(summ['url'], set_cookie='age_check_done=1') if resp.status == 404: # 404の時、空のエントリを作成(表形式のみ)して返す _emsg('I', 'ページが見つかりませんでした: ', summ['url']) if not summ['pid']: summ['pid'], summ['cid'] = _libssw.gen_pid(summ['url']) if p_args.cid_l: summ['url'] = '' else: if not summ['subtitle']: summ['subtitle'] = summ['title'] summ['image_sm'], summ['image_lg'] = _build_image_url( service, summ['cid']) wktxt_t = _format_wikitext_t(summ, '', '/'.join(summ['director']), args.dir_col, _build_addcols(args.add_column, summ), retrieval) _verbose('wktxt_t: ', wktxt_t) return False, resp.status, _ReturnVal(summ['release'], summ['pid'], summ['title'], summ['title_dmm'], summ['url'], summ['time'], summ('maker', 'maker_id'), summ('label', 'label_id'), summ('series', 'series_id'), summ['actress'], summ['link_label'], summ['link_series'], wktxt_a='', wktxt_t=wktxt_t) elif resp.status != 200: return False, resp.status, ('HTTP status', resp.status) # 構文ミスの修正 # html = _libssw.sub(sub_href, html) # HTMLの解析 if not dmmparser: dmmparser = _libssw.DMMParser(autostrip=args.autostrip, longtitle=args.longtitle, check_rental=args.check_rental, check_rltd=args.check_rltd) try: summ.update(dmmparser(he, service, summ, ignore_pfmrs=rawpfmrs)) except _libssw.OmitTitleException as e: # 除外対象なので中止 return False, 'Omitted', (e.key, e.word) _verbose('summ: ', summ.items()) if dmmparser.data_replaced: service = dmmparser.data_replaced # joinデータがあったら補完 if summ['url'] in join_d: summ.merge(join_d[summ['url']]) if args.pid: summ['pid'] = args.pid # 画像がまだないときのリンク自動生成 if not summ['image_lg']: summ['image_sm'], summ['image_lg'] = _build_image_url( service, summ['cid']) _verbose('image_sm: ', summ['image_sm']) _verbose('image_lg: ', summ['image_lg']) # # タイトルの調整 # # 削除依頼対応 for dl in _libssw.HIDE_NAMES_V: summ['title'] = summ['title'].replace(dl, '').strip() on_dmm = summ['title'] # wiki構文と衝突する文字列の置き換え modified = _libssw.trans_wikisyntax(on_dmm) if _AUTOMODIFY: # ♥の代替文字列の置き換え modified = _libssw.sub(_sub_heart, modified) summ['title'] = modified if not summ['title_dmm'] and modified != on_dmm: summ['title_dmm'] = on_dmm _verbose('summ[title]: ', summ['title']) _verbose('summ[title_dmm]: ', summ['title_dmm']) # レーベル/シリーズ一覧へのリンク情報の設定 if (not args.hide_list) and args.check_listpage: _resolve_pagelink(summ, args) _verbose('summ[link_label]: ', summ['link_label']) _verbose('summ[link_series]: ', summ['link_series']) if args.note: summ['note'] = list(_expansion(args.note, summ)) + summ['note'] _verbose('note: ', summ['note']) add_column = _build_addcols(args.add_column, summ) _verbose('add column: ', add_column) # 出演者文字列の作成 pfmrslk = () if rawpfmrs: # ウィキテキスト pfmrslk = _libssw.re_linkpare.findall(rawpfmrs) pfmrsstr, pnum = rawpfmrs, len(pfmrslk) elif len(summ['actress']) < 2 and not summ['number'] and args.table == 0: # 女優ページ用のみ作成で出演者数が1人ならやらない pfmrsstr, pnum = '', 0 else: pfmrsstr, pnum = _libssw.stringize_performers(summ['actress'], summ['number'], args.follow_rdr) # 監督文字列の作成 dirstr = '/'.join(summ['director']) # table形式用副題の生成 if retrieval == 'series': # シリーズ名が list_page にあってタイトルの先頭からシリーズ名と # 同じ文字列があれば落とす。 # list_page に値がなければタイトルをそのまま入れる。 if not summ['subtitle']: summ['subtitle'] = _re.sub(r'^{}[、。!?・…♥]*'.format(summ['series']), '', summ['title'], flags=_re.I).strip() elif not summ['subtitle']: # タイトルをそのまま副題に(表形式用) summ['subtitle'] = summ['title'] _verbose('subtitle: ', summ['subtitle']) # 未取得情報のチェック if _VERBOSE: _check_missings(summ) # ウィキテキストの作成 wikitext_a = _format_wikitext_a(summ, pnum, pfmrsstr, service) if args.table != 1 else () wikitext_t = _format_wikitext_t(summ, pfmrsstr, dirstr, args.dir_col, add_column, retrieval) if args.table else '' if __name__ != '__main__': # モジュール呼び出しならタプルで返す。 return True, summ['url'], _ReturnVal( summ['release'], summ['pid'], summ['title'], summ['title_dmm'], summ['url'], summ['time'], summ('maker', 'maker_id'), summ('label', 'label_id'), summ('series', 'series_id'), summ['actress'], summ['link_label'], summ['link_series'], wikitext_a, wikitext_t) else: # 書き出す output = [''] if wikitext_a: output.append(wikitext_a) if wikitext_t: output.append(wikitext_t) print(*output, sep='\n') if args.copy: _verbose('copy 2 clipboard') _libssw.copy2clipboard(''.join(output)) if args.browser: # wikiのページを開く if args.table != 1: pages = pfmrslk or summ['actress'] for a in pages: _libssw.open_ssw(a[1] or a[0]) if args.table: _libssw.open_ssw(summ['link_label']) _libssw.open_ssw(summ['link_series'])
def makeproditem(cid, service, sub_pid): pid = libssw.gen_pid(cid, sub_pid)[0] verbose('built cid: {}, pid: {}'.format(cid, pid)) url = libssw.build_produrl(service, cid) return url, libssw.Summary(url=url, title='', cid=cid, pid=pid)
def main(argv=None): args = get_args(argv or sys.argv[1:]) make = MakeType(actress=args.table != 1, table=args.table) outfile = parse_outfile(args, make) verbose('outfile: ', outfile) ids = tuple(libssw.extr_ids(args.keyword, args.cid)) verbose('ids: ', ids) if not args.retrieval: args.retrieval = libssw.extr_ids.retrieval emsg('I', '対象: {}'.format(args.retrieval)) # -L, -K , -U 以外では --not-in-series は意味がない if args.retrieval not in {'label', 'maker', 'url'}: args.n_i_s = False verbose('force disabled n_i_s') if args.retrieval == 'actress': for i in filter(lambda i: i in libssw.HIDE_NAMES, ids): emsg('W', '削除依頼が出されている女優です: {}'.format(libssw.HIDE_NAMES[i])) ids.remove(i) # 除外対象 no_omits = libssw.gen_no_omits(args.no_omit) verbose('non omit target: ', no_omits) # 品番生成用パターンのコンパイル sub_pid = (re.compile(args.pid_regex[0], re.I), args.pid_regex[1]) if args.pid_regex else None # 副題生成用パターンのコンパイル re_subtitle = (re.compile(args.subtitle_regex[0], re.I), args.subtitle_regex[1]) if args.subtitle_regex else None # フィルター用パターン filter_id, fidattr = det_filterpatn(args) re_filter_pid_s = args.filter_pid_s and re.compile(args.filter_pid_s, re.I) re_filter_ttl = args.filter_title and re.compile(args.filter_title, re.I) # 作成開始品番 key_id, key_type, kidattr = det_keyinfo(args) not_key_id = libssw.NotKeyIdYet(key_id, key_type, kidattr) listparser = libssw.DMMTitleListParser(no_omits=no_omits, patn_pid=sub_pid) seriesparser = libssw.DMMTitleListParser(patn_pid=sub_pid, show_info=False) # 作品情報取得用イテラブルの作成 p_gen = make_pgen(args, ids, listparser, sub_pid, key_id, key_type, kidattr) # 作品情報の取り込み # 新着順 products = OrderedDict((u, p) for u, p in p_gen) emsg('I', '一覧取得完了') total = len(products) if not total: emsg('E', '検索結果は0件でした。') if not args.service: # TSVやウィキテキスト入力の場合の作品情報からサービス判定 args.service = libssw.resolve_service(next(iter(products))) join_d = dict() libssw.ret_joindata(join_d, args) if (args.join_tsv or args.join_wiki or args.join_html) and not len(join_d): emsg('E', '--join-* オプションで読み込んだデータが0件でした。') if args.existings_html: # 既存の一覧ページから既出の作品情報の取得 verbose('existings html') existings = set(k[0] for k in libssw.from_html(args.existings_html, service=args.service)) if not existings: emsg('E', '--existings-* オプションで読み込んだデータが0件でした。') else: existings = set() # 作品情報の作成 verbose('Start building product info') if not VERBOSE and args.wikitext: print('作成中...', file=sys.stderr, flush=True) wikitexts = [] title_list = [] nis_series_names = set() # 発見したシリーズ名 (n_i_s用) nis_series_urls = set() # 発見したシリーズ一覧のURL (n_i_s用) rest = total omitted = listparser.omitted before = True if key_id else False dmmparser = libssw.DMMParser(no_omits=no_omits, patn_pid=sub_pid, start_date=args.start_date, start_pid_s=args.start_pid_s, filter_pid_s=re_filter_pid_s, pass_bd=args.pass_bd, n_i_s=args.n_i_s, longtitle=args.longtitle, check_rental=args.check_rental, check_rltd=args.check_rltd) if args.retrieval in {'maker', 'label', 'series'}: keyiter = libssw.sort_by_id(products) else: keyiter = iter(products) for url in keyiter: props = products[url] # 品番の生成 if not props.pid: props.pid, props.cid = libssw.gen_pid(props.url, sub_pid) # 開始ID指定処理(--{start,last}-{p,c}id) if before: # 指定された品番が見つかるまでスキップ if not_key_id(getattr(props, kidattr)): emsg( 'I', '作品を除外しました: {}={} (id not met yet)'.format( kidattr, getattr(props, kidattr))) omitted += 1 rest -= 1 continue else: before = False if key_type == 'start': emsg('I', '開始IDが見つかりました: {}'.format(getattr(props, kidattr))) else: emsg('I', '最終IDが見つかりました: {}'.format(getattr(props, kidattr))) continue # 品番(pid/cid)が指定されたパターンにマッチしないものはスキップ処理(--filter-{p,c}id) if filter_id and not filter_id.search(getattr(props, fidattr)): emsg( 'I', '作品を除外しました: {}={} (filtered)'.format(fidattr, getattr(props, fidattr))) omitted += 1 rest -= 1 continue # 作品名が指定されたパターンにマッチしないものはスキップ処理(--filter-title) if args.filter_title and not re_filter_ttl.search(props.title): emsg('I', '作品を除外しました: title={} (filtered)'.format(props.title)) omitted += 1 rest -= 1 continue # 一覧ページ内に既存の作品はスキップ(--existings-) if props.url in existings: emsg('I', '作品を除外しました: pid={} (already existent)'.format(props.pid)) omitted += 1 rest -= 1 continue # 既知のシリーズ物のURLならスキップ (--not-in-series) if props.url in nis_series_urls: emsg('I', '作品を除外しました: title="{}" (known series)'.format(props.title)) omitted += 1 rest -= 1 continue if props.url in join_d: # joinデータがあるとデータをマージ props.merge(join_d[props.url]) if args.hunter: props.title = join_d[props.url].title # 副題の生成 if args.retrieval == 'series': # シリーズ一覧時のカスタムサブタイトル props.subtitle = libssw.sub(re_subtitle, props.title).strip() \ if args.subtitle_regex else '' if args.wikitext: # ウィキテキストを作成 libssw.inprogress('(残り {} 件/全 {} 件: 除外 {} 件) '.format( rest, total, omitted)) verbose('Call dmm2ssw') b, status, data = dmm2ssw.main(props, args, dmmparser) # 返り値: # b -> Bool # status -> url if b else http.status or 'Omitted' # data -> if b: # ReturnVal(release, # pid, # title, # title_dmm, # url, # time, # ('maker', 'maker_id'), # ('label', 'label_id'), # ('series', 'series_id'), # wikitext_a, # wikitext_t) # else: # (key, hue) or empty ReturnVal (404) verbose('Return from dmm2ssw: {}, {}, {}'.format(b, status, data)) if b: wikitexts.append(data) elif status == 404: wikitexts.append(data) else: emsg( 'I', '作品を除外しました: ' 'cid={0}, reason=("{1[0]}", {1[1]})'.format( props.cid, data)) if args.n_i_s and data[0] == 'series': # no-in-series用シリーズ作品先行取得 verbose('Retriving series products...') nis_series_names.add(data[1].name) priurls = libssw.join_priurls('series', data[1].sid, service=args.service) nis_series_urls.update( u[0] for u in libssw.from_dmm(seriesparser, priurls)) omitted += 1 else: # 一覧出力 title_list.append( props.tsv('url', 'title', 'pid', 'actress', 'number', 'director', 'note')) rest -= 1 if wikitexts: # ウィキテキストの書き出し verbose('Writing wikitext') # アーティクル名の決定 article_name, article_header = det_articlename(args, ids, wikitexts, listparser) verbose('article name: ', article_name) verbose('article header: ', repr(article_header)) if not libssw.le80bytes(article_name): emsg('W', 'ページ名が80バイトを超えています') # ソート sortkeys = set_sortkeys(args.sort_key) for k in sortkeys: wikitexts.sort(key=attrgetter(k)) if args.add_column: add_header = '|'.join(c.split(':')[0] for c in args.add_column) + '|' args.add_column = tuple(truncate_th(args.add_column)) else: add_header = '' verbose('add header: {}\nadd column: {}'.format( add_header, args.add_column)) if make.table and args.header: table_header = '|~{{}}|PHOTO|{}|ACTRESS|{}{}RELEASE|NOTE|'.format( 'SUBTITLE' if args.retrieval == 'series' else 'TITLE', 'DIRECTOR|' if args.dir_col else '', add_header) else: table_header = '' build_page = BuildPage(wikitexts, args.split, args.retrieval, article_name, article_header, table_header) print(file=sys.stderr) result = '\n'.join( finalize(build_page, args.row, make, args.n_i_s, nis_series_names, outfile)) build_page.open_browser(args.browser) if args.copy: libssw.copy2clipboard(result) else: # タブ区切り一覧の書き出し fd = open(args.out, outfile.writemode) if args.out else sys.stdout print(*title_list, sep='\n', file=fd) if args.out: fd.close()
def main(): global ROOTID global PREFIXES existings = OrderedDict() newcomers = OrderedDict() mk_prefix = Counter() mk_ophans = [] mk_ophans_prods = dict() mk_ophans_prefix = Counter() mk_ophans_latest = '' lb_newcomers = dict() lb_name = dict() lb_url = dict() lb_prods = dict() lb_prefix = Counter() lb_latest = dict() lb_series = dict() lb_ophans = dict() lb_ophans_prods = dict() lb_ophans_prefix = Counter() lb_ophans_latest = dict() sr_name = dict() sr_url = dict() sr_prods = dict() sr_prefix = Counter() sr_latest = dict() args = get_args() PREFIXES = args.prefixes if args.root.startswith('http://'): # IDがURL渡しだったときの対処 ROOTID = libssw.get_id(args.root)[0] target = libssw.get_article(args.root) service = libssw.resolve_service(args.root) else: ROOTID = args.root target = args.target service = args.service verbose('root id: {}'.format(ROOTID)) verbose('target: {}'.format(target)) verbose('service: {}'.format(service)) listparser = libssw.DMMTitleListParser(no_omits=('イメージビデオ', '総集編'), show_info=False) ret_members = RetrieveMembers(listparser, service) flprefix = '{}.{}'.format(target, ROOTID) pkfile = tuple( Path(args.pickle_path or '.').glob('{}.*.pickle'.format(flprefix))) pkfile = pkfile[0] if pkfile else None if pkfile: with pkfile.open('rb') as f: (existings, lb_name, lb_url, lb_prods, lb_latest, sr_name, sr_url, sr_prods, sr_latest, lb_series, lb_ophans, lb_ophans_prods, lb_ophans_latest, mk_ophans, mk_ophans_prods, mk_ophans_latest) = pickle.load(f) exist_set = set(existings) # 新規追加分を取得 priurls = libssw.join_priurls(target, ROOTID, service=service) try: last_pid = next(reversed(existings.values()))['pid'] except StopIteration: last_pid = None # メーカーの新規作品情報の取得 for nurl, nprops in libssw.from_dmm(listparser, priurls, key_id=last_pid, key_type='last', idattr='pid', ignore=True): if nurl not in exist_set: newcomers[nurl] = dict(nprops) nc_num = len(newcomers) total = nc_num + len(existings) if not total: emsg('E', '検索結果は0件でした。') article_name = listparser.article[0][0] # メーカー名がわかったところで出力ファイルのチェック outstem = '{}.{}'.format(flprefix, libssw.trans_filename(article_name)) outfile = args.outfile or '{}.wiki'.format(outstem) if args.replace: writemode = 'w' else: libssw.files_exists('w', outfile) writemode = 'x' emsg('I', '{} [id={}, 新規{}/全{}作品]'.format(article_name, ROOTID, nc_num, total)) # まずレーベル別にまとめ lb_set = set(lb_name) lb_set_add = lb_set.add for lid, lname, lurl, lprods in ret_members('label', newcomers, exist_set, last_pid): if lid not in lb_set: # 新規レーベル lb_name[lid] = lname lb_url[lid] = lurl lb_prods[lid] = lprods lb_series[lid] = [] lb_set_add(lid) else: # 既知レーベルの新規作品 for u in reversed(lprods): lb_prods[lid][u] = lprods[u] lb_newcomers[lid] = lprods lb_latest[lid] = get_latest(lprods) emsg('I', 'レーベル: {} [id={}, 新規{}作品]'.format(lname, lid, len(lprods))) # # メーカーその他作品まとめ # ncmk_ophans = ret_members.ophans.copy() ncmk_ophans_prods = ret_members.ophans_prods.copy() emsg('I', '{}その他: {}作品'.format(article_name, len(ncmk_ophans_prods))) # メーカーその他作品の追加 mk_ophans.extend(ncmk_ophans) for u in reversed(ncmk_ophans_prods): mk_ophans_prods[u] = ncmk_ophans_prods[u] verbose('mk_ophans_prods: {}'.format(len(mk_ophans_prods))) # メーカーその他作品の品番およびプレフィクス if args.regen_pid: for p in mk_ophans_prods: mk_ophans_prods[p]['pid'] = libssw.gen_pid( mk_ophans_prods[p]['url'])[0] mk_ophans_prefix = count_prefixes(mk_ophans_prods) # メーカーその他作品の最新リリース日 ncmk_ophans_latest = ret_members.ophans_latest if ncmk_ophans_latest > mk_ophans_latest: mk_ophans_latest = ncmk_ophans_latest # # レーベル別まとめ # # 新作情報を追加してレーベル全体のプレフィクス情報の再作成 for lid in lb_prods: if args.regen_pid: for p in lb_prods[lid]: lb_prods[lid][p]['pid'] = libssw.gen_pid( lb_prods[lid][p]['url'])[0] lb_prefix[lid] = count_prefixes(lb_prods[lid]) # レーベルごとにシリーズまとめ for lid in lb_prods: lprods = lb_prods[lid] if lb_name[lid].startswith(IGNORE_LABELS) and args.suppress: lb_series[lid] = () lb_ophans_prefix[lid] = () continue emsg('I', '') emsg('I', 'レーベル「{}」のシリーズ'.format(lb_name[lid])) verbose('exising ophans: {}'.format(len(lb_ophans.get(lid, ())))) sr_set = set(sr_name) sr_set_add = sr_set.add for sid, sname, surl, sprods in ret_members('series', lprods, exist_set, last_pid): if sid not in sr_set: sr_name[sid] = sname sr_url[sid] = surl sr_prods[sid] = sprods sr_set_add(sid) else: for u in reversed(sprods): sr_prods[sid][u] = sprods[u] emsg('I', 'シリーズ: {} [id={}, 新規{}作品]'.format(sname, sid, len(sprods))) sr_latest[sid] = get_latest(sprods) try: lb_series[lid].append(sid) except KeyError: lb_series[lid] = [sid] # レーベルその他作品まとめ nclb_ophans = ret_members.ophans.copy() nclb_ophans_prods = ret_members.ophans_prods.copy() emsg('I', '{}その他: {}作品'.format(lb_name[lid], len(nclb_ophans_prods))) nclb_ophans_latest = ret_members.ophans_latest if lid not in lb_ophans: lb_ophans[lid] = [] lb_ophans_prods[lid] = OrderedDict() lb_ophans_latest[lid] = '0000/00/00' lb_ophans[lid].extend(nclb_ophans) for u in reversed(nclb_ophans_prods): lb_ophans_prods[lid][u] = nclb_ophans_prods[u] verbose('lb_ophans_prods[{}]: {}'.format(lid, len(lb_ophans_prods))) nclb_ophans_latest = ret_members.ophans_latest if nclb_ophans_latest > lb_ophans_latest[lid]: lb_ophans_latest[lid] = nclb_ophans_latest verbose('lb_ophans_prods: {}'.format(lid, len(lb_ophans_prods))) for lid in lb_ophans_prods: verbose('lb_ophans_prods[{}]: {}'.format(lid, len(lb_ophans_prods[lid]))) if args.regen_pid: for p in lb_ophans_prods[lid]: lb_ophans_prods[lid][p]['pid'] = libssw.gen_pid( lb_ophans_prods[lid][p]['url'])[0] lb_ophans_prefix[lid] = count_prefixes(lb_ophans_prods[lid]) verbose('lb_ophans_prefix[{}]: {}'.format(lid, len(lb_ophans_prefix[lid]))) for sid in sr_prods: if args.regen_pid: for p in sr_prods[sid]: sr_prods[sid][p]['pid'] = libssw.gen_pid( sr_prods[sid][p]['url'])[0] sr_prefix[sid] = count_prefixes(sr_prods[sid]) for url in reversed(newcomers): existings[url] = newcomers[url] mk_prefix = count_prefixes(existings) print('\n') fd = open(outfile, writemode) if target == 'maker': print('*[[{}(メーカー)]]'.format(article_name), file=fd) # print('全{}作品'.format(total), file=fd) summ_prefixes(mk_prefix, fd) print(time.strftime('(%Y年%m月%d日現在)'), file=fd) if args.sort_key == 'release': keyiter = lb_latest.items() reverse = True elif args.sort_key == 'name': keyiter = lb_name.items() reverse = False elif args.sort_key == 'number': keyiter = tuple((lid, len(lb_prods[lid])) for lid in lb_prods) reverse = True if not args.only_series: for n, item in enumerate(sorted(keyiter, key=itemgetter(1), reverse=reverse), start=1): lid = item[0] print('**{}.[[{}]]'.format(n, lb_name[lid]), file=fd) summ_prefixes(lb_prefix[lid], fd) if args.latest: print('-最新リリース: {}'.format(lb_latest[lid]), file=fd) if args.dmm: print('-[[DMMの一覧>{}]]'.format(lb_url[lid]), file=fd) if not args.only_label: # シリーズ別出力 numofseries = len(lb_series.get(lid, ())) numofoph = len(lb_ophans_prefix.get(lid, ())) is_exist = numofseries or numofoph if is_exist: print('[+]', file=fd) print('シリーズ数:', numofseries, file=fd) try: print_serises(lb_series[lid], sr_name, sr_prefix, sr_prods, sr_url, sr_latest, args.dmm, args.latest, args.sort_key, fd) except KeyError: pass if numofoph: print('***{}その他'.format(lb_name[lid]), file=fd) summ_prefixes(lb_ophans_prefix[lid], fd) if args.latest: print('-最新リリース: {}'.format(lb_ophans_latest[lid]), file=fd) if is_exist: print('[END]', file=fd) print(file=fd) if mk_ophans: print('**{}その他'.format(article_name), file=fd) summ_prefixes(mk_ophans_prefix, fd) if args.latest: print('-最新リリース: {}'.format(mk_ophans_latest), file=fd) elif not args.only_label: """only-series""" print_serises(sr_name, sr_name, sr_prefix, sr_prods, sr_url, sr_latest, args.dmm, args.latest, args.sort_key, fd) fd.close() print('出力ファイル:', outfile) if newcomers or args.regen_pid: pkpath = Path(args.pickle_path or '.') / '{}.pickle'.format(outstem) try: pkpath.rename(pkpath.with_suffix(pkpath.suffix + '.bak')) except FileNotFoundError: pass verbose('save file: {}'.format(pkpath)) with pkpath.open('wb') as f: pickle.dump((existings, lb_name, lb_url, lb_prods, lb_latest, sr_name, sr_url, sr_prods, sr_latest, lb_series, lb_ophans, lb_ophans_prods, lb_ophans_latest, mk_ophans, mk_ophans_prods, mk_ophans_latest), f) # キャッシュディレクトリの削除 if args.clear_cache: libssw.clear_cache()
def main(): args = get_args() verbose('args: ', args) # 一覧ページからチェックする作品情報を取得 if args.from_wikitext: targets = OrderedDict(libssw.from_wiki((args.target, ))) listname = libssw.from_wiki.article and libssw.from_wiki.article[0][0] else: targets = OrderedDict(libssw.from_html((args.target, ), cache=False)) listname = libssw.from_html.article # 一覧ページ名の取得 listname = args.list_name or listname verbose('listname: ', listname) if not listname: emsg('E', '一覧ページ名を取得できませんでした。-l オプションで指定してください。') # listp_url = gen_sswurl(listname) listp = libssw.quote(listname) verbose('quoted listp: ', listp) print('ページ名:', listname) not_sid = libssw.NotKeyIdYet(args.start_pid, 'start', 'pid') before = True if args.start_pid else False shortfalls = set() for prod_url in targets: # 作品情報 props = targets[prod_url] verbose('props: ', props.items()) if before and not_sid(libssw.gen_pid(prod_url)): continue else: before = False if not props.actress: continue if any('総集編' in n for n in props.note): continue print('\nTITLE: {}'.format(props.title)) print('URL: {}'.format(prod_url)) notfounds = [] # 作品の出演者情報 for actr in props.actress: if not any(actr[:2]): continue else: shown = actr[0] dest = actr[1] or actr[0] result = '' print('* {}({}):'.format(dest, shown) if shown != dest else '* {}:'.format(shown), '...\b\b\b', end='') rdr = libssw.follow_redirect(dest) if rdr and rdr != dest: dest = rdr print('(リダイレクトページ) ⇒ {}: '.format(rdr), end='') actr_url = gen_sswurl(dest) # 女優名のページをチェック present, link2list, linked = check_actrpage( actr_url, listp, prod_url) verbose('present: {}, link2list: {}, linked: {}'.format( present, link2list, linked)) if not present: notfounds.append(dest) shortfalls.add(dest) if link2list == 404: result += '✕ (女優ページなし)'.format(shown) else: # 女優ページになかったら作品URLで検索してヒットしたWikiページでチェック for purl, label in searchwiki_by_url(prod_url): if label.startswith(dest): present, link2list, linked = check_actrpage( purl, listp, prod_url) if present: result += ' ⇒ {}'.format(label) break else: result += '✕ (女優ページあり)' else: if linked: result += '○' elif link2list: result += '△ (他の一覧ページへのリンクあり: {})'.format(','.join( '"{}"'.format(libssw.unquote(p)) for p in link2list)) else: result += '△ (一覧ページへのリンクなし)' print(result, actr_url) # ウィキテキストの作成 if notfounds and args.gen_wikitext: props['title'] = '' # 副題の時もあるので一旦リセット b, status, data = dmm2ssw.main(props=props, p_args=argparse.Namespace( note=args.note, series=args.series, label=args.label, linklabel=args.linklabel, hide_list=args.hide_list, smm=False)) verbose('Return from dmm2ssw: {}, {}, {}'.format(b, status, data)) if b: print() print(data.wktxt_a) if args.browser: libssw.open_ssw(notfounds)
def main(): args = get_args() libssw.files_exists('r', *args.wikifiles) if args.out: if args.replace: writemode = 'w' else: libssw.files_exists('w', args.out) writemode = 'x' else: writemode = None g_actid = [] seq = [] contents = dict() release = dict() # 女優IDがURL渡しだったときの対処 add_actid(g_actid, args.actress_id) # 除外対象 no_omits = libssw.gen_no_omits(args.no_omit) verbose('non omit target: ', no_omits) # ウィキテキストの読み込み # 女優IDも取得 for key, rdate, item in get_existing(g_actid, args.wikifiles): seq.append(key) contents[key] = item release[key] = rdate verbose('key: ', key) verbose('rdate: ', rdate) verbose('item: ', item) # 複数のIDがあった時にカンマで区切る aidstr = ','.join(g_actid) emsg('I', '女優ID: ', aidstr) listparser = libssw.DMMTitleListParser(no_omits) priurls = libssw.join_priurls('actress', aidstr) # Wikiにない作品情報の取り込み emsg('I', '作品一覧を取得中...') products = OrderedDict((u, p) for u, p in libssw.from_dmm(listparser, priurls) if u not in seq) emsg('I', '一覧取得完了') total = len(products) if not total: emsg('E', '検索結果は0件でした。') verbose('Start building product info') if not VERBOSE: print('作成中...', file=sys.stderr, flush=True) # 不足分のウィキテキストを作成 current = seq[:] newitems = [] rest = total omitted = 0 dmmparser = libssw.DMMParser(no_omits) for url in products: props = products[url] verbose('props: ', props.items()) props.pid, g_cid = libssw.gen_pid(props.url) libssw.inprogress('(残り {} 件/全 {} 件: 除外 {} 件) '.format( rest, total, omitted)) b, status, data = dmm2ssw.main(props=props, p_args=args, dmmparser=dmmparser) verbose('Return from dmm2ssw: {}, {}, {}'.format(b, status, data)) if b: newitems.append(data) elif status == 404: emsg('I', 'ページが見つかりませんでした: url="{}"'.format(props.url)) newitems.append(data) else: emsg( 'I', 'ページを除外しました: ' 'cid={0}, reason=("{1[0]}", "{1[1]}")'.format(props.cid, data)) omitted += 1 rest -= 1 verbose('rest: {} / total: {} / omitted: {}'.format( rest, total, omitted)) # レンタル先行作品があった場合のためソート newitems.sort(key=itemgetter(0), reverse=True) # マージ i = -1 for new in newitems: verbose('new: ', new) if new.url in seq: # レンタル版に変更にあったものの既存チェック continue for i, key in enumerate(seq[i + 1:], start=i + 1): # 時系列で途中のデータの挿入 verbose('i, key: {}, {}'.format(i, key)) if not key.isdecimal(): verbose('new: {} > curr: {}'.format( new.release.replace('/', '.'), release[key])) if new.release.replace('/', '.') > release[key]: # 新規データの挿入 verbose('insert: {}, {}'.format(key, contents[key][1])) seq.insert(i, new.url) contents[new.url] = new.wktxt_a release[new.url] = new.release break elif '----' in contents[key]: seq.append(new.url) contents[new.url] = new.wktxt_a release[new.url] = new.release break else: # 残りのデータの追加 seq.append(new.url) contents[new.url] = new.wktxt_a release[new.url] = new.release if args.diff: # 差分の出力 libssw.show_diff(tuple(map(contents, current)), tuple(map(contents, seq)), '追加前', '追加後') # 出力 header = False i = 0 fd = open(args.out, writemode) if args.out else sys.stdout while seq: key = seq.pop(0) if key.startswith('http://'): i += 1 if args.split and not i % args.split: print('// {}'.format(i), file=fd) content = contents[key] if content.startswith('*'): header = True print(content, file=fd) if (not header or len(content) > 2) and seq: print(file=fd) header = False print() if args.out: fd.close()