Merge branch 'menu-flow-and-display' of cmccabe/linkulator2 into master

This commit is contained in:
cmccabe 2019-12-15 06:46:35 -05:00 committed by Gitea
commit e2a78fd68f
3 changed files with 89 additions and 70 deletions

View File

@ -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
View File

@ -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"""

View File

@ -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