I'm trying to go through and entire workspace and list each element in a treeview, but when I attempt to grab the sheets in the found folders the getSheets() method in the Folder class always returns null. Am I doing something wrong?
TreeItem<String> workspace = new TreeItem<>("Earls Workspace", workspaceIcon);
workspace.setExpanded(true);
try {
Workspace earlsWorkspace = SmartsheetConnector.getInstance().getSmartsheet().workspaces().getWorkspace(*****);
List<Sheet> sheets = earlsWorkspace.getSheets();
List<Folder> folders = earlsWorkspace.getFolders();
for (Folder folder : folders) {
TreeItem<String> item = new TreeItem<>(folder.getName(), new ImageView(folderIcon));
System.out.println("Folder: " + folder.getName());
List<Sheet> folderSheets = folder.getSheets(); <- problem is here
System.out.println(folderSheets.toArray());
for (Sheet sheet : folderSheets) {
TreeItem<String> subItem = new TreeItem<>(sheet.getName(), new ImageView(sheetIcon));
item.getChildren().add(subItem);
}
workspace.getChildren().add(item);
}
for (Sheet sheet : sheets) {
TreeItem<String> item = new TreeItem<>(sheet.getName(), new ImageView(sheetIcon));
workspace.getChildren().add(item);
}
sheetExplorer.setRoot(workspace);
} catch (SmartsheetException ex) {
ex.printStackTrace();
}
I've purposefully blocked out the workspace ID.
Since the Java SDK mimics the Smartsheet API, the GET workspace by ID function only returns high level folder information, and does not include the sheets within the folder, which is why it is returning null. There are two ways to solve your problem:
After getting a list of folders from your workspace, you can call the GET folder by ID function, and that will return a list of sheets within a folder.
Workspace earlsWorkspace = SmartsheetConnector.getInstance().getSmartsheet().workspaces().getWorkspace(*****);
List<Folder> folders = earlsWorkspace.getFolders();
for (Folder folder : folders) {
List<Sheet> folderSheets = SmartsheetConnector.getInstance().getSmartsheet().folders().getFolder(folder.getId()).getSheets();
for (Sheet sheet : folderSheets) {
System.out.println(sheet.getName());
}
}
Call the getHome() function. This will return a nested list of all Home objects, including sheets, workspaces and folders, and optionally reports and/or templates depending on the EnumSet that you pass in. You will have to go through the list of workspaces and find the one that you are interested in. From there, you can loop through the folders, and call folder.getSheets() to get a list of sheets within a folder.
Home home = SmartsheetConnector.getInstance().getSmartsheet().home().getHome(EnumSet.of(ObjectInclusion.TEMPLATES);
In the next release of the SDK, there will be an option to specify if you want to load all of the contents, including nested folders and nested sheets within a workspace, so you can easily call folder.getSheets(), just like you were doing, and get back a list of sheets.
Related
I retrieved all items in my SharePoint list using .GetItems() command.
However, it does not have contain folder type items in my result.
A type of ERMS Folder Content Type do exists in the list, as below:
Documents of other content types are still being displayed, no issues.
May I know if I have used the incorrect commands to retrieve folders in a SharePoint list?
Below is my code snippet:
$baseUrl = "http://test.com"
$web = Get-SPWeb($baseUrl)
$RDlistUrl = $baseUrl + "/RecordsDocument"
$RDlist = $web.GetList($RDlistUrl)
$RDitems = $RDlist.GetItems()
foreach ($RDitem in $RDitems)
{
if ($RDitem.ContentType.Name.Contains("Folder"))
{
//no output captured.
}
splist.GetItems() would not get folder items. You have to use splist.folders to get folder items : https://learn.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ms443958(v=office.14)
Please change your code to this:
#Get folder items
$RDitems = $RDlist.Folders
foreach ($RDitem in $RDitems)
{
if ($RDitem.ContentType.Name.Contains("Folder"))
{
$RDitem
}
}
I am trying to transfer ownership of all my .pdf files to another account with more space. I am testing the code with a single folder in my drive.
function transfer() {
var user = Session.getActiveUser();
var folder = DriveApp.getFolderById('123folder-id456789-VxdZjULVQkPAaJ');
var files = folder.getFilesByType(MimeType.PDF);
while (files.hasNext()) {
var file = files.next();
if (file.getOwner() == user) file.setOwner('example#gmail.com');
}
}
When I run the code, none of the files change ownership.
How about this modification?
Modification points:
In your script, it tries to compare the objects of Session.getActiveUser() and file.getOwner(). I think that this is the reason of your issue.
So how about this modification? Please think of this as just one of several answers.
Modified script:
function transfer() {
var user = Session.getActiveUser().getEmail(); // Modified
var folder = DriveApp.getFolderById('123folder-id456789-VxdZjULVQkPAaJ');
var files = folder.getFilesByType(MimeType.PDF);
while (files.hasNext()) {
var file = files.next();
if (file.getOwner().getEmail() == user) file.setOwner('example#gmail.com'); // Modified
}
}
In this modification, the emails are compared.
References:
getActiveUser()
getOwner()
Class User
If this didn't resolve your issue, I apologize.
Currently drive can't transefere the ownership of file that are not build-in, like pdf, zip, etc. So you must download them and reupload from the other account. I wrote a colab to do that without consume my bandwith. It can recursively transfere an entire folder with both build-in file types and other file types.
I am making a GTK+3 App with GJS where users select a folder from a GtkFileChooserButton (action property set to select-folder). I want to find all image files in the given folder the user have selected, so I can display one of the images.
I tried this._fileChooserButton.get_files() and this._folderChooseButton.get_uris() but they only return one file, which is the path to the selected folder. Like this:
_init(application) {
this._folderChooseButton.connect('file-set', () => {
this._onFolderChosen();
});
}
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
// somehow get files from the folder here
this._image.set_from_file(files[1]);
}
From the API it is not really clear to me, how do I find out which image files are inside the user's selected directory (and subdirectories)?
OK, after help from patrick, georges and matthias at guadec, here is what I got.
The get_file() function I tried returns a GFile, which in this case is a folder (in UNIX, folders are also files). In order to get the files within the directory path, we need to call enumerate_children_async() on our GFile, returned by the get_file() function.
The enumate_children_async() function takes five parameters:
A comma-separated attribute list. In our case, since we want the identifiers of the children in the directory, we want to use the attribute called standard::name.
FileQueryInfoFlag: This allows to either follow or not follow symbolic links. In this case, we will use FileQueryInfoFlag.NONE which will not follow symbolic links.
io_priority: How high priority the IO operation should have (we will use GLib.PRIORITY_DEFAULT)
cancellable: A cancellable, which is a way to cancel this operation, in this case we will leave it as null.
callback: This is the function/code you want to run in response to the files having been retreived.
More info on this function is at GJS-Docs at GNOME.org
The enumerate_children_async() function returns a GFileEnumerator, which we can use to retreive a number of the files, by calling next_files_async(), which takes these arguments:
num_files: How many files you want to retreive. In your case, we use 1.
io_priority and cancellable (same as above).
callback: Where we can run a function or code to actually retreive the file.
Below, is the final code for doing this.
const { Gio, GLib, GObject, Gtk } = imports.gi; // import Gio and GLib API at top of your document.
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
let files = folder.enumerate_children_async(
'standard::name',
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
this._fileEnumerator = null;
try {
this._fileEnumerator = folder.enumerate_children_finish(result);
} catch (e) {
log('(Error) Could not retreive list of files! Error:' + e);
return;
}
this._readNextFile();
});
}
_readNextFile() {
if (!this._fileEnumerator)
return;
let fileInfo = null;
this._fileEnumerator.next_files_async(
1,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
try {
fileInfo = this._fileEnumerator.next_files_finish(result);
} catch (e) {
log('Could not retreive the next file! Error:' + e);
return;
}
let file = fileInfo[0].get_name();
let filePath = GLib.build_filenamev([this._folderChooseButton.get_filename(), file]);
this._carousselImage.set_from_file(filePath);
});
}
Our team uses TFS to manage workflow in the following flow:
work item -> source control -> changelist -> manual deploy to servers
Is there any way to just get a list of files with complete directory structure for a given changelist? Ideally, I'd like to be able to select multiple changelists and/or work items to get all the changelists associated with a work item, and get a complete directory structure for files in the changelists/work items.
Any suggestions would be appreciated, thanks!
You can probably use the following code snippit to get started
Uri tfsUri = new Uri(#"http://server:8080/tfs");
string serverPath = #"$/Project";
//Connect to the project collection
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
tfsUri, new UICredentialsProvider());
//Get the source code control service.
var sourceControl = projectCollection.GetService<VersionControlServer>();
var history = sourceControl.QueryHistory(
serverPath, //Source control path to the item. Like $/Project/Path ...
LatestVersionSpec.Instance, //Search latest version
0, //No unique deletion id.
RecursionType.Full, //Full recursion on the path
null, //All users
new ChangesetVersionSpec("9829"), //From the 7 days ago ...
LatestVersionSpec.Instance, //To the current version ...
Int32.MaxValue, //Include all changes. Can limit the number you get back.
true, //Include details of items, not just metadata.
false //Slot mode is false.
);
//Enumerate of the changesets.
foreach (Changeset changeset in history.OfType<Changeset>().Take(1))
{
foreach (var change in changeset.Changes)
{
change.Item.ServerItem.Dump();
}
}
I used the code in the link mentioned below to merge word files into a single file
http://devpinoy.org/blogs/keithrull/archive/2007/06/09/updated-how-to-merge-multiple-microsoft-word-documents.aspx
However, seeing the output file i realized that it was unable to copy header image in the first document. How do we merge documents preserving format and content.
I will suggest to use GroupDocs.Merger Cloud for merging multiple word document to a single word document, it keeps the formatting and contents of the source documents. It is a platform independent REST API solution without depending on any third-party tool or software.
Sample C# code:
var configuration = new GroupDocs.Merger.Cloud.Sdk.Client.Configuration(MyAppSid, MyAppKey);
var apiInstance_Document = new GroupDocs.Merger.Cloud.Sdk.Api.DocumentApi(configuration);
var apiInstance_File = new GroupDocs.Merger.Cloud.Sdk.Api.FileApi(configuration);
var pathToSourceFiles = #"C:/Temp/input/";
var remoteFolder = "Temp/";
var joinItem_list = new List<JoinItem>();
try
{
DirectoryInfo dir = new DirectoryInfo(pathToSourceFiles);
System.IO.FileInfo[] files = dir.GetFiles();
foreach (System.IO.FileInfo file in files)
{
var request_upload = new GroupDocs.Merger.Cloud.Sdk.Model.Requests.UploadFileRequest(remoteFolder + file.Name, File.Open(file.FullName, FileMode.Open));
var response_upload = apiInstance_File.UploadFile(request_upload);
var item = new JoinItem
{
FileInfo = new GroupDocs.Merger.Cloud.Sdk.Model.FileInfo
{ FilePath = remoteFolder + file.Name }
};
joinItem_list.Add(item);
}
var options = new JoinOptions
{
JoinItems = joinItem_list,
OutputPath = remoteFolder + "Merged_Document.docx"
};
var request = new JoinRequest(options);
var response = apiInstance_Document.Join(request);
Console.WriteLine("Output file path: " + response.Path);
}
catch (Exception e)
{
Console.WriteLine("Exception while Merging Documents: " + e.Message);
}
That code is inserting a page break after each file.
Since sections control headers, if a second or subsequent document has a header, you'll probably be wanting to keep the original section properties, and insert those after your first document.
If you look at your original document as a docx, you'll probably see that your section is a document level section properties element.
The easiest way around your problem may be to create a second section properties element inside the last paragraph (which contains the header information). Then this should just stay there when the documents are merged (ie other paragraphs added after it).
That's the theory. See also http://www.pcreview.co.uk/forums/thread-898133.php
But I haven't tried it; it assumes InsertFile behaves as I expect it should.