-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
C2N14
committed
Jun 15, 2018
0 parents
commit bd6ed48
Showing
18 changed files
with
3,254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
venv/ | ||
snap/ | ||
.idea/ | ||
releases/ | ||
*.egg-info/ | ||
*.egg | ||
*__pycache__/ | ||
*.pyc | ||
*.py[cod] |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
recursive-include automathemely/lib * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
|
||
![](automathemely/lib/automathemely_large.svg) | ||
|
||
# AutomaThemely | ||
|
||
Simple, set-and-forget python application for changing between GNOME themes according to light and dark hours | ||
|
||
## Getting Started | ||
|
||
### Prerequisites | ||
|
||
* Obviously having the GNOME desktop environment (or maybe not, see [notes](#notes) for more info) | ||
* Python 3.5+ | ||
* Crontab | ||
* GTK+ 3.0+ (optional, for the settings manager GUI) | ||
* Pip3 (optional, for installation) | ||
|
||
### Installing | ||
|
||
You can go to [releases](https://github.com/C2N14/AutomaThemely/releases) and download whichever package suits your needs | ||
|
||
Or install it through snapcraft (Not yet, TODO) | ||
|
||
``` | ||
snap install automathemely --classic | ||
``` | ||
|
||
Or even clone the project and install it yourself (icons and shortcuts will not be installed) | ||
|
||
``` | ||
git clone https://github.com/C2N14/AutomaThemely.git | ||
cd AutomaThemely | ||
python3 setup.py install | ||
``` | ||
|
||
### Running | ||
|
||
Once installed, run once to generate a settings file | ||
|
||
``` | ||
automathemely | ||
``` | ||
|
||
And then run again with `-m` or `--manager` use the settings manager (requires GTK) | ||
|
||
``` | ||
automathemely --manage | ||
``` | ||
|
||
Or manually set the settings with `-s` or `--setting` if you somehow don't have GTK in your system | ||
|
||
``` | ||
# To show all the available options | ||
automathemely --list | ||
# For example: | ||
automathemely --setting themes.light=Adwaita | ||
``` | ||
|
||
Or you can even manually edit the configuration file in `/home/user/.config/AutomaThemely` | ||
|
||
Finally, update all the necessary crontabs to make sure it runs at the right hours | ||
|
||
``` | ||
automathemely --update | ||
``` | ||
|
||
And that's it! You don't have to worry about touching anything anymore. | ||
|
||
## Notes | ||
|
||
* Although it is specifically made for GNOME, it should be compatible with Unity, and other desktop environments could easily be implemented. | ||
* This program requires an active internet connection **ONLY** if you set *Auto Location* on (it uses your ip to determine your geolocation), otherwise you can manually set your location and you won't need it. | ||
* You should never really manually edit the version number on the configuration file because it will most likely be overwritten | ||
* Tested with Ubuntu 17.10 & Ubuntu 16.04 | ||
* Yeah, yeah, I know that icon is an eyesore but I'm no designer so it'll have to do until a better one is made ¯\\\_(ツ)_/¯ | ||
|
||
## License | ||
|
||
This project is licensed under the GPLv3 License - see [LICENSE](LICENSE) for details |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import os | ||
from pathlib import Path | ||
|
||
_ROOT = os.path.abspath(os.path.dirname(__file__)) | ||
__version__ = 1.0 | ||
|
||
|
||
def get_resource(path=''): | ||
return os.path.join(_ROOT, 'lib', path) | ||
|
||
|
||
def get_bin(path=''): | ||
return os.path.join(_ROOT, 'bin', path) | ||
|
||
|
||
def get_local(path=''): | ||
return os.path.join(str(Path.home()), '.config/AutomaThemely', path) | ||
|
||
|
||
def get_root(path=''): | ||
return os.path.join(_ROOT, path) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from . import argmanager | ||
from . import updsunhours | ||
from . import settsmanager |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#!/usr/bin/env python3 | ||
import json | ||
from sys import exit, path | ||
import argparse | ||
import pickle as pkl | ||
import fcntl | ||
import copy | ||
from automathemely import get_local | ||
|
||
parser = argparse.ArgumentParser() | ||
options = parser.add_mutually_exclusive_group() | ||
options.add_argument('-l', '--list', help='list all current settings', action='store_true', default=False) | ||
options.add_argument('-s', '--setting', help="change a specific setting (e.g. key.subkey=value)") | ||
options.add_argument('-m', '--manage', help='easier to use settings manager GUI', action='store_true', | ||
default=False) | ||
options.add_argument('-u', '--update', help='updates the sunrise and sunset\'s crontabs manually', action='store_true', | ||
default=False) | ||
|
||
|
||
# For --setting arg | ||
def lookup_dic(d, k): | ||
val = d | ||
for key in k: | ||
try: | ||
val = val[key] | ||
except KeyError: | ||
return False | ||
return True | ||
|
||
|
||
# For --setting arg | ||
def write_dic(dic, lis, val): | ||
if len(lis) == 0: | ||
return val | ||
else: | ||
key = lis.pop(0) | ||
dic[key] = write_dic(dic[key], lis, val) | ||
return dic | ||
|
||
|
||
# For --list arg | ||
def print_list(d, indent=0): | ||
for key, value in d.items(): | ||
print('{}{}'.format('\t' * indent, key), end='') | ||
if isinstance(value, dict): | ||
print('.') | ||
print_list(value, indent + 1) | ||
else: | ||
print(' = {}'.format(value)) | ||
|
||
|
||
# ARGUMENTS FUNCTION | ||
def main(us_se): | ||
args = parser.parse_args() | ||
if args.list: | ||
print('Current settings:') | ||
print_list(us_se) | ||
exit() | ||
|
||
elif args.setting: | ||
|
||
if not args.setting.count('=') == 1: | ||
exit('\nERROR: Invalid string (None or more than one "=" signs)') | ||
|
||
setts = args.setting.split('=') | ||
to_set_key = setts[0].strip() | ||
to_set_val = setts[1].strip() | ||
|
||
if to_set_key == '': | ||
exit('\nERROR: Invalid string (Empty key)') | ||
elif to_set_key[-1] == '.': | ||
exit('\nERROR: Invalid string (Key ends in dot)') | ||
if not to_set_val: | ||
exit('\nERROR: Invalid string (Empty value)') | ||
elif to_set_val.lower() in ['t', 'true', '1']: | ||
to_set_val = True | ||
elif to_set_val.lower() in ['f', 'false', '0']: | ||
to_set_val = False | ||
else: | ||
try: | ||
to_set_val = int(to_set_val) | ||
except ValueError: | ||
try: | ||
to_set_val = float(to_set_val) | ||
except ValueError: | ||
pass | ||
|
||
if to_set_key.count('.') > 0: | ||
key_list = [x.strip() for x in to_set_key.split('.')] | ||
else: | ||
key_list = [to_set_key] | ||
|
||
if lookup_dic(us_se, key_list): | ||
us_se = write_dic(us_se, key_list, to_set_val) | ||
|
||
with open(get_local('user_settings.json'), 'w') as file: | ||
json.dump(us_se, file, indent=4) | ||
|
||
# Warning if user disables auto by --setting | ||
if 'enabled' in to_set_key and not to_set_val: | ||
print('\nWARNING: Remember to set all the necessary values with either --settings or --manage') | ||
exit('Successfully set key "{}" as "{}"'.format(to_set_key, to_set_val)) | ||
|
||
else: | ||
exit('\nERROR: Key "{}" not found'.format(to_set_key)) | ||
|
||
# MANAGE | ||
elif args.manage: | ||
from . import settsmanager | ||
|
||
pid_file = '/tmp/automathemely_settings.pid' | ||
fp = open(pid_file, 'w') | ||
try: | ||
fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) | ||
except IOError: | ||
return 'Another instance of the settings manager is already running!', True | ||
else: | ||
new_se = settsmanager.main(copy.deepcopy(us_se)) | ||
|
||
# Dump file | ||
with open(get_local('user_settings.json'), 'w') as file: | ||
json.dump(new_se, file, indent=4) | ||
|
||
has_changed = (new_se != us_se) | ||
if has_changed: | ||
return 'Settings successfully saved', True | ||
else: | ||
return 'No changes were made', True | ||
|
||
# UPDATE | ||
elif args.update: | ||
from . import updsunhours | ||
output, is_error = updsunhours.main(us_se) | ||
if not is_error: | ||
with open(get_local('sun_hours.time'), 'wb') as file: | ||
pkl.dump(output, file, protocol=pkl.HIGHEST_PROTOCOL) | ||
return 'Sun hours successfully updated', True | ||
else: | ||
# Pass the error message for a notification popup | ||
return output, True |
Oops, something went wrong.