Esempio n. 1
0
        /// <summary>Creates the specified MDB.</summary>
        /// <param name="mdb">The MDB.</param>
        /// <param name="streamID">The stream identifier.</param>
        /// <param name="ownerID">The owner identifier (+user / -session / +subset).</param>
        /// <param name="subsetID">The subset identifier.</param>
        /// <param name="startTime">The start time.</param>
        /// <param name="audioFile">The audio file.</param>
        /// <returns></returns>
        public static MDBNowPlaying Create(MusicDataBase mdb, long streamID, long ownerID, long subsetID, DateTime startTime, MDBAudioFile audioFile)
        {
            var albumArtist = mdb.Artists.TryGetStruct(audioFile.AlbumArtistID);
            var artist      = mdb.Artists.TryGetStruct(audioFile.SongArtistID);
            var album       = mdb.Albums.TryGetStruct(audioFile.AlbumID);
            var genre       = mdb.Genres.TryGetStruct(audioFile.GenreID);
            var tag         = mdb.Tags.TryGetStruct(audioFile.TagID);

            return(new MDBNowPlaying()
            {
                StreamID = streamID,
                OwnerID = ownerID,
                SubsetID = subsetID,
                AudioFileID = audioFile.FileID,
                Duration = audioFile.Duration,
                StartDateTime = startTime,
                Title = audioFile.Title,
                ArtistName = artist.Name,
                AlbumArtistName = albumArtist.Name,
                AlbumName = album.Name,
                Genre = genre.Name,
                Genres = audioFile.Genres,
                Tag = tag.Name,
                Tags = audioFile.Tags,
            });
        }
Esempio n. 2
0
        internal static MDBOverview Create(MusicDataBase mdb, WebServer server)
        {
            double   fileSize          = mdb.Files.Sum(nameof(MDBFile.Size));
            double   audioFilesSize    = mdb.Files.Sum(nameof(MDBFile.Size), Search.FieldEquals(nameof(MDBFile.FileType), MDBFileType.mp3));
            double   imageFilesSize    = mdb.Files.Sum(nameof(MDBFile.Size), !Search.FieldEquals(nameof(MDBFile.FileType), MDBFileType.mp3) & !Search.FieldEquals(nameof(MDBFile.FileType), MDBFileType.unknown));
            TimeSpan audiofileDuration = TimeSpan.FromSeconds(Convert.ToDouble(mdb.AudioFiles.Sum(nameof(MDBAudioFile.Duration))));

            return(new MDBOverview()
            {
                ID = 1 + Math.Abs(mdb.Files.SequenceNumber),
                LastUpdate = DateTime.Now,
                Version = server.ServerVersionString,
                AlbumCount = mdb.Albums.RowCount,
                ArtistCount = mdb.Artists.RowCount,
                AudioDataSize = (long)audioFilesSize,
                AudioDataSizeString = audioFilesSize.FormatSize(),
                AudioFileCount = mdb.AudioFiles.RowCount,
                Duration = audiofileDuration,
                DurationString = audiofileDuration.FormatTime(),
                FileCount = mdb.Files.RowCount,
                GenreCount = mdb.Genres.RowCount,
                ImageCount = mdb.Images.RowCount,
                ImageDataSize = (long)imageFilesSize,
                ImageDataSizeString = imageFilesSize.FormatSize(),
                TagCount = mdb.Tags.RowCount,
            });
        }
Esempio n. 3
0
 void SetFtpMusicFolders(MusicDataBase mdb, FtpServer ftpServer)
 {
     lock (ftpServer.RootFolders)
     {
         ftpServer.RootFolders.Clear();
         foreach (var dir in mdb.MusicFolders)
         {
             try
             {
                 FileSystem.GetFileSystemEntries(dir);
                 string name         = Path.GetFileNameWithoutExtension(dir);
                 int    i            = 0;
                 string selectedName = name;
                 while (!ftpServer.RootFolders.TryAdd(selectedName, dir))
                 {
                     selectedName = name + (++i);
                 }
                 this.LogDebug("Added root <cyan>{0}<default> {1}", selectedName, dir);
             }
             catch (Exception ex)
             {
                 this.LogWarning(ex, "Cannot access folder {0}", dir);
             }
         }
         ftpServer.DisconnectAllClients();
     }
 }
Esempio n. 4
0
 MDBOverview GetOverview(MusicDataBase mdb, WebServer server)
 {
     if (cachedOverview.ID != Math.Abs(mdb.Files.SequenceNumber) + 1)
     {
         cachedOverview = MDBOverview.Create(mdb, server);
     }
     return(cachedOverview);
 }
Esempio n. 5
0
 /// <summary>Gets the full path.</summary>
 /// <param name="mdb">The MDB.</param>
 /// <param name="fileName">Name of the file.</param>
 /// <returns></returns>
 /// <exception cref="System.IO.DirectoryNotFoundException">Parent Folder missing!</exception>
 public string GetFullPath(MusicDataBase mdb, string fileName)
 {
     if (fileName == null)
     {
         throw new ArgumentNullException("fileName");
     }
     return(FileSystem.Combine(Name, fileName));
 }
        /// <summary>Loads the specified <see cref="MDBPlayListItem"/>.</summary>
        /// <param name="mdb">The <see cref="MusicDataBase"/> instance.</param>
        /// <param name="item">The <see cref="MDBPlayListItem"/>.</param>
        /// <returns></returns>
        public static MDBFileSelection Load(MusicDataBase mdb, MDBPlayListItem item)
        {
            var result = new MDBFileSelection();

            result.AudioFile    = mdb.AudioFiles.TryGetStruct(item.AudioFileID);
            result.File         = mdb.Files.TryGetStruct(result.AudioFile.FileID);
            result.NowPlaying   = MDBNowPlaying.Create(mdb, item.StreamID, item.OwnerID, item.SubsetID, DateTime.MinValue, result.AudioFile);
            result.PlayListItem = item;
            return(result);
        }
Esempio n. 7
0
 /// <summary>
 /// Gets the full path of the file
 /// </summary>
 /// <param name="mdb">The mdb instance</param>
 /// <returns></returns>
 public string GetFullPath(MusicDataBase mdb)
 {
     if (FolderID == 0)
     {
         if (ReferenceEquals(Extension, null))
         {
             return(Name);
         }
         return(Name + Extension);
     }
     return(mdb.Folders.GetStruct(FolderID).GetFullPath(mdb, Name + Extension));
 }
Esempio n. 8
0
        /// <summary>Loads the specified album.</summary>
        /// <param name="mdb">The MDB.</param>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public static RPCAlbum Load(MusicDataBase mdb, MDBAlbum album)
        {
            MDBArtist artist = mdb.Artists.GetStruct(album.ArtistID);
            var       files  = mdb.AudioFiles.GetStructs(nameof(MDBAudioFile.AlbumID), album.ID);
            var       result = new RPCAlbum()
            {
                ID         = album.ID,
                Name       = album.Name,
                ArtistID   = artist.ID,
                ArtistName = artist.Name,
                Duration   = new TimeSpan(files.Sum(f => f.Duration.Ticks)),
                Tags       = files.SelectMany(f => f.TagNames).Distinct().Join(";"),
                Genres     = files.SelectMany(f => f.GenreNames).Distinct().Join(";"),
                TrackCount = files.Count,
                Errors     = (MDBMetaErrors)files.BinaryOr(f => (long)f.MetaErrors),
            };

            return(result);
        }
Esempio n. 9
0
        /// <summary>Loads the artist from the specified MusicDataBase tables.</summary>
        /// <param name="mdb">The MusicDataBase.</param>
        /// <param name="artist">The artist.</param>
        /// <returns>Returns a new <see cref="RPCArtist"/> instance</returns>
        public static RPCArtist Load(MusicDataBase mdb, MDBArtist artist)
        {
            var files = mdb.AudioFiles.GetStructs(
                Search.FieldEquals(nameof(MDBAudioFile.SongArtistID), artist.ID) |
                Search.FieldEquals(nameof(MDBAudioFile.AlbumArtistID), artist.ID));

            var result = new RPCArtist()
            {
                ID         = artist.ID,
                Name       = artist.Name,
                Errors     = (MDBMetaErrors)files.BinaryOr(f => (long)f.MetaErrors),
                TitleCount = files.Count,
                Tags       = files.SelectMany(f => f.TagNames).Distinct().Join(";"),
                Genres     = files.SelectMany(f => f.GenreNames).Distinct().Join(";"),
                Duration   = new TimeSpan(files.Sum(f => f.Duration.Ticks)),
            };

            result.AlbumCount = mdb.Albums.Count(nameof(MDBAlbum.ArtistID), artist.ID);
            return(result);
        }
Esempio n. 10
0
        /// <summary>Loads the dataset using the specified MDB instance.</summary>
        /// <param name="mdb">The MDB.</param>
        /// <param name="file">The file.</param>
        /// <returns></returns>
        public static RPCAudioFile Load(MusicDataBase mdb, MDBAudioFile file)
        {
            MDBArtist   albumArtist, titleArtist;
            MDBAlbum    album;
            MDBCategory category;
            MDBGenre    genre;
            MDBTag      tag;

            mdb.Artists.TryGetStruct(file.AlbumArtistID, out albumArtist);
            mdb.Artists.TryGetStruct(file.SongArtistID, out titleArtist);
            mdb.Albums.TryGetStruct(file.AlbumID, out album);
            mdb.Categories.TryGetStruct(file.CategoryID, out category);
            mdb.Genres.TryGetStruct(file.GenreID, out genre);
            mdb.Tags.TryGetStruct(file.TagID, out tag);
            return(new RPCAudioFile()
            {
                AlbumID = album.ID,
                AlbumName = album.Name,
                AlbumArtistID = albumArtist.ID,
                AlbumArtistName = albumArtist.Name,
                TitleArtistID = titleArtist.ID,
                TitleArtistName = titleArtist.Name,
                AudioFileID = file.FileID,
                Category = category.Name,
                Duration = file.Duration,
                Errors = file.Errors,
                Genre = genre.Name,
                Genres = file.Genres,
                MetaErrors = file.MetaErrors,
                RecordingDate = file.RecordingDate,
                Tag = tag.Name,
                Tags = file.Tags,
                TrackCount = file.TrackCount,
                TrackNumber = file.TrackNumber,
                Title = file.Title,
            });
        }
Esempio n. 11
0
        /// <summary>Initializes a new instance of the <see cref="WebInterface" /> class.</summary>
        /// <param name="mdb">The MusicDataBase instance.</param>
        /// <param name="authTables">The authentication tables.</param>
        /// <param name="player">The player.</param>
        /// <exception cref="System.ArgumentNullException">
        /// mdb
        /// or
        /// authTables
        /// </exception>
        /// <exception cref="ArgumentNullException">mdb
        /// or
        /// player</exception>
        public WebInterface(MusicDataBase mdb, AuthTables authTables, IPlayer player)
        {
            FileCrawler = new FileCrawler(mdb);
            ArtCrawler  = new ArtCrawler(mdb);

            this.mdb        = mdb ?? throw new ArgumentNullException(nameof(mdb));
            this.authTables = authTables ?? throw new ArgumentNullException(nameof(authTables));
            this.player     = player ?? throw new ArgumentNullException(nameof(player));

            EmptyImage = WebImage.FromFile(FileSystem.Combine(mdb.WebFolder, "images", "empty.png"), mdb.CacheFolder);
            this.LogInfo("Loading album replacement images...");
            ReplaceAlbumImages = Directory.GetFiles(FileSystem.Combine(mdb.WebFolder, "images"), "cd-??.png").Select(f => WebImage.FromFile(f, mdb.CacheFolder)).ToArray();
            if (ReplaceAlbumImages.Length == 0)
            {
                ReplaceAlbumImages = new WebImage[] { WebImage.FromFile(FileSystem.Combine(mdb.WebFolder, "images", "no-image.png"), mdb.CacheFolder) };
            }

            this.LogInfo("Loading artist replacement images...");
            ReplaceArtistImages = Directory.GetFiles(FileSystem.Combine(mdb.WebFolder, "images"), "artist-??.png").Select(f => WebImage.FromFile(f, mdb.CacheFolder)).ToArray();
            if (ReplaceArtistImages.Length == 0)
            {
                ReplaceArtistImages = new WebImage[] { WebImage.FromFile(FileSystem.Combine(mdb.WebFolder, "images", "no-image.png"), mdb.CacheFolder) };
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MDBAudioFileSelector"/> class.
 /// </summary>
 /// <param name="mdb">The MDB.</param>
 public MDBAudioFileSelector(MusicDataBase mdb)
 {
     this.mdb = mdb;
     rnd      = new Random();
 }
Esempio n. 13
0
 public DesktopPlayer(MusicDataBase mdb, long streamID)
 {
     this.mdb = mdb;
     selector = new MDBAudioFileSelector(mdb);
     StreamID = streamID;
 }
Esempio n. 14
0
 public ArtCrawler(MusicDataBase mdb)
 {
     this.mdb = mdb;
 }
Esempio n. 15
0
 /// <summary>Loads the dataset using the specified MDB instance.</summary>
 /// <param name="mdb">The MDB.</param>
 /// <param name="audioFileID">The audio file identifier.</param>
 /// <returns></returns>
 public static RPCAudioFile Load(MusicDataBase mdb, long audioFileID)
 {
     return(Load(mdb, mdb.AudioFiles[audioFileID]));
 }
Esempio n. 16
0
 /// <summary>Initializes a new instance of the <see cref="MDBBroadcaster"/> class.</summary>
 /// <param name="mdb">The MDB.</param>
 public MDBBroadcaster(MusicDataBase mdb)
 {
     this.mdb = mdb;
 }
Esempio n. 17
0
        protected override void Worker()
        {
            if (LogConsole != null)
            {
                LogConsole.ExceptionMode = LogExceptionMode.Full;
                LogConsole.Flags        |= LogConsoleFlags.DisplayTimeStamp;
                LogConsole.Mode          = LogReceiverMode.Opportune;
            }

            Logger.DebugReceiver?.Close();

            //init the async mysql connection class we want to use.
            //new MySql.Data.MySqlClient.MySqlConnection().Dispose();

            WebServer      webServer   = null;
            FtpServer      ftpServer   = null;
            MusicDataBase  mdb         = null;
            MDBBroadcaster broadcaster = null;
            DesktopPlayer  player      = null;

            try
            {
                var rootFolder = FileSystem.ProgramDirectory;
                webServer = new WebServer();
                mdb       = new MusicDataBase(rootFolder);
                if (LogSystem != null)
                {
                    //allow user to override loglevel by commandline
                    if (LogSystem.Level == LogLevel.Information)
                    {
                        LogSystem.Level = mdb.Config.ReadEnum <LogLevel>("MusicDataBase", "LogLevel", LogLevel.Information);
                    }
                }

                this.LogInfo("Loading Database...");
                mdb.Load();

                MemoryStorage.Default.LogVerboseMessages = LogSystem?.Level == LogLevel.Verbose;
                if (null != mdb.Database)
                {
                    mdb.Database.Storage.LogVerboseMessages = MemoryStorage.Default.LogVerboseMessages;
                }

                if (mdb.Config.ReadBool("MusicDataBase", "ClearDatabase", false))
                {
                    foreach (ITable t in mdb.Tables)
                    {
                        t.Clear();
                    }
                }

                mdb.Save();

                this.LogInfo("Loading auth tables...");
                if (mdb.Database != null)
                {
                    webServer.AuthTables.Connect(TableConnectorMode.Direct, mdb.Database);
                }
                else
                {
                    try
                    {
                        webServer.AuthTables.Load(mdb.DataBasePath);
                    }
                    catch (Exception ex)
                    {
                        this.LogWarning(ex, "Load auth tables failed. Recreating...");
                    }
                }
                authTables = webServer.AuthTables;

                var authInterface = new AuthInterface <MDBUserLevel>(webServer);
                {
                    //auth interface
                    User admin = webServer.AuthTables.CheckAdminPresent();
                    if (mdb.Config.ReadBool("MusicDataBase", "LocalhostIsAdmin", false))
                    {
                        authInterface.DefaultLocalhostUser = admin;
                    }
                }

                this.LogInfo("Initializing FtpServer...");
                ftpServer             = new FtpServer();
                ftpServer.CheckLogin += this.FtpServerCheckLogin;
                //add music dirs to ftp server
                SetFtpMusicFolders(mdb, ftpServer);

                int ftpPort = mdb.Config.ReadInt32("FtpServer", "Port", 8021);
                ftpServer.Listen(ftpPort);

                player = new DesktopPlayer(mdb, (long)MDBStreamType.JukeBob);
                player.Start();

                this.LogInfo("Initializing WebServer...");
                webServer.SessionMode       = WebServerSessionMode.Cookie;
                webServer.SessionTimeout    = TimeSpan.FromDays(1);
                webServer.PerformanceChecks = mdb.Config.ReadBool("WebServer", "PerformanceChecks", false);
                webServer.EnableExplain     = mdb.Config.ReadBool("WebServer", "Explain", false);
                webServer.TransmitLayout    = false;
                webServer.EnableTemplates   = true;
                webServer.CheckAccess      += WebServerCheckAccess;
                webServer.StaticFilesPath   = mdb.WebFolder;

                //prepare rpc
                var avatarFolder = mdb.GetFolderConfig("MusicDataBase", "AvatarFolder", "avatar");
                webServer.Register(new AvatarInterface(avatarFolder));
                webServer.Register(authInterface);
                var webInterface = new WebInterface(mdb, webServer.AuthTables, player);

                webInterface.LogCollector.Level            = LogLevel.Debug;
                webInterface.LogCollector.MaximumItemCount = 1000;
                webInterface.LogCollector.ExceptionMode    = LogExceptionMode.Full;

                webServer.Register(webInterface);
                webServer.Register(new HostInterface(this));

                //start server
                int webPort = mdb.Config.ReadInt32("WebServer", "Port", 8080);
                webServer.Listen(webPort);

                mdb.SetHostConfiguration(Environment.UserName + "." + Environment.MachineName, webPort, ftpPort, mdb.GetLocalAddresses());

                //using (Streamer streamer = new Streamer(mdb, MDBStreamType.JukeBox))
                broadcaster = new MDBBroadcaster(mdb);
                broadcaster.Start();

                if (mdb.Config.ReadBool("Crawler", "RunAtStartup", false))
                {
                    webInterface.FileCrawler.Start();
                }

                //main loop
                this.LogNotice("Entering main loop...");
                while (!ServiceParameters.Shutdown)
                {
                    ServiceParameters.WaitForShutdown(1000);
                    //SetConsoleTitle();
                }
            }
            finally
            {
                //cleanup
                broadcaster?.Dispose();
                ftpServer?.Close();
                player?.Stop();
                player?.Dispose();
                authTables?.Save();
                authTables = null;
                mdb?.Save();
                webServer?.Close();
            }
            this.LogInfo("Shutdown completed.");
            Logger.Flush();
        }