Example #1
0
        public IActionResult SearchByHistory([FromBody] HistorySong historySong)
        {
            try
            {
                using AvailableSongContext availableSongContext = CreateAvailableSongContext(out DbSet <AvailableSong> availableSongs);

                // ID で検索
                AvailableSong?result = availableSongs.SingleOrDefault(x => x.Id == historySong.AvailableSongId);
                if (result == null)
                {
                    // フルパスで検索
                    // 実際の運用時は外部アプリケーションが予約可能曲データベースを作成することが想定され、AvailableSongId が変更されている場合も想定されるため、パスでも検索する
                    result = availableSongs.FirstOrDefault(x => x.Path == historySong.Path);
                }
                if (result == null)
                {
                    // ファイル名で検索
                    result = availableSongs.FirstOrDefault(x => EF.Functions.Like(x.Path, $"%\\{Path.GetFileName(historySong.Path)}%"));
                }

                if (result == null)
                {
                    return(NotAcceptable());
                }
                return(File(JsonSerializer.SerializeToUtf8Bytes(result), ServerConstants.MIME_TYPE_JSON));
            }
            catch (Exception excep)
            {
                Debug.WriteLine("曲履歴検索サーバーエラー:\n" + excep.Message);
                Debug.WriteLine(" スタックトレース:\n" + excep.StackTrace);
                return(InternalServerError());
            }
        }
Example #2
0
        public IActionResult GetThumbnail(String?id)
        {
            try
            {
                using AvailableSongContext availableSongContext = CreateAvailableSongContext(out DbSet <AvailableSong> availableSongs);
                AvailableSong?availableSong = availableSongs.SingleOrDefault(x => x.Id == id);
                if (availableSong == null)
                {
                    // ID が見つからない
                    return(NotAcceptable());
                }

                using ThumbnailContext thumbnailContext = CreateThumbnailContext(out DbSet <Thumbnail> thumbnails);
                Thumbnail?thumbnail = thumbnails.FirstOrDefault(x => x.Path == availableSong.Path);
                if (thumbnail == null)
                {
                    // ID に対応するサムネイルが無い
                    thumbnail = DefaultThumbnail;
                    if (thumbnail == null)
                    {
                        throw new Exception();
                    }
                }

                // キャッシュチェック
                if (IsEntityTagValid(thumbnail.LastModified))
                {
                    Debug.WriteLine("GetThumbnail() キャッシュ有効: " + id);
                    return(NotModified());
                }

                // 実際の運用時はサムネイルの返却に時間がかかることを想定
                Random random = new();
                Thread.Sleep(random.Next(500, 1000));

                Debug.WriteLine("GetThumbnail() キャッシュ無し: " + id);
                DateTimeOffset       lastModified = new DateTimeOffset(YbdCommon.ModifiedJulianDateToDateTime(thumbnail.LastModified));
                EntityTagHeaderValue eTag         = GenerateEntityTag(thumbnail.LastModified);
                return(File(thumbnail.Bitmap, thumbnail.Mime, lastModified, eTag));
            }
            catch (Exception excep)
            {
                Debug.WriteLine("サムネイル取得サーバーエラー:\n" + excep.Message);
                Debug.WriteLine(" スタックトレース:\n" + excep.StackTrace);
                return(InternalServerError());
            }
        }
Example #3
0
 public IActionResult SearchById(String?id)
 {
     try
     {
         using AvailableSongContext availableSongContext = CreateAvailableSongContext(out DbSet <AvailableSong> availableSongs);
         AvailableSong?result = availableSongs.SingleOrDefault(x => x.Id == id);
         if (result == null)
         {
             return(NotAcceptable());
         }
         return(File(JsonSerializer.SerializeToUtf8Bytes(result), ServerConstants.MIME_TYPE_JSON));
     }
     catch (Exception excep)
     {
         Debug.WriteLine("曲 ID 検索サーバーエラー:\n" + excep.Message);
         Debug.WriteLine(" スタックトレース:\n" + excep.StackTrace);
         return(InternalServerError());
     }
 }
Example #4
0
        // ====================================================================
        // API(ApiController)
        // ====================================================================

        // --------------------------------------------------------------------
        // 状態を返す
        // --------------------------------------------------------------------
        public override String ControllerStatus()
        {
            String status;

            try
            {
                using AvailableSongContext availableSongContext = CreateAvailableSongContext(out DbSet <AvailableSong> availableSongs);
#if DEBUG
                Thread.Sleep(1000);
#endif

                // FirstOrDefault を使用すると列の不足を検出できる
                availableSongs.FirstOrDefault(x => x.Id == String.Empty);

                status = "正常 / 曲数:" + availableSongs.Count();
            }
            catch (Exception excep)
            {
                status = "エラー / " + excep.Message;
                Debug.WriteLine("検索 API 状態取得サーバーエラー:\n" + excep.Message);
                Debug.WriteLine(" スタックトレース:\n" + excep.StackTrace);
            }
            return(status);
        }
Example #5
0
        public IActionResult SearchByWord(String?query)
        {
            try
            {
                // キャッシュチェック
                DateTime lastModified = ServerCommon.LastModified(ServerConstants.FILE_NAME_AVAILABLE_SONGS);
                if (IsEntityTagValid(YbdCommon.DateTimeToModifiedJulianDate(lastModified)))
                {
                    Debug.WriteLine("SearchByWord() キャッシュ有効: " + query);
                    return(NotModified());
                }

                SearchWord searchWord = new SearchWord(query);
                if (!searchWord.IsValid(out String? errorMessage))
                {
                    return(BadRequest());
                }

                using AvailableSongContext availableSongContext = CreateAvailableSongContext(out DbSet <AvailableSong> availableSongs);
                IQueryable <AvailableSong> searchResults = availableSongs;
                if (searchWord.Type == SearchWordType.AnyWord)
                {
                    // なんでも検索
                    String[] anyWords = SplitKeyword(searchWord.AnyWord);
                    for (Int32 i = 0; i < anyWords.Length; i++)
                    {
                        searchResults = SearchByAnyWord(searchResults, anyWords[i]);
                    }
                }
                else
                {
                    // 曲名
                    // ToDo: SearchBySongName() を関数化すると実行できるが、地の文にすると例外が発生する
                    String[] songNames = SplitKeyword(searchWord.SongName);
                    for (Int32 i = 0; i < songNames.Length; i++)
                    {
                        searchResults = SearchBySongName(searchResults, songNames[i]);
                    }

                    // タイアップ名
                    String[] tieUpNames = SplitKeyword(searchWord.TieUpName);
                    for (Int32 i = 0; i < tieUpNames.Length; i++)
                    {
                        searchResults = SearchByTieUpName(searchResults, tieUpNames[i]);
                    }

                    // 歌手名
                    String[] artistNames = SplitKeyword(searchWord.ArtistName);
                    for (Int32 i = 0; i < artistNames.Length; i++)
                    {
                        searchResults = SearchByArtistName(searchResults, artistNames[i]);
                    }

                    // 制作会社
                    String[] makers = SplitKeyword(searchWord.MakerName);
                    for (Int32 i = 0; i < makers.Length; i++)
                    {
                        searchResults = SearchByMaker(searchResults, makers[i]);
                    }

                    // カラオケ動画制作者
                    String[] workers = SplitKeyword(searchWord.Worker);
                    for (Int32 i = 0; i < workers.Length; i++)
                    {
                        searchResults = SearchByWorker(searchResults, workers[i]);
                    }

                    // ファイル名
                    String[] pathes = SplitKeyword(searchWord.Path);
                    for (Int32 i = 0; i < pathes.Length; i++)
                    {
                        searchResults = SearchByPath(searchResults, pathes[i]);
                    }
                }

                // 追加ヘッダー
                AddTotalCountToHeader(searchResults.Count());

                // 検索結果は AvailableSongContext の寿命と共に尽きるようなので、ToArray() で新しいコンテナに格納する
                AvailableSong[]      results = SortSearchResult(searchResults, searchWord.Sort).Skip(YbdConstants.PAGE_SIZE * searchWord.Page).Take(YbdConstants.PAGE_SIZE).ToArray();
                EntityTagHeaderValue eTag    = GenerateEntityTag(YbdCommon.DateTimeToModifiedJulianDate(lastModified));
                return(File(JsonSerializer.SerializeToUtf8Bytes(results), ServerConstants.MIME_TYPE_JSON, lastModified, eTag));
            }
            catch (Exception excep)
            {
                Debug.WriteLine("キーワード検索サーバーエラー:\n" + excep.Message);
                Debug.WriteLine(" スタックトレース:\n" + excep.StackTrace);
                return(InternalServerError());
            }
        }