Merge branch 'menu-flow-and-display' of cmccabe/linkulator2 into master
This commit is contained in:
commit
e2a78fd68f
|
@ -26,6 +26,7 @@ class DefaultUser:
|
|||
datafile: Path = datadir / PATHS.datafile
|
||||
ignorefile: Path = datadir / PATHS.ignorefile
|
||||
settingsfile: Path = datadir / PATHS.settingsfile
|
||||
lastlogin: float
|
||||
browser: str = "lynx"
|
||||
|
||||
def save(self):
|
||||
|
|
13
data.py
13
data.py
|
@ -128,8 +128,9 @@ class LinkData:
|
|||
"""sort link_data by creation date"""
|
||||
self.link_data.sort(key=lambda x: x[2], reverse=True)
|
||||
|
||||
def add(self, record):
|
||||
"""Add a record to the data file, and to link_data"""
|
||||
def add(self, record) -> int:
|
||||
"""Add a record to the data file, and to link_data. Returns a new post
|
||||
ID, if record is a post, or -1"""
|
||||
if os.path.exists(config.USER.datafile):
|
||||
append_write = "a" # append if already exists
|
||||
else:
|
||||
|
@ -145,15 +146,15 @@ class LinkData:
|
|||
)
|
||||
)
|
||||
|
||||
new_post_id = -1
|
||||
if record.category:
|
||||
record = record._replace(
|
||||
ID_if_parent=max([record[0] for record in self.link_data if record[0]])
|
||||
+ 1
|
||||
)
|
||||
new_post_id = max([record[0] for record in self.link_data if record[0]]) + 1
|
||||
record = record._replace(ID_if_parent=new_post_id)
|
||||
self.link_data.insert(0, list(record))
|
||||
self.generate_category_data()
|
||||
else:
|
||||
self.link_data.insert(0, list(record))
|
||||
return new_post_id
|
||||
|
||||
def generate_category_data(self):
|
||||
"""generate categories list and category count from sorted link data"""
|
||||
|
|
145
linkulator
145
linkulator
|
@ -7,7 +7,7 @@ import getpass
|
|||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from time import time
|
||||
from urllib.parse import urlparse
|
||||
from datetime import datetime
|
||||
from shutil import which
|
||||
|
@ -40,8 +40,8 @@ def print_categories():
|
|||
def print_category_details(view_cat):
|
||||
"""produces category detail data, prints it to the console. returns dict
|
||||
containing an index of threads"""
|
||||
header = "\n\n{:>4s} {:<15s}{:<12s} #RESP {:<13s}".format(
|
||||
"ID#", "DATE", "AUTHOR", "DESC"
|
||||
header = "\n{}\n\n{:>4s} {:<15s}{:<12s} #RESP {:<13s}".format(
|
||||
style_text(view_cat["name"].upper(), "bold"), "ID#", "DATE", "AUTHOR", "DESC"
|
||||
)
|
||||
out = ""
|
||||
link_count = 0
|
||||
|
@ -50,14 +50,14 @@ def print_category_details(view_cat):
|
|||
for line in link_data:
|
||||
if line[4] == view_cat["name"]:
|
||||
link_count += 1
|
||||
thread_index[link_count] = str(line[0])
|
||||
thread_index[link_count] = line[0]
|
||||
parent_id = line[1] + "+" + str(line[2])
|
||||
replies = [line for line in link_data if line[3] == parent_id]
|
||||
new_replies = len(
|
||||
[line for line in replies if line[2] >= config.USER.lastlogin]
|
||||
)
|
||||
newmarker = "*" if new_replies or line[2] >= config.USER.lastlogin else ""
|
||||
_dt = datetime.utcfromtimestamp(float(line[2])).strftime("%Y-%m-%d")
|
||||
_dt = datetime.fromtimestamp(float(line[2])).strftime("%Y-%m-%d")
|
||||
out += "{:4d} {:<15s}{:<12s} [{:3d}] {:s}{}\n".format(
|
||||
link_count, _dt, line[1], len(replies), line[6], newmarker
|
||||
)
|
||||
|
@ -71,39 +71,56 @@ def print_category_details(view_cat):
|
|||
return thread_index
|
||||
|
||||
|
||||
def print_thread_details(post_id):
|
||||
def print_thread_details(post_id) -> tuple:
|
||||
"""produces thread detail data, prints it to the console"""
|
||||
parent_id = ""
|
||||
url: str = ""
|
||||
# get post data
|
||||
parent_id: str = ""
|
||||
post_url: str = ""
|
||||
for line in link_data:
|
||||
if str(line[0]) == post_id:
|
||||
parent_id = line[1] + "+" + str(line[2])
|
||||
parent_user = line[1]
|
||||
parent_timestamp = line[2]
|
||||
url = line[5]
|
||||
if line[0] == post_id:
|
||||
parent_id = "{}+{}".format(line[1], str(line[2]))
|
||||
post_username = line[1]
|
||||
post_datetime = datetime.fromtimestamp(float(line[2])).strftime("%c")
|
||||
post_category = line[4]
|
||||
post_url = line[5]
|
||||
post_title = line[6]
|
||||
|
||||
# if post is not found, return empty string
|
||||
if parent_id == "":
|
||||
print("Sorry, no thread found with that ID.")
|
||||
return ""
|
||||
for line in link_data:
|
||||
if line[1] == parent_user and line[2] == parent_timestamp:
|
||||
ftime = time.strftime(
|
||||
"%b %d %Y", time.gmtime(float(parent_timestamp))
|
||||
) ## UGGHH...
|
||||
print("\n\n{:<15}: {}".format(style_text("Title", "bold"), line[6]))
|
||||
print("{:<15}: {}".format(style_text("Link", "bold"), line[5]))
|
||||
print("{:<15}: {}".format(style_text("User", "bold"), line[1]))
|
||||
print("{:<15}: {}".format(style_text("Date", "bold"), ftime))
|
||||
raise ValueError("Sorry, no thread found with that ID.")
|
||||
|
||||
print("\n{}:\n".format(style_text("Replies", "underline")))
|
||||
# get replies data
|
||||
replies = sorted([line for line in link_data if line[3] == parent_id])
|
||||
|
||||
replies = [line for line in link_data if line[3] == parent_id]
|
||||
# post detail view
|
||||
print("\n\n{:<17}: {}".format(style_text("Title", "bold"), post_title))
|
||||
print("{:<17}: {}".format(style_text("Link", "bold"), post_url))
|
||||
print("{:<17}: {}".format(style_text("Category", "bold"), post_category))
|
||||
print("{:<17}: {}".format(style_text("User", "bold"), post_username))
|
||||
print("{:<17}: {}".format(style_text("Date", "bold"), post_datetime))
|
||||
|
||||
# post reply view
|
||||
if replies:
|
||||
print("\n{}:\n".format(style_text("Replies", "underline")))
|
||||
for line in replies:
|
||||
print("{}: {}".format(style_text(line[1], "bold"), line[6]))
|
||||
comment_author = line[1]
|
||||
comment_date = datetime.fromtimestamp(float(line[2])).isoformat(
|
||||
sep=" ", timespec="minutes"
|
||||
)
|
||||
comment = line[6]
|
||||
print(
|
||||
" {} {}: {}".format(
|
||||
comment_date, style_text(comment_author, "bold"), comment
|
||||
)
|
||||
)
|
||||
else:
|
||||
print("No replies yet. Be the first!")
|
||||
return parent_user, parent_timestamp, url
|
||||
print("\nNo replies yet. Be the first!")
|
||||
|
||||
# return data used by menu control
|
||||
return parent_id, post_url
|
||||
|
||||
|
||||
## CONTROLS
|
||||
|
||||
|
||||
def view_link_in_browser(url):
|
||||
|
@ -128,7 +145,7 @@ def view_link_in_browser(url):
|
|||
subprocess.call([config.USER.browser, url])
|
||||
|
||||
|
||||
def reply(parent_user, parent_timestamp):
|
||||
def reply(parent_id):
|
||||
"""Prompt for reply, validate input, save validated input to disk and update
|
||||
link_data. Calls view_thread when complete."""
|
||||
while True:
|
||||
|
@ -144,8 +161,8 @@ def reply(parent_user, parent_timestamp):
|
|||
else:
|
||||
record = data.LinkDataRecord(
|
||||
username=getpass.getuser(),
|
||||
timestamp=str(time.time()),
|
||||
parent_id="{}+{}".format(parent_user, parent_timestamp),
|
||||
timestamp=str(time()),
|
||||
parent_id=parent_id,
|
||||
link_title_or_comment=comment,
|
||||
)
|
||||
LinkData.add(record)
|
||||
|
@ -185,7 +202,7 @@ def get_input(item: str) -> str:
|
|||
)
|
||||
|
||||
|
||||
def post_link():
|
||||
def post_link() -> int:
|
||||
"""Handles the link posting process"""
|
||||
|
||||
category_text = (
|
||||
|
@ -206,17 +223,17 @@ def post_link():
|
|||
title = get_input("Title")
|
||||
except ValueError:
|
||||
print("Post cancelled")
|
||||
return
|
||||
return -1
|
||||
|
||||
record = data.LinkDataRecord(
|
||||
username=getpass.getuser(),
|
||||
timestamp=str(time.time()),
|
||||
timestamp=str(time()),
|
||||
category=category,
|
||||
link_URL=url,
|
||||
link_title_or_comment=title,
|
||||
)
|
||||
|
||||
LinkData.add(record)
|
||||
return LinkData.add(record)
|
||||
|
||||
|
||||
def search(keyword):
|
||||
|
@ -241,9 +258,6 @@ def search(keyword):
|
|||
## if next_step...
|
||||
|
||||
|
||||
## CONTROLS
|
||||
|
||||
|
||||
def menu_view_categories():
|
||||
"""Displays list of categories, takes keyboard input and
|
||||
executes corresponding functions."""
|
||||
|
@ -259,14 +273,15 @@ def menu_view_categories():
|
|||
if option == "q":
|
||||
return
|
||||
if option == "p":
|
||||
post_link()
|
||||
post_id = post_link()
|
||||
if post_id >= 0:
|
||||
menu_view_thread_details(post_id)
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
cat_index = categories[int(option) - 1]
|
||||
menu_view_category_details(cat_index)
|
||||
except (IndexError, ValueError):
|
||||
print("Sorry, that category does not exist. Try again.")
|
||||
try:
|
||||
cat_index = categories[int(option) - 1]
|
||||
menu_view_category_details(cat_index)
|
||||
except (IndexError, ValueError):
|
||||
print("Sorry, that category does not exist. Try again.")
|
||||
|
||||
|
||||
def menu_view_category_details(cat_index):
|
||||
|
@ -290,15 +305,16 @@ def menu_view_category_details(cat_index):
|
|||
if option == "m":
|
||||
return
|
||||
if option == "p":
|
||||
post_link()
|
||||
post_id = post_link()
|
||||
if post_id >= 0:
|
||||
menu_view_thread_details(post_id)
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
link = thread_index[int(option)]
|
||||
menu_view_thread_details(link)
|
||||
except (KeyError, ValueError):
|
||||
# Catch a Post ID that is not in the thread list or is not a number
|
||||
print("{}\n\n".format(style_text("Invalid category ID/entry", "bold")))
|
||||
try:
|
||||
post_id = thread_index[int(option)]
|
||||
menu_view_thread_details(post_id)
|
||||
except (KeyError, ValueError):
|
||||
# Catch a Post ID that is not in the thread list or is not a number
|
||||
print("{}\n\n".format(style_text("Invalid category ID/entry", "bold")))
|
||||
|
||||
|
||||
def menu_view_thread_details(post_id):
|
||||
|
@ -313,23 +329,24 @@ def menu_view_thread_details(post_id):
|
|||
)
|
||||
|
||||
while True:
|
||||
parent_user, parent_timestamp, url = print_thread_details(post_id)
|
||||
parent_id, post_url = print_thread_details(post_id)
|
||||
option = input(option_text).lower()
|
||||
if option == "m":
|
||||
return
|
||||
if option == "b":
|
||||
view_link_in_browser(url)
|
||||
view_link_in_browser(post_url)
|
||||
continue
|
||||
elif option == "r":
|
||||
reply(parent_user, parent_timestamp)
|
||||
if option == "r":
|
||||
reply(parent_id)
|
||||
continue
|
||||
elif option == "p":
|
||||
post_link()
|
||||
continue
|
||||
elif option == "q":
|
||||
if option == "p":
|
||||
post_id = post_link()
|
||||
if post_id >= 0:
|
||||
continue
|
||||
break
|
||||
if option == "q":
|
||||
graceful_exit()
|
||||
else:
|
||||
print("{}\n\n".format(style_text("Invalid entry", "bold")))
|
||||
print("{}\n\n".format(style_text("Invalid entry", "bold")))
|
||||
|
||||
|
||||
## GENERAL
|
||||
|
|
Loading…
Reference in New Issue