Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
- move limiter and progress to internal packages
- add mutex to limiter to fix race
- fix bug in limiter preventing accurate limiting
- oauth2 callback server: use context timeout instead of quit channel
- move cli to cmd/youtubeuploader directory
- add Go test
- add Github actions for test, lint and release
  • Loading branch information
porjo committed Oct 13, 2023
1 parent a13795b commit d358ce7
Show file tree
Hide file tree
Showing 22 changed files with 1,155 additions and 617 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/gotest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Go Tests

on:
push:


jobs:
lint:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
cache: false
-
name: golangci-lint
uses: golangci/golangci-lint-action@v3

test:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
-
name: Set up Go
uses: actions/setup-go@v4
-
name: Go tests
run: go test -v -race ./...
32 changes: 32 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: goreleaser

on:
push:
tags:
- '*'

permissions:
contents: write

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- run: git fetch --force --tags
-
name: Set up Go
uses: actions/setup-go@v4
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
*.json
!test/*.json
*.token
!test/*.token
*.mp4
*.avi
*.mkv
Expand All @@ -9,4 +11,5 @@
.*.swp
vendor
youtubeuploader
!cmd/youtubeuploader/
dist/
18 changes: 10 additions & 8 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
- bash check_tag.sh {{.Version}}
# TODO how to verify signed tags without needing to install public key?
#- git tag -v {{.Version}}
builds:
- env:
- CGO_ENABLED=0
main: ./cmd/youtubeuploader
ldflags:
- -X main.appVersion={{.Version}}
targets:
Expand All @@ -22,13 +24,13 @@ builds:
- openbsd_amd64
archives:
-
replacements:
darwin: Darwin
linux: Linux
windows: Windows
amd64: x86_64
freebsd: FreeBSD
openbsd: OpenBSD
name_template: >-
{{- .ProjectName }}_
{{- .Version }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end -}}
format_overrides:
- goos: windows
format: zip
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Youtube Uploader

![Go workflow](https://github.com/porjo/youtubeuploader/actions/workflows/gotest.yml/badge.svg?event=push)

Scripted uploads to youtube.

- upload video files from local disk or from the web.
Expand Down
9 changes: 0 additions & 9 deletions check_tag.sh

This file was deleted.

136 changes: 136 additions & 0 deletions cmd/youtubeuploader/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"context"
"flag"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"strings"

yt "github.com/porjo/youtubeuploader"
"github.com/porjo/youtubeuploader/internal/limiter"
"github.com/porjo/youtubeuploader/internal/utils"
"google.golang.org/api/googleapi"
)

const inputTimeLayout = "15:04"

var (
filename = flag.String("filename", "", "video filename. Can be a URL. Read from stdin with '-'")
thumbnail = flag.String("thumbnail", "", "thumbnail filename. Can be a URL")
caption = flag.String("caption", "", "caption filename. Can be a URL")
title = flag.String("title", "", "video title")
description = flag.String("description", "uploaded by youtubeuploader", "video description")
language = flag.String("language", "en", "video language")
categoryId = flag.String("categoryId", "", "video category Id")
tags = flag.String("tags", "", "comma separated list of video tags")
privacy = flag.String("privacy", "private", "video privacy status")
quiet = flag.Bool("quiet", false, "suppress progress indicator")
rateLimit = flag.Int("ratelimit", 0, "rate limit upload in Kbps. No limit by default")
metaJSON = flag.String("metaJSON", "", "JSON file containing title,description,tags etc (optional)")
metaJSONout = flag.String("metaJSONout", "", "filename to write uploaded video metadata into (optional)")
limitBetween = flag.String("limitBetween", "", "only rate limit between these times e.g. 10:00-14:00 (local time zone)")
oAuthPort = flag.Int("oAuthPort", 8080, "TCP port to listen on when requesting an oAuth token")
showAppVersion = flag.Bool("version", false, "show version")
chunksize = flag.Int("chunksize", googleapi.DefaultUploadChunkSize, "size (in bytes) of each upload chunk. A zero value will cause all data to be uploaded in a single request")
notifySubscribers = flag.Bool("notify", true, "notify channel subscribers of new video. Specify '-notify=false' to disable.")
debug = flag.Bool("debug", false, "turn on verbose log output")
sendFileName = flag.Bool("sendFilename", true, "send original file name to YouTube")

// this is set by compile-time to match git tag
appVersion string = "unknown"
)

func main() {

var err error

flag.Parse()
config := yt.Config{
Filename: *filename,
Thumbnail: *thumbnail,
Caption: *caption,
Title: *title,
Description: *description,
Language: *language,
CategoryId: *categoryId,
Tags: *tags,
Privacy: *privacy,
Quiet: *quiet,
RateLimit: *rateLimit,
MetaJSON: *metaJSON,
MetaJSONOut: *metaJSONout,
LimitBetween: *limitBetween,
OAuthPort: *oAuthPort,
ShowAppVersion: *showAppVersion,
Chunksize: *chunksize,
NotifySubscribers: *notifySubscribers,
SendFileName: *sendFileName,
}

config.Logger = utils.NewLogger(*debug)

config.Logger.Debugf("Youtubeuploader version: %s\n", appVersion)

if config.ShowAppVersion {
fmt.Printf("Youtubeuploader version: %s\n", appVersion)
os.Exit(0)
}

if config.Filename == "" {
fmt.Printf("\nYou must provide a filename of a video file to upload\n")
fmt.Printf("\nUsage:\n")
flag.PrintDefaults()
os.Exit(1)
}

if config.Title == "" {
config.Title = strings.ReplaceAll(filepath.Base(config.Filename), filepath.Ext(config.Filename), "")
}

var limitRange limiter.LimitRange
if config.LimitBetween != "" {
limitRange, err = limiter.ParseLimitBetween(config.LimitBetween, inputTimeLayout)
if err != nil {
fmt.Printf("Invalid value for -limitBetween: %v", err)
os.Exit(1)
}
}

videoReader, filesize, err := yt.Open(config.Filename, yt.VIDEO)
if err != nil {
log.Fatal(err)
}
defer videoReader.Close()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

transport, err := limiter.NewLimitTransport(config.Logger, http.DefaultTransport, limitRange, filesize, config.RateLimit)
if err != nil {
log.Fatal(err)
}

err = yt.Run(ctx, transport, config, videoReader)
if err != nil {
log.Fatal(err)
}

}
Loading

0 comments on commit d358ce7

Please sign in to comment.