Esempio n. 1
0
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'])
Esempio n. 2
0
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)
Esempio n. 3
0
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()
Esempio n. 4
0
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()
Esempio n. 5
0
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)
Esempio n. 6
0
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()