elevengo

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 11, 2020 License: MIT Imports: 10 Imported by: 4

README

ElevenGo

GoDoc

A Golang API wrapper for 115 NetDisk Service.

Example

import "github.com/deadblue/elevengo"

// Create agent
agent = elevengo.Default()

// Import credentials to login
cr = &elevengo.Credentials{
    UID: "",
    CID: "",
    SEID: "",
}
if err := agent.ImportCredentials(cr); err != nil {
    panic(err)
}

// List files under root.
for cursor := elevengo.FileCursor(); cursor.HasMore(); cursor.Next() {
    if files, err := agent.FileList("0", cursor); err != nil {
        panic(err)
    } else {
        // TODO: deal with the files
    }
}

You can find more example on GoDoc.

Features

  • Login
    • Import credentials from cookies
    • Login via QRCode
    • Login via Account/Password (No idea)
  • File API
    • List
    • Search
    • Rename
    • Move
    • Copy
    • Delete
    • Mkdir
    • Stat
    • Storage Stat
    • Download
    • Upload
  • Offline API
    • List tasks
    • Create URL task(s)
    • Delete tasks
    • Clear tasks
  • Other
    • Captcha

TODO list

  • Current version:
    • Print some logs via Logger interface.
  • Next version:
    • Handle more upstream errors.
    • Implement download/upload method, with progress echo.

License

MIT

Documentation

Overview

"elevengo" is an API wrapper for 115 NetDisk service, it bases on 115 web APIs which captured from their web pages.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsFileExist

func IsFileExist(err error) bool

func IsFileNotExist

func IsFileNotExist(err error) bool

func IsOfflineCaptcha

func IsOfflineCaptcha(err error) bool

func IsOfflineExist

func IsOfflineExist(err error) bool

func IsQrcodeExpire

func IsQrcodeExpire(err error) bool

Types

type Agent

type Agent struct {
	// contains filtered or unexported fields
}

Agent holds an user's credentials, and provides methods to access upstream server's features, such as file management, offline download, etc.

func Default

func Default() *Agent

Create agent with default settings.

func New

func New(name string) *Agent

Create agent with specific name. The name will be used in User-Agent request header.

func (*Agent) CaptchaKeyImage

func (a *Agent) CaptchaKeyImage(session *CaptchaSession, index int) ([]byte, error)

Get one CAPTCHA key image data.

You can call this method multiple times, it will return the same character in different font on every calling.

It is useful when you try to train your CAPTCHA solver.

func (*Agent) CaptchaStart

func (a *Agent) CaptchaStart() (session *CaptchaSession, err error)

Start a CAPTCHA session.

Example:

// Start CAPTCHA session
session, err := agent.CaptchaStart()
if err != nil {
	panic(err)
}
// TODO: Solve the CAPTCHA here.
// Submit CAPTCHA code
if err = agent.CaptchaSubmit(session, code); err != nil {
	panic(err)
}

func (*Agent) CaptchaSubmit

func (a *Agent) CaptchaSubmit(session *CaptchaSession, code string) (err error)

Submit the CAPTCHA code.

func (*Agent) CreateDownloadTicket

func (a *Agent) CreateDownloadTicket(pickcode string) (ticket *DownloadTicket, err error)

Create a download ticket.

Now Agent does not support downloading file, you need using a thirdparty tool to do that, such as wget/curl/aria2.

Example:

// Create download ticket
ticket, err := agent.CreateDownloadTicket("pickcode")
if err != nil {
	log.Fatal(err)
}
// Download file via "curl"
cmd := exec.Command("/usr/bin/curl", ticket.Url)
for name, value := range ticket.Headers {
	cmd.Args = append(cmd.Args, "-H", fmt.Sprintf("%s: %s", name, value))
}
cmd.Args = append(cmd.Args, "-o", ticket.FileName)
if err = cmd.Run(); err != nil {
	log.Fatal(err)
}

func (*Agent) CreateUploadTicket

func (a *Agent) CreateUploadTicket(parentId string, info UploadInfo) (ticket *UploadTicket, err error)

Create an upload ticket.

When uploading a large file, it is recommended to use a thirdparty tool, such as "curl".

Example:

filename := "/path/to/file"
// Get file info
info, err := os.Stat(filename)
if err != nil {
	log.Fatal(err)
}
// Create upload ticket
ticket, err := agent.CreateUploadTicket(parentId, info)
if err != nil {
	log.Fatal(err)
}
// Upload file via curl
cmd := exec.Command("/usr/bin/curl", "-o", "/dev/null", "-#", ticket.Endpoint)
for name, value := range ticket.Values {
	cmd.Args = append(cmd.Args, "-F", fmt.Sprintf("%s=%s", name, value))
}
cmd.Args = append(cmd.Args, "-F", fmt.Sprintf("%s=@%s", ticket.FileField, filename))
if err = cmd.Run(); err != nil {
	log.Fatal(err)
}

func (*Agent) CredentialsExport

func (a *Agent) CredentialsExport() (cr *Credentials, err error)

Export credentials from agent, you can store it for future use.

func (*Agent) CredentialsImport

func (a *Agent) CredentialsImport(cr *Credentials) (err error)

Import credentials into agent.

func (*Agent) FileCopy

func (a *Agent) FileCopy(parentId string, fileIds ...string) (err error)

Copy files into specific directory.

func (*Agent) FileDelete

func (a *Agent) FileDelete(parentId string, fileIds ...string) (err error)

Delete files from a directory.

func (*Agent) FileList

func (a *Agent) FileList(parentId string, cursor Cursor) (files []*File, err error)

Get file list from specific directory.

The upstream API restricts the data count in response, so for a directory which contains a lot of files. you need pass a cursor to receive the cursor information, and use it to fetch remain files.

The cursor should be created by FileCursor(), and DO NOT pass it as nil even you try to get file list from a empty directory.

func (*Agent) FileMkdir

func (a *Agent) FileMkdir(parentId, name string) (directoryId string, err error)

Create a directory under a directory with specific name.

func (*Agent) FileMove

func (a *Agent) FileMove(parentId string, fileIds ...string) (err error)

Move files into specific directory.

func (*Agent) FileRename

func (a *Agent) FileRename(fileId, name string) (err error)

Rename file.

func (*Agent) FileSearch

func (a *Agent) FileSearch(rootId, keyword string, cursor Cursor) (files []*File, err error)

Recursively search files which's name contains the keyword and under the directory.

func (*Agent) FileStat

func (a *Agent) FileStat(fileId string) (info *FileInfo, err error)

Get file information related to the file ID. Since the upstream response is cheap, this method cat not return more information.

func (*Agent) OfflineAdd

func (a *Agent) OfflineAdd(url ...string) (err error)

Add one or more offline tasks by URL.

func (*Agent) OfflineClear

func (a *Agent) OfflineClear(flag *OfflineClearFlag) (err error)

Clear specific type of offline tasks.

The "flag" parameter indicates which type of tasks will be clear, you can pass nil to clear the done tasks but keep the downloaded files.

func (*Agent) OfflineDelete

func (a *Agent) OfflineDelete(deleteFile bool, hash ...string) (err error)

Delete some offline tasks. if "deleteFile" is true, the downloaded files will be deleted.

func (*Agent) OfflineList

func (a *Agent) OfflineList(cursor Cursor) (tasks []*OfflineTask, err error)

Get some of offline tasks.

The upstream API returns at most 30 tasks for one request, caller need pass a cursor to receive the cursor information, and use it to get remain tasks.

The cursor should be created by OfflineCursor(), DO NOT pass it as nil.

func (*Agent) QrcodeLogin

func (a *Agent) QrcodeLogin(session *QrcodeSession) error

Login through QRcode. You SHOULD call this method ONLY when `QrcodeStatus.IsAllowed()` is true.

func (*Agent) QrcodeStart

func (a *Agent) QrcodeStart() (session *QrcodeSession, err error)

Start a QRcode login process.

Example:

session, err := agent.QrcodeStart()
if err != nil {
	panic(error)
}
// TODO: Show QRcode and prompt user to scan it on mobile app.
for {
	if status, err := agent.QrcodeStatus(session); err != nil {
		panic(err)
	} else {
		if status.IsAllowed() {
			err = agent.QrcodeLogin(session)
			break
		} else status.IsCanceled() {
			fmt.Println("User canceled this login!")
			break
		}
	}
}

func (*Agent) QrcodeStatus

func (a *Agent) QrcodeStatus(session *QrcodeSession) (status QrcodeStatus, err error)

Get QRcode status.

The upstream API uses a long-pull request for 30 seconds, so this API will also block at most 30 seconds, be careful to use it in main goroutine.

The QRcode has 4 status: - Waiting - Scanned - Allowed - Canceled

The QRcode will expire in 5 mimutes, when it expired, an error will be return, caller can use IsQrcodeExipre() to check that.

func (*Agent) StorageStat

func (a *Agent) StorageStat() (info *StorageInfo, err error)

Get storage size information.

func (*Agent) UploadFile

func (a *Agent) UploadFile(parentId, localFile string) (err error)

A simple upload implementation without progress echo.

func (*Agent) Version

func (a *Agent) Version() string

Get agent version.

func (*Agent) VideoHlsContent

func (a *Agent) VideoHlsContent(pickcode string) (content []byte, err error)

Get HLS content of a video.

For video file, the upstream server support HLS streaming. Caller can use this method to get the HLS content, and play it through thirdparty tools, such as "mpv".

Example:

// Get HLS content for a video
hls, err := agent.VideoHlsContent("pickcode")
if err != nil {
	log.Fatal(err)
}
// Start mpv process with reading file from STDIN
cmd := exec.Command("/path/to/mpv", "-")
cmd.Stdin = bytes.NewReader(hls)
if err = cmd.Run(); err != nil {
	log.Fatal(err)
}

type CaptchaSession

type CaptchaSession struct {
	// CAPTCHA image data.
	CodeImage []byte

	// CAPTCHA keys image data.
	KeysImage []byte
	// contains filtered or unexported fields
}

CaptchaSession holds CAPTCHA images and session information during a CAPTCHA process.

There are 4 Chinese characters on "CodeImage" and 10 Chinese characters on "KeysImage" (5 columns by 2 rows). User should find the 4 characters on "CodeImage" from "KeysImage", the indexes of these characters is the CAPTCHA code.

The index bases on 0, starts from left top corner, increases from left to right, then from top to bottom.

For example:

Assume the code image is

+---------------+
| J | F | C | H |
+---------------+

and the keys image is

+-------------------+
| A | B | C | D | E |
+-------------------+
| F | G | H | I | J |
+-------------------+

Then the CAPTCHA code is "9527", you can call Agent.CaptchaSubmit() to submit it.

type Credentials

type Credentials struct {
	UID  string
	CID  string
	SEID string
}

Credentials contains required information that the upstream server uses to authenticate a signed-in user.

In detail, three cookies are required: "UID", "CID", "SEID", you can find them from your browser cookie storage.

type Cursor

type Cursor interface {

	// Return true if the cursor has not been used or there is some data remain.
	HasMore() bool

	// Move cursor to the start of the remaining data.
	Next()

	// Return total amount of the data.
	Total() int
}

Due to the upstream API restriction, some list methods can not get the whole data in one request. Cursor is design for these methods, to get data page-by-page.

There are two types of cursors for different methods:

* File cursor: created by FileCursor(), used in Agent.FileList() and Agent.FileSearch().

* Offline cursor: created by OfflineCursor(), used in Agent.OfflineList().

A typical usage (call FileList for example):

// Assume "agent" is an Agent instance, and "parentId" is the directory ID
// where you want to get file list from.
for cursor := FileCursor(); cursor.HasMore(); cursor.Next() {
	if files, err := agent.FileList(parentId, cursor); err != nil {
		// handle error
		break
	} else {
		// deal with the files
	}
}

func FileCursor

func FileCursor() Cursor

Create a file cursor for "Agent.FileList()" and "Agent.FileSearch()".

func OfflineCursor

func OfflineCursor() Cursor

Create a cursor for "Agent.OfflineList()" method.

type DownloadTicket

type DownloadTicket struct {
	// Download URL.
	Url string
	// Request headers which SHOULD be sent with download URL.
	Headers map[string]string
	// File name.
	FileName string
	// File size in bytes.
	FileSize int64
}

DownloadTicket contains all required information to download a file.

type File

type File struct {
	// True means a file.
	IsFile bool
	// True means a directory.
	IsDirectory bool
	// Unique ID for the file.
	FileId string
	// Parent directory ID.
	ParentId string
	// File name.
	Name string
	// File size in bytes, 0 for directory.
	Size int64
	// Pick code, you can use this to create a download ticket.
	PickCode string
	// Sha1 hash value of the file, empty for directory.
	Sha1 string
	// Create time of the file.
	CreateTime *time.Time
	// Update time of the file.
	UpdateTime *time.Time
}

File describe a remote file or directory.

type FileInfo

type FileInfo struct {
	// True means a file.
	IsFile bool
	// True means a directory.
	IsDirectory bool
	// File name.
	Name string
	// Sha1 hash value of the file, empty for directory.
	Sha1 string
	// Pick code for downloading.
	PickCode string
	// Create time of the file.
	CreateTime *time.Time
	// Update time of the file.
	UpdateTime *time.Time
	// Parent directory ID list.
	ParentIds []string
}

FileInfo is returned by FileStat(), contains basic information of a file.

type OfflineClearFlag

type OfflineClearFlag struct {
	// contains filtered or unexported fields
}

Parameter for "Agent.OfflineClear()" method. Default value is to clear all done tasks without deleteing downloaded files.

func (*OfflineClearFlag) All

func (f *OfflineClearFlag) All(delete bool) *OfflineClearFlag

Clear all tasks, delete the downloaded files if "delete" is true.

func (*OfflineClearFlag) Done

func (f *OfflineClearFlag) Done(delete bool) *OfflineClearFlag

Clear done tasks, delete the downloaded files if "delete" is true.

func (*OfflineClearFlag) Failed

func (f *OfflineClearFlag) Failed() *OfflineClearFlag

Clear failed tasks.

func (*OfflineClearFlag) Running

func (f *OfflineClearFlag) Running() *OfflineClearFlag

Clean running tasks.

type OfflineTask

type OfflineTask struct {
	// Unique hash of the task.
	InfoHash string
	// Task name.
	Name string
	// Task URL.
	Url string
	// Task status.
	Status OfflineTaskStatus
	// Download percent of the task, 0 to 100.
	Percent float64
	// File ID of the downloaded file on remote server.
	FileId string
}

OfflineTask describe a remote download task.

type OfflineTaskStatus

type OfflineTaskStatus int

Describe status of an offline task.

func (OfflineTaskStatus) IsDone

func (s OfflineTaskStatus) IsDone() bool

Return true if the task has been done.

func (OfflineTaskStatus) IsFailed

func (s OfflineTaskStatus) IsFailed() bool

Return true if the task has been failed.

func (OfflineTaskStatus) IsRunning

func (s OfflineTaskStatus) IsRunning() bool

Return true if the task is still running.

type QrcodeSession

type QrcodeSession struct {
	// The raw data of QR code, caller should use thridparty tools/libraries
	// to convert it into QR code matrix or image.
	Content string
	// contains filtered or unexported fields
}

QrcodeSession holds the information during a QRcode login process.

type QrcodeStatus

type QrcodeStatus int

QrcodeStatus is returned by `Agent.QrcodeStatus()`. You can call `QrcodeStatus.IsXXX()` method to check the status, or directly check its value.

func (QrcodeStatus) IsAllowed

func (qs QrcodeStatus) IsAllowed() bool

Return true if user allowed this login process, you can call "Agent.QrcodeLogin()" after then.

func (QrcodeStatus) IsCanceled

func (qs QrcodeStatus) IsCanceled() bool

Return true if user canceled this login process.

func (QrcodeStatus) IsScanned

func (qs QrcodeStatus) IsScanned() bool

Return true if user has scanned the QRcode, but still not allow or cancel this login.

func (QrcodeStatus) IsWaiting

func (qs QrcodeStatus) IsWaiting() bool

Return true if user still does not scan the QRcode.

type StorageInfo

type StorageInfo struct {
	// Total size in bytes.
	Size int64
	// Used size in bytes.
	Used int64
	// Avail size in bytes.
	Avail int64
}

Storage information.

type UploadInfo

type UploadInfo interface {
	// Name of the upload file.
	Name() string
	// Size in bytes of the upload file.
	Size() int64
}

UploadInfo contains all required information to create an upload ticket.

If you want to upload a generic file, you can use os.FileInfo as UploadInfo, see "Agent.CreateUploadTicket" doc for detail.

If you want to upload a memory data as file, you need implement it.

type UploadTicket

type UploadTicket struct {
	// Remote URL which will receive the file content.
	Endpoint string
	// Field name for the upload file.
	FileField string
	// Other parameters that should be sent with the file.
	Values map[string]string
}

UploadTicket contains all required information to upload a file.

Directories

Path Synopsis
This package contains all internal types that you needn't care about.
This package contains all internal types that you needn't care about.
"plugin" package declare some interfaces that developer can implement himself.
"plugin" package declare some interfaces that developer can implement himself.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL