Skip to content

Commit

Permalink
v0.1.2 Introducing recursive protection
Browse files Browse the repository at this point in the history
 - introduces recursive protection
 - updates READMEs and setup.py
  • Loading branch information
alanzchen committed Feb 21, 2017
1 parent 8bfcded commit f856ec5
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 33 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The disaster could have been avoided.

`pip install rm-protection` and optionally, `alias rm="rm-p"` for your daily user and **root** (so that it works for `sudo`).

2. Protect your files using `protect`.
2. Protect your files using `protect`. If you want to protect everything inside, `protect -R`.

3. Happy rm-ing!

Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Quick Start
``pip install rm-protection``

1. Install from PyPi and make an alias for ``rm-p``.
2. Protect your files using ``protect``.
2. Protect your files using ``protect``. If you want to protect everything inside, ``protect -R``.
3. Happy rm-ing!

How does it work?
Expand Down
2 changes: 2 additions & 0 deletions rm_protection/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ class Config():
def __init__(self):
self.suffix = ".rm-protection"
self.invalid = ['.', '..', './', '../']
self.protect_prefix = 'protect: '
self.rm_prefix = 'rm-p: '
14 changes: 11 additions & 3 deletions rm_protection/protect.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
from rm_protection.config import Config


c = Config()


def pprint(msg):
global c
print(c.protect_prefix + msg)


def protect(protect_args=None):
c = Config()
global c
flags = ''
option_end = False
if not protect_args:
Expand All @@ -17,12 +25,12 @@ def protect(protect_args=None):
elif (arg.startswith("-") and not option_end):
flags = flags + arg[arg.rfind('-') + 1:]
elif arg in c.invalid:
print('protect: "." and ".." may not be protected')
pprint('"." and ".." may not be protected')
else:
path = abspath(expv(expu(arg)))
evalpath = dirname(path) + "/." + basename(path) + c.suffix
if not exists(path):
print("Warning: " + path + " does not exist")
pprint("Warning: " + path + " does not exist")
with open(evalpath, "w") as f:
question = input("Question for " + path + ": ")
answer = input("Answer: ")
Expand Down
72 changes: 45 additions & 27 deletions rm_protection/rm_p.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,44 @@


c = Config()
evaledpaths = []


def pprint(msg):
global c
print(c.rm_prefix + msg)


def ask(evalpath, parent=False):
with open(evalpath, "r") as f:
question = f.readline().rstrip("\n")
answer = f.readline().rstrip("\n")
try:
flags = f.readline().rstrip("\n")
except:
flags = ''
if parent and 'R' not in flags:
print(original_path(evalpath) + ' is protected but flag "R" is missing.')
return True
else:
print(original_path(evalpath) + ": " + question)
if input("Answer: ") == answer:
global evaledpaths
if evalpath in evaledpaths:
return True
else:
with open(evalpath, "r") as f:
question = f.readline().rstrip("\n")
answer = f.readline().rstrip("\n")
try:
flags = f.readline().rstrip("\n")
except:
flags = ''
if parent and 'R' not in flags:
pprint(original_path(evalpath) + ' is protected but flag "R" is missing')
evaledpaths.append(evalpath)
return True
else:
print("Wrong answer! " + original_path(evalpath) + " will not be removed")
print("The answer is stored in " + evalpath)
return False
if parent:
pprint('The parent directory ' + original_path(evalpath) + ' is protected')
pprint(original_path(evalpath) + ": " + question)
if input("Answer: ") == answer:
evaledpaths.append(evalpath)
return True
else:
if parent:
return False
else:
pprint("Wrong answer! " + original_path(evalpath) + " will not be removed")
pprint("The answer is stored in " + evalpath)
return False


def original_path(evalpath):
Expand All @@ -39,6 +56,7 @@ def original_path(evalpath):
else:
return basepath + '/' + filename


def ask_in(q, a):
return bool(input(q) in a)

Expand All @@ -61,20 +79,19 @@ def gen_eval(path):
return basedir + "/." + basename(path) + c.suffix


def parent_clear(file_evalpaths):
def parent_clear(file_evalpaths, path):
for filepath in file_evalpaths:
parent_eval = file_evalpaths[filepath]
if exists(parent_eval):
print('The parent directory ' + filepath + ' is protected')
result = ask(parent_eval, parent=True)
if not result:
print(filepath + ' will not be removed')
if not ask(parent_eval, parent=True):
pprint(path + ' will not be removed')
return False
return True


def rm(rm_args=None):
global c
global evaledpaths
args = ''
paths = []
evalpaths = []
Expand All @@ -91,27 +108,27 @@ def rm(rm_args=None):
file_evalpaths = gen_evalpaths(path)
evalpath = gen_eval(path)
if c.suffix in arg:
print(path + " is a protection file")
pprint(path + " is a protection file")
if ask_in(q="Do you want to remove it? (y/n) ", a="Yesyes"):
args += arg + ' '
else:
print(path + " will not be removed")
pprint(path + " will not be removed")
continue
if exists(evalpath):
if ask(evalpath):
paths.append(path)
evalpaths.append(evalpath)
else:
continue
if not parent_clear(file_evalpaths):
if not parent_clear(file_evalpaths, path):
continue
if isdir(path):
find_exec = "find " + path + " -name " + "\".*" + c.suffix + "\"" + " -print"
out, err = Popen(find_exec, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True).communicate()
for pfile in iter(out.splitlines()):
print("A protected file or directory is found inside " + path)
pprint("A protected file or directory is found inside " + path)
if not ask(pfile):
print("Terminated due to potentially dangerous action")
pprint("Terminated due to potentially dangerous action")
exit(1)
args += arg + ' '
Popen("rm " + args, shell=True).wait()
Expand All @@ -120,7 +137,8 @@ def rm(rm_args=None):
if exists(evalpath) and not exists(path):
remove_protection_files += evalpath + ' '
if remove_protection_files:
Popen("rm " + remove_protection_files, shell=True)
Popen("rm " + remove_protection_files, shell=True).wait()
evaledpaths = []


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

setup(
name="rm_protection",
version="0.1.1.1",
version="0.1.2",
license='MIT',
description="A safe alternative for \"rm\" with minimum difference.",
author='Alan Chen',
Expand Down

0 comments on commit f856ec5

Please sign in to comment.