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); }
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"); } } }
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}"); } }
// [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)); }