How to upload the Image to server in blackberry 10 cascades? - qml

I have tried the following code for image uploading,in this code am able to get the response from server but the image size is always zero in server.Can anyone help me about this regards,
void App::uploadImage(){
QString path(QDir::currentPath() + "/app/native/assets/Icon/img.jpg");
QNetworkRequest request(
QUrl( "http://domain.com?type=uploadimages&deviceid=12323"));
QByteArray boundary = "-------------------------32142544626177";
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "error read image";
return;
}
QByteArray fileContent(file.readAll());
QByteArray data = "--" + boundary + "\r\n";
data +=
"Content-Disposition: form-data; name=\"data\"; filename=\"img.jpg\";\r\n";
data += "Content-Type: image/jpg\r\n\r\n" + fileContent + "\r\n";
data += "--" + boundary + "--\r\n";
request.setRawHeader("Content-Type",
"multipart/form-data; boundary=" + boundary);
request.setRawHeader("Content-Length",
QString::number(data.size()).toAscii());
file.close();
qDebug() << "data" << data.size();
QNetworkAccessManager *am = new QNetworkAccessManager(this);
QNetworkReply *reply = am->post(request, "&data=" +data);
QObject::connect(am, SIGNAL(finished(QNetworkReply*)), this,
SLOT(replyFinished(QNetworkReply*)));
}
void App::replyFinished(QNetworkReply* reply) {
reply->open(QIODevice::ReadOnly);
if (reply->error() == QNetworkReply::NoError) {
QByteArray str = (reply->readAll());
QString response = QString::fromUtf8(str.data(), str.size());
qDebug() << " response " << response;
}
else{
qDebug() << "error response server";
}
}

QString body = "" ;
const QUrl url("http://someurl.to/make/the/post" );
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPartData;
body = "" ;
QTextStream(&body) << "";
textPartData.setHeader(QNetworkRequest::ContentTypeHeader, "application/json; charset=utf-8");
textPartData.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"data\""));
textPartData.setBody(body.toAscii());
for(int i=0; i< number_of_files_to_send ; i++){
QHttpPart imagePart;
QString header_body = "";
QTextStream(&header_body) << "form-data; name=\"" << name_of_the_file << "\"; filename=\"" << name_of_the_file << ".jpg\"" ;
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(header_body));
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
//prepare file for upload
QString filepath;
QTextStream(&filepath) << FunkyPigeonBlackberry::getInstance()->dataModelProductDetails()->custom_image(i).value("cut_image").toString();
// pack the new file
QFile *file = new QFile(filepath);
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(imagePart);
}
multiPart->append(textPartData);
multiPart->append(textPartProductDetails);
multiPart->append(textPartDataDelivery);
QNetworkRequest request(url);
QNetworkReply* reply = m_networkAccessManager->post(request, multiPart);
connect(reply, SIGNAL(finished()), this, SLOT(onNetworkResponse()));

Related

yaml-cpp always creates a scalar node with size 0

I'd like to use yaml-cpp for storeing some config-values. In order to get in touch with yaml-cpp, I've written a method which creates a node (_config is from Type YAML::Node), put some values in it and write it into a file:
void write_config()
{
std::ofstream fout("/home/user/config.yaml");
_config["Foo"]["0"] = "0";
_config["Foo"]["1"] = "1";
_config["Foo"]["2"] = "2";
_config["Foo"]["3"] = "3";
_config["Foo"]["4"] = "4";
_config["Foo"]["5"] = "5";
fout << _config;
}
after running this Method, a valid yaml file is created:
Foo:
1: 1
3: 3
0: 0
5: 5
4: 4
2: 2
After that, I have created a Method to read the file and print some information:
void load_config()
{
_config = YAML::Node("/home/user/config.yaml");
cout << "_config: " << _config << endl;
cout << "doc.Type(): " << _config.Type() << "\n";
cout << "doc.size(): " << _config.size() << "\n";
for (const auto& kv : _config)
{
std::cout << kv.first.as<std::string>() << "\n"; // prints Foo
std::cout << kv.second.as<std::string>() << "\n"; // prints Foo
}
}
but the output is:
_config: /home/user/config.yaml
doc.Type(): 2
doc.size(): 0
could someone tell me why the Node is empty (size == 0) and how I can read the file properly?
Thank you in advance!
I've found my Mistake...
_config = YAML::Node("/home/user/config.yaml");
should be
_config = YAML::LoadFile("/home/user/config.yaml");

using AE.Net.Mail how to send mail with image inline

I using AE.Net.Mail in .net project.
I sent html mail and file attachment by gmail api and it work perfect.
But i dont know way to embed an image in body mail with it?
Somebody help me ?
string To = txtTo.Text;
string Subject = txtEmailSubject.Text;
string Body = hdfEmailContentSend.Value;
string InputAttachmentArr = hdfInputAttachmentArr.Value;
var msg = new AE.Net.Mail.MailMessage();
msg.From = new MailAddress("haunguyen1791990#gmail.com", "=?UTF-8?B?" + EncodeTo64UTF8(User.FullName) + "?=");
msg.ReplyTo.Add(msg.From);
msg.To.Add(new MailAddress(To));
msg.Subject = "=?UTF-8?B?" + EncodeTo64UTF8(Subject) + "?=";
msg.Body = Body;
var result = SendMessage(InputAttachmentArr, msg, "");
private Google.Apis.Gmail.v1.Data.Message SendMessage(string InputAttachmentArr, AE.Net.Mail.MailMessage msg, string ThreadId) {
try {
bool isAttackFile = false;
string boundary = "boundary_" + DateTime.Now.ToString("yyyyMMddHHmmss");
var service = CRMGmailUtils.DefineServiceGet(Server.MapPath(".") + "\\client_secret.json");
//get info file attachment
List<string> lstAttachFile = InputAttachmentArr.Split(',').ToList();
lstAttachFile.RemoveAll(item => item.Length == 0);
foreach (var item in lstAttachFile) {
string filePath = Server.MapPath("~/" + "Upload/gmail/" + item);
var bytes = File.ReadAllBytes(filePath);
AE.Net.Mail.Attachment file = new AE.Net.Mail.Attachment(bytes, GetMimeType(item), item, true);
msg.Attachments.Add(file);
isAttackFile = true;
}
var msgStr = new StringWriter();
//if file attachment not exists, set type mail is html
if (!isAttackFile) {
msg.ContentType = "text/html";
}
msg.Save(msgStr);
string data = msgStr.ToString();
//else i customize body mail with new boundary
if (isAttackFile) {
string beginBody = "Content-Type: multipart/alternative; boundary=" + boundary;
//beginBody += "\n\n--" + boundary;
//beginBody += "\nContent-Type: text/plain; charset=UTF-8";
//beginBody += "\n\n*2*";
beginBody += "\n\n--" + boundary;
beginBody += "\nContent-Type: text/html; charset=UTF-8";
string endBody = "\n\n--" + boundary + "--";
msg.Body += endBody;
string parentBoundary = Regex.Match(data, #"----(.*?)--").Groups[1].Value;
Regex rgx = new Regex("----" + parentBoundary);
data = rgx.Replace(data, "----" + parentBoundary + "\n" + beginBody, 1);
}
string raw = Base64UrlEncode(data.ToString());
var result = new Google.Apis.Gmail.v1.Data.Message();
//case send with reply
if (!string.IsNullOrEmpty(ThreadId)) {
result = service.Users.Messages.Send(new Google.Apis.Gmail.v1.Data.Message { Raw = raw, ThreadId = ThreadId }, "me").Execute();
} else {
//case send new mail
result = service.Users.Messages.Send(new Google.Apis.Gmail.v1.Data.Message { Raw = raw }, "me").Execute();
}
DeleteAttackFile(lstAttachFile);
return result;
} catch (Exception objEx) {
throw objEx;
}
}

how to utf-8 encode the file name with uploading the file content in multi part post

Having uploading file working fine except when the file name is double byte.
The code snippet below shows a possible place to do the file name encoding, but not sure if it is right, or where is the right place to apply "charset=utf-8". Any help is appreciated.
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
DataInputStream inputStream = null;
String urlString = WebApiConstants.getInstance().getBaseURL();
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "--BoundaryStringUsingCurrentTime”+currentTimeMillis();
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
try {
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
List<BasicNameValuePair> headers = getHeaderNameValuePairs();
for (BasicNameValuePair hdr : headers) {
connection.setRequestProperty(hdr.getName(), hdr.getValue());
}
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"requests\"" + lineEnd);
outputStream.writeBytes("Content-Type: application/json" + lineEnd + lineEnd);
outputStream.writeBytes(getJsonDataString(attachment.getMessageId()));
outputStream.writeBytes(lineEnd + twoHyphens + boundary + lineEnd);
/* ???
// could encode the fail name and put in, not sure if it is right?
String fileNameUtf8 = URLEncoder.encode(fileName, "UTF-8");
outputStream.writeBytes("Content-Disposition: form-data; name=\"file0\";filename=\""
+ fileNameUtf8 + "\"" + lineEnd);
*/
outputStream.writeBytes("Content-Disposition: form-data; name=\"file0\";filename=\""
+ fileName + "\"" + lineEnd);
outputStream.writeBytes("Content-Type: " + mimeType + lineEnd + lineEnd);
FileInputStream fileInputStream = new FileInputStream(new File(pathToFile));
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
… … …
… … …
You can encode the filename like this:
final private static String hexStr = "0123456789ABCDEF";
private static String MimeEncodeQP(String s)
{
byte[] bytes = s.getBytes("UTF-8");
StringBuilder output = new StringBuilder(12 + (bytes.length * 3));
output.append("=?UTF-8?Q?");
for ( final byte b : bytes )
{
if( b == 32 )
{
output.append('_');
}
else if( ((b >= 33) && (b <= 60)) ||
((b >= 62) && (b <= 126)) )
{
output.append((char) b);
}
else
{
output.append('=')
.append(hexStr.charAt((b & 0xF0) >> 4)
.append(hexStr.charAt(b & 0x0F));
}
}
output.append("?=");
return output.toString();
}
outputStream.writeBytes("Content-Disposition: form-data; name=\"file0\";filename=\"" + MimeEncodeQP(fileName) + "\"" + lineEnd);
Read the following specs for more details:
RFC 2045 "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", Section 67 "Quoted-Printable Content-Transfer-Encoding"
RFC 2047 "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text"
RFC 7578 "Returning Values from Forms: multipart/form-data", Section 5.1 "Non-ASCII Field Names and Values".
HTML4, Section 17.13.4.2 "multipart/form-data"
HTML5, Section 4.10.22.7 "Multipart form data"

How to get detailed error message when QTWebKit fails to load a page?

QtWebKit calls QWebPage::loadFinished ( false ) when a web page failed to load - but gives no clue as to why it failed.
How do I get a detailed error message, like HTTP response code or other message?
It turns out there are a couple ways to get more detail about failures:
Implement the onResourceRequested and onResourceReceived callbacks on page:
page.onResourceRequested = function (resource) {
log('resource requested: ' + resource.url);
}
page.onResourceReceived = function (resource) {
log('resource received: ' + resource.status + ' ' + resource.statusText + ' ' +
resource.contentType + ' ' + resource.url);
}
If you are looking for more detail still, you need to patch PhantomJS internals. Update its CustomPage object (in WebPage.cpp) to implement QTWebKit's ErrorExtension. Here is code you can add that does that:
protected:
bool supportsExtension(Extension extension) const {
if (extension == QWebPage::ErrorPageExtension)
{
return true;
}
return false;
}
bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0)
{
if (extension != QWebPage::ErrorPageExtension)
return false;
ErrorPageExtensionOption *errorOption = (ErrorPageExtensionOption*) option;
std::cerr << "Error loading " << qPrintable(errorOption->url.toString()) << std::endl;
if(errorOption->domain == QWebPage::QtNetwork)
std::cerr << "Network error (" << errorOption->error << "): ";
else if(errorOption->domain == QWebPage::Http)
std::cerr << "HTTP error (" << errorOption->error << "): ";
else if(errorOption->domain == QWebPage::WebKit)
std::cerr << "WebKit error (" << errorOption->error << "): ";
std::cerr << qPrintable(errorOption->errorString) << std::endl;
return false;
}
This will give you most of the error information, but you can still get onLoadFinished(success=false) events without getting more detail. From my research, the primary cause of those is canceled load requests. QTWebKit sends a fail notification for cancellations, but doesn't report any detail.

Issue Parsing File with YAML-CPP

In the following code, I'm having some sort of issue getting my .yaml file parsed using parser.GetNextDocument(doc);. After much gross debugging, I've found that the (main) issue here is that my for loop is not running, due to doc.size() == 0; What am I doing wrong?
void
BookView::load()
{
aBook.clear();
QString fileName =
QFileDialog::getOpenFileName(this, tr("Load Address Book"),
"", tr("Address Book (*.yaml);;All Files (*)"));
if(fileName.isEmpty())
{
return;
}
else
{
try
{
std::ifstream fin(fileName.toStdString().c_str());
YAML::Parser parser(fin);
YAML::Node doc;
std::map< std::string, std::string > entry;
parser.GetNextDocument(doc);
std::cout << doc.size();
for( YAML::Iterator it = doc.begin(); it != doc.end(); it++ )
{
*it >> entry;
aBook.push_back(entry);
}
}
catch(YAML::ParserException &e)
{
std::cout << "YAML Exception caught: "
<< e.what()
<< std::endl;
}
}
updateLayout( Navigating );
}
The .yaml file being read was generated using yaml-cpp, so I assume it is correctly formed YAML, but just in case, here's the file anyways.
^#^#^#\230---
-
address: ******************
comment: None.
email: andrew(dot)levenson(at)gmail(dot)com
name: Andrew Levenson
phone: **********^#
Edit: By request, the emitting code:
void
BookView::save()
{
QString fileName =
QFileDialog::getSaveFileName(this, tr("Save Address Book"), "",
tr("Address Book (*.yaml);;All Files (*)"));
if (fileName.isEmpty())
{
return;
}
else
{
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this, tr("Unable to open file"),
file.errorString());
return;
}
std::vector< std::map< std::string, std::string > >::iterator itr;
std::map< std::string, std::string >::iterator mItr;
YAML::Emitter yaml;
yaml << YAML::BeginSeq;
for( itr = aBook.begin(); itr < aBook.end(); itr++ )
{
yaml << YAML::BeginMap;
for( mItr = (*itr).begin(); mItr != (*itr).end(); mItr++ )
{
yaml << YAML::Key << (*mItr).first << YAML::Value << (*mItr).second;
}
yaml << YAML::EndMap;
}
yaml << YAML::EndSeq;
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_5);
out << yaml.c_str();
}
}
Along the lines of what you thought, the problem is that you're writing using QDataStream but reading using plain std::ifstream. You need to do either one or the other.
If you want to use the QDataStream, you'll need to read it in as well. Check out the doc for more detail, but it looks like you can just grab the YAML string:
QDataStream in(&file);
QString str;
in >> str;
and then pass it to yaml-cpp:
std::stringstream stream; // remember to include <sstream>
stream << str; // or str.toStdString() - I'm not sure about how QString works
YAML::Parser parser(stream);
// etc.
The point of a std::stringstream is to transform your string containing YAML into a stream that the YAML parser can read.