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
This commit is contained in:
Anna Buianova 2020-03-12 00:25:12 +03:00 committed by GitHub
parent e6afbd043b
commit f05e5254bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 7 deletions

View file

@ -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?

View file

@ -1,12 +1,33 @@
<hr />
<h2 class="m-0 mb-3"><%= link_to @podcast.title, "/#{@podcast.slug}" %></h2>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card mb-3">
<div class="card-header">
<h2 class="m-0"><%= link_to @podcast.title, "/#{@podcast.slug}" %></h2>
<h3>Fetch episodes</h3>
</div>
<div class="card-body">
<%= form_with(url: fetch_internal_podcast_path(@podcast.id), method: :post, local: true) do %>
<div class="form-group">
<%= check_box_tag :force %>
<%= label_tag :force %>
<small>(When checked, the existing episodes' urls will be re-checked and episodes reachable and https fields will be updated accordingly if needed.)</small>
</div>
<div class="form-group">
<%= text_field_tag :limit, 5, size: 2 %>
<%= label_tag :limit %>
<small>(The number of episodes to fetch. When set to an empty string, last 1_000 episodes will be fetched.)</small>
</div>
<%= submit_tag "Fetch episodes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
<div class="card mb-3">
<div class="card-header">
<h3>Manage Admins</h3>
</div>
<div class="card-body">
<% if @podcast.admins.present? %>
<h3>Admins:</h3>
<ul class="list-group list-group-flush mb-3">
<% @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 @@
</div>
<%= f.submit "Add Admin", class: "btn btn-primary" %>
<% end %>
</div>
</div>
<div class="card mb-3">
<div class="card-header">
<h3>Edit Podcast</h3>
</div>
<div class="card-body">
<%= form_for [:internal, @podcast] do |f| %>
<hr>
<div class="form-group">

View file

@ -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

View file

@ -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

View file

@ -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