# frozen_string_literal: true # == Schema Information # # Table name: posts # # id :bigint not null, primary key # anonymous :boolean default(FALSE), not null # commenting_allowed :boolean default(TRUE), not null # comments_count :integer default(0), not null # deletion_reason :string # description :string # description_editing_allowed :boolean default(TRUE), not null # destroyed_content :boolean default(FALSE), not null # downvotes_count :integer default(0), not null # duplication_checked :boolean default(FALSE), not null # faves_count :integer default(0), not null # first_seen_at :datetime # hidden_from_users :boolean default(FALSE), not null # hidden_key :text # hides_count :integer default(0), not null # ip :inet # media_type :string default("image"), not null # processed :boolean default(FALSE), not null # referrer :string default(""), not null # score :integer default(0), not null # scratchpad :string # source_url :string # tag_editing_allowed :boolean default(TRUE), not null # tag_list_cache :string # tag_list_plus_alias_cache :string # upvotes_count :integer default(0), not null # user_agent :string default(""), not null # created_at :datetime not null # updated_at :datetime not null # deleted_by_id :integer # duplicate_id :integer # user_id :integer # # Foreign Keys # # fk_rails_... (deleted_by_id => users.id) # fk_rails_... (duplicate_id => posts.id) # fk_rails_... (user_id => users.id) # class PostSerializer < BaseSerializer # @param [Post] post def self.serialize(post, options = {}) show_full = !post.hidden_from_users? || options[:show_hidden] locations = post.locations.map { |loc| self.serialize_post_location(loc) } base_attrs = { id: post.id, media_type: post.media_type, # String - The type of media associated with this post. Currently, (paste | image). created_at: post.created_at, # DateTime - The creation time, in UTC, of the post. first_seen_at: post.first_seen_at, # DateTime - The time, in UTC, the post was first seen (before any duplicate merging). hidden_from_users: post.hidden_from_users?, # Bool - Whether the post is hidden. A post is hidden if it is merged or deleted for a rule violation. orig_sha512_hash: post.orig_sha512_hash, # String - The SHA512 hash of the post as it was originally uploaded. processed: post.processed?, # Bool - Whether the post has finished background processing. sha512_hash: post.sha512_hash, # String - The SHA512 hash of this post after it has been processed. source_url: post.source_url, # String - The current source URL of the post. tag_ids: post.tag_ids, # Array - A list of tag IDs the post has. tags: post.tags.pluck(:name), # Array - A list of tag names the post has. updated_at: post.updated_at, # DateTime - The time, in UTC, the post was last updated. locations: locations } base_attrs = base_attrs.merge({ full_tags: TagSerializer.serialize_collection(post.tags.to_a) }) if options[:full_tag_responses] base_attrs = base_attrs.merge(serialize_full(post)) if show_full base_attrs = base_attrs.merge({ deletion_reason: post.deletion_reason }) if post.hidden_from_users? base_attrs = base_attrs.merge({ duplicate_id: post.duplicate_id }) if post.duplicate_id.present? base_attrs end private # Fields that are included for posts that are visible to users. # @param [Post] post def self.serialize_full(post) media_attrs = case post.media_type when 'image' serialize_image(post.image) else {} end view_urls = post.media.file.view_urls base_attrs = { comment_count: post.comments_count,# Integer - The number of comments the post has. description: post.description, # String - The post's description. downvotes: post.downvotes_count, # Integer - The number of downvotes the post has. faves: post.faves_count, # Integer - The number of favourites the post has. representations: view_urls, score: post.score, # Integer - The post's score - usually the number of upvotes minus the number of downvotes. size: post.file.size, upvotes: post.upvotes_count, # Integer - The number of upvotes the post has. view_url: view_urls[:full], wilson_score: post.wilson_score # Float - The lower bound of the Wilson score interval for the post, based on its upvotes and downvotes, given a z-score corresponding to a confidence of 99.5%. } base_attrs.merge(media_attrs) end # Fields that are used for posts that are visible and have a media_type of 'image'. # @param [Post::Image] image def self.serialize_image(image) { animated: image.is_animated?, # Boolean - Whether the image is animated. aspect_ratio: image.aspect_ratio, # Float - The image's width divided by its height. duration: image.duration, # Float - The number of seconds the animation runs for, if animated, otherwise 0. format: image.format, # String - The file extension of the image. One of "gif", "jpg", "jpeg", "png", "svg", "webm", "mp4" height: image.height, # Integer - The image's height, in pixels. mime_type: image.mime_type, # String - The MIME type of the image. One of "image/gif", "image/jpeg", "image/png", "image/svg+xml", "video/webm". name: image.name, # String - The filename that the image was uploaded with. thumbnails_generated: # Bool - Whether the image has finished thumbnail generation. Do not attempt to load images from view_url or representations if this is false. image.thumbnails_generated?, width: image.width, # Integer - The image's width, in pixels. intensities: serialize_image_intensity(image.intensity) } end # @param [Post::Image::Intensity] intensity def self.serialize_image_intensity(intensity) return nil if intensity.nil? { nw: intensity.nw, ne: intensity.ne, sw: intensity.sw, se: intensity.se } end # @param [Post::Location] location def self.serialize_post_location(location) { location: location.location, id_at_location: location.id_at_location, url_at_location: location.url_at_location } end end