Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
kookster committed Nov 23, 2024
2 parents 3cc10c8 + 2a9e8f5 commit 77a9750
Show file tree
Hide file tree
Showing 29 changed files with 248 additions and 75 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
ruby 3.3.5
ruby 3.3.6
nodejs 20.7.0
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ruby:3.3.5-alpine
FROM ruby:3.3.6-alpine

LABEL org.prx.app="yes"
LABEL org.prx.spire.publish.ecr="RAILS_APP"
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.3.5"
ruby "3.3.6"

# core
gem "activerecord-session_store"
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ DEPENDENCIES
webmock

RUBY VERSION
ruby 3.3.5p100
ruby 3.3.6p108

BUNDLED WITH
2.5.18
2.5.23
30 changes: 13 additions & 17 deletions app/controllers/feeds_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ def index

# GET /feeds/1
def show
@feed.assign_attributes(feed_params_with_apple)
@feed.assign_attributes(feed_params)
authorize @feed
@apple_show_options = get_apple_show_options(@feed)
end

# GET /feeds/new
Expand All @@ -22,19 +23,25 @@ def new
@feed.clear_attribute_changes(%i[file_name podcast_id private slug])
end

def get_apple_show_options(feed)
if feed.apple? && feed.apple_config&.key
feed.apple_show_options
end
end

def new_apple
@feed = Feeds::AppleSubscription.new(podcast: @podcast, private: true)
@feed.build_apple_config
@feed.apple_config.build_key
authorize @feed

@feed.assign_attributes(feed_params_with_apple)
@feed.assign_attributes(feed_params)
render "new"
end

# POST /feeds
def create
@feed = @podcast.feeds.new(feed_params_with_apple)
@feed = @podcast.feeds.new(feed_params)
@feed.slug = "" if @feed.slug.nil?
authorize @feed

Expand Down Expand Up @@ -114,10 +121,6 @@ def feed_params
params.fetch(:feed, {}).permit(:slug).merge(nilified_feed_params)
end

def feed_params_with_apple
params.fetch(:feed, {}).permit(:slug).merge(nilified_feed_params).merge(apple_params)
end

def nilified_feed_params
nilify params.fetch(:feed, {}).permit(
:lock_version,
Expand All @@ -144,20 +147,13 @@ def nilified_feed_params
:paid,
:sonic_id,
:type,
:apple_show_id,
itunes_category: [],
itunes_subcategory: [],
feed_tokens_attributes: %i[id label token _destroy],
feed_images_attributes: %i[id original_url size alt_text caption credit _destroy _retry],
itunes_images_attributes: %i[id original_url size alt_text caption credit _destroy _retry]
)
end

def apple_params
nilify params.fetch(:feed, {}).permit(
apple_config_attributes: {
id: :id,
key_attributes: %i[id provider_id key_id key_pem_b64]
}
itunes_images_attributes: %i[id original_url size alt_text caption credit _destroy _retry],
apple_config_attributes: [:id, :publish_enabled, :sync_blocks_rss, {key_attributes: %i[id provider_id key_id key_pem_b64]}]
)
end
end
7 changes: 0 additions & 7 deletions app/javascript/controllers/apple_key_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,7 @@ export default class extends Controller {
const keyId = fields[1].split(".")[0]

this.providerTargets.forEach((target) => (target.value = provider))
this.providerTarget.disabled = false
this.providerTarget.focus()
this.providerTarget.disabled = true

this.keyTargets.forEach((target) => (target.value = keyId))
this.keyTarget.disabled = false
this.keyTarget.focus()
this.keyTarget.disabled = true
}

convertKeyToB64(fileText) {
Expand Down
12 changes: 7 additions & 5 deletions app/models/apple/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module Apple
class Api
API_BASE = "https://api.podcastsconnect.apple.com/v1/"

ERROR_RETRIES = 3
SUCCESS_CODES = [200, 201].freeze
DEFAULT_BATCH_SIZE = 5
Expand Down Expand Up @@ -79,10 +81,6 @@ def jwt
JWT.encode(jwt_payload, ec_key, "ES256", jwt_headers)
end

def api_base
"https://api.podcastsconnect.apple.com/v1/"
end

def list_shows
get("shows")
end
Expand Down Expand Up @@ -115,8 +113,12 @@ def get_paged_collection(api_frag)
res.flatten
end

def self.join_url(api_frag)
URI.join(API_BASE, api_frag)
end

def join_url(api_frag)
URI.join(api_base, api_frag)
self.class.join_url(api_frag)
end

def local_api_retry_errors(tries: ERROR_RETRIES)
Expand Down
14 changes: 11 additions & 3 deletions app/models/apple/episode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -382,16 +382,20 @@ def remove_episode_audio_container_parameters
end

def publishing_state_bridge_params(state)
self.class.publishing_state_bridge_params(apple_id, state)
end

def self.publishing_state_bridge_params(apple_id, state)
{
request_metadata: {
apple_episode_id: apple_id
},
api_url: api.join_url("episodePublishingRequests").to_s,
api_parameters: publishing_state_parameters(state)
api_url: Apple::Api.join_url("episodePublishingRequests").to_s,
api_parameters: publishing_state_params(apple_id, state)
}
end

def publishing_state_parameters(state)
def self.publishing_state_params(apple_id, state)
{
data: {
type: "episodePublishingRequests",
Expand All @@ -410,6 +414,10 @@ def publishing_state_parameters(state)
}
end

def publishing_state_parameters(state)
self.class.publishing_state_params(apple_id, state)
end

def apple?
feeder_episode.apple?
end
Expand Down
10 changes: 10 additions & 0 deletions app/models/apple/key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ class Key < ApplicationRecord

validate :provider_id_is_valid, if: :provider_id?
validate :ec_key_format, if: :key_pem_b64?
validate :must_have_working_key

def must_have_working_key
return if Rails.env.test? || !changed?
api = Apple::Api.from_key(self)
Apple::Show.apple_shows_json(api)
rescue => err
logger.error(err)
errors.add(:key_id, "must have a working Apple key")
end

def provider_id_is_valid
if provider_id.include?("_")
Expand Down
23 changes: 17 additions & 6 deletions app/models/apple/show.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,29 @@ class Show
:private_feed,
:api

def self.apple_shows_json(api)
api.get_paged_collection("shows")
end

def self.apple_episode_json(api, show_id)
api.get_paged_collection("shows/#{show_id}/episodes")
end

def self.connect_existing(apple_show_id, apple_config)
api = Apple::Api.from_apple_config(apple_config)

SyncLog.log!(feeder_id: apple_config.public_feed.id,
feeder_type: :feeds,
sync_completed_at: Time.now.utc,
external_id: apple_show_id)
if (sl = SyncLog.find_by(feeder_id: apple_config.public_feed.id, feeder_type: :feeds))
if apple_show_id.blank?
return sl.destroy!
elsif sl.external_id != apple_show_id
sl.update!(external_id: apple_show_id)
end
else
SyncLog.log!(feeder_id: apple_config.public_feed.id,
feeder_type: :feeds,
sync_completed_at: Time.now.utc,
external_id: apple_show_id)
end

api = Apple::Api.from_apple_config(apple_config)
new(api: api,
public_feed: apple_config.public_feed,
private_feed: apple_config.private_feed)
Expand Down
8 changes: 7 additions & 1 deletion app/models/feed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Feed < ApplicationRecord

after_initialize :set_defaults
before_validation :sanitize_text
before_save :set_public_feeds_url
before_save :set_public_feeds_url, :check_enclosure_changes
after_create :set_default_episodes

scope :default, -> { where(slug: nil) }
Expand Down Expand Up @@ -106,6 +106,12 @@ def set_public_feeds_url
end
end

def check_enclosure_changes
if persisted? && (enclosure_prefix_changed? || enclosure_template_changed?)
self.enclosure_updated_at = Time.now
end
end

# copy all episodes in default_feed to this one
# TODO: is this always the right logic?
def set_default_episodes
Expand Down
29 changes: 29 additions & 0 deletions app/models/feeds/apple_subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class Feeds::AppleSubscription < Feed

after_create :republish_public_feed

after_save_commit :update_apple_show

has_one :apple_config, class_name: "::Apple::Config", dependent: :destroy, autosave: true, validate: true, inverse_of: :feed

accepts_nested_attributes_for :apple_config, allow_destroy: true, reject_if: :all_blank
Expand All @@ -23,6 +25,14 @@ class Feeds::AppleSubscription < Feed
validate :must_be_private
validate :must_have_token

# for soft delete, need a unique slug to be able to make another
def paranoia_destroy_attributes
{
deleted_at: current_time_from_proper_timezone,
slug: "#{slug} - #{Time.now.to_i}"
}
end

def set_defaults
self.slug ||= DEFAULT_FEED_SLUG
self.title ||= DEFAULT_TITLE
Expand All @@ -35,6 +45,25 @@ def set_defaults
super
end

def update_apple_show
if previous_changes[:apple_show_id]
Apple::Show.connect_existing(apple_show_id, apple_config)
end
end

def apple_show_options
used_ids = Feed.apple.distinct.where("id != ?", id).pluck(:apple_show_id).compact
api = Apple::Api.from_apple_config(apple_config)
shows_json = Apple::Show.apple_shows_json(api) || []
shows_json
.filter { |sj| sj["attributes"]["publishingState"] != "ARCHIVED" }
.filter { |sj| !used_ids.include?(sj["id"]) }
.map { |sj| ["#{sj["id"]} (#{sj["attributes"]["title"]})", sj["id"]] }
rescue => err
logger.error(err)
[]
end

def guess_audio_format
default_feed_audio_format || episode_audio_format || DEFAULT_AUDIO_FORMAT
end
Expand Down
2 changes: 1 addition & 1 deletion app/policies/apple/config_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ def create?
end

def update?
false
FeedPolicy.new(token, resource.feed).update?
end
end
6 changes: 3 additions & 3 deletions app/policies/feed_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ def create?
end

def new_apple?
create?
update?
end

def update?
PodcastPolicy.new(token, resource.podcast).update?
PodcastPolicy.new(token, resource.podcast).update? && !resource.edit_locked?
end

def destroy?
resource.custom? && update? && !resource.apple?
resource.custom? && update?
end
end
1 change: 1 addition & 0 deletions app/representers/api/auth/feed_representer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Api::Auth::FeedRepresenter < Api::BaseRepresenter
property :url
property :new_feed_url
property :enclosure_prefix
property :enclosure_updated_at
property :display_episodes_count
property :display_full_episodes_count
property :episode_offset_seconds
Expand Down
14 changes: 12 additions & 2 deletions app/views/feeds/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@
<%= form_with(url: url, model: model, method: method, html: {autocomplete: "off"}, data: data) do |form| %>
<div class="row my-4 mx-2" data-controller="feed-tokens" data-feed-tokens-unsaved-outlet="form">
<div class="col-lg-8">
<% if feed.edit_locked? %>
<div class="col-12">
<div class="alert alert-danger" role="alert">
<b><%= t(".title.warning") %></b>
<%= t(".help.locked").html_safe %>
</div>
</div>
<% end %>
<div class="row" data-controller="feed-link">
<% if feed.default? %>
<%= render "form_main", podcast: podcast, feed: feed, form: form %>
<%= render "form_audio_format", podcast: podcast, feed: feed, form: form %>
<% elsif apple_feed?(feed) %>
<%= render "form_apple_config", podcast: podcast, feed: feed, form: form %>
<%= render "form_audio_format", podcast: podcast, feed: feed, form: form %>
<%= render "form_ad_zones", podcast: podcast, feed: feed, form: form %>
<% if feed.persisted? %>
<%= render "form_audio_format", podcast: podcast, feed: feed, form: form %>
<%= render "form_ad_zones", podcast: podcast, feed: feed, form: form %>
<% end %>
<% else %> <%# custom feeds %>
<%= render "form_main", podcast: podcast, feed: feed, form: form %>
<%= render "form_auth", podcast: podcast, feed: feed, form: form %>
Expand Down
Loading

0 comments on commit 77a9750

Please sign in to comment.