Skip to content

Commit

Permalink
Merge branch 'feature/wizard' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
mauricerenck committed Jul 25, 2019
2 parents 9924f6d + e96a93a commit fd19323
Show file tree
Hide file tree
Showing 21 changed files with 588 additions and 94 deletions.
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ You can now see your download stats in the panel. This currently works only, if

## Features

* ✅ Import wizard, move your existing podcast to kirby
* ✅ Panel blueprint section for episodes
* ✅ Panel blueprint for extended RSS feed (including all new iTunes specifications)
* ✅ Run multiple podcasts with just one Kirby installation
Expand All @@ -29,17 +30,34 @@ You can now see your download stats in the panel. This currently works only, if
* ✅ Statistics view in Panel
* ✅ Prefill fields from your ID3 data

### Planned

* Import your old podcast to Kirby Podcaster
* Snippet for Podlove Subscribe box
### Changelog

* 2019-07-25 - Podcaster Wizard, import your existing podcast into kirby
* 2019-07-24 - New Apple Podcast Categories

## Installation

- `composer require mauricerenck/podcaster`
- unzip [master.zip](https://github.com/mauricerenck/kirby-podcaster/releases/latest) as folder `site/plugins/kirby-podcaster`
- `git submodule add https://github.com/mauricerenck/kirby-podcaster.git site/plugins/kirby-podcaster`

### Move your existing Podcast to Kirby

![stats sample](doc-assets/create-wizard.png)

1. In the panel create a new page. Name it however you want, select the template `Podcaster Wizard`. After the page is created, open it in the panel.
2. Enter your current feed url, select the target page. Below this page all episodes and the feed will be created. Make sure there are no other pages within your target page, otherwise the import may fail.
3. Enter the template that should be used for your episodes. If your content files look like `article.txt` your template name i `article`.
4. You can now decide if the episodes should be created as draft (default and recommended) or unlisted.
5. Hit the `Start import` button and lean back.

![stats sample](doc-assets/wizard-panel.png)

**Please do not close the wizard page, or the import will be interrupted and fail**

After the import is finished, you should delete the import wizard page, you don't need it anymore.

### Create RSS-Feed
Log into the panel and go to the folder containing your podcast episodes. Add a new unlisted page and name it `feed` using the template `podcasterfeed`. Please note that there is a problem, the template currently doesn't appear in the template list, so you have to add or change it by hand, naming the markdown-file `podcasterfeed`. The feed can then be edited in the panel.

Expand Down
23 changes: 0 additions & 23 deletions UPDATE-FROM-K2.md

This file was deleted.

62 changes: 62 additions & 0 deletions blueprints/pages/podcasterwizard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
title: Podcaster Wizard
tabs:
wizard:
label: Wizard
icon: wand
columns:
- width: 1/3
sections:
wizardInfo:
type: fields
fields:
wizardHead:
type: headline
label: Import Wizard
wizardInfo:
type: info
label: Hello there!️️
theme: positive
text: This wizard helps you transfering your existing podcast to Kirby. It uses your RSS-Feed for that. All information will be imported from this feed.
wizardStep1:
type: info
label: Needed information
text: Please enter the URL of your current podcast feed. Then select the page which will function as your target. All episodes and the feed will be created as children of this page. Hit save, then start the import.
wizardStep2:
type: info
label: Be aware
theme: negative
text: This feature is experimental. It'll create new pages and add information. Please backup your data before you do this. Also make sure the target page has no other pages in it. Otherwise the import may fail!
- width: 2/3
sections:
wizardSteps:
type: fields
fields:
wizardInfos:
type: headline
label: Start your import
podcasterWizardSrcFeed:
type: url
label: Your source RSS-Feed
required: true
podcasterWizardDestination:
type: pages
label: Parent Page
width: 1/3
required: true
podcasterWizardTemplate:
type: text
label: Template Name
help: Without file extension, if your content files look like 'article.txt' then your template name is 'article'
width: 1/3
required: true
podcasterWizardPageStatus:
type: toggle
label: Page Status
default: no
text:
Draft
Unlisted
help: Pages created by this wizard will be drafts. If you want, they can also be unlisted.
width: 1/3
podstatsFeed:
type: podcasterWizard
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mauricerenck/podcaster",
"version": "1.1.4",
"version": "1.2.0",
"description": "A podcast plugin for Kirby 3",
"type": "kirby-plugin",
"license": "MIT",
Expand All @@ -18,6 +18,7 @@
"utils/PodcasterStatsFile.php",
"utils/PodcasterStatsMysql.php",
"utils/PodcasterStatsPodTrac.php",
"utils/PodcasterWizard.php",
"lib/PiwikTracker.php"
]
},
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

174 changes: 174 additions & 0 deletions config/api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?php

namespace Plugin\Podcaster;

use Xml;
use File;

return [
'routes' => [
[
'pattern' => 'podcaster/stats/(:any)/year/(:num)/month/(:num)',
'action' => function ($podcast, $year, $month) {
if (option('mauricerenck.podcaster.statsInternal') === false || option('mauricerenck.podcaster.statsType') === 'file') {
$errorMessage = ['error' => 'cannot use stats on file method, use mysql version instead'];
echo new Response(json_encode($errorMessage), 'application/json', 501);
}

$podcasterStats = new PodcasterStats();
$stats = $podcasterStats->getEpisodeStatsOfMonth($podcast, $year, $month);
return [
'stats' => $stats
];
}
],
[
'pattern' => 'podcaster/stats/(:any)/(:any)/yearly-downloads/(:any)',
'action' => function ($podcast, $type, $year) {
if (option('mauricerenck.podcaster.statsInternal') === false || option('mauricerenck.podcaster.statsType') === 'file') {
$errorMessage = ['error' => 'cannot use stats on file method, use mysql version instead'];
echo new Response(json_encode($errorMessage), 'application/json', 501);
}

$podcasterStats = new PodcasterStats();
$stats = $podcasterStats->getDownloadsOfYear($podcast, $year, $type);
return [
'stats' => $stats
];
}
],
[
'pattern' => 'podcaster/stats/(:any)/top/(:num)',
'action' => function ($podcast, $limit) {
if (option('mauricerenck.podcaster.statsInternal') === false || option('mauricerenck.podcaster.statsType') === 'file') {
$errorMessage = ['error' => 'cannot use stats on file method, use mysql version instead'];
echo new Response(json_encode($errorMessage), 'application/json', 501);
}

$podcasterStats = new PodcasterStats();
$stats = $podcasterStats->getTopDownloads($podcast, $limit);
return [
'stats' => $stats
];
}
],
[
'pattern' => 'podcaster/wizard/checkfeed',
'action' => function () {
try {
$feedUrl = $_SERVER['HTTP_X_FEED_URI'];
} catch (Exeption $e) {
echo 'Could not read feed';
}

$feed = implode(file($feedUrl));
return Xml::parse($feed);
}
],
[
'pattern' => 'podcaster/wizard/createFeed',
'action' => function () {
$headerTarget = $_SERVER['HTTP_X_TARGET_PAGE'];

$targetPage = kirby()->page($headerTarget);
$pageData = json_decode(file_get_contents('php://input'));

$wizardHelper = new PodcasterWizard();

$newPageData = [
'slug' => 'feed',
'template' => 'podcasterfeed',
'draft' => false,
'content' => [
'podcasterSource' => $targetPage->slug(),
'title' => $wizardHelper->getField($pageData, 'title'),
'podcasterTitle' => $wizardHelper->getField($pageData, 'title'),
'podcasterDescription' => $wizardHelper->getField($pageData, 'description'),
'podcasterSubtitle' => $wizardHelper->getField($pageData, 'itunessubtitle'),
'podcasterKeywords' => $wizardHelper->getField($pageData, 'ituneskeywords'),
'podcasterCopyright' => $wizardHelper->getField($pageData, 'copyright'),
'podcasterLink' => $wizardHelper->getField($pageData, 'link'),
'podcasterLanguage' => $wizardHelper->getField($pageData, 'language'),
'podcasterType' => $wizardHelper->getField($pageData, 'itunestype'),
'podcasterExplicit' => $wizardHelper->getField($pageData, 'itunesexplicit'),
'podcasterBlock' => $wizardHelper->getField($pageData, 'itunesblock')
]
];

$feed = $targetPage->createChild($newPageData);

return json_encode(['title' => $pageData->title, 'slug' => $feed->id()]);
},
'method' => 'POST'
],
[
'pattern' => 'podcaster/wizard/createEpisode',
'action' => function () {
$headerTarget = $_SERVER['HTTP_X_TARGET_PAGE'];
$headerTemplate = $_SERVER['HTTP_X_PAGE_TEMPLATE'];
$pageStatus = ($_SERVER['HTTP_X_PAGE_STATUS'] === 'false');

$targetPage = kirby()->page($headerTarget);
$pageData = json_decode(file_get_contents('php://input'));

$wizardHelper = new PodcasterWizard();
$slug = $wizardHelper->getPageSlug($wizardHelper->getField($pageData, 'link'), $wizardHelper->getField($pageData, 'title'));

$newPageData = [
'slug' => $slug,
'template' => $headerTemplate,
'draft' => $pageStatus,
'content' => [
'title' => $wizardHelper->getField($pageData, 'title'),
'date' => $wizardHelper->getField($pageData, 'pubDate'),
'podcasterSeason' => $wizardHelper->getField($pageData, 'itunesseason'),
'podcasterEpisode' => $wizardHelper->getField($pageData, 'itunesepisode'),
'podcasterEpisodeType' => $wizardHelper->getField($pageData, 'itunesepisodetype'),
'podcasterExplizit' => $wizardHelper->getField($pageData, 'itunesexplicit'),
'podcasterBlock' => $wizardHelper->getField($pageData, 'itunesblock'),
'podcasterTitle' => $wizardHelper->getField($pageData, 'title'),
'podcasterSubtitle' => $wizardHelper->getField($pageData, 'itunessubtitle'),
'podcasterDescription' => $wizardHelper->getField($pageData, 'description'),
]
];

$episode = $targetPage->createChild($newPageData);
$mp3FileName = $slug . '.mp3';

return json_encode(['title' => $pageData->title, 'slug' => $episode->id(), 'file' => $wizardHelper->getField($pageData, 'file')]);
},
'method' => 'POST'
],
[
'pattern' => 'podcaster/wizard/createFile',
'action' => function () {
$headerTarget = $_SERVER['HTTP_X_TARGET_PAGE'];

$episode = kirby()->page($headerTarget);
$pageData = json_decode(file_get_contents('php://input'));

$wizardHelper = new PodcasterWizard();
$slug = $episode->slug();

$mp3FileName = $slug . '.mp3';
$mp3 = $wizardHelper->downloadMp3($wizardHelper->getField($pageData, 'file'), $mp3FileName);

$file = File::create([
'source' => kirby()->root('plugins') . '/kirby-podcaster/tmp/' . $mp3FileName,
'parent' => $episode,
'filename' => $mp3FileName,
'template' => 'podcaster-episode',
'content' => [
'duration' => $wizardHelper->getField($pageData, 'itunesduration'),
'episodeTitle' => $wizardHelper->getField($pageData, 'itunestitle')
]
]);

unlink(kirby()->root('plugins') . '/kirby-podcaster/tmp/' . $mp3FileName);

return json_encode(['created' => $mp3FileName]);
},
'method' => 'POST'
]
]
];
Binary file added doc-assets/create-wizard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc-assets/wizard-panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit fd19323

Please sign in to comment.