Skip to content
Snippets Groups Projects
FakePodcastsAnalyticsSeeder.php 7.73 KiB
Newer Older
  • Learn to ignore specific revisions
  •  * Class FakePodcastsAnalyticsSeeder Inserts Fake Analytics in the database
    
     * @copyright  2020 Ad Aures
    
     * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
     * @link       https://castopod.org/
     */
    
    namespace App\Database\Seeds;
    
    use App\Entities\Episode;
    use App\Entities\Podcast;
    
    use App\Models\EpisodeModel;
    
    use CodeIgniter\Database\Seeder;
    
    use GeoIp2\Database\Reader;
    use GeoIp2\Exception\AddressNotFoundException;
    
    
    class FakePodcastsAnalyticsSeeder extends Seeder
    {
    
        {
            $jsonUserAgents = json_decode(
    
                file_get_contents('https://raw.githubusercontent.com/opawg/user-agents/master/src/user-agents.json'),
    
    Benjamin Bellamy's avatar
    Benjamin Bellamy committed
            $jsonRSSUserAgents = json_decode(
                file_get_contents(
    
                    'https://raw.githubusercontent.com/opawg/podcast-rss-useragents/master/src/rss-ua.json',
    
    Benjamin Bellamy's avatar
    Benjamin Bellamy committed
                ),
    
            $podcast = (new PodcastModel())->first();
    
    
            if (! $podcast instanceof Podcast) {
                throw new Exception("COULD NOT POPULATE DATABASE:\n\tCreate a podcast with episodes first.\n");
            }
    
            $firstEpisode = (new EpisodeModel())
                ->selectMin('published_at')
                ->first();
    
            if (! $firstEpisode instanceof Episode) {
                throw new Exception("COULD NOT POPULATE DATABASE:\n\tCreate an episode first.");
            }
    
            for (
                $date = strtotime((string) $firstEpisode->published_at);
                $date < strtotime('now');
                $date = strtotime(date('Y-m-d', $date) . ' +1 day')
            ) {
                $analyticsPodcasts = [];
                $analyticsPodcastsByHour = [];
                $analyticsPodcastsByCountry = [];
                $analyticsPodcastsByEpisode = [];
                $analyticsPodcastsByPlayer = [];
                $analyticsPodcastsByRegion = [];
    
                $episodes = (new EpisodeModel())
                    ->where('podcast_id', $podcast->id)
                    ->where('`published_at` <= UTC_TIMESTAMP()', null, false)
                    ->findAll();
                foreach ($episodes as $episode) {
                    $age = floor(($date - strtotime((string) $episode->published_at)) / 86400);
                    $probability1 = floor(exp(3 - $age / 40)) + 1;
    
                    for (
                        $lineNumber = 0;
    
                        $lineNumber < random_int(1, (int) $probability1);
    
                        ++$lineNumber
                    ) {
                        $probability2 = floor(exp(6 - $age / 20)) + 10;
    
                        $player =
                            $jsonUserAgents[
    
                                random_int(1, count($jsonUserAgents) - 1)
    
                        $service =
                            $jsonRSSUserAgents[
    
                                random_int(1, count($jsonRSSUserAgents) - 1)
    
                        $app = $player['app'] ?? '';
                        $device = $player['device'] ?? '';
                        $os = $player['os'] ?? '';
                        $isBot = $player['bot'] ?? 0;
    
    
                        $cityReader = new Reader(WRITEPATH . 'uploads/GeoLite2-City/GeoLite2-City.mmdb');
    
                        $countryCode = 'N/A';
                        $regionCode = 'N/A';
                        $latitude = null;
                        $longitude = null;
                        try {
                            $city = $cityReader->city($fakeIp);
    
    
                            $countryCode = $city->country->isoCode ?? 'N/A';
    
    
                            $regionCode = $city->subdivisions === []
                                ? 'N/A'
                                : $city->subdivisions[0]->isoCode;
                            $latitude = round((float) $city->location->latitude, 3);
                            $longitude = round((float) $city->location->longitude, 3);
                        } catch (AddressNotFoundException) {
                            //Bad luck, bad IP, nothing to do.
    
                        $hits = random_int(0, (int) $probability2);
    
    
                        $analyticsPodcasts[] = [
                            'podcast_id'       => $podcast->id,
                            'date'             => date('Y-m-d', $date),
    
                            'duration'         => random_int(60, 3600),
                            'bandwidth'        => random_int(1000000, 10000000),
    
                            'hits'             => $hits,
                            'unique_listeners' => $hits,
                        ];
                        $analyticsPodcastsByHour[] = [
                            'podcast_id' => $podcast->id,
                            'date'       => date('Y-m-d', $date),
    
                            'hits'       => $hits,
                        ];
                        $analyticsPodcastsByCountry[] = [
                            'podcast_id'   => $podcast->id,
                            'date'         => date('Y-m-d', $date),
                            'country_code' => $countryCode,
                            'hits'         => $hits,
                        ];
                        $analyticsPodcastsByEpisode[] = [
                            'podcast_id' => $podcast->id,
                            'date'       => date('Y-m-d', $date),
                            'episode_id' => $episode->id,
                            'age'        => $age,
                            'hits'       => $hits,
                        ];
                        $analyticsPodcastsByPlayer[] = [
                            'podcast_id' => $podcast->id,
                            'date'       => date('Y-m-d', $date),
                            'service'    => $service,
                            'app'        => $app,
                            'device'     => $device,
                            'os'         => $os,
                            'is_bot'     => $isBot,
                            'hits'       => $hits,
                        ];
                        $analyticsPodcastsByRegion[] = [
                            'podcast_id'   => $podcast->id,
                            'date'         => date('Y-m-d', $date),
                            'country_code' => $countryCode,
                            'region_code'  => $regionCode,
                            'latitude'     => $latitude,
                            'longitude'    => $longitude,
                            'hits'         => $hits,
                        ];
                    }
    
    
                $this->db
                    ->table('analytics_podcasts')
                    ->ignore(true)
                    ->insertBatch($analyticsPodcasts);
                $this->db
                    ->table('analytics_podcasts_by_hour')
                    ->ignore(true)
                    ->insertBatch($analyticsPodcastsByHour);
                $this->db
                    ->table('analytics_podcasts_by_country')
                    ->ignore(true)
                    ->insertBatch($analyticsPodcastsByCountry);
                $this->db
                    ->table('analytics_podcasts_by_episode')
                    ->ignore(true)
                    ->insertBatch($analyticsPodcastsByEpisode);
                $this->db
                    ->table('analytics_podcasts_by_player')
                    ->ignore(true)
                    ->insertBatch($analyticsPodcastsByPlayer);
                $this->db
                    ->table('analytics_podcasts_by_region')
                    ->ignore(true)
                    ->insertBatch($analyticsPodcastsByRegion);