FLOSS Project Planets

wishdesk.com: Professional Drupal tech support for your website’s smooth work

Planet Drupal - Thu, 2020-04-23 11:05
We offer Drupal support services at very affordable prices through our quick, easy-to-apply, and reliable Drupal helpdesk. Learn more about the tech support by WishDesk in this post.
Categories: FLOSS Project Planets

qed42.com: Authenticated User Cart with Gatsby and Drupal commerce

Planet Drupal - Thu, 2020-04-23 09:29
Authenticated User Cart with Gatsby and Drupal commerce Body

We are building a decoupled E-commerce site with Gatsby and Drupal commerce. As you are well aware of the fact that in all the web applications one of the most important features is user authenticated browsing. I will not go into the details of why user-authenticated browsing is important as you will find plenty of blog posts on that.

This blog post is aimed at users who may find themselves struggling like I did while trying to add the user authentication functionality to a Gatsby site. So let us get started.

Goal
  • User should be able to register
  • User should be able to log in as an authenticated user
  • User should be able to add products to their cart as an authenticated user
Prerequisite
  1. Your Drupal commerce site should be up and going with all the commerce modules enabled that are provided by default.
  2. You should be able to fetch your Drupal data in your Gatsby site.
  3. Also, we will need the commerce cart API module which provides a RESTful interface to interact with our cart in Drupal.
Let’s Get started
  1. Go to REST option under web services and enable all the cart and user resources with the below permissions.

We are done from the Drupal end here. Let’s move to the Gatsby end now.

On Gatsby End 1. Register

The first thing we will do is add user registration functionality.

export const registerUser = async (name, password, email) => { const token = await fetch(`${url}rest/session/token?value`); const sessionToken = await token.text(); if (sessionToken) { const res = await fetch(`${url}user/register?_format=hal_json`, { method: 'POST', headers: { 'Content-Type': 'application/hal+json', 'X-CSRF-TOKEN': sessionToken, }, body: JSON.stringify({ _links: { type: { href: `${url}rest/type/user/user`, }, }, name: { value: name }, mail: { value: email }, pass: { value: password }, }), }); const data = await res.json(); return data; } };

Create your UserRegistration form and pass all the valid arguments to the registerUser function. Now submit your form to see your user registered on the Drupal end under the People tab. In case you get any permission issues, check under config/people/accounts to see if visitors are allowed to register.

Now that our user is registered. Our next step is to log in.

2. Login

Our log in functionality is based on the React Context API. So it is necessary you know how the Context API works.

Visit this link and copy four of the below-mentioned files:

  1. drupalOauth.js.
  2. drupalOauthContext.js
  3. withDrupalOauthConsumer.js
  4. withDrupalOauthProvider.js

Place all four files in a single directory named drupal-OAuth. Next, wrap your base component with DrupalOAuthConsumer to initialise the context provider. Your base component will look something like this:

import drupalOauth from '../components/drupal-oauth/drupalOauth'; import withDrupalOauthProvider from '../components/drupal-oauth/withDrupalOauthProvider'; // Initialize a new drupalOauth client which we can use to seed the context provider. const drupalOauthClient = new drupalOauth({  drupal_root: 'your drupal root url',  client_id: 'your simple OAuth consumer Id',  client_secret: 'Your simple OAuth consumer key', }); // ... the component definition goes here ... export default withDrupalOauthProvider(drupalOauthClient, Layout)

Now to create your sign in or login form take a look at below code:

import React, {Component} from 'react'; import { FaSpinner } from 'react-icons/fa'; import withDrupalOauthConsumer from '../DrupalOauth/withDrupalOauthConsumer'; class SignIn extends Component { constructor(props){ super(props); this.handleSubmit=this.handleSubmit.bind(this); } state = { processing: false, username: '', password: '', error: null, }; handleSubmit = () => { event.preventDefault(); this.setState({ processing: true }); const { username, password } = this.state; if(!username && !password) { this.setState({ processing: false }); this.setState({error: "User name and password doesn't exist"}) } else { this.props.drupalOauthClient.handleLogin(username, password, '').then((res) => { localStorage.setItem('username', JSON.stringify(username)); if(res !==undefined){ this.setState({ open: false, processing: false }); this.setState({ error: 'You are now logged in'}); this.props.updateAuthenticatedUserState(true); setTimeout(() => { document.location.href="/"; }, 3000); } else { this.setState({ processing: false }); this.setState({error: "User name and password doesn't exist"}) } }); } }; render() { const { error, processing } = this.state; return ( Login Now! {error &&

{error}

} username this.setState({ [event.target.name]: event.target.value }) } /> {errors.password &&

{errors.password}

} Password this.setState({ [event.target.name]: event.target.value }) } /> { processing ? FaSpinner : Login } ); } } export default withDrupalOauthConsumer(SignIn);

When you submit the form Drupal will take care of generating the OAuth token and return it to you. To check this you can wrap your component with DrupalOAuthConsumer, and check via the props.userAuthenticated.

To understand in-depth how the code works. You can follow this link.

One thing to note here is that the above code does not take into account the user login on Drupal end. So to be able to log in on Drupal end add the drupalLogIn code to your drupalOauth.js file and call it inside the fetchOauthToken function. So that every time user tries to log in on Gatsby end, user session get’s initiated on Drupal end as well.

/** * Login request to Drupal. * * Exchange username and password. * @param username * @param password * @returns {Promise} * Returns a promise that resolves to JSON response from Drupal. */ const drupalLogIn = async (username, password) => { const response = await fetch(loginUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: username, pass: password, }), }); if (response.ok) { const json = await response.json(); if (json.error) { throw new Error(json.error.message); } return json; }

Remember we are only taking into account the login functionality here. If you are trying to implement the logout functionality as well, make the below piece of code work same as login.

/** * Logout request to Drupal. * * Logs the user out on drupal end. */ const drupalLogout = async () => { const oauthToken = await isLoggedIn(); const logoutoken = oauthToken.access_token; if (logoutoken) { const res = await fetch(`${process.env.GATSBY_DRUPAL_ROOT}/user/logout?_format=json`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${logoutoken}`, }, }); if (res.ok) { return true; } } };

Also, take into account that drupalOauth.js is a class service. So drupalLogin and drupalLogout are the implementation of a class and need some modifications.

Authenticated Commerce Cart

Now that our user is logged in and registered, our next step is to post the data to our commerce cart.

If you go through the commerce cart API documentation. It explains how commerce cart API module works. To post data to the cart as an authenticated user you must be logged in. Once you are logged in. We can POST, GET, UPDATE our cart. Go through below code. Which is fairly simple to understand. We are just taking the access token generated by simple OAuth from Drupal end on login that we have already stored in our browser local storage and sending it as a bearer token as part our request header to the Drupal end so it can recognise that the user is Authenticated.

import axios from 'axios'; const TokenGenerator = require('uuid-token-generator'); const url = process.env.GATSBY_CART_API_URL; class CartService { getCartToken() { const tokgen = new TokenGenerator(); const oauthToken = JSON.parse(localStorage.getItem('drupal-oauth-token')); var myHeaders = new Headers(); let cartToken = ''; if(!oauthToken) { cartToken = (localStorage.getItem('cartToken') !== null) ? JSON.parse(localStorage.getItem('cartToken')) : tokgen.generate(); myHeaders.append('Commerce-Cart-Token', cartToken); myHeaders.append('Content-Type', 'application/json'); localStorage.setItem('cartToken', JSON.stringify(cartToken)); } else { cartToken = oauthToken.access_token; localStorage.setItem('cartToken', JSON.stringify(cartToken)); myHeaders.append('Authorization' , `Bearer ${cartToken}`,); myHeaders.append('Content-Type', 'application/json',); } return myHeaders; } getCartItem = async () => { const header = await this.getCartToken(); const res = await fetch(`${url}cart?_format=json`, { method: 'GET', headers: header }); const cartData = await res.json(); return cartData; } addCartItem = async (id, quantity) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/add?_format=json`, { method: 'POST', headers: header, body: JSON.stringify([{ purchased_entity_type: 'commerce_product_variation', purchased_entity_id: id, quantity: quantity }]) }) const data = await res.json(); return data; } updateCartItem = async (quantity, order_item_id, order_id) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/${order_id}/items/${order_item_id}?_format=json`, { method: 'PATCH', headers: header, body: JSON.stringify({ "quantity": quantity }) }) const data = await res.json(); return data; } removeCartItem = async(order_id, order_item_id) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/${order_id}/items/${order_item_id}?_format=json`,{ method: 'Delete', headers: header, }) if (res.status == 204) { const data = await this.getCartItem() return data; } } removeCart = async(order_id) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/${order_id}/items?_format=json`,{ method: 'Delete', headers: header, }) if (res.status == 204) { const data = await this.getCartItem() return data; } } } const CartHandler = new CartService(); export default CartHandler;

This will allow you to post the cart data as an anonymous user when you are logged in as well as authenticated user once you are logged in. (Add uuid-token-generator) to your packages to make it work.

To add a product to your cart you can simply import the CartService class into your component and use it as :

import CartHandler from '../Services/CartService'; CartHandler.addCartItem(variationId, quantity);

This is it. Cheers! We are done here. We have been able to successfully register the user, authenticate the user and post data to our commerce cart.

P.S -  If you face any issues. Kindly mention in the comments.

 

Danish Shah Thu, 04/23/2020 - 18:59
Categories: FLOSS Project Planets

KDE's April 2020 Apps Update

Planet KDE - Thu, 2020-04-23 09:00

A new bundle of KDE applications is here! In these releases, you can expect to find more features, stability improvements, and more user-friendly tools that will help you work more effectively.

There are dozens of changes to look forward to in most of your favorite applications. Take Dolphin, for example. Windows Samba shares are now fully discoverable.

On the topic of playing music: the Elisa music player is adding features by leaps and bounds. This release brings a new “Now Playing” view, easy accessibility through the system tray, and an option to minimize the playlist whenever you want. Thanks to the recently-added visual shuffle mode, it’s much easier to rearrange your music in the playlists.

These are just the highlights of what’s new in KDE’s applications this month. Read on to find out about everything we’ve prepared for you.

Okular

Okular is KDE’s application that allows you to read PDFs, Markdown documents, comic books, and many other document formats. In this release, Okular received some accessibility improvements for desktop and touchscreen users alike. For the former, Okular now implements smooth scrolling both when you are using the mouse wheel and the keyboard. For touchscreen users, the latest version of Okular comes with inertial scrolling.

Okular smooth scrooling. Illustration: David Revoy, CC-BY-SA-4.0 Dolphin

KDE’s powerful file manager Dolphin adds new features, allowing you to better interact with remote file systems like Samba shares and SSH servers. Now you can start watching movies stored on remote sites without having to download them, and instead stream them directly from the cloud to your player through Dolphin.

In a similar vein, connecting with Windows Samba shares and taking advantage of all the services they offer has never been easier, as Samba shares are now discoverable via the WS-Discovery protocol used by modern versions of Windows. This allows you to seamlessly integrate your Linux box into a Windows network.

As for the news from the usability department: you don’t need your mouse anymore to move focus to and from the terminal panel. Now you can just use the keyboard shortcut Ctrl + Shift + F4. Another long-awaited feature is searching for files not just by their names or content, but also by their tags.

Support for 7Zip files is now built into Dolphin, meaning you can navigate these compressed files as if they were file system folders. When you install external search applications like KFind, Dolphin lets you quickly access them by creating a link.

Finally, a seemingly small feature that can be a big time-saver is the new “Duplicate” function. Select one or more files or folders, hit Ctrl + D (or right-click and choose “Duplicate Here”) and - bam! A copy of each selected item will appear right alongside the originals.

Lokalize

Lokalize is a utility you can use to translate gettext and xliff files. It now supports the Language-Tool grammatical correction, which helps translators by highlighting grammatical errors in the text.

KMail

KMail is KDE’s most popular email client and part of Kontact, a suite of programs that help you manage your emails, contacts, and tasks. Quite a few improvements are included in this new release. For starters, email messages can now be easily exported to PDF, and messages formatted with Markdown are displayed better. The security aspect has also received some attention. More specifically, KMail shows a warning when the message composer opens after clicking a link that asks you to attach a file.

Konsole

Konsole is a terminal emulator that you use to run command-line instructions, processes, and programs. The latest version of Konsole lets you use the Alt key + a number key to jump directly to any of the first 9 tabs.

Gwenview

Gwenview is KDE’s favorite image viewer, and in this version, the developers have resolved two major issues. The application no longer hangs on launch when the system clipboard contains text from KDE Connect, and importing photos to or from remote locations has been fixed.

Elisa

Elisa is a simple and popular music player, and this release features the “Now Playing” view that makes it more attractive.

It’s not all about the looks, though. Elisa is also more functional, as you can now access it through the system tray and minimize the playlist whenever you want. This means you can keep listening to your favorite music even when the main Elisa window is closed. The new visual shuffle mode makes it easier to rearrange your music in the playlists, and shows you which song will be played next.

Kdenlive

Kdenlive is KDE’s advanced video-editing application, and the new version makes editing faster thanks to its configurable preview resolution. The preview also improves multitrack viewing, making it easy to select tracks from the ones you are editing all at the same time.

Down on the timeline, the team has improved snapping clips by only snapping on active tracks. They have also fixed the group snap feature and added a shortcut to bypass snapping on move. Another thing you can now do is directly drop your files (videos, music and images) from your file explorer into the timeline. The new “zooming on keyframes” feature will help carry out more precise work. Professional video editors and users coming from other editing tools will undoubtedly appreciate the OpenTimelineIO import/export feature.

This release of Kdenlive also comes with many bug fixes, like the ones for the Motion Tracker, which was broken on some systems. It now lets you add a Pitch compensation filter, as well as add “Move and resize” to a Rotoscoping shape. The crash of the DVD Wizard and a bug that plagued the changing of the record volume from the mixer have also been sorted. The Kdenlive team has also added tagging, rating, and filtering functionality to the project bin.

The new Windows version of Kdenlive also comes with fixes to the timeline dialogs, which previously didn’t accept keyboard input. Additionally, you can now select the audio backend on Windows.

Yakuake

Yakuake is a terminal window that you can pull down from the top of the Plasma desktop by pressing F12. It is handy for running quick instructions on the command-line, and then moving out of the way.

When you open new tabs or split panes in this version of Yakuake, you can now start them in the same directory as the current tab/split. You can also resize Yakuake’s window vertically by dragging on its bottom bar.

System Settings

The online accounts integration page in System Settings lets you configure things like your Google account, or set up access to your Nextcloud account. The page has been completely overhauled, and now sports a clean, modern look with a much more reliable functionality.

KDE Connect

KDE Connect is an application that helps you integrate your phone with your desktop and vice versa. One of the newest features shipped with this release is the ability to start new conversations with the SMS app.

Other changes include remote media players now showing up in the media player applet, a new set of connection status icons, and improved call notification handling.

In the bug fix department, the error that caused file sharing to block the calling application has been resolved, and the problems with transferring really large files have been sorted out.

Spectacle

Spectacle, KDE’s screen-capturing software, added usability features and resolved some papercuts. One of them prevented you from copying a screenshot to the clipboard when you opened Spectacle from the command-line with the –nonotify option. Although this may have been a niche problem, the point is now you can do exactly that. Likewise, older versions had problems when you tried to drag a screenshot from Spectacle to the default filename pattern that included subfolders. Those problems have been solved.

Another useful improvement in the new version of Spectacle comes in the form of “Defaults” and “Revert” buttons. You can use them to go back to a prior configuration, or even remove all prior custom configurations and restore everything to its default value.

Spectacle will not only remember your default configuration, but also the last used screenshot area. This helps you stay consistent, making it easier to create shots of the same shape and size as your previous ones.

Krita 4.2.9

There were a number of technical upgrades behind the scenes in this release but also smoother paint brush outlines which don’t flicker when you hover over the canvas. “Airbrush” and “Airbrush Rate” was added to the Color Smudge brush, and a new Ratio setting, also for the Color Smudge brush, which allows making the shape of the brush flatter using the different sensors. A new Split Layer into Selection Mask feature allows you to create a new layer for every color in the active layer.

Smb4K

The 3.0.4 release of Smb4K fixes several issues and crashes, especially in the mounter. It also makes Smb4K compilable again with Qt version 5.9 and lower.

KIO GDrive 1.3

This major release of the plugin which integrates Google Drive with KDE’s applications adds a support for the Shared Drives feature of Google Drive.

It also includes a new “Copy Google URL to clipboard” action in the Dolphin context-menu.

20.04 release notesPackage download wiki page20.04 source info page20.04 full changelog

Categories: FLOSS Project Planets

Qt Creator 4.12 released

Planet KDE - Thu, 2020-04-23 05:42

We are happy to announce the release of Qt Creator 4.12!

Categories: FLOSS Project Planets

1xINTERNET blog: The Drupal heart is beating strong

Planet Drupal - Thu, 2020-04-23 05:14
The Drupal heart is beating strong hadda 2020-04-23 - 11:14 Category Drupal Planet Drupal 22. April 2020

Yesterday was a good day for the Drupal community, because it very clearly showed how much power can be released when we stick together

The world has been upside down the last few weeks because of the COVID-19, affecting individuals and businesses around the world. To meet unforeseen financial troubles due to the cancellation of DrupalCon Minneapolis, the Drupal association reached out to the community for help. 

 

Viral donations for the Drupal Association 

#DrupalCares went viral where individuals and companies were encouraged to help the Drupal Association with donations.

Last week Dries and Vanessa Buytaert announced that they would match individual donations up to $100k which then lead to a group of dedicated business leaders in the Drupal ecosystem coming together and deciding to match for another $100k

That means that every $1 donation will become $3. Now that's what I call a positive viral affect! 

1xINTERNET supports the Drupal project

1xINTERNET has always been a driving force when it comes to supporting the Drupal project and the Drupal Association, and therefore we didn’t think twice about taking part. Our whole team is deeply dedicated and I'm so proud of our employees at 1xINTERNET that also donated individually to the project.

Here we are in a powerful group of companies that today announced that together they will match individual #DrupalCares contributions for another $100,000, because we believe in the power of Drupal. We all have the same goal, to see Drupal thrive and grow and continue to be the force it is. 

 

It made my day to receive these positive news about the power of the Drupal community and what we are capable of. Last August I wrote a blogpost about Contributing to Open Source where I highlighted my opinion of the importance of being an active member in our community. I'm now more convinced of how important it is and I'm pretty sure a lot of you agree with me.

#DrupalCares Challenge

We see the purpose highlighted at this time when online presence has never been as important with the world physically shutting down around us. Drupal provides infrastructure for many public health organizations and health care systems that now are delivering information about the COVID-19 pandemic situation to millions of people as well as many Higher Educational websites providing important information to students all over the world.

I encourage you to take part and keep the Drupal heart pumping.

See all information about the status of the #DrupalCare project, its not too late to visit the  donation  page and take part.

Categories: FLOSS Project Planets

Gábor Hojtsy: First week's update on the Drupal 9 Module Porting Challenge; organising a porting day on April 28, 2020

Planet Drupal - Thu, 2020-04-23 03:40

I launched the Drupal 9 Module Porting Challenge a week ago, and wow it is going well! I pledged to donate €9 for each newly Drupal 9 compatible drupal.org project to the #DrupalCares campaign up to a total of €900. Since then Ron Northcutt joined on April 20 with another €900 and Ofer Shaal joined on April 21 with another €450, so the challenge now goes to a total of €2250! Our donation will potentially be matched by Dries and Vanessa Buytaert and then a group of organisations will match it again for a potential total of €6750 donated.

State of the challenge

After a week, my original budget is almost spent, so I am preparing to donate it tomorrow! Let's make Ron and Ofer donate their whole pool as well! We are standing at €837 of €2250 covered by 93 newly Drupal 9 compatible projects in one week.

According to our static analysis at least, over 3600 projects only need a single line info.yml file change and a new release. It is worth checking if one of your projects are in there so we don't let Ofer and Ron keep their money either! ;)

Porting day on April 28, 2020

Some projects will admittedly not be as easy as a one line change though, so I am organising a Drupal 9 porting day for April 28, 2020. I commit to be available in European times to consult on fixing deprecation issues and would love to see you there! Let's meet online in the #d9readiness channel on Drupal slack (drupal.org/slack). We'll use slack threads to discuss projects to help coordinate the work. We may use other tools as needed to speed up the process, still exploring the possibilities. Stay tuned! For now, if you can be available for even one hour, you are welcome to join!

Categories: FLOSS Project Planets

Mike Hommey: Announcing git-cinnabar 0.5.5

Planet Debian - Thu, 2020-04-23 03:21
Please partake in the git-cinnabar survey.

Git-cinnabar is a git remote helper to interact with mercurial repositories. It allows to clone, pull and push from/to mercurial remote repositories, using git.

Get it on github.

These release notes are also available on the git-cinnabar wiki.

What’s new since 0.5.4?
  • Updated git to 2.26.2 for the helper.
  • Improved experimental support for pushing merges.
  • Fixed a few issues with experimental support for python 3.
  • Don’t complain the helper is outdated if it’s newer.
  • Auto-enable graft when cinnabarclone contains a graft that can be fulfilled.
  • Exclude git-cinnabar notes and git-filter-branch backups from graft candidates.
  • Graft failures are more now silent.
  • Fixed handling of a null manifest.
Categories: FLOSS Project Planets

Kushal Das: mod_wsgi and a Python extention

Planet Python - Thu, 2020-04-23 02:40

I was working on a performance analysis of a web API. After I identified the possible issues, I tried to see if I can use a native extension for that part of code (it is a Flask application). In this case the extension was written in Rust. It worked very well. In both test environment and using mod_wsgi-express it was super fast. But it failed when I tried to use it in the production under nginx + mod_wsgi combination. The import modulename statement was just stuck. Causing a timeout in the application. There were no other error messages or log lines.

Found the cause only after having a chat with Graham. After listening to the problem, he told me the solution in seconds. To set the Application Group as %{GLOBAL}.

WSGIApplicationGroup %{GLOBAL}

This is to make sure that we are using the first (main) interpreter, instead of any of the sub-intepreters. The reason explained in the mod_wsgi documentation

The consequences of attempting to use a C extension module for Python which is implemented against the simplified API for GIL state management in any sub interpreter besides the first, is that the code is likely to deadlock or crash the process.

Categories: FLOSS Project Planets

Agiledrop.com Blog: Owen Lansbury, co-founder of PreviousNext: DrupalSouth, running code sprints in the sun & GovCMS

Planet Drupal - Thu, 2020-04-23 02:23

A co-founder of PreviousNext and a member of the Drupal Association Board of Directors, Owen Lansbury is a key figure in the Drupal world, with his company also largely responsible for the mass adoption of Drupal in the Australian government. Find out more about Owen's journey with Drupal in our interview.

READ MORE
Categories: FLOSS Project Planets

James Bennett: Truths programmers should know about case

Planet Python - Thu, 2020-04-23 01:14

A couple weeks ago I gave a talk about usernames at North Bay Python. The content came mostly from things I’ve learned in roughly 12 years of maintaining django-registration, which has taught me more than I ever wanted to know about how complex even “simple” things can be.

I mentioned toward the beginning of the talk, though, that it wasn’t going to be one of those “falsehoods programmers believe about X” things. If …

Read full entry

Categories: FLOSS Project Planets

James Bennett: django-registration 3.0

Planet Python - Thu, 2020-04-23 01:14

Today I’m pleased to announce the release of django-registration 3.0. This is a pretty big update, and one that’s been coming for a while, so I want to take a moment to go briefly through the changes (if you want the full version, you can check out the upgrade guide in the documentation).

This also marks the retirement of the 2.x release series of django-registration; 2.5.2 is on PyPI, and I intend for it to be …

Read full entry

Categories: FLOSS Project Planets

OSTraining: How to Create a Bartik Subtheme in Drupal 8

Planet Drupal - Thu, 2020-04-23 00:00

Subthemes inherit the theme resources of their parent theme. If you want to build your site with Bartik, which is the default theme in a Drupal installation, you will have to create a subtheme. That way, you can make CSS, JS or template overrides to the subtheme, without having to worry about losing those changes when the parent theme gets updated.

Keep reading to learn how!

Categories: FLOSS Project Planets

Tandem's Drupal Blog: Altering Views Ajax in Drupal 8

Planet Drupal - Wed, 2020-04-22 20:00
April 23, 2020 A straight forward guide on how to have your JavaScript fire after each Drupal 8 Views AJAX call is made. Overview We have a client that had a unique situation with one of their views exposed filters setup. We had a set of checkboxes with a set of corresponding images (that were checkboxes with images for labels) that could also ...
Categories: FLOSS Project Planets

Matt Layman: More Onboarding Goodness - Building SaaS #53

Planet Python - Wed, 2020-04-22 20:00
In this episode, we continued with onboarding. I added unit tests for the new form and explained how foreign keys are wired through in CreateView. Then we marched on to the next template in the flow. In the last stream, we set all the context data for the view that shows the form to create a grade level for the school. With the context in place, and the form structure set, I added the form class that will create the GradeLevel record.
Categories: FLOSS Project Planets

The Three of Wands: Building Pyrseia II: Fleshing out Clients and Servers

Planet Python - Wed, 2020-04-22 19:59

This is the second article in the Pyrseia series. The others are:

If you want to follow along with the code, this article refers to commit 2db40614bd926d1ef2854669a634fcfa3ba25502.

Decoupling the API from the Client

The last time we checked in with our small Calculator project, the client and API parts were intertwined, and looked like this:

@client class CalculatorRpc: @rpc async def add(self, a: int, b: int) -> int: ...

Since the server needs to depend on the API too, but we don't want the server to depend on the client, let's split up the API into a separate class.

api.py:

from pyrseia import rpc class Calculator: @rpc async def add(self, a: int, b: int) -> int: ...

client.py:

from pyrseia import create_client from pyrseia.httpx import httpx_client_adapter async def create_calculator_client(url: str) -> Calculator: return await create_client(httpx_client_adapter(url))

Off the bat, creating a client is an async operation now, because the client might need to initialize using the event loop.

Connecting the Client to the network

Creating a client returns a subclass of the API that you can actually use to perform calls. Ideally, we would use Python's type system to stop you accidentally calling the API class directly (i.e. calling api.Calculator().add(1, 2) rather than client.add(1, 2)), but I haven't figured out how to do this yet. (Abstract base classes don't quite fit due to Mypy limitations.)

Following a component-based approach, creating a client requires a client network adapter. The exact type of this argument is AsyncContextManager[ClientAdapter], and ClientAdapter is just a type alias for Callable[[bytes], Awaitable[bytes]]. This looks scary, so let's untangle it.

Essentially, the client needs a component that it can give bytes to and await it to get bytes back. This is exactly described with Callable[[bytes], Awaitable[bytes]]. If you had an instance of this type, you'd use it like this:

async def use(something: Callable[[bytes], Awaitable[bytes]]): res = await something(b"") # res is an instance of bytes.

As we mentioned, this is aliased as (pyrseia.)ClientAdapter to save on typing (pun intended).

So what's the deal with this AsyncContextManager[ClientAdapter] then? Async context managers are basically a more convenient way of making async factories. The client doesn't just need a ClientAdapter, it needs a way to create, asynchronously, a client adapter on every request. If someone handed you an instance of AsyncContextManager[ClientAdapter], here's how you'd use it:

async def use_again(something: AsyncContextManager[ClientAdapter]): async with something as client_adapter: res = await client_adapter(b"") # res is bytes.

Now, maybe not every network library needs to async create a client on every request, but this is a good lowest common denominator. Using this API, we can basically adapt any network protocol library to our clients. Within reason.

I've written two network adapters for our clients: pyrseia.httpx.httpx_client_adapter and pyrseia.aiohttp.aiohttp_client_adapter. Here's the source of the httpx adapter, just for you to get a taste (imports elided):

def httpx_client_adapter( url: str, timeout: Optional[int] = None ) -> AsyncContextManager[ClientAdapter]: @asynccontextmanager async def adapter() -> AsyncGenerator[ClientAdapter, None]: async with AsyncClient(timeout=timeout) as client: async def sender(payload: bytes) -> bytes: res = await client.post(url, data=payload) return res.content yield sender return adapter()

I'm not going to claim this is super simple - there's a lot of complexity in these few lines of code. There's also a lot of power. Hopefully it could be a good starting point if you want to write your own someday. (As long as we keep this API 😉.)

Again, with the proper type annotations, Mypy can check all of this. If your sender, for example, takes a str instead of bytes by accident, Mypy will disallow it.

So, given a server URL, we can create and use the client to access our remote Calculator implementation. And we can pick between two HTTP libraries to do so! There's also an async pyrseia.close_client you're supposed to await to gracefully close your clients.

Servers and Request Contexts

The server component has become generic with respect to two types: the actual API that it's implementing, and a request context class.

A request context is metadata that's specific to every instance of an incoming request. A simple example of request metadata is the remote IP address of the client, although that's HTTP/TCP specific. For example, if the server was connected to a message bus (like Redis pubsub or Kafka) instead of an HTTP endpoint, the request context might not have this particular piece of information.

Since we want the server to be very versatile, we let the creator of the server pick the exact request context class.

So let's say you decide to expose a server for the Calculator interface using HTTP, and you want to use Starlette to be the bridge to the outside world (or the source of requests, depending on how lyrical you're feeling). A good choice for a request context class would then be starlette.requests.Request.

So how does your code use the request context? When you write an implementation for an @rpc endpoint, the first argument to your coroutine can, optionally, be an instance of the request context class. So you could write:

server.py:

from pyrseia import server from starlette.requests import Request from .api import Calculator serv = server(Calculator, ctx_cls=Request) # type: Server[Calculator, Request] @serv.implement(Calculator.add) async def add(ctx: Request, a: int, b: int) -> int: print(ctx.client) # Print the IP address and port of the requester. return a + b

This is also checked by Mypy!

So how do we actually serve our server? Like this.

app.py:

from pyrseia.starlette import create_starlette_app from .server import serv app = create_starlette_app(serv)

and use Uvicorn to start it:

$ uvicorn app:app

create_starlette_app takes a server of type Server[Any, starlette.requests.Request, so Mypy will also make sure you connect these together properly, if you use it. You won't be able to create a Starlette app from a server that expects an aiohttp request.

Speaking of aiohttp, I've also written a helper to create an aiohttp app (pyrseia.aiohttp.create_aiohttp_app) so you have your choice of server tech. Aiohttp apps aren't ASGI apps so they can't be run with Uvicorn, though.

You might want to use your own class for the request context though. Easy bridging what your network runners provide and what you want will be one of the next steps for Pyrseia.

Does this actually work, though?

It does! I've written tests in the repository for all of these adapters (although I use Hypercorn to run the Starlette app), and they work just fine. You could write an app using Pyrseia now!

Pyrseia is still missing a few crucial pieces, though. We don't have control over the wire format, so interoperability is still tricky. Until we deal with this in a flexible way, Pyrseia will only work with itself. We have loftier goals than that, though. We should also consider how to transfer errors/exceptions over the wire.

Stay tuned!

Categories: FLOSS Project Planets

parallel @ Savannah: GNU Parallel 20200422 ('10years') released [stable]

GNU Planet! - Wed, 2020-04-22 17:13

GNU Parallel 20200422 ('10years') [stable] has been released. It is available for download at: http://ftpmirror.gnu.org/parallel/

No new functionality was introduced in parallel so this is a good candidate for a stable release.

This release celebrates GNU Parallel's 10 years as a GNU tool:

> commit ed2dfb1043768154d4e7678e01e10287155fa834
> Author: Ole Tange <ole@tange.dk>
> Date:   Thu Apr 22 01:23:00 2010 +0200
>
>    Name change: Parallel is now GNU Parallel.
>    Basic structure for sshlogin and sshloginfile.


Unfortunately the physical celebrations has been cancelled due to COVID19.

Quote of the month:

  I wish more command line software had example pages as robust as GNU Parallel
    -- Lucidbeaming @lucidbeaming

New in this release:

  • parsort makes GNU sort run faster for files with more than 1M lines.
  • Bug fixes and man page updates.

News about GNU Parallel:

Get the book: GNU Parallel 2018 http://www.lulu.com/shop/ole-tange/gnu-parallel-2018/paperback/product-23558902.html

GNU Parallel - For people who live life in the parallel lane.

About GNU Parallel

GNU Parallel is a shell tool for executing jobs in parallel using one or more computers. A job can be a single command or a small script that has to be run for each of the lines in the input. The typical input is a list of files, a list of hosts, a list of users, a list of URLs, or a list of tables. A job can also be a command that reads from a pipe. GNU Parallel can then split the input and pipe it into commands in parallel.

If you use xargs and tee today you will find GNU Parallel very easy to use as GNU Parallel is written to have the same options as xargs. If you write loops in shell, you will find GNU Parallel may be able to replace most of the loops and make them run faster by running several jobs in parallel. GNU Parallel can even replace nested loops.

GNU Parallel makes sure output from the commands is the same output as you would get had you run the commands sequentially. This makes it possible to use output from GNU Parallel as input for other programs.

For example you can run this to convert all jpeg files into png and gif files and have a progress bar:

  parallel --bar convert {1} {1.}.{2} ::: *.jpg ::: png gif

Or you can generate big, medium, and small thumbnails of all jpeg files in sub dirs:

  find . -name '*.jpg' |
    parallel convert -geometry {2} {1} {1//}/thumb{2}_{1/} :::: - ::: 50 100 200

You can find more about GNU Parallel at: http://www.gnu.org/s/parallel/

You can install GNU Parallel in just 10 seconds with:

    $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
       fetch -o - http://pi.dk/3 ) > install.sh
    $ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
    12345678 3374ec53 bacb199b 245af2dd a86df6c9
    $ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
    029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
    $ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
    40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
    60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
    $ bash install.sh

Watch the intro video on http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial (man parallel_tutorial). Your command line will love you for it.

When using programs that use GNU Parallel to process data for publication please cite:

O. Tange (2018): GNU Parallel 2018, March 2018, https://doi.org/10.5281/zenodo.1146014.

If you like GNU Parallel:

  • Give a demo at your local user group/team/colleagues
  • Post the intro videos on Reddit/Diaspora*/forums/blogs/ Identi.ca/Google+/Twitter/Facebook/Linkedin/mailing lists
  • Get the merchandise https://gnuparallel.threadless.com/designs/gnu-parallel
  • Request or write a review for your favourite blog or magazine
  • Request or build a package for your favourite distribution (if it is not already there)
  • Invite me for your next conference

If you use programs that use GNU Parallel for research:

  • Please cite GNU Parallel in you publications (use --citation)

If GNU Parallel saves you money:

About GNU SQL

GNU sql aims to give a simple, unified interface for accessing databases through all the different databases' command line clients. So far the focus has been on giving a common way to specify login information (protocol, username, password, hostname, and port number), size (database and table size), and running queries.

The database is addressed using a DBURL. If commands are left out you will get that database's interactive shell.

When using GNU SQL for a publication please cite:

O. Tange (2011): GNU SQL - A Command Line Tool for Accessing Different Databases Using DBURLs, ;login: The USENIX Magazine, April 2011:29-32.

About GNU Niceload

GNU niceload slows down a program when the computer load average (or other system activity) is above a certain limit. When the limit is reached the program will be suspended for some time. If the limit is a soft limit the program will be allowed to run for short amounts of time before being suspended again. If the limit is a hard limit the program will only be allowed to run when the system is below the limit.

Categories: FLOSS Project Planets

FSF Blogs: Your FSF membership makes timely, important work possible

GNU Planet! - Wed, 2020-04-22 16:33

The last few months have been eventful to say the least. Putting together our annual LibrePlanet conference is always an inspiring time, in which we engage with new and existing community members about many different free software issues and perspectives. Our annual associate member meeting, also held online this year, brings us focus and helps us understand how the work we do is received. One of the things we learned from the member meeting notes of this year is that it is good to share what we are working on. As a Free Software Foundation (FSF) associate member, you are at the core of our community, so we'd like to share some of the things we're initiating, things that are on our minds, and how you can get more involved!

Connecting people without sacrificing freedom Tackling the problem of nonfree communication platforms

As announced at the LibrePlanet 2020 conference, in the keynote by executive director John Sullivan, we've been building up a working group focused on freedom in communications technology.

The COVID-19 pandemic has given us and the world a reminder of the pressing need for free (as in freedom) communication tools: networks and clients that have user freedom as their top priority.

Living in freedom depends on being able to communicate in freedom. Now, as people are confronted with online communication more than ever, it is important to remain committed to our ethics surrounding them, and we want to provide the knowledge and resources needed for people to take their freedom into their own hands. The aim of the Communicating in Freedom working group is to gather experts, activists, and users to document and address these obstacles.

We have already started our work in this area, for example, by sharing a list of free communication platforms we use to conduct our everyday business. The list provides information to counter the consistent pressure on people to forfeit their freedom and privacy in order to be able to communicate professionally or socially by using applications like Zoom, and other proprietary systems. There is also an ongoing documentation project happening on the LibrePlanet wiki about remote communication tools, and we started the collaborative documentation of resources on public production of COVID-19 related material called Hackers and Hospitals.

Behind the scenes, we have been hard at work helping some institutions use more free software to meet their needs, and we have been thinking about how we can motivate and help provide free resources to people that are not able to set this up themselves. Stay tuned for blog posts and emails that are related to this topic. In the meantime, you can already sign up to the remote communication email list to join this important conversation.

Involving the community in the LibrePlanet conference

The LibrePlanet conference is our pride and joy. Every year, it brings a wide range of free software enthusiasts and newcomers to the movement together to talk about the success and progress of free software globally. We want to do more to involve community members in different elements of the organization of the conference, to keep it dynamic and improving. We're formalizing our plans to bring together a group of community members to assist with the talk selection process. We also want to continue involving people in things like outreach, promotion, organizing and promoting satellite instances, and more.

We're still working on the details, but as we're currently still tingling from the success of this year's online version of LibrePlanet, we'd love to hear from you at campaigns@fsf.org if you see yourself taking on any of these responsibilities.

Update to the High Priority Projects (HPP) list

The High Priority Projects (HPP) list has been an important campaign of the FSF since 2005. The HPP list draws attention to a relatively small number of projects of great strategic importance to the goal of freedom for all computer users. The list serves to foster work on projects that are important for increasing the adoption and use of free software applications and free software operating systems, and it serves as inspiration for community members to initiate projects. We work hard all year on ongoing and new initiatives that take up much of our time, many within the listed priority areas, and we have not had the time to step back to revisit the list since January 2017, but a lot has happened in the free software movement, and with an eye on future developments and opportunities, we feel it is important that the list is updated now.

A public call for submissions for the list will follow shortly after the review committee has been finalized.

Making free software a kitchen table issue Building relationships to grow the movement

Connecting with new audiences, especially young people, is one of our biggest challenges, and we are fully aware of the benefits of collaborations and connecting through media. In this spirit, we interviewed young hackers at the LibrePlanet conference, and asked them to tell us more about their views on free software. The video and audio of this interview will be released soon. We also initiated the Award for Outstanding New Free Software Contributor this year, so we can honor and promote the young enthusiasts that are the future of our movement.

The list of blogs, media outlets, and journalists that we can write to is forever evolving, and building relationships is key, but it takes time. If we want to make free software a kitchen table issue, we need to be at the forefront of media outlets and people's minds. The FSF campaigns team is constantly developing and learning, and though we take this part of our jobs very seriously, we can always use help! We appreciate anyone contacting campaigns@fsf.org us to introduce us to your contacts, or to link us to your favorite blogs and magazines. In the last few months, we have also added a Mastodon account to our list of social media. You can connect with us at https://hostux.social/@fsf.

Speak up for free software to the media

The FSF Community Team is a network of activists who aim to spread the free software philosophy in the press, and in blogs, forums, and social media. The idea is to help the FSF respond immediately to articles, posts, and discussions related to free software. These are non-inflammatory and persuasive rapid responses to those who misunderstand or misrepresent free software. It is a longstanding and important method of activism to have concerned people speaking up directly to media outlets they follow, and explaining why these issues are important in their own words.

Connect with other FSF associate members in the forum

If you haven't already, please join us in the FSF member forum. It is a great place to meet other free software activists. It's a place only members and staff have access to, and therefore guaranteed to be a place where you will find great free software connections.

Your support keeps us going

We're a small team, and we have a high workload and big dreams, and associate members provide the energy and resources to help us make these dreams a reality. We thank the members who gathered online in March at the annual associate members meeting and provided us with thoughtful feedback; but even if you were not able to attend, we can always use your help and your ideas, and we love connecting with you.

Now that remote and digital connections are playing a bigger role in our daily lives than ever before, it is important to communicate about and push for free software continuously. We don't want to come out of this crisis realizing people were forced to give up their freedom in order to live their daily lives with technology. We want to improve conditions now, and even more importantly, we want to build social and technical infrastructure so that we will all be better prepared for a future crisis. We are grateful for your continued support, which is critical in allowing us to do so. Please continue your advocacy for free software, and bring new people into the fold. We need you.

Thank you for being an associate member.

Categories: FLOSS Project Planets

Your FSF membership makes timely, important work possible

FSF Blogs - Wed, 2020-04-22 16:33

The last few months have been eventful to say the least. Putting together our annual LibrePlanet conference is always an inspiring time, in which we engage with new and existing community members about many different free software issues and perspectives. Our annual associate member meeting, also held online this year, brings us focus and helps us understand how the work we do is received. One of the things we learned from the member meeting notes of this year is that it is good to share what we are working on. As a Free Software Foundation (FSF) associate member, you are at the core of our community, so we'd like to share some of the things we're initiating, things that are on our minds, and how you can get more involved!

Connecting people without sacrificing freedom Tackling the problem of nonfree communication platforms

As announced at the LibrePlanet 2020 conference, in the keynote by executive director John Sullivan, we've been building up a working group focused on freedom in communications technology.

The COVID-19 pandemic has given us and the world a reminder of the pressing need for free (as in freedom) communication tools: networks and clients that have user freedom as their top priority.

Living in freedom depends on being able to communicate in freedom. Now, as people are confronted with online communication more than ever, it is important to remain committed to our ethics surrounding them, and we want to provide the knowledge and resources needed for people to take their freedom into their own hands. The aim of the Communicating in Freedom working group is to gather experts, activists, and users to document and address these obstacles.

We have already started our work in this area, for example, by sharing a list of free communication platforms we use to conduct our everyday business. The list provides information to counter the consistent pressure on people to forfeit their freedom and privacy in order to be able to communicate professionally or socially by using applications like Zoom, and other proprietary systems. There is also an ongoing documentation project happening on the LibrePlanet wiki about remote communication tools, and we started the collaborative documentation of resources on public production of COVID-19 related material called Hackers and Hospitals.

Behind the scenes, we have been hard at work helping some institutions use more free software to meet their needs, and we have been thinking about how we can motivate and help provide free resources to people that are not able to set this up themselves. Stay tuned for blog posts and emails that are related to this topic. In the meantime, you can already sign up to the remote communication email list to join this important conversation.

Involving the community in the LibrePlanet conference

The LibrePlanet conference is our pride and joy. Every year, it brings a wide range of free software enthusiasts and newcomers to the movement together to talk about the success and progress of free software globally. We want to do more to involve community members in different elements of the organization of the conference, to keep it dynamic and improving. We're formalizing our plans to bring together a group of community members to assist with the talk selection process. We also want to continue involving people in things like outreach, promotion, organizing and promoting satellite instances, and more.

We're still working on the details, but as we're currently still tingling from the success of this year's online version of LibrePlanet, we'd love to hear from you at campaigns@fsf.org if you see yourself taking on any of these responsibilities.

Update to the High Priority Projects (HPP) list

The High Priority Projects (HPP) list has been an important campaign of the FSF since 2005. The HPP list draws attention to a relatively small number of projects of great strategic importance to the goal of freedom for all computer users. The list serves to foster work on projects that are important for increasing the adoption and use of free software applications and free software operating systems, and it serves as inspiration for community members to initiate projects. We work hard all year on ongoing and new initiatives that take up much of our time, many within the listed priority areas, and we have not had the time to step back to revisit the list since January 2017, but a lot has happened in the free software movement, and with an eye on future developments and opportunities, we feel it is important that the list is updated now.

A public call for submissions for the list will follow shortly after the review committee has been finalized.

Making free software a kitchen table issue Building relationships to grow the movement

Connecting with new audiences, especially young people, is one of our biggest challenges, and we are fully aware of the benefits of collaborations and connecting through media. In this spirit, we interviewed young hackers at the LibrePlanet conference, and asked them to tell us more about their views on free software. The video and audio of this interview will be released soon. We also initiated the Award for Outstanding New Free Software Contributor this year, so we can honor and promote the young enthusiasts that are the future of our movement.

The list of blogs, media outlets, and journalists that we can write to is forever evolving, and building relationships is key, but it takes time. If we want to make free software a kitchen table issue, we need to be at the forefront of media outlets and people's minds. The FSF campaigns team is constantly developing and learning, and though we take this part of our jobs very seriously, we can always use help! We appreciate anyone contacting campaigns@fsf.org us to introduce us to your contacts, or to link us to your favorite blogs and magazines. In the last few months, we have also added a Mastodon account to our list of social media. You can connect with us at https://hostux.social/@fsf.

Speak up for free software to the media

The FSF Community Team is a network of activists who aim to spread the free software philosophy in the press, and in blogs, forums, and social media. The idea is to help the FSF respond immediately to articles, posts, and discussions related to free software. These are non-inflammatory and persuasive rapid responses to those who misunderstand or misrepresent free software. It is a longstanding and important method of activism to have concerned people speaking up directly to media outlets they follow, and explaining why these issues are important in their own words.

Connect with other FSF associate members in the forum

If you haven't already, please join us in the FSF member forum. It is a great place to meet other free software activists. It's a place only members and staff have access to, and therefore guaranteed to be a place where you will find great free software connections.

Your support keeps us going

We're a small team, and we have a high workload and big dreams, and associate members provide the energy and resources to help us make these dreams a reality. We thank the members who gathered online in March at the annual associate members meeting and provided us with thoughtful feedback; but even if you were not able to attend, we can always use your help and your ideas, and we love connecting with you.

Now that remote and digital connections are playing a bigger role in our daily lives than ever before, it is important to communicate about and push for free software continuously. We don't want to come out of this crisis realizing people were forced to give up their freedom in order to live their daily lives with technology. We want to improve conditions now, and even more importantly, we want to build social and technical infrastructure so that we will all be better prepared for a future crisis. We are grateful for your continued support, which is critical in allowing us to do so. Please continue your advocacy for free software, and bring new people into the fold. We need you.

Thank you for being an associate member.

Categories: FLOSS Project Planets

Pages