Exemple #1
0
        public object Get(DownloadLicense downloadRequest)
        {
            var cacheKey = UrnId.Create <Model.License>("IssueToken", downloadRequest.Token.ToString());
            var license  = cacheClient.Get <Portable.Licensing.License>(cacheKey);

            if (license == null)
            {
                return(new HttpResult(HttpStatusCode.NotFound));
            }

            var responseStream = new MemoryStream();

            license.Save(responseStream);

            var response = new HttpResult(responseStream, "application/xml");

            response.Headers[HttpHeaders.ContentDisposition] = "attachment; filename=License.lic";

            return(response);
        }
Exemple #2
0
        private async Task <string> aaxToM4bConverterDecryptAsync(string cacheDir, string destinationDir, LibraryBook libraryBook)
        {
            DecryptBegin?.Invoke(this, $"Begin decrypting {libraryBook}");

            try
            {
                validate(libraryBook);

                var api = await InternalUtilities.AudibleApiActions.GetApiAsync(libraryBook.Account, libraryBook.Book.Locale);

                var contentLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId);

                var aaxcDecryptDlLic = new DownloadLicense
                                       (
                    contentLic.ContentMetadata?.ContentUrl?.OfflineUrl,
                    contentLic.Voucher?.Key,
                    contentLic.Voucher?.Iv,
                    Resources.UserAgent
                                       );

                if (Configuration.Instance.AllowLibationFixup)
                {
                    aaxcDecryptDlLic.ChapterInfo = new AAXClean.ChapterInfo();

                    foreach (var chap in contentLic.ContentMetadata?.ChapterInfo?.Chapters)
                    {
                        aaxcDecryptDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs));
                    }
                }


                var format = Configuration.Instance.DecryptToLossy ? OutputFormat.Mp3 : OutputFormat.Mp4a;

                var extension = format switch
                {
                    OutputFormat.Mp4a => "m4b",
                    OutputFormat.Mp3 => "mp3",
                    _ => throw new NotImplementedException(),
                };

                var proposedOutputFile = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].{extension}");


                aaxcDownloader = new AaxcDownloadConverter(proposedOutputFile, cacheDir, aaxcDecryptDlLic, format)
                {
                    AppName = "Libation"
                };
                aaxcDownloader.DecryptProgressUpdate += (s, progress) => UpdateProgress?.Invoke(this, progress);
                aaxcDownloader.DecryptTimeRemaining  += (s, remaining) => UpdateRemainingTime?.Invoke(this, remaining);
                aaxcDownloader.RetrievedCoverArt     += AaxcDownloader_RetrievedCoverArt;
                aaxcDownloader.RetrievedTags         += aaxcDownloader_RetrievedTags;

                // REAL WORK DONE HERE
                var success = await Task.Run(() => aaxcDownloader.Run());

                // decrypt failed
                if (!success)
                {
                    return(null);
                }

                return(aaxcDownloader.OutputFileName);
            }
            finally
            {
                DecryptCompleted?.Invoke(this, $"Completed downloading and decrypting {libraryBook.Book.Title}");
            }
        }
Exemple #3
0
 /// <summary>
 /// Downloadしたライセンス情報をもとにLocalStorageに保存するキャッシュライセンスを作成する
 /// </summary>
 /// <param name="license">ダウンロードライセンス</param>
 /// <returns></returns>
 public static CachedLicense LicenseCache(DownloadLicense license)
 {
     return(new CachedLicense(license));
 }
        private async Task <bool> downloadAudiobookAsync(LibraryBook libraryBook)
        {
            OnStreamingBegin($"Begin decrypting {libraryBook}");

            try
            {
                downloadValidation(libraryBook);

                var api = await libraryBook.GetApiAsync();

                var contentLic = await api.GetDownloadLicenseAsync(libraryBook.Book.AudibleProductId);

                var audiobookDlLic = new DownloadLicense
                                     (
                    contentLic?.ContentMetadata?.ContentUrl?.OfflineUrl,
                    contentLic?.Voucher?.Key,
                    contentLic?.Voucher?.Iv,
                    Resources.USER_AGENT
                                     );

                //I assume if ContentFormat == "MPEG" that the delivered file is an unencrypted mp3.
                //I also assume that if DrmType != Adrm, the file will be an mp3.
                //These assumptions may be wrong, and only time and bug reports will tell.
                var outputFormat =
                    contentLic.ContentMetadata.ContentReference.ContentFormat == "MPEG" ||
                    (Configuration.Instance.AllowLibationFixup && Configuration.Instance.DecryptToLossy) ?
                    OutputFormat.Mp3 : OutputFormat.M4b;

                if (Configuration.Instance.AllowLibationFixup || outputFormat == OutputFormat.Mp3)
                {
                    audiobookDlLic.ChapterInfo = new AAXClean.ChapterInfo();

                    foreach (var chap in contentLic.ContentMetadata?.ChapterInfo?.Chapters)
                    {
                        audiobookDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs));
                    }
                }

                var outFileName = AudibleFileStorage.Audio.GetInProgressFilename(libraryBook, outputFormat.ToString().ToLower());

                var cacheDir = AudibleFileStorage.DownloadsInProgressDirectory;

                abDownloader
                    = contentLic.DrmType != AudibleApi.Common.DrmType.Adrm ? new UnencryptedAudiobookDownloader(outFileName, cacheDir, audiobookDlLic)
                    : Configuration.Instance.SplitFilesByChapter ? new AaxcDownloadMultiConverter(
                          outFileName, cacheDir, audiobookDlLic, outputFormat,
                          AudibleFileStorage.Audio.CreateMultipartRenamerFunc(libraryBook)
                          )
                    : new AaxcDownloadSingleConverter(outFileName, cacheDir, audiobookDlLic, outputFormat);
                abDownloader.DecryptProgressUpdate += (_, progress) => OnStreamingProgressChanged(progress);
                abDownloader.DecryptTimeRemaining  += (_, remaining) => OnStreamingTimeRemaining(remaining);
                abDownloader.RetrievedTitle        += (_, title) => OnTitleDiscovered(title);
                abDownloader.RetrievedAuthors      += (_, authors) => OnAuthorsDiscovered(authors);
                abDownloader.RetrievedNarrators    += (_, narrators) => OnNarratorsDiscovered(narrators);
                abDownloader.RetrievedCoverArt     += AaxcDownloader_RetrievedCoverArt;
                abDownloader.FileCreated           += (_, path) => OnFileCreated(libraryBook, path);

                // REAL WORK DONE HERE
                var success = await Task.Run(abDownloader.Run);

                return(success);
            }
            finally
            {
                OnStreamingCompleted($"Completed downloading and decrypting {libraryBook.Book.Title}");
            }
        }