UWSCで掲示板を操作する

UWSC公式掲示板で、インターネット間通信の話が出ていた。
掲示板仲介にしてやってみたら、と書いたので、やってみた。



スクリプト

InternetControl.uws

OPTION EXPLICIT

IFB LENGTH(PARAM_STR) THEN
	// CommandLine
	SELECT PARAM_STR[0]
	CASE "SEND"
		WITH InternetControl.Send(PARAM_STR[1])
			PRINT .responseText
		ENDWITH
	CASE "GetMessage"
		PRINT InternetControl.GetMessage(PARAM_STR[1])
	CASE "PutMessage"
		PRINT InternetControl.PutMessage(PARAM_STR[1], PARAM_STR[2], PARAM_STR[3])
	SELEND
	MSGBOX("End")
ELSE
	IFB GET_UWSC_NAME = "InternetControl.uws" THEN
		// DEMO
		DIM loop = TRUE, pp = SPLIT("(新規) (終了)"), res, name = "test", to, msg
		name = INPUT("名前を入力してください", name)
		WHILE loop
			WHILE G_MOUSE_X
				res = InternetControl.GetMessage(name)
				IF LENGTH(res) THEN MSGBOX(res)
				SLEEP(0.1)
			WEND

			res = POPUPMENU(pp)
			IFB res > -1 THEN
				SELECT pp[res]
				CASE pp[LENGTH(pp)-2]
					to = INPUT("宛先を入力してください")
				CASE pp[LENGTH(pp)-1]
					loop = FALSE
				DEFAULT
					to = pp[res]
				SELEND
				IFB loop THEN
					msg = INPUT("メッセージを入力してください")
					msg = InternetControl.PutMessage(name, to, msg)
					IFB LENGTH(msg) THEN
						MSGBOX("失敗しました<#CR><#CR>" + msg)
					ELSEIF res = LENGTH(pp) - 2 THEN
						pp = SPLIT(to + " " + JOIN(pp))
						MSGBOX("メッセージを登録しました")
					ENDIF
				ENDIF
			ENDIF
		WEND
	ENDIF
ENDIF



MODULE InternetControl

	DIM FUKI_DASHI = TRUE
	CONST DEF_URL = "http://uwsc.bbs.fc2.com/"

	FUNCTION Send(url, dummyAdd=FALSE, async=FALSE, method="GET", para=NULL, user=NULL, pass=NULL)
		IF FUKI_DASHI THEN BALLOON("Send",,,,,,,,100)
		RESULT = CREATEOLEOBJ("MSXML2.XMLhttp")
		IFB dummyAdd THEN
			GETTIME()
			url = url + "?time=" + G_TIME_HH2 + G_TIME_NN2 + G_TIME_SS2 + G_TIME_ZZ2
		ENDIF
		RESULT.open(method, url, async, user, pass)
		IF LENGTH(para) THEN RESULT.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
		RESULT.send(para)
		IF FUKI_DASHI THEN BALLOON()
	FEND

	// 別スレッドのオブジェクトは監視できない
	// 最大30秒待ち
	FUNCTION Result(msxh, count=300)
		IF FUKI_DASHI THEN BALLOON("Result",,,,,,,,100)
		WHILE (msxh.readyState = 0 OR msxh.readyState = 1) AND count > 0
			SLEEP(0.1)
			count = count - 1
		WEND
		RESULT = NULL
		IFB msxh.readyState = 4 THEN
			RESULT = CREATEOLEOBJ("htmlfile")
			IFB msxh.status = 200 THEN
				RESULT.write(msxh.responseText)
			ELSE
				RESULT.write(msxh.statusText)
			ENDIF
			GETKEYSTATE(VK_CONTROL)
			IF GETKEYSTATE(VK_CONTROL) THEN PRINT RESULT.body.innerText
		ENDIF
		IF FUKI_DASHI THEN BALLOON()
	FEND

	// 自分宛未読メッセージ取得
	FUNCTION GetMessage(name, url=DEF_URL)
		DIM html = Result(Send(url, TRUE))
		IF FUKI_DASHI THEN BALLOON("GetMessage",,,,,,,,100)
		RESULT = ""
		IF html = NULL THEN EXIT
		DIM divs = html.getElementsByTagName("div")
		DIM i, bRes = FALSE
		FOR i = divs.length - 1 TO 0 STEP -1
			SELECT divs.item(i).className
			CASE "topic2"
				IFB !bRes THEN
					RESULT = GetMessageSub(name, divs.item(i))
					IF LENGTH(RESULT) THEN BREAK
				ENDIF
				bRes = FALSE
			CASE "res"
				bRes = TRUE
			SELEND
		NEXT
		IF FUKI_DASHI THEN BALLOON()
	FEND
	FUNCTION GetMessageSub(name, div)
		DIM spans = div.getElementsByTagName("span")
		DIM i, bFound = FALSE, to = EMPTY
		RESULT = ""
		FOR i = 0 TO spans.length - 1
			SELECT spans.item(i).className
			CASE "subj"
				IF spans.item(i).innerText = name THEN bFound = TRUE
			CASE "name"
				IFB bFound THEN
					to = COPY(spans.item(i).innerText, 3)
					RESULT = RESULT + to
				ENDIF
			CASE "date"
				IF bFound THEN RESULT = RESULT + " - " + spans.item(i).innerText
			CASE "col1"
				IF bFound THEN RESULT = RESULT + "<#CR><#CR>" + spans.item(i).innerText
				BREAK
			SELEND
		NEXT
		DIM tids = div.getElementsByTagName("input")
		IFB bFound AND tids.length > 0 AND tids.item(1).name = "tid" THEN
			GETTIME()
			to = PutMessage(name, to, "処理済み<#CR>"+G_TIME_YY4+G_TIME_MM2+G_TIME_DD2+G_TIME_HH2+G_TIME_NN2+G_TIME_SS2+G_TIME_ZZ2, tids.item(1).value)
			IF LENGTH(to) THEN MSGBOX("メッセージ処理に失敗しました<#CR><#CR>" + to)
		ENDIF
	FEND

	FUNCTION PutMessage(name, to, msg, tid=EMPTY, url=DEF_URL)
		DIM para = "act=post&name=" + name + "&dai=" + to + "&msg=" + ENCODE(msg, CODE_URL)
		IF LENGTH(tid) THEN para = para + "&tid=" + tid
		DIM html = Result(Send(url, FALSE, FALSE, "POST", para))
		DIM bf = html.getElementById("bbsform2")
		RESULT = EMPTY
		IFB bf <> NOTHING THEN
			DIM ps = bf.getElementsByTagName("p")
			IF ps.length THEN RESULT = ps.item(0).innerText
		ENDIF
	FEND

ENDMODULE

使い方

の前に、fc2の掲示板を使ってみたのだけど、やたら遅い。
で、非同期が面倒で同期処理なので、ちょっと使い物にならない速度。
非同期にしたり、掲示板を変えれば解消しそうだけど、解析が必要になるね。


一応、使い方。
起動すると、名前を聞いてくるので、ユニークな名前を入れてください。
そうすると、掲示板にアクセスに行って、自分宛のメッセージがあれば表示。
マウスのx座標を0、すなわち左端に持っていくとBALLOONが出てない時なら、POPUPメッセージが出る。
(終了)で終わり。
(新規登録)すると、宛先を聞いてきて、メッセージが送れる。
メッセージを送ると、掲示板に、名前が自分の名前、件名が宛先、本文にメッセージを登録する。
次回からは、POPUPメッセージに登録されるので、宛先は選択できる。


そんな感じ。
掲示板の制約で、60秒に1回しか登録できません。
それから、日本語を含まないメッセージは登録できません。


使いづらい、、、。

備考

私が立てた掲示板は好きに使ってくれて良いですが、私のきまぐれでメンテします。
引数とスクリプト名で動作を切り分けるトリックは、しろまささん発案です。ありがとうございます!