2018-12-15 19:31:35 +00:00
#!/usr/bin/env python3
import os
import sys
import sqlite3 as sql
import datetime , time
import subprocess
2018-12-16 18:37:59 +00:00
import readline
2018-12-21 03:48:04 +00:00
import signal
2018-12-15 19:31:35 +00:00
class c :
black = ' '
red = ' \033 [0;31m '
b_red = ' \033 [1;31m '
yellow = ' \033 [1;33m '
green = ' \033 [0;32m '
b_green = ' \033 [1;32m '
cyan = ' \033 [0;36m '
b_cyan = ' \033 [1;36m '
purple = ' \033 [1;35m '
blue = ' \033 [0;34m '
b_blue = ' \033 [1;34m '
white = ' \033 [1;37m '
end = ' \033 [0m '
db_path = ' ./cspc.sqlite '
userdir = os . path . expanduser ( ' ~ ' )
user = os . path . split ( userdir ) [ - 1 ]
topic = None
post = None
available_ids = [ ]
2018-12-16 18:18:24 +00:00
messages = [ ]
2018-12-21 03:48:04 +00:00
last_log = False
2018-12-15 19:31:35 +00:00
def go_back ( ) :
global post
global topic
# If just viewed a post
if post and topic :
post = None
else :
post = None
topic = None
def get_prompt ( ) :
if post :
ident = ' Post ' . format ( post )
elif topic :
ident = ' Posts ' . format ( topic )
else :
ident = ' Topics '
return ' {} CSPC [ {} {} {} ] {} > {} ' . format ( c . yellow , c . white , ident , c . yellow , c . b_green , c . end )
def get_data ( ) :
if post and topic :
2018-12-16 18:18:24 +00:00
get_single_post ( )
2018-12-15 19:31:35 +00:00
elif topic :
get_posts ( )
else :
get_topics ( )
def show_help ( ) :
2018-12-16 18:18:24 +00:00
help_menu = [
' {} add: {} add a new topic/post/reply (whichever is relavent tot he screen you are on) ' . format ( c . cyan , c . end ) ,
' {} back: {} move up a level (post->posts->topics) ' . format ( c . cyan , c . end ) ,
' {} help: {} display this menu ' . format ( c . cyan , c . end ) ,
' {} item id: {} enter the item number to view it ' . format ( c . cyan , c . end ) ,
2018-12-21 04:07:41 +00:00
' {} q, quit, exit: {} leave cspc ' . format ( c . cyan , c . end ) ,
' {} posts created since your last login to cspc have dates in green {} ' . format ( c . green , c . end )
2018-12-16 18:18:24 +00:00
]
for x in help_menu :
messages . append ( x )
2018-12-15 19:31:35 +00:00
def make_add ( ) :
action = False
if post and topic :
action = ' reply '
elif topic :
action = ' post '
else :
action = ' topic '
verify = input ( ' {} Are you sure you would like to add a new {} {} {} (y/n)? {} ' . format ( c . cyan , c . b_blue , action , c . cyan , c . end ) )
verify = verify . lower ( )
if verify in [ ' y ' , ' yes ' , ' yeah ' , ' yup ' , ' ya ' ] :
add_new ( action )
def add_new ( a ) :
header = " 5 10 15 20 25 30 35 40 45 50 \n ....|....|....|....|....|....|....|....|....|....| "
title = None
body = None
if not a == ' reply ' :
title = input ( ' {} Enter the new {} s title: {} ' . format ( c . white , a , c . end ) )
content = [ ]
if not a == ' topic ' :
print ( ' {} Enter your content. To finish, enter a period as the only \n text on its row. {} ' . format ( c . yellow , c . end ) )
print ( header )
while True :
line = input ( ' {} > {} ' . format ( c . green , c . end ) )
if line == ' . ' :
break
content . append ( line )
confirm = input ( ' {} Submit the new {} (y/n)? {} ' . format ( c . white , a , c . end ) )
if confirm . lower ( ) in [ ' y ' , ' ya ' , ' yes ' , ' yeah ' ] :
body = ' \n ' . join ( content )
else :
print ( ' {} not saved ' . format ( a ) )
return False
payload = { ' title ' : title , ' body ' : body }
add_to_db ( a , payload )
def parse_command ( com ) :
global topic
global post
2018-12-16 18:18:24 +00:00
global messages
2018-12-15 19:31:35 +00:00
comlist = [ ' add ' , ' help ' , ' quit ' , ' back ' ]
if com == ' back ' :
go_back ( )
elif com == ' help ' :
show_help ( )
elif com in [ ' quit ' , ' q ' , ' exit ' ] :
2018-12-21 03:48:04 +00:00
set_last_log ( )
2018-12-15 19:31:35 +00:00
sys . exit ( 0 )
elif com == ' add ' :
make_add ( )
elif com == ' rm ' :
make_delete ( )
else :
try :
ident = int ( com )
if not ident in available_ids :
2018-12-16 18:18:24 +00:00
messages . append ( ' {} ERROR: {} is not an available option! \n ' . format ( c . red , com , c . end ) )
2018-12-15 19:31:35 +00:00
return False
if not topic :
topic = ident
elif not post :
post = ident
else :
2018-12-16 18:18:24 +00:00
messages . append ( ' {} A number command is not relevant right now... {} ' . format ( c . purple , c . end ) )
2018-12-15 19:31:35 +00:00
except ValueError :
2018-12-16 18:18:24 +00:00
messages . append ( ' {} Input not recognized {} ' . format ( c . red , c . end ) )
2018-12-15 19:31:35 +00:00
#------- DB Related --------#
def check_and_build_db ( ) :
if not os . path . isfile ( db_path ) :
conn = sql . connect ( db_path )
c = conn . cursor ( )
c . execute ( " CREATE TABLE data (topic_id INTEGER DEFAULT NULL, post_id INTEGER DEFAULT NULL, type text NOT NULL, title text DEFAULT NULL, body text DEFAULT NULL, author text NOT NULL, last_updated INTEGER NOT NULL) " )
conn . commit ( )
conn . close ( )
def db_do ( query , var = False , noresval = False ) :
2018-12-16 18:18:24 +00:00
global messages
2018-12-15 19:31:35 +00:00
if os . path . isfile ( db_path ) :
conn = sql . connect ( db_path )
c = conn . cursor ( )
if var :
c . execute ( query , var )
else :
c . execute ( query )
if noresval :
out = c . rowcount
else :
out = [ ]
for row in c :
out . append ( row )
conn . commit ( )
conn . close ( )
return out
else :
2018-12-16 18:18:24 +00:00
messages . append ( " {} ERROR: {} Database cannot be found or is corrupt " . format ( c . red , c . end ) )
2018-12-15 19:31:35 +00:00
return False
def get_posts ( ) :
global available_ids
global topic
available_ids = [ ]
q = " SELECT rowid, title, author, last_updated FROM data WHERE type = ' post ' and topic_id = ? ORDER BY last_updated DESC "
v = ( topic , )
res = db_do ( q , v )
2018-12-16 18:18:24 +00:00
print ( ' {} {:^6} {:35} {:12} {:18} {} ' . format ( c . yellow , ' ID ' , ' Post Title ' , ' Author ' , ' Last Updated ' , c . end ) )
2018-12-21 04:30:03 +00:00
print ( ' {} ------------------------------------------------------------------------------ {} ' . format ( c . yellow , c . end ) )
2018-12-15 19:31:35 +00:00
if not len ( res ) :
2018-12-16 18:18:24 +00:00
print ( ' \n {} There are no posts for this topic yet. Add one! {} ' . format ( c . cyan , c . end ) )
2018-12-15 19:31:35 +00:00
else :
for row in res :
available_ids . append ( row [ 0 ] )
dtime = datetime . datetime . utcfromtimestamp ( row [ 3 ] ) . strftime ( ' % Y- % m- %d % H: % M ' )
title = row [ 1 ]
if len ( title ) > 35 :
title = ' {} ... ' . format ( title [ : 32 ] )
2018-12-21 04:30:03 +00:00
if last_log > row [ 3 ] or not last_log :
2018-12-21 03:48:04 +00:00
print ( ' ( {:^4} ) {:35} {:12} {:18} ' . format ( row [ 0 ] , title , row [ 2 ] , dtime ) )
else :
print ( ' ( {:^4} ) {:35} {:12} {} {:18} {} ' . format ( row [ 0 ] , title , row [ 2 ] , c . green , dtime , c . end ) )
2018-12-15 19:31:35 +00:00
return True
def get_topics ( ) :
global available_ids
available_ids = [ ]
q = " SELECT title, last_updated, rowid FROM data WHERE type = ' topic ' ORDER BY last_updated DESC "
res = db_do ( q )
2018-12-16 18:18:24 +00:00
print ( ' {} {:^6} {:35} {:18} {} ' . format ( c . yellow , ' ID ' , ' Topic Name ' , ' Last Updated ' , c . end ) )
print ( ' {} ----------------------------------------------------------------- {} ' . format ( c . yellow , c . end ) )
2018-12-15 19:31:35 +00:00
for row in res :
available_ids . append ( row [ 2 ] )
dtime = datetime . datetime . utcfromtimestamp ( row [ 1 ] ) . strftime ( ' % Y- % m- %d % H: % M ' )
title = row [ 0 ]
if len ( title ) > 35 :
title = ' {} ... ' . format ( title [ : 32 ] )
2018-12-21 04:30:03 +00:00
if last_log > row [ 1 ] or not last_log :
2018-12-21 03:48:04 +00:00
print ( ' ( {:^4} ) {} {:35} {} {:18} ' . format ( row [ 2 ] , c . cyan , title , c . end , dtime ) )
else :
print ( ' ( {:^4} ) {} {:35} {} {:18} {} ' . format ( row [ 2 ] , c . cyan , title , c . green , dtime , c . end ) )
2018-12-15 19:31:35 +00:00
return True
2018-12-16 18:18:24 +00:00
def get_single_post ( ) :
global topic
global post
q1 = " SELECT title, body, author, last_updated FROM data WHERE type = ' post ' and topic_id = ? and rowid = ? "
v1 = ( topic , post )
res1 = db_do ( q1 , v1 )
q2 = " SELECT body, author, last_updated FROM data WHERE type = ' reply ' and post_id = ? and topic_id = ? ORDER BY last_updated ASC "
v2 = ( post , topic )
res2 = db_do ( q2 , v2 )
post_title = " {} Title: {} {} {} " . format ( c . yellow , c . white , res1 [ 0 ] [ 0 ] , c . end )
post_author = " {} Author: {} {} {} " . format ( c . yellow , c . white , res1 [ 0 ] [ 2 ] , c . end )
dtime = datetime . datetime . utcfromtimestamp ( res1 [ 0 ] [ 3 ] ) . strftime ( ' % Y- % m- %d % H: % M ' )
post_time = " {} Post date: {} {} {} \n " . format ( c . yellow , c . white , dtime , c . end )
post_body = res1 [ 0 ] [ 1 ]
print ( post_title )
print ( post_author )
print ( post_time )
print ( post_body )
print ( " \n {} - - - - - - - - - - - - - - - - {} \n " . format ( c . white , c . end ) )
if len ( res2 ) :
for row in res2 :
dtime = datetime . datetime . utcfromtimestamp ( row [ 2 ] ) . strftime ( ' % Y- % m- %d % H: % M ' )
print ( " {} | {} \n " . format ( row [ 1 ] , dtime ) )
print ( row [ 0 ] )
print ( " \n - - - - - - - \n " )
else :
print ( ' No replies. Add one! ' )
def update_time ( t ) :
if topic and post :
q = " UPDATE data SET last_updated = ? WHERE rowid in (?, ?) "
v = ( t , topic , post )
elif topic :
q = " UPDATE data SET last_updated = ? WHERE rowid = ? "
v = ( t , topic )
else :
return True
res = db_do ( q , v , noresval = True )
return res
2018-12-15 19:31:35 +00:00
def add_to_db ( action , data ) :
2018-12-16 18:18:24 +00:00
utime = int ( time . time ( ) )
2018-12-15 19:31:35 +00:00
q = " INSERT INTO data VALUES (?, ?, ?, ?, ?, ?, ?) "
2018-12-16 18:18:24 +00:00
v = ( topic , post , action , data [ ' title ' ] , data [ ' body ' ] , user , utime )
2018-12-15 19:31:35 +00:00
res = db_do ( q , v , noresval = True )
if not res :
2018-12-16 18:18:24 +00:00
messages . append ( " {} ERROR: {} There was an error adding your topic " . format ( c . red , c . end ) )
2018-12-15 19:31:35 +00:00
return False
2018-12-16 18:18:24 +00:00
tupdate = update_time ( utime )
2018-12-15 19:31:35 +00:00
return True
2018-12-21 03:48:04 +00:00
def get_last_log ( ) :
global last_log
filepath = ' {} /.cspc ' . format ( userdir )
if not os . path . isfile ( filepath ) :
with open ( filepath , ' w ' ) as f :
current = int ( time . time ( ) )
f . write ( str ( current ) )
with open ( filepath , ' r ' ) as f :
data = f . read ( )
try :
last_log = int ( data )
except :
last_log = False
def set_last_log ( ) :
filepath = ' {} /.cspc ' . format ( userdir )
with open ( filepath , ' w ' ) as f :
current = int ( time . time ( ) )
f . write ( str ( current ) )
2018-12-15 19:31:35 +00:00
#------- Main loop --------#
def mainloop ( ) :
2018-12-16 18:18:24 +00:00
global messages
2018-12-15 19:31:35 +00:00
while True :
subprocess . run ( [ ' clear ' ] )
print ( ' {} Colorfield Space Bulletin Board {} \n \n ' . format ( c . b_blue , c . end ) )
output = get_data ( )
# print the formatted data
print ( ' ' )
2018-12-16 18:18:24 +00:00
for x in messages :
print ( x )
print ( ' ' )
2018-12-15 19:31:35 +00:00
command = input ( get_prompt ( ) )
print ( ' ' )
2018-12-16 18:18:24 +00:00
messages = [ ]
2018-12-15 19:31:35 +00:00
if not command :
continue
parse_command ( command )
if __name__ == ' __main__ ' :
2018-12-21 03:48:04 +00:00
signal . signal ( signal . SIGINT , signal . SIG_IGN )
2018-12-15 19:31:35 +00:00
check_and_build_db ( )
2018-12-21 03:48:04 +00:00
get_last_log ( )
2018-12-15 19:31:35 +00:00
mainloop ( )