Category Archives: Linux

Linux Tips & Tutos.

Sony Xperia Z3 Tethering Error after Update to Android 6.0.1

Once you update your Sony Xperia Z3 to Android 6.0.1, Tethering might break.

sony-xperia-z3-compact

It has to do with something related to Operator APN and DNS resolution. The update forces APN resolution to succeed before activation. It’s amongts new tactics of Telecom operators tyranny. Anyway:

  • Enable Development mode on your Smartphone (CGo to Settings -> Phone Details -> Click several times on Build Number)
  • On your Ubuntu 16.04, install Android SKD along with ADB and fastboot (sudo apt install android-tools-adb android-tools-fastboot -y) (ref: https://www.linuxbabe.com/ubuntu/how-to-install-adb-fastboot-ubuntu-16-04-16-10-14-04)
  • Start an adb shell by typing the following command: adb shell
  • At the adb shell prompt, run this command: settings put global tether_dun_required 0
  • hanine @col in /opt/android-studio/bin (13 entries, 0 hidden)
    7 2005 $ adb shell
    shell@D6603:/ $ settings put global tether_dun_required 0
    shell@D6603:/ $ exit
  • Type exit, then disconnect your phone and reboot

Huawei E3531s-2 on Ubuntu 14.04

The BroadBand modem Huawei E3531s-2 on Ubuntu 14.04 does not work out of the box.

Let’s make it work.

  • – Install supervisor:

sudo apt-get install supervisor -y

  • Add a supervisor configuration to a new program: A script we’ell shortly create, In /etc/supervisor/conf.d/broadband.conf

[program:broadband]
command=/usr/bin/broadband
autostart=true
autorestart=true
stderr_logfile=/var/log/broadband_err.log
stdout_logfile=/var/log/broadband_info.log

  • Write a script in /usr/bin/broadband and make it executable.

#!/bin/bash
# Script to enable Mobile Broadband
# Author: (hanynowsky@gmail.com)
WAIT=25
# Huawei E3531s-2
localcon="Meditel2"
connector(){
isBUP=$(nmcli con status | grep -i "${localcon}")
if [ -z "${isBUP}" ];then
echo "Broadband Connection Status is void: ${isBUP}"
nmcli nm wwan on;
sleep 1;
nmcli nm wwan off;
sleep 1;
if [ -n "${isBUP}" ];then
echo "Switching Off connection to ${localcon}"
nmcli con down id "${localcon}";
fi
sleep 1;
echo "Trying to Connect to $localcon"
nmcli con up id "${localcon}";
if [ "$?" -eq 0  ]; then
echo "Connection Established."
fi
sleep 1
fi
#exit 0;
}

while true; do
if [ -n "$(lsusb | grep '12d1:15ce')" ]; then
# This will switch to modem mode : 12d1:15b1
sudo usb_modeswitch -v 12d1 -p 15ce -M '55534243123456780000000000000011062000000100000000000000000000'
echo "Activating modem, please wait ${WAIT} seconds."
notify-send -u normal -a broadband "Connecting Broadband" "Modem $(lsusb | grep -i huawei). \nPlease wait 25 seconds"
sleep $WAIT
fi
isModem=$(lsusb | grep -iE '12d1:15b1|modem on')
if [ -n "${isModem}" ]; then
eval connector
fi
done

  • Change ‘localcon=”Meditel2″‘ to the name of your BroadBand Connection (You should have already configured it using Network Manager Applet)
  • Restart Supervisor.
sudo service supervisor restart

Now everytime, you plug the broadband device, it will get connected through the BroadBand connection configuration you already set up. In our case it’s called “Meditel2”.

Please note that once you plug the device, you have to wait 30 seconds before the connection is established.

Persist your screen brightness settings in Linux

If you like me have a machine running Linux OS and want to be able to persist your screen’s brightness setting, here is a small script that does the trick. (I don’t know if that feature lacks only in Ubuntu running in a Dell XPS 15 l502x or common to all Linux laptops)

Initially the problem is that once you reboot the machine, you lose the brightness setting and you have to manually adjust again. Annoying!

With the following instructions, you’ll be able to fix that. Tested in Ubuntu 13.10.

Copy these following three scripts in your Desktop folder (Or in the same folder) and give them execution permission:

RESET script (brightness-reset.sh):

#!/bin/bash
# Author: Hanine HAMZIOUI ALMADANY <hanynowsky@gmail.com>
# This script sets the brightness in Ubuntu as it is not persistent upon reboot

# In order to manually execute these commands below, the user must be root

# Brightness values are integers that range from 0 to 15
DEFAULT_BRIGHTNESS=7
CUSTOMBRIGHTNESS="$HOME/brightness/last_brightness"

if [ -f $CUSTOMBRIGHTNESS ];then echo $(cat $CUSTOMBRIGHTNESS) > /sys/class/backlight/acpi_video0/brightness
else echo $DEFAULT_BRIGHTNESS > /sys/class/backlight/acpi_video0/brightness
fi
exit 0

Brightness RUN (brightness-run.sh)

#!/bin/bash

# Persist Brightness value in Ubuntu 13.10
# Author Hanine HAMZIOUI ALMADANY <hanynowsky@gmail.com>

if [ -f "brightness-reset.sh" ]; then
sudo cp -v brightness-reset.sh /etc/init.d/ && sudo chmod +x /etc/init.d/brightness-reset.sh
else echo "brightness-reset file does not exist, it must be in the same folder. Terminating..."; exit 0;
fi

if [ -f "brightness-save.sh" ]; then
sudo cp -v brightness-save.sh /etc/init.d/ && sudo chmod +x /etc/init.d/brightness-save.sh
else echo "brightness-save file does not exist, it must be in the same folder. Terminating..."; exit 0;
fi

sudo ln -s /etc/init.d/brightness-save.sh /etc/rc0.d/K10brightness-save # Brightness SAVE Symbolic link to RC 0
sudo ln -s /etc/init.d/brightness-save.sh /etc/rc6.d/K10brightness-save # Brightness SAVE Symbolic link to RC 6

rawfile=`cat /etc/rc.local | grep "/etc/init.d/brightness-reset.sh"`
if [ -z "$rawfile" ]; then
sudo sed -e 's/exit 0//g' -i /etc/rc.local
sudo echo "#Reset screeen brightness" >> /etc/rc.local
sudo echo "/etc/init.d/reset-brightness.sh" >> /etc/rc.local
sudo echo "exit 0" >> /etc/rc.local
else echo "RC.LOCAL file is already customized to reset brightness at startup...If you think otherwise, do it manually again!"
fi

exit 0;

BRIGHTNESS Save (brightness-save.sh)

#!/bin/bash

# Author: Hanine HAMZIOUI ALMADANY <hanynowsky@gmail.com>
# Target: Ubuntu 13.10 and below
# Script that saves the last brightness value used

CUSTOMBRIGHTNESS="$HOME/brightness/last_brightness"
mkdir -p $(dirname $CUSTOMBRIGHTNESS)
cat /sys/class/backlight/acpi_video0/brightness > $CUSTOMBRIGHTNESS
exit 0;

then

chmod +x ~/Desktop/brightness-*

And finally; from your terminal again:

bash ~/Desktop/brightness-run.sh

You will be prompted for your user password.

Now adjust brightness ti a certain value and reboot. 😉

QT Application with Java. Possible? Yes QT Jambi does it.

If you’ve never heard about it, you can build rich cross-platform GUIs with Qt Jambi., while coding in Java. What?
Yes, QT Jambi is a QT Binding to Java, allowing you to develop QT GUI using Java instead of C++.
It practically is the same thing as Java-Gnome library which is a GTK+ binding.

QT Jambi is still maintained as opposite to rumors. And the last snapshot was build on 11 November 2012.
If you want to give it a shot, the following is a ‘get started’ tuto:

Environment:

  • OS: Ubuntu 12.10 AMD64
  • Desktop: Unity
  • IDE 1: Netbeans 7.3
  • JDK: Oracle JDK 1.7.u10
  • IDE 2: Eclipse Juno

First, install Qt Jambi from its PPA:


sudo add-apt-repository ppa:qtjambi-community/libqtjambi-snapshots && sudo apt-get update && sudo apt-get install --install-suggests libqtjambi-snapshot qtjambi-examples-snapshot qtjambi-designer-snapshot ant-qtjambi-snapshot libqtjambi-redist-snapshot

Then, use this script, to tell your JDK where to find corresponding QT libraries used by QT Jambi:

#!/bin/bash

#| Title: CopyJambi
#| Author: Hanine HAMZIOUI
#| Contact: <hanynowsky@gmail.com>
#| Date:  Sat 15 Dec 2012 03:57:00 AM WET
#| License: GNU GPL v3+
#| Description: Create symlinks to QT libs in default JDK for Jambi.
#| Version: 1.0
#| Environment: Netbeans 7.3 on Ubuntu 12.10 AMD64
#| Compliance: bash, zsh, ksh, dash, sh

# sudo add-apt-repository ppa:qtjambi-community/libqtjambi-snapshots
# sudo apt-get update
#sudo apt-get install --install-suggests libqtjambi-snapshot qtjambi-examples-snapshot qtjambi-designer-snapshot ant-qtjambi-snapshot libqtjambi-redist-snapshot

OPERATION() {
# Pick the JDK path
if [ -n "${JAVA_HOME}" ]; then jdk=${JAVA_HOME}
else
    if [ -d "/usr/lib/jvm/default-java" ]; then jdk=/usr/lib/jvm/default-java
    else whiptail --msgbox "No JAVA_HOME was found. Script will abort." "$LINES" "$COLUMNS"; exit 0
    fi
fi

# Two Temporary files that receive names of libraries to be copied
tmp1=$HOME/tmp/qtlibslist.txt
tmp2=$HOME/tmp/qtjnilibslist.txt

# Get the names of libraries to be copied
ls /usr/lib/x86_64-linux-gnu/ | grep libQt | sed -e '/.prl$/g' -e '/.a$/g' -e '/[0-9].[0-9]$/g' | perl -ne 's/^$//g || print' > ${tmp1}
ls /usr/lib/x86_64-linux-gnu/ | tr '[:upper:]' '[:lower:]' | grep libqt | sed -e '/.prl$/g' -e '/.a$/g' -e '/[0-9].[0-9]$/g' | perl -ne 's/^$//g || print' >> ${tmp1}
ls /usr/lib/jni |  tr '[:upper:]' '[:lower:]' | grep trolltech > ${tmp2}
ls /usr/lib/jni |  tr '[:upper:]' '[:lower:]' | grep jambi >> ${tmp2}

# Create symbolic links to QT libraries
count=0
while read line; do
sudo ln -v -s /usr/lib/x86_64-linux-gnu/${line} /usr/lib/${line}
sudo ln -v -s /usr/lib/x86_64-linux-gnu/${line} ${jdk}/jre/lib/amd64/${line}
((count++))
done < ${tmp1}
echo "Copied ${count} QT libraries Symbolic links"

# Create symbolic links to Jambi Libraries
i=0
while read inline; do
sudo ln -v -s /usr/lib/jni/${inline} ${jdk}/jre/lib/amd64/${inline}
sudo ln -s -v /usr/lib/jni/${inline} /usr/lib/${inline}
((count++))
done < ${tmp2}
echo "Copied ${i} Jambi QT libraries Symbolic links"

# Remove temporary files
if [ -f ${tmp1} ] || [ -f ${tmp2} ]
    then rm -v ${tmp1}; rm -v ${tmp2}
fi
}

# Make sure the user system is amd64
arch=$(uname -i)
if [ "${arch}" = "x86_64" ]; then eval OPERATION
else whiptail --msgbox "Your system architecture is not AMD64. Script will not continue. Abort." "$LINES" "$COLUMNS"
fi
exit 0

The above script will create symbolic links in your JDK path. If you want you can copy the libraries instead of just symlinking them.

Next step is to create a Java Project in Netbeans and import Qt Jambi library in classpath as well as QT Jambi Demos library. (You’ll find them in /usr/share/java/)

jambi-netbeans

Here is a screenshot of a demo example :

Jambi-Example

You can test with a simpler example (Hello World):


package jambi;

import com.trolltech.qt.gui.*;

public class HellowWorld {

public static void main(String args[]) {
QApplication.initialize(args);
QPushButton hello = new QPushButton("Hello World!");
hello.resize(120, 40);
hello.setWindowTitle("Hello World");
hello.show();
QApplication.execStatic();
QApplication.shutdown();
}
}

Notice:

When running a QT Jambi java file, you might encounter this error :
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f6b95e362ba, pid=10602, tid=140100171314944
#
# JRE version: 7.0_10-b18
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libQtGui.so.4+0x2602ba] QWidgetPrivate::deleteTLSysExtra()+0x3a
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/hanine/Workspace/test/jambi/hs_err_pid10602.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp

Yet, entering : ulimit -c unlimited does not help at all. It sounds like an old bug related to Java HotSpot, where a zip file is read and modified in the same time. In other situations this bug is overriden using -Xmx option (e.g. -Xmx2900m : Maximum Memory : 2.9 GB )
E.G: java -Xmx:1864m -Xms:1864m myapp.jar sets minimum & maximum java memory heaps to 1864 MB for myapp.jar.
So, it appears that in almost all cases, a java file with the following statements will produce this error:

 public static void main(String args[]) {
        QApplication.initialize(args);

        Wiggly d = new Wiggly(null);
        d.show();

        QApplication.execStatic();
        QApplication.shutdown();
    }

So to get rid of this error, change the code to look like this instead (Still investigating on the root problem though):

 public static void main(String args[]) {
        QApplication.initialize(args);
        new Wiggly(null).show();

        QApplication.execStatic();
        QApplication.shutdown();
    }

Running your Qt Application from terminal

When you clean and build with Netbeans, you’d get a Jar File in your project workspace, in a folder named dist.
Make this jar file executable : chmod +x /path/to/this/jar/file.jar
and run it from terminal: java -jar /path/to/this/jar/file.jar

Qt Application executed as a JAR file.

Qt Application executed as a JAR file.

Eclipse Juno IDE

You can achieve the same thing using Eclipse if it’s your preferred IDE. Just make sure you install qt-jambi from Launchpad PPA and run the above script:

  • – Use the script from above or just download it from here : QtJambiCopierSCript
  • – Save it in your Desktop and run : bash ~/Desktop/jambicopy.sh
  • – Follow instructions if any.
  • – Open Eclipse Juno, Create a Java Project and add external libraries from /usr/share/java/
  • – Adding the qtjambi.jar and qtjambi-examples.jar does the job.

jambi-eclipse

GUI Designer

Unlike Java-Gnome binding library which does not yet integrate with GUI designer GLADE, Qt Jambi integrates with QT Designer.
If you followed instructions above, go to your Terminal and type:

qtjambi-designer.sh

or

bash /usr/bin/qtjambi-designer.sh

This will launch QT Jambi Designer. Henceforth, you can start designing visually your GUI. Once finished, save the work as a "*.jui" file, which you would reuse as your Application UI.
Normally, Qt Designer produces a file with "*.ui" extension; but QT Jambi team has modified the thing with custom modifications that allow better integration and generation of UI java files.
qtjambi-designer
We will cover this later in this same post.
Thanks for reading.
—————
N.B: Qt Jambi Community website is down since yesterday (14th December).
You can browse other useful resources that will get you accustomed to QT Jambi quickly: QT JAMBI RESOURCES

Take a screenshot while a menu is activated in Ubuntu

If you’re running Ubuntu and want to take a screenshot using the gnome-screenshot utility, you would notice that when you press the PRINT SCREEN keyboard key while a panel or launcher menu is activated, the screen shooter does not get executed. This is a known bug due to some old Xorg issue:
https://bugs.launchpad.net/ubuntu/+source/gnome-utils/+bug/29894

Meanwhile, You can work around it by adding a delay before it gets executed. During this delay, you activate the menu you want to include in the screenshot.
Think about a more advanced screenshot utility which is SHUTTER (sudo apt-get install shutter).

Here is a comfortable solution:

1- Install Kazam
2- Install VLC media player in order to use the cvlc dummy interface command.
3- Install dconf-editor or CompizManager in order to bind the keyboard PRINT key to a custom command.
4- Create a script that will run Kazam with a custom delay if installed.

Copy/Paste the following code in a text file, and save it into your home directory and name it: screenshooter.sh

#!/bin/bash

# This script runs shutter screenshooter if installed instead of gnome-screenshot

shutterbin="/usr/bin/shutter"
cvlcbin="/usr/bin/cvlc"
sound="/usr/share/sounds/freedesktop/stereo/camera-shutter.oga"
arg="$@"

if [ -z ${arg} ]
    then delay=3
    else delay=${arg}
fi

if [ -f "${shutterbin}" ] 
    then
        if [ -f "${cvlcbin}" ]
            then shutter -f -d ${delay} & sleep ${delay} && cvlc --play-and-exit ${sound}
            else shutter -f -d ${delay}
        fi
    else gnome-screenshot
fi
exit 0

Workspace 1_001
Then, go to CompizConfig in Gnome_Compatibility/Commands and bind the PRINT command to this command:
bash ~/screenshooter.sh 3
This means, when you press the PRINT key, Kazam or gnome-screenshot will be launched within a delay of 3 seconds, the necessary time for you to activate the menu you want to printed in the screenshot.
CVLC was used just to play the camera sound the screenshot is taken. You can get rid of it if you want by modifying the script if you don’t want to install VLC.

The following is a screencast demonstarting this post.

If you have any questions or any better solutions, please post a comment.

A lazy way to debianize a Java application ( JDebianizer )

As a heavy user of Debian based system like Ubuntu, if you’re developing Java Swing applications and want to distibute them to end users either for testing purposes or as a stable software, the first thing you think about is the Debian archive. Distributing Java software as JAR files may not be the best thing towards Debian OS and its derivatives users.

You still have many helper scripts like javahelper ( sudo apt-get install javahelper ) which is itself a bunch of scripts (jh_something), each one having a specific purpose, to help you package your Java application as a Debian file. Besides, it gets irritating to use embedded package installers which do not respect to an extent the system packaging policies and which steals some of your freedom in that matter.

So, What about using only one script that semi-automates the debian packaging for us?
Well, in the recent post Bomico, we gave mention of a tiny Java application that had to be debianized in order to be natively installed in Ubuntu 12.04. To achieve this, we wrote a small script ( JDebianizer script ) that semi-automates debian packaging for us.

Java DEbianizer
The follwoing is the so-called JDebianizer script as it was snapshot the first time. If you want to get the updated script please go to JDebianizer Github REPO:

#!/bin/bash

# Title		:	JDebianizer
# Description 	: 	Script tested only in Ubuntu. 
# 			This script is for Java developers who want to package a simple application for Ubuntu users as a Debian 				file.
# Rules			DO NOT execute this script with root power (sudo). 
#			The script will try to install md5deep needed to generate md5 sums.
#			If no internet connection, md5sums will be used instead.
#			JDebianizer is  onsole-only, so run it from Terminal or any other Shell.
#			Script is compliant only with BASH & KSH. Don't run it with SH, ZSH, DASH..).
# Usage		:	In order to run the JDebianizer, switch to current directory that contains the script
# 			and enter: 
# 			./jdebianizer 
# 			or: 
# 			cd /path/to/containing/folder && bash jdebianizer			
# Dependencies	:	md5deep, whiptail, zenity		
# Author 	: 	Hanine HAMZIOUI <hanynowsky@gmail.com> حنين
# Version 	: 	1.0a
# License	:	GNU GPL V3+
# Date created	:	Wed 14 Nov 2012 12:40:32 AM WET 

# ----------------- TODO -----------------------------

# TODO 1- add support for several icon sizes
# TODO 2- add support for verbosity
# TODO 3- add support for javadoc: jh_installjavadoc
# TODO 4- add support for many config files
# TODO 5- add support for other application folders (/etc /usr/share/menu)

# -------------- Global variables ----------------------
JDVERSION="JDebianizer 1.0. \nCopyright (C) 2012 - 2013. Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
JDebianizer is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Written by Hanine HAMZIOUI."
ROWS=$(echo "$LINES" | bc )
COLS=$(echo "$COLUMNS" | bc)
LOGFILE=$HOME/tmp/jdebianizer.log
CONFIGFILE=$HOME/.config/jdebianizer.conf
TEMPFILE=$HOME/tmp/jdtemp.log
ZWINICON=/usr/share/icons/hicolor/48x48/apps/distributor-logo.png

# ----------------Re-execute the SCRIPT-----
restartscript(){
echo "JDebianzier filename is: $0"
filename=$(echo "$0" | sed -e 's/ /\\ /g' )
echo "Modified JDebianizer filename is: $filename"
if [ -f "$filename" ]; then eval bash "$filename"
else echo "Path to file is incorrect or contains trailing spaces. (e.g. ~/Ubuntu One/jdebianizer)"; exit 0
fi
}

# ----------------JAYATANA INSTALLER --------
DESKTOP=$(echo $XDG_CURRENT_DESKTOP)
JDKPATH=$(echo $JAVA_HOME | grep .)
USERHOME=$(echo $HOME)
JAYATANADD="http://java-swing-ayatana.googlecode.com/svn/tags/1.2.4/jayatana"
JAYABUILD="$USERHOME/jayatana/build.xml"
JAYALOG="$USERHOME/Desktop/jayatana-stall.log"

# INSTALL 
JAYAINSTALL(){
sudo apt-get -y install openjdk-7-jdk libunity-dev libxt-dev gcc make ant subversion 
sudo update-java-alternatives -s java-1.7.0-openjdk-amd64 
svn checkout $JAYATANADD 
sudo ant install -buildfile $JAYABUILD -v
sudo ant config -v 
sudo update-alternatives --config java 
sudo update-alternatives --config javac
sudo ant install -Djava.home.7=/usr/lib/jvm/java-7-openjdk-amd64 -f $JAYABUILD -v -l $JAYALOG
sudo ant config -Djava.home.7=$JDKPATH -buildfile $JAYABUILD -v -l $JAYALOG
sudo chmod 777 $JAYALOG
echo "Jayatana Installation finished. Run a Java Swing Application and check if it is integrated with global menu."
whiptail --msgbox "Jayatana Installation finished. Run a Java Swing Application and check if it is integrated with global menu.\nA log file : $JAYALOG was created." "$LINES" "$COLUMNS"
}

INSTALLCOM () {
if [ -d "$JAVA_HOME/jre/lib/endorsed" ] 
	then CHECKJAYA=$(ls $JAVA_HOME/jre/lib/endorsed/* | grep "jayatana")
		if [ -n "$CHECKJAYA" ]
			then whiptail --yesno "Seems like Jayatana is already installed. Proceed anyway?" 20 80 --title "Jayatana" --backtitle "Jayatana Installation Check"
				if [ "$?" = 0 ] 
					then echo "Trying to re-install Jayatana"; eval JAYAINSTALL
					else echo "Aborted by $USER"; eval restartscript
				fi
			else echo "Seems like Jayatana is not installed."; eval JAYAINSTALL
		fi
	else echo "Jayatana seems to be not installed yet for your default JRE."; eval JAYAINSTALL
fi
}

# UNINSTALL
UNINSTALLCOM (){
sudo ant deinstall -buildfile $JAYABUILD -v
sudo ant deconfig -buildfile $JAYABUILD -v
sudo ant deconfig -Djava.home.7=$JDKPATH -buildfile $JAYABUILD -v -logfile $JAYALOG
echo "Jayatana uninstallation has finished."
}

# DELETE Jayatana Folder created by subversion checkout
UNDIR() {
whiptail --yesno "Delete Jayatana Folder too?" "$LINES" "$COLUMNS" --backtitle "Ubuntu Global Menu Support for Java Swing Applications" --title "JDebianizer"
if [ "$?" = 0 ]; then mv $HOME/jayatana $HOME/.local/share/Trash/files/
elif [ "$?" = 1 ]; then echo "Jayatana Folder is kept by $USER , you can delete it later : ~/jayatana";
else echo "Jayatana Folder is kept by $USER , you can delete it later : ~/jayatana";
fi
}

# COMMON
COMMON() {
echo "$JDKPATH : is your default JDK." 
echo $(java -version)
}

# PROMPT INSTALL
RUNINST() {
eval COMMON;
whiptail --yesno "Install/Uninstall Jayatana (ESCAPE or CTRL+C to cancel)" "$LINES" "$COLUMNS" --yes-button "Install" --no-button "Uninstall" --backtitle "Ubuntu Global Menu Support for Java Swing Applications" --title "JDebianizer"
case "$?" in 
0) eval INSTALLCOM; exit 0;;
1) eval UNINSTALLCOM;eval UNDIR;exit 0;;
255) echo "Aborted by $USER";exit 0;; # code returned by ESCAPE is 255
esac
}

# JAYATANA MAIN
jayamain() { # "${DESKTOP,,}"
if [ "${DESKTOP}" = "unity" ] || [ "${DESKTOP}" = "Unity" ]; then eval RUNINST
	else echo "Your Desktop environment is ${DESKTOP}. You cannot Install Jayatana. (Required: Unity Shell)"
fi
}

# -------------------------- ARGS -----------
argfu(){
for arg in $@
	do
		case "$arg" in
			--version|--v|--V) unset arg; echo -e "$JDVERSION"; exit 0;;
			--help|--h|--?|-?) echo -e "Run the script and follow instructions if any.\nUSAGE: \n./jdebianizer [OPTION...]\n\nOPTIONS: \n--v, --version Show the package version\n--c, --clean Remove files created by JDebianizer\n";exit 0;;
			--clean|--c) echo -e "Removing JDebianizer files";
				if [ -f "$LOGFILE" ]; then rm -v $LOGFILE 
					else echo "No Log File found."
				fi
				if [ -f "$CONFIGFILE" ]; then rm -v $CONFIGFILE 
					else echo "No Config File Found."
				fi
				exit 0;;
			-v|--verbose) echo -e "Running in Verbose mode.";exit 0;; # TODO set the var to be used with whiptail
			"") break;;
		esac
done
}
argfu "$@";

# START
# Make sure the user has copied jar libraries if any and main executable package jar in a given folder
start() {
# clear the screen
tput clear
# Move cursor to screen location X,Y (top left is 0,0)
tput cup 2 15
# Set a foreground colour using ANSI escape
tput setaf 3
echo "JDebianizer. 1.0. (Debianize your Java Application)"
tput cup 3 15
tput setaf 5
echo "https://github.com/hanynowsky/jdebianizer"
tput sgr0
tput cup 5 17
# Set reverse video mode
tput rev
echo "I M P O R T A N T - N O T I C E"
tput sgr0
tput cup 7 15
echo "A. Create a folder and put your executable Java program as well as its dependencies (jar file libraries) in it"
tput cup 8 15
echo "B. The executable jar file should have the same lowercase name as the package. E.g: logism.jar"
tput cup 9 15
echo "C. Prepare a 48x48 PNG image to be used as the icon of your Java application"
tput cup 10 15
echo "D. You can eventually add documentation files you want to include in the debian package."
# Set bold mode 
tput bold
tput cup 13 15
echo "1. Start JDebianzer"
tput cup 14 15
echo "2. Exit JDebianzer"
tput cup 15 15
echo "3. Install Jayatana (Ubuntu Global Menu Support for Java Swing Applications)"
tput cup 17 15
read -p "Enter your choice [ 1 / 2 / 3 ]  " choice
if [ "$choice" = "1" ] ; then echo "Starting JDebianizer..."
elif [ "$choice" = "3" ] ; then tput sgr0; echo "Starting Jayatana installer..."; eval jayamain
elif [ "$choice" = "2" ] ; then exit 0
else echo "exiting JDebianizer"; exit 0
fi
tput clear
tput sgr0
tput rc
}
eval start;

whiptail --yesno "Welcome to JDebianizer. First of All, copy your package's main executable jar file (Must have the same name as the package name), as well as its dependency jar libraries, in the same folder (example: /home/yourusername/mypackagejars_folder), then select 'yes'. Clicking no means you still have not done so." "$LINES" "$COLUMNS" --clear
if [ "$?" -eq 0 ]; then echo "Great! Let us continue then."
else echo "Existing script. Retry when you're ready."; exit 0;
fi

exitoption(){
if [ $exitcode = 0 ]; then echo "$USER said okay: $exitcode"
elif [ ${exitcode} = 1 ]; then echo "$USER said NO - Canceled: $exitcode"; exit 0
else echo "$? - Continue...";
fi
}

# ---------------CONFIG File ------------------
packpropform(){
zenity --forms --text="Package Properties" --add-entry="Package-Name" --add-entry="Version" --add-entry="Maintainer-Name" --add-entry="Maintainer-Surname" --add-entry="Email" --add-entry="Homepage" --window-icon $ZWINICON --title "JDebianizer" > $TEMPFILE
exitcode=$?
eval exitoption;
echo "Grabbed Package Properties"
}

parseconfig(){
i=0
while read line; do
	if [[ "$line" =~ ^[^#]*= ]] 
		then 
		name[i]=$(echo $line | cut -d'=' -f 1) 
		array[i]=$(echo $line | cut -d'=' -f 2)
		((i++))
		# echo "${array[i]}"
	fi
done < $CONFIGFILE
}

lineasvar(){ 
cat $TEMPFILE | sed -e 's#|#\n#g' > $LOGFILE
i=0
while read line; do
    	array[i]=$(echo "${line}")
	if [ -z "${array[i]}" ] 
		then echo "No field should be empty. Please Retry."; exit 0
		else echo "${array[i]}"
	fi
	((i++))
done < $LOGFILE

echo "The entered item 1 is: ${array[0]}" | tr '[:upper:]' '[:lower:]'
echo "The entered item 2 is: ${array[1]}" | tr '[:upper:]' '[:lower:]'
echo "The entered item 3 is: ${array[2]}"
echo "The entered item 4 is: ${array[3]}"
echo "The entered item 5 is: ${array[4]}"
echo "The entered item 6 is: ${array[5]}"
rm $TEMPFILE
}

if [ -f "$CONFIGFILE" ] 
	then whiptail --yesno "Config File Exists. Overwrite it?" 20 50
		if [ "$?" -eq 0 ] 
			then eval packpropform; eval lineasvar
			else eval parseconfig; echo "Found config file for package ${array[0]}" 
		fi
	else echo "CONFIG FILE does not exist. Please enter package properties values."; eval packpropform; eval lineasvar
fi

PACKNAME=$(echo "${array[0]}" | tr '[:upper:]' '[:lower:]')  	# Package name : must be lowercase  "${PACKNAME,,}"
upperpackname=$(echo "${PACKNAME}" | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g')
PVERSION=$(echo "${array[1]}" | tr '[:upper:]' '[:lower:]') 	# Package Ubuntu version
ROOTDIR=$(echo $HOME/Desktop/$PACKNAME"_"$PVERSION | grep .)	# Root folder to debianize
MAND="man"							# Workaround for key word man
mfname=$(echo "${array[2]}" | tr '[:lower:]' '[:upper:]')
msname=$(echo "${array[3]}" | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g')
maintainer="$msname $mfname"
memail=$(echo "<${array[4]}>" | tr '[:upper:]' '[:lower:]')
homepage=$(echo "${array[5]}" | tr '[:upper:]' '[:lower:]')

# --------------- Append Config File ------------------ 
echo "[PACKAGE]" > "$CONFIGFILE" # TODO before appending check for duplicates by PACKNAME
echo "PACKNAME=${PACKNAME}" >> "$CONFIGFILE"
echo "PVERSION=${PVERSION}" >> "$CONFIGFILE"
echo "MFNAME=${mfname}" >> "$CONFIGFILE"
echo "MSNAME=${msname}" >> "$CONFIGFILE"
echo "MEMAIL=${memail}" >> "$CONFIGFILE"
echo "HOMEPAGE=${homepage}" >> "$CONFIGFILE"

# ------------- Desktop File variables ----------------
PICON="/usr/share/icons/hicolor/48x48/apps/$PACKNAME.png"		# Desktop file Icon
COMMENT=$(echo "${PACKNAME} $PVERSION - A Java based Application" sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g')	
									# Desktop file comment
GENAME=$(echo "${PACKNAME}"|sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g')	# Desktop file generic name
DNAME=$(echo "${PACKNAME}"| sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g')	# Desktop file application name - First letter is 
									# Uppercase "${DNAME^^[PATTERN]}"
PTYPE="Application"							# Desktop file type
DVERSION="1.0" 								# Desktop file version

# CREATE NECESSARY DIRECTORIES
# We can create them using : mkdir $ROOTDIR/{DEBIAN,usr{share{man{man1},icons,doc{$PACKNAME},$PACKNAME{lib},applications},bin}}
create_dirs(){
if [ ! -d "$ROOTDIR" ]; then mkdir -p $ROOTDIR; sudo chmod -R 777 $ROOTDIR # Unlock root folder
else echo "Root folder exists. OK. Skipping."; sudo chmod -R 777 $ROOTDIR; sudo chown $USER:$USER -R $ROOTDIR
fi
BINDIR="${ROOTDIR}/usr/bin"
if [ ! -d "${BINDIR}" ]; then mkdir -p ${BINDIR}
else echo "bin folder exists. OK. Skipping."
fi
DEBDIR="${ROOTDIR}/DEBIAN"
if [ ! -d "${DEBDIR}" ]; then mkdir -p ${DEBDIR}
else echo "DEBIAN folder exists. OK. Skipping."
fi
DOCDIR="${ROOTDIR}/usr/share/doc/${PACKNAME}"
if [ ! -d "$DOCDIR" ]; then mkdir -p $DOCDIR
else echo "doc folder exists. OK. Skipping."
fi
SHAPPDIR="$ROOTDIR/usr/share/applications"
if [ ! -d "$SHAPPDIR" ]; then mkdir -p $SHAPPDIR
else echo "share applications folder exists. OK. Skipping."
fi
MANDIR="$ROOTDIR/usr/share/$MAND/man1"
if [ ! -d "$MANDIR" ]; then mkdir -p $MANDIR
else echo "man1 folder exists. OK. Skipping."
fi
PACKDIR="$ROOTDIR/usr/share/$PACKNAME"
if [ ! -d "$PACKDIR" ]; then mkdir -p $PACKDIR
else echo "Package folder exists.Ok. Skipping."
fi
LIBDIR="$ROOTDIR/usr/share/$PACKNAME/lib"
if [ ! -d "$LIBDIR" ]; then mkdir -p $LIBDIR; echo "Created lib folder"
else echo "lib folder exists.Ok. Skipping."
fi
DICONDIR="$ROOTDIR/usr/share/icons/hicolor/48x48/apps"
if [ ! -d "$DICONDIR" ]; then mkdir -p $DICONDIR; echo "Created icon folder"
else echo "icon folder exists.Ok. Skipping."
fi
}
eval create_dirs;

# ------------------Copy LIBRARIES & main binary EXECUTABLE-----
sudo chmod 777 -R $ROOTDIR # Give full permission to allow writing
libpath=$(zenity --file-selection --directory --title "Select the folder containing jars")
exitcode=$?
eval exitoption;
echo "Jar Files Folder Confirmed."
CHECKJARS=$(ls -1 $libpath/*.jar  2>/dev/null | wc -l)
CHECKJAR=$(ls -1 $libpath/$PACKNAME.jar  2>/dev/null | wc -l)
jarscount=$(echo "$CHECKJARS+0" | bc)
if [ -d "$libpath" ] || [ $jarscount -gt 0 ]; then echo "Trying to copy: $libpath/*.jar" $LIBDIR"/" ; 
echo "${CHECKJARS} jar files found"; ls -l ${libpath} | grep "\.jar\$"; # grep "\.jar$"
cp -v $libpath/*.jar $LIBDIR/ # $libpath"/." to cp all content;
else echo "the folder you specified does not contain the necessary jar files."
fi
jarcount=$(echo "$CHECKJAR+0" | bc)
if [ ! $jarcount -eq 0 ]; then mv $LIBDIR"/"$PACKNAME".jar" $PACKDIR"/"$PACKNAME".jar"
else echo "Main jar not found"
fi
CHECKFILES=$(ls -1 $libpath  2>/dev/null | wc -l)
a=$(echo $CHECKFILES+0 | bc)
result=$(echo "$CHECKJARS" | bc)
if [ $a -gt $result ]; then echo "folder has $CHECKFILES files, $CHECKJARS being jars" ;echo "WARNING: $libpath contains non-jar files.";
echo "But we have not copied them. Copied only jar files."
else echo "No files beside jar files on $libpath. Great! Let us continue." 
fi
# --------------------------------------------------------------

echo "Working on: "$ROOTDIR " for debianizing package $PACKNAME" | grep .

# --------------Create a DESKTOP FILE ----------------------
# We can use desktop-file-install to install the desktop file in a given folder
DESKFILE="$ROOTDIR/usr/share/applications/$PACKNAME.desktop"	# Desktop file path name
writedeskfile(){
echo "Creating Desktop file"$DESKFILE
echo "[Desktop Entry]" > $DESKFILE
echo "Type=$PTYPE" >> $DESKFILE
echo "Name=$DNAME" >> $DESKFILE
if [ -z "$CATEGORIES" ] && [ -z $CATOTHER ]; then desktop-file-edit --add-category "Utility;Java;" $DESKFILE
else echo $CATEGORIES
fi
echo "Other categories: " $CATOTHER
echo "GenericName=$GENAME" >> $DESKFILE
echo "Comment=$COMMENT" >> $DESKFILE
echo "Exec=$PACKNAME" >> $DESKFILE
echo "Terminal=false" >> $DESKFILE
echo "Icon=$PICON" >> $DESKFILE
echo "Version=$DVERSION" >> $DESKFILE

MCATGET=$(whiptail --checklist "Choose Main Categories (Desktop File *.desktop). Use space to select and Tab to switch." 25 50 16 "AudioVideo" 0 "Audio" 0 "Video" 0 "Development" 0 "Game" 0 "Graphics" 0 "Office" 0 "Science" 0 "Settings" 0 "Utility" 1 "Network" 0 "Education" 0 "System" 0 --noitem 3>&1 1>&2 2>&3) 
exitcode=$?
eval exitoption;
echo "Main Desktop categories copied."
ACATGET=$(whiptail --checklist "Choose Additional Categories (Desktop File *.desktop). Use space to select and Tab to switch." "$LINES" "$COLUMNS" 25 "Java" 1 "GTK;GNOME" 0 "Building" 0 "IDE" 0 "Profiling" 0 "Translation" 0 "Calendar" 0 "ContactManagement" 0 "Database" 0 "Dictionary" 0 "Chart" 0 "Email" 0 "Finance" 0 "FlowChart" 0 "PDA" 0 "ProjectManagement" 0 "Presentation" 0 "2DGraphics" 0 "VectorGraphics" 0 "RasterGraphics" 0 "3DGraphics" 0 "TextTools" 0 "InstantMessaging" 0 "Chat" 0 "WebDevelopment" 0 "Music" 0 "Biology" 0 "Chemistry" 0 "ComputerScience" 0 "Electricity" 0 "ImageProcessing" 0 "Physics" 0 "Engineering" 0 "ConsoleOnly" 0 --noitem 3>&1 1>&2 2>&3) 
exitcode=$?
eval exitoption;
echo "Additional Desktop categories confirmed."
CATEGORIES=$(echo "$MCATGET"";""$ACATGET" | sed -e 's# #;#g' -e 's#"##g')	# Desktop file Categories
CATOTHER=$(whiptail --inputbox "Any other categories to add (Seperate by semi-comma). Leave blank if none." 10 30 3>&1 1>&2 2>&3 | sed -e 's# ##g' -e 's#[^a-zA-Z\;]##g')							# Desktop Other categories

desktop-file-edit --add-category $CATEGORIES $DESKFILE
CATOTHERF=$("${CATOTHER}" | tr '[:upper:]' '[:lower:]')
desktop-file-edit --add-category $(echo "${CATOTHERF}" | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g') $DESKFILE
echo "StartupNotify=true" >> $DESKFILE
echo "X-Ubuntu-Gettext-Domain=$PACKNAME" >> $DESKFILE
}

pastedicon(){
LOCICON=$(zenity --file-selection --file-filter "*.png" --title "Select Your package Icon (PNG format and 48x48 resolution)")
exitcode=$?
eval exitoption;
echo "Desktop Icon confirmed."
if [ -r $LOCICON ]; then cp -v -u $LOCICON "${ROOTDIR}${PICON}"
else echo "No PNG Icon found"; whiptail --msgbox "No PNG found. Exiting" $ROWS $COLS; exit 0
fi
}

if [ -f "$ROOTDIR/$PICON" ]; then echo "Desktop icon already exists."
else eval pastedicon
fi

if [ -f "$DESKFILE" ]; then whiptail --yesno "Desktop file already exists. Overwrite it?" 20 80
if [ "$?" -eq 0 ]; then rm -v "$DESKFILE"; eval writedeskfile
else echo "Existing Desktop file kept by $USER"
fi
else eval writedeskfile
fi
desktop-file-edit ${DESKFILE}

# -----------------------Create CONTROL file----------------
CONTFILE=$ROOTDIR/DEBIAN/control
priority=$(echo "optional" | tr '[:upper:]' '[:lower:]') # All properties are lowercase
architecture=$(echo "all" | tr '[:upper:]' '[:lower:]')
instsize=$(du -s $ROOTDIR | grep -o "^[0-9]*") # size should be appended at the very end
sectionstring=(admin cli-mono comm database debug devel doc editors education electronics embedded fonts games gnome gnu-r gnustep graphics hamradio haskell httpd interpreters introspection java kde kernel libdevel libs lisp localization mail math metapackages misc net news ocaml oldlibs otherosfs perl php python ruby science shells sound tasks tex text utils vcs video web x11 xfce zope)
sectionget(){
sectionvalue=$(whiptail --inputbox "Enter the appropriate Control Section amongst the following list (type java if you are not sure):\n\nadmin cli-mono comm database debug devel doc editors education electronics embedded fonts games gnome gnu-r gnustep graphics hamradio haskell httpd interpreters introspection java kde kernel libdevel libs lisp localization mail math metapackages misc net news ocaml oldlibs otherosfs perl php python ruby science shells sound tasks tex text utils vcs video web x11 xfce zope" 25 80 "java" 3>&1 1>&2 2>&3)
for (( s=0; s < ${#sectionstring[*]}; s++ )); do
lowersectv=$(echo "${sectionvalue}" | tr '[:upper:]' ':lower:')
if [ "${lowersectv}" = "${sectionstring[s]}" ] 
then section="${lowersectv}"; echo "It is okay. We have found your control section listed."
else section="java"; echo "Warriga, what you have typed does not figure in the Debian control section list...:(" 2>/dev/null
fi
done	
echo "Control file section property confirmed."
}

writecont(){
eval sectionget;
exitcode=$?
eval exitoption;
				
depends=$(echo -e "libjava-gnome-java (>= 4.1.1), jarwrapper" | zenity --text-info --title "Control File dependencies. separate with comma and space." --editable  --width=700 --height=300)
exitcode=$?
eval exitoption;
echo "Control file dependencies confirmed."
defscription="Body Mass Index Computer\n
 Check your body mass index with Bomico.\n Bomico is a small program written in Java and interfaced with Swing.\n See Documentation online at https://github.com/hanynowsky/bomico/wiki\r"
description=$(echo -e $defscription | zenity --text-info --title "Control File description (First line must not exceed 80 Characters.)" --editable --width=600 --height=300)
exitcode=$?
eval exitoption;
echo "Control file description confirmed."
echo "Creating postinst file "$CONTFILE
echo "Package: ${PACKNAME}" >> $CONTFILE
echo "Version: $PVERSION" >> $CONTFILE
echo "Section: ${section}" >> $CONTFILE
echo "Priority: ${priority}" >> $CONTFILE
echo "Architecture: ${architecture}" >> $CONTFILE
echo "Depends: $depends" >> $CONTFILE
echo "Maintainer: $maintainer $memail" >> $CONTFILE
echo "Installed-Size: $instsize" >> $CONTFILE
echo "Homepage: $homepage">> $CONTFILE
echo -e "Description: $description\r" >> $CONTFILE
}
if [ -f "$CONTFILE" ]; then whiptail --yesno "control file exists. Overwrite it?" 20 80
if [ "$?" -eq 0 ]; then rm -v "$CONTFILE"; eval writecont
else echo "Existing control file kept by $USER"
fi
else eval writecont
fi

# -----------------------Create PREINST file----------------
PREINSTFILE=$ROOTDIR/DEBIAN/preinst
if [ -f "$PREINSTFILE" ]; then rm -v $PREINSTFILE
else echo "postinst file not present. Going ahead..."
fi
echo "Creating preinst file "$PREINSTFILE
echo "#!/bin/sh -e" > $PREINSTFILE
echo "echo 'preinst is executing'" >> $PREINSTFILE
echo "javahome=\$(echo \$JAVA_HOME)" >> $PREINSTFILE
echo "javadef=\"/usr/lib/jvm/default-java/jre/bin/java\"" >> $PREINSTFILE
echo "if [ -n \"\$javahome\" ] || [ -f \"\$javadef\" ]; then echo \"your JAVA_HOME is \$javahome\"" >> $PREINSTFILE
echo "else whiptail --yesno 'ERROR: JAVA_HOME seems to be not set. Or no JRE is installed.\n Do you want to install OpenJDK JRE?' 25 50" >> $PREINSTFILE
echo "if [ \"\$?\" -eq 0 ]; then sudo apt-get install -y openjdk-7-jre" >> $PREINSTFILE
echo "else echo 'Please Install a Java JRE and re-install this package again.'; exit 0" >> $PREINSTFILE
echo "fi" >> $PREINSTFILE
echo "fi" >> $PREINSTFILE
echo "exit 0;" >> $PREINSTFILE

# -----------------------Create POSTINST file----------------
PINSTFILE=$ROOTDIR/DEBIAN/postinst
if [ -f "$PINSTFILE" ]; then rm -v $PINSTFILE
else echo "postinst file not present. Going ahead..."
fi
echo "Creating postinst file "$PINSTFILE
echo "#!/bin/sh -e" >> $PINSTFILE
echo "echo postinst is executing" >> $PINSTFILE
echo "LOGUSER=\`who | sed -e 's#-##g' -e 's#tty##g' -e 's#pts##g' -e 's#[0-9()\:]##g' -e 's#^[ \t]*##' -e 's#[ \t]*\$##' | grep . -m 1\`" >> $PINSTFILE
echo "BPATH=/usr/share/$PACKNAME/$PACKNAME.jar" >> $PINSTFILE
echo "DPATH=/usr/share/applications/$PACKNAME.desktop" >> $PINSTFILE
echo "LDPATH=\$HOME/.local/share/applications" >> $PINSTFILE
echo "LDFPATH=\$HOME/.local/share/applications/$PACKNAME.desktop" >> $PINSTFILE
echo "sudo chmod +x \$BPATH" >> $PINSTFILE
echo "sudo chmod 644 \$DPATH" >> $PINSTFILE
echo "cp \$DPATH \$LDPATH" >> $PINSTFILE
echo "echo Logged user is \$LOGUSER" >> $PINSTFILE
echo "sudo chown \$LOGUSER:\$LOGUSED \$LDFPATH" >> $PINSTFILE #echo "sudo chown \$LOGUSER:\$LOGUSER \$LDFPATH" >> $PINSTFILE
echo "exit 0;" >> $PINSTFILE

# -----------------------Create PRERM file----------------
PRERMFILE=$ROOTDIR/DEBIAN/prerm
if [ -f "$PRERMFILE" ]; then rm -v $PRERMFILE
else echo "prerm file not present. Going ahead..."
fi
echo "Creating prerm file "$PRERMFILE
echo "#!/bin/sh -e" >> $PRERMFILE
echo "echo prerm is being executed" >> $PRERMFILE
echo "exit 0;" >> $PRERMFILE

# -----------------------Create POSTRM file----------------
POSTRMFILE=$ROOTDIR/DEBIAN/postrm
if [ -f "$POSTRMFILE" ]; then rm -v $POSTRMFILE
else echo "postinst file not present."
fi
echo "Creating Postrm file "$POSTRMFILE
echo "#!/bin/sh -e" >> $POSTRMFILE
echo "echo postrm is executing" >> $POSTRMFILE
echo "# Remember that if symlinks are used , an embedded IF dealing with symlink must be used -L" >> $POSTRMFILE
echo "PHOME=\$HOME/$PACKNAME" >> $POSTRMFILE
echo "LDFILE=\$HOME/.local/share/applications/$PACKNAME.desktop" >> $POSTRMFILE
echo -e "if [ -d "\$PHOME" ]; then sudo chmod 777 -R \$PHOME; rm -r \$PHOME \n else echo '$PACKNAME home folder not found' \n fi \n if [ -f "\$LDFILE" ]; then rm \$LDFILE \n else echo '$PACKNAME.desktop in local folder not found' \n fi  " >> $POSTRMFILE
echo "exit 0;" >> $POSTRMFILE
echo 'creator was executed'.

# -----------------Create the FAKE BINARY------------------
FBINARY=$ROOTDIR/usr/bin/$PACKNAME
if [ -f "$FBINARY" ]; then rm -v $FBINARY
else echo "Fake binary $FBINARY file not present."
fi
echo "Creating fake binary file $FBINARY"
echo "#!/bin/sh" >> $FBINARY
echo "export EXECBIN=/usr/share/$PACKNAME" >> $FBINARY
echo "argfu(){
for arg in \$@
do
case \$arg in
--version|--v|--V) unset arg; echo '${upperpackname} $PVERSION'; exit 0;;
--help|--h|--?|-?) echo 'Run the script and follow instructions if any.\nCheck Manual (man $PACKNAME).'; exit 0;;
'') break;;
esac
done
}
argfu \$@;" >> $FBINARY
echo "java -jar \$EXECBIN/$PACKNAME.jar \$*" >> $FBINARY

# ---------------- AUTHORS File ---------------
writeauth(){
echo "$maintainer $memail" > $DOCDIR/AUTHORS
echo "Surname FAMILYNAME <authoremailusername@domain.ext>" | zenity --text-info --title "Other Authors" --editable --height=200 --width=490 >> $DOCDIR/AUTHORS
}
if [ -f "$DOCDIR/AUTHORS" ]; then whiptail --yesno "AUTHORS file exists. Overwrite it?" "$LINES" "$COLUMNS"
if [ "$?" -eq 0 ]; then eval writeauth
else echo "The existing AUTHORS file is kept."
fi
else eval writeauth
fi

# ---------------- COPYRIGHT File ----------
writecopy(){
PSOURCE=$(whiptail --inputbox "Enter Package Source code repository here: " 25 50 "http://" 3>&1 1>&2 2>&3)
PLICENSE=$(whiptail --radiolist "Choose Copyright License" 25 50 14 "BSD" 0 "GPL" 0 "GPL-1" 0 "GPL-2" 0 "GPL-3" 1 "LGPL" 0 "LGPL-2" 0 "LGPL-2.1" 0 "LGPL-3" 0 "GFDL-1.3" 0 "GFDL-1.2" 0 "GFDL" 0 "Artistic" 0 "Apache-2.0" 0 --noitem 3>&1 1>&2 2>&3)
echo "Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=REVISION" > $DOCDIR/copyright
echo "Upstream-Name: $PACKNAME" >> $DOCDIR/copyright
echo "Upstream-contact: $maintainer $memail" >> $DOCDIR/copyright
echo "Source: $PSOURCE" >> $DOCDIR/copyright
echo -e "\n" >> $DOCDIR/copyright
echo "Files: *" >> $DOCDIR/copyright
cyear=$(date +%Y)
echo "Copyright: Copyright $cyear $maintainer $memail" >> $DOCDIR/copyright
echo "License: $PLICENSE" >> $DOCDIR/copyright
echo " " >> $DOCDIR/copyright
echo -e "\n" >> $DOCDIR/copyright
echo "You should have received a copy of the GNU License
 along with $PACKNAME.  If not, see <http://www.gnu.org/licenses/>.
 .
 On Debian systems, the complete text of the GNU General
 Public License version can be found in /usr/share/common-licenses/" >> $DOCDIR/copyright
}
if [ -f "$DOCDIR/copyright" ]; then whiptail --yesno "Copyright file exists. Overwrite it?" "$LINES" "$COLUMNS"
if [ "$?" -eq 0 ]; then eval writecopy
else echo "The existing Copyright file is kept."
fi
else eval writecopy
fi

# --------------------README File ------------
writereadme(){
READMETEXT=$(echo "" | zenity --text-info --title "Edit README file" --editable)
echo -e "${upperpackname}. ${PVERSION}\n" > $DOCDIR/README
echo "Description: $READMETEXT" >> $DOCDIR/README
echo "Homepage: $homepage" >> $DOCDIR/README
}

GZFILEN="README"
GZFILE="$DOCDIR/README"
GZFUN="writereadme"
gzaction(){
if [ -f "$GZFILE" ] && [ -f "$GZFILE.gz" ]; then whiptail --yesno "$GZFILEN & $GZFILEN.gz files exist. Overwrite GZIPED file?" "$LINES" "$COLUMNS"
if [ "$?" -eq 1 ]; then rm -v "$GZFILE"
else whiptail --yesno "Gzip existing $GZFILEN file (yes) & Create new $GZFILEN file (no)" "$LINES" "$COLUMNS"
if [ "$?" -eq 0 ]; then gzip -v -f -9 $GZFILE
else eval $GZFUN; gzip -v -f -9 $GZFILE
fi
fi
elif [ ! -f "$GZFILE" ] && [ -f "$GZFILE.gz" ]; then whiptail --yesno "$GZFILEN.gz file exist. Overwrite it?" "$LINES" "$COLUMNS"
if [ "$?" -eq 1 ]; then echo "Keeping exisiting $GZFILEN.gz"
else eval $GZFUN; gzip -v -f -9 $GZFILE
fi
elif [ -f "$GZFILE" ] && [ ! -f "$GZFILE.gz" ]; then whiptail --yesno "$GZFILEN file exist. Overwrite it?" "$LINES" "$COLUMNS"
if [ "$?" -eq 1 ]; then gzip -v -f -9 $GZFILE
else eval $GZFUN; gzip -v -f -9 $GZFILE
fi
elif [ ! -f "$GZFILE" ] && [ ! -f "$GZFILE" ]; then $GZFUN; gzip -v -f -9 $GZFILE
else echo "Nothing done for $GZFILEN file."
fi
}
eval gzaction

# ------------------- NEWS File --------------
TODAY=$(echo $(date +%a", "%d" "%b" "%Y" "%H:%M:%S" "%z))
writenews(){
echo -e "${upperpackname} $PVERSION:
	$TODAY

	Fixes and New Features:
	-----------------------
	Initial support for Ubuntu Global Menu.
	Creation of .desktop installation file.
	5 Formulas to calculate the BMI.
	Export BMI follow-up.
	Mediocre Audio support (Will be improved in future).
	Fixed Some layout issues." > $DOCDIR/NEWS

readmev=$(cat $DOCDIR/NEWS | zenity --text-info --title "Edit NEWS File" --editable --width=500 --height=500) 
echo -e "$readmev" > $DOCDIR/NEWS
}
GZFILEN="NEWS"
GZFILE="$DOCDIR/NEWS"
GZFUN="writenews"
eval gzaction

# ------------------- CHANGELOG.DEBIAN File --------------
writeclog(){
echo "Writing changelog.Debian"
echo -e "$PACKNAME ($PVERSION) stable; urgency=low

  * Updated Exit Action.
    Closes: #999999

  * Added New Icons.

 -- $maintainer $memail  $TODAY" > $DOCDIR/changelog.Debian
readclog=$(cat $DOCDIR/changelog.Debian | zenity --text-info --title "Edit changelog.Debian File" --editable --width=500 --height=500) 
echo -e "$readclog" > $DOCDIR/changelog.Debian
}

GZFILEN="changelog.Debian"
GZFILE="$DOCDIR/changelog.Debian"
GZFUN="writeclog"
eval gzaction

# ------------------- TODO_File --------------
writetodo(){
TODOLIST=$(echo -e "1- Add feature X.\n" | zenity --text-info --title "TODO LIST EDITOR" --editable)
echo "TODO LIST: " > $DOCDIR/TODO
echo -e "\n" >> $DOCDIR/TODO
echo "$TODOLIST" >> $DOCDIR/TODO
}
if [ -f "$DOCDIR/TODO" ]; then whiptail --yesno "TODO file exists. Overwrite it?" 20 80
if [ "$?" -eq 0 ]; then eval writetodo
else echo "The existing TODO file is kept."; export readtodo=$(cat $DOCDIR/TODO | zenity --text-info --title "Edit TODO File" --editable --width=500 --height=500); echo -e "$readtodo" > $DOCDIR/TODO
fi
else eval writetodo
fi

# ------------------THANKS File ----------------
writethanks(){
THANKSTEXT=$(echo -e "1- Special thanks go to: \n" | zenity --text-info --title "THANKS File EDITOR" --editable)
echo "$THANKSTEXT" >> $DOCDIR/THANKS
}
if [ -f "$DOCDIR/THANKS" ]; then whiptail --yesno "THANKS file exists. Overwrite it?" 20 80
if [ "$?" -eq 0 ]; then eval writethanks
else echo "The existing THANKS file is kept."; export readthx=$(cat $DOCDIR/THANKS | zenity --text-info --title "Edit THANKS File" --editable --width=500 --height=500); echo -e "$readthx" > $DOCDIR/THANKS
fi
else eval writethanks
fi

# ----------------- MANUAL File---------------------
MANFILE=$MANDIR/$PACKNAME.1

writeman(){
MANDATE=$(date "+%Y-%m-%d")
SHORTDESC=$(whiptail --inputbox "Manual file Short description: " "$LINES" "$COLUMNS" "Body Mass Index Computer")
LONGDESC=$(whiptail --inputbox "Manual file Long description: " "$LINES" "$COLUMNS" "A tiny Java application that calculates your body mass index.")

echo ".TH ${PACKNAME} 1 $MANDATE ${PACKNAME} ${PACKNAME}" > $MANFILE
echo ".SH NAME" >> $MANFILE
echo "${upperpackname} - ${SHORTDESC}" >> $MANFILE
echo ".SH SYNOPSIS" >> $MANFILE
echo ".B" >> $MANFILE
echo ".I ${PACKNAME}" >> $MANFILE
echo "[OPTIONS]" >> $MANFILE
echo ".SH DESCRIPTION" >> $MANFILE
echo ".I ${PACKNAME}" >> $MANFILE
echo "${LONGDESC}" >> $MANFILE
echo "\." >> $MANFILE
echo ".SH OPTIONS" >> $MANFILE
echo "Help options" >> $MANFILE
echo ".TP" >> $MANFILE
echo "\\\fB\-?\\\fR, \\\fB\-\-help\\\fR" >> $MANFILE
echo "Show help options" >> $MANFILE
echo ".PP" >> $MANFILE
echo "Application options" >> $MANFILE
echo ".TP" >> $MANFILE
echo "\\\fB\--version\\\fR, \\\fB\-\-v\\\fR" >> $MANFILE
echo "Show version info." >> $MANFILE
echo ".SH AUTHORS" >> $MANFILE
echo "- ${maintainer} (${memail:1:(( ${#memail} - 2 ))}) - ${homepage}" >> $MANFILE
manv=$(cat $MANFILE | zenity --text-info --title "Edit Manual File" --editable --width=500 --height=500) 
echo -e "$manv" > $MANFILE
}
GZFILEN="${PACKNAME}.1"
GZFILE=${MANDIR}/${PACKNAME}.1
GZFUN="writeman"
eval gzaction

# ----------------- Other DOCS ---------------------------
otherdocs=$(zenity --file-selection --title "Select other files to include - Cancel if none" --multiple)
transodocs=$(echo "$otherdocs" | sed 's#|# #g')
if [ -z "$otherdocs" ]; then echo "No other doc files selected"
else cp -u -v -t $DOCDIR/ $transodocs
fi

# -----------------------CORRECT PERMISSION---------------
sudo chmod 755 -R $ROOTDIR
if [ -f $ROOTDIR/DEBIAN/md5sums ]; then sudo chmod 644 -c $ROOTDIR/DEBIAN/md5sums
else echo "md5sums does not exist."
fi

sudo chmod 644 -v $ROOTDIR/DEBIAN/control
sudo chmod 644 -v $ROOTDIR/usr/share/doc/$PACKNAME/*
sudo chmod 644 -v $ROOTDIR/usr/share/applications/*
sudo chmod 644 -v $ROOTDIR/usr/share/icons/hicolor/48x48/apps/*
sudo chmod 644 -v $ROOTDIR/usr/share/$MAND/man1/*
sudo chmod 644 -v $ROOTDIR/usr/share/$PACKNAME/lib/*;
JARPATH="$ROOTDIR/usr/share/$PACKNAME/$PACKNAME.jar" 
if [ -f "$JARPATH" ]; then echo "$JARPATH jar is found";
sudo chmod ugo-x -c $ROOTDIR/usr/share/$PACKNAME/$PACKNAME".jar" # remove execution right from executables but add it with postinst
else echo "$JARPATH not found or owner/perm problem"
fi

# ---------- MD5 SUMS FILE for all files in usr folder.----
hasdeep=$(dpkg -s md5deep 2>/dev/null | grep "md5deep" -m 1) # INSTALL md5deep UTILITY - To generate MD5 sums
if [ -z "$hasdeep" ]; then sudo apt-get install -y md5deep
	else echo "md5deep is already installed"
fi
export MATCH=$ROOTDIR"/"
if [ -f "$ROOTDIR/DEBIAN/md5sums" ]; then echo "md5sums exists. removing it"; sudo rm -v $ROOTDIR/DEBIAN/md5sums
	else echo "md5sums file does not exist" 
fi
echo "Creating md5sums file."

md5deeper(){
md5deep -r $ROOTDIR | sed -e '/DEBIAN/g' -e "s#$MATCH##g" | perl -ne 's/^$//g || print' | tee $ROOTDIR/DEBIAN/md5sums;
}
md5classic(){
LINES=$(ls -R $ROOTDIR | grep ^"$ROOTDIR/usr" | sed -e 's/^[.]//g' -e 's/[:]$//g') # HIDDEN DIRS NOT SUPPORTED by PATTERN
i=0
for line in $LINES; do
	if [ -d "$line" ]; then md5sum $line/* | sed -e "s#$MATCH##g" >> $ROOTDIR/DEBIAN/md5sums
	else echo "Directory. Skip."
	fi
done
perl -ne 's/^$//g || print' -i $ROOTDIR/DEBIAN/md5sums # Should be replaced by sed or awk
}

if [ -f "/usr/bin/md5deep" ]; then eval md5deeper 
else eval md5classic
fi

chmod 644 $ROOTDIR/DEBIAN/md5sums
echo "MD5 Sums written in: " " $ROOTDIR/DEBIAN/md5sums"  

# ------------- DEBIAN PACKAGER---------------
echo "Executing debian builder"
fakeroot dpkg-deb -v --build $ROOTDIR

# ------------- LINTIAN ----------------------  
echo "Executing Lintian & Desktop file validator"
datum=$(eval echo $(date +%Y/%m/%d/:%H:%M:%S))
echo $datum > $LOGFILE
lintian -v -i $ROOTDIR.deb | tee -a $LOGFILE | zenity --progress --text "Validating $PACKNAME..." --percentage 10 --pulsate --auto-close --no-cancel
desktop-file-validate $ROOTDIR/usr/share/applications/$PACKNAME.desktop >> $LOGFILE 
linte=$(cat $LOGFILE | grep "E:")
lintw=$(cat $LOGFILE | grep "W:")
if [ -n "$linte" ]; then lemsg="ERRORS"; export nsicon="error"
elif [ -n "$lintw" ]; then lwmsg="WARNINGS"; export nsicon="error"
else lmsg="no errors, nor warnings."; export nsicon="emblem-default"
fi
FINSTALTEXT="finished Debianization of $PACKNAME at $datum with $lmsg$lemsg / $lwmsg. Check $LOGFILE though for warnings (W:) or errors (E:) and correct them by running JDebianizer again. If not, proceed with the Debian file installation. "
notify-send -u low -a JDebianizer -i $nsicon "JDebianizer" "Finished with $lmsg.\n$lemsg\n$lwmsg" -t 1000
whiptail --textbox $LOGFILE 20 80
whiptail --msgbox "$FINSTALTEXT" 20 80
whiptail --yesno "Install the_produced Debian file? $ROOTDIR.deb" 20 80
if [ "$?" -eq 0 ]; then echo "Trying to install the Debian file.";sudo dpkg -i $ROOTDIR.deb
else whiptail --textbox "Script finished. You can install the produced Debian file manually." 20 80
fi

# ---------RE-EXECUTE THE SCRIPT ------------------
eval restartscript
exit 0;

If you feel like it’s a good idea, don’t hesitate to join the repository channel JDebianizer Github REPO and contribute to it. The script actually works fine for simple Java Swing applications, but needs many enhancements.

Specifications

For now the script supposes your Java application is already built (E.g: ANT) and that you have in hands a main JAR file (your app) and eventually some libraries it depends on and you want to debianize the whole as one package.

  • Script must not be executed root power (sudo).
  • The Option (Jayatana Install {Ubuntu Global Menu Integration for Java Swing Apps}) requires internet connection.
  • JDebianizer is Console-only, so it must be run from Terminal or any other Shell.
  • JDebianizer is not compliant with ZSH.

For your Packaging culture