Skip to content

Commit

Permalink
Impl. Project - FileEncoders API
Browse files Browse the repository at this point in the history
  • Loading branch information
RayFinney committed Feb 14, 2023
1 parent 71ff652 commit 52e9437
Show file tree
Hide file tree
Showing 5 changed files with 407 additions and 3 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
A 3Q Golang Client.
This is a lightweight (no dependencies) 3Q API v2 Go/Golang client.

3Q SDN API Documentation: https://sdn.3qsdn.com/api/doc
3Q SDN Open API Spec: https://sdn.3qsdn.com/api/doc.json
# Installation
Run ```go get github.com/RayFinney/threeq-go``` to install the client.

Expand All @@ -10,10 +12,10 @@ Run ```go get github.com/RayFinney/threeq-go``` to install the client.
- [x] 01.01 ApiKey
- [x] 02.00 Projects
- [ ] 02.01 Project - Custom Metadata Definitions
- [ ] 02.02 Project -go get FileEncoders
- [x] 02.02 Project - FileEncoders
- [ ] 02.03 Project - FileEncoderPipeline
- [x] 03.00 Channels
- [ ] 03.01 Channel - Picture
- [ ] 03.01 Channel - Picture
- [ ] 03.02 Channel - Metadata
- [ ] 03.03 Channel - Ingest
- [ ] ~~03.03 Channel - Input (Deprecated)~~
Expand Down
211 changes: 211 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ import (
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/textproto"
"path/filepath"
"reflect"
"strconv"
"strings"
"time"
)

var basePath = "https://sdn.3qsdn.com/api/v2"
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func EscapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}

type threeQGo struct {
httpClient *http.Client
Expand Down Expand Up @@ -227,6 +236,208 @@ func (t *threeQGo) DeleteProject(id int64) error {
return nil
}

func (t *threeQGo) GetFileEncoderSettings(projectID int64) (FileEncodingSetting, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/projects/%d/fileencodersettings", basePath, projectID), nil)
t.setRequestHeaders(req)
if err != nil {
return FileEncodingSetting{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileEncodingSetting{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileEncodingSetting{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileEncodingSetting{}, err
}
var settings FileEncodingSetting
err = json.Unmarshal(body, &settings)
return settings, err
}

func (t *threeQGo) UpdateFileEncoderSettings(projectID int64, settings FileEncoderSettingsUpdate) (FileEncodingSetting, error) {
payloadJson, err := json.Marshal(settings)
if err != nil {
return FileEncodingSetting{}, err
}
req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/projects/%d/fileencodersettings", basePath, projectID), bytes.NewBuffer(payloadJson))
t.setRequestHeaders(req)
if err != nil {
return FileEncodingSetting{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileEncodingSetting{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileEncodingSetting{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileEncodingSetting{}, err
}
var sResult FileEncodingSetting
err = json.Unmarshal(body, &sResult)
return sResult, nil
}

func (t *threeQGo) SetWatermarkPicture(projectID int64, filename, contentType string, watermark io.Reader) error {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
h := make(textproto.MIMEHeader)
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
EscapeQuotes("file"), EscapeQuotes(filepath.Base(filename))))
h.Set("Content-Type", contentType)
part, _ := writer.CreatePart(h)
_, err := io.Copy(part, watermark)
if err != nil {
return err
}
err = writer.Close()
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/projects/%d/fileencodersettings/watermarkpicture", basePath, projectID), body)
t.setRequestHeaders(req)
if err != nil {
return err
}

response, err := t.httpClient.Do(req)
if err != nil {
return err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return err
}
return nil
}

func (t *threeQGo) GetFileFormatSettings(projectID int64) (FileFormatSettings, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/projects/%d/fileformatsettings", basePath, projectID), nil)
t.setRequestHeaders(req)
if err != nil {
return FileFormatSettings{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileFormatSettings{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileFormatSettings{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileFormatSettings{}, err
}
var settings FileFormatSettings
err = json.Unmarshal(body, &settings)
return settings, err
}

func (t *threeQGo) GetFileFormat(projectID int64, fileFormatID int64) (FileFormat, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/projects/%d/fileformatsettings/%d", basePath, projectID, fileFormatID), nil)
t.setRequestHeaders(req)
if err != nil {
return FileFormat{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileFormat{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileFormat{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileFormat{}, err
}
var settings FileFormat
err = json.Unmarshal(body, &settings)
return settings, err
}

func (t *threeQGo) AddFileFormat(projectID int64, fileFormatID int64) (FileEncodingSetting, error) {
req, err := http.NewRequest(http.MethodPatch, fmt.Sprintf("%s/projects/%d/fileencodersettings/fileformat/%d", basePath, projectID, fileFormatID), nil)
t.setRequestHeaders(req)
if err != nil {
return FileEncodingSetting{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileEncodingSetting{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileEncodingSetting{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileEncodingSetting{}, err
}
var settings FileEncodingSetting
err = json.Unmarshal(body, &settings)
return settings, err
}

func (t *threeQGo) RemoveFileFormat(projectID int64, fileFormatID int64) (FileEncodingSetting, error) {
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/projects/%d/fileencodersettings/fileformat/%d", basePath, projectID, fileFormatID), nil)
t.setRequestHeaders(req)
if err != nil {
return FileEncodingSetting{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileEncodingSetting{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileEncodingSetting{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileEncodingSetting{}, err
}
var settings FileEncodingSetting
err = json.Unmarshal(body, &settings)
return settings, err
}

func (t *threeQGo) UpdateFileFormat(projectID int64, fileFormatID int64, fileFormat FileFormatUpdate) (FileFormat, error) {
payloadJson, err := json.Marshal(fileFormat)
if err != nil {
return FileFormat{}, err
}
req, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/projects/%d/fileformatsettings/%d", basePath, projectID, fileFormatID), bytes.NewBuffer(payloadJson))
t.setRequestHeaders(req)
if err != nil {
return FileFormat{}, err
}
response, err := t.httpClient.Do(req)
if err != nil {
return FileFormat{}, err
}
body, err := io.ReadAll(response.Body)
if err != nil {
return FileFormat{}, err
}
defer response.Body.Close()
if err := t.checkForErrorsInResponse(response); err != nil {
return FileFormat{}, err
}
var sResult FileFormat
err = json.Unmarshal(body, &sResult)
return sResult, nil
}

func (t *threeQGo) GetChannels() ([]Channel, error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/channels", basePath), nil)
t.setRequestHeaders(req)
Expand Down
90 changes: 90 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,96 @@ func TestCreateChannelRecorder(t *testing.T) {
}
}

func TestGetFileEncoderSettings(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.GetFileEncoderSettings(49763)
if err != nil {
t.Fatal(err)
}
}

func TestUpdateFileEncoderSettings(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.UpdateFileEncoderSettings(49763, FileEncoderSettingsUpdate{
UseEncoding: true,
UsePremiumEncoding: false,
UsePreProcessing: false,
UseAIServices: false,
SourceLanguage: "eng",
GenerateSubtitles: false,
UseDeinterlace: false,
UseTwoPass: false,
UseCMAF: false,
UseBPFrames: true,
PackageAudioOnlyVariant: false,
PackageForDRM: false,
UseWatermark: false,
WatermarkPosition: "bottom-right",
UseCropping: false,
CroppingParameters: "",
NormalizeAudio: false,
UseFirstAudioTrack: false,
UseAllAudioTracks: false,
})
if err != nil {
t.Fatal(err)
}
}

func TestGetFileFormatSettings(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.GetFileFormatSettings(49763)
if err != nil {
t.Fatal(err)
}
}

func TestGetFileFormat(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.GetFileFormat(49763, 1)
if err != nil {
t.Fatal(err)
}
}

func TestUpdateFileFormat(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.UpdateFileFormat(49763, 1, FileFormatUpdate{
VideoBitRate: 4000,
VideoProfile: "main",
VideoFPS: 25,
AudioBitRate: 152,
AudioSampleRate: 48000,
AudioChannels: 2,
})
if err != nil {
t.Fatal(err)
}
}

func TestAddFileFormat(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.AddFileFormat(49763, 1)
if err != nil {
t.Fatal(err)
}
}

func TestRemoveFileFormat(t *testing.T) {
client := NewClient(nil)
client.SetAPIKey(os.Getenv("API_KEY"))
_, err := client.RemoveFileFormat(49763, 1)
if err != nil {
t.Fatal(err)
}
}

func TestEncodeQuery(t *testing.T) {
query := encodeQuery(FileSearchOptions{
IncludeDeleted: false,
Expand Down
Loading

0 comments on commit 52e9437

Please sign in to comment.