SET AppKey TO $'''KEY''' SET AppUrl TO $'''https://file.thinhsoft.com''' SET AppLibraries TO $'''C:\Users\lethi\Development\pad-libraries''' # List Files **REGION List Files SET Page TO 1 SET PageSize TO 50 SET FileList TO { } LABEL 'Get new files' @@CustomSummary: 'List Files' Scripting.RunDotNetScript Imports: $'''System.Collections.Generic System.Data System.Net System.Web.Script.Serialization ''' Language: System.DotNetActionLanguageType.CSharp ReferenceRootPath: AppLibraries Script: $'''ErrorMessage = string.Empty; OutputTable = new DataTable(); TotalCount = 0; TotalPages = 0; try { var url = string.Format("{0}/api/files?page={1}&pageSize={2}", BaseUrl, Page, PageSize); var client = new WebClient(); client.Headers.Add("X-Api-Key", ApiKey); var json = client.DownloadString(url); var serializer = new JavaScriptSerializer(); var root = (Dictionary)serializer.DeserializeObject(json); var pagination = (Dictionary)root["pagination"]; TotalCount = Convert.ToInt32(pagination["totalCount"]); TotalPages = Convert.ToInt32(pagination["totalPages"]); var table = new DataTable(); table.Columns.Add("PublicId", typeof(string)); table.Columns.Add("FileName", typeof(string)); table.Columns.Add("ContentType", typeof(string)); table.Columns.Add("Size", typeof(long)); table.Columns.Add("UploadedAt", typeof(string)); var dataArray = (object[])root["data"]; foreach (var item in dataArray) { var obj = (Dictionary)item; var row = table.NewRow(); row["PublicId"] = obj["publicId"].ToString(); row["FileName"] = obj["fileName"].ToString(); row["ContentType"] = obj["contentType"].ToString(); row["Size"] = Convert.ToInt64(obj["size"]); row["UploadedAt"] = obj["uploadedAt"].ToString(); table.Rows.Add(row); } OutputTable = table; } catch (Exception ex) { ErrorMessage = ex.ToString(); } ''' @'name:BaseUrl': AppUrl @'type:BaseUrl': $'''String''' @'direction:BaseUrl': $'''In''' @'name:ApiKey': AppKey @'type:ApiKey': $'''String''' @'direction:ApiKey': $'''In''' @'name:Page': Page @'type:Page': $'''Int''' @'direction:Page': $'''In''' @'name:PageSize': PageSize @'type:PageSize': $'''Int''' @'direction:PageSize': $'''In''' @'name:OutputTable': $'''''' @'type:OutputTable': $'''Datatable''' @'direction:OutputTable': $'''Out''' @'name:TotalCount': $'''''' @'type:TotalCount': $'''Int''' @'direction:TotalCount': $'''Out''' @'name:TotalPages': $'''''' @'type:TotalPages': $'''Int''' @'direction:TotalPages': $'''Out''' @'name:ErrorMessage': $'''''' @'type:ErrorMessage': $'''String''' @'direction:ErrorMessage': $'''Out''' @OutputTable=> OutputTable @TotalCount=> TotalCount @TotalPages=> TotalPages @ErrorMessage=> ErrorMessage IF IsNotEmpty(ErrorMessage) THEN EXIT Code: 0 ErrorMessage: $'''System Exception: %ErrorMessage%''' END Variables.MergeDataTables FirstDataTable: FileList SecondDataTable: OutputTable MergeMode: Variables.MergeMode.AddExtraColumns IF Page <= TotalPages THEN Variables.IncreaseVariable Value: Page IncrementValue: 1 GOTO 'Get new files' END **ENDREGION # Upload Files **REGION Upload Files Display.SelectFileDialog.SelectFiles Title: $'''Upload Files''' IsTopMost: True CheckIfFileExists: True SelectedFiles=> FilesToUpload LOOP FOREACH FileToUpload IN FilesToUpload @@CustomSummary: 'Upload Files' Scripting.RunDotNetScript Imports: $'''System.Collections.Generic System.Net System.Text System.Web.Script.Serialization ''' Language: System.DotNetActionLanguageType.CSharp ReferenceRootPath: AppLibraries Script: $'''ErrorMessage = string.Empty; PublicId = string.Empty; FileName = string.Empty; try { var url = string.Format("{0}/api/files/upload", BaseUrl); var client = new WebClient(); client.Headers.Add("X-Api-Key", ApiKey); var responseBytes = client.UploadFile(url, "POST", FilePath); var json = Encoding.UTF8.GetString(responseBytes); var serializer = new JavaScriptSerializer(); var root = (Dictionary)serializer.DeserializeObject(json); PublicId = root["publicId"].ToString(); FileName = root["fileName"].ToString(); } catch (Exception ex) { ErrorMessage = ex.ToString(); } ''' @'name:BaseUrl': AppUrl @'type:BaseUrl': $'''String''' @'direction:BaseUrl': $'''In''' @'name:ApiKey': AppKey @'type:ApiKey': $'''String''' @'direction:ApiKey': $'''In''' @'name:FilePath': FileToUpload @'type:FilePath': $'''String''' @'direction:FilePath': $'''In''' @'name:PublicId': $'''''' @'type:PublicId': $'''String''' @'direction:PublicId': $'''Out''' @'name:FileName': $'''''' @'type:FileName': $'''String''' @'direction:FileName': $'''Out''' @'name:ErrorMessage': $'''''' @'type:ErrorMessage': $'''String''' @'direction:ErrorMessage': $'''Out''' @PublicId=> PublicId @FileName=> FileName @ErrorMessage=> ErrorMessage IF IsNotEmpty(ErrorMessage) THEN EXIT Code: 0 ErrorMessage: $'''System Exception: %ErrorMessage%''' END END **ENDREGION # Download Files **REGION Download Files IF IsNotEmpty(FileList) THEN Variables.RetrieveDataTableColumnIntoList DataTable: FileList ColumnNameOrIndex: 1 ColumnAsList=> FileListNameOnly Display.SelectFromListDialog.SelectItemsFromList Title: $'''Download Files''' List: FileListNameOnly IsTopMost: True AllowEmpty: False PreSelectItemsWithPlus: False SelectedIndexes=> FileToDownloadIndexes IF IsNotEmpty(FileToDownloadIndexes) THEN Display.SelectFolder Description: $'''Download Location''' IsTopMost: True SelectedFolder=> DownloadLocation END LOOP FOREACH FileToDownloadIndex IN FileToDownloadIndexes SET DownloadPublicId TO FileList[FileToDownloadIndex]['PublicId'] @@CustomSummary: 'Download Files' Scripting.RunDotNetScript Imports: $'''System.IO System.Net System.Text.RegularExpressions ''' Language: System.DotNetActionLanguageType.CSharp ReferenceRootPath: AppLibraries Script: $'''ErrorMessage = string.Empty; SavedFilePath = string.Empty; try { var url = string.Format("{0}/api/files/{1}/download", BaseUrl, PublicId); var client = new WebClient(); client.Headers.Add("X-Api-Key", ApiKey); var fileBytes = client.DownloadData(url); var disposition = client.ResponseHeaders["Content-Disposition"]; var downloadName = PublicId; if (disposition != null) { // Ký tự \ đã được phục hồi để C# hiểu đúng chuỗi Regex var match = Regex.Match(disposition, "filename=\"?([^\";\\r\\n]+)\"?"); if (match.Success) downloadName = match.Groups[1].Value.Trim(); } SavedFilePath = Path.Combine(SaveFolder, downloadName); File.WriteAllBytes(SavedFilePath, fileBytes); } catch (Exception ex) { ErrorMessage = ex.ToString(); } ''' @'name:BaseUrl': AppUrl @'type:BaseUrl': $'''String''' @'direction:BaseUrl': $'''In''' @'name:ApiKey': AppKey @'type:ApiKey': $'''String''' @'direction:ApiKey': $'''In''' @'name:PublicId': DownloadPublicId @'type:PublicId': $'''String''' @'direction:PublicId': $'''In''' @'name:SaveFolder': DownloadLocation @'type:SaveFolder': $'''String''' @'direction:SaveFolder': $'''In''' @'name:SavedFilePath': $'''''' @'type:SavedFilePath': $'''String''' @'direction:SavedFilePath': $'''Out''' @'name:ErrorMessage': $'''''' @'type:ErrorMessage': $'''String''' @'direction:ErrorMessage': $'''Out''' @SavedFilePath=> SavedFilePath @ErrorMessage=> ErrorMessage IF IsNotEmpty(ErrorMessage) THEN EXIT Code: 0 ErrorMessage: $'''System Exception: %ErrorMessage%''' END END END **ENDREGION # Delete Files **REGION Delete Files IF IsNotEmpty(FileList) THEN Variables.RetrieveDataTableColumnIntoList DataTable: FileList ColumnNameOrIndex: 1 ColumnAsList=> FileListNameOnly Display.SelectFromListDialog.SelectItemsFromList Title: $'''Delete Files''' List: FileListNameOnly IsTopMost: True AllowEmpty: False PreSelectItemsWithPlus: False SelectedIndexes=> FileToDeleteIndexes LOOP FOREACH FileToDeleteIndex IN FileToDeleteIndexes SET DeletePublicId TO FileList[FileToDeleteIndex]['PublicId'] @@CustomSummary: 'Delete Files' Scripting.RunDotNetScript Imports: $'''System.Net ''' Language: System.DotNetActionLanguageType.CSharp ReferenceRootPath: AppLibraries Script: $'''// Input: BaseUrl, ApiKey, PublicId (string) // Output: IsDeleted (bool), ErrorMessage (string) ErrorMessage = string.Empty; IsDeleted = false; try { var url = string.Format("{0}/api/files/{1}", BaseUrl, PublicId); var client = new WebClient(); client.Headers.Add("X-Api-Key", ApiKey); client.UploadString(url, "DELETE", ""); IsDeleted = true; } catch (WebException wex) { if (wex.Response != null) { var httpResponse = (HttpWebResponse)wex.Response; if ((int)httpResponse.StatusCode == 404) ErrorMessage = "File not found."; else ErrorMessage = string.Format("HTTP {0}: {1}", (int)httpResponse.StatusCode, httpResponse.StatusDescription); } else { ErrorMessage = wex.ToString(); } } catch (Exception ex) { ErrorMessage = ex.ToString(); } ''' @'name:BaseUrl': AppUrl @'type:BaseUrl': $'''String''' @'direction:BaseUrl': $'''In''' @'name:ApiKey': AppKey @'type:ApiKey': $'''String''' @'direction:ApiKey': $'''In''' @'name:PublicId': DeletePublicId @'type:PublicId': $'''String''' @'direction:PublicId': $'''In''' @'name:IsDeleted': $'''''' @'type:IsDeleted': $'''Bool''' @'direction:IsDeleted': $'''Out''' @'name:ErrorMessage': $'''''' @'type:ErrorMessage': $'''String''' @'direction:ErrorMessage': $'''Out''' @IsDeleted=> IsDeleted @ErrorMessage=> ErrorMessage IF IsNotEmpty(ErrorMessage) THEN EXIT Code: 0 ErrorMessage: $'''System Exception: %ErrorMessage%''' END END END **ENDREGION