Added mod ability to parse Imgur URLs to extract the ID. Also, commented out or fixed tests that had broken after I dumbed down the searching function
parent
22f5375f78
commit
a5e49c7aa8
|
@ -12,6 +12,11 @@ class Mod < ActiveRecord::Base
|
|||
|
||||
FORBIDDEN_NAMES = %q(new create edit update destroy)
|
||||
|
||||
IMGUR_IMAGE_URLS = [
|
||||
%r{\Ahttps?://imgur\.com/(\w+)\Z},
|
||||
%r{\Ahttps?://i\.imgur\.com/(\w+)\.(\w+)\Z}
|
||||
]
|
||||
|
||||
### Relationships
|
||||
#################
|
||||
|
||||
|
@ -53,7 +58,7 @@ class Mod < ActiveRecord::Base
|
|||
scope :sort_by_popular, -> { includes(:forum_post).order('forum_posts.views_count desc') }
|
||||
|
||||
scope :filter_by_search_query, ->(query) do
|
||||
where('mods.name LIKE ? OR mods.summary LIKE ?', "%#{query}%", "%#{query}%")
|
||||
where('mods.name LIKE ? OR mods.summary LIKE ? OR mods.description LIKE ?', "%#{query}%", "%#{query}%", "%#{query}%")
|
||||
end
|
||||
|
||||
# def self.filter_by_search_query(query)
|
||||
|
@ -120,6 +125,13 @@ class Mod < ActiveRecord::Base
|
|||
self.errors[:github].push I18n.t('activerecord.errors.models.mod.attributes.github.invalid')
|
||||
end
|
||||
end
|
||||
|
||||
# Imgur
|
||||
validate do
|
||||
if extract_imgur_id(imgur) == false
|
||||
self.errors[:imgur].push I18n.t('activerecord.errors.models.mod.attributes.imgur.invalid')
|
||||
end
|
||||
end
|
||||
|
||||
### Attributes
|
||||
#################
|
||||
|
@ -129,6 +141,24 @@ class Mod < ActiveRecord::Base
|
|||
attr_accessor :imgur_normal
|
||||
alias_attribute :github_path, :github
|
||||
|
||||
def imgur=(val)
|
||||
imgur_id = extract_imgur_id(val)
|
||||
if imgur_id == false
|
||||
write_attribute(:imgur, val)
|
||||
else
|
||||
write_attribute(:imgur, imgur_id)
|
||||
end
|
||||
end
|
||||
|
||||
def extract_imgur_id(val)
|
||||
if val =~ /\A[A-Z0-9]+\Z/i or val.blank?
|
||||
val
|
||||
else
|
||||
match = IMGUR_IMAGE_URLS.map{|reg| match = reg.match(val) }.compact.first
|
||||
match ? match[1] : false
|
||||
end
|
||||
end
|
||||
|
||||
def imgur_url
|
||||
"http://imgur.com/#{imgur}"
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
= f.input :official_url
|
||||
= f.input :forum_url
|
||||
= f.input :summary, as: :text
|
||||
= f.input :imgur, label: link_to(@mod.imgur_url, @mod.imgur_normal)
|
||||
= f.input :imgur
|
||||
%li.nested-form.mod-versions
|
||||
= f.semantic_fields_for :versions do |ff|
|
||||
= render 'version_fields', f: ff
|
||||
|
|
|
@ -67,6 +67,8 @@ en:
|
|||
invalid: Invalid Github path or URL
|
||||
categories_list:
|
||||
invalid: "Invalid categories: %{categories}"
|
||||
imgur:
|
||||
invalid: "Invalid Imgur URL or ID. Remember it has to be a single picture, not an album."
|
||||
|
||||
formtastic:
|
||||
labels:
|
||||
|
@ -74,6 +76,7 @@ en:
|
|||
forum_url: 'Forum URL'
|
||||
official_url: 'Official URL'
|
||||
media_links_string: 'Pictures or gifs links'
|
||||
imgur: Imgur.com URL or ID
|
||||
|
||||
mod_version:
|
||||
released_at: 'Release day'
|
||||
|
|
217
lib/imgur.rb
217
lib/imgur.rb
|
@ -1,127 +1,134 @@
|
|||
class Imgur
|
||||
attr_accessor :url
|
||||
attr_reader :string, :id, :thumbnail_id, :is_album, :extension, :thumbnail_url, :canonical_url, :valid
|
||||
alias_method :to_s, :string
|
||||
alias_method :to_string, :string
|
||||
alias_method :valid?, :valid
|
||||
# class Imgur
|
||||
# attr_accessor :url
|
||||
# attr_reader :string, :id, :thumbnail_id, :is_album, :extension, :thumbnail_url, :canonical_url, :valid
|
||||
# alias_method :to_s, :string
|
||||
# alias_method :to_string, :string
|
||||
# alias_method :valid?, :valid
|
||||
|
||||
IMGUR_IMAGE_URLS = [
|
||||
%r{\Ahttps?://imgur\.com/(\w+)\Z},
|
||||
%r{\Ahttps?://i\.imgur\.com/(\w+)\.(\w+)\Z}
|
||||
]
|
||||
# IMGUR_IMAGE_URLS = [
|
||||
# %r{\Ahttps?://imgur\.com/(\w+)\Z},
|
||||
# %r{\Ahttps?://i\.imgur\.com/(\w+)\.(\w+)\Z}
|
||||
# ]
|
||||
|
||||
IMGUR_ALBUM_URLS = [
|
||||
%r{\Ahttps?://imgur\.com/a/(\w+)\Z},
|
||||
%r{\Ahttps?://imgur\.com/gallery/(\w+)\Z}
|
||||
]
|
||||
# IMGUR_ALBUM_URLS = [
|
||||
# %r{\Ahttps?://imgur\.com/a/(\w+)\Z},
|
||||
# %r{\Ahttps?://imgur\.com/gallery/(\w+)\Z}
|
||||
# ]
|
||||
|
||||
|
||||
def url=(val)
|
||||
@url = val
|
||||
clean
|
||||
parse_url
|
||||
@url
|
||||
end
|
||||
# def url=(val)
|
||||
# @url = val
|
||||
# clean
|
||||
# parse_url
|
||||
# @url
|
||||
# end
|
||||
|
||||
def parse_url
|
||||
if @url
|
||||
match = nil
|
||||
if (match = get_album_match)
|
||||
@is_album = true
|
||||
@id = match[1]
|
||||
@extension = nil
|
||||
@canonical_url = generate_canonical_url
|
||||
elsif (match = get_image_match)
|
||||
@is_album = false
|
||||
@id = match[1]
|
||||
@thumbnail_id = match[1]
|
||||
@thumbnail_url = generate_thumbnail_url
|
||||
@canonical_url = generate_canonical_url
|
||||
end
|
||||
# def id=(val)
|
||||
# @is_album = false
|
||||
# @id = val
|
||||
# @url = @canonical_url = generate_canonical_url
|
||||
# end
|
||||
|
||||
if match && (image_url = request_canonical_page_image_url)
|
||||
match = get_image_match(image_url)
|
||||
# def parse_url
|
||||
# if @url
|
||||
# match = nil
|
||||
# if (match = get_album_match)
|
||||
# @is_album = true
|
||||
# @id = match[1]
|
||||
# @extension = nil
|
||||
# @canonical_url = generate_canonical_url
|
||||
# elsif (match = get_image_match)
|
||||
# @is_album = false
|
||||
# @id = match[1]
|
||||
# @thumbnail_id = match[1]
|
||||
# @thumbnail_url = generate_thumbnail_url
|
||||
# @canonical_url = generate_canonical_url
|
||||
# end
|
||||
|
||||
if @is_album
|
||||
@thumbnail_id = match[1]
|
||||
@thumbnail_url = generate_thumbnail_url
|
||||
else
|
||||
@extension = match[2]
|
||||
end
|
||||
# if match && (image_url = request_canonical_page_image_url)
|
||||
# match = get_image_match(image_url)
|
||||
|
||||
@string = generate_string
|
||||
@valid = true
|
||||
else
|
||||
clean
|
||||
@valid = false
|
||||
end
|
||||
else
|
||||
@valid = true
|
||||
end
|
||||
end
|
||||
# if @is_album
|
||||
# @thumbnail_id = match[1]
|
||||
# @thumbnail_url = generate_thumbnail_url
|
||||
# else
|
||||
# @extension = match[2]
|
||||
# end
|
||||
|
||||
### Serialization for ActiveRecord
|
||||
# @string = generate_string
|
||||
# @valid = true
|
||||
# else
|
||||
# clean
|
||||
# @valid = false
|
||||
# end
|
||||
# else
|
||||
# @valid = true
|
||||
# end
|
||||
# end
|
||||
|
||||
def self.dump(imgur)
|
||||
raise ::ActiveRecord::SerializationTypeMismatch unless imgur.is_a?(self)
|
||||
imgur.to_s
|
||||
end
|
||||
# ### Serialization for ActiveRecord
|
||||
|
||||
def self.load(val)
|
||||
# def self.dump(imgur)
|
||||
# raise ::ActiveRecord::SerializationTypeMismatch unless imgur.is_a?(self)
|
||||
# imgur.to_s
|
||||
# end
|
||||
|
||||
end
|
||||
# def self.load(val)
|
||||
|
||||
### Private land
|
||||
# end
|
||||
|
||||
private
|
||||
# ### Private land
|
||||
|
||||
def request_canonical_page_image_url
|
||||
response = Net::HTTP.get_response(URI(@canonical_url))
|
||||
if response.code == '200'
|
||||
doc = Nokogiri::HTML response.body
|
||||
# private
|
||||
|
||||
image_src = doc.css('link[rel="image_src"]').first
|
||||
# def request_canonical_page_image_url
|
||||
# response = Net::HTTP.get_response(URI(@canonical_url))
|
||||
# if response.code == '200'
|
||||
# doc = Nokogiri::HTML response.body
|
||||
|
||||
if image_src
|
||||
image_src.attribute('href').value
|
||||
else
|
||||
nil
|
||||
end
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
# image_src = doc.css('link[rel="image_src"]').first
|
||||
|
||||
def get_image_match(url = @url)
|
||||
match = nil
|
||||
IMGUR_IMAGE_URLS.any? {|reg| match = reg.match(url) }
|
||||
match
|
||||
end
|
||||
# if image_src
|
||||
# image_src.attribute('href').value
|
||||
# else
|
||||
# nil
|
||||
# end
|
||||
# else
|
||||
# nil
|
||||
# end
|
||||
# end
|
||||
|
||||
def get_album_match
|
||||
match = nil
|
||||
IMGUR_ALBUM_URLS.any? {|reg| match = reg.match(@url) }
|
||||
match
|
||||
end
|
||||
# def get_image_match(url = @url)
|
||||
# match = nil
|
||||
# IMGUR_IMAGE_URLS.any? {|reg| match = reg.match(url) }
|
||||
# match
|
||||
# end
|
||||
|
||||
def generate_canonical_url
|
||||
album = @is_album ? 'a/' : ''
|
||||
"http://imgur.com/#{album}#{id}"
|
||||
end
|
||||
# def get_album_match
|
||||
# match = nil
|
||||
# IMGUR_ALBUM_URLS.any? {|reg| match = reg.match(@url) }
|
||||
# match
|
||||
# end
|
||||
|
||||
def generate_thumbnail_url
|
||||
"http://i.imgur.com/#{@thumbnail_id}s.jpg"
|
||||
end
|
||||
# def generate_canonical_url
|
||||
# album = @is_album ? 'a/' : ''
|
||||
# "http://imgur.com/#{album}#{id}"
|
||||
# end
|
||||
|
||||
def generate_string
|
||||
"#{@id}.#{@extension} #{@thumbnail_id}"
|
||||
end
|
||||
# def generate_thumbnail_url
|
||||
# "http://i.imgur.com/#{@thumbnail_id}s.jpg"
|
||||
# end
|
||||
|
||||
def clean
|
||||
@string = nil
|
||||
@id = nil
|
||||
@thumbnail_id = nil
|
||||
@is_album = nil
|
||||
@extension = nil
|
||||
@thumbnail_url = nil
|
||||
end
|
||||
end
|
||||
# def generate_string
|
||||
# "#{@id}.#{@extension} #{@thumbnail_id}"
|
||||
# end
|
||||
|
||||
# def clean
|
||||
# @string = nil
|
||||
# @id = nil
|
||||
# @thumbnail_id = nil
|
||||
# @is_album = nil
|
||||
# @extension = nil
|
||||
# @thumbnail_url = nil
|
||||
# end
|
||||
# end
|
|
@ -129,7 +129,7 @@ RSpec.describe ModsController, type: :controller do
|
|||
|
||||
it { expect(response).to be_success }
|
||||
it { expect(response).to render_template 'index' }
|
||||
it { expect(assigns(:mods)).to eq Mod.sort_by_most_recent.filter_by_search_query('potato') }
|
||||
it { expect(assigns(:mods).to_a).to match Mod.sort_by_most_recent.filter_by_search_query('potato').to_a }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
# subject(:imgur) { Imgur.new }
|
||||
|
||||
# describe '#url', vcr: true do
|
||||
# it 'should work with ID assignment' do
|
||||
# imgur.id = '5xnCbtj'
|
||||
# expect(imgur.is_album).to eq false
|
||||
# expect(imgur.thumbnail_url).to eq 'http://i.imgur.com/5xnCbtjs.jpg'
|
||||
# expect(imgur.url).to eq 'http://imgur.com/5xnCbtj'
|
||||
# end
|
||||
|
||||
# it 'should detect that its an image with an image URL' do
|
||||
# imgur.url = 'http://imgur.com/5xnCbtj'
|
||||
# expect(imgur.to_s).to eq '5xnCbtj.jpg 5xnCbtj'
|
||||
|
|
|
@ -291,6 +291,22 @@ RSpec.describe Mod, :type => :model do
|
|||
expect(mod.imgur_normal).to eq 'http://i.imgur.com/VRi7OWV.jpg'
|
||||
expect(mod.imgur_thumbnail).to eq 'http://i.imgur.com/VRi7OWVb.jpg'
|
||||
end
|
||||
|
||||
it 'should extract the ID from an Imgur URL' do
|
||||
mod.imgur = 'https://i.imgur.com/5yc64LJ.png'
|
||||
mod.save!
|
||||
expect(mod.imgur).to eq '5yc64LJ'
|
||||
end
|
||||
|
||||
it 'should be invalid with a non-id' do
|
||||
mod.imgur = 'ns-#$@#$'
|
||||
expect(mod).to be_invalid
|
||||
end
|
||||
|
||||
it 'should be invalid with an URL other than Imgur' do
|
||||
mod.imgur = 'https://lesserimagehost.com/5yc64LJ.png'
|
||||
expect(mod).to be_invalid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -454,15 +470,15 @@ RSpec.describe Mod, :type => :model do
|
|||
expect(Mod.filter_by_search_query('banana')).to eq [m2]
|
||||
end
|
||||
|
||||
context 'find on name, summary and description' do
|
||||
it 'should return them with name > summary > description precedence' do
|
||||
m1 = create(:mod, summary: 'This is a bananaFace! simulator')
|
||||
m2 = create(:mod, name: 'This is a BaNaNAnana simulator')
|
||||
m3 = create(:mod, description: 'This is a bananarama simulator')
|
||||
# context 'find on name, summary and description' do
|
||||
# it 'should return them with name > summary > description precedence' do
|
||||
# m1 = create(:mod, summary: 'This is a bananaFace! simulator')
|
||||
# m2 = create(:mod, name: 'This is a BaNaNAnana simulator')
|
||||
# m3 = create(:mod, description: 'This is a bananarama simulator')
|
||||
|
||||
expect(Mod.filter_by_search_query('banana')).to eq [m2, m1, m3]
|
||||
end
|
||||
end
|
||||
# expect(Mod.filter_by_search_query('banana')).to eq [m2, m1, m3]
|
||||
# end
|
||||
# end
|
||||
|
||||
context 'using other scopes' do
|
||||
it 'should work when filtering by version' do
|
||||
|
@ -488,35 +504,35 @@ RSpec.describe Mod, :type => :model do
|
|||
expect(Mod.filter_by_category(c1).filter_by_search_query('potato')).to eq [m2]
|
||||
end
|
||||
|
||||
context 'sorting alphabetically' do
|
||||
it 'search should take precedence to alphabeticallity' do
|
||||
m1 = create(:mod, name: 'C Potato')
|
||||
m2 = create(:mod, name: 'B Potato')
|
||||
m3 = create(:mod, name: 'A Potato')
|
||||
m4 = create(:mod, summary: 'B Potatou', name: 'B1')
|
||||
m5 = create(:mod, summary: 'A Potatou', name: 'A1')
|
||||
m6 = create(:mod, summary: 'C Potatou', name: 'C1')
|
||||
m7 = create(:mod, description: 'A Potatoeiu', name: 'A2')
|
||||
m8 = create(:mod, description: 'C Potatoeiu', name: 'C2')
|
||||
m9 = create(:mod, description: 'B Potatoeiu', name: 'B2')
|
||||
# context 'sorting alphabetically' do
|
||||
# it 'search should take precedence to alphabeticallity' do
|
||||
# m1 = create(:mod, name: 'C Potato')
|
||||
# m2 = create(:mod, name: 'B Potato')
|
||||
# m3 = create(:mod, name: 'A Potato')
|
||||
# m4 = create(:mod, summary: 'B Potatou', name: 'B1')
|
||||
# m5 = create(:mod, summary: 'A Potatou', name: 'A1')
|
||||
# m6 = create(:mod, summary: 'C Potatou', name: 'C1')
|
||||
# m7 = create(:mod, description: 'A Potatoeiu', name: 'A2')
|
||||
# m8 = create(:mod, description: 'C Potatoeiu', name: 'C2')
|
||||
# m9 = create(:mod, description: 'B Potatoeiu', name: 'B2')
|
||||
|
||||
expect(Mod.sort_by_alpha.filter_by_search_query('potato')).to eq [m3, m2, m1, m5, m4, m6, m7, m9, m8]
|
||||
end
|
||||
end
|
||||
# expect(Mod.sort_by_alpha.filter_by_search_query('potato')).to eq [m3, m2, m1, m5, m4, m6, m7, m9, m8]
|
||||
# end
|
||||
# end
|
||||
|
||||
it 'should work when sorting by recently updated' do
|
||||
m1 = create(:mod, name: 'C Potato', versions: [build(:mod_version, released_at: 9.days.ago)])
|
||||
m2 = create(:mod, name: 'B Potato', versions: [build(:mod_version, released_at: 8.days.ago)])
|
||||
m3 = create(:mod, name: 'A Potato', versions: [build(:mod_version, released_at: 7.days.ago)])
|
||||
m4 = create(:mod, summary: 'B Potatou', versions: [build(:mod_version, released_at: 5.days.ago)])
|
||||
m5 = create(:mod, summary: 'A Potatou', versions: [build(:mod_version, released_at: 4.days.ago)])
|
||||
m6 = create(:mod, summary: 'C Potatou', versions: [build(:mod_version, released_at: 6.days.ago)])
|
||||
m7 = create(:mod, description: 'A Potatoeiu', versions: [build(:mod_version, released_at: 1.days.ago)])
|
||||
m8 = create(:mod, description: 'C Potatoeiu', versions: [build(:mod_version, released_at: 3.days.ago)])
|
||||
m9 = create(:mod, description: 'B Potatoeiu', versions: [build(:mod_version, released_at: 2.days.ago)])
|
||||
# it 'should work when sorting by recently updated' do
|
||||
# m1 = create(:mod, name: 'C Potato', versions: [build(:mod_version, released_at: 9.days.ago)])
|
||||
# m2 = create(:mod, name: 'B Potato', versions: [build(:mod_version, released_at: 8.days.ago)])
|
||||
# m3 = create(:mod, name: 'A Potato', versions: [build(:mod_version, released_at: 7.days.ago)])
|
||||
# m4 = create(:mod, summary: 'B Potatou', versions: [build(:mod_version, released_at: 5.days.ago)])
|
||||
# m5 = create(:mod, summary: 'A Potatou', versions: [build(:mod_version, released_at: 4.days.ago)])
|
||||
# m6 = create(:mod, summary: 'C Potatou', versions: [build(:mod_version, released_at: 6.days.ago)])
|
||||
# m7 = create(:mod, description: 'A Potatoeiu', versions: [build(:mod_version, released_at: 1.days.ago)])
|
||||
# m8 = create(:mod, description: 'C Potatoeiu', versions: [build(:mod_version, released_at: 3.days.ago)])
|
||||
# m9 = create(:mod, description: 'B Potatoeiu', versions: [build(:mod_version, released_at: 2.days.ago)])
|
||||
|
||||
expect(Mod.sort_by_most_recent.filter_by_search_query('potato')).to eq [m3, m2, m1, m5, m4, m6, m7, m9, m8]
|
||||
end
|
||||
# expect(Mod.sort_by_most_recent.filter_by_search_query('potato')).to eq [m3, m2, m1, m5, m4, m6, m7, m9, m8]
|
||||
# end
|
||||
|
||||
# it 'should work when sorting by comments' do
|
||||
|
||||
|
|
Loading…
Reference in New Issue