Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dogancelik committed Mar 22, 2017
0 parents commit f9b0f39
Show file tree
Hide file tree
Showing 9 changed files with 397 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.exe
*.png
build/
23 changes: 23 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
image: golang:latest

stages:
- test
- build
- deploy

before_script:
- cd $CI_PROJECT_DIR
- export GOBIN=$GOROOT/bin
- chmod +x run
- ./run prebuild

test:
stage: test
except: [tags]
script: [./run test]

buildall:
stage: build
script: [./run buildall]
artifacts:
paths: [imgops*]
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ImgOps

This is a CLI tool for reverse searching images through ImgOps website.
It supports files and URLs.

## How It Works

1. You upload a file or pass a URL to the tool
2. Depending on your choice, it will open search results from sites you want.
These are Google, TinEye, Yandex, Bing, Reddit and few others
If you don't provide a “target”, it will open ImgOps page with the provided image.

## Download

[Click here](https://github.com/dogancelik/imgops/releases/latest) to download latest version.

## How To Use

Open up your command prompt:

### Upload a file

Reverse search a local file and open Google & TinEye results:

```batch
imgops "C:\my_file.jpg" google,tineye
```

### Pass a URL

Reverse search a URL and open Google results:

```batch
imgops "http://example.com/foobar.jpg" google
```
67 changes: 67 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main

import (
"fmt"
"os"

"github.com/skratchdot/open-golang/open"
)

import . "github.com/tj/go-debug"

var cmdAction string = ""
var debug = Debug("imgops")
var QueryMap map[string]string = getIdMap()

var Version string

func main() {
fmt.Printf("ImgOps %s by Doğan Çelik (dogancelik.com)\n", Version)

cmdPath := ""
cmdAction = ""

if len(os.Args) > 1 {
cmdPath = os.Args[1]
} else {
fmt.Println("No file or URL")
os.Exit(1)
}

if len(os.Args) > 2 {
cmdAction = os.Args[2]
}

debug("Path: %s", cmdPath)
debug("Action: %s", cmdAction)
debug("Queries: %v", QueryMap)

var urls []string
var errUpload error
if isUrl(cmdPath) == true {
debug("Start URL upload")
urls, errUpload = UploadURL(cmdPath, cmdAction)
} else {

if _, err := os.Stat(cmdPath); os.IsNotExist(err) {
fmt.Println("File doesn't exist:", cmdPath)
os.Exit(2)
}
debug("Start file upload")
urls, errUpload = UploadFile(cmdPath, cmdAction)
}

if errUpload != nil && len(urls) == 0 {
fmt.Println("Error during upload:", errUpload)
os.Exit(3)
} else {
if errUpload != nil {
fmt.Printf("Warning wrong action '%s'; will open ImgOps instead\n", cmdAction)
}

for _, url := range urls {
open.Start(url)
}
}

}
62 changes: 62 additions & 0 deletions run
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash

export COMMIT_HASH=`git rev-parse --short @`
export COMMIT_DATE=`git log -1 --pretty=format:%cI | sed -r -e 's/T.*//' -e 's/-//g'`

function PREBUILD {
go get ./...
}

function BUILD {
echo "=== ${FUNCNAME[0]} ==="
echo "GOOS: $GOOS"
echo "GOARCH: $GOARCH"

# If $GOOS or $GOARCH is emtpy, remove dashes
OUT_FILE=`echo "imgops-${GOOS:-_}-${GOARCH:-_}" | sed s/-_//g`
OUT_FILE+=`go env GOEXE`
echo "Filename: $OUT_FILE"

# Use $VERSION if empty use $CI_BUILD_TAG if empty use $CI_BUILD_REF
VERSION=${VERSION:-${CI_BUILD_TAG:-#${CI_BUILD_REF:0:6}}}
echo "Version: ${VERSION:-\$VERSION is empty}"

go build -ldflags "-X main.Version=$VERSION" -o $OUT_FILE
}

function TEST {
echo "=== ${FUNCNAME[0]} ==="
TEST_URL="https://encrypted.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"
OUT_FILE="test.png"
if [[ ! -f $OUT_FILE ]]; then
wget -nv $TEST_URL -O $OUT_FILE
fi
go test
}

function BUILDALL {
echo "=== ${FUNCNAME[0]} ==="
OSES="windows linux darwin"
for OS in $OSES; do
export GOOS=$OS
export GOARCH=amd64
BUILD
done
}

function HELP {
echo -e "ImgOps Build Tool\nCommands: prebuild, build, test, buildall, help"
}

case $1 in
prebuild)
PREBUILD ;;
build)
BUILD ;;
test)
TEST ;;
buildall)
BUILDALL ;;
*)
HELP ;;
esac
78 changes: 78 additions & 0 deletions upload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package main

import (
"errors"
"io/ioutil"
"path/filepath"
"strings"

"github.com/parnurzeal/gorequest"
)

const uploadUrl string = "https://imgops.com/upload/uploadPhoto-action.asp"
const uploadSearch string = "userUploadTempCache"

var defaultAction bool
var finalUrl string

func setDefaultAction(targetAction string) {
if targetAction != "" {
defaultAction = false
} else {
defaultAction = true
}
}

func UploadURL(targetUrl string, targetAction string) ([]string, error) {
setDefaultAction(targetAction)
newUrl := "https://imgops.com/" + targetUrl
finalUrl = newUrl

if defaultAction {
return strings.Fields(newUrl), nil
} else {
_, body, errs := gorequest.New().Get(newUrl).End()
if errs != nil {
return strings.Fields(""), errors.New("GET error")
} else {
return findHref(body, targetAction, finalUrl)
}
}
}

func redirectPolicy(req gorequest.Request, via []gorequest.Request) error {
finalUrl = req.URL.String()
if defaultAction {
return errors.New("Stop redirection")
} else {
return nil
}
}

func UploadFile(targetPath string, targetAction string) ([]string, error) {
setDefaultAction(targetAction)

debug("Read file from path")
bytes, _ := ioutil.ReadFile(targetPath)

debug("Make a POST request")
_, body, errs := gorequest.New().
Post(uploadUrl).
RedirectPolicy(redirectPolicy).
Type("multipart").
SendFile(bytes, filepath.Base(targetPath), "photo").
End()
debug("POST request errors: %v", errs)

debug("Final URL: %s", finalUrl)
debug("Stop redirection: %b", defaultAction)
if defaultAction {
if len(finalUrl) > 0 {
return strings.Fields(finalUrl), nil
} else {
return strings.Fields(""), errors.New("Could not get final URL after Redirect")
}
} else {
return findHref(body, targetAction, finalUrl)
}
}
41 changes: 41 additions & 0 deletions upload_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"strings"
"testing"
)

const testUrl string = "https://encrypted.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"
const testFile string = "test.png"

func TestFileUpload(t *testing.T) {
var err error

if _, err = UploadFile(testFile, ""); err != nil {
t.Error(err)
}

if _, err = UploadFile(testFile, "google"); err != nil {
t.Error(err)
}

if _, err = UploadURL(testFile, "wrong"); !strings.Contains(err.Error(), "No link") {
t.Error(err)
}
}

func TestUrlUpload(t *testing.T) {
var err error

if _, err = UploadURL(testUrl, ""); err != nil {
t.Error(err)
}

if _, err = UploadURL(testUrl, "google, yandex"); err != nil {
t.Error(err)
}

if _, err = UploadURL(testUrl, "wrong"); !strings.Contains(err.Error(), "No link") {
t.Error(err)
}
}
69 changes: 69 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

import (
"errors"
"fmt"
"strings"

"github.com/PuerkitoBio/goquery"
)

func isUrl(targetPath string) bool {
return strings.Contains(targetPath, "http:") || strings.Contains(targetPath, "https:")
}

func getIdMap() map[string]string {
return map[string]string{
"google": "#t85",
"bing": "#t101",
"tineye": "#t11",
"reddit": "#t97",
"yandex": "#t72",
"baidu": "#t74",
"so": "#t109",
"sogou": "#t110",
}
}

func findHref(document, targetStr, finalUrl string) ([]string, error) {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(document))
if err != nil {
return strings.Fields(""), err
} else {
queryList := getQueryList(targetStr)
debug("Queries: %v", queryList)
foundUrls := make([]string, 0, len(queryList))

for _, query := range queryList {
href, attrOk := doc.Find(query).Attr("href")
debug("Get href from query '%s': %v", query, attrOk)

if attrOk {
foundUrls = append(foundUrls, href)
}
}

if len(foundUrls) > 0 {
return foundUrls, nil
} else {
return strings.Fields(finalUrl), errors.New(fmt.Sprintf("No link is found in targets: %s", queryList))
}
}
}

// Returns queries of found targets
func getQueryList(s string) []string {
split := strings.Split(s, ",")

found := make([]string, 0, len(split))
for _, val := range split {
key := strings.TrimSpace(val)
query, mapOk := QueryMap[key]
if mapOk {
debug("Query for '%s' is found: %s", key, query)
found = append(found, query)
}
}

return found
}

0 comments on commit f9b0f39

Please sign in to comment.