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 04:37 pm (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
map и lambda — это устаревшая классика. Каждый раз, когды ты их используешь, задайся вопросом — почему не comprehension?! dict comprehension даже в 2.7 есть.

pages = {x: 1 for x in fossil(["wiki", "list"]).split("\n")}
Edited Date: 2017-11-05 04:38 pm (UTC)

Date: 2017-11-14 08:43 am (UTC)
filin: (Default)
From: [personal profile] filin
scala, haskell... Ну да, ты на языках высокого уровня нынче не пишешь.

В хаскеле, впрочем, list comprehension используется редко. А вот monad comprehension - в хвост и в гриву, иначе с монадами получается нечитаемый код. А в scala, насколько я могу видеть, и списковый тоже часто.

И код на ней, кстати, ближе к tcl получается.

Date: 2017-11-14 02:05 pm (UTC)
filin: (Default)
From: [personal profile] filin
Ну, не знаю... На мой нынешний взгляд, шелл - это язык уровня ассемблера. По характеристикам "читаемо человеком", "шансы не запутаться, обрабатывая ситуации, отличные от идеальных" и, если речь не о zsh, "запомните это, дети, ибо понять это невозможно".

Пока у тебя ситуация идеальная, шелл, конечно, повыше уровнем будет. На нем в одну строку выражается то, что на приличном ЯВУ занимает 10 (при условии, что у тебя GNU tools, потому что это далеко не на нем самом выражается). Зато в неидеальных на приличном ЯВУ это ну, 20, а на шелле минимум 100, и неидеальность в процессе только прогрессирует. Такой язык я считаю низкоуровневым.

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

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

Profile

vitus_wagner: My photo 2005 (Default)
vitus_wagner

June 2025

S M T W T F S
1 23 4 56 7
89 1011 12 13 14
1516 17 18 192021
2223 2425 2627 28
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 10th, 2025 05:25 am
Powered by Dreamwidth Studios