From 2c5dfb0b291b809d667e0a366f7afe62022c7e3f Mon Sep 17 00:00:00 2001 From: Prayag Jain Date: Thu, 11 Mar 2021 00:17:55 +0530 Subject: [PATCH 1/2] Added CONTRIBUTION.md, changed code style to PEP8, docstring style to Google Python Style Guide and fixed a bug. --- .pylintrc | 2 + .vscode/settings.json | 4 + CHANGELOG.md | 14 +- CONTRIBUTION.md | 94 +++++ README.md | 3 +- konsave/__main__.py | 97 ++++- konsave/__pycache__/__main__.cpython-39.pyc | Bin 1729 -> 2056 bytes konsave/__pycache__/funcs.cpython-39.pyc | Bin 8743 -> 10104 bytes konsave/__pycache__/vars.cpython-39.pyc | Bin 558 -> 613 bytes konsave/funcs.py | 371 ++++++++++++-------- konsave/vars.py | 16 +- setup.py | 5 + 12 files changed, 424 insertions(+), 182 deletions(-) create mode 100644 .pylintrc create mode 100644 .vscode/settings.json create mode 100644 CONTRIBUTION.md diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..631e989 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,2 @@ +[MASTER] +disable=broad-except, too-many-locals \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cc67606 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.linting.pylintEnabled": true, + "python.linting.enabled": true +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d97c6..1628d0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,13 +10,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ``CHANGELOG.md`` file with (Keep a Changelog)[https://keepachangelog.com/en/1.0.0/] format. -## [1.1.5] - 2021-03-06 +## [1.1.6] - 2021-03-11 +### Changes +- Changed code style to [PEP8](https://www.python.org/dev/peps/pep-0008/) +- Changed docstring style to [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) + +## Additions +- Added a CONTRIBUTIONS.md + +## Fixes +- Fixed a possible bug. Refer to [#26](https://github.com/Prayag2/konsave/issues/26). + +## [1.1.5] - 2021-03-08 ### Changes - Changed `print_msg` to `log`. - Changed `check_error` function to a decorator (Thanks to (this article)[https://medium.com/swlh/handling-exceptions-in-python-a-cleaner-way-using-decorators-fae22aa0abec]) for easier maintenance. - Improved logging - ## [1.1.4] - 2021-03-07 ### Changes - Created a function called `copy` to replace `shutil.copytree`. This would add support for python versions <= 3.7. diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md new file mode 100644 index 0000000..a91da1f --- /dev/null +++ b/CONTRIBUTION.md @@ -0,0 +1,94 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, +email, or any other method with the owners of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Ensure any install or build dependencies are removed before the end of the layer when doing a + build. +2. Update the README.md with details of changes to the interface. +3. Increase the version number in `konsave/vars.py`. The versioning scheme we use is [SemVer](http://semver.org/). +4. Introduced changes should be briefly described in `CHANGELOG.md`. +4. Create a pull request and wait for the response. + +## Code Guidelines +1. This project uses the [PEP8](https://www.python.org/dev/peps/pep-0008/) code style. Your code must follow the same before you create a pull request. Your [PyLint](https://www.pylint.org/) score should be 10.00/10. You can use [black formatter](https://github.com/psf/black) to format your code quickly. +2. Every function in your code *must* have a docstring that follows [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html). Use [Darglint](https://github.com/terrencepreilly/darglint) to double check. + +## Code of Conduct + +### Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +### Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +### Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +### Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at prayagjain2@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file diff --git a/README.md b/README.md index fb39b23..aae0e2b 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,7 @@ You may need to log out and log in to see all the changes. ### Wipe all profiles `konsave -w` or `konsave --wipe` ## Contribution -You can contribute by reporting issues or fixing bugs! -Introduced changes should be briefly described in `CHANGELOG.md`. +Please read [CONTRIBUTION.md](https://github.com/Prayag2/konsave/blob/master/CONTRIBUTION.md) for info about contributing. ## License This project uses GNU General Public License 3.0 diff --git a/konsave/__main__.py b/konsave/__main__.py index 8622127..156297a 100755 --- a/konsave/__main__.py +++ b/konsave/__main__.py @@ -1,30 +1,93 @@ +""" +This is the main module +""" + ## IMPORT ## import argparse -from konsave.funcs import * -from konsave.vars import VERSION +from konsave.funcs import ( + list_profiles, + save_profile, + remove_profile, + apply_profile, + export, + import_profile, + wipe, +) +from konsave.vars import VERSION, list_of_profiles, length_of_lop ## MAIN ## def main(): + """ + The main function that handles all the arguments and options + """ ## PARSER SETTINGS ## parser = argparse.ArgumentParser( - prog='Konsave', - epilog="Please report bugs at https://www.github.com/prayag2/konsave" + prog="Konsave", + epilog="Please report bugs at https://www.github.com/prayag2/konsave", ) ## ADDING ARGS ## - parser.add_argument('-l', '--list', required=False, action='store_true', help='Lists created profiles') - parser.add_argument('-s', '--save', required=False, type=str, help='Save current config as a profile', - metavar='') - parser.add_argument('-r', '--remove', required=False, type=int, help='Remove the specified profile', metavar='') - parser.add_argument('-a', '--apply', required=False, type=int, help='Apply the specified profile', metavar='') - parser.add_argument('-e', '--export-profile', required=False, type=int, - help='Export a profile and share with your friends!', metavar='') - parser.add_argument('-i', '--import-profile', required=False, type=str, help='Import a konsave file', - metavar='') - parser.add_argument('-f', '--force', required=False, action='store_true', help='Overwrite already saved profiles') - parser.add_argument('-v', '--version', required=False, action='store_true', help='Show version') - parser.add_argument('-w', '--wipe', required=False, action='store_true', help='Wipes all profiles.') + parser.add_argument( + "-l", + "--list", + required=False, + action="store_true", + help="Lists created profiles", + ) + parser.add_argument( + "-s", + "--save", + required=False, + type=str, + help="Save current config as a profile", + metavar="", + ) + parser.add_argument( + "-r", + "--remove", + required=False, + type=int, + help="Remove the specified profile", + metavar="", + ) + parser.add_argument( + "-a", + "--apply", + required=False, + type=int, + help="Apply the specified profile", + metavar="", + ) + parser.add_argument( + "-e", + "--export-profile", + required=False, + type=int, + help="Export a profile and share with your friends!", + metavar="", + ) + parser.add_argument( + "-i", + "--import-profile", + required=False, + type=str, + help="Import a konsave file", + metavar="", + ) + parser.add_argument( + "-f", + "--force", + required=False, + action="store_true", + help="Overwrite already saved profiles", + ) + parser.add_argument( + "-v", "--version", required=False, action="store_true", help="Show version" + ) + parser.add_argument( + "-w", "--wipe", required=False, action="store_true", help="Wipes all profiles." + ) ## PARSING ARGS ## args = parser.parse_args() @@ -51,5 +114,5 @@ def main(): ## CALLING MAIN ## -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/konsave/__pycache__/__main__.cpython-39.pyc b/konsave/__pycache__/__main__.cpython-39.pyc index f1c25dc589001d3f613035f2a0b21e2df5c474e3..6a10d456e3e8eeb6773368c339d3b6e4f075bf7e 100644 GIT binary patch delta 956 zcmb`GL2J}N6vs2kWRlG$*&;;{wFcB}_afdE!GofREw;tO9E_ov?Z#%3Fqv&_DXdTr z9+g}@_To{zc+{^k`UU(3qN2V@*xC=^5Z=7^e>3k*ev^C-UM+-45O@ZRkH79ceb9ds zUYI?BC^e{&qSVY0MKD{r$t`MeOfk2q%?Tykp$>Pc%X_qk^je&Iyifbwr#=s80GgeW zmj(^lAa!<3L0NcYfNE|SBlqB(w>in`2p&0M5l^xr;$=F`nK%2UkFz>*RFG%2j4M%& zvz*n+uajLi4^=1_FHglmQdRl>Nt&?dRVkzjGp^?o9q(lo8(GSEd}n>*{@SWqXq%Md z`HFe~eOa+BCozb5S-n5(p&P>~dW{5@{X_K3lP*~Q$U;W(7Q7(svXKmRBwg8Sb1xto zq{HSDI**3U*VcYV7twNa*1Y;~2pCol?s^f7%{hYcwAhkaSpbwoMw6sS;l-mQ&s$1~ z*q(A$NKlG2Dl5IRZVNQG%`bic*c6ug6%&IGE7lr9tIZyMG!rHyguZ0a2Sc&uC@k&T z<5FxfMLL!Ow^|EQ*xC;}igPxCfG8X=%7GF!^jCHzvOhnGZ$jEx`^fxBoKq1pe-QUS#!%hI$ooUA*4oW7 zxjc*DD9Vjv{UyfnXhAt~oR(X0EY3iN20MTnuwBzPRCh!*!4_G|>K~g9gFoM~3-90I tIk^Hc?^Yz7L5n5hI+R+{^;&ZYJmuc(eu!HLqS^<8Z5LhXEn+uu(O3P5GsD2MxSVi#OYz=l^Z1+ze zzybhip3xhKFD?5vr^WxO5|h!4FVaa>sUs0i>D-Ov$Etjy&vy%M4Q)h} z<(B7#tv8ms&dQ>7E1eZaJNOX64zo%&5BW{#Ht+c0o{whz5`j<#6zCt$I}ic=%V`(7 z5CFqyraOSwX*RrDhu5&a_2W2CvLcRqT-%Qp;Xzs0_pJ>_#cnNvxg00Do^IFkz9PwG f9P2K2{Rda4Qy=GLI#Ti}MOE9mKKKwYf6a$~5B8xV diff --git a/konsave/__pycache__/funcs.cpython-39.pyc b/konsave/__pycache__/funcs.cpython-39.pyc index 8745df2ea5273cb9d482657402a729f50ace679d..e9937edeb5553fdff8aa8fc97af4b4cde315a4d3 100644 GIT binary patch literal 10104 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 /dev/null 2>&1 & disown') + """ + Replaces plasmashell + """ + log("restarting kde...") + os.system("plasmashell --replace > /dev/null 2>&1 & disown") # PARSE AND SEARCH IN A CONFIG FILE @exception_handler def search_config(path, section, option): - ''' - This function will parse config files and search for specific values - ''' + """This function will parse config files and search for specific values + + Args: + path: path to a config file + section: name of the section to search in + option: name of the option to search for + + Returns: + str: the found value + """ config = configparser.ConfigParser(strict=False) config.read(path) return config[section][option] @@ -69,23 +105,17 @@ def search_config(path, section, option): # LOAD CONFIG FILE @exception_handler def load_config(): - """ - Load the yaml file which contains the files and folders to be saved - - The file should be formatted like this: - - --- - entries: - - folder name - - file name - - another file name - - another folder name + """Loads config file + Returns: + list: the names of files and folders in conf.yaml """ - default_config_path = resource_filename('konsave', 'conf.yaml') + default_config_path = resource_filename("konsave", "conf.yaml") if not os.path.exists(CONFIG_FILE): shutil.copy(default_config_path, CONFIG_FILE) - return yaml.load(resource_stream('konsave', 'conf.yaml'), Loader=yaml.FullLoader)["entries"] + return yaml.load( + resource_stream("konsave", "conf.yaml"), Loader=yaml.FullLoader + )["entries"] with open(CONFIG_FILE) as file: config = yaml.load(file, Loader=yaml.FullLoader) @@ -95,22 +125,26 @@ def load_config(): # COPY FILE/FOLDER @exception_handler def copy(source, dest): - ''' + """ This function was created because shutil.copytree gives error if the destination folder exists and the argument "dirs_exist_ok" was introduced only after python 3.8. This restricts people with python 3.7 or less from using Konsave. This function will let people with python 3.7 or less use Konsave without any issues. It uses recursion to copy files and folders from "source" to "dest" - ''' - assert (type(source) == str and type(dest) == str), "Invalid path" - assert (source != dest), "Source and destination can't be same" - assert (os.path.exists(source)), "Source path doesn't exist" - + + Args: + source: the source destination + dest: the destination to copy the file/folder to + """ + assert isinstance(source, str) and isinstance(dest, str), "Invalid path" + assert source != dest, "Source and destination can't be same" + assert os.path.exists(source), "Source path doesn't exist" + if not os.path.exists(dest): os.mkdir(dest) - + if os.path.isdir(source): - for item in os.listdir(source): + for item in os.listdir(source): source_path = os.path.join(source, item) dest_path = os.path.join(dest, item) @@ -126,136 +160,153 @@ def copy(source, dest): # LIST PROFILES @exception_handler -def list_profiles(list_of_profiles, length_of_lop): - ''' - Lists all the created profiles - ''' +def list_profiles(profile_list, profile_count): + """Lists all the created profiles + + Args: + profile_list: the list of all created profiles + profile_count: number of profiles created + """ # assert - assert (os.path.exists(PROFILES_DIR) and length_of_lop != 0), "No profile found." + assert os.path.exists(PROFILES_DIR) and profile_count != 0, "No profile found." # run print("Konsave profiles:") - print(f"ID\tNAME") - for i, item in enumerate(list_of_profiles): + print("ID\tNAME") + for i, item in enumerate(profile_list): print(f"{i + 1}\t{item}") # SAVE PROFILE @exception_handler -def save_profile(name, list_of_profiles, force=False): - ''' - Saves necessary config files in ~/.config/konsave/profiles/ - ''' +def save_profile(name, profile_list, force=False): + """Saves necessary config files in ~/.config/konsave/profiles/ + + Args: + name: name of the profile + profile_list: the list of all created profiles + force: force overwrite already created profile, optional + """ # assert - assert (name not in list_of_profiles or force), "Profile with this name already exists" + assert name not in profile_list or force, "Profile with this name already exists" # run log("saving profile...") - PROFILE_DIR = os.path.join(PROFILES_DIR, name) - mkdir(PROFILE_DIR) + profile_dir = os.path.join(PROFILES_DIR, name) + mkdir(profile_dir) entries = load_config() for entry in entries: source = os.path.join(CONFIG_DIR, entry) if os.path.exists(source): if os.path.isdir(source): - copy(source, os.path.join(PROFILE_DIR, entry)) + copy(source, os.path.join(profile_dir, entry)) else: - shutil.copy(source, PROFILE_DIR) + shutil.copy(source, profile_dir) - log('Profile saved successfully!') + log("Profile saved successfully!") # APPLY PROFILE @exception_handler -def apply_profile(id, list_of_profiles, length_of_lop): - ''' - Applies profile of the given id - ''' +def apply_profile(profile_id, profile_list, profile_count): + """Applies profile of the given id + + Args: + profile_id: id of the profile to be applied + profile_list: the list of all created profiles + profile_count: number of profiles created + """ # Lowering id by 1 - id -= 1 + profile_id -= 1 # assert - assert (length_of_lop != 0), "No profile saved yet." - assert (id in range(length_of_lop)), "Profile not found :(" + assert profile_count != 0, "No profile saved yet." + assert profile_id in range(profile_count), "Profile not found :(" # run - name = list_of_profiles[id] - PROFILE_DIR = os.path.join(PROFILES_DIR, name) + name = profile_list[profile_id] + profile_dir = os.path.join(PROFILES_DIR, name) - log('copying files...') + log("copying files...") - copy(PROFILE_DIR, CONFIG_DIR) + copy(profile_dir, CONFIG_DIR) restart_kde() - log("Profile applied successfully! Please log-out and log-in to see the changes completely!") + log( + "Profile applied successfully! Please log-out and log-in to see the changes completely!" + ) # REMOVE PROFILE @exception_handler -def remove_profile(id, list_of_profiles, length_of_lop): - ''' - Removes the specified profile - ''' +def remove_profile(profile_id, profile_list, profile_count): + """Removes the specified profile - # Lowering id by 1 - id -= 1 + Args: + profile_id: id of the profile to be removed + profile_list: the list of all created profiles + profile_count: number of profiles created + """ + + # Lowering profile_id by 1 + profile_id -= 1 # assert - assert (id in range(length_of_lop)), "Profile not found." + assert profile_id in range(profile_count), "Profile not found." # run - item = list_of_profiles[id] - log('removing profile...') + item = profile_list[profile_id] + log("removing profile...") shutil.rmtree(os.path.join(PROFILES_DIR, item)) - log('removed profile successfully') + log("removed profile successfully") # EXPORT PROFILE @exception_handler -def export(id, list_of_profiles, length_of_lop): - ''' - It will export the specified profile as a ".knsv" file in the home directory - ''' +def export(profile_id, profile_list, profile_count): + """It will export the specified profile as a ".knsv" file in the home directory + + Args: + profile_id: id of the profile to be exported + profile_list: the list of all created profiles + profile_count: number of profiles created + """ - # lowering id by 1 - id -= 1 + # lowering profile_id by 1 + profile_id -= 1 # assert - assert (id in range(length_of_lop)), "Profile not found." + assert profile_id in range(profile_count), "Profile not found." # run - item = list_of_profiles[id] - PROFILE_DIR = os.path.join(PROFILES_DIR, item) - EXPORT_PATH = os.path.join(HOME, item) + item = profile_list[profile_id] + profile_dir = os.path.join(PROFILES_DIR, item) + export_path = os.path.join(HOME, item) - if os.path.exists(EXPORT_PATH): - rand_str = list('abcdefg12345') + if os.path.exists(export_path): + rand_str = list("abcdefg12345") shuffle(rand_str) - EXPORT_PATH = EXPORT_PATH + ''.join(rand_str) + export_path = export_path + "".join(rand_str) # compressing the files as zip log("Exporting profile. It might take a minute or two...") - CONFIG_EXPORT_PATH = mkdir(os.path.join(EXPORT_PATH, "config")) - PLASMA_EXPORT_PATH = mkdir(os.path.join(EXPORT_PATH, "plasma")) - CURSOR_EXPORT_PATH = mkdir(os.path.join(EXPORT_PATH, "cursor")) - ICON_EXPORT_PATH = mkdir(os.path.join(EXPORT_PATH, "icons")) - # VARIABLES - KDE_GLOBALS = os.path.join(PROFILE_DIR, 'kdeglobals') + config_export_path = mkdir(os.path.join(export_path, "config")) + plasma_export_path = mkdir(os.path.join(export_path, "plasma")) + cursor_export_path = mkdir(os.path.join(export_path, "cursor")) + icon_export_path = mkdir(os.path.join(export_path, "icons")) - icon = search_config(KDE_GLOBALS, 'Icons', 'Theme') - cursor = search_config(os.path.join(PROFILE_DIR, 'kcminputrc'), 'Mouse', 'cursorTheme') + kde_globals = os.path.join(profile_dir, "kdeglobals") - PLASMA_DIR = os.path.join(HOME, '.local/share/plasma') - LOCAL_ICON_DIR = os.path.join(HOME, '.local/share/icons', icon) - USR_ICON_DIR = os.path.join('/usr/share/icons', icon) - LOCAL_CURSOR_DIR = os.path.join(HOME, '.icons', cursor) - USR_CURSOR_DIR = os.path.join('/usr/share/icons', cursor) + icon = search_config(kde_globals, "Icons", "Theme") + cursor = search_config( + os.path.join(profile_dir, "kcminputrc"), "Mouse", "cursorTheme" + ) def check_path_and_copy(path1, path2, export_location, name): if os.path.exists(path1): @@ -265,76 +316,88 @@ def check_path_and_copy(path1, path2, export_location, name): else: log(f"Couldn't find {path1} or {path2}. Skipping...") + if icon is not None: + local_icon_dir = os.path.join(HOME, ".local/share/icons", icon) + usr_icon_dir = os.path.join("/usr/share/icons", icon) + log("Exporting icon theme") + check_path_and_copy(local_icon_dir, usr_icon_dir, icon_export_path, icon) - log("Exporting icon theme") - check_path_and_copy(LOCAL_ICON_DIR, USR_ICON_DIR, ICON_EXPORT_PATH, icon) + if cursor is not None: + local_cursor_dir = os.path.join(HOME, ".icons", cursor) + usr_cursor_dir = os.path.join("/usr/share/icons", cursor) + log("Exporting cursors...") + check_path_and_copy( + local_cursor_dir, usr_cursor_dir, cursor_export_path, cursor + ) - log("Exporting cursors...") - check_path_and_copy(LOCAL_CURSOR_DIR, USR_CURSOR_DIR, CURSOR_EXPORT_PATH, cursor) + plasma_dir = os.path.join(HOME, ".local/share/plasma") log("Exporting plasma files") - copy(PLASMA_DIR, PLASMA_EXPORT_PATH) + copy(plasma_dir, plasma_export_path) log("Exporting config files") - copy(PROFILE_DIR, CONFIG_EXPORT_PATH) + copy(profile_dir, config_export_path) log("Creating archive") - shutil.make_archive(EXPORT_PATH, 'zip', EXPORT_PATH) + shutil.make_archive(export_path, "zip", export_path) - shutil.rmtree(EXPORT_PATH) - shutil.move(EXPORT_PATH + '.zip', EXPORT_PATH + export_extension) + shutil.rmtree(export_path) + shutil.move(export_path + ".zip", export_path + EXPORT_EXTENSION) - log(f"Successfully exported to {EXPORT_PATH}{export_extension}") + log(f"Successfully exported to {export_path}{EXPORT_EXTENSION}") # IMPORT PROFILE @exception_handler def import_profile(path): - ''' - This will import an exported profile - ''' + """This will import an exported profile + + Args: + path: path of the `.knsv` file + """ # assert - assert (is_zipfile(path) and path[-5:] == export_extension), "Not a valid konsave file" + assert ( + is_zipfile(path) and path[-5:] == EXPORT_EXTENSION + ), "Not a valid konsave file" item = os.path.basename(path)[:-5] - assert (not os.path.exists(os.path.join(PROFILES_DIR, item))), "A profile with this name already exists" + assert not os.path.exists( + os.path.join(PROFILES_DIR, item) + ), "A profile with this name already exists" # run - log("Importing profile. It might take a minute or two...") - item = os.path.basename(path).replace(export_extension, '') - - TEMP_PATH = os.path.join(KONSAVE_DIR, 'temp', item) + item = os.path.basename(path).replace(EXPORT_EXTENSION, "") - with ZipFile(path, 'r') as zip: - zip.extractall(TEMP_PATH) + temp_path = os.path.join(KONSAVE_DIR, "temp", item) - CONFIG_IMPORT_PATH = os.path.join(TEMP_PATH, 'config') - PLASMA_IMPORT_PATH = os.path.join(TEMP_PATH, 'plasma') - ICON_IMPORT_PATH = os.path.join(TEMP_PATH, 'icons') - CURSOR_IMPORT_PATH = os.path.join(TEMP_PATH, 'cursor') + with ZipFile(path, "r") as zip_file: + zip_file.extractall(temp_path) - PLASMA_DIR = os.path.join(HOME, '.local/share/plasma') - LOCAL_ICON_DIR = os.path.join(HOME, '.local/share/icons') - LOCAL_CURSOR_DIR = os.path.join(HOME, '.icons') - PROFILE_DIR = os.path.join(PROFILES_DIR, item) + config_import_path = os.path.join(temp_path, "config") + plasma_import_path = os.path.join(temp_path, "plasma") + icon_import_path = os.path.join(temp_path, "icons") + cursor_import_path = os.path.join(temp_path, "cursor") - check_mark = u'\u2713' + plasma_dir = os.path.join(HOME, ".local/share/plasma") + local_icon_dir = os.path.join(HOME, ".local/share/icons") + local_cursor_dir = os.path.join(HOME, ".icons") + profile_dir = os.path.join(PROFILES_DIR, item) log("Importing config files") - copy(CONFIG_IMPORT_PATH, PROFILE_DIR) + copy(config_import_path, profile_dir) log("Importing plasma files") - copy(PLASMA_IMPORT_PATH, PLASMA_DIR) + copy(plasma_import_path, plasma_dir) log("Importing icons") - copy(ICON_IMPORT_PATH, LOCAL_ICON_DIR) + copy(icon_import_path, local_icon_dir) log("Importing cursors") - copy(CURSOR_IMPORT_PATH, LOCAL_CURSOR_DIR) + copy(cursor_import_path, local_cursor_dir) - shutil.rmtree(TEMP_PATH) + shutil.rmtree(temp_path) log("Profile successfully imported!") @@ -342,12 +405,12 @@ def import_profile(path): # WIPE @exception_handler def wipe(): - ''' + """ This function will wipe all profiles - ''' - confirm = input("This will wipe all your profiles. Enter \"WIPE\" Tto continue: ") - if confirm == 'WIPE': + """ + confirm = input('This will wipe all your profiles. Enter "WIPE" Tto continue: ') + if confirm == "WIPE": shutil.rmtree(PROFILES_DIR) log("Removed all profiles!") else: - log("Aborting...") \ No newline at end of file + log("Aborting...") diff --git a/konsave/vars.py b/konsave/vars.py index d71bf54..e575c69 100644 --- a/konsave/vars.py +++ b/konsave/vars.py @@ -1,15 +1,18 @@ +""" +This module contains all the variables for konsave +""" ## IMPORT ## import os ## GLOBAL VARS ## -HOME = os.path.expandvars('$HOME') -CONFIG_DIR = os.path.join(HOME, '.config') -KONSAVE_DIR = os.path.join(CONFIG_DIR, 'konsave') -PROFILES_DIR = os.path.join(KONSAVE_DIR, 'profiles') +HOME = os.path.expandvars("$HOME") +CONFIG_DIR = os.path.join(HOME, ".config") +KONSAVE_DIR = os.path.join(CONFIG_DIR, "konsave") +PROFILES_DIR = os.path.join(KONSAVE_DIR, "profiles") CONFIG_FILE = os.path.join(KONSAVE_DIR, "conf.yaml") -export_extension = '.knsv' +EXPORT_EXTENSION = ".knsv" # Create PROFILES_DIR if it doesn't exist if not os.path.exists(PROFILES_DIR): @@ -19,5 +22,4 @@ length_of_lop = len(list_of_profiles) # Current Version -VERSION = "1.1.5" - +VERSION = "1.1.6" diff --git a/setup.py b/setup.py index a57b1f8..e513a21 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,12 @@ +""" +Setup module +""" from setuptools import setup, find_packages def read_desc(): + """Reads the README + """ with open('README.md', 'r') as desc: return desc.read() From 9ae2bddee937f5555f54f4772c21b8d3a2d14eaa Mon Sep 17 00:00:00 2001 From: Prayag Jain Date: Thu, 11 Mar 2021 13:27:53 +0530 Subject: [PATCH 2/2] Updated readme --- .gitignore | 3 ++- CHANGELOG.md | 1 + README.md | 15 +++++++++++---- konsave/__pycache__/__main__.cpython-39.pyc | Bin 2056 -> 2056 bytes konsave/__pycache__/funcs.cpython-39.pyc | Bin 10104 -> 10108 bytes konsave/__pycache__/vars.cpython-39.pyc | Bin 613 -> 613 bytes 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index a81c8ee..2fb7440 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ # Byte-compiled / optimized / DLL files -__pycache__/ +__pycache__ *.py[cod] *$py.class + # C extensions *.so diff --git a/CHANGELOG.md b/CHANGELOG.md index 1628d0d..f1bf152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changes - Changed code style to [PEP8](https://www.python.org/dev/peps/pep-0008/) - Changed docstring style to [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) +- Updated README ## Additions - Added a CONTRIBUTIONS.md diff --git a/README.md b/README.md index aae0e2b..fb28d84 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ -# Konsave (Save Plasma Customization) -A CLI program that will let you save and apply your KDE Plasma customizations with just one command! Also, it has a "K" in the name :D +

Konsave (Save Plasma Customization)

+

A CLI program that will let you save and apply your KDE Plasma customizations with just one command! Also, it has a "K" in the name :D

--- -![ezgif-7-e0c7257f0aef](https://user-images.githubusercontent.com/39525869/109611033-a6732c80-7b53-11eb-9ece-ffd9cef49047.gif) +

+ +

--- ## Dependencies @@ -11,7 +13,7 @@ A CLI program that will let you save and apply your KDE Plasma customizations wi `pip install pyyaml` ## Installation -Install from PyPI +Install from PyPI `python -m pip install konsave` ## Usage @@ -36,6 +38,11 @@ You may need to log out and log in to see all the changes. `konsave -v` or `konsave --version` ### Wipe all profiles `konsave -w` or `konsave --wipe` + +## Uninstall Konsave +To uninstall konsave, run the following: +`python -m pip uninstall konsave` + ## Contribution Please read [CONTRIBUTION.md](https://github.com/Prayag2/konsave/blob/master/CONTRIBUTION.md) for info about contributing. diff --git a/konsave/__pycache__/__main__.cpython-39.pyc b/konsave/__pycache__/__main__.cpython-39.pyc index 6a10d456e3e8eeb6773368c339d3b6e4f075bf7e..c53942780df857fb5f07593d6f950fbfaafff1a9 100644 GIT binary patch delta 20 ZcmeAW=n&veKVJT`LwWd{H+_yv6c diff --git a/konsave/__pycache__/funcs.cpython-39.pyc b/konsave/__pycache__/funcs.cpython-39.pyc index e9937edeb5553fdff8aa8fc97af4b4cde315a4d3..d991af0c0dee0917b2ad990ec77e5282246ae47d 100644 GIT binary patch delta 62 zcmez2_s5Snk(ZZ?0SMScJQE}~^8S)%44KTKV9&