From f05e5254bb27cfefb16d44dd3b632b80a3c0e283 Mon Sep 17 00:00:00 2001 From: Anna Buianova Date: Thu, 12 Mar 2020 00:25:12 +0300 Subject: [PATCH] Fetch podcast's episodes from /internal (#6593) [deploy] * Formalized and improved Podcasts::GetEpisodesWorker documentation * Basic functionality for fetching podcasts episodes from /internal * Improved notice on fetching * Reorganized /internal/podcasts edit page --- .../internal/podcasts_controller.rb | 10 +++++- app/views/internal/podcasts/edit.html.erb | 35 ++++++++++++++++--- app/workers/podcasts/get_episodes_worker.rb | 7 ++-- config/routes.rb | 1 + spec/requests/internal/podcasts_spec.rb | 20 +++++++++++ 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/app/controllers/internal/podcasts_controller.rb b/app/controllers/internal/podcasts_controller.rb index 502989eb8..77cc5548f 100644 --- a/app/controllers/internal/podcasts_controller.rb +++ b/app/controllers/internal/podcasts_controller.rb @@ -1,7 +1,7 @@ class Internal::PodcastsController < Internal::ApplicationController layout "internal" - before_action :find_podcast, only: %i[edit update remove_admin add_admin] + before_action :find_podcast, only: %i[edit update fetch remove_admin add_admin] before_action :find_user, only: %i[remove_admin add_admin] def index @@ -22,6 +22,14 @@ class Internal::PodcastsController < Internal::ApplicationController end end + def fetch + limit = params[:limit].to_i.zero? ? nil : params[:limit].to_i + force = params[:force].to_i == 1 + Podcasts::GetEpisodesWorker.perform_async(podcast_id: @podcast.id, limit: limit, force: force) + flash[:notice] = "Podcast's episodes fetching was scheduled (#{@podcast.title}, ##{@podcast.id})" + redirect_to internal_podcasts_path + end + def remove_admin removed_roles = @user.remove_role(:podcast_admin, @podcast) if removed_roles.empty? diff --git a/app/views/internal/podcasts/edit.html.erb b/app/views/internal/podcasts/edit.html.erb index 7e9e2d80a..35d929404 100644 --- a/app/views/internal/podcasts/edit.html.erb +++ b/app/views/internal/podcasts/edit.html.erb @@ -1,12 +1,33 @@ +
+

<%= link_to @podcast.title, "/#{@podcast.slug}" %>

-
+
-

<%= link_to @podcast.title, "/#{@podcast.slug}" %>

+

Fetch episodes

+
+
+ <%= form_with(url: fetch_internal_podcast_path(@podcast.id), method: :post, local: true) do %> +
+ <%= check_box_tag :force %> + <%= label_tag :force %> + (When checked, the existing episodes' urls will be re-checked and episodes reachable and https fields will be updated accordingly if needed.) +
+
+ <%= text_field_tag :limit, 5, size: 2 %> + <%= label_tag :limit %> + (The number of episodes to fetch. When set to an empty string, last 1_000 episodes will be fetched.) +
+ <%= submit_tag "Fetch episodes", class: "btn btn-primary" %> + <% end %> +
+
+
+
+

Manage Admins

<% if @podcast.admins.present? %> -

Admins:

    <% @podcast.admins.each do |admin| %> <%= form_for @podcast, url: remove_admin_internal_podcast_path(@podcast.id), html: { method: :delete, class: "form-inline" } do |f| %> @@ -33,7 +54,13 @@
<%= f.submit "Add Admin", class: "btn btn-primary" %> <% end %> - +
+
+
+
+

Edit Podcast

+
+
<%= form_for [:internal, @podcast] do |f| %>
diff --git a/app/workers/podcasts/get_episodes_worker.rb b/app/workers/podcasts/get_episodes_worker.rb index 11d0928e3..bf018cbaf 100644 --- a/app/workers/podcasts/get_episodes_worker.rb +++ b/app/workers/podcasts/get_episodes_worker.rb @@ -4,8 +4,11 @@ module Podcasts sidekiq_options queue: :high_priority, retry: 10 - # podcast_data should be a Hash with keys :podcast_id, :limit, and :force_update - # :limit and :force_update are both optional - there are default values + # @param podcast_data [Hash] + # * :podcast_id [Integer] + # * :limit [Integer] (1_000) - number of episodes that will be fetched for this podcast + # * :force_update [Integer] (false) - if set to true, existing episodes' urls will be re-checked + # the episodes' `https` and `reachable` fields will be updated accordingly if needed def perform(podcast_data = {}) # Sidekiq turns arguments into Strings so the Ruby keyword argument sorcery doesn't work here # prevent any mismatch between String keys and Symbol keys diff --git a/config/routes.rb b/config/routes.rb index be45b380b..afe64cd80 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -55,6 +55,7 @@ Rails.application.routes.draw do resources :permissions, only: %i[index] resources :podcasts, only: %i[index edit update destroy] do member do + post :fetch post :add_admin delete :remove_admin end diff --git a/spec/requests/internal/podcasts_spec.rb b/spec/requests/internal/podcasts_spec.rb index 0add1d47b..cacf8cccb 100644 --- a/spec/requests/internal/podcasts_spec.rb +++ b/spec/requests/internal/podcasts_spec.rb @@ -72,4 +72,24 @@ RSpec.describe "/internal/podcasts", type: :request do expect(response).to redirect_to(internal_podcasts_path) end end + + describe "POST /internal/podcasts/:id/fetch_podcasts" do + it "redirects back to index with a notice" do + post fetch_internal_podcast_path(podcast.id) + expect(response).to redirect_to(internal_podcasts_path) + expect(flash[:notice]).to include("Podcast's episodes fetching was scheduled (#{podcast.title}, ##{podcast.id})") + end + + it "schedules a worker to fetch episodes" do + sidekiq_assert_enqueued_with(job: Podcasts::GetEpisodesWorker, args: [{ podcast_id: podcast.id, limit: 5, force: false }]) do + post fetch_internal_podcast_path(podcast.id), params: { limit: "5", force: nil } + end + end + + it "schedules a worker without limit and with force" do + sidekiq_assert_enqueued_with(job: Podcasts::GetEpisodesWorker, args: [{ podcast_id: podcast.id, force: true, limit: nil }]) do + post fetch_internal_podcast_path(podcast.id), params: { force: "1", limit: "" } + end + end + end end