Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branching (multiple lists) #1

Open
rosikand opened this issue Sep 19, 2022 · 1 comment
Open

Branching (multiple lists) #1

rosikand opened this issue Sep 19, 2022 · 1 comment

Comments

@rosikand
Copy link
Owner

Below is a draft for implementing branching (control multiple lists with one script). It works similar to git branching.

"""
File: todo.py
------------------
BETA new version of Lemnos with branching. 
Simple command-line to-do list manager. See README.md for getting started 
and how to use the program. 
"""

import sys 
import os
import glob
from os.path import exists

curr_dir_path = os.path.dirname(os.path.realpath(__file__))
BASE_PATH = os.path.join(curr_dir_path, "lists") 
LIST_PATH = "grfs.txt"
LIST_FILE_PATH = os.path.join(BASE_PATH, LIST_PATH)


def show_branches():
	"""
	Note to self: didn't do indexing yet. 
	Function to show current branches stored in ./lists. 
	Activated by 'branch' or 'b'. 
	"""

	txt_files = glob.glob(BASE_PATH + '/*.txt', recursive=True)
	#txt_files.sort() 
	#idx = 0
	for file_path in txt_files:
		#idx += 1
		branch_name = file_path[file_path.rfind("/") + 1:file_path.rfind(".")]
		file = "- " + branch_name
		#file = str(idx) + ". " + branch_name
		if (branch_name + ".txt") == LIST_PATH:
			file = file + " (current branch)"
		print(file)


def current_branch():
	"""
	Show current branch name. 
	Activated by 'branch current' or 'bc'.
	"""

	txt_files = glob.glob(BASE_PATH + '/*.txt', recursive=True)
	txt_files.sort() 
	for file_path in txt_files:
		branch_name = file_path[file_path.rfind("/") + 1:file_path.rfind(".")]
		file = "- " + branch_name
		if (branch_name + ".txt") == LIST_PATH:
			print(branch_name)


def delete_branch(branch_name):
	"""
	Function to delete a branch. 
	Activated by 'branch delete' or 'bd'. 
	"""
	assert (branch_name + ".txt") != LIST_PATH, "cannot delete current branch"
	txt_files = glob.glob(BASE_PATH + '/*.txt', recursive=True)
	txt_files.sort() 
	for file_path in txt_files:
		curr_branch = file_path[file_path.rfind("/") + 1:file_path.rfind(".")]
		if branch_name == curr_branch:
			branch_path = os.path.join(BASE_PATH, branch_name + ".txt")
			if os.path.exists(branch_path):
			  	#os.remove(branch_path)
			  	subpath = os.path.join(BASE_PATH, "archived", branch_name + ".txt")
			  	if os.path.exists(subpath):
			  		subpath = os.path.join(BASE_PATH, "archived", branch_name + "1.txt")
			  	os.rename(branch_path, subpath)
			else:
			  print("The branch does not exist")
			print(f"'{branch_name}' archived successfully")
			sys.exit()

	print("Error: branch does not exist")
			


def switch_branches(branch_name):
	"""
	Function to switch branches stored in ./lists. 
	Activated by 'branch switch' or 'bs'. 
	"""

	txt_files = glob.glob(BASE_PATH + '/*.txt', recursive=True)
	txt_files.sort() 
	branch_exists = False
	for file_path in txt_files:
		file = file_path[file_path.rfind("/") + 1:file_path.rfind(".")]
		if file == branch_name:
			branch_exists = True

	if branch_exists == False:
		print("Error: branch does not exist")
		sys.exit()


	f = open(__file__, 'r')
	lines = f.readlines()
	list_path_idx = -1
	idx = 0
	for l in lines:
		l = l.strip()
		template_string = f'LIST_PATH = "{LIST_PATH}"'
		if l == template_string:
			list_path_idx = idx
			break
		idx += 1

	new_string = branch_name + '.txt'
	lines[list_path_idx] = f'LIST_PATH = "{new_string}"' + '\n'

	with open(__file__, "w") as f:
	    contents = "".join(lines)
	    f.write(contents)

	print(f"Switched to branch '{branch_name}'")


def new_branch(branch_name):
	"""
	Function to make a new branch. 
	Activated by "branch new" or "bn". 
	"""

	path_string = branch_name + ".txt"
	new_path = os.path.join(BASE_PATH, path_string)
	assert not exists(new_path), "branch already exists"
	f = open(new_path, "x")
	print(f"'{branch_name}' branch created")
	switch_branches(branch_name)


def length(file_obj):
	"""
	Function that takes in the file object 
	(pointing to list.txt) and returns the number of
	items in the list. 
	"""
	count = 0

	for line in file_obj:
		count += 1 

	return count


def add(item_string):
	"""
	Function that appends the item based on what the 
	user specified as a command line argument to list.txt. 
	"""
	curr_num_items = length(open(LIST_FILE_PATH))
	curr_index = curr_num_items + 1
	og_string = item_string  # for printing purposes 
	item_string = str(curr_index) + ". " + item_string + '\n'
	file = open(LIST_FILE_PATH, "a")
	file.write(item_string)
	file.close()

	print('Added "' + og_string + '" to the to-do list.') 


def show():
	"""
	Function that prints out the list. It also displays 
	the number of items in the list. 
	"""

	file = open(LIST_FILE_PATH)
	branch_str = LIST_PATH[:LIST_PATH.rfind(".")]
	for line in file:
		print(line, end='')  # use end to avoid printing \n 

	

	print(f"Number of items (branch: {branch_str}):", length(open(LIST_FILE_PATH)))


def search(query):
	"""
	Function that searches the list for the query. Looks 
	for exact match in the list. If query is not found, 
	it prints nothing.   
	"""

	file = open(LIST_FILE_PATH)

	for line in file:
		line_list = line.split()
		for elem in line_list:
			if str(query) == str(elem):
				print(line, end = '')

	
def show_priority():
	"""
	Function that prints out prioritized items in the list. 
	It also displays the number of prioritized items in the 
	list. 
	"""

	file = open(LIST_FILE_PATH)
	count = 0 

	for line in file:
		if "*" in line:
			count += 1
			print(line, end='')  # use end to avoid printing \n 

	print("Number of prioritized items:", count)


def make_prioritized(idx):
	"""
	Function that prioritizes the element at idx. 
	"""

	# store list of lines to use later (since we will overwrite these lines) 
	temp_file_obj = open(LIST_FILE_PATH, "r") 
	line_list = temp_file_obj.readlines()
	temp_file_obj.close()

	updated_list = open(LIST_FILE_PATH, "w") 
	i = 1
	for line in line_list:
		if i == idx:
			dot_idx = line.find(".")
			line = line[:dot_idx + 1] + " *" + line[dot_idx + 2:]

		updated_list.write(line)
		i += 1

	updated_list.close()


def unprioritize(idx):
	"""
	Function that un-prioritizes the element at idx. 
	"""

	# store list of lines to use later (since we will overwrite these lines) 
	temp_file_obj = open(LIST_FILE_PATH, "r") 
	line_list = temp_file_obj.readlines()
	temp_file_obj.close()

	updated_list = open(LIST_FILE_PATH, "w") 
	i = 1
	for line in line_list:
		if i == idx:
			line = line.replace("*", "")

		updated_list.write(line)
		i += 1

	updated_list.close()
	

def complete(idx):
	"""
	Function that completes (deletes) the line (item) at the 
	specified index from the list. 
	"""

	# store list of lines to use later (since we will overwrite these lines) 
	temp_file_obj = open(LIST_FILE_PATH, "r") 
	line_list = temp_file_obj.readlines()
	temp_file_obj.close()
	

	updated_list = open(LIST_FILE_PATH, "w") 
	curr_idx = 1
	line_count = 0  # num lines appended to new list 
	for line in line_list:
		if curr_idx < idx:
			updated_list.write(line)
			line_count += 1
		if curr_idx > idx:
			line_count += 1 
			dot_idx = line.find(".")
			line = str(line_count) + line[dot_idx:]
			updated_list.write(line)

		curr_idx += 1 


def erase():
	"""
	Function that erases the contents of the list. 
	"""

	file = open(LIST_FILE_PATH, "w")
	file.close() 


def main():
	user_arguments = sys.argv[1:]
	arg_count = len(user_arguments)  # num user arguments 

	# print out list if no argument was specified 
	if arg_count == 0:
		show()  # show the list 
		sys.exit() 

	# add item to list if 'add' argument is specified 
	if (user_arguments[0] == "add" or user_arguments[0] == "a") and arg_count > 1:
		add(' '.join(user_arguments[1:]))
	
	# search the list with given argument as query if 'search' argument is specified
	if (user_arguments[0] == "search" or user_arguments[0] == "s") and arg_count > 1:
		search(' '.join(user_arguments[1:]))

	# print out list if 'show' argument is specified
	if user_arguments[0] == "show":
		show()
	
	# print out prioritized items from list 
	if (user_arguments[0] == "priority" or user_arguments[0] == "p") and arg_count == 1:
		show_priority()

	# prioritize element 
	if (user_arguments[0] == "prioritize" or user_arguments[0] == "p") and arg_count == 2:
		specified_idx = int(user_arguments[1]) 
		if specified_idx > length(open(LIST_FILE_PATH)) or specified_idx <= 0:
			print("Item index out of bounds")
			sys.exit() 
		make_prioritized(specified_idx)

	# un-prioritize element 
	if (user_arguments[0] == "unprioritize" or user_arguments[0] == "u") and arg_count == 2:
		specified_idx = int(user_arguments[1]) 
		if specified_idx > length(open(LIST_FILE_PATH)) or specified_idx <= 0:
			print("Item index out of bounds")
			sys.exit() 
		unprioritize(specified_idx)

	# print out num items in list if 'len' argument is specified
	if user_arguments[0] == "len" or user_arguments[0] == "l":
		print("Number of items:", length(open(LIST_FILE_PATH)))

	# complete (delete) specific item from list 
	if (user_arguments[0] == "complete" or user_arguments[0] == "c") and arg_count == 2:
		specified_idx = int(user_arguments[1]) 
		if specified_idx > length(open(LIST_FILE_PATH)) or specified_idx <= 0:
			print("Item index out of bounds")
			sys.exit() 
		complete(specified_idx)

	# erase items from list 
	if user_arguments[0] == "erase" or user_arguments[0] == "e":
		erase()

	# branch runner code 
	# print out branches if 'branch' argument is specified
	if (user_arguments[0] == "branch" or user_arguments[0] == "b") and (len(user_arguments) < 2): 
		show_branches() 
	elif (user_arguments[0] == "branch new") or (user_arguments[0] == "bn"):
		# create new branch 
		assert len(user_arguments) > 1, "must provide branch name"
		new_branch(user_arguments[1])
	elif (user_arguments[0] == "branch switch") or (user_arguments[0] == "bs"):
		# switch branches
		assert len(user_arguments) > 1, "must provide branch name"
		switch_branches(user_arguments[1])
	elif (user_arguments[0] == "branch current") or (user_arguments[0] == "bc"):
		# get current branch 
		current_branch()
	elif (user_arguments[0] == "branch delete") or (user_arguments[0] == "bd"):
		# switch branches
		assert len(user_arguments) > 1, "must provide branch name"
		delete_branch(user_arguments[1])
	elif (len(user_arguments) > 1):
		if (user_arguments[0] == "branch") and (user_arguments[1] == "current"):
			current_branch()
		elif (user_arguments[0] == "branch") and (user_arguments[1] == "new"):
			assert len(user_arguments) > 2, "must provide branch name"
			new_branch(user_arguments[2])
		elif (user_arguments[0] == "branch") and (user_arguments[1] == "switch"):
			assert len(user_arguments) > 2, "must provide branch name"
			switch_branches(user_arguments[2])
		elif (user_arguments[0] == "branch") and (user_arguments[1] == "delete"):
			assert len(user_arguments) > 2, "must provide branch name"
			delete_branch(user_arguments[2])


if __name__ == '__main__':
    main()
@rosikand
Copy link
Owner Author

This allows you to do:

  1. List branches
(base) username@computer ~ % python3 todo.py b
- jobs
- clubs
- grfs (current branch)
- ec
- base
  1. Switch branches
(base) username@computer ~ % python3 todo.py bs base
Switched to branch 'base'

view current branch:

(base) username@computer  ~ % python3 todo.py branch current
base

You can also create and delete branches with bn (create) and bd (delete).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant