Commit 7202b986 authored by Benjamin Bellamy's avatar Benjamin Bellamy 💬
Browse files

feat(analytics): add service name from rss user-agent

BREAKING CHANGE: analytics_podcasts_by_player table and analytics_podcasts procedure were updated
parent 8ca5b33b
Loading
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -55,7 +55,15 @@ class Analytics extends Controller
    ) {
        helper('media');

        podcast_hit($podcastId, $episodeId, $bytesThreshold, $fileSize);
        $serviceName = isset($_GET['s']) ? $_GET['s'] : '';

        podcast_hit(
            $podcastId,
            $episodeId,
            $bytesThreshold,
            $fileSize,
            $serviceName
        );
        return redirect()->to(media_url(implode('/', $filename)));
    }
}
+23 −4
Original line number Diff line number Diff line
@@ -15,13 +15,32 @@ class Feed extends Controller
{
    public function index($podcastName)
    {
        // The page cache is set to a decade so it is deleted manually upon podcast update
        $this->cachePage(DECADE);

        helper('rss');

        $podcast = (new PodcastModel())->where('name', $podcastName)->first();
        if (!$podcast) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }

        return $this->response->setXML(get_rss_feed($podcast));
        $service = null;
        try {
            $service = \Opawg\UserAgentsPhp\UserAgentsRSS::find(
                $_SERVER['HTTP_USER_AGENT']
            );
        } catch (\Exception $e) {
            // If things go wrong the show must go on and the user must be able to download the file
            log_message('critical', $e);
        }
        $cacheName =
            "podcast{$podcast->id}_feed" .
            ($service ? "_{$service['slug']}" : '');
        if (!($found = cache($cacheName))) {
            $found = get_rss_feed(
                $podcast,
                $service ? '?s=' . urlencode($service['name']) : ''
            );
            cache()->save($cacheName, $found, DECADE);
        }
        return $this->response->setXML($found);
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -25,6 +25,10 @@ class AddAnalyticsPodcastsByPlayer extends Migration
            'date' => [
                'type' => 'date',
            ],
            'service' => [
                'type' => 'VARCHAR',
                'constraint' => 128,
            ],
            'app' => [
                'type' => 'VARCHAR',
                'constraint' => 128,
@@ -51,6 +55,7 @@ class AddAnalyticsPodcastsByPlayer extends Migration
        $this->forge->addPrimaryKey([
            'podcast_id',
            'date',
            'service',
            'app',
            'device',
            'os',
+3 −2
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ CREATE PROCEDURE `{$prefix}analytics_podcasts` (
    IN `p_region_code` VARCHAR(3) CHARSET utf8mb4,
    IN `p_latitude` FLOAT,
    IN `p_longitude` FLOAT,
    IN `p_service` VARCHAR(128) CHARSET utf8mb4,
    IN `p_app` VARCHAR(128) CHARSET utf8mb4,
    IN `p_device` VARCHAR(32) CHARSET utf8mb4,
    IN `p_os` VARCHAR(32) CHARSET utf8mb4,
@@ -52,8 +53,8 @@ IF NOT `p_bot` THEN
        VALUES (p_podcast_id, p_country_code, p_region_code, p_latitude, p_longitude, DATE(NOW())) 
        ON DUPLICATE KEY UPDATE `hits`=`hits`+1;
END IF;
INSERT INTO `{$prefix}analytics_podcasts_by_player`(`podcast_id`, `app`, `device`, `os`, `bot`, `date`) 
    VALUES (p_podcast_id, p_app, p_device, p_os, p_bot, DATE(NOW())) 
INSERT INTO `{$prefix}analytics_podcasts_by_player`(`podcast_id`, `service`, `app`, `device`, `os`, `bot`, `date`) 
    VALUES (p_podcast_id, p_service, p_app, p_device, p_os, p_bot, DATE(NOW())) 
    ON DUPLICATE KEY UPDATE `hits`=`hits`+1;
END
EOD;
+16 −13
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ function set_user_session_player()
        $userAgent = $_SERVER['HTTP_USER_AGENT'];

        try {
            $playerFound = \Podlibre\UserAgentsPhp\UserAgents::find($userAgent);
            $playerFound = \Opawg\UserAgentsPhp\UserAgents::find($userAgent);
        } catch (\Exception $e) {
            // If things go wrong the show must go on and the user must be able to download the file
        }
@@ -227,6 +227,7 @@ function webpage_hit($podcast_id)
 *   ✅ Castopod does not do pre-load
 *   ✅ IP deny list https://github.com/client9/ipcat
 *   ✅ User-agent Filtering https://github.com/opawg/user-agents
 *   ✅ RSS User-agent https://github.com/opawg/podcast-rss-useragents
 *   ✅ Ignores 2 bytes range "Range: 0-1"  (performed by official Apple iOS Podcast app)
 *   ✅ In case of partial content, adds up all requests to check >1mn was downloaded
 *   ✅ Identifying Uniques is done with a combination of IP Address and User Agent
@@ -234,11 +235,17 @@ function webpage_hit($podcast_id)
 * @param int $episodeId The Episode ID
 * @param int $bytesThreshold The minimum total number of bytes that must be downloaded so that an episode is counted (>1mn)
 * @param int $fileSize The podcast complete file size
 * @param string $serviceName The name of the service that had fetched the RSS feed
 *
 * @return void
 */
function podcast_hit($podcastId, $episodeId, $bytesThreshold, $fileSize)
{
function podcast_hit(
    $podcastId,
    $episodeId,
    $bytesThreshold,
    $fileSize,
    $serviceName
) {
    $session = \Config\Services::session();
    $session->start();

@@ -328,22 +335,18 @@ function podcast_hit($podcastId, $episodeId, $bytesThreshold, $fileSize)
                // We save the download count for this user until midnight:
                cache()->save($listenerHashId, $downloadsByUser, $midnightTTL);

                $app = $session->get('player')['app'];
                $device = $session->get('player')['device'];
                $os = $session->get('player')['os'];
                $bot = $session->get('player')['bot'];

                $db->query("CALL $procedureName(?,?,?,?,?,?,?,?,?,?,?);", [
                $db->query("CALL $procedureName(?,?,?,?,?,?,?,?,?,?,?,?);", [
                    $podcastId,
                    $episodeId,
                    $session->get('location')['countryCode'],
                    $session->get('location')['regionCode'],
                    $session->get('location')['latitude'],
                    $session->get('location')['longitude'],
                    $app == null ? '' : $app,
                    $device == null ? '' : $device,
                    $os == null ? '' : $os,
                    $bot == null ? 0 : $bot,
                    $serviceName,
                    $session->get('player')['app'],
                    $session->get('player')['device'],
                    $session->get('player')['os'],
                    $session->get('player')['bot'],
                    $newListener,
                ]);
            }
Loading