Opening a maxon::URL in the browser: Anchors and query parameters?



  • Follow-up to: How do I open a maxon::Url in the default web browser?

    Hi,

    I am trying to open a maxon::URL in the browser. It basically works, but lacks essential support for HTML anchors (delimited with "#") and - even more important - does not seem to handle query parameters (starting with "?" and separated with "&") correctly by default.

    Here is some code about the latter. I want to open the website where potential customers can request an activation key for my plugin:

    // Build request query string
    maxon::BaseArray<maxon::String> urlQueryParts;
    if (licensingInfo.firstName.IsPopulated())
    {
    	urlQueryParts.Append("firstname="_s + licensingInfo.firstName) iferr_ignore();
    }
    if (licensingInfo.lastName.IsPopulated())
    {
    	urlQueryParts.Append("lastname="_s + licensingInfo.lastName) iferr_ignore();
    }
    if (licensingInfo.organization.IsPopulated())
    {
    	urlQueryParts.Append("organization="_s + licensingInfo.organization) iferr_ignore();
    }
    if (licensingInfo.systemCode.IsPopulated())
    {
    	urlQueryParts.Append("inputcode="_s + licensingInfo.systemCode) iferr_ignore();
    }
    const maxon::String urlQueryString(JoinElements(urlQueryParts, "&"_s));
    
    // Build request URL
    maxon::Url url(GeLoadString(IDS_DEMOKEYGENERATORURL));
    url.Set(maxon::URLFLAGS::QUERY, urlQueryString) iferr_ignore();
    
    // DEBUG: Print URL to console
    maxon::String urlString = url.ToString(nullptr);
    GePrint(urlString);
    
    // Open URL in browser
    url.IoShowInOS(maxon::IOSHOWINOSFLAGS::OPEN_IN_EXPLORER) iferr_ignore();
    

    The part with adding the query parameters to the URL works fine, even though I think it's quite a lot of code for something so simple. I'm doing it this way, because the SDK docs about UrlInterface::SetUrl() kind of hints to this.

    The GePrint(urlString) call prints the following:

    https://demo.mypluginsite.com?firstname=Arthur&lastname=Dent&inputcode=14004902462
    

    So, that looks like exactly what I need. However, when calling url.IoShowInOS(), Safari tries to open this URL:

    https://demo.mypluginsite.com%3ffirstname=arthur&lastname=dent&inputcode=14004902462
    

    And when I set my MacBook's default browser to Chrome instead, Chrome just opens a new tab at about:blank. This happens on my old macBook with El Capitan as well as on a new iMac with macOS Catalina.

    My questions:

    • Why are the firstname and lastname values lower-case, and how can I prevent that from happening?
    • Why is the "?" before the query parameters escaped, and how can I prevent that from happening?
    • Why does Chrome not open the URL at all?

    Thanks for help & advice!

    Cheers,
    Frank



  • In Python, it's dead simple to open the default web browser with a URL and query parameters.

    import webbrowser
    URL = "https://demo.mypluginsite.com?firstname=Arthur&lastname=Dent&inputcode=12312312320"
    webbrowser.open(URL)
    

    Guess, if Maxon::URL can't do that, I'll have to write a Python plugin and call it from within my C++ code :-/

    Cheers,
    Frank



  • I ended up solving the problem with Python. Still, I would really appreciate some feedback from Maxon about why this doesn't work, if something can be done to fix it (and what), or a confirmation that it's actually a bug in Cinema. As things are now, maxon::Url::IoShowInOS() is not really usable to open URLs in the web browser. And that's a pity, because it would be really useful, too e.g. open a help website from within a PluginHelpDelegate.

    Here's my solution (works in R20 - R23):

    #include "ge_prepass.h"
    #include "operatingsystem.h"
    #include "maxon/vm.h"
    #include "maxon/cpython.h"
    #if API_VERSION >= 23000
    // R23+: Load Python 3
    #include "maxon/cpython37_raw.h"
    #else
    // Pre-R23: Load Python 2.7
    #include "maxon/cpython27_raw.h"
    #endif
    #if API_VERSION >= 22000
    #include "maxon/errortypes.h"
    #endif
    #include "c4d_general.h"
    #include "lib_py.h"
    
    ///
    /// \brief Simplified version of the ExecutePythonScript() example from the SDK docs
    ///
    maxon::Result<void> ExecutePythonCodeSimple(const maxon::String &code)
    {
    	iferr_scope;
    
    	// Check code
    	if (code.IsEmpty())
    		return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    
    	// Create VM ref and scope
    #if API_VERSION >= 23000
    	const maxon::VirtualMachineRef& vm = MAXON_CPYTHON37VM();
    #else
    	const maxon::VirtualMachineRef& vm = MAXON_CPYTHON27VM();
    #endif
    	const maxon::VirtualMachineScopeRef scope = vm.CreateScope() iferr_return;
    
    	// Init script
    	iferr (scope.Init("Python Script"_s, code, maxon::ERRORHANDLING::PRINT, nullptr))
    	{
    		const String errorMessage = "Error on Init()"_s;
    		return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
    	}
    
    	// set __name__ = __main__
    	scope.Add("__name__"_s, maxon::Data("__main__"_s)) iferr_return;
    
    	// executes the script and returns when it got executed.
    	// info: if the script causes an unexpected infinite loop, Execute() does not return
    	// and there is no way to stop from the outside.
    	iferr (scope.Execute())
    	{
    		const String errorMessage = "Error on Execute()"_s;
    		return maxon::UnknownError(MAXON_SOURCE_LOCATION, errorMessage);
    	}
    
    	return maxon::OK;
    }
    

    And I'm using it like this:

    maxon::Result<void> OpenUrlInBrowser(const maxon::Url &url)
    {
    	iferr_scope;
    
    	maxon::String urlString = url.ToString(nullptr);
    
    	// Build Python code
    	maxon::String theCode;
    	theCode = "import webbrowser\n"_s;
    	theCode += "URL = \""_s + urlString + "\"\n"_s;
    	theCode += "webbrowser.open(URL)\n"_s;
    
    	// Execute code
    	TF4D::Python::ExecutePythonCodeSimple(theCode) iferr_return;
    
    	return maxon::OK;
    }
    

    Greetings,
    Frank



  • Hi @fwilleke80 I can indeed confirm the issue, and I will create a bug report about it.
    This is the mac only issue and with Chrome on Windows everything work as expected.

    Regarding your Python implementation, it's alright to do it as you did 😉

    Have a nice weekend,
    Cheers,
    Maxime.



  • Thanks for confirming!

    The strange thing is that I can reproduce this even in R20. Seems, not many people use this function to open URLs.

    I'll mark this as solved then, as my solution presented in this thread works flawlessly on all R2x releases.

    Cheers,
    Frank