Building Drop-Down Menu

Meilix Generator has a dropdown menu which consists of links to code, issues and different FOSSASIA projects. The drop down menu appears after clicking on 3×3 dots present on the top right corner. The menu gets closed while clicking on the same dots. We want the menu to close close when we click somewhere else on the screen.

The problem statement is to close the menu bar while clicking anywhere on the white screen of the web app.

Solution:

For that I have to add a listener to the rest of the body to add class “hidden”.

We first remove the old onclick listener from the body tag which open the pop-up to show up the option. We replace it with its class.

<div onclick="document.getElementsByClassName('custom-menu-cont')[0].classList.toggle('hidden')" class="custom-menubutton">
      <i class="glyphicon glyphicon-th" style="font-size:20px;"></i>
    </div>

 

<div class="custom-menubutton">
      <i class="glyphicon glyphicon-th" style="font-size:20px;"></i>
    </div>

 

Then the dropdown menu doesn’t open while clicking on the dots also. So we added a script outside the body tag to

  • Open the dropdown menu pop-up on clicking on the 3×3 dots.
  • Close the pop-up while clicking on that dots or anywhere on the white screen of the webapp.

<script type="text/javascript">
	function hideDiv(){
        document.getElementsByClassName('custom-menu-cont')[0].classList.toggle('hidden')
}
document.addEventListener("click", hideDiv);	
</script>

 

We are working in html so we have to add the type of the script. We add the function hideDiv to open and close the pop-up while clicking on dots.

We then add the eventListener to hide the pop-up while clicking anywhere on the screen.

Reference:

Stackoverflow Pop-up closing

Adding JS in HTML W3School

 

 

Build Button Resolution in Meilix

Meilix Generator is a webapp which has a build button and after clicking the button it triggers the travis of Meilix repository. You can even generate ISO from your phone. But while opening the web app on a phone, we came to see that the build button is not properly visible. Footer of the page hide the build button. This blog shows the way to identify the build button issue and to make it responsive for all screen sizes.

Error Rectification

There are two elements that need correction:

  • Build button
  • Footer

Build Button

<input class="btn btn-info mx-auto btn-block" id="file-upload" value="Build" required="" type="submit">

 

Here build button act as a input submit button.

class="form-group"> class="btn btn-info mx-auto btn-block" id="file-upload" value="Build" required="" type="submit" style="height: 50px; width: 360px; border-radius: 500px;"/>

 

We first added the group to include the button in that form. Then we add the build button property to give the button certain look.

But now also the footer overlap the button. So now we need to work on footer part.

Footer

<footer class="footer">

 

We remove footer class and made a new div tag with the id = “deployment”. Then we set the css for the deployment id to customise its appearance.

     #deployment {
      position: absolute;
      text-align: center;
      width: 100%;
      padding: 10px;
      bottom: 0px;
      border-top: 1px solid #bfbfbf;
      background-color: #f9f9f9;
    }

 

This set the footer and build button appropriate to become responsive for all sizes.

Reference:

HTML form tag

Input type Submit tag

Adding Features into Meilix Generator Webapp

Meilix Generator is a webapp generated in FOSSASIA which takes input from user and send it to Meilix to trigger a build. Then a release is made whose link is emailed to the user. The webapp contains a form where there are fields for installing a particular packages, etc. In the following we will discuss about the ways to achieve the configurations in Meilix ISO without even touching the Meilix repo.

For adding an option in the webapp:

Editing the frontend

We need to edit this line in the index.html with this line:

<input name = "GENERATOR_package_vlc" type = "checkbox" value = "vlc" id = "vlc">

 

Making the script

Then we have to add a script in the script folder. This script is called by Meilix build script. This script contains the variable “GENERATOR_package_vlc”.

We name this file vlc-package.sh

Content:

#!/bin/bash
if echo "$GENERATOR_package_vlc" | grep -q vlc; then 
sudo apt-get install -q -y vlc; fi

 

Line 2 checks that the vlc is checked in the checkbox or not, if it is checked then the other next line gets executed otherwise not.

Calling the script from Meilix (needs to be done only once)

We will add a line in the Meililx build script to call those script present in the Meilix Generator repo.

SCRIPT_URL=https://www.github.com/fossasia/meilix-generator/archive/master.zip
wget -O $scripts.zip $SCRIPT_URL
unzip scripts.zip
SCRIPTS_FOLDER_IN_ZIP="meilix-generator-master/scripts"
ls $SCRIPTS_FOLDER_IN_ZIP; do
$SCRIPTS_FOLDER_IN_ZIP/script; done			#execute all scripts

 

Setting the URL via travis build config post to get all the values starting with GENERATOR_

GENERATOR_ = request.form['GENERATOR_']

 

So overall the abstract of the idea is:

  1. Getting the variables from html to travis as environment variable
  2. Cloning the meilix repo
  3. Executing all the scripts present.

References:

Request HTTP Python

Online Installation media

 

Implementation of Features in Generator UI

In the early stage of development, Meilix Generator only has wallpaper and event name customization. But today the webapp has bunch of customization and features list which enables an user to design its own customizable ISO.

Iteration in the form

Meilix Generator came across several changes in the form throughout the time.

At starting we only have an email part where the ISO get mailed, a name for the event so as to distinguish the ISO image and an image upload which will be set as the default desktop wallpaper in the ISO.

Then the user gets a link which get activated after 20 minutes. Till then user have to preserve the link to download the ISO.

Then we introduced a new field which contains event link and this link will be set as the homepage of the browser. And we change the basic UI of the webapp.

At the same we implemented SendGrid to send the user the email link in their mail. This decreases the burden of carrying the downloadable link till the ISO becomes ready.

Finally today Meilix Generator looks like this. It got some more customizable fields like providing default search engine, bookmark enabling or disabling and packages to include in the ISO.

It has a link on the footer from which the latest pre-build ISO can be downloaded instantly and another link which takes user to the releases page of Meilix.

Reference:

SendGrid Email Delivery Service

SendGrid Email API

Deleting Meilix Github Releases

Meilix is the repository which uses build script to generate community version of lubuntu as LXQT Desktop. Meilix-Generator is the webapp which uses Meilix to generate ISO and deploy it on Meilix Github Release. Then the webapp mail the link of the ISO to the user.
Increasing number of ISO will increase the number of releases which results in dirty looking of Meilix repository. So we need to delete older releases after certain interval of time to make the repository release page looks good and decrease unwanted space.
This releases_maintainer.sh script will do this work for us.

#!/usr/bin/env bash
set -e
echo "This is a script to delete obsolete meilix iso builds by Abishek V Ashok"
echo "You have to add an authorization token to make it functional."

# jq is the JSON parser we will be using
sudo apt-get -y install jq

# Storing the response to a variable for future usage
response=`curl https://api.github.com/repos/fossasia/meilix/releases | jq '.[] | .id, .published_at'`

index=1  # when index is odd, $i contains id and when it is even $i contains published_date
delete=0 # Should we delete the release?
current_year=`date +%Y`  # Current year eg) 2001
current_month=`date +%m` # Current month eg) 2
current_day=`date +%d`   # Current date eg) 24

for i in $response; do
    if [ $((index % 2)) -eq 0 ]; then # We get the published_date of the release as $i's value here
        published_year=${i:1:4}
        published_month=${i:6:2}
        published_day=${i:9:2}

        if [ $published_year -lt $current_year ]; then
             let "delete=1"
        else
            if [ $published_month -lt $current_month ]; then
                let "delete=1"
            else
                if [ $((current_day-$published_day)) -gt 10 ]; then
                    let "delete=1"
                fi
            fi
        fi
    else # We get the id of the release as $i`s value here
        if [ $delete -eq 1 ]; then
            curl -X DELETE -H "Authorization: token $KEY" https://api.github.com/repos/fossasia/meilix/releases/$i
            let "delete=0"
        fi
    fi
    let "index+=1"
done

This code uses Github API to curl the Meilix releases. Github API is very useful in providing lots of information but here we are only concerned with the release date and time of the build.
Then we setup a condition if that satisfies then the release will automatically will get deleted.

For taking care of the authentication, a token has been uploaded to the Travis settings of Meilix of FOSSASIA.

The personal token has been generated by a user with write access to the repository with repo scope token.

This sort out the issue of having bulk of releases in the Meilix repository of FOSSASIA.

References:
Users Github API  by REST API v3
Repo Github API   by REST API v3

Wallpaper Strategy for Meilix Generator

We were first hosting the wallpaper uploaded by user on the Heroku server which was downloaded by the Travis CI which was previous solution for sending wallpaper to the Travis CI, but the problem was that wallpaper was downloaded only when build started building the ISO.

Downloading the hosted wallpaper was not a problem but the problem in that method was that the wallpaper hosted can be changed if another user also starts the build using Meilix Generator and uploads the wallpaper which will replace the previous wallpaper so simultaneous builds was not possible in previous method and resulted in conflicts.

So we thought of a sending the wallpaper to the Travis CI server for that we used base64 to and encoded it to a string using this.

with open(filename,'rb') as f:
    os.environ["Wallpaper"] = str(base64.b64encode(f.read()))[1:]

 

After uploading we send it as a variable to Travis CI and decode it. We will receive a binary file after decoding now we need to detect the mime type of the file and rename it accordingly before applying for that we use a script like this.

#renaming wallpaper according to extension png or jpg
for f in wallpaper; do
    type=$( file "$f" | grep -oP '\w+(?= image data)' )
    case $type in  
        PNG)  newext=png ;;
        JPEG) newext=jpg ;;
        *)    echo "??? what is this: $f"; continue ;;
    esac
    mv "$f" "${f%.*}.$newext"
done

 

After fixing the wallpaper extension we can apply it using the themes by replacing it with the theme wallpaper.

Resources

Base64 python documentation

How to Send a Script as Variable to the Meilix ISO with Travis and Meilix Generator

We wanted to add more features to Melix Generator web app to be able to customize Meilix ISO with more features so we thought of sending every customization we want to apply as a different variable and then use the scripts from Meilix Generator repo to generate ISO but that idea was bad as many variables are to be made and need to be maintained on both Heroku and Travis CI and keep growing with addition of features to web app.

So we thought of a better idea of creating a combined script with web app for each feature to be applied to ISO and send it as a variable to Travis CI.

Now another problem was how to send script as a variable after generating it as json do not support special characters inside the script. We tried escaping the special characters and the data was successfully sent to Travis CI and was shown in config but when setting that variable as an environment variable in Travis CI the whole value of variable was not taken as we had spaces in the script.

So to eliminate that problem we encoded the variable in the app as base64 and sent it to Travis CI and used it using following code.

To generate the variable from script.

with open('travis_script_1.sh','rb') as f:
    os.environ["TRAVIS_SCRIPT"] = str(base64.b64encode(f.read()))[1:]

 

For this we have to import base64 module and open the script generated in binary mode and using base64 we encode the script and using Travis CI API we send variable as script to the Travis CI to build the ISO with script in chroot we were also required to make changes in Meilix to be able to decode the script and then copy it into chroot during the ISO build.

sudo su <<EOF
echo "$TRAVIS_SCRIPT" > edit/meilix-generator.sh
mv browser.sh edit/browser.sh
EOF 

 

Using script inside chroot.

chmod +x meilix-generator.sh browser.sh
echo "$(<meilix-generator.sh)" #to test the file
./browser.sh
rm browser.sh

Resources

Base64 python documentation from docs.python.org

Base64 bash tutorial from scottlinux.com by Scott Miller

su in a script from unix.stackexchange.com answered by Ankit

How to customize LXQT for Meilix

We had a task of customizing the LXQT (LXQt is the Qt port and the upcoming version of LXDE, the Lightweight Desktop Environment) desktop environment in Meilix for events. For example, we can use a distro at events for presentations so during presentations things like system sounds, notifications and panel can be disturbing elements of presentations so we required LXQT to be pre configured for that so the time required in configuration is not wasted or none of the presentations are disturbed.

The default configuration of LXQT are present in ~/.config/lxqt. Configuration files are in This directory is initialized automatically. The default configuration for new users is found in /etc/xdg/lxqt but we are going to use skel for this so that if there are some changes in future in the LXQT code and they do not match default settings we can always be back to default settings by deleting user side changes. Similar to LXDE. LXQt provides a GUI applications to change its settings as well.

While Openbox is the default window manager we have used in Meilix with  LXQt, you can specify a different window manager to use with LXQt via by editing ~/.config/lxqt/session.conf. To a window manager of choice. Change the following line:

window_manager=openbox

 

We have used the Openbox for Meilix.

To create a configuration for panel we can go to ~/.config/lxqt and edit the panel.conf file if it is not present we can create a file named panel.conf and add/edit the code.

[panel1]
hidable=true 

 

GIF representing auto hide of panel.

In order to configure more things like notification we can edit the ~/.config/lxqt/notification.conf.

We can change things like the placement or the size of notification or the timeout of notification in this file.

For eg:

 [General]
__userfile__=true
placement=top-left
server_decides=1
spacing=6
width=295

 

We can now place all the configurations inside the skel folder so that every new user gets the same configurations we have made.

Resources

Shorten the Travis build time of Meilix

Meilix is a lubuntu based script. It uses Travis to compile and deploy the iso as Github Release. Normally Travis took around 17-21 minutes to build the script and then to deploy the iso on the page. It is quite good that one gets the iso in such a small interval of time but if we would able to decrease this time even more then that will be better.

Meilix script consists of basically 2 tests and 1 deploy:

The idea behind reducing the time of Meilix building is to parallely run the tests which are independent to each other. So here we run the build.sh and aptRepoUpdater.sh parallely to reduce the time upto some extent.
This pictures denotes that both the tests are running parallely and Github Releases is waiting for them to get complete successfully to deploy the iso.

Let’s see the code through which this made possible:

jobs:
  include:
    - script: ./build.sh
    - script: 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./scripts/aptRepoUpdater.sh; fi'
    - stage: GitHub Release
      script: echo "Deploying to GitHub releases ..."

Here we included a job section in which we wrote the test which Travis has to carry out parallely. This will run both the script at the same time and can help to reduce the time.
After both the script run successfully then Github Release the iso.

Here we can see that we are only able to save around 30-40 seconds and that much matters a lot in case if we have more than 1 build going on the same time.

Links to follow:
Travis guide to build stages

Firefox Customization for Meilix

Meilix a lightweight operating system can be easily customized. This article talks about the way one must proceed to customize the configuration of Firefox of Meilix or on its own Linux distro and how to copy the configuration file of Firefox directly to the home folder of the user.
Meilix script contains a pref.js file which is responsible for providing the configuration. This file contains various function through which one can edit them according to its need to get the required configuration of its need.

Let’s see an example:

user_pref("browser.startup.homepage", "http://www.google.com/cse/home?cx=partner-pub-6065445074637525:8941524350");

This line is used to set the browser startup page and it can be edited according to user choice to find the same page whenever he starts his Firefox.

There are several lines too which can be edited to make the required changes.

How does this work?

This is the Mozilla User Preference file and should be placed in the location /home/user_name/.mozilla/firefox/*.default/prefs.js. It actually controls the attributes of Firefox preference and set the command from here to change it.

How to use it?

One can directly go and edit it according to the choice to use it.

How meilix script uses it to change the user preference?

As we can see that .mozilla folder should be under the home directory, therefore we copy the .mozilla to the the skel folder, so that it gets automatically copied to the home location and we would be able to use.
There is also a shell script which comes in handy to implement the browser startup page and the script even copies the configuration file.

1.#!/bin/bash

2.# firefox
3.# http://askubuntu.com/questions/73474/how-to-install-firefox-addon-from-command-line-in-scripts
4.for user_name in `ls /home/`
5.do
  6.preferences_file="`echo /home/$user_name/.mozilla/firefox/*.default/prefs.js`"
  7.if [ -f "$preferences_file" ]
  8.then
    9.echo "user_pref(\"browser.startup.homepage\", \"https://google.com/\");" >> $preferences_file
  10.fi
11.done

This file is taken from here. And it used in Meilix to run the script to set the default startup page in Firefox. This will be taken input from the user end from the Meilix Generator webapp and it will change the line 9 url according to the input given by the user.
On line 3, *.default will set automatically by the script itself, it generated randomly.
After that, the script will copy the prefs.js in its location and it will implement the changes.

Links to follow:

Firefox-preference guide
Firefox-editing-configuration