Feeds
FSF Blogs: Help us meet our goal of thirty-three new associate members by July 26
Help us meet our goal of thirty-three new associate members by July 26
Beta for Amarok 3.1 available
Dear fans of music & open source music players,
in preparation of the upcoming Amarok 3.1 release, a beta release (3.0.81) has been prepared.
As is observable from the ChangeLog, in addition to various bugfixes, there will be some, but not that many, new features included in the upcoming version. However, there has been a lot of Qt6 compatibility preparation work done under the hood, so version number 3.1 reflects the amount of changed code better than 3.0.2 would. 3.1.0 is likely to be released in early August, and all help catching any regressions during this period is highly appreciated. (n.b. one won't be able to compile a Qt6 Amarok with 3.1 yet, but perhaps with the eventual 3.2)
The source tarball is available on download.kde.org and it has been signed with Tuomas Nurmi's GPG key. There doesn't appear to be many binary packages of the beta available, at least at the moment, but the various nightly git builds provided by various splendid packagers are also based on corresponding source code, so using them and reporting findings is also a valid way to participate in the beta test effort.
Happy listening!
Kirigami Addons 1.4
Kirigami Addons 1.4 is out! This release introduce a new module to manage actions similar to that we can find in the QtWidgets world with KXmlGui. This was not written from scratch but upstream the existing infrastructure from Merkuro (ex-Kalendar) and Marknote. These two applications have already been ported to this new module and more like Tokodon or KDE Keychain will follow soon.
This includes a shortcut editor to assign and modify the shortcuts of an application and a command bar to quickly search and trigger actions
Similar to KXmlGui, the actions are defined in C++, which allows to make use KStandardActions and get consistent shortcuts accross all your applications.
class MyApplication : public AbstractKirigamiApplication { Q_OBJECT QML_ELEMENT public: explicit MyApplication(QObject *parent = nullptr); void setupActions() override; Q_SIGNALS: void addNotebook(); }; MyApplication::MyApplication(QObject *parent) : AbstractKirigamiApplication(parent) { setupActions(); } void MyApplication::setupActions() { AbstractKirigamiApplication::setupActions(); auto actionName = QLatin1String("add_notebook"); if (KAuthorized::authorizeAction(actionName)) { auto action = mainCollection()->addAction(actionName, this, &MyApplication::addNotebook); action->setText(i18nc("@action:inmenu", "New Notebook")); action->setIcon(QIcon::fromTheme(QStringLiteral("list-add-symbolic"))); mainCollection()->addAction(action->objectName(), action); mainCollection()->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_N)); } }These new actions can then be used from QML thanks to the new Kirigami.Action::fromQAction property.
import org.kde.kirigamiaddons.statefulapp as StatefulApp import org.kde.kirigamiaddons.settings as Settings StatefulApp.StatefulWindow { id: root windowName: 'Main' application: MyApplication { configurationView: Settings.ConfigurationView { ... } } Kirigami.Action { fromQAction: MyApplication.action('add_notebook') } Connections { target: MyApplication function onAddNotebook(): void { ... } } }There is a new template available in KAppTemplate, which allows you to kickstart your new Kirigami application with the basic skeleton with this new module and other “Kirigami Addons” modules.
Other ChangesThe FormCard design was tweaked a bit more when using a dark theme, thanks to James and Joshua for their feedback.
Speaking of FormCard, with the development of KeyChain, I ended up adding a new component to the FormCard collection: FormTextAreaDelegate. This component is the equivalent of FormTextFieldDelegate but with a TextArea instead. FormComboBoxDelegate and FormTextFieldDelegate also received a bunch of new properties and functions to proxy the underlying QtQuick.Controls component.
Evgeniy Harchenko tweaked a bit the headers of the TableView component.
Finally, a new contributor Andreas Gattringer fixed a crash in the video maximizing component which was affecting NeoChat.
Packager SectionYou can find the package on download.kde.org and it has been signed with my GPG key.
Four Kitchens: Why time is of the essence for a Drupal 11 migration
Director of Projects
Alongside her project management duties, Shanice is passionate about expanding Four Kitchens’ DEI efforts and fostering a culture of advocates and allies.
January 1, 1970
Platform upgrade.
For any IT manager, especially those at large organizations, these two words are enough to cause stress. Even if you just completed a move to Drupal 10, the release of Drupal 11 is around the corner with the latest version available in late July 2024.
What does that mean for your organization? Primarily, your greatest takeaway is that you shouldn’t feel the anxiety of another looming deadline. You still have two years to complete the upgrade. Plus, engineering plans are just starting to come together about how to tackle the upgrade multiple different ways. Time is still on your side.
However, just because a move to Drupal 11 isn’t cause for immediate alarm doesn’t mean you shouldn’t start planning an upgrade. You and your organization will see considerable benefits by addressing this change sooner rather than later.
What the move to Drupal 11 means for your websiteIn terms of adding new tools or website features, moving to Drupal 11 doesn’t mean much for your organization. Drupal rolls out upgrades differently than conventional software platforms. Version 11 will seem a lot like Drupal 10.3 in terms of new functionality.
Instead, Drupal will be deprecating features to eliminate unnecessary or outdated code from the core platform. For example, in moving from Drupal 9.5 to 10, the CKEditor 4 module was removed to make room for CKEditor 5. For Drupal 11, the Book module will be deprecated.
If your organization doesn’t use this feature, its subtraction amounts to a positive by eliminating unneeded weight to the platform. If you do, then Book will still function in a more nimble way as a contrib module.
Ultimately, your organization won’t see any new features from Drupal 11 until the release of the next version, Drupal 11.1. Does that mean you should wait until then to start planning a website upgrade? You guessed it — absolutely not.
Why get ahead of Drupal 11?The biggest benefit of planning your upgrade to Drupal 11 early is to avoid the scramble of a last-minute migration. This creates headaches for your team, and you also run into crowded schedules if you rely on a development partner. You don’t just run the risk of incurring unnecessary charges for trying to plan an upgrade at the last minute. You also risk limited availability as development agencies support other clients who also waited until the last minute.
Plus, planning to migrate to Drupal 11 now enables you to sidestep the complications of upgrading after 11.1 is released. Version 11.1 will include new features, and migrating across two versions will be more difficult, especially if you manage multiple websites.
Making the Drupal 11 move now gives you a leaner version of the platform while leaving you better positioned for 11.1. In all, your journey to Drupal 11.1 will be significantly faster and easier if you’ve already completed the migration to Drupal 11.
What stakeholders need to know about Drupal 11As you plan an upgrade to Drupal 11, you need to keep your stakeholders informed about what to expect. Rather than getting bogged down with deprecations or other elements, you should frame the upgrade as a maintenance release.
In other words, the migration is primarily a way to improve your organization’s position going forward. Along with creating an easier path toward accessing the new features coming for 11.1, this update also will improve the performance and scalability of the platform for your websites.
How to plan a Drupal 11 migrationDrupal 11 will be released in late July. Consequently, your organization has a long runway toward completing an upgrade. In fact, you have two years until version 10 reaches its end of life in mid- to late 2026.
While that sounds like an eternity from now, your organization has more options at its disposal for planning an upgrade the sooner you begin. With enough lead time, you could include much of the work of preparing for Drupal 11 as part of a Continuous Care program with Four Kitchens.
Depending on your subscription tier, you can allocate your hours differently to support the upgrade. Alternatively, you can plan to allocate additional hours to your tier to complete the upgrade. Or, you can upgrade to Drupal 11 as part of a standalone project separate from your Continuous Care engagement.
The point, ultimately, is to underscore that you have options. At Four Kitchens, we’re already working on our upgrade plan to guide our clients through a seamless transition to Drupal 11. By considering the right approach for your organization sooner rather than later, you can ensure you still have options for navigating this upgrade in a timely, efficient way.
If you’re ready to start planning, we should talk.
The post Why time is of the essence for a Drupal 11 migration appeared first on Four Kitchens.
Bounteous.com: The Future of Experimentation: Acquia Convert
PyCoder’s Weekly: Issue #639 (July 23, 2024)
#639 – JULY 23, 2024
View in Browser »
The asyncio.gather() function takes an optional argument return_exceptions which changes the behavior of the co-routine when an error occurs. This article shows you how to use it.
JASON BROWNLEE
In this tutorial, you’ll learn about Python’s protocols and how they can help you get the most out of using Python’s type hint system and static type checkers.
REAL PYTHON
Let Judoscale solve your scaling issues. We support Django, Flask, and FastAPI, and we also autoscale your Celery and RQ task queues. Traffic spike? Scaled up. Quiet night? Scaled down. Work queue backlog? No problem →
JUDOSCALE sponsor
Free-threaded mode is available as a compile option in the beta of Python 3.13. Simon decided to try it out on his Mac.
SIMON WILLISON
Take this quiz to test your knowledge about the available built-in functions in Python. By taking this quiz, you’ll deepen your understanding of how to use these functions and the common programming problems they cover, from mathematical computations to Python-specific features.
REAL PYTHON
In this course, you’ll practice the main steps of the web scraping process. You’ll write a script that uses Python’s requests library to scrape and parse data from a website. You’ll also interact with HTML forms using tools like Beautiful Soup and Mechanical Soup to extract specific information.
REAL PYTHON course
When playing with generators in asynchronous code, Sam ran into some things he didn’t quite expect with how and when resources get cleaned up. This article shows you what you can and can’t control, and in some cases whether you should.
SAM EISENHANDLER
Tired of emailing files around & trying to use general-purpose collaboration tools? Posit Connect makes it easy to share, collaborate, & get feedback on your data science work including Jupyter notebooks, Streamlit, & other analytics applications.
POSIT sponsor
In this article, the author talks about the different approaches they use to create new code depending on the mood, the feature or bug at hand, and their confidence level. Five different approaches are covered.
JUHA-MATTI SANTALA
Date and times are problematic and there are all sorts of problems you can get into when you use them in Python. This post talks about one challenge when using epoch timestamp numbers.
JOËL PERRAS
This post shows you how to take a Python script and turn it into a web application using FastAPI. It includes information about how to choose endpoints and how to do authentication.
AHMED LEMINE
eBPF is a tool available on Linux to dig into the profile of your code. In this article, Nikolay uses it to inspect when the GIL gets invoked in CPython.
NIKOLAY SIVOK
Pagination in Django uses the rather slow SELECT COUNT(*) SQL call. This article looks at how to speed up counting with Django and PostgreSQL.
NIK TOMAZIC
In Python, “change” can mean two different things. Assignment changes which object a variable points to. Mutation, changes the object itself.
TREY HUNNER
This post compares Flask and Django, from what they specialize in to what it takes to do a personal web site in each.
WILL VINCENT
You can use the Python built-in function iter with two arguments to create an iterator from a function.
RODRIGO GIRÃO SERRÃO
This tutorial details how to integrate GraphQL with Django using Strawberry.
TESTDRIVEN.IO • Shared by Michael Herman
GITHUB.COM/POMPONCHIK • Shared by Evgeniy Blinov (pomponchik)
Satyrn: macOS App for Jupyter Nobtebooks Datasketch: Probabilistic Data Structures pyNES: Python Programming for Nintendo 8 Bits staged-script: Divide Automation Scripts Into StagesGITHUB.COM/SANDIALABS • Shared by Jason M. Gates
Events Weekly Real Python Office Hours Q&A (Virtual) July 24, 2024
REALPYTHON.COM
July 25, 2024
MEETUP.COM
July 27 to July 28, 2024
PYOHIO.ORG
July 27, 2024
MEETUP.COM
July 27, 2024
MEETUP.COM
Happy Pythoning!
This was PyCoder’s Weekly Issue #639.
View in Browser »
[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]
GNU Guix: The European Union must keep funding free software
Guix is the fruit of a combination of volunteer work by an amazing number of people, work paid for by employers, but also work sponsored by public institutions. The European Commission’s Next Generation Internet (NGI) calls have been instrumental in that regard. News that NGI funding could vanish came to us as a warning signal.
Since 2020, NGI has supported many free software projects, allowing for significant strides on important topics that would otherwise be hard to fund. As an example, here are some of the NGI grants that directly benefited Guix and related projects:
- the full-source bootstrap, which includes groundwork not just in Guix but crucially in Mes and sister projects (blog post);
- porting Guix to the RISC-V architecture;
- porting GNU Mes and associated projects to RISC-V and AArch64;
- porting the full-source bootstrap to the RISC-V architecture;
- the Cuirass continuous integration tool (blog post);
- the Guile implementation of the Guix build daemon (blog post);
- distributed system daemon management with the Shepherd and Goblins, under the aegis of the Spritely Institute (blog post).
- a new garbage collector for Guile, the Scheme implementation that Guix builds upon.
Over the years, NGI has more than demonstrated that public financial support for free software development makes a difference. We strongly believe that this support must continue, that it must strengthen the development of innovative software where user autonomy and freedom is a central aspect.
For these reasons, the Guix project joins a growing number of projects and organizations in signing the following open letter to the European Commission.
The open letter below was initially published by petites singularités. English translation provided by OW2.
Open Letter to the European CommissionSince 2020, Next Generation Internet (NGI) programmes, part of European Commission's Horizon programme, fund free software in Europe using a cascade funding mechanism (see for example NLnet's calls). This year, according to the Horizon Europe working draft detailing funding programmes for 2025, we notice that Next Generation Internet is not mentioned any more as part of Cluster 4.
NGI programmes have shown their strength and importance to supporting the European software infrastructure, as a generic funding instrument to fund digital commons and ensure their long-term sustainability. We find this transformation incomprehensible, moreover when NGI has proven efficient and economical to support free software as a whole, from the smallest to the most established initiatives. This ecosystem diversity backs the strength of European technological innovation, and maintaining the NGI initiative to provide structural support to software projects at the heart of worldwide innovation is key to enforce the sovereignty of a European infrastructure. Contrary to common perception, technical innovations often originate from European rather than North American programming communities, and are mostly initiated by small-scaled organisations.
Previous Cluster 4 allocated 27 million euros to:
- "Human centric Internet aligned with values and principles commonly shared in Europe" ;
- "A flourishing internet, based on common building blocks created within NGI, that enables better control of our digital life" ;
- "A structured ecosystem of talented contributors driving the creation of new internet commons and the evolution of existing internet commons".
In the name of these challenges, more than 500 projects received NGI funding in the first 5 years, backed by 18 organisations managing these European funding consortia.
NGI contributes to a vast ecosystem, as most of its budget is allocated to fund third parties by the means of open calls, to structure commons that cover the whole Internet scope - from hardware to application, operating systems, digital identities or data traffic supervision. This third-party funding is not renewed in the current program, leaving many projects short on resources for research and innovation in Europe.
Moreover, NGI allows exchanges and collaborations across all the Euro zone countries as well as "widening countries"¹, currently both a success and an ongoing progress, likewise the Erasmus programme before us. NGI also contributes to opening and supporting longer relationships than strict project funding does. It encourages implementing projects funded as pilots, backing collaboration, identification and reuse of common elements across projects, interoperability in identification systems and beyond, and setting up development models that mix diverse scales and types of European funding schemes.
While the USA, China or Russia deploy huge public and private resources to develop software and infrastructure that massively capture private consumer data, the EU can't afford this renunciation. Free and open source software, as supported by NGI since 2020, is by design the opposite of potential vectors for foreign interference. It lets us keep our data local and favors a community-wide economy and know-how, while allowing an international collaboration.
This is all the more essential in the current geopolitical context: the challenge of technological sovereignty is central, and free software allows to address it while acting for peace and sovereignty in the digital world as a whole.
In this perspective, we urge you to claim for preserving the NGI programme as part of the 2025 funding programme.
¹ As defined by Horizon Europe, widening Member States are Bulgaria, Croatia, Cyprus, Czechia, Estonia, Greece, Hungary, Latvia, Lituania, Malta, Poland, Portugal, Romania, Slovakia, and Slovenia. Widening associated countries (under condition of an association agreement) include Albania, Armenia, Bosnia, Feroe Islands, Georgia, Kosovo, Moldavia, Montenegro, Morocco, North Macedonia, Serbia, Tunisia, Turkeye, and Ukraine. Widening overseas regions are Guadeloupe, French Guyana, Martinique, Reunion Island, Mayotte, Saint-Martin, The Azores, Madeira, the Canary Islands.
Mike Driscoll: ANN: ObjectListView3 for wxPython
ObjectListView is a third-party wxPython widget that wraps the wx.ListCtrl. I have used it for over 10 years in quite a few different GUI applications because it works much nicer than wx.ListCtrl does. Unfortunately, ObjectListView was never integrated into wxPython core like some other amazing third-party packages were, and so it has become broken over the past couple of years such that you can’t use it with the latest version of Python / wxPython.
So, I decided to fork the project, as its defects were simple enough that I could resolve them quickly. The new version of ObjectListView is now called ObjectListView3.
You can get the new version of ObjectListview here:
- ObjectListView3 on the Python Packaging Index
- ObjectListView3 on GitHub
Note that this version of ObjectListView works with Python 3.11+ and wxPython 4.2+. It may work with earlier versions as well.
InstallationIf you’d like to install ObjectListView3, you can use Python’s pip to do so like this:
python -m pip install ObjectListView3Now let’s see how an example of using ObjectListView!
Sample UsageThe following is an application that starts out by listing two books in an ObjectListView3 widget. When you press the “Update OLV” button, it will add three more books to the ObjectListView3 widget.
This demonstrates how to create the ObjectListview3 widget and update it after the application is running:
import wx from ObjectListView3 import ObjectListView, ColumnDefn class Book(object): """ Model of the Book object Contains the following attributes: 'ISBN', 'Author', 'Manufacturer', 'Title' """ def __init__(self, title, author, isbn, mfg): self.isbn = isbn self.author = author self.mfg = mfg self.title = title class MainPanel(wx.Panel): def __init__(self, parent): super().__init__(parent=parent, id=wx.ID_ANY) self.products = [ Book("wxPython in Action", "Robin Dunn", "1932394621", "Manning"), Book("Hello World", "Warren and Carter Sande", "1933988495", "Manning"), ] self.dataOlv = ObjectListView( self, wx.ID_ANY, style=wx.LC_REPORT | wx.SUNKEN_BORDER ) self.setBooks() # Allow the cell values to be edited when double-clicked self.dataOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK # create an update button updateBtn = wx.Button(self, wx.ID_ANY, "Update OLV") updateBtn.Bind(wx.EVT_BUTTON, self.updateControl) # Create some sizers mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.dataOlv, 1, wx.ALL | wx.EXPAND, 5) mainSizer.Add(updateBtn, 0, wx.ALL | wx.CENTER, 5) self.SetSizer(mainSizer) def updateControl(self, event): """ Update the ObjectListView """ product_dict = [ { "title": "Core Python Programming", "author": "Wesley Chun", "isbn": "0132269937", "mfg": "Prentice Hall", }, { "title": "Python Programming for the Absolute Beginner", "author": "Michael Dawson", "isbn": "1598631128", "mfg": "Course Technology", }, { "title": "Learning Python", "author": "Mark Lutz", "isbn": "0596513984", "mfg": "O'Reilly", }, ] data = self.products + product_dict self.dataOlv.SetObjects(data) def setBooks(self, data=None): self.dataOlv.SetColumns( [ ColumnDefn("Title", "left", 220, "title"), ColumnDefn("Author", "left", 200, "author"), ColumnDefn("ISBN", "right", 100, "isbn"), ColumnDefn("Mfg", "left", 180, "mfg"), ] ) self.dataOlv.SetObjects(self.products) class MainFrame(wx.Frame): def __init__(self): wx.Frame.__init__( self, parent=None, id=wx.ID_ANY, title="ObjectListView Demo", size=(800, 600), ) panel = MainPanel(self) class OLVDemoApp(wx.App): def __init__(self, redirect=False, filename=None): super().__init__(redirect, filename) def OnInit(self): # create frame here frame = MainFrame() frame.Show() return True def main(): """ Run the demo """ app = OLVDemoApp() app.MainLoop() if __name__ == "__main__": main()When you initially run this code, you will see the following application:
When you press the “Update OLV” button, the application will update to look like the following:
Wrapping UpThe ObjectListView3 widget makes working with tabular data easy in wxPython. You also get nice editing, sorting and more from this widget via different mixins or styles. Give ObjectListView3 a try when you create your next wxPython GUI application.
The post ANN: ObjectListView3 for wxPython appeared first on Mouse Vs Python.
The Drop Times: Inside Look at DrupalCamp Colorado 2024: What to Expect from the Event
DataWars.io: Free AP Computer Science A Practice Exercises | DataWars
Real Python: pandas GroupBy: Grouping Real World Data in Python
Whether you’ve just started working with pandas and want to master one of its core capabilities, or you’re looking to fill in some gaps in your understanding about .groupby(), this course will help you to break down and visualize a pandas GroupBy operation from start to finish.
This course is meant to complement the official pandas documentation and the pandas Cookbook, where there are self-contained, bite-sized examples. Here, however, you’ll focus on three more involved walkthroughs that use real-world datasets.
In this course, you’ll cover:
- How to use pandas GroupBy operations on real-world data
- How the split-apply-combine chain of operations works
- How to decompose the split-apply-combine chain into steps
- How to categorize methods of a pandas GroupBy object based on their intent and result
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Sitback Solutions: Making the polyfill.io vulnerability a thing of the past for Drupal
Russell Coker: More About Kogan 5120*2160 Monitor
On the 18th of May I blogged about my new 5120*2160 monitor [1]. One thing I noted was that one Netflix movie had run in an aspect ratio that used all space on the monitor. I still don’t know if the movie in question was cropped in a letterbox manner but other Netflix shows in “full screen” mode don’t extend to both edges. Also one movie I downloaded as in 3840*1608 resolution which is almost exactly the same aspect ratio as my monitor. I wonder if some company is using 5120*2160 screens for TVs, 4K and FullHD are rumoured to be cheaper than most other resolutions partly due to TV technology being used for monitors. There is the Anamorphic Format of between 2.35:1 and 2.40:1 [2] which is a close match for the 2.37:1 of my new monitor.
I tried out the HDMI audio on a Dell laptop and my Thinkpad Yoga Gen3 and found it to be of poor quality, it seemed limited to 2560*1440, at this time I’m not sure how much of the fault is due to the laptops and how much is due to the monitor. The monitor docs state that it needs HDMI version 2.1 which was released in 2017 and my Thinkpad Yoga Gen3 was released in 2018 so probably doesn’t have that. The HDMI cable in question did 4K resolution on my previous monitor so it should all work at a minimum of 4K resolution.
The switching between inputs is a problem. If I switch between DisplayPort for my PC and HDMI for a laptop the monitor will usually timeout before the laptop establishes a connection and then switch back to the DisplayPort input. So far I have had to physically disconnect the input source I don’t want to use. The DisplayPort switch that I’ve used doesn’t seem designed to work with resolutions higher than 4K.
I’ve bought a new USB-C dock which is described as doing 8K which means that as my Thinkpad is described as supporting 5120×2880@60Hz over USB-C I should be able to get 5120*2160 without any problems, however for unknown reasons I only get 4K. For work I’m using a Dell Latitude 7400 2in1 that’s apparently only capable of 4096*2304 @24 Hz which is less pixels than 5120*2160 and it will also only do 4K resolution. But for both those cases it’s still a significant improvement over 2560*1440. I tested with a Dell Latitude 7440 which gave the full 5120*2160 resolution, I was unable to find specs on what the maximum resolution of the 7440 is. I also have bought DisplayPort switch rated at 8K resolution. I got a switch that doesn’t also do USB because the ones that do 8K resolution and USB are about $70. The only KVM switch I saw for 8K resolution at a reasonable price was one designed for switching between two laptops and there doesn’t seem to be any adaptors to convert from regular DisplayPort to USB-C alternative mode so that wasn’t viable. Currently I have the old KVM switch used for USB only (for keyboard and mouse) and the new switch which only does DisplayPort. So I have two buttons to push when switching between input sources which isn’t too bad.
It seems that for PCs resolutions with more pixels than 4K are as difficult and inconvenient now as 4K was 6 years ago when I started doing it. If you want higher than 4K resolution to just work at this time then you need Apple hardware.
The monitor has a series of modes for different types of output, I’ve found “standard” to be good for text and “movie” to be good for watching movies/TV and for playing RTS games. I previously wrote about how to use ddcutil to use a monitor as a KVM switch [3], unfortunately I can’t do this with the new monitor as the time that the monitor waits for a good signal on a new input after changing is shorter than the time taken for Linux on the laptops I’m using to enable HDMI output. I’ve found the following commands to do the basics.
# get display mode ddcutil getvcp DC # set standard mode ddcutil setvcp DC 0 # set movie mode ddcutil setvcp DC 03Now that I have that going the next thing I want to do is to have it switch between “standard” and “movie” modes when I switch keyboard focus.
- [1] https://etbe.coker.com.au/2024/05/18/kogan-5120×2160-40-monitor/
- [2] https://en.wikipedia.org/wiki/Anamorphic_format
- [3] https://etbe.coker.com.au/2022/07/19/ddc-switch/
Related posts:
- Kogan 5120*2160 40″ Monitor I’ve just got a new Kogan 5120*2160 40″ curved monitor....
- Dell 32″ 4K Monitor and DisplayPort Switch After determining that the Philips 43″ monitor was too large...
- DDC as a KVM Switch With the recent resurgence in Covid19 I’ve been working from...
DrupalEasy: Getting ready to run your first migration
Migrating content into Drupal is an extremely useful skill for most Drupal developers. Often, the most difficult step in learning to do migrations is the first one - that of getting everything set up and running your first migration to ensure that everything is working as expected.
Most Drupal migration-related blog posts and documentation that I've seen either completely ignore the setup process or gloss over it before diving into the details of writing migrations. I like to ensure, both here, and when working with participants in our Professional Module Development course, that we ensure a solid understanding of this process to build not only skills, but confidence.
This blog post will explain how to set up and run your first (very simple) Drupal migration. The process I will outline is actually the same steps I do when beginning to write a custom migration - just to make sure I have everything "hooked up" properly before I start getting into the more complex aspects of the project.
I generally write migrations on my local machine, using DDEV as the local development environment.
Configuration migrations vs. Plugin migrationsWhen creating a custom migration, one of the initial decisions to be made is whether you'll write the migrations as plugins or configuration entities. I've always used configuration entities, but there are pros and cons to both approaches. Here, we will focus on configuration entity migrations.
There are some minor differences in the workflow presented below when using plugin migrations. For more information on the differences, I recommend Mauricio Dinarte's article.
Core and contrib modules usedIf you're planning on following along with this article, the following modules should be installed and enabled:
Drupal core:
- Migrate
- Migrate Drupal
Contrib:
- Migrate tools (for Drush commands) https://www.drupal.org/project/migrate_tools
- Migrate plus (migrations as configuration, additional process plugins, and more) https://www.drupal.org/project/migrate_plus
This blog post will demonstrate importing a small portion of user data from a Drupal 7 site into a Drupal 10 site. Normally, the first step is setting up the source data: in this case a Drupal 7 database. I normally create a new d7 database on the same MariaDB server as the Drupal 10 site (using DDEV, this is quite easy) and then import the Drupal 7 database into it.
Next, we have to tell the Drupal 10 site about the d7 source database. This can be done by adding the following database connection array to the bottom of your settings.local.php file (which I know you're using!):
$databases['migrate']['default'] = array( 'driver' => 'mysql', 'database' => 'd7', 'username' => 'db', 'password' => 'db', 'host' => 'db', 'port' => 3306, 'prefix' => '', );Note the database key is migrate and the database name is d7. Everything else is identical to the regular Drupal 10 database credentials in DDEV. If you're using Lando or another local development environment, then your database connection array may be different.
Custom migration moduleNext, we need a custom module to house our migration. The easiest way to create one is via Drush's generate command:
$ drush generate module Welcome to module generator! –––––––––––––––––––––––––––––– Module name: ➤ My d7 migration Module machine name [my_d7_migration]: ➤ Module description: ➤ Migrations from Drupal 7 site. Package [Custom]: ➤ Dependencies (comma separated): ➤ migrate, migrate_drupal, migrate_plus Would you like to create module file? [No]: ➤ Would you like to create install file? [No]: ➤ Would you like to create README.md file? [No]: ➤ The following directories and files have been created or updated: ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– • /var/www/html/web/modules/custom/my_d7_migration/my_d7_migration.info.ymlOnce created, go ahead and enable the module as well:
$ drush en my_d7_migrationMigration group configurationAs this blog post will be writing migrations as configuration entities, create a new config/install directory in your new module.
We'll define a migration group to which all of our migrations will belong - this is what connects each migration to the source d7 database. Create a new migrate_plus.migration_group.my_group.yml file in the new config/install directory with the following contents:
id: my_d7_migration label: My Drupal 7 migration. description: Content from Drupal 7 site. source_type: Source Drupal 7 site shared_configuration: source: key: migrate migration_tags: - Drupal 7 - my_d7_migrationThe most important bit of this configuration is the source key of migrate; this links up this migration group with the d7 database, with the migrate key we previously configured. Then, any migration created that is in this group automatically has access to the source d7 database.
Simple sample migration configurationNext, let's look at a super simple example migration for user entities. This will not be a complete user migration, but rather just enough to migrate something. Many migration blog posts, documentation pages and other sources provide guidance and examples for writing migration configuration files (remember, this blog post is focused on all of the configuration and mechanics that normally aren't covered in other places.)
Here's the user migration configuration we'll use. Create a new /config/install/migrate_plus.migration.user.yml file in your custom module with the following contents:
id: user label: Migrate D7 users. migration_group: my_d7_migration source: plugin: d7_user process: name: name pass: pass mail: mail created: created access: access login: login status: status timezone: timezone destination: plugin: entity:userReputable Drupal migration articles and documentation will explain that migrations need a source (extraction,) some processing (transform,) and a destination (where to load the data.) Often these three concepts will be called ETL. Each of these concepts are easy to spot in our sample configuration file:
- The data is coming from the d7_user plugin (provided by Drupal core with the data source being that of the my_d7_migration group which we configured in a previous step.)
- The processing of the data in this simple migration is just field mapping (to: from.) Many migration configurations have transformations as part of this section, often provided by Drupal process plugins.
- The destination is Drupal user entities.
Again, these instructions are specific to Drupal migration configurations when created as configuration entities. Instructions for migration configuration written as plugins are slightly different (and not covered in this article.)
As we are dealing with configuration entities, they must be imported into the active configuration store - which, by default, is the Drupal database. This is easily accomplished with the drush cim --partial command. This must be run each and every time a migration configuration file is modified. This is one of the (few, in my opinion) downsides of writing migrations as configurations.
Next, I often check the status of migration via the drush migrate:status command. When using the Migrate Drupal module, it is recommended to always use the --group option otherwise the output of migrate:status can get a bit messy (due to all the default migrations that will be displayed.)
The drush migrate:import and migrate:rollback commands should be self-explanatory. Each can be used with either the --group option or with a migration name (as shown below.) I almost always use the --update option on migrate:import for updating previously imported data.
Finally, keep the drush migrate:reset command in your back pocket when writing custom migrations. If the migration crashes, you'll need to use this to reset its status from processing to idle in order to run it again.
Here's a full set of the command specific to the sample user migration, migration group, and custom module created in this article:
$ drush cim --partial --source=modules/custom/my_d7_migration/config/install $ drush migrate:status --group=whatever $ drush migrate:import user --update $ drush migrate:reset user $ drush migrate:rollback userWhat's next?What I've presented in this article is 90% of what I regularly use when running migrations. Sure, there are a few edge cases where oddities occur, but I believe this is a solid base of knowledge to start with.
Once all this makes sense, I encourage you to utilize other blog posts and documentation to extend the user migration we started, or write new ones based on other resources. Once you're comfortable writing additional migrations, learning how to create your own process plugins is the natural next step. As process plugins are written as PHP classes, some knowledge of module development is necessary.
Interested in learning more about Drupal module development? Check out DrupalEasy's 15-week Professional Module Development course!
Additional resources- UnderstandDrupal.com - loads of resources about Drupal migrations from Mauricio Dinarte.
- Tag1's recent series about migrations (also written by Mauricio Dinarte!):
- Migration related modules (definitely not an exhaustive list, but a solid start):
- Migrate plus
- Migrate tools
- Migrate devel
- Migrate process extra - process plugins for migrations.
- Migrate conditions - additional process plugins for migrations.
- Migrate source CSV - allows migrations from .csv files.
- Migration tools - even more process plugins and additional helper classes and methods for migration.
- Migrate upgrade - Drush support for the Drupal core migrations from Drupal 6 and 7.
Lead image generated by OpenAI.
Python Bytes: #393 Dare enter the Bash dungeon?
Golems GABB: Best SEO Practices for Drupal Websites in 2024
If you are enthusiastic about Best SEO Practices for Drupal Websites in 2024 and want to grow your website traffic, you are just in the right place! Drupal is like a wise friend on the web who helps you complete tasks quickly without understanding many programming details. Also, it has some cool tricks that make your website both Google-friendly and user-friendly. And here we go, deeper into optimizing your SEO for Drupal!
Drupal SEO Checklist in 2024All right, let's make a rough Drupal SEO checklist.
Specbee: Top 8 Drupal modules that can improve user engagement
Building and Running QML Android Applications
Qt Creator uses Gradle for project building. Once your project code is ready, select the Android kit for building in Qt Creator. Click build, and Qt Creator will generate Gradle configuration files for you. However, you may encounter errors such as:
Execution failed for task ':processDebugResources'. A failure occurred while executing com.android.build.gradle.internal.res.LinkApplicationAndroidResourcesTask$TaskAction Android resource linking failed aapt2 E 07-23 15:59:44 51907 51907 LoadedArsc.cpp:94] RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data. aapt2 E 07-23 15:59:44 51907 51907 ApkAssets.cpp:149] Failed to load resources table in APK '/home/zhy/Android/Sdk/platforms/android-35/android.jar'.
This is because the current Gradle plugin version does not support android-35. SeeHow to fix "Execution failed for task ':app:processDebugResources'. > Android resource linking failed"[Android/Flutter] - Stack Overflow
To resolve this issue, you need to modify the Gradle configuration.
Navigate to the /build/Qt_6_7_2_Clang_arm64_v8a-Debug/android-build folder in your project.
Open the build.gradle file and locate the dependencies block:
dependencies { classpath 'com.android.tools.build:gradle:7.4.1' }com.android.tools.build:gradle:7.4.1 refers to the Android Gradle Plugin (AGP). This default version is from 2022 and is quite outdated.
You can find the latest version here: Maven Repository: com.android.tools.build » gradle
Update the plugin version to a newer one, for example:
dependencies { classpath 'com.android.tools.build:gradle:8.4.1' }Additionally, when upgrading the plugin version, ensure compatibility with the Gradle version.
Check the relationship between the Gradle and AGP versions here: Android Gradle plugin 8.5 release notes | Android Studio | Android Developers
Therefore, you should use at least Gradle version 8.6 to support this plugin.
Navigate to the ./gradle/wrapper folder and open the gradle-wrapper.properties file. This file defines the Gradle version used by the project.
Find the line: distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
Change it to:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
This update specifies that the project will use Gradle version 8.6.
After making these changes, click on build. It will automatically download the specified version of Gradle and then download the necessary Gradle plugins.
If successful, you can find the built APK at ./build/outputs/apk/debug.
Running and Installing APKIn a Linux environment, you can use the adb command to install the APK on your Android device. Alternatively, you can use Qt Creator for one-click deployment.
After connecting your Android device via USB, use the adb command to install the APK:
adb install android-build-debug.apkMake sure that your Android device has Developer Mode enabled. You can find specific instructions on how to enable Developer Mode based on your device model through an online search.