This commit is contained in:
@@ -173,8 +173,8 @@ class PostsController < ApplicationController
|
||||
return head :unauthorized unless current_user
|
||||
return head :forbidden unless current_user.gte_member?
|
||||
|
||||
force = truthy_param?(params[:force])
|
||||
merge = truthy_param?(params[:merge])
|
||||
force = bool?(:force)
|
||||
merge = bool?(:merge)
|
||||
return head :bad_request if force && merge
|
||||
|
||||
base_version_no = nil
|
||||
@@ -201,15 +201,14 @@ class PostsController < ApplicationController
|
||||
base_snapshot = post_snapshot_from_version(base_version)
|
||||
current_snapshot = post_snapshot_from_record(post)
|
||||
end
|
||||
incoming_snapshot = post_incoming_snapshot(post,
|
||||
title:,
|
||||
incoming_snapshot = post_incoming_snapshot(title:,
|
||||
original_created_from:,
|
||||
original_created_before:,
|
||||
tag_names:,
|
||||
parent_post_ids:)
|
||||
|
||||
snapshot_to_apply =
|
||||
if post.version_no == base_version_no || force
|
||||
if force || post.version_no == base_version_no || current_snapshot == base_snapshot
|
||||
incoming_snapshot
|
||||
else
|
||||
changes = post_snapshot_changes(base_snapshot, current_snapshot, incoming_snapshot)
|
||||
@@ -448,30 +447,36 @@ class PostsController < ApplicationController
|
||||
version_no
|
||||
end
|
||||
|
||||
def truthy_param?(value) = ActiveModel::Type::Boolean.new.cast(value)
|
||||
|
||||
def post_snapshot_from_version version
|
||||
{ title: version.title,
|
||||
original_created_from: snapshot_time(version.original_created_from),
|
||||
original_created_before: snapshot_time(version.original_created_before),
|
||||
tag_names: version.tags.to_s.split.filter { !(_1.start_with?('nico:')) }.sort,
|
||||
tag_names: editable_tag_names_from_version(version),
|
||||
parent_post_ids: snapshot_parent_post_ids_from_version(version) }
|
||||
end
|
||||
|
||||
def editable_tag_names_from_version version
|
||||
version.tags.to_s.split.reject { |name| name.downcase.start_with?('nico:') }.sort
|
||||
end
|
||||
|
||||
def post_snapshot_from_record post
|
||||
{ title: post.title,
|
||||
original_created_from: snapshot_time(post.original_created_from),
|
||||
original_created_before: snapshot_time(post.original_created_before),
|
||||
tag_names: post.tags.joins(:tag_name).order('tag_names.name').pluck('tag_names.name'),
|
||||
tag_names: editable_tag_names_from_post(post),
|
||||
parent_post_ids: post.parent_posts.order(:id).pluck(:id) }
|
||||
end
|
||||
|
||||
def post_incoming_snapshot post, title:, original_created_from:, original_created_before:,
|
||||
tag_names:, parent_post_ids:
|
||||
def editable_tag_names_from_post post
|
||||
post.tags.not_nico.joins(:tag_name).order('tag_names.name').pluck('tag_names.name')
|
||||
end
|
||||
|
||||
def post_incoming_snapshot title:, original_created_from:, original_created_before:,
|
||||
tag_names:, parent_post_ids:
|
||||
{ title:,
|
||||
original_created_from: snapshot_time(original_created_from),
|
||||
original_created_before: snapshot_time(original_created_before),
|
||||
tag_names: incoming_tag_names_for_snapshot(post, tag_names),
|
||||
tag_names: incoming_tag_names_for_snapshot(tag_names),
|
||||
parent_post_ids: parent_post_ids.sort }
|
||||
end
|
||||
|
||||
@@ -494,44 +499,10 @@ class PostsController < ApplicationController
|
||||
value.to_s
|
||||
end
|
||||
|
||||
def incoming_tag_names_for_snapshot post, raw_tag_names
|
||||
manual_names = normalised_manual_tag_names_for_snapshot(raw_tag_names)
|
||||
def incoming_tag_names_for_snapshot raw_tag_names
|
||||
tags = Tag.normalise_tags!(raw_tag_names, with_tagme: false)
|
||||
|
||||
existing_tags =
|
||||
Tag
|
||||
.joins(:tag_name)
|
||||
.where(tag_names: { name: manual_names })
|
||||
.to_a
|
||||
|
||||
expanded_names = Tag.expand_parent_tags(existing_tags).map(&:name)
|
||||
|
||||
(manual_names + expanded_names).uniq.sort
|
||||
end
|
||||
|
||||
def normalised_manual_tag_names_for_snapshot raw_tag_names
|
||||
if raw_tag_names.any? { |name| name.downcase.start_with?('nico:') }
|
||||
raise Tag::NicoTagNormalisationError
|
||||
end
|
||||
|
||||
pairs = raw_tag_names.map do |raw_name|
|
||||
prefix, category =
|
||||
Tag::CATEGORY_PREFIXES.find { |p, _| raw_name.downcase.start_with?(p) } || ['', nil]
|
||||
|
||||
name = TagName.canonicalise(raw_name.sub(/\A#{ Regexp.escape(prefix) }/i, '')).first
|
||||
|
||||
[name, category]
|
||||
end
|
||||
|
||||
names = pairs.map(&:first)
|
||||
|
||||
has_deerjikist = pairs.any? do |name, category|
|
||||
category == :deerjikist ||
|
||||
Tag.joins(:tag_name).where(category: :deerjikist, tag_names: { name: }).exists?
|
||||
end
|
||||
|
||||
names << Tag.no_deerjikist.name unless has_deerjikist
|
||||
|
||||
names.uniq.sort
|
||||
Tag.expand_parent_tags(tags).map(&:name).uniq.sort
|
||||
end
|
||||
|
||||
def post_conflict_json post:, base_version_no:, base_snapshot:,
|
||||
@@ -618,29 +589,53 @@ class PostsController < ApplicationController
|
||||
original_created_from: snapshot[:original_created_from],
|
||||
original_created_before: snapshot[:original_created_before])
|
||||
|
||||
tags = Tag.normalise_tags!(snapshot[:tag_names], with_tagme: false)
|
||||
TagVersioning.record_tag_snapshots!(tags, created_by_user: current_user)
|
||||
editable_tags = Tag.normalise_tags!(snapshot[:tag_names], with_tagme: false)
|
||||
TagVersioning.record_tag_snapshots!(editable_tags, created_by_user: current_user)
|
||||
|
||||
readonly_tags = post.tags.nico.to_a
|
||||
|
||||
tags = readonly_tags + editable_tags
|
||||
tags = Tag.expand_parent_tags(tags)
|
||||
sync_post_tags!(post, tags)
|
||||
|
||||
sync_post_tags!(post, tags)
|
||||
sync_parent_posts!(post, snapshot[:parent_post_ids])
|
||||
|
||||
PostVersionRecorder.record!(post:, event_type: :update, created_by_user: current_user)
|
||||
end
|
||||
|
||||
def merge_post_snapshots base_snapshot, current_snapshot, incoming_snapshot
|
||||
[:title, :original_created_from, :original_created_before, :tag_names, :parent_post_ids].map {
|
||||
[_1, merge_scaler_snapshot_value(base_snapshot[_1],
|
||||
[:title, :original_created_from, :original_created_before].map {
|
||||
[_1, merge_scalar_snapshot_value(base_snapshot[_1],
|
||||
current_snapshot[_1],
|
||||
incoming_snapshot[_1])]
|
||||
}.to_h
|
||||
}.to_h.merge([:tag_names, :parent_post_ids].map {
|
||||
[_1, merge_set_snapshot_value(base_snapshot[_1],
|
||||
current_snapshot[_1],
|
||||
incoming_snapshot[_1])]
|
||||
}.to_h)
|
||||
end
|
||||
|
||||
def merge_scaler_snapshot_value base, current, mine
|
||||
def merge_scalar_snapshot_value base, current, mine
|
||||
return mine if current == base
|
||||
return current if mine == base || current == mine
|
||||
|
||||
raise ArgumentError, '競合してゐる項目はマージできません.'
|
||||
end
|
||||
|
||||
def merge_set_snapshot_value base, current, mine
|
||||
base = base.to_a
|
||||
current = current.to_a
|
||||
mine = mine.to_a
|
||||
|
||||
added_by_current = current - base
|
||||
removed_by_current = base - current
|
||||
added_by_me = mine - base
|
||||
removed_by_me = base - mine
|
||||
|
||||
merged = base + added_by_current + added_by_me
|
||||
merged -= removed_by_current
|
||||
merged -= removed_by_me
|
||||
|
||||
merged.uniq.sort
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user