public object AmazonWebHook(AmazonNotification notification) { return(base.ExecuteFunction("AmazonWebHook", delegate() { if (notification != null) { if (notification.Type == "SubscriptionConfirmation") { if (!string.IsNullOrEmpty(notification.SubscribeURL)) { WebRequest.Create(notification.SubscribeURL).GetResponse(); } } if (notification.Type == "Notification") { if (!string.IsNullOrEmpty(notification.Message)) { AmazonJobInfo jobInfo = JsonConvert.DeserializeObject <AmazonJobInfo>(notification.Message); if (jobInfo != null) { Guid asset_id = Guid.Empty; Asset asset = null; if (Guid.TryParse(jobInfo.outputKeyPrefix.Replace(AmazonEncodingDaemon.OUTPUT_PREFIX, "").Trim('/'), out asset_id)) { switch (jobInfo.state) { case "ERROR": asset = this.API.Direct.Assets.UpdateEncodingInfo(asset_id, jobInfo.jobId, false, EncoderStatus.fail.ToString(), "Amazon Error: " + jobInfo.messageDetails, false); if (asset != null && asset.encode_attempts >= this.MaximumRetries) { this.API.Integration.Email.SendAdminEmail("Video Encoder", string.Format("The following video has failed to encode after {0} attempts.<br/><br/>asset_id: {1}<br/>raw_url: {2}<br/>log: {3}", asset.encode_attempts, asset.asset_id, asset.raw_url, asset.encode_log)); } break; case "WARNING": this.API.Direct.Assets.UpdateEncodingInfo(asset_id, jobInfo.jobId, true, EncoderStatus.processing.ToString(), "Amazon Warning: " + jobInfo.messageDetails, false); break; case "COMPLETED": asset = this.API.Direct.Assets.GetById(asset_id); if (asset != null) { HealthReporter.Current.UpdateMetric(HealthTrackType.Each, HealthReporter.VIDEO_TRANSCODE_COMPLETE_SUCCESS, 0, 1); string mediaFile = string.Format("{0}/{1}", jobInfo.outputKeyPrefix.Trim('/'), jobInfo.outputs[0].key.TrimStart('/')); string thumbFile = string.Format("{0}/{1}", jobInfo.outputKeyPrefix.Trim('/'), jobInfo.outputs[0].thumbnailPattern.TrimStart('/').Replace("{count}", "00001") + ".png"); asset.raw_url = AmazonUtility.ConstructAmazonUrl(string.Empty, this.AmazonPublicUrl, this.AmazonBucket, mediaFile); asset.public_url = AmazonUtility.ConstructAmazonUrl(this.AmazonCloudFrontUrl, this.AmazonPublicUrl, this.AmazonBucket, mediaFile); asset.thumb_large_url = AmazonUtility.ConstructAmazonUrl(this.AmazonCloudFrontUrl, this.AmazonPublicUrl, this.AmazonBucket, thumbFile); asset.thumb_medium_url = asset.thumb_large_url; asset.thumb_small_url = asset.thumb_large_url; asset.encode_required = false; asset.encode_processing = false; asset.available = true; asset.encode_status = EncoderStatus.complete.ToString(); asset.encode_log += "Amazon Completed Processing on " + DateTime.UtcNow.ToString() + "|" + notification.Message; asset.resize_required = true; asset.resize_mode = "fitnopadding"; this.API.Direct.Assets.Update(asset); this.API.Integration.Synchronization.AgitateDaemon(AmazonImageResizeDaemon.DAEMON_NAME); } else { HealthReporter.Current.UpdateMetric(HealthTrackType.Each, HealthReporter.VIDEO_TRANSCODE_COMPLETE_FAILED, 0, 1); } break; case "PROGRESSING": this.API.Direct.Assets.UpdateEncodingInfo(asset_id, jobInfo.jobId, true, EncoderStatus.processing.ToString(), "Amazon Started Processing on " + DateTime.UtcNow.ToString(), false); break; default: break; } } } } } } return this.Http200("OK", ""); })); }
/// <summary> /// Returns empty string on success /// </summary> public virtual Asset ProcessPhoto(Asset asset) { return(base.ExecuteFunction("ProcessPhoto", delegate() { try { // get recent, just in case asset = this.API.Direct.Assets.GetById(asset.asset_id); if (asset == null || !asset.resize_required) { return null; // short circuit } asset.resize_attempts++; asset.resize_attempt_utc = DateTime.UtcNow; this.API.Direct.Assets.UpdateResizeAttemptInfo(asset.asset_id, asset.resize_attempts, asset.resize_attempt_utc.GetValueOrDefault(), "Attempting to resize"); System.Drawing.Image original = null; try { string raw_url = asset.raw_url; if (asset.type == AssetType.Video) { raw_url = asset.thumb_large_url; } original = this.GetImageFromUrl(raw_url); if (original == null) { return null; } int ix = raw_url.LastIndexOf('/'); string prefix = asset.raw_url.Substring(0, ix).Trim('/') + "/"; ix = prefix.ToLower().IndexOf(this.AmazonBucket.ToLower()); if (ix > -1) { prefix = prefix.Substring(ix + this.AmazonBucket.Length); } ix = prefix.ToLower().IndexOf(this.AmazonCloudFrontUrl.ToLower()); if (ix > -1) { prefix = prefix.Substring(ix + this.AmazonCloudFrontUrl.Length); } prefix = prefix.TrimStart('/'); string extension = Path.GetExtension(asset.raw_url); string imageCodecName = "jpeg"; EncoderParameters encoderParameters = new EncoderParameters(1); encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L); PixelFormat format = PixelFormat.Format24bppRgb; ResizeMode resizeMode = ResizeMode.Fill; if (!string.IsNullOrEmpty(asset.resize_mode)) { if (!Enum.TryParse <ResizeMode>(asset.resize_mode, true, out resizeMode)) { resizeMode = ResizeMode.Fill; // fallback } } if (resizeMode == ResizeMode.Fit) // we never want a backcolor { imageCodecName = "png"; extension = ".png"; format = PixelFormat.Format32bppArgb; } string cacheBuster = string.Format("{0}{1:HHmmss}", DateTime.UtcNow.DayOfYear, DateTime.UtcNow); string destinationSmall = prefix + cacheBuster + Path.GetFileNameWithoutExtension(asset.raw_url) + "_sm" + extension; string destinationMedium = prefix + cacheBuster + Path.GetFileNameWithoutExtension(asset.raw_url) + "_md" + extension; string destinationLarge = prefix + cacheBuster + Path.GetFileNameWithoutExtension(asset.raw_url) + "_lg" + extension; // create thumb Image smallImage = null; Image mediumImage = null; Image largeImage = null; try { Size dimensions = new Size(); if (TryParseDimensions(asset.thumb_small_dimensions, out dimensions)) { smallImage = ImageFormatter.Resize(original, resizeMode, (AnchorStyles.Middle | AnchorStyles.Center), dimensions.Width, dimensions.Height, format, InterpolationMode.HighQualityBicubic, Color.Transparent); } if (TryParseDimensions(asset.thumb_medium_dimensions, out dimensions)) { mediumImage = ImageFormatter.Resize(original, resizeMode, (AnchorStyles.Middle | AnchorStyles.Center), dimensions.Width, dimensions.Height, format, InterpolationMode.HighQualityBicubic, Color.Transparent); } if (TryParseDimensions(asset.thumb_large_dimensions, out dimensions)) { largeImage = ImageFormatter.Resize(original, resizeMode, (AnchorStyles.Middle | AnchorStyles.Center), dimensions.Width, dimensions.Height, format, InterpolationMode.HighQualityBicubic, Color.Transparent); } using (AmazonS3Client client = new AmazonS3Client(this.AmazonKeyID, this.AmazonSecret, RegionEndpoint.USEast1)) { // save small if (smallImage != null) { this.FlipImageIfNeeded(original, smallImage); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream()) { smallImage.Save(memoryStream, GetCodecInfo(imageCodecName), encoderParameters); memoryStream.Position = 0; PutObjectRequest request = new PutObjectRequest() { BucketName = this.AmazonBucket, Key = destinationSmall, CannedACL = S3CannedACL.PublicRead, InputStream = memoryStream }; PutObjectResponse result = client.PutObject(request); if (result == null || (result.HttpStatusCode != HttpStatusCode.OK && result.HttpStatusCode != HttpStatusCode.Created)) { throw new Exception("Error saving to amazon"); } } } // save medium if (mediumImage != null) { this.FlipImageIfNeeded(original, mediumImage); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream()) { mediumImage.Save(memoryStream, GetCodecInfo(imageCodecName), encoderParameters); memoryStream.Position = 0; PutObjectRequest request = new PutObjectRequest() { BucketName = this.AmazonBucket, Key = destinationMedium, CannedACL = S3CannedACL.PublicRead, InputStream = memoryStream }; PutObjectResponse result = client.PutObject(request); if (result == null || (result.HttpStatusCode != HttpStatusCode.OK && result.HttpStatusCode != HttpStatusCode.Created)) { throw new Exception("Error saving to amazon"); } } } // save large if (largeImage != null) { this.FlipImageIfNeeded(original, largeImage); using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream()) { largeImage.Save(memoryStream, GetCodecInfo(imageCodecName), encoderParameters); memoryStream.Position = 0; PutObjectRequest request = new PutObjectRequest() { BucketName = this.AmazonBucket, Key = destinationLarge, CannedACL = S3CannedACL.PublicRead, InputStream = memoryStream }; PutObjectResponse result = client.PutObject(request); if (result == null || (result.HttpStatusCode != HttpStatusCode.OK && result.HttpStatusCode != HttpStatusCode.Created)) { throw new Exception("Error saving to amazon"); } } } asset = this.API.Direct.Assets.GetById(asset.asset_id); // get recent if (asset != null) { if (smallImage != null) { asset.thumb_small_url = AmazonUtility.ConstructAmazonUrl(this.AmazonCloudFrontUrl, this.AmazonPublicUrl, this.AmazonBucket, destinationSmall); asset.thumb_small_dimensions = string.Format("{0}x{1}", smallImage.Width, smallImage.Height); } if (mediumImage != null) { asset.thumb_medium_url = AmazonUtility.ConstructAmazonUrl(this.AmazonCloudFrontUrl, this.AmazonPublicUrl, this.AmazonBucket, destinationMedium); asset.thumb_medium_dimensions = string.Format("{0}x{1}", mediumImage.Width, mediumImage.Height); } if (largeImage != null) { asset.thumb_large_url = AmazonUtility.ConstructAmazonUrl(this.AmazonCloudFrontUrl, this.AmazonPublicUrl, this.AmazonBucket, destinationLarge); asset.thumb_large_dimensions = string.Format("{0}x{1}", largeImage.Width, largeImage.Height); } asset.available = true; asset.resize_processing = false; asset.resize_required = false; asset.resize_status = EncoderStatus.complete.ToString(); asset.resize_log += "Resize Completed Processing on " + DateTime.UtcNow.ToString(); this.API.Direct.Assets.Update(asset); HealthReporter.Current.UpdateMetric(HealthTrackType.Each, HealthReporter.PHOTO_RESIZE_SUCCESS, 0, 1); } else { HealthReporter.Current.UpdateMetric(HealthTrackType.Each, HealthReporter.PHOTO_RESIZE_FAILED, 0, 1); } return asset; } } finally { if (smallImage != null) { smallImage.Dispose(); } if (mediumImage != null) { mediumImage.Dispose(); } if (largeImage != null) { largeImage.Dispose(); } } } finally { if (original != null) { original.Dispose(); } } } catch (Exception ex) { this.API.Direct.Assets.UpdateResizeInfo(asset.asset_id, false, EncoderStatus.not_processed.ToString(), CoreUtility.FormatException(ex)); HealthReporter.Current.UpdateMetric(HealthTrackType.Each, HealthReporter.PHOTO_RESIZE_FAILED, 0, 1); this.IFoundation.LogError(ex, "PerformProcessPhoto"); return null; } })); }