Advertisement
Guest User

Untitled

a guest
Mar 20th, 2017
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.75 KB | None | 0 0
  1. package uptobox
  2.  
  3. import (
  4. "github.com/ncw/rclone/fs"
  5. "github.com/pkg/errors"
  6. "net/http"
  7. "net/http/cookiejar"
  8. "net/url"
  9. "encoding/json"
  10. "time"
  11. "io"
  12. "github.com/ncw/rclone/dircache"
  13. "path"
  14. "strings"
  15. "github.com/PuerkitoBio/goquery"
  16. "regexp"
  17. "strconv"
  18. "fmt"
  19. "mime/multipart"
  20. "bytes"
  21. "io/ioutil"
  22. )
  23.  
  24. func init() {
  25. fs.Register(&fs.RegInfo{
  26. Name: "Uptobox",
  27. Description: "Uptobox Drive",
  28. NewFs: NewFs,
  29. Options: []fs.Option{
  30. {
  31. Name: "name",
  32. Help: "Uptobox username",
  33. Optional: false,
  34. },
  35. {
  36. Name: "pass",
  37. Help: "Uptobox password",
  38. Optional: false,
  39. IsPassword: true,
  40. },
  41. },
  42. })
  43. }
  44.  
  45. type Fs struct {
  46. name string
  47. root string
  48. features *fs.Features // optional features
  49. token string
  50. dirCache *dircache.DirCache
  51. trueRootID string
  52. httpClient *http.Client
  53. }
  54.  
  55. type Object struct {
  56. fs *Fs
  57. remote string
  58. id string
  59. size int64
  60. date time.Time
  61. numId string
  62. }
  63.  
  64. type loginResponse struct {
  65. Error string `json:"error"`
  66. Success string `json:"success"`
  67. Msg string `json:"msg"`
  68. }
  69.  
  70. // NewFs constructs an Fs from the path, container:path
  71. func NewFs(name, root string) (fs.Fs, error) {
  72. root = strings.Trim(root, "/")
  73. user := fs.ConfigFileGet(name, "name")
  74. pass := fs.ConfigFileGet(name, "pass")
  75.  
  76. if user == "" {
  77. return nil, errors.New("No username specified")
  78. }
  79. if pass == "" {
  80. return nil, errors.New("No password speciefied")
  81. }
  82. pass, err := fs.Reveal(pass)
  83. if err != nil {
  84. return nil, err
  85. }
  86.  
  87. // Get auth cookie
  88. resp, err := http.PostForm("https://login.uptobox.com/logarithme",
  89. url.Values{"login": {user}, "password": {pass}, "op": {"login"}})
  90.  
  91. if err != nil || resp.StatusCode != 200 {
  92. return nil, errors.New("Can't login")
  93. }
  94.  
  95. var jsonResponse loginResponse
  96. err = json.NewDecoder(resp.Body).Decode(&jsonResponse)
  97.  
  98. if err != nil {
  99. return nil, err
  100. }
  101. if jsonResponse.Error != "" {
  102. return nil, errors.New(jsonResponse.Error)
  103. }
  104.  
  105. // Get Cookie
  106. cookie := ""
  107. for _, ck := range resp.Cookies() {
  108. if ck.Name == "xfss" {
  109. cookie = ck.Value
  110. break
  111. }
  112. }
  113. if cookie == "" {
  114. return nil, errors.New("Invalid authentification cookie")
  115. }
  116.  
  117. // Create http client with auth cookie
  118. u, _ := url.Parse("https://uptobox.com")
  119. jar, _ := cookiejar.New(nil)
  120. jar.SetCookies(u, []*http.Cookie{{
  121. Name: "xfss",
  122. Value: cookie,
  123. Path: "/",
  124. Domain: ".uptobox.com",
  125. }})
  126.  
  127. // FS structure
  128. f := &Fs{
  129. name: name,
  130. root: root,
  131. token: "",
  132. trueRootID: "0",
  133. httpClient: &http.Client{
  134. Jar: jar,
  135. CheckRedirect: func(req *http.Request, via []*http.Request) error {
  136. return http.ErrUseLastResponse
  137. },
  138. },
  139. }
  140.  
  141. //Retrieve Uptobox Token
  142. resp, err = f.httpClient.Get("https://uptobox.com/?op=my_files")
  143. defer resp.Body.Close()
  144.  
  145. doc, err := goquery.NewDocumentFromReader(resp.Body)
  146. if err != nil {
  147. return nil, err
  148. }
  149.  
  150. // Extract token
  151. // Todo : Optimize
  152. /*tokenInput := doc.Find(".input_append input[name=token]")
  153. tokenValue := tokenInput.Attr("value")
  154. if tokenValue == nil {
  155. return nil, errors.New("Can't retrieve token")
  156. }
  157. f.token = tokenValue*/
  158. doc.Find(".input_append input[name=token]").Each(func(idx int, sel *goquery.Selection) {
  159. for _, a := range sel.Nodes[0].Attr {
  160. if a.Key == "value" {
  161. f.token = a.Val
  162. }
  163. }
  164. })
  165.  
  166. // Set features
  167. f.features = (&fs.Features{}).Fill(f)
  168.  
  169. // Init dircache
  170. f.dirCache = dircache.New(root, "0", f)
  171. err = f.dirCache.FindRoot(false)
  172. if err != nil {
  173. // Assume it is a file
  174. newRoot, remote := dircache.SplitPath(root)
  175. newF := *f
  176. newF.dirCache = dircache.New(newRoot, f.trueRootID, &newF)
  177. newF.root = newRoot
  178. // Make new Fs which is the parent
  179. err = newF.dirCache.FindRoot(false)
  180. if err != nil {
  181. // No root so return old f
  182. return f, nil
  183. }
  184. //Find File
  185. _, err := f.FindFile(newF.dirCache.RootID(), remote)
  186. if err != nil {
  187. if err == fs.ErrorObjectNotFound {
  188. // File doesn't exist so return old f
  189. return f, nil
  190. }
  191. return nil, err
  192. }
  193. // return an error with an fs which points to the parent
  194. return &newF, fs.ErrorIsFile
  195. }
  196. // Return fs
  197. return f, nil
  198. }
  199.  
  200. // Name of the remote (as passed into NewFs)
  201. func (f *Fs) Name() string {
  202. return f.name
  203. }
  204.  
  205. // Root of the remote (as passed into NewFs)
  206. func (f *Fs) Root() string {
  207. return f.root
  208. }
  209.  
  210. // String converts this Fs to a string
  211. func (f *Fs) String() string {
  212. return fmt.Sprintf("Uptobox")
  213. }
  214.  
  215. // Precision return the precision of this Fs
  216. func (f *Fs) Precision() time.Duration {
  217. return time.Second
  218. }
  219.  
  220. // Hashes returns the supported hash sets.
  221. func (f *Fs) Hashes() fs.HashSet {
  222. return fs.HashSet(fs.HashNone)
  223. }
  224.  
  225. // Features returns the optional features of this Fs
  226. func (f *Fs) Features() *fs.Features {
  227. return f.features
  228. }
  229.  
  230. // ListDir reads the directory specified by the job into out, returning any more jobs
  231. func (f *Fs) ListDir(out fs.ListOpts, job dircache.ListDirJob) (jobs []dircache.ListDirJob, err error) {
  232.  
  233. // Get max tries value
  234. maxTries := fs.Config.LowLevelRetries
  235.  
  236. // Try
  237. for tries := 1; tries <= maxTries; tries++ {
  238.  
  239. // Send request
  240. resp, err := f.httpClient.Get("https://uptobox.com/?op=my_files&fld_id=" + job.DirID)
  241.  
  242. // Check http code and retry
  243. if err != nil || resp.StatusCode != 200 {
  244. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  245. fs.Debugf(f, "Directory listing failed for %q, low level retry %d/%d", job.Path, tries, maxTries)
  246. continue
  247. }
  248.  
  249. // Parse HTML
  250. doc, _ := goquery.NewDocumentFromReader(resp.Body)
  251.  
  252. // Extract Files
  253. doc.Find("table.files .cell_files").Each(func(idx int, sel *goquery.Selection) {
  254. name, _ := sel.Find("td:nth-child(2) a").Html()
  255. fileUrl, _ := sel.Find("td:nth-child(2) a").Attr("href")
  256. id := path.Base(fileUrl)
  257.  
  258. // Only for real files
  259. if name != "&nbsp;" && name != "" && name != " " {
  260.  
  261. fullfile, err := f.GetFile(id, job.Path)
  262. if err != nil {
  263. return
  264. }
  265.  
  266. out.Add(fullfile)
  267. }
  268. })
  269.  
  270. // Extract Folders
  271. doc.Find("table.files td:not([style='max-width:1000px;']):nth-child(1) a").Each(func(idx int, sel *goquery.Selection) {
  272. reg, _ := regexp.Compile("(.*) \\((.*)$")
  273. name := reg.ReplaceAllString(sel.Text(), "$1")
  274. dirlink, _ := sel.Attr("href")
  275. dirid := strings.Replace(dirlink, "?op=my_files&fld_id=", "", 1)
  276.  
  277. if out.IncludeDirectory(job.Path + name) {
  278.  
  279. // Only for reals paths
  280. if name != "&nbsp;" && name != "" && name != " " {
  281.  
  282. // Create dir item
  283. dir := &fs.Dir{
  284. Name: job.Path + name,
  285. Bytes: -1,
  286. Count: -1,
  287. }
  288.  
  289. // Add directory
  290. if out.AddDir(dir) {
  291. return
  292. }
  293.  
  294. // Recursive path
  295. if job.Depth > 0 {
  296. jobs = append(jobs, dircache.ListDirJob{DirID: dirid, Path: job.Path + name + "/", Depth: job.Depth - 1})
  297. }
  298. }
  299. }
  300. })
  301.  
  302. // Close HTML Request
  303. resp.Body.Close()
  304.  
  305. // Return directory
  306. return jobs, nil
  307. }
  308.  
  309. // Error
  310. return nil, err
  311. }
  312.  
  313. // List walks the path returning files and directories into out
  314. func (f *Fs) List(out fs.ListOpts, dir string) {
  315. f.dirCache.List(f, out, dir)
  316. }
  317.  
  318. func (f *Fs) NewObject(remote string) (fs.Object, error) {
  319. return f.FindFile(f.dirCache.RootID(), remote)
  320. }
  321.  
  322. func (f *Fs) Put(in io.Reader, src fs.ObjectInfo) (fs.Object, error) {
  323. f.dirCache.FindRoot(true)
  324.  
  325. resp, err := f.httpClient.Get("https://uptobox.com/")
  326. defer resp.Body.Close()
  327. doc, _ := goquery.NewDocumentFromReader(resp.Body)
  328. uploadUrl, _ := doc.Find("form#fileupload").Attr("action")
  329.  
  330. var bodyReader io.Reader
  331. bodyReader, bodyWriter := io.Pipe()
  332. writer := multipart.NewWriter(bodyWriter)
  333. contentType := writer.FormDataContentType()
  334. contentLength := int64(-1)
  335.  
  336. buf := make([]byte, 1)
  337. n, err := io.ReadFull(in, buf)
  338. isZeroLength := err == io.EOF
  339. if !isZeroLength && err != nil {
  340. return nil, err
  341. }
  342. in = io.MultiReader(bytes.NewReader(buf[:n]), in)
  343.  
  344. errChan := make(chan error, 1)
  345. go func() {
  346. defer bodyWriter.Close()
  347. var err error
  348.  
  349. part, err := writer.CreateFormFile("files[]", src.Remote())
  350. if err != nil {
  351. errChan <- err
  352. return
  353. }
  354. if _, err := io.Copy(part, in); err != nil {
  355. errChan <- err
  356. return
  357. }
  358. errChan <- writer.Close()
  359. }()
  360.  
  361. if isZeroLength {
  362. buf, err := ioutil.ReadAll(bodyReader)
  363. if err != nil {
  364. return nil, err
  365. }
  366. bodyReader = bytes.NewReader(buf)
  367. contentLength = int64(len(buf))
  368. }
  369.  
  370. req, err := http.NewRequest("POST", uploadUrl, bodyReader)
  371.  
  372. if err != nil {
  373. return nil, err
  374. }
  375.  
  376. req.ContentLength = contentLength
  377. req.Header.Add("Content-Type", contentType)
  378. f.httpClient.Do(req)
  379.  
  380. return f.FindFile(f.dirCache.RootID(), src.Remote())
  381. }
  382.  
  383. func (f *Fs) Mkdir(dir string) error {
  384. err := f.dirCache.FindRoot(true)
  385. if err != nil {
  386. return err
  387. }
  388. if dir != "" {
  389. _, err = f.dirCache.FindDir(dir, true)
  390. }
  391. return err
  392. }
  393.  
  394. func (f *Fs) Rmdir(dir string) error {
  395. panic("implement Rmdir")
  396. }
  397.  
  398. // Get Files informations from uid
  399. func (f *Fs) GetFile(fileuid string, basepath string) (*Object, error) {
  400.  
  401. // Get max tries value
  402. maxTries := fs.Config.LowLevelRetries
  403.  
  404. // Try
  405. for tries := 1; tries <= maxTries; tries++ {
  406.  
  407. // Get advanced informations
  408. fileInfo, err := f.httpClient.Get("https://uptobox.com/" + fileuid)
  409.  
  410. // Check http code and retry
  411. if err != nil || (fileInfo.StatusCode != 200 && fileInfo.StatusCode != 302) {
  412. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  413. fs.Debugf(f, "Advanced file informations error for %q, low level retry %d/%d", fileuid, tries, maxTries)
  414. continue
  415. }
  416.  
  417. // Parse HTML
  418. fileHTML, _ := goquery.NewDocumentFromReader(fileInfo.Body)
  419. fileSize, _ := fileHTML.Find("input[name='file_size_real']").Attr("value")
  420. fullName, _ := fileHTML.Find("input[name='fname']").Attr("value")
  421. rsize, _ := strconv.ParseInt(fileSize, 10, 64)
  422.  
  423. // Close HTTP
  424. fileInfo.Body.Close()
  425.  
  426. // Return Object
  427. return &Object{
  428. fs: f,
  429. remote: path.Join(basepath, fullName),
  430. id: fileuid,
  431. size: rsize,
  432. date: time.Now(),
  433. }, nil
  434.  
  435. // TODO : Get Upload time from HEAD request on file download link
  436. // TODO : Cache File request and File HEAD requests
  437. }
  438. return nil, fs.ErrorObjectNotFound
  439. }
  440.  
  441. func (f *Fs) FindFile(pathID string, filename string) (*Object, error) {
  442. maxTries := fs.Config.LowLevelRetries
  443.  
  444. // Try
  445. for tries := 1; tries <= maxTries; tries++ {
  446. // Send request
  447. resp, err := f.httpClient.Get("https://uptobox.com/?op=my_files&fld_id=" + pathID)
  448.  
  449. // Check http code and retry
  450. if err != nil || resp.StatusCode != 200 {
  451. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  452. fs.Debugf(f, "Directory listing failed for id %q, low level retry %d/%d", pathID, tries, maxTries)
  453. continue
  454. }
  455.  
  456. doc, _ := goquery.NewDocumentFromReader(resp.Body)
  457.  
  458. var obj *Object = nil
  459.  
  460. doc.Find("table.files .cell_files").Each(func(idx int, sel *goquery.Selection) {
  461. fileUrl, _ := sel.Find("td:nth-child(2) a").Attr("href")
  462. id := path.Base(fileUrl)
  463.  
  464. fullfile, err := f.GetFile(id, "")
  465. fullfile.numId, _ = sel.Find("td:nth-child(1) input").Attr("value")
  466. if err == nil && path.Base(fullfile.remote) == filename {
  467. obj = fullfile
  468. }
  469. })
  470.  
  471. if obj == nil {
  472. return nil, fs.ErrorObjectNotFound
  473. }
  474. return obj, nil
  475. }
  476. return nil, errors.New("Failed to resolve uptobox")
  477. }
  478.  
  479. // FindLeaf finds a directory of name leaf in the folder with ID pathID
  480. func (f *Fs) FindLeaf(pathID, leaf string) (pathIDOut string, found bool, err error) {
  481.  
  482. // Get max tries value
  483. maxTries := fs.Config.LowLevelRetries
  484.  
  485. // Try
  486. for tries := 1; tries <= maxTries; tries++ {
  487.  
  488. // Send request
  489. resp, err := f.httpClient.Get("https://uptobox.com/?op=my_files&fld_id=" + pathID)
  490.  
  491. // Check http code and retry
  492. if err != nil || resp.StatusCode != 200 {
  493. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  494. fs.Debugf(f, "Directory listing failed for id %q, low level retry %d/%d", pathID, tries, maxTries)
  495. continue
  496. }
  497.  
  498. // Parse HTML
  499. doc, _ := goquery.NewDocumentFromReader(resp.Body)
  500.  
  501. // Out ID
  502. outID := ""
  503.  
  504. // Extract Folders
  505. doc.Find("table.files td:not([style='max-width:1000px;']):nth-child(1) a").Each(func(idx int, sel *goquery.Selection) {
  506. reg, _ := regexp.Compile("(.*) \\((.*)$")
  507. name := reg.ReplaceAllString(sel.Text(), "$1")
  508. dirlink, _ := sel.Attr("href")
  509. dirid := strings.Replace(dirlink, "?op=my_files&fld_id=", "", 1)
  510.  
  511. if name == leaf {
  512. outID = dirid
  513. }
  514. })
  515.  
  516. // Close HTML Request
  517. resp.Body.Close()
  518.  
  519. // Return directory
  520. if outID == "" {
  521. return "", false, nil
  522. }
  523.  
  524. // Return id
  525. return outID, true, nil
  526. }
  527.  
  528. // Error
  529. return "", false, nil
  530. }
  531.  
  532. // CreateDir makes a directory with pathID as parent and name leaf
  533. func (f *Fs) CreateDir(pathID, leaf string) (newID string, err error) {
  534. resp, err := f.httpClient.PostForm("https://uptobox.com/", url.Values{
  535. "op": {"my_files"},
  536. "create_new_folder": {leaf},
  537. "fld_id": {pathID},
  538. "key": {""},
  539. "pub": {"1"},
  540. "to_folder": {"0"},
  541. "token": {f.token},
  542. })
  543. if err != nil {
  544. return "", err
  545. }
  546. if resp.StatusCode != 302 {
  547. return "", errors.New("Could not create dir")
  548. }
  549. childID, found, err := f.FindLeaf(pathID, leaf)
  550. if found != true {
  551. return "", errors.New("Failed to create directory")
  552. }
  553. return childID, err
  554. }
  555.  
  556. // Return a string version
  557. func (o *Object) String() string {
  558. if o == nil {
  559. return "<nil>"
  560. }
  561. return o.remote
  562. }
  563.  
  564. // Remote returns the remote path
  565. func (o *Object) Remote() string {
  566. return o.remote
  567. }
  568.  
  569. // ModTime returns the modification time of the object
  570. func (o *Object) ModTime() time.Time {
  571.  
  572. /*
  573. // Get max tries value
  574. maxTries := fs.Config.LowLevelRetries
  575.  
  576. // Time
  577. filetime := ""
  578.  
  579. for tries := 1; tries <= maxTries; tries++ {
  580.  
  581. // Send request
  582. resp, err := o.fs.httpClient.Head("http://www59.uptobox.com/d/tqy2g7wsh7dnpxkqdkhjgwj3moaakjwgztax7ex2cwfjviss2vubxn6l7g6caxyq42oyrbhm6qo6c2snk4/Bricks%20in%20Motion.mkv")
  583.  
  584. // Check http code and retry
  585. if err != nil || resp.StatusCode != 200 {
  586. time.Sleep(time.Duration(tries * 500) * time.Millisecond)
  587. fs.Debugf(o.fs, "Get modtime failed for id %q, low level retry %d/%d", o.id, tries, maxTries)
  588. continue
  589. }
  590.  
  591. // Set time
  592. filetime = resp.Header.Get("last-date-modified")
  593.  
  594. // Close HTTP request
  595. resp.Body.Close()
  596.  
  597. // Return
  598. break;
  599. }*/
  600.  
  601. return time.Now()
  602. }
  603.  
  604. // Size returns the size of an object in bytes
  605. func (o *Object) Size() int64 {
  606. return o.size
  607. }
  608.  
  609. func (o *Object) Fs() fs.Info {
  610. return o.fs
  611. }
  612.  
  613. // Hash returns nothing, not supported
  614. func (o *Object) Hash(fs.HashType) (string, error) {
  615. return "", nil
  616. }
  617.  
  618. // Storable returns a boolean showing whether this object storable
  619. func (o *Object) Storable() bool {
  620. return true
  621. }
  622.  
  623. // SetModTime return an error, not supported
  624. func (o *Object) SetModTime(time.Time) error {
  625. return fs.ErrorCantSetModTime
  626. }
  627.  
  628. // Get download URL from UID
  629. func (f *Fs) GetDownloadURL(fileuid string) (string, error) {
  630.  
  631. // Get max tries value
  632. maxTries := fs.Config.LowLevelRetries
  633.  
  634. // Try
  635. for tries := 1; tries <= maxTries; tries++ {
  636.  
  637. // Get advanced informations
  638. fileInfo, err := f.httpClient.Get("https://uptobox.com/" + fileuid)
  639.  
  640. // Check http code and retry
  641. if err != nil || (fileInfo.StatusCode != 200 && fileInfo.StatusCode != 302) {
  642. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  643. fs.Debugf(f, "Download-link generation failed (%q), low level retry %d/%d", fileuid, tries, maxTries)
  644. continue
  645. }
  646.  
  647. // Get 302 redirect
  648. if fileInfo.StatusCode == 302 {
  649. return string(fileInfo.Header.Get("Location")), nil
  650. }
  651.  
  652. // Parse values
  653. fileHTML, _ := goquery.NewDocumentFromReader(fileInfo.Body)
  654. fileSize, _ := fileHTML.Find("input[name='file_size_real']").Attr("value")
  655. fullName, _ := fileHTML.Find("input[name='fname']").Attr("value")
  656. rand, _ := fileHTML.Find("input[name='rand']").Attr("value")
  657.  
  658. // Close HTTP
  659. fileInfo.Body.Close()
  660.  
  661. // If Auto 302 is disabled, execute second request
  662. fileDownload, err := f.httpClient.PostForm("https://uptobox.com/"+fileuid, url.Values{
  663. "op": {"download2"},
  664. "id": {fileuid},
  665. "fname": {fullName},
  666. "file_size_real": {fileSize},
  667. "rand": {rand},
  668. "referer": {"https://uptobox.com/?op=my_files"},
  669. "method_free": {""},
  670. "method_premium": {""},
  671. "down_direct": {"1"},
  672. })
  673.  
  674. // Check http code and retry
  675. if err != nil || (fileInfo.StatusCode != 200) {
  676. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  677. fs.Debugf(f, "Download-link generation failed (%q), low level retry %d/%d", fileuid, tries, maxTries)
  678. continue
  679. }
  680.  
  681. // Extract link
  682. fileHTML, _ = goquery.NewDocumentFromReader(fileDownload.Body)
  683. url, _ := fileHTML.Find(".bg_page div div:nth-child(2) a").Attr("href")
  684.  
  685. // Close HTTP
  686. fileDownload.Body.Close()
  687.  
  688. // Return url
  689. return url, nil
  690. }
  691.  
  692. // Return error
  693. return "", errors.New("Download-link generation failed")
  694. }
  695.  
  696. // Open an object for read
  697. func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) {
  698. fileUrl, err := o.fs.GetDownloadURL(o.id)
  699. if err != nil {
  700. return nil, err
  701. }
  702. resp, err := o.fs.httpClient.Get(fileUrl)
  703. return resp.Body, err
  704. }
  705.  
  706. func (o *Object) Update(in io.Reader, src fs.ObjectInfo) error {
  707. panic("implement Update")
  708. }
  709.  
  710. func (o *Object) Remove() error {
  711.  
  712. // Get max tries value
  713. maxTries := fs.Config.LowLevelRetries
  714.  
  715. // Try
  716. for tries := 1; tries <= maxTries; tries++ {
  717.  
  718. // Send request
  719. resp, _ := o.fs.httpClient.Get("https://uptobox.com/?op=my_files&del_code=" + o.id + "&token=" + o.fs.token)
  720.  
  721. // Check success
  722. if resp.StatusCode == 302 || resp.StatusCode == 200 {
  723. return nil
  724. }
  725. }
  726. return errors.New("File deletion failed")
  727. }
  728.  
  729. func (f *Fs) Move(src fs.Object, remote string) (fs.Object, error) {
  730. panic("sqdqsdsqd")
  731.  
  732. // Source dir
  733. _, srcDirectoryID, errSrc := f.dirCache.FindPath(path.Dir(src.Remote()), false)
  734.  
  735. // Check source path
  736. if errSrc != nil {
  737. return src, errSrc
  738. }
  739.  
  740. // Find remote path
  741. _, dstDirectoryID, errDst := f.dirCache.FindPath(remote, true)
  742.  
  743. // Check path exists
  744. if errDst != nil {
  745. return src, errDst
  746. }
  747.  
  748. // Get file
  749. file, errFile := f.FindFile(srcDirectoryID, path.Base(remote))
  750.  
  751. // Check file return
  752. if errFile != nil {
  753. return src, errFile
  754. }
  755.  
  756. // Get max tries value
  757. maxTries := fs.Config.LowLevelRetries
  758.  
  759. // Try
  760. for tries := 1; tries <= maxTries; tries++ {
  761.  
  762. println("fld_id : " + srcDirectoryID)
  763. println("file_id : " + file.numId)
  764. println("fld_id : " + dstDirectoryID)
  765.  
  766. // Send request
  767. resp, err := f.httpClient.PostForm("https://uptobox.com/", url.Values{
  768. "create_new_folder": {""},
  769. "op": {"my_files"},
  770. "token": {f.token},
  771. "fld_id": {srcDirectoryID},
  772. "key": {""},
  773. "file_id": {file.numId},
  774. "pub": {"0"},
  775. "to_folder": {dstDirectoryID},
  776. "to_folder_move": {"Move files"},
  777. })
  778.  
  779. // Check http code and retry
  780. if err != nil || (resp.StatusCode != 302 && resp.StatusCode != 200) {
  781. time.Sleep(time.Duration(tries*500) * time.Millisecond)
  782. fs.Debugf(f, "Moving file failed (%q), low level retry %d/%d", file.id, tries, maxTries)
  783. continue
  784. }
  785.  
  786. // Get new file
  787. newFileObj, errObj := f.GetFile(file.id, remote)
  788.  
  789. // Check success
  790. if errObj == nil {
  791. return newFileObj, nil
  792. }
  793.  
  794. // Error break
  795. break
  796. }
  797. return nil, errors.New("Moving file failed")
  798. }
  799.  
  800. var (
  801. _ fs.Fs = &Fs{}
  802. _ fs.Mover = &Fs{}
  803. _ fs.Object = &Object{}
  804. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement