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

master
Zequez 2015-07-13 08:50:31 -03:00
parent 22f5375f78
commit a5e49c7aa8
7 changed files with 205 additions and 142 deletions

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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