vitus_wagner: My photo 2005 (Default)
[personal profile] vitus_wagner
Тут в связи с переездом всех моих сюжетов в единую платформу - fossil, решил заодно проверить, много ли у меня в соотвествующих wiki висячих ссылок.

Написал скриптик:
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Поиск висячих ссылок в fossil wiki
Запускается из открытого checkout-а.
Предполагает что все страницы в формате markdown
"""

import re,sys,os
if sys.stdout.encoding != 'UTF-8':
    import codecs
    sys.stdout = codecs.getwriter('utf-8')(sys.stdout, 'strict')


from subprocess import Popen,PIPE,CalledProcessError
def fossil(args, stdin=None):
    """
    Запускаем fossil  с аргументами из списка args.
    передавая ему на вход строку stdin.
    Возвращает stdout. 
    Выбрасывает CalledProcessError если fossil-у что-то не понравилось
    """
    p=Popen(["fossil"]+args,stdin=PIPE, stdout=PIPE,stderr=PIPE)
    (out,err) = p.communicate(stdin)
    if p.returncode!=0:
        print >>sys.stderr,err
        raise CalledProcessError(p.returncode," ".join(["fossil"]+args),err)
    return out

#
# Получить список страниц и сконвертирвоать его в ключи словаря со
# значениями 1
#
pages=dict(map(lambda x:(x,1),fossil(["wiki","list"]).split("\n")))
#
# Поскольку в конце вывода fossil wiki list есть перевод строки,
# в словаре будет один лишний элемент с пустым ключом
del pages['']

print "Wiki contains %d pages" % len(pages.keys())
dangling={}

for page in pages:
    contents = fossil(["wiki","export",page])
    for link in re.finditer("\(wiki\?name=([^)]+)\)",contents):
        linkname=link.group(1).replace("+"," ")
        linkname=re.sub("%([0-9A-Fa-f]{2})",lambda m:chr(int(m.group(1),16)),linkname)
        anchor=linkname.find("#")
        if anchor > -1:
            linkname=linkname[:anchor]
        if linkname in pages: 
            continue
        if linkname in dangling:
            dangling[linkname].add(page)
        else:
            dangling[linkname]=set([page])

print "Found %d dangling links"%len(dangling.keys())
for page in sorted(dangling.keys()):
    print u"%-40s %s"%(page.decode("utf-8"),",".join(dangling[page]).decode("utf-8"))
и погонял его на все репозитории.

Результат

репозиторийвсего страницвисячих ссылок
Русалки340
Ясмина2060
Спейсиане226122
Галактическая Федерация76116


Что удивительно - наиболее давно разрабатываемая реальность - самая бедная (тем более что я знаю, что там еще многие существующие страницы нуждаются в серьезной доработке. Я, например на страницу Вента не залил ни одной из нарисованных еще четверть века назад и давно отсканированных карт Венты.

Все плохо и в вики по единственной законченной книге - спейсианской. Там, кстати, могут быть посчитаны не все висячие ссылки, поскольку там присутствуют страницы в формате Fossil Wiki, а вышеприведенный скрипт парсит только markdown.

Date: 2017-11-05 02:25 pm (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
Нет необходимости использовать словарь, если всё, что тебе нужно — уникальный список.

pages = set(fossil(["wiki","list"]).split("\n"))

Так ты и от map избаляешься, и от глупой лямбды.

print "Wiki contains %d pages" % len(pages)
Edited Date: 2017-11-05 02:26 pm (UTC)

Date: 2017-11-05 06:20 pm (UTC)
From: [personal profile] ramendik
Как написать на Питоне скрипт, который не получается понять с первого прочтения?

Сложно, но возможно - задействовать re...

Profile

vitus_wagner: My photo 2005 (Default)
vitus_wagner

July 2025

S M T W T F S
  12345
6789 1011 12
13141516 17 1819
20212223 242526
2728293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 24th, 2025 12:26 pm
Powered by Dreamwidth Studios