diff options
Diffstat (limited to 'app/models')
| -rw-r--r-- | app/models/blog.rb | 55 | ||||
| -rw-r--r-- | app/models/ckeditor/asset.rb | 4 | ||||
| -rw-r--r-- | app/models/ckeditor/attachment_file.rb | 13 | ||||
| -rw-r--r-- | app/models/ckeditor/picture.rb | 14 | ||||
| -rw-r--r-- | app/models/comment.rb | 39 | ||||
| -rw-r--r-- | app/models/concerns/recordable.rb | 9 | ||||
| -rw-r--r-- | app/models/concerns/votable.rb | 51 | ||||
| -rw-r--r-- | app/models/game.rb | 13 | ||||
| -rw-r--r-- | app/models/global.rb | 20 | ||||
| -rw-r--r-- | app/models/link.rb | 15 | ||||
| -rw-r--r-- | app/models/quote.rb | 48 | ||||
| -rw-r--r-- | app/models/scrobble.rb | 2 | ||||
| -rw-r--r-- | app/models/stream.rb | 20 | ||||
| -rw-r--r-- | app/models/update.rb | 15 | ||||
| -rw-r--r-- | app/models/user.rb | 2 | ||||
| -rw-r--r-- | app/models/vote.rb | 5 |
16 files changed, 287 insertions, 38 deletions
| diff --git a/app/models/blog.rb b/app/models/blog.rb index 322a808..03c0619 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb | |||
| @@ -1,19 +1,62 @@ | |||
| 1 | class Blog < ApplicationRecord | 1 | class Blog < ApplicationRecord |
| 2 | has_many :records, as: :recordable, inverse_of: :recordable | 2 | include Recordable |
| 3 | include Votable | ||
| 4 | |||
| 5 | acts_as_taggable | ||
| 6 | |||
| 7 | has_many :comments | ||
| 8 | belongs_to :user | ||
| 9 | |||
| 10 | has_many_attached :images do |attachable| | ||
| 11 | attachable.variant :thumb, resize_to_limit: [300, 300] | ||
| 12 | end | ||
| 3 | 13 | ||
| 4 | validates :title, presence: true | 14 | validates :title, presence: true |
| 5 | validates :body, presence: true, if: :published | 15 | validates :body, presence: true, if: :published |
| 6 | validates :slug, presence: true, format: /\A[-a-z0-9]+\z/, if: :published | 16 | validates :slug, presence: true, format: /\A[-a-z0-9]+\z/, if: :published |
| 7 | 17 | validates :user, presence: true | |
| 8 | accepts_nested_attributes_for :records, allow_destroy: true | 18 | validates :images, content_type: ['image/png', 'image/jpeg', 'video/mp4', 'image/gif'] |
| 9 | 19 | ||
| 10 | before_validation :set_draft_title | 20 | before_validation :set_draft_title |
| 11 | before_save :set_published_at | 21 | before_save :set_published_at |
| 22 | after_save :send_webmentions | ||
| 12 | 23 | ||
| 13 | def path | 24 | def path |
| 14 | "/says/#{slug}" | 25 | "/says/#{slug}" |
| 15 | end | 26 | end |
| 16 | 27 | ||
| 28 | def taggable | ||
| 29 | self | ||
| 30 | end | ||
| 31 | |||
| 32 | def has_read_more | ||
| 33 | body.include?("<!--MORE-->") | ||
| 34 | end | ||
| 35 | |||
| 36 | def short_body | ||
| 37 | body[0..(body.index("<!--MORE-->")-1)] | ||
| 38 | end | ||
| 39 | |||
| 40 | def to_param | ||
| 41 | slug | ||
| 42 | end | ||
| 43 | |||
| 44 | def visible_date | ||
| 45 | if published | ||
| 46 | published_at | ||
| 47 | else | ||
| 48 | updated_at | ||
| 49 | end | ||
| 50 | end | ||
| 51 | |||
| 52 | def prev | ||
| 53 | Blog.where(published: true).where("published_at < ?", published_at).order(published_at: :desc).first | ||
| 54 | end | ||
| 55 | |||
| 56 | def next | ||
| 57 | Blog.where(published: true).where("published_at > ?", published_at).order(published_at: :asc).first | ||
| 58 | end | ||
| 59 | |||
| 17 | private | 60 | private |
| 18 | def set_draft_title | 61 | def set_draft_title |
| 19 | if self.title.blank? and not self.published | 62 | if self.title.blank? and not self.published |
| @@ -30,4 +73,10 @@ class Blog < ApplicationRecord | |||
| 30 | self.published_at = nil | 73 | self.published_at = nil |
| 31 | end | 74 | end |
| 32 | end | 75 | end |
| 76 | |||
| 77 | def send_webmentions | ||
| 78 | return unless self.published | ||
| 79 | |||
| 80 | SendWebmentionsJob.perform_later self | ||
| 81 | end | ||
| 33 | end | 82 | end |
| diff --git a/app/models/ckeditor/asset.rb b/app/models/ckeditor/asset.rb deleted file mode 100644 index cf636ed..0000000 --- a/app/models/ckeditor/asset.rb +++ /dev/null | |||
| @@ -1,4 +0,0 @@ | |||
| 1 | class Ckeditor::Asset < ActiveRecord::Base | ||
| 2 | include Ckeditor::Orm::ActiveRecord::AssetBase | ||
| 3 | include Ckeditor::Backend::Paperclip | ||
| 4 | end | ||
| diff --git a/app/models/ckeditor/attachment_file.rb b/app/models/ckeditor/attachment_file.rb deleted file mode 100644 index fe09132..0000000 --- a/app/models/ckeditor/attachment_file.rb +++ /dev/null | |||
| @@ -1,13 +0,0 @@ | |||
| 1 | class Ckeditor::AttachmentFile < Ckeditor::Asset | ||
| 2 | has_attached_file :data, | ||
| 3 | url: '/uploads/attachments/:id/:filename', | ||
| 4 | path: ':rails_root/public/uploads/attachments/:id/:filename' | ||
| 5 | |||
| 6 | validates_attachment_presence :data | ||
| 7 | validates_attachment_size :data, less_than: 100.megabytes | ||
| 8 | do_not_validate_attachment_file_type :data | ||
| 9 | |||
| 10 | def url_thumb | ||
| 11 | @url_thumb ||= Ckeditor::Utils.filethumb(filename) | ||
| 12 | end | ||
| 13 | end | ||
| diff --git a/app/models/ckeditor/picture.rb b/app/models/ckeditor/picture.rb deleted file mode 100644 index 02aa9b2..0000000 --- a/app/models/ckeditor/picture.rb +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | class Ckeditor::Picture < Ckeditor::Asset | ||
| 2 | has_attached_file :data, | ||
| 3 | url: '/uploads/pictures/:id/:style_:basename.:extension', | ||
| 4 | path: ':rails_root/public/uploads/pictures/:id/:style_:basename.:extension', | ||
| 5 | styles: { content: '800>', thumb: '118x100#' } | ||
| 6 | |||
| 7 | validates_attachment_presence :data | ||
| 8 | validates_attachment_size :data, less_than: 2.megabytes | ||
| 9 | validates_attachment_content_type :data, content_type: /\Aimage/ | ||
| 10 | |||
| 11 | def url_content | ||
| 12 | url(:content) | ||
| 13 | end | ||
| 14 | end | ||
| diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 0000000..b85f3b6 --- /dev/null +++ b/app/models/comment.rb | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | class Comment < ApplicationRecord | ||
| 2 | extend Enumerize | ||
| 3 | |||
| 4 | belongs_to :blog | ||
| 5 | |||
| 6 | has_many :replies, class_name: "Comment", foreign_key: "reply_to_id" | ||
| 7 | belongs_to :reply_to, class_name: "Comment", optional: true | ||
| 8 | |||
| 9 | validates :body, presence: true | ||
| 10 | validates :username, presence: true | ||
| 11 | validates :email, presence: true, format: URI::MailTo::EMAIL_REGEXP | ||
| 12 | |||
| 13 | scope :published_and_ordered, -> { where(status: :published).order(published_at: :asc) } | ||
| 14 | |||
| 15 | enumerize :status, | ||
| 16 | in: [:published, :pending, :rejected], | ||
| 17 | default: :published, | ||
| 18 | predicates: true | ||
| 19 | |||
| 20 | before_save :set_published_at | ||
| 21 | |||
| 22 | def gravatar_url | ||
| 23 | hash = Digest::MD5.hexdigest(email) | ||
| 24 | "https://www.gravatar.com/avatar/#{hash}?size=40&default=identicon&rating=g" | ||
| 25 | end | ||
| 26 | |||
| 27 | private | ||
| 28 | |||
| 29 | def set_published_at | ||
| 30 | if self.published? | ||
| 31 | if self.published_at.blank? | ||
| 32 | self.published_at = DateTime.now | ||
| 33 | end | ||
| 34 | else | ||
| 35 | self.published_at = nil | ||
| 36 | end | ||
| 37 | end | ||
| 38 | |||
| 39 | end | ||
| diff --git a/app/models/concerns/recordable.rb b/app/models/concerns/recordable.rb new file mode 100644 index 0000000..bbbb582 --- /dev/null +++ b/app/models/concerns/recordable.rb | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | module Recordable | ||
| 2 | extend ActiveSupport::Concern | ||
| 3 | |||
| 4 | included do | ||
| 5 | has_many :records, as: :recordable, inverse_of: :recordable | ||
| 6 | |||
| 7 | accepts_nested_attributes_for :records, allow_destroy: true | ||
| 8 | end | ||
| 9 | end | ||
| diff --git a/app/models/concerns/votable.rb b/app/models/concerns/votable.rb new file mode 100644 index 0000000..40b3a2a --- /dev/null +++ b/app/models/concerns/votable.rb | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | module Votable | ||
| 2 | extend ActiveSupport::Concern | ||
| 3 | |||
| 4 | included do | ||
| 5 | has_many :votes, as: :votable | ||
| 6 | |||
| 7 | def already_upvoted?(ip) | ||
| 8 | !votes.where(ip: ip, upvote: 1).empty? | ||
| 9 | end | ||
| 10 | |||
| 11 | def already_downvoted?(ip) | ||
| 12 | !votes.where(ip: ip, upvote: 0).empty? | ||
| 13 | end | ||
| 14 | |||
| 15 | def upvote!(ip) | ||
| 16 | return false if already_upvoted?(ip) | ||
| 17 | |||
| 18 | if already_downvoted?(ip) | ||
| 19 | votes.where(ip: ip, upvote: 0).first.delete | ||
| 20 | self.downvotes -= 1 | ||
| 21 | save! | ||
| 22 | else | ||
| 23 | votes.create(ip: ip, upvote: 1).save | ||
| 24 | self.upvotes += 1 | ||
| 25 | save! | ||
| 26 | end | ||
| 27 | end | ||
| 28 | |||
| 29 | def downvote!(ip) | ||
| 30 | return false if already_downvoted?(ip) | ||
| 31 | |||
| 32 | if already_upvoted?(ip) | ||
| 33 | votes.where(ip: ip, upvote: 1).first.delete | ||
| 34 | self.upvotes -= 1 | ||
| 35 | save! | ||
| 36 | else | ||
| 37 | votes.create(ip: ip, upvote: 0).save | ||
| 38 | self.downvotes += 1 | ||
| 39 | save! | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 43 | def like!(url, name) | ||
| 44 | return false unless votes.where(liker_url: url).empty? | ||
| 45 | |||
| 46 | votes.create(liker_url: url, liker_name: name, upvote: 1).save | ||
| 47 | self.upvotes += 1 | ||
| 48 | save! | ||
| 49 | end | ||
| 50 | end | ||
| 51 | end | ||
| diff --git a/app/models/game.rb b/app/models/game.rb new file mode 100644 index 0000000..de33377 --- /dev/null +++ b/app/models/game.rb | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | class Game < ApplicationRecord | ||
| 2 | extend Enumerize | ||
| 3 | |||
| 4 | audited only: [:status, :progress] | ||
| 5 | |||
| 6 | validates :title, presence: true | ||
| 7 | validates :status, presence: true | ||
| 8 | |||
| 9 | enumerize :status, | ||
| 10 | in: [:playing, :upcoming, :held, :dropped, :finished], | ||
| 11 | default: :upcoming | ||
| 12 | |||
| 13 | end | ||
| diff --git a/app/models/global.rb b/app/models/global.rb new file mode 100644 index 0000000..7c7d6d4 --- /dev/null +++ b/app/models/global.rb | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | class Global < ApplicationRecord | ||
| 2 | def self.get_filtered_comments | ||
| 3 | row = find_by_key("filtered_comments") | ||
| 4 | if row | ||
| 5 | row[:int_value] | ||
| 6 | else | ||
| 7 | 0 | ||
| 8 | end | ||
| 9 | end | ||
| 10 | |||
| 11 | def self.increment_filtered_comments | ||
| 12 | row = find_by_key("filtered_comments") | ||
| 13 | if row | ||
| 14 | row.int_value += 1 | ||
| 15 | row.save | ||
| 16 | else | ||
| 17 | create(key: "filtered_comments", int_value: 1) | ||
| 18 | end | ||
| 19 | end | ||
| 20 | end | ||
| diff --git a/app/models/link.rb b/app/models/link.rb new file mode 100644 index 0000000..81ffa2b --- /dev/null +++ b/app/models/link.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | class Link < ApplicationRecord | ||
| 2 | include Recordable | ||
| 3 | |||
| 4 | acts_as_taggable | ||
| 5 | |||
| 6 | validates :title, :url, presence: true | ||
| 7 | |||
| 8 | def path | ||
| 9 | url | ||
| 10 | end | ||
| 11 | |||
| 12 | def taggable | ||
| 13 | self | ||
| 14 | end | ||
| 15 | end | ||
| diff --git a/app/models/quote.rb b/app/models/quote.rb new file mode 100644 index 0000000..b1d25b4 --- /dev/null +++ b/app/models/quote.rb | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | class Quote < ApplicationRecord | ||
| 2 | extend Enumerize | ||
| 3 | |||
| 4 | include Votable | ||
| 5 | |||
| 6 | acts_as_taggable | ||
| 7 | |||
| 8 | has_one_attached :audio | ||
| 9 | |||
| 10 | validates :content, presence: true | ||
| 11 | |||
| 12 | enumerize :state, | ||
| 13 | in: [:published, :pending, :hidden], | ||
| 14 | default: :published, | ||
| 15 | predicates: true | ||
| 16 | |||
| 17 | scope :published, -> { where(state: :published) } | ||
| 18 | scope :pending, -> { where(state: :pending) } | ||
| 19 | |||
| 20 | def title | ||
| 21 | "Quote \##{id}" | ||
| 22 | end | ||
| 23 | |||
| 24 | def published_date | ||
| 25 | created_at.strftime("%B %d %Y at %I:%M:%S") + created_at.strftime(" %p").downcase + created_at.strftime(" %Z") | ||
| 26 | end | ||
| 27 | |||
| 28 | def has_extra? | ||
| 29 | has_notes? or has_tags? | ||
| 30 | end | ||
| 31 | |||
| 32 | def has_notes? | ||
| 33 | !notes.empty? | ||
| 34 | end | ||
| 35 | |||
| 36 | def has_tags? | ||
| 37 | !tags.empty? | ||
| 38 | end | ||
| 39 | |||
| 40 | def self.ransackable_attributes(auth_object = nil) | ||
| 41 | ["content", "notes"] | ||
| 42 | end | ||
| 43 | |||
| 44 | def self.ransackable_associations(auth_object = nil) | ||
| 45 | [] | ||
| 46 | end | ||
| 47 | |||
| 48 | end | ||
| diff --git a/app/models/scrobble.rb b/app/models/scrobble.rb new file mode 100644 index 0000000..f527612 --- /dev/null +++ b/app/models/scrobble.rb | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | class Scrobble < ApplicationRecord | ||
| 2 | end | ||
| diff --git a/app/models/stream.rb b/app/models/stream.rb index 7faa370..6a738e2 100644 --- a/app/models/stream.rb +++ b/app/models/stream.rb | |||
| @@ -1,13 +1,29 @@ | |||
| 1 | class Stream < ApplicationRecord | 1 | class Stream < ApplicationRecord |
| 2 | has_many :records, as: :recordable, inverse_of: :recordable | 2 | include Recordable |
| 3 | |||
| 4 | acts_as_taggable | ||
| 5 | |||
| 3 | has_many :updates | 6 | has_many :updates |
| 4 | 7 | ||
| 5 | validates :title, presence: true | 8 | validates :title, presence: true |
| 6 | validates :slug, presence: true, format: /\A[-a-z0-9]+\z/ | 9 | validates :slug, presence: true, format: /\A[-a-z0-9]+\z/ |
| 7 | 10 | ||
| 8 | accepts_nested_attributes_for :records, allow_destroy: true | 11 | before_create :set_post_timestamp |
| 9 | 12 | ||
| 10 | def path | 13 | def path |
| 11 | "/thinks/#{slug}" | 14 | "/thinks/#{slug}" |
| 12 | end | 15 | end |
| 16 | |||
| 17 | def to_param | ||
| 18 | slug | ||
| 19 | end | ||
| 20 | |||
| 21 | def taggable | ||
| 22 | self | ||
| 23 | end | ||
| 24 | |||
| 25 | private | ||
| 26 | def set_post_timestamp | ||
| 27 | self.latest_post_at = self.created_at | ||
| 28 | end | ||
| 13 | end | 29 | end |
| diff --git a/app/models/update.rb b/app/models/update.rb index 41cc453..a98a5d4 100644 --- a/app/models/update.rb +++ b/app/models/update.rb | |||
| @@ -1,12 +1,23 @@ | |||
| 1 | class Update < ApplicationRecord | 1 | class Update < ApplicationRecord |
| 2 | has_many :records, as: :recordable, inverse_of: :recordable | 2 | include Recordable |
| 3 | |||
| 3 | belongs_to :stream | 4 | belongs_to :stream |
| 4 | 5 | ||
| 5 | validates :stream, :body, presence: true | 6 | validates :stream, :body, presence: true |
| 6 | 7 | ||
| 7 | accepts_nested_attributes_for :records, allow_destroy: true | 8 | after_create :set_latest_timestamp |
| 8 | 9 | ||
| 9 | def path | 10 | def path |
| 10 | "/thinks/#{stream.slug}\#update-#{id}" | 11 | "/thinks/#{stream.slug}\#update-#{id}" |
| 11 | end | 12 | end |
| 13 | |||
| 14 | def taggable | ||
| 15 | stream | ||
| 16 | end | ||
| 17 | |||
| 18 | private | ||
| 19 | def set_latest_timestamp | ||
| 20 | self.stream.latest_post_at = self.created_at | ||
| 21 | self.stream.save! | ||
| 22 | end | ||
| 12 | end | 23 | end |
| diff --git a/app/models/user.rb b/app/models/user.rb index 555729a..f9f68fa 100644 --- a/app/models/user.rb +++ b/app/models/user.rb | |||
| @@ -5,4 +5,6 @@ class User < ApplicationRecord | |||
| 5 | :recoverable, :rememberable, :trackable, :validatable | 5 | :recoverable, :rememberable, :trackable, :validatable |
| 6 | 6 | ||
| 7 | has_secure_token :pokeviewer_token | 7 | has_secure_token :pokeviewer_token |
| 8 | |||
| 9 | has_many :blogs | ||
| 8 | end | 10 | end |
| diff --git a/app/models/vote.rb b/app/models/vote.rb new file mode 100644 index 0000000..fced5bd --- /dev/null +++ b/app/models/vote.rb | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | class Vote < ApplicationRecord | ||
| 2 | belongs_to :votable, polymorphic: true | ||
| 3 | |||
| 4 | validates :upvote, presence: true, inclusion: { in: [0, 1] } | ||
| 5 | end | ||
