Ejemplo n.º 1
0
        public async Task <Playlist> FetchProviderPlaylistAsync(PlaylistProvider provider)
        {
            Playlist playlist = await GetPlaylistAsync(provider);

            if (Playlist.IsNullOrEmpty(playlist))
            {
                logger.Debug(
                    MyOperation.PlaylistFetching,
                    OperationStatus.Failure,
                    new LogInfo(MyLogInfoKey.Provider, provider.Name));

                return(null);
            }

            if (!string.IsNullOrWhiteSpace(provider.ChannelNameOverride))
            {
                foreach (Channel channel in playlist.Channels)
                {
                    channel.Name = provider.ChannelNameOverride;
                }
            }

            logger.Debug(
                MyOperation.PlaylistFetching,
                OperationStatus.Success,
                new LogInfo(MyLogInfoKey.Provider, provider.Name));

            return(playlist);
        }
Ejemplo n.º 2
0
        public async Task <IActionResult> GetFile(string publicId, [FromQuery] string provider = "m3u", CancellationToken cancellationToken = default)
        {
            var idGuid = GetInternalPlaylistId(publicId);

            var playlist = await _dbContext.Playlist.FirstOrDefaultAsync(x => x.UniqueId == idGuid, cancellationToken);

            if (playlist == null)
            {
                return(NotFound(publicId));
            }

            PlaylistProvider <Playlist <TvgMedia>, TvgMedia> sourceProvider = null;

            try
            {
                sourceProvider = _providerFactory.CreateInstance(playlist.SynkConfig.Uri, provider);
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }

            using (sourceProvider)
                using (var pl = new Playlist <TvgMedia>(sourceProvider))
                    using (var sourcePl = new Playlist <TvgMedia>(playlist.TvgMedias.Where(x => x.Enabled && !x.MediaGroup.Disabled)))
                    {
                        return(await pl.PushAsync(sourcePl, cancellationToken).ContinueWith(t =>
                        {
                            return File(sourceProvider.PlaylistStream.ToArray(), "text/plain");
                        }));
                    }
        }
Ejemplo n.º 3
0
        public async Task <IActionResult> Import(string playlistName, string playlistUrl, string provider, IFormFile file, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(playlistName))
            {
                throw new ArgumentNullException(nameof(provider));
            }

            if (string.IsNullOrEmpty(playlistName))
            {
                playlistName = file.FileName.Replace(Path.GetExtension(file.FileName), string.Empty); //TODO : catch all ArgumentException et les passer en BadRequest
            }
            //Vérifier si la playlist existe bien avant

            PlaylistProvider <Playlist <TvgMedia>, TvgMedia> providerInstance = null;

            try
            {
                providerInstance = _providerFactory.CreateInstance(playlistUrl, provider);
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }

            var playlistStream = file.OpenReadStream();

            if (string.IsNullOrEmpty(playlistUrl))
            {
                //TODO : Save file and get Url
                throw new ApplicationException("Import playlist from file not supported yet !!");
            }

            using (providerInstance)
            {
                var user = await _dbContext.Users.FindAsync(new object[] { UserId }, cancellationToken);

                if (user == null)
                {
                    return(BadRequest($"User {this.UserEmail} not found"));
                }

                var pl = await _playlistService.SynkPlaylistAsync(() => new Playlist
                {
                    UserId       = user.Id,
                    Freindlyname = playlistName,
                    Status       = PlaylistStatus.Enabled,
                    SynkConfig   = null,
                    Tags         = new Dictionary <string, string> {
                        { PlaylistTags.ImportProvider, provider }
                    }
                }, providerInstance, _xtreamService.IsXtreamPlaylist(playlistUrl), true, cancellationToken);

                ClearCache();

                var result = PlaylistModel.ToLightModel(pl, Url);
                return(Created(result.PublicUrl, result));
            }
        }
Ejemplo n.º 4
0
        public async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            IQueryable <Playlist> playlists = _dbContext.Playlist
                                              .Include(x => x.User)
                                              //.ThenInclude(u => u.Devices)
                                              .Where(x => x.Status == PlaylistStatus.Enabled);

            playlists.AsParallel().WithCancellation(cancellationToken).ForAll(async pl =>
            {
                try
                {
                    PlaylistProvider <Playlist <TvgMedia>, TvgMedia> provider = null;
                    try
                    {
                        provider = _providerFactory.CreateInstance(pl.SynkConfig.Uri, pl.SynkConfig.Provider);
                    }
                    catch (Exception)
                    {
                        throw new ApplicationException("Can't resolve playlist provider");
                    }

                    (IEnumerable <TvgMedia> tvgMedia, IEnumerable <TvgMedia> removed) =
                        await _playlistService.DiffWithSourceAsync(() => pl, provider, false, cancellationToken);

                    if (removed.Any() || tvgMedia.Any())
                    {
                        _logger.LogInformation($"Diff detected for the playlist {pl.Id} of user {pl.UserId}");

                        //publish message to Rabbit
                        await _bus.Publish(new DiffPlaylistEvent
                        {
                            Id                 = pl.Id,
                            PlaylistName       = pl.Freindlyname,
                            UserId             = pl.User.Email,
                            RemovedMediasCount = removed.Count(),
                            RemovedMedias      = removed.Take(10),
                            NewMediasCount     = tvgMedia.Count(),
                            NewMedias          = tvgMedia.Take(10)
                        }, cancellationToken);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);
                    await _bus.Publish(new TraceEvent
                    {
                        Message = $"playlistId : {pl.Id}, Exception :{ex.Message}",
                        UserId  = pl.User.Email,
                        Level   = TraceEvent.LevelTrace.Error,
                        Source  = nameof(DiffHostedService)
                    }, cancellationToken);
                }
            }
                                                                              );
        }
Ejemplo n.º 5
0
        async Task <Playlist> GetPlaylistAsync(PlaylistProvider provider)
        {
            Playlist playlist = await GetPlaylistForTodayAsync(provider);

            if (Playlist.IsNullOrEmpty(playlist))
            {
                playlist = GetPlaylistForPastDays(provider);
            }

            return(playlist);
        }
        public async Task <Playlist> FetchProviderPlaylistAsync(PlaylistProvider provider)
        {
            Playlist playlist = null;

            for (int i = 0; i < applicationSettings.DaysToCheck; i++)
            {
                DateTime date = DateTime.Now.AddDays(-i);

                playlist = LoadPlaylistFromCache(provider, date);

                if (playlist is null)
                {
                    string playlistFile = await DownloadPlaylistFileAsync(provider, date);

                    playlist = playlistFileBuilder.TryParseFile(playlistFile);

                    if (!Playlist.IsNullOrEmpty(playlist) && !provider.DontCache)
                    {
                        cache.StorePlaylistFile(provider.Id, date, playlistFile);
                    }
                }

                if (!(playlist is null))
                {
                    break;
                }
            }

            if (Playlist.IsNullOrEmpty(playlist))
            {
                logger.Debug(
                    MyOperation.PlaylistFetching,
                    OperationStatus.Failure,
                    new LogInfo(MyLogInfoKey.Provider, provider.Name));

                return(null);
            }

            if (!string.IsNullOrWhiteSpace(provider.ChannelNameOverride))
            {
                foreach (Channel channel in playlist.Channels)
                {
                    channel.Name = provider.ChannelNameOverride;
                }
            }

            logger.Debug(
                MyOperation.PlaylistFetching,
                OperationStatus.Success,
                new LogInfo(MyLogInfoKey.Provider, provider.Name));

            return(playlist);
        }
Ejemplo n.º 7
0
        internal static PlaylistProvider ToServiceModel(this PlaylistProviderEntity dataObject)
        {
            PlaylistProvider serviceModel = new PlaylistProvider();

            serviceModel.Id                  = dataObject.Id;
            serviceModel.IsEnabled           = dataObject.IsEnabled;
            serviceModel.Priority            = dataObject.Priority;
            serviceModel.DontCache           = dataObject.DontCache;
            serviceModel.Name                = dataObject.Name;
            serviceModel.UrlFormat           = dataObject.UrlFormat;
            serviceModel.ChannelNameOverride = dataObject.ChannelNameOverride;

            return(serviceModel);
        }
Ejemplo n.º 8
0
        internal static PlaylistProviderEntity ToDataObject(this PlaylistProvider serviceModel)
        {
            PlaylistProviderEntity dataObject = new PlaylistProviderEntity();

            dataObject.Id                  = serviceModel.Id;
            dataObject.IsEnabled           = serviceModel.IsEnabled;
            dataObject.Priority            = serviceModel.Priority;
            dataObject.DontCache           = serviceModel.DontCache;
            dataObject.Name                = serviceModel.Name;
            dataObject.UrlFormat           = serviceModel.UrlFormat;
            dataObject.ChannelNameOverride = serviceModel.ChannelNameOverride;

            return(dataObject);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Synk playlist and match epg, logos and groups
        /// </summary>
        /// <param name="playlist">Playlist</param>
        /// <param name="resetAndSynch">Reset and synchronize playlist from scrach</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <Playlist> SynkPlaylistAsync(Playlist playlist, bool resetAndSynch = false,
                                                       CancellationToken cancellationToken   = default)
        {
            if (playlist == null)
            {
                throw new ArgumentNullException($"Playlist not found");
            }
            if (!playlist.IsSynchronizable || playlist.SynkConfig.AutoSynchronize)
            {
                throw new ApplicationException($"Playlist isn't synchronizable or not auto synchrizable is disabled");
            }

            PlaylistProvider <Playlist <TvgMedia>, TvgMedia> provider = null;

            try
            {
                provider = _providerFactory.CreateInstance(playlist.SynkConfig.Uri, playlist.SynkConfig.Provider);
            }
            catch (Exception)
            {
                throw new ApplicationException("Can't resolve playlist provider");
            }

            if (resetAndSynch)
            {
                return(await SynkPlaylistAsync(() => _dbcontext.Playlist.Find(playlist.Id), provider, false, resetAndSynch, cancellationToken));
            }

            var(tvgMedia, removed) = await DiffWithSourceAsync(() => playlist, provider, true, cancellationToken);

            var changed = false;

            if (removed != null && removed.Any())
            {
                playlist.TvgMedias.RemoveAll(x => removed.Any(r => r.Id == x.Id));
                changed = true;
            }
            if (tvgMedia != null && tvgMedia.Any())
            {
                playlist.TvgMedias.AddRange(tvgMedia);
                changed = true;
            }
            if (changed)
            {
                playlist.TvgMedias = playlist.TvgMedias;
                var resRq = await _dbcontext.SaveChangesAsync(cancellationToken);
            }
            return(playlist);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Synk playlist and match epg, logos and groups
        /// </summary>
        /// <param name="getPlaylist"></param>
        /// <param name="provider"></param>
        /// <param name="isXtreamPlaylist"></param>
        /// <param name="force"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task <Playlist> SynkPlaylistAsync(Func <Playlist> getPlaylist, PlaylistProvider <Playlist <TvgMedia>, TvgMedia> provider = default, bool isXtreamPlaylist = false, bool force = false,
                                                       CancellationToken cancellationToken = default)
        {
            var playlistEntity = getPlaylist();

            if (playlistEntity == null)
            {
                throw new ArgumentNullException($"Playlist not found");
            }
            if (!playlistEntity.IsSynchronizable)
            {
                throw new ApplicationException($"Playlist isn't synchronizable");
            }

            try
            {
                provider = _providerFactory.CreateInstance(playlistEntity.SynkConfig.Uri, playlistEntity.SynkConfig.Provider);
            }
            catch (Exception)
            {
                throw new ApplicationException("Can't resolve playlist provider");
            }

            using (var playlist = new Playlist <TvgMedia>(provider))
            {
                var sourceList = await playlist.PullAsync(cancellationToken);

                //Faire passer les handlers
                sourceList = ExecuteHandlersAsync(sourceList, cancellationToken);

                if (sourceList.Any())
                {
                    playlistEntity.TvgMedias = sourceList.Where(x => x.IsValid).ToList();
                }

                UpdateIsXtreamTag(isXtreamPlaylist, playlistEntity);
            }

            if (playlistEntity.CreatedDate == default)
            {
                await _dbcontext.Playlist.AddAsync(playlistEntity, cancellationToken);
            }

            playlistEntity.TvgMedias = playlistEntity.TvgMedias;
            var res = await _dbcontext.SaveChangesAsync(cancellationToken);

            return(playlistEntity);
        }
Ejemplo n.º 11
0
        public async Task <IActionResult> DiffAsync([FromBody] PlaylistPostModel playlistPostModel, CancellationToken cancellationToken = default)
        {
            //TODO: Déduire le provider from playlist (isXtream => xtreamProvider, m3u ou tvlist)
            // Load dynmaiquement all providers (singleton)
            PlaylistProvider <Playlist <TvgMedia>, TvgMedia> providerInstance = null;

            try
            {
                providerInstance = _providerFactory.CreateInstance(playlistPostModel.Url, playlistPostModel.Provider);
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }

            try
            {
                var user = await _dbContext.Users.FindAsync(new object[] { UserId }, cancellationToken);

                if (user == null)
                {
                    return(BadRequest($"User {this.UserEmail} not found"));
                }

                var playlist = await _dbContext.Playlist
                               .FirstOrDefaultAsync(x => x.SynkConfig.Url == playlistPostModel.Url, cancellationToken) ?? new Playlist
                {
                    UserId       = user.Id,
                    Freindlyname = playlistPostModel.Freindlyname,
                    Status       = playlistPostModel.Status,
                    SynkConfig   = new SynkConfig {
                        Url = playlistPostModel.Url, Provider = playlistPostModel.Provider
                    }
                };

                using (providerInstance)
                {
                    var pl = await _playlistService
                             .DiffWithSourceAsync(() => playlist, providerInstance, cancellationToken : cancellationToken);

                    return(Ok(pl));
                }
            }
            catch (HttpRequestException)
            {
                throw new BusinessException($"Playlist url {playlistPostModel.Url} not reachable");
            }
        }
Ejemplo n.º 12
0
        Playlist LoadPlaylistFromCache(PlaylistProvider provider, DateTime date)
        {
            if (provider.DontCache)
            {
                return(null);
            }

            string content = cache.GetPlaylistFile(provider.Id, date);

            if (string.IsNullOrWhiteSpace(content))
            {
                return(null);
            }

            return(playlistFileBuilder.TryParseFile(content));
        }
Ejemplo n.º 13
0
        public async Task <IActionResult> ImportFromUrl([FromBody] PlaylistPostModel playlistPostModel, CancellationToken cancellationToken)
        {
            //Vérifier si la playlist existe-elle avant
            var stopwatch = Stopwatch.StartNew();

            PlaylistProvider <Playlist <TvgMedia>, TvgMedia> providerInstance = null;

            try
            {
                providerInstance = _providerFactory.CreateInstance(playlistPostModel.Url, playlistPostModel.Provider);
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }

            using (providerInstance)
            {
                var user = await _dbContext.Users.FindAsync(new object[] { UserId }, cancellationToken);

                if (user == null)
                {
                    return(BadRequest($"User {this.UserEmail} not found"));
                }

                var pl = await _playlistService.SynkPlaylistAsync(() => new Playlist
                {
                    UserId       = user.Id,
                    Freindlyname = playlistPostModel.Freindlyname,
                    Status       = PlaylistStatus.Enabled,
                    SynkConfig   = new SynkConfig {
                        Url = playlistPostModel.Url
                    },
                    Tags = new Dictionary <string, string> {
                        { PlaylistTags.ImportProvider, playlistPostModel.Provider }
                    }
                }, providerInstance, _xtreamService.IsXtreamPlaylist(playlistPostModel.Url), cancellationToken : cancellationToken);

                ClearCache();

                stopwatch.Stop();
                _logger.LogInformation($"Elapsed time : {stopwatch.Elapsed.ToString("c")}");

                var model = PlaylistModel.ToLightModel(pl, Url);
                return(Created(model.PublicUrl, model));
            }
        }
Ejemplo n.º 14
0
        async Task <Playlist> GetPlaylistForTodayAsync(PlaylistProvider provider)
        {
            string playlistFile = await DownloadPlaylistFileAsync(provider, DateTime.UtcNow);

            Playlist playlist = LoadPlaylistFromCache(provider, DateTime.UtcNow);

            if (playlist is null)
            {
                playlist = playlistFileBuilder.TryParseFile(playlistFile);
            }

            if (!Playlist.IsNullOrEmpty(playlist) && !provider.DontCache)
            {
                cache.StorePlaylistFile(provider.Id, DateTime.UtcNow, playlistFile);
            }

            return(playlist);
        }
Ejemplo n.º 15
0
        public MusicDataManager()
        {
            _databaseFile =
                new FileInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                                          "Hurricane", "database.sqlite"));

            Images    = new ImagesProvider();
            Artists   = new ArtistProvider(Images);
            Albums    = new AlbumsProvider(Artists);
            Tracks    = new TrackProvider(Artists, Images, Albums);
            Playlists = new PlaylistProvider(Tracks);
            UserData  = new UserDataProvider();

            LastfmApi    = new LastfmApi(Artists);
            MusicManager = new MusicManager();
            MusicManager.TrackChanged   += MusicManager_TrackChanged;
            MusicManager.NewTrackOpened += MusicManager_NewTrackOpened;
            MusicStreamingPluginManager  = new MusicStreamingPluginManager();
        }
Ejemplo n.º 16
0
        public ViewManager(PlaylistProvider playlistProvider)
        {
            ViewItems = new ObservableCollection <ISideListItem>
            {
                new HomeView(),
                new CollectionView(),
                new ChartsView(),
                new QueueView(),
                new HistoryView()
            };

            playlistProvider.PlaylistAdded   += PlaylistProvider_PlaylistAdded;
            playlistProvider.PlaylistRemoved += PlaylistProvider_PlaylistRemoved;
            foreach (var userPlaylist in playlistProvider.Playlists)
            {
                ViewItems.Add(new PlaylistView(userPlaylist));
            }

            ViewSource = CollectionViewSource.GetDefaultView(ViewItems);
            ViewSource.GroupDescriptions.Add(new PropertyGroupDescription("ViewCategorie"));
        }
Ejemplo n.º 17
0
        Playlist GetPlaylistForPastDays(PlaylistProvider provider)
        {
            if (!provider.UrlFormat.Contains("{0"))
            {
                return(null);
            }

            Playlist playlist = null;

            for (int i = 1; i < applicationSettings.DaysToCheck; i++)
            {
                DateTime date = DateTime.UtcNow.AddDays(-i);

                playlist = LoadPlaylistFromCache(provider, date);

                if (!(playlist is null))
                {
                    break;
                }
            }

            return(playlist);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Genére un rapport avec les new medias et
        /// les médias qui n'existes plus
        /// </summary>
        /// <param name="id"></param>
        /// <param name="force"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task <(IEnumerable <TvgMedia> tvgMedia, IEnumerable <TvgMedia> removed)> DiffWithSourceAsync(Func <Playlist> getPlaylist,
                                                                                                                  PlaylistProvider <Playlist <TvgMedia>, TvgMedia> provider, bool force = false,
                                                                                                                  CancellationToken cancellationToken = default)
        {
            var pl = getPlaylist();

            if (pl == null)
            {
                throw new ArgumentNullException($"Playlist not found");
            }

            if (!pl.IsSynchronizable)
            {
                throw new ApplicationException($"Playlist isn't synchronizable");
            }

            using (var playlist = new Playlist <TvgMedia>(provider))
            {
                var sourceList = await playlist.PullAsync(cancellationToken);

                if (sourceList == null)
                {
                    return(new List <TvgMedia>(), pl.TvgMedias ?? new List <TvgMedia>());
                }
                if (pl.TvgMedias == null || !pl.TvgMedias.Any())
                {
                    return(sourceList, null);
                }

                return(sourceList.Where(s => pl.TvgMedias.All(t => t.Url != s.Url)).ToList(), pl.TvgMedias.Where(s => sourceList.All(t => t.Url != s.Url)).ToList());
            }
        }
Ejemplo n.º 19
0
        async Task <string> DownloadPlaylistFileAsync(PlaylistProvider provider, DateTime date)
        {
            string url = string.Format(provider.UrlFormat, date);

            return(await fileDownloader.TryDownloadStringAsync(url));
        }