github.com/0chain/gosdk@v1.17.11/winsdk/storage.go (about) 1 package main 2 3 /* 4 #include <stdlib.h> 5 */ 6 import ( 7 "C" 8 ) 9 10 import ( 11 "encoding/json" 12 "errors" 13 "fmt" 14 "os" 15 "time" 16 17 "github.com/0chain/gosdk/core/common" 18 "github.com/0chain/gosdk/zboxcore/marker" 19 "github.com/0chain/gosdk/zboxcore/sdk" 20 ) 21 22 // GetFileStats get file stats of blobbers 23 // 24 // return 25 // { 26 // "error":"", 27 // "result":"xxx", 28 // } 29 // 30 //export GetFileStats 31 func GetFileStats(allocationID, remotePath *C.char) *C.char { 32 defer func() { 33 if r := recover(); r != nil { 34 log.Error("win: crash ", r) 35 } 36 }() 37 38 allocID := C.GoString(allocationID) 39 path := C.GoString(remotePath) 40 41 if len(allocID) == 0 { 42 return WithJSON(nil, errors.New("allocationID is required")) 43 } 44 45 if len(path) == 0 { 46 return WithJSON(nil, errors.New("remotePath is required")) 47 } 48 49 allocationObj, err := getAllocation(allocID) 50 if err != nil { 51 return WithJSON(nil, err) 52 } 53 54 stats, err := allocationObj.GetFileStats(path) 55 if err != nil { 56 return WithJSON(nil, err) 57 } 58 59 result := make([]*sdk.FileStats, 0, len(stats)) 60 61 //convert map[string]*sdk.FileStats to []*sdk.FileStats 62 for _, v := range stats { 63 result = append(result, v) 64 } 65 66 return WithJSON(result, nil) 67 } 68 69 // Delete delete path 70 // 71 // return 72 // { 73 // "error":"", 74 // "result":"true", 75 // } 76 // 77 //export Delete 78 func Delete(allocationID, path *C.char) *C.char { 79 defer func() { 80 if r := recover(); r != nil { 81 log.Error("win: crash ", r) 82 } 83 }() 84 85 allocID := C.GoString(allocationID) 86 87 alloc, err := getAllocation(allocID) 88 if err != nil { 89 return WithJSON(false, err) 90 } 91 92 s := C.GoString(path) 93 94 err = alloc.DoMultiOperation([]sdk.OperationRequest{ 95 { 96 OperationType: "delete", 97 RemotePath: s, 98 }, 99 }) 100 101 if err != nil { 102 return WithJSON(false, err) 103 } 104 105 log.Info("winsdk: deleted ", s) 106 107 return WithJSON(true, nil) 108 } 109 110 type MultiOperationOption struct { 111 OperationType string `json:"OperationType,omitempty"` 112 RemotePath string `json:"RemotePath,omitempty"` 113 DestName string `json:"DestName,omitempty"` // Required only for rename operation 114 DestPath string `json:"DestPath,omitempty"` // Required for copy and move operation` 115 } 116 117 // MultiOperation - do copy, move, delete and createdir operation together 118 // ## Inputs 119 // - allocationID 120 // - jsonMultiOperationOptions: Json Array of MultiOperationOption. eg: "[{"operationType":"move","remotePath":"/README.md","destPath":"/folder1/"},{"operationType":"delete","remotePath":"/t3.txt"}]" 121 // return 122 // { 123 // "error":"", 124 // "result":"true", 125 // } 126 // 127 //export MultiOperation 128 func MultiOperation(_allocationID, _jsonMultiOperationOptions *C.char) *C.char { 129 defer func() { 130 if r := recover(); r != nil { 131 log.Error("win: crash ", r) 132 } 133 }() 134 allocationID := C.GoString(_allocationID) 135 jsonMultiOperationOptions := C.GoString(_jsonMultiOperationOptions) 136 if allocationID == "" { 137 return WithJSON(false, errors.New("AllocationID is required")) 138 } 139 140 var options []MultiOperationOption 141 err := json.Unmarshal([]byte(jsonMultiOperationOptions), &options) 142 if err != nil { 143 return WithJSON(false, err) 144 } 145 totalOp := len(options) 146 operations := make([]sdk.OperationRequest, totalOp) 147 for idx, op := range options { 148 operations[idx] = sdk.OperationRequest{ 149 OperationType: op.OperationType, 150 RemotePath: op.RemotePath, 151 DestName: op.DestName, 152 DestPath: op.DestPath, 153 } 154 155 log.Info("multi-operation: index=", idx, " op=", op.OperationType, " remotePath=", op.RemotePath, " destName=", op.DestName, " destPath=", op.DestPath) 156 } 157 allocationObj, err := getAllocation(allocationID) 158 if err != nil { 159 return WithJSON(false, err) 160 } 161 err = allocationObj.DoMultiOperation(operations) 162 if err != nil { 163 return WithJSON(false, err) 164 } 165 return WithJSON(true, nil) 166 167 } 168 169 // GetFileMeta get metadata by path 170 // ## Inputs 171 // - allocationID 172 // - path 173 // - authTicket 174 // 175 // ## Outputs 176 // 177 // return 178 // { 179 // "error":"", 180 // "result":"true", 181 // } 182 // 183 //export GetFileMeta 184 func GetFileMeta(allocationID, path, authTicket *C.char) *C.char { 185 defer func() { 186 if r := recover(); r != nil { 187 log.Error("win: crash ", r) 188 } 189 }() 190 allocID := C.GoString(allocationID) 191 192 t := C.GoString(authTicket) 193 194 var ticket *marker.AuthTicket 195 196 var alloc *sdk.Allocation 197 var err error 198 isShared := len(t) > 0 199 if isShared { 200 alloc, ticket, err = getAllocationWith(t) 201 } else { 202 alloc, err = getAllocation(allocID) 203 } 204 205 if err != nil { 206 log.Error("win: ", err) 207 return WithJSON(nil, err) 208 } 209 210 s := C.GoString(path) 211 212 var f *sdk.ConsolidatedFileMeta 213 if isShared { 214 f, err = alloc.GetFileMetaFromAuthTicket(t, ticket.FilePathHash) 215 } else { 216 f, err = alloc.GetFileMeta(s) 217 } 218 219 if err != nil { 220 log.Error("win: ", err, " authTicket=", t, " path=", s) 221 return WithJSON(nil, err) 222 } 223 224 return WithJSON(f, nil) 225 } 226 227 // BulkUpload - upload files from local path to remote path 228 // ## Inputs 229 // - allocationID 230 // - files: Json Array of UploadFile 231 // return 232 // { 233 // "error":"", 234 // "result":"true", 235 // } 236 // 237 //export BulkUpload 238 func BulkUpload(allocationID, files *C.char) *C.char { 239 defer func() { 240 if r := recover(); r != nil { 241 log.Error("win: crash ", r) 242 } 243 }() 244 allocID := C.GoString(allocationID) 245 workdir, _ := os.UserHomeDir() 246 jsFiles := C.GoString(files) 247 var options []UploadFile 248 err := json.Unmarshal([]byte(jsFiles), &options) 249 if err != nil { 250 return WithJSON(nil, err) 251 } 252 totalUploads := len(options) 253 filePaths := make([]string, totalUploads) 254 fileNames := make([]string, totalUploads) 255 remotePaths := make([]string, totalUploads) 256 thumbnailPaths := make([]string, totalUploads) 257 chunkNumbers := make([]int, totalUploads) 258 encrypts := make([]bool, totalUploads) 259 isUpdates := make([]bool, totalUploads) 260 isWebstreaming := make([]bool, totalUploads) 261 262 statusBar := NewStatusBar(statusUpload, "") 263 264 for idx, option := range options { 265 filePaths[idx] = option.Path 266 fileNames[idx] = option.Name 267 thumbnailPaths[idx] = option.ThumbnailPath 268 remotePaths[idx] = option.RemotePath 269 chunkNumbers[idx] = option.ChunkNumber 270 isUpdates[idx] = option.IsUpdate 271 isWebstreaming[idx] = option.IsWebstreaming 272 encrypts[idx] = option.Encrypt 273 if option.IsWebstreaming { 274 originalLookupHash := getLookupHash(allocID, option.RemotePath+option.Name) 275 _, transcodeRemotePath := sdk.GetTranscodeFile(option.RemotePath + option.Name) 276 transcodeLookupHash := getLookupHash(allocID, transcodeRemotePath) 277 transcodeFiles.Add(originalLookupHash, transcodeLookupHash) 278 statusUpload.Add(transcodeLookupHash, &Status{}) 279 280 } else { 281 statusUpload.Add(getLookupHash(allocID, option.RemotePath+option.Name), &Status{}) 282 } 283 284 } 285 286 a, err := getAllocation(allocID) 287 if err != nil { 288 return WithJSON(nil, err) 289 } 290 291 err = a.StartMultiUpload(workdir, filePaths, fileNames, thumbnailPaths, encrypts, chunkNumbers, remotePaths, isUpdates, isWebstreaming, statusBar) 292 if err != nil { 293 return WithJSON(nil, err) 294 } 295 return WithJSON(nil, nil) 296 } 297 298 // GetUploadStatus - get upload status 299 // ## Inputs 300 // - lookupHash 301 // 302 // ## Outputs 303 // 304 // { 305 // "error":"", 306 // "result":"{'Started':false,'CompletedBytes': 0,Error:”,'Completed':false}", 307 // } 308 // 309 //export GetUploadStatus 310 func GetUploadStatus(lookupHash *C.char) *C.char { 311 defer func() { 312 if r := recover(); r != nil { 313 log.Error("win: crash ", r) 314 } 315 }() 316 h := C.GoString(lookupHash) 317 318 h2, ok := transcodeFiles.Get(h) 319 320 if ok { 321 h = h2 322 } 323 324 s, ok := statusUpload.Get(h) 325 326 if !ok { 327 s = &Status{} 328 } 329 330 return WithJSON(s, nil) 331 } 332 333 // SetNumBlockDownloads - set global the number of blocks on downloading 334 // ## Inputs 335 // - num 336 // 337 // ## Outputs 338 // 339 // { 340 // "error":"", 341 // "result":"", 342 // } 343 // 344 //export SetNumBlockDownloads 345 func SetNumBlockDownloads(num int) { 346 sdk.SetNumBlockDownloads(num) 347 } 348 349 // DownloadFile - downalod file 350 // ## Inputs 351 // - allocationID 352 // - localPath 353 // - remotePath 354 // - verifyDownload 355 // - isFinal 356 // 357 // ## Outputs 358 // 359 // { 360 // "error":"", 361 // "result":"true", 362 // } 363 // 364 //export DownloadFile 365 func DownloadFile(allocationID, localPath, remotePath *C.char, verifyDownload, isFinal bool) *C.char { 366 defer func() { 367 if r := recover(); r != nil { 368 log.Error("win: crash ", r) 369 } 370 }() 371 allocID := C.GoString(allocationID) 372 373 alloc, err := getAllocation(allocID) 374 if err != nil { 375 return WithJSON(false, err) 376 } 377 378 statusBar := NewStatusBar(statusDownload, "") 379 380 err = alloc.DownloadFile(C.GoString(localPath), C.GoString(remotePath), verifyDownload, statusBar, isFinal) 381 if err != nil { 382 return WithJSON(false, err) 383 } 384 385 return WithJSON(true, nil) 386 } 387 388 // DownloadThumbnail - downalod thumbnial 389 // ## Inputs 390 // - allocationID 391 // - localPath 392 // - remotePath 393 // - verifyDownload 394 // - isFinal 395 // 396 // ## Outputs 397 // 398 // { 399 // "error":"", 400 // "result":"true", 401 // } 402 // 403 //export DownloadThumbnail 404 func DownloadThumbnail(allocationID, localPath, remotePath *C.char, verifyDownload bool, isFinal bool) *C.char { 405 defer func() { 406 if r := recover(); r != nil { 407 log.Error("win: crash ", r) 408 } 409 }() 410 allocID := C.GoString(allocationID) 411 412 alloc, err := getAllocation(allocID) 413 if err != nil { 414 return WithJSON(false, err) 415 } 416 417 r := C.GoString(remotePath) 418 419 lookupHash := getLookupHash(allocID, r) 420 statusBar := NewStatusBar(statusDownload, lookupHash+":thumbnail") 421 422 err = alloc.DownloadThumbnail(C.GoString(localPath), r, verifyDownload, statusBar, isFinal) 423 if err != nil { 424 return WithJSON(false, err) 425 } 426 427 return WithJSON(true, nil) 428 } 429 430 // DownloadSharedFile - downalod shared file by authTicket 431 // ## Inputs 432 // - localPath 433 // - authTicket 434 // - verifyDownload 435 // - isFinal 436 // 437 // ## Outputs 438 // 439 // { 440 // "error":"", 441 // "result":"{"AllocationID":"xxx","LookupHash":"xxxxxx" }", 442 // } 443 // 444 //export DownloadSharedFile 445 func DownloadSharedFile(localPath, authTicket *C.char, verifyDownload bool, isFinal bool) *C.char { 446 defer func() { 447 if r := recover(); r != nil { 448 log.Error("win: crash ", r) 449 } 450 }() 451 info := &SharedInfo{} 452 t, at, err := decodeAuthTicket(authTicket) 453 if err != nil { 454 return WithJSON(info, err) 455 } 456 457 info.AllocationID = t.AllocationID 458 info.LookupHash = t.FilePathHash 459 460 alloc, err := getAllocation(t.AllocationID) 461 if err != nil { 462 return WithJSON(info, err) 463 } 464 465 statusBar := NewStatusBar(statusDownload, t.FilePathHash) 466 467 err = alloc.DownloadFromAuthTicket(C.GoString(localPath), at, t.FilePathHash, t.FileName, verifyDownload, statusBar, isFinal) 468 if err != nil { 469 return WithJSON(info, err) 470 } 471 472 return WithJSON(info, nil) 473 } 474 475 // DownloadSharedThumbnail - downalod shared thumbnial by authTicket 476 // ## Inputs 477 // - localPath 478 // - authTicket 479 // - verifyDownload 480 // - isFinal 481 // 482 // ## Outputs 483 // 484 // { 485 // "error":"", 486 // "result":"{"AllocationID":"xxx","LookupHash":"xxx" }", 487 // } 488 // 489 //export DownloadSharedThumbnail 490 func DownloadSharedThumbnail(localPath, authTicket *C.char, verifyDownload bool, isFinal bool) *C.char { 491 defer func() { 492 if r := recover(); r != nil { 493 log.Error("win: crash ", r) 494 } 495 }() 496 info := &SharedInfo{} 497 t, at, err := decodeAuthTicket(authTicket) 498 if err != nil { 499 log.Error("win: ", err, " authTicket=", at) 500 return WithJSON(info, err) 501 } 502 info.AllocationID = t.AllocationID 503 info.LookupHash = t.FilePathHash 504 505 alloc, err := getAllocation(t.AllocationID) 506 if err != nil { 507 log.Error("win: ", err, " authTicket=", at) 508 return WithJSON(info, err) 509 } 510 511 statusBar := NewStatusBar(statusDownload, t.FilePathHash) 512 513 err = alloc.DownloadThumbnailFromAuthTicket(C.GoString(localPath), at, t.FilePathHash, t.FileName, verifyDownload, statusBar, isFinal) 514 if err != nil { 515 log.Error("win: ", err, " authTicket=", at, " lookuphash=", t.FilePathHash) 516 return WithJSON(info, err) 517 } 518 519 return WithJSON(info, nil) 520 } 521 522 // DownloadFileBlocks - downalod file blocks 523 // ## Inputs 524 // - allocationID 525 // - localPath 526 // - remotePath 527 // - startBlock 528 // - endBlock 529 // - numBlocks 530 // - verifyDownload 531 // - isFinal 532 // 533 // ## Outputs 534 // 535 // { 536 // "error":"", 537 // "result":"true", 538 // } 539 // 540 //export DownloadFileBlocks 541 func DownloadFileBlocks(allocationID, 542 localPath, remotePath *C.char, startBlock int64, endBlock int64, 543 numBlocks int, verifyDownload bool, isFinal bool) *C.char { 544 defer func() { 545 if r := recover(); r != nil { 546 log.Error("win: crash ", r) 547 } 548 }() 549 550 allocID := C.GoString(allocationID) 551 552 alloc, err := getAllocation(allocID) 553 if err != nil { 554 return WithJSON(false, err) 555 } 556 557 r := C.GoString(remotePath) 558 559 lookupHash := getLookupHash(allocID, r) 560 statusBar := NewStatusBar(statusDownload, lookupHash+fmt.Sprintf(":%v-%v-%v", startBlock, endBlock, numBlocks)) 561 562 err = alloc.DownloadFileByBlock(C.GoString(localPath), r, startBlock, endBlock, numBlocks, verifyDownload, statusBar, isFinal) 563 if err != nil { 564 return WithJSON(false, err) 565 } 566 567 return WithJSON(true, nil) 568 } 569 570 // DownloadSharedFileBlocks - downalod shared file blocks 571 // ## Inputs 572 // - localPath 573 // - remotePath 574 // - startBlock 575 // - endBlock 576 // - numBlocks 577 // - verifyDownload 578 // - isFinal 579 // 580 // ## Outputs 581 // 582 // { 583 // "error":"", 584 // "result":"true", 585 // } 586 // 587 //export DownloadSharedFileBlocks 588 func DownloadSharedFileBlocks(localPath, authTicket *C.char, startBlock int64, endBlock int64, 589 numBlocks int, verifyDownload bool, isFinal bool) *C.char { 590 defer func() { 591 if r := recover(); r != nil { 592 log.Error("win: crash ", r) 593 } 594 }() 595 596 info := &SharedInfo{} 597 t, at, err := decodeAuthTicket(authTicket) 598 if err != nil { 599 return WithJSON(info, err) 600 } 601 info.AllocationID = t.AllocationID 602 info.LookupHash = t.FilePathHash 603 604 alloc, err := getAllocation(t.AllocationID) 605 if err != nil { 606 return WithJSON(info, err) 607 } 608 609 statusBar := NewStatusBar(statusDownload, t.FilePathHash+fmt.Sprintf(":%v-%v-%v", startBlock, endBlock, numBlocks)) 610 611 err = alloc.DownloadFromAuthTicketByBlocks(C.GoString(localPath), at, startBlock, endBlock, numBlocks, t.FilePathHash, t.FileName, verifyDownload, statusBar, isFinal) 612 if err != nil { 613 return WithJSON(info, err) 614 } 615 616 return WithJSON(info, nil) 617 } 618 619 // GetDownloadStatus - get download status 620 // ## Inputs 621 // - key: lookuphash/lookuphash:thumbnail/lookuphash:startBlock-endBlock-numBlocks/lookuphash:startBlock-endBlock-numBlocks:thumbnail 622 // 623 // ## Outputs 624 // 625 // { 626 // "error":"", 627 // "result":"{'Started':false,'CompletedBytes': 0,Error:”,'Completed':false}", 628 // } 629 // 630 //export GetDownloadStatus 631 func GetDownloadStatus(key *C.char, isThumbnail bool) *C.char { 632 defer func() { 633 if r := recover(); r != nil { 634 log.Error("win: crash ", r) 635 } 636 }() 637 k := C.GoString(key) 638 if isThumbnail { 639 k += ":thumbnail" 640 } 641 642 s, ok := statusDownload.Get(k) 643 644 if !ok { 645 s = &Status{} 646 } 647 648 return WithJSON(s, nil) 649 } 650 651 // CreateAuthTicket - create AuthTicket for sharing 652 // ## Inputs 653 // - allocationID 654 // - remotePath 655 // - refereeClientID 656 // - refereePublicEncryptionKey 657 // - availableAfter 658 // - expirationSeconds 659 // 660 // ## Outputs 661 // 662 // { 663 // "error":"", 664 // "result":"{}", 665 // } 666 // 667 //export CreateAuthTicket 668 func CreateAuthTicket(allocationID, remotePath, refereeClientID, refereePublicEncryptionKey, availableAfter *C.char, expirationSeconds int64) *C.char { 669 defer func() { 670 if r := recover(); r != nil { 671 log.Error("win: crash ", r) 672 } 673 }() 674 alloc, err := getAllocation(C.GoString(allocationID)) 675 676 if err != nil { 677 log.Error("win: ", err) 678 return WithJSON(nil, err) 679 } 680 681 rPath := C.GoString(remotePath) 682 683 fileMeta, err := alloc.GetFileMeta(rPath) 684 if err != nil { 685 log.Error("win: ", err) 686 return WithJSON(nil, err) 687 } 688 689 af := time.Now() 690 availableAfterString := C.GoString(availableAfter) 691 692 if len(availableAfterString) > 0 { 693 aa, err := common.ParseTime(af, availableAfterString) 694 if err != nil { 695 log.Error("win: ", err) 696 return WithJSON(nil, err) 697 } 698 af = *aa 699 } 700 701 at, err := alloc.GetAuthTicket(rPath, fileMeta.Name, fileMeta.Type, C.GoString(refereeClientID), C.GoString(refereePublicEncryptionKey), expirationSeconds, &af) 702 if err != nil { 703 log.Error("win: ", err) 704 return WithJSON(nil, err) 705 } 706 707 return WithJSON(at, nil) 708 709 } 710 711 // DeleteAuthTicket - delete AuthTicket 712 // ## Inputs 713 // - allocationID 714 // - remotePath 715 // - refereeClientID 716 // 717 // ## Outputs 718 // 719 // { 720 // "error":"", 721 // "result":"true", 722 // } 723 // 724 //export DeleteAuthTicket 725 func DeleteAuthTicket(allocationID, remotePath, refereeClientID *C.char) *C.char { 726 defer func() { 727 if r := recover(); r != nil { 728 log.Error("win: crash ", r) 729 } 730 }() 731 alloc, err := getAllocation(C.GoString(allocationID)) 732 if err != nil { 733 log.Error("win: ", err) 734 return WithJSON(false, err) 735 } 736 737 rPath := C.GoString(remotePath) 738 739 err = alloc.RevokeShare(rPath, C.GoString(refereeClientID)) 740 if err != nil { 741 log.Error("win: ", err) 742 return WithJSON(false, err) 743 } 744 745 return WithJSON(true, nil) 746 747 } 748 749 func CancelUpload(allocationID, remotePath *C.char) *C.char { 750 defer func() { 751 if r := recover(); r != nil { 752 log.Error("win: crash ", r) 753 } 754 }() 755 alloc, err := getAllocation(C.GoString(allocationID)) 756 if err != nil { 757 log.Error("win: ", err) 758 return WithJSON(false, err) 759 } 760 761 rPath := C.GoString(remotePath) 762 err = alloc.CancelUpload(rPath) 763 if err != nil { 764 log.Error("win: ", err) 765 return WithJSON(false, err) 766 } 767 return WithJSON(true, nil) 768 } 769 770 func PauseUpload(allocationID, remotePath *C.char) *C.char { 771 defer func() { 772 if r := recover(); r != nil { 773 log.Error("win: crash ", r) 774 } 775 }() 776 alloc, err := getAllocation(C.GoString(allocationID)) 777 if err != nil { 778 log.Error("win: ", err) 779 return WithJSON(false, err) 780 } 781 782 rPath := C.GoString(remotePath) 783 err = alloc.PauseUpload(rPath) 784 if err != nil { 785 log.Error("win: ", err) 786 return WithJSON(false, err) 787 } 788 return WithJSON(true, nil) 789 } 790 791 // SetUploadMode sets upload mode 792 // 793 // ## Inputs 794 // - mode: 0 for low, 1 for medium, 2 for high 795 func SetUploadMode(mode int) { 796 switch mode { 797 case 0: 798 sdk.SetUploadMode(sdk.UploadModeLow) 799 case 1: 800 sdk.SetUploadMode(sdk.UploadModeMedium) 801 case 2: 802 sdk.SetUploadMode(sdk.UploadModeHigh) 803 } 804 }