diff --git a/app/models/post/sql_methods.rb b/app/models/post/sql_methods.rb
index c9107ef9..a0779eb5 100644
--- a/app/models/post/sql_methods.rb
+++ b/app/models/post/sql_methods.rb
@@ -66,6 +66,7 @@ module Post::SqlMethods
conds << "FALSE"
end
+ generate_sql_range_helper(q[:ratio], "ratio", conds, cond_params)
generate_sql_range_helper(q[:post_id], "p.id", conds, cond_params)
generate_sql_range_helper(q[:mpixels], "p.width*p.height/1000000.0", conds, cond_params)
generate_sql_range_helper(q[:width], "p.width", conds, cond_params)
@@ -314,15 +315,15 @@ module Post::SqlMethods
sql << " ORDER BY width*height/1000000.0"
when "portrait"
- sql << " ORDER BY 1.0*width/GREATEST(1, height)"
+ sql << " ORDER BY ratio"
when "landscape"
- sql << " ORDER BY 1.0*width/GREATEST(1, height) DESC"
+ sql << " ORDER BY ratio DESC"
when "portrait_pool"
# We can only do this if we're searching for a pool.
if q.key?(:pool)
- sql << " ORDER BY 1.0*width / GREATEST(1, height), nat_sort(pools_posts.sequence), pools_posts.post_id"
+ sql << " ORDER BY ratio, nat_sort(pools_posts.sequence), pools_posts.post_id"
end
when "change", "change_asc"
diff --git a/app/models/tag/parse_methods.rb b/app/models/tag/parse_methods.rb
index a9c7e21f..8eafa399 100644
--- a/app/models/tag/parse_methods.rb
+++ b/app/models/tag/parse_methods.rb
@@ -9,16 +9,19 @@ module Tag::ParseMethods
end
def parse_cast(x, type)
- if type == :integer
+ case type
+ when :integer
x.to_i
- elsif type == :float
+ when :float
x.to_f
- elsif type == :date
+ when :date
begin
x.to_date
rescue
nil
end
+ when :rational
+ Rational(x.tr(":", "/")).to_f.round(3) rescue 0
end
end
@@ -68,9 +71,11 @@ module Tag::ParseMethods
next
end
- if token =~ /^(unlocked|deleted|ext|user|sub|vote|-vote|fav|md5|-rating|rating|width|height|mpixels|score|source|id|date|pool|-pool|parent|order|change|holds|pending|shown|limit):(.+)$/
+ if token =~ /^(ratio|unlocked|deleted|ext|user|sub|vote|-vote|fav|md5|-rating|rating|width|height|mpixels|score|source|id|date|pool|-pool|parent|order|change|holds|pending|shown|limit):(.+)$/
if Regexp.last_match[1] == "user"
q[:user] = Regexp.last_match[2]
+ elsif Regexp.last_match[1] == "ratio"
+ q[:ratio] = parse_helper(Regexp.last_match[2], :rational)
elsif Regexp.last_match[1] == "vote"
vote, user = Regexp.last_match[2].split(":", 2)
user_id = User.find_by_name(user).id rescue nil
diff --git a/app/views/help/cheatsheet.en.html.erb b/app/views/help/cheatsheet.en.html.erb
index 2e915e1d..3aee6dee 100644
--- a/app/views/help/cheatsheet.en.html.erb
+++ b/app/views/help/cheatsheet.en.html.erb
@@ -70,6 +70,9 @@
mpixels:2.5..
Search for posts with 2.5 million pixels or greater (uses same syntax as id search).
+ ratio:16:9
+ Search for posts with aspect ratio of approximately 16:9 (uses same syntax as id search).
+
date:2007-01-01
Search for posts uploaded on a certain date (uses same syntax as id search).
diff --git a/db/migrate/20250329151230_add_ratio_to_posts.rb b/db/migrate/20250329151230_add_ratio_to_posts.rb
new file mode 100644
index 00000000..6af28582
--- /dev/null
+++ b/db/migrate/20250329151230_add_ratio_to_posts.rb
@@ -0,0 +1,5 @@
+class AddRatioToPosts < ActiveRecord::Migration[7.2]
+ def change
+ add_column :posts, :ratio, 'numeric GENERATED ALWAYS AS (ROUND(width::numeric / GREATEST(1, height), 3)) STORED'
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 84b636bb..198acdcc 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1105,7 +1105,8 @@ CREATE TABLE public.posts (
frames_pending text DEFAULT ''::text NOT NULL,
frames_warehoused boolean DEFAULT false NOT NULL,
updated_at timestamp with time zone,
- tags_array character varying[]
+ tags_array character varying[],
+ ratio numeric GENERATED ALWAYS AS (round(((width)::numeric / (GREATEST(1, height))::numeric), 3)) STORED
);
@@ -3302,186 +3303,186 @@ ALTER TABLE ONLY public.users
SET search_path TO "$user", public;
INSERT INTO "schema_migrations" (version) VALUES
-('1'),
-('10'),
-('11'),
-('12'),
-('13'),
-('14'),
-('15'),
-('16'),
-('17'),
-('18'),
-('19'),
-('2'),
-('20'),
-('20080901000000'),
-('20080927145957'),
-('20081015004825'),
-('20081015004855'),
-('20081015004938'),
-('20081015005018'),
-('20081015005051'),
-('20081015005124'),
-('20081015005201'),
-('20081015005919'),
-('20081015010657'),
-('20081016002814'),
-('20081018175545'),
-('20081023224739'),
-('20081024083115'),
-('20081024223856'),
-('20081025222424'),
-('20081105030832'),
-('20081122055610'),
-('20081130190723'),
-('20081130191226'),
-('20081203035506'),
-('20081204062728'),
-('20081205061033'),
-('20081205072029'),
-('20081208220020'),
-('20081209221550'),
-('20081210193125'),
-('20090115234541'),
-('20090123212834'),
-('20090208201752'),
-('20090215000207'),
-('20090903232732'),
-('20091228170149'),
-('20100101225942'),
-('20100827031936'),
-('20100831065951'),
-('20100903220234'),
-('20100906054326'),
-('20100907042612'),
-('20100907210915'),
-('20100907215811'),
-('20101011000658'),
-('20101027013550'),
-('20101116221443'),
-('20101212021821'),
-('20101218070942'),
-('20110116202516'),
-('20110228010717'),
-('20120331040429'),
-('20120505130017'),
-('20120624121058'),
-('20120723155345'),
-('20120723161914'),
-('20120804130515'),
-('20120813155642'),
-('20120830051636'),
-('20120920171733'),
-('20120920172947'),
-('20120920173324'),
-('20120920173803'),
-('20120920174218'),
-('20120921040720'),
-('20130326154700'),
-('20130326161630'),
-('20140309152432'),
-('20140427041839'),
-('20140429125422'),
-('20140905023318'),
-('20151207113346'),
-('20160113112901'),
-('20160329065325'),
-('20160329065802'),
-('20160329154133'),
-('20160329160235'),
-('20160329161636'),
-('20160330063707'),
-('20180624074601'),
-('20190518111956'),
-('20190817070727'),
-('20191110172526'),
-('20200908180652'),
-('20201103140508'),
-('20210211213304'),
-('21'),
-('22'),
-('23'),
-('24'),
-('25'),
-('26'),
-('27'),
-('28'),
-('29'),
-('3'),
-('30'),
-('31'),
-('32'),
-('33'),
-('34'),
-('35'),
-('36'),
-('37'),
-('38'),
-('39'),
-('4'),
-('40'),
-('41'),
-('42'),
-('43'),
-('44'),
-('45'),
-('46'),
-('47'),
-('48'),
-('49'),
-('5'),
-('50'),
-('51'),
-('52'),
-('53'),
-('54'),
-('55'),
-('56'),
-('57'),
-('58'),
-('59'),
-('6'),
-('60'),
-('61'),
-('62'),
-('63'),
-('64'),
-('65'),
-('66'),
-('67'),
-('68'),
-('69'),
-('7'),
-('70'),
-('71'),
-('72'),
-('73'),
-('74'),
-('75'),
-('76'),
-('77'),
-('78'),
-('79'),
-('8'),
-('80'),
-('81'),
-('82'),
-('83'),
-('84'),
-('85'),
-('86'),
-('87'),
-('88'),
-('89'),
-('9'),
-('90'),
-('91'),
-('9142010220946'),
-('92'),
-('93'),
-('94'),
+('96'),
('95'),
-('96');
-
+('94'),
+('93'),
+('92'),
+('9142010220946'),
+('91'),
+('90'),
+('9'),
+('89'),
+('88'),
+('87'),
+('86'),
+('85'),
+('84'),
+('83'),
+('82'),
+('81'),
+('80'),
+('8'),
+('79'),
+('78'),
+('77'),
+('76'),
+('75'),
+('74'),
+('73'),
+('72'),
+('71'),
+('70'),
+('7'),
+('69'),
+('68'),
+('67'),
+('66'),
+('65'),
+('64'),
+('63'),
+('62'),
+('61'),
+('60'),
+('6'),
+('59'),
+('58'),
+('57'),
+('56'),
+('55'),
+('54'),
+('53'),
+('52'),
+('51'),
+('50'),
+('5'),
+('49'),
+('48'),
+('47'),
+('46'),
+('45'),
+('44'),
+('43'),
+('42'),
+('41'),
+('40'),
+('4'),
+('39'),
+('38'),
+('37'),
+('36'),
+('35'),
+('34'),
+('33'),
+('32'),
+('31'),
+('30'),
+('3'),
+('29'),
+('28'),
+('27'),
+('26'),
+('25'),
+('24'),
+('23'),
+('22'),
+('21'),
+('20250329151230'),
+('20210211213304'),
+('20201103140508'),
+('20200908180652'),
+('20191110172526'),
+('20190817070727'),
+('20190518111956'),
+('20180624074601'),
+('20160330063707'),
+('20160329161636'),
+('20160329160235'),
+('20160329154133'),
+('20160329065802'),
+('20160329065325'),
+('20160113112901'),
+('20151207113346'),
+('20140905023318'),
+('20140429125422'),
+('20140427041839'),
+('20140309152432'),
+('20130326161630'),
+('20130326154700'),
+('20120921040720'),
+('20120920174218'),
+('20120920173803'),
+('20120920173324'),
+('20120920172947'),
+('20120920171733'),
+('20120830051636'),
+('20120813155642'),
+('20120804130515'),
+('20120723161914'),
+('20120723155345'),
+('20120624121058'),
+('20120505130017'),
+('20120331040429'),
+('20110228010717'),
+('20110116202516'),
+('20101218070942'),
+('20101212021821'),
+('20101116221443'),
+('20101027013550'),
+('20101011000658'),
+('20100907215811'),
+('20100907210915'),
+('20100907042612'),
+('20100906054326'),
+('20100903220234'),
+('20100831065951'),
+('20100827031936'),
+('20100101225942'),
+('20091228170149'),
+('20090903232732'),
+('20090215000207'),
+('20090208201752'),
+('20090123212834'),
+('20090115234541'),
+('20081210193125'),
+('20081209221550'),
+('20081208220020'),
+('20081205072029'),
+('20081205061033'),
+('20081204062728'),
+('20081203035506'),
+('20081130191226'),
+('20081130190723'),
+('20081122055610'),
+('20081105030832'),
+('20081025222424'),
+('20081024223856'),
+('20081024083115'),
+('20081023224739'),
+('20081018175545'),
+('20081016002814'),
+('20081015010657'),
+('20081015005919'),
+('20081015005201'),
+('20081015005124'),
+('20081015005051'),
+('20081015005018'),
+('20081015004938'),
+('20081015004855'),
+('20081015004825'),
+('20080927145957'),
+('20080901000000'),
+('20'),
+('2'),
+('19'),
+('18'),
+('17'),
+('16'),
+('15'),
+('14'),
+('13'),
+('12'),
+('11'),
+('10'),
+('1');