Compare commits
No commits in common. "master" and "v0.1.1" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -16,7 +16,7 @@
|
|||||||
*.out
|
*.out
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
vendor/
|
# vendor/
|
||||||
|
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
@ -1,24 +1,10 @@
|
|||||||
pipeline:
|
pipeline:
|
||||||
build_test:
|
build:
|
||||||
image: golang:1.16
|
|
||||||
commands:
|
|
||||||
- go build
|
|
||||||
|
|
||||||
test:
|
|
||||||
image: golang:1.16
|
|
||||||
commands:
|
|
||||||
- apt update
|
|
||||||
- apt install -f lsof
|
|
||||||
- go test -v ./...
|
|
||||||
|
|
||||||
build_release:
|
|
||||||
image: golang:1.16
|
image: golang:1.16
|
||||||
commands:
|
commands:
|
||||||
- go mod vendor
|
- go mod vendor
|
||||||
- GOOS=linux GOARCH=amd64 go build -ldflags "-X git.metaunix.net/BitGoblin/adept/cmd.version=${CI_COMMIT_TAG}" -o "dist/adept-linux-amd64-${CI_COMMIT_TAG}"
|
- GOOS=linux GOARCH=amd64 go build -o "dist/adept-linux-amd64-${CI_COMMIT_TAG}"
|
||||||
- GOOS=windows GOARCH=amd64 go build -ldflags "-X git.metaunix.net/BitGoblin/adept/cmd.version=${CI_COMMIT_TAG}" -o "dist/adept-windows-amd64-${CI_COMMIT_TAG}.exe"
|
- GOOS=windows GOARCH=amd64 go build -o "dist/adept-windows-amd64-${CI_COMMIT_TAG}.exe"
|
||||||
when:
|
|
||||||
event: tag
|
|
||||||
|
|
||||||
gitea_release:
|
gitea_release:
|
||||||
image: plugins/gitea-release
|
image: plugins/gitea-release
|
||||||
|
38
Makefile
38
Makefile
@ -1,38 +0,0 @@
|
|||||||
BINARY_NAME=adept
|
|
||||||
|
|
||||||
all: build test
|
|
||||||
|
|
||||||
compile:
|
|
||||||
go build -o ${BINARY_NAME} adept.go
|
|
||||||
|
|
||||||
test:
|
|
||||||
go test -v ./...
|
|
||||||
|
|
||||||
run:
|
|
||||||
go build -o ${BINARY_NAME} adept.go
|
|
||||||
./${BINARY_NAME}
|
|
||||||
|
|
||||||
install:
|
|
||||||
useradd ${BINARY_NAME}
|
|
||||||
usermod -aG ${BINARY_NAME} ${BINARY_NAME}
|
|
||||||
cp ./${BINARY_NAME} /usr/bin/${BINARY_NAME}
|
|
||||||
chown root:root /usr/bin/${BINARY_NAME}
|
|
||||||
chmod 755 /usr/bin/${BINARY_NAME}
|
|
||||||
cp ./build/etc/systemd/system/${BINARY_NAME}.service /etc/systemd/system/${BINARY_NAME}.service
|
|
||||||
chown root:root /etc/systemd/system/${BINARY_NAME}.service
|
|
||||||
chmod 644 /etc/systemd/system/${BINARY_NAME}.service
|
|
||||||
mkdir /etc/${BINARY_NAME}
|
|
||||||
cp ./build/etc/${BINARY_NAME}/${BINARY_NAME}.toml /etc/${BINARY_NAME}/
|
|
||||||
chown -R ${BINARY_NAME}:${BINARY_NAME} /etc/${BINARY_NAME}
|
|
||||||
chmod 644 /etc/${BINARY_NAME}/${BINARY_NAME}.toml
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
userdel ${BINARY_NAME}
|
|
||||||
rm /usr/bin/${BINARY_NAME}
|
|
||||||
rm /etc/systemd/system/${BINARY_NAME}.service
|
|
||||||
rm -rf /etc/${BINARY_NAME}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
go clean
|
|
||||||
|
|
||||||
.PHONY: all test clean
|
|
23
README.md
23
README.md
@ -1,24 +1,3 @@
|
|||||||
# adept
|
# adept
|
||||||
|
|
||||||
Bit Goblin video transcoder service
|
Bit Goblin video transcoder service
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
**Note: currently Adept will only run on Linux as `lsof` is a runtime dependency, which doesn't have a Windows equivalent. This will be rectified in the future.**
|
|
||||||
|
|
||||||
Build dependencies:
|
|
||||||
* go
|
|
||||||
* make
|
|
||||||
|
|
||||||
Runtime dependencies:
|
|
||||||
* ffmpeg
|
|
||||||
* lsof
|
|
||||||
|
|
||||||
To install dependencies on Ubuntu: `apt install golang make ffmpeg lsof`
|
|
||||||
To install dependencies on Red Hat/AlmaLinux: `dnf install go make ffmpeg lsof`
|
|
||||||
|
|
||||||
To install Adept as a system service: `make build && sudo make install`
|
|
||||||
|
|
||||||
## Uninstallation
|
|
||||||
|
|
||||||
To uninstall Adept (if it was installed through make): `sudo make uninstall`
|
|
33
adept.go
33
adept.go
@ -1,21 +1,34 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.metaunix.net/BitGoblin/adept/cmd"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"git.metaunix.net/BitGoblin/adept/config"
|
"git.metaunix.net/BitGoblin/adept/config"
|
||||||
|
"git.metaunix.net/BitGoblin/adept/transcoder"
|
||||||
)
|
)
|
||||||
|
|
||||||
// start the app - that's where all the good stuff happens
|
|
||||||
func main() {
|
func main() {
|
||||||
// load configuration via Viper
|
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
// configure our app logging
|
r := transcoder.NewRepository(viper.GetString("transcoder.repository"))
|
||||||
logHandle := config.InitLogging()
|
|
||||||
if logHandle != nil {
|
|
||||||
defer logHandle.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// launch the Cobra CLI framework
|
// main program loop - runs infinitely until externally terminated
|
||||||
cmd.Execute()
|
for {
|
||||||
|
ingestFiles := r.SearchIngest()
|
||||||
|
|
||||||
|
for _, i := range ingestFiles {
|
||||||
|
// archive file
|
||||||
|
r.ArchiveFile(i.Name())
|
||||||
|
// transcode file
|
||||||
|
transcoder.Transcode(i.Name())
|
||||||
|
// clean up source file
|
||||||
|
r.CleanupFile(i.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// sleep for X minutes - specified in the adept.toml config file
|
||||||
|
interval := viper.GetInt("transcoder.interval")
|
||||||
|
time.Sleep(time.Duration(interval) * time.Minute)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check that we've been supplied a valid version
|
|
||||||
VERSION="$1"
|
|
||||||
if [ "$VERSION" == "" ]; then
|
|
||||||
echo -e "You must supply a version tag like './build_deb.sh 1.2.3'."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Trim the leading 'v' from version number
|
|
||||||
if [[ "${VERSION:0:1}" == "v" ]]; then
|
|
||||||
VERSION="${VERSION:1}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create workspace for our deb package
|
|
||||||
WORKDIR="adept_$VERSION"
|
|
||||||
mkdir "$WORKDIR"
|
|
||||||
|
|
||||||
# Copy build sources into workspace
|
|
||||||
cp -r build/etc "$WORKDIR/"
|
|
||||||
mkdir -p "$WORKDIR/usr/bin/"
|
|
||||||
cp "dist/adept-linux-amd64-v$VERSION" "$WORKDIR/usr/bin/adept"
|
|
||||||
|
|
||||||
# Create debian control file
|
|
||||||
mkdir "$WORKDIR/DEBIAN"
|
|
||||||
cat > "$WORKDIR/DEBIAN/control"<< EOF
|
|
||||||
Package: adept
|
|
||||||
Version: $VERSION
|
|
||||||
Section: video
|
|
||||||
Priority: optional
|
|
||||||
Architecture: amd64
|
|
||||||
Depends: ffmpeg (>= 4), lsof
|
|
||||||
Maintainer: Gregory Ballantine <gballantine@bitgoblin.tech>
|
|
||||||
Description: Bit Goblin video transcoding service.
|
|
||||||
EOF
|
|
||||||
# Copy maintainer scripts
|
|
||||||
cp build/scripts/* "$WORKDIR/DEBIAN/"
|
|
||||||
#chmod +rx "$WORKDIR"/DEBIAN/pre*
|
|
||||||
chmod +rx "$WORKDIR"/DEBIAN/post*
|
|
||||||
|
|
||||||
# Build deb package!
|
|
||||||
dpkg-deb --build "$WORKDIR"
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
rm -rf "$WORKDIR"
|
|
@ -1,74 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check that we've been supplied a valid version
|
|
||||||
VERSION="$1"
|
|
||||||
if [ "$VERSION" == "" ]; then
|
|
||||||
echo -e "You must supply a version tag like './build_rpm.sh 1.2.3'."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Trim the leading 'v' from version number
|
|
||||||
if [[ "${VERSION:0:1}" == "v" ]]; then
|
|
||||||
VERSION="${VERSION:1}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Tar up source files
|
|
||||||
mkdir rpm-temp
|
|
||||||
cp -r cmd config transcoder util adept.go go.mod go.sum LICENSE Makefile README.md rpm-temp/
|
|
||||||
tar cvzf "adept-$VERSION.tar.gz" rpm-temp/*
|
|
||||||
mv "adept-$VERSION.tar.gz" ~/rpmbuild/SOURCES/
|
|
||||||
|
|
||||||
# Create debian control file
|
|
||||||
cat > "./adept.spec"<< EOF
|
|
||||||
Name: adept
|
|
||||||
Version: $VERSION
|
|
||||||
Release: 1%{?dist}
|
|
||||||
Summary: Bit Goblin video transcoding service
|
|
||||||
|
|
||||||
License: BSD 2-Clause
|
|
||||||
Source0: %{name}-%{version}.tar.gz
|
|
||||||
|
|
||||||
BuildRequires: golang
|
|
||||||
BuildRequires: systemd-rpm-macros
|
|
||||||
|
|
||||||
Provides: %{name} = %{version}
|
|
||||||
|
|
||||||
%description
|
|
||||||
Bit Goblin video transcoding service
|
|
||||||
|
|
||||||
%global debug_package %{nil}
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%autosetup
|
|
||||||
|
|
||||||
|
|
||||||
%build
|
|
||||||
go build -v -o %{name}
|
|
||||||
|
|
||||||
|
|
||||||
%install
|
|
||||||
install -Dpm 0755 %{name} %{buildroot}%{_bindir}/%{name}
|
|
||||||
install -Dpm 0755 build/etc/%{name}/%{name}.toml %{buildroot}%{_sysconfdir}/%{name}/%{name}.toml
|
|
||||||
install -Dpm 644 build/etc/systemd/%{name}.service %{buildroot}%{_unitdir}/%{name}.service
|
|
||||||
|
|
||||||
%check
|
|
||||||
# go test should be here... :)
|
|
||||||
|
|
||||||
%post
|
|
||||||
%systemd_post %{name}.service
|
|
||||||
|
|
||||||
%preun
|
|
||||||
%systemd_preun %{name}.service
|
|
||||||
|
|
||||||
%files
|
|
||||||
%dir %{_sysconfdir}/%{name}
|
|
||||||
%{_bindir}/%{name}
|
|
||||||
%{_unitdir}/%{name}.service
|
|
||||||
%config(noreplace) %{_sysconfdir}/%{name}/%{name}.toml
|
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
* Thu Nov 17 2022 Gregory Ballantine $VERSION
|
|
||||||
- check git.metaunix.net/BitGoblin/adept for a changelog
|
|
||||||
EOF
|
|
||||||
|
|
||||||
rpmbuild -ba adept.spec
|
|
@ -1,15 +0,0 @@
|
|||||||
log_to_file = true
|
|
||||||
log_file = '/var/log/adept/adept.log'
|
|
||||||
log_level = 'info'
|
|
||||||
|
|
||||||
[transcoder]
|
|
||||||
repository = '/srv/adept'
|
|
||||||
interval = 15
|
|
||||||
video_format = 'mov'
|
|
||||||
video_codec = 'dnxhd'
|
|
||||||
video_profile = 'dnxhr_hq'
|
|
||||||
video_resolution = '1920x1080'
|
|
||||||
video_framerate = 60
|
|
||||||
video_color = 'yuv422p'
|
|
||||||
audio_codec = 'pcm_s16le'
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Adept video transcoder service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=adept
|
|
||||||
Group=adept
|
|
||||||
ExecStart=/usr/bin/adept
|
|
||||||
SuccessExitStatus=143
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
@ -1,36 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
GETENT_USER=$(getent passwd adept)
|
|
||||||
# Create the adept user if it doesn't already exist
|
|
||||||
if [ "$GETENT_USER" = "" ]; then
|
|
||||||
echo "Creating the 'adept' user."
|
|
||||||
useradd -r adept
|
|
||||||
else
|
|
||||||
echo "The 'adept' user already exists, skipping creation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
GETENT_GROUP=$(getent group adept)
|
|
||||||
# Create the adept group if it doesn't already exist
|
|
||||||
if [ "$GETENT_GROUP" = "" ]; then
|
|
||||||
echo "Creating the 'adept' group."
|
|
||||||
groupadd adept
|
|
||||||
usermod -aG adept adept
|
|
||||||
else
|
|
||||||
echo "The 'adept' group already exists, skipping creation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Change the directory ownership of /etc
|
|
||||||
chown -R adept:adept /etc/adept
|
|
||||||
|
|
||||||
# Create the log directory under /var/log
|
|
||||||
if [ ! -d /var/log/adept ]; then
|
|
||||||
echo "Creating /var/log/adept to store log files."
|
|
||||||
mkdir /var/log/adept
|
|
||||||
chown adept:adept /var/log/adept
|
|
||||||
else
|
|
||||||
echo "/var/log/adept already exists, skipping creation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
#DEBHELPER#
|
|
||||||
|
|
||||||
exit 0
|
|
35
cmd/root.go
35
cmd/root.go
@ -1,35 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
"git.metaunix.net/BitGoblin/adept/transcoder"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ./adept - this is the primary command and is how the service is intended to be launched
|
|
||||||
var rootCmd = &cobra.Command{
|
|
||||||
Use: "adept",
|
|
||||||
Short: "Adept is a video transcoder service",
|
|
||||||
Long: `An automated video transcoder service that archives ingested footage.
|
|
||||||
https://git.metaunix.net/BitGoblin/adept`,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
// initialize the video repository
|
|
||||||
r := transcoder.NewRepository(viper.GetString("transcoder.repository"))
|
|
||||||
|
|
||||||
// create transcoder object and start the main loop
|
|
||||||
t := transcoder.NewTranscoder(*r)
|
|
||||||
t.Start()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the main function to launch Cobra
|
|
||||||
func Execute() {
|
|
||||||
if err := rootCmd.Execute(); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
24
cmd/setup.go
24
cmd/setup.go
@ -1,24 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
"git.metaunix.net/BitGoblin/adept/transcoder"
|
|
||||||
)
|
|
||||||
|
|
||||||
// initializes the sub-command
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(setupCmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
var setupCmd = &cobra.Command{
|
|
||||||
Use: "setup",
|
|
||||||
Short: "Initialize the video directories.",
|
|
||||||
Long: `Adept can't run gif it doesn't have a place to ingest/transcode files from.`,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
// initialize the video repository
|
|
||||||
r := transcoder.NewRepository(viper.GetString("transcoder.repository"))
|
|
||||||
r.Setup()
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
version string
|
|
||||||
)
|
|
||||||
|
|
||||||
// initializes the sub-command
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(versionCmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
var versionCmd = &cobra.Command{
|
|
||||||
Use: "version",
|
|
||||||
Short: "Display version info.",
|
|
||||||
Long: `In case you're curious, run this command to find out the version info.`,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
log.Printf("Adept version %s", version)
|
|
||||||
log.Printf("Built with Go %s", runtime.Version())
|
|
||||||
log.Printf("View source at https://git.metaunix.net/BitGoblin/adept")
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
"git.metaunix.net/BitGoblin/adept/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitLogging() *os.File {
|
|
||||||
var fileHandle *os.File = nil
|
|
||||||
|
|
||||||
if viper.GetBool("log_to_file") {
|
|
||||||
// open a file
|
|
||||||
var err error
|
|
||||||
fileHandle, err = os.OpenFile(util.ResolveTilde(viper.GetString("log_file")), os.O_APPEND | os.O_CREATE | os.O_RDWR, 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error opening log file: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a MultiWriter instance so we can write to both console AND file
|
|
||||||
mw := io.MultiWriter(os.Stdout, fileHandle)
|
|
||||||
// set our multiwriter object as the output for logging
|
|
||||||
log.SetOutput(mw)
|
|
||||||
|
|
||||||
return fileHandle
|
|
||||||
}
|
|
3
go.mod
3
go.mod
@ -11,14 +11,13 @@ require (
|
|||||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||||
github.com/spf13/afero v1.8.2 // indirect
|
github.com/spf13/afero v1.8.2 // indirect
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/cobra v1.5.0 // indirect
|
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/spf13/viper v1.12.0
|
github.com/spf13/viper v1.12.0
|
||||||
github.com/stretchr/testify v1.8.0 // indirect
|
|
||||||
github.com/subosito/gotenv v1.3.0 // indirect
|
github.com/subosito/gotenv v1.3.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
gopkg.in/ini.v1 v1.66.4 // indirect
|
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0 // indirect
|
||||||
)
|
)
|
||||||
|
14
go.sum
14
go.sum
@ -93,10 +93,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
|
|||||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
@ -240,8 +238,6 @@ github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpT
|
|||||||
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
@ -305,7 +301,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||||
@ -330,7 +325,6 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
|||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
|
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
@ -342,8 +336,6 @@ github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
|
|||||||
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
|
||||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||||
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
|
|
||||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
@ -352,8 +344,6 @@ github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
|
|||||||
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
|
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
@ -361,8 +351,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
||||||
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
|
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
|
||||||
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
|
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
@ -854,8 +842,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
|
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
|
||||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
@ -8,45 +8,31 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
basePath string
|
basePath string
|
||||||
ingestPath string
|
|
||||||
archivePath string
|
|
||||||
outputPath string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repository struct constructor
|
|
||||||
func NewRepository(path string) *Repository {
|
func NewRepository(path string) *Repository {
|
||||||
|
// make sure repository base directory exists
|
||||||
|
create_repo_dir(path)
|
||||||
|
|
||||||
|
// make sure the ingest, archive, and output directories exist
|
||||||
|
subDirs := []string{"ingest", "archive", "output"}
|
||||||
|
for _, d := range subDirs {
|
||||||
|
subPath := filepath.Join(path, d)
|
||||||
|
create_repo_dir(subPath)
|
||||||
|
}
|
||||||
|
|
||||||
r := new(Repository)
|
r := new(Repository)
|
||||||
r.basePath = path
|
r.basePath = path
|
||||||
r.ingestPath = filepath.Join(path, "ingest")
|
|
||||||
r.archivePath = filepath.Join(path, "archive")
|
|
||||||
r.outputPath = filepath.Join(path, "output")
|
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repository getters
|
|
||||||
func (r *Repository) GetIngestPath() string {
|
|
||||||
return r.ingestPath
|
|
||||||
}
|
|
||||||
func (r *Repository) GetOutputPath() string {
|
|
||||||
return r.outputPath
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes the video repository by ensuring the directories are available
|
|
||||||
func (r *Repository) Setup() {
|
|
||||||
// make sure repository base directory exists
|
|
||||||
create_repo_dir(r.basePath)
|
|
||||||
// make sure the folder structure is setup
|
|
||||||
create_repo_dir(r.ingestPath)
|
|
||||||
create_repo_dir(r.archivePath)
|
|
||||||
create_repo_dir(r.archivePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Repository) SearchIngest() []os.FileInfo {
|
func (r *Repository) SearchIngest() []os.FileInfo {
|
||||||
|
ingestPath := filepath.Join(r.basePath, "ingest")
|
||||||
|
|
||||||
log.Printf("Searching ingest directory for files to transcode...")
|
log.Printf("Searching ingest directory for files to transcode...")
|
||||||
|
|
||||||
ingestDir, err := os.Open(r.ingestPath)
|
ingestDir, err := os.Open(ingestPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error opening ingest directory: %s", err)
|
log.Fatalf("Error opening ingest directory: %s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -62,29 +48,27 @@ func (r *Repository) SearchIngest() []os.FileInfo {
|
|||||||
|
|
||||||
func (r *Repository) ArchiveFile(inFile string) {
|
func (r *Repository) ArchiveFile(inFile string) {
|
||||||
// create ingest and archive paths
|
// create ingest and archive paths
|
||||||
ingestFilePath := filepath.Join(r.ingestPath, inFile)
|
ingestPath := filepath.Join(r.basePath, "ingest", inFile)
|
||||||
archiveFilePath := filepath.Join(r.archivePath, inFile)
|
archivePath := filepath.Join(r.basePath, "archive", inFile)
|
||||||
|
|
||||||
log.Printf("Copying %s to the archive.", ingestFilePath)
|
log.Printf("Copying %s to the archive.", ingestPath)
|
||||||
|
|
||||||
// open ingest file
|
// open ingest file
|
||||||
source, err := os.Open(ingestFilePath)
|
source, err := os.Open(ingestPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error opening file in ingest: %s.", err)
|
log.Fatalf("Error opening file in ingest: %s.", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
sourceStat, _ := source.Stat()
|
|
||||||
sourceMode := sourceStat.Mode()
|
|
||||||
defer source.Close()
|
defer source.Close()
|
||||||
|
|
||||||
// attempt to create destination file
|
// attempt to create destination file
|
||||||
destination, err := os.Create(archiveFilePath)
|
destination, err := os.Create(archivePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error opening archive file: %s.", err)
|
log.Fatalf("Error opening archive file: %s.", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer destination.Close()
|
defer destination.Close()
|
||||||
destination.Chmod(sourceMode)
|
destination.Chmod(0755)
|
||||||
|
|
||||||
// perform the file copy
|
// perform the file copy
|
||||||
_, err = io.Copy(destination, source)
|
_, err = io.Copy(destination, source)
|
||||||
@ -96,10 +80,10 @@ func (r *Repository) ArchiveFile(inFile string) {
|
|||||||
|
|
||||||
func (r *Repository) CleanupFile(inFile string) {
|
func (r *Repository) CleanupFile(inFile string) {
|
||||||
// create ingest path
|
// create ingest path
|
||||||
ingestFilePath := filepath.Join(r.ingestPath, inFile)
|
ingestPath := filepath.Join(r.basePath, "ingest", inFile)
|
||||||
|
|
||||||
// remove the file
|
// remove the file
|
||||||
os.Remove(ingestFilePath)
|
os.Remove(ingestPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func create_repo_dir(path string) {
|
func create_repo_dir(path string) {
|
||||||
|
@ -6,61 +6,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"git.metaunix.net/BitGoblin/adept/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Transcoder struct {
|
func Transcode(inFile string) {
|
||||||
repo Repository
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transcoder object constructor
|
|
||||||
func NewTranscoder(r Repository) *Transcoder {
|
|
||||||
t := new(Transcoder)
|
|
||||||
t.repo = r
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the main transcoder loop
|
|
||||||
func (t *Transcoder) Start() {
|
|
||||||
// main program loop - runs infinitely until externally terminated
|
|
||||||
for {
|
|
||||||
ingestFiles := t.repo.SearchIngest()
|
|
||||||
|
|
||||||
if len(ingestFiles) < 1 {
|
|
||||||
log.Println("There were no files found in ingest to transcode; skipping run.")
|
|
||||||
} else {
|
|
||||||
for _, i := range ingestFiles {
|
|
||||||
// check if the file is open in another program (e.g. still being written to)
|
|
||||||
if util.IsFileLocked(filepath.Join(t.repo.GetIngestPath(), i.Name())) {
|
|
||||||
log.Printf("%s appears to be open in another program; skipping it for this run.", i.Name())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// archive file
|
|
||||||
t.repo.ArchiveFile(i.Name())
|
|
||||||
// transcode file
|
|
||||||
t.Transcode(i.Name())
|
|
||||||
// clean up source file
|
|
||||||
t.repo.CleanupFile(i.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sleep for X minutes - specified in the adept.toml config file
|
|
||||||
interval := viper.GetInt("transcoder.interval")
|
|
||||||
time.Sleep(time.Duration(interval) * time.Minute)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Transcoder) Transcode(inFile string) {
|
|
||||||
// create ingest and archive paths
|
// create ingest and archive paths
|
||||||
ingestPath := filepath.Join(t.repo.GetIngestPath(), inFile)
|
ingestPath := filepath.Join(viper.GetString("transcoder.repository"), "ingest", inFile)
|
||||||
outputName := strings.Join([]string{util.FilenameWithoutExtension(inFile), viper.GetString("transcoder.video_format")}, ".")
|
outputPath := filepath.Join(viper.GetString("transcoder.repository"), "output", inFile)
|
||||||
outputPath := filepath.Join(t.repo.GetOutputPath(), outputName)
|
|
||||||
|
|
||||||
log.Printf("Transcoding video file %s.", ingestPath)
|
log.Printf("Transcoding video file %s.", ingestPath)
|
||||||
|
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
)
|
|
||||||
|
|
||||||
// define our test suite struct
|
|
||||||
type EnvTestSuite struct {
|
|
||||||
suite.Suite
|
|
||||||
}
|
|
||||||
|
|
||||||
// the tilde should expand to user's home directory
|
|
||||||
func (s *EnvTestSuite) TestResolveTilde() {
|
|
||||||
resolvedPath := ResolveTilde("~")
|
|
||||||
assert.NotEqual(s.T(), resolvedPath, "~")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the tilde + relative path gets expanded fully
|
|
||||||
func (s *EnvTestSuite) TestResolveTildePath() {
|
|
||||||
resolvedPath := ResolveTilde("~/test")
|
|
||||||
assert.NotEqual(s.T(), resolvedPath, "~/test")
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed to run the test suite
|
|
||||||
func TestEnvTestSuite(t *testing.T) {
|
|
||||||
suite.Run(t, new(EnvTestSuite))
|
|
||||||
}
|
|
12
util/file.go
12
util/file.go
@ -1,7 +1,6 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -9,14 +8,3 @@ import (
|
|||||||
func FilenameWithoutExtension(filename string) string {
|
func FilenameWithoutExtension(filename string) string {
|
||||||
return strings.TrimSuffix(filename, path.Ext(filename))
|
return strings.TrimSuffix(filename, path.Ext(filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsFileLocked(filepath string) bool {
|
|
||||||
cmd := exec.Command("/usr/bin/lsof", filepath)
|
|
||||||
stdout, _ := cmd.Output()
|
|
||||||
|
|
||||||
if strings.Contains(string(stdout), filepath) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
)
|
|
||||||
|
|
||||||
// define our test suite struct
|
|
||||||
type FileTestSuite struct {
|
|
||||||
suite.Suite
|
|
||||||
TestFile string
|
|
||||||
}
|
|
||||||
|
|
||||||
// run before tests to set up
|
|
||||||
func (s *FileTestSuite) SetupSuite() {
|
|
||||||
s.TestFile = "testfile.txt"
|
|
||||||
// create the test file for file lock testing
|
|
||||||
file, _ := os.Create(s.TestFile)
|
|
||||||
file.Close() // do this just to make extra sure the file handle is closed
|
|
||||||
}
|
|
||||||
// run after tests to clean up
|
|
||||||
func (s *FileTestSuite) TearDownSuite() {
|
|
||||||
// remove the test file since it's no longer needed
|
|
||||||
os.Remove(s.TestFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// test the filename extension removal works
|
|
||||||
func (s *FileTestSuite) TestFilenameWithoutExtension() {
|
|
||||||
filename := FilenameWithoutExtension(s.TestFile)
|
|
||||||
|
|
||||||
if filename != "testfile" {
|
|
||||||
s.T().Logf("FilenameWithoutExtension returned '%s'; it should be 'testfile'.", filename)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// test that IsFileLocked returns true when the file is active
|
|
||||||
func (s *FileTestSuite) TestFileShouldBeLocked() {
|
|
||||||
file, err := os.Open(s.TestFile)
|
|
||||||
if err != nil {
|
|
||||||
s.T().Logf("Unable to open file %s: %s", s.TestFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.True(s.T(), IsFileLocked(s.TestFile))
|
|
||||||
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// test that IsFileLocked returns false when the file is not active
|
|
||||||
func (s *FileTestSuite) TestFileShouldNotBeLocked() {
|
|
||||||
file, err := os.Open(s.TestFile)
|
|
||||||
if err != nil {
|
|
||||||
s.T().Logf("Unable to open file %s: %s", s.TestFile, err)
|
|
||||||
}
|
|
||||||
file.Close() // we want this closed now so it's NOT open!
|
|
||||||
|
|
||||||
assert.False(s.T(), IsFileLocked(s.TestFile))
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is needed to run the test suite
|
|
||||||
func TestFileTestSuite(t *testing.T) {
|
|
||||||
suite.Run(t, new(FileTestSuite))
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user