一人もくもく会 α verでサービス開始しました。
請求書作成システム α verでサービス開始しました。

サイボウズLiveを作る-第3回-トピック登録まで

グループは作成できたので次は実際のコンテンツを作成していく。 とりあえず仕様的にシンプルそうな掲示板を作ってみることにした。 (もしかすると細かい機能が多くあるのかもしれないが)

処理的に特筆するところは特に何もなかったが、 投稿に関してはwysiwygエディタを入れた。

最終的に画像のアップロードも必要だと思うので有料になるCKEditorは無し。 最近のスタンダードがよく分からなかったのでStarやForkが非常に多い下記を入れてみた。

github.com

昔のwysiwygエディタといえば、textareaをターゲットにして起動すれば勝手にぜんぶやってくれたが、 これは多分SPA等も考慮されていると思うので勝手にPOSTまで出来るようにはなっていない。 そのため自前でハンドリングしてhiddenタグに入れる。 (Vueで書き直し予定なのでできたらまた追記)

import Quill from 'quill';

$(function() {
  $('div.richtext').each(function() {
    const $this = $(this);
    const quill = new Quill(this, {
      theme: 'snow',
    })
    $this.data('quill', quill);
    quill.on('text-change', function(delta, oldDelta, source) {
      const html = $this.find('.ql-editor').html();
      this.next('input[type=hidden]').val(html);
    }.bind($this))
})
  <div class="form-group">
    <%= label f, :body, "本文", class: "control-label" %>
    <div class="richtext">
      <p><%= raw(Ecto.Changeset.get_field(@changeset, :body)) %></p>
    </div>
    <input type="hidden" name="board_topic[body]" value="<%= Ecto.Changeset.get_field(@changeset, :body) %>">
    <%= error_tag f, :body %>
  </div>

htmlを取る方法も特に無いようなので、 issueを探ってみたら.ql-editor内をそのまま使えばいいとの事だったのでそのようにした。

現在までの完成分はこちら。 とりあえずコメント投稿まで。カテゴリも設定、絞り込みできるようにした。 その他の処理はほぼエラー。 あとはタイムゾーンの設定をしていないので時刻がおかしい。

Copying live

サイボウズLiveを作る-第2回-グループ登録まで

アイコンは出来たので引き続きグループの作成機能。

本家だととりあえず一番簡単なパターンでは、グループ名だけ入力すれば登録できる。 とりあえずそこまでを作った。 アイコンも選択できるようにしている。

実装は非常にシンプルで、まずモデルに所属メンバー用のアソシエーションを設定。マイグレーションなどもマニュアル通り。

  many_to_many :users, Cybozulive.User, join_through: "groups_users"

登録処理もシンプル。

  def create(conn, %{"group" => group_params}) do
    user = Auth.get_user(conn)
    changeset = Ecto.build_assoc(user, :groups)
    |> Group.changeset(group_params)
    |> Ecto.Changeset.put_assoc(:users, [user])

    case Repo.insert(changeset) do
      {:ok, group} ->
        conn
        |> put_flash(:info, "グループを作成しました。")
        |> redirect(to: group_path(conn, :show, group))
      {:error, changeset} ->
        icons = IconRepo.get_select_icons(user.id)
        render(conn, "new.html", changeset: changeset, icons: icons, show_group: false)
    end
  end

とりあえずここまでを公開した。

Copying live

https://live.alphabrend.com

GCEのf1-micro、1台にDBまで全部詰め込み。 Let's EncryptでSSL対応。 体裁とか未完成の部分はぐちゃぐちゃ。

arc_ectoでDBにファイル名を直接保存したい時

GitHub - stavro/arc_ecto: An integration with Arc and Ecto.

を使うと、postされた画像を簡単に登録することができる。

ただ、そのためにはmodelの型も専用のものに変えなければいけないので、 string型でなくなってしまう関係で直接ファイル名を保存することが出来ない。

とりあえず下記のようにすると保存することが出来た。

  %Icon{id: current_id, icon: %{
    file_name: filename,
    updated_at: nil
  }}
  |> Repo.insert!

updated_atはパターンマッチの関係でエラーになるので入れている。

PhoenixのTaskでDBにアクセスする

PhoenixでTaskを試した。

実際にはPhoenixではなくmix自体のtaskを作成して実行するだけ。

ただ、単にtask内でRepoを使ってDBアクセスしようとすると下記のようなエラーが出る。

repo App.Repo is not started, please ensure it is part of your supervision tree

どうもRepoはちゃんとスタートさせなければならないらしい。

最終的に下記の様にRepoの初期化を入れることで動いた。

defmodule Mix.Tasks.Aiue.Oooo do
  use Mix.Task

  alias App.Repo
  alias App.User

  import Mix.Ecto

  @shortdoc "aiueo"

  @moduledoc """
    This is aiuoe
  """

  def run(args) do
    Mix.shell.info "=== Active user ==="

    ensure_repo(Repo, args)
    ensure_started(Repo, [])
    user = Repo.one!(User)

    changeset = User.changeset(user, %{email: "test@example.com"})
    Repo.update!(changeset)

    IO.inspect(user)
  end
end

サイボウズLiveを作る-第1回-アイコン登録まで

概要

サイボウズLiveが終了するとのこと。

無料グループウェア「サイボウズLive」サービス終了のお知らせ | サイボウズ株式会社

丁度他のアプリケーション作成が一区切りついたところだったので、今度はサイボウズLiveのコピーを作ってみようと思う。 ざっと見てみたらそんなにページ数も多くなさそうな気もするし。

一通り作ってはみようと思うが特に代替、移行先として呼びこむつもりはない。 そんなアクセスが来たら止まるだろうし。

仕様

  • Elixir1.5
  • Phoenix1.3
  • Bootstrap Material Design

JavaScriptはAngularかVueを使おうかと思ったが、面倒だったことを思い出すと嫌になったのでやめた。 ソロだし付属のbrunchでES6を使ってjQueryで綺麗に書けば十分。

PhoenixでVueも簡単に使えるようなので置き換え中。

とりあえず作ったところ

認証

とりあえずTwitterでログインできるようにした。

GitHub - ueberauth/ueberauth_twitter: Twitter Strategy for Überauth

ユーザー作成やログイン部分は自分で勝手にやりたかったので、 ログインURLの発行とcallbackのパラメータ構築だけ任せ、 取得したパラメータであれこれやっている。

defmodule Cybozulive.AuthController do
  use Cybozulive.Web, :controller

  alias Cybozulive.UserRepo

  plug Ueberauth

  def request(conn, _params) do
    Ueberauth.Strategy.Helpers.callback_url(conn)
  end

  def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
    conn
    |> put_flash(:error, "Failed to authenticate.")
    |> redirect(to: "/")
  end

  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
    user = UserRepo.find_or_create!(auth)
    conn
    |> Cybozulive.Auth.set_user(user)
    |> redirect(to: "/")
  end
end

アイコンの登録

とりあえず掲示板とか作りたいところだが、

  • 掲示板作るにはグループが要る
  • グループ作るにはアイコンが要る

ということで面倒だがとりあえずアイコンを登録できる機能を作った。

phoenix.gen.htmlとarc_ectoでちゃちゃっと作れた。 そのままだと画像は公開されないので、

Elixir / Phoenix — Uploading images locally (With ARC)

にあるとおり、Plug.Staticの設定で公開できる。

  plug Plug.Static,
    at: "/uploads", from: Path.expand("./uploads"), gzip: false

f:id:dala:20171101231504p:plain

(公開側はBootstrap Material Designだが、管理画面は面倒だし本当は作りたくなかったのでPhoenixデフォルトのBootstrap)

全部これで登録はやってられないのでスクリプトで一括登録で作成予定。

Phoenixで作った請求書作成システムをリリース

Elixir & Phonenixで作った請求書作成システムをリリースした。

元々Misocaを使っていたが、弥生の傘下に入ってからフリープランでは5通までしか作成できなくなってしまった。

別に良いかと思っていたが、ちっちゃい請求が続いたりするとどうも超えてしまうのではないかと怖くなることが多くなった。 そのため、ちょうどElixir & Phoenixで遊んでいたので自分で作ったら良いんじゃないかと思い作成してみたところうまくいった。

請求書作成サービス

Bill Builder

基本的には自分で使う用なので質素でシンプル。 別に使いたい人がいたら使ってもらっていいと思う。 まだステージングサーバーもなくDBバックアップもしてないけど、 自分で使っているのでそのうちする予定。

安定するかは不明だけど、自分で使わないといけないから使える程度にはメンテナンス&拡張する予定。

本番環境

  • Elixir 1.5
  • Phoenix 1.3
  • MySQL 5.7
  • Google Compute Engine f1-micro
  • Systemctlによるサービス実行
  • SendGrid
  • Let's Encrypt
  • bootstrap material design

開発環境

docker-composeに下記のようなサービスを入れている。

Elixir & Phoenixで開発してみた感想

非常に良い。とにかくphoenix.gen.htmlでモデル、コントローラ、テンプレートまでざっと作成してくれるのが良い。 それだけで参考になるしちょっといじれば動くのでとてもスムーズに色々進む。 テンプレートがデフォルトでbootstrapなのもいい。 phpだとCakePHP3も同様に最高だった。Laravelはコントローラのメソッドが空なのでやる気をなくす。

Elixir自体が今まで使っていた言語とちょっと違うので癖があり躓いたりしたが、 慣れたら本当に気持ちよく迅速に開発できそう。

デプロイ

色々Elixirのデプロイ方法もあるみたいだが、とりあえず今は手動。 頻繁なリリースもないし、今のところ誰も使ってないのでとめちゃいけないということもないし。

とはいえ、手動でもデプロイは非常に簡単。

  • gitでpull
  • compile
  • cssやjsいじってればそちらもビルド
  • マイグレーション追加してたらmigrate
  • 準備出来たらsystemctlでrestart

多分restartの瞬間くらいしかダウンタイムも無いと思うのでのんびりできる。 Elixir自体が自分でサービス稼働させているからこその利点。

運用費

とりあえずf1-microだし誰も使ってない限りは無料。 (1サーバーにElixirもMySQLも全部入っている) だれか使い始めたら適当に広告でも張るがあまり意味なさそう。

今後の拡張

毎月同じ金額の請求をメールで送るとかできたら良いな、と思ってたけど、 実は届いていなかった、とかがあると怖いので実装するかどうか検討中。 SendGrid使っているためログは見やすいので問題ないのかもしれない。

領収書は使わないけど、体裁ほとんど同じでいいなら作ろうかなとも思う。

まとめ

またなんかPhoenixで作りたい。

Bill Builder

wkhtmltopdfでpdf作成に失敗する時

wkhtmltopdfで何度試してもエラーが出ていた。

アクセス権限もあっているし、ファイルも存在するし中身もおかしくないし…。

色々試した結果、今回は拡張子に.htmlをつけたら変換できるようになった。 (一時ファイルのため拡張子がなかった)

その時々によって色々理由は異なるだろうがとりあえずひとつのパターン。