├── configuration files ├── info.php ├── 000-default.conf ├── phpmyadmin.conf └── apache2.conf ├── Media ├── demo.gif ├── demo2.gif ├── icon.png ├── sckde.png ├── scpop.png ├── scut.png ├── scut2.png ├── bitmap.png ├── scfdr4.png ├── sckde2.png ├── sckde4.png ├── scpop2.png ├── scpop3.png ├── scpop4.png ├── demo_0.0.4.gif ├── notif-demo.gif ├── tray-demo.gif ├── functional1.png ├── functional2.png ├── functional3.png ├── install-demo.gif ├── chengeport-demo.gif ├── shortcut-menu.gif ├── Em-nxsdW8AAX8by.jpeg ├── Screenshot_20201115_195724.png ├── Screenshot from 2020-11-15 19-34-52.png └── WhatsApp Image 2020-11-11 at 01.26.52.jpeg ├── install ├── uninstall.sh ├── Installer └── install.sh ├── check_release.py ├── LICENSE ├── tray.py ├── CODE_OF_CONDUCT.md ├── README.md ├── main.py └── interface.glade /configuration files/info.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Media/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/demo.gif -------------------------------------------------------------------------------- /Media/demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/demo2.gif -------------------------------------------------------------------------------- /Media/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/icon.png -------------------------------------------------------------------------------- /Media/sckde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/sckde.png -------------------------------------------------------------------------------- /Media/scpop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scpop.png -------------------------------------------------------------------------------- /Media/scut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scut.png -------------------------------------------------------------------------------- /Media/scut2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scut2.png -------------------------------------------------------------------------------- /Media/bitmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/bitmap.png -------------------------------------------------------------------------------- /Media/scfdr4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scfdr4.png -------------------------------------------------------------------------------- /Media/sckde2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/sckde2.png -------------------------------------------------------------------------------- /Media/sckde4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/sckde4.png -------------------------------------------------------------------------------- /Media/scpop2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scpop2.png -------------------------------------------------------------------------------- /Media/scpop3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scpop3.png -------------------------------------------------------------------------------- /Media/scpop4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/scpop4.png -------------------------------------------------------------------------------- /Media/demo_0.0.4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/demo_0.0.4.gif -------------------------------------------------------------------------------- /Media/notif-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/notif-demo.gif -------------------------------------------------------------------------------- /Media/tray-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/tray-demo.gif -------------------------------------------------------------------------------- /Media/functional1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/functional1.png -------------------------------------------------------------------------------- /Media/functional2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/functional2.png -------------------------------------------------------------------------------- /Media/functional3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/functional3.png -------------------------------------------------------------------------------- /Media/install-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/install-demo.gif -------------------------------------------------------------------------------- /Media/chengeport-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/chengeport-demo.gif -------------------------------------------------------------------------------- /Media/shortcut-menu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/shortcut-menu.gif -------------------------------------------------------------------------------- /Media/Em-nxsdW8AAX8by.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/Em-nxsdW8AAX8by.jpeg -------------------------------------------------------------------------------- /Media/Screenshot_20201115_195724.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/Screenshot_20201115_195724.png -------------------------------------------------------------------------------- /Media/Screenshot from 2020-11-15 19-34-52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/Screenshot from 2020-11-15 19-34-52.png -------------------------------------------------------------------------------- /Media/WhatsApp Image 2020-11-11 at 01.26.52.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CleoMenezesJr/LAMPP-Manager/HEAD/Media/WhatsApp Image 2020-11-11 at 01.26.52.jpeg -------------------------------------------------------------------------------- /install/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt purge --remove mariadb-server -y 4 | sudo apt purge --remove mariadb-client -y 5 | sudo apt purge --remove php* -y 6 | sudo apt purge --remove phpmyadmin php-mbstring php-zip php-gd php-json php-curl -y 7 | sudo apt purge --remove vsftpd -y 8 | sudo apt purge --remove apache2 apache2-bin -y 9 | sudo apt autoremove -y 10 | echo 11 | echo 'Restart LAMPP Manager and see you son!' 12 | exit -------------------------------------------------------------------------------- /check_release.py: -------------------------------------------------------------------------------- 1 | from requests import get 2 | 3 | class CheckRelease: 4 | current_version = 'v0.0.4' 5 | 6 | @classmethod 7 | def _getInformation(cls): 8 | with get('https://api.github.com/repos/CleoMenezes/LAMPP-Manager/releases') as releases: 9 | cls.release = releases.json()[0]['tag_name'] 10 | 11 | @classmethod 12 | def checkRelease(cls): 13 | cls._getInformation() 14 | return cls.current_version != cls.release 15 | 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Cleo Menezes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /install/Installer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import gi 3 | gi.require_version('Gtk', '3.0') 4 | 5 | from gi.repository import Gtk 6 | from gi.repository import GObject 7 | 8 | import os 9 | from subprocess import Popen, PIPE 10 | import fcntl 11 | 12 | wnd = Gtk.Window() 13 | scroll = Gtk.ScrolledWindow() 14 | wnd.set_default_size(550, 550) 15 | wnd.connect("destroy", Gtk.main_quit) 16 | label = Gtk.Label() 17 | label.set_alignment(0, 0) 18 | wnd.add(scroll) 19 | scroll.add(label) 20 | wnd.show_all() 21 | sub_proc = Popen("sudo ./install.sh", stdout=PIPE, shell=True) 22 | sub_outp = "" 23 | 24 | def on_main_window_destroy(self, *args): 25 | Gtk.main_quit() 26 | 27 | def non_block_read(output): 28 | ''' even in a thread, a normal read with block until the buffer is full ''' 29 | fd = output.fileno() 30 | fl = fcntl.fcntl(fd, fcntl.F_GETFL) 31 | fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) 32 | op = output.read() 33 | if op == None: 34 | return '' 35 | return op.decode('utf-8') 36 | 37 | 38 | 39 | def update_terminal(): 40 | label.set_text(label.get_text() + non_block_read(sub_proc.stdout)) 41 | return sub_proc.poll() is None 42 | 43 | GObject.timeout_add(100, update_terminal) 44 | Gtk.main() 45 | -------------------------------------------------------------------------------- /install/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo apt update & sudo apt upgrade -y 4 | sudo apt purge --remove apache* php* mariadb* -y 5 | sudo apt autoremove -y 6 | sudo apt install mariadb-server -y 7 | sudo apt install mariadb-client -y 8 | sudo apt install php -y 9 | cd /opt/LAMPP-Manager/configuration\ files 10 | sudo mv -f /opt/LAMPP-Manager/configuration\ files/ info.php /var/www/html/ 11 | sudo a2enmod rewrite 12 | sudo service apache2 restartx 13 | cd /opt/LAMPP-Manager/configuration\ files 14 | sudo mv -f 000-default.conf /etc/apache2/sites-available/ 15 | sudo apt install phpmyadmin php-mbstring php-zip php-gd php-json php-curl -y 16 | cd /opt/LAMPP-Manager/configuration\ files 17 | sudo mv apache2.conf /etc/apache2/ 18 | sudo ln -s /usr/share/phpmyadmin /var/www/ 19 | sudo chown -R www-data:www-data /usr/share/phpmyadmin 20 | sudo a2enconf phpmyadmin.conf 21 | sudo mkdir -p /var/lib/phpmyadmin/tmp 22 | sudo chown www-data:www-data /var/lib/phpmyadmin/tmp 23 | sudo a2enmod proxy_fcgi setenvif 24 | sudo chmod 777 -R /var/www/html 25 | sudo apt-get install vsftpd 26 | sudo apt install libnotify-bin 27 | sudo apt install apache2-bin -y 28 | sudo a2enconf php*.*-fpm 29 | sudo apt install apache2 30 | 31 | echo 32 | echo 'Restart LAMPP Manager and Enjoy!' 33 | exit -------------------------------------------------------------------------------- /tray.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import signal 3 | import gi 4 | import os 5 | gi.require_version('Gtk', '3.0') 6 | gi.require_version('AppIndicator3', '0.1') 7 | from gi.repository import Gtk, AppIndicator3 8 | 9 | class Indicator(): 10 | def __init__(self): 11 | self.app = 'Lampp Manager' 12 | iconpath = "/home/cleomenezesjr/CODE/LAMPP Manager/Media/bitmap.png" 13 | self.indicator = AppIndicator3.Indicator.new( 14 | self.app, iconpath, 15 | AppIndicator3.IndicatorCategory.OTHER) 16 | self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) 17 | self.indicator.set_menu(self.create_menu()) 18 | 19 | def create_menu(self): 20 | menu = Gtk.Menu() 21 | # menu item 1 22 | openLM = Gtk.MenuItem('Open Lamp Manager') 23 | openLM.connect('activate', self.openLM) 24 | menu.append(openLM) 25 | # separator 26 | # menu_sep = Gtk.SeparatorMenuItem() 27 | # menu.append(menu_sep) 28 | # quit 29 | item_quit = Gtk.MenuItem('Quit') 30 | item_quit.connect('activate', self.stop) 31 | menu.append(item_quit) 32 | 33 | menu.show_all() 34 | return menu 35 | 36 | def openLM(self, source): 37 | os.popen('pkill -f main.py; python3 main.py') 38 | os.popen('python3 main.py; exit') 39 | 40 | def stop(self, source): 41 | os.popen('pkill -f main.py') 42 | Gtk.main_quit() 43 | 44 | Indicator() 45 | signal.signal(signal.SIGINT, signal.SIG_DFL) 46 | Gtk.main() -------------------------------------------------------------------------------- /configuration files/000-default.conf: -------------------------------------------------------------------------------- 1 | GNU nano 5.2 /etc/apache2/sites-available/000-default.conf 2 | 3 | # The ServerName directive sets the request scheme, hostname and port that 4 | # the server uses to identify itself. This is used when creating 5 | # redirection URLs. In the context of virtual hosts, the ServerName 6 | # specifies what hostname must appear in the request's Host: header to 7 | # match this virtual host. For the default virtual host (this file) this 8 | # value is not decisive as it is used as a last resort host regardless. 9 | # However, you must set it for any further virtual host explicitly. 10 | #ServerName www.example.com 11 | 12 | ServerAdmin webmaster@localhost 13 | DocumentRoot /var/www/html 14 | 15 | # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, 16 | # error, crit, alert, emerg. 17 | # It is also possible to configure the loglevel for particular 18 | # modules, e.g. 19 | #LogLevel info ssl:warn 20 | 21 | ErrorLog ${APACHE_LOG_DIR}/error.log 22 | CustomLog ${APACHE_LOG_DIR}/access.log combined 23 | 24 | # For most configuration files from conf-available/, which are 25 | # enabled or disabled at a global level, it is possible to 26 | # include a line for only one particular virtual host. For example the 27 | # following line enables the CGI configuration for this host only 28 | # after it has been globally disabled with "a2disconf". 29 | #Include conf-available/serve-cgi-bin.conf 30 | 31 | 32 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 33 | 34 | AllowOverride All 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /configuration files/phpmyadmin.conf: -------------------------------------------------------------------------------- 1 | # phpMyAdmin default Apache configuration 2 | 3 | Alias /phpmyadmin /usr/share/phpmyadmin 4 | 5 | 6 | Options SymLinksIfOwnerMatch 7 | DirectoryIndex index.php 8 | 9 | 10 | 11 | AddType application/x-httpd-php .php 12 | 13 | 14 | SetHandler application/x-httpd-php 15 | 16 | 17 | php_value include_path . 18 | php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp 19 | php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/ 20 | php_admin_value mbstring.func_overload 0 21 | 22 | 23 | 24 | AddType application/x-httpd-php .php 25 | 26 | 27 | SetHandler application/x-httpd-php 28 | 29 | 30 | php_value include_path . 31 | php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp 32 | php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/ 33 | php_admin_value mbstring.func_overload 0 34 | 35 | 36 | 37 | 38 | # Disallow web access to directories that don't need it 39 | 40 | Require all denied 41 | 42 | 43 | Require all denied 44 | 45 | 46 | Require all denied 47 | 48 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at produtor.junior.menezes@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 |
4 | LAMPP Manager 5 |
6 | LAMPP Manager 7 |
8 |

9 | 10 | 11 | 12 |

13 | A great way to manage and install LAMPP services
14 | GitHub stars 15 | GitHub followers 16 | 17 | Download 19 |

20 |

21 | 22 | ![screenshot](Media/demo_0.0.4.gif) 23 | 24 |

25 | 26 | 27 | # ⚈ About & How to use 28 | Disclaimer: This project was created in order to facilitate the use of LAMPP. Before it was just a personal project to facilitate my day to day, but I decided to share it. Please enjoy and let me know any issues! 29 | 30 |

31 | LAMPP Manager is a front end of LAMPP services where it will also have resources to facilitate day-to-day use, such as shortcuts to open the server directory, phpmyadmin and etc., and also to install LAMPP in an easy and intuitive way. 32 | I created an interface as clean as possible, without distractions, where you can simply start Apache or stop MySQL or simply with one click stop or start all services. 33 | 34 | Maybe for those who are used to doing everything for the Terminal they won't care much, but believe me, those who are starting in the Linux world sometimes just want to download a program that solves all of this in an easy and intuitive way. 35 |

36 | 37 |

38 | 🚧 Don't forget that it's still going on day by day... 🚧 39 |

40 | 41 |
42 | 43 | # ⚈ How to get started 44 |

45 | LAMPP Manager is now available in DEB and RPM. 46 | 47 | ### Deb installation 48 | To install the deb version it is only necessary to download the file here,install via your package installer probably just by opening the file. Install it as you normally do with any other program. 49 | 50 | ### Rpm installation 51 | Our version in RPM is still experimental and was made through conversion by Alien but all the code was adapted to work in Fedora. 52 | 1. Download the RPM file here 53 | 2. Install Alien: ```sudo yum install alien``` 54 | 3. Go to the directory where the lampp-manager _ *. *. *. rpm file is and run ```alien -i lampp-manager _ *. *. *. rpm``` 55 | 56 | Install it as you normally do with any other program. When the installation is finished, no other process is necessary. 57 | 58 | ## Installation of LAMPP 59 | After wasting a lot of time setting up a new environment and several times having problems with the installation of LAMPP, I tested several solutions and decided to create a simple script for installing and configuring the entire environment. LAMPP Manager. 60 | I hope you enjoy your time programming. 61 | 62 | To install or uninstall it you just need to access the menu button on the upper left, click on Install LAMPP and choose between the Install Now and Uninstall options. After that, a Terminal window will open asking for your root password in order to execute your script. 63 | Remember, there are settings that must be manual such as configuring MySQL, Phpmyadmin and etc. 64 | 65 |
66 | 67 |

68 | 69 | ![screenshot](Media/install-demo.gif) 70 | 71 |

72 |

73 | 74 | 75 | # ⚈ New Features 76 |

77 | 78 | ## Change port services 79 | 80 | This was certainly the most requested feature. Now you can easily change the service port just by clicking on the corresponding button on the right side, choose the port, click on the Change button, confirm the change and that's it! 81 | By default the FTP used is VSFPd, the port must still be changed manually. 82 | 83 | 84 |

85 | 86 | ![screenshot](Media/chengeport-demo.gif) 87 | 88 |

89 | 90 | ## App indicator 91 | 92 | We now have an indicator on the tray that runs in the background so you can access LAMPP Manager more easily. spoiler: in the future they will be able to turn services on and off through there. 93 | 94 | ![screenshot](Media/tray-demo.gif) 95 | 96 | 97 | ## Notifications 98 | 99 | In addition to showing the status and ports of the services, LAMPP Manager now notifies you when these changes occur. 100 | 101 | ![screenshot](Media/notif-demo.gif) 102 | 103 | ## Shortcuts 104 | 105 | Some shortcuts on the menu to facilitate the workflow. 106 | 107 | 108 | ![screenshot](Media/shortcut-menu.gif) 109 | 110 |
111 | 112 | # ⚈ Some Screenshots 113 | 114 |
115 |

116 |

Pop!_OS

117 |
118 |

Fedora

119 |
120 |

KDE Neon

121 |
122 |

123 | 124 | 125 | 126 | # ⚈ Tech Stack 127 | 128 | The following tools were used in the construction of the project: 129 | 130 | - [Python](https://www.python.org/) 131 | - [GTK](https://www.gtk.org/) 132 | - [Glade](https://glade.gnome.org/) 133 | - [Bash](https://www.gnu.org/software/bash/) 134 | 135 |

⚈ Bugs

136 |

137 | Please report any type of bug. Remember that this is an open source project and will evolve with everyone's help. :) 138 | Make the Linux world a friendlier place. 139 |

140 | 141 | 142 | ## License 143 | 144 | MIT 145 | 146 | --- 147 | 148 | > LinkedIn [Cleo-menezes-jr](https://www.linkedin.com/in/cleo-menezes-jr/)  ·  149 | > GitHub [CleoMenezes](https://github.com/CleoMenezes)  ·  150 | > Twitter [@Menemezis](https://twitter.com/Menemezis)  ·  151 | > Instagram [@cleo.menemezes](https://www.instagram.com/cleo.menemezes/)  ·  152 | -------------------------------------------------------------------------------- /configuration files/apache2.conf: -------------------------------------------------------------------------------- 1 | # This is the main Apache server configuration file. It contains the 2 | # configuration directives that give the server its instructions. 3 | # See http://httpd.apache.org/docs/2.4/ for detailed information about 4 | # the directives and /usr/share/doc/apache2/README.Debian about Debian specific 5 | # hints. 6 | # 7 | # 8 | # Summary of how the Apache 2 configuration works in Debian: 9 | # The Apache 2 web server configuration in Debian is quite different to 10 | # upstream's suggested way to configure the web server. This is because Debian's 11 | # default Apache2 installation attempts to make adding and removing modules, 12 | # virtual hosts, and extra configuration directives as flexible as possible, in 13 | # order to make automating the changes and administering the server as easy as 14 | # possible. 15 | 16 | # It is split into several files forming the configuration hierarchy outlined 17 | # below, all located in the /etc/apache2/ directory: 18 | # 19 | # /etc/apache2/ 20 | # |-- apache2.conf 21 | # | `-- ports.conf 22 | # |-- mods-enabled 23 | # | |-- *.load 24 | # | `-- *.conf 25 | # |-- conf-enabled 26 | # | `-- *.conf 27 | # `-- sites-enabled 28 | # `-- *.conf 29 | # 30 | # 31 | # * apache2.conf is the main configuration file (this file). It puts the pieces 32 | # together by including all remaining configuration files when starting up the 33 | # web server. 34 | # 35 | # * ports.conf is always included from the main configuration file. It is 36 | # supposed to determine listening ports for incoming connections which can be 37 | # customized anytime. 38 | # 39 | # * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ 40 | # directories contain particular configuration snippets which manage modules, 41 | # global configuration fragments, or virtual host configurations, 42 | # respectively. 43 | # 44 | # They are activated by symlinking available configuration files from their 45 | # respective *-available/ counterparts. These should be managed by using our 46 | # helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See 47 | # their respective man pages for detailed information. 48 | # 49 | # * The binary is called apache2. Due to the use of environment variables, in 50 | # the default configuration, apache2 needs to be started/stopped with 51 | # /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not 52 | # work with the default configuration. 53 | 54 | 55 | # Global configuration 56 | # 57 | 58 | # 59 | # ServerRoot: The top of the directory tree under which the server's 60 | # configuration, error, and log files are kept. 61 | # 62 | # NOTE! If you intend to place this on an NFS (or otherwise network) 63 | # mounted filesystem then please read the Mutex documentation (available 64 | # at ); 65 | # you will save yourself a lot of trouble. 66 | # 67 | # Do NOT add a slash at the end of the directory path. 68 | # 69 | #ServerRoot "/etc/apache2" 70 | 71 | # 72 | # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. 73 | # 74 | #Mutex file:${APACHE_LOCK_DIR} default 75 | 76 | # 77 | # The directory where shm and other runtime files will be stored. 78 | # 79 | 80 | DefaultRuntimeDir ${APACHE_RUN_DIR} 81 | 82 | # 83 | # PidFile: The file in which the server should record its process 84 | # identification number when it starts. 85 | # This needs to be set in /etc/apache2/envvars 86 | # 87 | PidFile ${APACHE_PID_FILE} 88 | 89 | # 90 | # Timeout: The number of seconds before receives and sends time out. 91 | # 92 | Timeout 300 93 | 94 | # 95 | # KeepAlive: Whether or not to allow persistent connections (more than 96 | # one request per connection). Set to "Off" to deactivate. 97 | # 98 | KeepAlive On 99 | 100 | # 101 | # MaxKeepAliveRequests: The maximum number of requests to allow 102 | # during a persistent connection. Set to 0 to allow an unlimited amount. 103 | # We recommend you leave this number high, for maximum performance. 104 | # 105 | MaxKeepAliveRequests 100 106 | 107 | # 108 | # KeepAliveTimeout: Number of seconds to wait for the next request from the 109 | # same client on the same connection. 110 | # 111 | KeepAliveTimeout 5 112 | 113 | 114 | # These need to be set in /etc/apache2/envvars 115 | User ${APACHE_RUN_USER} 116 | Group ${APACHE_RUN_GROUP} 117 | 118 | # 119 | # HostnameLookups: Log the names of clients or just their IP addresses 120 | # e.g., www.apache.org (on) or 204.62.129.132 (off). 121 | # The default is off because it'd be overall better for the net if people 122 | # had to knowingly turn this feature on, since enabling it means that 123 | # each client request will result in AT LEAST one lookup request to the 124 | # nameserver. 125 | # 126 | HostnameLookups Off 127 | 128 | # ErrorLog: The location of the error log file. 129 | # If you do not specify an ErrorLog directive within a 130 | # container, error messages relating to that virtual host will be 131 | # logged here. If you *do* define an error logfile for a 132 | # container, that host's errors will be logged there and not here. 133 | # 134 | ErrorLog ${APACHE_LOG_DIR}/error.log 135 | 136 | # 137 | # LogLevel: Control the severity of messages logged to the error_log. 138 | # Available values: trace8, ..., trace1, debug, info, notice, warn, 139 | # error, crit, alert, emerg. 140 | # It is also possible to configure the log level for particular modules, e.g. 141 | # "LogLevel info ssl:warn" 142 | # 143 | LogLevel warn 144 | 145 | # Include module configuration: 146 | IncludeOptional mods-enabled/*.load 147 | IncludeOptional mods-enabled/*.conf 148 | 149 | # Include list of ports to listen on 150 | Include ports.conf 151 | 152 | 153 | # Sets the default security model of the Apache2 HTTPD server. It does 154 | # not allow access to the root filesystem outside of /usr/share and /var/www. 155 | # The former is used by web applications packaged in Debian, 156 | # the latter may be used for local directories served by the web server. If 157 | # your system is serving content from a sub-directory in /srv you must allow 158 | # access here, or in any related virtual host. 159 | 160 | Options FollowSymLinks 161 | AllowOverride None 162 | Require all denied 163 | 164 | 165 | 166 | AllowOverride None 167 | Require all granted 168 | 169 | 170 | 171 | Options Indexes FollowSymLinks 172 | AllowOverride None 173 | Require all granted 174 | 175 | 176 | # 177 | # Options Indexes FollowSymLinks 178 | # AllowOverride None 179 | # Require all granted 180 | # 181 | 182 | 183 | 184 | 185 | # AccessFileName: The name of the file to look for in each directory 186 | # for additional configuration directives. See also the AllowOverride 187 | # directive. 188 | # 189 | AccessFileName .htaccess 190 | 191 | # 192 | # The following lines prevent .htaccess and .htpasswd files from being 193 | # viewed by Web clients. 194 | # 195 | 196 | Require all denied 197 | 198 | 199 | 200 | # 201 | # The following directives define some format nicknames for use with 202 | # a CustomLog directive. 203 | # 204 | # These deviate from the Common Log Format definitions in that they use %O 205 | # (the actual bytes sent including headers) instead of %b (the size of the 206 | # requested file), because the latter makes it impossible to detect partial 207 | # requests. 208 | # 209 | # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. 210 | # Use mod_remoteip instead. 211 | # 212 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 213 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 214 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 215 | LogFormat "%{Referer}i -> %U" referer 216 | LogFormat "%{User-agent}i" agent 217 | 218 | # Include of directories ignores editors' and dpkg's backup files, 219 | # see README.Debian for details. 220 | 221 | # Include generic snippets of statements 222 | IncludeOptional conf-enabled/*.conf 223 | 224 | # Include the virtual host configurations: 225 | IncludeOptional sites-enabled/*.conf 226 | 227 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 228 | 229 | Include /etc/phpmyadmin/apache.conf 230 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '3.0') 3 | from gi.repository import Gtk 4 | import subprocess 5 | import os 6 | from time import sleep 7 | import threading 8 | from check_release import CheckRelease 9 | 10 | 11 | builder = Gtk.Builder() 12 | 13 | builder.add_from_file("interface.glade") 14 | 15 | class Handler(object): 16 | 17 | def __init__(self, *args, **kwargs): 18 | super(Handler, self).__init__(*args, **kwargs) 19 | 20 | self.button_a_start = builder.get_object('button_a_start') 21 | self.button_a_stop = builder.get_object('button_a_stop') 22 | self.button_m_start = builder.get_object('button_m_start') 23 | self.button_m_stop = builder.get_object('button_m_stop') 24 | self.apache_status = builder.get_object('apache_status') 25 | self.mysql_status = builder.get_object('mysql_status') 26 | self.open_directory = builder.get_object('open_directory') 27 | self.check_updtae = builder.get_object('check_update') 28 | self.log_mysql = builder.get_object('log_mysql') 29 | self.install_lampp = builder.get_object('install_lampp') 30 | self.button_a_restart = builder.get_object('button_a_restart') 31 | self.button_m_restart = builder.get_object('button_m_restart') 32 | self.button_start_all = builder.get_object('button_start_all') 33 | self.button_stop_all = builder.get_object('button_stop_all') 34 | self.button_restart_all = builder.get_object('button_restart_all') 35 | self.button_p_start = builder.get_object('button_p_start') 36 | self.button_p_stop = builder.get_object('button_p_stop') 37 | self.ftpd_status = builder.get_object('ftpd_status') 38 | self.button_p_stop = builder.get_object('button_p_stop') 39 | self.button_p_restart = builder.get_object('button_p_restart') 40 | self.about = builder.get_object('about') 41 | self.apache_port = builder.get_object('apache_port') 42 | self.mysql_port = builder.get_object('mysql_port') 43 | self.ftp_port = builder.get_object('ftp_port') 44 | self.apache_img_status = builder.get_object('apache_img_status') 45 | self.mysql_img_status = builder.get_object('mysql_img_status') 46 | self.ftpd_img_status = builder.get_object('ftpd_img_status') 47 | self.localhost = builder.get_object('localhost') 48 | self.phpmyadmin = builder.get_object('phpmyadmin') 49 | self.php_info = builder.get_object('php_info') 50 | self.entry_apache_port = builder.get_object('entry_apache_port') 51 | self.send_apache_port = builder.get_object('send_apache_port') 52 | self.send_mysql_port = builder.get_object('send_mysql_port') 53 | self.entry_mysql_port = builder.get_object('entry_mysql_port') 54 | 55 | # Quit button # 56 | def on_main_window_destroy(self, *args): 57 | Gtk.main_quit() 58 | # Getting services port # 59 | def get_apache_port(self, *args): 60 | with open('/etc/apache2/ports.conf', 'r') as apache_port_file: 61 | text_file = apache_port_file.readlines() 62 | self.current_apache_port = str(text_file[4].replace('Listen', '').strip()) 63 | return self.current_apache_port 64 | 65 | 66 | def get_mysql_port(self, *args): 67 | with open('/etc/mysql/mariadb.conf.d/50-server.cnf', 'r') as mysql_port_file: 68 | text_file = mysql_port_file.readlines() 69 | self.current_mysql_port = str(text_file[18].replace('#port', '').strip().replace('= ', '')) 70 | return self.current_mysql_port 71 | 72 | # Validating services # 73 | def validate_apache(self, *args): 74 | self.status_command_a = subprocess.run('service apache2 status', stdout=subprocess.PIPE, text=True, shell=True) 75 | return str(self.status_command_a.stdout) 76 | 77 | 78 | def validate_mysql(self, *args): 79 | self.status_command_m = subprocess.run('service mysql status', stdout=subprocess.PIPE, text=True, shell=True) 80 | return str(self.status_command_m.stdout) 81 | 82 | def validate_ftp(self, *args): 83 | self.status_command_f = subprocess.run('service vsftpd status', stdout=subprocess.PIPE, text=True, shell=True) 84 | return str(self.status_command_f.stdout) 85 | 86 | ################################ Notification area ################################ 87 | 88 | # Services Status # 89 | 90 | def apache_notify(self, status): 91 | 92 | a_status = status 93 | 94 | if 'active (running)' in self.validate_apache(): 95 | new_port = 'Active' 96 | elif 'inactive (dead)' in self.validate_apache(): 97 | new_port = 'Inactive' 98 | 99 | 100 | if (self.current_port != new_port) and (new_port == "Active") and (a_status != 'restart'): 101 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Has been activated"', stdout=subprocess.PIPE, text=True, shell=True) 102 | 103 | elif (self.current_port == new_port) and (new_port == "Active") and (a_status != 'restart'): 104 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Service was already activated"', stdout=subprocess.PIPE, text=True, shell=True) 105 | 106 | elif (self.current_port != new_port) and (new_port == "Inactive") and (a_status != 'restart'): 107 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Has been disabled"', stdout=subprocess.PIPE, text=True, shell=True) 108 | 109 | elif (self.current_port == new_port) and (new_port == "Inactive") and (a_status != 'restart'): 110 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Service was already disabled"', stdout=subprocess.PIPE, text=True, shell=True) 111 | 112 | elif (a_status == 'restart') and (new_port == "Active"): 113 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Service restarted"', stdout=subprocess.PIPE, text=True, shell=True) 114 | 115 | elif (a_status == 'restart') and (new_port == "Inactive"): 116 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Could not restart"', stdout=subprocess.PIPE, text=True, shell=True) 117 | 118 | else: 119 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Apache Status" "Cannot connet"', stdout=subprocess.PIPE, text=True, shell=True) 120 | 121 | def mysql_notify(self, status): 122 | 123 | a_mysql = status 124 | 125 | if 'active (running)' in self.validate_mysql(): 126 | new_port = 'Active' 127 | elif 'inactive (dead)' in self.validate_mysql(): 128 | new_port = 'Inactive' 129 | 130 | if (self.current_port != new_port) and (new_port == "Active") and (a_mysql != 'restart'): 131 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Has been activated"', stdout=subprocess.PIPE, text=True, shell=True) 132 | 133 | elif (self.current_port == new_port) and (new_port == "Active") and (a_mysql != 'restart'): 134 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Service was already activated"', stdout=subprocess.PIPE, text=True, shell=True) 135 | 136 | elif (self.current_port != new_port) and (new_port == "Inactive") and (a_mysql != 'restart'): 137 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Has been disabled"', stdout=subprocess.PIPE, text=True, shell=True) 138 | 139 | elif (self.current_port == new_port) and (new_port == "Inactive") and (a_mysql != 'restart'): 140 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Service was already disabled"', stdout=subprocess.PIPE, text=True, shell=True) 141 | 142 | elif (a_mysql == 'restart') and (new_port == "Active"): 143 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Service restarted"', stdout=subprocess.PIPE, text=True, shell=True) 144 | 145 | elif (a_mysql == 'restart') and (new_port == "Inactive") and (a_mysql != 'Inactive'): 146 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Could not restart"', stdout=subprocess.PIPE, text=True, shell=True) 147 | 148 | else: 149 | subprocess.run('notify-send -i /Media/bitmap.png -u low "MySQL Status" "Cannot connet"', stdout=subprocess.PIPE, text=True, shell=True) 150 | 151 | def ftp_notify(self, status): 152 | 153 | f_status = status 154 | 155 | if 'active (running)' in self.validate_ftp(): 156 | new_port = 'Active' 157 | elif 'inactive (dead)' in self.validate_ftp(): 158 | new_port = 'Inactive' 159 | 160 | if (self.current_port != new_port) and (new_port == "Active") and (f_status != 'restart'): 161 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Has been activated"', stdout=subprocess.PIPE, text=True, shell=True) 162 | 163 | elif (self.current_port == new_port) and (new_port == "Active") and (f_status != 'restart'): 164 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Service was already activated"', stdout=subprocess.PIPE, text=True, shell=True) 165 | 166 | elif (self.current_port != new_port) and (new_port == "Inactive") and (f_status != 'restart'): 167 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Has been disabled"', stdout=subprocess.PIPE, text=True, shell=True) 168 | 169 | elif (self.current_port == new_port) and (new_port == "Inactive") and (f_status != 'restart'): 170 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Service was already disabled"', stdout=subprocess.PIPE, text=True, shell=True) 171 | 172 | elif (f_status == 'restart') and (new_port == "Active"): 173 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Service restarted"', stdout=subprocess.PIPE, text=True, shell=True) 174 | 175 | elif (f_status == 'restart') and (new_port == "Inactive"): 176 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Could not restart"', stdout=subprocess.PIPE, text=True, shell=True) 177 | 178 | else: 179 | subprocess.run('notify-send -i /Media/bitmap.png -u low "FTPd Status" "Cannot connet"', stdout=subprocess.PIPE, text=True, shell=True) 180 | 181 | 182 | ################################################################################ 183 | 184 | # Apache service control # 185 | 186 | def on_button_a_start_clicked(self, *args): 187 | # Start apache service 188 | self.current_port = self.apache_status.get_text() 189 | subprocess.run('service apache2 start', shell=True) 190 | self.apache_notify('Active') 191 | 192 | 193 | def on_button_a_stop_clicked(self, *args): 194 | # Stop apache service 195 | self.current_port = self.apache_status.get_text() 196 | subprocess.run('service apache2 stop', shell=True) 197 | self.apache_notify('Inactive') 198 | 199 | 200 | def on_button_a_restart_clicked(self, *args): 201 | # Restart apache service 202 | self.current_port = self.apache_status.get_text() 203 | subprocess.run('service apache2 restart', shell=True) 204 | self.apache_notify('restart') 205 | 206 | 207 | ################################################################################ 208 | 209 | # MySQL service control # 210 | 211 | def on_button_m_start_clicked(self, *args): 212 | # Start apache service 213 | self.current_port = self.mysql_status.get_text() 214 | subprocess.run('service mysql start', shell=True) 215 | self.mysql_notify('Active') 216 | 217 | 218 | def on_button_m_stop_clicked(self, *args): 219 | # Stop apache service 220 | self.current_port = self.mysql_status.get_text() 221 | subprocess.run('service mysql stop', shell=True) 222 | self.mysql_notify('Inactive') 223 | 224 | 225 | def on_button_m_restart_clicked(self, *args): 226 | # Restart apache service 227 | self.current_port = self.mysql_status.get_text() 228 | subprocess.run('service mysql restart', shell=True) 229 | self.mysql_notify('restart') 230 | 231 | 232 | ################################################################################ 233 | 234 | # FTP service control # 235 | 236 | def on_button_p_start_clicked(self, *args): 237 | # Start FTP service 238 | self.current_port = self.ftpd_status.get_text() 239 | subprocess.run('service vsftpd start', shell=True) 240 | self.ftp_notify('Active') 241 | 242 | def on_button_p_stop_clicked(self, *args): 243 | # Stop FTP service 244 | self.current_port = self.ftpd_status.get_text() 245 | subprocess.run('service vsftpd stop', shell=True) 246 | self.ftp_notify('Inactive') 247 | 248 | def on_button_p_restart_clicked(self, *args): 249 | # Restart FTP service 250 | self.current_port = self.ftpd_status.get_text() 251 | subprocess.run('service vsftpd restart', shell=True) 252 | self.ftp_notify('restart') 253 | 254 | ################################################################################ 255 | 256 | # Open directory button # 257 | 258 | def on_open_directory_clicked(self, *args): 259 | os.popen('for file_manager in $file_manager thunar konqueror nautilus dolphin deepin nemo xfe; do if which $file_manager > /dev/null 2>&1; then exec $file_manager /var/www/html; fi; done') 260 | 261 | # Open directory logs apache # 262 | 263 | def on_log_mysql_clicked(self,*args): 264 | os.popen('for file_manager in $file_manager thunar konqueror nautilus dolphin deepin nemo xfe; do if which $file_manager > /dev/null 2>&1; then exec $file_manager admin:///var/log/mysql; fi; done') 265 | 266 | # Open about # 267 | 268 | def on_about_clicked(self, *args): 269 | import os 270 | os.popen('sudo -u `logname` sensible-browser https://github.com/CleoMenezes/LAMPP-Manager/ ; exit') 271 | 272 | # Open localhost # 273 | 274 | def on_localhost_clicked(self, *args): 275 | os.popen(f'sudo -u `logname` sensible-browser http://localhost:{str(self.get_apache_port())}/ ; exit') 276 | 277 | # Open phpmyadmin 278 | 279 | def on_phpmyadmin_clicked(self, *args): 280 | os.popen(f'sudo -u `logname` sensible-browser http://localhost:{str(self.get_apache_port())}/phpmyadmin/ ; exit') 281 | 282 | # Open info.php 283 | 284 | def on_php_info_clicked(self, *args): 285 | os.popen(f'sudo -u `logname` sensible-browser http://localhost:{str(self.get_apache_port())}/info.php ; exit') 286 | 287 | # Check update 288 | 289 | def on_check_update_clicked(self, *args): 290 | try: 291 | if CheckRelease.checkRelease(): 292 | subprocess.run('notify-send -i /Media/bitmap.png -u low "There is a new update" "A new version is available on GitHub"', shell=True) 293 | else: 294 | subprocess.run('notify-send -i /Media/bitmap.png -u low "There is not a new update" "We are working for it, new features are available soon"', shell=True) 295 | except: 296 | subprocess.run('notify-send -i /Media/bitmap.png -u low "Service unavailable" "There is a problem accessing the link, please try again later"', shell=True) 297 | 298 | 299 | # Start all services # 300 | def on_button_start_all_clicked(self, *args): 301 | 302 | self.on_button_a_start_clicked() 303 | self.on_button_m_start_clicked() 304 | self.on_button_p_start_clicked() 305 | 306 | # Stop all services # 307 | def on_button_stop_all_clicked(self, *args): 308 | 309 | self.on_button_a_stop_clicked() 310 | self.on_button_m_stop_clicked() 311 | self.on_button_p_stop_clicked() 312 | 313 | # Restart all services # 314 | def on_button_restart_all_clicked(self, *args): 315 | 316 | self.on_button_a_restart_clicked() 317 | self.on_button_m_restart_clicked() 318 | self.on_button_p_restart_clicked() 319 | 320 | # Install LAMPP # 321 | 322 | def on_install_lampp_clicked(self, *args): 323 | os.popen('cd install && for terminal in $TERMINAL x-terminal-emulator urxvt rxvt terminator Eterm aterm xterm gnome-terminal roxterm xfce4-terminal; do if which $terminal > /dev/null 2>&1; then exec $terminal --noclose -e sudo ./install.sh; fi; done') 324 | 325 | # Install LAMPP # 326 | 327 | def on_uninstall_lampp_clicked(self, *args): 328 | os.popen('cd install && for terminal in $TERMINAL x-terminal-emulator urxvt rxvt terminator Eterm aterm xterm gnome-terminal roxterm xfce4-terminal; do if which $terminal > /dev/null 2>&1; then exec $terminal --noclose -e sudo ./uninstall.sh; fi; done') 329 | ################################################################################ 330 | 331 | # change ports # 332 | 333 | def on_send_apache_port_clicked(self, *args): 334 | # Change apache port 335 | current_port = self.get_apache_port() 336 | new_port = self.entry_apache_port.get_text() 337 | subprocess.run(f'pkexec sed -i "5 s/{current_port}/{new_port}/" /etc/apache2/ports.conf', shell=True) 338 | 339 | if current_port != self.get_apache_port(): 340 | subprocess.run(f'notify-send -i /Media/bitmap.png -u low "Apache Port" "Port changed from {current_port} to {new_port}"', stdout=subprocess.PIPE, text=True, shell=True) 341 | else: 342 | subprocess.run(f'notify-send -i /Media/bitmap.png -u low "Apache Port" "There were no changes"', stdout=subprocess.PIPE, text=True, shell=True) 343 | 344 | def on_send_mysql_port_clicked(self, *args): 345 | # Change mysql port 346 | current_port = self.get_mysql_port() 347 | new_port = self.entry_mysql_port.get_text() 348 | subprocess.run(f'pkexec sed -i "5 s/{current_port}/{new_port}/" /etc/mysql/mariadb.conf.d/50-server.cnf', shell=True) 349 | 350 | if current_port != self.get_mysql_port(): 351 | subprocess.run(f'notify-send -i /Media/bitmap.png -u low "MySQL Port" "Port changed from {current_port} to {new_port}"', stdout=subprocess.PIPE, text=True, shell=True) 352 | else: 353 | subprocess.run(f'notify-send -i /Media/bitmap.png -u low "MySQL Port" "There were no changes"', stdout=subprocess.PIPE, text=True, shell=True) 354 | 355 | 356 | ################################################################################ 357 | 358 | class CurrentServiceStatus(Handler): 359 | def __init__(self, *args): 360 | super().__init__() 361 | 362 | 363 | while True: 364 | 365 | try: 366 | if self.validate_apache()[0] == '●': 367 | # Putting current status of Apache # 368 | if 'dead' in self.validate_apache(): 369 | self.apache_status.set_text('Inactive') 370 | self.apache_img_status.set_from_icon_name('emblem-unreadable', 1) 371 | elif 'running' in self.validate_apache(): 372 | self.apache_status.set_text('Active') 373 | self.apache_img_status.set_from_icon_name('emblem-default', 1) 374 | else: 375 | self.apache_status.set_text('Cannot connect') 376 | self.apache_img_status.set_from_icon_name('emblem-important', 1) 377 | 378 | # Putting current Apache port # 379 | self.apache_port.set_text(self.get_apache_port()) 380 | 381 | current_a = str(self.get_apache_port()) 382 | current_b = str(self.entry_apache_port.get_text()) 383 | 384 | if current_b == str("."): 385 | self.entry_apache_port.set_text(self.get_apache_port()) 386 | elif current_b == current_a: 387 | pass 388 | 389 | except: 390 | self.apache_status.set_text('Not found') 391 | self.apache_img_status.set_from_icon_name('emblem-important', 1) 392 | 393 | self.entry_apache_port.set_text('Not found') 394 | 395 | 396 | # Putting current status of MySQL service # 397 | 398 | try: 399 | if self.validate_mysql()[0] == '●': 400 | if 'dead' in self.validate_mysql(): 401 | self.mysql_status.set_text('Inactive') 402 | self.mysql_img_status.set_from_icon_name('emblem-unreadable', 1) 403 | 404 | elif 'running' in self.validate_mysql(): 405 | self.mysql_status.set_text('Active') 406 | self.mysql_img_status.set_from_icon_name('emblem-default', 1) 407 | 408 | self.mysql_port.set_text(self.get_mysql_port()) 409 | 410 | current_a = str(self.get_mysql_port()) 411 | current_b = str(self.entry_mysql_port.get_text()) 412 | 413 | if current_b == str("."): 414 | self.entry_mysql_port.set_text(self.get_mysql_port()) 415 | elif current_b == current_a: 416 | pass 417 | 418 | 419 | except: 420 | self.mysql_status.set_text('Not found') 421 | self.mysql_img_status.set_from_icon_name('emblem-important', 1) 422 | 423 | self.entry_mysql_port.set_text('Not found') 424 | 425 | 426 | # Putting current status of FTP service # 427 | 428 | try: 429 | if self.validate_ftp()[0] == '●': 430 | if 'dead' in self.validate_ftp(): 431 | self.ftpd_status.set_text('Inactive') 432 | self.ftpd_img_status.set_from_icon_name('emblem-unreadable', 1) 433 | 434 | elif 'running' in self.validate_ftp(): 435 | self.ftpd_status.set_text('Active') 436 | self.ftpd_img_status.set_from_icon_name('emblem-default', 1) 437 | 438 | self.ftp_port.set_text('2121') 439 | 440 | 441 | except: 442 | self.ftpd_status.set_text('Not found') 443 | self.ftpd_img_status.set_from_icon_name('emblem-important', 1) 444 | 445 | self.ftp_port.set_text('Not found') 446 | 447 | sleep(10) 448 | 449 | 450 | thread = threading.Thread(target=CurrentServiceStatus, daemon=True) 451 | thread.start() 452 | 453 | builder.connect_signals(Handler()) 454 | window = builder.get_object('main_window') 455 | window.show_all() 456 | 457 | if __name__ == '__main__': 458 | Gtk.main() -------------------------------------------------------------------------------- /interface.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | True 8 | False 9 | 10 | 11 | False 12 | 13 | 14 | True 15 | False 16 | vertical 17 | 18 | 19 | True 20 | False 21 | start 22 | start 23 | 2 24 | 2 25 | 2 26 | Change Apache Port 27 | 28 | 29 | False 30 | True 31 | 0 32 | 33 | 34 | 35 | 36 | True 37 | True 38 | start 39 | start 40 | 2 41 | 2 42 | . 43 | number 44 | 45 | 46 | False 47 | False 48 | 1 49 | 50 | 51 | 52 | 53 | Change 54 | True 55 | True 56 | True 57 | start 58 | start 59 | 2 60 | 2 61 | 62 | 63 | 64 | False 65 | False 66 | 2 67 | 68 | 69 | 70 | 71 | 72 | 73 | False 74 | 75 | 76 | True 77 | False 78 | vertical 79 | 80 | 81 | True 82 | False 83 | start 84 | start 85 | 2 86 | 2 87 | Change MySQL Port 88 | 89 | 90 | False 91 | True 92 | 0 93 | 94 | 95 | 96 | 97 | True 98 | True 99 | start 100 | start 101 | 2 102 | 2 103 | . 104 | number 105 | 106 | 107 | False 108 | False 109 | 1 110 | 111 | 112 | 113 | 114 | Change 115 | True 116 | True 117 | True 118 | start 119 | start 120 | 2 121 | 2 122 | 123 | 124 | 125 | False 126 | False 127 | 2 128 | 129 | 130 | 131 | 132 | 133 | 134 | False 135 | 136 | 137 | True 138 | False 139 | 140 | 141 | Instal NOW 142 | True 143 | True 144 | True 145 | 2 146 | 2 147 | 2 148 | 2 149 | 150 | 151 | 152 | 0 153 | 0 154 | 155 | 156 | 157 | 158 | Uninstall 159 | True 160 | True 161 | True 162 | 2 163 | 2 164 | 2 165 | 2 166 | 167 | 168 | 169 | 1 170 | 0 171 | 172 | 173 | 174 | 175 | 176 | 177 | False 178 | False 179 | center 180 | 400 181 | 110 182 | center 183 | 184 | 185 | 186 | True 187 | False 188 | LAMPP Manager 189 | True 190 | 191 | 192 | True 193 | False 194 | 195 | 196 | True 197 | True 198 | False 199 | True 200 | main_window 201 | none 202 | popover1 203 | 204 | 205 | 206 | 207 | 208 | 0 209 | 0 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | True 219 | False 220 | vertical 221 | 222 | 223 | True 224 | False 225 | center 226 | center 227 | 10 228 | True 229 | True 230 | 231 | 232 | True 233 | False 234 | MySQL 235 | 236 | 237 | 2 238 | 2 239 | 240 | 241 | 242 | 243 | Stop 244 | True 245 | True 246 | True 247 | 4 248 | 4 249 | 3 250 | 3 251 | 252 | 253 | 254 | 5 255 | 2 256 | 257 | 258 | 259 | 260 | Start 261 | True 262 | True 263 | True 264 | 4 265 | 4 266 | 3 267 | 3 268 | 269 | 270 | 271 | 4 272 | 1 273 | 274 | 275 | 276 | 277 | Start 278 | True 279 | True 280 | True 281 | 4 282 | 4 283 | 3 284 | 3 285 | 286 | 287 | 288 | 4 289 | 2 290 | 291 | 292 | 293 | 294 | True 295 | False 296 | center 297 | 298 | 299 | 3 300 | 1 301 | 302 | 303 | 304 | 305 | True 306 | False 307 | center 308 | 309 | 310 | 3 311 | 2 312 | 313 | 314 | 315 | 316 | True 317 | False 318 | 10 319 | 10 320 | Module 321 | 322 | 323 | 324 | 325 | 326 | 2 327 | 0 328 | 329 | 330 | 331 | 332 | True 333 | False 334 | center 335 | 336 | 337 | 4 338 | 0 339 | 340 | 341 | 342 | 343 | True 344 | False 345 | center 346 | 347 | 348 | 6 349 | 0 350 | 351 | 352 | 353 | 354 | True 355 | False 356 | Actions 357 | 358 | 359 | 360 | 361 | 362 | 5 363 | 0 364 | 365 | 366 | 367 | 368 | True 369 | False 370 | . 371 | 372 | 373 | 8 374 | 2 375 | 376 | 377 | 378 | 379 | True 380 | False 381 | center 382 | 383 | 384 | 7 385 | 1 386 | 387 | 388 | 389 | 390 | True 391 | False 392 | center 393 | 394 | 395 | 7 396 | 2 397 | 398 | 399 | 400 | 401 | Restart 402 | True 403 | True 404 | True 405 | 4 406 | 4 407 | 3 408 | 3 409 | 410 | 411 | 412 | 6 413 | 1 414 | 415 | 416 | 417 | 418 | Restart 419 | True 420 | True 421 | True 422 | 4 423 | 4 424 | 3 425 | 3 426 | 427 | 428 | 429 | 6 430 | 2 431 | 432 | 433 | 434 | 435 | True 436 | False 437 | center 438 | 439 | 440 | 4 441 | 4 442 | 443 | 444 | 445 | 446 | True 447 | False 448 | center 449 | 450 | 451 | 5 452 | 4 453 | 454 | 455 | 456 | 457 | True 458 | False 459 | center 460 | 461 | 462 | 6 463 | 4 464 | 465 | 466 | 467 | 468 | Start all 469 | True 470 | True 471 | True 472 | 4 473 | 4 474 | 3 475 | 3 476 | 477 | 480 | 481 | 482 | 4 483 | 5 484 | 485 | 486 | 487 | 488 | Stop All 489 | True 490 | True 491 | True 492 | 4 493 | 4 494 | 3 495 | 3 496 | 497 | 498 | 499 | 5 500 | 5 501 | 502 | 503 | 504 | 505 | Restart All 506 | True 507 | True 508 | True 509 | 4 510 | 4 511 | 3 512 | 3 513 | 514 | 515 | 516 | 6 517 | 5 518 | 519 | 520 | 521 | 522 | True 523 | False 524 | FTPd 525 | 526 | 527 | 2 528 | 3 529 | 530 | 531 | 532 | 533 | Start 534 | True 535 | True 536 | True 537 | 4 538 | 4 539 | 3 540 | 3 541 | 542 | 543 | 544 | 4 545 | 3 546 | 547 | 548 | 549 | 550 | Stop 551 | True 552 | True 553 | True 554 | 4 555 | 4 556 | 3 557 | 3 558 | 559 | 560 | 561 | 5 562 | 3 563 | 564 | 565 | 566 | 567 | Restart 568 | True 569 | True 570 | True 571 | 4 572 | 4 573 | 3 574 | 3 575 | 576 | 577 | 578 | 6 579 | 3 580 | 581 | 582 | 583 | 584 | True 585 | False 586 | . 587 | 588 | 589 | 8 590 | 3 591 | 592 | 593 | 594 | 595 | True 596 | False 597 | center 598 | 599 | 600 | 3 601 | 3 602 | 603 | 604 | 605 | 606 | True 607 | False 608 | center 609 | 610 | 611 | 7 612 | 3 613 | 614 | 615 | 616 | 617 | True 618 | False 619 | . 620 | 621 | 622 | 623 | 624 | 625 | 8 626 | 1 627 | 628 | 629 | 630 | 631 | True 632 | False 633 | Status 634 | 635 | 636 | 637 | 638 | 639 | 8 640 | 0 641 | 642 | 643 | 644 | 645 | True 646 | False 647 | Port 648 | 649 | 650 | 651 | 652 | 653 | 9 654 | 0 655 | 656 | 657 | 658 | 659 | True 660 | False 661 | - 662 | 663 | 664 | 665 | 666 | 667 | 9 668 | 1 669 | 670 | 671 | 672 | 673 | True 674 | False 675 | Apache 676 | 677 | 678 | 2 679 | 1 680 | 681 | 682 | 683 | 684 | True 685 | False 686 | gtk-missing-image 687 | 688 | 689 | 1 690 | 2 691 | 692 | 693 | 694 | 695 | True 696 | False 697 | gtk-missing-image 698 | 699 | 700 | 1 701 | 3 702 | 703 | 704 | 705 | 706 | True 707 | False 708 | gtk-missing-image 709 | 710 | 711 | 1 712 | 1 713 | 714 | 715 | 716 | 717 | True 718 | False 719 | - 720 | 721 | 722 | 723 | 724 | 725 | 9 726 | 2 727 | 728 | 729 | 730 | 731 | True 732 | False 733 | - 734 | 735 | 736 | 737 | 738 | 739 | 9 740 | 3 741 | 742 | 743 | 744 | 745 | Stop 746 | True 747 | True 748 | True 749 | 4 750 | 4 751 | 3 752 | 3 753 | 754 | 755 | 756 | 5 757 | 1 758 | 759 | 760 | 761 | 762 | True 763 | True 764 | False 765 | True 766 | start 767 | start 768 | main_window 769 | left 770 | popover2 771 | 772 | 773 | 774 | 775 | 776 | 10 777 | 1 778 | 779 | 780 | 781 | 782 | True 783 | True 784 | False 785 | True 786 | start 787 | start 788 | main_window 789 | left 790 | popover3 791 | 792 | 793 | 794 | 795 | 796 | 10 797 | 2 798 | 799 | 800 | 801 | 802 | True 803 | True 804 | False 805 | True 806 | start 807 | start 808 | main_window 809 | left 810 | 811 | 812 | 813 | 814 | 815 | 10 816 | 3 817 | 818 | 819 | 820 | 821 | True 822 | False 823 | center 824 | 825 | 826 | 0 827 | 1 828 | 829 | 830 | 831 | 832 | True 833 | False 834 | center 835 | 836 | 837 | 0 838 | 2 839 | 840 | 841 | 842 | 843 | True 844 | False 845 | center 846 | 847 | 848 | 0 849 | 3 850 | 851 | 852 | 853 | 854 | True 855 | False 856 | center 857 | center 858 | 5 859 | Media/bitmap.png 860 | 861 | 862 | 0 863 | 5 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | False 929 | True 930 | 1 931 | 932 | 933 | 934 | 935 | 936 | 937 | False 938 | center 939 | center 940 | 941 | 942 | True 943 | False 944 | 945 | 946 | True 947 | False 948 | 949 | 950 | True 951 | True 952 | False 953 | True 954 | main_window 955 | popover4 956 | 957 | 958 | True 959 | False 960 | Install LAMPP 961 | 13 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | False 970 | True 971 | 0 972 | 973 | 974 | 975 | 976 | True 977 | False 978 | 979 | 980 | False 981 | True 982 | 1 983 | 984 | 985 | 986 | 987 | Open Directory 988 | True 989 | True 990 | True 991 | none 992 | 993 | 994 | 995 | False 996 | True 997 | 2 998 | 999 | 1000 | 1001 | 1002 | Check update 1003 | True 1004 | True 1005 | True 1006 | none 1007 | 1008 | 1009 | 1010 | False 1011 | True 1012 | 3 1013 | 1014 | 1015 | 1016 | 1017 | True 1018 | False 1019 | 1020 | 1021 | False 1022 | True 1023 | 4 1024 | 1025 | 1026 | 1027 | 1028 | Localhost 1029 | True 1030 | True 1031 | True 1032 | none 1033 | 1034 | 1035 | 1036 | False 1037 | True 1038 | 5 1039 | 1040 | 1041 | 1042 | 1043 | True 1044 | False 1045 | 1046 | 1047 | False 1048 | True 1049 | 6 1050 | 1051 | 1052 | 1053 | 1054 | phpMyAdmin 1055 | True 1056 | True 1057 | True 1058 | none 1059 | 1060 | 1061 | 1062 | False 1063 | True 1064 | 7 1065 | 1066 | 1067 | 1068 | 1069 | True 1070 | False 1071 | 1072 | 1073 | False 1074 | True 1075 | 8 1076 | 1077 | 1078 | 1079 | 1080 | PHP Info 1081 | True 1082 | True 1083 | True 1084 | none 1085 | 1086 | 1087 | 1088 | False 1089 | True 1090 | 9 1091 | 1092 | 1093 | 1094 | 1095 | MySQL Logs 1096 | True 1097 | True 1098 | True 1099 | none 1100 | 1101 | 1102 | 1103 | False 1104 | True 1105 | 10 1106 | 1107 | 1108 | 1109 | 1110 | True 1111 | False 1112 | 1113 | 1114 | False 1115 | True 1116 | 11 1117 | 1118 | 1119 | 1120 | 1121 | About 1122 | True 1123 | True 1124 | True 1125 | none 1126 | 1127 | 1128 | 1129 | False 1130 | True 1131 | 12 1132 | 1133 | 1134 | 1135 | 1136 | 1 1137 | 2 1138 | 1139 | 1140 | 1141 | 1142 | True 1143 | False 1144 | center 1145 | 4 1146 | Menu 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1 1153 | 0 1154 | 1155 | 1156 | 1157 | 1158 | True 1159 | False 1160 | center 1161 | 1162 | 1163 | 1 1164 | 1 1165 | 1166 | 1167 | 1168 | 1169 | True 1170 | False 1171 | center 1172 | 1173 | 1174 | 0 1175 | 2 1176 | 1177 | 1178 | 1179 | 1180 | True 1181 | False 1182 | center 1183 | 1184 | 1185 | 2 1186 | 2 1187 | 1188 | 1189 | 1190 | 1191 | True 1192 | False 1193 | center 1194 | 1195 | 1196 | 1 1197 | 3 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | --------------------------------------------------------------------------------