MS has announced directory like blob storage, and I'm trying to use it like directories.
Having save some blobs by names:
Common\Service1\Type1\Object1
Common\Service1\Type1\Object2
Common\Service1\Type2\Object1
Common\Service1\Type2\Object2
Common\Service1\Type3\Object1
Common\Service1\Type3\Object2
Common\Service1\Type3\Object3
I'd like to have possibility to enumerate subdirectories, e.g. I have blobclient referenced to Common container name, and I would like to get subcontainers list Type1, Type2, Type3. Is it possible to get list of subdirectories in some directory. Using ListBlobs returns full list of blobs within current container.
If you would like to list all "subdirectories" in "Common\Service1" directory you can use something like this:
var directory = blobContainer.GetDirectoryReference(#"Common/Service1");
var folders = directory.ListBlobs().Where(b => b as CloudBlobDirectory != null).ToList();
foreach (var folder in folders)
{
Console.WriteLine(folder.Uri);
}
Full code sample:
var random = new Random();
CloudStorageAccount storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
var cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer blobContainer = cloudBlobClient.GetContainerReference("test-container");
blobContainer.CreateIfNotExists();
string[] objects = new[]
{
#"Common\Service1\Type1\Object1", #"Common\Service1\Type1\Object2", #"Common\Service1\Type2\Object1",
#"Common\Service1\Type2\Object2", #"Common\Service1\Type3\Object1", #"Common\Service1\Type3\Object2",
#"Common\Service1\Type3\Object3"
};
foreach (var newObject in objects)
{
var newBlob = blobContainer.GetBlockBlobReference(newObject);
var buffer = new byte[1024];
random.NextBytes(buffer);
newBlob.UploadFromByteArray(buffer,0,buffer.Length);
}
var directory = blobContainer.GetDirectoryReference(#"Common/Service1");
var folders = directory.ListBlobs().Where(b => b as CloudBlobDirectory != null).ToList();
foreach (var folder in folders)
{
Console.WriteLine(folder.Uri);
}
This will output Uri for Type1,Type2 and Type3 directory.
Building on b2zw2a's answer:
The # is only needed when using \, not /.
Don't chain ToList() after ListBlobs(). ListBlobs() provides lazy loading and will give you better perf.
Use OfType<CloudBlobDirectory>() to filter out only the type you want
Giving you:
var directory = blobContainer.GetDirectoryReference("Common/Service1");
var folders = directory.ListBlobs().OfType<CloudBlobDirectory>();
foreach (var folder in folders)
{
Console.WriteLine(folder.Uri);
}
var nameList=logoContainer.ListBlobs().Where(b => b as CloudBlobDirectory != null).Select(x => x.Uri + "").ToList();
By using this you can get all the filenames in a single query.
Related
I have one list of complex object. How can I distinct the list using their IDs?
I cant use toSet and similars, because the hashcode from the objects all are diferent.
1) Vanilla Dart
Loop through the list, adding IDs to a set as you go. Whenever you add an ID to the set that didn't already exist, add that element to a new list of distinct values.
void main() {
var list = [
Data('a'),
Data('a'),
Data('b'),
Data('c'),
];
var idSet = <String>{};
var distinct = <Data>[];
for (var d in list) {
if (idSet.add(d.id)) {
distinct.add(d);
}
}
}
class Data {
Data(this.id);
final String id;
}
2) Packages
Several packages exist that expand on default the Iterable utility methods, such as flinq or darq. They add a distinct method you can call to easily get a list of unique members of a list based on some property of the members.
import 'package:darq/darq.dart';
void main() {
var list = [
Data('a'),
Data('a'),
Data('b'),
Data('c'),
];
var distinct = list.distinct((d) => d.id).toList();
}
(Disclaimer, I am the maintainer of darq.)
Try to use this extension:
extension IterableExtension<T> on Iterable<T> {
Iterable<T> distinctBy(Object getCompareValue(T e)) {
var result = <T>[];
this.forEach((element) {
if (!result.any((x) => getCompareValue(x) == getCompareValue(element)))
result.add(element);
});
return result;
}
}
Using:
var distinctList = someList.distinctBy((x) => x.oid);
Or you can use a hash there.
I am trying to modify the way ember-i18n localizations are loaded. What I want to do is have the localizations in a separate file from the main app javascript file.
Ideally, the structure would remain the same as now. So I would have app/locales/fr/translations.js and app/locales/de/translations.js , each having content similar to this:
export default {
key: "value"
}
So I thought I need to write a custom addon, which would alter the build process. This addon would need to:
Ignore app/locales from final build
Compile all the translation files into one
Transpile the new file with babel
Copy the file in dist/assets/translations.js
The combined translation file would look something like this:
export default {
fr: {
key: "value"
},
de: {
key: "value"
}
This way, I would be able to use and instance initializer and simply import and use this module:
import Translations from 'my-translations';
export function initialize(instance) {
const i18n = instance.lookup('service:i18n');
for(let lang in Translations) {
if(Translations.hasOwnProperty(tag)) {
i18n.addTranslations(tag, Translations[tag]);
}
}
}
Also, index.html would be:
<script src="assets/vendor.js"></script>
<script src="assets/translations.js"></script>
<script src="assets/my-app.js"></script>
Well, I started writing the custom addon, but I got stuck. I managed to ignore the locales, and I wrote code that parses all the localizations, but I do not know how to write the new translations file in dist. What hook do I neeed to use, to be able to write into dist? Any help? Thank you so much.
Here is the code I wrote:
Stuff I use
var Funnel = require('broccoli-funnel');
var stew = require('broccoli-stew');
var fs = require('fs');
var writeFile = require('broccoli-file-creator');
var mergeTrees = require('broccoli-merge-trees');
preprocessTree: function(type, tree) {
if(type !== 'js') {return tree;}
var treeWithoutLocales = new Funnel(tree, {
exclude: ['**/locales/*/translations.js']
});
var translations = {};
var files = fs.readdirSync('app/locales');
files.forEach((tag) => {
if(tag !== 'fr') {return;}
let contents = fs.readFileSync('app/locales/' + tag + '/translations.js', 'utf8');
contents = contents.replace(/^export default /, '');
contents = contents.replace(/;$/, '');
contents = JSON.parse(contents);
translations[tag] = contents;
});
// Should do something with this .. how to write in dist? and when? I need it compiled with babel
var fileTree = writeFile('/my-app/locales/translations.js', 'export default ' + JSON.stringify(translations) + ';');
return treeWithoutLocales;
}
I am not sure if you actually asked a question; but here goes some kind of answer.
Why complicate? Just use James Rosen's i18n addon used by a lot of projects.
I am working on Sitecore 8.1 and I am implementing filter functionality for one of the page by Sitecore lucene. Fot filtering I am using predicate builder. I have 3 multi-lists field on detail items
Product
Category
Services
Now on listing page I have all three group filters as checkboxes as given in below image -
My Requirement is I want to apply Or between inside the group like between products condition should be Or and between two groups condition should be And. For example products and Category should be And.
I followed http://getfishtank.ca/blog/building-dynamic-content-search-linq-queries-in-sitecore-7 blog post to implement this
To achieve this what I am trying -
var builder = PredicateBuilder.True<TestResultItem>();
var Categorybuilder = PredicateBuilder.False<TestResultItem>();
if (!string.IsNullOrEmpty(Categorys))
{
var CategoryItems = Categorys.Split('|');
foreach (var Category in CategoryItems)
{
var ct = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(Categorys, true);
Categorybuilder = Categorybuilder.Or(i => i.Category.Contains(ct));
}
}
var Servicebuilder = PredicateBuilder.False<TestResultItem>();
if (!string.IsNullOrEmpty(Service))
{
var ServiceItems = Service.Split('|');
foreach (var ser in ServiceItems)
{
var si = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(ser, true);
Servicebuilder = Servicebuilder.Or(i => i.Service.Contains(si));
}
}
var productsbuilder = PredicateBuilder.False<TestResultItem>();
if (!string.IsNullOrEmpty(products))
{
var productItems = products.Split('|');
foreach (var product in productItems)
{
var pd = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(product, true);
productsbuilder = productsbuilder.Or(i => i.Category.Contains(pd));
}
}
Servicebuilder = Servicebuilder.Or(Categorybuilder);
productsbuilder = productsbuilder.Or(Servicebuilder);
builder = builder.And(productsbuilder);
The above given code is not working for me. I know I am doing something wrong as I am not good with Predicate builder, Or condition is not working between check boxes group.
Can anyone please tell me where I am wrong in given code or any best way to achieve this.
Any help would be appreciated
I did something similar recently and it works like this:
Create your "or" predicates:
var tagPredicate = PredicateBuilder.False<BlogItem>();
tagPredicate = tagValues.Aggregate(tagPredicate, (current, tag) => current.Or(p => p.Tags.Contains(tag)))
where tagValues is an IEnumerable containing the normalized guids.
I do this for several guid lists. In the end I wrap them together like this:
var predicate = PredicateBuilder.True<BlogItem>();
predicate = predicate.And(tagPredicate);
predicate = predicate.And(...);
Looking at your code: first of all change
Servicebuilder = Servicebuilder.Or(Categorybuilder);
productsbuilder = productsbuilder.Or(Servicebuilder);
builder = builder.And(productsbuilder);
into
builder = builder.And(Categorybuilder);
builder = builder.And(Servicebuilder);
builder = builder.And(productsbuilder);
You need to have one main predicate to join filters with AND condition & other predicates (e.g. for categories or services or products) to join filters internally with OR condition.
// This is your main predicate builder
var builder = PredicateBuilder.True<TestResultItem>();
var Categorybuilder = PredicateBuilder.False<TestResultItem>();
var Servicebuilder = PredicateBuilder.False<TestResultItem>();
var productsbuilder = PredicateBuilder.False<TestResultItem>();
builder = builder.And(Categorybuilder);
builder = builder.And(Servicebuilder);
builder = builder.And(productsbuilder);
Hope this will help you.
Thanks all for providing your inputs -
I updated the code as per your inputs and now it's working.
There was two changes in my old code one was builder for multilist should be inside the if statement and also adding newly created builder to main builder on same location (inside the if statement) -
I am sharing the code below so that if anyone want to use it he can easily copy from here -
var builder = PredicateBuilder.True<TestResultItem>();
if (!string.IsNullOrEmpty(Categorys))
{ var Categorybuilder = PredicateBuilder.False<TestResultItem>();
var CategoryItems = Categorys.Split('|');
foreach (var Category in CategoryItems)
{
var ct = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(Categorys, true);
Categorybuilder = Categorybuilder.Or(i => i.Category.Contains(ct));
}
builder = builder.And(Categorybuilder);
}
if (!string.IsNullOrEmpty(Service))
{
var Servicebuilder = PredicateBuilder.False<TestResultItem>();
var ServiceItems = Service.Split('|');
foreach (var ser in ServiceItems)
{
var si = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(ser, true);
Servicebuilder = Servicebuilder.Or(i => i.Service.Contains(si));
}
builder = builder.And(Servicebuilder);
}
if (!string.IsNullOrEmpty(products))
{
var productsbuilder = PredicateBuilder.False<TestResultItem>();
var productItems = products.Split('|');
foreach (var product in productItems)
{
var pd = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(product, true);
productsbuilder = productsbuilder.Or(i => i.Category.Contains(pd));
}
builder = builder.And(productsbuilder);
}
In the above code Categorys, Service and products are pipe separated values which are coming from Sitecore Multi-list field.
Thanks again everyone for help!!
When you execute a query on a List that is a Document Library, ListItems have a File member that is not populated. Obviously the query doesn't pull in all data by default for performance reasons, but I can't figure out a way to tell the query to populate the File Member, since the query syntax is generic for all Lists and only Document Libraries contain files in them.
In order to retrieve ListItem with File property initialized it should be specified explicitly via ClientRuntimeContext.Load Method:
private static ListItem GetListItem(string url, ICredentials creds, string listTitle, int listItemId)
{
using (var clientContext = new ClientContext(url))
{
clientContext.Credentials = creds;
var list = clientContext.Web.Lists.GetByTitle(listTitle);
var listItem = list.GetItemById(listItemId);
clientContext.Load(list);
clientContext.Load(listItem, i => i.File); //specify File property
clientContext.ExecuteQuery();
return listItem;
}
}
This sample code should help you out:
var ctx = SP.ClientContext.get_current();
var itemFile = ctx.get_web().get_lists().getByTitle("Shared Documents").getItemById(1).get_file();
ctx.load(itemFile);
ctx.executeQueryAsync(function(){
console.log(itemFile.get_title());
},function(sender,args){
console.log(args.get_message());
});
Let's say I've got a solution with one or more projects, and I've just kicked off a build using the following method:
_dte.Solution.SolutionBuild.Build(true); // EnvDTE.DTE
How can I get the output paths for each project that just built? For example...
c:\MySolution\Project1\Bin\x86\Release\
c:\MySolution\Project2\Bin\Debug
Please don't tell me this is the only way...
// dte is my wrapper; dte.Dte is EnvDte.DTE
var ctxs = dte.Dte.Solution.SolutionBuild.ActiveConfiguration
.SolutionContexts.OfType<SolutionContext>()
.Where(x => x.ShouldBuild == true);
var temp = new List<string>(); // output filenames
// oh shi
foreach (var ctx in ctxs)
{
// sorry, you'll have to OfType<Project>() on Projects (dte is my wrapper)
// find my Project from the build context based on its name. Vomit.
var project = dte.Projects.First(x => x.FullName.EndsWith(ctx.ProjectName));
// Combine the project's path (FullName == path???) with the
// OutputPath of the active configuration of that project
var dir = System.IO.Path.Combine(
project.FullName,
project.ConfigurationManager.ActiveConfiguration
.Properties.Item("OutputPath").Value.ToString());
// and combine it with the OutputFilename to get the assembly
// or skip this and grab all files in the output directory
var filename = System.IO.Path.Combine(
dir,
project.ConfigurationManager.ActiveConfiguration
.Properties.Item("OutputFilename").Value.ToString());
temp.Add(filename);
}
This makes me want to retch.
You can get to the output folder(s) by traversing the file names in the Built output group of each project in EnvDTE:
var outputFolders = new HashSet<string>();
var builtGroup = project.ConfigurationManager.ActiveConfiguration.OutputGroups.OfType <EnvDTE.OutputGroup>().First(x => x.CanonicalName == "Built");
foreach (var strUri in ((object[])builtGroup.FileURLs).OfType<string>())
{
var uri = new Uri(strUri, UriKind.Absolute);
var filePath = uri.LocalPath;
var folderPath = Path.GetDirectoryName(filePath);
outputFolders.Add(folderPath.ToLower());
}