public async Task <IActionResult> OnGetAsync([FromQuery] int offset = 0) { this.Offset = offset; VisifyUser user = await _userManager.GetUserAsync(User); if (user == null) { return(NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.")); } VOption <IList <VisifySavedTrack> > stracks = await DatabaseService.GetUsersSavedTracks(user.Id, offset, 50); if (!stracks.WasSuccess) { StatusMessage = "Sorry, we coudln't retrieve your saved songs, we are having database problems. Please try again later."; IsDisabled = true; } VOption <int> libCountO = await DatabaseService.GetUserLibraryCount(user.Id); if (!libCountO.WasSuccess) { StatusMessage = "Sorry, we coudln't retrieve your saved songs, we are having database problems. Please try again later."; IsDisabled = true; } SavedTracks = stracks.Value; LibraryCount = libCountO.Value; CanGoForwards = (!IsDisabled && this.Offset < LibraryCount); CanGoBackwards = (!IsDisabled && this.Offset > 0); return(Page()); }
public async Task <VOption <RateLimit> > GetRateLimits(string userid) { // Check user is rate limited VOption <RateLimit> rlo = await DatabaseService.GetUsersRateLimits(userid); return(rlo); }
public async Task <IActionResult> GetArtistLinks() { VisifyUser user = await _userManager.GetUserAsync(User); if (user == null) { logger.LogInformation($"Tried to get Artist Song Count graph data for user {_userManager.GetUserId(User)}, but user did not exist"); return(NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.")); } // Get the tracks and artists VOption <IList <VisifySavedTrack> > stracks = await DatabaseService.GetUsersSavedTracks(user.Id, limit : 10_000); if (!stracks.WasSuccess) { logger.LogError($"Failed to retreive saved tracks for user {_userManager.GetUserId(User)}", stracks.ErrorMessage); return(Json("FAILED")); } // create a proper d3 structure Dictionary <string, FDGNode> nodes = new Dictionary <string, FDGNode>(); Dictionary <string, FDGEdge> edges = new Dictionary <string, FDGEdge>(); foreach (VisifySavedTrack vst in stracks.Value) { string tid = $"tid_{vst.VisifyTrack.SpotifyId}"; string[] idarr = new string[2]; foreach (VisifyArtist va in vst.VisifyTrack.Artists) { string sid = $"aid_{va.SpotifyId}"; idarr[0] = sid; idarr[1] = tid; Array.Sort(idarr); string lid0 = String.Join("", idarr); string lid1 = $"at_{lid0}"; if (!nodes.ContainsKey(sid)) { nodes.Add(sid, new FDGNode(sid, 0, va.ArtistName, 0, 1)); } else { nodes[sid].size += 1; } nodes.Add(lid1, new FDGNode(lid1, 0, vst.VisifyTrack.TrackName, 1, 1)); if (!edges.ContainsKey(lid0)) { edges.Add(lid0, new FDGEdge(lid1, sid, 0.1)); } } } Dictionary <string, object> keys = new Dictionary <string, object>() { { "nodes", nodes.Values }, { "links", edges.Values } }; return(Json(keys)); }
/// <summary> /// Draw a circle on an image. /// </summary> /// <example> /// <code language="lang-csharp"> /// image.Mutate(x => x.DrawCircle(ink, cx, cy, radius, fill: bool)); /// </code> /// </example> /// <param name="ink">Color for pixels.</param> /// <param name="cx">Centre of draw_circle.</param> /// <param name="cy">Centre of draw_circle.</param> /// <param name="radius">Radius in pixels.</param> /// <param name="fill">Draw a solid object.</param> public void DrawCircle(double[] ink, int cx, int cy, int radius, bool?fill = null) { var options = new VOption(); options.AddIfPresent(nameof(fill), fill); this.Call("draw_circle", options, ink, cx, cy, radius); }
/// <summary> /// Paint a rectangle on an image. /// </summary> /// <example> /// <code language="lang-csharp"> /// image.Mutate(x => x.DrawRect(ink, left, top, width, height, fill: bool)); /// </code> /// </example> /// <param name="ink">Color for pixels.</param> /// <param name="left">Rect to fill.</param> /// <param name="top">Rect to fill.</param> /// <param name="width">Rect to fill.</param> /// <param name="height">Rect to fill.</param> /// <param name="fill">Draw a solid object.</param> public void DrawRect(double[] ink, int left, int top, int width, int height, bool?fill = null) { var options = new VOption(); options.AddIfPresent(nameof(fill), fill); this.Call("draw_rect", options, ink, left, top, width, height); }
/// <summary> /// Paint an image into another image. /// </summary> /// <example> /// <code language="lang-csharp"> /// image.Mutate(x => x.DrawImage(sub, x, y, mode: Enums.CombineMode)); /// </code> /// </example> /// <param name="sub">Sub-image to insert into main image.</param> /// <param name="x">Draw image here.</param> /// <param name="y">Draw image here.</param> /// <param name="mode">Combining mode.</param> public void DrawImage(Image sub, int x, int y, Enums.CombineMode?mode = null) { var options = new VOption(); options.AddIfPresent(nameof(mode), mode); this.Call("draw_image", options, sub, x, y); }
/// <summary> /// Flood-fill an area. /// </summary> /// <example> /// <code language="lang-csharp"> /// image.Mutate(x => x.DrawFlood(ink, x, y, test: Image, equal: bool)); /// </code> /// </example> /// <param name="ink">Color for pixels.</param> /// <param name="x">DrawFlood start point.</param> /// <param name="y">DrawFlood start point.</param> /// <param name="test">Test pixels in this image.</param> /// <param name="equal">DrawFlood while equal to edge.</param> public void DrawFlood(double[] ink, int x, int y, Image test = null, bool?equal = null) { var options = new VOption(); options.AddIfPresent(nameof(test), test); options.AddIfPresent(nameof(equal), equal); this.Call("draw_flood", options, ink, x, y); }
/// <summary> /// Flood-fill an area. /// </summary> /// <example> /// <code language="lang-csharp"> /// image.Mutate(x => x.DrawFlood(ink, x, y, out var left, test: Image, equal: bool)); /// </code> /// </example> /// <param name="ink">Color for pixels.</param> /// <param name="x">DrawFlood start point.</param> /// <param name="y">DrawFlood start point.</param> /// <param name="left">Left edge of modified area.</param> /// <param name="test">Test pixels in this image.</param> /// <param name="equal">DrawFlood while equal to edge.</param> public void DrawFlood(double[] ink, int x, int y, out int left, Image test = null, bool?equal = null) { var options = new VOption(); options.AddIfPresent(nameof(test), test); options.AddIfPresent(nameof(equal), equal); options.Add("left", true); var results = this.Call("draw_flood", options, ink, x, y) as object[]; var opts = results?[1] as VOption; left = opts?["left"] is int out1 ? out1 : 0; }
internal VOption BuildLoadOptionsFromImageType(ImageType imageType) { var result = new VOption(); if (imageType == ImageType.Svg || imageType == ImageType.Pdf) { result.Add("dpi", Options.Density); } else if (imageType == ImageType.Magick) { result.Add("density", Options.Density.ToString(CultureInfo.InvariantCulture)); } if (imageType.SupportsPages) { result.Add("n", Options.PageCount); result.Add("page", Options.PageIndex); } return(result); }
/// <summary> /// Flood-fill an area. /// </summary> /// <example> /// <code language="lang-csharp"> /// image.Mutate(x => x.DrawFlood(ink, x, y, out var left, out var top, out var width, out var height, test: Image, equal: bool)); /// </code> /// </example> /// <param name="ink">Color for pixels.</param> /// <param name="x">DrawFlood start point.</param> /// <param name="y">DrawFlood start point.</param> /// <param name="left">Left edge of modified area.</param> /// <param name="top">top edge of modified area.</param> /// <param name="width">width of modified area.</param> /// <param name="height">height of modified area.</param> /// <param name="test">Test pixels in this image.</param> /// <param name="equal">DrawFlood while equal to edge.</param> public void DrawFlood(double[] ink, int x, int y, out int left, out int top, out int width, out int height, Image test = null, bool?equal = null) { var options = new VOption(); options.AddIfPresent(nameof(test), test); options.AddIfPresent(nameof(equal), equal); options.Add("left", true); options.Add("top", true); options.Add("width", true); options.Add("height", true); var results = this.Call("draw_flood", options, ink, x, y) as object[]; var opts = results?[1] as VOption; left = opts?["left"] is int out1 ? out1 : 0; top = opts?["top"] is int out2 ? out2 : 0; width = opts?["width"] is int out3 ? out3 : 0; height = opts?["height"] is int out4 ? out4 : 0; }
private async Task <VOption <OAuthToken> > CheckRefesh(OAuthToken token) { // Check if keys need to be refreshed if (token.ShouldRenew) { VOption <OAuthToken> refreshed = await RenewToken(token); if (!refreshed.WasSuccess) { // failed. Error and move on. logger.Error($"Failed to renew tokens for some reason for user {token.AspNetUserId}"); return(new VOption <OAuthToken>(refreshed.ErrorCode, refreshed.ErrorMessage)); } token = refreshed.Value; // Save token to db VOption <bool> opt = await SaveTokenToDb(token); if (!opt.WasSuccess) { return(new VOption <OAuthToken>(ErrorCodes.DatabaseWriteError, $"Failed to write tokens to database for user {token.AspNetUserId}")); // Database failure } } return(new VOption <OAuthToken>(token)); }
internal void SaveLoadBuffer(string saver, string loader, Image im, int maxDiff = 0, VOption kwargs = null) { var buf = Operation.Call(saver, kwargs, im) as byte[]; var x = Operation.Call(loader, buf) as Image; Assert.Equal(x.Width, im.Width); Assert.Equal(x.Height, im.Height); Assert.Equal(x.Bands, im.Bands); Assert.True((im - x).Abs().Max() <= maxDiff); }
public string Execute(string[] args) { // If you set a number to zero (0), it will resize on the other specified axis. var width = 200; var height = 0; // "both" - for both up and down. // "up" - only upsize. // "down" - only downsize. // "force" - force size, that is, break aspect ratio. const string size = "both"; // Just for example. var buffer = File.ReadAllBytes(Filename); // Find the name of the load operation vips will use to load a buffer // so that we can work out what options to pass to NewFromBuffer(). var loader = Image.FindLoadBuffer(buffer); if (loader == null) { // No known loader is found, stop further processing. throw new Exception("Invalid or unsupported image format. Is it a valid image?"); } var loadOptions = new VOption { { "access", Enums.Access.Sequential }, { "fail", FailOnError } }; var stringOptions = ""; if (LoaderSupportPage(loader)) { // -1 means "until the end of the document", handy for animated images. loadOptions.Add("n", -1); stringOptions = "[n=-1]"; } Image image; try { image = (Image)Operation.Call(loader, loadOptions, buffer); // Or: // image = Image.NewFromBuffer(buffer, kwargs: loadOptions); // (but the loader is already found, so the above will be a little faster). } catch (VipsException e) { throw new Exception("Image has a corrupt header.", e); } var inputWidth = image.Width; var inputHeight = image.Height; // Use 64-bit unsigned type, to handle PNG decompression bombs. if ((ulong)(inputWidth * inputHeight) > MaxImageSize) { throw new Exception( "Image is too large for processing. Width x height should be less than 71 megapixels."); } var pageHeight = image.PageHeight; var isCmyk = image.Interpretation == Enums.Interpretation.Cmyk; var isLabs = image.Interpretation == Enums.Interpretation.Labs; var embeddedProfile = image.Contains(VipsMetaIccName); string importProfile = null; string exportProfile = null; string intent = null; // Ensure we're using a device-independent color space if ((embeddedProfile || isCmyk) && !isLabs) { // Embedded profile; fallback in case the profile embedded in the image // is broken. No embedded profile; import using default CMYK profile. importProfile = isCmyk ? Enums.Interpretation.Cmyk : Enums.Interpretation.Srgb; // Convert to sRGB using embedded or import profile. exportProfile = Enums.Interpretation.Srgb; // Use "perceptual" intent to better match imagemagick. intent = Enums.Intent.Perceptual; } // Scaling calculations var thumbnailWidth = width; var thumbnailHeight = height; if (width > 0 && height > 0) // Fixed width and height { var xFactor = (double)inputWidth / width; var yFactor = (double)pageHeight / height; if (xFactor > yFactor) // Or: if (xFactor < yFactor) { thumbnailHeight = (int)Math.Round(pageHeight / xFactor); } else { thumbnailWidth = (int)Math.Round(inputWidth / yFactor); } } else if (width > 0) // Fixed width { if (size == "force") { thumbnailHeight = pageHeight; height = pageHeight; } else { // Auto height var yFactor = (double)inputWidth / width; height = (int)Math.Round(pageHeight / yFactor); // Height is missing, replace with a huuuge value to prevent // reduction or enlargement in that axis thumbnailHeight = VipsMaxCoord; } } else if (height > 0) // Fixed height { if (size == "force") { thumbnailWidth = inputWidth; width = inputWidth; } else { // Auto width var xFactor = (double)pageHeight / height; width = (int)Math.Round(inputWidth / xFactor); // Width is missing, replace with a huuuge value to prevent // reduction or enlargement in that axis thumbnailWidth = VipsMaxCoord; } } else // Identity transform { thumbnailWidth = inputWidth; width = inputWidth; thumbnailHeight = pageHeight; height = pageHeight; } // Note: don't use "image.ThumbnailImage". Otherwise, none of the very fast // shrink-on-load tricks are possible. This can make thumbnailing of large // images extremely slow. image = Image.ThumbnailBuffer(buffer, thumbnailWidth, stringOptions, thumbnailHeight, size, false, importProfile: importProfile, exportProfile: exportProfile, intent: intent); image.WriteToFile("thumbnail.webp", new VOption { { "strip", true } }); // Or: /*buffer = image.WriteToBuffer(".webp", new VOption * { * {"strip", true} * });*/ return("See thumbnail.webp"); }
public async Task <VOption <bool> > GetUsersLibrary(string spotifyId) { try { IdentityUserLogin <string> loginforuser = _context.UserLogins.Where(x => x.LoginProvider == "Spotify" && x.ProviderKey == spotifyId).FirstOrDefault(); string aspnetuserId = loginforuser.UserId; if (loginforuser == null) { //Critical error logger.Error("User had no tokens at all."); return(new VOption <bool>(ErrorCodes.NoUserByThatNameError, $"No user tokens found for user {aspnetuserId}")); } string spotifyid = loginforuser.ProviderKey; // Check if User is rate limited VOption <RateLimit> rlo = await GetRateLimits(spotifyid); if (!rlo.WasSuccess) { return(new VOption <bool>(rlo.ErrorCode, rlo.ErrorMessage)); } if (rlo.Value.RateLimitExpiresAt >= DateTimeOffset.Now) { logger.Info($"user {aspnetuserId} is still rate limited"); return(new VOption <bool>(false)); // Rate limited condition } // Get Keys OAuthToken token = GetUserTokens(aspnetuserId, spotifyId); // Refresh if necessary + saves to db VOption <OAuthToken> refreshedO = await CheckRefesh(token); if (!refreshedO.WasSuccess) { return(new VOption <bool>(refreshedO.ErrorCode, refreshedO.ErrorMessage)); } // Get real offset int trueOffset = Math.Max(0, rlo.Value.LimitedAtOffset); // Get most recently added track VOption <DateTimeOffset> dtoo = await DatabaseService.GetMostRecentlyAddedAtForUser(spotifyid); if (!dtoo.WasSuccess) { return(new VOption <bool>(dtoo.ErrorCode, dtoo.ErrorMessage)); } bool cont = true; while (cont) { // Fetch from Spotify VOption <Paging <SavedTrack> > libraryo = await _GetUsersSpotifyLibrary(token, trueOffset); if (!libraryo.WasSuccess) { logger.Error($"Failed to get spotify library tracks for user {aspnetuserId}"); RateLimit nrl = new RateLimit(spotifyid, rlo.Value.RateLimitExpiresAt, trueOffset); // write offset to DB VOption <bool> writeSuccess = await DatabaseService.InsertRateLimitForUser(aspnetuserId, spotifyId, nrl); return(new VOption <bool>(libraryo.ErrorCode, libraryo.ErrorMessage)); } Paging <SavedTrack> pst = libraryo.Value; IList <VisifySavedTrack> fromPaging = _visifyTracksFromPaging(spotifyid, pst, dtoo.Value); if (String.IsNullOrWhiteSpace(pst.Next) || !fromPaging.Any()) { cont = false; } VOption <bool> insertSuccess = await DatabaseService.InsertVisifySavedTracks(aspnetuserId, spotifyId, fromPaging); if (!insertSuccess.WasSuccess) { RateLimit nrl = new RateLimit(spotifyid, rlo.Value.RateLimitExpiresAt, trueOffset); VOption <bool> writeSuccess = await DatabaseService.InsertRateLimitForUser(aspnetuserId, spotifyId, nrl); return(new VOption <bool>(insertSuccess.ErrorCode, insertSuccess.ErrorMessage)); } trueOffset += 50; } // Erase RateLimits await DatabaseService.ClearUserRateLimits(spotifyId); return(new VOption <bool>()); } catch (Exception e) { logger.Error(e, "Failed to get users library"); return(new VOption <bool>(ErrorCodes.MiscFailure, "Failed to get user library")); } }
public static (Image Image, ImageType ImageType) OpenInput(InputDescriptor descriptor, string accessMethod) { descriptor = Guard.NotNull(descriptor, nameof(descriptor)); Image image; ImageType imageType; if (descriptor.Buffer != null) { if (descriptor.RawChannels > 0) { // raw, uncompressed pixel data image = Image.NewFromMemory(descriptor.Buffer, descriptor.RawWidth, descriptor.RawHeight, descriptor.RawChannels, Enums.BandFormat.Uchar); image.Set("interpretation", descriptor.RawChannels < 3 ? Enums.Interpretation.Bw : Enums.Interpretation.Srgb); imageType = ImageType.Raw; } else { // Compressed data imageType = ImageType.FromBuffer(descriptor.Buffer); if (imageType == ImageType.Unknown) { throw new VipsException("Input buffer contains unsupported image format."); } try { var option = new VOption { { "access", accessMethod }, { "fail", descriptor.FailOnError } }; if (imageType == ImageType.Svg || imageType == ImageType.Pdf) { option.Add("dpi", descriptor.Density); } if (imageType == ImageType.Magick) { option.Add("density", descriptor.Density); } if (imageType.SupportsPages) { option.Add("n", descriptor.Pages); option.Add("page", descriptor.Page); } image = Image.NewFromBuffer(descriptor.Buffer, null, null, null, option); if (imageType == ImageType.Svg || imageType == ImageType.Pdf || imageType == ImageType.Magick) { image.SetDensity(descriptor.Density); } } catch (Exception ex) { throw new VipsException($"Input buffer has corrupt header: {ex.Message}", ex); } } } else { if (descriptor.CreateChannels > 0) { // create new image var background = new List <double> { descriptor.CreateBackground[0], descriptor.CreateBackground[1], descriptor.CreateBackground[2] }; if (descriptor.CreateChannels == 4) { background.Add(descriptor.CreateBackground[3]); } image = Image.NewFromArray(background.ToArray()); // TODO: suspect image.Set("interpretation", Enums.Interpretation.Srgb); imageType = ImageType.Raw; } else { imageType = ImageType.FromFile(descriptor.File !); if (imageType == ImageType.Missing) { throw new VipsException($"Input file {descriptor.File} is missing."); } if (imageType == ImageType.Unknown) { throw new VipsException("Input file contains unsupported image format."); } try { var option = new VOption { { "access", accessMethod }, { "fail", descriptor.FailOnError } }; if (imageType == ImageType.Svg || imageType == ImageType.Pdf) { option.Add("dpi", descriptor.Density); } if (imageType == ImageType.Magick) { option.Add("density", descriptor.Density); } if (imageType.SupportsPages) { option.Add("n", descriptor.Pages); option.Add("page", descriptor.Page); } image = Image.NewFromFile(descriptor.File, null, null, null, option); if (imageType == ImageType.Svg || imageType == ImageType.Pdf || imageType == ImageType.Magick) { image.SetDensity(descriptor.Density); } } catch (Exception ex) { throw new VipsException($"Input file has corrupt header: {ex.Message}", ex); } } } return(image, imageType); }
public async Task <IActionResult> GetArtistCollabLinks() { VisifyUser user = await _userManager.GetUserAsync(User); if (user == null) { logger.LogInformation($"Tried to get Artist Collab Link graph data for user {_userManager.GetUserId(User)}, but user did not exist"); return(NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.")); } // Get the tracks and artists VOption <IList <VisifySavedTrack> > stracks = await DatabaseService.GetUsersSavedTracks(user.Id, limit : 10_000); if (!stracks.WasSuccess) { logger.LogError($"Failed to retreive saved tracks for user {_userManager.GetUserId(User)}", stracks.ErrorMessage); return(Json("FAILED")); } // create a proper d3 structure Dictionary <string, FDGNode> nodes = new Dictionary <string, FDGNode>(); Dictionary <string, FDGEdge> edges = new Dictionary <string, FDGEdge>(); foreach (VisifySavedTrack vst in stracks.Value) { string tid = $"tid_{vst.VisifyTrack.SpotifyId}"; string[] idarr = new string[2]; Stack <string> artistsOnThisTrack = new Stack <string>(vst.VisifyTrack.Artists.Count); for (int i = 0; i < vst.VisifyTrack.Artists.Count; i++) { VisifyArtist va = vst.VisifyTrack.Artists[i]; if (!nodes.ContainsKey(va.SpotifyId)) { nodes.Add(va.SpotifyId, new FDGNode(va.SpotifyId, 0, va.ArtistName, 1, 1000)); } artistsOnThisTrack.Push(va.SpotifyId); } while (artistsOnThisTrack.Count > 0) { string a = artistsOnThisTrack.Pop(); foreach (string othera in artistsOnThisTrack) { idarr[0] = a; idarr[1] = othera; Array.Sort(idarr); string lid0 = String.Join("", idarr); Dictionary <string, string> tn = new Dictionary <string, string>() { { "name", vst.VisifyTrack.TrackName } }; if (edges.ContainsKey(lid0)) { edges[lid0].strength += 0.1; edges[lid0].tracks.Add(tn); } else { FDGEdge n = new FDGEdge(othera, a, 0.1); n.tracks.Add(tn); edges.Add(lid0, n); } } } } Dictionary <string, object> keys = new Dictionary <string, object>() { { "nodes", nodes.Values }, { "links", edges.Values } }; return(Json(keys)); }