Added the ability to search posts and manage them. Plus minor changes.

This commit is contained in:
= 2022-06-04 20:55:46 +05:30
parent d82e6479a9
commit 4812961014
1 changed files with 89 additions and 65 deletions

154
gempost
View File

@ -30,7 +30,7 @@ postDir = wdir + "postdir/" # all post files along with the archive.gmi are stor
indexFile = wdir + "postIndex" # the index is maintained in this file
editor = "nano --restricted -t"
def menuFunction(menu = []):
def menuFunction(menu = [], headerLine = "Use the arrow keys or j,k to make a selection. Press 'c' to cancel.\n"):
stdscr = curses.initscr() # initializing curses
curses.noecho()
curses.cbreak()
@ -49,7 +49,6 @@ def menuFunction(menu = []):
if (menu == []): # do nothing if list is empty
curses.endwin()
print("\nYou don't have any posts yet.")
return None
highlight, highlight_prev = 0, 0 # variable that controls which entry is selected, variable that stores its previous value
@ -87,7 +86,8 @@ def menuFunction(menu = []):
endOfPage = len(imenu)
highlight = endOfPage - 1
stdscr.addstr("Use the arrow keys or j,k to make a selection. Press 'c' to cancel.\n")
#stdscr.addstr("Use the arrow keys or j,k to make a selection. Press 'c' to cancel.\n")
stdscr.addstr(headerLine)
for sno in range(len(imenu)):
if (sno == highlight):
@ -209,28 +209,12 @@ def newpost(title, existing_content = None):
else:
modified = True # modify the function if doing this for existing file
"""
uf = input("\n1 - (DEFAULT) automatically generate filename using a random hash\n2 - enter filename manually\n-> ")
if (uf == '2'):
while True:
filename = input("\nFilename (.gmi will be added automatically): ")
if filename[-1] == '\n': # removing newline character that creeps in there due to input()
filename = filename[:-1]
if f"{filename}.gmi" in listdir(f"{wdir}postdir/"):
prYellow("This filename already exists. Please use a different filename.")
else:
break
else:
filename = sha1(str(f"{title}{random()}").encode("utf-8")).hexdigest() # generating a unique filename
"""
filename = sha1(str(f"{title}{random()}").encode("utf-8")).hexdigest() # generating a unique filename
exec(f"touch {wdir + filename}.gmi") # creating empty file
ch = input("\nAdd an ASCII Art header to your post? (define it in blogpostHeader.gmi): ([y]/n) ")
if (ch == 'n' or ch == 'N'):
pass
else:
che = input("\nAdd an ASCII Art header to your post? (define it in blogpostHeader.gmi): (y/[n]) ")
if (che == 'y' or che == 'Y'):
try:
with open(f"{wdir}blogpostHeader.gmi") as a: # checking if header for each post has been defined
postHeader = a.readlines()
@ -238,12 +222,12 @@ def newpost(title, existing_content = None):
with open(f"{wdir + filename}.gmi",'w') as f:
f.writelines(postHeader)
except FileNotFoundError:
postHeader = ""
postHeader = [""]
else:
postHeader = [""]
if modified: # add content to file using the existing_content list instead of opening editor
if (ch != 'n' or ch != 'N'):
with open(f"{wdir}blogpostHeader.gmi") as a: # loading post header
postHeader = a.readlines()
if (che != 'y' or che == 'Y'):
with open(f"{wdir+filename}.gmi", 'w') as o:
o.writelines(postHeader + existing_content)
else:
@ -279,30 +263,29 @@ def newpost(title, existing_content = None):
prGreen("\n Your post is live!") # yay?
def manage():
allposts = [] # storing all indexFile entries inside a list
with open(f"{indexFile}",'r') as i:
allposts = i.readlines()
def manage(direct = ""):
""" Posts management function. If direct is given a string filename, then that filename is selected directly. """
if (direct == ""):
with open(f"{indexFile}",'r') as i: # storing all indexFile entries inside a list
allposts = i.readlines()
#if (len(allposts) == 0): # exit function if no files in index
#return 0
postsList = []
for i in allposts: # creating a list containing titles corresponding to filenames
postsList.append([i[56:-1],i[11:51]])
postsList = []
for i in allposts: # creating a list containing titles corresponding to filenames
postsList.append([i[56:-1],i[11:51]])
menuItems = []
for i in postsList: # formatting it into a string list for the ncurses menu function
menuItems.append(f"{i[0]} | {i[1]}")
menuItems = []
for i in postsList: # formatting it into a string list for the ncurses menu function
menuItems.append(f"{i[0]} | {i[1]}")
which = menuFunction(menuItems)
which = menuFunction(menuItems)
if (which == None): # menuFunction returns None if the list supplied to it is empty
print("\nCancelled.")
return 0
if (which == None): # menuFunction returns None if the list supplied to it is empty
if (menuItems == []):
print("You don't have any posts yet.")
print("\nCancelled.")
return 0
print(f"\nYou have selected:\n\nTitle: {postsList[which][0]}\nFilename: {postsList[which][1]}.gmi")
print(f"\nYou have selected:\n\nTITLE: {postsList[which][0]}\nFILENAME: {postsList[which][1]}.gmi")
try:
mode = int(input("\nSELECT MODE:\n1 - EDIT\n2 - DELETE\n3 - CANCEL\n-> ")) # what does the user want to do with the selection?
@ -311,34 +294,45 @@ def manage():
return 0
if (mode == 1): # if mode is EDIT, open editor with the post file
print(f'\nEditing "{postsList[which][0]}" ...')
exec(f"{editor} {postDir}{postsList[which][1]}.gmi")
prGreen("Post updated.")
if (direct == ""):
print(f'\nEditing "{postsList[which][0]}" ...')
exec(f"{editor} {postDir}{postsList[which][1]}.gmi")
else:
print(f'\nEditing {direct}.gmi')
exec(f"{editor} {postDir}{direct}.gmi")
prGreen("\nPost updated.")
elif (mode == 2): # for DELETE mode, first delete post file, delete its reference from {wdir}postIndex, and rebuild the {wdir}posts.gmi and {postDir}archive.gmi files
exec(f"mv {postDir}{postsList[which][1]}.gmi {wdir}trash/")
print(f"\nfile moved to trash")
exec(f"sed -i '/{postsList[which][1]}.gmi/d' {indexFile}")
print(f"postIndex updated")
if (direct == ""):
exec(f"mv {postDir}{postsList[which][1]}.gmi {wdir}trash/")
exec(f"sed -i '/{postsList[which][1]}.gmi/d' {indexFile}")
else:
exec(f"mv {postDir}{direct}.gmi {wdir}trash/")
exec(f"sed -i '/{direct}.gmi/d' {indexFile}")
rebuildReferences(None, None, "delete")
print(f"\nfile moved to trash")
print(f"postIndex updated")
print("rebuilt posts.gmi, archive.gmi")
prGreen("All done.")
elif (mode == 3):
print("\nCancelled.")
else:
pass
# information strings
helpText = f"""
helpText = """
gempost (v0.6) - *experimental* gemlog manager for tilde.team
Available arguments:
post - create a new post
Usage:
post (without arguments) Write a blog post from scratch.
post [path to file without braces] Post from .gmi file. First line will be used as heading.
post (without arguments) Write a blog post from scratch
post [path to file] Post from .gmi file, first line will be used as heading
manage - edit or delete your posts
search [search term] - Search your post headings for a search term and manage just those posts
purge - premanently delete the files in trash/
init - set up your public_gemini/ directory for gempost
reset - delete all posts and re-initialize public_gemini/
@ -429,23 +423,19 @@ elif (arg == "qs"):
elif (arg == "post"):
checkInit()
if (len(argv) == 3): # checking if more than 1 arg (except python) to see if source file has been supplied
if (len(argv) >= 3): # checking if more than 1 arg (except python) to see if source file has been supplied
filePath = argv[2] # storing that file's path in a var
print(f"Using file {filePath}") # tell the user that the program is using a source file
exiting_content, firstLine = [], "" # content of the file, and title respectively
exiting_content = [] # stores content of the file
title = input("\nPOST TITLE: ")
try:
with open(filePath, 'r') as f: # populating file content and title variables
existing_content = f.readlines()
firstLine = existing_content[0][2:] # first line, used as title
newpost(title, existing_content)
if (firstLine[-1] == '\n'): # if there is a NewLine character at the end of title line (probably will be), remove it from post title
firstLine = firstLine[:-1]
if (len(firstLine) == 0): # message and exit if title empty
prRed("Post title cannot be empty.")
exit()
else:
newpost(firstLine, existing_content)
except FileNotFoundError:
prRed("Invalid file path / file does not exist.")
@ -462,6 +452,40 @@ elif (arg == "manage"):
checkInit()
manage()
elif (arg == "search"):
checkInit()
if (len(argv) >= 3): # getting search term from args
t = argv[2]
else:
prYellow("No search term specified.")
exit()
allposts = [] # storing all indexFile entries inside a list
with open(f"{indexFile}",'r') as i:
allposts = i.readlines()
postsList = []
for i in allposts: # creating a list containing titles corresponding to filenames for posts that have the search term in their titles
if t in i[56:-1]:
postsList.append([i[56:-1],i[11:51]])
menuItems = []
for i in postsList: # formatting it into a string list for the ncurses menu function
menuItems.append(f"{i[0]} | {i[1]}")
which = menuFunction(menuItems, "Search listing:\n")
if (which == None): # menuFunction returns None if the list supplied to it is empty
print("\nNo items found.")
exit()
else:
print(f"\nYou have selected:\n\nTITLE: {postsList[which][0]}\nFILENAME: {postsList[which][1]}.gmi")
c = input("\nOpen manager? (y/[n]) ")
if (c == 'y' or c == 'Y'):
manage(f"{postsList[which][1]}")
elif (arg == "purge"): # permanently delete trashed posts
checkInit()
if (len(listdir(f"{wdir}trash/")) == 0):