Qt QWebView class custom User-Agent - qt

Is there an easy way to setup the User-Agent the QWebView class is using?
The only relevant link I found searching was this
http://www.qtforum.org/article/27073/how-to-set-user-agent-in-qwebview.html
I'm learning C++/Qt right now and I don't really understant what's explained on that website. Maybe someone knows an easy way to do it? Or can help me understand that code?

Qt allows you to provide a user agent based on the URL rather than a single user agent no matter what the URL is. The idea then is to return the user agent any time a new webpage is created:
class UserAgentWebPage : public QWebPage {
QString userAgentForUrl(const QUrl &url ) const {
return QString("My User Agent");
}
};
In order to use that page instead of the standard page that is created, you can set that page on the browser control object before making the request:
yourWebView->setPage(new UserAgentWebPage(parent));
I would actually expect a factory to be present somewhere that will guarantee that the webpage created is always of a certain type, but I didn't see one.
Yet another option should be to set the user agent header within the QNetworkRequest:
QNetworkRequest request = new QNetworkRequest();
request->setRawHeader(
QString("User-Agent").toAscii(),
QString("Your User Agent").toAscii()
);
// ... set the URL, etc.
yourWebView->load(request);
You would actually want to check whether it's toAscii() or toUtf8() or one of the other variants as I'm not sure exactly what the HTTP standard allows.

simply,
class myWebPage : public QWebPage
{
virtual QString userAgentForUrl(const QUrl& url) const {
return "your user agent";
}
};
//Attention here is new myWebPage() not new myWebPage(parent)
UI->webView->setPage(new myWebPage());

Related

Adding type to a document uploaded in Alfresco through behaviour

I am trying to associate a document type to xz:xylo, whenever a document is uploaded in a particular workspace of Alfresco, it should get attached to a type which I defined in xylomodel.xml.
I am trying to achieve this via Alfresco behaviour as procceding via Share has some limitation for my requirement.
Can anyone please correct me if the code attached is syntactically correct and I am approaching correctly.
enter code here
public class ApplyXyloAspect implements NodeServicePolicies.OnCreateNodePolicy {`
private NodeService nodeService;
private PolicyComponent policyComponent;
// Behaviours
private Behaviour onCreateNode;
}
/**
^When a document of type #XyloCmsType(name = "X:xz:Xylo") is created than aspects from xyloModel.xml
^needs to be applied
*/
public void init() {
// Create behaviours
if workspace=workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg
org.alfresco.repo.node.NodeServicePolicies this.onCreateNode = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT);
// Bind behaviours to node policies
this.policyComponent.bindClassBehaviour(Qname.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
Qname.createQName(XYLO.NAMESPACE_XYLO_CONTENT_MODEL, XYLO.TYPE_xz_xyloModel),
this.onCreateNode
);
}
Depending on your requirements you might be better off achieving this through Folder Rules.
If folder rules are not adequate, or if I'm misunderstanding your use of the very specific NodeRef of workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg then I would just check in the onCreateNode method if the created node's parent matches that NodeRef, rather than trying to check in the init method.
so in your init method you would just do something like this:
this.onCreateNode = new JavaBehaviour(this, "onCreateNode", Behaviour.NotificationFrequency.FIRST_EVENT);
this.policyComponent.bindClassBehaviour(NodeServicePolicies.OnCreateNodePolicy.QNAME, Qname.createQName(XYLO.NAMESPACE_XYLO_CONTENT_MODEL, XYLO.TYPE_xz_xyloModel), this.onCreateNode);
And then just check if the node is a child of the node you're trying to have be the parent, in this case you said it would be workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg.
So the onCreateNode method would look something like this.
#Override
public void onCreateNode(ChildAssociationRef childAssociationRef){
NodeRef idealParentNodeRef = new NodeRef("workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg");
NodeRef nodeRef = childAssociationRef.getChildRef();
NodeRef parentRef = childAssociationRef.getParentRef();
//First double check and make sure all the nodes exist.
if(nodeService.exists(nodeRef) && nodeService.exists(parentRef) && nodeService.exists(idealParentNodeRef)){
//then check if the parentRef and the idealParentNodeRef match
if(parentRef.equals(idealParentNodeRef)){
nodeService.addAspect(nodeRef, /*QName of the Aspect you want to add*/);
}
}
}
If you know for a fact the node/workspace you're uploading to will be very specific every time you could just do this, though I would probably also suggest throwing in some error handling, logging, etc. but this would get you started at least.
Note that, generally, you shouldn't necessarily expect the NodeRef to stay the same every time, granted, I'm just showing you what you could do based on the information from your post rather than what you should do (which would be finding some other way to reference the NodeRef/workspace you're trying to use, and going on from there, depending on whether that NodeRef/workspace is a Folder or Site, or something else).
Hope this helps.

QtWebkit custom dns setting without system settings

I want to change my dns for every one of my request for some reasons! I work with Qt 5.3 and QtWebkit! I do search but i can not find anything that can help me!
Actually QDnsLookup can't force QtWebkit to set its load() function to use specific look up and it use the system Dns setting at the end!
Any idea?!
Create you own QNAM subclass and QWebPage subclass. Implement you DNS resolver there. Then set it for each QWebPage you create. This way you will get full network control of what happens in WebKit.
To be sure all WebPages will get your QNAM, subclass QWebView too and set your QWebPage subclass as page in constructor. Also overload createWindow function so all new QWebView pages(like popups) will be created as your QWebView subclass.
YourWebView::YourWebView(QWidget *parent):QWebView(parent)
{
this->setPage(new YourWebPageSubclass());
...
QWebView * YourWebView::createWindow(QWebPage::WebWindowType type)
{
YourWebView * view = Q_NULLPTR;
switch(type)
{
case QWebPage::WebBrowserWindow:
view = new YourWebView(0);
break;
case QWebPage::WebModalDialog:
view = new YourWebView(0);
view->setWindowModality(Qt::ApplicationModal);
break;
}
return view;
}
YourWebPageSubclass::YourWebPageSubclass(QObject *parent):QWebPage(parent)
{
this->setNetworkAccessManager(new YourQNAM(this));
...

Umbraco and dynamic URL content at root level

I need to port a website to asp.net and decided to use Umbraco as the underlying CMS.
The issue I'm having is I need to retain the URL structure of the current site.
The current URL template looks like the following
domain.com/{brand}/{product}
This is hard to make a route for since it mixes in with all the other content on the site. Like domain.com/foo/bar which is not a brand or product.
I've coded up a IContentFinder, and injected it into the Umbraco pipeline, that check the URL structure and determins if domain.com/{brand} matches any of the known brands on the site, in which case i find the content by its internal route domain.com/products/ and pass along {brand}/{model} as HttpContext Items and return it using the IContentFinder.
This works, but it also means no MVC controller is called. So now I'm left with fetching from the database in the cshtml file which is not so pretty and kind of breaks MVC conventions.
What i really wan't is to take the url domain.com/{brand}/{product} and rewrite it to domain.com/products/{brand}/{product} and then being able to hit a ProductsController serving up the content based on the parameters brand and product.
There are a couple of ways to do this.
It depends a bit on your content setup. If your products exist as pages in Umbraco, then I think you are on the right path.
In your content finder, remember to set the page you've found on the request like this request.PublishedContent = content;
Then you can take advantage of Route Hijacking to add a ProductController that will get called for that request: https://our.umbraco.org/Documentation/Reference/Routing/custom-controllers
Example implementation:
protected bool TryFindContent(PublishedContentRequest docReq, string docType)
{
var segments = docReq.Uri.GetAbsolutePathDecoded().Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
string[] exceptLast = segments.Take(segments.Length - 1).ToArray();
string toMatch = string.Format("/{0}", string.Join("/", exceptLast));
var found = docReq.RoutingContext.UmbracoContext.ContentCache.GetByRoute(toMatch);
if (found != null && found.DocumentTypeAlias == docType)
{
docReq.PublishedContent = found;
return true;
}
return false;
}
public class ProductContentFinder : DoctypeContentFinderBase
{
public override bool TryFindContent(PublishedContentRequest contentRequest)
{
// The "productPage" here is the alias of your documenttype
return TryFindContent(contentRequest, "productPage");
}
}
public class ProductPageController : RenderMvcController {}
In the example the document type has an alias of "productPage". That means that the controller needs to be named exactly "ProductPageController" and inherit the RenderMvcController.
Notice that it does not matter what the actual pages name is.

Handling errors in QWebView / QWebPage

I wish to get more information than just success = false in loadFinished (this is most often just a canceled load). From the documentation and other posts on this site, I gathered I should subclass QWebPage and override the extension() method to handle the ErrorPageExtension.
However, I'm not getting it to work, i.e., no matter what I try my extension method does not get called. I'm probably doing something really stupid but not seeing it. Basically my class looks like this:
class MyWebPage : public QWebPage
{
Q_OBJECT
public:
MyWebPage(QObject* parent = 0) : QWebPage(parent) {}
virtual bool extension(Extension extension,
const ExtensionOption* option = 0,
ExtensionReturn* output = 0)
{
// blah
}
virtual bool supportsExtension(Extension extension)
{
// blah
}
};
The implementation of the methods is not the problem, I have a breakpoint there and it never gets called. I create an instance like
MyWebPage* page = new MyWebPage(this);
mUi.WebView->setPage(page);
I'm a bit uncertain about the life time of a QWebPage object in QWebView, but from my tests it seems the QWebPage always remains the same instance and simply loads new content. So I assumed I should simply give my page to the QWebView, I didn't see another way to make it use my derived class. But when loading bogus URLs, non-existing local files, or unsupported content, either via the WebView or directly via the mainframe of the page, I never get the call with ErrorPageExtension information.
Any help is appreciated. This is using Qt 4.8.2.
There is a bit mistake:
...
virtual bool supportsExtension(Extension extension) const // const!!!
{
return QWebPage::ErrorPageExtension === extension;
}
...
You forgot to copy the const modifier.

Using ASP.net membership to get aspnet_Users in silverlight

Hope somebody can help.
Have looked around on the net but cannot seem to solve (or understand) this.
I have tried the code posted at
http://blogs.msdn.com/b/kylemc/archive/2010/05/10/using-asp-net-membership-in-silverlight.aspx
(not going to repeat the class MembershipServiceUser here as it is quite long and can be seen on the mentioned page)
I have set up the domain service with the class and the code to return the users:
//[RequiresRole("Managers")]
public IEnumerable<MembershipServiceUser> GetAllUsers()
{
return Membership.GetAllUsers().Cast<MembershipUser>().Select(u => new MembershipServiceUser(u));
}
I took out the RequiresRole for testing.
What I seem to be a bit blonde about is the calling of the GetAllUsers() method.
In my code behind I am using:
MembershipDataContext context = new MembershipDataContext();
EntityQuery<MembershipServiceUser> users = context.GetAllUsersQuery();
I am not 100% sure if this is the correct way to use the method or if something else is wrong because
context.GetAllUsersQuery(); returns "Enumeration yielded no results"
One question is also in the code kylmc uses //RequiresRole("Admin")]. Is this a custom role created in the ASP.NET Configuration editor?
Looking at another tutorial regarding using the ASP.NET authentication service in Silverlight, I create a role called "Managers" and added the login user to that role.
Logging in using a user with role Managers doesn't help and results are still not yielded.
Any ideas I could possible look at?
Many thanks
Neill
There are two steps involved with querying.
Get a query object from the Domain Service context (synchronous).
Load the query from the Domain Service context (asynchronous).
Example:
public void Load()
{
// define the query
var query = context.GetAllUsersQuery();
// start running the query, and when the results return call
// OnGetAllUsersLoaded
context.Load(query, OnGetAllUsersLoaded, null);
}
public void OnGetAllUsersLoaded(LoadOperation op)
{
var results = op.Entities;
}

Resources