このコミットが含まれているのは:
@@ -56,7 +56,38 @@ class Post < ApplicationRecord
|
||||
super(options).merge(thumbnail: nil)
|
||||
end
|
||||
|
||||
def snapshot_tag_names = tags.joins(:tag_name).order('tag_names.name').pluck('tag_names.name')
|
||||
def snapshot_tag_names
|
||||
post_tags
|
||||
.kept
|
||||
.joins(tag: :tag_name)
|
||||
.includes(:sections, tag: :tag_name)
|
||||
.order('tag_names.name')
|
||||
.map do |post_tag|
|
||||
name = post_tag.tag.tag_name.name
|
||||
sections = post_tag.sections.sort_by(&:begin_ms)
|
||||
|
||||
next name if sections.empty?
|
||||
|
||||
"#{ name }#{ sections.map { Post.section_literal(_1) }.join }"
|
||||
end
|
||||
end
|
||||
|
||||
def self.section_literal section
|
||||
"[#{ Post.ms_to_time(section.begin_ms) }-#{ Post.ms_to_time(section.end_ms) }]"
|
||||
end
|
||||
|
||||
def self.ms_to_time ms
|
||||
total_s = ms / 1_000
|
||||
s = total_s % 60
|
||||
min = (total_s / 60) % 60
|
||||
h = total_s / 3_600
|
||||
|
||||
if h.positive?
|
||||
'%d:%02d:%02d' % [h, min, s]
|
||||
else
|
||||
'%d:%02d' % [min, s]
|
||||
end
|
||||
end
|
||||
|
||||
def snapshot_parent_post_ids = parents.order(:id).pluck(:id)
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@ class PostTag < ApplicationRecord
|
||||
belongs_to :created_user, class_name: 'User', optional: true
|
||||
belongs_to :deleted_user, class_name: 'User', optional: true
|
||||
|
||||
has_many :sections, -> { order(:begin_ms) }, class_name: 'PostTagSection',
|
||||
foreign_key: [:post_id, :tag_id],
|
||||
primary_key: [:post_id, :tag_id],
|
||||
dependent: :delete_all,
|
||||
inverse_of: :post_tag
|
||||
|
||||
validates :post_id, presence: true
|
||||
validates :tag_id, presence: true
|
||||
validates :post_id, uniqueness: {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
class PostTagSection < ApplicationRecord
|
||||
self.primary_key = :post_id, :tag_id, :begin_ms
|
||||
|
||||
belongs_to :post
|
||||
belongs_to :tag
|
||||
|
||||
belongs_to :post_tag, -> { kept }, foreign_key: [:post_id, :tag_id],
|
||||
primary_key: [:post_id, :tag_id],
|
||||
inverse_of: :sections,
|
||||
optional: true
|
||||
|
||||
validates :post_id, presence: true
|
||||
validates :tag_id, presence: true
|
||||
|
||||
validates :begin_ms, presence: true,
|
||||
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
|
||||
validates :end_ms, presence: true,
|
||||
numericality: { only_integer: true, greater_than: :begin_ms }
|
||||
end
|
||||
+44
-2
@@ -92,22 +92,45 @@ class Tag < ApplicationRecord
|
||||
|
||||
def self.normalise_tags! tag_names, with_tagme: true,
|
||||
with_no_deerjikist: true,
|
||||
deny_nico: true
|
||||
deny_nico: true,
|
||||
with_sections: false
|
||||
if deny_nico && tag_names.any? { |n| n.downcase.start_with?('nico:') }
|
||||
raise NicoTagNormalisationError
|
||||
end
|
||||
|
||||
sections = { }
|
||||
tags = tag_names.map do |name|
|
||||
pf, cat = CATEGORY_PREFIXES.find { |p, _| name.downcase.start_with?(p) } || ['', nil]
|
||||
|
||||
name = TagName.canonicalise(name.sub(/\A#{ pf }/i, '')).first
|
||||
|
||||
sections_by_tag = []
|
||||
while n = name.sub!(/^(\S*?)\[([0-9:.]*?)-([0-9:.]*?)\](\S*?)$/, '\1\4 \2 \3')
|
||||
name, *section_raw = n.split
|
||||
|
||||
begin_ms, end_ms = section_raw.map { time_to_ms(_1) }
|
||||
next if begin_ms == end_ms
|
||||
|
||||
begin_ms, end_ms = end_ms, begin_ms if begin_ms > end_ms
|
||||
|
||||
sections_by_tag << [begin_ms, end_ms]
|
||||
end
|
||||
|
||||
find_or_create_by_tag_name!(name, category: (cat || :general)).tap do |tag|
|
||||
tag.update!(category: cat) if cat && tag.category != cat
|
||||
sections[tag.id] = sections_by_tag if sections_by_tag.present?
|
||||
end
|
||||
end
|
||||
|
||||
tags << Tag.tagme if with_tagme && tags.size < 10 && tags.none?(Tag.tagme)
|
||||
tags << Tag.no_deerjikist if with_no_deerjikist && tags.all? { |t| !(t.deerjikist?) }
|
||||
tags.uniq(&:id)
|
||||
tags.uniq!(&:id)
|
||||
|
||||
if with_sections
|
||||
{ tags:, sections: }
|
||||
else
|
||||
tags
|
||||
end
|
||||
end
|
||||
|
||||
def self.expand_parent_tags tags
|
||||
@@ -228,4 +251,23 @@ class Tag < ApplicationRecord
|
||||
errors.add :category, 'ニジラーと紐づいてゐるタグはニジラー・カテゴリである必要があります.'
|
||||
end
|
||||
end
|
||||
|
||||
def self.time_to_ms str
|
||||
parts = str.split(':')
|
||||
|
||||
s_part = parts.pop
|
||||
s, ms = s_part.split('.')
|
||||
|
||||
total_s = s.to_i
|
||||
|
||||
if parts.length >= 1
|
||||
total_s += parts.pop.to_i * 60
|
||||
end
|
||||
|
||||
if parts.length >= 1
|
||||
total_s += parts.pop.to_i * 3_600
|
||||
end
|
||||
|
||||
total_s * 1_000 + ms.to_s.ljust(3, '0')[0, 3].to_i
|
||||
end
|
||||
end
|
||||
|
||||
新しい課題から参照
ユーザをブロックする