# [1.0.0-alpha.60](https://code.podlibre.org/podlibre/castopod-host/compare/v1.0.0-alpha.59...v1.0.0-alpha.60) (2021-06-21)
### Features
- **rss:** add ˂podcast:guid˃ tag for channel
([1fab10e](https://code.podlibre.org/podlibre/castopod-host/commit/1fab10eb0d63bb7c3edf34ffe691e2aec2c2e43c))
# [1.0.0-alpha.59](https://code.podlibre.org/podlibre/castopod-host/compare/v1.0.0-alpha.58...v1.0.0-alpha.59) (2021-06-15)
### Bug Fixes
......
......@@ -33,6 +33,9 @@ performance improvements ⚡.
- Remove all files except `.env` and `public/media`
- Copy the new files from the downloaded package into your server
- Note: you may need to reset files permissions as during the install
process. Check
[Security Concerns section in INSTALL.md](./INSTALL.md#security-concerns).
4. Alpha releases may come with additional update instructions (see
[releases page](https://code.podlibre.org/podlibre/castopod-host/-/releases)).
......
......@@ -11,7 +11,7 @@ declare(strict_types=1);
|
| NOTE: this constant is updated upon release with Continuous Integration.
*/
defined('CP_VERSION') || define('CP_VERSION', '1.0.0-alpha.59');
defined('CP_VERSION') || define('CP_VERSION', '1.0.0-alpha.60');
/*
| --------------------------------------------------------------------
......
......@@ -192,6 +192,7 @@ class PodcastController extends BaseController
}
$podcast = new Podcast([
'guid' => podcast_uuid(url_to('podcast_feed', $this->request->getPost('name'))),
'title' => $this->request->getPost('title'),
'name' => $this->request->getPost('name'),
'description_markdown' => $this->request->getPost('description'),
......
......@@ -128,11 +128,17 @@ class PodcastImportController extends BaseController
(string) $nsPodcast->location->attributes()['osm'],
);
}
if (property_exists($nsPodcast, 'guid') && $nsPodcast->guid !== null) {
$guid = (string) $nsPodcast->guid;
} else {
$guid = podcast_uuid(url_to('podcast_feed', $this->request->getPost('name')));
}
$podcast = new Podcast([
'guid' => $guid,
'name' => $this->request->getPost('name'),
'imported_feed_url' => $this->request->getPost('imported_feed_url'),
'new_feed_url' => base_url(route_to('podcast_feed', $this->request->getPost('name'))),
'new_feed_url' => url_to('podcast_feed', $this->request->getPost('name')),
'title' => (string) $feed->channel[0]->title,
'description_markdown' => $converter->convert($channelDescriptionHtml),
'description_html' => $channelDescriptionHtml,
......
......@@ -24,6 +24,10 @@ class AddPodcasts extends Migration
'unsigned' => true,
'auto_increment' => true,
],
'guid' => [
'type' => 'CHAR',
'constraint' => 36,
],
'actor_id' => [
'type' => 'INT',
'unsigned' => true,
......@@ -190,6 +194,7 @@ class AddPodcasts extends Migration
$this->forge->addPrimaryKey('id');
// TODO: remove name in favor of username from actor
$this->forge->addUniqueKey('name');
$this->forge->addUniqueKey('guid');
$this->forge->addUniqueKey('actor_id');
$this->forge->addForeignKey('actor_id', 'activitypub_actors', 'id', '', 'CASCADE');
$this->forge->addForeignKey('category_id', 'categories', 'id');
......
......@@ -23,6 +23,7 @@ use RuntimeException;
/**
* @property int $id
* @property string $guid
* @property int $actor_id
* @property Actor|null $actor
* @property string $name
......@@ -137,6 +138,7 @@ class Podcast extends Entity
*/
protected $casts = [
'id' => 'integer',
'guid' => 'string',
'actor_id' => 'integer',
'name' => 'string',
'title' => 'string',
......
......@@ -148,4 +148,18 @@ if (! function_exists('format_duration')) {
}
}
if (! function_exists('podcast_uuid')) {
/**
* Generate UUIDv5 for podcast. For more information, see
* https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md#guid
*/
function podcast_uuid(string $feedUrl): string
{
$uuid = service('uuid');
// 'ead4c236-bf58-58c6-a2c6-a6b28d128cb6' is the uuid of the podcast namespace
return $uuid->uuid5('ead4c236-bf58-58c6-a2c6-a6b28d128cb6', $feedUrl)
->toString();
}
}
//--------------------------------------------------------------------
......@@ -50,6 +50,7 @@ if (! function_exists('get_rss_feed')) {
$channel->addChild('generator', 'Castopod Host - https://castopod.org/');
$channel->addChild('docs', 'https://cyber.harvard.edu/rss/rss.html');
$channel->addChild('guid', $podcast->guid, $podcastNamespace);
$channel->addChild('title', $podcast->title);
$channel->addChildWithCDATA('description', $podcast->description_html);
......
......@@ -33,6 +33,7 @@ class PodcastModel extends Model
*/
protected $allowedFields = [
'id',
'guid',
'title',
'name',
'description_markdown',
......
{
"name": "podlibre/castopod-host",
"version": "1.0.0-alpha59",
"version": "1.0.0-alpha60",
"type": "project",
"description": "Castopod Host is an open-source hosting platform made for podcasters who want engage and interact with their audience.",
"homepage": "https://castopod.org",
......
{
"name": "castopod-host",
"version": "1.0.0-alpha.59",
"version": "1.0.0-alpha.60",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0-alpha.59",
"version": "1.0.0-alpha.60",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@amcharts/amcharts4": "^4.10.17",
{
"name": "castopod-host",
"version": "1.0.0-alpha.59",
"version": "1.0.0-alpha.60",
"description": "Castopod Host is an open-source hosting platform made for podcasters who want engage and interact with their audience.",
"private": true,
"license": "AGPL-3.0-or-later",
......