From 214243b3fec4937e45ef1ceaba1149004cdf3b44 Mon Sep 17 00:00:00 2001
From: Benjamin Bellamy <ben@podlibre.org>
Date: Thu, 11 Feb 2021 17:41:20 +0000
Subject: [PATCH] fix(rss-import): add Castopod user-agent, handle redirects
 for downloaded files, add Content namespace

---
 app/Controllers/Admin/PodcastImport.php | 29 ++++++++++++-----
 app/Helpers/media_helper.php            | 42 +++++++++++++++++++++++--
 app/Language/en/PodcastImport.php       |  9 ++----
 app/Language/fr/PodcastImport.php       |  8 +----
 app/Views/admin/podcast/import.php      | 28 +++++++++++------
 5 files changed, 83 insertions(+), 33 deletions(-)

diff --git a/app/Controllers/Admin/PodcastImport.php b/app/Controllers/Admin/PodcastImport.php
index 05625077a8..cfea7a4397 100644
--- a/app/Controllers/Admin/PodcastImport.php
+++ b/app/Controllers/Admin/PodcastImport.php
@@ -76,6 +76,7 @@ class PodcastImport extends BaseController
                 ->with('errors', $this->validator->getErrors());
         }
         try {
+            ini_set('user_agent', 'Castopod/' . CP_VERSION);
             $feed = simplexml_load_file(
                 $this->request->getPost('imported_feed_url')
             );
@@ -98,6 +99,9 @@ class PodcastImport extends BaseController
         $nsPodcast = $feed->channel[0]->children(
             'https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md'
         );
+        $nsContent = $feed->channel[0]->children(
+            'http://purl.org/rss/1.0/modules/content/'
+        );
 
         if ((string) $nsPodcast->locked === 'yes') {
             return redirect()
@@ -313,6 +317,9 @@ class PodcastImport extends BaseController
             $nsPodcast = $item->children(
                 'https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md'
             );
+            $nsContent = $item->children(
+                'http://purl.org/rss/1.0/modules/content/'
+            );
 
             $slug = slugify(
                 $this->request->getPost('slug_field') === 'title'
@@ -328,13 +335,21 @@ class PodcastImport extends BaseController
             }
             $slugs[] = $slug;
 
-            $itemDescriptionHtml =
-                $this->request->getPost('description_field') === 'summary'
-                    ? $nsItunes->summary
-                    : ($this->request->getPost('description_field') ===
-                    'subtitle_summary'
-                        ? $nsItunes->subtitle . '<br/>' . $nsItunes->summary
-                        : $item->description);
+            $itemDescriptionHtml = null;
+            switch ($this->request->getPost('description_field')) {
+                case 'content':
+                    $itemDescriptionHtml = $nsContent->encoded;
+                    break;
+                case 'summary':
+                    $itemDescriptionHtml = $nsItunes->summary;
+                    break;
+                case 'subtitle_summary':
+                    $itemDescriptionHtml =
+                        $nsItunes->subtitle . '<br/>' . $nsItunes->summary;
+                    break;
+                default:
+                    $itemDescriptionHtml = $item->description;
+            }
 
             $newEpisode = new \App\Entities\Episode([
                 'podcast_id' => $newPodcastId,
diff --git a/app/Helpers/media_helper.php b/app/Helpers/media_helper.php
index 77d77478f7..e512a289f5 100644
--- a/app/Helpers/media_helper.php
+++ b/app/Helpers/media_helper.php
@@ -6,6 +6,8 @@
  * @link       https://castopod.org/
  */
 
+use CodeIgniter\HTTP\ResponseInterface;
+
 /**
  * Saves a file to the corresponding podcast folder in `public/media`
  *
@@ -34,14 +36,50 @@ function save_podcast_media($file, $podcast_name, $media_name)
 
 function download_file($fileUrl)
 {
+    $client = \Config\Services::curlrequest();
+    $uri = new \CodeIgniter\HTTP\URI($fileUrl);
+
+    $response = $client->get($uri, [
+        'headers' => [
+            'User-Agent' => 'Castopod/' . CP_VERSION,
+        ],
+    ]);
+
+    // redirect to new file location
+    $newFileUrl = $fileUrl;
+    while (
+        in_array(
+            $response->getStatusCode(),
+            [
+                ResponseInterface::HTTP_MOVED_PERMANENTLY,
+                ResponseInterface::HTTP_FOUND,
+                ResponseInterface::HTTP_SEE_OTHER,
+                ResponseInterface::HTTP_NOT_MODIFIED,
+                ResponseInterface::HTTP_TEMPORARY_REDIRECT,
+                ResponseInterface::HTTP_PERMANENT_REDIRECT,
+            ],
+            true
+        )
+    ) {
+        $newFileUrl = (string) trim(
+            $response->getHeader('location')->getValue()
+        );
+        $newLocation = new \CodeIgniter\HTTP\URI($newFileUrl);
+        $response = $client->get($newLocation, [
+            'headers' => [
+                'User-Agent' => 'Castopod/' . CP_VERSION,
+            ],
+            'http_errors' => false,
+        ]);
+    }
     $tmpFilename =
         time() .
         '_' .
         bin2hex(random_bytes(10)) .
         '.' .
-        pathinfo($fileUrl, PATHINFO_EXTENSION);
+        pathinfo($newFileUrl, PATHINFO_EXTENSION);
     $tmpFilePath = WRITEPATH . 'uploads/' . $tmpFilename;
-    file_put_contents($tmpFilePath, file_get_contents($fileUrl));
+    file_put_contents($tmpFilePath, $response->getBody());
 
     return new \CodeIgniter\Files\File($tmpFilePath);
 }
diff --git a/app/Language/en/PodcastImport.php b/app/Language/en/PodcastImport.php
index 5660a280f4..1ce609d3d3 100644
--- a/app/Language/en/PodcastImport.php
+++ b/app/Language/en/PodcastImport.php
@@ -25,13 +25,8 @@ return [
         'link' => '&lt;link&gt;',
         'title' => '&lt;title&gt;',
     ],
-    'description_field' => [
-        'label' => 'Source field used for episode description / show notes',
-        'description' => '&lt;description&gt;',
-        'summary' => '&lt;itunes:summary&gt;',
-        'subtitle_summary' =>
-            '&lt;itunes:subtitle&gt; + &lt;itunes:summary&gt;',
-    ],
+    'description_field' =>
+        'Source field used for episode description / show notes',
     'force_renumber' => 'Force episodes renumbering',
     'force_renumber_hint' =>
         'Use this if your podcast does not have episode numbers but wish to set them during import.',
diff --git a/app/Language/fr/PodcastImport.php b/app/Language/fr/PodcastImport.php
index 539d06095a..371185a142 100644
--- a/app/Language/fr/PodcastImport.php
+++ b/app/Language/fr/PodcastImport.php
@@ -26,13 +26,7 @@ return [
         'link' => '&lt;link&gt; (adresse)',
         'title' => '&lt;title&gt; (titre)',
     ],
-    'description_field' => [
-        'label' => 'Champs pour la description des épisodes',
-        'description' => '&lt;description&gt;',
-        'summary' => '&lt;itunes:summary&gt;',
-        'subtitle_summary' =>
-            '&lt;itunes:subtitle&gt; + &lt;itunes:summary&gt;',
-    ],
+    'description_field' => 'Champs pour la description des épisodes',
     'force_renumber' => 'Forcer la re-numérotation des épisodes',
     'force_renumber_hint' =>
         'Utilisez ceci si le podcast à importer ne contient pas de numéros d’épisodes mais que vous souhaitez en ajouter pendant l’import.',
diff --git a/app/Views/admin/podcast/import.php b/app/Views/admin/podcast/import.php
index 4d4f1f1386..e6f484c849 100644
--- a/app/Views/admin/podcast/import.php
+++ b/app/Views/admin/podcast/import.php
@@ -111,7 +111,7 @@
 <?= form_fieldset_close() ?>
 
 <?= form_fieldset('', ['class' => 'flex flex-col mb-4']) ?>
-    <legend><?= lang('PodcastImport.description_field.label') ?></legend>
+    <legend><?= lang('PodcastImport.description_field') ?></legend>
     <label for="description" class="inline-flex items-center">
         <?= form_radio(
             [
@@ -124,9 +124,7 @@
                 ? old('description_field') == 'description'
                 : true
         ) ?>
-        <span class="ml-2"><?= lang(
-            'PodcastImport.description_field.description'
-        ) ?></span>
+        <span class="ml-2">&lt;description&gt;</span>
     </label>
     <label for="summary" class="inline-flex items-center">
         <?= form_radio(
@@ -140,9 +138,7 @@
                 ? old('description_field') == 'summary'
                 : false
         ) ?>
-        <span class="ml-2"><?= lang(
-            'PodcastImport.description_field.summary'
-        ) ?></span>
+        <span class="ml-2">&lt;itunes:summary&gt;</span>
     </label>
     <label for="subtitle_summary" class="inline-flex items-center">
         <?= form_radio(
@@ -156,9 +152,21 @@
                 ? old('description_field') == 'subtitle_summary'
                 : false
         ) ?>
-        <span class="ml-2"><?= lang(
-            'PodcastImport.description_field.subtitle_summary'
-        ) ?></span>
+        <span class="ml-2">&lt;itunes:subtitle&gt; + &lt;itunes:summary&gt;</span>
+    </label>
+    <label for="content" class="inline-flex items-center">
+        <?= form_radio(
+            [
+                'id' => 'content',
+                'name' => 'description_field',
+                'class' => 'form-radio text-green-500',
+            ],
+            'content',
+            old('description_field')
+                ? old('description_field') == 'content'
+                : false
+        ) ?>
+        <span class="ml-2">&lt;content:encoded&gt;</span>
     </label>
 <?= form_fieldset_close() ?>
 
-- 
GitLab