このコミットが含まれているのは:
@@ -2,26 +2,25 @@ class WikiPagesController < ApplicationController
|
||||
rescue_from Wiki::Commit::Conflict, with: :render_wiki_conflict
|
||||
|
||||
def index
|
||||
# 互換性のための化石リソース
|
||||
# TODO: ヘルプ追加後にヘルプからも取得する作りに変更する.
|
||||
|
||||
title = params[:title].to_s.strip
|
||||
descriptions =
|
||||
TagDescription.where(language_code: 'ja')
|
||||
.includes(tag: :tag_names)
|
||||
pages = unmigrated_wiki_pages.includes(tag_name: :tag)
|
||||
|
||||
tag_groups = TagGroup.all
|
||||
if title.present?
|
||||
pattern = "%#{ ApplicationRecord.sanitize_sql_like(title) }%"
|
||||
descriptions = descriptions.joins(tag: :tag_names)
|
||||
.where(tag_names: { language_code: 'ja', primary_flg: true })
|
||||
.where('tag_names.name LIKE ?', pattern).limit(20)
|
||||
tag_groups = TagGroup.where("CONCAT('タググループ:', name) LIKE ?", pattern).limit(20)
|
||||
tag_groups = tag_groups.where(
|
||||
'CONCAT(?, name) LIKE ?', TagGroupRepr::PREFIX, pattern).limit(20)
|
||||
pages = pages.where('tag_names.name LIKE ?', pattern).limit(20)
|
||||
end
|
||||
|
||||
json = descriptions.map { |description| WikiPageRepr.tag_description(description) }
|
||||
json.concat(tag_groups.map { |tag_gorup| WikiPageRepr.tag_group(tag_group) })
|
||||
json.concat(tag_groups.map { WikiPageRepr.tag_group(_1) })
|
||||
json.concat(WikiPageRepr.base(pages))
|
||||
json = json.first(20) if title.present?
|
||||
render json:
|
||||
@@ -32,6 +31,9 @@ class WikiPagesController < ApplicationController
|
||||
|
||||
return render_wiki_page_by_tag_description tag_description if tag_description
|
||||
|
||||
tag_group = TagGroup.find_by(id: params[:id])
|
||||
return render_tag_group tag_group if tag_group
|
||||
|
||||
page = WikiPage.joins(:tag_name)
|
||||
.includes(tag_name: :tag)
|
||||
.find_by(id: params[:id])
|
||||
@@ -42,6 +44,13 @@ class WikiPagesController < ApplicationController
|
||||
def show_by_title
|
||||
title = params[:title].to_s.strip
|
||||
|
||||
if title.start_with?(TagGroupRepr::PREFIX)
|
||||
name = title.delete_prefix(TagGroupRepr::PREFIX)
|
||||
tag_group = TagGroup.find_by(name:)
|
||||
return render_tag_group tag_group if tag_group
|
||||
return head :not_found
|
||||
end
|
||||
|
||||
tag_description = tag_description_by_title(title)
|
||||
|
||||
return render_wiki_page_by_tag_description tag_description if tag_description
|
||||
@@ -55,12 +64,17 @@ class WikiPagesController < ApplicationController
|
||||
|
||||
def exists
|
||||
return head :no_content if TagDescription.exists?(id: params[:id])
|
||||
return head :no_content if TagGroup.exists?(id: params[:id])
|
||||
|
||||
head WikiPage.exists?(id: params[:id]) ? :no_content : :not_found
|
||||
end
|
||||
|
||||
def exists_by_title
|
||||
title = params[:title].to_s.strip
|
||||
if title.start_with?(TagGroupRepr::PREFIX)
|
||||
exists = TagGroup.exists?(name: title.delete_prefix(TagGroupRepr::PREFIX))
|
||||
return head exists ? :no_content : :not_found
|
||||
end
|
||||
return head :no_content if tag_description_by_title(title)
|
||||
|
||||
exists = WikiPage.joins(:tag_name).exists?(tag_names: { name: title })
|
||||
@@ -81,29 +95,33 @@ class WikiPagesController < ApplicationController
|
||||
to_rev = to ? versions.find(to) : versions.find_by!(version_no: description.version_no)
|
||||
resource = WikiPageRepr.tag_description(description)
|
||||
else
|
||||
page = WikiPage.joins(:tag_name).includes(tag_name: :tag).find(id)
|
||||
from_rev = from && page.wiki_revisions.find(from)
|
||||
to_rev = to ? page.wiki_revisions.find(to) : page.current_revision
|
||||
if ((from_rev && !from_rev.content?) || !to_rev&.content?)
|
||||
return render_unprocessable_entity('差分を表示できない版です.')
|
||||
tag_group = TagGroup.find_by(id:)
|
||||
if tag_group
|
||||
from_rev = from && group_version(tag_group, from)
|
||||
to_rev = to ? group_version(tag_group, to) : current_group_version(tag_group)
|
||||
return head :not_found if (from && !from_rev) || !to_rev
|
||||
|
||||
from_body = from_rev && render_group_version(from_rev)
|
||||
to_body = render_group_version(to_rev)
|
||||
resource = { 'id' => tag_group.id,
|
||||
'title' => "#{ TagGroupRepr::PREFIX }#{ tag_group.name }",
|
||||
'deprecated_at' => nil }
|
||||
else
|
||||
page = WikiPage.joins(:tag_name).includes(tag_name: :tag).find(id)
|
||||
from_rev = from && page.wiki_revisions.find(from)
|
||||
to_rev = to ? page.wiki_revisions.find(to) : page.current_revision
|
||||
if ((from_rev && !from_rev.content?) || !to_rev&.content?)
|
||||
return render_unprocessable_entity('差分を表示できない版です.')
|
||||
end
|
||||
from_body = from_rev&.body
|
||||
to_body = to_rev.body
|
||||
resource = WikiPageRepr.base(page)
|
||||
end
|
||||
resource = WikiPageRepr.base(page)
|
||||
end
|
||||
|
||||
diffs = Diff::LCS.sdiff(from_rev&.body&.lines || [], to_rev.body.lines)
|
||||
diff_json = diffs.map { |change|
|
||||
case change.action
|
||||
when ?=
|
||||
{ type: 'context', content: change.old_element }
|
||||
when ?!
|
||||
[{ type: 'removed', content: change.old_element },
|
||||
{ type: 'added', content: change.new_element }]
|
||||
when ?+
|
||||
{ type: 'added', content: change.new_element }
|
||||
when ?-
|
||||
{ type: 'removed', content: change.old_element }
|
||||
end
|
||||
}.flatten.compact
|
||||
from_body ||= from_rev&.body
|
||||
to_body ||= to_rev.body
|
||||
diff_json = wiki_diff(from_body, to_body)
|
||||
|
||||
render json: { wiki_page_id: resource.fetch('id'),
|
||||
title: resource.fetch('title'),
|
||||
@@ -111,6 +129,8 @@ class WikiPagesController < ApplicationController
|
||||
older_revision_id: from_rev&.id,
|
||||
newer_revision_id: to_rev.id,
|
||||
diff: diff_json }
|
||||
rescue TagGroupMarkdownRenderer::UnsupportedStructure => error
|
||||
render_unprocessable_entity(error.message)
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -199,6 +219,11 @@ class WikiPagesController < ApplicationController
|
||||
return render json: description_changes(TagDescription.where(id: description.id))
|
||||
end
|
||||
|
||||
tag_group = id && TagGroup.find_by(id:)
|
||||
if tag_group
|
||||
return render json: tag_group_changes(TagGroupVersion.where(tag_group_id: tag_group.id))
|
||||
end
|
||||
|
||||
pages = id ? WikiPage.where(id:) : unmigrated_wiki_pages
|
||||
revisions = WikiRevision.joins(wiki_page: :tag_name)
|
||||
.where(wiki_page_id: pages.select(:id))
|
||||
@@ -217,14 +242,102 @@ class WikiPagesController < ApplicationController
|
||||
timestamp: rev.created_at }
|
||||
}
|
||||
unless id
|
||||
json.concat(tag_group_changes(TagGroupVersion.all))
|
||||
json.concat(description_changes(TagDescription.where(language_code: 'ja')))
|
||||
json.sort_by! { |row| -row[:revision_id] }
|
||||
json = json.each_with_index.sort_by do |row, index|
|
||||
[-row.fetch(:timestamp).to_f, index]
|
||||
end.map(&:first)
|
||||
end
|
||||
render json: json.first(200)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def render_tag_group group
|
||||
version = if params[:version].present?
|
||||
group_version(group, params[:version])
|
||||
else
|
||||
current_group_version(group)
|
||||
end
|
||||
return head :not_found unless version
|
||||
|
||||
representation = if params[:version].present?
|
||||
TagGroupRepr.historical(version)
|
||||
else
|
||||
TagGroupRepr.one(group)
|
||||
end
|
||||
render_group_representation(representation, version)
|
||||
end
|
||||
|
||||
def render_group_version version
|
||||
representation = TagGroupRepr.historical(version)
|
||||
TagGroupMarkdownRenderer.render(representation)
|
||||
end
|
||||
|
||||
def render_group_representation representation, version
|
||||
body = TagGroupMarkdownRenderer.render(representation)
|
||||
versions = TagGroupVersion.where(tag_group_id: version.tag_group_id)
|
||||
pred = versions.find_by(version_no: version.version_no - 1)&.id
|
||||
succ = versions.find_by(version_no: version.version_no + 1)&.id
|
||||
updated_at = version.created_at
|
||||
render json: {
|
||||
'id' => version.tag_group_id,
|
||||
'title' => "#{ TagGroupRepr::PREFIX }#{ representation.fetch('name') }",
|
||||
'deprecated_at' => nil,
|
||||
'body' => body,
|
||||
'revision_id' => version.id,
|
||||
'pred' => pred,
|
||||
'succ' => succ,
|
||||
'updated_at' => updated_at }
|
||||
rescue TagGroupMarkdownRenderer::UnsupportedStructure => error
|
||||
render_unprocessable_entity(error.message)
|
||||
end
|
||||
|
||||
def current_group_version group
|
||||
TagGroupVersion.find_by(tag_group_id: group.id, version_no: group.version_no)
|
||||
end
|
||||
|
||||
def group_version group, version_id
|
||||
TagGroupVersion.find_by(tag_group_id: group.id, id: version_id)
|
||||
end
|
||||
|
||||
def wiki_diff from_body, to_body
|
||||
diffs = Diff::LCS.sdiff(from_body.to_s.lines, to_body.to_s.lines)
|
||||
diffs.map { |change|
|
||||
case change.action
|
||||
when ?=
|
||||
{ type: 'context', content: change.old_element }
|
||||
when ?!
|
||||
[{ type: 'removed', content: change.old_element },
|
||||
{ type: 'added', content: change.new_element }]
|
||||
when ?+
|
||||
{ type: 'added', content: change.new_element }
|
||||
when ?-
|
||||
{ type: 'removed', content: change.old_element }
|
||||
end
|
||||
}.flatten.compact
|
||||
end
|
||||
|
||||
def tag_group_changes versions
|
||||
rows = versions.includes(:created_by_user).order(id: :desc).limit(200).to_a
|
||||
groups = TagGroup.where(id: rows.map(&:tag_group_id).uniq).index_by(&:id)
|
||||
predecessors = TagGroupVersion.where(tag_group_id: groups.keys,
|
||||
version_no: rows.map { _1.version_no - 1 })
|
||||
.pluck(:tag_group_id, :version_no, :id)
|
||||
.to_h { |group_id, number, version_id| [[group_id, number], version_id] }
|
||||
rows.map do |version|
|
||||
group = groups.fetch(version.tag_group_id)
|
||||
user = version.created_by_user
|
||||
{ revision_id: version.id,
|
||||
pred: predecessors[[group.id, version.version_no - 1]],
|
||||
succ: nil,
|
||||
wiki_page: { id: group.id, title: "#{ TagGroupRepr::PREFIX }#{ version.name }",
|
||||
deprecated_at: nil },
|
||||
user: user && { id: user.id, name: user.name },
|
||||
kind: 'content', message: nil, timestamp: version.created_at }
|
||||
end
|
||||
end
|
||||
|
||||
def render_wiki_page_or_404 page
|
||||
return head :not_found unless page
|
||||
|
||||
@@ -273,12 +386,11 @@ class WikiPagesController < ApplicationController
|
||||
|
||||
def unmigrated_wiki_pages
|
||||
descriptions = TagDescription.where(language_code: 'ja')
|
||||
tag_groups = TagGroup.all
|
||||
|
||||
WikiPage
|
||||
.joins(:tag_name)
|
||||
.where.not(id: descriptions.select(:id))
|
||||
.where.not(id: tag_groups.select(:id))
|
||||
.where.not('tag_names.name LIKE ?', "#{ TagGroupRepr::PREFIX }%")
|
||||
.where('tag_names.tag_id IS NULL OR tag_names.tag_id NOT IN (?)',
|
||||
descriptions.select(:tag_id))
|
||||
end
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする