From 911ba27071027e8dbc58559f3160b84c8118a259 Mon Sep 17 00:00:00 2001 From: Taras Date: Tue, 2 Jul 2024 20:00:31 +0300 Subject: [PATCH] chore: fix url parsing, update tests (#2) * fix url parsing, update tests * test ci * update golang version --- .github/workflows/go.yml | 8 ++++---- fromURL.go | 32 ++++++++++++++------------------ fromURL_test.go | 20 ++++++++++---------- uploadImage.go | 36 ++++++++++++++++++++---------------- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5b61fb2..14bc63e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -14,17 +14,17 @@ jobs: strategy: fail-fast: false matrix: - go: ['1.13', '1.14'] + go: ['1.22.4'] steps: - uses: actions/setup-go@v1 with: go-version: ${{ matrix.go }} - + - uses: actions/checkout@v2 - + - name: Build run: go build -v . - + - name: Test env: IMGURCLIENTID: ${{ secrets. IMGURCLIENTID }} diff --git a/fromURL.go b/fromURL.go index 66293ce..261e4f4 100644 --- a/fromURL.go +++ b/fromURL.go @@ -51,6 +51,17 @@ func matchesSlice(url string, validFormats []string) bool { return false } +func extractIdFromUrl(url string) string { + if end := strings.LastIndex(url, "?"); end != -1 { + url = url[:end] + } + start := strings.LastIndex(url, "/") + 1 + if pos := strings.LastIndex(url, "-"); pos > start { + start = pos + 1 + } + return url[start:] +} + // GetInfoFromURL tries to query imgur based on information identified in the URL. // returns image/album info, status code of the request, error func (client *Client) GetInfoFromURL(url string) (*GenericInfo, int, error) { @@ -102,12 +113,7 @@ func (client *Client) directImageURL(url string) (*GenericInfo, int, error) { func (client *Client) albumURL(url string) (*GenericInfo, int, error) { var ret GenericInfo - start := strings.LastIndex(url, "/") + 1 - end := strings.LastIndex(url, "?") - if end == -1 { - end = len(url) - } - id := url[start:end] + id := extractIdFromUrl(url) if id == "" { return nil, -1, errors.New("Could not find ID in URL " + url + ". I was going down imgur.com/a/ path.") } @@ -120,12 +126,7 @@ func (client *Client) albumURL(url string) (*GenericInfo, int, error) { func (client *Client) galleryURL(url string) (*GenericInfo, int, error) { var ret GenericInfo - start := strings.LastIndex(url, "/") + 1 - end := strings.LastIndex(url, "?") - if end == -1 { - end = len(url) - } - id := url[start:end] + id := extractIdFromUrl(url) if id == "" { return nil, -1, errors.New("Could not find ID in URL " + url + ". I was going down imgur.com/gallery/ path.") } @@ -145,12 +146,7 @@ func (client *Client) galleryURL(url string) (*GenericInfo, int, error) { func (client *Client) imageURL(url string) (*GenericInfo, int, error) { var ret GenericInfo - start := strings.LastIndex(url, "/") + 1 - end := strings.LastIndex(url, "?") - if end == -1 { - end = len(url) - } - id := url[start:end] + id := extractIdFromUrl(url) if id == "" { return nil, -1, errors.New("Could not find ID in URL " + url + ". I was going down imgur.com/ path.") } diff --git a/fromURL_test.go b/fromURL_test.go index ef78c4d..3ea7d69 100644 --- a/fromURL_test.go +++ b/fromURL_test.go @@ -13,7 +13,7 @@ func TestGetFromURLAlbumSimulated(t *testing.T) { defer server.Close() client, _ := NewClient(httpC, "testing", "") - ge, status, err := client.GetInfoFromURL("https://imgur.com/a/VZQXk") + ge, status, err := client.GetInfoFromURL("https://imgur.com/a/gianluca-giminis-bikes-VZQXk") if err != nil { t.Errorf("GetInfoFromURL() failed with error: %v", err) t.FailNow() @@ -68,8 +68,8 @@ func TestGetFromURLAlbumReal(t *testing.T) { } TEST_URLS := []string{ - "https://imgur.com/a/VZQXk", - "https://imgur.io/a/VZQXk", + "https://imgur.com/a/gianluca-giminis-bikes-VZQXk", + "https://imgur.io/a/gianluca-giminis-bikes-VZQXk", } for _, url := range TEST_URLS { @@ -130,7 +130,7 @@ func TestGetFromURLGAlbumSimulated(t *testing.T) { defer server.Close() client, _ := NewClient(httpC, "testing", "") - ge, status, err := client.GetInfoFromURL("https://imgur.com/gallery/VZQXk") + ge, status, err := client.GetInfoFromURL("https://imgur.com/gallery/as-turns-out-most-people-cannot-draw-bike-VZQXk") if err != nil { t.Errorf("GetInfoFromURL() failed with error: %v", err) t.FailNow() @@ -166,7 +166,7 @@ func TestGetFromURLGAlbumReal(t *testing.T) { expected map[string]interface{} }{ { - galleryURL: "https://imgur.com/gallery/VZQXk", + galleryURL: "https://imgur.com/gallery/as-turns-out-most-people-cannot-draw-bike-VZQXk", expected: map[string]interface{}{ "title": "As it turns out, most people cannot draw a bike.", "cover": "CJCA0gW", @@ -178,7 +178,7 @@ func TestGetFromURLGAlbumReal(t *testing.T) { }, }, { - galleryURL: "https://imgur.com/gallery/t6l1GiW", + galleryURL: "https://imgur.com/gallery/funny-random-meme-twitter-dump-t6l1GiW", expected: map[string]interface{}{ "title": "Funny Random Meme and Twitter Dump", "cover": "60wTouU", @@ -190,7 +190,7 @@ func TestGetFromURLGAlbumReal(t *testing.T) { }, }, { - galleryURL: "https://imgur.io/gallery/VZQXk", + galleryURL: "https://imgur.io/gallery/as-turns-out-most-people-cannot-draw-bike-VZQXk", expected: map[string]interface{}{ "title": "As it turns out, most people cannot draw a bike.", "cover": "CJCA0gW", @@ -202,7 +202,7 @@ func TestGetFromURLGAlbumReal(t *testing.T) { }, }, { - galleryURL: "https://imgur.io/gallery/t6l1GiW", + galleryURL: "https://imgur.io/gallery/funny-random-meme-twitter-dump-t6l1GiW", expected: map[string]interface{}{ "title": "Funny Random Meme and Twitter Dump", "cover": "60wTouU", @@ -292,8 +292,8 @@ func TestGetURLGalleryImageReal(t *testing.T) { } TEST_URLS := []string{ - "https://imgur.com/gallery/uPI76jY", - "https://imgur.io/gallery/uPI76jY", + "https://imgur.com/gallery/abandoned-chinese-fishing-village-uPI76jY", + "https://imgur.io/gallery/abandoned-chinese-fishing-village-uPI76jY", } for _, url := range TEST_URLS { diff --git a/uploadImage.go b/uploadImage.go index 49eaa0c..201a2a5 100644 --- a/uploadImage.go +++ b/uploadImage.go @@ -5,9 +5,9 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" + "mime/multipart" "net/http" - "net/url" "os" "strconv" ) @@ -15,7 +15,9 @@ import ( // UploadImage uploads the image to imgur // image Can be a binary file, base64 data, or a URL for an image. (up to 10MB) // album optional The id of the album you want to add the image to. -// For anonymous albums, album should be the deletehash that is returned at creation. +// +// For anonymous albums, album should be the deletehash that is returned at creation. +// // dtype The type of the file that's being sent; file, base64 or URL // title optional The title of the image. // description optional The description of the image. @@ -28,17 +30,20 @@ func (client *Client) UploadImage(image []byte, album string, dtype string, titl return nil, -1, errors.New("Passed invalid dtype: " + dtype + ". Please use file/base64/URL.") } - form := createUploadForm(image, album, dtype, title, description) + reqbody := &bytes.Buffer{} + writer := multipart.NewWriter(reqbody) + createUploadForm(writer, image, album, dtype, title, description) + writer.Close() URL := client.createAPIURL("image") - req, err := http.NewRequest("POST", URL, bytes.NewBufferString(form.Encode())) + req, err := http.NewRequest("POST", URL, reqbody) client.Log.Debugf("Posting to URL %v\n", URL) if err != nil { return nil, -1, errors.New("Could create request for " + URL + " - " + err.Error()) } req.Header.Add("Authorization", "Client-ID "+client.imgurAccount.clientID) - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Content-Type", writer.FormDataContentType()) if client.rapidAPIKey != "" { req.Header.Add("X-RapidAPI-Key", client.rapidAPIKey) } @@ -50,7 +55,7 @@ func (client *Client) UploadImage(image []byte, album string, dtype string, titl defer res.Body.Close() // Read the whole body - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return nil, -1, errors.New("Problem reading the body of " + URL + " - " + err.Error()) } @@ -72,23 +77,22 @@ func (client *Client) UploadImage(image []byte, album string, dtype string, titl return img.Ii, img.Status, nil } -func createUploadForm(image []byte, album string, dtype string, title string, description string) url.Values { - form := url.Values{} +func createUploadForm(writer *multipart.Writer, image []byte, album string, dtype string, title string, description string) { + part, _ := writer.CreateFormFile("image", "image") + _, _ = part.Write(image) - form.Add("image", string(image[:])) - form.Add("type", dtype) + _ = writer.WriteField("image", string(image[:])) + _ = writer.WriteField("type", dtype) if album != "" { - form.Add("album", album) + _ = writer.WriteField("album", album) } if title != "" { - form.Add("title", title) + _ = writer.WriteField("title", title) } if description != "" { - form.Add("description", description) + _ = writer.WriteField("description", description) } - - return form } // UploadImageFromFile uploads a file given by the filename string to imgur.