예제 #1
0
func Read(rf codec.Reader) (codec.Songs, error) {
	r, _, err := rf()
	if err != nil {
		return nil, err
	}
	// In order to not open the rar file up once per included file, keep around a
	// pointer to the reader during the inital listing phase and use that if we're
	// opening it. I would appreciate a better way to do this.
	var rd *rardecode.Reader
	var rfh *rardecode.FileHeader
	defer func() {
		rd = nil
	}()
	readRAR := func(name string, rf codec.Reader) codec.Reader {
		return func() (rc io.ReadCloser, sz int64, err error) {
			if rd != nil && rfh.Name == name {
				return ioutil.NopCloser(rd), rfh.UnPackedSize, nil
			}
			r, _, err := rf()
			if err != nil {
				return nil, 0, err
			}
			f := func(d *rardecode.Reader, fh *rardecode.FileHeader) (stop bool) {
				if fh.Name != name {
					return false
				}
				rc = &rarReader{r, d}
				sz = fh.UnPackedSize
				return true
			}
			err = read(r, f)
			if err == nil && rc == nil {
				err = fmt.Errorf("rar: %v unfound", name)
			}
			return
		}
	}
	defer r.Close()
	songs := make(codec.Songs)
	f := func(d *rardecode.Reader, fh *rardecode.FileHeader) (stop bool) {
		rd = d
		rfh = fh
		ss, _, _ := codec.ByExtension(fh.Name, readRAR(fh.Name, rf))
		for v, s := range ss {
			songs[codec.NewID(fh.Name, string(v))] = s
		}
		return false
	}
	if err := read(r, f); err != nil {
		return nil, err
	}
	return songs, nil
}
예제 #2
0
func (d *Dropbox) Refresh() (protocol.SongList, error) {
	service, err := d.getService()
	if err != nil {
		return nil, err
	}
	files := make(map[string]*dropbox.ListContent)
	songs := make(protocol.SongList)
	var ss codec.Songs
	dirs := []string{""}
	for {
		if len(dirs) == 0 {
			break
		}
		dir := dirs[0]
		dirs = dirs[1:]
		list, err := service.List().Path(dir).Do()
		if err != nil {
			return nil, err
		}
		for _, f := range list.Contents {
			if f.IsDir {
				dirs = append(dirs, f.Path)
				continue
			}
			ss, _, err = codec.ByExtension(f.Path, d.reader(f.Path, f.Bytes))
			if err != nil || len(ss) == 0 {
				continue
			}
			files[f.Path] = f
			for i, v := range ss {
				info, _ := v.Info()
				if info.Title == "" {
					title := path.Base(f.Path)
					if len(ss) != 1 {
						title += fmt.Sprintf(":%v", i)
					}
					info.Title = title
				}
				if info.Album == "" {
					info.Album = path.Base(dir)
				}
				songs[codec.NewID(f.Path, string(i))] = &info
			}
		}
	}
	d.Songs = songs
	d.Files = files
	return songs, err
}
예제 #3
0
func (d *Drive) Refresh() (protocol.SongList, error) {
	service, err := d.getService()
	if err != nil {
		return nil, err
	}
	files := make(map[string]*drive.File)
	songs := make(protocol.SongList)
	var nextPage string
	var ss codec.Songs
	for {
		fl, err := service.Files.
			List().
			PageToken(nextPage).
			Fields("nextPageToken", "files(fileExtension,id,name,size)").
			PageSize(1000).
			Do()
		if err != nil {
			return nil, err
		}
		nextPage = fl.NextPageToken
		for _, f := range fl.Files {
			ss, _, err = codec.ByExtension(f.FileExtension, d.reader(f.Id))
			if err != nil || len(ss) == 0 {
				continue
			}
			files[f.Id] = f
			for i, v := range ss {
				info, _ := v.Info()
				if info.Title == "" {
					title := f.Name
					if len(ss) != 1 {
						title += fmt.Sprintf(":%v", i)
					}
					info.Title = title
				}
				songs[codec.NewID(f.Id, string(i))] = &info
			}
		}
		if nextPage == "" {
			break
		}
	}
	d.Songs = songs
	d.Files = files
	return songs, err
}
예제 #4
0
func (f *File) Refresh() (protocol.SongList, error) {
	songs := make(protocol.SongList)
	err := filepath.Walk(f.Path, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			return nil
		}
		f, err := os.Open(path)
		if err != nil {
			return nil
		}
		defer f.Close()
		ss, _, err := codec.ByExtension(path, fileReader(path))
		if err != nil || len(ss) == 0 {
			return nil
		}
		for i, s := range ss {
			info, _ := s.Info()
			if info.Title == "" {
				title := filepath.Base(path)
				if len(ss) != 1 {
					title += fmt.Sprintf(":%v", i)
				}
				info.Title = title
			}
			if info.Album == "" {
				info.Album = filepath.Base(filepath.Dir(path))
			}
			songs[codec.NewID(path, string(i))] = &info
		}
		return nil
	})
	f.Songs = songs
	return songs, err
}