I want my application to be cross-platform and create a directory inside the users documents folder. I get that from QStandardPaths.
When creating a QUrl from that String it becomes c/path/to/documents/ instead of the desired c:/path/to/documents.
When you are creating QUrl the string before ":" is interpreted as URL protocol. To create one that point to local file, you should use fromLocalFile static method:
qDebug() << QUrl::fromLocalFile("c:\\path\\to\\documents");
This code will print the correct URL starting with file protocol prefix:
QUrl("file:///C:/path/to/documents")
You also have isLocalFile and toLocalFile methods.
Related
For integrating with a android binding project I need to provide a Uri pointing to a .zip file, which I have included in the assets and designated as AndroidAsset. How do I get the Uri for such a file?
I already tried ms-appx:///Assets/file.zip and file:///Assets/file.zip
Update:
Import to note is, that the function consuming the Uri is Android native code, so I suspect that ms-appx:// doesn't get resolved properly.
Update2:
It is not possible to provide a stream.
The method I am calling is shown in the sample here: https://github.com/Laerdal/Xamarin.Nordic.DFU.Android/blob/7244627c09e97e05ee2c8e05744f19055981486b/Sample/Nordic/FirmwareUpdater.cs#L27.
_dfuServiceInitiator.SetZip(firmwareZipFile);
The native implementation is shown here: https://github.com/NordicSemiconductor/Android-DFU-Library/blob/07bdaa50cfc5786790bf1ac589b14931de65d099/dfu/src/main/java/no/nordicsemi/android/dfu/DfuServiceInitiator.java#L620
public DfuServiceInitiator setZip(#NonNull final Uri uri) {
return init(uri, null, 0, DfuBaseService.TYPE_AUTO, DfuBaseService.MIME_TYPE_ZIP);
}
Files read from the StorageFile.GetFileFromApplicationUriAsync() method may not return a stable path on UWP, and this is particularly the case on particularly on Android or WebAssembly, where the file is not necessarily on the file system.
On Android, the file is a Stream directly built from the APK file, and on WebAssembly it is stored in a temporary location.
In order to use keep a stable copy of the file, use the following:
var file = await StorageFile.GetFileFromApplicationUriAsync(new System.Uri("ms-appx:///TextFile.txt"));
var newFile = await file.CopyAsync(Windows.Storage.ApplicationData.Current.LocalFolder, file.Name, NameCollisionOption.ReplaceExisting);
var txt = await FileIO.ReadTextAsync(newFile);
The method StorageFile.GetFileFromApplicationUriAsync can be used to get a StorageFile object from an ms-appx Uri.
Then you can use the Path property of the StoragFile to get the local android path. Make note to set the build action of the file as Content.
var file = await StorageFile.GetFileFromApplicationUriAsync(new System.Uri("ms-appx:///Assets/file.zip"));
Android.Net.Uri zipUri = Android.Net.Uri.Parse("file:///"+file.Path);
I am using java to get a json file through URL, in the web browser it works but from my java code:
//I have used also timer:foo?period=5000 but not working
from("direct:start")
.multicast()
.to("http://" + URL)
.to("file:" + path + "&fileName=report");
Even if it does not display errors, camel does not create the file "report".
Any sugestion?
Thank you in advance.
Not sure I fully understand your goal, but it looks like you are trying to call a rest endpoint for a json response and then write that response to a file. In your example above camel is trying to write a file and call the http endpoint with the same message instead of getting a response from the http endpoint, then writing it to your report file. You can also update your timer to have the fixedRate property equal to true to keep calling.
You can do something like:
from("timer:foo?fixedRate=true&period=5000")
.to("http://" + URL)
.log("my response: ${body}")
.to("file:" + path + "&fileName=report");
.NET 4.0 and this is a shell extension
when a file is selected my context menu handler get the mapped drive path but I need the UNC path for reasons too long to explain. Is there a way to get the UNC path from a mapped drive. Alternatively can I enumerate all mapped drives and what they map to so that based on the drive letter I can look up this information
You can use the WNetGetConnection() function to convert from a mapped drive letter to the UNC path.
I can't help you with .NET sorry (which you should be careful about writing shell extensions using) but in C++,
LPCWSTR pszPath = L"M:\\"; // mapped drive
if (GetDriveType(pszPath) == DRIVE_REMOTE)
{
// WNetGetConnection needs drive letter WITHOUT trailing backslash
wchar_t wchDrive[3] = { pszPath[0], pszPath[1], L'\0' };
wchar_t wchUNC[MAX_PATH];
DWORD dwLength = _countof(wchUNC);
if (WNetGetConnection(wchDrive, wchUNC, &dwLength) == NO_ERROR)
{
// do something with wchUNC
}
}
I'm using QT 5.0.2 prebuilt and QT creator 2.7.0 and my goal is to login to steam network programmatically using uname, password and steamguard code. Or to be more precise: get QNetworkAccessManager from its initial uninitialized state to the state where it could retrieve any data from steam related sites as if it was logged in as some user.
So the login happens in 4 steps (4 request-response combos):
NOTE: Steam site javascript uses post in all requests, but it seems that get also works.
Assume username "hyper"
1. Initial request:
post https://store.steampowered.com/login/getrsakey/?username=hyper
Here is my function:
void http::steam_auth(const QString &uname, const QString &pwd)
{
QString encrypted_password, sg, pkey_exp, pkey_mod, timestamp, emailsteamid;
QJsonDocument json_buffer;
QByteArray buffer;
QUrl rsa(steam_getrsa), login(steam_dologin); //steam login urls
QUrlQuery urlquery;
Here we send our request:
urlquery.addQueryItem("username", uname); //first step
urlquery.addQueryItem("l", "english"); //set communication language
rsa.setQuery(urlquery);
QNetworkRequest first(rsa);
QNetworkReply *reply = this->get(first);
buffer = reply->readAll();
As a response we get:
{"success":true,"publickey_mod":"AC41A964789638B6A3B3BD5ADD9F3680FA45881C70FD2032B10A3BB6D2ACF021C2B3D564DC44DE3054E3BF78A1753399223C794A0DED03A76CD1F1DFE851E30F0D6F14484C258EB6053676A47D20A68E11ECCD783F343594DDA3817AA5DCCE75FAF5C68BB197DA1FF12F22F9FCD83624D00A23CC57A367563ADBBCEDF5C8742A57B12A4BD04DC02A55C80F4F6984B1E2D5A99081510326E1C6BAB2C2723560487E8F7EA1A2CB55AEFC5594C9FBB71CAD553CB2D866214BC41156259FEC55362D38DCDBE8FADFB577FE0736CE3E37AF6D2CDDF28FA218C1E477E29B17713BFC48A227455B6B0DE09884CC0820CE40CD4877D93704D00E20A235FCF55D100A01C1","publickey_exp":"010001","timestamp":"284691100000"}
Which means everything is ok.
Now we need to encrypt our password before sending it
json_buffer = QJsonDocument::fromJson(buffer);
pkey_exp = json_buffer.object().value("publickey_exp").toString();
pkey_mod = json_buffer.object().value("publickey_mod").toString();
timestamp = json_buffer.object().value("timestamp").toString();
delete reply;
urlquery.clear();
encrypted_password = app::core::get_encrypted_password(pwd, pkey_exp, pkey_mod);
2. Send encrypted password:
urlquery.addQueryItem("username", uname);
urlquery.addQueryItem("password", encrypted_password);
urlquery.addQueryItem("emailauth", "");
urlquery.addQueryItem("captchagid", "");
urlquery.addQueryItem("captcha_text", "");
urlquery.addQueryItem("emailsteamid", "");
urlquery.addQueryItem("rsatimestamp", timestamp);
urlquery.addQueryItem("remember_login", "false");
login.setQuery(urlquery);
QNetworkRequest second(login);
second.setUrl(login);
reply = this->get(second);
buffer = reply->readAll();
We get a request string as follows:
post https://store.steampowered.com/login/dologin/?username=solidbeetle2&password=YmhTKVkRXyiCYe6wx+ZJ8PIhzj4A4BLWgJFOE5ge7nbIAM6m1G9qHh+Iqx30ZLdB0wW0xdWDNCgHBNPHKLA+P2pYhPF0DeL9v8UQsers6NCNNPZ0SFN4HhNlu6Gwh8QAjrNykev7N5FADXwJnFjPBvmvthATmrktVEtFYF54lckaPnijXYSDIpfEjmG8+bCDKT/GLaUiftA2QauUY9ap8WHSEoykiTmfL344ghzjhCA33UKx0NIgBrDdI1RLfHVcmAcU/c9NEhoHLOT93n8hqWY+YVx9VbOcKqqZPrbCiQoU2BZrqK6N7aj+K6kH0VWHH7+LD2KJx4BUJgHOmNqVDg%3D%3D&emailauth=&captchagid=&captcha_text=&emailsteamid=&rsatimestamp=50693150000&remember_login=false
It is perfectly valid as far as I can tell, JS on steam site sends ajax with the same, but...
Here is the problem
When I get a response with this it says message:Invalid login in json... But if I save the full query string from my request to file and then paste it either in browser or in HTTP Request builder inside HTTP Analyzer, it works fine displaying message:SteamGuard
What could be wrong? Is there something I'm missing? Does QNetworkAccessManager break this somehow?:c
Sorry if something is not clear, I'll try my best to explain again if needed.
Thanks in advance!
P.S. Is there any solid way to examine requests my app is sending?
P.S.S. my qt creator seems to crash when debugging projects with qml option, idk why...
I have inspected all this stuff and finally was able to achieve my goal.
In short the problem was in qt's web-oriented classes. It seemed obvious that qurlquery should encode characters such as / or = in their %-encoded form.. but it is NOT the case, therefore I had to replace them manually in QString. If someone needs a working routine, it can be found here (Its not pretty :c)
I am trying to upload a file to a FTP server, which is a local server created by vsftpd. I have set necessary parameters needed for connecting and transferring files in the vsftpd.conf file. My requirement is to upload a file to this server. When i logged statechanged messages, HostLookup, Connecting, Connected, Logged in, closing, and Unconnected messages were emitted by my ftp object. But when i check in the destination directory the file is there but of 0 size...What could be wrong? following is the code I used...
QImage img("./Sample.jpg");
QBuffer* buf = new QBuffer();
buf->open(QBuffer::ReadWrite);
buf->seek(0);
img.save(buf, "jpg");
connection = new QFtp();
connection->connectToHost("localhost");
connection->login();
connection->cd("ftpshare/");
connection->put(buf, "Sample.jpg", QFtp::Binary);
qDebug(QString::number(connection->error()).toLatin1());
qDebug(connection->errorString().toLatin1());
connect(connection,SIGNAL(stateChanged(int)),this,SLOT(ftpstatechanged(int)));
connection->close();
Are you sure the first line of finds the Sample.jpg in the folder it is looking in? Maybe the working directory is not what you think it is. Otherwise this should work just fine.
The problem was with usage of buffer. It got solved when I used QByteArray instead.
QImage img("./Sample.png");
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "PNG");
connection = new QFtp();
connection->connectToHost("localhost");
connection->login();
connection->cd("ftpshare/");
connection->put(ba, "Sample.png", QFtp::Binary);