I'm new to programming. I wrote this following code in Python. It's a simple script that locks and unlocks a folder (basic functionality of a folder-lock) with a password.
I hope someone could suggest me to improve the code and make it shorter. Currently, it can lock single folder; however, I wanna make it multi-threading so that it can work on more than one directory. Any suggestion or advice in this regard will be highly appreciated.
r""" FolderLockV1.py: A simple python script to lock a folder with a password """
import os
import sys
import stat
import shutil
import ctypes
import hashlib
__author__ = 'AJ'
__version__ = '1.0.0'
TEMP_LOCATION = os.path.join(os.path.expanduser('~'), 'Desktop', 'TEMP_FOLDER') # dir path where target will be hidden
PASS_FILE = os.path.join(os.path.expanduser('~'), 'Desktop/TEMP_FOLDER', 'password.txt') # password file
FILE_PATH_CURRENT_FOLDER_TEXT_FILE = os.path.join(os.path.expanduser('~'), 'Desktop/TEMP_FOLDER', 'current_folder.txt')
def hash_data(data):
""" A function that returns hashed data, here sha512 hashing has been implemented """
encrypt_data = data.encode('utf-8')
hashed = hashlib.sha512(encrypt_data).hexdigest()
return hashed
def current_fold_path_fetcher():
""" Returns folder_path input from the user """
while True:
x = input('Path to the folder you wish to lock\n>>> ')
if os.path.exists(x):
return x
print('Not a valid folder path')
def store_retrieve_info(file_path, **kwargs):
""" A modified function for writing and reading texts to/from text files """
if len(kwargs) < 1:
print('Need to provide kwarg(s)')
if 'text' in kwargs:
with open(file_path, 'w') as f:
f.write(kwargs['text'])
if 'read' in kwargs:
if kwargs['read'] is True:
with open(file_path, 'r') as f:
x = f.read()
return x
def folder_lock():
""" One of the core functions, it basically locks(rather moves) the folder to a secret path """
fold_path = current_fold_path_fetcher()
global FILE_PATH_CURRENT_FOLDER_TEXT_FILE
store_retrieve_info(FILE_PATH_CURRENT_FOLDER_TEXT_FILE, text=fold_path) # writes current dir path to txt file
pass_word = input('password\n>>> ')
pass_word_hashed = hash_data(pass_word) # inputted password is being hashed
global PASS_FILE
store_retrieve_info(PASS_FILE, text=pass_word_hashed) # writes hashed password in a text file
global TEMP_LOCATION
shutil.move(fold_path, TEMP_LOCATION) # moves current dir to the temp dir to make it visualize as locked
print('Folder Locked')
def folder_unlock():
""" The other core function that unlocks the target dir """
global PASS_FILE
global TEMP_LOCATION
global FILE_PATH_CURRENT_FOLDER_TEXT_FILE
current_folder_path_from_file = str(store_retrieve_info(FILE_PATH_CURRENT_FOLDER_TEXT_FILE, read=True)) # reads
# current folder path from stored txt file
current_folder_in_temp = TEMP_LOCATION + '\\' + current_folder_path_from_file.rsplit('\\', 1)[-1] # recreates the
# old dir path where the hidden dir was initially located
in_pass = input('Password\n>>> ')
in_pass_hashed = hash_data(in_pass) # inputted password by the user is being hashed for verification
read_password = str(store_retrieve_info(PASS_FILE, read=True)) # loads the saved password in the memory
if in_pass_hashed == read_password: # matches inputted password with stored one
shutil.move(current_folder_in_temp, current_folder_path_from_file) # moves target dir to it's original path
print('fokder unlocked')
remove_file() # removes the temp folder and it's contents
else:
print('incorrect pass')
def initial_checkups():
""" An initial checkup function that makes sure that a temp dir exists """
global TEMP_LOCATION
if os.path.exists(TEMP_LOCATION):
pass
else:
os.makedirs(TEMP_LOCATION)
ctypes.windll.kernel32.SetFileAttributesW(TEMP_LOCATION, 0x02) # changes file-mode to hidden, 0x01 value to
# make it visible
def remove_file():
""" A supporting function that removes temp dir and it's contents """
# There are three options to make it happen, only option 2 has been chosen
# global PASS_FILE
# global FILE_PATH_CURRENT_FOLDER_TEXT_FILE
global TEMP_LOCATION
# option 1: remove each file then changing file-mode of the folder, then remove dir
# os.remove(PASS_FILE)
# os.remove(FILE_PATH_CURRENT_FOLDER_TEXT_FILE)
# os.chmod(TEMP_LOCATION, stat.S_IWRITE)
# os.rmdir(TEMP_LOCATION)
# option 2: change file-mode and then remove dir
os.chmod(TEMP_LOCATION, stat.S_IWRITE) # changes file attribute to writable i.e., make it not readonly dir
shutil.rmtree(TEMP_LOCATION) # removes temp dir
# option 3: remove dir and it's contents without changing any file-mode, more direct approach
# os.system('rmdir /S /Q "{}"'.format(TEMP_LOCATION))
def get_choice():
""" A function that return user choices """
while True:
choice_input = input('Press "L" to lock folder\nPress "U" to unlock folder\n'
'Press "Q" to quit application').lower()
if choice_input in {'l', 'u', 'q'}:
return choice_input
print('Wrong option selected')
def main():
print('Welcome to FolderLocker V0.1 by AJ\n')
initial_checkups() # creates temp dir
choice_made = get_choice()
if choice_made == 'l':
folder_lock()
if choice_made == 'u':
try:
folder_unlock()
except FileNotFoundError:
print('You NEED TO LOCK a folder before you try unlocking it!!!')
os.system('pause') # allows user to read console message
else:
sys.exit(0)
if __name__ == '__main__':
main()