diff --git a/api.go b/api.go index 926188a..319a139 100644 --- a/api.go +++ b/api.go @@ -10,7 +10,7 @@ import ( "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" - "github.com/hrfee/jfa-go/mediabrowser" + "github.com/hrfee/mediabrowser" "github.com/knz/strtime" "github.com/lithammer/shortuuid/v3" "gopkg.in/ini.v1" diff --git a/go.mod b/go.mod index 7161429..1d79804 100644 --- a/go.mod +++ b/go.mod @@ -4,16 +4,12 @@ go 1.16 replace github.com/hrfee/jfa-go/docs => ./docs -replace github.com/hrfee/jfa-go/mediabrowser => ./mediabrowser - replace github.com/hrfee/jfa-go/common => ./common replace github.com/hrfee/jfa-go/ombi => ./ombi require ( - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/evanw/esbuild v0.8.50 // indirect github.com/fatih/color v1.10.0 github.com/fsnotify/fsnotify v1.4.9 github.com/gin-contrib/pprof v1.3.0 @@ -27,15 +23,14 @@ require ( github.com/google/uuid v1.1.2 // indirect github.com/hrfee/jfa-go/common v0.0.0-20210105184019-fdc97b4e86cc github.com/hrfee/jfa-go/docs v0.0.0-20201112212552-b6f3cd7c1f71 - github.com/hrfee/jfa-go/mediabrowser v0.0.0-20201112212552-b6f3cd7c1f71 github.com/hrfee/jfa-go/ombi v0.0.0-20201112212552-b6f3cd7c1f71 + github.com/hrfee/mediabrowser v0.1.0 github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible github.com/knz/strtime v0.0.0-20200924090105-187c67f2bf5e github.com/lithammer/shortuuid/v3 v3.0.4 github.com/mailgun/mailgun-go/v4 v4.3.0 github.com/mailru/easyjson v0.7.7 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 github.com/swaggo/gin-swagger v1.3.0 diff --git a/go.sum b/go.sum index 8d54574..a709783 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,4 @@ -cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= @@ -11,29 +9,18 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= 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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanw/esbuild v0.8.50 h1:97YxSC9Ni9zu82601vI93cSUS0C+WUcPPNIARuGcQtI= -github.com/evanw/esbuild v0.8.50/go.mod h1:y2AFBAGVelPqPodpdtxWWqe6n2jYf5FrsJbligmRmuw= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= @@ -44,7 +31,6 @@ github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc= github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w= @@ -99,9 +85,7 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -123,13 +107,14 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/hrfee/mediabrowser v0.1.0 h1:d4V/HQl+Hns6ZuAHDaArcQeaQqQlqSS6Xktb9Z1Ol8Y= +github.com/hrfee/mediabrowser v0.1.0/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U= github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible h1:CL0ooBNfbNyJTJATno+m0h+zM5bW6v7fKlboKUGP/dI= github.com/jordan-wright/email v4.0.1-0.20200917010138-e1c00e156980+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -144,10 +129,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/knz/strtime v0.0.0-20200924090105-187c67f2bf5e h1:ViPE0JEOvtw5I0EGUiFSr2VNKGNU+3oBT+oHbDXHbxk= github.com/knz/strtime v0.0.0-20200924090105-187c67f2bf5e/go.mod h1:4ZxfWkxwtc7dBeifERVVWRy9F9rTU9p0yCDgeCtlius= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -186,22 +169,15 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -229,16 +205,12 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= github.com/ugorji/go/codec v1.2.0 h1:As6RccOIlbm9wHuWYMlB30dErcI+4WiKWsYsmPkyrUw= github.com/ugorji/go/codec v1.2.0/go.mod h1:dXvG35r7zTX6QImXOSFhGMmKtX+wJ7VTWzGvYQGIjBs= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/writeas/go-strip-markdown v2.0.1+incompatible h1:IIqxTM5Jr7RzhigcL6FkrCNfXkvbR+Nbu1ls48pXYcw= github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9pXdk8V6MVnZmTzRG0alMNLMwa0J01fE= -github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/dl v0.0.0-20190829154251-82a15e2f2ead h1:jeP6FgaSLNTMP+Yri3qjlACywQLye+huGLmNGhBzm6k= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -246,11 +218,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -268,17 +238,14 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -291,19 +258,11 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b h1:ggRgirZABFolTmi3sn6Ivd9SipZwLedQ5wR0aAKnFxU= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -330,15 +289,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -354,11 +310,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -373,5 +326,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/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-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go index ed6d639..7feb057 100644 --- a/main.go +++ b/main.go @@ -24,8 +24,8 @@ import ( "github.com/fatih/color" "github.com/hrfee/jfa-go/common" _ "github.com/hrfee/jfa-go/docs" - "github.com/hrfee/jfa-go/mediabrowser" "github.com/hrfee/jfa-go/ombi" + "github.com/hrfee/mediabrowser" "github.com/lithammer/shortuuid/v3" "gopkg.in/ini.v1" ) diff --git a/mediabrowser/emby.go b/mediabrowser/emby.go deleted file mode 100644 index c95d210..0000000 --- a/mediabrowser/emby.go +++ /dev/null @@ -1,173 +0,0 @@ -package mediabrowser - -// Almost identical to jfapi, with the most notable change being the password workaround. - -import ( - "encoding/json" - "fmt" - "net/http" - "time" -) - -func embyDeleteUser(emby *MediaBrowser, userID string) (int, error) { - url := fmt.Sprintf("%s/Users/%s", emby.Server, userID) - req, _ := http.NewRequest("DELETE", url, nil) - for name, value := range emby.header { - req.Header.Add(name, value) - } - resp, err := emby.httpClient.Do(req) - defer emby.timeoutHandler() - return resp.StatusCode, err -} - -func embyGetUsers(emby *MediaBrowser, public bool) ([]User, int, error) { - var result []User - var data string - var status int - var err error - if time.Now().After(emby.CacheExpiry) { - if public { - url := fmt.Sprintf("%s/users/public", emby.Server) - data, status, err = emby.get(url, nil) - } else { - url := fmt.Sprintf("%s/users", emby.Server) - data, status, err = emby.get(url, emby.loginParams) - } - if err != nil || status != 200 { - return nil, status, err - } - json.Unmarshal([]byte(data), &result) - emby.userCache = result - emby.CacheExpiry = time.Now().Add(time.Minute * time.Duration(emby.cacheLength)) - if result[0].ID[8] == '-' { - emby.Hyphens = true - } - return result, status, nil - } - return emby.userCache, 200, nil -} - -func embyUserByName(emby *MediaBrowser, username string, public bool) (User, int, error) { - var match User - find := func() (User, int, error) { - users, status, err := emby.GetUsers(public) - if err != nil || status != 200 { - return User{}, status, err - } - for _, user := range users { - if user.Name == username { - return user, status, err - } - } - return User{}, status, err - } - match, status, err := find() - if match.Name == "" { - emby.CacheExpiry = time.Now() - match, status, err = find() - } - return match, status, err -} - -func embyUserByID(emby *MediaBrowser, userID string, public bool) (User, int, error) { - if emby.CacheExpiry.After(time.Now()) { - for _, user := range emby.userCache { - if user.ID == userID { - return user, 200, nil - } - } - } - if public { - users, status, err := emby.GetUsers(public) - if err != nil || status != 200 { - return User{}, status, err - } - for _, user := range users { - if user.ID == userID { - return user, status, nil - } - } - return User{}, status, err - } - var result User - var data string - var status int - var err error - url := fmt.Sprintf("%s/users/%s", emby.Server, userID) - data, status, err = emby.get(url, emby.loginParams) - if err != nil || status != 200 { - return User{}, status, err - } - json.Unmarshal([]byte(data), &result) - return result, status, nil -} - -// Since emby doesn't allow one to specify a password on user creation, we: -// Create the account -// Immediately disable it -// Set password -// Reeenable it -func embyNewUser(emby *MediaBrowser, username, password string) (User, int, error) { - url := fmt.Sprintf("%s/Users/New", emby.Server) - data := map[string]interface{}{ - "Name": username, - } - response, status, err := emby.post(url, data, true) - var recv User - json.Unmarshal([]byte(response), &recv) - if err != nil || !(status == 200 || status == 204) { - return User{}, status, err - } - // Step 2: Set password - id := recv.ID - url = fmt.Sprintf("%s/Users/%s/Password", emby.Server, id) - data = map[string]interface{}{ - "Id": id, - "CurrentPw": "", - "NewPw": password, - } - _, status, err = emby.post(url, data, false) - // Step 3: If setting password errored, try to delete the account - if err != nil || !(status == 200 || status == 204) { - _, err = emby.DeleteUser(id) - } - return recv, status, nil -} - -func embySetPolicy(emby *MediaBrowser, userID string, policy Policy) (int, error) { - url := fmt.Sprintf("%s/Users/%s/Policy", emby.Server, userID) - _, status, err := emby.post(url, policy, false) - if err != nil || status != 200 { - return status, err - } - return status, nil -} - -func embySetConfiguration(emby *MediaBrowser, userID string, configuration Configuration) (int, error) { - url := fmt.Sprintf("%s/Users/%s/Configuration", emby.Server, userID) - _, status, err := emby.post(url, configuration, false) - return status, err -} - -func embyGetDisplayPreferences(emby *MediaBrowser, userID string) (map[string]interface{}, int, error) { - url := fmt.Sprintf("%s/DisplayPreferences/usersettings?userId=%s&client=emby", emby.Server, userID) - data, status, err := emby.get(url, nil) - if err != nil || !(status == 204 || status == 200) { - return nil, status, err - } - var displayprefs map[string]interface{} - err = json.Unmarshal([]byte(data), &displayprefs) - if err != nil { - return nil, status, err - } - return displayprefs, status, nil -} - -func embySetDisplayPreferences(emby *MediaBrowser, userID string, displayprefs map[string]interface{}) (int, error) { - url := fmt.Sprintf("%s/DisplayPreferences/usersettings?userId=%s&client=emby", emby.Server, userID) - _, status, err := emby.post(url, displayprefs, false) - if err != nil || !(status == 204 || status == 200) { - return status, err - } - return status, nil -} diff --git a/mediabrowser/go.mod b/mediabrowser/go.mod deleted file mode 100644 index 5c022cc..0000000 --- a/mediabrowser/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/hrfee/jfa-go/mediabrowser - -go 1.15 diff --git a/mediabrowser/jfapi.go b/mediabrowser/jfapi.go deleted file mode 100644 index 2c9d0e0..0000000 --- a/mediabrowser/jfapi.go +++ /dev/null @@ -1,162 +0,0 @@ -package mediabrowser - -import ( - "encoding/json" - "fmt" - "net/http" - "time" -) - -func jfDeleteUser(jf *MediaBrowser, userID string) (int, error) { - url := fmt.Sprintf("%s/Users/%s", jf.Server, userID) - req, _ := http.NewRequest("DELETE", url, nil) - for name, value := range jf.header { - req.Header.Add(name, value) - } - resp, err := jf.httpClient.Do(req) - defer jf.timeoutHandler() - return resp.StatusCode, err -} - -func jfGetUsers(jf *MediaBrowser, public bool) ([]User, int, error) { - var result []User - var data string - var status int - var err error - if time.Now().After(jf.CacheExpiry) { - if public { - url := fmt.Sprintf("%s/users/public", jf.Server) - data, status, err = jf.get(url, nil) - } else { - url := fmt.Sprintf("%s/users", jf.Server) - data, status, err = jf.get(url, jf.loginParams) - } - if err != nil || status != 200 { - return nil, status, err - } - err := json.Unmarshal([]byte(data), &result) - if err != nil { - fmt.Println(err) - return nil, status, err - } - jf.userCache = result - jf.CacheExpiry = time.Now().Add(time.Minute * time.Duration(jf.cacheLength)) - if result[0].ID[8] == '-' { - jf.Hyphens = true - } - return result, status, nil - } - return jf.userCache, 200, nil -} - -func jfUserByName(jf *MediaBrowser, username string, public bool) (User, int, error) { - var match User - find := func() (User, int, error) { - users, status, err := jf.GetUsers(public) - if err != nil || status != 200 { - return User{}, status, err - } - for _, user := range users { - if user.Name == username { - return user, status, err - } - } - return User{}, status, err - } - match, status, err := find() - if match.Name == "" { - jf.CacheExpiry = time.Now() - match, status, err = find() - } - return match, status, err -} - -func jfUserByID(jf *MediaBrowser, userID string, public bool) (User, int, error) { - if jf.CacheExpiry.After(time.Now()) { - for _, user := range jf.userCache { - if user.ID == userID { - return user, 200, nil - } - } - } - if public { - users, status, err := jf.GetUsers(public) - if err != nil || status != 200 { - return User{}, status, err - } - for _, user := range users { - if user.ID == userID { - return user, status, nil - } - } - return User{}, status, err - } - var result User - var data string - var status int - var err error - url := fmt.Sprintf("%s/users/%s", jf.Server, userID) - data, status, err = jf.get(url, jf.loginParams) - if err != nil || status != 200 { - return User{}, status, err - } - json.Unmarshal([]byte(data), &result) - return result, status, nil -} - -func jfNewUser(jf *MediaBrowser, username, password string) (User, int, error) { - url := fmt.Sprintf("%s/Users/New", jf.Server) - stringData := map[string]string{ - "Name": username, - "Password": password, - } - data := make(map[string]interface{}) - for key, value := range stringData { - data[key] = value - } - response, status, err := jf.post(url, data, true) - var recv User - json.Unmarshal([]byte(response), &recv) - if err != nil || !(status == 200 || status == 204) { - return User{}, status, err - } - return recv, status, nil -} - -func jfSetPolicy(jf *MediaBrowser, userID string, policy Policy) (int, error) { - url := fmt.Sprintf("%s/Users/%s/Policy", jf.Server, userID) - _, status, err := jf.post(url, policy, false) - if err != nil || status != 200 { - return status, err - } - return status, nil -} - -func jfSetConfiguration(jf *MediaBrowser, userID string, configuration Configuration) (int, error) { - url := fmt.Sprintf("%s/Users/%s/Configuration", jf.Server, userID) - _, status, err := jf.post(url, configuration, false) - return status, err -} - -func jfGetDisplayPreferences(jf *MediaBrowser, userID string) (map[string]interface{}, int, error) { - url := fmt.Sprintf("%s/DisplayPreferences/usersettings?userId=%s&client=emby", jf.Server, userID) - data, status, err := jf.get(url, nil) - if err != nil || !(status == 204 || status == 200) { - return nil, status, err - } - var displayprefs map[string]interface{} - err = json.Unmarshal([]byte(data), &displayprefs) - if err != nil { - return nil, status, err - } - return displayprefs, status, nil -} - -func jfSetDisplayPreferences(jf *MediaBrowser, userID string, displayprefs map[string]interface{}) (int, error) { - url := fmt.Sprintf("%s/DisplayPreferences/usersettings?userId=%s&client=emby", jf.Server, userID) - _, status, err := jf.post(url, displayprefs, false) - if err != nil || !(status == 204 || status == 200) { - return status, err - } - return status, nil -} diff --git a/mediabrowser/mediabrowser.go b/mediabrowser/mediabrowser.go deleted file mode 100644 index f5c4daf..0000000 --- a/mediabrowser/mediabrowser.go +++ /dev/null @@ -1,322 +0,0 @@ -// Mediabrowser provides user-related bindings to the Jellyfin & Emby APIs. -// Some data aren't bound to structs as jfa-go doesn't need to interact with them, for example DisplayPreferences. -// See Jellyfin/Emby swagger docs for more info on them. -package mediabrowser - -import ( - "bytes" - "compress/gzip" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "strings" - "time" -) - -// TimeoutHandler should recover from an http timeout or panic. -type TimeoutHandler func() - -// NewNamedTimeoutHandler returns a new Timeout handler that logs the error. -// name is the name of the server to use in the log (e.g Jellyfin/Emby) -// addr is the address of the server being accessed -// if noFail is false, the program will exit on a timeout. -func NewNamedTimeoutHandler(name, addr string, noFail bool) TimeoutHandler { - return func() { - if r := recover(); r != nil { - out := fmt.Sprintf("Failed to authenticate with %s @ %s: Timed out", name, addr) - if noFail { - log.Print(out) - } else { - log.Fatalf(out) - } - } - } -} - -type serverType int - -const ( - JellyfinServer serverType = iota - EmbyServer -) - -// ServerInfo stores info about the server. -type ServerInfo struct { - LocalAddress string `json:"LocalAddress"` - Name string `json:"ServerName"` - Version string `json:"Version"` - OS string `json:"OperatingSystem"` - ID string `json:"Id"` -} - -// MediaBrowser is an api instance of Jellyfin/Emby. -type MediaBrowser struct { - Server string - client string - version string - device string - deviceID string - useragent string - auth string - header map[string]string - ServerInfo ServerInfo - Username string - password string - Authenticated bool - AccessToken string - userID string - httpClient *http.Client - loginParams map[string]string - userCache []User - CacheExpiry time.Time - cacheLength int - noFail bool - Hyphens bool - serverType serverType - timeoutHandler TimeoutHandler -} - -// NewServer returns a new Mediabrowser object. -func NewServer(st serverType, server, client, version, device, deviceID string, timeoutHandler TimeoutHandler, cacheTimeout int) (*MediaBrowser, error) { - mb := &MediaBrowser{} - mb.serverType = st - mb.Server = server - mb.client = client - mb.version = version - mb.device = device - mb.deviceID = deviceID - mb.useragent = fmt.Sprintf("%s/%s", client, version) - mb.timeoutHandler = timeoutHandler - mb.auth = fmt.Sprintf("MediaBrowser Client=\"%s\", Device=\"%s\", DeviceId=\"%s\", Version=\"%s\"", client, device, deviceID, version) - mb.header = map[string]string{ - "Accept": "application/json", - "Content-type": "application/json; charset=UTF-8", - "X-Application": mb.useragent, - "Accept-Charset": "UTF-8,*", - "Accept-Encoding": "gzip", - "User-Agent": mb.useragent, - "X-Emby-Authorization": mb.auth, - } - mb.httpClient = &http.Client{ - Timeout: 10 * time.Second, - } - infoURL := fmt.Sprintf("%s/System/Info/Public", server) - req, _ := http.NewRequest("GET", infoURL, nil) - resp, err := mb.httpClient.Do(req) - defer mb.timeoutHandler() - if err == nil { - data, _ := ioutil.ReadAll(resp.Body) - json.Unmarshal(data, &mb.ServerInfo) - } - mb.cacheLength = cacheTimeout - mb.CacheExpiry = time.Now() - return mb, nil -} - -func (mb *MediaBrowser) get(url string, params map[string]string) (string, int, error) { - var req *http.Request - if params != nil { - jsonParams, _ := json.Marshal(params) - req, _ = http.NewRequest("GET", url, bytes.NewBuffer(jsonParams)) - } else { - req, _ = http.NewRequest("GET", url, nil) - } - for name, value := range mb.header { - req.Header.Add(name, value) - } - resp, err := mb.httpClient.Do(req) - defer mb.timeoutHandler() - if err != nil || resp.StatusCode != 200 { - if resp.StatusCode == 401 && mb.Authenticated { - mb.Authenticated = false - _, _, authErr := mb.Authenticate(mb.Username, mb.password) - if authErr == nil { - v1, v2, v3 := mb.get(url, params) - return v1, v2, v3 - } - } - return "", resp.StatusCode, err - } - defer resp.Body.Close() - var data io.Reader - encoding := resp.Header.Get("Content-Encoding") - switch encoding { - case "gzip": - data, _ = gzip.NewReader(resp.Body) - default: - data = resp.Body - } - buf := new(strings.Builder) - io.Copy(buf, data) - //var respData map[string]interface{} - //json.NewDecoder(data).Decode(&respData) - return buf.String(), resp.StatusCode, nil -} - -func (mb *MediaBrowser) post(url string, data interface{}, response bool) (string, int, error) { - params, _ := json.Marshal(data) - req, _ := http.NewRequest("POST", url, bytes.NewBuffer(params)) - for name, value := range mb.header { - req.Header.Add(name, value) - } - resp, err := mb.httpClient.Do(req) - defer mb.timeoutHandler() - if err != nil || resp.StatusCode != 200 { - if resp.StatusCode == 401 && mb.Authenticated { - mb.Authenticated = false - _, _, authErr := mb.Authenticate(mb.Username, mb.password) - if authErr == nil { - v1, v2, v3 := mb.post(url, data, response) - return v1, v2, v3 - } - } - return "", resp.StatusCode, err - } - if response { - defer resp.Body.Close() - var outData io.Reader - switch resp.Header.Get("Content-Encoding") { - case "gzip": - outData, _ = gzip.NewReader(resp.Body) - default: - outData = resp.Body - } - buf := new(strings.Builder) - io.Copy(buf, outData) - return buf.String(), resp.StatusCode, nil - } - return "", resp.StatusCode, nil -} - -// Authenticate attempts to authenticate using a username & password -func (mb *MediaBrowser) Authenticate(username, password string) (User, int, error) { - mb.Username = username - mb.password = password - mb.loginParams = map[string]string{ - "Username": username, - "Pw": password, - "Password": password, - } - buffer := &bytes.Buffer{} - encoder := json.NewEncoder(buffer) - encoder.SetEscapeHTML(false) - err := encoder.Encode(mb.loginParams) - if err != nil { - return User{}, 0, err - } - // loginParams, _ := json.Marshal(jf.loginParams) - url := fmt.Sprintf("%s/Users/authenticatebyname", mb.Server) - req, err := http.NewRequest("POST", url, buffer) - defer mb.timeoutHandler() - if err != nil { - return User{}, 0, err - } - for name, value := range mb.header { - req.Header.Add(name, value) - } - resp, err := mb.httpClient.Do(req) - if err != nil || resp.StatusCode != 200 { - return User{}, resp.StatusCode, err - } - defer resp.Body.Close() - var d io.Reader - switch resp.Header.Get("Content-Encoding") { - case "gzip": - d, _ = gzip.NewReader(resp.Body) - default: - d = resp.Body - } - data, err := io.ReadAll(d) - if err != nil { - return User{}, 0, err - } - var respData map[string]interface{} - json.Unmarshal(data, &respData) - mb.AccessToken = respData["AccessToken"].(string) - var user User - ju, err := json.Marshal(respData["User"]) - if err != nil { - return User{}, 0, err - } - json.Unmarshal(ju, &user) - mb.userID = user.ID - mb.auth = fmt.Sprintf("MediaBrowser Client=\"%s\", Device=\"%s\", DeviceId=\"%s\", Version=\"%s\", Token=\"%s\"", mb.client, mb.device, mb.deviceID, mb.version, mb.AccessToken) - mb.header["X-Emby-Authorization"] = mb.auth - mb.Authenticated = true - return user, resp.StatusCode, nil -} - -// DeleteUser deletes the user corresponding to the provided ID. -func (mb *MediaBrowser) DeleteUser(userID string) (int, error) { - if mb.serverType == JellyfinServer { - return jfDeleteUser(mb, userID) - } - return embyDeleteUser(mb, userID) -} - -// GetUsers returns all (visible) users on the Emby instance. -func (mb *MediaBrowser) GetUsers(public bool) ([]User, int, error) { - if mb.serverType == JellyfinServer { - return jfGetUsers(mb, public) - } - return embyGetUsers(mb, public) -} - -// UserByName returns the user corresponding to the provided username. -func (mb *MediaBrowser) UserByName(username string, public bool) (User, int, error) { - if mb.serverType == JellyfinServer { - return jfUserByName(mb, username, public) - } - return embyUserByName(mb, username, public) -} - -// UserByID returns the user corresponding to the provided ID. -func (mb *MediaBrowser) UserByID(userID string, public bool) (User, int, error) { - if mb.serverType == JellyfinServer { - return jfUserByID(mb, userID, public) - } - return embyUserByID(mb, userID, public) -} - -// NewUser creates a new user with the provided username and password. -func (mb *MediaBrowser) NewUser(username, password string) (User, int, error) { - if mb.serverType == JellyfinServer { - return jfNewUser(mb, username, password) - } - return embyNewUser(mb, username, password) -} - -// SetPolicy sets the access policy for the user corresponding to the provided ID. -func (mb *MediaBrowser) SetPolicy(userID string, policy Policy) (int, error) { - if mb.serverType == JellyfinServer { - return jfSetPolicy(mb, userID, policy) - } - return embySetPolicy(mb, userID, policy) -} - -// SetConfiguration sets the configuration (part of homescreen layout) for the user corresponding to the provided ID. -func (mb *MediaBrowser) SetConfiguration(userID string, configuration Configuration) (int, error) { - if mb.serverType == JellyfinServer { - return jfSetConfiguration(mb, userID, configuration) - } - return embySetConfiguration(mb, userID, configuration) -} - -// GetDisplayPreferences gets the displayPreferences (part of homescreen layout) for the user corresponding to the provided ID. -func (mb *MediaBrowser) GetDisplayPreferences(userID string) (map[string]interface{}, int, error) { - if mb.serverType == JellyfinServer { - return jfGetDisplayPreferences(mb, userID) - } - return embyGetDisplayPreferences(mb, userID) -} - -// SetDisplayPreferences sets the displayPreferences (part of homescreen layout) for the user corresponding to the provided ID. -func (mb *MediaBrowser) SetDisplayPreferences(userID string, displayprefs map[string]interface{}) (int, error) { - if mb.serverType == JellyfinServer { - return jfSetDisplayPreferences(mb, userID, displayprefs) - } - return embySetDisplayPreferences(mb, userID, displayprefs) -} diff --git a/mediabrowser/models.go b/mediabrowser/models.go deleted file mode 100644 index 2f3078c..0000000 --- a/mediabrowser/models.go +++ /dev/null @@ -1,118 +0,0 @@ -package mediabrowser - -import ( - "time" -) - -type magicParse struct { - Parsed time.Time `json:"parseme"` -} - -// Time embeds time.Time with a custom JSON Unmarshal method to work with Jellyfin & Emby's time formatting. -type Time struct { - time.Time -} - -func (t *Time) UnmarshalJSON(b []byte) (err error) { - // Trim quotes from beginning and end, and any number of Zs (indicates UTC). - for b[0] == '"' { - b = b[1:] - } - for b[len(b)-1] == '"' || b[len(b)-1] == 'Z' { - b = b[:len(b)-1] - } - // Trim nanoseconds and anything after, we don't care - i := len(b) - 1 - for b[i] != '.' && i > 0 { - i-- - } - if i != 0 { - b = b[:i] - } - t.Time, err = time.Parse("2006-01-02T15:04:05", string(b)) - return -} - -type User struct { - Name string `json:"Name"` - ServerID string `json:"ServerId"` - ID string `json:"Id"` - HasPassword bool `json:"HasPassword"` - HasConfiguredPassword bool `json:"HasConfiguredPassword"` - HasConfiguredEasyPassword bool `json:"HasConfiguredEasyPassword"` - EnableAutoLogin bool `json:"EnableAutoLogin"` - LastLoginDate Time `json:"LastLoginDate"` - LastActivityDate Time `json:"LastActivityDate"` - Configuration Configuration `json:"Configuration"` - // Policy stores the user's permissions. - Policy Policy `json:"Policy"` -} - -type SessionInfo struct { - RemoteEndpoint string `json:"RemoteEndPoint"` - UserID string `json:"UserId"` -} - -type AuthenticationResult struct { - User User `json:"User"` - AccessToken string `json:"AccessToken"` - ServerID string `json:"ServerId"` - SessionInfo SessionInfo `json:"SessionInfo"` -} - -type Configuration struct { - PlayDefaultAudioTrack bool `json:"PlayDefaultAudioTrack"` - SubtitleLanguagePreference string `json:"SubtitleLanguagePreference"` - DisplayMissingEpisodes bool `json:"DisplayMissingEpisodes"` - GroupedFolders []interface{} `json:"GroupedFolders"` - SubtitleMode string `json:"SubtitleMode"` - DisplayCollectionsView bool `json:"DisplayCollectionsView"` - EnableLocalPassword bool `json:"EnableLocalPassword"` - OrderedViews []interface{} `json:"OrderedViews"` - LatestItemsExcludes []interface{} `json:"LatestItemsExcludes"` - MyMediaExcludes []interface{} `json:"MyMediaExcludes"` - HidePlayedInLatest bool `json:"HidePlayedInLatest"` - RememberAudioSelections bool `json:"RememberAudioSelections"` - RememberSubtitleSelections bool `json:"RememberSubtitleSelections"` - EnableNextEpisodeAutoPlay bool `json:"EnableNextEpisodeAutoPlay"` -} -type Policy struct { - IsAdministrator bool `json:"IsAdministrator"` - IsHidden bool `json:"IsHidden"` - IsDisabled bool `json:"IsDisabled"` - BlockedTags []interface{} `json:"BlockedTags"` - EnableUserPreferenceAccess bool `json:"EnableUserPreferenceAccess"` - AccessSchedules []interface{} `json:"AccessSchedules"` - BlockUnratedItems []interface{} `json:"BlockUnratedItems"` - EnableRemoteControlOfOtherUsers bool `json:"EnableRemoteControlOfOtherUsers"` - EnableSharedDeviceControl bool `json:"EnableSharedDeviceControl"` - EnableRemoteAccess bool `json:"EnableRemoteAccess"` - EnableLiveTvManagement bool `json:"EnableLiveTvManagement"` - EnableLiveTvAccess bool `json:"EnableLiveTvAccess"` - EnableMediaPlayback bool `json:"EnableMediaPlayback"` - EnableAudioPlaybackTranscoding bool `json:"EnableAudioPlaybackTranscoding"` - EnableVideoPlaybackTranscoding bool `json:"EnableVideoPlaybackTranscoding"` - EnablePlaybackRemuxing bool `json:"EnablePlaybackRemuxing"` - ForceRemoteSourceTranscoding bool `json:"ForceRemoteSourceTranscoding"` - EnableContentDeletion bool `json:"EnableContentDeletion"` - EnableContentDeletionFromFolders []interface{} `json:"EnableContentDeletionFromFolders"` - EnableContentDownloading bool `json:"EnableContentDownloading"` - EnableSyncTranscoding bool `json:"EnableSyncTranscoding"` - EnableMediaConversion bool `json:"EnableMediaConversion"` - EnabledDevices []interface{} `json:"EnabledDevices"` - EnableAllDevices bool `json:"EnableAllDevices"` - EnabledChannels []interface{} `json:"EnabledChannels"` - EnableAllChannels bool `json:"EnableAllChannels"` - EnabledFolders []string `json:"EnabledFolders"` - EnableAllFolders bool `json:"EnableAllFolders"` - InvalidLoginAttemptCount int `json:"InvalidLoginAttemptCount"` - LoginAttemptsBeforeLockout int `json:"LoginAttemptsBeforeLockout"` - MaxActiveSessions int `json:"MaxActiveSessions"` - EnablePublicSharing bool `json:"EnablePublicSharing"` - BlockedMediaFolders []interface{} `json:"BlockedMediaFolders"` - BlockedChannels []interface{} `json:"BlockedChannels"` - RemoteClientBitrateLimit int `json:"RemoteClientBitrateLimit"` - AuthenticationProviderID string `json:"AuthenticationProviderId"` - PasswordResetProviderID string `json:"PasswordResetProviderId"` - SyncPlayAccess string `json:"SyncPlayAccess"` -} diff --git a/setup.go b/setup.go index 067fb48..e360841 100644 --- a/setup.go +++ b/setup.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/gin-gonic/gin" - "github.com/hrfee/jfa-go/mediabrowser" + "github.com/hrfee/mediabrowser" ) func (app *appContext) ServeSetup(gc *gin.Context) { diff --git a/storage.go b/storage.go index dc851cb..e8e34db 100644 --- a/storage.go +++ b/storage.go @@ -11,7 +11,7 @@ import ( "sync" "time" - "github.com/hrfee/jfa-go/mediabrowser" + "github.com/hrfee/mediabrowser" ) type Storage struct { diff --git a/userdaemon.go b/userdaemon.go index 944e2b6..5af1ddc 100644 --- a/userdaemon.go +++ b/userdaemon.go @@ -3,7 +3,7 @@ package main import ( "time" - "github.com/hrfee/jfa-go/mediabrowser" + "github.com/hrfee/mediabrowser" ) type userDaemon struct {