tag table

This commit is contained in:
byte[] 2019-11-29 13:26:44 -05:00
parent 964efa871c
commit bbad33a70c
10 changed files with 816 additions and 230 deletions

View file

@ -271,229 +271,643 @@
"pinkie pie"
]
},
"Season 9": {
"1-2": "the beginning of the end",
"3": "uprooted",
"4": "twilight's seven",
"5": "the point of no return",
"6": "common ground",
"7": "she's all yak",
"8": "frenemies (episode)",
"9": "sweet and smoky",
"10": "going to seed",
"11": "student counsel",
"12": "the last crusade (episode)",
"13": "between dark and dawn",
"14": "that's a laugh",
"15": "2 4 6 greaaat",
"16": "a trivial pursuit",
"17": "the summer sun setback",
"18": "she talks to angel",
"19": "dragon dropped",
"20": "a horse shoe-in",
"21": "daring doubt",
"22": "growing up is hard to do",
"23": "the big mac question",
"24-25": "the ending of the end",
"26": "the last problem"
},
"8": {
"1-2": "school daze",
"3": "the maud couple",
"4": "fake it 'til you make it",
"5": "grannies gone wild",
"6": "surf and/or turf",
"7": "horse play",
"8": "the parent map",
"9": "non-compete clause",
"10": "the break up breakdown",
"11": "molt down",
"12": "marks for effort",
"13": "the mean 6",
"14": "a matter of principals",
"15": "the hearth's warming club",
"16": "friendship university",
"17": "the end in friend",
"18": "yakity-sax",
"19": "on the road to friendship",
"20": "the washouts (episode)",
"21": "a rockhoof and a hard place",
"22": "what lies beneath",
"23": "sounds of silence",
"24": "father knows beast",
"25-26": "school raze",
"Special": "best gift ever"
},
"7": {
"1": "celestial advice",
"2": "all bottled up",
"3": "a flurry of emotions",
"4": "rock solid friendship",
"5": "fluttershy leans in",
"6": "forever filly",
"7": "parental glideance",
"8": "hard to say anything",
"9": "honest apple",
"10": "a royal problem",
"11": "not asking for trouble",
"12": "discordant harmony",
"13": "the perfect pear",
"14": "fame and misfortune",
"15": "triple threat",
"16": "campfire tales",
"17": "to change a changeling",
"18": "daring done?",
"19": "it isn't the mane thing about you",
"20": "a health of information",
"21": "marks and recreation",
"22": "once upon a zeppelin",
"23": "secrets and pies",
"24": "uncommon bond",
"25-26": "shadow play"
},
"6": {
"1-2": "the crystalling",
"3": "the gift of the maud pie",
"4": "on your marks",
"5": "gauntlet of fire",
"6": "no second prances",
"7": "newbie dash",
"8": "a hearth's warming tail",
"9": "the saddle row review",
"10": "applejack's \"day\" off",
"11": "flutter brutter",
"12": "spice up your life",
"13": "stranger than fan fiction",
"14": "the cart before the ponies",
"15": "28 pranks later",
"16": "the times they are a changeling",
"17": "dungeons and discords",
"18": "buckball season",
"19": "the fault in our cutie marks",
"20": "viva las pegasus",
"21": "every little thing she does",
"22": "ppov",
"23": "where the apple lies",
"24": "top bolt",
"25-26": "to where and back again"
},
"5": {
"1-2": "the cutie map",
"3": "castle sweet castle",
"4": "bloom and gloom",
"5": "tanks for the memories",
"6": "appleoosa's most wanted",
"7": "make new friends but keep discord",
"8": "the lost treasure of griffonstone",
"9": "slice of life (episode)",
"10": "princess spike",
"11": "party pooped",
"12": "amending fences",
"13": "do princesses dream of magic sheep",
"14": "canterlot boutique",
"15": "rarity investigates",
"16": "made in manehattan",
"17": "brotherhooves social",
"18": "crusaders of the lost mark",
"19": "the one where pinkie pie knows",
"20": "hearthbreakers",
"21": "scare master",
"22": "what about discord?",
"23": "the hooffields and mccolts",
"24": "the mane attraction",
"25-26": "the cutie remark"
},
"4": {
"1-2": "princess twilight sparkle (episode)",
"3": "castle mane-ia",
"4": "daring don't",
"5": "flight to the finish",
"6": "power ponies",
"7": "bats!",
"8": "rarity takes manehattan",
"9": "pinkie apple pie",
"10": "rainbow falls",
"11": "three's a crowd",
"12": "pinkie pride",
"13": "simple ways",
"14": "filli vanilli",
"15": "twilight time",
"16": "it ain't easy being breezies",
"17": "somepony to watch over me",
"18": "maud pie (episode)",
"19": "for whom the sweetie belle toils",
"20": "leap of faith",
"21": "testing testing 1-2-3",
"22": "trade ya",
"23": "inspiration manifestation",
"24": "equestria games",
"25-26": "twilight's kingdom"
},
"3": {
"1-2": "the crystal empire",
"3": "too many pinkie pies",
"4": "one bad apple",
"5": "magic duel",
"6": "sleepless in ponyville",
"7": "wonderbolts academy",
"8": "just for sidekicks",
"9": "apple family reunion",
"10": "spike at your service",
"11": "keep calm and flutter on",
"12": "games ponies play",
"13": "magical mystery cure"
},
"2": {
"1-2": "the return of harmony",
"3": "lesson zero",
"4": "luna eclipsed",
"5": "sisterhooves social",
"6": "the cutie pox",
"7": "may the best pet win",
"8": "the mysterious mare do well",
"9": "sweet and elite",
"10": "secret of my excess",
"11": "family appreciation day",
"12": "baby cakes",
"13": "hearth's warming eve (episode)",
"14": "the last roundup",
"15": "the super speedy cider squeezy 6000",
"16": "read it and weep",
"17": "hearts and hooves day (episode)",
"18": "a friend in deed",
"19": "putting your hoof down",
"20": "it's about time",
"21": "dragon quest",
"22": "hurricane fluttershy",
"23": "ponyville confidential",
"24": "mmmystery on the friendship express",
"25-26": "a canterlot wedding"
},
"1": {
"1-2": "friendship is magic",
"3": "the ticket master",
"4": "applebuck season",
"5": "griffon the brush off",
"6": "boast busters",
"7": "dragonshy",
"8": "look before you sleep",
"9": "bridle gossip",
"10": "swarm of the century",
"11": "winter wrap up",
"12": "call of the cutie",
"13": "fall weather friends",
"14": "suited for success",
"15": "feeling pinkie keen",
"16": "sonic rainboom (episode)",
"17": "stare master",
"18": "the show stoppers",
"19": "a dog and pony show",
"20": "green isn't your color",
"21": "over a barrel",
"22": "a bird in the hoof",
"23": "the cutie mark chronicles",
"24": "owl's well that ends well",
"25": "party of one",
"26": "the best night ever"
}
}
"Season 9": [
{
"1-2": "the beginning of the end"
},
{
"3": "uprooted"
},
{
"4": "twilight's seven"
},
{
"5": "the point of no return"
},
{
"6": "common ground"
},
{
"7": "she's all yak"
},
{
"8": "frenemies (episode)"
},
{
"9": "sweet and smoky"
},
{
"10": "going to seed"
},
{
"11": "student counsel"
},
{
"12": "the last crusade (episode)"
},
{
"13": "between dark and dawn"
},
{
"14": "that's a laugh"
},
{
"15": "2 4 6 greaaat"
},
{
"16": "a trivial pursuit"
},
{
"17": "the summer sun setback"
},
{
"18": "she talks to angel"
},
{
"19": "dragon dropped"
},
{
"20": "a horse shoe-in"
},
{
"21": "daring doubt"
},
{
"22": "growing up is hard to do"
},
{
"23": "the big mac question"
},
{
"24-25": "the ending of the end"
},
{
"26": "the last problem"
}
],
"8": [
{
"1-2": "school daze"
},
{
"3": "the maud couple"
},
{
"4": "fake it 'til you make it"
},
{
"5": "grannies gone wild"
},
{
"6": "surf and/or turf"
},
{
"7": "horse play"
},
{
"8": "the parent map"
},
{
"9": "non-compete clause"
},
{
"10": "the break up breakdown"
},
{
"11": "molt down"
},
{
"12": "marks for effort"
},
{
"13": "the mean 6"
},
{
"14": "a matter of principals"
},
{
"15": "the hearth's warming club"
},
{
"16": "friendship university"
},
{
"17": "the end in friend"
},
{
"18": "yakity-sax"
},
{
"19": "on the road to friendship"
},
{
"20": "the washouts (episode)"
},
{
"21": "a rockhoof and a hard place"
},
{
"22": "what lies beneath"
},
{
"23": "sounds of silence"
},
{
"24": "father knows beast"
},
{
"25-26": "school raze"
},
{
"Special": "best gift ever"
}
],
"7": [
{
"1": "celestial advice"
},
{
"2": "all bottled up"
},
{
"3": "a flurry of emotions"
},
{
"4": "rock solid friendship"
},
{
"5": "fluttershy leans in"
},
{
"6": "forever filly"
},
{
"7": "parental glideance"
},
{
"8": "hard to say anything"
},
{
"9": "honest apple"
},
{
"10": "a royal problem"
},
{
"11": "not asking for trouble"
},
{
"12": "discordant harmony"
},
{
"13": "the perfect pear"
},
{
"14": "fame and misfortune"
},
{
"15": "triple threat"
},
{
"16": "campfire tales"
},
{
"17": "to change a changeling"
},
{
"18": "daring done?"
},
{
"19": "it isn't the mane thing about you"
},
{
"20": "a health of information"
},
{
"21": "marks and recreation"
},
{
"22": "once upon a zeppelin"
},
{
"23": "secrets and pies"
},
{
"24": "uncommon bond"
},
{
"25-26": "shadow play"
}
],
"6": [
{
"1-2": "the crystalling"
},
{
"3": "the gift of the maud pie"
},
{
"4": "on your marks"
},
{
"5": "gauntlet of fire"
},
{
"6": "no second prances"
},
{
"7": "newbie dash"
},
{
"8": "a hearth's warming tail"
},
{
"9": "the saddle row review"
},
{
"10": "applejack's \"day\" off"
},
{
"11": "flutter brutter"
},
{
"12": "spice up your life"
},
{
"13": "stranger than fan fiction"
},
{
"14": "the cart before the ponies"
},
{
"15": "28 pranks later"
},
{
"16": "the times they are a changeling"
},
{
"17": "dungeons and discords"
},
{
"18": "buckball season"
},
{
"19": "the fault in our cutie marks"
},
{
"20": "viva las pegasus"
},
{
"21": "every little thing she does"
},
{
"22": "ppov"
},
{
"23": "where the apple lies"
},
{
"24": "top bolt"
},
{
"25-26": "to where and back again"
}
],
"5": [
{
"1-2": "the cutie map"
},
{
"3": "castle sweet castle"
},
{
"4": "bloom and gloom"
},
{
"5": "tanks for the memories"
},
{
"6": "appleoosa's most wanted"
},
{
"7": "make new friends but keep discord"
},
{
"8": "the lost treasure of griffonstone"
},
{
"9": "slice of life (episode)"
},
{
"10": "princess spike"
},
{
"11": "party pooped"
},
{
"12": "amending fences"
},
{
"13": "do princesses dream of magic sheep"
},
{
"14": "canterlot boutique"
},
{
"15": "rarity investigates"
},
{
"16": "made in manehattan"
},
{
"17": "brotherhooves social"
},
{
"18": "crusaders of the lost mark"
},
{
"19": "the one where pinkie pie knows"
},
{
"20": "hearthbreakers"
},
{
"21": "scare master"
},
{
"22": "what about discord?"
},
{
"23": "the hooffields and mccolts"
},
{
"24": "the mane attraction"
},
{
"25-26": "the cutie remark"
}
],
"4": [
{
"1-2": "princess twilight sparkle (episode)"
},
{
"3": "castle mane-ia"
},
{
"4": "daring don't"
},
{
"5": "flight to the finish"
},
{
"6": "power ponies"
},
{
"7": "bats!"
},
{
"8": "rarity takes manehattan"
},
{
"9": "pinkie apple pie"
},
{
"10": "rainbow falls"
},
{
"11": "three's a crowd"
},
{
"12": "pinkie pride"
},
{
"13": "simple ways"
},
{
"14": "filli vanilli"
},
{
"15": "twilight time"
},
{
"16": "it ain't easy being breezies"
},
{
"17": "somepony to watch over me"
},
{
"18": "maud pie (episode)"
},
{
"19": "for whom the sweetie belle toils"
},
{
"20": "leap of faith"
},
{
"21": "testing testing 1-2-3"
},
{
"22": "trade ya"
},
{
"23": "inspiration manifestation"
},
{
"24": "equestria games"
},
{
"25-26": "twilight's kingdom"
}
],
"3": [
{
"1-2": "the crystal empire"
},
{
"3": "too many pinkie pies"
},
{
"4": "one bad apple"
},
{
"5": "magic duel"
},
{
"6": "sleepless in ponyville"
},
{
"7": "wonderbolts academy"
},
{
"8": "just for sidekicks"
},
{
"9": "apple family reunion"
},
{
"10": "spike at your service"
},
{
"11": "keep calm and flutter on"
},
{
"12": "games ponies play"
},
{
"13": "magical mystery cure"
}
],
"2": [
{
"1-2": "the return of harmony"
},
{
"3": "lesson zero"
},
{
"4": "luna eclipsed"
},
{
"5": "sisterhooves social"
},
{
"6": "the cutie pox"
},
{
"7": "may the best pet win"
},
{
"8": "the mysterious mare do well"
},
{
"9": "sweet and elite"
},
{
"10": "secret of my excess"
},
{
"11": "family appreciation day"
},
{
"12": "baby cakes"
},
{
"13": "hearth's warming eve (episode)"
},
{
"14": "the last roundup"
},
{
"15": "the super speedy cider squeezy 6000"
},
{
"16": "read it and weep"
},
{
"17": "hearts and hooves day (episode)"
},
{
"18": "a friend in deed"
},
{
"19": "putting your hoof down"
},
{
"20": "it's about time"
},
{
"21": "dragon quest"
},
{
"22": "hurricane fluttershy"
},
{
"23": "ponyville confidential"
},
{
"24": "mmmystery on the friendship express"
},
{
"25-26": "a canterlot wedding"
}
],
"1": [
{
"1-2": "friendship is magic"
},
{
"3": "the ticket master"
},
{
"4": "applebuck season"
},
{
"5": "griffon the brush off"
},
{
"6": "boast busters"
},
{
"7": "dragonshy"
},
{
"8": "look before you sleep"
},
{
"9": "bridle gossip"
},
{
"10": "swarm of the century"
},
{
"11": "winter wrap up"
},
{
"12": "call of the cutie"
},
{
"13": "fall weather friends"
},
{
"14": "suited for success"
},
{
"15": "feeling pinkie keen"
},
{
"16": "sonic rainboom (episode)"
},
{
"17": "stare master"
},
{
"18": "the show stoppers"
},
{
"19": "a dog and pony show"
},
{
"20": "green isn't your color"
},
{
"21": "over a barrel"
},
{
"22": "a bird in the hoof"
},
{
"23": "the cutie mark chronicles"
},
{
"24": "owl's well that ends well"
},
{
"25": "party of one"
},
{
"26": "the best night ever"
}
]
}

View file

@ -42,6 +42,9 @@
button.button.js-tag-sauce-toggle data-click-toggle=".tagsauce, .js-imageform" data-click-focus=".js-taginput-plain:not(.hidden), .js-taginput-input"
' Cancel
.block.js-tagtable data-target='[name="image[tag_input]"]'
= PhilomenaWeb.TagView.quick_tags(@conn)
- else
p
' You can't edit the tags on this image.

View file

@ -61,6 +61,11 @@
button.button.button--state-warning.button--separate-left.button--bold id="tagsinput-load" type="button" title="This button loads any saved tags from your browser" Load
button.button.button--state-danger.button--separate-left.button--bold id="tagsinput-clear" type="button" title="This button will clear the list of tags above" Clear
p You can mouse over tags below to view a description, and click to add. Short tag names can be used and will expand to full.
.block.js-tagtable data-target='[name="image[tag_input]"]'
= PhilomenaWeb.TagView.quick_tags(@conn)
br
.field

View file

@ -35,9 +35,9 @@ h1 Search
a data-search-add="my:upvotes" data-search-show-help=" " My upvotes
a data-search-add="my:uploads" data-search-show-help=" " My uploads
a data-search-add="my:watched" data-search-show-help=" " My watched tags
/.flex__right
.flex__right
a href="#" data-click-toggle="#js-search-tags" Quick tags
a href=search_syntax_path Help
a href="/search/syntax" Help
.block__content
.hidden.walloftext data-search-help="numeric"
@ -93,8 +93,9 @@ h1 Search
code<> source_url:*deviantart.com*
| .
/#js-search-tags.hidden
/= render partial: 'tags/quick_tag_table', locals: { target: '.js-search-field' }
#js-search-tags.hidden
.block.js-tagtable data-target=".js-search-field"
= PhilomenaWeb.TagView.quick_tags(@conn)
.field.field--inline.flex-wrap
= submit "Search", class: "button button--state-primary"

View file

@ -0,0 +1,14 @@
elixir:
tabs = Enum.with_index(@data["tabs"])
tab_modes = @data["tab_modes"]
.block__header--sub.block__header--js--tabbed
= for {name, i} <- tabs do
= link name, to: "#", class: tab_class(i), data: [click_tab: name]
= for {name, i} <- tabs do
- tab_data = @data[name]
- tab_mode = tab_modes[name]
.block__tab.quick-tag-table__tab class=tab_body_class(i) data-tab=name
= render PhilomenaWeb.TagView, "_quick_tag_table_#{tab_mode}.html", tab: name, data: tab_data, shipping: @shipping, tags: @tags, conn: @conn

View file

@ -0,0 +1,8 @@
= for {heading, tag_names} <- @data do
div
strong = heading
br
= for tag_name <- tag_names do
= tag_link @tags[tag_name], tag_name
br

View file

@ -0,0 +1,9 @@
= for slice <- Enum.chunk_every(@data, 10) do
div
= for map <- slice do
- [{header, tag_name}] = Enum.to_list(map)
= header
' .
= tag_link @tags[tag_name], tag_name
br

View file

@ -0,0 +1,5 @@
= for slice <- Enum.chunk_every(@shipping[@tab], 10) do
div
= for tag_name <- slice do
= tag_link @tags[tag_name], tag_name
br

View file

@ -0,0 +1,10 @@
= for {heading, maps} <- @data do
div
strong = heading
br
= for {name, alias_name} <- maps do
=> name
' -
= tag_link @tags[alias_name], alias_name
br

View file

@ -1,3 +1,120 @@
defmodule PhilomenaWeb.TagView do
use PhilomenaWeb, :view
# this is bad practice, don't copy this.
alias Philomena.Tags.Implication
alias Philomena.Tags.Tag
alias Philomena.Repo
import Ecto.Query
def quick_tags(conn) do
case Application.get_env(:philomena, :quick_tags) do
nil ->
quick_tags =
Application.get_env(:philomena, :quick_tags_json)
|> Jason.decode!()
|> lookup_quick_tags()
|> render_quick_tags(conn)
Application.put_env(:philomena, :quick_tags, quick_tags)
quick_tags
quick_tags ->
quick_tags
end
end
def tab_class(0), do: "selected"
def tab_class(_), do: nil
def tab_body_class(0), do: nil
def tab_body_class(_), do: "hidden"
def tag_link(nil, tag_name), do: tag_name
def tag_link(tag, tag_name) do
title = title(implications(tag) ++ short_description(tag))
link tag_name, to: "#", title: title, data: [tag_name: tag_name, click_addtag: tag_name]
end
defp implications(%{implied_tags: []}), do: []
defp implications(%{implied_tags: it}) do
names =
it
|> Enum.map(& &1.name)
|> Enum.sort()
|> Enum.join(", ")
["Implies: #{names}"]
end
defp short_description(%{short_description: s}) when s in ["", nil], do: []
defp short_description(%{short_description: s}), do: [s]
defp title([]), do: nil
defp title(descriptions), do: Enum.join(descriptions, "\n")
defp lookup_quick_tags(%{"tabs" => tabs, "tab_modes" => tab_modes} = data) do
tags =
tabs
|> Enum.flat_map(&names_in_tab(tab_modes[&1], data[&1]))
|> tags_indexed_by_name()
shipping =
tabs
|> Enum.filter(&tab_modes[&1] == "shipping")
|> Map.new(fn tab ->
sd = data[tab]
{tab, implied_by_multitag(sd["implying"], sd["not_implying"])}
end)
{tags, shipping, data}
end
defp render_quick_tags({tags, shipping, data}, conn) do
render PhilomenaWeb.TagView, "_quick_tag_table.html", tags: tags, shipping: shipping, data: data, conn: conn
end
defp names_in_tab("default", data) do
Map.values(data)
|> List.flatten()
end
defp names_in_tab("season", data) do
data
|> Enum.flat_map(&Map.values/1)
end
defp names_in_tab("shorthand", data) do
data
|> Map.values()
|> Enum.flat_map(&Map.values/1)
end
defp names_in_tab(_mode, _data), do: []
defp tags_indexed_by_name(names) do
Tag
|> where([t], t.name in ^names)
|> preload(:implied_tags)
|> Repo.all()
|> Map.new(&{&1.name, &1})
end
defp implied_by_multitag(tag_names, ignore_tag_names) do
query =
from t in Tag,
left_join: i in Implication,
on: t.id == i.tag_id,
left_join: it in Tag,
on: it.id == i.implied_tag_id,
where: it.name in ^tag_names and it.name not in ^ignore_tag_names,
order_by: [desc: t.images_count],
preload: :implied_tags,
limit: 40
Repo.all(query)
end
end