├── .gitignore ├── AUTHORS ├── LICENSE ├── README.md ├── bin ├── ubuntu-first-steps └── ubuntu-first-steps-installer ├── data ├── create_icons.sh ├── icons │ ├── 1024x1024 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 128x128 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 16x16 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 192x192 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 20x20 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 22x22 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 24x24 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 256x256 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 28x28 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 32x32 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 36x36 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 40x40 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 480x480 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 48x48 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 512x512 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 64x64 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 72x72 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 8x8 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ ├── 96x96 │ │ └── apps │ │ │ └── ubuntu-first-steps.png │ └── scalable │ │ └── apps │ │ └── ubuntu-first-steps.svg └── ubuntu-first-steps.desktop ├── debian ├── changelog ├── compat ├── control ├── copyright ├── install ├── rules └── source │ └── format ├── images └── ubuntu-first-steps.png ├── po ├── es.po └── it.po ├── policykit └── actions │ └── com.ubuntu.pkexec.ubuntu-first-steps.policy ├── screenshots ├── ubuntu-first-steps-screenshot-1.png ├── ubuntu-first-steps-screenshot-2.png ├── ubuntu-first-steps-screenshot-3.png ├── ubuntu-first-steps-screenshot-4.png ├── ubuntu-first-steps-screenshot-5.png └── ubuntu-first-steps-screenshot-6.png └── src ├── application.py ├── comun.py ├── doitinbackground.py ├── installer.py ├── mainwindow.py ├── settings.py ├── sidewidget.py ├── tweak_desktop.py ├── tweak_dock.py ├── tweak_packages.py ├── tweak_privacy.py ├── tweak_repositories.py └── utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask instance folder 57 | instance/ 58 | 59 | # Scrapy stuff: 60 | .scrapy 61 | 62 | # Sphinx documentation 63 | docs/_build/ 64 | 65 | # PyBuilder 66 | target/ 67 | 68 | # IPython Notebook 69 | .ipynb_checkpoints 70 | 71 | # pyenv 72 | .python-version 73 | 74 | # celery beat schedule file 75 | celerybeat-schedule 76 | 77 | # dotenv 78 | .env 79 | 80 | # virtualenv 81 | venv/ 82 | ENV/ 83 | 84 | # Spyder project settings 85 | .spyderproject 86 | 87 | # Rope project settings 88 | .ropeproject 89 | 90 | # Visual Studio Code 91 | .vscode/ 92 | 93 | debian/files 94 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Lorenzo Carbonell Cerezo 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Lorenzo Carbonell Cerezo 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Welcome to Ubuntu First Steps 👋

2 | 3 | ![Licencia MIT](https://img.shields.io/badge/Licencia-MIT-green) 4 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b3e704c3f150404582cd23b9fcb4be32)](https://www.codacy.com/manual/atareao/ubuntu-first-steps?utm_source=github.com&utm_medium=referral&utm_content=atareao/ubuntu-first-steps&utm_campaign=Badge_Grade) 5 | [![CodeFactor](https://www.codefactor.io/repository/github/atareao/ubuntu-first-steps/badge/master)](https://www.codefactor.io/repository/github/atareao/ubuntu-first-steps/overview/master) 6 | 7 | [![Twitter: atareao](https://img.shields.io/twitter/follow/atareao.svg?style=social)](https://twitter.com/atareao) 8 | 9 | 11 | 12 | 13 | ## 🏠 [Homepage](https://www.atareao.es/aplicacion/ubuntu-first-steps/) 14 | 15 | ## Prerequisites 16 | 17 | Before you begin, ensure you have met the following requirements: 18 | 19 | * If you install it from PPA don't worry about, because all the requirements are included in the package 20 | * If you clone the repository, you need, at least, these dependencies, 21 | 22 | ``` 23 | python3-gi 24 | gir1.2-gtk-3.0 25 | gir1.2-gdkpixbuf-2.0 26 | gir1.2-glib-2.0 27 | gir1.2-vte-2.91 28 | gir1.2-handy-0.0 29 | ``` 30 | 31 | ## Installing Ubuntu First Steps 32 | 33 | To install **Ubuntu First Steps**, follow these steps: 34 | 35 | * In a terminal (`Ctrl+Alt+T`), run these commands 36 | 37 | ``` 38 | sudo add-apt-repository ppa:atareao/atareao 39 | sudo apt update 40 | sudo apt install ubuntu-first-steps 41 | ``` 42 | 43 | ## Using Ubuntu First Steps 44 | 45 | **Ubuntu First Steps** has 5 main sections to custom the Ubuntu User Experience 46 | 47 | * Custom dock 48 | 49 | ![Custom dock](./screenshots/ubuntu-first-steps-screenshot-1.png) 50 | 51 | * Custom desktop 52 | 53 | ![Custom desktop](./screenshots/ubuntu-first-steps-screenshot-2.png) 54 | 55 | * Privacy 56 | 57 | ![Privacy](./screenshots/ubuntu-first-steps-screenshot-3.png) 58 | 59 | * Repositories 60 | 61 | ![Repositories](./screenshots/ubuntu-first-steps-screenshot-4.png) 62 | 63 | * Applications 64 | 65 | ![Applications](./screenshots/ubuntu-first-steps-screenshot-5.png) 66 | 67 | ### About this application 68 | 69 | ![About this app](./screenshots/ubuntu-first-steps-screenshot-6.png) 70 | 71 | ## Contributing to Ubuntu First Steps 72 | 73 | To contribute to **Ubuntu First Steps**, follow these steps: 74 | 75 | 1. Fork this repository. 76 | 2. Create a branch: `git checkout -b `. 77 | 3. Make your changes and commit them: `git commit -m ''` 78 | 4. Push to the original branch: `git push origin /` 79 | 5. Create the pull request. 80 | 81 | Alternatively see the GitHub documentation on [creating a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request). 82 | 83 | ## 👤 Contributors ✨ 84 | 85 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 86 | 87 | 88 | 89 | 90 | 91 |

Lorenzo Carbonell

💻
92 | 93 | 94 | ## Contact 95 | 96 | If you want to contact me you can reach me at [atareao.es](https://www.atareao.es). 97 | 98 | ## License 99 | 100 | This project uses the following license: [MIT License](https://choosealicense.com/licenses/mit/). 101 | -------------------------------------------------------------------------------- /bin/ubuntu-first-steps: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import os 27 | import sys 28 | import gi 29 | try: 30 | gi.require_version('Handy', '0.0') 31 | except Exception as e: 32 | print(e) 33 | exit(-1) 34 | from gi.repository import Handy 35 | 36 | if __name__ == '__main__': 37 | mdir = os.path.dirname(os.path.abspath(__file__)) 38 | if mdir.startswith('/usr'): 39 | sys.path.insert( 40 | 1, '/usr/share/ubuntu-first-steps') 41 | else: 42 | sys.path.insert(1, os.path.normpath(os.path.join(mdir, '../src'))) 43 | from application import Application 44 | try: 45 | Handy.init(None) 46 | app = Application.get_default() 47 | exit_status = app.run(None) 48 | sys.exit(exit_status) 49 | except KeyboardInterrupt: 50 | exit() 51 | -------------------------------------------------------------------------------- /bin/ubuntu-first-steps-installer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import os 27 | import sys 28 | 29 | if __name__ == '__main__': 30 | if len(sys.argv) > 1: 31 | mdir = os.path.dirname(os.path.abspath(__file__)) 32 | if mdir.startswith('/usr'): 33 | sys.path.insert( 34 | 1, '/usr/share/ubuntu-first-steps') 35 | else: 36 | sys.path.insert(1, os.path.normpath(os.path.join(mdir, '../src'))) 37 | from installer import main 38 | try: 39 | main(sys.argv[1]) 40 | except KeyboardInterrupt: 41 | pass 42 | exit() 43 | 44 | -------------------------------------------------------------------------------- /data/create_icons.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for afile in $(ls icons/scalable/apps/*.svg) 3 | do 4 | filename="${afile##*/}" 5 | echo $filename 6 | filename="${filename/\.svg/.png}" 7 | for i in 8 16 20 22 24 28 32 36 40 48 64 72 96 128 192 256 480 512 1024 8 | do 9 | directory="icons/${i}x${i}" 10 | if [ -d "$directory" ] 11 | then 12 | rm -rf $directory 13 | fi 14 | directory=$directory/apps 15 | mkdir -p $directory 16 | inkscape -z -e "$directory"/"$filename" -w $i -h $i $afile 17 | done 18 | done 19 | -------------------------------------------------------------------------------- /data/icons/1024x1024/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/1024x1024/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/128x128/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/128x128/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/16x16/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/16x16/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/192x192/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/192x192/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/20x20/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/20x20/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/22x22/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/22x22/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/24x24/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/24x24/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/256x256/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/256x256/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/28x28/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/28x28/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/32x32/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/32x32/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/36x36/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/36x36/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/40x40/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/40x40/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/480x480/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/480x480/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/48x48/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/48x48/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/512x512/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/512x512/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/64x64/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/64x64/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/72x72/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/72x72/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/8x8/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/8x8/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/96x96/apps/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/data/icons/96x96/apps/ubuntu-first-steps.png -------------------------------------------------------------------------------- /data/icons/scalable/apps/ubuntu-first-steps.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 29 | 31 | 35 | 40 | 46 | 51 | 56 | 62 | 63 | 64 | 86 | 93 | 100 | 107 | 114 | 121 | 128 | 135 | 142 | 149 | 156 | 157 | 163 | 168 | 173 | 178 | 179 | -------------------------------------------------------------------------------- /data/ubuntu-first-steps.desktop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env xdg-open 2 | 3 | [Desktop Entry] 4 | Encoding=UTF-8 5 | Name=First steps with Ubuntu 6 | Comment=First steps with Ubuntu 7 | TryExec=/usr/bin/ubuntu-first-steps 8 | Exec=/usr/bin/ubuntu-first-steps 9 | Icon=ubuntu-first-steps 10 | StartupNotify=true 11 | Terminal=false 12 | Type=Application 13 | Categories=System;Application 14 | X-KDE-SubstituteUID=true 15 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | ubuntu-first-steps (0.1.1-20.04.06) focal; urgency=medium 2 | 3 | * Center main window 4 | * Using pkexec 5 | * Close installer window after install 6 | * Add gnome-weather to packages to install 7 | 8 | -- Lorenzo Carbonell Sat, 04 Jul 2020 12:17:28 +0200 9 | 10 | ubuntu-first-steps (0.0.9-20.04.06) focal; urgency=medium 11 | 12 | * Root in separate space 13 | * add gnome-sushi to applications to install 14 | 15 | -- Lorenzo Carbonell Sun, 26 Apr 2020 07:01:09 +0200 16 | 17 | ubuntu-first-steps (0.0.8-20.04.08) focal; urgency=medium 18 | 19 | * Change colors with Theme 20 | 21 | -- Lorenzo Carbonell Sat, 25 Apr 2020 14:52:29 +0200 22 | 23 | ubuntu-first-steps (0.0.7-20.04.03) focal; urgency=medium 24 | 25 | * Change name to Ubuntu First Steps 26 | 27 | -- Lorenzo Carbonell Sat, 25 Apr 2020 10:14:24 +0200 28 | 29 | ubuntu-first-steps (0.0.6-19.04ubuntu333) disco; urgency=medium 30 | 31 | * Added spanish translation 32 | * Changed launcher 33 | 34 | -- Lorenzo Carbonell Sun, 09 Jun 2019 10:33:59 +0200 35 | 36 | ubuntu-first-steps (0.0.5-19.04ubuntu0) disco; urgency=medium 37 | 38 | * First release 39 | 40 | -- Lorenzo Carbonell Wed, 05 Jun 2019 07:17:12 +0200 41 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: ubuntu-first-steps 2 | Section: utils 3 | Priority: extra 4 | Maintainer: Lorenzo Carbonell Cerezo 5 | Build-Depends: debhelper (>= 9) 6 | Standards-Version: 3.9.4 7 | Homepage: http://www.atareao.es 8 | 9 | Package: ubuntu-first-steps 10 | Architecture: all 11 | Depends: ${misc:Depends}, ${python:Depends}, 12 | python3-gi, 13 | python3-plumbum, 14 | gir1.2-gtk-3.0, 15 | gir1.2-gdkpixbuf-2.0, 16 | gir1.2-glib-2.0, 17 | gir1.2-vte-2.91, 18 | gir1.2-handy-0.0 19 | Description: ubuntu-first-steps helps you tweak Ubuntu 20 | ubuntu-first-steps is a program that helps you to tweak Ubuntu, 21 | after install a new version of Ubuntu. 22 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This work was packaged for Ubuntu by: 2 | 3 | Lorenzo Carbonell 4 | 5 | It was downloaded from: 6 | 7 | https://github.com/atareao/ubuntu-first-steps 8 | 9 | Upstream Author(s): 10 | 11 | Lorenzo Carbonell 12 | 13 | Copyright: 14 | 15 | 16 | 17 | License: 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. 36 | 37 | The Debian packaging is: 38 | 39 | Copyright (C) 2020 Lorenzo Carbonell 40 | 41 | -------------------------------------------------------------------------------- /debian/install: -------------------------------------------------------------------------------- 1 | bin/* /usr/bin 2 | src/*.py /usr/share/ubuntu-first-steps 3 | debian/changelog /usr/share/ubuntu-first-steps 4 | policykit/actions/com.ubuntu.pkexec.ubuntu-first-steps.policy /usr/share/polkit-1/actions 5 | data/ubuntu-first-steps.desktop /usr/share/applications 6 | data/icons/* /usr/share/icons/hicolor 7 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # Sample debian/rules that uses debhelper. 3 | # This file is public domain software, originally written by Joey Hess. 4 | # 5 | # This version is for packages that are architecture independent. 6 | 7 | # Uncomment this to turn on verbose mode. 8 | #export DH_VERBOSE=1 9 | 10 | build: build-stamp 11 | build-stamp: 12 | dh_testdir 13 | 14 | # Add here commands to compile the package. 15 | #$(MAKE) 16 | 17 | touch build-stamp 18 | 19 | clean: 20 | dh_testdir 21 | dh_testroot 22 | rm -f build-stamp 23 | 24 | # Add here commands to clean up after the build process. 25 | #$(MAKE) clean 26 | #$(MAKE) distclean 27 | 28 | dh_clean 29 | 30 | install: build 31 | dh_testdir 32 | dh_testroot 33 | dh_prep 34 | dh_installdirs 35 | dh_install 36 | # Create languages directories 37 | mkdir -p ${CURDIR}/debian/ubuntu-first-steps/usr/share/locale-langpack/es/LC_MESSAGES 38 | # End create languages directories 39 | # Compile languages 40 | msgfmt po/es.po -o ${CURDIR}/debian/ubuntu-first-steps/usr/share/locale-langpack/es/LC_MESSAGES/ubuntu-first-steps.mo 41 | # End comile languages 42 | # Add here commands to install the package into debian/. 43 | #$(MAKE) prefix=`pwd`/debian/`dh_listpackages`/usr install 44 | 45 | # Build architecture-independent files here. 46 | binary-indep: build install 47 | dh_testdir 48 | dh_testroot 49 | dh_installchangelogs 50 | dh_installdocs 51 | dh_installexamples 52 | # added gconf and icons 53 | dh_gconf 54 | dh_icons 55 | # dh_installmenu 56 | # dh_installdebconf 57 | # dh_installlogrotate 58 | # dh_installemacsen 59 | # dh_installcatalogs 60 | # dh_installpam 61 | # dh_installmime 62 | # dh_installinit 63 | # dh_installcron 64 | # dh_installinfo 65 | # dh_installwm 66 | # dh_installudev 67 | # dh_lintian 68 | # dh_bugfiles 69 | # dh_undocumented 70 | dh_installman 71 | dh_link 72 | dh_compress 73 | dh_fixperms 74 | # dh_perl 75 | # dh_pysupport 76 | dh_installdeb 77 | dh_gencontrol 78 | dh_md5sums 79 | dh_builddeb 80 | 81 | # Build architecture-dependent files here. 82 | binary-arch: build install 83 | # We have nothing to do by default. 84 | 85 | binary: binary-indep binary-arch 86 | .PHONY: build clean binary-indep binary-arch binary install 87 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /images/ubuntu-first-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/images/ubuntu-first-steps.png -------------------------------------------------------------------------------- /po/es.po: -------------------------------------------------------------------------------- 1 | # Spanish translations for start-here package. 2 | # Copyright (C) 2019 THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the start-here package. 4 | # Lorenzo , 2019. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: start-here - 0.0.5-19.04ubuntu0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2020-07-04 11:15+0200\n" 11 | "PO-Revision-Date: 2019-06-05 21:51+0200\n" 12 | "Last-Translator: Lorenzo \n" 13 | "Language-Team: Spanish\n" 14 | "Language: es\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | 20 | #: src/installer.py:73 21 | msgid "Add ppa repository" 22 | msgstr "Añade un repositorio PPA" 23 | 24 | #: src/installer.py:120 src/installer.py:188 25 | msgid "Cancel" 26 | msgstr "Cancelar" 27 | 28 | #: src/installer.py:136 src/installer.py:153 29 | msgid "Exit" 30 | msgstr "Salir" 31 | 32 | #: src/installer.py:139 33 | msgid "Installation completed!" 34 | msgstr "¡Instalación completa!" 35 | 36 | #: src/installer.py:142 37 | msgid "Installation NOT completed!" 38 | msgstr "¡NO se ha completado la instalación!" 39 | 40 | #: src/installer.py:146 src/installer.py:187 src/installer.py:223 41 | msgid "Ok" 42 | msgstr "Ok" 43 | 44 | #: src/installer.py:164 45 | #, python-format 46 | msgid "Executing: %s" 47 | msgstr "Ejecutando: %s" 48 | 49 | #: src/installer.py:185 50 | msgid "Do you want to stop the installation?" 51 | msgstr "¿Quieres abandonar la instalación?" 52 | 53 | #: src/installer.py:221 54 | msgid "You must be root to run this tool" 55 | msgstr "Debes tener derechos de administrador para ejecutar esta herramienta" 56 | 57 | #: src/tweak_repositories.py:106 src/mainwindow.py:115 58 | msgid "Repositories" 59 | msgstr "Repositorios" 60 | 61 | #: src/tweak_desktop.py:65 src/mainwindow.py:109 62 | msgid "Custom desktop" 63 | msgstr "Personaliza el escritorio" 64 | 65 | #: src/tweak_desktop.py:79 66 | msgid "Small" 67 | msgstr "Pequeño" 68 | 69 | #: src/tweak_desktop.py:80 70 | msgid "Standard" 71 | msgstr "Estandar" 72 | 73 | #: src/tweak_desktop.py:81 74 | msgid "Large" 75 | msgstr "Grande" 76 | 77 | #: src/tweak_desktop.py:89 78 | msgid "Icon size" 79 | msgstr "Tamaño de icono" 80 | 81 | #: src/tweak_desktop.py:90 82 | msgid "Set the icon size on the desktop." 83 | msgstr "Establece el tamaño de los iconos en el escritorio" 84 | 85 | #: src/tweak_desktop.py:93 86 | msgid "Hide home" 87 | msgstr "Oculta el directorio Home" 88 | 89 | #: src/tweak_desktop.py:94 90 | msgid "Hide your user folder." 91 | msgstr "Oculta el directorio del usuario" 92 | 93 | #: src/tweak_desktop.py:97 94 | msgid "Hide trash" 95 | msgstr "Oculta la papelera" 96 | 97 | #: src/tweak_desktop.py:98 98 | msgid "Hide the trash folder." 99 | msgstr "Oculta el directorio de la papelera" 100 | 101 | #: src/tweak_desktop.py:101 102 | msgid "Calendar" 103 | msgstr "Calendario" 104 | 105 | #: src/tweak_desktop.py:113 106 | msgid "Show week number" 107 | msgstr "Muestra el número de semana" 108 | 109 | #: src/tweak_desktop.py:114 110 | msgid "Show week number in calendar." 111 | msgstr "Muestra el número de la semana en el calendario" 112 | 113 | #: src/tweak_desktop.py:117 114 | msgid "Hide date" 115 | msgstr "Oculta la fecha" 116 | 117 | #: src/tweak_desktop.py:118 118 | msgid "Hide date in the watch" 119 | msgstr "Oculta la fecha en el reloj" 120 | 121 | #: src/tweak_desktop.py:121 122 | msgid "Show seconds" 123 | msgstr "Muestra segundos" 124 | 125 | #: src/tweak_desktop.py:122 126 | msgid "Show seconds in the watch" 127 | msgstr "Muestra los segundos en el reloj" 128 | 129 | #: src/tweak_desktop.py:125 130 | msgid "Show weekday" 131 | msgstr "Muestra el día de la semana" 132 | 133 | #: src/tweak_desktop.py:126 134 | msgid "Show weekday in the watch" 135 | msgstr "Muestra el día de la semana en el reloj" 136 | 137 | #: src/tweak_desktop.py:129 138 | msgid "Battery" 139 | msgstr "Batería" 140 | 141 | #: src/tweak_desktop.py:140 142 | msgid "Show battery percentage" 143 | msgstr "Muestra el porcentaje de batería" 144 | 145 | #: src/tweak_desktop.py:141 146 | msgid "Show battery percentage." 147 | msgstr "Muestra el porcentaje de batería" 148 | 149 | #: src/tweak_desktop.py:144 150 | msgid "Experimental" 151 | msgstr "Experimental" 152 | 153 | #: src/tweak_desktop.py:155 154 | msgid "Enable HiDPI Fractional Scaling" 155 | msgstr "Habilita el escalado HiDPI fracionado" 156 | 157 | #: src/tweak_desktop.py:156 158 | msgid "Enable experimenal HiDPI Fractional Scaling." 159 | msgstr "Habilita el escalado HiDPI fracionado" 160 | 161 | #: src/tweak_privacy.py:58 162 | msgid "Peripherals" 163 | msgstr "Periféricos" 164 | 165 | #: src/tweak_privacy.py:71 166 | msgid "Disable camera" 167 | msgstr "Deshabilita la cámara" 168 | 169 | #: src/tweak_privacy.py:72 170 | msgid "Avoid applications to use the camera." 171 | msgstr "Evita que las aplicaciones puedan utilizar la cámara." 172 | 173 | #: src/tweak_privacy.py:74 174 | msgid "Disable microphone" 175 | msgstr "Deshabilita el micrófono." 176 | 177 | #: src/tweak_privacy.py:75 178 | msgid "Avoid applications to use the microphone." 179 | msgstr "Evita que las aplicaciones puedan utilizar el micrófono." 180 | 181 | #: src/tweak_privacy.py:77 182 | msgid "Disable sound outp" 183 | msgstr "Deshabilita el sonido" 184 | 185 | #: src/tweak_privacy.py:78 186 | msgid "Avoid applications to play sound." 187 | msgstr "Evita que las aplicaciones puedan reproducir sonido." 188 | 189 | #: src/tweak_privacy.py:81 190 | msgid "Identity" 191 | msgstr "Identidad" 192 | 193 | #: src/tweak_privacy.py:92 194 | msgid "Hide identity" 195 | msgstr "Oculta tu identidad" 196 | 197 | #: src/tweak_privacy.py:93 198 | msgid "Hide personal information." 199 | msgstr "Oculta información personal" 200 | 201 | #: src/tweak_privacy.py:96 202 | msgid "Remember" 203 | msgstr "Recuerda" 204 | 205 | #: src/tweak_privacy.py:108 206 | msgid "Forget application usage" 207 | msgstr "Olvida el uso de aplicaciones" 208 | 209 | #: src/tweak_privacy.py:109 210 | msgid "Forget application usage." 211 | msgstr "Olvida el uso de aplicaciones" 212 | 213 | #: src/tweak_privacy.py:112 214 | msgid "Forget recent files" 215 | msgstr "Olvida los archivos recientes" 216 | 217 | #: src/tweak_privacy.py:113 218 | msgid "Forget recent files." 219 | msgstr "Olvida los archivos recientes" 220 | 221 | #: src/tweak_privacy.py:116 222 | msgid "Remove temporary files" 223 | msgstr "Borra los archivos temporales" 224 | 225 | #: src/tweak_privacy.py:117 226 | msgid "Remove old temporary files automatically." 227 | msgstr "Borra los archivos temporales antiguos automáticamente" 228 | 229 | #: src/tweak_privacy.py:120 230 | msgid "Remove trash files" 231 | msgstr "Borra los archivos en la papelera" 232 | 233 | #: src/tweak_privacy.py:121 234 | msgid "Remove old trash files automatically." 235 | msgstr "Borra los archivos antiguos de la papelera automáticamente" 236 | 237 | #: src/tweak_privacy.py:124 238 | msgid "Statistics" 239 | msgstr "Estadísticas" 240 | 241 | #: src/tweak_privacy.py:136 242 | msgid "Send technical problems" 243 | msgstr "Envía problemas técnicos" 244 | 245 | #: src/tweak_privacy.py:137 246 | msgid "Send technical problems." 247 | msgstr "Envía problemas técnicos" 248 | 249 | #: src/tweak_privacy.py:140 250 | msgid "Send software usage" 251 | msgstr "Envía uso de software" 252 | 253 | #: src/tweak_privacy.py:141 254 | msgid "Send softwarew usage statistics." 255 | msgstr "Envía estadísticas de uso de software." 256 | 257 | #: src/tweak_privacy.py:144 258 | msgid "Ubuntu popularity contest" 259 | msgstr "Ubuntu popularity contest" 260 | 261 | #: src/tweak_privacy.py:145 262 | msgid "Send information about installed packages" 263 | msgstr "Envía información de los paquetes instalados" 264 | 265 | #: src/tweak_packages.py:113 src/mainwindow.py:118 266 | msgid "Applications" 267 | msgstr "Aplicaciones" 268 | 269 | #: src/tweak_dock.py:65 src/mainwindow.py:106 270 | msgid "Custom dock" 271 | msgstr "Personalizar el dock" 272 | 273 | #: src/tweak_dock.py:79 274 | msgid "Left" 275 | msgstr "Izquierda" 276 | 277 | #: src/tweak_dock.py:80 278 | msgid "Right" 279 | msgstr "Derecha" 280 | 281 | #: src/tweak_dock.py:81 282 | msgid "Top" 283 | msgstr "Arriba" 284 | 285 | #: src/tweak_dock.py:82 286 | msgid "Bottom" 287 | msgstr "Abajo" 288 | 289 | #: src/tweak_dock.py:90 290 | msgid "Dock position" 291 | msgstr "Posición del dock" 292 | 293 | #: src/tweak_dock.py:91 294 | msgid "Set the dock position on the screen." 295 | msgstr "Establece la posición del dock en la pantalla." 296 | 297 | #: src/tweak_dock.py:94 298 | msgid "Enable minimize click action" 299 | msgstr "Habilita la acción de minimizado por click en el dock" 300 | 301 | #: src/tweak_dock.py:95 302 | msgid "Minimize when clicking on a running app." 303 | msgstr "Minimiza cuando se hace click en una aplicación" 304 | 305 | #: src/tweak_dock.py:98 306 | msgid "Reduce dock length" 307 | msgstr "Reduce el tamaño del dock" 308 | 309 | #: src/tweak_dock.py:99 310 | msgid "Reduce the dock container to icons." 311 | msgstr "Reduce el dock al minimo para contener iconos" 312 | 313 | #: src/tweak_dock.py:102 314 | msgid "Force straight corner" 315 | msgstr "Fuerza las esquinas rectas" 316 | 317 | #: src/tweak_dock.py:103 318 | msgid "Make the borders in the dash non rounded." 319 | msgstr "Hace que los bordes del dock sean rectos" 320 | 321 | #: src/tweak_dock.py:118 322 | msgid "Isolate monitors" 323 | msgstr "Aisla los monitores" 324 | 325 | #: src/tweak_dock.py:119 326 | msgid "Provide monitor isolation" 327 | msgstr "Aisla los monitores" 328 | 329 | #: src/tweak_dock.py:121 330 | msgid "Multi monitor" 331 | msgstr "Multi monitor" 332 | 333 | #: src/tweak_dock.py:122 334 | msgid "Enable multi monitor dock" 335 | msgstr "Habilita el dock en varios monitores" 336 | 337 | #: src/tweak_dock.py:137 src/tweak_dock.py:138 338 | msgid "Hide applications button" 339 | msgstr "Oculta el botón de aplicaciones" 340 | 341 | #: src/tweak_dock.py:140 342 | msgid "Show apps at top" 343 | msgstr "Muestra el botón de aplicaciones en la parte superior" 344 | 345 | #: src/tweak_dock.py:141 346 | msgid "Show application button at top" 347 | msgstr "Muestra el botón de aplicaciones en la parte superior" 348 | 349 | #: src/tweak_dock.py:143 350 | msgid "Hide favorites" 351 | msgstr "Oculta los favoritos" 352 | 353 | #: src/tweak_dock.py:144 354 | msgid "Hide favorites apps" 355 | msgstr "Oculta las aplicaciones favoritas del dock" 356 | 357 | #: src/tweak_dock.py:146 358 | msgid "Hide running" 359 | msgstr "Oculta las aplicaciones en ejecución" 360 | 361 | #: src/tweak_dock.py:147 362 | msgid "Hide running apps" 363 | msgstr "Oculta las aplicaciones en ejecución en el dock" 364 | 365 | #: src/application.py:55 366 | msgid "ubuntu-first-steps" 367 | msgstr "ubuntu-fist-steps" 368 | 369 | #: src/application.py:151 370 | msgid "First steps in Ubuntu" 371 | msgstr "Primeros pasos en Ubuntu" 372 | 373 | #: src/mainwindow.py:112 374 | msgid "Privacy" 375 | msgstr "Privacidad" 376 | 377 | #: src/mainwindow.py:209 378 | msgid "Apply changes" 379 | msgstr "Aplicar todos los cambios" 380 | 381 | #: src/mainwindow.py:218 382 | msgid "Homepage" 383 | msgstr "Web" 384 | 385 | #: src/mainwindow.py:223 386 | msgid "Code" 387 | msgstr "Código" 388 | 389 | #: src/mainwindow.py:224 390 | msgid "Issues" 391 | msgstr "Problemas" 392 | 393 | #: src/mainwindow.py:229 394 | msgid "Twitter" 395 | msgstr "Twitter" 396 | 397 | #: src/mainwindow.py:230 398 | msgid "GitHub" 399 | msgstr "GitHub" 400 | 401 | #: src/mainwindow.py:235 402 | msgid "Donations" 403 | msgstr "Donaciones" 404 | 405 | #: src/mainwindow.py:240 406 | msgid "About" 407 | msgstr "Acerca de..." 408 | 409 | #: src/mainwindow.py:245 410 | msgid "Quit" 411 | msgstr "Salir" 412 | 413 | #: src/mainwindow.py:250 414 | msgid "Help" 415 | msgstr "Ayuda" 416 | 417 | #~ msgid "start-here" 418 | #~ msgstr "Primeros pasos" 419 | -------------------------------------------------------------------------------- /po/it.po: -------------------------------------------------------------------------------- 1 | # Italian translations for Ubuntu-first-steps. 2 | # Copyright (C) 2019 THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the start-here package. 4 | # ALbano Battistella , 202i. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: start-here - 0.0.5-19.04ubuntu0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2020-07-04 11:15+0200\n" 11 | "PO-Revision-Date: 2021-08-08 11:51+0200\n" 12 | "Last-Translator: Albano Battistella \n" 13 | "Language-Team: Italian\n" 14 | "Language: es\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 19 | 20 | #: src/installer.py:73 21 | msgid "Add ppa repository" 22 | msgstr "Aggiungi repository ppa" 23 | 24 | #: src/installer.py:120 src/installer.py:188 25 | msgid "Cancel" 26 | msgstr "Annulla" 27 | 28 | #: src/installer.py:136 src/installer.py:153 29 | msgid "Exit" 30 | msgstr "Esci" 31 | 32 | #: src/installer.py:139 33 | msgid "Installation completed!" 34 | msgstr "Installazione completata!" 35 | 36 | #: src/installer.py:142 37 | msgid "Installation NOT completed!" 38 | msgstr "Installazione NON completata!" 39 | 40 | #: src/installer.py:146 src/installer.py:187 src/installer.py:223 41 | msgid "Ok" 42 | msgstr "Ok" 43 | 44 | #: src/installer.py:164 45 | #, python-format 46 | msgid "Executing: %s" 47 | msgstr "In Esecuzione: %s" 48 | 49 | #: src/installer.py:185 50 | msgid "Do you want to stop the installation?" 51 | msgstr "Vuoi interrompere l'installazione?" 52 | 53 | #: src/installer.py:221 54 | msgid "You must be root to run this tool" 55 | msgstr "Devi essere root per eseguire questo strumento" 56 | 57 | #: src/tweak_repositories.py:106 src/mainwindow.py:115 58 | msgid "Repositories" 59 | msgstr "Repository" 60 | 61 | #: src/tweak_desktop.py:65 src/mainwindow.py:109 62 | msgid "Custom desktop" 63 | msgstr "Desktop personalizzato" 64 | 65 | #: src/tweak_desktop.py:79 66 | msgid "Small" 67 | msgstr "Piccolo" 68 | 69 | #: src/tweak_desktop.py:80 70 | msgid "Standard" 71 | msgstr "Standard" 72 | 73 | #: src/tweak_desktop.py:81 74 | msgid "Large" 75 | msgstr "Grande" 76 | 77 | #: src/tweak_desktop.py:89 78 | msgid "Icon size" 79 | msgstr "Dimensione icona" 80 | 81 | #: src/tweak_desktop.py:90 82 | msgid "Set the icon size on the desktop." 83 | msgstr "Imposta la dimensione dell'icona sul desktop." 84 | 85 | #: src/tweak_desktop.py:93 86 | msgid "Hide home" 87 | msgstr "Nascondi HOme" 88 | 89 | #: src/tweak_desktop.py:94 90 | msgid "Hide your user folder." 91 | msgstr "Nascondi la tua cartella utente." 92 | 93 | #: src/tweak_desktop.py:97 94 | msgid "Hide trash" 95 | msgstr "Nascondi cestino" 96 | 97 | #: src/tweak_desktop.py:98 98 | msgid "Hide the trash folder." 99 | msgstr "Nascondi la cartella del cestino." 100 | 101 | #: src/tweak_desktop.py:101 102 | msgid "Calendar" 103 | msgstr "Calendario" 104 | 105 | #: src/tweak_desktop.py:113 106 | msgid "Show week number" 107 | msgstr "Mostra il numero della settimana" 108 | 109 | #: src/tweak_desktop.py:114 110 | msgid "Show week number in calendar." 111 | msgstr "Mostra il numero della settimana nel calendario." 112 | 113 | #: src/tweak_desktop.py:117 114 | msgid "Hide date" 115 | msgstr "Nascondi data" 116 | 117 | #: src/tweak_desktop.py:118 118 | msgid "Hide date in the watch" 119 | msgstr "Nascondi la data nell'orologio" 120 | 121 | #: src/tweak_desktop.py:121 122 | msgid "Show seconds" 123 | msgstr "Mostra secondi" 124 | 125 | #: src/tweak_desktop.py:122 126 | msgid "Show seconds in the watch" 127 | msgstr "Mostra i secondi nell'orologio" 128 | 129 | #: src/tweak_desktop.py:125 130 | msgid "Show weekday" 131 | msgstr "Mostra giorno della settimana" 132 | 133 | #: src/tweak_desktop.py:126 134 | msgid "Show weekday in the watch" 135 | msgstr "Mostra il giorno della settimana nell'orologio" 136 | 137 | #: src/tweak_desktop.py:129 138 | msgid "Battery" 139 | msgstr "Battería" 140 | 141 | #: src/tweak_desktop.py:140 142 | msgid "Show battery percentage" 143 | msgstr "Mostra la percentuale della batteria" 144 | 145 | #: src/tweak_desktop.py:141 146 | msgid "Show battery percentage." 147 | msgstr "Mostra la percentuale della batteria." 148 | 149 | #: src/tweak_desktop.py:144 150 | msgid "Experimental" 151 | msgstr "Sperimentale" 152 | 153 | #: src/tweak_desktop.py:155 154 | msgid "Enable HiDPI Fractional Scaling" 155 | msgstr "Abilita il ridimensionamento HiDPI frazionario" 156 | 157 | #: src/tweak_desktop.py:156 158 | msgid "Enable experimenal HiDPI Fractional Scaling." 159 | msgstr "Abilita il ridimensionamento HiDPI frazionario." 160 | 161 | #: src/tweak_privacy.py:58 162 | msgid "Peripherals" 163 | msgstr "Periferiche" 164 | 165 | #: src/tweak_privacy.py:71 166 | msgid "Disable camera" 167 | msgstr "Disabilita camera" 168 | 169 | #: src/tweak_privacy.py:72 170 | msgid "Avoid applications to use the camera." 171 | msgstr "Evita applicazioni per utilizzare la fotocamera." 172 | 173 | #: src/tweak_privacy.py:74 174 | msgid "Disable microphone" 175 | msgstr "Disattiva microfono" 176 | 177 | #: src/tweak_privacy.py:75 178 | msgid "Avoid applications to use the microphone." 179 | msgstr "Evita applicazioni per usare il microfono." 180 | 181 | #: src/tweak_privacy.py:77 182 | msgid "Disable sound outp" 183 | msgstr "Disattiva uscita audio" 184 | 185 | #: src/tweak_privacy.py:78 186 | msgid "Avoid applications to play sound." 187 | msgstr "Evita applicazioni per riprodurre suoni." 188 | 189 | #: src/tweak_privacy.py:81 190 | msgid "Identity" 191 | msgstr "Identità" 192 | 193 | #: src/tweak_privacy.py:92 194 | msgid "Hide identity" 195 | msgstr "Nascondi identità" 196 | 197 | #: src/tweak_privacy.py:93 198 | msgid "Hide personal information." 199 | msgstr "Nascondi le informazioni personali." 200 | 201 | #: src/tweak_privacy.py:96 202 | msgid "Remember" 203 | msgstr "Recorda" 204 | 205 | #: src/tweak_privacy.py:108 206 | msgid "Forget application usage" 207 | msgstr "Dimentica l'utilizzo dell'applicazione" 208 | 209 | #: src/tweak_privacy.py:109 210 | msgid "Forget application usage." 211 | msgstr "Dimentica l'utilizzo dell'applicazione." 212 | 213 | #: src/tweak_privacy.py:112 214 | msgid "Forget recent files" 215 | msgstr "Dimentica i file recenti" 216 | 217 | #: src/tweak_privacy.py:113 218 | msgid "Forget recent files." 219 | msgstr "Dimentica i file recenti." 220 | 221 | #: src/tweak_privacy.py:116 222 | msgid "Remove temporary files" 223 | msgstr "Rimuovi i file temporanei" 224 | 225 | #: src/tweak_privacy.py:117 226 | msgid "Remove old temporary files automatically." 227 | msgstr "Rimuovi automaticamente i vecchi file temporanei." 228 | 229 | #: src/tweak_privacy.py:120 230 | msgid "Remove trash files" 231 | msgstr "Rimuovi i file nel cestino" 232 | 233 | #: src/tweak_privacy.py:121 234 | msgid "Remove old trash files automatically." 235 | msgstr "Rimuovi automaticamente i vecchi file nel cestino." 236 | 237 | #: src/tweak_privacy.py:124 238 | msgid "Statistics" 239 | msgstr "Statistiche" 240 | 241 | #: src/tweak_privacy.py:136 242 | msgid "Send technical problems" 243 | msgstr "Invia problemi tecnici" 244 | 245 | #: src/tweak_privacy.py:137 246 | msgid "Send technical problems." 247 | msgstr "Invia problemi tecnici." 248 | 249 | #: src/tweak_privacy.py:140 250 | msgid "Send software usage" 251 | msgstr "Invia utilizzo software" 252 | 253 | #: src/tweak_privacy.py:141 254 | msgid "Send softwarew usage statistics." 255 | msgstr "Invia statistiche sull'utilizzo del software." 256 | 257 | #: src/tweak_privacy.py:144 258 | msgid "Ubuntu popularity contest" 259 | msgstr "Concorso di popolarità di Ubuntu" 260 | 261 | #: src/tweak_privacy.py:145 262 | msgid "Send information about installed packages" 263 | msgstr "Invia informazioni sui pacchetti installati" 264 | 265 | #: src/tweak_packages.py:113 src/mainwindow.py:118 266 | msgid "Applications" 267 | msgstr "Applicazioni" 268 | 269 | #: src/tweak_dock.py:65 src/mainwindow.py:106 270 | msgid "Custom dock" 271 | msgstr "Personalizza dock" 272 | 273 | #: src/tweak_dock.py:79 274 | msgid "Left" 275 | msgstr "Sinistra" 276 | 277 | #: src/tweak_dock.py:80 278 | msgid "Right" 279 | msgstr "Destra" 280 | 281 | #: src/tweak_dock.py:81 282 | msgid "Top" 283 | msgstr "Alto" 284 | 285 | #: src/tweak_dock.py:82 286 | msgid "Bottom" 287 | msgstr "Basso" 288 | 289 | #: src/tweak_dock.py:90 290 | msgid "Dock position" 291 | msgstr "Posizione della dock" 292 | 293 | #: src/tweak_dock.py:91 294 | msgid "Set the dock position on the screen." 295 | msgstr "Imposta la posizione del dock sullo schermo." 296 | 297 | #: src/tweak_dock.py:94 298 | msgid "Enable minimize click action" 299 | msgstr "Abilita minimizzazione clic" 300 | 301 | #: src/tweak_dock.py:95 302 | msgid "Minimize when clicking on a running app." 303 | msgstr "Riduci a icona quando fai clic su un'app in esecuzione." 304 | 305 | #: src/tweak_dock.py:98 306 | msgid "Reduce dock length" 307 | msgstr "Riduci dimensioni del dock" 308 | 309 | #: src/tweak_dock.py:99 310 | msgid "Reduce the dock container to icons." 311 | msgstr "Riduci a icona il dock per contenere le icone" 312 | 313 | #: src/tweak_dock.py:102 314 | msgid "Force straight corner" 315 | msgstr "Forza angoli dritti" 316 | 317 | #: src/tweak_dock.py:103 318 | msgid "Make the borders in the dash non rounded." 319 | msgstr "Rendi i bordi nella dash non arrotondati." 320 | 321 | #: src/tweak_dock.py:118 322 | msgid "Isolate monitors" 323 | msgstr "Isola monitor" 324 | 325 | #: src/tweak_dock.py:119 326 | msgid "Provide monitor isolation" 327 | msgstr "Provvede l'isolamento del monitor" 328 | 329 | #: src/tweak_dock.py:121 330 | msgid "Multi monitor" 331 | msgstr "Multi monitor" 332 | 333 | #: src/tweak_dock.py:122 334 | msgid "Enable multi monitor dock" 335 | msgstr "Habilita el dock en varios monitores" 336 | 337 | #: src/tweak_dock.py:137 src/tweak_dock.py:138 338 | msgid "Hide applications button" 339 | msgstr "Nascondi il pulsante delle applicazioni" 340 | 341 | #: src/tweak_dock.py:140 342 | msgid "Show apps at top" 343 | msgstr "Mostra app in alto" 344 | 345 | #: src/tweak_dock.py:141 346 | msgid "Show application button at top" 347 | msgstr "Mostra il pulsante dell'applicazione in alto" 348 | 349 | #: src/tweak_dock.py:143 350 | msgid "Hide favorites" 351 | msgstr "Nascondi preferiti" 352 | 353 | #: src/tweak_dock.py:144 354 | msgid "Hide favorites apps" 355 | msgstr "Nascondi app preferite" 356 | 357 | #: src/tweak_dock.py:146 358 | msgid "Hide running" 359 | msgstr "Nascondi in esecuzione" 360 | 361 | #: src/tweak_dock.py:147 362 | msgid "Hide running apps" 363 | msgstr "Nascondi app in esecuzione" 364 | 365 | #: src/application.py:55 366 | msgid "ubuntu-first-steps" 367 | msgstr "ubuntu-fist-steps" 368 | 369 | #: src/application.py:151 370 | msgid "First steps in Ubuntu" 371 | msgstr "Primi passi in Ubuntu" 372 | 373 | #: src/mainwindow.py:112 374 | msgid "Privacy" 375 | msgstr "Privacy" 376 | 377 | #: src/mainwindow.py:209 378 | msgid "Apply changes" 379 | msgstr "Applica modifiche" 380 | 381 | #: src/mainwindow.py:218 382 | msgid "Homepage" 383 | msgstr "Homepage" 384 | 385 | #: src/mainwindow.py:223 386 | msgid "Code" 387 | msgstr "Codice" 388 | 389 | #: src/mainwindow.py:224 390 | msgid "Issues" 391 | msgstr "Problemi" 392 | 393 | #: src/mainwindow.py:229 394 | msgid "Twitter" 395 | msgstr "Twitter" 396 | 397 | #: src/mainwindow.py:230 398 | msgid "GitHub" 399 | msgstr "GitHub" 400 | 401 | #: src/mainwindow.py:235 402 | msgid "Donations" 403 | msgstr "Donazioni" 404 | 405 | #: src/mainwindow.py:240 406 | msgid "About" 407 | msgstr "Inoformazioni" 408 | 409 | #: src/mainwindow.py:245 410 | msgid "Quit" 411 | msgstr "Esci" 412 | 413 | #: src/mainwindow.py:250 414 | msgid "Help" 415 | msgstr "Aiuto" 416 | 417 | #~ msgid "start-here" 418 | #~ msgstr "Primi passi" 419 | -------------------------------------------------------------------------------- /policykit/actions/com.ubuntu.pkexec.ubuntu-first-steps.policy: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | Authentication is required to install packages and add PPA repositories 9 | configurator 10 | 11 | auth_admin 12 | auth_admin 13 | auth_admin 14 | 15 | /usr/bin/ubuntu-first-steps-installer 16 | true 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /screenshots/ubuntu-first-steps-screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/screenshots/ubuntu-first-steps-screenshot-1.png -------------------------------------------------------------------------------- /screenshots/ubuntu-first-steps-screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/screenshots/ubuntu-first-steps-screenshot-2.png -------------------------------------------------------------------------------- /screenshots/ubuntu-first-steps-screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/screenshots/ubuntu-first-steps-screenshot-3.png -------------------------------------------------------------------------------- /screenshots/ubuntu-first-steps-screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/screenshots/ubuntu-first-steps-screenshot-4.png -------------------------------------------------------------------------------- /screenshots/ubuntu-first-steps-screenshot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/screenshots/ubuntu-first-steps-screenshot-5.png -------------------------------------------------------------------------------- /screenshots/ubuntu-first-steps-screenshot-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atareao/ubuntu-first-steps/c4d740474b92ccf949f21fe35fd4427ca50f5e72/screenshots/ubuntu-first-steps-screenshot-6.png -------------------------------------------------------------------------------- /src/application.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Gio', '2.0') 30 | gi.require_version('GLib', '2.0') 31 | gi.require_version('GdkPixbuf', '2.0') 32 | except Exception as e: 33 | print(e) 34 | exit(1) 35 | from gi.repository import Gtk 36 | from gi.repository import Gio 37 | from gi.repository import GLib 38 | from gi.repository import GdkPixbuf 39 | 40 | from comun import _ 41 | import comun 42 | from mainwindow import MainWindow 43 | import webbrowser 44 | 45 | 46 | class Application(Gtk.Application): 47 | """ubuntu-first-steps application object.""" 48 | instance = None 49 | IS_DEVEL = True 50 | 51 | def __init__(self): 52 | Gtk.Application.__init__(self, 53 | application_id="es.atareao.ubuntu-first-steps", 54 | flags=Gio.ApplicationFlags.FLAGS_NONE) 55 | GLib.set_application_name(_("ubuntu-first-steps")) 56 | GLib.set_prgname("ubuntu-first-steps") 57 | self.alive = True 58 | 59 | self._menu = Gio.Menu() 60 | 61 | @staticmethod 62 | def get_default(): 63 | if Application.instance is None: 64 | Application.instance = Application() 65 | return Application.instance 66 | 67 | def do_startup(self): 68 | """Startup the application.""" 69 | Gtk.Application.do_startup(self) 70 | self.__setup_actions() 71 | 72 | def __setup_actions(self): 73 | self.__add_action( 74 | 'goto_homepage', 75 | callback=lambda x, y: webbrowser.open( 76 | 'https://www.atareao.es/aplicacion/ubuntu-first-steps/')) 77 | self.__add_action( 78 | 'goto_twitter', 79 | callback=lambda x, y: webbrowser.open( 80 | 'http://twitter.com/atareao')) 81 | self.__add_action( 82 | 'goto_github', 83 | callback=lambda x, y: webbrowser.open( 84 | 'https://github.com/atareao')) 85 | self.__add_action( 86 | 'goto_code', 87 | callback=lambda x, y: webbrowser.open( 88 | 'https://github.com/atareao/ubuntu-first-steps')) 89 | self.__add_action( 90 | 'goto_bug', 91 | callback=lambda x, y: webbrowser.open( 92 | 'https://github.com/atareao/ubuntu-first-steps/issues')) 93 | self.__add_action( 94 | 'goto_sugestion', 95 | callback=lambda x, y: webbrowser.open( 96 | 'https://github.com/atareao/ubuntu-first-steps/issues')) 97 | self.__add_action( 98 | 'goto_donate', 99 | callback=lambda x, y: webbrowser.open( 100 | 'https://www.atareao.es/donar/')) 101 | self.__add_action( 102 | 'about', 103 | callback=self.on_about_activate) 104 | self.__add_action( 105 | 'quit', 106 | callback=self.__on_quit) 107 | 108 | # Keyboard shortcuts. This includes actions defined in window.py.in 109 | self.set_accels_for_action("app.shortcuts", ["question"]) 110 | self.set_accels_for_action("app.quit", ["Q"]) 111 | self.set_accels_for_action("app.settings", ["comma"]) 112 | self.set_accels_for_action("win.add-account", ["N"]) 113 | self.set_accels_for_action("win.toggle-searchbar", ["F"]) 114 | 115 | def do_activate(self, *_): 116 | """On activate signal override.""" 117 | window = MainWindow(self) 118 | self.add_window(window) 119 | window.show_all() 120 | window.present() 121 | 122 | def action_clicked(self, action, variant): 123 | print(action, variant) 124 | if variant: 125 | action.set_state(variant) 126 | 127 | def __add_action(self, name, callback=None, var_type=None, 128 | value=None): 129 | if var_type is None: 130 | action = Gio.SimpleAction.new(name, None) 131 | else: 132 | action = Gio.SimpleAction.new_stateful( 133 | name, 134 | GLib.VariantType.new(var_type), 135 | GLib.Variant(var_type, value) 136 | ) 137 | if callback is None: 138 | callback = self.action_clicked 139 | action.connect('activate', callback) 140 | self.add_action(action) 141 | 142 | def __on_quit(self, *_): 143 | self.get_active_window().close() 144 | self.quit() 145 | 146 | def on_about_activate(self, widget, optional): 147 | ad = Gtk.AboutDialog(comun.APPNAME, self.get_active_window()) 148 | ad.set_name(comun.APPNAME) 149 | ad.set_version(comun.VERSION) 150 | ad.set_copyright('Copyrignt (c) 2019\nLorenzo Carbonell') 151 | ad.set_comments(_('First steps in Ubuntu')) 152 | ad.set_license(''' 153 | Permission is hereby granted, free of charge, to any person obtaining a copy 154 | of this software and associated documentation files (the "Software"), to deal 155 | in the Software without restriction, including without limitation the rights 156 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 157 | copies of the Software, and to permit persons to whom the Software is 158 | furnished to do so, subject to the following conditions: 159 | 160 | The above copyright notice and this permission notice shall be included in 161 | all copies or substantial portions of the Software. 162 | 163 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 164 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 166 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 167 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 168 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 169 | SOFTWARE 170 | ''') 171 | ad.set_website('http://www.atareao.es') 172 | ad.set_website_label('http://www.atareao.es') 173 | ad.set_authors([ 174 | 'Lorenzo Carbonell ']) 175 | ad.set_documenters([ 176 | 'Lorenzo Carbonell ']) 177 | ad.set_translator_credits('\ 178 | Lorenzo Carbonell \n') 179 | ad.set_program_name(comun.APPNAME) 180 | ad.set_logo(GdkPixbuf.Pixbuf.new_from_file(comun.ICON)) 181 | ad.run() 182 | ad.destroy() 183 | -------------------------------------------------------------------------------- /src/comun.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import os 27 | import sys 28 | import locale 29 | import gettext 30 | 31 | 32 | def is_package(): 33 | return __file__.find('src') < 0 34 | 35 | ###################################### 36 | 37 | 38 | APP = 'ubuntu-first-steps' 39 | APPNAME = 'Ubuntu First Steps' 40 | 41 | # check if running from source 42 | if is_package(): 43 | ROOTDIR = '/usr/share' 44 | LANGDIR = os.path.join(ROOTDIR, 'locale-langpack') 45 | APPDIR = os.path.join(ROOTDIR, APP) 46 | CHANGELOG = os.path.join(APPDIR, 'changelog') 47 | ICONDIR = os.path.join(ROOTDIR, 'icons', 'hicolor', 'scalable', 'apps') 48 | ICON = os.path.join(ICONDIR, 'ubuntu-first-steps.svg') 49 | else: 50 | ROOTDIR = os.path.dirname(__file__) 51 | LANGDIR = os.path.normpath(os.path.join(ROOTDIR, '../template1')) 52 | APPDIR = ROOTDIR 53 | DEBIANDIR = os.path.normpath(os.path.join(ROOTDIR, '../debian')) 54 | CHANGELOG = os.path.join(DEBIANDIR, 'changelog') 55 | ICON = os.path.normpath(os.path.join(ROOTDIR, '../data/icons/scalable/apps/ubuntu-first-steps.svg')) 56 | 57 | 58 | f = open(CHANGELOG, 'r') 59 | line = f.readline() 60 | f.close() 61 | pos = line.find('(') 62 | posf = line.find(')', pos) 63 | VERSION = line[pos + 1:posf].strip() 64 | if not is_package(): 65 | VERSION = VERSION + '-src' 66 | 67 | #### 68 | try: 69 | current_locale, encoding = locale.getdefaultlocale() 70 | language = gettext.translation(APP, LANGDIR, [current_locale]) 71 | language.install() 72 | if sys.version_info[0] == 3: 73 | _ = language.gettext 74 | else: 75 | _ = language.ugettext 76 | except Exception as e: 77 | print(e) 78 | _ = str 79 | APPNAME = _(APPNAME) 80 | -------------------------------------------------------------------------------- /src/doitinbackground.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('GObject', '2.0') 29 | gi.require_version('GLib', '2.0') 30 | except Exception as e: 31 | print(e) 32 | exit(1) 33 | from gi.repository import GObject 34 | from gi.repository import GLib 35 | from threading import Thread 36 | import subprocess 37 | import os 38 | import shlex 39 | import time 40 | 41 | 42 | class DoItInBackground(GObject.GObject, Thread): 43 | __gsignals__ = { 44 | 'started': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, (int, )), 45 | 'ended': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, (bool,)), 46 | 'done_one': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, 47 | (str,)), 48 | 'stopped': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ()), 49 | } 50 | 51 | def __init__(self, printer, commands): 52 | GObject.GObject.__init__(self) 53 | Thread.__init__(self) 54 | self.printer = printer 55 | self.commands = commands 56 | self.stopit = False 57 | self.ok = True 58 | self.daemon = True 59 | 60 | def emit(self, *args): 61 | GLib.idle_add(GObject.GObject.emit, self, *args) 62 | 63 | def execute(self, command): 64 | self.printer.feed(('$ %s\n\r' % (command)).encode()) 65 | env = os.environ.copy() 66 | answer = '' 67 | try: 68 | po = subprocess.Popen(shlex.split(command), 69 | shell=False, 70 | stdout=subprocess.PIPE, 71 | stderr=subprocess.PIPE, 72 | universal_newlines=True, 73 | env=env) 74 | for stdout_line in iter(po.stdout.readline, ''): 75 | answer += stdout_line 76 | stdout_line = stdout_line.replace('\n', '\n\r') 77 | self.printer.feed(stdout_line.encode()) 78 | return_code = po.wait() 79 | if command.startswith('add-apt-repository') and\ 80 | answer.find('OK') == -1: 81 | self.ok = False 82 | if return_code: 83 | output = 'Error: %s\n\r' % (return_code) 84 | output = output + po.stderr.read().replace('\n', '\n\r') +\ 85 | '\n\r' 86 | self.printer.feed(output.encode()) 87 | self.ok = False 88 | except OSError as e: 89 | print('Execution failed:', e) 90 | self.ok = False 91 | 92 | def stop(self, *args): 93 | self.stopit = True 94 | 95 | def run(self): 96 | self.emit('started', len(self.commands)) 97 | for index, command in enumerate(self.commands): 98 | if self.stopit is True: 99 | self.emit('stopped') 100 | return 101 | self.execute(command) 102 | time.sleep(1) 103 | self.emit('done_one', command) 104 | self.emit('ended', self.ok) 105 | -------------------------------------------------------------------------------- /src/installer.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('GLib', '2.0') 30 | gi.require_version('Vte', '2.91') 31 | except Exception as e: 32 | print(e) 33 | exit(1) 34 | from gi.repository import Gtk 35 | from gi.repository import GLib 36 | from gi.repository import Vte 37 | import os 38 | import sys 39 | import time 40 | import comun 41 | import json 42 | from comun import _ 43 | from doitinbackground import DoItInBackground 44 | import utils 45 | 46 | MARGIN = 5 47 | 48 | 49 | class SmartTerminal(Vte.Terminal): 50 | def __init__(self, parent): 51 | Vte.Terminal.__init__(self) 52 | self.parent = parent 53 | self.diib = None 54 | 55 | def execute(self, commands): 56 | self.diib = DoItInBackground(self, commands) 57 | self.diib.connect('started', self.parent.start) 58 | self.diib.connect('done_one', self.parent.increase) 59 | self.diib.connect('ended', self.parent.end) 60 | self.diib.connect('stopped', self.parent.stopped) 61 | self.diib.start() 62 | 63 | def stop(self): 64 | if self.diib is not None: 65 | self.diib.stop() 66 | 67 | 68 | class Installer(Gtk.Dialog): # needs GTK, Python, Webkit-GTK 69 | # def __init__(self, ppas_to_install, ppas_to_remove, apps_to_install, 70 | # apps_to_remove): 71 | def __init__(self, actions): 72 | Gtk.Dialog.__init__(self) 73 | self.set_title( _('Add ppa repository')) 74 | self.set_modal(True) 75 | self.set_destroy_with_parent(True) 76 | self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) 77 | self.set_icon_from_file(comun.ICON) 78 | self.set_size_request(600, 50) 79 | 80 | actions = json.loads(actions) 81 | self.ppas_to_install = actions['ppas_to_install'] 82 | self.ppas_to_remove = actions['ppas_to_remove'] 83 | self.apps_to_install = actions['apps_to_install'] 84 | self.apps_to_remove = actions['apps_to_remove'] 85 | 86 | box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 10) 87 | box.set_border_width(5) 88 | self.get_content_area().add(box) 89 | 90 | grid = Gtk.Grid() 91 | grid.set_column_spacing(MARGIN) 92 | grid.set_row_spacing(MARGIN) 93 | box.add(grid) 94 | 95 | self.label = Gtk.Label.new('') 96 | self.label.set_halign(Gtk.Align.START) 97 | grid.attach(self.label, 0, 1, 2, 1) 98 | 99 | self.progressbar = Gtk.ProgressBar() 100 | grid.attach(self.progressbar, 0, 2, 4, 1) 101 | 102 | expander = Gtk.Expander() 103 | expander.connect('notify::expanded', self.on_expanded) 104 | grid.attach(expander, 0, 3, 4, 4) 105 | 106 | alignment = Gtk.Alignment() 107 | # alignment.set_padding(1, 0, 2, 2) 108 | alignment.props.xscale = 1 109 | scrolledwindow = Gtk.ScrolledWindow() 110 | scrolledwindow.set_hexpand(True) 111 | scrolledwindow.set_vexpand(True) 112 | self.terminal = SmartTerminal(self) 113 | scrolledwindow.add(self.terminal) 114 | alignment.add(scrolledwindow) 115 | expander.add(alignment) 116 | 117 | hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5) 118 | grid.attach(hbox, 0, 8, 4, 1) 119 | 120 | self.button_cancel = Gtk.Button.new_with_label(_('Cancel')) 121 | self.button_cancel.connect('clicked', self.on_button_cancel_clicked) 122 | hbox.pack_start(self.button_cancel, False, False, 0) 123 | 124 | self.is_added = False 125 | self.value = 0.0 126 | self.is_installing = False 127 | self.show_all() 128 | self.progressbar.set_visible(False) 129 | self.label.set_visible(False) 130 | expander.set_expanded(True) 131 | time.sleep(1) 132 | self.start_installation() 133 | 134 | def end(self, anobject, ok, *args): 135 | self.is_installing = False 136 | self.button_cancel.set_label(_('Exit')) 137 | if ok is True: 138 | kind = Gtk.MessageType.INFO 139 | message = _('Installation completed!') 140 | else: 141 | kind = Gtk.MessageType.ERROR 142 | message = _('Installation NOT completed!') 143 | dialog = Gtk.MessageDialog() 144 | dialog.set_markup(message) 145 | dialog.set_property('message_type', kind) 146 | dialog.add_button(_('Ok'), Gtk.ButtonsType.OK) 147 | dialog.run() 148 | dialog.destroy() 149 | self.destroy() 150 | 151 | def stopped(self, anobject, *args): 152 | self.is_installing = False 153 | self.button_cancel.set_label(_('Exit')) 154 | self.destroy() 155 | 156 | def start(self, anobject, total, *args): 157 | self.is_installing = True 158 | self.label.set_visible(True) 159 | self.progressbar.set_visible(True) 160 | self.value = 0.0 161 | self.max_value = total 162 | 163 | def increase(self, anobject, command, *args): 164 | GLib.idle_add(self.label.set_text, _('Executing: %s') % command) 165 | self.value += 1.0 166 | fraction = self.value / self.max_value 167 | print(fraction) 168 | GLib.idle_add(self.progressbar.set_fraction, fraction) 169 | 170 | def decrease(self): 171 | self.value -= 1.0 172 | fraction = self.value / self.max_value 173 | GLib.idle_add(self.progressbar.set_fraction, fraction) 174 | 175 | def on_expanded(self, widget, data): 176 | if widget.get_property('expanded') is True: 177 | self.set_size_request(600, 300) 178 | else: 179 | self.set_size_request(600, 50) 180 | self.resize(600, 50) 181 | 182 | def on_button_cancel_clicked(self, button): 183 | if self.is_installing: 184 | dialog = Gtk.MessageDialog() 185 | dialog.set_markup(_('Do you want to stop the installation?')) 186 | dialog.set_property('message-type', Gtk.MessageType.INFO) 187 | dialog.add_button(_('Ok'), Gtk.ResponseType.OK) 188 | dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL) 189 | ans = dialog.run() 190 | if dialog.run() == Gtk.ResponseType.OK: 191 | GLib.idle_add(dialog.hide) 192 | self.terminal.stop() 193 | GLib.idle_add(dialog.destroy) 194 | 195 | def show_info(self): 196 | self.progressbar.set_visible(True) 197 | self.label.set_visible(True) 198 | 199 | def start_installation(self): 200 | commands = [] 201 | for ppa in self.ppas_to_install: 202 | commands.append('add-apt-repository -y ppa:{}'.format(ppa)) 203 | for ppa in self.ppas_to_remove: 204 | commands.append('add-apt-repository -y -r ppa:{}'.format(ppa)) 205 | if len(commands) > 0: 206 | commands.append('apt-get update') 207 | commands.append('apt-get upgrade') 208 | if len(self.apps_to_install) > 0: 209 | apps = ' '.join(self.apps_to_install) 210 | commands.append('apt-get -y install {}'.format(apps)) 211 | if len(self.apps_to_remove) > 0: 212 | apps = ' '.join(self.apps_to_remove) 213 | commands.append('apt-get -y remove {}'.format(apps)) 214 | print(commands) 215 | self.terminal.execute(commands) 216 | 217 | 218 | def main(args): 219 | if os.geteuid() != 0: 220 | dialog = Gtk.MessageDialog() 221 | dialog.set_markup(_('You must be root to run this tool')) 222 | dialog.set_property('message-type', Gtk.MessageType.ERROR) 223 | dialog.add_button(_('Ok'), Gtk.ResponseType.OK) 224 | dialog.run() 225 | return 226 | installer = Installer(args) 227 | installer.run() 228 | installer.destroy() 229 | exit(0) 230 | 231 | 232 | if __name__ == '__main__': 233 | actions = {'ppas_to_install': ['ppa:atareao/atareao'], 234 | 'ppas_to_remove': [], 235 | 'apps_to_install': ['my-weather-indicator'], 236 | 'apps_to_remove': [] 237 | } 238 | main(actions) 239 | exit(0) 240 | -------------------------------------------------------------------------------- /src/mainwindow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Gdk', '3.0') 30 | gi.require_version('Gio', '2.0') 31 | gi.require_version('GLib', '2.0') 32 | gi.require_version('GObject', '2.0') 33 | gi.require_version('Handy', '0.0') 34 | except Exception as e: 35 | print(e) 36 | exit(1) 37 | from gi.repository import Gtk 38 | from gi.repository import Gdk 39 | from gi.repository import Gio 40 | from gi.repository import GLib 41 | from gi.repository import GObject 42 | from gi.repository import Handy 43 | import os 44 | import json 45 | import subprocess 46 | import mimetypes 47 | import urllib 48 | import comun 49 | from comun import _ 50 | from sidewidget import SideWidget 51 | from utils import variant_to_value, CSS 52 | from settings import SettingRow 53 | from tweak_dock import TweakDock 54 | from tweak_desktop import TweakDesktop 55 | from tweak_privacy import TweakPrivacy 56 | from tweak_repositories import TweakRepositories 57 | from tweak_packages import TweakPackages 58 | from string import Template 59 | 60 | DEFAULT_CURSOR = Gdk.Cursor(Gdk.CursorType.ARROW) 61 | WAIT_CURSOR = Gdk.Cursor(Gdk.CursorType.WATCH) 62 | 63 | 64 | class MainWindow(Gtk.ApplicationWindow): 65 | __gsignals__ = { 66 | 'text-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, 67 | (object,)), 68 | 'save-me': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, 69 | (object,)), } 70 | 71 | def on_close(self, *args): 72 | pass 73 | 74 | def __init__(self, app, files=[]): 75 | Gtk.ApplicationWindow.__init__(self, application=app) 76 | self.app = app 77 | self.set_icon_from_file(comun.ICON) 78 | self.connect('destroy', self.on_close) 79 | 80 | self.get_root_window().set_cursor(WAIT_CURSOR) 81 | 82 | ''' 83 | max_action = Gio.SimpleAction.new_stateful( 84 | "maximize", None, GLib.Variant.new_boolean(False)) 85 | max_action.connect("change-state", self.on_maximize_toggle) 86 | self.add_action(max_action) 87 | ''' 88 | 89 | self.init_headerbar() 90 | 91 | mainbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5) 92 | self.add(mainbox) 93 | 94 | scrolledwindow = Gtk.ScrolledWindow() 95 | scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC, 96 | Gtk.PolicyType.AUTOMATIC) 97 | scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_OUT) 98 | scrolledwindow.set_visible(True) 99 | scrolledwindow.set_property('min-content-width', 200) 100 | mainbox.pack_start(scrolledwindow, False, False, 0) 101 | 102 | sidebar = Gtk.ListBox() 103 | sidebar.connect('row-activated', self.on_row_activated) 104 | scrolledwindow.add(sidebar) 105 | 106 | option1 = SideWidget(_('Custom dock'), 107 | 'preferences-ubuntu-panel-symbolic') 108 | sidebar.add(option1) 109 | option2 = SideWidget(_('Custom desktop'), 110 | 'preferences-desktop-display') 111 | sidebar.add(option2) 112 | option3 = SideWidget(_('Privacy'), 113 | 'preferences-system-privacy-symbolic') 114 | sidebar.add(option3) 115 | option4 = SideWidget(_('Repositories'), 116 | 'folder-remote-symbolic') 117 | sidebar.add(option4) 118 | option5 = SideWidget(_('Applications'), 119 | 'software-store-symbolic') 120 | sidebar.add(option5) 121 | 122 | self.stack = Gtk.Stack() 123 | sw = Gtk.ScrolledWindow(child=self.stack) 124 | mainbox.pack_start(sw, True, True, 0) 125 | 126 | self.tweakDock = TweakDock() 127 | self.stack.add_named(self.tweakDock, 'tweakDock') 128 | option1.set_stack('tweakDock') 129 | 130 | self.tweakDesktop = TweakDesktop() 131 | self.stack.add_named(self.tweakDesktop, 'tweakDesktop') 132 | option2.set_stack('tweakDesktop') 133 | 134 | self.tweakPrivacy = TweakPrivacy() 135 | self.stack.add_named(self.tweakPrivacy, 'tweakPrivacy') 136 | option3.set_stack('tweakPrivacy') 137 | 138 | self.tweakRepositories = TweakRepositories() 139 | self.stack.add_named(self.tweakRepositories, 'tweakRepositories') 140 | option4.set_stack('tweakRepositories') 141 | 142 | self.tweakPackages = TweakPackages() 143 | self.stack.add_named(self.tweakPackages, 'tweakPackages') 144 | option5.set_stack('tweakPackages') 145 | 146 | self.get_root_window().set_cursor(DEFAULT_CURSOR) 147 | 148 | self.load_css() 149 | self.set_size_request(800, 900) 150 | self.connect('realize', self.on_realize) 151 | self.show_all() 152 | 153 | def on_realize(self, *_): 154 | monitor = Gdk.Display.get_primary_monitor(Gdk.Display.get_default()) 155 | scale = monitor.get_scale_factor() 156 | monitor_width = monitor.get_geometry().width / scale 157 | monitor_height = monitor.get_geometry().height / scale 158 | width = self.get_preferred_width()[0] 159 | height = self.get_preferred_height()[0] 160 | self.move((monitor_width - width)/2, (monitor_height - height)/2) 161 | 162 | def on_row_activated(self, lb, sidewidget): 163 | self.stack.set_visible_child_name(sidewidget.get_stack()) 164 | 165 | def on_apply_clicked(self, *args): 166 | self.tweakDock.set_selected() 167 | self.tweakDesktop.set_selected() 168 | 169 | self.tweakDock.update() 170 | self.tweakDesktop.update() 171 | 172 | ppas_to_install, ppas_to_remove = self.tweakRepositories.set_selected() 173 | priv_to_install, priv_to_remove = \ 174 | self.tweakPrivacy.set_selected_packages() 175 | print(priv_to_remove) 176 | apps_to_install, apps_to_remove = self.tweakPackages.set_selected() 177 | apps_to_install = apps_to_install + priv_to_install 178 | apps_to_remove = apps_to_remove + priv_to_remove 179 | print(apps_to_remove) 180 | actions = len(ppas_to_install) + len(ppas_to_remove) + \ 181 | len(apps_to_install) + len(apps_to_remove) 182 | if actions > 0: 183 | actions = {'ppas_to_install': ppas_to_install, 184 | 'ppas_to_remove': ppas_to_remove, 185 | 'apps_to_install': apps_to_install, 186 | 'apps_to_remove': apps_to_remove 187 | } 188 | process = subprocess.Popen(['pkexec', 189 | 'ubuntu-first-steps-installer', 190 | json.dumps(actions)]) 191 | outs, errs = process.communicate() 192 | self.tweakRepositories.update() 193 | self.tweakPackages.update() 194 | self.tweakPrivacy.set_selected() 195 | self.tweakPrivacy.update() 196 | 197 | def init_headerbar(self): 198 | self.control = {} 199 | self.menu_selected = 'suscriptions' 200 | 201 | hb = Gtk.HeaderBar() 202 | hb.set_show_close_button(True) 203 | hb.props.title = comun.APPNAME 204 | self.set_titlebar(hb) 205 | 206 | self.apply_controls = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5) 207 | hb.pack_start(self.apply_controls) 208 | 209 | self.control['apply'] = Gtk.Button() 210 | self.control['apply'].connect('clicked', self.on_apply_clicked) 211 | self.control['apply'].set_tooltip_text(_('Apply changes')) 212 | self.control['apply'].add(Gtk.Image.new_from_gicon(Gio.ThemedIcon( 213 | name='preferences-system-symbolic'), Gtk.IconSize.BUTTON)) 214 | self.apply_controls.pack_start(self.control['apply'], 215 | False, False, 0) 216 | 217 | help_model = Gio.Menu() 218 | 219 | help_section1_model = Gio.Menu() 220 | help_section1_model.append(_('Homepage'), 'app.goto_homepage') 221 | help_section1 = Gio.MenuItem.new_section(None, help_section1_model) 222 | help_model.append_item(help_section1) 223 | 224 | help_section2_model = Gio.Menu() 225 | help_section2_model.append(_('Code'), 'app.goto_code') 226 | help_section2_model.append(_('Issues'), 'app.goto_bug') 227 | help_section2 = Gio.MenuItem.new_section(None, help_section2_model) 228 | help_model.append_item(help_section2) 229 | 230 | help_section3_model = Gio.Menu() 231 | help_section3_model.append(_('Twitter'), 'app.goto_twitter') 232 | help_section3_model.append(_('GitHub'), 'app.goto_github') 233 | help_section3 = Gio.MenuItem.new_section(None, help_section3_model) 234 | help_model.append_item(help_section3) 235 | 236 | help_section4_model = Gio.Menu() 237 | help_section4_model.append(_('Donations'), 'app.goto_donate') 238 | help_section4 = Gio.MenuItem.new_section(None, help_section4_model) 239 | help_model.append_item(help_section4) 240 | 241 | help_section5_model = Gio.Menu() 242 | help_section5_model.append(_('About'), 'app.about') 243 | help_section5 = Gio.MenuItem.new_section(None, help_section5_model) 244 | help_model.append_item(help_section5) 245 | 246 | help_section6_model = Gio.Menu() 247 | help_section6_model.append(_('Quit'), 'app.quit') 248 | help_section6 = Gio.MenuItem.new_section(None, help_section6_model) 249 | help_model.append_item(help_section6) 250 | 251 | self.control['help'] = Gtk.MenuButton() 252 | self.control['help'].set_tooltip_text(_('Help')) 253 | self.control['help'].set_menu_model(help_model) 254 | self.control['help'].add(Gtk.Image.new_from_gicon(Gio.ThemedIcon( 255 | name='open-menu-symbolic'), Gtk.IconSize.BUTTON)) 256 | hb.pack_end(self.control['help']) 257 | 258 | def on_toggled(self, widget, arg): 259 | if widget.get_active() is True: 260 | if arg == self.menu_selected: 261 | if self.menu[arg].get_active() is False: 262 | self.menu[arg].set_active(True) 263 | else: 264 | old = self.menu_selected 265 | self.menu_selected = arg 266 | self.menu[old].set_active(False) 267 | else: 268 | if self.menu_selected == arg: 269 | widget.set_active(True) 270 | 271 | def load_css(self): 272 | settings = Gio.Settings.new('org.gnome.desktop.interface') 273 | theme = variant_to_value(settings.get_user_value('gtk-theme')) 274 | if theme and theme.find('dark') > -1: 275 | background_color = '#373737' 276 | forecolor = '#d7d7d7' 277 | border_color = '#282828' 278 | hover_color = '#3e3e3e' 279 | caption_color = forecolor 280 | else: 281 | background_color = '#ffffff' 282 | forecolor = '#2d2d34' 283 | border_color = '#c3c9d0' 284 | hover_color = '#e0e0e1' 285 | caption_color = '#403f38' 286 | 287 | css = Template(CSS).substitute(background_color=background_color, 288 | border_color=border_color, 289 | forecolor=forecolor, 290 | hover_color=hover_color, 291 | caption_color=caption_color) 292 | css = str(css).encode() 293 | 294 | style_provider = Gtk.CssProvider() 295 | style_provider.load_from_data(css) 296 | Gtk.StyleContext.add_provider_for_screen( 297 | Gdk.Screen.get_default(), 298 | style_provider, 299 | Gtk.STYLE_PROVIDER_PRIORITY_USER) 300 | -------------------------------------------------------------------------------- /src/settings.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('GObject', '2.0') 29 | gi.require_version('Handy', '0.0') 30 | except Exception as e: 31 | print(e) 32 | exit(1) 33 | from gi.repository import GObject 34 | from gi.repository import Handy 35 | 36 | 37 | class SettingRow(Handy.ActionRow): 38 | 39 | def __init__(self, title, subtitle, widget): 40 | Handy.ActionRow.__init__(self) 41 | 42 | self.__populate_widget(title, subtitle, widget) 43 | 44 | def __populate_widget(self, title, subtitle, widget): 45 | self.set_title(title) 46 | self.set_subtitle(subtitle) 47 | self.add_action(widget) 48 | 49 | 50 | class SettingExpanderRow(Handy.ExpanderRow): 51 | toggled = GObject.Property(type=bool, default=False) 52 | 53 | def __init__(self, title, subtitle): 54 | Handy.ExpanderRow.__init__(self) 55 | 56 | self.__populate_widget(title, subtitle) 57 | 58 | def __populate_widget(self, title, subtitle): 59 | self.set_title(title) 60 | self.set_subtitle(subtitle) 61 | 62 | # Hackish solution until libhandy have a property for that 63 | expander_toggled_btn = self.get_children()[0].get_children()[3] 64 | expander_toggled_btn.bind_property("active", self, "toggled", 65 | GObject.BindingFlags.BIDIRECTIONAL) 66 | -------------------------------------------------------------------------------- /src/sidewidget.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('GObject', '2.0') 30 | except Exception as e: 31 | print(e) 32 | exit(1) 33 | from gi.repository import Gtk 34 | from gi.repository import GObject 35 | 36 | 37 | class SideWidget(Gtk.ListBoxRow): 38 | __gsignals__ = { 39 | 'clicked': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, 40 | (object,)), 41 | } 42 | 43 | def __init__(self, text, iconname='face-angel'): 44 | Gtk.ListBoxRow.__init__(self) 45 | self.set_name('sidewidget') 46 | 47 | box = Gtk.Box(Gtk.Orientation.HORIZONTAL, 5) 48 | self.add(box) 49 | 50 | self.image = Gtk.Image.new_from_icon_name(iconname, Gtk.IconSize.BUTTON) 51 | box.pack_start(self.image, False, False, 0) 52 | 53 | self.label = Gtk.Label(text) 54 | self.label.set_halign(Gtk.Align.START) 55 | box.pack_start(self.label, False, False, 5) 56 | 57 | self.stack = None 58 | 59 | def set_text(text): 60 | self.label.set_text(text) 61 | 62 | def set_stack(self, stack): 63 | self.stack = stack 64 | 65 | def get_stack(self): 66 | return self.stack 67 | -------------------------------------------------------------------------------- /src/tweak_desktop.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Gio', '2.0') 30 | gi.require_version('Handy', '0.0') 31 | except Exception as e: 32 | print(e) 33 | exit(1) 34 | from gi.repository import Gtk 35 | from gi.repository import Gio 36 | from gi.repository import Handy 37 | import os 38 | import json 39 | import mimetypes 40 | import urllib 41 | import comun 42 | from comun import _ 43 | from sidewidget import SideWidget 44 | from utils import get_desktop_environment 45 | from settings import SettingRow 46 | from utils import variant_to_value, select_value_in_combo 47 | from utils import get_selected_value_in_combo 48 | 49 | 50 | class TweakDesktop(Gtk.Overlay): 51 | 52 | def __init__(self): 53 | Gtk.Overlay.__init__(self) 54 | self.__set_ui() 55 | 56 | def __set_ui(self): 57 | handycolumn = Handy.Column() 58 | handycolumn.set_maximum_width(700) 59 | handycolumn.set_margin_top(24) 60 | self.add(handycolumn) 61 | 62 | box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5) 63 | handycolumn.add(box) 64 | 65 | label0 = Gtk.Label(_('Custom desktop')) 66 | label0.set_name('special') 67 | label0.set_alignment(0, 0.5) 68 | box.add(label0) 69 | 70 | listbox0 = Gtk.ListBox() 71 | box.add(listbox0) 72 | 73 | self.options = {} 74 | for index in range(0, 2): 75 | self.options[index] = Gtk.Switch() 76 | self.options[index].set_valign(Gtk.Align.CENTER) 77 | 78 | icon_size = Gtk.ListStore(str, str) 79 | icon_size.append([_('Small'), 'small']) 80 | icon_size.append([_('Standard'), 'standard']) 81 | icon_size.append([_('Large'), 'large']) 82 | 83 | self.options['icon-size'] = Gtk.ComboBox.new() 84 | self.options['icon-size'].set_model(icon_size) 85 | cell1 = Gtk.CellRendererText() 86 | self.options['icon-size'].pack_start(cell1, True) 87 | self.options['icon-size'].add_attribute(cell1, 'text', 0) 88 | 89 | listbox0.add(SettingRow(_('Icon size'), 90 | _('Set the icon size on the desktop.'), 91 | self.options['icon-size'])) 92 | 93 | listbox0.add(SettingRow(_('Hide home'), 94 | _('Hide your user folder.'), 95 | self.options[0])) 96 | 97 | listbox0.add(SettingRow(_('Hide trash'), 98 | _('Hide the trash folder.'), 99 | self.options[1])) 100 | 101 | label1 = Gtk.Label(_('Calendar')) 102 | label1.set_name('special') 103 | label1.set_alignment(0, 0.5) 104 | box.add(label1) 105 | 106 | listbox1 = Gtk.ListBox() 107 | box.add(listbox1) 108 | 109 | for index in range(2, 6): 110 | self.options[index] = Gtk.Switch() 111 | self.options[index].set_valign(Gtk.Align.CENTER) 112 | 113 | listbox1.add(SettingRow(_('Show week number'), 114 | _('Show week number in calendar.'), 115 | self.options[2])) 116 | 117 | listbox1.add(SettingRow(_('Hide date'), 118 | _('Hide date in the watch'), 119 | self.options[3])) 120 | 121 | listbox1.add(SettingRow(_('Show seconds'), 122 | _('Show seconds in the watch'), 123 | self.options[4])) 124 | 125 | listbox1.add(SettingRow(_('Show weekday'), 126 | _('Show weekday in the watch'), 127 | self.options[5])) 128 | 129 | label2 = Gtk.Label(_('Battery')) 130 | label2.set_name('special') 131 | label2.set_alignment(0, 0.5) 132 | box.add(label2) 133 | 134 | listbox2 = Gtk.ListBox() 135 | box.add(listbox2) 136 | 137 | self.options[6] = Gtk.Switch() 138 | self.options[6].set_valign(Gtk.Align.CENTER) 139 | 140 | listbox2.add(SettingRow(_('Show battery percentage'), 141 | _('Show battery percentage.'), 142 | self.options[6])) 143 | 144 | label3 = Gtk.Label(_('Experimental')) 145 | label3.set_name('special') 146 | label3.set_alignment(0, 0.5) 147 | box.add(label3) 148 | 149 | listbox3 = Gtk.ListBox() 150 | box.add(listbox3) 151 | 152 | self.options[7] = Gtk.Switch() 153 | self.options[7].set_valign(Gtk.Align.CENTER) 154 | 155 | listbox3.add(SettingRow(_('Enable HiDPI Fractional Scaling'), 156 | _('Enable experimenal HiDPI Fractional \ 157 | Scaling.'), 158 | self.options[7])) 159 | 160 | self.__load_default_states() 161 | 162 | def update(self): 163 | self.__load_default_states() 164 | 165 | def __load_default_states(self): 166 | settings = Gio.Settings.new( 167 | 'org.gnome.shell.extensions.desktop-icons') 168 | 169 | icon_size = variant_to_value( 170 | settings.get_user_value('icon-size')) 171 | if icon_size is None: 172 | select_value_in_combo(self.options['icon-size'], 'small') 173 | else: 174 | select_value_in_combo(self.options['icon-size'], icon_size) 175 | 176 | self.options[0].set_state(variant_to_value( 177 | settings.get_user_value('show-home')) is False) 178 | self.options[1].set_state(variant_to_value( 179 | settings.get_user_value('show-trash')) is False) 180 | 181 | settings = Gio.Settings.new( 182 | 'org.gnome.desktop.calendar') 183 | 184 | self.options[2].set_state(variant_to_value( 185 | settings.get_user_value('show-weekdate')) is True) 186 | 187 | settings = Gio.Settings.new( 188 | 'org.gnome.desktop.interface') 189 | 190 | self.options[3].set_state(variant_to_value( 191 | settings.get_user_value('clock-show-date')) is False) 192 | 193 | self.options[4].set_state(variant_to_value( 194 | settings.get_user_value('clock-show-seconds')) is True) 195 | 196 | self.options[5].set_state(variant_to_value( 197 | settings.get_user_value('clock-show-weekday')) is True) 198 | 199 | self.options[6].set_state(variant_to_value( 200 | settings.get_user_value('show-battery-percentage')) is True) 201 | 202 | settings = Gio.Settings.new( 203 | 'org.gnome.mutter') 204 | self.options[7].set_state(variant_to_value( 205 | settings.get_user_value('experimental-features')) is not None) 206 | 207 | def set_selected(self): 208 | settings = Gio.Settings.new( 209 | 'org.gnome.shell.extensions.desktop-icons') 210 | 211 | icon_size = get_selected_value_in_combo( 212 | self.options['icon-size']) 213 | if icon_size == 'small': 214 | settings.reset('icon-size') 215 | else: 216 | settings.set_string('icon-size', icon_size) 217 | if self.options[0].get_active() is True: 218 | settings.set_boolean('show-home', False) 219 | else: 220 | settings.reset('show-home') 221 | if self.options[1].get_active() is True: 222 | settings.set_boolean('show-trash', False) 223 | else: 224 | settings.reset('show-trash') 225 | 226 | settings = Gio.Settings.new( 227 | 'org.gnome.desktop.calendar') 228 | 229 | if self.options[2].get_active() is True: 230 | settings.set_boolean('show-weekdate', True) 231 | else: 232 | settings.reset('show-weekdate') 233 | 234 | settings = Gio.Settings.new( 235 | 'org.gnome.desktop.interface') 236 | if self.options[3].get_active() is True: 237 | settings.set_boolean('clock-show-date', False) 238 | else: 239 | settings.reset('clock-show-date') 240 | if self.options[4].get_active() is True: 241 | settings.set_boolean('clock-show-seconds', True) 242 | else: 243 | settings.reset('clock-show-seconds') 244 | if self.options[5].get_active() is True: 245 | settings.set_boolean('clock-show-weekday', True) 246 | else: 247 | settings.reset('clock-show-weekday') 248 | if self.options[6].get_active() is True: 249 | settings.set_boolean('show-battery-percentage', True) 250 | else: 251 | settings.reset('show-battery-percentage') 252 | 253 | settings = Gio.Settings.new( 254 | 'org.gnome.mutter') 255 | if self.options[7].get_active() is True: 256 | if os.environ.get('XDG_SESSION_TYPE') == 'x11': 257 | settings.set_strv('experimental-features', 258 | ['x11-randr-fractional-scaling']) 259 | else: 260 | settings.set_strv('experimental-features', 261 | ['scale-monitor-framebuffer']) 262 | else: 263 | settings.reset('experimental-features') 264 | -------------------------------------------------------------------------------- /src/tweak_dock.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Gio', '2.0') 30 | gi.require_version('Handy', '0.0') 31 | except Exception as e: 32 | print(e) 33 | exit(1) 34 | from gi.repository import Gtk 35 | from gi.repository import Gio 36 | from gi.repository import Handy 37 | import os 38 | import json 39 | import mimetypes 40 | import urllib 41 | import comun 42 | from comun import _ 43 | from sidewidget import SideWidget 44 | from utils import get_desktop_environment 45 | from settings import SettingRow 46 | from utils import variant_to_value, select_value_in_combo 47 | from utils import get_selected_value_in_combo 48 | 49 | 50 | class TweakDock(Gtk.Overlay): 51 | 52 | def __init__(self): 53 | Gtk.Overlay.__init__(self) 54 | self.__set_ui() 55 | 56 | def __set_ui(self): 57 | handycolumn = Handy.Column() 58 | handycolumn.set_maximum_width(700) 59 | handycolumn.set_margin_top(24) 60 | self.add(handycolumn) 61 | 62 | box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5) 63 | handycolumn.add(box) 64 | 65 | label = Gtk.Label(_('Custom dock')) 66 | label.set_name('special') 67 | label.set_alignment(0, 0.5) 68 | box.add(label) 69 | 70 | listbox0 = Gtk.ListBox() 71 | box.add(listbox0) 72 | 73 | self.options = {} 74 | for index in range(0, 3): 75 | self.options[index] = Gtk.Switch() 76 | self.options[index].set_valign(Gtk.Align.CENTER) 77 | 78 | dock_position = Gtk.ListStore(str, str) 79 | dock_position.append([_('Left'), 'LEFT']) 80 | dock_position.append([_('Right'), 'RIGHT']) 81 | dock_position.append([_('Top'), 'TOP']) 82 | dock_position.append([_('Bottom'), 'BOTTOM']) 83 | 84 | self.options['dock-position'] = Gtk.ComboBox.new() 85 | self.options['dock-position'].set_model(dock_position) 86 | cell1 = Gtk.CellRendererText() 87 | self.options['dock-position'].pack_start(cell1, True) 88 | self.options['dock-position'].add_attribute(cell1, 'text', 0) 89 | 90 | listbox0.add(SettingRow(_('Dock position'), 91 | _('Set the dock position on the screen.'), 92 | self.options['dock-position'])) 93 | 94 | listbox0.add(SettingRow(_('Enable minimize click action'), 95 | _('Minimize when clicking on a running app.'), 96 | self.options[0])) 97 | 98 | listbox0.add(SettingRow(_('Reduce dock length'), 99 | _('Reduce the dock container to icons.'), 100 | self.options[1])) 101 | 102 | listbox0.add(SettingRow(_('Force straight corner'), 103 | _('Make the borders in the dash non rounded.'), 104 | self.options[2])) 105 | 106 | label1 = Gtk.Label('Monitor') 107 | label1.set_name('special') 108 | label1.set_alignment(0, 0.5) 109 | box.add(label1) 110 | 111 | listbox1 = Gtk.ListBox() 112 | box.add(listbox1) 113 | 114 | for index in range(3, 5): 115 | self.options[index] = Gtk.Switch() 116 | self.options[index].set_valign(Gtk.Align.CENTER) 117 | 118 | listbox1.add(SettingRow(_('Isolate monitors'), 119 | _('Provide monitor isolation'), 120 | self.options[3])) 121 | listbox1.add(SettingRow(_('Multi monitor'), 122 | _('Enable multi monitor dock'), 123 | self.options[4])) 124 | 125 | label2 = Gtk.Label('Show in dock') 126 | label2.set_name('special') 127 | label2.set_alignment(0, 0.5) 128 | box.add(label2) 129 | 130 | listbox2 = Gtk.ListBox() 131 | box.add(listbox2) 132 | 133 | for index in range(5, 9): 134 | self.options[index] = Gtk.Switch() 135 | self.options[index].set_valign(Gtk.Align.CENTER) 136 | 137 | listbox2.add(SettingRow(_('Hide applications button'), 138 | _('Hide applications button'), 139 | self.options[5])) 140 | listbox2.add(SettingRow(_('Show apps at top'), 141 | _('Show application button at top'), 142 | self.options[6])) 143 | listbox2.add(SettingRow(_('Hide favorites'), 144 | _('Hide favorites apps'), 145 | self.options[7])) 146 | listbox2.add(SettingRow(_('Hide running'), 147 | _('Hide running apps'), 148 | self.options[8])) 149 | 150 | self.__load_default_states() 151 | 152 | def update(self): 153 | self.__load_default_states() 154 | 155 | def __load_default_states(self): 156 | settings = Gio.Settings.new( 157 | 'org.gnome.shell.extensions.dash-to-dock') 158 | 159 | dock_position = variant_to_value( 160 | settings.get_user_value('dock-position')) 161 | print('===', dock_position, '===') 162 | if dock_position is None: 163 | select_value_in_combo(self.options['dock-position'], 'LEFT') 164 | else: 165 | print(dock_position) 166 | select_value_in_combo(self.options['dock-position'], dock_position) 167 | 168 | self.options[0].set_state(variant_to_value( 169 | settings.get_user_value('click-action')) == 'minimize') 170 | self.options[1].set_state(variant_to_value( 171 | settings.get_user_value('extend-height')) is False) 172 | self.options[2].set_state(variant_to_value( 173 | settings.get_user_value('force-straight-corner')) is True) 174 | self.options[3].set_state(variant_to_value( 175 | settings.get_user_value('isolate-monitors')) is True) 176 | self.options[4].set_state(variant_to_value( 177 | settings.get_user_value('multi-monitor')) is True) 178 | self.options[5].set_state(variant_to_value( 179 | settings.get_user_value('show-show-apps-button')) is False) 180 | self.options[6].set_state(variant_to_value( 181 | settings.get_user_value('show-apps-at-top')) is True) 182 | self.options[7].set_state(variant_to_value( 183 | settings.get_user_value('show-favorites')) is False) 184 | self.options[8].set_state(variant_to_value( 185 | settings.get_user_value('show-running')) is False) 186 | 187 | def set_selected(self): 188 | settings = Gio.Settings.new( 189 | 'org.gnome.shell.extensions.dash-to-dock') 190 | dock_position = get_selected_value_in_combo( 191 | self.options['dock-position']) 192 | if dock_position == 'LEFT': 193 | settings.reset('dock-position') 194 | else: 195 | print(dock_position) 196 | settings.set_string('dock-position', dock_position) 197 | if self.options[0].get_active() is True: 198 | settings.set_string('click-action', 'minimize') 199 | else: 200 | settings.reset('click-action') 201 | if self.options[1].get_active() is True: 202 | settings.set_boolean('extend-height', False) 203 | else: 204 | settings.reset('extend-height') 205 | if self.options[2].get_active() is True: 206 | settings.set_boolean('force-straight-corner', True) 207 | else: 208 | settings.reset('force-straight-corner') 209 | if self.options[3].get_active() is True: 210 | settings.set_boolean('isolate-monitors', True) 211 | else: 212 | settings.reset('isolate-monitors') 213 | if self.options[4].get_active() is True: 214 | settings.set_boolean('multi-monitor', True) 215 | else: 216 | settings.reset('multi-monitor') 217 | if self.options[5].get_active() is False: 218 | settings.reset('show-show-apps-button') 219 | else: 220 | settings.set_boolean('show-show-apps-button', False) 221 | 222 | if self.options[6].get_active() is True: 223 | settings.set_boolean('show-apps-at-top', True) 224 | else: 225 | settings.reset('show-apps-at-top') 226 | if self.options[7].get_active() is False: 227 | settings.reset('show-favorites') 228 | else: 229 | settings.set_boolean('show-favorites', False) 230 | if self.options[8].get_active() is False: 231 | settings.reset('show-running') 232 | else: 233 | settings.set_boolean('show-running', False) 234 | self.__load_default_states() 235 | -------------------------------------------------------------------------------- /src/tweak_packages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Handy', '0.0') 30 | except Exception as e: 31 | print(e) 32 | exit(1) 33 | from gi.repository import Gtk 34 | from gi.repository import Handy 35 | from comun import _ 36 | from settings import SettingRow 37 | from utils import is_installed 38 | 39 | 40 | class TweakPackages(Gtk.Overlay): 41 | 42 | def __init__(self): 43 | Gtk.Overlay.__init__(self) 44 | self.__set_repositories() 45 | self.__set_ui() 46 | 47 | def __set_repositories(self): 48 | self.packages = {} 49 | self.packages[0] = ['VLC', 50 | 'VLC is the VideoLAN project\'s media player.', 51 | 'vlc'] 52 | self.packages[1] = ['GIMP', 53 | 'GIMP is an advanced picture editor', 54 | 'gimp'] 55 | self.packages[2] = ['gimp-plugin-registry', 56 | '', 57 | 'gimp-plugin-registry'] 58 | self.packages[3] = ['gmic', 59 | '', 60 | 'gmic'] 61 | self.packages[4] = ['gimp-gmic', 62 | '', 63 | 'gimp-gmic'] 64 | self.packages[5] = ['Blender', 65 | 'Blender is an integrated 3d suite for modelling, \ 66 | animation, rendering, post-production, interactive creation and playback \ 67 | (games)', 68 | 'blender'] 69 | self.packages[6] = ['gufw', 70 | 'gufw is an easy and intuitive way to manage your \ 71 | Linux firewall.', 72 | 'gufw'] 73 | self.packages[7] = ['Inkscape', 74 | 'Inkscape is an illustration editor which has \ 75 | everything needed to create professional-quality computer art.', 76 | 'inkscape'] 77 | self.packages[8] = ['Steam', 78 | 'Steam is a popular digital distribution platform \ 79 | for video games by Valve.', 80 | 'steam'] 81 | self.packages[9] = ['FileZilla', 82 | 'FileZilla is a complete FTP client.', 83 | 'filezilla'] 84 | self.packages[10] = ['Flameshot', 85 | 'Powerful and simple to use screenshot software', 86 | 'flameshot'] 87 | self.packages[11] = ['Sushi', 88 | 'Preview tool for the GNOME Shell desktop', 89 | 'gnome-sushi'] 90 | self.packages[12] = ['Weather', 91 | 'The weather in your desktop via GNOME', 92 | 'gnome-weather'] 93 | self.packages[13] = ['Geary', 94 | 'Geary is an open-source e-mail client for the \ 95 | Linux desktop', 96 | 'geary'] 97 | self.packages[14] = ['Caffeine', 98 | 'Lock Screen Inhibitor', 99 | 'caffeine'] 100 | self.packages[15] = ['Corebird', 101 | 'The Twitter application for the Linux Desktop', 102 | 'corebird'] 103 | 104 | def __set_ui(self): 105 | handycolumn = Handy.Column() 106 | handycolumn.set_maximum_width(700) 107 | handycolumn.set_margin_top(24) 108 | self.add(handycolumn) 109 | 110 | box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5) 111 | handycolumn.add(box) 112 | 113 | label0 = Gtk.Label(_('Applications')) 114 | label0.set_name('special') 115 | label0.set_alignment(0, 0.5) 116 | box.add(label0) 117 | 118 | listbox0 = Gtk.ListBox() 119 | box.add(listbox0) 120 | 121 | self.options = {} 122 | for index in range(0, len(self.packages)): 123 | self.options[index] = Gtk.Switch() 124 | self.options[index].set_valign(Gtk.Align.CENTER) 125 | listbox0.add(SettingRow(self.packages[index][0], 126 | self.packages[index][1], 127 | self.options[index])) 128 | self.options[index].set_state( 129 | is_installed(self.packages[index][2])) 130 | 131 | def update(self): 132 | for index in range(0, len(self.packages)): 133 | self.options[index].set_state( 134 | is_installed(self.packages[index][2])) 135 | 136 | def set_selected(self): 137 | to_install = [] 138 | to_remove = [] 139 | for index in range(0, len(self.packages)): 140 | if self.options[index].get_state() is True: 141 | if is_installed(self.packages[index][2]) is False: 142 | to_install.append(self.packages[index][2]) 143 | else: 144 | if is_installed(self.packages[index][2]) is True: 145 | to_remove.append(self.packages[index][2]) 146 | return to_install, to_remove 147 | -------------------------------------------------------------------------------- /src/tweak_privacy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Gio', '2.0') 30 | gi.require_version('Handy', '0.0') 31 | except Exception as e: 32 | print(e) 33 | exit(1) 34 | from gi.repository import Gtk 35 | from gi.repository import Gio 36 | from gi.repository import Handy 37 | from comun import _ 38 | from settings import SettingRow 39 | from utils import variant_to_value 40 | from utils import is_installed 41 | 42 | 43 | class TweakPrivacy(Gtk.Overlay): 44 | 45 | def __init__(self): 46 | Gtk.Overlay.__init__(self) 47 | self.__set_ui() 48 | 49 | def __set_ui(self): 50 | handycolumn = Handy.Column() 51 | handycolumn.set_maximum_width(700) 52 | handycolumn.set_margin_top(24) 53 | self.add(handycolumn) 54 | 55 | box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5) 56 | handycolumn.add(box) 57 | 58 | label0 = Gtk.Label(_('Peripherals')) 59 | label0.set_name('special') 60 | label0.set_alignment(0, 0.5) 61 | box.add(label0) 62 | 63 | listbox0 = Gtk.ListBox() 64 | box.add(listbox0) 65 | 66 | self.options = {} 67 | for index in range(0, 3): 68 | self.options[index] = Gtk.Switch() 69 | self.options[index].set_valign(Gtk.Align.CENTER) 70 | 71 | listbox0.add(SettingRow(_('Disable camera'), 72 | _('Avoid applications to use the camera.'), 73 | self.options[0])) 74 | listbox0.add(SettingRow(_('Disable microphone'), 75 | _('Avoid applications to use the microphone.'), 76 | self.options[1])) 77 | listbox0.add(SettingRow(_('Disable sound outp'), 78 | _('Avoid applications to play sound.'), 79 | self.options[2])) 80 | 81 | label1 = Gtk.Label(_('Identity')) 82 | label1.set_name('special') 83 | label1.set_alignment(0, 0.5) 84 | box.add(label1) 85 | 86 | listbox1 = Gtk.ListBox() 87 | box.add(listbox1) 88 | 89 | self.options[3] = Gtk.Switch() 90 | self.options[3].set_valign(Gtk.Align.CENTER) 91 | 92 | listbox1.add(SettingRow(_('Hide identity'), 93 | _('Hide personal information.'), 94 | self.options[3])) 95 | 96 | label2 = Gtk.Label(_('Remember')) 97 | label2.set_name('special') 98 | label2.set_alignment(0, 0.5) 99 | box.add(label2) 100 | 101 | listbox2 = Gtk.ListBox() 102 | box.add(listbox2) 103 | 104 | for index in range(4, 8): 105 | self.options[index] = Gtk.Switch() 106 | self.options[index].set_valign(Gtk.Align.CENTER) 107 | 108 | listbox2.add(SettingRow(_('Forget application usage'), 109 | _('Forget application usage.'), 110 | self.options[4])) 111 | 112 | listbox2.add(SettingRow(_('Forget recent files'), 113 | _('Forget recent files.'), 114 | self.options[5])) 115 | 116 | listbox2.add(SettingRow(_('Remove temporary files'), 117 | _('Remove old temporary files automatically.'), 118 | self.options[6])) 119 | 120 | listbox2.add(SettingRow(_('Remove trash files'), 121 | _('Remove old trash files automatically.'), 122 | self.options[7])) 123 | 124 | label3 = Gtk.Label(_('Statistics')) 125 | label3.set_name('special') 126 | label3.set_alignment(0, 0.5) 127 | box.add(label3) 128 | 129 | listbox3 = Gtk.ListBox() 130 | box.add(listbox3) 131 | 132 | for index in range(8, 11): 133 | self.options[index] = Gtk.Switch() 134 | self.options[index].set_valign(Gtk.Align.CENTER) 135 | 136 | listbox3.add(SettingRow(_('Send technical problems'), 137 | _('Send technical problems.'), 138 | self.options[8])) 139 | 140 | listbox3.add(SettingRow(_('Send software usage'), 141 | _('Send softwarew usage statistics.'), 142 | self.options[9])) 143 | 144 | listbox3.add(SettingRow(_('Ubuntu popularity contest'), 145 | _('Send information about installed packages'), 146 | self.options[10])) 147 | 148 | self.__load_default_states() 149 | 150 | def update(self): 151 | self.__load_default_states() 152 | 153 | def __load_default_states(self): 154 | settings = Gio.Settings.new( 155 | 'org.gnome.desktop.privacy') 156 | self.options[0].set_state(variant_to_value( 157 | settings.get_user_value('disable-camera')) is True) 158 | self.options[1].set_state(variant_to_value( 159 | settings.get_user_value('disable-microphone')) is True) 160 | self.options[2].set_state(variant_to_value( 161 | settings.get_user_value('disable-sound-output')) is True) 162 | self.options[3].set_state(variant_to_value( 163 | settings.get_user_value('hide-identity')) is True) 164 | self.options[4].set_state(variant_to_value( 165 | settings.get_user_value('remember-app-usage')) is False) 166 | self.options[5].set_state(variant_to_value( 167 | settings.get_user_value('remember-recent-files')) is False) 168 | self.options[6].set_state(variant_to_value( 169 | settings.get_user_value('remove-old-temp-files')) is True) 170 | self.options[7].set_state(variant_to_value( 171 | settings.get_user_value('remove-old-trash-files')) is True) 172 | self.options[8].set_state(variant_to_value( 173 | settings.get_user_value('report-technical-problems')) is True) 174 | self.options[9].set_state(variant_to_value( 175 | settings.get_user_value('send-software-usage-stats')) is True) 176 | self.options[10].set_state(is_installed('popularity-contest')) 177 | 178 | def set_selected(self): 179 | settings = Gio.Settings.new( 180 | 'org.gnome.desktop.privacy') 181 | if self.options[0].get_active() is True: 182 | settings.set_boolean('disable-camera', True) 183 | else: 184 | settings.reset('disable-camera') 185 | if self.options[1].get_active() is True: 186 | settings.set_boolean('disable-microphone', True) 187 | else: 188 | settings.reset('disable-microphone') 189 | if self.options[2].get_active() is True: 190 | settings.set_boolean('disable-sound-output', True) 191 | else: 192 | settings.reset('disable-sound-output') 193 | if self.options[3].get_active() is True: 194 | settings.set_boolean('hide-identity', True) 195 | else: 196 | settings.reset('hide-identity') 197 | if self.options[4].get_active() is True: 198 | settings.set_boolean('remember-app-usage', False) 199 | else: 200 | settings.reset('remember-app-usage') 201 | if self.options[5].get_active() is True: 202 | settings.set_boolean('remember-recent-files', False) 203 | else: 204 | settings.reset('remember-recent-files') 205 | if self.options[6].get_active() is True: 206 | settings.set_boolean('remove-old-temp-files', True) 207 | else: 208 | settings.reset('remove-old-temp-files') 209 | if self.options[7].get_active() is True: 210 | settings.set_boolean('remove-old-trash-files', True) 211 | else: 212 | settings.reset('remove-old-trash-files') 213 | if self.options[8].get_active() is True: 214 | settings.set_boolean('report-technical-problems', True) 215 | else: 216 | settings.reset('report-technical-problems') 217 | if self.options[9].get_active() is True: 218 | settings.set_boolean('send-software-usage-stats', True) 219 | else: 220 | settings.reset('send-software-usage-stats') 221 | 222 | def set_selected_packages(self): 223 | to_install = [] 224 | to_remove = [] 225 | if self.options[10].get_state() is True: 226 | if is_installed('popularity-contest') is False: 227 | to_install.append('popularity-contest') 228 | else: 229 | if is_installed('popularity-contest') is True: 230 | to_remove.append('popularity-contest') 231 | return to_install, to_remove 232 | -------------------------------------------------------------------------------- /src/tweak_repositories.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('Gtk', '3.0') 29 | gi.require_version('Gio', '2.0') 30 | gi.require_version('Handy', '0.0') 31 | except Exception as e: 32 | print(e) 33 | exit(1) 34 | from gi.repository import Gtk 35 | from gi.repository import Gio 36 | from gi.repository import Handy 37 | import os 38 | import glob 39 | import json 40 | import mimetypes 41 | import urllib 42 | import comun 43 | from comun import _ 44 | from sidewidget import SideWidget 45 | from utils import get_desktop_environment 46 | from settings import SettingRow 47 | from utils import variant_to_value, select_value_in_combo 48 | from utils import get_selected_value_in_combo 49 | 50 | 51 | class TweakRepositories(Gtk.Overlay): 52 | 53 | def __init__(self): 54 | Gtk.Overlay.__init__(self) 55 | self.__set_repositories() 56 | self.__set_ui() 57 | 58 | def __set_repositories(self): 59 | self.ppas = {} 60 | self.ppas[0] = ['LibreOffice Fresh', 61 | 'Latest stable release of the LibreOffice office \ 62 | suite', 63 | 'libreoffice/ppa'] 64 | self.ppas[1] = ['Grub Customizer', 65 | 'If you want to customize the GRUB screen of your \ 66 | system', 67 | 'danielrichter2007/grub-customizer'] 68 | self.ppas[2] = ['WebUpd8', 69 | 'PPA containing a lot of useful applications that are \ 70 | mostly updated to their latest versions', 71 | 'nilarimogard/webupd8'] 72 | self.ppas[3] = ['FreeCAD', 73 | 'Latest stable release of FreeCAD', 74 | 'freecad-maintainers/freecad-stable'] 75 | self.ppas[4] = ['Inkscape', 76 | 'Latest stable release of Inkscape', 77 | 'inkscape.dev/stable'] 78 | self.ppas[5] = ['OBS Studio', 79 | 'Latest stable release of OBS Studio', 80 | 'obsproject/obs-studio'] 81 | self.ppas[6] = ['Handbrake', 82 | 'Latest stable release of Handbrake', 83 | 'stebbins/handbrake-releases'] 84 | self.ppas[7] = ['Lutris', 85 | 'Latest stable release of Lutris', 86 | 'lutris-team/lutris'] 87 | self.ppas[8] = ['Gimp', 88 | 'Latest stable release of Gimp', 89 | 'otto-kesselgulasch/gimp'] 90 | self.ppas[9] = ['Blender', 91 | 'Latest stable release of Blender', 92 | 'thomas-schiex/blender'] 93 | self.ppas[10] = ['Audacity', 94 | 'Unofficial. Most recent relase version of Audacity', 95 | 'buntuhandbook1/audacity'] 96 | 97 | def __set_ui(self): 98 | handycolumn = Handy.Column() 99 | handycolumn.set_maximum_width(700) 100 | handycolumn.set_margin_top(24) 101 | self.add(handycolumn) 102 | 103 | box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 5) 104 | handycolumn.add(box) 105 | 106 | label0 = Gtk.Label(_('Repositories')) 107 | label0.set_name('special') 108 | label0.set_alignment(0, 0.5) 109 | box.add(label0) 110 | 111 | listbox0 = Gtk.ListBox() 112 | box.add(listbox0) 113 | 114 | self.options = {} 115 | installed_ppas = self.get_installed_ppas() 116 | for index in range(0, len(self.ppas)): 117 | self.options[index] = Gtk.Switch() 118 | self.options[index].set_valign(Gtk.Align.CENTER) 119 | listbox0.add(SettingRow(self.ppas[index][0], 120 | self.ppas[index][1], 121 | self.options[index])) 122 | self.options[index].set_state( 123 | self.ppas[index][2] in installed_ppas) 124 | 125 | def update(self): 126 | installed_ppas = self.get_installed_ppas() 127 | for index in range(0, len(self.ppas)): 128 | self.options[index].set_state( 129 | self.ppas[index][2] in installed_ppas) 130 | 131 | def set_selected(self): 132 | to_install = [] 133 | to_remove = [] 134 | installed_ppas = self.get_installed_ppas() 135 | for index in range(0, len(self.ppas)): 136 | if self.options[index].get_state() is True: 137 | if self.ppas[index][2] not in installed_ppas: 138 | to_install.append(self.ppas[index][2]) 139 | else: 140 | if self.ppas[index][2] in installed_ppas: 141 | to_remove.append(self.ppas[index][2]) 142 | return to_install, to_remove 143 | 144 | def get_installed_ppas(self): 145 | ppas = [] 146 | ppa_folder = '/etc/apt/sources.list.d' 147 | for ppa in glob.glob(os.path.join(ppa_folder, '*.list')): 148 | filename, extension = os.path.splitext( 149 | os.path.os.path.basename(ppa)) 150 | ppa = '-'.join(filename.split('-')[:-1]).replace('-ubuntu', '') 151 | if ppa.count('-') > 1: 152 | data = ppa.split('-') 153 | ppa = '-'.join(data[:-1]) + '/' + data[-1] 154 | else: 155 | ppa = ppa.replace('-', '/') 156 | if ppa is not None and len(ppa) > 0: 157 | ppas.append(ppa) 158 | return ppas 159 | -------------------------------------------------------------------------------- /src/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: UTF-8 -*- 3 | # 4 | # This file is part of ubuntu-first-steps 5 | # 6 | # Copyright (c) 2020 Lorenzo Carbonell Cerezo 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | # SOFTWARE 25 | 26 | import gi 27 | try: 28 | gi.require_version('GLib', '2.0') 29 | except Exception as e: 30 | print(e) 31 | exit(1) 32 | from gi.repository import GLib 33 | import os 34 | import re 35 | from plumbum import local 36 | 37 | 38 | def variant_to_value(variant): 39 | '''Returns the value of a GLib.Variant 40 | ''' 41 | # pylint: disable=unidiomatic-typecheck 42 | if type(variant) != GLib.Variant: 43 | return variant 44 | type_string = variant.get_type_string() 45 | if type_string == 's': 46 | return variant.get_string() 47 | elif type_string == 'i': 48 | return variant.get_int32() 49 | elif type_string == 'b': 50 | return variant.get_boolean() 51 | elif type_string == 'as': 52 | # In the latest pygobject3 3.3.4 or later, g_variant_dup_strv 53 | # returns the allocated strv but in the previous release, 54 | # it returned the tuple of (strv, length) 55 | if type(GLib.Variant.new_strv([]).dup_strv()) == tuple: 56 | return variant.dup_strv()[0] 57 | else: 58 | return variant.dup_strv() 59 | else: 60 | print('error: unknown variant type: {}'.format(type_string)) 61 | return variant 62 | 63 | 64 | def select_value_in_combo(combo, value): 65 | model = combo.get_model() 66 | for i, item in enumerate(model): 67 | if value == item[1]: 68 | combo.set_active(i) 69 | return 70 | combo.set_active(0) 71 | 72 | 73 | def get_selected_value_in_combo(combo): 74 | model = combo.get_model() 75 | return model.get_value(combo.get_active_iter(), 1) 76 | 77 | 78 | def is_running(process): 79 | ps = local['ps'] 80 | if re.search(process, ps['axw']()): 81 | return True 82 | return False 83 | 84 | 85 | def is_installed(package): 86 | try: 87 | dpkgquery = local['dpkg-query'] 88 | result = dpkgquery['-W', '-f=\'${Status}\'', package]() 89 | return result == '\'install ok installed\'' 90 | except Exception: 91 | pass 92 | return False 93 | 94 | 95 | def get_desktop_environment(): 96 | desktop_session = os.environ.get("DESKTOP_SESSION") 97 | # easier to match if we doesn't have to deal with caracter cases 98 | if desktop_session is not None: 99 | desktop_session = desktop_session.lower() 100 | if desktop_session in ["gnome", "unity", "cinnamon", "mate", 101 | "budgie-desktop", "xfce4", "lxde", "fluxbox", 102 | "blackbox", "openbox", "icewm", "jwm", 103 | "afterstep", "trinity", "kde"]: 104 | return desktop_session 105 | # ## Special cases ## 106 | # Canonical sets $DESKTOP_SESSION to Lubuntu rather than 107 | # LXDE if using LXDE. 108 | # There is no guarantee that they will not do the same with 109 | # the other desktop environments. 110 | elif "xfce" in desktop_session or\ 111 | desktop_session.startswith("xubuntu"): 112 | return "xfce4" 113 | elif desktop_session.startswith("ubuntu"): 114 | return "unity" 115 | elif desktop_session.startswith("lubuntu"): 116 | return "lxde" 117 | elif desktop_session.startswith("kubuntu"): 118 | return "kde" 119 | elif desktop_session.startswith("razor"): # e.g. razorkwin 120 | return "razor-qt" 121 | elif desktop_session.startswith("wmaker"): # eg. wmaker-common 122 | return "windowmaker" 123 | if os.environ.get('KDE_FULL_SESSION') == 'true': 124 | return "kde" 125 | elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): 126 | if "deprecated" not in os.environ.get( 127 | 'GNOME_DESKTOP_SESSION_ID'): 128 | return "gnome2" 129 | # From http://ubuntuforums.org/showthread.php?t=652320 130 | elif is_running("xfce-mcs-manage"): 131 | return "xfce4" 132 | elif is_running("ksmserver"): 133 | return "kde" 134 | return "unknown" 135 | 136 | 137 | CSS = ''' 138 | window hdycolumn box list row combobox{ 139 | padding-top: 10px; 140 | padding-bottom: 10px; 141 | } 142 | #sidewidget{ 143 | padding: 10px; 144 | } 145 | window hdycolumn box list row{ 146 | background-color: $background_color; 147 | padding: 2px 8px; 148 | margin: 0; 149 | border: 1px solid $border_color; 150 | border-bottom: 0px; 151 | color: $forecolor; 152 | } 153 | window hdycolumn box list row:hover{ 154 | background-color: $hover_color; 155 | } 156 | window hdycolumn box list row:selected{ 157 | background-color: $hover_color; 158 | } 159 | window hdycolumn box list row:last-child{ 160 | border-bottom: 1px solid $border_color; 161 | } 162 | 163 | window hdycolumn box list row separator { 164 | background-color: $border_color; 165 | } 166 | 167 | #special{ 168 | font-size: 14px; 169 | font-weight:bold; 170 | color: $caption_color; 171 | margin-bottom: 8px; 172 | } 173 | 174 | #label:hover, 175 | #label{ 176 | color: rgba(1, 1, 1, 1); 177 | } 178 | #label:selected{ 179 | color: rgba(0, 1, 0, 1); 180 | } 181 | #button:hover, 182 | #button { 183 | border-image: none; 184 | background-image: none; 185 | background-color: rgba(0, 0, 0, 0); 186 | border-color: rgba(0, 0, 0, 0); 187 | border-image: none; 188 | border-radius: 0; 189 | border-width: 0; 190 | border-style: solid; 191 | text-shadow: 0 0 rgba(0, 0, 0, 0); 192 | box-shadow: 0 0 rgba(0, 0, 0, 0), 0 0 rgba(0, 0, 0, 0); 193 | } 194 | #button:hover{ 195 | background-color: rgba(0, 0, 0, 0.1); 196 | }''' 197 | 198 | if __name__ == '__main__': 199 | print(get_desktop_environment()) 200 | --------------------------------------------------------------------------------