Browse Source

Restructure code + switch to RWMutex

master
PrivateGER 3 years ago
parent
commit
979f59a13d
Signed by: PrivateGER GPG Key ID: CAE625C962F94C67
  1. 26
      DirectoryIndexers/DirectoryIndexer.go
  2. 43
      PageHandlers/Index.go
  3. 66
      PageHandlers/Search.go
  4. 58
      PageHandlers/View.go
  5. 0
      PageHandlers/templates/index.html
  6. 0
      PageHandlers/templates/search.html
  7. 11
      PageHandlers/templates/view.html
  8. 4
      go.mod
  9. 139
      main.go

26
DirectoryIndexer.go → DirectoryIndexers/DirectoryIndexer.go

@ -1,4 +1,4 @@
package main
package DirectoryIndexers
import (
"fmt"
@ -11,8 +11,8 @@ import (
)
type FileList struct {
files map[string]VideoFile
mu sync.Mutex
Files map[string]VideoFile
*sync.RWMutex
}
type VideoFile struct {
@ -22,13 +22,12 @@ type VideoFile struct {
Id string
}
var FL FileList
func Index(path string, results chan FileList) {
var FL FileList
func ScanDirectory(group *sync.WaitGroup, path string) {
defer group.Done()
FL.mu.Lock()
defer FL.mu.Unlock()
// 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...")
@ -38,7 +37,7 @@ func ScanDirectory(group *sync.WaitGroup, path string) {
return
}
FL.files = make(map[string]VideoFile)
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
@ -57,7 +56,7 @@ func ScanDirectory(group *sync.WaitGroup, path string) {
id := filenameToID(video.Name())
FL.files[id] = VideoFile{
FL.Files[id] = VideoFile{
Filename: video.Name(),
Extension: extension,
Title: filenameToTitle(video.Name(), extension),
@ -65,6 +64,11 @@ func ScanDirectory(group *sync.WaitGroup, path string) {
}
}
FL.Unlock()
results <- FL
close(results)
fmt.Println("Archive scan finished.")
}

43
PageHandlers/Index.go

@ -0,0 +1,43 @@
package PageHandlers
import (
_ "embed"
"fmt"
"html/template"
"net/http"
"strconv"
"ytdlp-viewer/DirectoryIndexers"
)
//go:embed templates/index.html
var indexTmplSource string
var indexTmpl *template.Template
type IndexPageData struct {
FileCount string
Files map[string]DirectoryIndexers.VideoFile
}
func init() {
var err error
indexTmpl = template.New("index.tmpl")
indexTmpl, err = indexTmpl.Parse(indexTmplSource)
if err != nil {
fmt.Println(err)
}
}
func Index(writer http.ResponseWriter, request *http.Request, FL *DirectoryIndexers.FileList) {
FL.RLock()
defer FL.RUnlock()
data := IndexPageData{
FileCount: strconv.Itoa(len(FL.Files)),
Files: FL.Files,
}
err := indexTmpl.Execute(writer, data)
if err != nil {
fmt.Println(err)
}
}

66
PageHandlers/Search.go

@ -0,0 +1,66 @@
package PageHandlers
import (
_ "embed"
"fmt"
"html/template"
"log"
"net/http"
"strconv"
"strings"
"ytdlp-viewer/DirectoryIndexers"
)
//go:embed templates/search.html
var searchTmplSource string
var searchTmpl *template.Template
func init() {
var err error
searchTmpl = template.New("search.tmpl")
searchTmpl, err = searchTmpl.Parse(searchTmplSource)
if err != nil {
fmt.Println(err)
}
}
type SearchPageData struct {
Results []DirectoryIndexers.VideoFile
ResultCount string
SearchTerm string
}
func SearchHandler(writer http.ResponseWriter, request *http.Request, FL *DirectoryIndexers.FileList) {
FL.RLock()
defer FL.RUnlock()
keys, ok := request.URL.Query()["term"]
if !ok || len(keys[0]) < 1 {
log.Println("Url Param 'term' is missing")
return
}
var results []DirectoryIndexers.VideoFile
for _, video := range FL.Files {
if video.Id == keys[0] {
results = append(results, video)
break
}
if strings.Contains(strings.ToUpper(video.Title), strings.ToUpper(keys[0])) {
results = append(results, video)
continue
}
}
data := SearchPageData{
Results: results,
ResultCount: strconv.Itoa(len(results)),
SearchTerm: keys[0],
}
err := searchTmpl.Execute(writer, data)
if err != nil {
fmt.Println(err)
}
}

58
PageHandlers/View.go

@ -0,0 +1,58 @@
package PageHandlers
import (
_ "embed"
"fmt"
"html/template"
"log"
"net/http"
"ytdlp-viewer/DirectoryIndexers"
)
//go:embed templates/view.html
var viewTmplSource string
var viewTmpl *template.Template
type ViewPageData struct {
Title string
Filename string
Id string
Extension string
}
func init() {
var err error
viewTmpl = template.New("view.tmpl")
viewTmpl, err = viewTmpl.Parse(viewTmplSource)
if err != nil {
fmt.Println(err)
}
}
func View(writer http.ResponseWriter, request *http.Request, FL *DirectoryIndexers.FileList) {
FL.RLock()
defer FL.RUnlock()
keys, ok := request.URL.Query()["id"]
if !ok || len(keys[0]) < 1 {
log.Println("Url Param 'id' is missing")
return
}
if _, ok := FL.Files[keys[0]]; !ok {
return
}
video := FL.Files[keys[0]]
data := ViewPageData{
Title: video.Title,
Filename: video.Filename,
Id: video.Id,
Extension: video.Extension,
}
err := viewTmpl.Execute(writer, data)
if err != nil {
fmt.Println(err)
}
}

0
templates/index.html → PageHandlers/templates/index.html

0
templates/search.html → PageHandlers/templates/search.html

11
templates/view.html → PageHandlers/templates/view.html

@ -5,16 +5,23 @@
<title>{{.Title}} | {{.Id}}</title>
<link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/videojs-seek-buttons/dist/videojs-seek-buttons.css" rel="stylesheet">
<style>
.centeredvideo {
display: block;
margin-left: auto;
margin-right: auto
}
</style>
</head>
<body>
<video class="video-js vjs-big-play-centered" id="player" height="480" width="720" controls autoplay data-setup="{}">
<video class="video-js vjs-big-play-centered centeredvideo" id="player" height="480" width="720" controls autoplay data-setup="{}">
<source src="/videos/{{.Filename}}">
</video>
<h1>{{.Title}}</h1>
<p>Filetype: {{.Extension}}</p>
<p>Youtube ID: {{.Id}}</p>
<p>Filename: {{.Filename}}</p>
<a href="/videos/{{.Filename}}">direct video link</a>
<a href="/videos/{{.Filename}}">Direct video link</a>
<script src="https://vjs.zencdn.net/7.15.4/video.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/videojs-seek-buttons/dist/videojs-seek-buttons.min.js"></script>

4
go.mod

@ -2,6 +2,4 @@ module ytdlp-viewer
go 1.17
require github.com/dlclark/regexp v1.4.0
require github.com/dlclark/regexp2 v1.4.0 // indirect
require github.com/dlclark/regexp2 v1.4.0

139
main.go

@ -3,154 +3,45 @@ package main
import (
_ "embed"
"fmt"
"log"
"net/http"
"os"
"strconv"
"strings"
"sync"
"text/template"
"ytdlp-viewer/DirectoryIndexers"
"ytdlp-viewer/PageHandlers"
)
//go:embed templates/index.html
var indexTmplSource string
//go:embed templates/search.html
var searchTmplSource string
//go:embed templates/view.html
var viewTmplSource string
type IndexPageData struct {
FileCount string
Files map[string]VideoFile
}
type SearchPageData struct {
Results []VideoFile
ResultCount string
SearchTerm string
}
type ViewPageData struct {
Title string
Filename string
Id string
Extension string
}
func main() {
path := os.Getenv("directory")
if path == "" {
path = "Z:/MainArchive"
path = "/home/latte/NFS/MainArchive/"
}
var wg sync.WaitGroup
wg.Add(1)
var FL DirectoryIndexers.FileList
resultChannel := make(chan DirectoryIndexers.FileList)
fmt.Println("Starting scanner at", path)
go ScanDirectory(&wg, path)
go DirectoryIndexers.Index(path, resultChannel)
wg.Wait()
FL = <-resultChannel
FL.mu.Lock()
fmt.Println(strconv.Itoa(len(FL.files)))
for _, file := range FL.files {
/*FL.RLock()
fmt.Println(strconv.Itoa(len(FL.Files)))
for _, file := range FL.Files {
fmt.Println("Name:", file.Title,"Extension:", file.Extension, "ID:", file.Id)
}
FL.mu.Unlock()
indexTmpl, err := template.New("index.tmpl").Parse(indexTmplSource)
if err != nil {
fmt.Println(err)
}
searchTmpl, err := template.New("search.tmpl").Parse(searchTmplSource)
if err != nil {
fmt.Println(err)
}
viewTmpl, err := template.New("view.tmpl").Parse(viewTmplSource)
if err != nil {
fmt.Println(err)
}
FL.RUnlock()*/
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
FL.mu.Lock()
defer FL.mu.Unlock()
data := IndexPageData{
FileCount: strconv.Itoa(len(FL.files)),
Files: FL.files,
}
err := indexTmpl.Execute(writer, data)
if err != nil {
fmt.Println(err)
}
PageHandlers.Index(writer, request, &FL)
})
http.HandleFunc("/search", func(writer http.ResponseWriter, request *http.Request) {
FL.mu.Lock()
defer FL.mu.Unlock()
keys, ok := request.URL.Query()["term"]
if !ok || len(keys[0]) < 1 {
log.Println("Url Param 'term' is missing")
return
}
var results []VideoFile
for _, video := range FL.files {
if video.Id == keys[0] {
results = append(results, video)
break
}
if strings.Contains(strings.ToUpper(video.Title), strings.ToUpper(keys[0])) {
results = append(results, video)
continue
}
}
data := SearchPageData{
Results: results,
ResultCount: strconv.Itoa(len(results)),
SearchTerm: keys[0],
}
err := searchTmpl.Execute(writer, data)
if err != nil {
fmt.Println(err)
}
PageHandlers.SearchHandler(writer, request, &FL)
})
http.HandleFunc("/view", func(writer http.ResponseWriter, request *http.Request) {
FL.mu.Lock()
defer FL.mu.Unlock()
keys, ok := request.URL.Query()["id"]
if !ok || len(keys[0]) < 1 {
log.Println("Url Param 'id' is missing")
return
}
if _, ok := FL.files[keys[0]]; !ok {
return
}
video := FL.files[keys[0]]
data := ViewPageData{
Title: video.Title,
Filename: video.Filename,
Id: video.Id,
Extension: video.Extension,
}
err := viewTmpl.Execute(writer, data)
if err != nil {
fmt.Println(err)
}
PageHandlers.View(writer, request, &FL)
})
http.Handle("/videos/", http.StripPrefix("/videos/", http.FileServer(http.Dir(path))))
err = http.ListenAndServe(":8000", nil)
err := http.ListenAndServe(":8000", nil)
if err != nil {
fmt.Println(err)
os.Exit(1)

Loading…
Cancel
Save