diff --git a/app/queries/posts/top_tracks.rb b/app/queries/posts/top_tracks.rb index 5460ee0..b95e50a 100644 --- a/app/queries/posts/top_tracks.rb +++ b/app/queries/posts/top_tracks.rb @@ -5,14 +5,26 @@ module Adamantium module Queries module Posts class TopTracks - include Deps["settings", "repos.post_repo"] + include Deps["settings", "repos.post_repo", "repos.top_track_repo"] def call(slug:) post = post_repo.fetch!(slug) + start_date = TimeMath.week.floor(post.published_at).to_i + end_date = TimeMath.week.ceil(post.published_at).to_i + + top_tracks = top_track_repo.for_post(id: post.id) + + return top_tracks unless top_tracks.empty? lastfm = Lastfm.new(settings.lastfm_api_key, settings.lastfm_secret) - lastfm.user.get_weekly_track_chart(user: "dNitza", from: TimeMath.week.floor(post.published_at).to_i, to: TimeMath.week.ceil(post.published_at).to_i) + tracks = lastfm.user.get_weekly_track_chart(user: "dNitza", from: start_date, to: end_date) + + if track = tracks.first + top_track_repo.upsert(post_id: post.id, name: track["name"], artist: track.dig("artist", "content"), url: track["url"], mb_id: track["mbid"]) + end + + top_track_repo.for_post(id: post.id) end end end diff --git a/app/repos/top_track_repo.rb b/app/repos/top_track_repo.rb new file mode 100644 index 0000000..2b93734 --- /dev/null +++ b/app/repos/top_track_repo.rb @@ -0,0 +1,17 @@ +module Adamantium + module Repos + class TopTrackRepo < Adamantium::Repo[:top_tracks] + def for_post(id:) + top_tracks + .where(post_id: id) + .to_a + end + + def upsert(post_id:, name:, artist:, url:, mb_id:) + top_tracks + .upsert({name: name, artist: artist, url: url, mb_id: mb_id, post_id: post_id}, + { target: :post_id, update: {name: name, artist: artist, url: url, mb_id: mb_id, post_id: post_id} }) + end + end + end +end diff --git a/app/views/posts/top_tracks.rb b/app/views/posts/top_tracks.rb index 7a6138c..b0b200f 100644 --- a/app/views/posts/top_tracks.rb +++ b/app/views/posts/top_tracks.rb @@ -5,15 +5,15 @@ module Adamantium config.layout = false expose :name do |track:| - track["name"] + track.name end expose :artist do |track:| - track.dig("artist", "content") + track.artist end expose :url do |track:| - track["url"] + track.url end end end diff --git a/db/migrate/20230612061813_create_top_tracks.rb b/db/migrate/20230612061813_create_top_tracks.rb new file mode 100644 index 0000000..c24ff37 --- /dev/null +++ b/db/migrate/20230612061813_create_top_tracks.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + create_table :top_tracks do + column :artist, :text + column :name, :text + column :url, :text + column :mb_id, :text # musicbrainz.org ID + foreign_key :post_id, :posts, null: false, unique: true + end + end +end diff --git a/lib/adamantium/persistence/relations/top_tracks.rb b/lib/adamantium/persistence/relations/top_tracks.rb new file mode 100644 index 0000000..7ad9a73 --- /dev/null +++ b/lib/adamantium/persistence/relations/top_tracks.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Adamantium + module Persistence + module Relations + class TopTracks < ROM::Relation[:sql] + schema :top_tracks, infer: true + + auto_struct(true) + end + end + end +end diff --git a/slices/admin/actions/posts/syndicate.rb b/slices/admin/actions/posts/syndicate.rb index 61fdfcd..932a626 100644 --- a/slices/admin/actions/posts/syndicate.rb +++ b/slices/admin/actions/posts/syndicate.rb @@ -7,7 +7,7 @@ module Admin include Deps["commands.posts.syndicate"] def handle(req, res) - syndicate.(post_id: req.params[:id], target: req.params[:target]) + syndicate.call(post_id: req.params[:id], target: req.params[:target]) end end end diff --git a/slices/admin/commands/posts/syndicate.rb b/slices/admin/commands/posts/syndicate.rb index 54252e0..47ea067 100644 --- a/slices/admin/commands/posts/syndicate.rb +++ b/slices/admin/commands/posts/syndicate.rb @@ -11,7 +11,7 @@ module Admin def call(post_id:, target:) post = post_repo.find(id: post_id) - dayone.(name: post[:name], content: post[:content]) if target.to_sym == :day_one + dayone.call(name: post[:name], content: post[:content]) if target.to_sym == :day_one Success() end end