Gravaterの画像を自分で描く
何
一日目だしハードルは無いに等しい。ということで、今までやりたかったがやっていなかったGravater*1を設定することにした。
好きなキャラクターの画像は心に良いが、そのまま引っ張ってくるのはあまりよろしくない。そこで神絵師*2だ。 神絵師なら版権絵も自分のテイストに落としこんでいい感じになるはず。
描く
描いた。Krita*3、一太郎30周年記念ペンタブ*4を用いた。 ちなみにこれに一時間かけている。察せ。
平グモちゃん*5可愛い。可愛い平グモちゃんを描いたからには可愛い絵が爆誕しているはずだ。
上げる
先ずは上記サイトにて登録。メールが来るので承認ページへ。
上げた。達成感がある。段々恥ずかしくなってくるが耐える。
おわり
2日目は@karasuTXのはず。
*2:これは神絵師になるのが目的のカレンダー、らしい。
Golangのtemplateライブラリハマり
ちょこちょこやっているので追加するかも。
ブレース"{" "}"が{{}}の前後に書けないっていう。
LeTeX用のテンプレートを書こうとしてハマる。
というわけで、
\title{{print "{"}}{{.Booktitle}}{{print "}"}}
のようにして解決した(解決していない)。
げっちゅな屋でスクレイピング2
何
以前のエントリで書いたのは月別の発売日を出力するものでしたが、今回は検索を行うものを書きました。基本は一緒で、URL、クエリ、matcherなどが変わりました。要は別サイトをスクレイピングした感じになりました。
詰まった所
- クエリをEucJPにするのを忘れてしばらく時間を使った。
- 発売日に特徴的なタグがついていない(諦めて該当箇所全部出すことにした)。
code
package main import ( "flag" "fmt" "net/http" "strings" "io/ioutil" "net/http/cookiejar" "net/url" "github.com/yhat/scrape" "golang.org/x/net/html" "golang.org/x/net/html/atom" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) var ( keyword string title string brand string person string isbn string jan string age string genre string startDate string endDate string sort string sort2 string listCount string listType string search string ) func eucjpToUtf8(str string) (string, error) { ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewDecoder())) if err != nil { return "", err } return string(ret), err } func utf8ToEucjp(str string) (string, error) { ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewEncoder())) if err != nil { return "", err } return string(ret), err } func main() { flag.StringVar(&keyword, "keyword", "", "search keyword") flag.StringVar(&keyword, "k", "", "search keyword short") flag.StringVar(&title, "title", "", "search title") flag.StringVar(&title, "t", "", "search title short") flag.StringVar(&brand, "brand", "", "search brand") flag.StringVar(&brand, "b", "", "search brand short") flag.StringVar(&person, "person", "", "search person") flag.StringVar(&person, "p", "", "search person short") flag.StringVar(&isbn, "isbn", "", "search isbn") flag.StringVar(&isbn, "i", "", "search isbn short") flag.StringVar(&jan, "jan", "", "search jan") flag.StringVar(&jan, "j", "", "search jan short") flag.StringVar(&age, "age", "", "age") flag.StringVar(&age, "a", "", "age short") flag.StringVar(&genre, "genre", "pc_soft", "genre") flag.StringVar(&genre, "g", "pc_soft", "genre default pc_soft") flag.StringVar(&startDate, "startdate", "", "start date") flag.StringVar(&startDate, "sd", "", "start date short") flag.StringVar(&endDate, "enddate", "", "end date") flag.StringVar(&endDate, "ed", "", "end date short") flag.StringVar(&listCount, "listcount", "100", "list") flag.StringVar(&listCount, "lc", "100", "list short default 100") flag.StringVar(&listType, "listtype", "list", "list type default list") flag.StringVar(&listType, "lt", "list", "list type short") flag.StringVar(&sort, "sort", "release_date", "sort default release_date") flag.StringVar(&sort2, "sort2", "down", "sort2 default down") flag.StringVar(&search, "search", "search", "search default search") flag.StringVar(&search, "s", "search", "search short") flag.Parse() getchuURL := "http://www.getchu.com/php/nsearch.phtml" jar, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ Name: "getchu_adalt_flag", Value: "getchu.com", Path: "/", Domain: "www.getchu.com", } cookies = append(cookies, cookie) u, _ := url.Parse(getchuURL) jar.SetCookies(u, cookies) client := &http.Client{ Jar: jar, } brand, _ = utf8ToEucjp(brand) title, _ = utf8ToEucjp(title) keyword, _ = utf8ToEucjp(keyword) person, _ = utf8ToEucjp(person) values := url.Values{} values.Set("search_keyword", keyword) values.Add("search_title", title) values.Add("search_brand", brand) values.Add("search_person", person) values.Add("search_isbn", isbn) values.Add("search_jan", jan) values.Add("start_date", startDate) values.Add("end_date", endDate) values.Add("sort", sort) values.Add("sort2", sort2) values.Add("list_count", listCount) values.Add("list_type", listType) values.Add("age", age) values.Add("genre", genre) values.Add("search", search) valuesEncoded := values.Encode() req, _ := http.NewRequest("POST", getchuURL, strings.NewReader(valuesEncoded)) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() root, err := html.Parse(resp.Body) if err != nil { panic(err) } req.Header.Add("Content-Type", "application/x-www-form-urlencoded") matcherTitle := func(n *html.Node) bool { if n.DataAtom == atom.Div { return scrape.Attr(n, "class") == "content_block" } return false } titles := scrape.FindAll(root, matcherTitle) for i, title := range titles { title, err := eucjpToUtf8(scrape.Text(title)) if err != nil { panic(err) } fmt.Printf("%d: %s\n", i, title) } }
げっちゅな屋でスクレイピング
なに
まだとりあえずタイトルが引っぱれるだけですが。golangでscrapeライブラリを使っています。
先達がコチラhttp://akb428.hatenablog.com/?page=1437903964。
追記(2016-11-10)
year、monthを引数にとってその年月の発売作品のタイトルを並べます。引数なしの場合、現在の月の発売作品を並べます。 respをCloseするようにしたのと、ブランド、発売日を表示するようにしました。
utf-8に変換してます Go言語で文字コード変換 - Qiita。
code
package main import ( "flag" "fmt" "net/http" "strings" "time" "io/ioutil" "net/http/cookiejar" "net/url" "github.com/yhat/scrape" "golang.org/x/net/html" "golang.org/x/net/html/atom" "golang.org/x/text/encoding/japanese" "golang.org/x/text/transform" ) const ( stdLongYear = "2006" stdNumMonth = "1" ) var ( year string month string ) func eucjpToUtf8(str string) (string, error) { ret, err := ioutil.ReadAll(transform.NewReader(strings.NewReader(str), japanese.EUCJP.NewDecoder())) if err != nil { return "", err } return string(ret), err } func main() { t := time.Now() flag.StringVar(&year, "year", t.Format(stdLongYear), "sell year") flag.StringVar(&month, "month", t.Format(stdNumMonth), "sell month") flag.Parse() getchuUrl := "http://www.getchu.com/all/price.html?genre=pc_soft&gage=adult" jar, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ Name: "getchu_adalt_flag", Value: "getchu.com", Path: "/", Domain: "www.getchu.com", } cookies = append(cookies, cookie) u, _ := url.Parse(getchuUrl) jar.SetCookies(u, cookies) client := &http.Client{ Jar: jar, } postData := strings.NewReader("&year=" + year + "&month=" + month) req, _ := http.NewRequest("POST", getchuUrl, postData) req.Header.Add("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() root, err := html.Parse(resp.Body) if err != nil { panic(err) } matcherGame := func(n *html.Node) bool { if n.DataAtom == atom.A && n.Parent != nil && n.Parent.Parent != nil { return scrape.Attr(n.Parent, "align") == "left" } return false } matcherSellday := func(n *html.Node) bool { if n.DataAtom == atom.Td { return scrape.Attr(n, "class") == "black" && scrape.Attr(n, "align") == "center" } return false } matcherBrand := func(n *html.Node) bool { if n.DataAtom == atom.Td { return scrape.Attr(n, "class") == "black" && scrape.Attr(n, "align") == "left" } return false } games := scrape.FindAll(root, matcherGame) selldays := scrape.FindAll(root, matcherSellday) brands := scrape.FindAll(root, matcherBrand) selldayList := make(map[int]string) for i, sellday := range selldays { selldayList[i] = scrape.Text(sellday) } brandList := make(map[int]string) for i, brand := range brands { brandList[i], err = eucjpToUtf8(scrape.Text(brand)) if err != nil { panic(err) } } for i, game := range games { // sellday, err := eucjpToUtf8(scrape.Text(sellday)) game, err := eucjpToUtf8(scrape.Text(game)) if err != nil { panic(err) } fmt.Printf("%s: %s| %s\n", selldayList[i], game, brandList[i]) } }
VPSでLXD+SoftEtherVPN(Server側)
こんな記事があったのでやろうとしてみた。
タイトルと違うって? そりゃ失敗したからね!
具体的にはlxcだけの操作になってるところを今のlxd/lxc環境でやるのはひっかかりが多くて、っていうのと tun
君が作れなかったり、つくれたと思ってもダメだったりしたので*1諦めました。
なら他のVPNサービスは?って調べたら
ever-day-jp: LXCとSoftEtherを利用してサーバー上にセキュアな作業システムを作る その2
がヒットしたのでやったらイケた。
今回はさくらのVPS(Ubuntu14.04)で建てました。速度とかはまあ家の回線がksなので全く違いがわからない程度です。
LXDの用意
LXD*2はUbuntu15.04ならaptで入りますが14.04ではビルドの必要がーー今回はありません。そう、Ubuntuならね。
% sudo apt-add-repository ppa:ubuntu-lxc/lxd-stable % sudo apt update % sudo apt install lxd
あ、「 apt-add-repository
がないのだけれど」という方は
% sudo apt install software-properties-common
としてください。
LXDの起動
さて、LXDを入れたらまずコンテナイメージを入手しましょう、ということで
# lxd-images import lxc ubuntu trusty amd64 --alias trusty
で14.04のイメージを入手、
2015年9月1日のリリースで上のやり方は廃止されました*3。Ubuntu、busybox以外のときの方法がニュースのところに載っています。
Ubuntuなら
# lxd-images import ubuntu trusty amd64 --alias trusty
のようにすれば良いようです。Ubuntuは接続先がlinuxcontainers.orgからcloud-images.ubuntu.comに変わったみたいです。繋がらないと思ったら lxd-images sync
などを試してみるとまた接続先が変わっていたりするかもしれません。
# lxc launch trusty container-vpn
でコンテナを作成、起動します。
コンテナの中に入るには
# lxc exec コンテナ名 /bin/bash
などとすれば入れますがrootで入ってしまうので、初めにsshを入れてしまうと後はsshで入って通常ユーザに。 コンテナのローカルなIPは
# lxc list
で見られます。なお、このようにして作られたコンテナの中には最初からubuntuというユーザがいるのでpasswd
でパスワードを変えておきましょう。
そしていよいよSoftEtherVPNのビルドに移るのですが、なんかもう色々と面倒だな、と参考のブログ記事同様
sudo apt-add-repository ppa:dajhorn/softether
とするとあら簡単。ppaの登録は各々の責任で行ってください。
VPN Serverの設定
sudo vpncmd /server localhost /CMD HubCreate HUB名 /password: パスワード sudo vpncmd /server localhost /CMD BridgeCreate HUB名 /DEVICE:eth0 sudo vpncmd /server localhost /CMD HubDelete DEFAULT sudo vpncmd /server localhost /CMD VpnAzureSetEnable yes sudo vpncmd /server localhost /CMD Flush sudo vpncmd /server localhost /CMD VpnAzureGetStatus
というわけで対話セッションを省略した場合の簡易セットアップ。ほぼ参考記事のままですね。HUBを作り、デフォルトを削除し、VPNAzureの設定を有効にし、そのアドレスを確認しておくという流れです。VPNAzureがあればコンテナからホストに出る手間がないので楽ができる、というか僕はそれ以外のやり方ががが。
下書きしたのが随分前になってしまったので抜けや更新情報が多いかも。