Example #1
0
func (fh *FileHandle) Release(ctx context.Context, req *fuse.ReleaseRequest) error {
	if fh.r == nil {
		if fh.f.name == ".description" {
			glog.Infof("Entered Release: .description file\n")
			return nil
		}

		if fh.f.name[0] == '.' {
			return fuse.EPERM
		}
	}

	if fh.r == nil {
		glog.Info("Release: There is no file handler.\n")
		return fuse.EIO
	}
	glog.Infof("Releasing the file: %s\n", fh.r.Name())

	if fh.f != nil && fh.f.artist == "drop" {
		glog.Infof("Entered Release dropping the song: %s\n", fh.f.name)
		ret_val := fh.r.Close()

		PushFileItem(*fh.f, DelayedHandleDrop)
		return ret_val
	}

	if fh.f != nil && fh.f.artist == "playlists" {
		glog.Infof("Entered Release with playlist song: %s\n", fh.f.name)
		ret_val := fh.r.Close()

		PushFileItem(*fh.f, DelayedHandlePlaylistSong)
		return ret_val
	}

	// This is not an music file or this is a strange situation.
	if fh.f == nil || len(fh.f.artist) < 1 || len(fh.f.album) < 1 {
		glog.Info("Entered Release: Artist or Album not set.\n")
		return fh.r.Close()
	}

	glog.Infof("Entered Release: Artist: %s, Album: %s, Song: %s\n", fh.f.artist, fh.f.album, fh.f.name)
	ret_val := fh.r.Close()
	extension := filepath.Ext(fh.f.name)
	songPath, err := store.GetFilePath(fh.f.artist, fh.f.album, fh.f.name)
	if err != nil {
		return err
	}

	if extension == ".mp3" {
		//TODO: Use the correct artist and album
		musicmgr.SetMp3Tags(fh.f.artist, fh.f.album, fh.f.song, songPath)
	}
	return ret_val
}
Example #2
0
func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
	glog.Infof("Entered Open with file name: %s.\n", f.name)

	if f.name == ".description" {
		return &FileHandle{r: nil, f: f}, nil
	}

	if f.name[0] == '.' {
		return nil, fuse.EPERM
	}

	if runtime.GOOS == "darwin" {
		resp.Flags |= fuse.OpenDirectIO
	}

	if req.Flags.IsReadOnly() {
		glog.Info("Open: File requested is read only.\n")
	}
	if req.Flags.IsReadWrite() {
		glog.Info("Open: File requested is read write.\n")
	}
	if req.Flags.IsWriteOnly() {
		glog.Info("Open: File requested is write only.\n")
	}

	var err error
	var songPath string
	if f.artist == "drop" {
		songPath, err = store.GetDropFilePath(f.name, f.mPoint)
		PushFileItem(*f, DelayedVoid)
	} else if f.artist == "playlists" {
		songPath, err = store.GetPlaylistFilePath(f.album, f.name, f.mPoint)
		PushFileItem(*f, DelayedVoid)
	} else {
		songPath, err = store.GetFilePath(f.artist, f.album, f.name)
	}
	if err != nil {
		glog.Error(err)
		return nil, err
	}

	r, err := os.OpenFile(songPath, int(req.Flags), 0666)
	if err != nil {
		return nil, err
	}
	return &FileHandle{r: r, f: f}, nil
}
Example #3
0
func (f *File) Attr(ctx context.Context, a *fuse.Attr) error {
	glog.Infof("Entering file Attr with name: %s, Artist: %s and Album: %s.\n", f.name, f.artist, f.album)
	if f.name[0] == '.' {
		if f.name == ".description" {
			descriptionJson, err := store.GetDescription(f.artist, f.album, f.name)
			if err != nil {
				return err
			}

			a.Size = uint64(len(descriptionJson))
			a.Mode = 0444
			if config_params.uid != 0 {
				a.Uid = uint32(config_params.uid)
			}
			if config_params.gid != 0 {
				a.Gid = uint32(config_params.gid)
			}
		} else {
			return fuse.EPERM
		}
	} else {
		var songPath string
		var err error
		if f.artist == "drop" {
			songPath, err = store.GetDropFilePath(f.name, f.mPoint)
			PushFileItem(*f, nil)
		} else if f.artist == "playlists" {
			songPath, err = store.GetPlaylistFilePath(f.album, f.name, f.mPoint)
			PushFileItem(*f, nil)
		} else {
			songPath, err = store.GetFilePath(f.artist, f.album, f.name)
		}

		if err != nil {
			glog.Infof("Error getting song path: %s\n", err)
			return err
		}

		r, err := os.Open(songPath)
		if err != nil {
			glog.Infof("Error opening file: %s\n", err)
			return err
		}
		defer r.Close()

		fi, err := r.Stat()
		if err != nil {
			glog.Infof("Error getting file status: %s\n", err)
			return err
		}

		a.Size = uint64(fi.Size())
		a.Mode = 0777
		if config_params.uid != 0 {
			a.Uid = uint32(config_params.uid)
		}
		if config_params.gid != 0 {
			a.Gid = uint32(config_params.gid)
		}
	}
	return nil
}
Example #4
0
// DelayedHandlePlaylistSong handles a dropped file
// inside a playlist and is called by the background
// dispatcher after some time has passed.
func DelayedHandlePlaylistSong(f File) error {
	rootPoint := f.mPoint
	if rootPoint[len(rootPoint)-1] != '/' {
		rootPoint = rootPoint + "/"
	}

	path := rootPoint + "playlists/" + f.album + "/" + f.name

	extension := filepath.Ext(f.name)
	if extension != ".mp3" {
		os.Remove(path)
		return errors.New("File is not an mp3.")
	}

	src, err := os.Stat(path)
	if err != nil || src.IsDir() {
		return errors.New("File not found.")
	}

	err, tags := musicmgr.GetMp3Tags(path)
	if err != nil {
		os.Remove(path)
		return err
	}

	artist := store.GetCompatibleString(tags.Artist)
	album := store.GetCompatibleString(tags.Album)
	title := tags.Title
	if strings.HasSuffix(title, ".mp3") {
		title = title[:len(title)-len(".mp3")]
	}
	title = store.GetCompatibleString(title) + ".mp3"

	newPath, err := store.GetFilePath(artist, album, title)
	if err == nil {
		var playlistFile playlistmgr.PlaylistFile
		playlistFile.Title = title
		playlistFile.Artist = artist
		playlistFile.Album = album
		playlistFile.Path = newPath
		err = store.AddFileToPlaylist(playlistFile, f.album)
	} else {
		err = store.HandleDrop(path, rootPoint)
		if err == nil {
			newPath, err = store.GetFilePath(artist, album, title)
			if err == nil {
				var playlistFile playlistmgr.PlaylistFile
				playlistFile.Title = title
				playlistFile.Artist = artist
				playlistFile.Album = album
				playlistFile.Path = newPath
				err = store.AddFileToPlaylist(playlistFile, f.album)
			}
		}
	}

	os.Remove(path)
	if err == nil {
		err = store.RegeneratePlaylistFile(f.album, rootPoint)
	}
	return err
}
Example #5
0
func (d *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
	glog.Infof("Entering Lookup with artist: %s, album: %s and name: %s.\n", d.artist, d.album, name)
	if name == ".description" {
		return &File{artist: d.artist, album: d.album, song: name, name: name, mPoint: d.mPoint}, nil
	}

	if name[0] == '.' {
		return nil, fuse.EIO
	}

	if len(d.artist) < 1 {
		if name == "drop" {
			return &Dir{fs: d.fs, artist: "drop", album: "", mPoint: d.mPoint}, nil
		}
		if name == "playlists" {
			return &Dir{fs: d.fs, artist: "playlists", album: "", mPoint: d.mPoint}, nil
		}

		_, err := store.GetArtistPath(name)
		if err != nil {
			glog.Info(err)
			return nil, err
		}
		return &Dir{fs: d.fs, artist: name, album: "", mPoint: d.mPoint}, nil
	}

	if len(d.album) < 1 && d.artist != "drop" && d.artist != "playlists" {
		_, err := store.GetAlbumPath(d.artist, name)
		if err != nil {
			glog.Info(err)
			return nil, err
		}
		return &Dir{fs: d.fs, artist: d.artist, album: name, mPoint: d.mPoint}, nil
	}

	var err error
	if d.artist == "drop" {
		_, err = store.GetDropFilePath(name, d.mPoint)
		if err != nil {
			glog.Info(err)
			return nil, fuse.ENOENT
		}
	} else if d.artist == "playlists" {
		if len(d.album) < 1 {
			_, err = store.GetPlaylistPath(name)
			if err != nil {
				glog.Info(err)
				return nil, fuse.ENOENT
			}
			return &Dir{fs: d.fs, artist: d.artist, album: name, mPoint: d.mPoint}, nil
		} else {
			_, err = store.GetPlaylistFilePath(d.album, name, d.mPoint)
			if err != nil {
				glog.Info(err)
				return nil, fuse.ENOENT
			}
		}
	} else {
		_, err = store.GetFilePath(d.artist, d.album, name)
		if err != nil {
			glog.Info(err)
			return nil, err
		}
	}
	extension := filepath.Ext(name)
	songName := name[:len(name)-len(extension)]
	return &File{artist: d.artist, album: d.album, song: songName, name: name, mPoint: d.mPoint}, nil
}
Example #6
0
func (d *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
	//TODO: Correct this function to work with drop folder.
	name := req.Name
	glog.Infof("Entered Remove function with Artist: %s, Album: %s and Name: %s.\n", d.artist, d.album, name)

	if name == ".description" {
		return nil
	}

	if name[0] == '.' {
		return fuse.EIO
	}

	if req.Dir {
		if len(name) < 1 {
			return fuse.EIO
		}

		if len(d.artist) < 1 {
			if name == "drop" {
				return fuse.EIO
			}

			if name == "playlists" {
				return fuse.EIO
			}

			err := store.DeleteArtist(name, d.mPoint)
			if err != nil {
				return fuse.EIO
			}

			return nil
		}

		if d.artist == "playlists" {
			store.DeletePlaylist(name, d.mPoint)
			return nil
		}

		err := store.DeleteAlbum(d.artist, name, d.mPoint)
		if err != nil {
			return fuse.EIO
		}

		return nil
	} else {
		if len(d.artist) < 1 || len(d.album) < 1 {
			return fuse.EIO
		}

		fullPath, err := store.GetFilePath(d.artist, d.album, name)
		if err != nil {
			return fuse.EIO
		}

		if d.artist == "playlists" {
			err := store.DeletePlaylistSong(d.album, name, false)
			if err != nil {
				return fuse.EIO
			}
		}

		err = store.DeleteSong(d.artist, d.album, name, d.mPoint)
		if err != nil {
			return fuse.EIO
		}

		//TODO: Check if there are no more files in the folder
		//      and delete the folder.

		err = os.Remove(fullPath)
		if err != nil {
			return err
		}

		return nil
	}
}