• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Voice data server for navigation voice changer app.


Commit MetaInfo

Révisionae283adbf2622f043734a355425664789d75200c (tree)
l'heure2013-10-26 04:57:08
AuteurHMML <hmml3939@gmai...>
CommiterHMML

Message de Log

Add news listing and headline display.

Change Summary

Modification

--- a/Gemfile
+++ b/Gemfile
@@ -45,6 +45,7 @@ end
4545 # Use debugger
4646 # gem 'debugger', group: [:development, :test]
4747
48+gem 'rails_autolink', '~> 1.1.5'
4849 gem 'anjlab-bootstrap-rails', '~> 3.0.0.3', :require => 'bootstrap-rails'
4950 gem 'rails-i18n'
5051 gem 'kaminari'
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -154,6 +154,8 @@ GEM
154154 remotipart (~> 1.0)
155155 safe_yaml (~> 0.9)
156156 sass-rails (~> 4.0)
157+ rails_autolink (1.1.5)
158+ rails (> 3.1)
157159 railties (4.0.0)
158160 actionpack (= 4.0.0)
159161 activesupport (= 4.0.0)
@@ -237,6 +239,7 @@ DEPENDENCIES
237239 rails (= 4.0.0)
238240 rails-i18n
239241 rails_admin
242+ rails_autolink (~> 1.1.5)
240243 responders
241244 rspec-rails
242245 rubyzip
--- /dev/null
+++ b/app/assets/javascripts/news.js.coffee
@@ -0,0 +1,3 @@
1+# Place all the behaviors and hooks related to the matching controller here.
2+# All this logic will automatically be available in application.js.
3+# You can use CoffeeScript in this file: http://coffeescript.org/
--- /dev/null
+++ b/app/assets/stylesheets/news.css.scss
@@ -0,0 +1,3 @@
1+// Place all the styles related to the news controller here.
2+// They will automatically be included in application.css.
3+// You can use Sass (SCSS) here: http://sass-lang.com/
--- a/app/assets/stylesheets/nvc-serv.css.scss
+++ b/app/assets/stylesheets/nvc-serv.css.scss
@@ -92,4 +92,15 @@ h5 { font-size: 14px; }
9292 .rating-container {
9393 display: inline-block;
9494 vertical-align: top;
95-}
\ No newline at end of file
95+}
96+
97+.news-item {
98+ .time { color: #999; }
99+}
100+
101+.navbar .headline {
102+ max-width: 14em;
103+ white-space: nowrap;
104+ overflow: hidden;
105+ text-overflow: ellipsis;
106+}
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -4,7 +4,7 @@ class ApplicationController < ActionController::Base
44 protect_from_forgery with: :exception
55 respond_to :html, :xml, :json
66 responders :flash
7- before_action :set_locale
7+ before_action :set_locale, :get_headline
88
99 class ProcessError < StandardError
1010 def initialize(msg, status = 404)
@@ -32,6 +32,13 @@ class ApplicationController < ActionController::Base
3232 end
3333 end
3434
35+ def get_headline
36+ @headline = Rails.cache.fetch("headline", expires_in: 600) do
37+ day_after = Time.now - Rails.configuration.headline_daylimit.days
38+ News.where(skip_headline: false).where('created_at > ?', day_after).first
39+ end
40+ end
41+
3542 def raise_error_400(msg = "")
3643 raise ProcessError.new(msg, 400)
3744 end
--- /dev/null
+++ b/app/controllers/news_controller.rb
@@ -0,0 +1,51 @@
1+class NewsController < ApplicationController
2+ # GET /news
3+ # GET /news.xml
4+ def index
5+ @news = News.page(params[:page])
6+ respond_with(@news)
7+ end
8+
9+ # GET /news/1
10+ # GET /news/1.xml
11+ def show
12+ @news = News.find(params[:id])
13+ respond_with(@news)
14+ end
15+
16+ # GET /news/new
17+ # GET /news/new.xml
18+ def new
19+ @news = News.new
20+ respond_with(@news)
21+ end
22+
23+ # GET /news/1/edit
24+ def edit
25+ @news = News.find(params[:id])
26+ end
27+
28+ # POST /news
29+ # POST /news.xml
30+ def create
31+ @news = News.new(params[:news])
32+ flash[:notice] = 'News was successfully created.' if @news.save
33+ respond_with(@news)
34+ end
35+
36+ # PUT /news/1
37+ # PUT /news/1.xml
38+ def update
39+ @news = News.find(params[:id])
40+ flash[:notice] = 'News was successfully updated.' if @news.update(params[:news])
41+ respond_with(@news)
42+ end
43+
44+ # DELETE /news/1
45+ # DELETE /news/1.xml
46+ def destroy
47+ @news = News.find(params[:id])
48+ @news.destroy
49+ respond_with(@news)
50+ end
51+end
--- /dev/null
+++ b/app/helpers/news_helper.rb
@@ -0,0 +1,2 @@
1+module NewsHelper
2+end
--- /dev/null
+++ b/app/models/news.rb
@@ -0,0 +1,3 @@
1+class News < ActiveRecord::Base
2+ default_scope -> { order('created_at desc') }
3+end
--- a/app/views/layouts/_navigation.html.haml
+++ b/app/views/layouts/_navigation.html.haml
@@ -5,11 +5,17 @@
55 %span.icon-bar
66 %span.icon-bar
77 = link_to t('navi.brand'), root_path, :class => 'navbar-brand'
8- %div.navbar-collapse.collapse#main-nav-collapse
8+ .navbar-collapse.collapse#main-nav-collapse
99 %ul.nav.navbar-nav
1010 %li{class: controller.controller_name == 'welcome' && controller.action_name == 'guide' ? 'active' : ''}
1111 = link_to t('navi.guide'), welcome_guide_path
1212 %li{class: controller.controller_name == 'navi_voices' && controller.action_name == 'index' ? 'active' : ''}
1313 = link_to t('navi.voice_data'), navi_voices_path
1414 %li{class: controller.controller_name == 'navi_voices' && controller.action_name == 'new' ? 'active' : ''}
15- = link_to t('navi.upload'), new_navi_voice_path
\ No newline at end of file
15+ = link_to t('navi.upload'), new_navi_voice_path
16+ %li{class: controller.controller_name == 'news' ? 'active' : ''}
17+ = link_to t('navi.news'), news_index_path
18+ - if @headline
19+ %p.navbar-text.pull-right.headline
20+ %span.glyphicon.glyphicon-exclamation-sign
21+ = link_to "#{@headline.created_at.strftime('%m/%d')} #{@headline.title}", @headline, class: 'navbar-link'
--- /dev/null
+++ b/app/views/news/_form.html.haml
@@ -0,0 +1,10 @@
1+= simple_form_for(@news) do |f|
2+ = f.error_notification
3+
4+ .form-inputs
5+ = f.input :title
6+ = f.input :body
7+ = f.input :skip_headline
8+
9+ .form-actions
10+ = f.button :submit
--- /dev/null
+++ b/app/views/news/edit.html.haml
@@ -0,0 +1,7 @@
1+%h1 Editing news
2+
3+= render 'form'
4+
5+= link_to 'Show', @news
6+\|
7+= link_to 'Back', news_index_path
--- /dev/null
+++ b/app/views/news/index.html.haml
@@ -0,0 +1,13 @@
1+- content_for :title do
2+ = t '.title'
3+%h1= t '.title'
4+
5+- @news.each do |news|
6+ .news-item.panel.panel-default
7+ .panel-heading
8+ .time.pull-right= news.created_at.strftime '%F %T'
9+ %b= news.title
10+ .panel-body
11+ = auto_link simple_format news.body
12+
13+= paginate @news
--- /dev/null
+++ b/app/views/news/index.json.jbuilder
@@ -0,0 +1,4 @@
1+json.array!(@news) do |news|
2+ json.extract! news, :title, :body, :skip_headline
3+ json.url news_url(news, format: :json)
4+end
--- /dev/null
+++ b/app/views/news/new.html.haml
@@ -0,0 +1,5 @@
1+%h1 New news
2+
3+= render 'form'
4+
5+= link_to 'Back', news_index_path
--- /dev/null
+++ b/app/views/news/show.html.haml
@@ -0,0 +1,11 @@
1+- content_for :title do
2+ = @news.title + ' - ' + t('navi.news')
3+
4+.news-item.panel.panel-default
5+ .panel-heading
6+ .time.pull-right= @news.created_at.strftime '%F %T'
7+ %b= @news.title
8+ .panel-body
9+ = auto_link simple_format @news.body
10+
11+= link_to t('.back_to_index'), news_index_path, class: 'btn btn-default'
--- /dev/null
+++ b/app/views/news/show.json.jbuilder
@@ -0,0 +1 @@
1+json.extract! @news, :title, :body, :skip_headline, :created_at, :updated_at
--- a/config/application.rb
+++ b/config/application.rb
@@ -27,5 +27,6 @@ module NvcServ
2727 }
2828 config.admin_user = nil
2929 config.admin_pass = nil
30+ config.headline_daylimit = 7
3031 end
3132 end
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -25,6 +25,11 @@ en:
2525 title: Listing Voice Data
2626 show:
2727 title: Voice Data Details
28+ news:
29+ index:
30+ title: News
31+ show:
32+ back_to_index: Back to news index
2833 simple_form:
2934 hints:
3035 navi_voice:
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -2,6 +2,7 @@ ja:
22 activerecord:
33 models:
44 navi_voice: ナビ音声
5+ news: お知らせ
56 attributes:
67 navi_voice:
78 title: タイトル
@@ -22,6 +23,9 @@ ja:
2223 tos_agree: 以下の規約上問題ありません
2324 created_at: アップロード日時
2425 dlcount: ダウンロード回数
26+ news:
27+ title: タイトル
28+ body: 本文
2529 unit:
2630 metric: メートル
2731 imperial: ヤード・ポンド
@@ -37,6 +41,11 @@ ja:
3741 title: 音声データ一覧
3842 show:
3943 title: 音声データの詳細
44+ news:
45+ index:
46+ title: お知らせ一覧
47+ show:
48+ back_to_index: お知らせ一覧に戻る
4049 simple_form:
4150 hints:
4251 navi_voice:
@@ -58,5 +67,6 @@ ja:
5867 guide: 作成ガイド
5968 voice_data: 音声データ
6069 upload: アップロード
70+ news: お知らせ
6171
6272 site_title: ナビボイスチェンジャー
\ No newline at end of file
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -13,6 +13,7 @@ NvcServ::Application.routes.draw do
1313 get 'archive'
1414 end
1515 end
16+ resources :news, only: [:index, :show]
1617
1718 # The priority is based upon order of creation: first created -> highest priority.
1819 # See how all your routes lay out with "rake routes".
--- /dev/null
+++ b/db/migrate/20131025183439_create_news.rb
@@ -0,0 +1,12 @@
1+class CreateNews < ActiveRecord::Migration
2+ def change
3+ create_table :news do |t|
4+ t.string :title, default: '', null: false
5+ t.text :body, default: ''
6+ t.boolean :skip_headline, default: false, null: false
7+
8+ t.timestamps
9+ end
10+ add_index :news, :created_at
11+ end
12+end
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
1111 #
1212 # It's strongly recommended that you check this file into your version control system.
1313
14-ActiveRecord::Schema.define(version: 20130802111636) do
14+ActiveRecord::Schema.define(version: 20131025183439) do
1515
1616 create_table "dl_log_entries", force: true do |t|
1717 t.string "ident"
@@ -47,6 +47,16 @@ ActiveRecord::Schema.define(version: 20130802111636) do
4747 add_index "navi_voices", ["dlcount"], name: "index_navi_voices_on_dlcount"
4848 add_index "navi_voices", ["rating", "disabled"], name: "index_navi_voices_on_rating_and_disabled"
4949
50+ create_table "news", force: true do |t|
51+ t.string "title", default: "", null: false
52+ t.text "body", default: ""
53+ t.boolean "skip_headline", default: false, null: false
54+ t.datetime "created_at"
55+ t.datetime "updated_at"
56+ end
57+
58+ add_index "news", ["created_at"], name: "index_news_on_created_at"
59+
5060 create_table "ratings", force: true do |t|
5161 t.string "ident"
5262 t.integer "navi_voice_id"
--- /dev/null
+++ b/spec/controllers/news_controller_spec.rb
@@ -0,0 +1,160 @@
1+require 'spec_helper'
2+
3+# This spec was generated by rspec-rails when you ran the scaffold generator.
4+# It demonstrates how one might use RSpec to specify the controller code that
5+# was generated by Rails when you ran the scaffold generator.
6+#
7+# It assumes that the implementation code is generated by the rails scaffold
8+# generator. If you are using any extension libraries to generate different
9+# controller code, this generated spec may or may not pass.
10+#
11+# It only uses APIs available in rails and/or rspec-rails. There are a number
12+# of tools you can use to make these specs even more expressive, but we're
13+# sticking to rails and rspec-rails APIs to keep things simple and stable.
14+#
15+# Compared to earlier versions of this generator, there is very limited use of
16+# stubs and message expectations in this spec. Stubs are only used when there
17+# is no simpler way to get a handle on the object needed for the example.
18+# Message expectations are only used when there is no simpler way to specify
19+# that an instance is receiving a specific message.
20+
21+describe NewsController do
22+
23+ # This should return the minimal set of attributes required to create a valid
24+ # News. As you add validations to News, be sure to
25+ # adjust the attributes here as well.
26+ let(:valid_attributes) { { "title" => "MyString" } }
27+
28+ # This should return the minimal set of values that should be in the session
29+ # in order to pass any filters (e.g. authentication) defined in
30+ # NewsController. Be sure to keep this updated too.
31+ let(:valid_session) { {} }
32+
33+ describe "GET index" do
34+ it "assigns all news as @news" do
35+ news = News.create! valid_attributes
36+ get :index, {}, valid_session
37+ assigns(:news).should eq([news])
38+ end
39+ end
40+
41+ describe "GET show" do
42+ it "assigns the requested news as @news" do
43+ news = News.create! valid_attributes
44+ get :show, {:id => news.to_param}, valid_session
45+ assigns(:news).should eq(news)
46+ end
47+ end
48+
49+ describe "GET new" do
50+ it "assigns a new news as @news" do
51+ get :new, {}, valid_session
52+ assigns(:news).should be_a_new(News)
53+ end
54+ end
55+
56+ describe "GET edit" do
57+ it "assigns the requested news as @news" do
58+ news = News.create! valid_attributes
59+ get :edit, {:id => news.to_param}, valid_session
60+ assigns(:news).should eq(news)
61+ end
62+ end
63+
64+ describe "POST create" do
65+ describe "with valid params" do
66+ it "creates a new News" do
67+ expect {
68+ post :create, {:news => valid_attributes}, valid_session
69+ }.to change(News, :count).by(1)
70+ end
71+
72+ it "assigns a newly created news as @news" do
73+ post :create, {:news => valid_attributes}, valid_session
74+ assigns(:news).should be_a(News)
75+ assigns(:news).should be_persisted
76+ end
77+
78+ it "redirects to the created news" do
79+ post :create, {:news => valid_attributes}, valid_session
80+ response.should redirect_to(News.last)
81+ end
82+ end
83+
84+ describe "with invalid params" do
85+ it "assigns a newly created but unsaved news as @news" do
86+ # Trigger the behavior that occurs when invalid params are submitted
87+ News.any_instance.stub(:save).and_return(false)
88+ post :create, {:news => { "title" => "invalid value" }}, valid_session
89+ assigns(:news).should be_a_new(News)
90+ end
91+
92+ it "re-renders the 'new' template" do
93+ # Trigger the behavior that occurs when invalid params are submitted
94+ News.any_instance.stub(:save).and_return(false)
95+ post :create, {:news => { "title" => "invalid value" }}, valid_session
96+ response.should render_template("new")
97+ end
98+ end
99+ end
100+
101+ describe "PUT update" do
102+ describe "with valid params" do
103+ it "updates the requested news" do
104+ news = News.create! valid_attributes
105+ # Assuming there are no other news in the database, this
106+ # specifies that the News created on the previous line
107+ # receives the :update_attributes message with whatever params are
108+ # submitted in the request.
109+ News.any_instance.should_receive(:update).with({ "title" => "MyString" })
110+ put :update, {:id => news.to_param, :news => { "title" => "MyString" }}, valid_session
111+ end
112+
113+ it "assigns the requested news as @news" do
114+ news = News.create! valid_attributes
115+ put :update, {:id => news.to_param, :news => valid_attributes}, valid_session
116+ assigns(:news).should eq(news)
117+ end
118+
119+ it "redirects to the news" do
120+ news = News.create! valid_attributes
121+ put :update, {:id => news.to_param, :news => valid_attributes}, valid_session
122+ response.should redirect_to(news)
123+ end
124+ end
125+
126+ describe "with invalid params" do
127+ it "assigns the news as @news" do
128+ news = News.create! valid_attributes
129+ # Trigger the behavior that occurs when invalid params are submitted
130+ News.any_instance.stub(:save).and_return(false)
131+ put :update, {:id => news.to_param, :news => { "title" => "invalid value" }}, valid_session
132+ assigns(:news).should eq(news)
133+ end
134+
135+ it "re-renders the 'edit' template" do
136+ news = News.create! valid_attributes
137+ # Trigger the behavior that occurs when invalid params are submitted
138+ News.any_instance.stub(:save).and_return(false)
139+ put :update, {:id => news.to_param, :news => { "title" => "invalid value" }}, valid_session
140+ response.should render_template("edit")
141+ end
142+ end
143+ end
144+
145+ describe "DELETE destroy" do
146+ it "destroys the requested news" do
147+ news = News.create! valid_attributes
148+ expect {
149+ delete :destroy, {:id => news.to_param}, valid_session
150+ }.to change(News, :count).by(-1)
151+ end
152+
153+ it "redirects to the news list" do
154+ news = News.create! valid_attributes
155+ delete :destroy, {:id => news.to_param}, valid_session
156+ response.should redirect_to(news_index_url)
157+ end
158+ end
159+
160+end
--- /dev/null
+++ b/spec/helpers/news_helper_spec.rb
@@ -0,0 +1,15 @@
1+require 'spec_helper'
2+
3+# Specs in this file have access to a helper object that includes
4+# the NewsHelper. For example:
5+#
6+# describe NewsHelper do
7+# describe "string concat" do
8+# it "concats two strings with spaces" do
9+# expect(helper.concat_strings("this","that")).to eq("this that")
10+# end
11+# end
12+# end
13+describe NewsHelper do
14+ pending "add some examples to (or delete) #{__FILE__}"
15+end
--- /dev/null
+++ b/spec/models/news_spec.rb
@@ -0,0 +1,5 @@
1+require 'spec_helper'
2+
3+describe News do
4+ pending "add some examples to (or delete) #{__FILE__}"
5+end
--- /dev/null
+++ b/spec/requests/news_spec.rb
@@ -0,0 +1,11 @@
1+require 'spec_helper'
2+
3+describe "News" do
4+ describe "GET /news" do
5+ it "works! (now write some real specs)" do
6+ # Run the generator again with the --webrat flag if you want to use webrat methods/matchers
7+ get news_index_path
8+ response.status.should be(200)
9+ end
10+ end
11+end
--- /dev/null
+++ b/spec/routing/news_routing_spec.rb
@@ -0,0 +1,35 @@
1+require "spec_helper"
2+
3+describe NewsController do
4+ describe "routing" do
5+
6+ it "routes to #index" do
7+ get("/news").should route_to("news#index")
8+ end
9+
10+ it "routes to #new" do
11+ get("/news/new").should route_to("news#new")
12+ end
13+
14+ it "routes to #show" do
15+ get("/news/1").should route_to("news#show", :id => "1")
16+ end
17+
18+ it "routes to #edit" do
19+ get("/news/1/edit").should route_to("news#edit", :id => "1")
20+ end
21+
22+ it "routes to #create" do
23+ post("/news").should route_to("news#create")
24+ end
25+
26+ it "routes to #update" do
27+ put("/news/1").should route_to("news#update", :id => "1")
28+ end
29+
30+ it "routes to #destroy" do
31+ delete("/news/1").should route_to("news#destroy", :id => "1")
32+ end
33+
34+ end
35+end
--- /dev/null
+++ b/spec/views/news/edit.html.haml_spec.rb
@@ -0,0 +1,22 @@
1+require 'spec_helper'
2+
3+describe "news/edit" do
4+ before(:each) do
5+ @news = assign(:news, stub_model(News,
6+ :title => "MyString",
7+ :body => "MyText",
8+ :skip_headline => false
9+ ))
10+ end
11+
12+ it "renders the edit news form" do
13+ render
14+
15+ # Run the generator again with the --webrat flag if you want to use webrat matchers
16+ assert_select "form[action=?][method=?]", news_path(@news), "post" do
17+ assert_select "input#news_title[name=?]", "news[title]"
18+ assert_select "textarea#news_body[name=?]", "news[body]"
19+ assert_select "input#news_skip_headline[name=?]", "news[skip_headline]"
20+ end
21+ end
22+end
--- /dev/null
+++ b/spec/views/news/index.html.haml_spec.rb
@@ -0,0 +1,26 @@
1+require 'spec_helper'
2+
3+describe "news/index" do
4+ before(:each) do
5+ assign(:news, [
6+ stub_model(News,
7+ :title => "Title",
8+ :body => "MyText",
9+ :skip_headline => false
10+ ),
11+ stub_model(News,
12+ :title => "Title",
13+ :body => "MyText",
14+ :skip_headline => false
15+ )
16+ ])
17+ end
18+
19+ it "renders a list of news" do
20+ render
21+ # Run the generator again with the --webrat flag if you want to use webrat matchers
22+ assert_select "tr>td", :text => "Title".to_s, :count => 2
23+ assert_select "tr>td", :text => "MyText".to_s, :count => 2
24+ assert_select "tr>td", :text => false.to_s, :count => 2
25+ end
26+end
--- /dev/null
+++ b/spec/views/news/new.html.haml_spec.rb
@@ -0,0 +1,22 @@
1+require 'spec_helper'
2+
3+describe "news/new" do
4+ before(:each) do
5+ assign(:news, stub_model(News,
6+ :title => "MyString",
7+ :body => "MyText",
8+ :skip_headline => false
9+ ).as_new_record)
10+ end
11+
12+ it "renders new news form" do
13+ render
14+
15+ # Run the generator again with the --webrat flag if you want to use webrat matchers
16+ assert_select "form[action=?][method=?]", news_index_path, "post" do
17+ assert_select "input#news_title[name=?]", "news[title]"
18+ assert_select "textarea#news_body[name=?]", "news[body]"
19+ assert_select "input#news_skip_headline[name=?]", "news[skip_headline]"
20+ end
21+ end
22+end
--- /dev/null
+++ b/spec/views/news/show.html.haml_spec.rb
@@ -0,0 +1,19 @@
1+require 'spec_helper'
2+
3+describe "news/show" do
4+ before(:each) do
5+ @news = assign(:news, stub_model(News,
6+ :title => "Title",
7+ :body => "MyText",
8+ :skip_headline => false
9+ ))
10+ end
11+
12+ it "renders attributes in <p>" do
13+ render
14+ # Run the generator again with the --webrat flag if you want to use webrat matchers
15+ rendered.should match(/Title/)
16+ rendered.should match(/MyText/)
17+ rendered.should match(/false/)
18+ end
19+end