Added the ability to search posts and manage them. Plus minor changes.
This commit is contained in:
parent
d82e6479a9
commit
4812961014
154
gempost
154
gempost
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue