Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
C2N14 committed Jun 15, 2018
0 parents commit bd6ed48
Show file tree
Hide file tree
Showing 18 changed files with 3,254 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
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]
675 changes: 675 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
recursive-include automathemely/lib *
79 changes: 79 additions & 0 deletions README.md
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
21 changes: 21 additions & 0 deletions automathemely/__init__.py
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)
3 changes: 3 additions & 0 deletions automathemely/autoth_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import argmanager
from . import updsunhours
from . import settsmanager
140 changes: 140 additions & 0 deletions automathemely/autoth_tools/argmanager.py
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
Loading

0 comments on commit bd6ed48

Please sign in to comment.