Weblog
Patrik Lauha: Muuttolintujen Kevät - Automatic Bird Sound Classifier
Patrik Lauha: Muuttolintujen Kevät - Automatic Bird Sound Classifier
LIFEPLAN project: international bio monitoring project, with DNA samples, camera traps, audio recordings. This is a huge amount of data.
Muuttolintujen Kevät (“Spring of migratory birds”) is a mobile application based citizen science campaign where citizens collect bird observations with help of an automated bird sound classifier of Finnish birds. You can download the app on your phone. Recordings are analyzed with AI model, which is trained to recognize the vocalizations of Finnish birds. You need a Finnish phone operator for the app to work.
You can also scroll through your old observations, see a list of species you have recorded. You see the confidence percentage of the bird recognition. Also a small game: listen and choose the correct bird.
We have more than 300 thousand users. This is 5 percent of the Finnish population! 16 million recordings. Most common species: common chaffinch, eurasian blue tit, great tit, common blackbird, willow warbler. So the people help us to collect data about birds in nature, without us having to install lots and lots of audio equipment.
We transform audio to a spectogram image. Why? Image recognition is really good. And it is natural to represent audio as an image. With audio you have about 48,000 tiny data points per second. Represented as image this is much less, but enough for the pattern to be recognizable. We use a short-time Fourier transform. See also https://bsg.laji.fi
We use TensorFlow and Keras in Python. Convolutional neural netword processes input audio in 3-second segments. Training data from global bird sounds library xeno-canto, Finnish field recordings, and our phone app. Trained for 263 Finnish bird species. Output is then for each species the likelyhood that there is a match.
We use data augmentation to avoid data overfitting, where the model would be really good at recognizing only the training data based on irrelevant details. In Python: Scipy, colorednoise, noisereduce.
With passive acoustic monitoring we record the whole day and can see what birds are most active in the early morning. With the data from citizens, we see most data a bit later in the morning, because people are asleep before, and another peak near the end of the day.
Ongoing research: with the app data:
- Digital twinning and real-time bird forecasts. With the data we get really good predictions of when the migratory birds are coming and going. We can also show predictions of where and at which time you are most likely to hear your favorite bird, so you can be there.
- Complementing the breeding bird atlas: https://lintuatlas.fi
- Humanities / social sciences study of nature experience. In the app you can record your nature experience: tell how your surroundings look, how you feel, what you hear, smell, think. We don't know who is behind the recordings, so you should feel safe to use this part of the application.
For training we need a large computer. For classification we don't need much.
Plone Foundation Annual General Meeting
Plone Foundation Annual General Meeting at Plone Conference 2025 in Jyväskylä, Finland.
Main goals the past year:
- Strengthen the Plone Foundation. Push for more diversity in the community. We are a bit too much European, male, and white. And old? Google Summer of Code helps here. Some people travelled here by train, which is better for our carbon footprint. Have a straightforward sponsorship program. A document was drafted with a written list of requirements to organize a Plone conference or sprint. We try to find new funding sources. We are looking to establish an EU entity to reduce costs associated with financial transactions. We have better defined benefits and duties of Foundation membership. Align sprint funding with sponsorship commitments and the product roadmap, so the roadmap was aligned with the funding of sprints. A sprint should move the roadmap forward, but it is also important that it builds community. Ensure financial operations and transfer of the treasury, making the work of the treasurer future proof. Steve Piercy has stepped up for this, doing a lot of work figuring out the situation, making it clearer, make sure the treasurer has access to accounts where needed.
- Empower the Plone community. More in-person events, like sprints. Thinking of ways to better train newcomers. have a clear and community-adopted roadmap, shared between Classic and Volto Teams. The PloneEdu Team was revamped. plone.org Dev Team and Content Team, relaunch planned for next year. Helped conference organizers with regular meetings. If you know some organisation that wants to throw money at an open source, Python, Javascript project, contact Steve and he will help you write a grant application.
- Promote and market Plone. We had 8 new releases of Plone since last conference. We publish every sprint report. Improve plone.org SEO and metadata. Encouraging participation in community events: TuneUp days, sprints, World Plone Day, PloneConf. PloneGov-BR will organize a Plone Symposium in November.
We have new Foundation members. Currently 96 active members from 21 countries. 215 emeritus members. 3 pending.
- Community and code. Every month meeting of the Steering Circle, led by Eric Steele. 21 active new contributors, and 4 for Zope. GSOC: 3 students joined, supported by 6 mentors. Thank you! We had 5 strategic sprints this year. Also Plone Tune-Ups each third Friday of the month. World Plone Day with 48 videos. We supported the Plone Conference 2025 organization.
- Evangelism and outreach. CMS Garden. Plone Tagung. Some podcasts/videos. Sponsors: 6 premium, 4 standard, and a one-time 1000 dollar donation from the Frappe organisation. Plus individual sponsors via GitHub, which amounts to about 500 euro per month.
Board of Directors. We had four candidates for three seats on the next board. Elected have been Rikupekka Oksanen, Eric Brehault, and Gildardo Bautista. Thank you Mikel and Guido for their service on the board, they are stepping out now.
Alexander now "pulls a Sjoerd". That points to an old board member who always tried to end the meeting as soon as possible. Meeting adjourned.
Daniel Vahla: Preparing for a Free-Threaded Python World
Talk by Daniel Vahla at Plone Conference 2025 and PyCon Finland in Jyväskylä, Finland.
Slides are here: https://pycon2025.vahla.fi
This is a recap on thread safety and synchronisation primitives. Python is going to a free-threaded model.
I am consultant at Mavericks Software, 7 years of Python experience.
Why does this talk matter? Python 3.14 has an opt-in with GIL-free builds, via python3.14t
. True parallism means real race conditions. We need to protect ourselves in ways that the GIL (global interpreter lock) did for us.
Without synchronization, multiple threads can touch the same data.
Demo: game of throwing dice by three players, each in a separate thread. A player plays until they have 20 points. This goes wrong, only one of the three throws gets used for all three.
So we add a Lock. Only one thread can hold the lock at a time. Others wait until it is released. This works.
We can use RLock: Recursive locking. With a regular lock you cannot acquire the same lock twice in same thread. In our game we will say: if you roll 6, you can roll again. This needs the RLock.
Demo 3: semaphore. This is like a lock with a counter, allowing limited access. N threads can have access at the same time. For example used for connection pools, resource limits, rate limiting. In our game we will allow at most 2 players to play the game. On join, we acquire the semaphore, and when finished, we release it.
Demo 4: BoundedSemaphore. You may need a defensive semaphore. This is for bug detection. Semaphore can release more than acquired. For best practice: always use the BoundedSemaphore.
Demo 5: Event. A simple signal. A boolean flag. Threads can wait()
for event. One thread callse set()
to wake all. We use this in our game to wait until all threads have been created.
Demo 6: Condition. For complex coordination: a Wait plus Notify. wait()
releases locks and blocks. notify()
or notify_all()
wakes the waiters. You should always use this in a while loop, to avoid spurious wakeups. Used for producer-consumer patterns. We will use this to wait for enough players to join.
Demo 7: Barrier. For Phase Sync. Cleaner than Condition for rounds. Created with a party count: Barrier(n)
. You can have optional action callbacks. Used for multi-phase algorithms, round-based games, synchronizing computational stages. We use it in our game to wait for 3 players and play 3 rounds. In the callback we will print that a new round has started.
Key takeaways:
- GIL-free is here, opt-in
- Thread safety is critical
- Know your primitives, use the right tool for the job
- Test now with
python3.14t
. - Always use
BoundedSemaphore
overSemaphore
. - If you are not sure if something is safe, just use a Lock.
Guido Stevens: Living Software for a Living World
Talk by Guido Stevens at Plone Conference 2025 in Jyväskylä, Finland.
I read the GoF (Gang of Four) book 'Design Patterns'. When I read what it says about the adapter pattern, which I use every day in Plone, it just takes the fun out of it. Overabstraction is wrong. If humans can't understand a pattern or architecture, it is wrong.
Book 'A Pattern Language', 1977. Much different from the GoF book. More inspired by Christopher Alexander. More human.
In 2000-2004 I was using PHP, with test driven development, full version control. 2007-2010: Plone 2.1, 2.5, with TTW skins, which had no tests and no version control, so a step back. But the ZCA (Zope Component Architecture) came. This has several of the Design Patterns: Interface, Adapter, Utility (Singleton), Subscriber (Observer). Some others might be useful, like Strategy.
I used to completely specify Interfaces, which is how it is intended. But nowadays they are mostly just marker interfaces, which work because they serve as hooks into the ZCA.
Before adapters there was excessive polymorphism. Just look at the CatalogTool in Products.CMFPlone, and try to follow its multiple inheritance. You can overdo it. With adapters you have separation of concerns. You create an adapter that gets the UID from an object. And you create a utility that resolves the UID into an object.
Subscriber (Observer): a subject broadcasts event. It has no knowledge of its subscribers. These subscribe to events, and execute some code on it.
We have actor, action, context: an editor publishes a news item. And this sends 5000 notifications via email, and the editor needs to wait. That does not scale. So we need a notifications sub system. Alessandro is the technical architect and lead developer here. We log the 'published' event in an SQL database, and then the transaction is done.
Then we schedule notifications. Here we use the Chain of Responsibility pattern: for each logged event, for each channel, for each category, for each recipient: if channel is active for category and recipient: store the notification in SQL.
Then we dispatch the notifications. For some we will send emails, for some we send them later in a digest email.
Christopher Alexander, mentioned before, wrote 'The Nature of Order'. There are lots of patterns, but you can condense it to 15 structural patterns. Structure preserving presentations, process, time. Inspired by nature, fractals.
How do we apply this to the software challenge we have? In Quaive we have a Calendar app. This has notifications. This is implemented in adapters and subscribers. Same for other apps. Same pattern. So we have the notifications framework that does the heavy lifting, this is the trunk. And then we have the apps (leaves or branches) that use the patterns. So developers can zoom in on the business logic in a single app, and forget about everything else.
Object reuse was the 1995 Patterns goal. But now we have frameworks, that coordinate reuse. It is not not import library
, but you make you of the code flow in the framework.
Plone rocks. It is a community that makes a framework and a framework that makes a community.
Lightning talks Thursday
Lightning talks on Thursday at Plone Conference 2025 in Jyväskylä, Finland.
Mari: Social skills in Finland
Today's lesson: use of personal space. An internet meme is that Finnish people need a lot of personal space. There have been actual academic studies around this: it is actually a thing! You have high contact cultures and low-contact cultures. Finland has 16 people per square kilometer, India has over 400.
Herman Melville: "We cannot live only for ourselves. A thousand fibers connect us with our fellow-men."
If a Fin steps back from you in conversation, do not see it as an insult, just a different culture.
Plone Sponsorships
First: if you have not voted for the Plone Foundation Board elections, do so, if you are a member.
There have been a lot of sprints today. And these are the things where most of the money of the foundation goes to. So sponsoring Plone is important. See https://plone.org/foundation/sponsorship
We have drafted a new sponsorship program, and hope to start with it soon. We will contact all current sponsors.
Thomas Lambert: How to integrate +100 different themes
SmartWeb is a Plone application to help municipalities in Belgium to manage their website. By now more than 100 websites in production. Each website has its own layout/theme. Our graphic designer creates a Figma layout, together with the municipality. We use Barceloneta inside a base theme. Then pnpm with some custom CSS for each site.
Maurits van Rees: SFIA skills framework
SFIA is the global skills and competency framework for the digital world. See https://sfia-online.org/ This is a client of Zest Software, and I work for them via my own company Py76. A few days ago I found out that they recently started sponsoring Plone, so that is nice, and I thought I would present their website here. It is a Plone 6.1 Classic UI site, using Mosaic.
The SFIA framework defines skills on levels between 1 and 7. An organisation can use this to see where a team is missing skills. Maybe a team needs someone with a Programming/software development skill at level 4. You can use the text on this site as basis for a job offering. Or you see that the team already has someone with this skill on a lower level, and they could grow with some training. As individual you can look at which skills you have and at which level you are using it. You can look what the responsibilities and expectations are on the next higher level. Or find a list of related skills that may be interesting for you.
The stack is: CloudFlare, Apache, Varnish, 2 zeo clients, a zeo server. We only very recently added Varnish. It seemed fine enough without it, and we had CloudFlare. But by default CloudFlare basically only caches CSS, JS, images. No html, unless you configure it differently. And then AI bots started querying the site, causing slow responses. So we added Varnish and this helped.
It is a multilingual site, translated into 13 languages. Does anyone here have more languages in a site? No.
But how do you edit a Japanese page as editor if you can’t read Japanese? CodeSyntax has made an add-on for this: cs.adminlanguage
. This is only active when you are logged in as Editor. Messages in the plone domain are not translated, so important parts of the UI are in English.
Every three years they release a new version of their skills framework. This is prepared in English. Then we export this as XML. This gets uploaded to an external service where it gets translated in the other languages, partially by human translators, but AI or translation memories are getting a larger role. Then we import it and create the new content in Plone.
There is also a control panel to create an html export. You select an image, a title, optional extra css, and select the content to export and the language. Then you click the button to generate the html. And more importantly you can generate a PDF. This uses the same HTML, and transforms it with Prince, which is installed on the server.
They are nice people to work with, so thank you Peter, Ian, and Lucy!
Rob Gietema: New Volto form block
The current form block uses custom widgets. Would be nicer to reuse existing ones. Reuse the backend with some minor changes. Provided wrappers with the logic that is needed for the form, so you can use "dumb" custom widgets where needed. You can specify a custom form component.
Piero Nicolli: 42
If you want to use the under development Seven project today, you can, but you currently need to use Volto for the editing. So I made a package in the collective on the name fortytwo
(Seven times Plone 6).
Antoine Duchene: Document generation in Plone 6
Some metrics: we produce around 110 thousand documents per month across all our business apps. Roughly 2500 templates in the wild. The engine is the Appy framework, relying on LibreOffice. We made collective.documentgenerator
. Version 4 works on Plone 6 (Classic UI). Already used in production at iMio. Manageable LibreOffice templates TTW with specific content types.
Luna: Website builder distribution
Based on Volto. Demo.
Johannes Raggam: bssp
We will have another Buschenschanksprint (bssp) in 2026. This is in Austria. Topic of course Plone, Classic UI, Volto, but you can bring your own topics. I organise apartments so people can sleep there. You can of course book your own if you want a more private sphere. The Buschenschank is a traditional restaurant with cold plates with cheese and sausage and such.
Tuesday 26 to Sunday 31 May 2026. You can already register.
Philip Bauer: Is it awesome?
You have probably created awesome add-ons. But have you "awesomed" it? Register it in our awesome lists:
- For Plone backend / Classic UI: https://github.com/collective/awesome-plone
- For Volto: https://github.com/collective/awesome-volto