public void shouldNotBeEmptyAfterUpdate() { var target = new LocalLibrary(@"C:\Temp\Library"); target.updateLibrary(); Assert.AreNotEqual(0, target.getBookCount(), "Why there aren't any books?"); }
public void RemoveFolder(LocalLibraryModel model) { StorageApplicationPermissions.FutureAccessList.Remove(model.Token); LocalLibraryDb.Instance.RemoveLocalLibrary(model); LocalLibrary.Remove(model); LocalGallery.Where(it => it.LibraryId == model.Id).ToList().ForEach(it => LocalGallery.Remove(it)); }
private async Task <Unit> MovePath(TvContext dbContext, Parameters parameters) { LibraryPath path = parameters.LibraryPath; LocalLibrary newLibrary = parameters.Library; path.LibraryId = newLibrary.Id; if (await dbContext.SaveChangesAsync() > 0) { List <int> ids = await dbContext.Connection.QueryAsync <int>( @"SELECT MediaItem.Id FROM MediaItem WHERE LibraryPathId = @LibraryPathId", new { LibraryPathId = path.Id }) .Map(result => result.ToList()); foreach (int id in ids) { Option <MediaItem> maybeMediaItem = await _searchRepository.GetItemToIndex(id); foreach (MediaItem mediaItem in maybeMediaItem) { _logger.LogInformation("Moving item at {Path}", await GetPath(dbContext, mediaItem)); await _searchIndex.UpdateItems(_searchRepository, new List <MediaItem> { mediaItem }); } } } return(Unit.Default); }
/// <summary> /// The start function /// </summary> void Start() { //Initialise NFC AndroidNFCReader.enableBackgroundScan(); AndroidNFCReader.ScanNFC("GameController", "OnMove"); //Set the mapmid active so the map can be filled MapMid.SetActive(true); // Create the locallibrary local = new LocalLibrary(); //Set the mapmid inactive MapMid.SetActive(false); //Set the energy sprite so it shows correctly GameObject newImageObject = GameObject.Find("Energy" + PlayerState.energy); Image newImage = newImageObject.GetComponent <Image>(); placeholderImage.sprite = newImage.sprite; //Set the correct Jeep Image Image jeep = GameObject.Find("JeepImage").GetComponent <Image>(); jeep.sprite = GameObject.Find("Jeep" + PlayerState.vehicle).GetComponent <Image>().sprite; //Set the correct Hat Image Image hat = GameObject.Find("HatImage").GetComponent <Image>(); hat.sprite = GameObject.Find("Hat" + PlayerState.hat).GetComponent <Image>().sprite; }
private Task DeleteLocalItem(MusicItem item) { return(TryFileDeletion(async() => { await LocalLibrary.Delete(item); // Updates the UI. Apparently, MusicFolder.MusicItems.Remove(item); does not update the UI. await RefreshCurrentFolder(); })); }
private async Task DownloadIfNecessary(MusicItem track) { var maybeLocalUri = await LocalLibrary.LocalUriIfExists(track); if (maybeLocalUri == null) { await BackgroundDownloader.DownloadAsync(track); } }
protected override async Task EnsureHasDuration(MusicItem track) { var uri = await LocalLibrary.LocalUriIfExists(track); if (uri != null) { track.Duration = await StoreBeamPlayer.MediaElement.UriDuration(uri); } }
public async Task AddFolder(params IFolderItem[] paths) { foreach (var path in paths) { var gallery = await ScanForGalleryAsync(path); var result = LocalLibraryDb.Instance.AddLocalLibrary(path, gallery); LocalLibrary.Add(result); gallery.ForEach(it => LocalGallery.Add(it)); } }
public List <Book> GetBooksInLibrary(Book book, LocalLibrary library) { using (var context = new AuthContext()) { return(context.Books .Include(_book => _book.Author) .Include(_book => _book.LocalLibrary) .Where(_book => _book.Name == book.Name && _book.Author.Name == book.Author.Name /* && book.LocalLibrary.Id == library.Id*/) .ToList()); } }
/// <summary> /// Downloads the song if it is not already available offline. /// </summary> /// <param name="track"></param> /// <returns>the local uri of the downloaded track</returns> public async Task <Uri> DownloadAsync(MusicItem track) { await BeforeDownload(track); var maybeLocalUri = await PhoneLocalLibrary.Instance.LocalUriIfExists(track); if (maybeLocalUri != null) { return(maybeLocalUri); } return(await AddTransferAsync(track.Source, LocalLibrary.AbsolutePathTo(track))); }
protected void Delete(MusicItem song) { try { var shouldRemove = song.IsSourceLocal; LocalLibrary.Delete(song.Path); // refreshes the items in the current view if (shouldRemove) { MusicFolder.MusicItems.Remove(song); } } catch (Exception e) { Send("Unable to delete. Perhaps the file is in use. " + e.Message); } }
private async Task <LocalLibraryViewModel> PersistLocalLibrary( TvContext dbContext, LocalLibrary localLibrary) { await dbContext.LocalLibraries.AddAsync(localLibrary); await dbContext.SaveChangesAsync(); if (_entityLocker.LockLibrary(localLibrary.Id)) { await _workerChannel.WriteAsync(new ForceScanLocalLibrary(localLibrary.Id)); } return(ProjectToViewModel(localLibrary)); }
protected static async Task <Validation <BaseError, LocalLibrary> > PathsMustBeValid( TvContext dbContext, LocalLibrary localLibrary, int?existingLibraryId = null) { List <string> allPaths = await dbContext.LocalLibraries .Include(ll => ll.Paths) .Filter(ll => existingLibraryId == null || ll.Id != existingLibraryId) .ToListAsync() .Map(list => list.SelectMany(ll => ll.Paths).Map(lp => lp.Path).ToList()); return(Optional(localLibrary.Paths.Count(folder => allPaths.Any(f => AreSubPaths(f, folder.Path)))) .Where(length => length == 0) .Map(_ => localLibrary) .ToValidation <BaseError>("Path must not belong to another library path")); }
/// <summary> /// Downloads the song in the background if it's not already available offline. /// </summary> /// <param name="track"></param> public async Task SubmitDownload(MusicItem track) { await BeforeDownload(track); try { var maybeLocalUri = await PhoneLocalLibrary.Instance.LocalUriIfExists(track); if (maybeLocalUri == null) { // For Subsonic, the response may be transcoded audio, in which case the // path to the track, which has the original file extension as stored on // the server, may be incorrect (example: response is transcoded to .mp3, // path is .flac). // TODO: Ensure that the file is stored locally with the correct extension, // that is, find out whether the response is transcoded. var destination = LocalLibrary.AbsolutePathTo(track); var downloadUri = MusicProvider.DownloadUriFor(track); // Only downloads tracks that are stored as MP3s, because this app does not support other local file formats. if (destination.EndsWith("mp3")) { var downloadable = new Downloadable(downloadUri, destination); if (LoadTransfersCount() < 3) { AddTransfer(downloadUri, destination); } else { // add the download to persistent storage from which it will be taken // later when there are fewer concurrent downloads DownloadDataContext.Add(downloadable); } } } } catch (PathTooLongException) { // Thrown if track.Path is about over 190 characters long, but I'm not sure what // the limit is and I don't want to be too defensive with this so I catch and // suppress the exception when it occurs. // The exception says "The specified path, file name, or both are too long. // The fully qualified file name must be less than 260 characters, and the // directory name must be less than 248 characters.", however, I don't know // the length of the fully qualified path name, so 190 chars is an estimate. AddMessage("Download of " + track.Name + " failed. The path is too long: " + track.Path); } }
private async Task <Unit> DoDeletion(TvContext dbContext, LocalLibrary localLibrary) { List <int> ids = await dbContext.Connection.QueryAsync <int>( @"SELECT MediaItem.Id FROM MediaItem INNER JOIN LibraryPath LP on MediaItem.LibraryPathId = LP.Id WHERE LP.LibraryId = @LibraryId", new { LibraryId = localLibrary.Id }) .Map(result => result.ToList()); await _searchIndex.RemoveItems(ids); _searchIndex.Commit(); dbContext.LocalLibraries.Remove(localLibrary); await dbContext.SaveChangesAsync(); return(Unit.Default); }
private static Task <Validation <BaseError, Parameters> > LocalLibraryMustExist( TvContext dbContext, UpdateLocalLibrary request) => dbContext.LocalLibraries .Include(ll => ll.Paths) .SelectOneAsync(ll => ll.Id, ll => ll.Id == request.Id) .MapT( existing => { var incoming = new LocalLibrary { Name = request.Name, Paths = request.Paths.Map(p => new LibraryPath { Id = p.Id, Path = p.Path }).ToList(), MediaSourceId = existing.Id }; return(new Parameters(existing, incoming)); }) .Map(o => o.ToValidation <BaseError>("LocalLibrary does not exist."));
//private async Task<Uri> DownloadIfNotExists(MusicItem track, Func<Task<Uri>> performDownload) { // var maybeLocalUri = await LocalLibrary.LocalUriIfExists(track); // if(maybeLocalUri != null) { // return maybeLocalUri; // } // return await performDownload(); //} /// <summary> /// Prepares a download. A return value of null indicates that the download shall /// not proceed. This may be the case if the track already exists locally, or some /// IO error prevents the download, for example if the intended destination path /// is too long. /// </summary> /// <param name="track"></param> /// <returns>download parameters, or null if the track shall not be downloaded</returns> private async Task <DownloadParameters> GetDownloadInfo(MusicItem track) { var maybeLocalUri = await LocalLibrary.LocalUriIfExists(track); if (maybeLocalUri == null) { try { var source = RemoveCredentialsFromQueryParams(track.Source); var destFile = await Utils.FileTo(PathTo(track)); return(new DownloadParameters(source, destFile)); } catch (IOException) { // may have thrown PathTooLongException // does not proceed with the download return(null); } } else { return(null); } }
public async Task <string> Upload(MusicItem song, string resource) { await DownloadIfNecessary(song); await EnsureHasDuration(song); // TODO refactor to HttpClient extension method or some such using (var content = new MultipartFormDataContent()) { // the trickery with quotes is due to bugs in the recipient of the uploaded content, Play Framework 2 // see http://stackoverflow.com/questions/17900934/httpclient-uploading-multipartformdata-to-play-2-framework foreach (var param in content.Headers.ContentType.Parameters.Where(param => param.Name.Equals("boundary"))) { param.Value = param.Value.Replace("\"", String.Empty); } return(await LocalLibrary.WithStream <string>(song, async stream => { var fileName = ProviderService.Instance.PathHelper.FileNameOf(song.Path); content.Add(new StreamContent(stream), "\"file\"", "\"" + fileName + "\""); content.Headers.Add(TrackHeader, JsonConvert.SerializeObject(new PimpTrack(song))); using (var httpResponse = await LongTimeoutClient.PostAsync(resource, content)) { return await httpResponse.Content.ReadAsStringAsync(); } })); } }
public async Task CalculateConsumedGb() { var bytes = await LocalLibrary.ConsumedDiskSpaceBytes(); ConsumedGb = 1.0D * bytes / 1024 / 1024 / 1024; }
private record RequestParameters( LocalLibrary LocalLibrary, string FFprobePath, string FFmpegPath, bool ForceScan, int LibraryRefreshInterval);
public void shouldBeEmptyUponCreation() { var target = new LocalLibrary(); Assert.AreEqual(0, target.getBookCount(), "Why are there any books?"); }
public void shouldBeAvailable() { var target = new LocalLibrary(@"C:\Temp\Library"); Assert.IsTrue(target.isAvailable()); }
private record Parameters(LocalLibrary Existing, LocalLibrary Incoming);
protected static Task <Validation <BaseError, LocalLibrary> > NameMustBeValid( ILocalLibraryRequest request, LocalLibrary localLibrary) => request.NotEmpty(c => c.Name) .Bind(_ => request.NotLongerThan(50)(c => c.Name)) .Map(_ => localLibrary).AsTask();
public async Task SubmitDownloads(IEnumerable <MusicItem> tracks) { await BeforeDownload(tracks); try { var remoteTracks = await tracks.FilterAsync(async track => await PhoneLocalLibrary.Instance.LocalUriIfExists(track) == null); var downloadables = remoteTracks .Select(track => new Downloadable(MusicProvider.DownloadUriFor(track), LocalLibrary.AbsolutePathTo(track))) .Where(d => d.Destination.EndsWith("mp3")) .ToList(); var transfers = LoadTransfersCount(); var queueables = (transfers < 3 ? downloadables.Skip(3) : downloadables).ToList(); if (transfers < 3) { foreach (var dl in downloadables.Take(3).ToList()) { AddTransfer(dl.Source, dl.Destination); } } if (queueables.Count > 0) { // add the download to persistent storage from which it will be taken // later when there are fewer concurrent downloads DownloadDataContext.AddAll(queueables); } } catch (PathTooLongException) { // Thrown if track.Path is about over 190 characters long, but I'm not sure what // the limit is and I don't want to be too defensive with this so I catch and // suppress the exception when it occurs. // The exception says "The specified path, file name, or both are too long. // The fully qualified file name must be less than 260 characters, and the // directory name must be less than 248 characters.", however, I don't know // the length of the fully qualified path name, so 190 chars is an estimate. AddMessage("Unable to submit all tracks for download. A file path was too long."); } }