fic_tracker/lib/fic_tracker/models/chapter.rb

126 lines
2.8 KiB
Ruby

# frozen_string_literal: true
require 'digest'
module FicTracker::Models
class Chapter < Sequel::Model
# 3/day
CONTENT_REFRESH_INTERVAL = 12 * 60 * 60
CONTENT_CACHE_TIME = 14 * 24 * 60 * 60
plugin :serialization, :json, :data
many_to_one :story
def after_create
if @content
key = cache_key + [:content]
FicTracker.cache.set(key, @content, CONTENT_CACHE_TIME)
end
if @content_type
key = cache_key + [:content_type]
FicTracker.cache.set(key, @content_type, CONTENT_CACHE_TIME)
end
end
def allow_upsert!
insert_conflict(
target: [:story_id, :index],
update: {
slug: Sequel[:excluded][:slug],
etag: Sequel[:excluded][:etag],
name: Sequel[:excluded][:name],
url: Sequel[:excluded][:url],
published_at: Sequel[:excluded][:published_at],
updated_at: Sequel[:excluded][:updated_at],
last_refresh: Sequel[:excluded][:last_refresh],
data: Sequel[:excluded][:data],
}
)
end
def to_s
return "Chapter #{index}" unless name
"Chapter #{index}: #{name}"
end
def backend
story&.backend
end
def content?
return true if @content
return false unless cache_key
key = cache_key + [:content]
FicTracker.cache.has?(key)
end
def content
return @content if @content
return unless cache_key
key = cache_key + [:content]
@content ||= FicTracker.cache.get(key)
refresh_content! unless @content
@content
end
def content=(content)
if cache_key
key = cache_key + [:content]
FicTracker.cache.set(key, content, CONTENT_CACHE_TIME)
end
@content = content
end
def content_type?
return true if @content_type
return false unless cache_key
key = cache_key + [:content]
FicTracker.cache.has?(key)
end
def content_type
return @content_type if @content_type
return unless cache_key
key = cache_key + [:content_type]
@content_type ||= FicTracker.cache.get(key)
refresh_content! unless @content_type
@content_type
end
def content_type=(type)
if cache_key
key = cache_key + [:content_type]
FicTracker.cache.set(key, type, CONTENT_CACHE_TIME)
end
@content_type = type
end
def cache_key
return unless backend
backend.cache_key + [:c, slug]
end
def refresh_content
return unless backend && needs_content_refresh?
refresh_content!
end
def refresh_content!
backend.load_chapter(self, story)
end
def needs_content_refresh?
Time.now - (last_refresh || Time.at(0)) >= CONTENT_REFRESH_INTERVAL
end
end
end