Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

Visual Studio for macでmac用GUIアプリケーションをつくってみる

Visual StudioとかM$用でしょ? というのも今は昔。
イマドキのVSはmac用もあります。
www.visualstudio.com
.NETフレームワーク対応はもとより、なんとxamarinだのnode.jsの開発環境までついてます!
GUIも結構格好いいし……ボクの知ってる頃のM$さんじゃありませんね。

というわけで、今回はこいつでmacOSGUIアプリ*1を作ってみます。

実際のところ

まずは、下記よりソフト本体を導入。
www.visualstudio.com

さて、本チャンに入っていくわけですが……結構手間が掛かります。
一応、Getting startedはありますけどね。
Hello, Mac - Xamarin

ここは現代の利器に頼りましょう。
Samples - Xamarin
のサンプルスクリプトやバイナリ一式がおいてあるGitリポジトリをクローンし

$ git clone --depth 1 https://github.com/xamarin/mac-samples

まずは王道のHello World風なボタンとラベルが一個だけのアプリいってみましょう。
Hello, Mac - Xamarin

$ open mac-samples/Hello_Mac/Hello_Mac.sln

で、ビルドしてやれば無事起動しました。
f:id:shuzo_kino:20171024213804p:plain

上記を踏まえた上で、以下のサイトの手順を一個一個追っていくと
やってることが分かるかと思います。
これを参考に、どこを弄るとボタンの名前が変わるか等々を実験してみると面白いかもしれません。
Hello, Mac - Xamarin


……ちなみに、私はgetting startedから着手したもののタイポなのか何なのかボタンが起動しませんでした。
よくみると、生成される文字列もなんかWEBと違いましたしね……。

*1:いうてボタンがついてるだけ

jQueryのhtml()とtext()について

jQueryのhtml()とtext()について

実際のところ

html()とtext()はデータの読み込み、書き込みを楽にできるやつです。
前者はタグを利用でき、後者は生テキストという違いがあります。

書き込みをするときは

$("#hoge").html("<li>something new</li>")

読み込み時は

var nyan = $("#hoge").html()

とやるだけです。

書き込みの場合は関数を持たせる事もできるので、
特定の箇所だけ強調……みたいな事もできます。

$( "div.demo-container" ).html(function() {
  var emphasis = "<em>" + $( "p" ).length + " paragraphs!</em>";
  return "<p>All new content for " + emphasis + "</p>";
});

【イベントログ】技術書展3に行ってきました

techbookfest.org


技術書展3に行ってきました
会場は秋葉原UDX
当日は台風21号接近という悪条件。
そのうえ、私は諸用で現地入りが15時と中々厳しい状態……。
が、開場時間が17時と割りと長いこともあって在庫が残っていました。

会場の様子

UDX名物、電子掲示板

会場にはイメージキャラのポップが

雰囲気は完全にコミケ技術島です。
そのため、本以外にもディスプレイが中々キマっていて素敵。
人型ロボ!

レーザー発振器!!

潜水艇!!!

【読書メモ】映像研には手を出すな! 2

映像研には手を出すな! 2 (ビッグコミックス)

映像研には手を出すな! 2 (ビッグコミックス)

前巻も最高でしたが、今回も最高です。
この本では、ロボット部からプロモーション動画を作る依頼を請けてから文化祭までの動きが描かれています。

管理畑の金森が相変わらずいい味だしてますね。
その努力をクリエイティブ根性でアレコレしてしまう二人組も相変わらず。
時々差し込まれる設定画ページのケレン味も切れ味を増しているように感じます。

それに加えて、この号から創作論……というか、作家のモチベーション論なネタがチラホラみられました。

「あんたは他人のために絵を描けるほど器用な人間なんすか」
「あなたがダメだと思うから、この作品はダメなんですよ。他人なんて関係ない。監督なんすよ、あんたは。」
「あんたがこのロボットに満足できないなら、”更に好き勝手描く”以外の選択肢はないんすよ!」
「"ロケットはここがカッコイイんだ!"っていう画圧に感動するわけよ! "わかってんじゃんアンタ!!"ってさ」
「大半の人が細部を見てなくても、私は私を救わなきゃいけないんだ。動きの一つ一つに感動する人に、私はここにいるって、言わなきゃいけないんだ。」
……という、名台詞も炸裂して終始、良さみに溢れている(語彙喪失

websocketで来た内容をIFTTTに投稿してみる

Python製軽量WEB鯖Bottleを使い、websocketで来た内容をIFTTTに投稿してみます。
……jQueryクソ雑魚勢なので、やたら苦労しました……。

実際のところ

構成

ファイル構成は以下の記事と同様
shuzo-kino.hateblo.jp

$ tree
.
├── app.py
├── static
│   └── js
│       └── client.js
└── templates
    └── base.jade

3 directories, 3 files

スクリプト

app.py
from bottle import route, get, post, request, run, redirect, static_file, Bottle
#jade対応
from bottle_jade import JadePlugin
#websocket対応
from bottle.ext.websocket import GeventWebSocketServer
from bottle.ext.websocket import websocket
#static対応
from os import path as op
#IFTTT投稿用
import requests


#初期化
app = Bottle()
templates = op.dirname(op.abspath(__file__)) + '/templates/'
jade = app.install(JadePlugin(template_folder=templates))

#静的ファイル置き場
@route('/static/:path#.+#', name='static')
def static(path):
    return static_file(path, root='static')

#ページ群本体
@get('/page')
def topPage():
	context = {"body": "basePage"} 
	return jade.render('base.jade', **context)     

@post('/page')
def postAction():
	theText = request.params.get('message')
	if theText:
		data = {"value1": theText, "value2": "def", "value3": "ghi"}
		headers = {'Content-Type': "application/json"}
		url = 'https://maker.ifttt.com/trigger/{{YOURAPPNAME}}/with/key/{{YOURACCOUNT}}'
		response = requests.post(url, json=data, headers=headers)
		messageString = "you posted: %s to IFTTT" % theText 
		print(messageString)
	return "You didn't post anything."

@get('/websocket', apply=[websocket])
def echo(ws):
    while True:
        msg = ws.receive()
        if msg is not None:
            ws.send(msg)
        else: break

#アプリ起動
run(host='localhost', port=8080, server=GeventWebSocketServer)

client.js

$(document).ready(function() {
            if (!window.WebSocket) {
                if (window.MozWebSocket) {
                    window.WebSocket = window.MozWebSocket;
                } else {
                    $('#messages').html("<li id=messages>Your browser doesn't support WebSockets.</li>");
                }
            }
            ws = new WebSocket('ws://127.0.0.1:8080/websocket');
            ws.onopen = function(evt) {
                $('#messages').append('<li id="messages">WebSocket connection opened.</li>');
            }
            ws.onmessage = function(evt) {
                $('#messages').html('<li id="messages">' + evt.data + '</li>');
            }
            ws.onclose = function(evt) {
	        $('#messages').append('<li id="messages">WebSocket connection closed.</li>');
            }
            $('#send').submit(function() {
                ws.send($('input:first').val());
                $('input:first').val('').focus();
                return false;
            });

	//ajax
      $('#ajax').submit(function(e) {
        var msg = $('li#messages').text();
        $.ajax({
            type: 'POST',
            url: '/page',
            data: "message=" + msg,
            success: function(response) {
                $('#ajaxP').html(response);
            }
        });
        e.preventDefault();
      });
});
index.jade
head
    meta charset="utf-8"
    title jQuerySample
    script(src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js")
    script(src="/static/js/client.js")

body
  h2 #{body}

  form#send(action='.')
    input(type="text" value="message")
    input(type="submit" value="Send")
  div#messages

  hr
  
  form#ajax(action="/page" method="post")
    input(type="submit" value="Post to IFTTT")

動作

開くとこんな塩梅。
上の方のメッセージは投稿で上書きされる形式
f:id:shuzo_kino:20171021160934p:plain
今回、受け取り先はIFTTTのWEB HOCK経由でメール受信です。
なのでこんな感じで回答がきます
f:id:shuzo_kino:20171021162225p:plain

BottleでjQueryのPOSTアクションをうけとる

クソ雑魚なのでjQueryは避けていたのですが……
色々作るときに不便なのでやってみることにしました。
重いものを作る気はないので、Bottleと連携させます。

実際のところ

構成

$ tree
.
├── app.py
├── static
│   └── js
│       └── client.js
└── templates
    └── base.jade

3 directories, 3 files

スクリプトの中身

app.py

from bottle import route, get, post, request, run, redirect, static_file, Bottle
from bottle_jade import JadePlugin
from os import path as op

#初期化
app = Bottle()
templates = op.dirname(op.abspath(__file__)) + '/templates/'
jade = app.install(JadePlugin(template_folder=templates))

#静的ファイル置き場
@route('/static/:path#.+#', name='static')
def static(path):
    return static_file(path, root='static')

#ページ群本体
@get('/page')
def topPage():
	context = {"body": "basePage"} 
	return jade.render('base.jade', **context)     

@post('/page')
def postAction():
	theText = request.params.get('message')
	if theText:
		messageString = "you posted: %s" % theText 
		print(messageString)
		return messageString
	return "You didn't post anything."

#アプリ起動
run(host='localhost', port=8080)


templates/base.jade

head
    meta charset="utf-8"
    title jQuerySample
    script(src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js")
    script(src="/static/js/client.js")

body
  h2 #{body}

  form(action="/page" method="post")
    b please input blog contents. >>
    input#ajaxTextbox(name="body" type"text")
    input#ajaxButton(type="submit" value="Submit")
  hr
  p#ajaxP Nothing to see here.


static/js/client.js

$(document).ready(function() {
      $('form').submit(function(e) {
        var msg = document.getElementById('ajaxTextbox').value;
        $.ajax({
            type: 'POST',
            url: '/page',
            data: "message=" + msg,
            success: function(response) {
                $('#ajaxP').html(msg);
            }
        });
        e.preventDefault();
      });
})

動かす

素はこんなページ
f:id:shuzo_kino:20171019222902p:plain

入力フォームに"44"と入れ投稿すると、"ajaxP"のidがついたトコが更新されます
f:id:shuzo_kino:20171019222916p:plain

コンソールにはこんな感じで出ます

you posted: 44
127.0.0.1 - - [19/Oct/2017 22:10:15] "POST /page HTTP/1.1" 200 14

Mosquittoをwebsocket対応にさせる その2:mqttws31を動かす

shuzo-kino.hateblo.jp
の続きです。
まずはbottle抜きで有名所のJS製MQTTクライアントmqttws31を動かしてみます

実際のところ

まずはindex.html。
mqttws31はCDN版を借りてきます。
そっけないので、本文に"sample"とか書いてますが、ここはお好みで。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>TEST</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="client.js"></script>
</head>
<body>
<p>sample</p>
</body>
</html>

"client.js"はこんな塩梅。
元ネタはconsole.logなんてハイカラなものを使ってますが
縄文人の私はalertで楽をします

// Create a client instance
var client = new Paho.MQTT.Client("localhost", 9090 , "clientId" + new Date().getTime());

// set callback handlers
client.onMessageArrived = onMessageArrived;

// connect the client
client.connect({onSuccess:onConnect});

// called when the client connects
function onConnect() {
    // Once a connection has been made, make a subscription and send a message.
    alert("onConnect");
    client.subscribe("PUBLIC/log/#");
}

// called when a message arrives
function onMessageArrived(message) {
    alert('payload: ' + message.payloadString);
}

動かす

前の記事で設定したwebsockets対応鯖を立ち上げ、
publisherで投稿してみます。

$ mosquitto_pub -h localhost -t PUBLIC/log/a -m 64 -q 1

なにかミスってなければ、"payload: 64"と期待した通りにでます。
f:id:shuzo_kino:20171018233012p:plain