Flask-Admin GeoAlchemy2 example doesn't show a map - mapbox

I'm trying to run this example about how to use Flask-Admin displaying maps: https://github.com/flask-admin/flask-admin/tree/master/examples/geo_alchemy.
In README.rst, there's this instruction:
You will notice that the maps are not rendered. To see them, you will have to register for a free account at Mapbox and set the MAPBOX_MAP_ID and MAPBOX_ACCESS_TOKEN config variables accordingly.
I already have a valid MAPBOX_ACCESS_TOKEN, and I went to MapBox to look for a MAPBOX_MAP_ID. There I read that MAP_ID was deprecated, and now I'll have to obtain a tileset ID, and it's described as a label composed by <my_mapbox_user_name>.the_tileset_ID itself.
So I located the code as they described in the instructions (in my case, mapbox-streets-v8) and fulfilled the config.py parameters:
MAPBOX_MAP_ID = '<my_mapbox_user_name>.mapbox-streets-v8'
MAPBOX_ACCESS_TOKEN = 'pk.eyJ1...'
However, I couldn't see any map displayed or any error message.
How can I fix it?

I think there is a small bug in file Lib\site-packages\flask_admin\static\admin\js\form.js. The original URL generated to get a tile is:
https://api.mapbox.com/styles/v1/mapbox/<MAPBOX_MAP_ID parameter>/tiles/12/2258/2457?access_token=<MAPBOX_ACCESS_TOKEN parameter>
However, the correct one is:
https://api.mapbox.com/styles/v1/<MAPBOX_MAP_ID parameter>/tiles/12/2258/2457?access_token=<MAPBOX_ACCESS_TOKEN parameter>
That is, I had to remove the mapbox word from the URL.
To do that I made some changes in form.js file:
//var mapboxUrl = 'https://api.mapbox.com/styles/v1/mapbox/'+window.MAPBOX_MAP_ID+'/tiles/{z}/{x}/{y}?access_token='+window.MAPBOX_ACCESS_TOKEN
var mapboxUrl = 'https://api.mapbox.com/styles/v1/'+window.MAPBOX_MAP_ID+'/tiles/{z}/{x}/{y}?access_token='+window.MAPBOX_ACCESS_TOKEN
Then, it's working now:

Related

QGIS: Get Layout's Grid CRS (QgsLayoutItemMapGrid)?

Still learning QGIS using Python, but getting there...thanks to this site!
I'm trying to extract the CRS of the GRID that my layout is using. I think the Class I need to use is QgsLayoutItemMapGrid but can't get there from my testing:
projectInstance = QgsProject.instance()
projectLayoutManager = projectInstance.layoutManager()
# I checked and mine is the 'first' layout, viz [0]
mylayout = projectLayoutManager.layouts()[0]
# found this method in the API reference, but doesn't seem to have CRS etc
mygrid = mylayout.gridSettings()
... but I can't get beyond this. Maybe a different starting point? Any tips? Thanks.

How do I clear an element before rendering?

I have inherited an older project using jquery.
I am modernising the code.
In particular this $(selector).html("<h1>lol</h1>"); which as far as I understand is a full replacement of the selectors content.
I always end up with an error if I try to render to a cleared element.
This code:
const appDiv: HTMLElement = document.getElementById('app');
appDiv.innerHTML = `<h1>TypeScript Starter</h1>`;
// trying to replace jquery $(selector).html("<h1>lol</h1>");
appDiv.innerHTML = '';
render(html`<h1>lol</h1>`, appDiv);
appDiv.innerHTML = '';
render(html`<h1>lol</h1>`, appDiv);
Or see my stackblitz
I always get the following error:
Error in lit-html.js (93:55)
Cannot read properties of null (reading 'insertBefore')
Do you know what I am missing? 🧐
Thanks!
Note: This is a duplicate of my question (and based on a suggested technique) from a closed Lit Github Issue
Note: Maybe I am talking rubbish. I can't find a clear answer if render REPLACES content or APPENDS content. A concrete answer on that would be fine!
Lit v1 will clear the container before rendering the first time. Lit v2 will not.
Only clear the existing container content once before using render. After that render will correctly update content from previous render calls.
const appDiv: HTMLElement = document.getElementById('app');
appDiv.innerHTML = `<h1>TypeScript Starter</h1>`;
// trying to replace jquery $(selector).html("<h1>lol</h1>");
appDiv.innerHTML = '';
render(html`<h1>lol</h1>`, appDiv);
render(html`<h1>lol2</h1>`, appDiv);

Stop huge error output from testing-library

I love testing-library, have used it a lot in a React project, and I'm trying to use it in an Angular project now - but I've always struggled with the enormous error output, including the HTML text of the render. Not only is this not usually helpful (I couldn't find an element, here's the HTML where it isn't); but it gets truncated, often before the interesting line if you're running in debug mode.
I simply added it as a library alongside the standard Angular Karma+Jasmine setup.
I'm sure you could say the components I'm testing are too large if the HTML output causes my console window to spool for ages, but I have a lot of integration tests in Protractor, and they are SO SLOW :(.
I would say the best solution would be to use the configure method and pass a custom function for getElementError which does what you want.
You can read about configuration here: https://testing-library.com/docs/dom-testing-library/api-configuration
An example of this might look like:
configure({
getElementError: (message: string, container) => {
const error = new Error(message);
error.name = 'TestingLibraryElementError';
error.stack = null;
return error;
},
});
You can then put this in any single test file or use Jest's setupFiles or setupFilesAfterEnv config options to have it run globally.
I am assuming you running jest with rtl in your project.
I personally wouldn't turn it off as it's there to help us, but everyone has a way so if you have your reasons, then fair enough.
1. If you want to disable errors for a specific test, you can mock the console.error.
it('disable error example', () => {
const errorObject = console.error; //store the state of the object
console.error = jest.fn(); // mock the object
// code
//assertion (expect)
console.error = errorObject; // assign it back so you can use it in the next test
});
2. If you want to silence it for all the test, you could use the jest --silent CLI option. Check the docs
The above might even disable the DOM printing that is done by rtl, I am not sure as I haven't tried this, but if you look at the docs I linked, it says
"Prevent tests from printing messages through the console."
Now you almost certainly have everything disabled except the DOM recommendations if the above doesn't work. On that case you might look into react-testing-library's source code and find out what is used for those print statements. Is it a console.log? is it a console.warn? When you got that, just mock it out like option 1 above.
UPDATE
After some digging, I found out that all testing-library DOM printing is built on prettyDOM();
While prettyDOM() can't be disabled you can limit the number of lines to 0, and that would just give you the error message and three dots ... below the message.
Here is an example printout, I messed around with:
TestingLibraryElementError: Unable to find an element with the text: Hello ther. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
...
All you need to do is to pass in an environment variable before executing your test suite, so for example with an npm script it would look like:
DEBUG_PRINT_LIMIT=0 npm run test
Here is the doc
UPDATE 2:
As per the OP's FR on github this can also be achieved without injecting in a global variable to limit the PrettyDOM line output (in case if it's used elsewhere). The getElementError config option need to be changed:
dom-testing-library/src/config.js
// called when getBy* queries fail. (message, container) => Error
getElementError(message, container) {
const error = new Error(
[message, prettyDOM(container)].filter(Boolean).join('\n\n'),
)
error.name = 'TestingLibraryElementError'
return error
},
The callstack can also be removed
You can change how the message is built by setting the DOM testing library message building function with config. In my Angular project I added this to test.js:
configure({
getElementError: (message: string, container) => {
const error = new Error(message);
error.name = 'TestingLibraryElementError';
error.stack = null;
return error;
},
});
This was answered here: https://github.com/testing-library/dom-testing-library/issues/773 by https://github.com/wyze.

trying to access Thunderbird-tabmail does not work

I want to open a new tab with a gloda conversation from inside calendar code.
I receive an error from error console:
window not defined (or document not defined), depending on which of the two I use to Access tabmail:
let tabmail = window.document.getElementById("tabmail");
let tabmail = document.getElementById("tabmail");
The code works fine if the js file is included in an overlay xul-file.
But I want to use it outside of xul in my code.
Somewhere in my calendar code (in my 'addevent'), the same code throws the error.
This code is originally called from a rightclick on an email, but several layers deep into calendar code.
In MDN, I read that window is global? So what do I Need to do to add an tab?
This part works if tabmail is properly referenced:
tabmail.openTab("glodaList", {
collection: queryCollection,
message: aCollection.items[0],
title: tabTitle,
background: false
});
So how do I get a reference for tabmail?
Any help is appreciated.
after trying and looking through code for really some time before posting, it took only ca. 20 minutes to accidentally find the solution after submitting the question..
While browsing mailutils on mxr for something else, I found the solution in some function:
mail3PaneWindow = Services.wm.getMostRecentWindow("mail:3pane");
if (mail3PaneWindow) var tabmail = mail3PaneWindow.document.getElementById("tabmail");

CQ5.5: getting Style of a target page

I've been working on this for sometime now, and I keep running into a wall. I think I'm close, but I figured someone out here in the land of SO might have some deeper insight if not a better way of doing what I'm trying to do.
Basically lets look at this scenario. I have a logo w/ some text that can be set from a few different places. If we look at the setup here is what it looks like.
Hiearchy:
Homepage [has designPath]
- Child Microsite Page [has designPath]
- Logo Component
Logic Flow (in logo component):
if properties.get("logoText") {
use this
} else if currentStyle.get("logoTextFromStyle") {
use this
} else if parentStyle.get("logoTextFromGlobal") {
use this
} else {
be blank
}
My query is with how to get the "parentStyle" of this page. Looking at the docs here: http://dev.day.com/docs/en/cq/5-5/javadoc/com/day/cq/wcm/api/designer/Style.html
I've been able to come up with the fact that I can get a Style object from the "designer" object made available via defineObjects. This is defined with the other utility objects like "pageManager, resourceUtil, resource, currentPage, etc".
With that being said this doesn't seem to work.
//assuming we have getting homePage earlier and it is a valid cq Page resource
Resource homePageResource.slingRequest.getResourceResolver().getResource(homePage.getPath());
Style homePageStyle = designer.getStyle(homePageResource);
at this point homePageStyle is null. To do some more testing I i tried passing currentPage.getPath() instead of homePage.getPath(). I assumed this would give me the currentPage resource and would in end yield the currentStyle object. This also resulted in a null Style object. From this I think I can safely conclude I'm passing the incorrect resource type.
I attempted to load the the cq:designPath into the resource hoping to get a Designer resourceType but to no avail.
I am curious if anyone has run into this problem before. I apologize if I've gone into too much detail, but I wanted to lay out the "why" to my question as well, just in case there was a better way overall of accomplishing this.
I've figured out how to return the style. Here is the rundown of what I did.
//get your page object
Page targetPage = pageManager.getPage("/path/to/target");
//get the Design object of the target page
Design homePageDesign = designer.getDesign(homePage);
//extract the style from the design using the design path
Style homePageStyle = homePageDesign.getStyle(homePageDesign.getPath());
it's very interesting the definition of "getStyle" is a little different from the designer.getStyle vs a Design.getStyle. designer.getStyle asks for a resource whereas Design.getStyle will take the path to a Design "cell" and return the appropriate Style.
I did some testing and it looks like it does work with inherited Styles/Designs. So if my cq:designPath is set at level 1 and I look up a page on at level 2 they will return the Design/Style at the cq:designPath set at level 1.
I hope this helps someone else down the way.
I tried this approach but was not getting the Styles in the Style object.
When we do this:
Design homePageDesign = designer.getDesign(homePage);
In this Design object we get the path till the project node i.e etc/design/myproject
After this if we try to extract the Style from the design path we do not get it.
However I implemented it in a different way.
In the design object, we also get the complete JSON of designs for(etc/design/myproject).
Get the sling:resourceType of the target page and get the value after last index of "/".
Check if this JSON contains the last value. If it contains, you can get your styles, i.e. image, etc.