Nerds N' Computers

ソフトウェア技術や思ったことについて書きます.

ソフトウェア技術や思ったことについていろいろと書きます.

Ajax+Flaskを用いたコンタクトフォーム作成

経緯

ウェブ制作の一環として、コンタクトフォームを作ることになったのですが、既にある物を使うくらいなら勉強にもなるし、1から作ろうと考え他のがきっかけです。 実際、phpなどを使う方法もあるのですが、pythonに慣れていたため、flaskを使おうと思いました。 

アーキテクチャ

Untitled Diagram.png

参考にしたサイト

CSSフレームワーク: - Bulma

Flaskでは: - Jinja2の使い方がわかるとFlaskを用いた開発がよりスマートになる - Flask-Mail documentation - Attaching content and links to messages (Slack)

HTMLの中身

HTMLで必要になってくるのはformタグ内のmethodactionの指定であり、コンタクトフォームであるので下記のように記しておくべきである。

<form id="contact-form" method="POST" action="/127.0.0.1:5000">

今回はFlaskを使用しているため、actionの指定先はFlaskを立ち上げるサーバになる。 したがって、htmlの中身は下記のようになる

<form id="contact-form" method="POST" action="/127.0.0.1:5000">
    <div>
        <div class="field">
            <label class="label">Name</label>
            <div class="control">
                <input name="name" class="input" type="text" placeholder="Name" required>
            </div>
        </div>
        <div class="field">
            <label class="label">Email</label>
            <div class="control">
            <input id="email" name="email" class="input" type="email" placeholder="Email" required>
            </p>
            <p id="email-error" class="help is-danger email-success">
                This email is invalid
            </p>
        </div>
        <div class="field">
            <label class="label">Message</label>
            <div class="control">
                <textarea name="message" class="textarea" placeholder="Textarea" required></textarea>
            </div>
        </div>
        <div>
            <div class="control">
                <button id="submit" class="button is-link">Submit</button>
            </div>
            <div class="control">
                <button id="cancel" class="button is-text">Cancel</button>
            </div>
        </div>
    </div>
</form>
<div id="result"></div>

簡略化のために氏名・メールアドレス・メッセージだけにした。ここで重要になるのが、inputtextareabuttonであるので、他の要素はとりあえずは無視して良い。

jsの中身

まず、フォームの中身をオブジェクト型で取ってくる

var form = document.forms.contactForm;

これを使用して、もしsubmitボタンが押された時、それらをajaxで処理する。

ajaxの部分について

初めに、デフォルトではsubmitをした時にデフォルトでPOSTするようになっているのでこれをしないように明言する必要がある。

$(form).submit(function(e) {
   // prevent it from POSTing
   e.preventDefault();
   
   //ここに必要なコードを記述していく
}

では実際に内容を書いていきます。 ajaxdataは正規化されていないといけないので、下記のように正規化する。

var formData = $(form).serialize();

そしてこれを用いて、ajaxに渡す内容は下記のようになる

$.ajax({
  type: 'POST',
  url: 'http://127.0.0.1:5000',
  data: formData
})

urlはflaskで指定する番号になるため、とりあえずはこのままにしておく。実際にサーバがあるのならそれをここに記述する。

成功した時

.done(function(response) {
    // ここに成功時の動作を記述する
})

失敗時

.fail(function(response) {
    // ここに失敗時の動作を記述する
});

jsのまとめ

したがって、以上のコードをまとめると下記のようになる

// Object of the form
var form = document.forms.contactForm;

/*
 * This function receives the form and sends it
 * using ajax.
 */
function sendForm(e) {
  // When 'submit' was clicked
  $(form).submit(function(e) {
    // prevent it from POSTing
    e.preventDefault();

    var formData = $(form).serialize();

    $.ajax({
      type: 'POST',
      url: 'http://127.0.0.1:5000',
      data: formData
    })
    // If succeeded, show a popup message
    .done(function(response) {
      // reset form inputs
      $('form :input').val('');
    })
    .fail(function(response) {
      // 失敗時の記述
    });
  });
};

form.name.addEventListener('change', sendForm, false);

となる。私は成功時は更にポップアップメッセージを追加し、失敗時はそのエラーを吐くようにしました。 色々工夫の方法はあると思うので、自由に書いてください。

Flaskの中身

pythonコードのでは実際にslackやメールを送信するという動作を行います。
メールは flask_mail を使用すると実装ができ、slackは slackweb というパッケージを使用すると実装ができます。

flask_mail

上記でも参考サイトであげさせていただいたFlask-Mail documentationを参考に送信するメールのコードを書く。 単純にメールを送信するコードは下記のようになる:

from flask_mail import Message

@app.route("/")
def send():

    msg = Message('Hello',
                  sender='from@example.com',
                  recipients=['to_1@example.com', 'to_2@example.com'])

しかし、これでは同期処理となり、時間がかかるため、非同期処理にメールを送信する方法がある。 これを行うには、 threadingパッケージの Threadメソッドを用いる。

from threading import Thread

from flask_mail import Message, Mail


def send_async_mail(app, msg):
    """
    Send mail asynchronously
    """
    mail = Mail(app)
    with app.app_context():
        mail.send(msg)

def send_mail(email, app, html, sender, mail_title):
    """
    Send mail to receiver
    """
    msg = Message(
            mail_title,
            sender=('name', 'sender@example.com'),
            recipients=[email],
            bcc=[sender],
            )
    msg.html = html
    thr = Thread(target=self.send_async_mail, args=[app, msg])
    thr.start()

    return True

とすれば、メールを非同期処理で送信することができます!

ここで、メールをhtmlでフォーマットしたい場合、Flaskはjinja2との相性が良いのでFlask-Mail documentationを参考にすると綺麗に作成できると思います。

Slack

今回、Slackには簡単にコンタクトフォームの内容を送信してみることにした。こちらはSlackが提供しているAPIですぐ実装ができます。 その前に、Slackにメッセージが送れるようにWebhook URLの発行が必要で、下記のサイトを参考にすると簡単にできます。 SlackのWebhook URL取得手順

URLを取得できればあとは簡単です。 Attaching content and links to messages (Slack)を参考に、好きな形でメッセージを送信します。 まず、メッセージの作成です。

def create_message():
        attachments = []
        attachment = {
                'fallbacks': 'New Contact Has Arrived!',
                'title': "New Contact Has Arrived!",
                'color': '#anycolor',
                'fields': [
                    {
                        'title': 'Date',
                        'value': date,
                        'short': True
                        },
                    {
                        'title': 'Name',
                        'value': name,
                        'short': True
                        },
                    {
                       # Any other fields
                        },
                    ]
                }
        attachments.append(attachment)

        return attachments

これでメッセージの作成ができました。あとは先ほど取得したwebhook urlを用いてメッセージの送信を行います。

import slackweb

slack = slackweb.Slack(url=WEBHOOK_URL)


def send_to_slack(slack):
        slack.notify(attachments=format_attachment())


if __name__ == '__main__':
        send_to_slack(slack)

以上で、メールとslackにメッセージを送信することができました!

最後に

コンタクトフォームを作る方法は色々あると思いますが、flaskを用いると結構簡単に作れてしまうことがわかりました。実際、色々な機能を追加するとまた違いますが、、、

Julia言語について

初めに

今回ブログを作ったと同時にJuliaという言語に興味があったので, 少しずつ勉強も兼ねてまとめていきたいと思います.(2018年10月にて)

この回ではJuliaという言語で, どういった背景をもとに作られたのか, ブログやドキュメントからまとめていきます.

背景

Juliaという言語は Jeff Bezanson, Stefan Karpinski, Viral Shah, Alan Edelmanなどによって作られた言語です.

プログラミング言語Fortranから始まり, 現在まで数多くのものが作られてきました. 例えば, C言語はその速さとコンパクトさが特徴であり, Rubyは他言語に比べダイナミックです.

このように, 各言語にはそれぞれメリット・デメリットがあり, あるものに秀でている分, それ以外は他言語に劣ることが多いです.

そこで, 全てに秀でている 'Greedy' な言語を作ったのが彼らであり, C, Ruby, Python, Lispなどの影響を受けJuliaが誕生しました.

インストール

インストールするには以下の4つの手段があります(macを用いた場合)(もしかしたら他にも方法はあると思います...) :

  • オフィシャルホームページからパッケージをインストール
  • brew
  • Github
  • Jupyter

オフィシャルホームページ

オフィシャルホームページからダウンロードができます: Julia Downloads

Brew

brew cask install julia

Github

Githubからフォークすることもできます: github.com

しかし, Githubからインストールする場合はパッケージを全てインストールすることに注意してください.

Jupyter

JuliaBox

基本的な使い方

インストールがうまくいくと julia というコマンドが使用できるようになります.

また, pythonと同様にコマンドラインjulia と打つとREPL (Read Eval Print Loop) が開かれます.

$ julia

   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.1 (2018-09-29)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia>

と表示されれば成功です.

ファイル端末子は .jlであり, ファイルの実行方法は以下の様です.

$ julia file.jl [arg1 arg2...]

簡単に Hello, World! を表示してみると,

println("Hello, World!")

となります.
pythonからの人はダブルクォーテーションで括ることに注意が必要そうです(自分がシングルクォーテーションだったので).

感想

触った感じ, pythonなどよりかはmatlablispの影響の方が大きいのかな, といった感じでした. 重たいコードを書いていないので速さの判定などはできなかったので今後に期待といったところでしょうか?

参考文献

https://julialang.org/blog/2012/02/why-we-created-julia

Introducing Julia/Getting started - Wikibooks, open books for an open world

Platform specific instructions for installing Julia

H

KubernetesにおけるLoadBalancerとIngressの違いについて

Kubernetesでは, インターネットからクラスタ内部のPodにアクセスするためにServiceやIngressを通して内部のPodにアクセスできるように必要があります.

このとき一般的な公開方法としてLoad Balancer Serviceを使う方法とIngressを用いる方法がありますが, (NodePortやClusterIPで公開する方法は, 用途が限られるので割愛します) 本記事ではそれぞれの機能と使い分けについて簡単に解説しようと思います.

続きを読む