2021年4月19日 (月)

さくらインターネットのレンタルサーバーでGOで書いたCGIを動かした(苦労)話

作っているCGIは一言で言えば、データベースから利用者の指定した条件で引っ張ってきたデータを表やグラフにして提供する、というようなものです。

自分でサーバーを立てて、みたいなことをやる機材も気力もないのでレンタルサーバーを使うことにします。
・GOのコンパイラーが使えて
・GOで書いたCGIを動作させてることができる(許されている)
レンタルサーバーということになるのですが、今契約しているさくらインターネットのレンタルサーバーがこれに該当します。

ただ残念なことに私が契約しているサーバーはOSが「FreeBSD 9.1-RELEASE-p24 #0: Thu Feb 5 10:03:29 JST 2015」ということで、これにはGOのコンパイラーは入っていません。何年か前からOSは徐々に新しいバージョンへ移行しているようですが、私のサーバーのOSの更新がいつになるのかよくわかりません。そこで新しいサーバーを借りてみました。こちらは「FreeBSD 11.2-RELEASE-p14 #0: Mon Aug 19 22:38:50 UTC 2019」とGOが使えるやつでした(お試し期間があるので、その間にチェックが可能です)
GOは「go version go1.15.5 freebsd/amd64」でした。
レンタルサーバーはMySQLとSSHが使える中でいちばんお安いスタンダードプランで月524円でした。

ところでFreeBSD 9.1の方にGOのコンパイラーを入れてはどうかとも考えるのですが、これはやめた方がよさそうです。
FreeBSD 9.1ではコンパイラのバイナリは古いバージョンのものしか動かないのですが、ググると「Go 1.4.3 バイナリで Go 1.7.4 ソースをビルドする 」みたいな話がありました。実際1.4.3のコンパイラは動くのを確かめたのですが...

・MySQLのアクセスのために"github.com/go-sql-driver/mysql"を使っていて
・このSQL Driverは「
Go 1.10 or higher. We aim to support the 3 latest versions of Go.」
・一方「Go 1.10 now requires FreeBSD 10.3 or later」

ということでFreeBSD 9.1でどうにかしようというのはムリみたいです。11.2で作ったモジュールを9.1に持っていっても動かないのは確認済みですし w

--------------

GOコンパイラーが使える環境は整ったのでCGIのコーディングなのですが、今回は次のようなパッケージを使用しました。

1. "net/http"
2. "html/template"

3. "github.com/PuerkitoBio/goquery"
4. "database/sql"
5. "github.com/go-sql-driver/mysql"

6. "github.com/ajstarks/svgo/float"

7. "github.com/dustin/go-humanize"

--------------

3.、4.、5.はMySQLのアクセス用です。

これについてはいろんな記事があるのでそういうのを参照すればいいのですが、次の問題には手間取りました。

  「技術向上 - MySQL - invalid memory address or nil pointer dereference【Go】

私と同じところではまる人もいそうな気がするので紹介しておきます。

--------------

6.はグラフを作るのに使っています。まあ、グラフができさえすればいいということであれば、それなりのパッケージがあるのですが、(SVG大好き人間なので)自前で作っています。これからSVGの特色を生かしていければと思っています。
なお"github.com/ajstarks/svgo/"というのもあり、これだと座標をint型で与えることになるのでグラフを作るというような目的
であればfloatのついた方(座標はfloat64で与えます)がいいでしょう。intの方で作って拡大・縮小の機能を利用したほうがいのかもとも思いますが。

これについても一点だけ書いておくと、SVGを書き出すファイルはClose()する前にFlush()する必要があります。これをしないとSVGが途中でぶった切れてしまいます。

--------------

7.は表に数値を表示するとき3桁ごとにカンマを入れるという目的で使っています。

--------------

ド素人で、最初は簡単なCGIなのでstdoutにhtmlを出力すればいいんだろうくらいに考えていたのですが、あさはかな考えでちゃんと1.とか2.を使うべきです。

"net/http"はおもしろくて、CGIとして作ったプログラムがソースを一行書き換えるだけでWebサーバーのように動きます。

	if OS == "windows" {
// Webサーバーとして起動
http.ListenAndServe(":8080", nil)
} else { // "freebsd"
// CGIとして起動
cgi.Serve(nil)
}


このおかげで

・Windowsでプログラムを作り、Windows10上でテストする。
・テストが完了したらレンタルサーバーにftpで上げてコンパイルする。

というときWindowsでWebサーバーを用意する必要がありません。もっともWindowsとFreeBSDでまったく同じソースが動くわけでもないです。
パスがからむところは注意した方がいいようです(要するにWebサーバーから見える景色とCGIから見える景色は異なる)
一例を上げると

	if OS == "windows" {  //  SVGファイルの置き場所
http.Handle("/", http.FileServer(http.Dir("public")))
}
	rootPath := ""
if OS == "freebsd" {
rootPath = os.Getenv("SCRIPT_NAME")
}
http.HandleFunc(rootPath+"/top", HandlerTopForm)
.
.

上の方はSVGファイルを表示させるhtmlを

  <img src="/TEST/public/46.svg" alt="" width="100%">

のようにして、表示できるようにするためです。

下の方はURLがWindowsの場合
  http://localhost/top
になるのに対しレンタルサーバーでは
  http://xxx.sakura.ne.jp/CGI.cgi/top
みたいになることへの対応です。

以上、コーディングはWindowsだったら/FreeBSDだったらとなっていますが、意味的にはWebサーバーだったら/CGIだったらということです。これらはもっと簡単な対策があるのかもしれませんが...

--------------

ところで、実際のところソースをレンタルサーバーに持っていってコンパイルすると頻繁に強制終了が発生してコンパイルできないことがあります。このとき動いているプロセスをkillするとコンパイルできるので、どうやら何かのリソースの制限みたいなのにひっかかっているようです(同じような現象として「go get」を行ったときの強制終了というのもあります)

この対策は簡単で、Windowsでテストが終わったら、そのままクロスコンパイルしてロードモジュールを作りこれをアップロードすればOKです。

書き忘れましたが Windows側は
  go version go1.15.5 windows/amd64
です。IDEはliteideを使っています。

--------------

"html/template"は、面倒くさそうだなあと思って使い始めたのですが、こんなに便利なものはないです。コーディング量が画期的に減るということもあるのですが、ちょっとした変更がソースではなくテンプレートの方で済ませられるのでらくちんです。

ちょっと複雑なhtmlになると最初どうしたらいいかよくわからなかったのですが、

1. htmlを複数に分割して、それぞれにデータを与える。
2. htmlの構造に合わせた構造体を作る(構造体を作るときどのようなhtmlで使うかを意識しておく)

のどちらかで(あるいは両方を組み合わせれば)対応できるようです。2.の方がすっきりしているようですが、実際はかなり泥臭い構造体になってしまうので、まあどっちもどっちみたいな気がします。

1.の方はこんな感じです。

	tpl := template.Must(template.ParseFiles(
"templates/top1.gtpl",
"templates/top2.gtpl",
))
...
...
if err := tpl.ExecuteTemplate(w, "top1.gtpl", eventlist); err != nil {
...
...
}
...
...
if err := tpl.ExecuteTemplate(w, "top2.gtpl", eventinf); err != nil {
...
...
}


それからHTML5だとinputをformとは別に書いたり、formの中に(formactionを使って)複数のsubmitをおいたりできるので、このあたりを利用するとレイアウトの自由度が格段に大きくなります。

以上、雑然としていますが、私がつまずいたポイントを思い出しながら書いてみました。

他にもviでUTF-8が表示できないとか、Windows側のMySQLでUTF-8が使えない、と言ったこともあったのですが、これはCGIに限ったことではないので省略します。

ここまで来るのにずいぶんググったのですが、なかなか自分が必要とする情報に行き着きませんでした。そういうとき少しは参考になるのではと思います。

2020年6月28日 (日)

SHOWROOM - イベントでの配信者の獲得ポイント数を取得する - スマホ版(android版)

Playストアのレビューに「これぞ神アプリ!」という声が多いandroidのアプリ termux を利用して、SHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版)にあるソースをスマホに移植してみました。

具体的な手順を以下に記しますが、迷うところは何もない"一本道"で簡単に環境構築から実行までできました。
しいて言えばハードウェア関連(OTG、bluetoothで接続するキーボード、マウスとそれに関連する設定)がいろいろやっかいです。ググるとキーボード入力が思うように行かないという話もいろいろあります。これについては環境が落ち着いたところで記事にまとめたいと思っています。

今回の環境
android 7.0
termux v0.95
go1.14.4 android/arm64

ZTE BLADE V0800 3GB/32GB Qualcomm Snapdragon 435 8コア 1.4G
USBキーボード (OTG+セルフパワータイプのUSBハブ)
USBマウス( 〃 )
Chromecast Charcoal
REGZA 19RE2 

-------

ずっとPC中心の生活をしていたのですが、去年の11月にPCが壊れてしまいそのままスマホ中心の生活になってしまいました。
スマホがあればPCがなくてもけっこういろいろなことができるものだと再認識している今日このごろです。
termux を使ったり、この記事を書くときは スマホにキーボードとマウスを接続し、Chromecastで画面をテレビにミラーリングしています。
ちなみにテレビにミラーリングするときはいわゆるドットバイドットにして左端が切れないようにしておくのと、termuxのフォントを小さくしておく(Ctrl+Alt+"-"、大きくするのはとうぜんCtrl+Alt+"+" )のがポイントです。
Screenshot_20200628091354
viでソースを編集しているところ。termuxのフォントを小さくしてあるのでステータスバーやボトムナビゲーション(?)がやたら大きく見えます w

-------

ソースはSHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版) にあるものがそのまま使えます。ただ(最大)1分ウェイトするところがあり、これは無反応とみなされて待ってるあいだにダイアログが表示されるようなので、6秒ごとに何か出力するとかした方がいいと思います。この対応でバックグラウンドでも動くと思います。

ウェイトをしている

  time.Sleep(time.Duration(60-ss) * time.Second)

のところを例えば

   for et := 0; et < 60-ss; et += 5 {
    fmt.Print(".")
    time.Sleep(5 * time.Second)
  }

とします(上と下は処理内容が少々(最大4秒ですし、この差が累積することもないです)違います。私は気になりませんが、数分に一度データを取得するので気になるという方は、ここだけでなく全体的にタイミングを見直してください)

--------

具体的な手順

termuxをplayストアからダウンロード、インストールして実行するとシェルのプロンプトが表示されますので、コマンドを以下のように実行して行きます。

補足

"termux-setup-storage" を実行すると内部ストレージへのシンボリックリンクが ~/storage の下にできます。どこでも参照できるわけでもないようで、今のところ私は ~/storage/dowloads でデータのやりとりをしています。
なお SDカードは /mnt/sdcard で参照できます。

"apt install vim" は vi を使うためです。"apt install git"は今回は必要ないのですが、"go get ....." で必要になることがあるので....

"apt install termux-elf-cleaner" はロードモジュールを実行したときの warning が表示されないようにするために必要です。ビルドと実行のあいだで使っています。

実行時にデータファイルとして RoomList.txt とRoomList.txtでファイル名を指定した一つ以上のファイル(この例では mikakunin_showroomer.txt )が必要です。
ファイルの内容は(タブがスペースになっていますが)下記に表示させていますが、このファイルでのテストは "mikakunin_showroomer" のイベントが終了するまでしかできません。それ以後は実行中のイベントで同じように作ってください。念のため。

----------

$ apt update
..........................

$ apt upgrade
..........................

$ termux-setup-storage

$ ls
storage

$ apt install vim
..........................

$ apt install git
..........................

$ apt install termux-elf-cleaner
..........................

$ apt install golang
..........................

$ go env
..........................

$ mkdir go

$ cd go

$ cp -r ~/storage/downloads/EvalPoint2 .

$ cd EvalPoint2

$ ls
EvalPoint2-a.go RoomList.txt
EvalPoint2.go mikakunin_showroomer.txt

$ cat RoomList.txt
mikakunin_showroomer.txt

$ cat mikakunin_showroomer.txt
0 0 0
Room00 e50cf1039407 mikakunin_showroomer 96747 false 1 2
Room01 61a5e3199543 mikakunin_showroomer 243565 false 1 2
Room02 norichan mikakunin_showroomer 192641 false 1 2
Room03 kogachan mikakunin_showroomer 198346 false 1 2
Room04 c8f783773817 mikakunin_showroomer 291006 false 1 2

$ ./EvalPoint2-a 6 5 2 0 0 0
Interval= 5 Mod= 2 HH_Detail= 0
skip mm=37..........
0 0 0
Room00 e50cf1039407 mikakunin_showroomer 96747 false 1
Room01 61a5e3199543 mikakunin_showroomer 243565 false 1
Room02 norichan mikakunin_showroomer 192641 false 1
Room03 kogachan mikakunin_showroomer 198346 false 1
Room04 c8f783773817 mikakunin_showroomer 291006 false 1
5
1 1867385 90882 e50cf1039407
2 1776503 90882 61a5e3199543
3 1354703 421800 norichan
4 729289 625414 kogachan
5 699805 29484 c8f783773817
2020/6/27 8:38:2 1867385 1776503 1354703729289 699805
.......^C
$

 



2019年10月28日 (月)

SHOWROOMのAPI - 「ライブ情報」の取得..JSONのもう一つの扱い方

前記事 SHOWROOMのAPI - 「ライブ情報」の取得(GO言語のソースつき)にSHOWROOMのAPIから返されるJSONからデータを取得する方法があります。これは複雑な(大きな)JSONからひとつ、ぶたつのデータを取り出すやり方としてはいいのですが、JSONから取り出すデータが多いとき(特にほとんどのデータがほしいとき)には面倒になるので、JSONに対応する構造体を作ってそこに代入させる方が手間がかかりません。

前記事とほとんど同じ機能をもつサンプルプログラムを作成しましたので紹介しておきます。この程度だったらどっちでも同じようなものですが....
(参考にしたサイトなども前記事にあります)

---------------------

恥ずかしくて書きたくないのですが、このプログラムはちょっとはまりました。「パッケージ外から参照できるのは最初の文字が大文字の変数だけ」というのを忘れてました。忘れてたというか、どういう場合このルールが適用されるのかよく理解できていませんでした w
(逆に言うと大文字だと外部から参照できるわけで、変数名の付け方はちゃんと考えるようにします。いまさらですが...)

=======================================

/*
Room_IDで指定したルームの配信状況を確認するためのAPI  live_info のテストプログラムです。
 
	Live_Live_info Room_ID
 
		Room_ID		配信ルームのID、アカウントっぽい方じゃなくて(ふつう)数字6桁くらいのやつです。
 
	参考
		SHOWROOMのAPI - 「ライブ情報」の取得(GO言語のソースつき)
		http://seppina.cocolog-nifty.com/blog/2019/10/post-7df814.html
 
*/
 
package main
 
import (
	"fmt"
	"os"
 
	"encoding/json"
	"net/http"
)
 
func Live_Live_info2(id string) (live_status int, is_enquete bool, bg_image string, status int) {
 
	status = 0
 
	//	配信者ルームの配信状況を確認するためのURL(このURLについては記事参照)
	URL := "https://www.showroom-live.com/api/live/live_info?room_id=" + id
 
	resp, err := http.Get(URL)
	if err != nil {
		//	一時的にデータが取得できない。
		resp.Body.Close()
		status = 1
		return
		//		panic(err)
	}
	defer resp.Body.Close()
 
	//	JSONをデコードする。
	var result struct {
		Age_verification_status int
		Video_type              int
		Enquete_gift_num        int
		Is_enquete              bool
		Bcsvr_port              int
		Live_type               int
		Is_free_gift_only       bool
		Bcsvr_host              string
		Live_id                 int
		Is_enquete_result       bool
		Live_status             int
		Room_name               string
		Room_id                 int
		Bscvr_key               string
		Background_image_url    string
	}
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		panic(err)
	}
 
	live_status = result.Live_status
	is_enquete = result.Is_enquete
	bg_image = result.Background_image_url
 
	return
}
 
func main() {
 
	//	パラメータの数をチェックします。
	if len(os.Args) != 2 {
		fmt.Println("usage:", os.Args[0], "room_id")
		return
	}
 
	live_status, is_enquete, bg_image, status := Live_Live_info2(os.Args[1])
 
	if status != 0 {
		fmt.Println("Error in intLive_Live_info() status=", status)
	} else {
		fmt.Println("live_status=", live_status, "is_enquete=", is_enquete, "bg_image=<", bg_image, ">")
	}
 
}
 

2019年10月26日 (土)

SHOWROOMのAPI - 「ライブ情報」の取得(GO言語のソースつき)

先日「SHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版)」という記事を書き、使っているAPIのURLは某巨大掲示板にころがってたやつです、って書いたのですが、SHOWROOMのAPIをきちんとまとめられている方がいらっしゃいました。

  「たける - SHOWROOMのAPIについて(現在26個公開。引き続き調査中)

---------

SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()」に書いたように今"自動三周ツール"の改良版を作成しています。その中で応援しているルーム(星投げ・種投げの対象ルーム)が配信中か否かのチェックを視聴者数が0でないかということでやっていたのですが、ちょっとタイムラグがあるようです。

どうしようか考えていたのですが、上の記事を見ると、ちゃんと配信状況を知るAPIがあるみたいです。これを使わない手はないと思いAPIの機能チェックのプログラムを書いてみました(ソースは記事の最後にあります)

Live_statusが具体的にどういう値になるのかわからなかったのですが、テストプログラムを実行してみると、配信中でないとき 1、配信中のとき 2、となるようです。

Result

最初の実行結果は配信中のもので、Live_statusは2となっています。次の実行結果は配信終了後のものでLive_statusは1になっています。

これ以外の値をとるのかとらないのか?は今後の課題です。

なお、JSONのデコードは

  「qiita @msh5 - Go言語でJSONに泣かないためのコーディングパターン

の記事を参考にさせていただきました。

-----------------------------

main()
  SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()

  SetEnvironment() 環境やポリシーに依存するパラメータを設定します。

  SetBlackList() 星集め/種集めの対象としないルームのリストを作ります。

  GetCategoryList() 公式枠/アマチュア枠に該当するジャンル(の位置)をオンライブ画面から検出します。

  BreakDownSchedule() 配信スケジュールから星集め/種集め、星投げ/種投げ、カウントの
   SHOWROOM 星集め・星投げツール スケジュールの詳細化 BreakDownSchedule() (三周のやり方を例に)

  Scheduler() タスクリストにしたがって星集め/種集め、星投げ/種投げ、カウントを行います。

    MakeTaskList() タスクリストから現在時(時分)に実行すべきタスクの集まり(タスクグループ)を抜き出します。

    GetRoomList() 星集め/種集めの対象とするルームのリストを作ります。

    CollectStarts() 星集め/種集めを行います。

    ThrowStars() 星投げ/種投げを行います。

    Count50() カウントを行います。

共通して使用する主な関数

  MakeNewPage() ブラウザ画面を開きます。
  ClosePage() ブラウザ画面を閉じます。


=================================================

» 続きを読む

2019年9月25日 (水)

SHOWROOM 星集め・星投げツール スケジュールの詳細化 BreakDownSchedule() (三周のやり方を例に)

例えば「15時00分からの公式枠・○○さんの配信で3周する」という目標を立てます。そうするとそれを実現するために配信開始前・開始後にいろんな"作業"が必要になります。

Photo_20190924234901



(1)~(15)が必要な"作業"です。このブログの記事(とソース中のコメント)では、次のような"用語"を使うことにします。

・スケジュール
配信予定とそれに対する対応の計画をいいます。
「公式枠・○○さんの15時00分から90分の配信で最初3周+50カウントし、次の解除で1周+50カウントする。解除は15時15分」
みたいなやつです。スケジュールはスケジュールファイルとしてプログラムの入力となります。スケジュールファイルには複数のスケジュールを書くことができます。

・タスク
スケジュールを実現するために必要な作業の一つ一つを言います。星・種を集める、星・種を投げる、カウントするがそれに相当します。
上の図で(1)から(15)で示したものがそれです。

・タスクリスト
一日のすべてのタスクの集まりです。タスクリストファイルに書き込まれています。

・タスクグループ
指定した時刻に始めるべきタスクとそれに継続して実行する一連のタスクを言います。
上の図で配信開始時に行われる「(3) 1周目分の星投げ、(4) 2周目分の星集め、(5) 星投げ」の三つのタスクの集合がそれです。

-------------------------------------

このプログラムではプログラム実行開始時(と任意の時刻に)スケジュールをファイルから読み込み、タスクリストを作成してファイルに書き込みます。

その後、毎分0秒にタスクリストファイルを読み込み、もしタスク実行時間が現在時に一致するものが見つかれば、実行時間が一致するタスクから開始されるタスクグループを抽出します。
そして抽出したタスクグループにしたがって個々のタスクを実行していきます。

今回はスケジュールからタスクリストを作成しファイルに書き込む関数 BreakDownSchedule()のソースを紹介します。
なお、このソースはShowroomLibパッケージから該当部分を抜粋したものであり、このままではコンパイルできませんので念の為。
ShowroomLibパッケージのソース全体は後日公開します。

※ main()については SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()の記事にあります。

=========================================

スケジュールファイルの例
(15:30配信開始、配信時間は60分、解除は開始900秒後、3周、公式枠、アカウントはnamexxxx)

# 1. 配信開始時刻 HH:MM
#
# 2. 予定配信時間(分) 1時間配信+カウント枠のケースは(たとえば)90とします。
#
# 3. 配信開始から解除までの時間(秒) 配信開始が15時、解除が15時15分であれば900とします。
#
# 4. カテゴリー Official:公式枠、Amateur:アマチュア枠
#
# 5. 対象配信ルームのURLの最後のフィールド(アカウント)
#
# 6. 備考
#
15:30 60 900 3 Official namexxxx test

=========================================

タスクファイルの例

# 1. タスク種別 C:星(種)集め、T:星(種)投げ、N:50カウント
#
# 2. タスク開始時刻 HH:MM:SS
# ただし、99:99:99 は直前のタスクに引き続き実行する。
#
# 3. カテゴリー 0:公式枠、1:アマチュア枠
#
# 4. タスクが"C"のとき、集めるべき各色ごとの星(種)の数
# タスクが"T"のとき、星(種)投げの回数
# すべての色で10個(あるいは9個)投げるのを1回とします。
# タスクが"N"のとき、カウントの回数(通常50)
#
# 5. タスクが"C"のとき、1:配信ルームリストで昇順に集める
# -1:配信ルームリストで降順に集める
# (通常は昇順で、降順にするのは3周の2周目分のときです)
#
# 6 タスクが"C"のとき、true:現在の星数にかかわらずかならず一回星を集める
# false:目標星数があれば星集めはしない
# (通常はfalseで、trueにするのはいわゆる"捨て星"のときです)
#
# 7 タスクが"C"のとき、true:配信ルームリストを作り直さない
# false:配信ルームリストを作り直す。
# (通常はfalseで、trueにするのは星集め・星投げを2分割するときの2回目です)
#
# 8. タスクが"T"のとき、対象配信ルームのURLの最後のフィールド(アカウント)
#

C 13:44:20 0 99 1 false false n/a
C 14:44:20 0 99 1 true false n/a
T 15:30:00 0 10 0 false false namexxxx
C 99:99:99 0 90 -1 false false n/a
T 99:99:99 0 9 0 false false namexxxx
C 15:44:20 0 50 1 false false n/a
T 99:99:99 0 5 0 false false namexxxx
C 99:99:99 0 50 1 false true n/a
T 99:99:99 0 5 0 false false namexxxx
N 99:99:99 0 50 1 false false namexxxx

開始時刻が99時99分99秒となっているのは、直前のタスクに継続して順次実行することを意味しています。
したがってこのタスクファイルには4つのタスクグループがあります。
解除は開始900秒後ですから、3周目分の星集め開始時刻は15時45分となるわけですが、その前に配信ルームリストを作らなければならないので星集めのタスクの開始時刻は15時44分20秒となっています。実際に星を集め始めるのは15時45分00秒となります。

=========================================

main()
  SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()

  SetEnvironment() 環境やポリシーに依存するパラメータを設定します。

  SetBlackList() 星集め/種集めの対象としないルームのリストを作ります。

  GetCategoryList() 公式枠/アマチュア枠に該当するジャンル(の位置)をオンライブ画面から検出します。

  BreakDownSchedule() 配信スケジュールから星集め/種集め、星投げ/種投げ、カウントの
   SHOWROOM 星集め・星投げツール スケジュールの詳細化 BreakDownSchedule() (三周のやり方を例に)

  Scheduler() タスクリストにしたがって星集め/種集め、星投げ/種投げ、カウントを行います。

    MakeTaskList() タスクリストから現在時(時分)に実行すべきタスクの集まり(タスクグループ)を抜き出します。

    GetRoomList() 星集め/種集めの対象とするルームのリストを作ります。

    CollectStarts() 星集め/種集めを行います。

    ThrowStars() 星投げ/種投げを行います。

    Count50() カウントを行います。

共通して使用する主な関数

  MakeNewPage() ブラウザ画面を開きます。
  ClosePage() ブラウザ画面を閉じます。

=========================================
=========================================




» 続きを読む

2019年9月17日 (火)

SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()

これまで、なんでもいいから三周できればいいや、みたいな気持ちでプログラムを書いていたのですが、心をいれかえて少しは役にたつようなプログラムになればという気持ちで作りました。

特徴(というか目標)

・全体の構造や処理の内容がわかりやすく、再利用・改修が容易なプログラム。

今回のプログラムはShowroom - 自動星集め・星投げ・カウントツール)にあるソースを改修したのものではなく、その反省をもとに新たに作成したものです。

・GO言語らしいプログラム、GO言語のプログラミングの参考になるようなプログラム
 (そういう気持ちで作っているという意味で、じっさいそうなってるかどうかはわかりません。
  もちろん他の言語に移植しにくいようなものにはしません)

・環境に依存しないように作る(要するにハードコーディングはしない。と言ってもSHOWROOMのシステムを相手にしてるわけで...)

・特に公式枠・アマチュア枠のジャンルの変更にはできるだけ影響を受けないようにする(これまでさんざん泣かされたところです)

・Goroutineは使わない。
  Goroutineを使えば処理の時間を短縮できるのですが、プログラムの可読性がおちるので今回はやめました。
  (今後Goroutineを使うバージョンも作る予定はあります)

※ 誤解を招きそうなので補足しておきます。Goroutineを使ったからプログラムがわかりにくくなるということはないのですが、Goroutineを完全に非同期で動かすことはできず、ある程度お互いの動作を意識する必要があり、その部分があるためにわかりにくくなる、という意味です。

--------

・配信者さんに合わせたスケジュール(タスクリスト)が作れる(要するに時間にルーズな配信者さんにもある程度対応できる)

・可能な限り星集めの"解除"の時刻を正確にコントロールする(PCのRTCが正確という条件で不確かさを1秒以下に抑える)
 これによって3時間おき一日7配信みたいなのにも対応できるかと思います(まだ実際にやってみていないですけど)

・PCの過負荷やムリな設定条件などで三周できそうにないときも最大の星数種数が投げられるように最適化する。

--------

今回はmain()のソースを紹介します。これから順次各関数の紹介・説明をしていきます。

main()
  SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()

  SetEnvironment() 環境やポリシーに依存するパラメータを設定します。

  SetBlackList() 星集め/種集めの対象としないルームのリストを作ります。

  GetCategoryList() 公式枠/アマチュア枠に該当するジャンル(の位置)をオンライブ画面から検出します。

  BreakDownSchedule() 配信スケジュールから星集め/種集め、星投げ/種投げ、カウントの
   SHOWROOM 星集め・星投げツール スケジュールの詳細化 BreakDownSchedule() (三周のやり方を例に)

  Scheduler() タスクリストにしたがって星集め/種集め、星投げ/種投げ、カウントを行います。

    MakeTaskList() タスクリストから現在時(時分)に実行すべきタスクの集まり(タスクグループ)を抜き出します。

    GetRoomList() 星集め/種集めの対象とするルームのリストを作ります。

    CollectStarts() 星集め/種集めを行います。

    ThrowStars() 星投げ/種投げを行います。

    Count50() カウントを行います。

共通して使用する主な関数

  MakeNewPage() ブラウザ画面を開きます。
  ClosePage() ブラウザ画面を閉じます。

» 続きを読む

2019年8月30日 (金)

SHOWROOM - 自動三周ツール(視聴ボーナス版)(もう一つの自動星集め・星投げ・カウントツール

以前書いた記事SHOWROOM - 自動三周ツール(もう一つの自動星集め・星投げ・カウントツールにあるツールは星集め(種集め)がいわゆる「ツイボ」で行われていました。7月からツイボによる星集めはできず、「視聴ボーナス」だけが星集めの手段となりました。

あしかっぴ(@pf_ashika)さんから「視聴ボーナス」対応のGO/agouti版ソースをいただきましたので、公開することにします。じつはこのソースはツイボで星集めができなくなる前にいただいたのですが、いろいろやりとりをしてるうちに一ヶ月以上経ってしまいました。大半は私の怠慢です。すみません。

以下からダウンロード可能です。内容は ソース sh880_20190801.go と 入力データ StartTime1.txt です。

    ダウンロード - sh880_20190801.zip

ソースの使い方はプログラム冒頭のコメントを御覧ください。特に

//	Sep.	環境に依存するするものはプログラム冒頭のconstで定義しました。
//	Sep.	Log_Dir  User_Data_Dir がそれです。
//	Seo.	ご自身の環境に合わせて変更してお使いください  <============= **重要**
//	Sep.	特にUser_Data_Dirについてはプログラムを起動する前に--user-data-dirオプションで指定して
//	Sep.	Chromeを起動して、SHOWROOMにログインしてSHOWROOMにの視聴環境を整えておくことが必要です。

のところに注意していただければと思います。

---------

ところで私の作った Showroom - 自動星集め・星投げ・カウントツール) の方はその後大幅に改良を行ってリス活に活用中ですが、現在「初心に戻って」一から書き直しているところです。

  2019.09.18 記事を書き始めました! => SHOWROOM 新・自動三周ツール -- GO言語によるブラウザ制御 (1) main()

最近書いている一連の記事をご覧になればなんとなくわかっていただけると思いますが、

  1.機能ごとに関数を作って提供し、どなたでも自分の必要とする機能をもったプログラムを容易に構成できるようにする。
  2.ハードコーディングは極力避ける(といっても相手がSHOWROOMという生きたシステムなので限度がありますが)
  3.agoutiを使う必然性がない部分はgoquery(やencoding/jason)を利用して負荷軽減を図る。
  4.GOの言語仕様の特性を活用し、またできるだけパッケージを利用した作りとする。
  5.機能の使いやすさ・わかりやすさを優先し、星集め・星投げを非同期で動作させるような作りはいったん排除する。

というような方針でやってます。

2019年8月11日 (日)

SHOWROOM - 自動星集め/種集め - 配信ルームリストの取得(ソース)

現在、SHOWROOMでの自動星集め/種集め、さらには自動星投げ/種投げツール(両方合わせれば自動三周ツール)の作成に必要な要素について記事を書いています。前記事 SHOWROOM - 自動星集め/種集め - 配信ジャンルの取得(ソース) では公式、アマチュアそれぞれのジャンルの求め方について書いたので、今回はそれぞれのジャンルにある配信ルームのリストを作ることになります。
(次は「星集め関数」の予定です)

前回、今回の記事はブラウザを開きそこから必要なデータを取得する方法ですので、SHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版)SHOWROOM - イベント貢献ランキング(貢献ポイント)を取得する関数(ソース) のようにブラウザを開かずJSONあるいはHTMLをスクレイピングする方法に比較すると若干パフォーマンス的に劣る方法になります。

じつはムム@SRさん( あるいは Showroom イベント ポイント遷移グラフ公開所)から



というご指摘をいただいています。要するにこの配信ルームのリストを作る機能もブラウザを開かずに(つまりgo/agoutiではなくJSONのパースだけで)作れるということです。そちらの方がパフォーマンス的に有利かと思いますが、すでにこの関数を作りかけていたのでひとまずこちらから公開することにします。JSON版もそのうち作って公開したいと思います。

プログラム自体それほど大きなものではありませんし、コメントも入れてあるので記事の最後にそのまま公開することにします。
main()(テストプログラム部)の実行にはGetCategoryList()が必要ですが、これはPackage ShowroomLibを作ってそれにおさめています(パッケージはビルドしたあとインストールが必要です。念のため)
もちろん前記事のソースからGetCategoryList()を持ってきてこのソースに追加してもかまいませんが、その場合は
  IdxAmateur, IdxOfficial, status := ShowroomLib.GetCategoryList(...
のところはとうぜん
  IdxAmateur, IdxOfficial, status := GetCategoryList(...
とします。

最近多少はGO言語やagoutiの使い方がわかってきたので、今までよりはだいぶマシなプログラムになっていると思います(あくまで"今までより"ですが)

セレクターはこれまでブラウザの開発ツールでCSSセレクターをコピーしてきてそれを使っていたのですが、かならずしも意図したものにならない場合があり、今回はhtmlの構造を考えながらセレクターを作っています。
また"li"のところのデータの取得ではMultiSelectionを使ってみました(セレクション取得のための All()、セレクション数を得る Count()、個別のセレクションを得る At() )
個別に取得するのとたいして違いはないのですが、今回は後ろからデータを取得しなければならないケースがあり最初に個数が必要なので。

※ 自動星集め・星投げについてはすでにソースを公開(「Showroom - 自動星集め・星投げ・カウントツール)」 )していますが、機能ごとにソースを分けてない上にふつうは必要にならないような機能を盛り込んだこともあってソースの可読性がよろしくないです。またハードコーティングされた部分もありますし、コメントの位置や量にムラがあります。そこでそのあたりを改善して自分の目的にあったプログラムを作っていただけるようにしようと、機能ごとに関数を分けて一つずつ記事にしている次第です。
もうひとつの 「Showroom - 自動三周ツール(もう一つの自動星集め・星投げ・カウントツール)」  の方もすでにあしかっぴ(@pf_ashika)さんから視聴ボーナス対応版のソースをいただいているので、公開予定ですが、私のソースをベースにされているため同じ課題が残っています。

» 続きを読む

2019年8月 7日 (水)

SHOWROOM - 自動星集め/種集め - 配信ジャンルの取得(ソース)

SHOWROOMで星あるいは種を集めようとするとオンライブ画面から公式枠なりアマチュア枠なりのジャンルに移動して、現在配信されている配信画面を次々に開いていく必要があるのですが、ジャンル構成がたびたび変更されるのでその都度対応=プログラムの修正=を行うということになってました(Showroom - 自動星集め・星投げ・カウントツールなど)

公式枠はジャンルの3番目から7番目、アマチュア枠は10番目というようなハードコーディングをやってるからそうなるわけで、今回はオンライブ画面から公式枠とアマチュア枠のジャンルがどこにあるか調べてジャンル位置のリストを作る関数を作ってみました。

ジャンルの追加、削除、位置の変更に対し、何もしなくてもあるいはデータファイルを変更するだけで対応できるようになります。

記事の最後にソースをおいておきます。利用法を含めかなり細かい説明を入れたつもりなので、記事での説明は省略します。

それからいつジャンルのリストを作業をするかが問題です。星集めのプログラムの中で一日に一回やっておけばじゅうぶんみたいに思えるのですが、これまでの仕様変更(ジャンル枠の変更)は16時とかずいぶん思い切った(?)時間に行われたことがありましたから星集めの都度やっておいた方が無難かも....

なお、こういうをやってると規約上どうなんだろう、という問題が発生するわけですが、それはご自身で考えてください。
すべてアウト(にできるぞ!)、とも受け取れる規約ですが、私の場合は、ここまではセーフ、ここから先はグレー、という線を自分なりに想定してやってます。

ところでこういうのは、ほどほどにしておけばだいじょうぶ、と安心してもいられないことを最近知りました。

  岡崎市立中央図書館事件(Wikipedia)
  「Librahack


SHOWROOMのエンジニアさんは優秀そうだから、こんなことはないと思いますが、お互い気をつけましょう。

---------------------

SHOWROOMのための関数(GO言語、ソース)

  SHOWROOMのイベント参加者のリストを取得する(GO, スクレイピング)
  SHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版)
  SHOWROOM - イベント貢献ランキング(貢献ポイント)を取得する関数(ソース)

» 続きを読む

2019年7月29日 (月)

SHOWROOM - イベント貢献ランキング(貢献ポイント)を取得する関数(ソース)

イベント貢献ランキングの取得については以前書いた

  Showroom - イベントの獲得ポイント数を取得して記録するツール

にもあったのですが、パフォーマンス(負荷)の問題があるので

  SHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版)

と同じように書き直してみました。つまり go/agouti をやめて go/goquery を使っています。

また関数のインターフェースについては、最近のいくつかの記事と同様に

  1.  実行時のパラメータ(イベントIDや配信者ID)は引数として渡し
  2.  結果はすべて戻り値として受け取る
  3.  結果がリストの場合はSliceとして受け渡す

という方針にしました。ソースはそれほど長くないのでこの記事の最後にそのまま掲載します。

関数のインターフェースやサンプルプログラムの実行方法についてはコメントにあります。

ところで、貢献ポイントランキングを取得することに意味があるのか、というのがあるのですが、
まあぜったい必要になるというのは減算が発生したとき、原因アカウントを特定するときくらいでしょうか w
もっとも貢献ポイントランキングがあればかならず原因アカウントを特定できるわけでもありませんが。

配信者さんにとっては、○○くん、最近サボリ気味だから気合入れておこうかなあ、とか...

なお減算については

  「Showroom - 複数アカウント(複垢)問題の真実 - 実験計画
  「Showroomの重複アカウント(複垢)減算はこうして起きる


に書いたのですが、ムム@SRさん( あるいは Showroom イベント ポイント遷移グラフ公開所)によれば実際はもっと"複雑怪奇"なケースもあるようです。

サンプルプログラムの実行結果
Photo_20190729003701

じつはさらに(もうちょっとだけ)パフォーマンスがいい方法があるようです。公開に問題なさそうであれば、そのうち記事にします。

---------------------------------------------

» 続きを読む

«SHOWROOM - イベントでの配信者の獲得ポイント数を取得する(改良版)

フォト

サイト内検索

  • 記事を探されるんでしたらこれがいちばん早くて確実です。私も使ってます (^^;; 検索窓が表示されるのにちょっと時間がかかるのはどうにかしてほしいです。

新着記事

リンク元別アクセス数

  • (アクセス元≒リンク元、原則PCのみ・ドメイン別、サイト内等除く)

人気記事ランキング

  • (原則PCのみ、直近2週間)
無料ブログはココログ