#!/usr/bin/env python
# ver1.4.1 3/1恒心
#1.4.0のソースコードを勝手に改造してArchiveテンプレートからCallinshowテンプレートで出力するように変更
#
# 使用上の注意
# 当プログラムは一切無保証です
# 基本的に最新のツイートを上から順にwiki文に変換していきます
# Nitterinstanceは使うnitterのインスタンス、Archivetodayは使うarchivetodayのミラー
# Archivetodaystandardはwikiで標準的に使われてるミラーのURLですを
# 上3つのURLでは末尾の/も含めて下さいでないとバグります(例:○:'https://archive.is/' ×:'https://archive.is')
# 玉ねぎ環境でなければNitterinstanceとArchivetodayのURLはクリアネット版に変え、Curlheadからtorsocksを取らないとダメです
# でもツイートに含まれるリンクを全部踏みに行くので変なサイト踏むこと考えたら玉ねぎ推奨
# nitterというのはJSなしでツイッター見放題検索し放題という有能ですのでこれを使って特定ナリ事実追求ナリのワークに励むことを切に望む
# https://github.com/zedeus/nitter/wiki/Instances nitterのインスタンス一覧ですを
# Limitは上限なので100じゃ足りなければ適当に増やすこと
# 検索クエリを入れるナリと言われたら検索欄に突っ込む文を入れてください
# from:アカウント名は不要でスペースのところは改行で区切ります
# 「from:Callinshow 無能 脱糞 弟殺し」なら「無能」→改行→「脱糞」→改行→「弟殺し」→空欄で改行とナリます
# ここにツイートの本文を入れる!と言われたら記録の最後を指定できます
# ツイートの本文から1行分コピペしてペタっとするのが使い方
# 2行以上に対応してないだけになんとも言えないですわ・・・・・・
import subprocess
import codecs
import re
from time import sleep
Nitterinstance = 'https://nitter.skrep.in/'
Archivetoday = 'http://archiveiya74codqgiixo33q62qlrqtkgmcitqx5u2oeqnmn5bpcbiyd.onion/'
Archivetodaystandard = 'https://archive.ph/'
Curlhead = 'torsocks curl -sS -A "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0" '
Redirectcurl = ' -w "%{redirect_url}" -o /dev/null 2> /dev/null'
Searchquery = "search?q=from%3A"
Limit = 400
Andamp = '&' + 'amp;'
HTMLtext = '<div class="tweet-content media-body" dir="auto">'
def get_redirect_url(src_url):
srcb_url = src_url
srca_url = subprocess.run(Curlhead + srcb_url + Redirectcurl, stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8')
while srca_url != '':
srcb_url = srca_url
srca_url = subprocess.run(Curlhead + srcb_url + Redirectcurl, stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8')
else:
return srcb_url
def make_txt(txt_data):
txt_data = '{|class="wikitable" style="text-align: left;"\n' + txt_data
with codecs.open('tweet.txt', 'w', 'utf-8') as f:
f.write(txt_data)
print("テキストファイル手に入ったやで〜")
exit()
def get_newpage(source_url):
for ratelimit_counter in range(8):
new_page = subprocess.run(Curlhead + '"' + Nitterinstance + source_url + '"', stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8')
if HTMLtext in new_page:
return new_page
break
else:
sleep(3)
else:
print('インスタンス 通信制限 多すぎ 無能 スクリプト 続行不能 強制終了')
make_txt(output_txt)
account_flag = True
while account_flag:
print("アカウント名を入れなければない。")
account_str = input()
account_check = subprocess.run(Curlhead + '"' + Nitterinstance + account_str + '"' + ' | grep "<title>"', stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8')
if 'Error' in account_check:
print(account_str + "は実在の人物ではありませんでした")
elif account_check == "":
print("インスタンスが死んでいるまたは末尾の/が抜けてますを")
exit()
else:
print("最終的に出会ったのが@" + account_str + "だった。")
account_flag = False
query_flag = True
while query_flag:
print("検索クエリを入れるナリ。空欄を入れると検索開始ナリ。")
query_str = [account_str]
query_input = input()
while query_input != '':
query_str.append(query_input)
query_input = input()
query_check = get_newpage(Searchquery + '+'.join(query_str))
if 'No items found' in query_check:
print("適切なクエリを入力することを切に望む。")
else:
print("クエリのピースが埋まっていく。")
query_flag = False
print("ここにツイートの本文を入れる!すると・・・・なんと一致するツイートで記録を中断する!(これは本当の仕様です。)ちなみに、空欄だと" + str(Limit) + "件まで終了しない。")
end_blank = True
end_str = input()
if end_str != '':
end_blank = False
output_txt = '|}'
tweet_list = query_check
for i in range(Limit):
if not HTMLtext in tweet_list:
newlist_url = "search" + subprocess.run('grep -m 1 \'<div class="show-more">\' | sed \'s/.*<a href="//\' | sed \'s/">Load more.*//\'',input=tweet_list.encode('utf-8'),stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace(Andamp,'&').replace('\n','')
tweet_list = get_newpage(newlist_url)
row_number = int(subprocess.run('grep -n -m 1 \'<div class="tweet-content media-body" dir="auto">\' | cut -f 1 --delim=\':\' ',input=tweet_list.encode('utf-8'),stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('\n',''))
tweet_url = 'https://twitter.com' + subprocess.run('sed -n ' + str(row_number - 3) + 'p | sed \'s/^.*a href="//\' | sed \'s/#m.*$//\'',input=tweet_list.encode('utf-8'),stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('\n','')
if tweet_url == 'https://twitter.com':
print("急に残りツイートが無くなったな終了するか")
break
elif account_str.lower() not in tweet_url.lower():
tweet_list = tweet_list.replace(HTMLtext, '済', 1)
print('リツイートなのでポア')
continue
archive_url = subprocess.run(Curlhead + '"' + Archivetoday + tweet_url + '" | grep -m 1 "display:block;color:blue;font-size:16px;word-break:break-word" | sed \'s/.*display:block;color:blue;font-size:16px;word-break:break-word" href="//\' | cut -f 1 --delim=\'"\' | sed \'s#https\\{0,1\\}://[^/]*/#' + Archivetodaystandard + '#\'',stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('\n','')
if Archivetodaystandard not in archive_url:
print(tweet_url + "の魚拓がない。これはいけない。")
archive_url = Archivetodaystandard + tweet_url
tweet_toprow = subprocess.run('grep -n -m 1 \'<div class="tweet-content media-body" dir="auto">\' | cut -f 1 --delim=\':\'',input=tweet_list.encode('utf-8'),stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('\n','')
tweet_bottomrow = subprocess.run('tail -n +' + tweet_toprow + ' | grep -n -m 1 "</div>" | cut -f 1 --delim=\':\'',input=tweet_list.encode('utf-8'),stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('\n','')
tweet_content = subprocess.run('tail -n +' + tweet_toprow + ' | head -n ' + tweet_bottomrow + ' | sed \'s/^.*<div class="tweet-content media-body" dir="auto">//\' | sed \'s#</div>.*$##\' | sed \'s#<a href="/[^<]*>##g\' | sed -r \'s#<a href="(http[^"]*)">[^<]*</a>*#\\n{{Archive|1=\\1|2=' + Archivetoday + '\\1|3=\\1}}#g\' | sed \'s#</a>##g\' | sed \'s/$/<br>/\' | sed \'$ s/<br>//\'',input=tweet_list.encode('utf-8'),stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('#','<nowiki>#</nowiki>').rstrip()
for archive_link in re.findall(Archivetoday + 'http[^|]*',tweet_content):
src_url = archive_link.replace(Archivetoday,'')
archive_redirectedlink = Archivetoday + get_redirect_url(src_url)
archive_new = subprocess.run(Curlhead + '"' + archive_redirectedlink + '" | sed \'s/>/>\\n/g\'| grep -m 1 "display:block;color:blue;font-size:16px;word-break:break-word" | sed \'s/.*display:block;color:blue;font-size:16px;word-break:break-word" href="//\' | cut -f 1 --delim=\'"\' | sed \'s#https\\{0,1\\}://[^/]*/#' + Archivetodaystandard + '#\'',stdout=subprocess.PIPE,shell=True).stdout.decode('utf-8').replace('\n','')
if archive_new == '':
print(archive_link.replace(Archivetoday,'') + "の魚拓がない。これはいけない。")
archive_new = archive_link.replace(Archivetoday,Archivetodaystandard)
tweet_content = tweet_content.replace(archive_link,archive_new)
output_txt = '!{{CallinShowLink|1=' + tweet_url + '|2=' + archive_url + '}}\n|-\n|\n' + tweet_content + '\n|-\n' + output_txt
print("ツイートを" + str(i + 1) + "件も記録したンゴwwwwwwwwwww")
tweet_list = tweet_list.replace(HTMLtext, '済', 1)
if not end_blank and end_str in tweet_content:
print("目的ツイート発見でもう尾張屋根")
break
else:
print(str(Limit) + "件も記録している。もうやめにしませんか。")
make_txt(output_txt)