Documentation
¶
Overview ¶
Package lanzou resolves Lanzou (蓝奏云) public and password share links.
Features:
- public / password shares
- Alibaba WAF/ESA acw_sc__v2 cookie
- CDN pseudo-link resolution and risk-page fallback
- optional local download
Index ¶
- Constants
- Variables
- func CalcAcwScV2(arg1 string) (string, error)
- func CalcAcwScV2With(arg1, mask string, perm []int) (string, error)
- func ConfigKeys() [][2]string
- func ConfigPathUsed() string
- func DefaultConfigPath() string
- func DownloadShareWithName(shareURL, password, destDir, filename string) (string, error)
- func ExtractArg1(html string) (string, bool)
- func ExtractShareDescription(html string) string
- func FormatConvertNote(origName, uploadName, mode, suffix string, size int64) string
- func FormatNoteDebug(desc string) string
- func FormatPartNote(groupID, origName, uploadName string, index, total int, size int64, ...) string
- func FormatRawNote(origName, uploadName string, size int64) string
- func FormatSplitName(format, origBase string, index, total int, suffix string) string
- func GetConfigValue(cfg Config, key string) (string, error)
- func IsAcwChallenge(html string) bool
- func IsPasswordProtected(html string) bool
- func IsUploadAllowedExt(ext string) bool
- func NoteKind(desc string) string
- func SaveConfig(path string, cfg Config) error
- func SetConfigCache(cfg Config)
- type Account
- func (a *Account) Cookie() string
- func (a *Account) CreateFolder(name, parentID, describe string) (string, error)
- func (a *Account) DeleteFile(fileID string) (string, error)
- func (a *Account) DeleteFolder(folderID string) (string, error)
- func (a *Account) DeleteFolderByName(name, fatherID string) (string, error)
- func (a *Account) EnsureLogin() error
- func (a *Account) FetchNotes(list []ListEntry) map[string]string
- func (a *Account) GetFileDescribe(fileID string) (string, error)
- func (a *Account) GetFileDownloadInfo(fileID string) (shareURL, pwd string, err error)
- func (a *Account) GetFileInfo(fileID string) (*FileInfo, error)
- func (a *Account) GetFileInfoRaw(fileID string) (string, error)
- func (a *Account) GetFilePassword(fileID string) (string, error)
- func (a *Account) GetFolderIDByName(name, fatherID string) (string, error)
- func (a *Account) GetFolderInfo(folderID string) (*FolderInfo, error)
- func (a *Account) List(folderID string) ([]ListEntry, error)
- func (a *Account) Login() error
- func (a *Account) MoveFile(fileID, folderID string) (string, error)
- func (a *Account) SetCookie(cookie string)
- func (a *Account) SetFileDescribe(fileID, describe string) (string, error)
- func (a *Account) SetFilePassword(fileID, pwd string) (string, error)
- func (a *Account) SetFolderNameAndDescribe(folderID, name, describe string) (string, error)
- func (a *Account) SetFolderPassword(folderID, pwd string) (string, error)
- func (a *Account) Upload(localPath, folderID string) (*UploadResult, error)
- func (a *Account) Verification() bool
- type AccountOption
- type Client
- func (c *Client) Download(rawURL, destDir, filename, referer string) (string, error)
- func (c *Client) DownloadShare(shareURL, password, destDir, filename string) (string, error)
- func (c *Client) DownloadShareNote(shareURL string, opt DownloadShareOptions) (string, error)
- func (c *Client) Parse(shareURL string, opt Options) (*Result, error)
- func (c *Client) ResolveDirectURL(cdnURL string, shareReferer ...string) (string, error)
- type Config
- type ConvertMeta
- type DisplayEntry
- type DownloadShareOptions
- type FileInfo
- type FileNote
- type FolderInfo
- type ListEntry
- type Options
- type PartMeta
- type Result
- type UploadPart
- type UploadResult
Constants ¶
const ( EntryFolder = 0 EntryFile = 1 )
EntryType: 0 folder, 1 file.
const NoteVersion = 1
Note schema version.
const Version = "0.3.6"
Version is the library / CLI release version.
Variables ¶
var (
ErrPasswordRequired = errors.New("password required for this share link")
)
Sentinel errors.
Functions ¶
func CalcAcwScV2 ¶
CalcAcwScV2 computes cookie value from arg1.
func CalcAcwScV2With ¶
CalcAcwScV2With allows custom mask/perm.
func ConfigKeys ¶ added in v0.2.4
func ConfigKeys() [][2]string
ConfigKeys lists settable keys with short descriptions.
func ConfigPathUsed ¶ added in v0.2.4
func ConfigPathUsed() string
ConfigPathUsed returns the path last used by GetConfig/SaveConfig.
func DefaultConfigPath ¶ added in v0.2.4
func DefaultConfigPath() string
DefaultConfigPath returns ~/.lanzou/config.json (or ./lanzou.config.json).
func DownloadShareWithName ¶ added in v0.3.6
DownloadShareWithName is DownloadShare with an explicit save filename.
func ExtractArg1 ¶
ExtractArg1 extracts arg1 from challenge HTML.
func ExtractShareDescription ¶ added in v0.3.6
ExtractShareDescription pulls the "文件描述" field from a share page HTML. Lanzou often HTML-entity-encodes the JSON note ("...).
func FormatConvertNote ¶ added in v0.2.5
FormatConvertNote builds a JSON convert note.
func FormatNoteDebug ¶ added in v0.2.8
FormatNoteDebug is a short human summary for logs.
func FormatPartNote ¶ added in v0.2.4
func FormatPartNote(groupID, origName, uploadName string, index, total int, size int64, nextFileID string) string
FormatPartNote builds a JSON part note. nextFileID is the remote file id of the next part (empty for last).
func FormatRawNote ¶ added in v0.3.0
FormatRawNote builds a JSON note for an upload that did not convert the suffix.
func FormatSplitName ¶ added in v0.2.4
FormatSplitName builds a part filename from template.
func GetConfigValue ¶ added in v0.2.4
GetConfigValue returns string form of one key.
func IsAcwChallenge ¶
IsAcwChallenge reports whether HTML is an acw challenge page.
func IsPasswordProtected ¶
IsPasswordProtected detects password share HTML.
func IsUploadAllowedExt ¶ added in v0.2.3
IsUploadAllowedExt reports whether ext (with or without leading dot) is accepted by Lanzou html5up.php.
func SaveConfig ¶ added in v0.2.4
SaveConfig writes cfg to path (empty = default path), creating parent dirs.
func SetConfigCache ¶ added in v0.2.4
func SetConfigCache(cfg Config)
SetConfigCache replaces the in-memory config (does not write disk).
Types ¶
type Account ¶ added in v0.1.3
type Account struct {
// contains filtered or unexported fields
}
Account is a logged-in Lanzou control-panel client.
func NewAccount ¶ added in v0.1.3
func NewAccount(username, password string, opts ...AccountOption) *Account
NewAccount creates an account client. Call Login or LoadCookie before API use.
func (*Account) CreateFolder ¶ added in v0.1.3
CreateFolder creates a folder. Returns raw JSON response body.
func (*Account) DeleteFile ¶ added in v0.1.3
DeleteFile deletes a file by id.
func (*Account) DeleteFolder ¶ added in v0.1.3
DeleteFolder deletes a folder by id.
func (*Account) DeleteFolderByName ¶ added in v0.1.3
DeleteFolderByName deletes a child folder by name.
func (*Account) EnsureLogin ¶ added in v0.1.3
EnsureLogin logs in if Verification fails.
func (*Account) FetchNotes ¶ added in v0.2.4
FetchNotes loads descriptions for file entries (best-effort).
func (*Account) GetFileDescribe ¶ added in v0.1.3
GetFileDescribe returns file description.
func (*Account) GetFileDownloadInfo ¶ added in v0.1.3
GetFileDownloadInfo returns share URL + password for a managed file.
func (*Account) GetFileInfo ¶ added in v0.1.3
GetFileInfo returns parsed file info.
func (*Account) GetFileInfoRaw ¶ added in v0.1.3
GetFileInfoRaw returns raw JSON for task=22.
func (*Account) GetFilePassword ¶ added in v0.1.3
GetFilePassword returns share password for a file.
func (*Account) GetFolderIDByName ¶ added in v0.1.3
GetFolderIDByName finds a child folder id by name under fatherID.
func (*Account) GetFolderInfo ¶ added in v0.1.3
func (a *Account) GetFolderInfo(folderID string) (*FolderInfo, error)
GetFolderInfo scrapes folder info page.
func (*Account) List ¶ added in v0.1.3
List returns folders + files under folderID ("-1" is root). Folders via task=47, files via task=5 (JSON APIs).
func (*Account) Login ¶ added in v0.1.3
Login POSTs task/uid/pwd to mlogin.php (same as browser/curl simple login).
func (*Account) SetFileDescribe ¶ added in v0.1.3
SetFileDescribe sets file description.
func (*Account) SetFilePassword ¶ added in v0.1.3
SetFilePassword sets a file share password.
func (*Account) SetFolderNameAndDescribe ¶ added in v0.1.3
SetFolderNameAndDescribe renames a folder and sets description.
func (*Account) SetFolderPassword ¶ added in v0.1.3
SetFolderPassword enables password on a folder.
func (*Account) Upload ¶ added in v0.1.3
func (a *Account) Upload(localPath, folderID string) (*UploadResult, error)
Upload uploads a local file to folderID ("-1" = root) via html5up.php.
Behaviour is controlled by GetConfig():
- suffix_auto_convert / suffix_name / suffix_mode for blocked extensions
- split_enable / split_size_mb / split_name_format / split_note for large files
Server hard limit remains 100MB per request.
func (*Account) Verification ¶ added in v0.1.3
Verification checks whether the current cookie session is valid.
type AccountOption ¶ added in v0.1.3
type AccountOption func(*Account)
AccountOption configures Account.
func WithAccountBase ¶ added in v0.1.3
func WithAccountBase(base string) AccountOption
WithAccountBase overrides the control-panel origin (default up.woozooo.com).
func WithCookieFile ¶ added in v0.1.3
func WithCookieFile(path string) AccountOption
WithCookieFile sets a path to load/save session cookies.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client holds HTTP state (cookies) for a lanzou session.
func (*Client) Download ¶
Download saves url into destDir and returns the path. Progress is printed to stderr when Content-Length is known.
func (*Client) DownloadShare ¶ added in v0.3.3
DownloadShare parses a share link and downloads in one flow, streaming the CDN body when the first response is already the file (avoids one-shot token burn).
func (*Client) DownloadShareNote ¶ added in v0.3.6
func (c *Client) DownloadShareNote(shareURL string, opt DownloadShareOptions) (string, error)
DownloadShareNote parses a share link, downloads, and applies convert/part notes:
- convert (zip): download then unzip single entry to original name
- convert (rename) / raw: save as original name
- part: download this part and follow next file ids (needs Account), merge to original name
Without a note, behaves like DownloadShare.
func (*Client) ResolveDirectURL ¶
ResolveDirectURL turns a CDN pseudo link into a downloadable URL. shareReferer should be the original share page URL when available.
Note: if the first CDN response is already a file stream, this function discards the body and returns cdnURL for a second GET. Prefer DownloadCDN / DownloadShare for large one-shot links.
type Config ¶ added in v0.2.4
type Config struct {
// SuffixAutoConvert: when true, unsupported suffixes are converted before upload.
SuffixAutoConvert bool `json:"suffix_auto_convert"`
// SuffixName: target extension without leading dot (default "zip").
SuffixName string `json:"suffix_name"`
// SuffixMode: "zip" = real compress; "rename" = only change/append extension.
SuffixMode string `json:"suffix_mode"`
// SplitEnable: split files larger than SplitSizeMB into chunks.
SplitEnable bool `json:"split_enable"`
// SplitSizeMB: max size of each chunk (must be 1..100, default 90).
SplitSizeMB int `json:"split_size_mb"`
// SplitNameFormat placeholders:
// {name} original basename without final ext
// {ext} original extension (no dot)
// {index} 1-based part index (zero-padded to 3 by default via {index:03d})
// {total} total parts
// {suffix} configured SuffixName
// Default: "{name}_s{index:03d}.{suffix}"
// Avoid "{name}_part{index}.zip" / "{name}.part{index}.zip":
// Lanzou CDN returns offline ERROR:102 for large files named *partNNN*.
// Note: names like "x.part001.zip" are rejected by Lanzou (error 7071);
// use underscore form instead.
SplitNameFormat string `json:"split_name_format"`
// SplitNote: write part metadata into file description after upload.
SplitNote bool `json:"split_note"`
// ListUnescape: group split parts when listing.
ListUnescape bool `json:"list_unescape"`
}
Config holds user preferences for upload conversion / splitting / list display. Stored as JSON at ~/.lanzou/config.json by default.
func DefaultConfig ¶ added in v0.2.4
func DefaultConfig() Config
DefaultConfig returns sensible defaults.
func GetConfig ¶ added in v0.2.4
func GetConfig() Config
GetConfig returns the process-wide cached config (loads once).
func LoadConfig ¶ added in v0.2.4
LoadConfig reads config from path (empty = default path). Missing file → defaults.
type ConvertMeta ¶ added in v0.2.5
type ConvertMeta struct {
Name string // original basename
As string // uploaded basename
Mode string // zip | rename (convert only)
Suffix string
Size int64
Raw bool // true when kind=raw
}
ConvertMeta is parsed from a convert (or raw) note.
func ParseConvertNote ¶ added in v0.2.5
func ParseConvertNote(desc string) (ConvertMeta, bool)
ParseConvertNote extracts ConvertMeta from convert or raw notes. raw is treated as a convert-with-same-name for resolution/display.
type DisplayEntry ¶ added in v0.2.4
type DisplayEntry struct {
// Kind: "DIR", "FILE", "SPLIT"
Kind string
// ID is folder/file id, or first-part id for SPLIT groups.
ID string
// Name is the display name (original name for SPLIT).
Name string
// Size is human size string when available.
Size string
// Extra is description / part summary.
Extra string
// Parts holds members when Kind=="SPLIT".
Parts []ListEntry
// Meta is filled for SPLIT from notes.
Meta *PartMeta
// Raw is the underlying list entry for non-grouped rows.
Raw *ListEntry
}
DisplayEntry is a list row after optional split-unescape grouping.
func UnescapeList ¶ added in v0.2.4
func UnescapeList(list []ListEntry, noteByID map[string]string, enabled bool) []DisplayEntry
UnescapeList groups split parts (via file description notes) into virtual rows. Folders and non-part files pass through unchanged. When list_unescape is false, returns a flat mapping of list entries.
noteByID is optional: map fileID → description. If nil / missing, only filename-based heuristics are NOT applied — notes are authoritative.
type DownloadShareOptions ¶ added in v0.3.6
DownloadShareOptions controls note-aware share download.
type FileNote ¶ added in v0.2.8
type FileNote struct {
V int `json:"v"`
Kind string `json:"kind"` // raw | convert | part
Name string `json:"name,omitempty"`
As string `json:"as,omitempty"`
Mode string `json:"mode,omitempty"`
Suffix string `json:"suffix,omitempty"`
ID string `json:"id,omitempty"`
Index int `json:"index,omitempty"`
Total int `json:"total,omitempty"`
Size int64 `json:"size,omitempty"`
Next string `json:"next,omitempty"` // next part file id (kind=part)
}
FileNote is the unified JSON metadata stored in Lanzou file descriptions. Schema v1 only (no legacy text markers):
{"v":1,"kind":"raw","name":"a.txt","as":"a.txt","size":12}
{"v":1,"kind":"convert","name":"a.dex","as":"a.dex.zip","mode":"zip","suffix":"zip","size":20}
{"v":1,"kind":"part","id":"G1","name":"big.bin","as":"big_part001.zip","index":1,"total":3,"size":1048576,"next":"FILEID2"}
For split files, each part's "next" is the remote file id of the following part (empty/absent on the last part). Clients may walk head → next → next.
func ParseFileNote ¶ added in v0.2.8
ParseFileNote parses a v1 JSON note only (after HTML unescape).
type FolderInfo ¶ added in v0.1.3
type FolderInfo struct {
Name string
Description string
URL string
Password string
FileCount string
FileSize string
}
FolderInfo holds scraped folder metadata.
type ListEntry ¶ added in v0.1.3
type ListEntry struct {
Type int `json:"type"` // 0 folder, 1 file
ID string `json:"id"`
Name string `json:"name"`
URL string `json:"url,omitempty"`
Size string `json:"size,omitempty"`
Time string `json:"time,omitempty"`
Description string `json:"description,omitempty"`
}
ListEntry is a folder or file row.
type Options ¶
Options for Parse.
func DefaultOptions ¶
func DefaultOptions() Options
DefaultOptions returns options with ResolveDirect enabled.
type PartMeta ¶ added in v0.2.4
type PartMeta struct {
GroupID string
Name string
As string
Index int
Total int
Size int64
Next string // next part file id
}
PartMeta is parsed from a part note.
func ParsePartNote ¶ added in v0.2.4
ParsePartNote extracts PartMeta from a JSON part note.
type Result ¶
type Result struct {
FID string
Filename string
PasswordProtected bool
CDNDomain string
Telecom string
Unicom string
Normal string
Direct string
SavedPath string
// Description is the share-page "文件描述" (often a JSON FileNote).
Description string
// Note is the parsed FileNote when Description is a v1 note.
Note *FileNote
// OrigName is the original basename from a convert/part/raw note.
OrigName string
// NoteKind is raw|convert|part when a note is present.
NoteKind string
}
Result of a successful Parse.
type UploadPart ¶ added in v0.2.4
UploadPart is one chunk of a split upload.
type UploadResult ¶ added in v0.1.4
type UploadResult struct {
FileID string // first / only file id
Name string // first / only remote name
RawJSON string
FolderID string
// Parts is non-empty when the file was split.
Parts []UploadPart `json:"parts,omitempty"`
// OrigName is the original local basename.
OrigName string `json:"orig_name,omitempty"`
// GroupID links split parts via file description.
GroupID string `json:"group_id,omitempty"`
}
UploadResult is the outcome of a successful Upload (single or multi-part).