Permalink
Browse files

Merge branch 'category'

  • Loading branch information...
yhara committed May 15, 2017
2 parents ff0036d + 7f034cb commit 3073924fbdb4c8f53dee6c457fd7de1a9048d48d
View
@@ -3,18 +3,12 @@ require 'irb'
require 'securerandom'
require 'bcrypt'
require 'io/console'
require_relative 'app/nlog2.rb'
$config = YAML.load_file("config/nlog2.yml")
namespace :db do
task :load_config do
require "./app"
end
end
desc "Open irb with ActiveRecord"
task :console do
require "./app"
ARGV.clear # To prevent `Errno::ENOENT: No such file or directory @ rb_sysopen - console`
IRB.start
end
View
@@ -0,0 +1,108 @@
class NLog2 < Sinatra::Base
# View Helpers
helpers do
KEEP_KEYS = [:category, :per]
def keep_params
return KEEP_KEYS.map{|s| [s, params[s]]}
.reject{|k, v| v.nil?}
.to_h
end
def previous_page_path(scope)
return nil if scope.first_page?
query = keep_params.merge(page: scope.prev_page)
return env['PATH_INFO'] + (query.empty? ? '' : "?#{query.to_query}")
end
def next_page_path(scope)
return nil if scope.last_page?
query = keep_params.merge(page: scope.next_page)
return env['PATH_INFO'] + (query.empty? ? '' : "?#{query.to_query}")
end
end
def per_in(rng)
return rng.end if params[:per].nil?
per = params[:per].to_i
return rng.begin if per < rng.begin
return rng.end if per > rng.end
return per
end
get '/' do
@posts = Post.published
.where(permanent: false)
.order(datetime: :desc)
.page(params[:page]).per(per_in(1..10))
slim :index
end
get '/_list' do
if (cat_name = params[:category])
@category = Category.find_by!(name: cat_name)
else
@category = nil
end
@posts = Post.published
.with_category(@category)
.where(permanent: false)
.order(datetime: :desc)
.page(params[:page]).per(per_in(1..100))
@articles = Post.published
.with_category(@category)
.where(permanent: true)
.order(updated_at: :desc)
slim :list
end
get %r{/(\d\d\d\d)/(\d\d)/(\d\d)/(.+)} do
*date, slug_or_id = *params[:captures]
d = Date.new(*date.map(&:to_i))
range = d.in_time_zone...(d+1).in_time_zone
cond = Post.published.where(permanent: false, slug: slug_or_id)
if (id = Integer(slug_or_id) rescue nil)
cond = cond.or(Post.where(id: id))
end
@post = cond.where(datetime: range).first or raise Sinatra::NotFound
@title = @post.title
slim :show
end
# Permanent articles (must not start with `_')
get %r{/([^_]\w+)} do |name|
@post = Post.published.where(permanent: true, slug: name).first
raise Sinatra::NotFound unless @post
@title = @post.title
slim :show
end
get '/screen.css' do
sass :screen # renders views/screen.sass as screen.css
end
get '/highlight.css' do
headers 'Content-Type' => 'text/css'
Rouge::Themes::Github.render(scope: '.highlight')
end
get '/_feed.xml' do
if params[:nodiary] == "1"
# Note: issues 404 if no such category
cat = Category.find_by!(name: "Diary")
@feed_posts = Post.published
.where(permanent: false)
.without_category(cat)
.order(datetime: :desc).limit(10)
@title_suffix = " (without diary)"
else
@feed_posts = Post.published
.where(permanent: false)
.order(datetime: :desc).limit(10)
@title_suffix = ""
end
builder :_feed
end
end
View
@@ -0,0 +1,43 @@
class NLog2 < Sinatra::Base
get '/_config/' do redirect '/_config' end
get '/_config' do
authenticate!
@flash = {}
slim :config
end
post '/_categories/' do
authenticate!
@flash = {}
category = Category.new(name: @params[:name])
if category.save
redirect '/_config'
else
@flash[:error] = "Failed to save record: #{category.errors.messages.inspect}"
slim :config
end
end
put '/_categories/:id' do
authenticate!
category = Category.find_by!(id: params[:id])
category.name = params[:name]
if category.save
redirect '/_config'
else
@flash[:error] = "Failed to save record: #{category.errors.messages.inspect}"
slim :config
end
end
delete '/_categories/:id' do
authenticate!
category = Category.find_by!(id: params[:id])
category.destroy
redirect '/_config'
end
end
View
@@ -0,0 +1,59 @@
class NLog2 < Sinatra::Base
get '/_edit' do redirect '/_edit/' end
get '/_edit/:id?' do
authenticate!
@flash = {}
if (id = params[:id])
@post = Post.find_by(id: id) or raise Sinatra::NotFound
else
@post = Post.new
@post.datetime = Time.now
end
@title = "Edit"
slim :edit
end
post '/_edit' do
authenticate!
@flash = {}
if (id = params[:id])
@post = Post.find_by(id: id) or raise Sinatra::NotFound
else
@post = Post.new
end
@post.permanent = (params[:permanent] == "yes")
@post.title = params[:title]
@post.slug = params[:slug]
@post.body = params[:body]
if (d = Time.zone.parse(params[:datetime]) rescue nil)
@post.datetime = d
else
@flash[:error] = "Failed to parse date: #{params[:datetime].inspect}"
@post.datetime = Time.now
end
@post.category = Category.find_by!(id: params[:category].to_i)
if params[:submit_by] == "Save" && !@flash[:error]
@post.published_at ||= Time.now
if @post.save
if @post.future?
@flash[:notice] = "Scheduled `#{@post.title}' to be posted at #{@post.author_datetime}"
@post = Post.new; @post.datetime = Time.now
slim :edit
else
redirect @post.path_to_show
end
else
@flash[:error] = "Failed to save record: #{@post.errors.messages.inspect}"
slim :edit
end
else
# Opt-out XSS Protection for this response, because it may contain
# <script> tag (eg. embedding SpeakerDeck) which the user has written.
headers "X-XSS-Protection" => "0"
@title = "Edit"
slim :edit
end
end
end
View
@@ -0,0 +1,13 @@
require 'active_record'
class Category < ActiveRecord::Base
has_many :posts
validates_uniqueness_of :name
NONE_TEXT = "(none)"
def self.list
Category.order(name: :asc).all
end
end
View
@@ -1,10 +1,23 @@
require 'active_record'
class Post < ActiveRecord::Base
belongs_to :category
validates_presence_of :body, :title, :datetime, :published_at
scope :published, ->{ where('datetime <= ?', Time.now) }
scope :future, ->{ where('datetime > ?', Time.now) }
scope :uncategorized, ->{ where('category_id IS NULL') }
scope :with_category, ->(cat){
if cat
where(category: cat)
else
all
end
}
scope :without_category, ->(cat){
where.not(category: cat).or(Post.where('category_id IS NULL'))
}
def permanent?
permanent
Oops, something went wrong.

0 comments on commit 3073924

Please sign in to comment.