Example #1
0
        public IActionResult New()
        {
            try
            {
                LoggerBundle.Trace("Registered PUT request on InviteController.New");
                if (!IsAuthorized(out IActionResult result, u => u.CanInvite))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // create new entry
                String token  = Guid.NewGuid().ToString("N").Substring(0, 16);
                Invite invite = new Invite
                {
                    CreateDate       = DateTime.Now
                    , ExpirationDate = DateTime.Now.AddDays(14)
                    , Token          = token
                };

                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    dc.SetUsers.Attach(AuthorizedUser);
                    AuthorizedUser.Invites.Add(invite);
                    dc.SaveChanges();
                }

                return(Ok(invite.ToJsonDictionary()));
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #2
0
        private Program()
        {
            using (DataContext dc = DataContextFactory.GetInstance())
            {
                LoggerBundle.Debug("Trying to load data of every model type...");

                foreach (Type t in Types)
                {
                    LoggerBundle.Trace($"Loading data for set of type '{t.Name}'...");
                    MethodInfo setMethod        = dc.GetType().GetMethods().First(x => x.Name.Equals("Set"));
                    MethodInfo setMethodGeneric = setMethod.MakeGenericMethod(t);
                    Object     set        = setMethodGeneric.Invoke(dc, new Object[] { });
                    MethodInfo methodLoad = typeof(EntityFrameworkQueryableExtensions).GetMethods()
                                            .First(x => x.Name.Equals("Load"));
                    MethodInfo methodLoadGeneric = methodLoad.MakeGenericMethod(t);
                    methodLoadGeneric.Invoke(set
                                             , new[]
                    {
                        set
                    });

                    dc.SetTracks.Load();
                    LoggerBundle.Trace("Loading data done.");
                }

                LoggerBundle.Debug("Done.");
            }
        }
Example #3
0
        public IActionResult GetAll([FromQuery(Name = "ps")] Int32 pageSize = 50, [FromQuery(Name = "p")] Int32 page = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on TracksController.GetAll");
                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                NormalizePageSize(ref pageSize);

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetTracks.AsNoTracking()
                              .Skip(page * pageSize)
                              .Take(pageSize)
                              .Select(x => x.ToJsonDictionary())
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #4
0
        private void HandleErrOutput(DataReceivedEventArgs arguments, Track track)
        {
            LoggerBundle.Trace($"Processing error response of track '{track}'...");
            try
            {
                String output = arguments?.Data?.Trim();
                if (String.IsNullOrEmpty(output))
                {
                    return;
                }

                LoggerBundle.Warn(new CalculationException(output));
                track.FingerprintError           = output;
                track.LastFingerprintCalculation = DateTime.Now;

                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    LoggerBundle.Trace($"Saving track '{track}'...");
                    dataContext.SetTracks.Attach(track);
                    dataContext.Entry(track).State = EntityState.Modified;
                    dataContext.SaveChanges();
                    LoggerBundle.Debug($"Successfully updated track '{track}'...");
                }
            }
            catch (Exception ex)
            {
                LoggerBundle.Error(ex);
            }
            finally
            {
                _buffer.Remove(track);
            }
        }
Example #5
0
        protected override void Process(String[] args)
        {
            OnProcessStarting();
            TriggerActions(args.ToList());

            List <Track> tracks;

            do
            {
                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    LoggerBundle.Debug("Preloading data...");
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    tracks = _includeFailed
                        ? dataContext.SetTracks.Where(x => !x.LastFingerprintCalculation.HasValue || null != x.FingerprintError)
                             .Take(_config.BufferSize)
                             .ToList()
                        : dataContext.SetTracks.Where(x => !x.LastFingerprintCalculation.HasValue)
                             .Take(_config.BufferSize)
                             .ToList();

                    sw.Stop();
                    LoggerBundle.Debug($"Getting data finished in {sw.ElapsedMilliseconds}ms");
                }
                LoggerBundle.Inform($"Batch contains {tracks.Count} record(s).");

                foreach (Track track in tracks)
                {
                    LoggerBundle.Trace($"Initializing process for track '{track}'...");
                    while (_buffer.Count >= _config.ParallelProcesses)
                    {
                        Thread.Sleep(1);
                    }

                    LoggerBundle.Trace($"Starting process for track '{track}'...");
                    Process p = new Process
                    {
                        StartInfo =
                        {
                            FileName                 = FingerprintCalculationExecutablePath
                            , Arguments              = $"-json \"{track.Path}\""
                            , CreateNoWindow         = true
                            , RedirectStandardError  = true
                            , RedirectStandardInput  = true
                            , RedirectStandardOutput = true
                            , UseShellExecute        = false
                        }
                    };
                    p.OutputDataReceived += (_, arguments) => HandleStdOutput(arguments, track);
                    p.ErrorDataReceived  += (_, arguments) => HandleErrOutput(arguments, track);
                    _buffer.Add(track);
                    LoggerBundle.Trace($"Starting computation process for file '{track}'...");
                    p.Start();
                    p.BeginOutputReadLine();
                    p.BeginErrorReadLine();
                    LoggerBundle.Debug($"Computation process started for file '{track}'");
                }
            }while (tracks.Count > 0);
        }
Example #6
0
        public IActionResult GetAll([FromQuery(Name = "ps")] Int32 pageSize = 50, [FromQuery(Name = "p")] Int32 page = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on InviteController.GetAll");
                if (!IsAuthorized(out IActionResult result, u => u.CanInvite))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                NormalizePageSize(ref pageSize);

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetInvites.Include(x => x.CreateUser)
                              .Include(x => x.RegisteredUser)
                              .AsNoTracking()
                              .Where(x => x.CreateUser.CanInvite)
                              .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedPayload.ClientId))
                              .OrderByDescending(x => x.CreateDate)
                              .Skip(page * pageSize)
                              .Take(pageSize)
                              .Select(x => x.ToJsonDictionary())
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #7
0
        protected override void Process(String[] args)
        {
            OnProcessStarting();
            TriggerActions(args.ToList());

            List <String> paths = args.Distinct().Select(x => x.Trim()).ToList();

            if (paths.Count.Equals(0))
            {
                LoggerBundle.Fatal(new ArgumentException("no argument given"));
                Environment.Exit(1);
            }

            foreach (String path in paths)
            {
                LoggerBundle.Inform($"Processing path '{path}'...");
                if (!Directory.Exists(path))
                {
                    LoggerBundle.Warn($"Path '{path}' not found. Skipping.");
                    continue;
                }

                LoggerBundle.Debug("Preloading data...");
                List <String> tracks;
                Stopwatch     sw = new Stopwatch();
                sw.Start();
                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    tracks = dataContext.SetTracks.AsNoTracking().Select(x => x.Path).ToList();
                }
                sw.Stop();
                LoggerBundle.Debug($"Getting data finished in {sw.ElapsedMilliseconds}ms");

                List <String>       buffer = new List <String>();
                DataSource <String> ds     = new PathDataSource(path, _config.Extensions);

                LoggerBundle.Inform($"Start to crawl path '{path}'...");
                foreach (String file in ds.Get())
                {
                    buffer.Add(file);

                    Int32 bufferCount = buffer.Count;
                    if (bufferCount < _config.BufferSize)
                    {
                        if (bufferCount % (_config.BufferSize < 1337 ? _config.BufferSize : 1337) == 0)
                        {
                            LoggerBundle.Trace($"Adding files to buffer [{bufferCount}/{_config.BufferSize}] ...");
                        }
                        continue;
                    }

                    ProcessBuffer(ref buffer, ref tracks);
                }

                ProcessBuffer(ref buffer, ref tracks);
            }
        }
Example #8
0
        public IActionResult GetAll([FromQuery(Name = "ps")] Int32 pageSize = 50, [FromQuery(Name = "p")] Int32 page = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on PlaylistsController.GetAll");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                NormalizePageSize(ref pageSize);

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    dc.SetUsers.Attach(AuthorizedUser);

                    List <Playlist> playlists = dc.SetPlaylists.AsNoTracking()
                                                .Include(x => x.CreateUser)
                                                .Include(x => x.PlaylistPermissions)
                                                .ThenInclude(x => x.User)
                                                .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId) ||
                                                       x.PlaylistPermissions.Any(y => y.User.UniqueId.Equals(AuthorizedUser.UniqueId)))
                                                .OrderBy(x => x.Name)
                                                .Skip(page * pageSize)
                                                .Take(pageSize)
                                                .ToList();

                    return(Ok(playlists.Select(x => new Dictionary <String, Object>
                    {
                        {
                            "UniqueId", x.UniqueId
                        }
                        ,
                        {
                            "Name", x.Name
                        }
                        ,
                        {
                            "CreateUser", x.CreateUser.ToJsonDictionary()
                        }
                        ,
                        {
                            "CanModify"
                            , x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId) ||
                            x.PlaylistPermissions.Any(y => y.User.UniqueId.Equals(AuthorizedUser.UniqueId) && y.CanModify)
                        }
                    })));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #9
0
        public IActionResult Update(Int32?id, [FromBody] PlaylistModel model)
        {
            try
            {
                LoggerBundle.Trace("Registered UPDATE request on PlaylistsController.Update");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (!id.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                String name = model.Name?.Trim();
                if (String.IsNullOrWhiteSpace(name) || name.Length < 3)
                {
                    LoggerBundle.Trace("Validation failed: invalid name");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Playlist playlist = dc.SetPlaylists.Include(x => x.CreateUser)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.Track)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.CreateUser)
                                        .Include(x => x.PlaylistPermissions)
                                        .ThenInclude(x => x.User)
                                        .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId))
                                        .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == playlist)
                    {
                        LoggerBundle.Trace($"No playlist found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    playlist.Name = name;
                    dc.SaveChanges();

                    return(Ok(playlist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #10
0
        public IActionResult Get(Int32?id)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on FilesController.Get");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (id == null)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode(StatusCodes.Status400BadRequest));
                }

                // get track
                Track track;
                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    track = dataContext.SetTracks.FirstOrDefault(x => x.UniqueId.Equals(id));
                }

                // validate
                if (null == track || !System.IO.File.Exists(track.Path))
                {
                    LoggerBundle.Trace($"Track not found for given id '{id}'");
                    return(StatusCode(StatusCodes.Status404NotFound));
                }

                FileSystemInfo file = new FileInfo(track.Path);
                if (!file.Exists)
                {
                    LoggerBundle.Warn($"File '{track.Path}' not found for given track. Cleanup your database.");
                    return(StatusCode(StatusCodes.Status404NotFound));
                }

                // get mime type
                if (!new FileExtensionContentTypeProvider().TryGetContentType(file.Name, out String contentType))
                {
                    // default fallback
                    contentType = $"audio/{file.Extension.Substring(1)}";
                }

                return(PhysicalFile(file.FullName, contentType));
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #11
0
        private void HandleStdOutput(DataReceivedEventArgs arguments, Track track)
        {
            LoggerBundle.Trace($"Processing response of track '{track}'...");
            try
            {
                String output = arguments?.Data?.Trim();
                if (String.IsNullOrEmpty(output))
                {
                    return;
                }

                LoggerBundle.Debug(Logger.DefaultLogFlags & ~LogFlags.SuffixNewLine
                                   , $"Trying to serialize computation output of file '{track}'...");
                JsonFingerprint jfp = JsonConvert.DeserializeObject <JsonFingerprint>(output);
                LoggerBundle.Debug(Logger.DefaultLogFlags & ~LogFlags.PrefixLoggerType & ~LogFlags.PrefixTimeStamp, "Ok.");

                track.LastFingerprintCalculation = DateTime.Now;
                track.FingerprintHash            = _hasher.Compute(jfp.Fingerprint);
                track.FingerprintError           = null;

                LoggerBundle.Trace($"Fingerprint hash: {track.FingerprintHash} for fingerprint {jfp.Fingerprint}");

                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    LoggerBundle.Trace($"Checking for duplicates for file '{track}'...");
                    if (dataContext.SetTracks.AsNoTracking().Any(x => x.FingerprintHash.Equals(track.FingerprintHash)))
                    {
                        LoggerBundle.Debug($"File with same fingerprint already in database. Path '{track}' will be skipped");
                        track.FingerprintError = "duplicate";
                    }
                    else
                    {
                        LoggerBundle.Trace($"No duplicate found for file '{track}'");
                        track.Duration    = jfp.Duration;
                        track.Fingerprint = jfp.Fingerprint;
                        LoggerBundle.Trace($"New meta data duration '{track.Duration}' and fingerprint '{jfp.Fingerprint}'");
                    }

                    LoggerBundle.Trace($"Saving file '{track.Path}'...");
                    dataContext.SetTracks.Attach(track);
                    dataContext.Entry(track).State = EntityState.Modified;
                    dataContext.SaveChanges();
                    LoggerBundle.Debug($"Successfully saved file '{track}'...");
                }
            }
            catch (Exception ex)
            {
                LoggerBundle.Error(ex);
            }
            finally
            {
                _buffer.Remove(track);
            }
        }
Example #12
0
        public IActionResult Login([FromBody] AuthenticationModel values)
        {
            try
            {
                LoggerBundle.Trace("Registered POST request on LoginsController.Login");

                //validate data
                String passwordBase64 = values?.Password;
                if (String.IsNullOrWhiteSpace(passwordBase64) || String.IsNullOrWhiteSpace(values.Username))
                {
                    LoggerBundle.Trace("Validation failed: empty username or password");
                    return(StatusCode((Int32)HttpStatusCode.Unauthorized));
                }

                // hash password
                Byte[] bPassword    = Convert.FromBase64String(passwordBase64);
                String password     = Encoding.UTF8.GetString(bPassword);
                String passwordHash = new Sha512HashPipe().Process(password);

                // normalize username
                values.Username = values.Username.Trim();

                // check database for given username
                User user;
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    user = dc.SetUsers.AsNoTracking().FirstOrDefault(x => x.Username.Equals(values.Username));
                }

                if (null == user)
                {
                    LoggerBundle.Trace($"No user found for given username '{values.Username}'");
                    return(StatusCode((Int32)HttpStatusCode.Unauthorized));
                }

                if (!user.Password.Equals(passwordHash))
                {
                    LoggerBundle.Trace($"Login attempt for user '{user.Username}' failed");
                    return(StatusCode((Int32)HttpStatusCode.Unauthorized));
                }

                // prepare token generation
                JwtPayload payload = UserJwtPayloadPipe.Process(user);
                return(ProcessPayload(payload));
            }
            catch (Exception ex)
            {
                LoggerBundle.Error(ex);
                return(StatusCode((Int32)HttpStatusCode.Unauthorized));
            }
        }
Example #13
0
        public IActionResult Create([FromBody] PlaylistModel model)
        {
            try
            {
                LoggerBundle.Trace("Registered PUT request on PlaylistsController.Create");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (model == null)
                {
                    LoggerBundle.Trace("Validation failed: model is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                String name = model.Name?.Trim();
                if (String.IsNullOrWhiteSpace(name) || name.Length < 3)
                {
                    LoggerBundle.Trace("Validation failed: invalid name");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    dc.SetUsers.Attach(AuthorizedUser);

                    Playlist playlist = new Playlist
                    {
                        CreateUser            = AuthorizedUser
                        , Name                = name
                        , PlaylistEntries     = new List <PlaylistEntry>()
                        , PlaylistPermissions = new List <PlaylistPermission>()
                    };
                    dc.SetPlaylists.Add(playlist);
                    dc.SaveChanges();

                    return(Ok(playlist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #14
0
        public IActionResult GetBySearchQuery(String query
                                              , [FromQuery(Name = "ps")] Int32 pageSize = 50
                                              , [FromQuery(Name = "p")] Int32 page      = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on RecordsController.GetBySearchQuery");
                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (String.IsNullOrWhiteSpace(query))
                {
                    LoggerBundle.Trace("Validation failed: empty query");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                NormalizePageSize(ref pageSize);
                query = query.Trim();

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetMusicBrainzRecords.AsNoTracking()
                              .Where(x => null != x.Title)
                              .Where(x => x.Title.Contains(query))
                              .Select(x => x.Title)
                              .OrderBy(x => x)
                              .Distinct()
                              .Skip(page * pageSize)
                              .Take(pageSize)
                              .Select(x => new Dictionary <String, Object>
                    {
                        {
                            "Title", x
                        }
                    })
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #15
0
        public IActionResult Delete(Int32?id)
        {
            try
            {
                LoggerBundle.Trace("Registered DELETE request on InviteController.Delete");
                if (!IsAuthorized(out IActionResult result, u => u.CanInvite))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (null == id)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Invite invite = dc.SetInvites.Include(x => x.CreateUser)
                                    .Include(x => x.RegisteredUser)
                                    .Where(x => x.CreateUser.CanInvite)
                                    .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId))
                                    .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == invite)
                    {
                        LoggerBundle.Trace($"No invite found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    if (null != invite.RegisteredUser)
                    {
                        LoggerBundle.Trace($"Invite with id '{id}' has already been used and can therefor not be deleted");
                        return(StatusCode((Int32)HttpStatusCode.Conflict));
                    }

                    dc.SetInvites.Remove(invite);
                    dc.SaveChanges();
                    return(Ok());
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #16
0
        public IActionResult GetById(Int32?id)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on PlaylistsController.GetById");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (id == null)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Playlist playlist = dc.SetPlaylists.AsNoTracking()
                                        .Include(x => x.CreateUser)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.Track)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.CreateUser)
                                        .Include(x => x.PlaylistPermissions)
                                        .ThenInclude(x => x.User)
                                        .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId) ||
                                               x.PlaylistPermissions.Any(y => y.User.UniqueId.Equals(AuthorizedUser.UniqueId)))
                                        .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == playlist)
                    {
                        LoggerBundle.Trace($"No playlist found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    return(Ok(playlist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #17
0
        public IActionResult Delete(Int32?id)
        {
            try
            {
                LoggerBundle.Trace("Registered DELETE request on PlaylistsController.Delete");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (!id.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Playlist playlist = dc.SetPlaylists.Include(x => x.PlaylistEntries)
                                        .Include(x => x.PlaylistPermissions)
                                        .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId))
                                        .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == playlist)
                    {
                        LoggerBundle.Trace($"No playlist found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    dc.SetPlaylistEntries.RemoveRange(playlist.PlaylistEntries);
                    dc.SetPlaylistPermissions.RemoveRange(playlist.PlaylistPermissions);
                    dc.SetPlaylists.Remove(playlist);
                    dc.SaveChanges();

                    return(Ok());
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #18
0
        private void ProcessBuffer(ref List <String> buffer, ref List <String> tracks)
        {
            LoggerBundle.Debug("Buffer full. Searching new entries...");
            List <String> newPaths      = buffer.Except(tracks).ToList();
            Int32         newPathsCount = newPaths.Count;

            LoggerBundle.Debug($"{newPathsCount} new files found");

            LoggerBundle.Debug("Saving to database...");
            Stopwatch sw = new Stopwatch();

            sw.Start();
            using (DataContext dataContext = DataContextFactory.GetInstance())
            {
                dataContext.ChangeTracker.AutoDetectChangesEnabled = false;
                // todo disable validation on save

                for (Int32 i = 0; i < newPathsCount; i++)
                {
                    dataContext.SetTracks.Add(new Track
                    {
                        Path = newPaths[i]
                    });
                    if (i % 1337 != 0)
                    {
                        continue;
                    }

                    dataContext.SaveChanges();
                    LoggerBundle.Trace($"Saved {i + 1}/{newPathsCount}...");
                }

                dataContext.SaveChanges();
            }

            sw.Stop();
            Int64 elms = sw.ElapsedMilliseconds;

            LoggerBundle.Debug($"Saved {newPathsCount} items in {elms}ms ({(Double) elms / newPathsCount}ms per item average)");

            tracks.AddRange(newPaths);
            buffer.Clear();
            LoggerBundle.Debug("Finished processing buffer. Returning.");
        }
Example #19
0
        public IActionResult Get()
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on GlobalsController.Get");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    return(Ok(new Dictionary <String, Object>
                    {
                        {
                            "Counts", new Dictionary <String, Object>
                            {
                                {
                                    "Tracks", dataContext.SetTracks.Count()
                                }
                                ,
                                {
                                    "Records", dataContext.SetMusicBrainzRecords.Count()
                                }
                                ,
                                {
                                    "Releases", dataContext.SetReleases.Count()
                                }
                                ,
                                {
                                    "Artists", dataContext.SetArtists.Count()
                                }
                            }
                        }
                    }));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #20
0
        public IActionResult GetByLookupQuery(String query
                                              , [FromQuery(Name = "ps")] Int32 pageSize = 50
                                              , [FromQuery(Name = "p")] Int32 page      = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on ArtistsController.GetByLookupQuery");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (String.IsNullOrWhiteSpace(query))
                {
                    LoggerBundle.Trace("Validation failed: empty query");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                NormalizePageSize(ref pageSize);
                query = query.Trim();

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetArtists.AsNoTracking()
                              .Where(x => x.Name.Equals(query))
                              .Include(x => x.MusicBrainzArtistMusicBrainzAliases)
                              .ThenInclude(x => x.MusicBrainzAlias)
                              .OrderBy(x => x.UniqueId)
                              .Skip(page * pageSize)
                              .Take(pageSize)
                              .Select(x => x.ToJsonDictionary())
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
        public IActionResult GetArtistsById(Int32?id
                                            , [FromQuery(Name = "ps")] Int32 pageSize = 50
                                            , [FromQuery(Name = "p")] Int32 page      = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on ReleasesController.GetArtistsById");
                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (id == null)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                NormalizePageSize(ref pageSize);

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetArtistCredits.AsNoTracking()
                              .FromSql(ReleaseQuery.GET_ARTISTS_BY_ID, id)
                              .Include(x => x.Artist)
                              .ThenInclude(x => x.MusicBrainzArtistMusicBrainzAliases)
                              .ThenInclude(x => x.MusicBrainzAlias)
                              .OrderBy(x => x.Name)
                              .Skip(page * pageSize)
                              .Take(pageSize)
                              .Select(x => x.ToJsonDictionary())
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #22
0
        public IActionResult GetById(Int32?id)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on ArtistsController.GetById");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (id == null)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    MusicBrainzArtist artist = dc.SetArtists.AsNoTracking()
                                               .Include(x => x.MusicBrainzArtistMusicBrainzAliases)
                                               .ThenInclude(x => x.MusicBrainzAlias)
                                               .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == artist)
                    {
                        LoggerBundle.Trace($"No artist found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    return(Ok(artist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #23
0
        public IActionResult GetBySearchQuery(String query
                                              , [FromQuery(Name = "ps")] Int32 pageSize = 50
                                              , [FromQuery(Name = "p")] Int32 page      = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on TracksController.GetBySearchQuery");
                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (String.IsNullOrWhiteSpace(query))
                {
                    LoggerBundle.Trace("Validation failed: empty query");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                NormalizePageSize(ref pageSize);
                query = query.Trim();
                query = $"%{query}%";

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetTracks.AsNoTracking()
                              .FromSql(TrackQuery.GET_TRACKS_LIKE_PATH, query)
                              .Skip(pageSize * page)
                              .Take(pageSize)
                              .Select(x => x.ToJsonDictionary())
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #24
0
        private void CleanInvisible()
        {
            List <Track> data;

            do
            {
                LoggerBundle.Inform("Removing invisible data");
                LoggerBundle.Debug("Getting data...");
                using (DataContext dataContext = DataContextFactory.GetInstance())
                {
                    data = dataContext.SetTracks.Where(x => null != x.LastAcoustIdApiCall).Where(x => 1 > x.AcoustIdResults.Count).OrderBy(x => x.UniqueId).Take(_config.BufferSize).ToList();

                    LoggerBundle.Inform($"Batch containing: {data.Count} entries");

                    foreach (Track track in data)
                    {
                        try
                        {
                            LoggerBundle.Debug($"Processing track '{track}'...");

                            if (File.Exists(track.Path))
                            {
                                File.Delete(track.Path);
                            }

                            dataContext.SetTracks.Remove(track);
                            dataContext.SaveChanges();

                            LoggerBundle.Trace("Processing done");
                        }
                        catch (Exception ex)
                        {
                            LoggerBundle.Error(ex);
                        }
                    }
                }
            }while (data.Count > 0);
        }
        public IActionResult GetAll([FromQuery(Name = "ps")] Int32 pageSize = 50, [FromQuery(Name = "p")] Int32 page = 0)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on ReleasesController.GetAll");
                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                NormalizePageSize(ref pageSize);

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    return(Ok(dc.SetReleases.AsNoTracking()
                              .Where(x => null != x.Title)
                              .Select(x => x.Title)
                              .OrderBy(x => x)
                              .Distinct()
                              .Skip(page * pageSize)
                              .Take(pageSize)
                              .Select(x => new Dictionary <String, Object>
                    {
                        {
                            "Title", x
                        }
                    })
                              .ToList()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #26
0
        public IActionResult DeletePermission(Int32?playlistId, Int32?permissionId)
        {
            try
            {
                LoggerBundle.Trace("Registered DELETE request on PlaylistsController.DeletePermission");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (!playlistId.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: playlist id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (!permissionId.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: permission id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Playlist playlist = dc.SetPlaylists.Include(x => x.CreateUser)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.Track)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.CreateUser)
                                        .Include(x => x.PlaylistPermissions)
                                        .ThenInclude(x => x.User)
                                        .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId))
                                        .FirstOrDefault(x => x.UniqueId.Equals(playlistId));

                    if (null == playlist)
                    {
                        LoggerBundle.Trace($"Validation failed: no playlist found for given id '{playlistId}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    PlaylistPermission entry =
                        playlist.PlaylistPermissions.FirstOrDefault(x => x.UniqueId.Equals(permissionId));

                    if (null == entry)
                    {
                        LoggerBundle.Trace($"Validation failed: no entry found in playlist for given id '{permissionId}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    dc.SetPlaylistPermissions.Remove(entry);
                    dc.SaveChanges();

                    return(Ok(playlist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #27
0
        public IActionResult GetRecordsById(Int32?id)
        {
            try
            {
                LoggerBundle.Trace("Registered GET request on TracksController.GetRecordsById");
                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (id == null)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Track track = dc.SetTracks.AsNoTracking()
                                  .Include(x => x.AcoustIdResults)
                                  .ThenInclude(x => x.AcoustId)
                                  .ThenInclude(x => x.MusicBrainzRecordAcoustIds)
                                  .ThenInclude(x => x.MusicBrainzRecord)
                                  .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == track)
                    {
                        LoggerBundle.Trace($"No track found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    // todo might need optimization with a direct database sql query

                    // loop references and keep track of relevant stats
                    Dictionary <MusicBrainzRecord, (Int32 count, Double sum)> ret =
                        new Dictionary <MusicBrainzRecord, (Int32, Double)>();

                    track.AcoustIdResults.ForEach(x =>
                    {
                        Double score = x.Score;
                        x.AcoustId.MusicBrainzRecordAcoustIds.ForEach(y =>
                        {
                            MusicBrainzRecord record = y.MusicBrainzRecord;
                            if (!ret.ContainsKey(record))
                            {
                                ret.Add(record, (1, score));
                                return; // continue
                            }

                            ret[record] = (ret[record].count + 1, ret[record].sum + score);
                        });
                    });

                    return(Ok(ret.Select(x => new Dictionary <String, Object>
                    {
                        {
                            "Score", x.Value.sum / x.Value.count
                        }
                        , // calculate match score (average)
                        {
                            "Record", x.Key.ToJsonDictionary()
                        }
                    })));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #28
0
        public IActionResult CreatePermission(Int32?id, [FromBody] PlaylistPermissionModel model)
        {
            try
            {
                LoggerBundle.Trace("Registered PUT request on PlaylistsController.CreatePermission");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (!id.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (null == model)
                {
                    LoggerBundle.Trace("Validation failed: model is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                Int32?userId = model.UserId;
                if (!userId.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: user identifier is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    User user = dc.SetUsers.FirstOrDefault(x => x.UniqueId.Equals(userId));
                    if (null == user)
                    {
                        LoggerBundle.Trace($"Validation failed: no user found for given id '{userId}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    Playlist playlist = dc.SetPlaylists.Include(x => x.CreateUser)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.Track)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.CreateUser)
                                        .Include(x => x.PlaylistPermissions)
                                        .ThenInclude(x => x.User)
                                        .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId))
                                        .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == playlist)
                    {
                        LoggerBundle.Trace($"Validation failed: no playlist found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    PlaylistPermission userPermission =
                        playlist.PlaylistPermissions.FirstOrDefault(x => x.User.UniqueId.Equals(userId));
                    if (null != userPermission)
                    {
                        // already exists
                        if (userPermission.CanModify != model.CanModify)
                        {
                            userPermission.CanModify = model.CanModify;
                            dc.SaveChanges();
                        }

                        return(Ok(playlist.ToJsonDictionary()));
                    }

                    userPermission = new PlaylistPermission
                    {
                        Playlist    = playlist
                        , CanModify = model.CanModify
                        , User      = user
                    };

                    dc.SetPlaylistPermissions.Add(userPermission);
                    dc.SaveChanges();

                    return(Ok(playlist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #29
0
        public IActionResult CreateEntry(Int32?id, [FromBody] PlaylistEntryModel model)
        {
            try
            {
                LoggerBundle.Trace("Registered PUT request on PlaylistsController.CreateEntry");

                if (!IsAuthorized(out IActionResult result))
                {
                    LoggerBundle.Trace("Request not authorized");
                    return(result);
                }

                // validate
                if (!id.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: id is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (null == model)
                {
                    LoggerBundle.Trace("Validation failed: model is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                Int32?trackId = model.TrackId;
                if (!trackId.HasValue)
                {
                    LoggerBundle.Trace("Validation failed: track identifier is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                String title = model.Title?.Trim();
                if (String.IsNullOrWhiteSpace(title))
                {
                    LoggerBundle.Trace("Validation failed: invalid title");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                // get data
                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    dc.SetUsers.Attach(AuthorizedUser);

                    Track track = dc.SetTracks.FirstOrDefault(x => x.UniqueId.Equals(trackId));
                    if (null == track)
                    {
                        LoggerBundle.Trace($"Validation failed: no track found for given id '{trackId}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    Playlist playlist = dc.SetPlaylists.Include(x => x.CreateUser)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.Track)
                                        .Include(x => x.PlaylistEntries)
                                        .ThenInclude(x => x.CreateUser)
                                        .Include(x => x.PlaylistPermissions)
                                        .ThenInclude(x => x.User)
                                        .Where(x => x.CreateUser.UniqueId.Equals(AuthorizedUser.UniqueId) ||
                                               x.PlaylistPermissions.Any(y => y.User.UniqueId.Equals(AuthorizedUser.UniqueId) && y.CanModify))
                                        .FirstOrDefault(x => x.UniqueId.Equals(id));

                    if (null == playlist)
                    {
                        LoggerBundle.Trace($"Validation failed: no playlist found for given id '{id}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    PlaylistEntry entry = new PlaylistEntry
                    {
                        CreateUser = AuthorizedUser
                        , Title    = title
                        , Track    = track
                        , Playlist = playlist
                    };
                    dc.SetPlaylistEntries.Add(entry);
                    dc.SaveChanges();

                    return(Ok(playlist.ToJsonDictionary()));
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }
Example #30
0
        public IActionResult Use(String token, [FromBody] InviteModel model)
        {
            try
            {
                LoggerBundle.Trace("Registered POST request on InviteController.Use");

                // validate
                if (null == token)
                {
                    LoggerBundle.Trace("Validation failed: token is null");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (null == model)
                {
                    LoggerBundle.Trace("Validation failed: model is undefined");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                String passwordBase64 = model.Password?.Trim();
                if (String.IsNullOrWhiteSpace(passwordBase64))
                {
                    LoggerBundle.Trace("Validation failed: password is empty");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                String username = model.Username?.Trim();
                if (String.IsNullOrWhiteSpace(username))
                {
                    LoggerBundle.Trace("Validation failed: username is empty");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                Byte[] bPassword = Convert.FromBase64String(passwordBase64);
                String password  = Encoding.UTF8.GetString(bPassword);

                if (password.Length < 8)
                {
                    LoggerBundle.Trace("Validation failed: password needs to be at least 8 characters long");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (!new Regex("[0-9]").IsMatch(password))
                {
                    LoggerBundle.Trace("Validation failed: password must contain at least one number");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (!new Regex("[a-zA-Z]").IsMatch(password))
                {
                    LoggerBundle.Trace("Validation failed: password must contain at least one letter");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                if (!new Regex("[^a-zA-Z0-9]").IsMatch(password))
                {
                    LoggerBundle.Trace("Validation failed: password must contain at least one special character");
                    return(StatusCode((Int32)HttpStatusCode.BadRequest));
                }

                using (DataContext dc = DataContextFactory.GetInstance())
                {
                    Invite invite = dc.SetInvites.Include(x => x.CreateUser)
                                    .Include(x => x.RegisteredUser)
                                    .Where(x => x.CreateUser.CanInvite)
                                    .FirstOrDefault(x => x.Token.Equals(token));

                    if (null == invite)
                    {
                        LoggerBundle.Trace($"No invite found for given token '{token}'");
                        return(StatusCode((Int32)HttpStatusCode.NotFound));
                    }

                    if (null != invite.RegisteredUser)
                    {
                        LoggerBundle.Trace($"Invite with token '{token}' has already been used");
                        return(StatusCode((Int32)HttpStatusCode.Conflict));
                    }

                    if (invite.ExpirationDate < DateTime.Now)
                    {
                        LoggerBundle.Trace($"Invite with token '{token}' has expired");
                        return(StatusCode((Int32)HttpStatusCode.BadRequest));
                    }

                    String passwordHash = new Sha512HashPipe().Process(password);

                    User newUser = new User
                    {
                        Password    = passwordHash
                        , Username  = username
                        , CanInvite = false
                        , Invite    = invite
                    };

                    dc.SetUsers.Add(newUser);
                    dc.SaveChanges();
                    return(Ok());
                }
            }
            catch (Exception ex)
            {
                return(HandleException(ex));
            }
        }