Get complete hierarchy of azure blob structure based on prefix - azure

I have following hierarchy in my azure storage container :
Container
-- Folder 1
-- Folder 2
-- Folder 2.1
-- File 1
-- File 2
-- File 3
What I'm searching for is a generic function where I can pass string e.g. "container/Folder1/Folder2" and it return me the hierarchy i.e.
-- Folder 2.1
-- File 1
-- File 2
-- File 3
I have following code in place but in this I'm not able to pass the prefix as "container/Folder1/Folder2". If I add "/" in prefix string then it throws error that invalid uri string.
static void printCloudDirectories(IEnumerable<IListBlobItem> blobList, Container cont)
{
foreach (var blobitem in blobList)
{
if (blobitem is CloudBlobDirectory)
{
var container = new Container();
var directory = blobitem as CloudBlobDirectory;
Console.WriteLine(directory.Prefix);
container.Name = directory.Prefix;
BlobContinuationToken token = null;
var directories = directory.ListBlobsSegmentedAsync(token).Result.Results;
printCloudDirectories(directories, container);
cont.Containers.Add(container);
}
else
{
cont.Children.Add(blobitem.Uri.AbsoluteUri);
}
}
}
public static void ListClientMethod(CloudBlobClient cloudBlobClient)
{
BlobContinuationToken token = null;
var containerSegments = cloudBlobClient.ListContainersSegmentedAsync(token).Result;
List<Container> containers = new List<Container>();
foreach (var container in containerSegments.Results)
{
Console.WriteLine("Container: " + container.Name);
var cont = new Container();
cont.Name = container.Name;
// ADD A CALL TO printCloudDirectories:
BlobContinuationToken token1 = null;
var blobs = container.ListBlobsSegmentedAsync(token1).Result.Results;
printCloudDirectories(blobs, cont);
containers.Add(cont);
}
}
public class Container
{
public Container()
{
Children = new List<string>();
Containers = new List<Container>();
}
public string Name { get; set; }
public List<string> Children { get; set; }
public List<Container> Containers { get; set; }
}
I use c# as coding language

Please use ListBlobsSegmentedAsync(String, Boolean, BlobListingDetails, Nullable<Int32>, BlobContinuationToken, BlobRequestOptions, OperationContext) method.
The 1st parameter to this method is the Blob Prefix and you need to specify Folder 1/Folder 2/ there.
2nd parameter to this method is useFlatBlobListing and you need to pass true for that.
It should return you a result like:
Folder 1/Folder 2/Folder 2.1/File 1
Folder 1/Folder 2/Folder 2.1/File 2
Folder 1/Folder 2/Folder 2.1/File 3
and you should be able to construct the desired treeview based on this.

Related

How do I access blob storage sub containers in my ASP.NET Core web application?

I've created a solution to access my container contents within my asp.net core 3.1 application and return that contents as a list to my view. At the moment the application access data in the root container which is called upload, however, this container has many sub containers and I would like to list the blobs in a specific one called 1799.
So, instead of accessing upload and showing me the full contents of that container, I want to access upload/1799 and list all the blobs within that container.
I cannot see of anyway to add this sub container to my method and allow this to happen, can anyone help?
Here is my code so far:
CarController.cs
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
namespace MyProject.Controllers
{
public class HomeController : Controller
{
private readonly IConfiguration _configuration;
private readonly string accessKey = string.Empty;
public HomeController(IConfiguration configuration)
{
_configuration = configuration;
accessKey = _configuration.GetConnectionString("AzureStorage");
}
[HttpGet]
public IActionResult Edit(int id)
{
var car = _carService.GetVessel(id);
string strContainerName = "uploads";
string subdir = "1799";
var filelist = new List<BlobListViewModel>();
BlobServiceClient blobServiceClient = new BlobServiceClient(accessKey);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(strContainerName);
var blobs = containerClient.GetBlobs();
foreach (var item in blobs)
{
filelist.Add(new BlobListViewModel
{
FileName = item.Name
});
}
return View(filelist);
}
}
I've hunted through all the documentation and I can't find anything related to this.
Thanks to David Browne for his comment, there is indeed a prefix option in GetBlob(). THey act like mini-filters in some ways allowing you to define what properties are returned and the blob state etc. Here is my code which has the options set to zero meaning Default for both Trait and State.
[HttpGet]
public IActionResult Edit(int id)
{
var car = _carService.GetVessel(id);
string strContainerName = "uploads";
string subdir = "1799";
var filelist = new List<BlobListViewModel>();
BlobServiceClient blobServiceClient = new BlobServiceClient(accessKey);
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(strContainerName);
//Traits, States, Prefix
var blobs = containerClient.GetBlobs(0, 0, subdir);
foreach (var item in blobs)
{
filelist.Add(new BlobListViewModel
{
FileName = item.Name
});
}
return View(filelist);
}

Acumatica How to iterate through files attached to Project?

I want to access all files attached to the current project. Im not able to find any files using the PXSelect statement below.
My Code
public PXSelect<UploadFile, Where<UploadFile.name, Like<Current<PMProject.contractCD>>>> Files;
string files = "";
foreach (UploadFile f in Files.Select())
{
files += "\n"+f.FileID;
}
Static GetFileNotes method of the PXNoteAttribute returns the list of identifiers of files attached to a record. Below is a code snippet showing how to retrieve all files attached to the current project:
public class ProjectEntryExt : PXGraphExtension<ProjectEntry>
{
public PXAction<PMProject> GetFiles;
[PXButton]
[PXUIField(DisplayName = "Get Files")]
protected void getFiles()
{
var projectCache = Base.Caches[typeof(PMProject)];
Guid[] files = PXNoteAttribute.GetFileNotes(projectCache, projectCache.Current);
foreach (Guid fileID in files)
{
var fm = new PX.SM.UploadFileMaintenance();
PX.SM.FileInfo fi = fm.GetFileWithNoData(fileID);
}
}
}

Add contacts to Marketing list on CRM2011

I'm trying to build a Workflow that add a Contact to a marketing list.
Everything seems to be fine, but when the code finishes firing, and I go to the marketing list -> members the contact is not in the list.
public class ContactToMList : CodeActivity
{
[Input("Contatto")]
[ReferenceTarget("contact")]
public InArgument<EntityReference> contact { get; set; }
[Input("Marketing List")]
[ReferenceTarget("list")]
public InArgument<EntityReference> MList { get; set; }
[Input("Inserimento")]
public InArgument<bool> inserimento { get; set; }
bool action = false;
private static IOrganizationService myService = null;
private static Log_Entity log = new Log_Entity(string.Empty, myService);
protected override void Execute(CodeActivityContext executionContext)
{
try
{
ITracingService tracingService = executionContext.GetExtension<ITracingService>();
// Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
// Create the Organiztion service
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
myService = service;
log.WriteLog("");
// Get the target entity from the context
Entity target = (Entity)context.InputParameters["Target"];
Guid contactiId = contact.Get<EntityReference>(executionContext).Id;
Guid ListId = MList.Get<EntityReference>(executionContext).Id;
bool insert = inserimento.Get<bool>(executionContext);
// Prepare DataContext by using AutoGenerated cs file
XrmDataContext datacontext = new XrmDataContext(service);
var MyContact = (from c in datacontext.ContactSet where c.ContactId == contactiId select c.Id).ToArray();
var MyList = (from l in datacontext.ListSet where l.Id == ListId select l).ToList().FirstOrDefault();
// tutti i membri della lista di marketing
var members = (from m in datacontext.ListMemberSet where m.ListId.Id == MyList.ListId select m.EntityId.Id).ToArray();
foreach (Guid id in members)
if (MyContact.FirstOrDefault() == id)
action = true;
if (insert && !action)
{
AddListMembersListRequest AddMemberRequest = new AddListMembersListRequest();
AddMemberRequest.ListId = ListId;
AddMemberRequest.MemberIds = MyContact;
// Use AddListMembersListReponse to get information about the request execution
AddListMembersListResponse AddMemberResponse = service.Execute(AddMemberRequest) as AddListMembersListResponse;
//service.Update(MyList);
}
else if (!insert && action)
{
RemoveMemberListRequest RemoveMemberRequest = new RemoveMemberListRequest();
RemoveMemberRequest.ListId = ListId;
RemoveMemberRequest.EntityId = MyContact.FirstOrDefault();
// Use AddListMembersListReponse to get information about the request execution
RemoveMemberListResponse RemoveMemberResponse = service.Execute(RemoveMemberRequest) as RemoveMemberListResponse;
// service.Update(MyList);
}
}
catch (Exception ex)
{
log.WriteLog(ex.Message);
}
}
}
aren't you erasing your values for AddMemberRequest.MemberIds after you set it?
EDIT:
Ok, I think I found it this time. Your public InArgument<bool> inserimento { get; set; } is likely the culprit.
In this case, your Workflow activity expects this to be defined upstream of the call to this Workflow. It's very likely statically set and never changed for both the Insert and Remove instances. If this is true, then it's being essentially hard coded for the Insert case, which makes the else if (!insert && action) evaluate to True for Remove and the if (insert && !action) evaluate to False for the Insert.
Since the code does work for Remove, it's reasonable to assume the bool action is working; therefore, I would start by looking into the other bool variable.
Let me know if I've missed it. (or if I'm right, I wouldn't mind the green check mark.)

How to get list of folders present in a directory in SVN using java

I am using svnkit-1.3.5.jar in my application. On one of my screens on clicking a button I need to display a jQuery dialog box containing list of folders present at a particular path in SVN. Does svnkit provide any method that retrieves all folder names present at a specific location? How do I achieve this in java?
Here is the code i use for the same purpose (uses svnkit library). Modified version of #mstrap's code for better clarity.
public static String NAME = "svnusername";
public static String PASSWORD = "svnpass";
public final String TRUNK_VERSION_PATH = "svn://192.168.1.1/path";
public static List<String> apiVersions;
public List<String> getApiVersion() {
logger.info("Getting API Version list....");
apiVersions = new ArrayList<String>();
SVNURL repositoryURL = null;
try {
repositoryURL = SVNURL.parseURIEncoded(TRUNK_VERSION_PATH);
} catch (SVNException e) {
logger.error(e);
}
SVNRevision revision = SVNRevision.HEAD;
SvnOperationFactory operationFactory = new SvnOperationFactory();
operationFactory.setAuthenticationManager(new BasicAuthenticationManager(NAME, PASSWORD));
SvnList list = operationFactory.createList();
list.setDepth(SVNDepth.IMMEDIATES);
list.setRevision(revision);
list.addTarget(SvnTarget.fromURL(repositoryURL, revision));
list.setReceiver(new ISvnObjectReceiver<SVNDirEntry>() {
public void receive(SvnTarget target, SVNDirEntry object) throws SVNException {
String name = object.getRelativePath();
if(name!=null && !name.isEmpty()){
apiVersions.add(name);
}
}
});
try {
list.run();
} catch (SVNException ex) {
logger.error(ex);
}
return apiVersions;
}
Cheers!!
final URL url = ...
final SVNRevision revision = ...
final SvnOperationFactory operationFactory = ...
final SvnList list = operationFactory.createList();
list.setDepth(SVNDepth.IMMEDIATES);
list.setRevision(revision);
list.addTarget(SvnTarget.fromURL(url, revision);
list.setReceiver(new ISvnObjectReceiver<SVNDirEntry>() {
public void receive(SvnTarget target, SVNDirEntry object) throws SVNException {
final String name = object.getRelativePath();
System.out.println(name);
}
});
list.run();

SharePoint 2010 folder woes

I've put together a function that creates a sharepoint folder in a document library based on the url that's past in as an argument. The code works and the folder shows up in sharepoint from the webapplication.
However, when I query the SPWeb object for the folder afterward, it says the folder doesnt exist. Which makes no sense to me. Stranger still, is that this very same code worked no too long ago. I had been using it to create tree structures in sharepoint.
Even if the query folder fails, the GetFolder still returns a the folder, but when I add files to the returned folder, I get a runtime exception indicating that the file doesn't exist...which I assume means the folder I am trying to add it to doesn't exist since the file I am adding, doesn't exist yet. Which is why I am adding it.
So my question is, why am I getting this error, and why does FolderExists return false when the folder actually exists? We know it exists because GetFolder actually returns it...
I've included some actual code from the app to make things clear.
If someone could have a look at the code and see and anything jumps out at them, that would be fantabulous...Thanks
Code to build folders:
public void CreateFolder(SPUriBuilder url)
{
try
{
Log.Instance.WriteToLog("CreateFolder({0})", url);
var library = GetLibrary(url.Library);
if (library != null)
{
// parse out string data
//
var parent = library.RootFolder.ServerRelativeUrl;
var segments = url.Account.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var path = parent;
// get default folder collection
//
SPFolderCollection subFolders = _web.GetFolder(parent).SubFolders;
// check for sub-folders to create
//
if (segments.Length > 0)
{
int i = 0;
do
{
// check for folder and create if non-existant
//
var buildPath = String.Format("{0}/{1}", path, segments[i]);
if (_web.GetFolder(buildPath).Exists == false)
_web.GetFolder(path).SubFolders.Add(segments[i]);
// retrieve new sub-folder collection
//
subFolders = _web.GetFolder(buildPath).SubFolders;
path = buildPath;
// next folder in path
//
i++;
}
while (i < segments.Length);
}
// finally, add folder of interest
//
subFolders.Add(url.Folder);
}
}
catch (Exception e)
{
throw new SPImportException("Exception: {0}, creating folder: {1} in Library: {2}", e.Message, url.Folder, url.Library);
}
}
Code to Query folder:
public bool FolderExists(SPUriBuilder url)
{
return _web.GetFolder(url.Uri.LocalPath).Exists;
}
Code to Get Folder:
private SPFolder GetFolder(SPUriBuilder url)
{
return _web.GetFolder(url.Uri.LocalPath);
}
The SPUriBuilder is a custom class I created to assemble the Uri:
public class SPUriBuilder
{
public string SiteUrl { get; private set; }
public string Library { get; private set; }
public string Parent { get; private set; }
public string Folder { get; private set; }
public string File { get; private set; }
public string Account { get; private set; }
public Uri Uri { get; private set; }
public SPUriBuilder(string siteUrl, string library, string account, string parent, string folder)
{
this.SiteUrl = siteUrl;
this.Library = library;
this.Account = account;
this.Parent = parent.Replace("\\", "/");
this.Parent = this.Parent.StartsWith("/") ? this.Parent.Substring(1) : this.Parent;
this.Folder = folder;
StringBuilder url = new StringBuilder();
url.AppendFormat("{0}/{1}/{2}", SiteUrl, Library, Account);
if (String.IsNullOrEmpty(Parent) == false)
url.AppendFormat("/{0}", Parent);
url.AppendFormat("/{0}", Folder);
this.Uri = new Uri(url.ToString());
}
public SPUriBuilder(SPUriBuilder uri, string file)
: this(uri.SiteUrl, uri.Library, uri.Account, uri.Parent, uri.Folder)
{
this.File = file;
StringBuilder url = new StringBuilder();
url.AppendFormat("{0}/{1}", this.Uri.ToString(), this.File);
this.Uri = new Uri(url.ToString());
}
public override string ToString()
{
return Uri.ToString();
}
}
I found the answer this to this myself. The problem was in the code used to create the folder.
var parent = library.RootFolder.ServerRelativeUrl;
// This line of code is incorrect, so it returned the wrong data, thus building the folder path incorrectly.
//
var segments = url.Account.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var path = parent;
// This is the replacement line of code that fixed the issue.
//
var segments = url.Uri.LocalPath.Substring(parent.Length+1).Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
// as well, this line had to be removed since it was no longer needed
//
// finally, add folder of interest
//
subFolders.Add(url.Folder);
Ultimately the issue turned out be that the folder structure did not exist that I was attempting to create the file in. One or more segments in the path were missing.
So if you ever see this error, make sure you're the folder exists that you are adding the file to. If it isn't, you will certainly experience this error.

Resources