Last active
April 7, 2020 07:19
-
-
Save faithandbrave/6cc5829db51f7abd57e2bcc226efac22 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import argparse | |
| import glob | |
| import re | |
| import os | |
| import urllib.request, urllib.error, urllib.parse | |
| import requests | |
| import sys | |
| def check_url(url: str, retry: int = 3) -> (bool, str): | |
| try: | |
| url_parts = urllib.parse.urlparse(url) | |
| res = requests.get("://".join([url_parts.scheme, url_parts.netloc])) | |
| if res.url: | |
| if res.url == url: | |
| return True, "" | |
| return check_url(res.url) | |
| else: | |
| return res.status_code != 404, "not found" | |
| except requests.exceptions.ConnectionError as e: | |
| return False, str(e) | |
| except requests.exceptions.RequestException as e: | |
| if retry <= 0: | |
| return False, str(e) | |
| return check_url(url, retry - 1) | |
| def fix_link(link: str) -> str: | |
| if "http" in link or ".md" in link: | |
| if "http" in link and "(" in link: | |
| link = link + ")" | |
| return re.sub("#.*", "", link.strip()) | |
| else: | |
| return "" | |
| def find_all_links(text: str) -> list: | |
| links = [] | |
| for m in re.finditer(r'\[(.*?)\]\((.*?)\)', text): | |
| link = fix_link(m.group(2)) | |
| if link: | |
| links.append(link) | |
| for m in re.finditer(r'[\*-] (.*?)\[link (.*?)\]', text): | |
| link = fix_link(m.group(2)) | |
| if link: | |
| links.append(link) | |
| return links | |
| if __name__ == '__main__': | |
| argparser = argparse.ArgumentParser(description="") | |
| argparser.add_argument("--check-inner-link", | |
| dest='check_inner_link', | |
| action='store_true', | |
| default=False) | |
| argparser.add_argument("--check-outer-link", | |
| dest='check_outer_link', | |
| action='store_true', | |
| default=False) | |
| args = argparser.parse_args() | |
| if not args.check_inner_link and not args.check_outer_link: | |
| print("unchecked", file=sys.stderr) | |
| sys.exit(1) | |
| found_error = False | |
| current_dir = os.getcwd() | |
| for p in glob.glob("**/*.md", recursive=True): | |
| dirname = os.path.dirname(p) | |
| with open(p) as f: | |
| text = f.read() | |
| for link in find_all_links(text): | |
| rel_link = "" | |
| if link.startswith("/"): | |
| rel_link = os.path.join(current_dir, link.lstrip("/")) | |
| elif not link.startswith("http"): | |
| rel_link = os.path.join(dirname, link) | |
| if link.startswith("http"): | |
| if not args.check_outer_link: | |
| continue | |
| exists, reason = check_url(link) | |
| if not exists: | |
| print("{} href {} not found. {}".format(p, link, reason), file=sys.stderr) | |
| found_error = True | |
| elif link.endswith(".nolink"): | |
| if not args.check_inner_link: | |
| continue | |
| if os.path.exists(rel_link): | |
| print("nolinked {} href {} found.".format(p, link), file=sys.stderr) | |
| found_error = True | |
| else: | |
| if not args.check_inner_link: | |
| continue | |
| if not os.path.exists(rel_link): | |
| print("{} href {} not found.".format(p, link), file=sys.stderr) | |
| found_error = True | |
| if found_error: | |
| sys.exit(1) |
Author
Author
https://raw.githubusercontent.com/cpprefjp/image/master/lang/cpp20/consistent_comparison_01.png
これにアクセスできない。 -> fixed
Author
めちゃくちゃ遅い。
URLチェックをなくすと、1.3秒でおわる。
URLチェックを入れるとおそらく数時間かかる。
Author
reference/tuple/make_from_tuple.md href `/reference/utility/forward.md` not found.
reference/atomic/atomic_flag_wait_explicit.md href notify_one.md not found.
reference/atomic/atomic_ref.md href atomic_ref[store.md not found.
reference/concepts/semiregular.md href /reference/concepts/default_constructible.md not found.
reference/string/basic_string/insert.md href /reference/string_view/basic_string_view/append.md not found.
reference/string/basic_string/assign.md href /reference/string_view/basic_string_view/append.md not found.
reference/string/basic_string/compare.md href /reference/string_view/basic_string_view/append.md not found.
reference/string/basic_string/replace.md href /reference/string_view/basic_string_view/append.md not found.
reference/string/basic_string/append.md href /reference/string_view/basic_string_view/append.md not found.
reference/functional/boyer_moore_searcher.md href /reference/concepts/default_constructible.md not found.
reference/functional/boyer_moore_horspool_searcher.md href /reference/concepts/default_constructible.md not found.
Author
日本語が含まれているURLを処理できない。 -> fixed
Author
URLに丸カッコが含まれているとURL内のカッコ閉じでパースされてしまう。正規表現でどうにかなるのかな… -> fixed (workaround)
[CRTP:Curiously Recurring Template Pattern](https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/奇妙に再帰したテンプレートパターン(Curiously_Recurring_Template_Pattern))
https://ja.wikipedia.org/wiki/ノルム_(体論)
Author
リダイレクトのはずが404が返ってきてしまう。 -> fixed requests.getとres.urlのチェックでいけた
Author
URLチェックできた気がするので、落ち着いた場所に行ったら実行してみる。数時間かかるので。
Author
リダイレクト先URLのチェックをつけた
Author
スクリプトの実行方法:
サイト内リンクのチェック (1秒くらいでおわる軽量タスク):
pip3 install requests
python3 link_check.py --check-inner-link
サイト外リンクのチェック (1時間くらいかかる重いタスクなので、1日1回程度の実行が望ましい):
pip3 install requests
python3 link_check.py --check-outer-link
(外部ライブラリはrequestsしか使っていないので、requirements.txtを作るほどでもないかなと)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ラムダ式に引っかかる。 -> fixed