S3PutObjectCopy Batch Operations change destination structure of output directories in .NET - c#

I'm using AWS.NET SDK and I'm trying to use S3CopyObjectOperation with CreateJob from batch operations. It works fine, I'm generating manifest on the fly with the following content:
mysourcebucket,folder/subdir/file1.txt
mysourcebucket,folder/subdir/file2.txt
Now I'm creating a job with CreateJob with the following request:
new CreateJobRequest(){
// some values ommited
Operation = new JobOperation(){
S3PutObjectCopy = new S3CopyObjectOperation{
StorageClass = Standard,
TargetResource = dstBucketArn,
TargetKeyPrefix = dstSubdir
}
},
Manifest = new JobManifest(){
Spec = new JobManifestSpec(){Fields={"Bucket","Key"}, Format= JobManifestFormat.S3BatchOperations_CSV_20180820},
Location= new JobManifestLocation(){
ObjectArn = //manifest key,
Etag = // manifest Etag
}
}
}
It is copying the files correctly under dstBucket. Output:
dstSubdir/folder/subdir/file1.txt
dstSubdir/folder/subdir/file2.txt
Is it possible to change target path somehow, so it doesn't include folder? Expected output:
dstSubdir/subdir/file1.txt
dstSubdir/subdir/file2.txt
Edit: Imageine simple scenario where I want to copy these objects and at some point copy them back into the same location. I won't be able to do that if I use TargetPrefix. In above example I'd create
targetbucket,dstSubdir/folder/subdir/file1.txt
targetbucket,dstSubdir/folder/subdir/file2.txt
And output would be in srcbucket:
srcSubdir/dstSubdir/folder/subdir/file1.txt
srcSubdir/dstSubdir/folder/subdir/file2.txt
The only solution that would work is not to use TargetPrefix at all and keep the same structure in src and dst buckets which is quite a big restriction in my case.
Ideally I'd like to pass
my-bucket,{"origKey": "object1key", "newKey": "newObject1Key"}
my-bucket,{"origKey": "object2key", "newKey": "newObject2Key"}
my-bucket,{"origKey": "object3key", "newKey": "newObject3Key"}
as presented in this example https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-invoke-lambda.html

Related

How do you recursively revert changes in a working copy using SharpSVN?

I have a project that will automatically merge and commit from a list of user-selected revisions from one branch to another. If a merge conflict occurs, the process is aborted and the working copy is reverted.
However, when I go to try again and select a revision that would normally not cause a conflict on a pristine working copy, I get the following error:
Merge failed: SharpSvn.SvnWorkingCopyException: Can't merge into conflicted node 'C:\SVN\MyProject\MyBranch\ProjectDirectory\SubDirectory\conflicted-file.cs'
Even if I do a revert on the working copy, it only appears to revert the svn:mergeinfo property, but not the files within (conflicted or not, the old files are still there). Is it not reverting recursively? I'm not seeing an option to do so otherwise.
Here's what I've tried so far:
using (var client = new SvnClient())
{
// [Authentication code goes here...]
var targetPath = $#"{_svnLocalRoot}\{project}\{branch}\";
// Clean Up
var cleanupArgs = new SvnCleanUpArgs()
{
BreakLocks = true,
ClearDavCache = true,
VacuumPristines = true,
FixTimestamps = true
};
client.CleanUp(targetPath, cleanupArgs);
// Revert
var revertArgs = new SvnRevertArgs()
{
Depth = SvnDepth.Infinity,
ClearChangelists = true
};
client.Revert(targetPath);
// Update
var updateArgs = new SvnUpdateArgs()
{
Depth = SvnDepth.Infinity
};
client.Update(targetPath, updateArgs);
// [Merge and commit code goes here...]
}
Short of deleting the entire working directory and doing a check-out (which takes a very long time), what do I need to do to get my working copy to a pristine state with no conflicts and the latest code?
I'm currently using SharpSvn.1.9-x64 version 1.9005.3940.224
It was as simple as a typo.
client.Revert(targetPath);
should have been:
client.Revert(targetPath, revertArgs);

Api for working with a classes as OOP?

I'm writing a 3rd party app that needs to read in .cs files and be able to manipulate classes, then ultimately save back to file.
The type of code I am looking at would be something like:
var classManager = new classManager();
var classes = classManager.LoadFromFile(filePath);
var class = classes[0]; // Just illustrating more than 1 class can exist in a file
var prop = new ClassProperty {Type=MyType.GetType() };
prop.AddGet("return x+y < 50");
//stuff like prop.ReadOnly = true;
class.AddProperty(prop);
var method = new ClassMethod {signature="int id, string name"};
method.MethodBody = GetMethodBodyAsString(); //not writing out an entire method body here
class.AddMethod(method);
class.SaveToFile(true); //Format code
Does such a library exist?
The .NET Compiler Platform Roslyn is what you're looking for. It supports parsing and editting cs files. Check out this post for an example

Copying annotations leads to a corrupted attachment

I'm implementing a plugin (POST Quote Create, Synchronous, Sandbox) to make it so that Notes are copied to the new record when a quote is revised.
My plugin boils down to this (snippet):
var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var Service = serviceFactory.CreateOrganizationService(context.UserId);
var notesQuery = new QueryExpression("annotation");
notesQuery.ColumnSet = new ColumnSet(true);
notesQuery.Criteria = new FilterExpression
{
FilterOperator = LogicalOperator.And,
Conditions =
{
new ConditionExpression("objecttypecode", ConditionOperator.Equal, "quote"),
new ConditionExpression("objectid", ConditionOperator.Equal, revisedQuoteId)
}
};
var notes = Service.RetrieveMultiple(notesQuery).Entities;
foreach (var n in notes)
{
var newNote = new Entity("annotation");
newNote.Attributes.Add("ownerid", n.GetAttributeValue<EntityReference>("ownerid"));
newNote.Attributes.Add("objectid", new EntityReference("quote", sourceEntity.Id));
newNote.Attributes.Add("objecttypecode", "quote");
newNote.Attributes.Add("subject", n.GetAttributeValue<string>("subject"));
newNote.Attributes.Add("notetext", n.GetAttributeValue<string>("notetext"));
newNote.Attributes.Add("isdocument", n.GetAttributeValue<bool>("isdocument"));
if (n.GetAttributeValue<bool>("isdocument"))
{
newNote.Attributes.Add("filesize", n.GetAttributeValue<int>("filesize"));
newNote.Attributes.Add("documentbody", n.GetAttributeValue<string>("documentbody"));
newNote.Attributes.Add("filename", n.GetAttributeValue<string>("filename"));
newNote.Attributes.Add("mimetype", n.GetAttributeValue<string>("mimetype"));
}
Service.Create(newNote);
}
Basically, I copy everything over, including an eventual attachment. Everything seems fine, the new revision shows fields, detail records and notes properly... everything but the attachment of the notes.
If I have a single note, with an attached test.txt which content is:
Test attachment
The OrganizationData service reads as follows:
<d:FileName>test.txt</d:FileName>
<d:FileSize m:type="Edm.Int32">39</d:FileSize>
<d:DocumentBody>H4sIAAAMaVMA/wtJLS5RSCwpSUzOyE3NK+HlAgCLmj1zEQAAAA==</d:DocumentBody>
Its "clone" has the correct subject and text, and also shows a test.txt attached which content is
‹ iS ÿI-.QH,)ILÎÈMÍ+áå ‹š=s
mimetype and filesize (while checking odata, I noticed that filesize is not actually correct!) appear to be correct (aka: the same as the original note I'm trying to copy), but OData seems to confirm something's off (it's different!):
<d:FileName>test.txt</d:FileName>
<d:FileSize m:type="Edm.Int32">60</d:FileSize
<d:DocumentBody>H4sIAED6aVMA/5Pv5mBg4MkMZvjP7amrF+iho+npc+6E71nth0+ZGLpn2RYLMjAwAABXqCwTJQAAAA==</d:DocumentBody>
The test.txt file was created from a command prompt (COPY CON test.txt, type, CTRL+Z).
I tried to change the file, and created a test.pdf through PDFCreator: AcroRead in turn whines and says the document is corrupted (so it seems like the issue is mimetype-agnostic).
I also tried re-implementing the same code through early binding (via the CRMSVCUTIL-generated classes) but it yields the exact same result (garbage instead of the attachment contents).
I attempted to hand-craft the documentbody like this:
// "VGVzdCBhdHRhY2htZW50" is Base64 for "Test attachment"
newNote.Attributes.Add("documentbody", "VGVzdCBhdHRhY2htZW50");
and the created file is correct.
I can't figure out what's going on: as far as I know, documentbody is supposed to be a Base64-encoded string which (again, as far as I know) shouldn't be any different when copied around. What am I missing ?
For reference, CRM is updated to UR13 but I repro'd it on a UR16 environment.
EDIT: Does NOT work (only for CRM 4)
Try this (not verified):
var notes = Service.RetrieveMultiple(notesQuery).Entities;
foreach (var newNote in notes)
{
newNote.annotationid = null;
newNote.Attributes.Add("objectid", new EntityReference("quote", sourceEntity.Id));
newNote.Attributes.Add("objecttypecode", "quote");
Service.Create(newNote);
}
Just saw this, in an article from MSDN:
Annotation setupAnnotation = new Annotation()
{
Subject = "Example Annotation",
FileName = "ExampleAnnotationAttachment.txt",
DocumentBody = Convert.ToBase64String(
new UnicodeEncoding().GetBytes("Sample Annotation Text")),
MimeType = "text/plain"
};
I see the document body is encoded according to the Unicode encoding. Maybe you should try to retrieve the encoding from the file and convert it to a string accordingly.

SharpSVN - How to get the previous revision?

I am trying to find an efficient way to get the previous revision of a file to do a text comparison using SharpSVN.
using (SvnClient c = new SvnClient())
{
c.Authentication.DefaultCredentials = new NetworkCredential(
ConfigurationManager.AppSettings.Get("SvnServiceUserName")
, ConfigurationManager.AppSettings.Get("SvnServicePassword")
, ConfigurationManager.AppSettings.Get("SvnServiceDomain")
);
c.Authentication.SslServerTrustHandlers += new EventHandler<SvnSslServerTrustEventArgs>(Authentication_SslServerTrustHandlers);
Collection<SvnFileVersionEventArgs> fileVersionCollection = new Collection<SvnFileVersionEventArgs>();
SvnRevisionRange range = new SvnRevisionRange(0, this.hooks.Revision);
SvnFileVersionsArgs args = new SvnFileVersionsArgs();
args.RetrieveProperties = true;
args.Range = range;
foreach (SvnChangeItem item in log.ChangedPaths)
{
string path = this.repositoryPath + item.Path;
bool gotFileVersions = false;
try
{
if (item.NodeKind == SvnNodeKind.File)
gotFileVersions = c.GetFileVersions(SvnTarget.FromString(path), args, out fileVersionCollection);
The code above is an example of performing my request, however it is extremely inefficient. My goal is to be able to select a revision, and also the previous revision. For example, if my repository is at r185, but I want to view the file at revision 100, and also view the same file's previous revision (which I wouldn't know what is), how can this be done?
I've looked at c.GetInfo() but this seems to only get the previous revision to the most current commit.
Thanks!
Try only getting the versions you're looking for. I'm assuming log is an instance of SvnLoggingEventArgs?
If so, use:
args.Range = new SvnRevisionRange(log.Revision, log.Revision - 1);
That way you'll only retrieve the changes from that revision, and because log.Revision is guaranteed to be the revision number of the change, if you subtract one, you have the previous version.
Do you need the Previous version (the version before the last commit) or the local unmodified version.
The Subversion working copy library has the following 'magic' versions
Working (SvnRevision.None) - What you have in your working copy
(includes local modifications)
Head (SvnRevision.Head) - The last committed version of a url in the
repository
Base (SvnRevision.Base) - The version you last committed or updated to.
Committed (SvnRevision.Comitted) - The last revision <= BASE in which the path was
modified
Previous (SvnRevision.Previous) - The last revision before Committed.
(Literally Committed-1)
To get one of these versions you can use SvnClient.Write()
using (SvnClient c = new SvnClient())
using (Stream to = File.Create(#"C:\temp\my.tmp"))
{
c.Write(new SvnPathTarget(#"F:\projects\file.cs", SvnRevision.Base), to);
}
The files for Working and Base are available locally. For the other versions Subversion has to contact the repository.

WP7: collection of images

I have images in folder Images in my windows phone solution. How can i get collection of images in this folder? Build Action of all images is "Content".
It had been bugging me that it wasn't possible to do this so I've done a bit of digging and have come up with a way of getting a list of all image files with the build action of "Resource". - Yes, this isn't quite what was asked for but hopefully this will still be useful.
If you really must use a build action of "Content" I'd use a T4 script to generate the list of files at build time. (This is what I do with one of my projects and it works fine.)
Assuming that the images are in a folder called "images" you can get them with the following:
var listOfImageResources = new StringBuilder();
var asm = Assembly.GetExecutingAssembly();
var mrn = asm.GetManifestResourceNames();
foreach (var resource in mrn)
{
var rm = new ResourceManager(resource.Replace(".resources", ""), asm);
try
{
var NOT_USED = rm.GetStream("app.xaml"); // without getting a stream, next statement doesn't work - bug?
var rs = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture, false, true);
var enumerator = rs.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().StartsWith("images/"))
{
listOfImageResources.AppendLine(enumerator.Key.ToString());
}
}
}
catch (MissingManifestResourceException)
{
// Ignore any other embedded resources (they won't contain app.xaml)
}
}
MessageBox.Show(listOfImageResources.ToString());
This just displays a list of the names, but hopefully it'll be easy to change this to do whatever you need to.
Any suggestions for improving this code will be greatly appreciated.

Categories

Resources