diff --git a/.gitignore b/.gitignore
index 67eaecb..a36f427 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,5 @@
*.toc
*.blg
*.bbl
+
+Gemfile.lock
diff --git a/Gemfile b/Gemfile
index 0f811e3..52edc1d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,3 +9,5 @@
gem "sinatra-activerecord"
gem "sqlite3"
gem "json"
+gem 'openssl'
+gem 'logger'
diff --git a/Gemfile.lock b/Gemfile.lock
index fef0522..7e779fb 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -25,9 +25,11 @@
i18n (1.6.0)
concurrent-ruby (~> 1.0)
json (2.2.0)
+ logger (1.4.1)
minitest (5.11.3)
multi_json (1.13.1)
mustermann (1.0.3)
+ openssl (2.1.2)
public_suffix (3.1.1)
rack (2.0.7)
rack-protection (2.0.5)
@@ -70,6 +72,8 @@
activerecord
activesupport
json
+ logger
+ openssl
sinatra
sinatra-activerecord
sinatra-contrib
diff --git a/README.md b/README.md
index cd7d045..4c70a60 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,184 @@
IntroQuiz2019
===============
+# 概要
+本システムは2019年度広瀬ゼミ夏合宿で使用したイントロクイズシステムです。1つの無線LANルータを用いてローカル環境で早押し式のイントロクイズをすることができます。研究のリサーチも含めたシステムであるため、可読性やセキュリティ面、その他プログラムに関する作り込みが甘い部分もありますので、ご了承ください。
+
+## 本システムの構成
+本システムは以下のようなファイル構造になっています。(隠しファイルを除く)
+```
+IntroQuiz2019/
+├── Gemfile
+├── Gemfile.lock
+├── README.md
+├── app.rb
+├── db
+│ ├── README.md
+│ ├── account.db
+│ └── schema.sql
+├── public
+│ ├── css
+│ │ ├── bootstrap-4.3.1 cssファイル(以下略)
+│ │ └── main.css
+│ ├── js
+│ │ ├── bootstrap-4.3.1 jsファイル(以下略)
+│ │ ├── client.js
+│ │ ├── controller.js
+│ │ ├── jquery-3.4.1.min.js
+│ │ ├── login.js
+│ │ ├── player.js
+│ │ └── viewer.js
+│ ├── jsSHA-2.3.1(以下略)
+│ ├── music
+│ │ ├── music_list.csv
+│ │ ├── 使用する音楽ファイル.mp3(以下略)
+│ │ └── README.md
+│ └── sound_effect
+│ ├── correct.mp3
+│ ├── hayaoshi.mp3
+│ ├── incorrect.mp3
+│ └── question.mp3
+└── views
+ ├── controller.erb
+ ├── error.erb
+ ├── index.erb
+ ├── login.erb
+ ├── select.erb
+ └── viewer.erb
+```
+
+## 開発環境
+開発環境は以下の通りです。
+* サーバーサイド : Ruby
+ - フレームワーク : sinatra
+* フロントエンド : JavaScript
+* データベース : SQLite3
+
+主にWebSocket通信を用いてリアルタイムに反映する早押しボタンを作成しています。
+
+## 準備するもの
+本システムを使用する上で以下のものを用意してください。なお、先頭に☆がついているものは必須で、その他は任意です。
+* 出題者
+ - ☆ サーバ用PC
+ - ☆ 無線LANルータ(インターネット環境不要)
+ - ☆ 出題用音楽ファイル(MP3形式)
+ - ディスプレイ用PC、または相当物(タブレット等)
+ - プロジェクタ、または相当物(テレビ等)
+ - スピーカー
+ - 景品・参加賞
+* 参加者
+ - ☆早押しボタン用スマートフォン、または相当物(タブレット、PC等)
+ - 手元確認用のディスプレイ用PC、または相当物(タブレット等)
+
+## 設定方法
+本システムの設定方法を以下に記述します。~~割と面倒なので覚悟してください。~~
+1. サーバ用PCの設定
+ * サーバ用PCを用意し、ターミナル上で以下のコマンドを実行して本システムをクローンします。
+ ```
+ % cd ~/
+ % git clone https://www.yatex.org/gitbucket/git/IntroQuiz2019/IntroQuiz2019.git
+ % cd ~/IntroQuiz2019
+ ```
+
+ * Rubyで使用するライブラリ(以下gem)をターミナル上で以下のコマンドを実行し、インストールします。この時、gemコマンドが使用できるかどうかを確認し、使用できない場合はインストールしてください。また、gemのインストール時にエラーが出ていないかも確認してください。
+ ```
+ % gem install bundler
+ % bundle install --path vendor/bundle
+ ```
+
+ * この時点で一旦起動確認のために以下のコマンドでサーバを立ち上げます。
+ ```
+ % bundle exec ruby app.rb
+ ```
+ 最後の行に`Listening on localhost:4567, CTRL+C to stop`と出てきたら、サーバが正常に立ち上がった証拠なので、 http://localhost:4567 にアクセスし、画面が表示されるか確認してください。
+
+
+2. 無線LANルータの設定
+ * 無線LANルータを準備します。インターネット環境はなくても大丈夫なので、無線LANルータをコンセントに刺すだけでいいです。
+
+ * (任意)サーバ用PCの固定IPアドレスを設定します。これは使用する無線LANルータによって設定方法が異なるため、設定方法をインターネット等で調べてください。
+
+
+3. controllerのログイン設定
+ * 出題者だけが出題ページにアクセスできるようにログインの設定を行います。controllerは隠しリンクになっていて、アクセスするにはClientのリンクをクリックした後、URLの末尾に `/controller` をつけてアクセスしてください。ログイン設定の詳細は https://www.yatex.org/gitbucket/IntroQuiz2019/IntroQuiz2019/blob/master/db/README.md に記述したので、そちらを参照してください。
+
+
+4. 出題曲の設定
+ * 出題曲の設定をします。3で設定したアカウントでログインに成功するとcontrollerページにアクセスすることができます。ですが、出題曲の設定をしていないため、曲リストが出るはずの場所に `body { text-align:center;font-family:helvetica` のようなものが表示されていると思います(たぶん)。
+ 出題曲の設定の詳細は https://www.yatex.org/gitbucket/IntroQuiz2019/IntroQuiz2019/blob/master/public/music/README.md に記述したので、そちらを参照してください。
+
+
+5. 本番環境の設定
+ * 上記の設定が全て完了し正常に動作することを確認したら、いよいよ本番環境を設定していきます。
+ まず、サーバ用PCを無線LANルータに接続します。この時インターネット環境は不要なので、無線LANルータにつながっていることのみを確認できればOKです。
+
+ * 無線LANルータに接続したら、以下のコマンドを実行し、IPアドレスをチェックします。なお、固定IPアドレスを設定した人はこの確認はなくても大丈夫です。
+ ```
+ % ifconfig
+ ...省略...
+ en0: flags=xxx mtu xxxx
+ options=xxxx
+ ether xx:xx:xx:xx:xx:xx
+ inet 192.168.xxx.xxx netmask 0xxxxxxxxx broadcast xxx.xxx.xxx.xxx
+ media: autoselect
+ status: active
+ ...省略...
+ ```
+ 何見たらいいかわからない人はとりあえず`en0`のところの`inet 192.168.xxx.xxx`のところを見ておけば大丈夫だと思います。
+
+ * IPアドレスを確認したら、システムを以下のコマンドで実行します。ここで、`-o`オプションをつけ、その後に確認したIPアドレスを入力します。また、`-p`オプションをつけることでポート番号を指定することもできます。(デフォルトは4567)
+ ```
+ % bundle exec ruby app.rb -o 192.168.xxx.xxx
+ ```
+ 最後の行に`Listening on 192.168.xxx.xxx:4567, CTRL+C to stop`(ポート番号を指定したなら4567のところが設定した番号)と出てきたら、サーバが正常に立ち上がった証拠なので、 http://192.168.xxx.xxx:4567 にアクセスし、画面が表示されるか確認してください。
+
+ * 画面を確認後、以下が正常に動作することを確認して設定完了です。
+ - チーム番号を選んで、送信を押すと、Pushボタンが出てくる。
+ - Pushボタンを押すと、ボタンが黄色になり、viewerページに選択したチーム番号が押した順番に表示される。
+ - `/controller`にアクセスし、ログインすることができる。
+ - 曲リストが表示されており、再生、停止、曲を最初まで巻き戻す、答えが流れる秒数にセットすることができる。
+ - 問題、正解、不正解の効果音を流すことができる。
+
+
+## 使用方法
+設定が完了したら、参加者に以下の設定をしてもらいます。
+1. 無線LANルータへの接続
+ - 設定した無線LANへ接続してもらいます。この無線LANルータにつないでいないとアクセスできません。
+
+
+2. イントロクイズシステムへのアクセス
+ - 立ち上げたサーバで設定したIPアドレスを使用し、Webブラウザからアクセスしてもらいます。アクセスするURLは http://192.168.xxx.xxx:4567 (ポート番号を指定したなら4567のところが設定した番号)です。
+
+
+3. チーム番号の選択
+ - ブラウザでアクセスしたら、チーム番号を選択してもらい、ボタンが押せるか確認してください。
+
+
+4. (任意)viewerの設定
+ - 前の画面が見えにくいなどの理由で手元に早押しした順番を準備したい場合は別端末にて1と2を行い、リンクからviewerにアクセスしてもらいます。
+
+
+5. Let's enjoy!!
+ - イントロクイズを楽しみましょう!
+
+
+## 注意事項
+* 基本的には問題ないと思いますが、思わぬ場所でエラーが起こる場合もありますので、その場合は最下部にある連絡先までご連絡ください。そしてそのエラーはなんとかしてください。
+
+* このシステムはかなり準備に労力が必要になるかと思いますので、事前に念入りに準備しておくことをお勧めします。
+
+
+## 免責事項
+* 本システムは自由にダウンロード・使用・改変をしても構いません。また、本システムを参考にし、別プログラムを作成しても構いません。ただし、本システムをほぼほぼ丸ごとコピーし、あたかも自分が作ったようにして公開することを一切禁じます。一生懸命作ったプログラムなので、そんなことをされると気分が悪くなるのでやめてください。
+
+* 本システムを使用・改変した際に発生したいかなる事象にも一切責任を負いませんのでご了承ください。というか、なるべく自分でなんとかしてください。
+
+* 本システムを使用する際には一言でもいいので、作者の名前を出してくれると大変嬉しいです。とっても気分が良くなりますし、今後の励みになります。
+
+* その他、不明な点、改善案などありましたら、作者の宛先までご連絡ください。
+
+```
+東北公益文科大学 16期生
+C116092A 佐藤文哉(☆フミちゃん☆)
+Email: c116092@h.koeki-u.ac.jp
+s4: ☆フミちゃん☆(https://www.yatex.org/s4/index.cgi?home+150)
+```
diff --git a/app.rb b/app.rb
index 314ca42..30d6024 100644
--- a/app.rb
+++ b/app.rb
@@ -1,14 +1,7 @@
require 'bundler/setup'
Bundler.require
require 'sinatra/reloader' if development?
-require 'sinatra-websocket'
-require 'active_support'
require 'active_support/core_ext'
-require 'sqlite3'
-require 'active_record'
-require 'json'
-require 'openssl'
-require 'logger'
enable :sessions
@@ -16,23 +9,29 @@
set :flags => (1..6).to_a.map{|i| [i, 0]}.to_h #どのチームが押したか管理するためのハッシュ
end
+#WebSocketを使うときの設定
set :server, 'thin'
set :sockets, []
+#logを端末上に標準エラー出力する
logger = Logger.new(STDOUT)
+#管理者用のデータベースの設定
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: './db/accounts.db'
)
+#データベースへの永続接続回避
after do
ActiveRecord::Base.connection.close
end
+#ActiveRecordのusersテーブルを扱う
class User < ActiveRecord::Base
end
+#参加者の早押しボタンページ
get '/' do
if session[:team].blank? #チームがsetされていないときに選択画面に遷移する
erb :select
@@ -50,6 +49,7 @@
end
end
+#WebSocket通信の処理
get '/websocket' do
if request.websocket? #WebSocket通信かどうかを確認
request.websocket do |ws|
@@ -84,7 +84,8 @@
end
end
-post '/setteam' do #チーム決定ボタンを押した時の処理
+#チーム決定ボタンを押した時の処理
+post '/setteam' do
t_num=params[:t_num].to_i
if t_num>=1 && t_num<=6
session[:team]=t_num
@@ -95,11 +96,13 @@
end
end
-get '/resetteam' do #チーム再選択ボタンを押した時の処理
+#チーム再選択ボタンを押した時の処理
+get '/resetteam' do
session.clear #チーム番号を保持しているセッションを消す
redirect "/"
end
+#プロジェクターや手元に解答順番を映す用の画面
get '/viewer' do
pushed=Array.new
settings.flags.sort_by{|key,value| value}.each do |key, value|
@@ -113,7 +116,10 @@
erb :viewer
end
-get '/controller' do #出題者が操作するページ
+
+#出題者が操作するページ
+get '/controller' do
+ #admin
if session[:admin].blank?
erb :login
elsif session[:admin]==8804912
@@ -130,6 +136,8 @@
end
end
+
+#出題者のログイン認証
post '/check' do
if params[:user_id]
user_id = params[:user_id]
diff --git a/db/README.md b/db/README.md
index aa37cbb..3a32b8f 100644
--- a/db/README.md
+++ b/db/README.md
@@ -1,7 +1,32 @@
-### ここにaccount.dbを入れる
-* dbファイルをgitに載せないために.gitignoreをこのディレクトリの直下に作る
-* dbディレクトリに移動し、ターミナル上で以下のコマンドを実行する
+### controllerのログイン設定
+
+このディレクトリ(`~/IntroQuiz2019/db/`)でcontrollerのログイン設定を行います。
+
+* dbディレクトリに移動して、ターミナル上で以下のコマンドを実行します。
```
-% sqlite3 account.db
+% sqlite3 accounts.db
sqlite> .read schema.sql
```
+
+* 現在、データベースにユーザを登録する機能が備わっていないため、アカウント情報を登録するには手動で登録する方法しかありません。
+手動でデータベースに登録する方法は以下の通りです。
+ - 以下のアカウント情報を作成します。なおpassword_digestはhogehogeをハッシュ化したものを使います。
+|id|user_id|password_digest|salt|created_at|updated_at|
+| :---: | :---: | :---: | :---: | :---: | :---: |
+|1|hogehoge|6675d764245522c5c3156406cf504de1eace95a28cc2ad5df6c79338d0193d7a|hogehoge|2019-xx-xx|2019-xx-xx|
+ - 以下のコマンドをターミナル上で実行します。なお、ターミナル上で sqlite> となっている場合は1行目の操作を飛ばします。
+ わからない人は大体コピペでも可です。
+ ```
+ % sqlite3 accounts.db
+ sqlite> INSERT INTO users VALUES (1, "hogehoge", "6675d764245522c5c3156406cf504de1eace95a28cc2ad5df6c79338d0193d7a", "hogehoge", "2019-xx-xx", "2019-xx-xx");
+ ```
+ ```
+ #以下INSERT文コピペ用テキスト(この下を3回クリックすると全選択)
+ INSERT INTO users VALUES (1, "hogehoge", "6675d764245522c5c3156406cf504de1eace95a28cc2ad5df6c79338d0193d7a", "hogehoge", "2019-01-01", "2019-01-01");
+ ```
+
+* 全て完了したら、イントロクイズシステムを起動し、`/controller`ページにログインできるかを確認します。なお、上記の設定を行うと以下のログイン名・パスワードでログインできる。
+```
+ログイン名: hogehoge
+パスワード: hogehoge
+```
diff --git a/public/music/README.md b/public/music/README.md
index cf1a7b4..25eccb1 100644
--- a/public/music/README.md
+++ b/public/music/README.md
@@ -1,3 +1,21 @@
-* ここに音楽ファイルを入れる
-* 音楽ファイルをgitに載せないために.gitignoreをこのディレクトリの直下に作る
+### 出題曲の設定
+このディレクトリ(`~/IntroQuiz2019/public/music/`)で出題曲の設定を行います。
+* まず最初に本ディレクトリ下に音楽ファイルをコピーします。音楽ファイルはMP3形式を使用してください。
+* その後、本ディレクトリ下にmusic_list.csvを作成します。
+CSVは以下の形式で記述してください。CSVは ,(カンマ) 区切りのデータにしてください。(Officeソフトで作った方が確実)
+
+なお、1行めのヘッダー行はCSVには含めません。
+また、答え合わせ用のサビ開始秒数は分を全て秒に直して記述してください。
+| 表示する曲名 | 音楽ファイル名.mp3 | 答え合わせ用サビの開始秒数 |
+| :---: | :---: | :---: |
+| 曲名1 | 曲名1.mp3 | 45 |
+| 曲名2 | 曲名2.mp3 | 86 |
+| ... | ... | ... |
+
+* 全て完了したら、イントロクイズシステムを起動して、`/controller`ページで以下の項目を確認してください。
+ - 曲のリストが正常に表示されているか。
+ - 曲名をクリックすると曲の時間がセットされているか。
+ - セットした曲が再生されるか。(何回か実行するとブラウザがサウンド再生をブロックする可能性があるため、ブロックを解除するなど確認)
+ - Answerボタンを押した時に再生開始秒数がCSVでセットしたサビの秒数になっているか。
+ - Answerを再生する時に想定どうりの部分が再生されるかどうか。(他の音楽ソフトの秒数をセットすると想定外の部分から流れる可能性があるため要注意)