feat: add Python linting support with pylint and black
This commit is contained in:
@@ -10,23 +10,26 @@ import glob
|
||||
sys.path.append(os.path.join(os.path.expanduser("~/.dotfiles"), "bin"))
|
||||
from helpers.functions import printfe, run_command
|
||||
|
||||
|
||||
def get_password():
|
||||
"""Get password from 1Password"""
|
||||
op_cmd = "op"
|
||||
|
||||
|
||||
# Try to get the password
|
||||
success, output = run_command([op_cmd, "read", "op://j7nmhqlsjmp2r6umly5t75hzb4/Dotfiles Secrets/password"])
|
||||
|
||||
success, output = run_command(
|
||||
[op_cmd, "read", "op://j7nmhqlsjmp2r6umly5t75hzb4/Dotfiles Secrets/password"]
|
||||
)
|
||||
|
||||
if not success:
|
||||
printfe("red", "Failed to fetch password from 1Password.")
|
||||
return None
|
||||
|
||||
|
||||
# Check if we need to use a token
|
||||
if "use 'op item get" in output:
|
||||
# Extract the token
|
||||
token = output.split("use 'op item get ")[1].split(" --")[0]
|
||||
printfe("cyan", f"Got fetch token: {token}")
|
||||
|
||||
|
||||
# Use the token to get the actual password
|
||||
success, password = run_command(
|
||||
[op_cmd, "item", "get", token, "--reveal", "--fields", "password"]
|
||||
@@ -37,20 +40,23 @@ def get_password():
|
||||
else:
|
||||
# We already got the password
|
||||
return output
|
||||
|
||||
|
||||
|
||||
def prompt_for_password():
|
||||
"""Ask for password manually"""
|
||||
import getpass
|
||||
|
||||
printfe("cyan", "Enter the password manually: ")
|
||||
password = getpass.getpass("")
|
||||
|
||||
|
||||
if not password:
|
||||
printfe("red", "Password cannot be empty.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
printfe("green", "Password entered successfully.")
|
||||
return password
|
||||
|
||||
|
||||
def calculate_checksum(file_path):
|
||||
"""Calculate SHA256 checksum of a file"""
|
||||
sha256_hash = hashlib.sha256()
|
||||
@@ -59,55 +65,66 @@ def calculate_checksum(file_path):
|
||||
sha256_hash.update(byte_block)
|
||||
return sha256_hash.hexdigest()
|
||||
|
||||
|
||||
def encrypt_folder(folder_path, password):
|
||||
"""Recursively encrypt files in a folder"""
|
||||
for item in glob.glob(os.path.join(folder_path, "*")):
|
||||
# Skip .gpg and .sha256 files
|
||||
if item.endswith(".gpg") or item.endswith(".sha256"):
|
||||
continue
|
||||
|
||||
|
||||
# Handle directories recursively
|
||||
if os.path.isdir(item):
|
||||
encrypt_folder(item, password)
|
||||
continue
|
||||
|
||||
|
||||
# Calculate current checksum
|
||||
current_checksum = calculate_checksum(item)
|
||||
checksum_file = f"{item}.sha256"
|
||||
|
||||
|
||||
# Check if file changed since last encryption
|
||||
if os.path.exists(checksum_file):
|
||||
with open(checksum_file, 'r') as f:
|
||||
with open(checksum_file, "r") as f:
|
||||
previous_checksum = f.read().strip()
|
||||
|
||||
|
||||
if current_checksum == previous_checksum:
|
||||
continue
|
||||
|
||||
|
||||
# Remove existing .gpg file if it exists
|
||||
gpg_file = f"{item}.gpg"
|
||||
if os.path.exists(gpg_file):
|
||||
os.remove(gpg_file)
|
||||
|
||||
|
||||
# Encrypt the file
|
||||
printfe("cyan", f"Encrypting {item}...")
|
||||
cmd = [
|
||||
"gpg", "--quiet", "--batch", "--yes", "--symmetric",
|
||||
"--cipher-algo", "AES256", "--armor",
|
||||
"--passphrase", password,
|
||||
"--output", gpg_file, item
|
||||
"gpg",
|
||||
"--quiet",
|
||||
"--batch",
|
||||
"--yes",
|
||||
"--symmetric",
|
||||
"--cipher-algo",
|
||||
"AES256",
|
||||
"--armor",
|
||||
"--passphrase",
|
||||
password,
|
||||
"--output",
|
||||
gpg_file,
|
||||
item,
|
||||
]
|
||||
|
||||
|
||||
success, _ = run_command(cmd)
|
||||
if success:
|
||||
printfe("cyan", f"Staging {item} for commit...")
|
||||
run_command(["git", "add", "-f", gpg_file])
|
||||
|
||||
|
||||
# Update checksum file
|
||||
with open(checksum_file, 'w') as f:
|
||||
with open(checksum_file, "w") as f:
|
||||
f.write(current_checksum)
|
||||
else:
|
||||
printfe("red", f"Failed to encrypt {item}")
|
||||
|
||||
|
||||
def decrypt_folder(folder_path, password):
|
||||
"""Recursively decrypt files in a folder"""
|
||||
for item in glob.glob(os.path.join(folder_path, "*")):
|
||||
@@ -115,36 +132,44 @@ def decrypt_folder(folder_path, password):
|
||||
if item.endswith(".gpg"):
|
||||
output_file = item[:-4] # Remove .gpg extension
|
||||
printfe("cyan", f"Decrypting {item}...")
|
||||
|
||||
|
||||
cmd = [
|
||||
"gpg", "--quiet", "--batch", "--yes", "--decrypt",
|
||||
"--passphrase", password,
|
||||
"--output", output_file, item
|
||||
"gpg",
|
||||
"--quiet",
|
||||
"--batch",
|
||||
"--yes",
|
||||
"--decrypt",
|
||||
"--passphrase",
|
||||
password,
|
||||
"--output",
|
||||
output_file,
|
||||
item,
|
||||
]
|
||||
|
||||
|
||||
success, _ = run_command(cmd)
|
||||
if not success:
|
||||
printfe("red", f"Failed to decrypt {item}")
|
||||
|
||||
|
||||
# Process directories recursively
|
||||
elif os.path.isdir(item):
|
||||
printfe("cyan", f"Decrypting folder {item}...")
|
||||
decrypt_folder(item, password)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2 or sys.argv[1] not in ["encrypt", "decrypt"]:
|
||||
printfe("red", "Usage: secrets.py [encrypt|decrypt]")
|
||||
return 1
|
||||
|
||||
|
||||
# Get the dotfiles path
|
||||
dotfiles_path = os.environ.get("DOTFILES_PATH", os.path.expanduser("~/.dotfiles"))
|
||||
secrets_path = os.path.join(dotfiles_path, "secrets")
|
||||
|
||||
|
||||
# Get the password
|
||||
password = get_password()
|
||||
if not password:
|
||||
password = prompt_for_password()
|
||||
|
||||
|
||||
# Perform the requested action
|
||||
if sys.argv[1] == "encrypt":
|
||||
printfe("cyan", "Encrypting secrets...")
|
||||
@@ -152,8 +177,9 @@ def main():
|
||||
else: # decrypt
|
||||
printfe("cyan", "Decrypting secrets...")
|
||||
decrypt_folder(secrets_path, password)
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
Reference in New Issue
Block a user