コンテンツにスキップ

利用者:Ftbbot/スクリプト

ここではFtbbotで使っているスクリプトの説明をします。ただし、必ずしも最新版のものとは限りません。また、公開のために使用しているファイルから一部変更している箇所もあります。バグやアドバイス等があれば私の会話ページまでお願いします。以下のスクリプトを自己責任で使用、改変するのはかまいませんが、その実行結果については責任を負えません

add_text.pyの修正[編集]

add_text.pyは「\n」の文字を改行とみなすことになっていますが、upオプションを使った場合には適用されません。削除依頼対処の報告は、ページ冒頭に書くことになっているため、これは非常に困る。バグだと思うのですが、どこに報告していいのかも分からないため、私は元のファイルを「add_text_up.py」の名でコピーし、以下の修正をして使っています。

「# If instead the text must be added above...」の行を探し、

    # If instead the text must be added above...
    else:
        newtext = addText + '\n' + text

elseの下に「addText = addText.replace('\\n', '\n')」と付け足します。

    # If instead the text must be added above...
    else:
        addText = addText.replace('\\n', '\n')
        newtext = addText + '\n' + text

BOM除去プログラム[編集]

pywikipediaで出力したテキストファイルは、バイトオーダーマーク(BOM)を含みますが、ウィンドウズでこのテキストファイルを再利用するには、再利用前にこのBOMを除去する必要があります。以下のプログラムでは、この除去のためにnon-BOM : http://www.vector.co.jp/soft/win95/util/se218158.html を使用しています。

実行ファイル[編集]

私はエクセルVBAの操作に慣れているため、pywikipediabotもVBAから呼び出すことにしています。エクセルの表に処理するページ名などを入力し、VBAマクロを実行して処理しています。

エクセルの入力画面
A B C
1 議論ページ名 特筆性の無いタレント20120101 対処
2 削除の場合、その理由 単独項目化するほどの必要性がない項目
3 対象ページ ほげ丸 存続初回
4 ほげ桜 削除初回
5 ふが太郎 版指定削除追加

上記のように入力し、マクロ「削除依頼対処の報告」を実施すると、「存続」と「版指定削除」は記事空間から削除依頼タグを除去してノートページに議論ページへの誘導リンクを追記、「削除」は記事を削除した後にノートページへの誘導リンクを追記します。

削除処理はこのマクロから実施できますが、版指定削除は手動で実施する必要があります。「削除の場合、その理由」は、削除の理由欄に利用されます。「存続」と「版指定削除」では無視されます。

実際のpywikipediaの実行は、いわゆるコマンドプロンプト シェルで呼び出して使用しています。コマンドラインで「○○の処理をしますか?」と英語で聞いてきますので、yかnを選びます。

VBAのソース[編集]

'このプログラムの実行には、pywikipediabot以外にも、次の外部プログラムが必要です。
'
'non-BOM : http://www.vector.co.jp/soft/win95/util/se218158.html

Option Explicit

Private Declare Function OpenProcess Lib "kernel32" _
    (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
     ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" _
    (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
    (ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INF = &H400&
Private Const STILL_ACTIVE = &H103&

Public Const myPW = "c:\pywikipedia\"
Public Const myPWlogPath = "c:\pywikipedia\logs\"

Sub コモンズへ移動()
'
' 削除依頼対処の報告 Macro
'
    Const myPageColumn = 2 'ページ名の保存列番号
    Const myToPageColumn = 3
    Const myReasonColumn = 5 '対処種別の保存列番号
    Const myPageStartLine = 3 'ページ名データの書き込み開始行
    Const myListsize = 500 '対象記事名保存の配列サイズ
    Const adTypeText = 2 'オブジェクトに保存するデータの種類を文字列型に指定する
    Const adSaveCreateOverWrite = 2 'ファイルがないとき作成する
    Const adCR = 13 '改行復帰を示します。
    Const adCRLF = -1
    Const adWriteLine = 1
    
    Dim myLine As Integer
    Dim myPagename As String
    Dim myToPagename As String
    Dim myLogname As String
    Dim myDiscuss As String
    Dim myTimename As String
    Dim myAction As String '対処方法の一時記憶
    Dim myListDel(0) '削除実行ファイルリストの保存場所
    Dim myLoop As Integer 'ループカウンタ
    Dim myFilename As String '処理対象ファイル名の一時記憶
    Dim myTemp As Variant
    Dim myCommandline As String
    Dim rc 'shellの戻り値を入れる
    Dim myMessagestr As String '報告の書式を入れる
    Dim myReason As String
    
    '
    myLine = myPageStartLine
    'myTimename = Format(Date, "yyyymmdd-") & Format(Time, "hhmmss")
    'myLogname = myTimename & ".log"
    
    Do
        myPagename = Cells(myLine, myPageColumn)
        If myPagename = "" Then Exit Do
                myToPagename = Cells(myLine, myToPageColumn)
        If Left(myToPagename, 5) = "ファイル:" Then myToPagename = "File:" & Mid(myToPagename, 6, 200)
        myReason = Cells(myLine, myReasonColumn)
        If (myToPagename <> "") Then
            myReason = myReason & ": [[commons:" & myToPagename & "]]"
        End If
        '削除対象リストに加える
        myListDel(0) = myPagename
        
        myFilename = myPWlogPath & "dellist.txt"
        一覧ファイルを作る myListDel, myFilename
        記事の削除 myReason, myFilename, True
        
        myLine = myLine + 1
    Loop
    
End Sub

Sub 緊急案件タグを取る()
    Dim myStr1 As String, myStr2 As String '置き換え前後の文字
    Dim mySummary As String
    Dim myPagename As String, myPagename2 As String
    Dim myLang As String, myOrg As String, myOrg2 As String
    
    mySummary = "-緊急案件タグ"
    If Cells(1, 1) <> "緊急案件タグ" Then End
    myPagename = "ノート:" & Cells(1, 2).Value
    
    myStr1 = "<noinclude>\[\[Category:緊急案件\|\s{{REVISIONTIMESTAMP}}\]\]</noinclude>"
    myStr2 = ""
    文字列の置換byリンク先 myPagename, mySummary, myStr1, myStr2

    myStr1 = "<noinclude>\[\[Category:緊急案件\]\]</noinclude>"
    myStr2 = ""
    文字列の置換byリンク先 myPagename, mySummary, myStr1, myStr2
End Sub

Function 文字列を正規表現用に修正(myString As String) As String
    Dim myTempString As String
    myTempString = myString
    myTempString = Replace(myTempString, " ", "\s")
    myTempString = Replace(myTempString, "(", "\(")
    myTempString = Replace(myTempString, ")", "\)")
    文字列を正規表現用に修正 = myTempString
End Function

Sub 文字列の置換byファイル(myFilename As String, mySummary As String, myStr1 As String, myStr2 As String)
    'ファイル「myFileName」の中で指定された記事について置換を行う。
    Dim Q As String
    Dim myCommandline As String
    Dim rc
    ChDir ("c:\pywikipedia")
    Q = Chr(34)
    myCommandline = "c:\python\python replace.py -regex -summary:" & Q & mySummary & Q & " -file:" & Q & myFilename & Q & " " & Q & myStr1 & Q & " " & Q & myStr2 & Q
    rc = Shell(myCommandline, vbNormalFocus)
    ShellEnd (rc)        '終了するまで待機
    If rc = 0 Then MsgBox "起動に失敗しました"
End Sub


Sub 文字列の置換byリンク先(myReference As String, mySummary As String, myStr1 As String, myStr2 As String)
    '記事名myReferenceを参照している記事について置換を行う。
    Dim Q As String
    Dim myCommandline As String
    Dim rc
    ChDir ("c:\pywikipedia")
    Q = Chr(34)
    myCommandline = "c:\python\python replace.py -regex -summary:" & Q & mySummary & Q & " -ref:" & Q & myReference & Q & " " & Q & myStr1 & Q & " " & Q & myStr2 & Q
    rc = Shell(myCommandline, vbNormalFocus)
    ShellEnd (rc)        '終了するまで待機
    If rc = 0 Then MsgBox "起動に失敗しました"
End Sub


Sub 削除依頼対処の報告()
'
' 削除依頼対処の報告 Macro
'
    Const myPageColumn = 2 'ページ名の保存列番号
    Const myActionColumn = 3 '対処種別の保存列番号
    Const myPageStartLine = 3 'ページ名データの書き込み開始行
    Const myListsize = 500 '対象記事名保存の配列サイズ
    Const adTypeText = 2 'オブジェクトに保存するデータの種類を文字列型に指定する
    Const adSaveCreateOverWrite = 2 'ファイルがないとき作成する
    Const adCR = 13 '改行復帰を示します。
    Const adCRLF = -1
    Const adWriteLine = 1
    
    Dim myLine As Integer
    Dim myPagename As String
    Dim myLogname As String
    Dim myDiscuss As String
    Dim myTimename As String
    Dim myAction As String '対処方法の一時記憶
    Dim myListDelAdd() '削除追加報告対象ファイルリストの保存場所(カッコ付けない)
    ReDim Preserve myListDelAdd(0)
    Dim myListDel() '削除実行ファイルリストの保存場所
    ReDim Preserve myListDel(0)
    Dim myListDelFirst() '削除処理初回ファイルリストの保存場所
    ReDim Preserve myListDelFirst(0)
    Dim myListDelAddKakko() '削除追加報告対象ファイルリストの保存場所(カッコ付ける)
    ReDim Preserve myListDelAddKakko(0)
    Dim myListMove() '削除処理タグ除去対象ファイルリストの保存場所
    ReDim Preserve myListMove(0)
    Dim myListKeep() '存続処理対象ファイルリストの保存場所
    ReDim Preserve myListKeep(0)
    Dim myListKeepAdd() '存続処理対象ファイル追加リストの保存場所
    ReDim Preserve myListKeepAdd(0)
    Dim myListRevdel() '特定版削除処理対象ファイルリストの保存場所
    ReDim Preserve myListRevdel(0)
    Dim myDelnum As Integer, myKeepnum As Integer, myPartkeepnum As Integer 'それぞれの対象記事数を記憶
    Dim myLoop As Integer 'ループカウンタ
    Dim myFilename As String '処理対象ファイル名の一時記憶
    Dim myTemp As Variant
    Dim myCommandline As String
    Dim rc 'shellの戻り値を入れる
    Dim myMessagestr As String '報告の書式を入れる
    Dim myReason As String
'
    myLine = myPageStartLine
    myTimename = Format(Date, "yyyymmdd-") & Format(Time, "hhmmss")
    myLogname = myTimename & ".log"
    myDiscuss = Cells(1, myPageColumn)
    If myDiscuss = "" Then
        myReason = Cells(2, myPageColumn)
    Else
        myReason = Cells(2, myPageColumn) & ":[[Wikipedia:削除依頼/" & myDiscuss & "]]"
    End If
    
    myDelnum = 0
    myKeepnum = 0
    myPartkeepnum = 0

    'ページリストを作る
    Do
        myPagename = Cells(myLine, myPageColumn)
        myAction = Cells(myLine, myActionColumn)
        Select Case myAction
            Case "削除初回":
                '削除初回リストに加える
                myListDelFirst(UBound(myListDelFirst)) = myPagename
                ReDim Preserve myListDelFirst(UBound(myListDelFirst) + 1)
                '削除対象リストに加える
                myListDel(UBound(myListDel)) = myPagename
                ReDim Preserve myListDel(UBound(myListDel) + 1)
            Case "削除追加":
                '削除報告追加リストに加える
                myListDelAddKakko(UBound(myListDelAddKakko)) = "ノート:" & myPagename
                ReDim Preserve myListDelAddKakko(UBound(myListDelAddKakko) + 1)
                '削除対象リストに加える
                myListDel(UBound(myListDel)) = myPagename
                ReDim Preserve myListDel(UBound(myListDel) + 1)
            Case "存続初回":
                '存続初回リストに加える
                myListKeep(UBound(myListKeep)) = myPagename
                ReDim Preserve myListKeep(UBound(myListKeep) + 1)
                '削除依頼タグ除去リストに加える
                myListMove(UBound(myListMove)) = myPagename
                ReDim Preserve myListMove(UBound(myListMove) + 1)
            Case "存続初回":
                '存続初回リストに加える
                myListKeep(UBound(myListKeep)) = myPagename
                ReDim Preserve myListKeep(UBound(myListKeep) + 1)
                '削除依頼タグ除去リストに加える
                myListMove(UBound(myListMove)) = myPagename
                ReDim Preserve myListMove(UBound(myListMove) + 1)
            Case "存続追加":
                '存続追加リストに加える
                myListKeepAdd(UBound(myListKeepAdd)) = "ノート:" & myPagename
                ReDim Preserve myListKeepAdd(UBound(myListKeepAdd) + 1)
                '削除依頼タグ除去リストに加える
                myListMove(UBound(myListMove)) = myPagename
                ReDim Preserve myListMove(UBound(myListMove) + 1)
            Case "版指定削除初回":
                '版指定削除初回リストに加える
                myListRevdel(UBound(myListRevdel)) = myPagename
                ReDim Preserve myListRevdel(UBound(myListRevdel) + 1)
                '削除依頼タグ除去リストに加える
                myListMove(UBound(myListMove)) = myPagename
                ReDim Preserve myListMove(UBound(myListMove) + 1)
            Case "版指定削除追加":
                '削除報告追加リストに加える
                myListDelAddKakko(UBound(myListDelAddKakko)) = "ノート:" & myPagename
                ReDim Preserve myListDelAddKakko(UBound(myListDelAddKakko) + 1)
                '削除依頼タグ除去リストに加える
                myListMove(UBound(myListMove)) = myPagename
                ReDim Preserve myListMove(UBound(myListMove) + 1)
            Case "版指定削除追加n":
                '削除報告追加リストに加える
                myListDelAdd(UBound(myListDelAdd)) = "ノート:" & myPagename
                ReDim Preserve myListDelAdd(UBound(myListDelAdd) + 1)
                '削除依頼タグ除去リストに加える
                myListMove(UBound(myListMove)) = myPagename
                ReDim Preserve myListMove(UBound(myListMove) + 1)
            Case Else
        End Select
        If myPagename = "" Then Exit Do
        myLine = myLine + 1
    Loop
        
    '★削除処理の実施
    If UBound(myListDel) > 0 Then
        myFilename = myPWlogPath & "dellist.txt"
        一覧ファイルを作る myListDel, myFilename
        記事の削除 myReason, myFilename, False
    End If
        
    '★削除依頼タグ除去処理
    If UBound(myListMove) > 0 Then
        myFilename = myPWlogPath & "removelist.txt"
        一覧ファイルを作る myListMove, myFilename
        削除依頼タグの除去 myFilename
    End If

    '★完全削除処理の初回報告
    If (UBound(myListDelFirst) > 0) And (myDiscuss <> "") Then
        myFilename = myPWlogPath & "delfirstlist.txt"
        一覧ファイルを作る myListDelFirst, myFilename
        myMessagestr = "{{subst:削除済みノート3|" & myDiscuss & "}}\n----\n"
        対処報告の初回 myDiscuss, myFilename, myMessagestr
    End If
        
    '★存続処理の初回報告
    If UBound(myListKeep) > 0 Then
        myFilename = myPWlogPath & "keeplist.txt"
        一覧ファイルを作る myListKeep, myFilename
        myMessagestr = "{{subst:不削除ノート3|" & myDiscuss & "}}\n----\n"
        対処報告の初回 myDiscuss, myFilename, myMessagestr
    End If
    
    '★存続処理の追加報告
    If UBound(myListKeepAdd) > 0 Then
        myFilename = myPWlogPath & "keepaddlist.txt"
        一覧ファイルを作る myListKeepAdd, myFilename
        削除依頼存続追加 myDiscuss, myFilename, True
    End If
    
    '★版指定削除の初回報告
    If UBound(myListRevdel) > 0 Then
        myFilename = myPWlogPath & "revdellist.txt"
        一覧ファイルを作る myListRevdel, myFilename
        myMessagestr = "{{subst:特定版削除済みノート2|" & myDiscuss & "}}\n----\n"
        対処報告の初回 myDiscuss, myFilename, myMessagestr
    End If
    
    '★削除の追加報告、記事名にカッコあり
    If UBound(myListDelAddKakko) > 0 Then
        myFilename = myPWlogPath & "addkakkolist.txt"
        一覧ファイルを作る myListDelAddKakko, myFilename
        削除依頼報告追加 myDiscuss, myFilename, True
    End If
    
    '★削除の追加報告、記事名にカッコなし
    If UBound(myListDelAdd) > 0 Then
        myFilename = myPWlogPath & "addlist.txt"
        一覧ファイルを作る myListDelAdd, myFilename
        削除依頼報告追加 myDiscuss, myFilename, False
    End If
    
End Sub

Sub 一覧ファイルを作る(myListFile, myFilename As String)
    Const adTypeText = 2 'オブジェクトに保存するデータの種類を文字列型に指定する
    Const adWriteLine = 1
    Const adSaveCreateOverWrite = 2 'ファイルがないとき作成する
    Dim txt As Object
    Dim myTemp As Variant
    Dim myCommandline As String
    Dim rc 'shellの戻り値を入れる
    
    ChDir ("c:\pywikipedia")
    Set txt = CreateObject("ADODB.Stream")
    txt.Type = adTypeText 'オブジェクトに保存するデータの種類を文字列型に指定する
    txt.Charset = "UTF-8" '文字列型のオブジェクトの文字コードを指定する
    txt.Open 'オブジェクトのインスタンスを作成
    
    '配列をオブジェクトに書き込む
    For Each myTemp In myListFile
        '1行ずつ書き込む
        'txt.WriteText (myTemp & Chr(13) & Chr(10)), adWriteLine
        txt.WriteText (myTemp), adWriteLine
    Next
    
    'オブジェクトの内容をファイルに保存
    txt.SaveToFile (myFilename), adSaveCreateOverWrite
    txt.Close 'オブジェクトを閉じる
    Set txt = Nothing 'メモリからオブジェクトを削除する
    
    'ファイルの先頭に付いたBOMを専用アプリケーションで除去。http://www.vector.co.jp/soft/win95/util/se218158.html
    myCommandline = "nbom " & myFilename
    rc = Shell(myCommandline, vbNormalFocus)
    ShellEnd (rc)        '終了するまで待機
    If rc = 0 Then MsgBox "起動に失敗しました"
End Sub

Sub 対処報告の初回(myDiscuss As String, myFilename As String, myMessagestr As String)
    Dim Q As String
    Dim mystr3 As String
    Dim Summary As String
    Dim myCommandline As String
    Dim rc

    ChDir ("c:\pywikipedia")
    Summary = "削除依頼対処の報告"
    Q = Chr(34)
    
    myCommandline = "c:\python\python add_text_up.py -talkpage -up -summary:" & Q & Summary & Q & " -file:" & Q & myFilename & Q & " -text:" & Q & myMessagestr & Q
    
    rc = Shell(myCommandline, vbNormalFocus)
    ShellEnd (rc)        '終了するまで待機
    If rc = 0 Then MsgBox "起動に失敗しました"

End Sub

Sub 削除依頼タグの除去(myFilename As String)
    Dim myStr1 As String, myStr2 As String '置き換え前後の文字
    Dim mySummary As String
    'myStr1 = "(<noinclude><!|<!)--削除についての議論が終了するまで、下記のメッセージ部分は除去しないでください。もしあなたがこのテンプレートを除去した場合、差し戻されます。またページが保護されることもあります。-->\r\n{{Sakujo/本体\|(.*?)\|(.*?)}}(\r\n.*?|)\r\n<!-- 削除についての議論が終了するまで、上記部分は削除しないでください。\s*(--></noinclude>|-->)((\r\n)*({{[cC]opyright(.*?)}}|{{著作権}})(\r\n)*|(\r\n)*)"
    myStr1 = "(<noinclude>\r\n<!|<noinclude><!|<!)--削除についての議論が終了するまで、下記のメッセージ部分は除去しないでください。もしあなたがこのテンプレートを除去した場合、差し戻されます。またページが保護されることもあります。-->\r\n{{Sakujo/本体\|(.*?)\|(.*?)}}(\r\n.*?|)\r\n<!-- 削除についての議論が終了するまで、上記部分は削除しないでください。\s*(-->\r\n</noinclude>|--></noinclude>|-->)((\r\n)*({{[cC]opyright(.*?)}}|{{著作権}}|{{copyvio}})(\r\n)*|(\r\n)*)"
    myStr2 = ""
    mySummary = "削除依頼の終了"
    文字列の置換byファイル myFilename, mySummary, myStr1, myStr2
End Sub

Sub 削除依頼報告追加(myDiscuss As String, myFilename As String, myKakko As Boolean)
    Dim myStr1 As String, myStr2 As String '置き換え前後の文字
    Dim mySummary As String
    Dim myDiscussPage As String
    
    If myKakko = True Then
        myDiscussPage = "「[[Wikipedia:削除依頼/" & myDiscuss & "]]」"
    Else
        myDiscussPage = "[[Wikipedia:削除依頼/" & myDiscuss & "]]"
    End If
    
    mySummary = "削除依頼対処の報告"
    myStr1 = "(.*?)(.度|過去に)(.*?)削除に関する議論は(.*?)をご覧ください。"
    myStr2 = "\1過去に\3削除に関する議論は\4、" & myDiscussPage & "をご覧ください。"
    文字列の置換byファイル myFilename, mySummary, myStr1, myStr2
    
    mySummary = "削除依頼対処の報告"
    myStr1 = "このページには削除された版があります。削除に関する議論は(.*?)をご覧ください。"
    myStr2 = "このページには削除された版があります。削除に関する議論は\1、" & myDiscussPage & "をご覧ください。"
    文字列の置換byファイル myFilename, mySummary, myStr1, myStr2
    
    mySummary = "削除依頼対処の報告"
    myStr1 = "この項目には審議(.*?)に基づき削除された版があります。"
    myStr2 = "この項目には審議\1、" & myDiscussPage & "に基づき削除された版があります。"
    文字列の置換byファイル myFilename, mySummary, myStr1, myStr2
End Sub

Sub 削除依頼存続追加(myDiscuss As String, myFilename As String, myKakko As Boolean)
    Dim myStr1 As String, myStr2 As String '置き換え前後の文字
    Dim mySummary As String
    Dim myDiscussPage As String
    
    If myKakko = True Then
        myDiscussPage = "「[[Wikipedia:削除依頼/" & myDiscuss & "]]」"
    Else
        myDiscussPage = "[[Wikipedia:削除依頼/" & myDiscuss & "]]"
    End If
    
    mySummary = "削除依頼対処の報告"
    myStr1 = "(.*?)(.度|過去に)(.*?)削除に(ついての|関する)議論は(.*?)をご覧ください。"
    myStr2 = "\1過去に\3削除についての議論は\5、" & myDiscussPage & "をご覧ください。"
    文字列の置換byファイル myFilename, mySummary, myStr1, myStr2
End Sub

Sub 記事の削除(myReason As String, myFilename As String, myAlways As Boolean)
    Dim Q As String
    Dim myCommandline As String
    Dim rc
    ChDir ("c:\pywikipedia")
    Q = Chr(34)
    myCommandline = "c:\python\python delete.py -summary:" & Q & myReason & Q & " -file:" & Q & myFilename & Q
    If myAlways = True Then myCommandline = myCommandline & " -always"
    rc = Shell(myCommandline, vbNormalFocus)
    ShellEnd (rc)        '終了するまで待機
    If rc = 0 Then MsgBox "起動に失敗しました"
End Sub

'Shellの終了を待つ
Private Sub ShellEnd(ProcessID As Long)
    Dim hProcess As Long
    Dim EndCode As Long
    Dim EndRet   As Long
    'ハンドルを取得する
     hProcess = OpenProcess(PROCESS_QUERY_INF, 1, ProcessID)
    '終わるまで待つ
    Do
        EndRet = GetExitCodeProcess(hProcess, EndCode)
        DoEvents
    Loop While (EndCode = STILL_ACTIVE)
    'ハンドルを閉じる
     EndRet = CloseHandle(hProcess)
End Sub