Commit 2359ad14 by tadyjp

Merge pull request #9 from tadyjp/wip/feat/0107_comments

[WIP] コメント機能
parents e9de798b 00834c01
#!/bin/sh #!/bin/sh
# SET YOUR ENV HERE.
export GOOGLE_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com" export GOOGLE_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com"
export GOOGLE_SECRET="xxxxxxxxxxxxxxxxxxxxxxxx" export GOOGLE_SECRET="xxxxxxxxxxxxxxxxxxxxxxxx"
export DB_TEST_USER="user"
export DB_TEST_PASS="pass"
export DB_DEVELOPMENT_USER="user"
export DB_DEVELOPMENT_PASS="pass"
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
/log/*.log /log/*.log
/tmp /tmp
/bin/set-env.sh .env
/coverage/.* /coverage/.*
*.bk *.bk
/db/*.sql
...@@ -19,3 +19,6 @@ IfUnlessModifier: ...@@ -19,3 +19,6 @@ IfUnlessModifier:
CyclomaticComplexity: CyclomaticComplexity:
Max: 10 Max: 10
RaiseArgs:
Enabled: false
language: ruby language: ruby
services:
- mysql
rvm: rvm:
- 2.0.0 - 2.0.0
before_script:
- mysql -e 'CREATE DATABASE rendezvous_test;'
env:
- DB_TEST_DATABASE=rendezvous_test DB_TEST_USER=travis
...@@ -14,6 +14,8 @@ gem 'uglifier' ...@@ -14,6 +14,8 @@ gem 'uglifier'
# Use CoffeeScript for .js.coffee assets and views # Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails' gem 'coffee-rails'
gem 'jquery-rails'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes # See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby # gem 'therubyracer', platforms: :ruby
...@@ -26,6 +28,8 @@ gem 'coffee-rails' ...@@ -26,6 +28,8 @@ gem 'coffee-rails'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder' gem 'jbuilder'
gem 'i18n_generators'
group :doc do group :doc do
# bundle exec rake doc:rails generates the API under doc/api. # bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false gem 'sdoc', require: false
...@@ -45,6 +49,9 @@ end ...@@ -45,6 +49,9 @@ end
# gem 'bootstrap-sass-rails' # gem 'bootstrap-sass-rails'
gem 'mysql2'
gem 'sqlite3'
gem 'devise' gem 'devise'
gem 'omniauth-google-oauth2' gem 'omniauth-google-oauth2'
...@@ -57,8 +64,6 @@ gem 'coderay' ...@@ -57,8 +64,6 @@ gem 'coderay'
group :development do group :development do
# Use sqlite3 as the database for Active Record # Use sqlite3 as the database for Active Record
gem 'sqlite3'
gem 'better_errors' gem 'better_errors'
gem 'binding_of_caller' gem 'binding_of_caller'
...@@ -74,24 +79,24 @@ group :development do ...@@ -74,24 +79,24 @@ group :development do
# rubocop # rubocop
gem 'rubocop' gem 'rubocop'
gem 'guard-rubocop' gem 'guard-rubocop'
gem 'guard-spring'
gem 'spring'
end end
group :development, :test do group :development, :test do
gem 'rspec-rails' gem 'rspec-rails'
gem 'guard-rspec'
gem 'guard-spring'
gem 'factory_girl_rails'
gem 'spring'
end
# group :test do # gem 'database_cleaner'
# gem 'email_spec' gem 'database_rewinder'
# end end
# group :production do group :test do
# gem 'rails_12factor' gem 'factory_girl_rails'
# gem 'pg' gem 'capybara'
# end gem 'launchy'
gem 'poltergeist'
gem 'coveralls', :require => false
end
# tree structure # tree structure
gem 'ancestry' gem 'ancestry'
...@@ -107,6 +112,5 @@ gem 'premailer' ...@@ -107,6 +112,5 @@ gem 'premailer'
gem 'faraday' gem 'faraday'
group :test do # Check mail format
gem 'coveralls', :require => false gem 'validates_email_format_of'
end
...@@ -9,7 +9,7 @@ GIT ...@@ -9,7 +9,7 @@ GIT
GIT GIT
remote: git://github.com/vmg/redcarpet.git remote: git://github.com/vmg/redcarpet.git
revision: 52c5fa3c5753d2125e827f235cdf4cb730484902 revision: 0c4cd0e7ea5f7f44e2953f3013fdf751af91162d
branch: master branch: master
specs: specs:
redcarpet (3.0.0) redcarpet (3.0.0)
...@@ -54,8 +54,15 @@ GEM ...@@ -54,8 +54,15 @@ GEM
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
builder (3.1.4) builder (3.1.4)
capybara (2.2.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
celluloid (0.15.2) celluloid (0.15.2)
timers (~> 1.1.0) timers (~> 1.1.0)
cliver (0.3.2)
coderay (1.1.0) coderay (1.1.0)
coffee-rails (4.0.1) coffee-rails (4.0.1)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
...@@ -73,6 +80,7 @@ GEM ...@@ -73,6 +80,7 @@ GEM
css_parser (1.3.5) css_parser (1.3.5)
addressable addressable
daemons (1.1.9) daemons (1.1.9)
database_rewinder (0.0.2)
debug_inspector (0.0.2) debug_inspector (0.0.2)
devise (3.2.2) devise (3.2.2)
bcrypt-ruby (~> 3.0) bcrypt-ruby (~> 3.0)
...@@ -81,7 +89,9 @@ GEM ...@@ -81,7 +89,9 @@ GEM
thread_safe (~> 0.1) thread_safe (~> 0.1)
warden (~> 1.2.3) warden (~> 1.2.3)
diff-lcs (1.2.5) diff-lcs (1.2.5)
docile (1.1.1) docile (1.1.2)
domain_name (0.5.15)
unf (>= 0.0.5, < 1.0.0)
erubis (2.7.0) erubis (2.7.0)
eventmachine (1.0.3) eventmachine (1.0.3)
execjs (2.0.2) execjs (2.0.2)
...@@ -90,8 +100,8 @@ GEM ...@@ -90,8 +100,8 @@ GEM
factory_girl_rails (4.3.0) factory_girl_rails (4.3.0)
factory_girl (~> 4.3.0) factory_girl (~> 4.3.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faraday (0.8.8) faraday (0.9.0)
multipart-post (~> 1.2.0) multipart-post (>= 1.2, < 3)
ffi (1.9.3) ffi (1.9.3)
formatador (0.2.4) formatador (0.2.4)
gmail_xoauth (0.4.1) gmail_xoauth (0.4.1)
...@@ -102,10 +112,7 @@ GEM ...@@ -102,10 +112,7 @@ GEM
lumberjack (~> 1.0) lumberjack (~> 1.0)
pry (>= 0.9.12) pry (>= 0.9.12)
thor (>= 0.18.1) thor (>= 0.18.1)
guard-rspec (4.2.0) guard-rubocop (1.0.1)
guard (>= 2.1.1)
rspec (>= 2.14, < 4.0)
guard-rubocop (1.0.0)
guard (~> 2.0) guard (~> 2.0)
rubocop (~> 0.10) rubocop (~> 0.10)
guard-spring (0.0.4) guard-spring (0.0.4)
...@@ -114,14 +121,24 @@ GEM ...@@ -114,14 +121,24 @@ GEM
hashie (2.0.5) hashie (2.0.5)
hike (1.2.3) hike (1.2.3)
htmlentities (4.3.1) htmlentities (4.3.1)
http-cookie (1.0.2)
domain_name (~> 0.5)
httpauth (0.2.0) httpauth (0.2.0)
i18n (0.6.9) i18n (0.6.9)
jbuilder (2.0.1) i18n_generators (1.2.1)
mechanize
rails (>= 3.0.0)
jbuilder (2.0.2)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
multi_json (>= 1.2.0) multi_json (>= 1.2.0)
jquery-rails (3.0.4)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1) json (1.8.1)
jwt (0.1.8) jwt (0.1.10)
multi_json (>= 1.5) multi_json (>= 1.5)
launchy (2.4.2)
addressable (~> 2.3)
listen (2.4.0) listen (2.4.0)
celluloid (>= 0.15.2) celluloid (>= 0.15.2)
rb-fsevent (>= 0.9.3) rb-fsevent (>= 0.9.3)
...@@ -130,14 +147,27 @@ GEM ...@@ -130,14 +147,27 @@ GEM
mail (2.5.4) mail (2.5.4)
mime-types (~> 1.16) mime-types (~> 1.16)
treetop (~> 1.4.8) treetop (~> 1.4.8)
mechanize (2.7.2)
domain_name (~> 0.5, >= 0.5.1)
http-cookie (~> 1.0.0)
mime-types (~> 1.17, >= 1.17.2)
net-http-digest_auth (~> 1.1, >= 1.1.1)
net-http-persistent (~> 2.5, >= 2.5.2)
nokogiri (~> 1.4)
ntlm-http (~> 0.1, >= 0.1.1)
webrobots (>= 0.0.9, < 0.2)
method_source (0.8.2) method_source (0.8.2)
mime-types (1.25.1) mime-types (1.25.1)
mini_portile (0.5.2) mini_portile (0.5.2)
minitest (4.7.5) minitest (4.7.5)
multi_json (1.8.2) multi_json (1.8.4)
multipart-post (1.2.0) multipart-post (2.0.0)
mysql2 (0.3.14)
net-http-digest_auth (1.4)
net-http-persistent (2.9)
nokogiri (1.6.1) nokogiri (1.6.1)
mini_portile (~> 0.5.0) mini_portile (~> 0.5.0)
ntlm-http (0.1.1)
oauth (0.4.7) oauth (0.4.7)
oauth2 (0.8.1) oauth2 (0.8.1)
faraday (~> 0.8) faraday (~> 0.8)
...@@ -145,23 +175,28 @@ GEM ...@@ -145,23 +175,28 @@ GEM
jwt (~> 0.1.4) jwt (~> 0.1.4)
multi_json (~> 1.0) multi_json (~> 1.0)
rack (~> 1.2) rack (~> 1.2)
omniauth (1.1.4) omniauth (1.2.1)
hashie (>= 1.2, < 3) hashie (>= 1.2, < 3)
rack rack (~> 1.0)
omniauth-google-oauth2 (0.2.1) omniauth-google-oauth2 (0.2.2)
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-oauth2 omniauth-oauth2
omniauth-oauth2 (1.1.1) omniauth-oauth2 (1.1.1)
oauth2 (~> 0.8.0) oauth2 (~> 0.8.0)
omniauth (~> 1.0) omniauth (~> 1.0)
orm_adapter (0.5.0) orm_adapter (0.5.0)
parser (2.0.0) parser (2.1.4)
ast (~> 1.1) ast (~> 1.1)
slop (~> 3.4, >= 3.4.5) slop (~> 3.4, >= 3.4.5)
poltergeist (1.5.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
polyglot (0.3.3) polyglot (0.3.3)
powerpack (0.0.9) powerpack (0.0.9)
premailer (1.7.9) premailer (1.8.0)
css_parser (>= 1.1.9) css_parser (>= 1.3.5)
htmlentities (>= 4.0.0) htmlentities (>= 4.0.0)
pry (0.9.12.4) pry (0.9.12.4)
coderay (~> 1.0) coderay (~> 1.0)
...@@ -170,7 +205,7 @@ GEM ...@@ -170,7 +205,7 @@ GEM
pry-rails (0.3.2) pry-rails (0.3.2)
pry (>= 0.9.10) pry (>= 0.9.10)
rack (1.5.2) rack (1.5.2)
rack-mini-profiler (0.1.31) rack-mini-profiler (0.9.0)
rack (>= 1.1.3) rack (>= 1.1.3)
rack-test (0.6.2) rack-test (0.6.2)
rack (>= 1.0) rack (>= 1.0)
...@@ -187,32 +222,29 @@ GEM ...@@ -187,32 +222,29 @@ GEM
activesupport (= 4.0.2) activesupport (= 4.0.2)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (1.1.4) rainbow (1.99.1)
rake (10.1.1) rake (10.1.1)
rb-fsevent (0.9.3) rb-fsevent (0.9.4)
rb-inotify (0.9.3) rb-inotify (0.9.3)
ffi (>= 0.5.0) ffi (>= 0.5.0)
rdoc (3.12.2) rdoc (4.1.1)
json (~> 1.4) json (~> 1.4)
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.7) rspec-core (2.14.7)
rspec-expectations (2.14.4) rspec-expectations (2.14.4)
diff-lcs (>= 1.1.3, < 2.0) diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.4) rspec-mocks (2.14.4)
rspec-rails (2.14.0) rspec-rails (2.14.1)
actionpack (>= 3.0) actionpack (>= 3.0)
activemodel (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
railties (>= 3.0) railties (>= 3.0)
rspec-core (~> 2.14.0) rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0) rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0) rspec-mocks (~> 2.14.0)
rubocop (0.15.0) rubocop (0.16.0)
parser (~> 2.0) parser (~> 2.1)
powerpack (~> 0.0.6) powerpack (~> 0.0.6)
rainbow (>= 1.1.4) rainbow (>= 1.1.4)
sass (3.2.13) sass (3.2.13)
...@@ -220,9 +252,9 @@ GEM ...@@ -220,9 +252,9 @@ GEM
railties (>= 4.0.0, < 5.0) railties (>= 4.0.0, < 5.0)
sass (>= 3.1.10) sass (>= 3.1.10)
sprockets-rails (~> 2.0.0) sprockets-rails (~> 2.0.0)
sdoc (0.3.20) sdoc (0.4.0)
json (>= 1.1.3) json (~> 1.8)
rdoc (~> 3.10) rdoc (~> 4.0, < 5.0)
simplecov (0.8.2) simplecov (0.8.2)
docile (~> 1.1.0) docile (~> 1.1.0)
multi_json multi_json
...@@ -259,8 +291,16 @@ GEM ...@@ -259,8 +291,16 @@ GEM
uglifier (2.4.0) uglifier (2.4.0)
execjs (>= 0.3.0) execjs (>= 0.3.0)
json (>= 1.8.0) json (>= 1.8.0)
unf (0.1.3)
unf_ext
unf_ext (0.0.6)
validates_email_format_of (1.5.3)
warden (1.2.3) warden (1.2.3)
rack (>= 1.0) rack (>= 1.0)
webrobots (0.1.1)
websocket-driver (0.3.2)
xpath (2.0.0)
nokogiri (~> 1.3)
PLATFORMS PLATFORMS
ruby ruby
...@@ -270,19 +310,25 @@ DEPENDENCIES ...@@ -270,19 +310,25 @@ DEPENDENCIES
ancestry ancestry
better_errors better_errors
binding_of_caller binding_of_caller
capybara
coderay coderay
coffee-rails coffee-rails
coveralls coveralls
database_rewinder
devise devise
factory_girl_rails factory_girl_rails
faraday faraday
guard-rspec
guard-rubocop guard-rubocop
guard-spring guard-spring
i18n_generators
jbuilder jbuilder
jquery-rails
launchy
mail mail
mysql2
nokogiri nokogiri
omniauth-google-oauth2 omniauth-google-oauth2
poltergeist
premailer premailer
pry-rails pry-rails
rack-mini-profiler rack-mini-profiler
...@@ -296,3 +342,4 @@ DEPENDENCIES ...@@ -296,3 +342,4 @@ DEPENDENCIES
sqlite3 sqlite3
thin thin
uglifier uglifier
validates_email_format_of
guard :rspec, all_after_pass: true, spring: true do # guard :rspec, all_after_pass: true do
watch(%r{^spec/.+_spec\.rb$}) # watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } # watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { 'spec' } # watch('spec/spec_helper.rb') { 'spec' }
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } # watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } # watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^spec/factories/(.+)\.rb$}) { 'spec/factories_spec.rb' } # watch(%r{^app/(.*)(\.erb|\.haml)$}) { 'spec/features' }
watch(%r{^spec/support/(.+)\.rb$}) { 'spec' } # watch(%r{^spec/factories/(.+)\.rb$}) { 'spec/factories_spec.rb' }
watch('config/routes.rb') { 'spec/routing' } # watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
watch('app/controllers/application_controller.rb') { 'spec/controllers' } # watch('config/routes.rb') { 'spec/routing' }
end # watch('app/controllers/application_controller.rb') { 'spec/controllers' }
# end
# guard :rubocop, all_after_pass: true, cli: ['--rails', '--auto-correct'] do
# watch(%r{.+\.rb$})
# watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
# end
guard :rubocop, all_after_pass: true, cli: ['--rails', '--auto-correct'] do guard :rubocop do
watch(%r{.+\.rb$}) watch(%r{.+\.rb$})
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) } watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
end end
guard :rspec do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^spec/spec_helper\.rb$}) { |m| 'spec' }
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) do |m|
%W(spec/routing/#{m[1]}_routing_spec.rb spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb spec/requests/#{m[1]}_spec.rb)
end
end
rendezvous rendezvous
========== ==========
A simple markdown-based wiki system for term.
## Badge ## Badge
[![Build Status](https://travis-ci.org/tadyjp/rendezvous.png)](https://travis-ci.org/tadyjp/rendezvous) [![Build Status](https://travis-ci.org/tadyjp/rendezvous.png)](https://travis-ci.org/tadyjp/rendezvous)
[![Coverage Status](https://coveralls.io/repos/tadyjp/rendezvous/badge.png)](https://coveralls.io/r/tadyjp/rendezvous) [![Coverage Status](https://coveralls.io/repos/tadyjp/rendezvous/badge.png)](https://coveralls.io/r/tadyjp/rendezvous)
[![Code Climate](https://codeclimate.com/github/tadyjp/rendezvous.png)](https://codeclimate.com/github/tadyjp/rendezvous) [![Code Climate](https://codeclimate.com/github/tadyjp/rendezvous.png)](https://codeclimate.com/github/tadyjp/rendezvous)
[![Dependency Status](https://gemnasium.com/tadyjp/rendezvous.png)](https://gemnasium.com/tadyjp/rendezvous) [![Dependency Status](https://gemnasium.com/tadyjp/rendezvous.png)](https://gemnasium.com/tadyjp/rendezvous)
## ENVの設定 # How to install and use.
Get code and install gems.
```
$ git clone git@github.com:tadyjp/rendezvous.git
$ cd rendezvous
$ bundle install
```
Create YOUR .ENV file.
``` ```
. ./bin/set-env.sh $ cp .env.example .env
$ vim .env
``` ```
Setup DB (Default: mysql).
```
$ bundle exec rake db:migrate
$ bundle exec rake db:seed
```
Set ENV before start server.
```
$ source .env
$ bundle exec rails s
```
And have fun with your team !
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// //
//= require_self //= require_self
// require jquery // require jquery
// require jquery_ujs //= require jquery_ujs
// require turbolinks // require turbolinks
//= require_tree ./lib //= require_tree ./lib
//= require_tree . //= require_tree .
......
...@@ -11,22 +11,32 @@ if window.location.pathname.match /^\/posts\/?$/ ...@@ -11,22 +11,32 @@ if window.location.pathname.match /^\/posts\/?$/
$this.addClass('active') $this.addClass('active')
id = $this.data('postId') id = $this.data('postId')
$.get('/posts/show_fragment', { id: id }) $.get("/posts/#{id}", {
fragment: 1
})
.done (data) -> .done (data) ->
$('#list_post').html(data) $('#list_post').html(data)
prettyPrint() prettyPrint()
# 初期に詳細を表示 # 初期に詳細を表示
# open post when `id` parameter set. # open post when `id` parameter set.
id_param = RV.tools.getQueryParams()["id"] id_param = RV.tools.getQueryParams()["id"]
if id_param? if id_param?
$(".post-list[data-post-id='#{id_param}']").addClass('active') $("a.post-list[data-post-id='#{id_param}']").addClass('active')
$.get('/posts/show_fragment', { $.get("/posts/#{id_param}", {
'id': id_param, fragment: 1
})
.done (data) ->
$('#list_post').html(data)
prettyPrint()
else
$el = $("a.post-list:eq(0)")
$el.addClass('active')
$.get("/posts/#{$el.data('postId')}", {
fragment: 1
}) })
.done (data) -> .done (data) ->
$('#list_post').html(data) $('#list_post').html(data)
prettyPrint() prettyPrint()
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
.app { .app {
padding-top: 70px;
.navbar-default .navbar-brand { .navbar-default .navbar-brand {
background-color: #428bca; background-color: #428bca;
color: #fff; color: #fff;
...@@ -51,9 +49,15 @@ ...@@ -51,9 +49,15 @@
width: 200px; width: 200px;
} }
/* side tree view
-------------------------------------------------- */
/* ul {
padding-left: 1em;
}
*/
/* home#show /* home#show
-------------------------------------------------- */ -------------------------------------------------- */
.text-box { /* .text-box {
padding: 9px 14px; padding: 9px 14px;
border: 1px solid #e1e1e8; border: 1px solid #e1e1e8;
border-radius: 4px; border-radius: 4px;
...@@ -81,7 +85,7 @@ ...@@ -81,7 +85,7 @@
border-top-left-radius: 0px; border-top-left-radius: 0px;
border-top-right-radius: 0px; border-top-right-radius: 0px;
} }
*/
/* posts#new /* posts#new
-------------------------------------------------- */ -------------------------------------------------- */
......
body[class^="posts-"] {
padding-top: 70px;
}
...@@ -9,4 +9,8 @@ class ApplicationController < ActionController::Base ...@@ -9,4 +9,8 @@ class ApplicationController < ActionController::Base
redirect_to root_path redirect_to root_path
end end
end end
rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
render text: "Required parameter missing: #{parameter_missing_exception.param}", status: :bad_request
end
end end
...@@ -5,12 +5,17 @@ require 'premailer' ...@@ -5,12 +5,17 @@ require 'premailer'
module RV::Mailer module RV::Mailer
include ApplicationHelper include ApplicationHelper
def compose_mail(post, user) def compose_mail(post, opts = {})
fail ArgumentError.new('post missing') unless post.present?
fail ArgumentError.new('user missing') unless opts[:user].present? && opts[:user].is_a?(User)
fail ArgumentError.new('to missing') unless opts[:to].present?
fail ArgumentError.new('to mail format invalid') unless ValidatesEmailFormatOf.validate_email_format(opts[:to]).nil?
html_body = generate_html_mail(post.body) html_body = generate_html_mail(post.body)
mail = Mail.new do mail = Mail.new do
from user.email from opts[:user].email
to user.email to opts[:to]
subject post.title subject post.title
body post.body body post.body
...@@ -22,8 +27,8 @@ module RV::Mailer ...@@ -22,8 +27,8 @@ module RV::Mailer
# set ActionGmailer # set ActionGmailer
config = { config = {
oauth2_token: user.google_auth_token, oauth2_token: opts[:user].google_auth_token,
account: user.email account: opts[:user].email
}.merge(Rendezvous::Application.config.action_mailer.smtp_settings) }.merge(Rendezvous::Application.config.action_mailer.smtp_settings)
mail.delivery_method(ActionGmailer::DeliveryMethod, config) mail.delivery_method(ActionGmailer::DeliveryMethod, config)
......
...@@ -21,14 +21,14 @@ class PostsController < ApplicationController ...@@ -21,14 +21,14 @@ class PostsController < ApplicationController
render text: h_application_format_markdown(params[:text]) render text: h_application_format_markdown(params[:text])
end end
def show_fragment
@post = Post.find(params[:id])
render layout: false, partial: 'posts/show_fragment'
end
# GET /posts/1 # GET /posts/1
# GET /posts/1.json # GET /posts/1.json
def show def show
if params[:fragment].present?
render layout: false, partial: 'posts/show_fragment'
else
render
end
end end
# GET /posts/new # GET /posts/new
...@@ -47,10 +47,12 @@ class PostsController < ApplicationController ...@@ -47,10 +47,12 @@ class PostsController < ApplicationController
# refresh google oauth token if expired # refresh google oauth token if expired
current_user.google_oauth_token_refresh! if current_user.google_oauth_token_expired? current_user.google_oauth_token_refresh! if current_user.google_oauth_token_expired?
compose_mail(@post, current_user).deliver compose_mail(@post, user: current_user, to: mail_params[:to]).deliver
redirect_to root_path(id: @post.id) redirect_to root_path(id: @post.id), flash: { success: 'Mail has sent!' }
rescue ActionGmailer::DeliveryError rescue ActionGmailer::DeliveryError
redirect_to root_path(id: @post.id), flash: { notice: 'Gmail authentication expired.' } redirect_to root_path(id: @post.id), flash: { notice: 'Gmail authentication expired.' }
rescue ArgumentError => err
redirect_to root_path(id: @post.id), flash: { alert: 'Mail format is invalid: ' + err.to_s }
end end
# GET /posts/1/edit # GET /posts/1/edit
...@@ -65,7 +67,7 @@ class PostsController < ApplicationController ...@@ -65,7 +67,7 @@ class PostsController < ApplicationController
respond_to do |format| respond_to do |format|
if @post.save if @post.save
format.html { redirect_to root_path(id: @post.id), notice: 'Post was successfully created.' } format.html { redirect_to root_path(id: @post.id), flash: { notice: 'Post was successfully created.' } }
format.json { render action: 'show', status: :created, location: @post } format.json { render action: 'show', status: :created, location: @post }
else else
format.html { render action: 'new' } format.html { render action: 'new' }
...@@ -81,7 +83,7 @@ class PostsController < ApplicationController ...@@ -81,7 +83,7 @@ class PostsController < ApplicationController
respond_to do |format| respond_to do |format|
if @post.update(post_params) if @post.update(post_params)
format.html { redirect_to root_path(id: @post.id), notice: 'Post was successfully updated.' } format.html { redirect_to root_path(id: @post.id), flash: { notice: 'Post was successfully updated.' } }
format.json { head :no_content } format.json { head :no_content }
else else
format.html { render action: 'edit' } format.html { render action: 'edit' }
...@@ -95,11 +97,26 @@ class PostsController < ApplicationController ...@@ -95,11 +97,26 @@ class PostsController < ApplicationController
def destroy def destroy
@post.destroy @post.destroy
respond_to do |format| respond_to do |format|
format.html { redirect_to posts_url } format.html { redirect_to posts_url, flash: { success: 'Post successfully deleted.' } }
format.json { head :no_content } format.json { head :no_content }
end end
end end
# POST /posts/1/comment
def comment
@post = set_post
@comment = @post.comments.build(comment_params.merge(author: current_user))
respond_to do |format|
if @comment.save
format.html { redirect_to posts_path(id: @post.id) }
format.json { render json: { status: 'ok', comment: @comment }, status: :created }
else
format.html { redirect_to posts_path(id: @post.id), flash: { alert: 'Comment is not saved.' } }
format.json { render json: @comment.errors, status: :unprocessable_entity }
end
end
end
private private
# Use callbacks to share common setup or constraints between actions. # Use callbacks to share common setup or constraints between actions.
...@@ -123,4 +140,12 @@ class PostsController < ApplicationController ...@@ -123,4 +140,12 @@ class PostsController < ApplicationController
_param_hash _param_hash
end end
end end
def mail_params
params.require(:mail).permit(:to).to_hash.symbolize_keys
end
def comment_params
params.require(:comment).permit(:body).to_hash
end
end end
...@@ -3,7 +3,7 @@ module PostsHelper ...@@ -3,7 +3,7 @@ module PostsHelper
def h_display_tree(node) def h_display_tree(node)
_html = '<ul>' _html = '<ul>'
if node.posts.count > 0 if node.posts.count > 0
_html << %Q{<li><a href="#{ root_path(q: '#' + node.name) }">#{node.name} <span class="badge">#{node.posts.count}</span></a></li>} _html << %Q{<li><a href="#{ posts_path(q: '#' + node.name) }">#{node.name} <span class="badge">#{node.posts.count}</span></a></li>}
end end
node.children.each do |_child| node.children.each do |_child|
_html << h_display_tree(_child) _html << h_display_tree(_child)
......
module StyleHelper
## Store style
# Usage:
# <% style do %>
# div {
# color: red;
# }
# <% end %>
def style(&block)
content_for(content_key, capture(&block))
end
## Render all style
def render_style
return if content_for(content_key).nil?
html_buf = '<style type="text/css">'
html_buf << content_for(content_key)
html_buf << '</style>'
html_buf.html_safe
end
private
# Use for `content_for`
def content_key
:style_addon
end
end
class Comment < ActiveRecord::Base
belongs_to :author, class_name: 'User'
belongs_to :post
validates :author_id, presence: true
validates :post_id, presence: true
validates :body, presence: true
end
...@@ -2,6 +2,7 @@ class Post < ActiveRecord::Base ...@@ -2,6 +2,7 @@ class Post < ActiveRecord::Base
has_many :post_tags has_many :post_tags
has_many :tags, through: :post_tags has_many :tags, through: :post_tags
belongs_to :author, class_name: 'User' belongs_to :author, class_name: 'User'
has_many :comments
# Named scope # Named scope
scope :search, (lambda do |query| scope :search, (lambda do |query|
...@@ -13,15 +14,15 @@ class Post < ActiveRecord::Base ...@@ -13,15 +14,15 @@ class Post < ActiveRecord::Base
query_list.each do |_query| query_list.each do |_query|
case _query case _query
when /^id:(.+)/ when /^id:(.+)/
_where_list = _where_list.where('id = ?', Regexp.last_match[1]) _where_list = _where_list.where(id: Regexp.last_match[1])
when /^title:(.+)/ when /^title:(.+)/
_where_list = _where_list.where('title LIKE ?', "%#{Regexp.last_match[1]}%") _where_list = _where_list.where('title LIKE ?', "%#{Regexp.last_match[1]}%")
when /^body:(.+)/ when /^body:(.+)/
_where_list = _where_list.where('body LIKE ?', "%#{Regexp.last_match[1]}%") _where_list = _where_list.where('body LIKE ?', "%#{Regexp.last_match[1]}%")
when /^@(.+)/ when /^@(.+)/
_where_list = _where_list.where('users.name = ?', Regexp.last_match[1]) _where_list = _where_list.where(users: { name: Regexp.last_match[1] })
when /^#(.+)/ when /^#(.+)/
_where_list = _where_list.where('tags.name = ?', Regexp.last_match[1]) _where_list = _where_list.where(tags: { name: Regexp.last_match[1] })
when /^date:(\d+)-(\d+)-(\d+)/ when /^date:(\d+)-(\d+)-(\d+)/
_date = Time.new(Regexp.last_match[1], Regexp.last_match[2], Regexp.last_match[3]) _date = Time.new(Regexp.last_match[1], Regexp.last_match[2], Regexp.last_match[3])
_where_list = _where_list.where('updated_at > ? AND updated_at < ?', _date, _date + 1.day) _where_list = _where_list.where('updated_at > ? AND updated_at < ?', _date, _date + 1.day)
......
...@@ -8,6 +8,7 @@ class User < ActiveRecord::Base ...@@ -8,6 +8,7 @@ class User < ActiveRecord::Base
devise :omniauthable, omniauth_providers: [:google_oauth2] devise :omniauthable, omniauth_providers: [:google_oauth2]
has_many :posts has_many :posts
has_many :comments
# Device # Device
def self.find_for_google_oauth2(access_token, signed_in_resource = nil) def self.find_for_google_oauth2(access_token, signed_in_resource = nil)
......
...@@ -9,23 +9,13 @@ ...@@ -9,23 +9,13 @@
<!-- Optional theme --> <!-- Optional theme -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.min.css">
<%= render_style %>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
</head> </head>
<body> <body class="<%= params[:controller] %>-<%= params[:action] %>">
<% if notice %> <%= render partial: 'partials/header_notifications' %>
<script type="text/javascript">
alert('<%= notice %>');
</script>
<!-- <p class="notice"><%= notice %></p> -->
<% end %>
<% if alert %>
<script type="text/javascript">
alert('<%= alert %>');
</script>
<!-- <p class="notice"><%= notice %></p> -->
<p class="alert"><%= alert %></p>
<% end %>
<%= yield %> <%= yield %>
......
...@@ -18,13 +18,17 @@ ...@@ -18,13 +18,17 @@
<div class="input-group"> <div class="input-group">
<input type="text" name="q" class="form-control" value="<%= params[:q] %>" placeholder="Search"> <input type="text" name="q" class="form-control" value="<%= params[:q] %>" placeholder="Search">
<span class="input-group-btn"> <span class="input-group-btn">
<button type="submit" class="btn btn-default"> <button type="submit" class="btn btn-default" data-disable-with="Searching...">
<span class="glyphicon glyphicon-search"></span> <span class="glyphicon glyphicon-search"></span>
</button> </button>
</span> </span>
</div> </div>
</form> </form>
<p class="navbar-text" id="header-search-hint">
<a href="#"><span class="glyphicon glyphicon-question-sign" data-toggle="modal" data-target="#header-search-description"></span></a>
</p>
<%= form_tag(destroy_user_session_path, :method => :delete, class: 'navbar-form navbar-right') do %> <%= form_tag(destroy_user_session_path, :method => :delete, class: 'navbar-form navbar-right') do %>
<%= submit_tag 'SignOut', class: 'btn btn-default' %> <%= submit_tag 'SignOut', class: 'btn btn-default' %>
<% end %> <% end %>
...@@ -41,3 +45,42 @@ ...@@ -41,3 +45,42 @@
</div><!-- /.navbar-collapse --> </div><!-- /.navbar-collapse -->
</div><!-- /.container --> </div><!-- /.container -->
</nav> </nav>
<!-- Modal #header-search-description -->
<div class="modal fade" id="header-search-description" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Search command</h4>
</div>
<div class="modal-body">
<dl class="dl-horizontal">
<dt>Search by title</dt>
<dd><pre><a href="<%= posts_path(q: 'title:ruby') %>">title:ruby</a></pre></dd>
<dt>Search by id</dt>
<dd><pre><a href="<%= posts_path(q: 'id:123') %>">id:123</a></pre></dd>
<dt>Search by body</dt>
<dd><pre><a href="<%= posts_path(q: 'body:ruby') %>">body:ruby</a></pre></dd>
<dt>Search by author</dt>
<dd><pre><a href="<%= posts_path(q: '@taro') %>">@taro</a></pre></dd>
<dt>Search by tag</dt>
<dd><pre><a href="<%= posts_path(q: '#ruby') %>">#ruby</a></pre></dd>
<dt>Search by date</dt>
<dd><pre><a href="<%= posts_path(q: 'date:2013-12-16') %>">date:2013-12-16</a></pre></dd>
<dt>Search by title or body</dt>
<dd><pre><a href="<%= posts_path(q: 'ruby') %>">ruby</a></pre></dd>
</dl>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<% style do %>
#header-search-hint{
margin-left: 0;
}
<% end %>
<% if flash[:success] %>
<div class="alert alert-success fade in">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<strong>Success</strong> <%= flash[:success] %>
</div>
<% end %>
<% if flash[:notice] %>
<div class="alert alert-warning fade in">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<strong>Notice</strong> <%= flash[:notice] %>
</div>
<% end %>
<% if flash[:alert] %>
<div class="alert alert-danger fade in">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<strong>Alert</strong> <%= flash[:alert] %>
</div>
<% end %>
<div style="text-align:right"> <div class="panel panel-default">
<a href="<%= mail_post_path(@post) %>" class="btn navbar-btn" style!="position:absolute;right:0;top:0;margin-top:2px;margin-top:3px;margin-right:3px;"> <div class="panel-heading">
Mail <h3 class="panel-title">
</a>
<a href="<%= fork_post_path(@post) %>" class="btn navbar-btn" style!="position:absolute;right:0;top:0;margin-top:2px;margin-top:3px;margin-right:3px;">
Fork
</a>
<a href="<%= edit_post_path(@post) %>" class="btn btn-primary navbar-btn" style!="position:absolute;right:0;top:0;margin-top:2px;margin-top:3px;margin-right:3px;">
<span class="glyphicon glyphicon-pencil"></span>
</a>
</div>
<div class="text-box title" style!="position:relative;">
<a href="<%= post_path(@post) %>"><%= @post.title %></a> <a href="<%= post_path(@post) %>"><%= @post.title %></a>
</div> </h3>
<div class="text-box meta"> </div>
<ul class="list-group">
<li class="list-group-item">
<%### Post meta ###%>
<% @post.tags.each do |tag| %> <% @post.tags.each do |tag| %>
<span class="label label-info"> <span class="label label-info">
<a href="<%= root_path(q: "##{tag.name}") %>">#<%= tag.name %></a> <a href="<%= posts_path(q: "##{tag.name}") %>">#<%= tag.name %></a>
</span> </span>
<% end %> <% end %>
<span class="label label-success"> <span class="label label-success">
<a href="<%= root_path(q: "@#{@post.author.name}") %>">@<%= @post.author.name %></a> <a href="<%= posts_path(q: "@#{@post.author.name}") %>">@<%= @post.author.name %></a>
</span> </span>
<span class="label label-danger"> <span class="label label-danger">
<a href="<%= root_path(q: "date:#{@post.updated_at.strftime('%Y-%m-%d')}") %>"><%= @post.updated_at.strftime('%Y-%m-%d') %></a> <a href="<%= posts_path(q: "date:#{@post.updated_at.strftime('%Y-%m-%d')}") %>"><%= @post.updated_at.strftime('%Y-%m-%d') %></a>
</span> </span>
</div>
<div class="text-box body viewer github"> <!-- Split button -->
<div class="btn-group pull-right" style="margin: -7px -12px 0 0;">
<button type="button" class="btn btn-primary">
<span class="glyphicon glyphicon-pencil"></span>
</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="<%= fork_post_path(@post) %>">Fork</a></li>
<li><a href="#" data-toggle="modal" data-target="#myModal">Mail to...</a></li>
<li class="divider"></li>
<li><%= link_to 'Delete', post_path(@post), method: :delete, data: { confirm: 'Are you sure?' } %></li>
</ul>
</div>
<%### /Post meta ###%>
</li>
</ul>
<div class="panel-body viewer github">
<%= h_application_format_markdown(@post.body) %> <%= h_application_format_markdown(@post.body) %>
</div>
</div> </div>
<%### Comments ###%>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Comments</h3>
</div>
<div class="panel-body">
<ul class="media-list">
<% @post.comments.each do |comment| %>
<li class="media">
<a class="pull-left" href="#">
<img class="media-object" src="<%= comment.author.image_url %>">
</a>
<div class="media-body">
<h4 class="media-heading"><%= comment.author.name %></h4>
<%= comment.body %>
</div>
</li>
<% end %>
<%= form_tag(comment_post_path, method: :post, data: { 'form-id' => "comment_#{@post.id}" }) do %>
<li class="media">
<a class="pull-left" href="#">
<img class="media-object" src="<%= current_user.image_url %>">
</a>
<div class="media-body">
<h4 class="media-heading"><%= current_user.name %></h4>
<%= text_area :comment, :body, class: 'form-control', placeholder: 'コメントする...' %>
<%= submit_tag 'Comment', class: 'btn btn-primary', data: { 'disable-with' => '...' } %>
</div>
</li>
<% end %>
<script type="text/javascript">
$("form[data-form-id='comment_<%= @post.id %>']").on('ajax:success', function(event, data, xhr) {
});
</script>
</ul>
</div>
</div>
<%### /Comments ###%>
<!-- Button trigger modal -->
<!-- <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
-->
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<%= form_tag mail_post_path(@post), method: :post, class: 'form-horizontal', role: 'form' do %>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">Mail this post to...</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="<%= @post.title %>" readonly>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">To</label>
<div class="col-sm-10">
<input type="email" name="mail[to]" class="form-control" id="inputEmail3" placeholder="Email">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">From</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="<%= current_user.email %>" readonly>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" data-disable-with="Sending...">Send</button>
</div>
</div><!-- /.modal-content -->
<% end %><%# form %>
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
...@@ -9,12 +9,20 @@ ...@@ -9,12 +9,20 @@
<div class="col-xs-6 col-md-4" id="sidebar" role="navigation"> <div class="col-xs-6 col-md-4" id="sidebar" role="navigation">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-list" data-toggle="tab">List</a></li>
<li><a href="#tab-tree" data-toggle="tab">Tag Tree</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab-list">
<div class="list-group"> <div class="list-group">
<% @posts.each do |post| %> <% @posts.each_with_index do |post, i| %>
<a href="#" data-post-id="<%= post.id %>" class="list-group-item post-list"><%= post.title %></a> <a href="#" data-post-id="<%= post.id %>" class="list-group-item post-list"><%= post.title %></a>
<% end %> <% end %>
</div> </div>
</div><!-- /.tab-pane -->
<div class="tab-pane" id="tab-tree">
<% cache('tag-tree', :expires_in => 1.hour) do %> <% cache('tag-tree', :expires_in => 1.hour) do %>
<div class="list-group"> <div class="list-group">
<% Tag.roots.each do |root| %> <% Tag.roots.each do |root| %>
...@@ -22,13 +30,15 @@ ...@@ -22,13 +30,15 @@
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
</div><!-- /.tab-pane -->
</div><!-- /.tab-content -->
</div><!--/span--> </div><!--/span-->
<div class="col-xs-12 col-sm-6 col-md-8"> <div class="col-xs-12 col-sm-6 col-md-8">
<div id="list_post"> <div id="list_post">
<p style="color:#aaa;font-size:30px">&lt;-- Select a post...</p> <p id="posts-placeholder" style="color:#aaa;font-size:30px">&lt;-- Select a post...</p>
</div> </div>
</div><!--/span--> </div><!--/span-->
...@@ -38,6 +48,9 @@ ...@@ -38,6 +48,9 @@
<hr> <hr>
<footer> <footer>
<a href="https://github.com/tadyjp/rendezvous">Github</a>
|
<a href="https://twitter.com/tady_jp">@tady_jp</a>
</footer> </footer>
</div><!--/.container--> </div><!--/.container-->
......
...@@ -6,22 +6,13 @@ ...@@ -6,22 +6,13 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-12">
<div id="xxxxxxxx"> <div id="xxxxxxxx">
<%= render partial: 'posts/show_fragment' %> <%= render partial: 'posts/show_fragment' %>
</div> </div>
</div><!--/span-->
</div><!--/row--> </div><!--/row-->
<hr> <hr>
<footer>
</footer>
</div><!--/.container--> </div><!--/.container-->
</div> </div>
#! /usr/bin/env python
import sys
def main():
print "SET sql_mode='NO_BACKSLASH_ESCAPES';"
lines = sys.stdin.read().splitlines()
for line in lines:
processLine(line)
def processLine(line):
if (
line.startswith("PRAGMA") or
line.startswith("BEGIN TRANSACTION;") or
line.startswith("COMMIT;") or
line.startswith("DELETE FROM sqlite_sequence;") or
line.startswith("INSERT INTO \"sqlite_sequence\"")
):
return
line = line.replace("AUTOINCREMENT", "AUTO_INCREMENT")
line = line.replace("DEFAULT 't'", "DEFAULT '1'")
line = line.replace("DEFAULT 'f'", "DEFAULT '0'")
line = line.replace(",'t'", ",'1'")
line = line.replace(",'f'", ",'0'")
in_string = False
newLine = ''
for c in line:
if not in_string:
if c == "'":
in_string = True
elif c == '"':
newLine = newLine + '`'
continue
elif c == "'":
in_string = False
newLine = newLine + c
print newLine
if __name__ == "__main__":
main()
...@@ -20,7 +20,8 @@ module Rendezvous ...@@ -20,7 +20,8 @@ module Rendezvous
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :ja I18n.enforce_available_locales = true
config.i18n.default_locale = 'ja'
# config.action_mailer.delivery_method = :action_gmailer # config.action_mailer.delivery_method = :action_gmailer
config.action_mailer.smtp_settings = { config.action_mailer.smtp_settings = {
......
...@@ -4,19 +4,32 @@ ...@@ -4,19 +4,32 @@
# Ensure the SQLite 3 gem is defined in your Gemfile # Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3' # gem 'sqlite3'
development: development:
adapter: sqlite3 adapter: mysql2
database: db/development.sqlite3 encoding: utf8
reconnect: false
database: <%= ENV['DB_DEVELOPMENT_DATABASE'] %>
pool: 5 pool: 5
timeout: 5000 username: <%= ENV['DB_DEVELOPMENT_USER'] %>
password: <%= ENV['DB_DEVELOPMENT_PASS'] %>
host: <%= ENV['DB_DEVELOPMENT_HOST'] %>
# Warning: The database defined as "test" will be erased and # Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake". # re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production. # Do not set this db to the same as development or production.
# test:
# adapter: sqlite3
# database: db/test.sqlite3
# pool: 5
# timeout: 5000
test: test:
adapter: sqlite3 adapter: mysql2
database: db/test.sqlite3 encoding: utf8
reconnect: false
database: <%= ENV['DB_TEST_DATABASE'] %>
pool: 5 pool: 5
timeout: 5000 username: <%= ENV['DB_TEST_USER'] %>
password: <%= ENV['DB_TEST_PASS'] %>
host: <%= ENV['DB_TEST_HOST'] %>
production: production:
adapter: sqlite3 adapter: sqlite3
......
# Be sure to restart your server when you modify this file. # Be sure to restart your server when you modify this file.
Rendezvous::Application.config.session_store :cookie_store, key: '_rendezvous_session' Rendezvous::Application.config.session_store :cookie_store,
key: '__rv__'
ja:
date:
abbr_day_names:
-
-
-
-
-
-
-
abbr_month_names:
-
- 1月
- 2月
- 3月
- 4月
- 5月
- 6月
- 7月
- 8月
- 9月
- 10月
- 11月
- 12月
day_names:
- 日曜日
- 月曜日
- 火曜日
- 水曜日
- 木曜日
- 金曜日
- 土曜日
formats:
default: ! '%Y/%m/%d'
long: ! '%Y年%m月%d日(%a)'
short: ! '%m/%d'
month_names:
-
- 1月
- 2月
- 3月
- 4月
- 5月
- 6月
- 7月
- 8月
- 9月
- 10月
- 11月
- 12月
order:
- :year
- :month
- :day
datetime:
distance_in_words:
about_x_hours:
one: 約1時間
other: 約%{count}時間
about_x_months:
one: 約1ヶ月
other: 約%{count}ヶ月
about_x_years:
one: 約1年
other: 約%{count}年
almost_x_years:
one: 1年弱
other: ! '%{count}年弱'
half_a_minute: 30秒前後
less_than_x_minutes:
one: 1分以内
other: ! '%{count}分未満'
less_than_x_seconds:
one: 1秒以内
other: ! '%{count}秒未満'
over_x_years:
one: 1年以上
other: ! '%{count}年以上'
x_days:
one: 1日
other: ! '%{count}日'
x_minutes:
one: 1分
other: ! '%{count}分'
x_months:
one: 1ヶ月
other: ! '%{count}ヶ月'
x_seconds:
one: 1秒
other: ! '%{count}秒'
prompts:
day:
hour:
minute:
month:
second:
year:
errors: &errors
format: ! '%{attribute}%{message}'
messages:
accepted: を受諾してください。
blank: を入力してください。
present: は入力しないでください。
confirmation: と%{attribute}の入力が一致しません。
empty: を入力してください。
equal_to: は%{count}にしてください。
even: は偶数にしてください。
exclusion: は予約されています。
greater_than: は%{count}より大きい値にしてください。
greater_than_or_equal_to: は%{count}以上の値にしてください。
inclusion: は一覧にありません。
invalid: は不正な値です。
less_than: は%{count}より小さい値にしてください。
less_than_or_equal_to: は%{count}以下の値にしてください。
not_a_number: は数値で入力してください。
not_an_integer: は整数で入力してください。
odd: は奇数にしてください。
record_invalid: バリデーションに失敗しました。 %{errors}
restrict_dependent_destroy: ! '%{record}が存在しているので削除できません。'
taken: はすでに存在します。
too_long: は%{count}文字以内で入力してください。
too_short: は%{count}文字以上で入力してください。
wrong_length: は%{count}文字で入力してください。
other_than: "は%{count}以外の値にしてください。"
template:
body: 次の項目を確認してください。
header:
one: ! '%{model}にエラーが発生しました。'
other: ! '%{model}に%{count}個のエラーが発生しました。'
helpers:
select:
prompt: 選択してください。
submit:
create: 登録する
submit: 保存する
update: 更新する
number:
currency:
format:
delimiter: ! ','
format: ! '%n%u'
precision: 0
separator: .
significant: false
strip_insignificant_zeros: false
unit:
format:
delimiter: ! ','
precision: 3
separator: .
significant: false
strip_insignificant_zeros: false
human:
decimal_units:
format: ! '%n %u'
units:
billion: 十億
million: 百万
quadrillion: 千兆
thousand:
trillion:
unit: ''
format:
delimiter: ''
precision: 3
significant: true
strip_insignificant_zeros: true
storage_units:
format: ! '%n%u'
units:
byte: バイト
gb: ギガバイト
kb: キロバイト
mb: メガバイト
tb: テラバイト
percentage:
format:
delimiter: ''
format: "%n%"
precision:
format:
delimiter: ''
support:
array:
last_word_connector:
two_words_connector:
words_connector:
time:
am: 午前
formats:
default: ! '%Y/%m/%d %H:%M:%S'
long: ! '%Y年%m月%d日(%a) %H時%M分%S秒 %z'
short: ! '%y/%m/%d %H:%M'
pm: 午後
# remove these aliases after 'activemodel' and 'activerecord' namespaces are removed from Rails repository
activemodel:
errors:
<<: *errors
activerecord:
errors:
<<: *errors
devise:
confirmations:
confirmed: アカウントを登録しました。
send_instructions: 登録方法を数分以内にメールでご連絡します。
send_paranoid_instructions: メールアドレスが登録されていれば、数分以内にアカウントを確認する方法が記載されているメールが届きます。
failure:
already_authenticated: 既にログインしています。
inactive: アカウントが有効化されていません。
invalid: メールアドレスまたはパスワードが違います。
last_attempt: あと一回間違えるとアカウントが凍結されます。
locked: アカウントが凍結されています。
not_found_in_database: メールアドレスまたはパスワードが違います。
timeout: セッションがタイムアウトしました。もう一度ログインしてください。
unauthenticated: 続けるにはログインまたはアカウントを登録してください。
unconfirmed: 本登録を行ってください。
mailer:
confirmation_instructions:
subject: アカウントの登録方法
reset_password_instructions:
subject: パスワードの再設定
unlock_instructions:
subject: アカウントの凍結解除
omniauth_callbacks:
failure: 「%{reason}」のため、%{kind}による認証ができませんでした。
success: '%{kind}による認証に成功しました。'
passwords:
no_token: パスワード再設定のメール以外からこのページへアクセスする事はできません。もしパスワード再設定のメールに記載されたリンクをクリックしてこのページへ訪れた場合、不完全なURLのリンクをクリックしていないか確認してください。メーラーによっては、リンクのURLが途中で切れる可能性があります。
send_instructions: パスワードの再設定方法を数分以内にメールでご連絡します。
send_paranoid_instructions: メールアドレスが登録されていれば、数分以内にパスワード再設定のメールが届きます。
updated: パスワードを変更し、ログインしました。
updated_not_active: パスワードを変更しました。
registrations:
destroyed: アカウントを削除しました。またのご利用をお待ちしております。
signed_up: アカウント登録を受け付けました。
signed_up_but_inactive: 登録に成功しました。しかし、アカウントが有効になっていないためログインできません。
signed_up_but_locked: 登録に成功しました。しかし、アカウントがロックされているためログインできません。
signed_up_but_unconfirmed: アカウント確認のリンクが入っているメールを送りました。 メール内のリンクでアカウントを有効にしてください。
update_needs_confirmation: アカウント情報を変更しました。しかし、メールアドレスを確認する必要があります。メール内のリンクで新しいメールアドレスを確認してください。
updated: アカウント情報を更新しました。
sessions:
signed_in: ログインしました。
signed_out: ログアウトしました。
unlocks:
send_instructions: アカウントの凍結解除方法を数分以内にメールでご連絡します。
send_paranoid_instructions: アカウントが登録されていれば、数分以内にアカウントの凍結解除方法が登録しているアドレスに届きます。
unlocked: アカウントを凍結解除しました。続けるにはログインしてください。
errors:
messages:
already_confirmed: は既に登録済みです
confirmation_period_expired: は%{period}以内に確認が必要です。もう一度要求してください。
expired: は期限が切れたため、新しく取得する必要があります
not_found: は見つかりませんでした
not_locked: は凍結されていません
not_saved: '%{count}個のエラーにより%{resource}を保存することができませんでした。'
ja:
activerecord:
models:
post: post #g
post_tag: post_tag #g
tag: tag #g
user: user #g
attributes:
post:
author: :activerecord.models.author #g
body: body #g
post_tags: post_tags #g
tags: tags #g
title: title #g
post_tag:
post: :activerecord.models.post #g
tag: :activerecord.models.tag #g
tag:
ancestry: ancestry #g
name: name #g
post_tags: post_tags #g
posts: posts #g
user:
current_sign_in_at: current_sign_in_at #g
current_sign_in_ip: current_sign_in_ip #g
email: email #g
encrypted_password: encrypted_password #g
google_auth_token: google_auth_token #g
google_refresh_token: google_refresh_token #g
google_token_expires_at: google_token_expires_at #g
image_url: image_url #g
last_sign_in_at: last_sign_in_at #g
last_sign_in_ip: last_sign_in_ip #g
name: name #g
posts: posts #g
remember_created_at: remember_created_at #g
reset_password_sent_at: reset_password_sent_at #g
reset_password_token: reset_password_token #g
...@@ -3,9 +3,10 @@ Rendezvous::Application.routes.draw do ...@@ -3,9 +3,10 @@ Rendezvous::Application.routes.draw do
root 'home#top', as: 'root' root 'home#top', as: 'root'
post 'posts/preview' => 'posts#preview' post 'posts/preview' => 'posts#preview'
get 'posts/show_fragment' => 'posts#show_fragment' # get 'posts/show_fragment' => 'posts#show_fragment'
get 'posts/:id/fork' => 'posts#fork', as: 'fork_post' get 'posts/:id/fork' => 'posts#fork', as: 'fork_post'
get 'posts/:id/mail' => 'posts#mail', as: 'mail_post' post 'posts/:id/mail' => 'posts#mail', as: 'mail_post'
post 'posts/:id/comment' => 'posts#comment', as: 'comment_post'
resources :posts resources :posts
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
......
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.integer :author_id
t.integer :post_id
t.text :body
t.timestamps
end
add_index :comments, [:author_id, :updated_at]
add_index :comments, [:post_id, :updated_at]
end
end
...@@ -11,7 +11,18 @@ ...@@ -11,7 +11,18 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20131228110818) do ActiveRecord::Schema.define(version: 20140106160129) do
create_table 'comments', force: true do |t|
t.integer 'author_id'
t.integer 'post_id'
t.text 'body'
t.datetime 'created_at'
t.datetime 'updated_at'
end
add_index 'comments', ['author_id', 'updated_at'], name: 'index_comments_on_author_id_and_updated_at', using: :btree
add_index 'comments', ['post_id', 'updated_at'], name: 'index_comments_on_post_id_and_updated_at', using: :btree
create_table 'post_tags', force: true do |t| create_table 'post_tags', force: true do |t|
t.integer 'post_id', null: false t.integer 'post_id', null: false
...@@ -20,8 +31,8 @@ ActiveRecord::Schema.define(version: 20131228110818) do ...@@ -20,8 +31,8 @@ ActiveRecord::Schema.define(version: 20131228110818) do
t.datetime 'updated_at' t.datetime 'updated_at'
end end
add_index 'post_tags', ['post_id'], name: 'index_post_tags_on_post_id' add_index 'post_tags', ['post_id'], name: 'index_post_tags_on_post_id', using: :btree
add_index 'post_tags', ['tag_id'], name: 'index_post_tags_on_tag_id' add_index 'post_tags', ['tag_id'], name: 'index_post_tags_on_tag_id', using: :btree
create_table 'posts', force: true do |t| create_table 'posts', force: true do |t|
t.string 'title' t.string 'title'
...@@ -38,7 +49,7 @@ ActiveRecord::Schema.define(version: 20131228110818) do ...@@ -38,7 +49,7 @@ ActiveRecord::Schema.define(version: 20131228110818) do
t.string 'ancestry' t.string 'ancestry'
end end
add_index 'tags', ['ancestry'], name: 'index_tags_on_ancestry' add_index 'tags', ['ancestry'], name: 'index_tags_on_ancestry', using: :btree
create_table 'users', force: true do |t| create_table 'users', force: true do |t|
t.string 'name' t.string 'name'
...@@ -60,7 +71,7 @@ ActiveRecord::Schema.define(version: 20131228110818) do ...@@ -60,7 +71,7 @@ ActiveRecord::Schema.define(version: 20131228110818) do
t.datetime 'google_token_expires_at' t.datetime 'google_token_expires_at'
end end
add_index 'users', ['email'], name: 'index_users_on_email', unique: true add_index 'users', ['email'], name: 'index_users_on_email', unique: true, using: :btree
add_index 'users', ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true add_index 'users', ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, using: :btree
end end
...@@ -39,12 +39,12 @@ _tag_tree.each do |_parent, _child| ...@@ -39,12 +39,12 @@ _tag_tree.each do |_parent, _child|
end end
# User # User
User.find_or_create_by(name: '山田太郎') do |_u| user_1 = User.find_or_create_by(name: '山田太郎') do |_u|
_u.email = "#{Devise.friendly_token[0, 20]}@example.com" _u.email = "#{Devise.friendly_token[0, 20]}@example.com"
_u.password = Devise.friendly_token[0, 20] _u.password = Devise.friendly_token[0, 20]
end end
User.find_or_create_by(name: '鈴木二郎') do |_u| user_2 = User.find_or_create_by(name: '鈴木二郎') do |_u|
_u.email = "#{Devise.friendly_token[0, 20]}@example.com" _u.email = "#{Devise.friendly_token[0, 20]}@example.com"
_u.password = Devise.friendly_token[0, 20] _u.password = Devise.friendly_token[0, 20]
end end
...@@ -57,13 +57,20 @@ end ...@@ -57,13 +57,20 @@ end
# Post # Post
users = User.all users = User.all
Post.delete_all
Dir.glob(Rails.root.join('db', 'seeds').to_s + '/*').each do |file_name| Dir.glob(Rails.root.join('db', 'seeds').to_s + '/*').each do |file_name|
Rails.logger.debug "[Post Tag] #{file_name}" Rails.logger.debug "[Post Tag] #{file_name}"
title = file_name.split('/').last title = file_name.split('/').last
post = Post.find_or_initialize_by(title: title) post = Post.new(title: title)
post.body = File.read(file_name) post.body = File.read(file_name)
post.author = users.sample post.author = users.sample
post.tags = [tags.sample, tags.sample] post.tags = [tags.sample, tags.sample]
post.save! post.save!
end end
# rubocop:disable LineLength
Post.first.comments.create(author: user_1, body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.')
Post.first.comments.create(author: user_2, body: 'Hooooooo....')
Post.first.comments.create(author: user_1, body: 'It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.')
# rubocop:enable LineLength
![Screen Shot 2013-11-20 at 12.23.19 AM.png](https://qiita-image-store.s3.amazonaws.com/0/10272/474c4435-35b5-60ee-18ef-dd11e2bbce3c.png "Screen Shot 2013-11-20 at 12.23.19 AM.png")
### 最終更新日 ### 最終更新日
- 2013-12-10 - 2013-12-10
......
require 'spec_helper'
class DummyClass; end
describe RV::Mailer do
let(:klass) { DummyClass.new.extend(RV::Mailer) }
let(:alice) { FactoryGirl.create(:alice) }
let(:post) { Post.create title: 'ruby rspec', body: 'This is first espec test: ruby' }
it 'valid' do
expect { klass.compose_mail(post, user: alice, to: 'dummy@example.com') }.not_to raise_error(ArgumentError)
end
it 'missing post' do
expect { klass.compose_mail(nil, user: alice, to: 'dummy@example.com') }.to raise_error(ArgumentError)
end
it 'missing user' do
expect { klass.compose_mail(post, user: nil, to: 'dummy@example.com') }.to raise_error(ArgumentError)
end
it 'missing to' do
expect { klass.compose_mail(post, user: alice, to: nil) }.to raise_error(ArgumentError)
end
it 'invalid to' do
expect { klass.compose_mail(post, user: alice, to: 'invalid.email') }.to raise_error(ArgumentError)
end
end
# FactoryGirl.define do
# factory :comment_1, class: Comment do
# body 'ruby'
# end
# end
require 'spec_helper'
include Warden::Test::Helpers
Warden.test_mode!
describe 'Request via js', js: true do
let(:user) { FactoryGirl.create(:login_user_1) }
before do
@post1 = Post.create title: 'ruby rspec', body: 'This is first espec test: ruby', author_id: user.id
@post2 = Post.create title: 'php test', body: 'PHP is very easy', author_id: user.id
@post3 = Post.create title: 'java java...', body: 'Java is not ruby...', author_id: user.id
end
before :each do
login_as user, scope: :user
visit '/posts'
end
it 'show first post' do
page.save_screenshot(Rails.root.join('tmp', 'screenshots', "a-#{Time.now.strftime('%Y-%m-%d %H%M%S')}.png"))
expect(page.find('.panel-title a').text).to include('ruby rspec')
end
it 'click post and show' do
find('.post-list:nth-child(3)').click
page.save_screenshot(Rails.root.join('tmp', 'screenshots', "b-#{Time.now.strftime('%Y-%m-%d %H%M%S')}.png"))
expect(page.find('.panel-title a').text).to include('java java...')
end
after :each do
page.driver.reset!
Warden.test_reset!
end
end
require 'spec_helper'
describe Comment do
describe 'validations' do
it 'blank author_id' do
expect(Comment.new(post_id: 1, body: 'test')).not_to be_valid
end
it 'blank post_id' do
expect(Comment.new(author_id: 1, body: 'test')).not_to be_valid
end
it 'blank body' do
expect(Comment.new(post_id: 1, author_id: 2)).not_to be_valid
end
end
end
...@@ -3,19 +3,18 @@ require 'spec_helper' ...@@ -3,19 +3,18 @@ require 'spec_helper'
describe User do describe User do
describe 'Instance method' do describe 'Instance method' do
before :each do
@alice = create(:alice) let(:alice) { create(:alice) }
@bob = create(:bob) let(:bob) { create(:bob) }
end
describe '#google_oauth_token_expired?' do describe '#google_oauth_token_expired?' do
it 'not expired' do it 'not expired' do
expect(@alice.google_oauth_token_expired?).to be_false expect(alice.google_oauth_token_expired?).to be_false
end end
it 'expired' do it 'expired' do
expect(@bob.google_oauth_token_expired?).to be_true expect(bob.google_oauth_token_expired?).to be_true
end end
end end
......
...@@ -10,6 +10,19 @@ require 'rspec/autorun' ...@@ -10,6 +10,19 @@ require 'rspec/autorun'
# require 'email_spec' # require 'email_spec'
require 'factory_girl' require 'factory_girl'
require 'capybara'
require 'capybara/rspec'
## Setting for polterguist.
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, timeout: 30)
end
Capybara.javascript_driver = :poltergeist
# Set capybara wait time (default: 2)
Capybara.default_wait_time = 10
# Requires supporting ruby files with custom matchers and macros, etc, # Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories. # in spec/support/ and its subdirectories.
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
...@@ -33,7 +46,7 @@ RSpec.configure do |config| ...@@ -33,7 +46,7 @@ RSpec.configure do |config|
# If you're not using ActiveRecord, or you'd prefer not to run each of your # If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false # examples within a transaction, remove the following line or assign false
# instead of true. # instead of true.
config.use_transactional_fixtures = true config.use_transactional_fixtures = false
# If true, the base class of anonymous controllers will be inferred # If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of # automatically. This will be the default behavior in future versions of
...@@ -54,4 +67,17 @@ RSpec.configure do |config| ...@@ -54,4 +67,17 @@ RSpec.configure do |config|
config.before(:all) do config.before(:all) do
FactoryGirl.reload FactoryGirl.reload
end end
config.include Capybara::DSL
config.before :suite do
DatabaseRewinder.clean_all
end
# config.before :each do
# end
config.after :each do
DatabaseRewinder.clean
end
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment