You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.1 KiB

package DirectoryIndexers
import (
"fmt"
"github.com/dlclark/regexp2"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"sync"
)
type FileList struct {
Files map[string]VideoFile
*sync.RWMutex
}
type VideoFile struct {
Filename string
Extension string
Title string
Id string
Metadata Metadata
}
func Index(path string, results chan FileList) {
var FL FileList
// Initialize the RWMutex HERE manually because *IT IS A POINTER TO A MUTEX*, so it defaults to a nil value
FL.RWMutex = &sync.RWMutex{}
FL.Lock()
fmt.Println("Scanning archive...")
fileList, err := ioutil.ReadDir(path)
if err != nil {
log.Println(err)
return
}
FL.Files = make(map[string]VideoFile)
for _, video := range fileList {
extension := filepath.Ext(video.Name())[1:]
// check if extension is one of valid yt-dlp extensions, if not ignore file
switch extension {
case "3gp",
"aac",
"flv",
"m4a",
"mp3",
"mp4",
"webm":
break
default:
continue
}
id := filenameToID(video.Name())
videoObject := VideoFile{
Filename: video.Name(),
Extension: extension,
Title: filenameToTitle(video.Name(), extension),
Id: id,
}
metadataFilename := strings.TrimSuffix(video.Name(), filepath.Ext(video.Name())) + ".info.json"
jsonMetadataFile, err := os.Open(path + metadataFilename)
if err != nil {
FL.Files[id] = videoObject
continue
}
metadataBytes, _ := ioutil.ReadAll(jsonMetadataFile)
_ = jsonMetadataFile.Close()
metadata, err := ParseMetadata(metadataBytes)
if err != nil {
FL.Files[id] = videoObject
continue
}
FL.Files[id] = VideoFile{
Filename: video.Name(),
Extension: extension,
Title: filenameToTitle(video.Name(), extension),
Id: id,
Metadata: metadata,
}
}
FL.Unlock()
results <- FL
close(results)
fmt.Println("Archive scan finished.")
}
func filenameToID(filename string) string {
r := regexp2.MustCompile("([^[]+(?=]))", regexp2.RegexOptions(0))
matches := regexp2FindAllString(r, filename)
if len(matches) == 0 {
fmt.Println("Got video without square-bracket ID format. Falling back to youtube-dl 11-char string matching (!THIS MAY CAUSE ISSUES!):", filename)
r = regexp2.MustCompile("-[A-Za-z0-9_-]{11}", regexp2.RegexOptions(0))
matches = regexp2FindAllString(r, filename)
if len(matches) == 0 {
log.Fatal("Got a video file without ID. Please remove or fix: " + filename)
}
// strips first dash away from the result (yes, I know this is DIRTY.
matches = []string{matches[len(matches)-1]}
matches[0] = matches[0][1:]
fmt.Println("Recovered ID:", matches[0])
}
return matches[len(matches)-1] // last element = the id between square brackets
}
func filenameToTitle(filename string, extension string) string {
title := strings.Replace(filename, "[" + filenameToID(filename) + "]", "", 1)
title = strings.Replace(title, "." + extension, "", 1)
title = strings.Replace(title, filenameToID(filename), "", 1)
return title
}
func regexp2FindAllString(re *regexp2.Regexp, s string) []string {
var matches []string
m, _ := re.FindStringMatch(s)
for m != nil {
matches = append(matches, m.String())
m, _ = re.FindNextMatch(m)
}
return matches
}