mirror of
https://code.castopod.org/adaures/castopod.git
synced 2024-09-30 05:31:22 +02:00
feat(episodes): replace all audio file URL parameters with base64 encoded data
This commit is contained in:
parent
391c349daa
commit
e1f65cd3b5
@ -31,6 +31,7 @@ $routes->setAutoRoute(false);
|
|||||||
|
|
||||||
$routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,191}');
|
$routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,191}');
|
||||||
$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}');
|
$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}');
|
||||||
|
$routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
@ -59,14 +60,10 @@ $routes->group(config('App')->installGateway, function ($routes) {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Route for podcast audio file analytics (/audio/podcast_id/episode_id/bytes_threshold/filesize/duration/podcast_folder/filename.mp3)
|
// Route for podcast audio file analytics (/audio/pack(podcast_id,episode_id,bytes_threshold,filesize,duration,date)/podcast_folder/filename.mp3)
|
||||||
$routes->add(
|
$routes->add('audio/(:base64)/(:any)', 'Analytics::hit/$1/$2', [
|
||||||
'audio/(:num)/(:num)/(:num)/(:num)/(:num)/(:any)',
|
|
||||||
'Analytics::hit/$1/$2/$3/$4/$5/$6',
|
|
||||||
[
|
|
||||||
'as' => 'analytics_hit',
|
'as' => 'analytics_hit',
|
||||||
]
|
]);
|
||||||
);
|
|
||||||
|
|
||||||
// Show the Unknown UserAgents
|
// Show the Unknown UserAgents
|
||||||
$routes->get('.well-known/unknown-useragents', 'UnknownUserAgents');
|
$routes->get('.well-known/unknown-useragents', 'UnknownUserAgents');
|
||||||
|
@ -46,24 +46,24 @@ class Analytics extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add one hit to this episode:
|
// Add one hit to this episode:
|
||||||
public function hit(
|
public function hit($base64EpisodeData, ...$filename)
|
||||||
$podcastId,
|
{
|
||||||
$episodeId,
|
helper('media', 'analytics');
|
||||||
$bytesThreshold,
|
|
||||||
$fileSize,
|
|
||||||
$duration,
|
|
||||||
...$filename
|
|
||||||
) {
|
|
||||||
helper('media');
|
|
||||||
|
|
||||||
$serviceName = isset($_GET['_from']) ? $_GET['_from'] : '';
|
$serviceName = isset($_GET['_from']) ? $_GET['_from'] : '';
|
||||||
|
|
||||||
|
$episodeData = unpack(
|
||||||
|
'IpodcastId/IepisodeId/IbytesThreshold/IfileSize/Iduration/IpublicationDate',
|
||||||
|
base64_url_decode($base64EpisodeData)
|
||||||
|
);
|
||||||
|
|
||||||
podcast_hit(
|
podcast_hit(
|
||||||
$podcastId,
|
$episodeData['podcastId'],
|
||||||
$episodeId,
|
$episodeData['episodeId'],
|
||||||
$bytesThreshold,
|
$episodeData['bytesThreshold'],
|
||||||
$fileSize,
|
$episodeData['fileSize'],
|
||||||
$duration,
|
$episodeData['duration'],
|
||||||
|
$episodeData['publicationDate'],
|
||||||
$serviceName
|
$serviceName
|
||||||
);
|
);
|
||||||
return redirect()->to(media_base_url($filename));
|
return redirect()->to(media_base_url($filename));
|
||||||
|
@ -35,6 +35,7 @@ CREATE PROCEDURE `{$prefix}analytics_podcasts` (
|
|||||||
IN `p_bot` TINYINT(1) UNSIGNED,
|
IN `p_bot` TINYINT(1) UNSIGNED,
|
||||||
IN `p_filesize` INT UNSIGNED,
|
IN `p_filesize` INT UNSIGNED,
|
||||||
IN `p_duration` INT UNSIGNED,
|
IN `p_duration` INT UNSIGNED,
|
||||||
|
IN `p_age` INT UNSIGNED,
|
||||||
IN `p_new_listener` TINYINT(1) UNSIGNED
|
IN `p_new_listener` TINYINT(1) UNSIGNED
|
||||||
) MODIFIES SQL DATA
|
) MODIFIES SQL DATA
|
||||||
DETERMINISTIC
|
DETERMINISTIC
|
||||||
@ -58,7 +59,7 @@ IF NOT `p_bot` THEN
|
|||||||
VALUES (p_podcast_id, @current_date, @current_hour)
|
VALUES (p_podcast_id, @current_date, @current_hour)
|
||||||
ON DUPLICATE KEY UPDATE `hits`=`hits`+1;
|
ON DUPLICATE KEY UPDATE `hits`=`hits`+1;
|
||||||
INSERT INTO `{$prefix}analytics_podcasts_by_episode`(`podcast_id`, `episode_id`, `date`, `age`)
|
INSERT INTO `{$prefix}analytics_podcasts_by_episode`(`podcast_id`, `episode_id`, `date`, `age`)
|
||||||
SELECT p_podcast_id, p_episode_id, @current_date, datediff(@current_datetime,`published_at`) FROM `{$prefix}episodes` WHERE `id`= p_episode_id
|
VALUES (p_podcast_id, p_episode_id, @current_date, p_age)
|
||||||
ON DUPLICATE KEY UPDATE `hits`=`hits`+1;
|
ON DUPLICATE KEY UPDATE `hits`=`hits`+1;
|
||||||
INSERT INTO `{$prefix}analytics_podcasts_by_country`(`podcast_id`, `country_code`, `date`)
|
INSERT INTO `{$prefix}analytics_podcasts_by_country`(`podcast_id`, `country_code`, `date`)
|
||||||
VALUES (p_podcast_id, p_country_code, @current_date)
|
VALUES (p_podcast_id, p_country_code, @current_date)
|
||||||
|
@ -179,9 +179,14 @@ class Episode extends Entity
|
|||||||
|
|
||||||
public function getEnclosureUrl()
|
public function getEnclosureUrl()
|
||||||
{
|
{
|
||||||
|
helper('analytics');
|
||||||
|
|
||||||
return base_url(
|
return base_url(
|
||||||
route_to(
|
route_to(
|
||||||
'analytics_hit',
|
'analytics_hit',
|
||||||
|
base64_url_encode(
|
||||||
|
pack(
|
||||||
|
'I*',
|
||||||
$this->attributes['podcast_id'],
|
$this->attributes['podcast_id'],
|
||||||
$this->attributes['id'],
|
$this->attributes['id'],
|
||||||
// bytes_threshold: number of bytes that must be downloaded for an episode to be counted in download analytics
|
// bytes_threshold: number of bytes that must be downloaded for an episode to be counted in download analytics
|
||||||
@ -192,12 +197,19 @@ class Episode extends Entity
|
|||||||
: $this->attributes['enclosure_headersize'] +
|
: $this->attributes['enclosure_headersize'] +
|
||||||
floor(
|
floor(
|
||||||
(($this->attributes['enclosure_filesize'] -
|
(($this->attributes['enclosure_filesize'] -
|
||||||
$this->attributes['enclosure_headersize']) /
|
$this->attributes[
|
||||||
$this->attributes['enclosure_duration']) *
|
'enclosure_headersize'
|
||||||
|
]) /
|
||||||
|
$this->attributes[
|
||||||
|
'enclosure_duration'
|
||||||
|
]) *
|
||||||
60
|
60
|
||||||
),
|
),
|
||||||
$this->attributes['enclosure_filesize'],
|
$this->attributes['enclosure_filesize'],
|
||||||
$this->attributes['enclosure_duration'],
|
$this->attributes['enclosure_duration'],
|
||||||
|
strtotime($this->attributes['published_at'])
|
||||||
|
)
|
||||||
|
),
|
||||||
$this->attributes['enclosure_uri']
|
$this->attributes['enclosure_uri']
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -30,6 +30,22 @@ if (!function_exists('getallheaders')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode Base64 for URLs
|
||||||
|
*/
|
||||||
|
function base64_url_encode($input)
|
||||||
|
{
|
||||||
|
return strtr(base64_encode($input), '+/=', '._-');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode Base64 from URL
|
||||||
|
*/
|
||||||
|
function base64_url_decode($input)
|
||||||
|
{
|
||||||
|
return base64_decode(strtr($input, '._-', '+/='));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set user country in session variable, for analytics purpose
|
* Set user country in session variable, for analytics purpose
|
||||||
*/
|
*/
|
||||||
@ -245,6 +261,7 @@ function podcast_hit(
|
|||||||
$bytesThreshold,
|
$bytesThreshold,
|
||||||
$fileSize,
|
$fileSize,
|
||||||
$duration,
|
$duration,
|
||||||
|
$publicationDate,
|
||||||
$serviceName
|
$serviceName
|
||||||
) {
|
) {
|
||||||
$session = \Config\Services::session();
|
$session = \Config\Services::session();
|
||||||
@ -311,6 +328,8 @@ function podcast_hit(
|
|||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$procedureName = $db->prefixTable('analytics_podcasts');
|
$procedureName = $db->prefixTable('analytics_podcasts');
|
||||||
|
|
||||||
|
$age = intdiv(time() - $publicationDate, 86400);
|
||||||
|
|
||||||
// We create a sha1 hash for this IP_Address+User_Agent+Podcast_ID (used to count unique listeners):
|
// We create a sha1 hash for this IP_Address+User_Agent+Podcast_ID (used to count unique listeners):
|
||||||
$listenerHashId =
|
$listenerHashId =
|
||||||
'_IpUaPo_' .
|
'_IpUaPo_' .
|
||||||
@ -337,7 +356,7 @@ function podcast_hit(
|
|||||||
cache()->save($listenerHashId, $downloadsByUser, $midnightTTL);
|
cache()->save($listenerHashId, $downloadsByUser, $midnightTTL);
|
||||||
|
|
||||||
$db->query(
|
$db->query(
|
||||||
"CALL $procedureName(?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
|
"CALL $procedureName(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
|
||||||
[
|
[
|
||||||
$podcastId,
|
$podcastId,
|
||||||
$episodeId,
|
$episodeId,
|
||||||
@ -352,6 +371,7 @@ function podcast_hit(
|
|||||||
$session->get('player')['bot'],
|
$session->get('player')['bot'],
|
||||||
$fileSize,
|
$fileSize,
|
||||||
$duration,
|
$duration,
|
||||||
|
$age,
|
||||||
$newListener,
|
$newListener,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user