スポンサーサイト

Tags :
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

FC2Blogに画像をアップロードするAppleScriptが動作するかをチェックするスクリプト書いた

ちょっと前に
ドラッグ&ドロップでFC2ブログに複数の画像をまとめてアップロードするAppleScript その4
てのを書きましたが、先週あたりにFC2Blogの管理画面がアップデートされて、アップロードする画像を選択するフォームが複数表示されるように変更された為(どうせなら、はてなfotolifeみたいにダイアログ中で複数選択出来る様にすれば良いのに)、スクレイピングに頼っている部分が動作しなくなっていたので元エントリのスクリプトを更新しておきました。

で、今回も使ってる方からの報告で動作しなくなってるのを知ったんですが、そちらに頼ってばっかりなのも何なので、上記のAppleScriptが動作するかどうかをチェックして、もし動作しなくなる様なFC2Blogの仕様変更があった場合にはメールで知らせるようなスクリプトをPythonで書いてcronで回す事にしました。AppleScriptで書いても良かったんですけど、cronで動かすのでほぼ常時電源の入ってるLinux PCで使える様に。

やってる事は、上記のAppleScriptと同じ方法でアップロードを試みて、失敗するとSubjectにどの処理で失敗したのか、本文はその時サーバから返って来たHTMLを入れて自分宛にメールを送ります。始めはサーバとやり取りするのにurllib2を使って書いてたんですが、画像等の『multipart/form-data』をすんなりPOST出来ない感じだったので、手っ取り早くcurlコマンドをpopen2モジュールで呼び出して処理しています。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, re
import smtplib
from popen2 import popen3
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate
from BeautifulSoup import BeautifulSoup

#SMTPでメールを送信
def send_mail(subject, body):
    from_addr = 'sender@example.com'
    to_addr = 'receiver@example.com'
    encoding = 'ISO-2022-JP'

    #メッセージを生成
    msg = MIMEText(body.encode(encoding), 'plain', encoding)
    msg['Subject'] = Header(subject, encoding)
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Date'] = formatdate()

    #送信
    s = smtplib.SMTP("localhost")
    s.sendmail(from_addr, [to_addr], msg.as_string())
    s.close()


#コマンドを実行し処理結果を返す
def popen(cmd):
    stdout, stdin, stderr = popen3(cmd)    
    rep = []
    for line in stdout: rep.append(line)
    return ''.join(rep)


def main():
    blogurl = 'http://MY_ACCOUNT.blog80.fc2.com/admin.php'
    uploadurl = 'http://blog80.fc2.com/control.php'
    passwd = 'MY_PASSWORD'
    id = 'MY_ACCOUNT'
    testfile = 'fc2blog_uploadtest.jpg'
    cookiefile = 'fc2uploader_cookie.txt'
    title = 'FC2Blog_uploadchaecker'
    
    #ログイン処理
    cmd  = 'curl -d "id=%s&pass=%s&mode=admin&mode=logging&process=in" -c "%s" -L "%s" | tail -n 300' % (id, passwd, cookiefile, blogurl)
    rep = popen(cmd)
    for line in rep.splitlines():
        if  'input type="password"' in line:
            send_mail(u'%s : ログインに失敗' % title, unicode(rep, 'EUC-JP'))
            sys.exit(0)

    #アップロード時にPOSTするcrcの値を取得
    cmd = 'curl -b %s -d "mode=control&process=upload" -L "%s" | grep \'name="crc"\' | sed \'s/\t*<input.*value=\"//\' | sed \'s/".*\'//' % (cookiefile, blogurl)
    rep = popen(cmd)
    crc =  rep.splitlines()[1]
    if crc == '':
        send_mail(u'%s : crc値の取得に失敗' % title, stdout.read())
        sys.exit()

    #テスト用画像をアップロード
    cmd  = 'curl -b %s -F "upfile[0]=@%s" -F mode=control -F process=upload -F width=200 -F height=200 -F overwrite=force -F type=upload -F crc=%s -F insert="" -L "%s"' % (cookiefile, testfile, crc, uploadurl)
    rep = popen(cmd)
    result = False
    for line in rep.splitlines():
        if testfile in line:
            result = True
    if result == True:
        #アップロード成功の場合
        soup = BeautifulSoup(rep)
        td = soup.find('td', 'manage')
        try:
            #ファイル削除用のcrc値、ファイルIDを取得
            m = re.search('fileno=([0-9]+)&crc=([0-9a-z]+)', str(td))
            fileno = m.group(1)
            crc = m.group(2)
            print fileno, crc
            #テスト用ファイルを削除
            cmd = 'curl -b %s -F mode=control -F process=upload -F type=delete -F no=%s -F crc=%s -F page=1 -F tail= -F sort=dd -L "%s"' % (cookiefile, fileno, crc, uploadurl)
            popen(cmd)
        except AttributeError:
            #ファイル削除用のcrc値、ファイルIDを取得出来ない場合
            send_mail(u'%s : 削除用ファイルID,crcの取得に失敗' % title, unicode(rep, 'EUC-JP'))
            sys.exit()
        #テスト用画像が削除出来ているかをチェック
        cmd = 'curl -b %s -d "mode=control&process=upload" -L "%s"' % (cookiefile, blogurl)
        rep = popen(cmd)
        for line in rep.splitlines():
            if testfile in line:
                send_mail(u'%s : ファイルの削除に失敗' % title, unicode(rep, 'EUC-JP'))
                sys.exit()
        send_mail(u'%s : 正常終了' % title, unicode(rep, 'EUC-JP'))
    else:
        #アップロード失敗
        send_mail(u'%s : ファイルのアップロードに失敗' % title, unicode(rep, 'EUC-JP'))
                
if __name__ == '__main__':
    main()

ドラッグ&ドロップでFC2ブログに複数の画像をまとめてアップロードするAppleScript その4

以前のエントリで公開していた、ドラッグ&ドロップでFC2Blogに複数の画像をまとめてアップロードするAppleScriptの改良版です。

こちらのエントリからのトラックバックを受けて気が付いたんですが(ご指摘ありがとうございます)、去年のFC2Blogのリニューアルで管理画面の仕様が変わったため、アップロード用のスクリプトが動作しなくなっていました。

いやまあ作った本人が言うのも何ですが、ついこの間まで自宅にOSX使える環境が無くて、このスクリプトも自分では全然使ってなかったんですよね…。

ただ、利用しておられる方も少なからずいらっしゃるので、早速新しい管理画面に対応した改良版を作りました。


■使い方
・まず、スクリプトエディタにこのスクリプトをコピペして、9行目『ユーザ名』の部分を書き換えます。
・必要に応じてその下の、サムネイルを作成するかどうか、サムネイルのサイズ、同名ファイルがあった場合上書きするか、の項目を書き換えます。
・スクリプトを『アプリケーション』として保存します。
・アプリケーションとして保存したスクリプト(ドロップレット)にアップロードする画像をドロップします。
・ダイアログが表示されるので、ログインする時のパスワードを入力します。
・……しばらく待つ
・終了を知らせるダイアログが表示されます。

FC2ブログにアップロード出来ない種類のファイル(.psdや.xlsなど)をアップロードしようとしても、エラーなどは表示されず、ただ何もアップロードされずに終了します。

スクリプトを実行すると、ホームディレクトリ以下の『ライブラリ/Cookies』フォルダにサーバとのやり取りに使うCookieを保存したファイル『fc2uploader_cookie.txt』が作られます。削除されてもスクリプトを実行する度に作成されます。

■注意点
Safariを使用している方は、保存時にエラーが出る場合スクリプト中の『円マーク』を『バックスラッシュ』に置換してください。

■2009.3.20追記
FC2Blogが複数アップロード対応になったため動作しなくなっていたのを修正。

■2013.6.19追記
FC2Blogの仕様変更でスクリプトが動作しなくなっていたのを修正。

■動作確認
MacOSX 10.5.6
(*
ユーザー毎の初期設定
*)

--管理画面のURL
property myURL : "http://admin.blog.fc2.com/control.php"

--ユーザ名、もしくは登録しているメールアドレスを入れる ※必ず書き換えてください
property myID : "『ユーザ名』"

--アップロード時に自動的にサムネイルを作成するか(offの場合は""にする)
property createThumb : "on"

--アップロード時に作成されるサムネイルのサイズ(幅・高さ)
property thumbWidth : 250
property thumbHeight : 250

--同名のファイルが既にある場合、上書きするかどうか
-- 上書きする場合は"force" 別名で保存する場合は"rename"にする
property overwrite : "force"

(*
ユーザー毎の初期設定ここまで
*)


property msg1 : "管理画面のパスワードを入力" as Unicode text
property msg2 : "終了しました。" as Unicode text
property msg3 : "ログインに失敗しました。" as Unicode text
property cookiePath : " ~/Library/Cookies/fc2uploader_cookie.txt" ----保存するcookieのパス

on open drop
	activate me
	set myPass to text returned of (display dialog msg1 default answer "")
	
	----ログイン処理&Cookie保存
	set loginScript to "curl -d \"id=" & myID & "&pass=" & myPass & "&mode=admin&mode=logging&process=in\" -c " & cookiePath & " -L " & myURL & " | tail -n 300"
	set response_login to do shell script loginScript as string
	----パスワードの入力フォームがレスポンスに含まれていた場合、ログイン失敗と判定(ちょっとこのへんが微妙…)
	if response_login contains "input type=\"password\"" then
		beep
		display dialog msg3 with icon 0 buttons "OK" default button 1
		error number -128
	end if
	
	--POST時に送信するCRCの値を取得(コード中にタブ記号が含まれています)
	set getCrcScript to "curl -b " & cookiePath & " -d \"mode=control&process=upload\" -L " & myURL & " | grep 'name=\"crc\"' | sed 's/	*<input.*value=\"//' | sed 's/\".*'//"
	set returnedCrc to 1st paragraph of (do shell script getCrcScript as string)
	
	----メインループ
	repeat with theFile in drop
		tell application "Finder"
			set fPath to POSIX path of theFile as Unicode text
			set uploadScript to "curl -b " & cookiePath & " -F \"upfile[0]=@" & fPath & "\" -F thumb=" & createThumb
			set uploadScript to uploadScript & " -F width=" & thumbWidth & " -F height=" & thumbHeight & " -F overwrite=" & overwrite
			set uploadScript to uploadScript & " -F mode=control -F process=upload -F type=upload -F crc=" & returnedCrc & " -F insert=\"\" -L " & myURL
			do shell script uploadScript
		end tell
	end repeat
	beep
	display dialog msg2 default button 1 buttons "OK"
end open

Webで利用される様々な文字列エンコードを扱うためのAppleScriptいろいろ

最近部品ばっかり。

前のエントリとかで文字参照を戻すスクリプトなんかをPython使って書いたりしましたが、PHP使えば遥かにシンプルに出来るので、Webで使われてる色々な文字列のエンコードに対応したAppleScriptをまとめました。ユニコード文字列専用なので、スクレイピング等でWebから取得した文字列は、適宜do shell scriptで『iconv -f EUC-JP -t UTF-8』に通すなどして文字コードをutf-8に変換してから処理してください。

あと、変換の精度はPHPに依存してるのであらかじめご了承ください。

変換できるのは、
・『Base64』
・『実体参照・数値文字参照』
・『URLエンコード』
のそれぞれエンコードとデコードです。

(*
Base64でエンコードする
"123ABCあいう&<>" => "MTIzQUJD44GC44GE44GGJjw+"
*)
on encodeBase64(str)
    set scpt to "php -r 'echo base64_encode(\"" & str & "\");'"
    return do shell script scpt
end encodeBase64



(*
Base64をデコードする
"MTIzQUJD44GC44GE44GGJjw+" => "123ABCあいう&<>"
*)
on decodeBase64(str)
    set scpt to "php -r 'echo base64_decode(\"" & str & "\");'"
    return do shell script scpt
end decodeBase64



(*
文字列を数値文字参照に変換する
"123ABC あいう&<>" => "&#49;&#50;&#51;&#65;&#66;&#67;&#12354;&#12356;&#12358;&#38;&#60;&#62;"
&や<>等の記号も&38;等の数値文字参照に変換
*)
on encodeNCR(str)
    set scpt to "php -r 'echo mb_encode_numericentity(\"" & str & "\", array(0x0, 0x10000, 0, 0xfffff), \"utf-8\");'"
    return do shell script scpt
end encodeNCR



(*
実体参照・数値文字参照を文字列に戻す
"&#49;&#50;&#51;&#65;&#66;&#67;&#12354;&#12356;&#12358;&amp;&lt;&gt;" => "123ABCあいう&<>"
*)
on decodeNCR(str)
    set scpt to "php -r 'echo html_entity_decode(mb_decode_numericentity(\"" & str & "\", array(0x0, 0x10000, 0, 0xfffff), \"utf-8\"));'"
    return do shell script scpt
end decodeNCR



(*
文字列をURLエンコードする
"123ABCあいう&<>" => "123ABC%E3%81%82%E3%81%84%E3%81%86%26%3C%3E"
*)
on encodeURL(str)
    set scpt to "php -r 'echo urlencode(\"" & str & "\");'"
    return do shell script scpt
end encodeURL



(*
URLエンコードされた文字列を元に戻す
"123ABC%E3%81%82%E3%81%84%E3%81%86%26%3C%3E" =>  "123ABCあいう&<>" 
*)
on decodeURL(str)
    set scpt to "php -r 'echo urldecode(\"" & str & "\");'"
    return do shell script scpt
end decodeURL

XML等の文字参照を通常の文字列に戻すAppleScript(その2)

■4/7追記 こちらのエントリにもっとシンプルなのがあります。
Webで利用される様々な文字列エンコードを扱うためのAppleScriptいろいろ


ちょっと前に『&amp;』や『&#12345;』といった文字参照を含む文字列を通常の文字列に戻すAppleScriptてのを書きましたが、あまりに処理が遅いので、もうちょっと速くなるよう書き直しました。

前回のはpythonでforループを一行に納める書き方がわからなかったというのもあって、文字コードを一文字ごとにdo shell scriptでpythonに渡してましたが、それだとやたら時間がかかるので、間にASCII文字が入る等して文字参照が途切れない限り出来るだけ一度にpythonの引数として渡すようにしました。

MacOSX10.5のAppleScriptならpythonを使わなくてもUnicode textのidプロパティで変換できるので、一文字ずつ処理するような書き方でもそれ程遅くならないかも知れません。なのでこのスクリプトは主に10.4以前のOSX向けです。

あと、数値文字参照の表記が10進、16進どちらでも変換できるようにしてあります。

■動作確認■
MacOSX 10.4.11
-- my_string -> 変換する文字参照を含んだ文字列
set my_string to "&#x300e;&#x26;&#x61;&#x6d;&#x70;&#x3b;&#x300f;&#x7b49;&#x306e;&#x5b9f;&#x4f53;&#x53c2;&#x7167;&#x3084;&#x300e;&#x26;&#x23;&#x31;&#x32;&#x33;&#x34;&#x35;&#x3b;&#x300f;&#x3068;&#x3044;&#x3063;&#x305f;&#x6570;&#x5024;&#x6587;&#x5b57;&#x53c2;&#x7167;&#x3092;&#x901a;&#x5e38;&#x306e;&#x6587;&#x5b57;&#x306b;&#x5909;&#x63db;&#x3057;&#x307e;&#x3059;" as Unicode text

display dialog (decodeStringsWithNCRs(my_string))

on decodeStringsWithNCRs(my_string)
    set resultStr to ""
    set ent to "" as Unicode text
    set ent_list to {}
    set flg to false
    repeat with cnt from 1 to (count of my_string)
        set chr to item cnt of my_string
        if chr is "&" and (item (cnt + 1) of my_string is not "&") then
            if flg is false then
                set flg to true
                set ent to chr
            else
                set resultStr to resultStr & ent
                set ent to "&"
            end if
        else if chr is ";" and flg is true then
            if ent starts with "&#" then
                set end of ent_list to ent & ";"
            else
                set resultStr to resultStr & decodeNCRs(ent_list) & decodeEntity(ent & ";")
                set ent_list to {}
            end if
            set flg to false
            set ent to ""
        else if flg is true then
            set ent to ent & chr
        else
            if ent_list is not {} then
                set resultStr to resultStr & decodeNCRs(ent_list) & chr
                set ent_list to {}
            else
                set resultStr to resultStr & chr
            end if
        end if        
    end repeat
    set resultStr to resultStr & decodeNCRs(ent_list)
end decodeStringsWithNCRs


on decodeNCRs(ncr_list)
    set args to "" as Unicode text
    repeat with w in ncr_list
        set w to items 3 thru -2 of w
        if w starts with "x" then set w to "0" & w
        set args to args & " " & w
    end repeat
    try
        set scpt to "python -c 'import sys;[sys.stdout.write(unichr(eval(i)).encode(\"utf-8\")) for i in sys.argv[1:]] ' " & args
        return do shell script scpt
    on error
        return false
    end try
end decodeNCRs


on decodeEntity(str)
    set html_ent to {"&amp;", "&lt;", "&gt;", "&quot;", "&apos;"}
    set decoded_ent to {"&", "<", ">", "\"", "'"}
    set cnt to 1
    repeat with he in html_ent
        if str is he as Unicode text then
            return item cnt of decoded_ent
        end if
        set cnt to cnt + 1
    end repeat
    return str
end decodeEntity

AppleSciptのシンタックスをハイライトするJavaScript(いちおう完成)

■2008-03-16追記 IEでの不具合を修正…できたか?■


前のエントリで途中経過というか副産物として、ハイライト表示するためのHTMLを生成するWebフォームとして公開してましたけど、JavaScriptをblogに設置しておけば勝手にハイライト出来るようになりました。『SyntaxHighlighter』の AppleScript用みたいな感じで。

<pre class="applescript">~</pre>の間にAppleScriptのコードを貼ると自動で行番号とともにハイライト表示します。

実際の表示はこんな感じ。
(* 拡張子を変更したファイル名を返す 簡易版 *)
on replaceExtension(fName, new_ext)
	tell application "Finder"
		set base_name to (do shell script "echo " & quoted form of fName & " | sed 's/\.[^.]*$//'") as Unicode text
		return base_name & "." & new_ext
	end tell
end replaceExtension
行番号表示のままだと、スクリプトエディタにコピペするとき行番号が邪魔になるので、プレーンなテキスト表示とトグルする事ができます。『SyntaxHighlighter』の場合プレーンテキストは別窓で開くんですが、こっちのほうが良いと思うんですがどうでしょう。

現状、とりあえず動く…程度のものなので書き直していくと思います。
Profile
choco
Author : choco

印刷・製版の現場を経て、広告制作会社でPhotoshopを使ったビジュアル制作を担当。

→現在は車載機器開発ベンダにて、組み込み3Dデータ作成やUIデザインなどを行っています。

Categories
Favorites


Search
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。