// Notify sends video to the notifiers func (o *Organizer) Notify(v polochon.Video, log *logrus.Entry) { log = log.WithField("function", "notify") for _, n := range o.config.Notifiers { if err := n.Notify(v, log); err != nil { log.Warnf("failed to send a notification from notifier: %q: %q", n.Name(), err) } } }
func (c *Cleaner) cleanDirectory(torrent *polochon.DownloadableInfos, log *logrus.Entry) error { if len(torrent.FilePaths) == 0 { return fmt.Errorf("no torrent files to clean") } // Get the path of one of the file to guess the directory that needs to be // deleted torrentFilePath := torrent.FilePaths[0] // Get the full path of the file filePath := filepath.Join(c.config.Watcher.Dir, torrentFilePath) // Get the directory of the file directoryPath := filepath.Dir(filePath) // Ensure the path is clean directoryPath = filepath.Clean(directoryPath) // We don't want to clean the DownloadDir if directoryPath == c.config.Downloader.DownloadDir { log.Debug("in the watching folder, no need to clean") return nil } // Get relative path of the directory to clean relDir, err := filepath.Rel(c.config.Downloader.DownloadDir, directoryPath) if err != nil { return err } // Get the first part of the directory to clean for filepath.Dir(relDir) != "." { relDir = filepath.Dir(relDir) log.Debugf("going higher : %s", relDir) } // Get the full path directoryToClean := filepath.Join(c.config.Downloader.DownloadDir, relDir) log.Debug("try to clean and delete") ok, err := IsEmpty(directoryToClean) if err != nil { log.Warnf("got error checking if directory is empty : %q", err) return err } if !ok { log.Debug("directory is not empty") return nil } log.Debug("everything is ready to delete the dir") // Delete the directory if err = c.deleteDirectory(directoryToClean, log); err != nil { return err } return nil }
func (c *Cleaner) clean(d polochon.Downloadable, log *logrus.Entry) error { torrent := d.Infos() // Going over all the files and remove only the allowed ones for _, tPath := range torrent.FilePaths { filePath := filepath.Join(c.config.Watcher.Dir, tPath) file := polochon.NewFile(filePath) // Check extension ext := path.Ext(filePath) if !stringInSlice(ext, c.config.File.AllowedExtentionsToDelete) { if !file.IsSymlink() { // Not allowed to delete these types of files log.WithFields(logrus.Fields{ "extension": ext, "file_to_clean": filePath, }).Debug("protected extention") continue } else { log.Debugf("file %q is a sym link, delete it", filePath) } } // If it's a symlink, delete the file as it has already been organized err := c.deleteFile(file.Path, log) if err != nil { log.Warnf("got error while removing file %q", err) continue } } // Need to check if we can delete the directory of the torrent err := c.cleanDirectory(torrent, log) if err != nil { log.Warnf("got error while deleting directory : %q", err) return err } return nil }
// searchSubtitles will search via hash, then filename, then info and return the best subtitle func (osp *osProxy) searchSubtitles(v interface{}, filePath string, log *logrus.Entry) (*openSubtitle, error) { // Look for subtitles with the hash sub, err := osp.checkConnAndExec(osp.searchSubtitlesByHash, v, filePath, log) if err != nil { log.Warnf("Got error looking for subtitle by hash : %q", err) } if sub != nil { log.Debug("We got the subtitle by hash") return &openSubtitle{os: sub, client: osp.client}, nil } log.Debug("Nothing in the result, need to check again with filename") // Look for subtitles with the filename sub, err = osp.checkConnAndExec(osp.searchSubtitlesByFilename, v, filePath, log) if err != nil { log.Warnf("Got error looking for subtitle by filename : %q", err) } if sub != nil { log.Debug("We got the subtitle by filename") return &openSubtitle{os: sub, client: osp.client}, nil } log.Debug("Still no good, need to check again with imdbID") // Look for subtitles with the title and episode and season or by imdbID sub, err = osp.checkConnAndExec(osp.searchSubtitlesByInfos, v, filePath, log) if err != nil { log.Warnf("Got error looking for subtitle by infos : %q", err) } if sub != nil { return &openSubtitle{os: sub, client: osp.client}, nil } return nil, polochon.ErrNoSubtitleFound }
// AddShowEpisode adds an episode to the store func (l *Library) AddShowEpisode(ep *polochon.ShowEpisode, log *logrus.Entry) error { if ep.Path == "" { return ErrMissingShowEpisodeFilePath } ok, err := l.HasShowEpisode(ep.ShowImdbID, ep.Season, ep.Episode) if err != nil { return err } if ok { // Get the old episode from the index oldEpisode, err := l.GetEpisode(ep.ShowImdbID, ep.Season, ep.Episode) if err != nil { return err } if err := l.DeleteShowEpisode(oldEpisode, log); err != nil { return err } } // Add the show if err := l.addShow(ep, log); err != nil { return err } // Create show season dir if necessary seasonDir := l.getSeasonDir(ep) if !exists(seasonDir) { if err := os.Mkdir(seasonDir, os.ModePerm); err != nil { return err } } // Move the file // If the show episode already in the right dir there is nothing to do if path.Dir(ep.Path) == seasonDir { log.Debug("show episode already in the destination folder") return nil } // Save the old path oldPath := ep.Path // Move the episode into the folder newPath := filepath.Join(seasonDir, path.Base(ep.Path)) log.Debugf("Moving episode to folder Old path: %q, New path: %q", ep.Path, newPath) if err := os.Rename(ep.Path, newPath); err != nil { return err } // Set the new movie path ep.Path = newPath // Create a symlink between the new and the old location if err := os.Symlink(ep.Path, oldPath); err != nil { log.Warnf("Error while making symlink between %s and %s : %+v", oldPath, ep.Path, err) } // Create show NFO if necessary if err := writeNFOFile(ep.NfoPath(), ep); err != nil { return err } return l.showIndex.Add(ep) }
// AddMovie adds a movie to the store func (l *Library) AddMovie(movie *polochon.Movie, log *logrus.Entry) error { if movie.Path == "" { return ErrMissingMovieFilePath } // Check if the movie is already in the library ok, err := l.HasMovie(movie.ImdbID) if err != nil { return err } if ok { // Get the old movie path from the index oldMovie, err := l.GetMovie(movie.ImdbID) if err != nil { return err } // Delete it if err := l.DeleteMovie(oldMovie, log); err != nil { return err } } storePath := l.getMovieDir(movie) // If the movie already in the right dir there is nothing to do if path.Dir(movie.Path) == storePath { log.Debug("Movie already in the destination folder") return nil } // Remove movie dir if it exisits if ok := exists(storePath); ok { log.Debug("Movie folder exists, remove it") if err := os.RemoveAll(storePath); err != nil { return err } } // Create the folder if err := os.Mkdir(storePath, os.ModePerm); err != nil { return err } // Move the movie into the folder newPath := filepath.Join(storePath, path.Base(movie.Path)) // Save the old path oldPath := movie.Path log.Debugf("Old path: %q, new path %q", movie.Path, newPath) if err := os.Rename(movie.Path, newPath); err != nil { return err } // Set the new movie path movie.Path = newPath // Create a symlink between the new and the old location if err := os.Symlink(movie.Path, oldPath); err != nil { log.Warnf("Error while making symlink between %s and %s : %+v", oldPath, movie.Path, err) } // Write NFO into the file if err := writeNFOFile(movie.NfoPath(), movie); err != nil { return err } // At this point the video is stored if err := l.movieIndex.Add(movie); err != nil { return err } if movie.Fanart == "" || movie.Thumb == "" { return ErrMissingMovieImageURL } // Download images for _, img := range []struct { url string savePath string }{ { url: movie.Fanart, savePath: movie.MovieFanartPath(), }, { url: movie.Thumb, savePath: movie.MovieThumbPath(), }, } { if err := download(img.url, img.savePath); err != nil { return err } } return nil }