Can not do math with structures in ColdFusion - data-structures

I am looping over a list and want to create a struct of struct if a struct key doesn't exist yet, but if it does exist, I want to only update one of the keys with a new value by adding something to the existing value of that key. It will not do that and I don't know why.
Here's the code:
<cfloop list="#recipeItemList#" index="ril">
<cfset thisrecipe = entityLoadByPK("recipes", #ril#)>
<cfloop array="#thisrecipe.getrecipeitem()#" index="recipeItems">
<cfif recipeItems.hasrawMaterial_id()>
<cfset theitem = entityLoadByPK("rawMaterials", recipeItems.getrawMaterial_id().getid())>
<cfinvoke method="getPrepByDate" component="/FEcomponents.production" returnvariable="makeAmount">
<cfinvokeargument name="recipe_id" value="#ril#">
<cfinvokeargument name="delivery_date" value="#delivery_date#">
</cfinvoke>
<cfset thisRecipeYield = #thisRecipe.getYield()#>
<cfif thisRecipeYield neq 0>
<cfset recipeRatio = makeAmount / thisRecipeYield>
</cfif>
<cfset thisQuantity = recipeRatio * #recipeItems.getitemQuantity()#>
<cfif structKeyExists(outerstruct, '#theitem.getid()#')>
<!--- we must add this quantity to the existing key, not create a new one --->
<cfset addthis = #outerstruct[theitem.getid()].totalToGet# + #thisQuantity#>
<cfset structInsert(outerstruct[theitem.getid()],'totalToGet', #addthis#,true)>
<!--- this is just to for testing to see if the value has changed, and it does not the 'addthis' value is always the latest value in the loop--->
#outerstruct[theitem.getid()].totalToGet# + #thisquantity# = #addthis# <BR>
<cfelse>
<!--- create a new struct --->
<cfset outerstruct[theitem.getid()] = structnew()>
<cfset outerstruct[theitem.getid()].rawMaterialid = #theitem.getid()#>
<cfset outerstruct[theitem.getid()].rawMaterialName = #theItem.getName()#>
<cfset outerstruct[theitem.getid()].totalToGet = #thisQuantity#>
<cfset outerstruct[theitem.getid()].uom = #theItem.getUOM().getname()#>
</cfif>
</cfif>
</cfloop>
</cfloop>
What am I doing wrong.
Thanks for your help

I think this will do what you want, I removed a few of the extra pound signs and changed the way you are updating the struct key. I'm sorry I am unable to run the code but I believe this should work.
<cfloop list="#recipeItemList#" index="ril">
<cfset thisrecipe = entityLoadByPK("recipes", #ril#)>
<cfloop array="#thisrecipe.getrecipeitem()#" index="recipeItems">
<cfif recipeItems.hasrawMaterial_id()>
<cfset theitem = entityLoadByPK("rawMaterials", recipeItems.getrawMaterial_id().getid())>
<cfinvoke method="getPrepByDate" component="/FEcomponents.production" returnvariable="makeAmount">
<cfinvokeargument name="recipe_id" value="#ril#">
<cfinvokeargument name="delivery_date" value="#delivery_date#">
</cfinvoke>
<cfset thisRecipeYield = thisRecipe.getYield()>
<cfset thisQuantity = recipeItems.getitemQuantity()>
<cfif thisRecipeYield neq 0>
<cfset recipeRatio = makeAmount / thisRecipeYield>
<cfset thisQuantity *= recipeRatio>
</cfif>
<cfif structKeyExists(outerstruct, theitem.getid())>
<!--- we must add this quantity to the existing key, not create a new one --->
<cfset outerstruct[theitem.getid()].totalToGet += thisQuantity>
<cfelse>
<!--- create a new struct --->
<cfset outerstruct[theitem.getid()] = structnew()>
<cfset outerstruct[theitem.getid()].rawMaterialid = theitem.getid()>
<cfset outerstruct[theitem.getid()].rawMaterialName = theItem.getName()>
<cfset outerstruct[theitem.getid()].totalToGet = thisQuantity>
<cfset outerstruct[theitem.getid()].uom = theItem.getUOM().getname()>
</cfif>
</cfif>
</cfloop>

Related

Access to the path is denied Xamarin forms

I am trying to copy my db file to internal storage root/document. My codes are working good till Android 9 but after it i am getting the error "System.UnauthorizedAccessException: Access to the path "/storage/emulated/0/Documents/FruitsApp/Backup/Fruits.db_2021-06-28 12:20:20" is denied"
I have try lots of way to copy all are working before Android 9 but after it i am getting above error. I am sharing my all codes. Thanks in advance.
----copy code
Java.IO.File mediaStorageDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments) + path);
if (!mediaStorageDir.Exists())
{
var tt = mediaStorageDir.Mkdirs();
if (mediaStorageDir.Mkdirs() == false)
{
var fail = "failed to create";
}
}
var directoryPath = mediaStorageDir.AbsolutePath;
////////--this way to create folder is working till andorid 9
//var PathExists = Directory.Exists(directoryPath);
//if (PathExists ==false)
//{
// Directory.CreateDirectory(directoryPath);
//}
var dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Fruits.db");
FileInfo file = new FileInfo(dbPath);
var dbName = file.Name;
var fullFileName = string.Concat("/", dbName + "_", Global.CurrentDateTime());
var newpath = string.Format("{0}{1}", directoryPath, fullFileName);
//////--- First way copy file from source to destination is working tille android 9
//using (FileStream sourceStream = System.IO.File.Open(dbPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
//using (FileStream destinationStream = System.IO.File.Create(newpath))
//{
// sourceStream.CopyToAsync(destinationStream);
//}
//////--- 2nd way copy file from source to destination is working tille android 9
byte[] dbFile = System.IO.File.ReadAllBytes(dbPath);
System.IO.File.WriteAllBytes(newpath, dbFile);
//////--- 3rd way copy file from source to destination is working tille android 9
//file.CopyTo(newpath);
I have try 3 ways to copy file from source to another all ways are working till android 9 but not working after android 9.
--Android Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1"
android:versionName="1.0" package="com.NewWave.FruitApp" android:installLocation="auto">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="30" />
<application android:requestLegacyExternalStorage="true" android:label="FruitApp"
android:theme="#style/MainTheme"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<!--<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />-->
</manifest>
I have a SQLite database saved in the internal storage of my cellphone, in a folder created folder named SQLite. I had troubles with the permissions and the path. Here's how I solved it:
private readonly SQLiteAsyncConnection _conn;
public LocalContext()
{
// Create directory for SQLite
Directory.CreateDirectory(Path.Combine("/storage/emulated/0/","SQLite"));
string dbPath = Path.Combine(
"/storage/emulated/0/SQLite",
"ventaMovil.db");
_conn = new SQLiteAsyncConnection(dbPath);
}
Before I called my LocalContext I check if you have writing permissions:
private async Task<bool> CheckPermissions()
{
var status = await _permissionService.CheckAndRequestPermissionAsync(new Permissions.StorageWrite());
if (status != PermissionStatus.Granted)
{
await App.Current.MainPage.DisplayAlert("Error", "You do not have writing permissions", "Okay");
return false;
}
return true;
}
For the permissions I use Xamarin Essentials:
public class PermissionService : IPermissionService
{
public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission) where T : Permissions.BasePermission
{
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
}
And in the Android Manifest I have these two:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Html.Kendo().MaskedTextBox() with two length?

I have this MaskedTextBox:
<div style="direction:ltr;padding-left:20px;">
#(Html.Kendo().MaskedTextBox()
.Name("nationalityCode")
.Mask("000000000000").HtmlAttributes(new { #class = "login-input user-pass", width = "300px", placeholder = "Enter you code" })
)
</div>
My problem is NationalityCode can be 8 or 12 length , If I use above code,then in Runtime enter a code with 8 length, it will pass null to controller .

How to read Toast Notification attributes in Windows Phone 8.1?

I have created below toast notification
ToastTemplateType toastType = ToastTemplateType.ToastText02;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastType);
XmlNodeList toastTextElement = toastXml.GetElementsByTagName("text");
toastTextElement[0].AppendChild(toastXml.CreateTextNode("Hello C# Corner"));
toastTextElement[1].AppendChild(toastXml.CreateTextNode("I am poping you from a Winmdows Phone App"));
IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("duration", "long");
((XmlElement)toastNode).SetAttribute("type", "Employee");
((XmlElement)toastNode).SetAttribute("launch", "<cat state='angry'><facebite state='true' /></cat>");
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
I want to know how to access the type attribute.
When I tried with below code it's returning null
var att = toast.Content.Attributes;
Debugging shows you the answer.
var att = toast.Content.ChildNodes[0].Attributes[1].NodeValue;
var att =
toast.Content
.SelectSingleNode("/toast/visual/binding")
.SelectNodes("text")[0].InnerText

How to get inserted image in a received gmail mail

I want to get the inserted image (not image attachment) in a received Gmail mail. How is this done using Google Apps Script?
I have tried to use urlfetchapp to get the image data from the image link address:
https//mail.google.com/mail/u/0/?ui=2&ik=c348ccba97&view=att&th=13bb892c352c45dc&attid=0.2&disp=emb&realattid=ii_13bb88f3e56aae8c&zw&atsh=1
in the email html body, but can not bypass the google login page. The response content data always is login page.
Edit: While the code below works on email drafts and canned responses, it does not let you access inline images in received email.
This code snippet is from a working mail merge I have that supports inline images (both embedded blobs and external references) and attachments as well. It takes the inline images and attachments from a draft/canned response, adds them to a new email and sends it:
...
//selectedTemplate is a Gmail Message (draft/canned response)
var emailTemplate = selectedTemplate.getBody();
var attachments = selectedTemplate.getAttachments();
if(emailTemplate.search(/<\img/ != -1)){
var inlineImages = {};
var imgVars = emailTemplate.match(/<img[^>]+>/g);
for(i in imgVars){
var title = imgVars[i].match(/title="([^\"]+\")/);
if (title) {
title = title[1].substr(0, title[1].length-1);
var titleEncoded = title.replace(/ /g,"-");
for(j in attachments){
if(attachments[j].getName() == title){
inlineImages[titleEncoded] = attachments[j].copyBlob().setName(titleEncoded);
attachments.splice(j,1);
}
}
var newImg = imgVars[i].replace(/src="[^\"]+\"/,"src=\"cid:"+titleEncoded+"\"");
emailTemplate = emailTemplate.replace(imgVars[i],newImg);
}
}
}
...
GmailApp.sendEmail("test#example.com", "my subject", "my body",
{attachments: attachments,
inlineImages: inlineImages});
Hope this helps.
I don't know how you are accessing your emails, but it doesn't look like you are using the GmailApp from the Gmail service. Once you've found the email you're interested in then examine the html body to find the <img>. Either src will be a url (linked image) or a cid (embedded image) that references an attachment.
A more recent approach to solving this.
The issue
For example, here's an email body retrieved with .getBody()
<div dir="ltr"><div><img src="?view=att&th=1401f70d4881e07f&attid=0.3&disp=emb&realattid=ii_1401f6fc7824ebe1&zw&atsh=1" alt="Inline image 4" width="200" height="180"><br></div><div><br></div><img src="?view=att&th=1401f70d4881e07f&attid=0.2&disp=emb&realattid=ii_1401f6e6c1d46c4b&zw&atsh=1" alt="Inline image 2" width="200" height="65"><div><br></div><div>
jtykuykyu</div><div><br></div><div><img src="?view=att&th=1401f70d4881e07f&attid=0.1&disp=emb&realattid=ii_1401f6e9df3a4b1c&zw&atsh=1" alt="Inline image 3" width="200" height="82"><br><div><br></div><div><br></div></div></div>
And here is the list of attachments for the email (among which are our inline images):
[13-07-30 08:28:08:378 CEST] Screen Shot 2013-07-12 at 1.54.31 PM.png
[13-07-30 08:28:08:379 CEST] Screen Shot 2013-07-23 at 5.38.51 PM.png
[13-07-30 08:28:08:380 CEST] Screen Shot 2013-07-25 at 9.05.15 AM.png
[13-07-30 08:28:08:381 CEST] test2.png
As you can see, there's no link between the name of those images and the information available in the img tags, so there's no safe way to rebuild a correct email with only those information.
The solution
How to solve that ? We can use the method .getRawContent() to get the actual email and parse it to get the information we need. Specifically, this method give us a relationship between the name of an attachment and the 'realattid' available in the email body:
Content-Type: image/png; name="Screen Shot 2013-07-25 at 9.05.15 AM.png"
Content-Transfer-Encoding: base64
Content-ID:
X-Attachment-Id: ii_1401f6e9df3a4b1c
Code snippet
Here's a code snippet to:
-Retrieve the body & attachments of an email
-Get all the img tags inside the body and see which ones are linked to attachments in the email
-Get the 'realattid' of each image and use .getRawContent() to link this 'realattid' to the right attachment
-Replace the img tag to correctly link it to the right attachment
-Indicate that this attachment is no longer a simple attachment but an inline image
-Once all that is done you have all the data you need to send a copy of this email with the correct inline images displayed.
//////////////////////////////////////////////////////////////////////////////
// Get inline images and make sure they stay as inline images
//////////////////////////////////////////////////////////////////////////////
var emailTemplate = selectedTemplate.getBody();
var rawContent = selectedTemplate.getRawContent();
var attachments = selectedTemplate.getAttachments();
var regMessageId = new RegExp(selectedTemplate.getId(), "g");
if (emailTemplate.match(regMessageId) != null) {
var inlineImages = {};
var nbrOfImg = emailTemplate.match(regMessageId).length;
var imgVars = emailTemplate.match(/<img[^>]+>/g);
var imgToReplace = [];
if(imgVars != null){
for (var i = 0; i < imgVars.length; i++) {
if (imgVars[i].search(regMessageId) != -1) {
var id = imgVars[i].match(/realattid=([^&]+)&/);
if (id != null) {
var temp = rawContent.split(id[1])[1];
temp = temp.substr(temp.lastIndexOf('Content-Type'));
var imgTitle = temp.match(/name="([^"]+)"/);
if (imgTitle != null) imgToReplace.push([imgTitle[1], imgVars[i], id[1]]);
}
}
}
}
for (var i = 0; i < imgToReplace.length; i++) {
for (var j = 0; j < attachments.length; j++) {
if(attachments[j].getName() == imgToReplace[i][0]) {
inlineImages[imgToReplace[i][2]] = attachments[j].copyBlob();
attachments.splice(j, 1);
var newImg = imgToReplace[i][1].replace(/src="[^\"]+\"/, "src=\"cid:" + imgToReplace[i][2] + "\"");
emailTemplate = emailTemplate.replace(imgToReplace[i][1], newImg);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
var message = {
htmlBody: emailTemplate,
subject: selectedTemplate.getSubject(),
attachments: attachments,
inlineImages: inlineImages
}

Why does CFHTTP return I/O Exception for a file path when trying to upload an image in Coldfusion?

I'm running Coldfusion8 and have a cfc which handles image processing.
The cfc runs fine when grabbing images from external sources, putting them into a temp storage, resizing and saving to S3. I now tried to run a new set of images from manual uploads through this cfc and all of a sudden, I'm getting an error.
First I grab the image, store it in a temp directory and then invoke my img_handler:
<cffile result="temp" action="upload" accept="image/jpeg,image/jpg" filefield="Dateiname8" destination="#variables.tempDirectory#" nameconflict="overwrite" />
<cfset variables.testFilePath = variables.tempDirectory & temp.serverFile>
<!--- catch CMYK --->
<cfimage action="info" source="#variables.testFilePath#" structname="cmyk" />
<cfif cmyk.colormodel.colorspace EQ "Any of the family of CMYK color spaces">
<cfthrow type="FileNotFound" message="#tx_settings_icons_error_cymk#" />
</cfif>
<cfif structKeyExists( cookie, "resolution")>
<cfset variables.screenWidth = cookie.resolution>
<cfelse>
<cfset variables.screenWidth = "na">
</cfif>
<!--- call image handler --->
<cfinvoke component="services.form_img_handler" method="upload" returnVariable="variables.worked">
<cfinvokeargument name="cm" value="upload_background" />
<cfinvokeargument name="pt" value="#variables.tempDirectory#" />
<cfinvokeargument name="fl" value="#temp.serverFile#" />
<cfinvokeargument name="se" value="#form.app_basic_id#" />
<cfinvokeargument name="ar" value="background" />
<cfinvokeargument name="ck" value="#variables.screenWidth#" />
<cfinvokeargument name="gb" value="" />
<cfinvokeargument name="ax" value="int" />
<cfinvokeargument name="al" value="#variables.allow#" />
</cfinvoke>
This works all right. The temp image is created and stored in the temp folder. My problem is when I try to read the image in my image_handler like so:
<cfhttp timeout="500"
throwonerror="no"
url="#LOCAL.tempDirectory##LOCAL.imgFile#"
method="get"
useragent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12"
getasbinary="yes"
result="LOCAL.objGet">
This produces the following error:
catch - struct
Charset: [empty string]
ErrorDetail: I/O Exception: For input string: "\website\test\mem\secure\Innentitel.jpg"
Filecontent: Connection Failure
Header: [empty string]
Mimetype: Unable to determine MIME type of file.
Responseheader:
[struct]
Statuscode: Connection Failure. Status code unavailable.
Text: YES
I'm pretty much clueless what is happening here.
Questions
My application is running on SSL, but if I can grab the image in the first step and store it in the temp directory, why is it that I cannot pull it in from there again from my cfc. Could the problem be my upload function using access="remote" as I am also calling this function as a webservice? If so, what can I do to have my function handle both remote and regular requests?
Thanks for help!
EDIT:
To clarify, the cfinvoke in the first code block calls my cfc for handling all image uploads to Amazon S3. Inside this cfc I'm making the cfhttp call in question. Here is how I'm doing it now using cfimage, which forces me to do all my validation before calling the cfc.
<cfcomponent output="false" hint="image handler - s3 manager">
<cffunction name="Init" access="public" returntype="any" output="false" hint="Initialize">
<cfreturn true />
</cffunction>
<!--- this is the function I'm calling --->
<cffunction name="upload" access="remote" output="false" hint="creates images and stores them to S3">
<cfargument name="cm" type="string" required="true" hint="original form submitted" />
<cfargument name="pt" type="string" required="true" hint="img path" />
<cfargument name="fl" type="string" required="true" hint="img filename" />
<cfargument name="se" type="string" required="true" hint="user id" />
<cfargument name="ar" type="string" required="true" hint="item id" />
<cfargument name="ck" type="string" required="true" hint="screen width" />
<cfargument name="gb" type="string" required="true" hint="item to send back something" />
<cfargument name="ax" type="string" required="true" hint="remote call y/n" />
<cfargument name="al" type="string" required="true" hint="allowed formats or def(ault)" />
<!--- lot of setters --->
<cfscript>
var LOCAL = {};
// arguments
LOCAL.command = cm;
LOCAL.imgPath = pt;
LOCAL.imgFile = fl;
LOCAL.sellerILN = se;
LOCAL.article = ar;
LOCAL.cookie = LSParseNumber(ck);
LOCAL.getBack = gb;
LOCAL.access = ax;
LOCAL.allow = al;
// command
if ( LOCAL.command NEQ "" ) {
LOCAL.action = LOCAL.command;
} else {
LOCAL.action = "upload";
}
// allow
if ( LOCAL.allow EQ "def" ){
LOCAL.allow = "png,jpg,jpeg";
}
// s3 misc
LOCAL.letter = "";
LOCAL.objGet = "";
LOCAL.bucketPath = Session.bucketPath;
LOCAL.bucketName = Session.bucketName;
LOCAL.acl = "public-read";
LOCAL.storage = "";
LOCAL.tempDirectory = expandPath( "../somewhere/secure/" );
LOCAL.failedLoads = "";
LOCAL.altFailedLoads = "";
LOCAL.createBucket = "false";
LOCAL.errorCount = 0;
LOCAL.altErrorCount = 0;
LOCAL.cacheControl = 1;
LOCAL.contentType = "image";
LOCAL.httptimeout = "300";
LOCAL.cacheDays = "30";
LOCAL.storageClass = "REDUCED_REDUNDANCY";
LOCAL.keyName = "";
LOCAL.baseUrl = "http://www.page.com";
LOCAL.imageSrc = "";
LOCAL.testFilePath = LOCAL.imgPath & LOCAL.imgFile;
LOCAL.fileExt = ListLast(LOCAL.imgFile, ".");
LOCAL.runner = "";
LOCAL.worked = "true";
LOCAL.or = "";
LOCAL.tag = "";
// background dimes - seldomly used, so declare here
if ( LOCAL.command EQ "upload_background") {
LOCAL.dims.backW = structNew();
LOCAL.dims.backW.s = 640;
LOCAL.dims.backW.m = 800;
LOCAL.dims.backW.l = 1024;
LOCAL.dims.backW.xl = 2048;
LOCAL.dims.backH = structNew();
LOCAL.dims.backH.s = 480;
LOCAL.dims.backH.m = 600;
LOCAL.dims.backH.l = 748;
LOCAL.dims.backH.xl = 1496;
}
</cfscript>
<!--- create up to 4 versions of each image and store to S3 --->
<cftry>
<cfif LOCAL.command EQ "upload_search">
<cfif LOCAL.cookie LT 320 >
<cfset LOCAL.runner = "l,s">
<cfelseif LOCAL.cookie GTE 320 AND LOCAL.cookie LTE 767>
<cfset LOCAL.runner = "l,m">
<cfelseif LOCAL.cookie GT 768 AND LOCAL.cookie LTE 1279>
<cfset LOCAL.runner = "xl,m">
<cfelseif LOCAL.cookie GT 1280>
<cfset LOCAL.runner = "xl,l">
</cfif>
<cfelseif LOCAL.command EQ "upload_import" OR LOCAL.command EQ "upload_background" OR LOCAL.command EQ "remove_background">
<cfset LOCAL.runner = "xl,l,m,s">
</cfif>
<!--- get image --->
<cfimage action="read" name="LOCAL.objGet" source="#LOCAL.tempDirectory##LOCAL.imgFile#">
<!--- I/O Exception: peer not authenticated...
<cfhttp timeout="500"
throwonerror="no"
url="https://www.website.com/test/mem/img/secure/#LOCAL.imgFile#"
method="get"
useragent="Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12"
getasbinary="yes"
result="LOCAL.objGet">
--->
So I'm now using cfimage to retrieve the image from the temp folder, which works fine vs. cfhttp. I had my image validation routine after the cfhttp call, which I now moved to outside of the cfc call. Not sure this is better/smarter, but at least it's working now.
cfhttp requires full URLs with protocol. A cursory glance at the error messages states ErrorDetail: I/O Exception: For input string: "\website\test\mem\secure\Innentitel.jpg".
If you convert it to a URL with protocol does it work?

Resources