Push Notifications: A New Feature Added to Ring Project

Push Notifications: A New Feature Added to Ring Project

Push notifications are essential part of the effective end-user experience on mobile platforms. They tend to boost the app engagement and users find them useful and handy as they ease their communications. Although push notifications are widely considered an advantage for most apps, they are regarded most useful for messaging, email and other types of communication apps in general. For this reason, our team of developers have been working hard to make sure Ring is equipped with such critical feature in lockstep with Ring users’ expectations. Today, Ring’s push notification is available for its Android and iOS versions and the users can stay informed of their accounts’ developments while their phones have been idle.

For more details, visit : https://ring.cx/en/news

For further information:

How to Create a Light and Fast-Loading Theme with Liferay?

When It Comes to Websites, Page Speed Matters!

This article is motivated by our website project accomplished by our Integration Platforms and AI Department using Liferay 7 (the latest version of Liferay Portal) for one of our clients– a large Canadian corporation in telecommunications and media industry. Alexis, our front-end developer, shares with you his first-hand experience of this project with the overarching objective to demonstrate how to create a light and fast-loading theme using Liferay portal? 

Right off the bat, we need to acknowledge the fact that, “The average online shopper expects your pages to load in two seconds or less…; after three seconds, up to 40% will abandon your site” (Gomez Inc., 2010). Thus,”page speed is increasingly important for websites” (see Lara Callender Hogan).

Thus, “page speed is increasingly important for websites.”

However, Liferay portal technology itself is not a one-size-fits-all solution. For example, in some cases, if the integrator does not develop a context-specific front-end libraries, the website will be crippled by unnecessary delays. Some experts have also suggested a mainstream recommended method which is to extend the Liferay theme by default. This, however, would result in a technical failure thereby extended web page loading time. Thus, based on the lessons learned from our past projects, i.e. experiential learning, and lucky to have the latest Liferay portal, Liferay 7, we decided to tweak the technology, develop a new module, and adapt it to unique expectations of our client. In what follows we share with you our feedback and the positive test results.

Liferay Portal: A Powerful, Yet Delicate Tool

Liferay is an Open Source Content Management System (CMS) and Portal, written in Java. Therefore, a service provider like us has flexibility to customize it as much as required to fully adapt it to the client’s needs. It provides the developers with an extensive user management, access rights and documents. However, there are some theme specific and performance issues to consider before starting a new website project. Here is a list:

  • Generally, a Liferay theme is home to a bulk of all the front-end libraries and styles needed by Liferay and its portlets. However, a big chunk of the codes and dependencies is useless for a guest visitor. In case of our client, these kinds of visitors form the majority of their users and indubitably the unnecessary code overload will cause performance issues and slow the site down.
  • Liferay imposes the presence of its Design Language, Lexicon (or rather, its only implementation: Clay). This may also cause several problems:
    • Mismatch between Design Language and the client’s design requirements can limit the project’s design feasibility.
    • This situation causes conflicts between CSS rules, therefore increasing the development time.
    • Liferay’s template bugfixes and updates can break the developed styles causing a an increase in maintenance time.
    • With content administration being on the pages, the developed styles can break the behavior of the administration styles also contributing to the increase of the development and maintenance time.

Although these issues impose challenges on a Liferay deployment project, we can offset their impact by developing front-end libraries, as you can read in what follows.

The Solution for Creating a Light and Fast-Loading Theme with Liferay

The solution to benefit from the state-of-the-art Liferay Portal while keeping in check the loading speed is to create a light theme without any Liferay front-end libraries such as senna.js, AlloyUi, Lexicon/Clay, etc.

However, in Liferay 7 this objective cannot be obtained as easy as it looks mainly due to not having the possibility to have an administration view of the site. In order to avoid this issue, we have internally developed a stand alone liferay module which is called “Theme Switcher“. This added functionality allows us to dictate the portal to display a theme according to the role of the user. Here is the link to the github repo: savoirfairelinux/liferay-theme-switcher

5 Steps Towards Setting Up a Light Theme

Here are the five steps for creating a light theme using Liferay 7. But before we get started, let’s look at this instance of a Liferay’s light theme which can be found on GitHub: savoirfairelinux/lightweight-liferay-theme. This theme is created using Maven, and if you wish to modify it you actually can. It is all open source.

Step 1 – Clean Up Your Themes

Remove the inclusions from the portal_normal.ftl file, mainly: <@liferay_util [" include "] page = top_head_include />. But also <@liferay_util [" include "] page = body_top_include /> and so on.

Step 2 – Repair the Themes

Unfortunately, the top_head_include variable does not only contain Liferay’s CSS and javascript libraries, but also many other things. It is therefore necessary to re-include the tags of the head that interest us. For some examples of the tags, consider the following:

  • The meta-tags that the user can define in each pages (keywords, description, etc.):

<@liferay_theme["meta-tags"] />

  • The definition of canonical URLs:
<#if !is_signed_in && layout.isPublicLayout() >
  <#assign completeURL = portalUtil.getCurrentCompleteURL(request) >
  <#assign canonicalURL = portalUtil.getCanonicalURL(completeURL, themeDisplay, layout) >
 
  <link href="${htmlUtil.escapeAttribute(canonicalURL)}" rel="canonical" />
 
  <#assign availableLocales = languageUtil.getAvailableLocales(themeDisplay.getSiteGroupId()) >
 
  <#if availableLocales?size gt 1 >
    <#list availableLocales as availableLocale>
      <#if availableLocale == localeUtil.getDefault() >
        <link href="${htmlUtil.escapeAttribute(canonicalURL) }" hreflang="x-default" rel="alternate" />
      </#if>
      <link href="${htmlUtil.escapeAttribute(portalUtil.getAlternateURL(canonicalURL, themeDisplay, availableLocale, layout)) }" hreflang="${localeUtil.toW3cLanguageId(availableLocale)}" rel="alternate" />
  </#list>
  </#if>
</#if> 

In order to know what to look for, and how, you need to know the basics of jsp which is used to generate the variable top_head_include. For more information, please consult the following link.

Step 3 – Organize the Themes

One of the challenges is that liferay-theme-tasks (link) which is a gulpfile provided by Liferay may not function smoothly. The good news is that you can organize the themes the way you want; i.e. according to your team’s development standards (sass, less, es6, etc.). In case of this client, we have used and embellished the usual gulpfile to our web projects. All headed by Maven and the front-end plugins.

Step 4 – Automate the Deployment of the Themes

Step 4 is perhaps the longest one, but as soon as it is completed you have a turnkey solution at hand. To quickly deploy the light theme files you have developed, take this advice. You do not have to compile and wait for the deployment of the theme for each modification of CSS or JavaScript (the features normally present in liferay-theme-tasks). In the OSGI context of Liferay 7, it is not possible to simply access the theme files (CSS, js, templates, etc.). Thus, you have to do the trick which you can learn by looking at the gulp `deployLocal:syncTheme` task.

The main idea is to transform the deploy module in webbundledir mode instead webbundle.

Step 5 – Enjoy the Developed and Deployed Themes

You now have a Liferay theme, which contains only what you want for your project, and which is deployable like any other Liferay themes. So, it is time to just enjoy the fruit of your efforts.

Results and Robustness Checks

In order to evaluate the performance of the theme(s) created, you can conduct three tests on each page (i.e. instance) with the same content. We have tried these tests, running each one of them on a Liferay server configured for production. Below are the three instances for which we used these tests (on a serveur with 8 CPU and 28Go of RAM, with a SSD disk).

3 Instances Tested for Robustness

  1. A Liferay vanilla theme, the “Classic” theme
  2. The light theme we developed for the client’s web page project
  3. A possible “real” case scenario: the “Classic” theme with more styles and JavaScript of the theme that we have developed for the client.

To perform these 3 tests, we used a local instance of speedtest.io (6.0.3), with Chrome 62. For each test, 10 calls were made, below is the summary of the results.

Results of the Test 1: The Classic Liferay Theme

  • 52 requests
  • 1064.77 kb
  • DOMContentLoaded: 1.24s (±31.95ms)
  • Load: 2.06s** (±52.89ms)
  • SpeedIndex: 1349 (±34.99)

We deemed these results acceptable as we could not find a single glitch in the theme as far as page performance was considered. The results are significant as they pass beyond the threshold for requests. As a rule of thumb, if the number of requests go beyond 40, it is considered a large number of requests.

Results of the Test 2: The Light Theme

  • 37 requests
  • 800.38 kb
  • DOMContentLoaded: 588ms (±42.96ms)
  • Load: 1.17s** (±55.17ms)
  • SpeedIndex: 863 (±39.57)

Fewer queries were made as it was a smaller page. Thus, this custom theme is more powerful than a basic Liferay theme!

Results of the Test 3: The Classic Theme with JavaScript and CSS of the Client’s Light Theme

  • 56 requests
  • 1214.59 kb
  • DOMContentLoaded: 2.22s (±457.34ms)
  • Load: 2.97s** (±458.11ms)
  • SpeedIndex: 2475 (±456.71)

Conclusion

Creating a light theme with Liferay is advantageous as it empowers you to maintain control over your company’s image by managing all the items that are sent to the browser. Liferay technology as a tool coupled with our expertise and years of experience working with it offer your company a solution, a powerful website, to stay on top of your content management efforts signaling a positive image to clients.

Overall, this experience has been an instructive and informative one. Our client and us are genuinely happy for the results are satisfactory and in line with our expectations. It is indeed a powerful website worthy of bearing its brand name.

 

FOSDEM 2018: What Are the Highlights to Remember?

On February 3rd and 4th, two members of Ring’s development team took part in FOSDEM 2018 in Brussels. FOSDEM (Free and Open Source Software Developers’ European Meeting), a major event for free software developers, is held annually since 2000 during the first week-end of February at the Université libre de Bruxelles. Sébastien Blin, a Ring project’s developer, shares with us his recent discoveries made during his visit to the free and open source software world of FOSDEM.

FOSDEM 2018

Sébastien says: “This year was my first experience at FOSDEM! When I arrived in Brussels, I took the opportunity to visit this beautiful city before going into two days of talks, presentations and meetings.”

Some Highlights

FOSDEM is the place to meet countless free software experts, to attend plenty of talks and to explore the most interesting and recent free and open source software projects.

In this event, I represented Savoir-faire Linux and gave two talks: one on Ring Project and the other on OpenDHT with Adrien Béraud. I also seized the chance to personally meet some very interesting developers whom I would not have been able to get acquainted with easily outside this event. All of this kept me quite busy and engaged so much so that I could not attend all the talks on my shopping list! However, here is a brief overview on those talks I participated:

  • Python 3: 10 years later: Python’s history and developments in the last 10 years.
  • GStreamer for tiny devices: some tools to optimize the size of the GStreamer binary (or other binaries) for platforms with little memory space.
  • Anonymous Whistleblowing with SecureDrop: a talk about a software which allows journalists and their sources to exchange anonymously and securely.
  • Speech-to-Text in Jitsi Meet: I was a little bit disappointed by this talk, because they use Google Speech API to do that, and I wanted to discover an alternative to current proprietary solutions. It is still a nice project to follow. It is planned to replace Google Speech API by a solution similar to Mozilla’s Common Voice.
  • Qt GUIs with Rust and GStreamer & Rust: It still good to see big libraries coming on Rust.
  • Tizen:RT : introduction to the Tizen ecosystem and Tizen:RT 

Also, I’m currently waiting to watch the videos of these talks:

It is a different feeling to watch these projects live! You also can attend a lot of talks in the Decentralized Room such as Contributopia (by Framasoft).

Other News

Based on my experience, I believe, one of the best spots to discover new projects was Building K which housed many stands showcasing the most recent projects and novel features of the existing projects. Plus, it was a great place to meet new interesting people! Here’s what I discovered:

  • Godot 3.0 is out!
  • VLC 3.0 is coming out!
  • Krita is now compatible with Python scripts!
  • I discover GitMate.io, I’ll try it soon!

I also discovered many other new features on Fedora, Mozilla, Qubes OS, Nextcloud, SecureDrop, Tor, etc.

My Talks

In FOSDEM I delivered two talks with my colleague Adrien. The details of them are below:

  • Ring as a free universal distributed communication platform

A conference about the state of Ring Project in 2018. The video is here and slides here . In order to explore more resources please check out the GitHub here.

  • OpenDHT: make your distributed project

A conference about OpenDHT. I mainly talked about the proxy feature and push notifications support. Watch the video here.

It was the first time I gave presentations in English in front of more than 200 attendants. It was… awesome! The public was receptive, questions were precise and they led to interesting discussions.

Final Remarks

First, I would like to thank Savoir-faire Linux for offering me the opportunity to talk at FOSDEM. I would also like to thank FOSDEM’s organizing team. They did a fantastic job of organizing about 10,000 participants along with logistics and operations such as scheduling, recording and publishing more than 100 talks online just in a matter of 2 days. It was indeed impressive. My own personal experience organizing tech events made me further realize and appreciate the efforts of the team behind the scene especially as the final outcome wowed the crowd!

Probably the only flip side of FOSDEM 2018 has been the lack of diversity in terms of gender and regions represented in the event. Perhaps, it would be great to encourage more female developers to join the event in 2019 and provide some further support to bring in the free software enthusiasts from less privileged sides of the planet. Free software community is an all inclusive crowd with no boundaries and for this reason we must do our best to celebrate diversity and empower those who need our support.

Inno Weekly #11

Web Development

Getting Started with Server-Side Rendering in Angular

By Kévin Barralon

This week we released a tutorial for developers using the Angular JavaScript framework to set them up with a pre-configured server-side rendering environment. This environment allows for the pre-rendering of an Angular site so that its contents can be made visible to robots (e.g. Google, Facebook, Twitter) and to improve the performance of Angular, as the state of the application is transferred from the server side to the client side.

As these features are new to the framework, the latest version of Angular (v5) is used for the tutorial. You can access the extensive version of this tutorial by reading the blog article: How to Create an Angular Application with Server-Side Rendering?

Bundle Your JavaScript Apps Using Parcel

By Jacob Cook

The JavaScript ecosystem is notorious for evolving very quickly. The modern JS application stack requires a variety of tooling mechanisms, including “bundlers”, which handle the generation and packaging of proper assets for the creation of a Web page. Up until now, two projects have reigned supreme in this space: Browserify and Webpack. They are not particularly known for their ease-of-use: for a preview, you only need to Google “Why is Webpack…” to get thousands of results like “Why is Webpack so slow?” or “Why is Webpack so complicated?”

It’s clear that the ecosystem needs some new utilities that can improve the startup process for cutting-edge JavaScript web applications. There is a new project on the scene called Parcel. This project aims to be an answer to many Webpack-related headaches. It does many things that Webpack does (code splitting, hot module replacement, code transpilation and transformation) with very little if any manual setup and no labyrinthine configuration files to write. It also uses a multicore compilation system, allowing CPU-hogging build operations to be spread across multiple workers and to better take advantage of those fancy processors we all use nowadays.

It remains to be seen if it will emerge as a solid competitor to Webpack, but if initial indications prove true, Parcel will be a huge boon to Web developers that want to get going with a modern project without having to run through their bottles of aspirin. Check out Parcel: https://parceljs.org/

Winter Break!

Thanks for following us for the past 11 editions. Our team wishes you a very happy and restful holiday season.

See you in January 2018!
Your Inno Weekly Team

How to Create an Angular Application with Server-Side Rendering?

Server-Side Rendering Management: An Angular’s Novelty Imposing a Challenge

Angular is a framework using the TypeScript Programming Language. Its 5th version (pentagonal-donut) was released in November 2017, containing new features and bugfixes. It is accompanied by the command line tool Angular CLI and new features such as a server-side rendering framework that has become very popular within the community of Angular users and developers.

However, one of the recurring problems that can be encountered when setting up a website with a modern library (e.g. Angular, React, Vue.js, etc.) is that, in general, web crawlers and robots will not be able to read that website! Therefore, if you want to share your article on Facebook, or simply be well referenced on search engines (i.e. SEO), this part may be complicated (although in the case of Google, it seems that their robots have recently learned to read pages generated by JavaScript).

The reason for this is simple: most robots do not know when your page will be entirely generated by JavaScript. Therefore, they will only be able to read a tiny part of your HTML – which is often a small ‘Loading …‘ message, and not very explicit! So, we are addressing this issue today in this post.

How To Create an Angular Application with Server-Side Rendering?

To overcome this problem we can use Angular CLI – the tool that helps to generate an Angular application from the command line. With its version 5 now available, it is now possible to manage a server state transfer to the client. For example, an application that makes a request to a REST API will not make the same request twice (i.e. on both server as well as client sides) while it can transfer the server-side result to the client. We will study these two cases successively in order to start an application with server-side rendering.

How to Initialize Your Angular Project?

Follow these steps in order to initialize your Angular project:

  • Start by installing the Angular CLI tool: npm i -g @angular/cli
  • Then, initialize the project: ng new ssr-app style = scss # Because it's better with SCSS.
  • Then, go to the directory of the generated application and launch the development server:
cd ssr-app
ng serve
  • Finally, visit http://localhost:4200/ and enjoy!

Now it’s time to configure the server-side rendering management.

How to Configure Server-Side Rendering?

Let’s start by installing the platform-server package: npm i -S @ angular / platform-server

In the file .angular-cli.json at the root of the project, you must add in the “apps” part, the following configuration:

{
   "name": "universal",
   "platform": "server",
   "root": "src",
   "outDir": "dist-server",
   "main": "main.server.ts",
   "tsconfig": "tsconfig.server.json",
   "environmentSource": "environments/environment.ts",
   "environments": {
      "dev": "environments/environment.ts",
      "prod": "environments/environment.prod.ts"
   }
}

In our src / app folder, we now need an app.server.module.ts file next to our app.module.ts file. This will be our entry point for our server-side application. Its content is:

import {NgModule} from '@angular/core';
import {ServerModule} from '@angular/platform-server';

import {AppModule} from './app.module';
import {AppComponent} from './app.component';

@NgModule({
   imports: [
      AppModule,
      ServerModule
   ],
   bootstrap: [AppComponent]
})
export class AppServerModule {
}

The file simply inherits modules from the app.module.ts file and adds the ServerModule module. As for the main.server.js file in the .angular-cli.json, we need to create it next to the main.ts file in the src / directory with the following content:

import {enableProdMode} from '@angular/core';
export {AppServerModule} from './app/app.server.module';

enableProdMode();

We also need to create a tsconfig.app.server.json file for TypeScript compilation next to tsconfig.app.json in the same directory:

{
   "extends": "./tsconfig.app.json",
   "compilerOptions": {
      "outDir": "../out-tsc/server",
      "module": "commonjs"
   },
   "exclude": [
      "test.ts",
      "**/*.spec.ts"
   ],
   "angularCompilerOptions": {
      "entryModule": "app/app.server.module#AppServerModule"
   }
}

In the src / app directory, we now need to modify the app.module.ts file by adding a method to our BrowserModule module:

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';

@NgModule({
   declarations: [
      AppComponent
   ],
   imports: [
      BrowserModule.withServerTransition({ appId: 'universal' })
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule {
}

We can now build our server side / client side application. To do so, add a line in the scripts of our package.json:

"scripts": {
   ...
   "universal": "ng build --prod && ng build --prod --app universal --output-hashing=none",
   ...
}

You may ask, what is this command for? It simply generates, on the one hand, a client-side build and, on the other hand, a server-side build (with reference to our app configured in the .angular-cli.json file). For the server side, we remove the creation of a hash on the file generated main.bundle.js for reference later.

If we run the npm run universal command, we get our two builds in two separate files, dist / and dist-server /.

From now on, we want to be able to launch our server. For now, the Angular Universal Package only supports Node.js and ASP.NET. We will write our server in Node.js.

We must first install the package @nguniversal/express-engine that will bootstrap our server Node.js with the Express framework. So just run the command npm i -S @nguniversal/express-engine.

We will then write a server.js file to the root of our project with this content:

require('zone.js/dist/zone-node');

const express = require('express');
const ngUniversal = require('@nguniversal/express-engine');

/**
* On charge le seul fichier de notre build côté serveur
*/
const bootstrap = require('./dist-server/main.bundle');

/**
* On crée motre instance Express
*/
const app = express();

app.get('/', (req, res) => res.render('index', {req, res}));

/**
* Obtient les fichiers statics provenant de la build dist/
*/
app.use(express.static(`${__dirname}/dist`));

/**
* Configuration de Express Engine
*/
app.engine('html', ngUniversal.ngExpressEngine({
   bootstrap: bootstrap.AppServerModuleNgFactory
}));
app.set('view engine', 'html');
app.set('views', 'dist');

/**
* Toutes les URLs renvoient à l'index.html du répertoire dist/
* Angular se charge se rediriger vers les bonnes routes
*/
app.get('*', (req, res) => res.render('index', {req, res}));

/**
* On lance notre serveur
*/
app.listen(3000, () => console.log(`Listening on http://localhost:3000`));

Time to celebrate! We have successfully configured our Angular application as well as our Node.js server.

Launch the server by typing ‘node server.js’ and go to the URL http://localhost:3000. Your page is server-side generated at launch, and then supported by the client-side build when loaded. If you disable JavaScript in your browser, your page is still generated because you have already properly configured it following these instructions.

How to Transfer the State of the Application?

Although our application works perfectly with this configuration, it is not completely optimal. If your application requires requests via a Rest API, for example, these will be done twice instead of once. Indeed, if the server is requested to make a request, the browser does not know it and will perform the same request a second time when the server side will take over.

For example, we can start by adding the HttpClientModule in our app.module.ts and our app.server.module.ts (the ideal would be to have a module file in common, but I leave you the freedom to do it!):

import {HttpClientModule} from '@angular/common/http';

@NgModule({
   ...
   imports: [
      ...
      HttpClientModule
   ],
   ...
})
export class AppModule {
}

Let’s go into our app.component.ts and delete the content we will replace with:

import {Component, OnInit} from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
   image: any;

   constructor(private http: HttpClient) {
}

ngOnInit() {
   this.http.get('http://www.splashbase.co/api/v1/images/random')
      .subscribe(data => this.image = data);
    }
}

We will display a random image retrieved via a Rest API.

For rendering, let’s edit our app.component.html file that we will replace with this unique tag:

< img *ngIf="image" [src]="image.url" >

This image will be the result of our request to the API.

If we start a build with npm run universal and launch our server with ‘node server.js’, we have our page working correctly. The only downside is that the image appears a few milliseconds and is then replaced by another image. The reason is the same as before, a request is made server side, and another is made client side once the page loaded. The client-side query is therefore useless.

The idea here is to transfer the state of our request to the client side so as not to multiply unnecessary requests. To do so, we will import the ServerTransferStateModule in our app.server.module.ts and the BrowserTransferStateModule in our app.module.ts:

/* app.server.module.ts */
import {ServerTransferStateModule} from '@angular/platform-server';

@NgModule({
   imports: [
      ServerTransferStateModule /* Ici ! */
   ],
   bootstrap: [AppComponent],
})
export class AppServerModule {}

/* app.module.ts */
import {BrowserTransferStateModule} from '@angular/platform-browser'

@NgModule({
imports: [
   ...
   BrowserTransferStateModule /* Ici ! */
   ],
   bootstrap: [AppComponent],
})
export class AppServerModule {}

Once the configuration is done, we can go to our app.component.ts file in order to create a key before the declaration of our Class and to add TransferState in our constructor, such as the following:

import {makeStateKey, TransferState} from '@angular/platform-browser';

const IMAGE_KEY = makeStateKey('image');

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
   ...
   constructor(private http: HttpClient,
      private state: TransferState) {
   }
...
}

Then we modify our ngOnInit method in the following way:

ngOnInit() {
   const image: any = this.state.get(IMAGE_KEY, null);

   /**
   * Si l'image n'est pac contenue dans notre clef, on effectue la requête
   */
   if (!image) {
      this.http.get('http://www.splashbase.co/api/v1/images/random')
         .subscribe(data => {
            this.image = data;
            this.state.set(IMAGE_KEY, data as any);
          });
   }

   /**
   * Sinon, on récupère le contenu de notre clef
   */
   else {
      this.image = image;
   }
}

We then launch a build of our application as well as our server.

npm run universal
node server.js

Now, the content of the image is transferred from the server to the client and the request is made only once!

Conclusion

You are now well equipped with all you need to start an Angular application with server-side rendering configuration. As a precaution, you may now refrain from using all objects available in your browser unreservedly. For example, you may want to verify whether an object is client side or not. Consider the following example:

import { PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

   constructor(
      @Inject(PLATFORM_ID) private platformId: Object,
      @Inject(APP_ID) private appId: string) {
      if (isPlatformBrowser(platformId)) {
         console.log('Je suis appelé côté client !')
      }
    }

All these tips are meant to simplify your Angular developments with all the benefits of server-side rendering! Please stay tuned for more helpful tips…

Press Review Inno #10

Design

What Is Design System?

By Patrick Bracquart

For several years now, the complexity of the websites and applications has pushed us towards rethinking the concept of design, as well as the methodologies we use in the design process. This rethink is pushed by an ever-expanding field of necessary skills and positions in design such as web analyst, UI/UX designer, interaction designer, front-end developer and so forth. It is within this context that the idea of “design systems” has come forward.

A design system is the primary UI/UX reference of a project. It provides us with a guide that can serve as a support for the entire chain of production, no matter the subject matter (fashion, style, food, services, …), the terminal (laptop, mobile phone, smartwatch, …) or even the deliverable (websites, mobile applications, management interfaces, …).

More complete than a simple set of guidelines, this guide does not just describe the (atomic) design elements or the user interactions, it also lays out the development standards that should be followed, the accessibility standards to put in place, as well as iconography and video, to name a few. These guidelines and standards ensure that the entire Design Ecosystem remains perfectly coherent.

Mobile

How to Use Versatile Namespace in Swift?

By Thibault Wittemberg

In Swift, some APIs such as RxSwift use a technique that confines the code they are exposing in a dedicated namespace. This eases a lot the code reading and allows to extend this namespace to add your very own features.

In this post we will see that it is quite simple to create your own namespace and so generically that it allows an external contributor to extend it in an elegant way.

Press Review Inno #9

PyCon 2017 (Part 2!)

Talk: “Double Click: Continue Building Better CLIs”

Summarized by Kévin Barralon

This PyCon Canada talk was a presentation of Click, a Python package that allows you to create CLIs (Command-Line Interfaces) with only a few lines of code.

Click is simple and easy to use, in that the configuration of commands happens almost entirely using decorators around your Python functions. For example, here is a simple function that can be used to repeat the word you pass it as an argument:

# hello.py
import click<span style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" data-mce-type="bookmark" class="mce_SELRES_start"></span>
@click.command()
@click.option('--count', default=1, type=int, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    for _ in range(count):
        click.echo(f'Hello {name}!') # Syntaxe de Python 3.6 !

if __name__ == '__main__':
    hello()

In just a few lines of code, you’ve created a command that can:

  • take an option --count with a default value of 1 and that is type-cast to an integer.
  • take an option --name which allows the user to state their name, thanks to the ‘prompt’ argument passed in the decorator

These values are passed directly as the count and name parameters of the decorated function.

To run this command in your terminal:

python3 test.py --count=3
Your name: Casimir 
Hello Casimir!
Hello Casimir!
Hello Casimir!

The other interesting (and practical!) point here is that if you pass the option --help when you call the command, you can see the docstring for your function, as well as information on each option that your comamnd supports thanks to the argument help passed in your decorators:

python3 hello.py --help

Usage: test.py [OPTIONS]

Simple program that greets NAME for a total of COUNT times.

Options:

Count INTEGER Number of greetings
Name TEXT The person to greet
Help Show this message and exit.

Rather than simply passing options to your command, you can also specify arguments. For example:

@click.command()
@click.argument('filename')
def touch(filename):
    click.echo(filename)

Then:

python3 touch.py foo.txt
foo.txt # Résultat

As you can see, the possibilities with Click are endless. Here are a few additional ones for fun:

  • Add the argument multiple=True in your decorator @click.option which will give you a tuple of all options passed to your command.
  • Add a callback as an argument to @click.option which will change the behaviour of your command (to define custom validation rules, for example).
  • Pass environment variables to your decorator (like so: envar="USERNAME").
    Define a limited or unlimited number of arguments that will return a tuple.
  • Add a File method as a type in your decorator (example: @click.argument('input', type=click.File('rb'))) which will automatically open a specified file and close it when necessary.

A list of all possibilities offered by this Python package is available in the documentation, which is indeed very well done.

Bonus!

The closing keynote on f-strings really seemed to motivate our team! Here’s an article by Maxime which adds to the one by Sébastien from last week:

What in the World Are F-Strings?

By Maxime Dupuis

The mechanism of Literal String Interpolation, known as f-strings, is a new arrival in the latest version of Python, 3.6. They are recognizable by the f (or F) at the beginning of a declaration of a string: f'My f-string!'. They are very similar in behaviour to template strings in JavaScript, which are defined using the ` character.

F-strings are useful because they can reference variables that will be automatically interpolated with the values of the local variables defined under the same name.

>>> age = 42
>>> first_name = 'Maxime'
>>> f"My name is {first_name} and I'm {age} years old"
"My name is Maxime and I'm 42 years old"
>>> # The use of an undefined variable will give us a NameError:
>>> f"{notdefined}"
Traceback (most recent call last):
  File "<stdin>;", line 1, in <module>
NameError: name 'notdefined' is not defined

They become very interesting when you consider their impact on performance. If we compare them to other ways to create strings in Python, we have the following:

python3.6 -m timeit -c 'age=42; first_name="Maxime"; f"My name is {first_name} and I'm {age} years old"'
10000000 loops, best of 3: 0.172 usec per loop
python3.6 -m timeit -c 'age=42; first_name="Maxime"; "My name is {first_name} and I'm {age} years old".format(first_name=first_name, age=age)'
1000000 loops, best of 3: 0.714 usec per loop
python3.6 -m timeit -c 'age=42; first_name="Maxime"; "My name is %s and I'm %s years old" % (prenom, age)'
1000000 loops, best of 3: 0.283 usec per loop
python3.6 -m timeit -c 'age=42; first_name="Maxime"; "My name is " + prenom + " and I'm " + str(age) + " years old"'
1000000 loops, best of 3: 0.449 usec per loop
python3.6 -m timeit -c 'from string import Template; age=42; first_name="Maxime"; Template("My name is $first_name and I'm $age years old").substitute(first_name=first_name, age=age)'
100000 loops, best of 3: 8.75 usec per loop

But it’s not only useful for its performance benefits. We can use f-strings to call functions, modify substrings, and many other things:

>>> total = 10.0
>>> taxes = 1.15
>>> f'Total: {total + taxes}'
'Total: 11.15'
>>> first_name = 'Maxime'
>>> f'My name is {first_name.upper()}'
'My name is MAXIME'

If f-strings interest you or you haven’t yet discovered all of the new things that Python 3.6 has to offer, check out the release notes.

Mobility

SwiftGen

By Thibault Wittemberg

When we develop an iOS app, we regularly need to access resources. The traditional way to use them in the code is to instantiate them with their identifiers (strings):

let avatar = UIImage(named: ‘darthVader’) // gets the ‘darthVader’ image from the assets folder
let name = NSLocalizedString (‘darthVader’, comment: ‘’) // gets the localized string with the key ‘darthVader’ from the Localizable.strings file

The same goes for fonts, storyboards and colors.
Swift is a strict language about type management and promotes the detection of errors at compile time rather than at run time.

That being said, what happens if one of the resources we want to instantiate is not found at run time? Since this instantiation is based on a string, it is subject to errors (typo errors). Therefore, we can use the SwiftGen tool which allows to secure this kind of manipulation:

  • It avoids typo errors
  • It allows auto completion
  • It ensures that the resources exist at compile time.

It operates as follows:

  • The “SwiftGen” executable is installed on the development workstation (either via Homebrew or via CocoaPods)
  • A custom build phase launches this executable for each compilation
  • SwiftGen scans the project’s resources and generates the Swift code representing them in a “type safe” manner

The resource identifiers will be transformed into enums that are much more secure and easy to use. Consider the following example:

let avatar = Asset.darthVader.image
let name = L10n.darthVader

It is even possible to customize the templates that will be used to generate the code if you want to apply a different coding style.

When combined with the “Reusable” framework (from the same author), we have tools that are almost mandatory (and we use them a lot at Savoir-faire Linux).

SwiftGen is made to be integrated with your continuous integration environment (the executable can be embedded in a CocoaPods dependency, it avoids installing it on the build machine). Read more on GitHub!

Contributions

New Release of num2words v0.5.6 with Support for New Languages!

By Ernesto Ortiz

It has been five months since the previous release of num2words v0.5.5, and these have been five really active months. A lot of new contributors have made some great improvements and have added support for new languages! Here are some of the latest changes, with “special thanks” to the contributors!

  • ‘Num2words’ has changed its coding conventions to follow PEP8. Code coverage has increased a lot, and we need your help to continue improving this, so check out the issues related to num2words
  • Now we can use other converters like to_currency, to_year, to_ordinal_num
  • Thanks to Tufan Kaynak for adding support for the Turkish localization
  • Thanks to Jesús Leganés-Combarro for adding support for Algerian French localization
  • Thanks to Armin Oliya for adding support for the Dutch localization
  • Thanks to Sergio Zholudov for adding support for the Ukrainian localization
  • Thanks to Blaž Bregar for adding support for the Slovenian localization
  • Thanks to Mārtiņš Šulcs for making a lot of improvements to the base code, to_currency functionalities and more!

Special thanks to everyone that has taken the time to report new issues, to make pull requests and to share their time and effort with this project!

You can check the new release at the following links:

Press Review Inno #8

Special Edition on PyConCa 2017

This week, we attended PyCon Canada which started on November 18 and lasted through 21. We are also proud and happy that we played a role in sponsoring this dynamic event. In this Special Edition of Press Review Inno, you find articles from our SFLers who actively participated in the event’s sessions.

PyCon 2017

Our Team Who Attended PyConCa 2017

 

Tutorial: Writing Tests that Write Themselves by David Kua

Summarized by Ernesto Rodriguez Ortiz

Stop worrying about corner cases and start loving the power property-based testing.

I just discovered the concept of property-based testing at PyCon Canada 2017, thanks to David Kua who prepared, showed and shared with us a great tutorial of property-based testing using the library Hypothesis. (Welcome to Hypothesis!)

In fact, the concept of property-based testing was popularized by the Haskell library Quickcheck. I am happy about my new discovery because I find myself too often thinking about corner cases in my tests, and now I don’t need to spend as much time considering this, as they will show up themselves with the help of Hypothesis.

So How Does This Work?

Hypothesis generates random data matching your specification and checks that your guarantee still holds up for each test case. Check out this really simple example:

# FILE NAME division.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
# You wrote these two lines way too fast...
def division(x, y):
    return x / y
 
# Hypothesis will now show you your mistakes...
from hypothesis import given, settings
import hypothesis.strategies as st
 
@given(st.integers(), st.integers())
@settings(max_examples=1000)
def test_commutativity_pbt(x, y):
    assert division(x, y) * y == x

Then run:

pytest --hypothesis-show-statistics division.py

You should see how Hypothesis has found the corner case:

ZeroDivisionError: division by zero

This is powerful stuff, so go play a little with the awesome tutorial prepared by David Kua and check the documentation of Hypothesis.

Closing Keynote – Mariatta Wijaya

Summarized by Sébastien Blin

During the closing keynote, Mariatta Wijaya, a Python Core Developer, presented us Python 3.6 through the lens of a PEP (Python Enhancement Proposal) that has been released in this version: PEP 498: Literal String Interpolation.

Mariatta explained the history of this PEP, from its beginnings as a Python mailing list post since a few years ago. The new feature introduced in this PEP, colloquially called “f-strings”, allows for an improved experience in creating strings with variables in them, all the while improving performance and making for a more codebase than when the % operator or str.format functions are used.

>>> import datetime
>>> name = 'Fred'
>>> age = 50
>>> anniversary = datetime.date(1991, 10, 12)
>>> f'My name is {name}, my age next year is {age+1}, my anniversary is {anniversary:%A, %B %d, %Y}.'
'My name is Fred, my age next year is 51, my anniversary is Saturday, October 12, 1991.'
>>> f’He said his name is {name!r}.'
"He said his name is 'Fred'."

She then gave a brief overview of the other PEPs released with Python 3.6 (including PEP 628 which adds math.tau, which did not exist prior, and the value of which is 6.28). The complete list of PEPs in Python 3.6 is available at Python 3.6 Release Schedule.

In any case, Mariatta invites us to upgrade to Python 3.6 as soon as possible, as well as to contribute to the evolution of the programming language through the creation of new PEPs at this GitHub repo.

Contributions

GitHub Releases a Team-Based Discussion Feature

By Romain Bertozzi

To contribute to open source software means to share with others, so it only follows that the ability to effectively communicate is critical. GitHub announced a new feature on the 20th of November centered around team-based discussions.

The idea of this feature is to create a space for conversations within a project that might not be best placed under issues or pull requests. These issues and PRs will now be freed up and will be less of a magnet for long, irrelevant comment threads. In addition to this, these new discussions, public or private, will have dedicated URLs and will be able to be easily shared and cited on other sites.

Here at Savoir-faire Linux, we welcome this news enthusiastically. We believe that it will bring more clarity around the discussions related to the creation, management and direction of a project. The centralization and the ease-of-use of these discussions are benefits that will allow for more transparency and longevity of conversations. It remains to be seen how this functionality will be adopted by GitHub users, who already have many different options available to them that they may be more used to.

Press Review Inno #7


Mobility

 

Generic Protocols and Type Erasure in Swift

With Swift, you can define protocols by associating one or more generic types. These types are defined using the associatedtype” keyword. The name Generic Type” is a bit misused here. We should actually talk about a placeholder for a reserved type. Indeed, we will see that such protocols do not offer great flexibility of use when we consider them as generic.

Useful Information:

 

Web Development

Django 2.0 Release Candidate Now Available

By Kévin Barralon

The Django web framework just published the first release candidate of its upcoming 2.0 version. Django 2.0 is scheduled to be released on December 1st.

Don’t be fooled by the name – this new major release of Django will not bring any major significant changes to the framework. The changes in the latest version should be of the same scale as those found in past new releases.

Despite this, the most important change in the 2.0 release is its incompatibility with Python 2.7, the support for which is scheduled to last only until 2020. Django 2.0 will only support a minimum version of Python 3.4, and of course it is highly recommended to go directly to the most recent version of Python, which is presently 3.6.

URL Routing

In terms of new features, the new function django.urls.path() renders the URL routing syntax much simpler and easier to read. So, instead of having to write url(r'^articles/(?P[0-9]{4})/$', views.year_archive), you can write path('articles//', views.year_archive). This new syntax will also allow the view to receive the URL arguments with the proper type already defined (a whole number in the case of year above, instead of a string).

It is still not possible to add a constraint to the URL route directly (in this example, the fact that the year should only consist of four digits). The current function django.conf.urls.url() will be replaced by django.urls.re_path() which will keep the existing functionality of allowing regular expressions to be placed in the definition of the route.

The functiondjango.conf.urls.include() will also be directly available under django.urls. This will allow you to import your modules like from django.urls import include, path.

Other New Things

Helpful Links:

Deploying Entire Services with Docker Swarm and GitLab CI

by Jacob Cook

Here at Savoir-faire Linux, I work on the deployment infrastructure for many of our hosted services, and am constantly looking for ways to improve our DevOps practice. Currently the deployment pipeline is centered around the use of Ansible to manually provision a service inside a virtual machine and adjust as necessary. But in an effort to make builds and deployments faster and more stable for our developers, we are looking at new approaches, including the use of Docker builds pushed to a registry and subsequently deployed using a pipeline like GitLab CI.

One of the tools that can be used to deploy a micro-service architecture (created with docker-compose) is called Docker Swarm. Using a set of servers configured to act in a swarm, one can deploy a stack of containers in a simple pattern with only docker stack deploy. Docker will then automatically choose the appropriate servers in the swarm to deploy to, and handle networking between the services just as if you were using docker-compose on your local machine. Neat, huh?

The best part is that it plays nicely with our existing build system in GitLab CI. We can build, test, release and deploy across our infrastructure using GitLab CI and GitLab Container Registry. There are still pieces of the puzzle to work out but it represents a major leap forward in the simplification and stability of our DevOps practice.

Further Reading:

Ring Universal Communication Platform Now on Android TV!

Ring keeps surprising communication experts and enthusiasts! Ring is now available on Android TV box and other smart TVs. Ring has become the only  communication software available on the Google Play Store for Android TVs, since the discontinuation of support for the TV version of Skype in June 2016. This new release is quite different from its mainstream app which can be downloaded on a myriad of devices such as cellular phones, tablets, Mac and PCs.

Recall that Ring is a free, distributed and universal communication software, available under the GPLv3+ license. Ring users can communicate in different ways, using it as a telephone (VoIP), a media sharing tool (audio/video), a messaging system, or as a communication platform for connected devices such as the case of the Internet of Things (IoT). Ring is often seen as a free and open source alternative to Skype. Its success is based on a distributed and decentralized network that guarantees a high level of privacy and confidentiality for its users. The Ring project – which became a GNU package in 2016 – has the unwavering support of the community of developers around the world as well as the Free Software Foundation.

Rethinking Ring for the Android TV

In order to make sure you will have a satisfying and enjoyable user experience, our developers have reworked the user interface of the Android Ring application to adapt it to Android TV standards. To accomplish this task, it was necessary to rethink the ergonomics and navigation of the Ring application to ensure it functions with a remote control and graphic components offered by the platform.

In fact, the architecture pattern underlying Ring Android application allows  developers to transfer the entire dependencies and data parts of the mobile version onto the TV app so as to be able to completely focus their attention on the GUI part.

Usability constraints have led developers to focus on key features like:

  • Contact search,
  • Online audio/video calls,
  • Shared screen display from the caller.

These features remain small, but the development continues to offer in coming weeks, expanded use possibilities. Having been designed with the objective of simplicity, stability and user-friendliness,  Ring can serve both domestic and professional needs. It can be used on Android TVs to connect family members together, or simply replace conference phones in corporate meeting rooms.  In fact, availability of the Ring as a TV app on the Google Play Store makes it an easier-to-use communication platform, in comparison to a secondary computer or display setup.

Ring on Android TV

Help us to improve Ring!

Ring is constantly improving to offer the best of communication. As the software is in active development process, some bugs remain and many challenges still await our team of developers. The assessments provided by the community of users, testers, and developers on the quality and use of the platform are then essential to help us identify problems, resolve them, and improve the experience.

For the next release of Ring on Android TV, lot of questions are focused on the compatibility of systems and webcams, other than Logitech as well as NVHI hardware. Also, we encourage curious, free software users and enthusiasts to test Ring on different medias and different systems. Your experience was a success? or crashes remain with your TV or TV box? Send us your comments at Ring@savoirfairelinux.com. You will also contribute to the success of Ring!

Download Ring on Android TV

If you want to experience this new communication platform, just download it for free from Google Play Store!

For further information: