Ejemplo n.º 1
0
        public async Task <EntryProcessResult> PreProcessEntry(ApplicationUser user, PodcastEntry entry)
        {
            var quota     = user.DiskQuota ?? _storageSettings.DefaultUserQuota;
            var totalUsed = (await _repository.GetAllForUserAsync(user.Id))
                            .Select(x => x.AudioFileSize)
                            .Sum();

            if (totalUsed >= quota)
            {
                return(EntryProcessResult.QuotaExceeded);
            }

            if (string.IsNullOrEmpty(entry.ImageUrl))
            {
                entry.ImageUrl = $"{_storageSettings.CdnUrl}/static/images/default-entry.png";
            }

            entry.Processed = false;
            _repository.AddOrUpdate(entry);
            try {
                var succeeded = await _unitOfWork.CompleteAsync();

                if (succeeded)
                {
                    BackgroundJob.Enqueue <ProcessNewEntryJob>(e => e.ProcessEntry(entry.Id, null));
                    return(EntryProcessResult.Succeeded);
                }
            } catch (DbUpdateException e) {
                _logger.LogError(e.Message);
            }
            return(EntryProcessResult.GeneralFailure);
        }
Ejemplo n.º 2
0
        protected void Page_Load(object sender, EventArgs e)
        {
            _UpdateCount = 0;

            if (UserSecurityClass == PoliticianSecurityClass)
            {
                PodcastEntry.AddCssClasses("hidden");
            }

            if (!IsPostBack)
            {
                var title = PoliticianName + " - Update Intro";
                Page.Title   = title;
                H2.InnerHtml = OfficeAndStatus;
                ShowIntroLink.Attributes["href"] = IntroPageUrl;
                //UpdateIssuesLink.Attributes["href"] = UpdateIssuesPageUrl;
                //ShowPoliticianIssueLink.Attributes["href"] = PoliticianIssuePageUrl;

                // Set temp nocache
                SetNoCacheForState();

                // mark if birthday is needed (politician access only)
                if (UserSecurityClass == PoliticianSecurityClass &&
                    string.IsNullOrWhiteSpace(Politicians.GetDateOfBirthAsString(PoliticianKey)))
                {
                    Master.FindControl("Body").AddCssClasses("need-dob");
                }
            }
        }
Ejemplo n.º 3
0
        public async Task <bool> ExecuteForEntry(PodcastEntry entry, string localFile,
                                                 bool updateEntry, PerformContext context)
        {
            try {
                if (!System.IO.File.Exists(localFile))
                {
                    return(false);
                }

                var imageUrl       = entry.GetImageUrl(_storageOptions.CdnUrl, _imageStorageOptions.ContainerName);
                var localImageFile = string.Empty;
                if (!string.IsNullOrEmpty(imageUrl))
                {
                    localImageFile = await HttpUtils.DownloadFile(imageUrl);

                    if (!System.IO.File.Exists(localImageFile))
                    {
                        localImageFile = await HttpUtils.DownloadFile("https://cdn.podnoms.com/static/images/pn-back.jpg");
                    }
                }

                _tagger.CreateTags(
                    localFile,
                    localImageFile,
                    entry.Title,
                    entry.Podcast.Title,
                    entry.Podcast.AppUser.GetBestGuessName(),
                    $"Copyright © {System.DateTime.Now.Year} {entry.Podcast.AppUser.GetBestGuessName()}",
                    $"Robot Powered Podcasts from{Environment.NewLine}https://podnoms.com/");
                entry.AudioLength = _tagger.GetDuration(localFile);

                if (updateEntry)
                {
                    entry.MetadataStatus = 1;
                    await _unitOfWork.CompleteAsync();
                }
            } catch (Exception e) {
                this.LogError($"Error tagging entry: {e.Message}");
            }
            return(true);
        }
        public async Task <ActivityLogPodcastEntry> AddLogEntry(
            PodcastEntry entry, string referrer, string userAgent, string clientAddress, string extraInfo = "")
        {
            try {
                var log = new ActivityLogPodcastEntry {
                    PodcastEntry  = entry,
                    Referrer      = referrer,
                    UserAgent     = userAgent,
                    ClientAddress = clientAddress,
                    ExtraInfo     = extraInfo
                };
                this.Create(log);
                await _unitOfWork.CompleteAsync();

                // BackgroundJob.Enqueue<GeocodeActivityJob>(r => r.GeocodeActivityItem(log, null));
                return(log);
            } catch (Exception e) {
                _logger.LogError($"Error logging podcast entry activity.\n{e.Message}");
            }
            return(null);
        }
        private async void __tryCreateEpisode(object?sender, MatchedTweetReceivedEventArgs incomingTweet)
        {
            _logger.LogDebug(incomingTweet.Json);

            ExceptionHandler.SwallowWebExceptions = false;
            ExceptionHandler.LogExceptions        = true;
            try {
                if (incomingTweet.Tweet.InReplyToStatusId == null)
                {
                    return;
                }

                var tweetId     = (long)incomingTweet.Tweet.InReplyToStatusId;
                var sourceTweet = await TweetAsync.GetTweet((long)incomingTweet.Tweet.InReplyToStatusId);

                var tweetToReplyTo = incomingTweet.Tweet;
                var targetUser     = incomingTweet.Tweet.CreatedBy.ScreenName;

                var user = await __getTargetUser(targetUser);

                if (user == null)
                {
                    await _createPublicErrorResponse(
                        tweetToReplyTo,
                        $"Hi @{targetUser}, sorry but I cannot find your account.\nPlease edit your profile and make sure your Twitter Handle is set correctly.\n{_appSettings.SiteUrl}/profile"
                        );

                    return;
                }

                using var scope = _provider.CreateScope();
                var(
                    processor,
                    podcastRepository,
                    entryRepository,
                    unitOfWork) = _getScopedServices(scope);

                // var podcast = (await podcastRepository.GetRandomForUser(user.Id));
                var podcast = await __getTargetPodcast(tweetToReplyTo.FullText, user.Id, podcastRepository);

                if (podcast == null)
                {
                    await _createPublicErrorResponse(
                        tweetToReplyTo,
                        $"Hi @{targetUser}, I cannot find the podcast to create this episode for, please make sure the podcast slug or URL is the first word after {_twitterSettings.Track}\n{_appSettings.SiteUrl}"
                        );

                    return;
                }

                var entry = new PodcastEntry {
                    Podcast          = podcast,
                    Processed        = false,
                    ProcessingStatus = ProcessingStatus.Accepted,
                    SourceUrl        = sourceTweet.Url
                };

                var status = await processor.GetInformation(entry, podcast.AppUserId);

                if (status != RemoteUrlType.SingleItem)
                {
                    await _createPublicErrorResponse(
                        tweetToReplyTo,
                        $"Hi @{targetUser}, sorry but I cannot find any media to parse in this tweet.\n{_appSettings.SiteUrl}"
                        );

                    return;
                }

                entry.Title       = $"New entry from {sourceTweet.CreatedBy.ScreenName}'s tweet";
                entry.Description = sourceTweet.Text;

                entryRepository.AddOrUpdate(entry);
                await unitOfWork.CompleteAsync();
                await _sendHubUpdate(user.Id.ToString(), entry.SerialiseForHub());

                //get JWT token so we can call into the job realtime stuff
                var token = await __getJwtTokenForUser(user);

                var processId = BackgroundJob.Enqueue <ProcessNewEntryJob>(
                    e => e.ProcessEntry(entry.Id, null));

                var message =
                    $"Hi @{targetUser}, your request was processed succesfully, you can find your new episode in your podcatcher or here\n{podcast.GetPagesUrl(_appSettings.PagesUrl)}";
                BackgroundJob.ContinueJobWith <SendTweetJob>(
                    processId, (r) => r.SendTweet(tweetToReplyTo.Id, message));
            } catch (Exception e) {
                _logger.LogError($"Error creating episode: {e.Message}");
            }
        }
Ejemplo n.º 6
0
        // [MaximumConcurrentExecutions(1)]
        // [DisableConcurrentExecution(timeoutInSeconds: 60 * 60 * 2)]
        public async Task <bool> Execute(ParsedItemResult item, Guid playlistId, PerformContext context)
        {
            _setContext(context);
            if (item is null || string.IsNullOrEmpty(item.VideoType))
            {
                return(false);
            }

            Log($"Starting process item:\n\t{item.Id}\n\t{item.Title}\n\thttps://www.youtube.com/watch?v={item.Id}");

            var playlist = await _playlistRepository.GetAsync(playlistId);

            var url = item.VideoType.ToLower().Equals("youtube") ? $"https://www.youtube.com/watch?v={item.Id}" :
                      item.VideoType.Equals("mixcloud") ? $"https://mixcloud.com/{item.Id}" :
                      string.Empty;

            if (string.IsNullOrEmpty(url))
            {
                LogError($"Unknown video type for ParsedItem: {item.Id} - {playlist.Id}");
            }
            else
            {
                Log($"Getting info");
                var info = await _audioDownloader.GetInfo(url, playlist.Podcast.AppUserId);

                if (info != RemoteUrlType.Invalid)
                {
                    Log($"URL is valid");

                    var podcast = await _podcastRepository.GetAsync(playlist.PodcastId);

                    var uid = Guid.NewGuid();
                    Log($"Downloading audio");
                    var localFile = Path.Combine(Path.GetTempPath(), $"{System.Guid.NewGuid()}.mp3");
                    try {
                        var entry = new PodcastEntry {
                            SourceUrl        = url,
                            ProcessingStatus = ProcessingStatus.Uploading,
                            Playlist         = playlist,
                            Podcast          = podcast
                        };
                        await _processor.GetInformation(entry, podcast.AppUserId);

                        podcast.PodcastEntries.Add(entry);
                        await _unitOfWork.CompleteAsync();

                        var result = await _preProcessor.PreProcessEntry(podcast.AppUser, entry);

                        return(result == EntryProcessResult.Succeeded);
                    } catch (AudioDownloadException e) {
                        //TODO: we should mark this as failed
                        //so we don't continuously process it
                        LogError(e.Message);
                    }
                }
                else
                {
                    LogError($"Processing playlist item {item.Id} failed");
                    return(false);
                }
            }

            return(true);
        }
        public async Task <IActionResult> Upload(string slug, IFormFile file)
        {
            _logger.LogDebug($"Uploading file for: {slug}");
            if (file is null || file.Length == 0)
            {
                return(BadRequest("No file found in stream"));
            }
            if (file.Length > _audioFileStorageSettings.MaxUploadFileSize)
            {
                return(BadRequest("Maximum file size exceeded"));
            }
            if (!_audioFileStorageSettings.IsSupported(file.FileName))
            {
                return(BadRequest("Invalid file type"));
            }

            var podcast = await _podcastRepository.GetForUserAndSlugAsync(_applicationUser.Slug, slug);

            if (podcast is null)
            {
                _logger.LogError($"Unable to find podcast");
                return(NotFound());
            }

            var entry = new PodcastEntry {
                Title            = Path.GetFileName(Path.GetFileNameWithoutExtension(file.FileName)),
                ImageUrl         = $"{_storageSettings.CdnUrl}/static/images/default-entry.png",
                Processed        = false,
                ProcessingStatus = ProcessingStatus.Processing,
                Podcast          = podcast
            };

            var localFile = await CachedFormFileStorage.CacheItem(_hostingEnvironment.WebRootPath, file);

            _logger.LogDebug($"Local file is: {localFile}");

            _entryRepository.AddOrUpdate(entry);

            _logger.LogDebug("Completing uow");
            await _unitOfWork.CompleteAsync();

            var authToken = _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"].ToString();

            if (string.IsNullOrEmpty(authToken))
            {
                return(Unauthorized("Auth token is empty"));
            }

            //convert uploaded file to extension
            var audioUrl = localFile
                           .Replace(_hostingEnvironment.WebRootPath, string.Empty)
                           .Replace(@"\", "/");

            _logger.LogDebug($"Starting processing jobs for url: {audioUrl}");

            BackgroundJob.Enqueue <ProcessNewEntryJob>(e =>
                                                       e.ProcessEntryFromUploadFile(entry.Id, audioUrl, authToken, null));

            var ret = _mapper.Map <PodcastEntry, PodcastEntryViewModel>(entry);

            return(Ok(ret));
        }