2016-04-30 03:17:06 +00:00
#!/usr/bin/python
2016-05-22 02:18:25 +00:00
'''
ttbp : tilde town blogging platform
( also known as the feels engine )
a console - based blogging program developed for tilde . town
copyright ( c ) 2016 ~ endorphant ( endorphant @tilde.town )
ttbp . py :
the main console interface
2016-06-15 01:51:49 +00:00
Permission is hereby granted , free of charge , to any person obtaining
a copy of this software and associated documentation files ( the
" Software " ) , to deal in the Software without restriction , including
without limitation the rights to use , copy , modify , merge , publish ,
distribute , sublicense , and / or sell copies of the Software , and to
permit persons to whom the Software is furnished to do so , subject to
the following conditions :
2016-05-22 02:18:25 +00:00
2016-06-15 01:51:49 +00:00
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software .
2016-05-22 02:18:25 +00:00
2016-06-15 01:51:49 +00:00
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND ,
EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION
OF CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
2016-05-22 02:18:25 +00:00
the complete codebase is available at :
https : / / github . com / modgethanc / ttbp
'''
2017-11-21 02:48:32 +00:00
from __future__ import absolute_import
2016-05-22 02:18:25 +00:00
2016-04-30 03:17:06 +00:00
import os
2018-03-16 05:30:48 +00:00
import sys
2016-05-01 17:44:49 +00:00
import tempfile
import subprocess
import time
2016-05-01 22:43:12 +00:00
import json
2017-12-04 04:05:04 +00:00
from email . mime . text import MIMEText
2017-11-26 02:39:58 +00:00
import datetime
2018-02-23 20:28:25 +00:00
from six . moves import input
2016-05-01 17:44:49 +00:00
2016-05-03 17:14:53 +00:00
import inflect
2016-04-30 03:17:06 +00:00
2017-11-21 06:02:10 +00:00
from . import config
2017-11-21 02:48:32 +00:00
from . import core
from . import chatter
2017-12-04 03:37:43 +00:00
from . import gopher
2017-11-21 02:48:32 +00:00
from . import util
2018-03-23 04:24:12 +00:00
__version__ = " 0.12.0 "
2016-05-23 02:42:31 +00:00
__author__ = " endorphant <endorphant@tilde.town) "
2016-05-03 17:14:53 +00:00
p = inflect . engine ( )
2016-05-01 22:26:26 +00:00
## ui globals
2017-11-21 06:02:10 +00:00
BANNER = util . attach_rainbow ( ) + config . BANNER + util . attach_reset ( )
2016-05-20 03:19:02 +00:00
SPACER = " \n "
2016-05-01 18:10:04 +00:00
INVALID = " please pick a number from the list of options! \n \n "
DUST = " sorry about the dust, but this part is still under construction. check back later! \n \n "
2016-05-09 02:59:48 +00:00
QUITS = [ ' exit ' , ' quit ' , ' q ' , ' x ' ]
EJECT = " eject button fired! going home now. "
2016-05-31 07:20:15 +00:00
RAINBOW = False
2016-05-01 18:10:04 +00:00
2016-05-01 22:26:26 +00:00
## ref
2017-12-06 03:50:45 +00:00
EDITORS = [ " nano " , " vim " , " vi " , " emacs " , " pico " , " ed " , " micro " ]
2016-05-02 15:26:51 +00:00
SUBJECTS = [ " help request " , " bug report " , " feature suggestion " , " general comment " ]
2017-12-31 16:52:56 +00:00
DEFAULT_SETTINGS = {
" editor " : " nano " ,
" publish dir " : None ,
" gopher " : False ,
2018-01-02 06:21:48 +00:00
" publishing " : False ,
" rainbows " : False ,
2018-03-23 04:11:40 +00:00
" post as nopub " : False ,
2017-12-31 16:52:56 +00:00
}
2016-05-01 22:26:26 +00:00
2017-12-31 17:52:23 +00:00
## user globals
SETTINGS = {
" editor " : " nano " ,
" publish dir " : None ,
" gopher " : False ,
2018-01-02 06:21:48 +00:00
" publishing " : False ,
2018-03-23 04:11:40 +00:00
" rainbows " : False ,
" post as nopub " : False ,
2017-12-31 17:52:23 +00:00
}
2016-10-10 21:53:02 +00:00
## ttbp specific utilities
def menu_handler ( options , prompt , pagify = 10 , rainbow = False , top = " " ) :
'''
This menu handler takes an incoming list of options , pagifies to a
pre - set value , and queries via the prompt . Calls print_menu ( ) and
list_select ( ) as helpers .
' top ' is an optional list topper , to be passed to redraw ( )
'''
optCount = len ( options )
page = 0
total = optCount / pagify
# don't display empty pages
if optCount % pagify == 0 :
total = total - 1
2018-01-03 03:28:04 +00:00
if total < 1 :
2018-01-02 06:21:48 +00:00
util . print_menu ( options , SETTINGS . get ( " rainbows " , False ) )
2016-11-08 23:38:15 +00:00
return util . list_select ( options , prompt )
2016-10-10 21:53:02 +00:00
else :
2018-02-28 18:16:51 +00:00
return page_helper ( options , prompt , pagify , rainbow , page , int ( total ) , top )
2016-10-10 21:53:02 +00:00
def page_helper ( options , prompt , pagify , rainbow , page , total , top ) :
'''
A helper to process pagination .
2016-11-08 23:38:15 +00:00
' pagify ' is the number of entries per page of display
' page ' is the current page number
' total ' is the total number of pages
' top ' is displyed after the banner redraw
2016-10-10 21:53:02 +00:00
'''
## make short list
x = 0 + page * pagify
y = x + pagify
optPage = options [ x : y ]
2018-01-02 06:21:48 +00:00
util . print_menu ( optPage , SETTINGS . get ( " rainbows " , False ) )
2018-02-28 18:16:51 +00:00
print ( " \n \t ( page {page} of {total} ; type ' u ' or ' d ' to scroll up and down) " . format ( page = page + 1 , total = total + 1 ) )
2016-10-10 21:53:02 +00:00
ans = util . list_select ( optPage , prompt )
if ans in util . NAVS :
error = " "
if ans == ' u ' :
if page == 0 :
error = " can ' t scroll up anymore! \n \n > "
else :
page = page - 1
else :
if page == total :
error = " can ' t scroll down anymore! \n \n > "
else :
page = page + 1
redraw ( error + top )
return page_helper ( options , prompt , pagify , rainbow , page , total , top )
2016-11-08 23:38:15 +00:00
elif ans is False :
return ans
else :
# shift answer to refer to index from original list
ans = ans + page * pagify
return ans
2016-05-01 18:10:04 +00:00
def redraw ( leftover = " " ) :
2016-05-22 04:45:04 +00:00
'''
screen clearing
* clears the screen and reprints the banner , plus whatever leftover text to be hilights
'''
2016-05-01 18:10:04 +00:00
os . system ( " clear " )
print ( BANNER )
print ( SPACER )
if leftover :
2017-12-31 16:52:56 +00:00
print ( " > {leftover} \n " . format ( leftover = leftover ) )
2016-04-30 03:17:06 +00:00
2017-12-31 16:52:56 +00:00
def main ( ) :
2016-05-22 04:45:04 +00:00
'''
main engine head
* called on program start
* calls config check
* proceeds to main menu
* handles ^ c and ^ d ejects
'''
2016-05-20 03:35:34 +00:00
redraw ( )
print ( """
2016-05-15 04:22:05 +00:00
if you don ' t want to be here at any point, press <ctrl-d> and it ' ll all go away .
just keep in mind that you might lose anything you ' ve started here. \
""" )
2016-05-11 03:54:44 +00:00
try :
2016-05-20 03:35:34 +00:00
print ( check_init ( ) )
2016-05-11 03:54:44 +00:00
except EOFError :
print ( stop ( ) )
2016-05-20 03:35:34 +00:00
return
redraw ( )
while 1 :
try :
print ( main_menu ( ) )
except EOFError :
print ( stop ( ) )
break
except KeyboardInterrupt :
redraw ( EJECT )
else :
break
2016-04-30 03:34:43 +00:00
def stop ( ) :
2016-05-22 04:45:04 +00:00
'''
2018-01-03 03:28:04 +00:00
returns an exit message .
2016-05-22 04:45:04 +00:00
'''
2016-05-20 03:35:34 +00:00
return " \n \n \t " + chatter . say ( " bye " ) + " \n \n "
2016-04-30 03:34:43 +00:00
def check_init ( ) :
2016-05-22 04:45:04 +00:00
'''
2018-01-03 03:28:04 +00:00
user environment validation
2016-05-22 04:45:04 +00:00
* checks for presence of ttbprc
* checks for last run version
'''
2016-05-20 03:35:34 +00:00
print ( " \n \n " )
if os . path . exists ( os . path . join ( os . path . expanduser ( " ~ " ) , " .ttbp " ) ) :
2018-02-20 00:15:21 +00:00
if config . USER == " endorphant " :
print ( " hey boss! :D \n " )
else :
print ( " {greeting} , {user} " . format ( greeting = chatter . say ( " greet " ) ,
user = config . USER ) )
2016-10-10 21:53:02 +00:00
2018-02-28 22:29:10 +00:00
load_settings = load_user_settings ( )
2016-10-10 21:53:02 +00:00
## ttbp env validation
2018-01-02 06:21:48 +00:00
if not user_up_to_date ( ) :
update_user_version ( )
2018-02-25 05:16:37 +00:00
2018-02-28 22:29:10 +00:00
if not valid_setup ( load_settings ) :
2016-10-10 21:53:02 +00:00
setup_repair ( )
2017-12-31 17:28:42 +00:00
else :
2018-02-23 20:28:25 +00:00
input ( " press <enter> to explore your feels. \n \n " )
2016-05-20 03:35:34 +00:00
2016-05-31 07:20:15 +00:00
core . load ( SETTINGS )
2016-05-20 03:35:34 +00:00
return " "
else :
return init ( )
2016-04-30 03:34:43 +00:00
def init ( ) :
2018-01-03 03:28:04 +00:00
""" Initializes new user by setting up ~/.ttbp directory and config file.
"""
2016-05-22 04:45:04 +00:00
2016-05-01 23:34:20 +00:00
try :
2018-03-23 04:11:40 +00:00
input ( config . intro_prompt )
2016-05-01 23:34:20 +00:00
except KeyboardInterrupt :
print ( " \n \n thanks for checking in! i ' ll always be here. \n \n " )
2016-05-02 15:26:51 +00:00
quit ( )
2016-05-01 23:34:20 +00:00
2017-12-31 17:52:23 +00:00
print ( " \n okay! gimme a second to get you set up! " )
time . sleep ( 1 )
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( .5 )
2017-12-31 17:52:23 +00:00
2016-05-22 04:45:04 +00:00
## record user in source list
2017-11-21 06:02:10 +00:00
users = open ( config . USERFILE , ' a ' )
users . write ( config . USER + " \n " )
2016-05-01 23:34:20 +00:00
users . close ( )
2016-05-22 04:45:04 +00:00
2017-11-29 17:20:37 +00:00
#subprocess.call(['chmod', 'a+w', config.USERFILE])
2017-11-22 05:12:49 +00:00
2016-05-22 04:45:04 +00:00
## make .ttbp directory structure
2017-12-31 17:52:23 +00:00
print ( " \n generating feels at {path} ... " . format ( path = config . PATH ) . rstrip ( ) )
2017-11-21 06:02:10 +00:00
subprocess . call ( [ " mkdir " , config . PATH ] )
subprocess . call ( [ " mkdir " , config . USER_CONFIG ] )
2018-03-16 02:41:22 +00:00
subprocess . call ( [ " mkdir " , config . MAIN_FEELS ] )
2016-05-15 04:22:05 +00:00
2017-11-21 06:02:10 +00:00
versionFile = os . path . join ( config . PATH , " version " )
2016-09-08 23:11:34 +00:00
open ( versionFile , " w " ) . write ( __version__ )
2016-05-22 04:45:04 +00:00
## create header file
2016-05-02 03:26:12 +00:00
header = gen_header ( )
2017-11-21 06:02:10 +00:00
headerfile = open ( os . path . join ( config . USER_CONFIG , " header.txt " ) , ' w ' )
2016-05-02 03:26:12 +00:00
for line in header :
headerfile . write ( line )
headerfile . close ( )
2016-05-15 04:22:05 +00:00
2016-05-22 04:45:04 +00:00
## copy footer and default stylesheet
2017-11-21 06:39:38 +00:00
with open ( os . path . join ( config . USER_CONFIG , ' footer.txt ' ) , ' w ' ) as f :
2017-11-21 06:02:10 +00:00
f . write ( config . DEFAULT_FOOTER )
2017-11-21 06:39:38 +00:00
with open ( os . path . join ( config . USER_CONFIG , ' style.css ' ) , ' w ' ) as f :
2017-11-21 06:02:10 +00:00
f . write ( config . DEFAULT_STYLE )
2016-05-01 23:34:20 +00:00
2016-05-22 04:45:04 +00:00
## run user-interactive setup and load core engine
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2017-12-31 17:52:23 +00:00
print ( " done setting up feels! " )
print ( " \n these are the default settings. you can change any of them now, or change them later at any time!! " )
2016-05-01 23:34:20 +00:00
setup ( )
2016-05-31 07:20:15 +00:00
core . load ( SETTINGS )
2016-05-02 03:26:12 +00:00
2018-03-23 04:11:40 +00:00
input ( """
you ' re all good to go, {friend} ! if you have any questions about how things
work here , check out the documentation from the main menu , ask in IRC , or
drop ~ endorphant a line !
hit < enter > to continue .
""" .format(friend=chatter.say( " friend " )))
2016-05-01 17:44:49 +00:00
return " "
2016-05-02 03:26:12 +00:00
def gen_header ( ) :
2016-05-22 04:45:04 +00:00
'''
header generator
builds header to insert username
'''
2016-05-15 04:22:05 +00:00
header = """
< ! DOCTYPE html PUBLIC \" -//W3C//DTD HTML 3.2//EN \" >
< html >
< head >
2016-05-22 04:45:04 +00:00
< ! - - - this header automatically generated by ttbp initialization on """ +time.strftime( " % Y- % m- %d % h:m " )+ """ - - - >
2017-11-21 06:02:10 +00:00
< title > ~ """ +config.USER+ """ on TTBP < / title >
2016-05-15 04:22:05 +00:00
< link rel = \" stylesheet \" href= \" style.css \" />
< / head >
< body >
< div id = \" meta \" >
2017-11-21 06:02:10 +00:00
< h1 > < a href = \" index.html# \" >~ " " " + config . USER + """ </a>@<a href= \" /~endorphant/ttbp \" >TTBP</a></h1>
2016-05-15 04:22:05 +00:00
< / div >
2016-05-20 03:35:34 +00:00
2016-05-15 04:22:05 +00:00
< ! - - - put your custom html here - - >
< ! - - - don ' t put anything after this line-->
< div id = \" tlogs \" > \
"""
2016-05-02 03:26:12 +00:00
return header
2018-02-28 22:29:10 +00:00
def valid_setup ( load_settings ) :
2016-10-10 21:53:02 +00:00
'''
2017-12-31 16:52:56 +00:00
Checks to see if user has a valid ttbp environment .
2016-10-10 21:53:02 +00:00
'''
2018-02-28 22:29:10 +00:00
if not load_settings :
2016-10-10 21:53:02 +00:00
return False
2017-12-31 16:52:56 +00:00
for option in iter ( DEFAULT_SETTINGS ) :
if option != " publish dir " and SETTINGS . get ( option , None ) is None :
2016-10-10 21:53:02 +00:00
return False
2017-12-31 16:52:56 +00:00
if core . publishing ( ) :
if SETTINGS . get ( " publish dir " , None ) is None :
print ( " CONFIG ERROR! publishing is enabled but no directory is set " )
2016-10-10 21:53:02 +00:00
return False
2017-12-31 16:52:56 +00:00
if ( not os . path . exists ( config . WWW ) or
not os . path . exists ( os . path . join ( config . PUBLIC ,
SETTINGS . get ( " publish dir " ) ) ) ) :
print ( " something ' s weird with your publishing directories. let ' s try rebuilding them! " )
update_publishing ( )
2017-12-05 04:18:42 +00:00
2016-10-10 21:53:02 +00:00
return True
2018-02-28 22:29:10 +00:00
def load_user_settings ( ) :
""" attempts to load user ' s ttbprc; returns settings dict if valie, otherwise
returns false """
global SETTINGS
if not os . path . isfile ( config . TTBPRC ) :
return False
try :
SETTINGS = json . load ( open ( config . TTBPRC ) )
except ValueError :
return False
core . load ( SETTINGS )
return SETTINGS
2016-05-31 07:20:15 +00:00
def setup_repair ( ) :
2016-05-22 04:45:04 +00:00
'''
2016-05-31 07:20:15 +00:00
setup repair function
2016-05-22 04:45:04 +00:00
* calls setup ( )
* handles ^ c
'''
2017-12-31 16:52:56 +00:00
global SETTINGS
2017-12-31 17:52:23 +00:00
print ( " \n your ttbp configuration doesn ' t look right. let me try to fix it.... \n \n " )
2017-12-31 16:52:56 +00:00
2018-01-02 06:21:48 +00:00
time . sleep ( 1 )
2017-12-31 16:52:56 +00:00
settings_map = {
" editor " : select_editor ,
" publishing " : select_publishing ,
" publish dir " : select_publish_dir ,
2018-01-02 06:21:48 +00:00
" gopher " : gopher . select_gopher ,
2018-02-28 22:29:10 +00:00
" rainbows " : toggle_rainbows ,
" post as nopub " : toggle_pub_default
2017-12-31 16:52:56 +00:00
}
for option in iter ( settings_map ) :
if SETTINGS . get ( option , None ) is None :
SETTINGS . update ( { option : " NOT SET " } )
SETTINGS . update ( { option : settings_map [ option ] ( ) } )
update_publishing ( )
core . reload_ttbprc ( SETTINGS )
save_settings ( )
2017-12-31 17:52:23 +00:00
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2018-02-23 20:28:25 +00:00
input ( " \n you ' re all good to go, " + chatter . say ( " friend " ) + " ! hit <enter> to continue. \n \n " )
2016-05-01 22:43:12 +00:00
2016-05-01 22:26:26 +00:00
def setup ( ) :
2016-05-22 04:45:04 +00:00
'''
master setup function
* editor selection
2017-12-05 04:18:42 +00:00
* publishing toggle ( publish / unpublish as needed )
2016-05-22 04:45:04 +00:00
* directory selection
2017-12-05 04:18:42 +00:00
* gopher opt in / out
2016-05-22 04:45:04 +00:00
TODO : break this out better ?
'''
2016-05-01 22:26:26 +00:00
global SETTINGS
2017-12-06 03:50:45 +00:00
menuOptions = [ ]
settingList = sorted ( list ( SETTINGS ) )
for setting in settingList :
menuOptions . append ( setting + " : \t " + str ( SETTINGS . get ( setting ) ) )
2018-01-02 06:21:48 +00:00
util . print_menu ( menuOptions , SETTINGS . get ( " rainbows " , False ) )
2017-12-06 03:50:45 +00:00
try :
2018-02-23 20:28:25 +00:00
choice = input ( " \n pick a setting to change (or type ' q ' to exit): " )
2017-12-06 03:50:45 +00:00
except KeyboardInterrupt :
redraw ( EJECT )
return SETTINGS
2018-03-23 04:17:33 +00:00
if choice is not " " :
if choice in QUITS :
redraw ( )
return SETTINGS
# editor selection
if settingList [ int ( choice ) ] == " editor " :
SETTINGS . update ( { " editor " : select_editor ( ) } )
redraw ( " text editor set to: {editor} " . format ( editor = SETTINGS [ " editor " ] ) )
save_settings ( )
return setup ( )
# publishing selection
elif settingList [ int ( choice ) ] == " publishing " :
SETTINGS . update ( { " publishing " : select_publishing ( ) } )
core . reload_ttbprc ( SETTINGS )
update_publishing ( )
redraw ( " publishing set to {publishing} " . format ( publishing = SETTINGS . get ( " publishing " ) ) )
save_settings ( )
return setup ( )
# publish dir selection
elif settingList [ int ( choice ) ] == " publish dir " :
publish_dir = select_publish_dir ( )
SETTINGS . update ( { " publish dir " : publish_dir } )
#update_publishing()
if publish_dir is None :
redraw ( " sorry, i can ' t set a publish directory for you if you don ' t have html publishing enabled. please enable publishing to continue. " )
else :
redraw ( " publishing your entries to {url} /index.html " . format (
url = " / " . join ( [ config . LIVE + config . USER ,
str ( SETTINGS . get ( " publish dir " ) ) ] ) ) )
save_settings ( )
return setup ( )
# gopher opt-in
elif settingList [ int ( choice ) ] == " gopher " :
SETTINGS . update ( { ' gopher ' : gopher . select_gopher ( ) } )
redraw ( ' gopher publishing set to: {gopher} ' . format ( gopher = SETTINGS [ ' gopher ' ] ) )
update_gopher ( )
save_settings ( )
return setup ( )
# rainbow menu selection
elif settingList [ int ( choice ) ] == " rainbows " :
SETTINGS . update ( { " rainbows " : toggle_rainbows ( ) } )
redraw ( " rainbow menus set to {rainbow} " . format ( rainbow = SETTINGS . get ( " rainbows " ) ) )
save_settings ( )
return setup ( )
#nopub toggling
elif settingList [ int ( choice ) ] == " post as nopub " :
SETTINGS . update ( { " post as nopub " : toggle_pub_default ( ) } )
redraw ( " posting default set to {nopub} " . format ( nopub = SETTINGS . get ( " post as nopub " ) ) )
save_settings ( )
return setup ( )
input ( " \n you ' re all good to go, {friend} ! hit <enter> to continue. \n \n " . format ( friend = chatter . say ( " friend " ) ) )
2017-12-06 03:50:45 +00:00
redraw ( )
2016-05-01 22:43:12 +00:00
2018-03-23 04:17:33 +00:00
return SETTINGS
2018-01-02 06:21:48 +00:00
2018-03-23 04:17:33 +00:00
else :
redraw ( " now changing your settings. press <ctrl-c> if you didn ' t mean to do this. " )
2018-02-28 17:23:34 +00:00
return setup ( )
2017-12-06 03:50:45 +00:00
def save_settings ( ) :
"""
Save current settings .
"""
ttbprc = open ( config . TTBPRC , " w " )
ttbprc . write ( json . dumps ( SETTINGS , sort_keys = True , indent = 2 , separators = ( ' , ' , ' : ' ) ) )
ttbprc . close ( )
2016-05-01 17:44:49 +00:00
## menus
2016-04-30 03:17:06 +00:00
def main_menu ( ) :
2016-05-22 04:45:04 +00:00
'''
main navigation menu
'''
2016-05-01 22:26:26 +00:00
menuOptions = [
2016-05-03 17:46:54 +00:00
" record your feels " ,
2018-03-12 03:46:15 +00:00
" manage your feels " ,
2016-05-03 17:46:54 +00:00
" check out your neighbors " ,
2016-05-05 00:04:16 +00:00
" browse global feels " ,
2016-10-10 21:53:02 +00:00
" scribble some graffiti " ,
2016-05-03 17:46:54 +00:00
" change your settings " ,
" send some feedback " ,
2016-05-23 02:42:31 +00:00
" see credits " ,
" read documentation " ]
2016-05-22 04:45:04 +00:00
2016-10-10 21:53:02 +00:00
print ( " you ' re at ttbp home. remember, you can always press <ctrl-c> to come back here. \n " )
2018-01-02 06:21:48 +00:00
util . print_menu ( menuOptions , SETTINGS . get ( " rainbows " , False ) )
2016-05-01 17:44:49 +00:00
2016-05-01 22:26:26 +00:00
try :
2018-02-23 20:28:25 +00:00
choice = input ( " \n tell me about your feels (or type ' q ' to exit): " )
2016-05-01 22:26:26 +00:00
except KeyboardInterrupt :
2016-05-09 02:59:48 +00:00
redraw ( EJECT )
2016-05-01 22:26:26 +00:00
return main_menu ( )
2016-05-01 17:44:49 +00:00
if choice == ' 0 ' :
2016-05-01 23:34:20 +00:00
redraw ( )
today = time . strftime ( " % Y % m %d " )
2018-03-16 02:41:22 +00:00
write_entry ( os . path . join ( config . MAIN_FEELS , today + " .txt " ) )
2016-05-31 07:20:15 +00:00
core . www_neighbors ( )
2016-05-01 17:44:49 +00:00
elif choice == ' 1 ' :
2018-03-13 21:40:09 +00:00
intro = " here are some options for managing your feels: "
redraw ( intro )
review_menu ( intro )
core . load_files ( )
2016-05-05 00:04:16 +00:00
elif choice == ' 2 ' :
2016-05-31 07:20:15 +00:00
users = core . find_ttbps ( )
2017-12-31 16:52:56 +00:00
prompt = " the following {usercount} {are} recording feels on ttbp: " . format (
usercount = p . no ( " user " , len ( users ) ) ,
are = p . plural ( " is " , len ( users ) ) )
2016-11-08 23:38:15 +00:00
redraw ( prompt )
view_neighbors ( users , prompt )
2016-05-05 00:04:16 +00:00
elif choice == ' 3 ' :
2016-10-10 21:53:02 +00:00
redraw ( " most recent global entries " )
2016-05-05 00:04:16 +00:00
view_feed ( )
elif choice == ' 4 ' :
2016-05-31 07:20:15 +00:00
graffiti_handler ( )
elif choice == ' 5 ' :
2016-05-23 02:42:31 +00:00
redraw ( " now changing your settings. press <ctrl-c> if you didn ' t mean to do this. " )
2017-12-06 03:50:45 +00:00
core . load ( setup ( ) ) # reload settings to core
2016-05-05 00:04:16 +00:00
elif choice == ' 6 ' :
2016-10-10 21:53:02 +00:00
redraw ( " you ' re about to send mail to ~endorphant about ttbp " )
2016-05-31 07:20:15 +00:00
feedback_menu ( )
elif choice == ' 7 ' :
2016-05-11 03:54:44 +00:00
redraw ( )
show_credits ( )
2016-05-31 07:20:15 +00:00
elif choice == ' 8 ' :
2018-03-23 03:16:45 +00:00
subprocess . call ( [ " lynx " , os . path . join ( config . INSTALL_PATH , " .. " , " doc " , " manual.html " ) ] )
2016-05-23 02:42:31 +00:00
redraw ( )
2016-05-09 02:59:48 +00:00
elif choice in QUITS :
2016-05-01 17:44:49 +00:00
return stop ( )
else :
2016-05-01 18:10:04 +00:00
redraw ( INVALID )
2016-05-01 17:44:49 +00:00
return main_menu ( )
2016-04-30 03:17:06 +00:00
2016-05-01 17:44:49 +00:00
def feedback_menu ( ) :
2016-05-22 04:45:04 +00:00
'''
feedback handling menu
* selects feedback type
* calls feedback writing function
'''
2018-01-02 06:21:48 +00:00
util . print_menu ( SUBJECTS , SETTINGS . get ( " rainbows " , False ) )
2018-02-23 20:28:25 +00:00
choice = input ( " \n pick a category for your feedback: " )
2016-04-30 03:17:06 +00:00
2016-05-01 17:44:49 +00:00
cat = " "
2016-05-03 17:14:53 +00:00
if choice in [ ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' ] :
2016-05-01 22:26:26 +00:00
cat = SUBJECTS [ int ( choice ) ]
2018-02-23 20:28:25 +00:00
entered = input ( """
2017-12-31 16:52:56 +00:00
composing a { mail_category } to ~ endorphant .
2016-05-15 04:22:05 +00:00
press < enter > to open an external text editor . mail will be sent once you save and quit .
2017-12-31 16:52:56 +00:00
""" .format(mail_category=cat))
2016-05-15 04:22:05 +00:00
redraw ( send_feedback ( entered , cat ) )
2016-05-01 18:10:04 +00:00
return
2016-05-01 17:44:49 +00:00
else :
2016-05-01 18:10:04 +00:00
redraw ( INVALID )
2016-05-01 17:44:49 +00:00
return feedback_menu ( )
2016-10-10 21:53:02 +00:00
def review_menu ( intro = " " ) :
'''
submenu for reviewing feels .
'''
menuOptions = [
" read over feels " ,
2018-03-12 02:30:10 +00:00
" modify feels publishing " ,
" backup your feels " ,
2018-03-17 02:38:01 +00:00
" import a feels backup " ,
2018-03-15 20:41:41 +00:00
" bury some feels " ,
2018-03-12 02:30:10 +00:00
" delete feels by day " ,
2018-03-13 21:40:09 +00:00
" purge all feels " ,
2018-03-16 05:30:48 +00:00
" wipe feels account "
2016-10-10 21:53:02 +00:00
]
2018-01-02 06:21:48 +00:00
util . print_menu ( menuOptions , SETTINGS . get ( " rainbows " , False ) )
2016-10-10 21:53:02 +00:00
2018-03-16 02:41:22 +00:00
choice = util . list_select ( menuOptions , " what would you like to do with your feels? (or ' q ' to return home) " )
2016-10-10 21:53:02 +00:00
2018-03-12 02:30:10 +00:00
top = " "
2018-03-16 02:41:22 +00:00
hasfeels = len ( os . listdir ( config . MAIN_FEELS ) ) > 0
2018-03-13 21:40:09 +00:00
nofeels = " you don ' t have any feels to work with, " + chatter . say ( " friend " ) + " \n \n > "
2018-03-12 02:30:10 +00:00
2016-10-10 21:53:02 +00:00
if choice is not False :
if choice == 0 :
2018-03-13 21:40:09 +00:00
if hasfeels :
redraw ( " your recorded feels, listed by date: " )
view_feels ( config . USER )
else :
top = nofeels
2016-10-10 21:53:02 +00:00
elif choice == 1 :
2018-03-13 21:40:09 +00:00
if hasfeels :
redraw ( " publishing status of your feels: " )
list_nopubs ( config . USER )
else :
top = nofeels
2018-03-12 02:30:10 +00:00
elif choice == 2 :
2018-03-13 21:40:09 +00:00
if hasfeels :
redraw ( " FEELS BACKUP " )
backup_feels ( )
else :
top = nofeels
2018-03-12 02:30:10 +00:00
elif choice == 3 :
2018-03-17 02:38:01 +00:00
redraw ( " loading feels backup " )
load_backup ( )
2018-03-15 20:41:41 +00:00
elif choice == 4 :
2018-03-22 17:46:41 +00:00
if hasfeels :
redraw ( " burying feels " )
bury_feels ( )
else :
top = nofeels
2018-03-17 02:38:01 +00:00
elif choice == 5 :
2018-03-15 20:17:21 +00:00
if hasfeels :
redraw ( " deleting feels " )
delete_feels ( )
else :
top = nofeels
2018-03-17 02:38:01 +00:00
elif choice == 6 :
2018-03-13 21:40:09 +00:00
if hasfeels :
redraw ( " !!!PURGING ALL FEELS!!! " )
purge_feels ( )
else :
top = nofeels
2018-03-16 05:30:48 +00:00
elif choice == 7 :
redraw ( " !!! WIPING FEELS ACCOUNT !!! " )
wipe_account ( )
2016-10-10 21:53:02 +00:00
else :
redraw ( )
return
2018-03-12 02:30:10 +00:00
redraw ( top + intro )
return review_menu ( intro )
2016-10-10 21:53:02 +00:00
2016-11-08 23:38:15 +00:00
def view_neighbors ( users , prompt ) :
2016-05-23 02:42:31 +00:00
'''
generates list of all users on ttbp , sorted by most recent post
* if user is publishing , list publish directory
'''
2016-05-02 15:26:51 +00:00
2016-05-03 17:52:07 +00:00
userList = [ ]
2016-05-23 02:42:31 +00:00
## assumes list of users passed in all have valid config files
2016-05-02 15:26:51 +00:00
for user in users :
userRC = json . load ( open ( os . path . join ( " /home " , user , " .ttbp " , " config " , " ttbprc " ) ) )
2016-05-23 02:42:31 +00:00
## retrieve publishing url, if it exists
2016-05-23 00:52:27 +00:00
url = " \t \t \t "
2016-05-20 15:06:42 +00:00
if userRC . get ( " publish dir " ) :
2017-11-21 06:02:10 +00:00
url = config . LIVE + user + " / " + userRC . get ( " publish dir " )
2016-05-23 02:42:31 +00:00
## find last entry
2018-02-25 05:16:37 +00:00
try :
files = os . listdir ( os . path . join ( " /home " , user , " .ttbp " , " entries " ) )
except OSError :
files = [ ]
2016-05-09 02:59:48 +00:00
files . sort ( )
2016-05-23 02:42:31 +00:00
lastfile = " "
2016-05-09 02:59:48 +00:00
for filename in files :
2016-05-11 04:10:04 +00:00
if core . valid ( filename ) :
2016-05-09 02:59:48 +00:00
lastfile = os . path . join ( " /home " , user , " .ttbp " , " entries " , filename )
2016-05-23 02:42:31 +00:00
## generate human-friendly timestamp
2016-05-10 16:14:53 +00:00
ago = " never "
2016-05-09 02:59:48 +00:00
if lastfile :
last = os . path . getctime ( lastfile )
2016-05-10 16:14:53 +00:00
since = time . time ( ) - last
ago = util . pretty_time ( int ( since ) ) + " ago "
2016-05-09 02:59:48 +00:00
else :
last = 0
2016-05-23 02:42:31 +00:00
## some formatting handwavin
urlpad = " "
if ago == " never " :
urlpad = " \t "
2016-05-03 17:52:07 +00:00
2016-05-23 02:42:31 +00:00
userpad = " "
if len ( user ) < 7 :
userpad = " \t "
2016-05-09 02:59:48 +00:00
2017-12-31 16:52:56 +00:00
userList . append ( [ " \t ~ {user} {userpad} \t ( {ago} ) {urlpad} \t {url} " . format ( user = user ,
userpad = userpad , ago = ago , urlpad = urlpad , url = url ) , last , user ] )
2016-05-23 02:42:31 +00:00
# sort user by most recent entry for display
2016-05-09 02:59:48 +00:00
userList . sort ( key = lambda userdata : userdata [ 1 ] )
userList . reverse ( )
sortedUsers = [ ]
2016-05-23 02:42:31 +00:00
userIndex = [ ]
2016-05-09 02:59:48 +00:00
for user in userList :
sortedUsers . append ( user [ 0 ] )
2016-05-23 02:42:31 +00:00
userIndex . append ( user [ 2 ] )
2016-05-09 02:59:48 +00:00
2018-03-16 02:41:22 +00:00
choice = menu_handler ( sortedUsers , " pick a townie to browse their feels, or type ' q ' to go home: " , 15 , SETTINGS . get ( " rainbows " , False ) , prompt )
2016-05-02 15:26:51 +00:00
2016-05-23 02:42:31 +00:00
if choice is not False :
2017-12-31 16:52:56 +00:00
redraw ( " ~ {user} ' s recorded feels, listed by date: \n " . format ( user = userIndex [ choice ] ) )
2016-05-23 02:42:31 +00:00
view_feels ( userIndex [ choice ] )
2016-11-08 23:38:15 +00:00
view_neighbors ( users , prompt )
2016-05-23 02:42:31 +00:00
else :
redraw ( )
return
2016-05-03 17:14:53 +00:00
2016-05-23 02:42:31 +00:00
def view_feels ( townie ) :
'''
generates a list of all feels by given townie and displays in
2018-01-03 00:00:02 +00:00
date order ; allows selection of one feel to read .
2016-05-23 02:42:31 +00:00
'''
2016-05-05 00:04:16 +00:00
2018-01-03 00:00:02 +00:00
metas , owner = generate_feels_list ( townie )
if len ( metas ) > 0 :
entries = [ ]
for entry in metas :
pub = " "
if core . nopub ( entry [ 0 ] ) :
pub = " (nopub) "
entries . append ( " " + entry [ 4 ] + " ( " + p . no ( " word " , entry [ 2 ] ) + " ) " + " \t " + pub )
return list_entries ( metas , entries , owner + " recorded feels, listed by date: " )
else :
redraw ( " no feels recorded by ~ " + townie )
def generate_feels_list ( user ) :
""" create a list of feels for display from the named user.
"""
2016-05-05 00:04:16 +00:00
filenames = [ ]
2016-10-10 21:53:02 +00:00
showpub = False
2016-05-05 00:04:16 +00:00
2018-01-03 00:00:02 +00:00
if user == config . USER :
2018-03-16 02:41:22 +00:00
entryDir = config . MAIN_FEELS
2016-05-23 02:42:31 +00:00
owner = " your "
2016-10-10 21:53:02 +00:00
if core . publishing ( ) :
showpub = True
2016-05-23 02:42:31 +00:00
else :
2018-01-03 03:37:08 +00:00
owner = " ~ " + user + " ' s "
2018-01-03 00:00:02 +00:00
entryDir = os . path . join ( " /home " , user , " .ttbp " , " entries " )
2016-05-23 02:42:31 +00:00
for entry in os . listdir ( entryDir ) :
filenames . append ( os . path . join ( entryDir , entry ) )
2016-05-05 00:04:16 +00:00
metas = core . meta ( filenames )
2016-10-06 15:38:14 +00:00
metas . sort ( key = lambda entry : entry [ 4 ] )
metas . reverse ( )
2016-05-03 17:14:53 +00:00
2018-01-03 00:00:02 +00:00
return metas , owner
2016-05-05 00:04:16 +00:00
2018-03-12 03:46:15 +00:00
def backup_feels ( ) :
""" creates a tar.gz of user ' s entries directory """
2018-03-17 01:53:52 +00:00
backupfile = os . path . join ( os . path . expanduser ( ' ~ ' ) , " feels-backup- " + time . strftime ( " % Y % m %d - % H % M % S " ) + " .tar.gz " )
2018-03-12 03:46:15 +00:00
print ( """ \
i ' m preparing all of your entries for backup. " " " )
print ( " ... " )
time . sleep ( 1 )
print ( """
ready to go ! a backup file will be saved to your home directory at :
{ backuploc } """ .format(backuploc=backupfile))
ans = util . input_yn ( """ \
would you like to create this backup ?
please enter """ )
if ans :
if not subprocess . call ( [ " tar " , " -C " , config . PATH , " -czf " , backupfile , " entries " ] ) :
2018-03-17 01:53:52 +00:00
subprocess . call ( [ " chmod " , " 600 " , backupfile ] )
if not os . path . exists ( config . BACKUPS ) :
subprocess . call ( [ " mkdir " , config . BACKUPS ] )
2018-03-23 03:53:24 +00:00
subprocess . call ( [ " chmod " , " 700 " , config . BACKUPS ] )
2018-03-17 01:53:52 +00:00
subprocess . call ( [ " cp " , backupfile , config . BACKUPS ] )
2018-03-22 20:27:35 +00:00
print ( " \n backup saved! i also put a copy at {backup_dir} for you. " . format ( backup_dir = config . BACKUPS ) )
2018-03-12 03:46:15 +00:00
else :
2018-03-23 03:39:07 +00:00
print ( config . mystery_error )
2018-03-12 03:46:15 +00:00
else :
print ( " no problem, {friend} ; come back whenever if you want a backup! " . format ( friend = chatter . say ( " friend " ) ) )
2018-03-13 20:58:28 +00:00
input ( " \n \n press <enter> to go back to managing your feels. \n \n " )
redraw ( )
return
2018-03-15 20:17:21 +00:00
def delete_feels ( ) :
""" handles deleting feels one at a time """
feel = input ( """ which day ' s feels do you want to load for deletion?
2018-03-17 01:53:52 +00:00
YYYYMMDD ( or ' q ' to cancel ) > """ )
2018-03-15 20:17:21 +00:00
if feel in util . BACKS :
return
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.1 )
2018-03-15 20:17:21 +00:00
print ( """ \
here ' s a preview of that feel. press <q> when you ' re done reviewing !
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """ )
2018-03-16 02:41:22 +00:00
if subprocess . call ( [ " less " , os . path . join ( config . MAIN_FEELS , feel + " .txt " ) ] ) :
2018-03-15 20:17:21 +00:00
redraw ( " deleting feels " )
print ( """ \
sorry , i couldn ' t find feels for {date} !
2018-03-17 01:53:52 +00:00
please try again , or type < q > to cancel .
""" .format(date=feel))
2018-03-15 20:17:21 +00:00
return delete_feels ( )
print ( """
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
feels deletion is irreversible ! if you ' re sure you want to delete this feel,
2018-03-17 01:53:52 +00:00
type the date again to confirm , or ' q ' to cancel . """ )
2018-03-15 20:17:21 +00:00
confirm = input ( " [ {feeldate} ]> " . format ( feeldate = feel ) )
if confirm == feel :
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2018-03-16 04:39:27 +00:00
core . delete_feel ( feel + " .txt " )
2018-03-15 20:17:21 +00:00
print ( " feels deleted! " )
else :
print ( " deletion canceled! " )
ans = util . input_yn ( """ do you want to delete a different feel?
please enter """ )
if ans :
redraw ( " deleting feels " )
return delete_feels ( )
else :
print ( " okay! please come back any time if you want to delete old feels! " )
input ( " \n \n press <enter> to go back to managing your feels. \n \n " )
redraw ( )
2018-03-17 01:53:52 +00:00
2018-03-15 20:17:21 +00:00
return
2018-03-13 20:58:28 +00:00
def purge_feels ( ) :
""" handles deleting all feels """
2018-03-23 03:39:07 +00:00
print ( config . feels_purge_prompt )
2018-03-13 20:58:28 +00:00
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2018-03-22 17:40:34 +00:00
print ( " ...loading feels... " )
time . sleep ( 1 )
2018-03-13 20:58:28 +00:00
print ( " ... " )
2018-03-16 02:41:22 +00:00
feelscount = len ( os . listdir ( config . MAIN_FEELS ) )
2018-03-13 20:58:28 +00:00
2018-03-13 21:22:36 +00:00
if feelscount > 0 :
purgecode = util . genID ( 5 )
2018-03-13 20:58:28 +00:00
2018-03-13 21:22:36 +00:00
print ( """
2018-03-22 17:40:34 +00:00
i ' ve loaded up all {count} of your feels for purging. if you ' re ready , carefully
type the following purge code :
2018-03-13 20:58:28 +00:00
_________
| |
| { purgecode } |
| _______ |
2018-03-13 21:22:36 +00:00
""" .format(purgecode=purgecode, count=feelscount))
2018-03-13 20:58:28 +00:00
2018-03-13 21:22:36 +00:00
ans = input ( " (leave blank or type anything else to cancel) > " )
2018-03-13 20:58:28 +00:00
2018-03-13 21:22:36 +00:00
if ans == purgecode :
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2018-03-13 21:22:36 +00:00
unpublish ( )
2018-03-23 01:59:19 +00:00
2018-03-16 02:41:22 +00:00
if not subprocess . call ( [ " rm " , " -rf " , config . MAIN_FEELS ] ) :
subprocess . call ( [ " mkdir " , config . MAIN_FEELS ] )
2018-03-22 22:43:45 +00:00
core . load_files ( )
2018-03-13 21:22:36 +00:00
print ( " ALL FEELS PURGED! you ' re ready to start fresh! " )
else :
2018-03-23 03:39:07 +00:00
print ( config . mystery_error )
2018-03-13 21:22:36 +00:00
else :
print ( " \n feels purge canceled! you ' re welcome to come back again. " )
2018-03-13 20:58:28 +00:00
else :
2018-03-13 21:22:36 +00:00
print ( " you don ' t have any feels to purge, " + chatter . say ( " friend " ) )
2018-03-13 20:58:28 +00:00
input ( " \n \n press <enter> to go back to managing your feels. \n \n " )
2018-03-12 03:46:15 +00:00
redraw ( )
return
2018-03-16 05:30:48 +00:00
def wipe_account ( ) :
""" handles wiping feels account """
2018-03-23 03:39:07 +00:00
print ( config . account_wipe_prompt )
2018-03-16 05:30:48 +00:00
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2018-03-22 17:40:34 +00:00
print ( " ...packaging up all your feels... " )
time . sleep ( 1 )
2018-03-16 05:30:48 +00:00
print ( " ... " )
purgecode = util . genID ( 5 )
print ( """
2018-03-22 17:40:34 +00:00
your account is all packed up ! if you ' re ready, carefully type the following
purge code :
2018-03-16 05:30:48 +00:00
_________
| |
| { purgecode } |
| _______ |
""" .format(purgecode=purgecode))
ans = input ( " (leave blank or type anything else to cancel) > " )
if ans == purgecode :
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2018-03-16 05:30:48 +00:00
unpublish ( )
2018-03-23 01:59:19 +00:00
if core . publishing ( ) :
publishDir = os . path . join ( config . PUBLIC , SETTINGS . get ( " publish dir " ) )
make_publish_dir ( publishDir )
2018-03-16 05:30:48 +00:00
if not subprocess . call ( [ " rm " , " -rf " , config . PATH ] ) :
print ( """
account deleted ! if you ever want to come back , you ' re always welcome to start
fresh : )
thank you for sharing your feels ! """ )
input ( " \n \n press <enter> to exit the feels engine. \n \n " )
sys . exit ( stop ( ) )
else :
2018-03-23 03:39:07 +00:00
print ( config . mystery_error )
2018-03-16 05:30:48 +00:00
else :
print ( " \n account deletion canceled! you ' re welcome to come back again. " )
input ( " \n \n press <enter> to go back to managing your feels. \n \n " )
redraw ( )
return
2018-03-17 01:53:52 +00:00
def load_backup ( ) :
"""
scans for archive files ( prompting for a file location if not found ) , opens ,
copies files to main feels directory ( skipping ones that already exist )
"""
print ( " scanning backup directory at {directory} ... " . format ( directory = config . BACKUPS ) )
2018-03-22 17:30:32 +00:00
time . sleep ( .5 )
2018-03-17 01:53:52 +00:00
print ( " ... \n " )
backups = [ ]
try :
for filename in os . listdir ( config . BACKUPS ) :
2018-03-22 03:34:34 +00:00
if " feels-backup " in filename and " .tar " in filename :
2018-03-17 01:53:52 +00:00
backups . append ( filename )
except FileNotFoundError :
subprocess . call ( [ " mkdir " , config . BACKUPS ] )
if len ( backups ) < 1 :
2018-03-22 17:30:32 +00:00
print ( """
2018-03-17 01:53:52 +00:00
sorry , i didn ' t find any feels backups! if you have a backup file handy, please
2018-03-22 16:55:04 +00:00
move it to { directory } and try running this tool again . \
""" .format(directory=config.BACKUPS))
2018-03-17 01:53:52 +00:00
else :
print ( " backup files found: \n " )
choice = menu_handler ( backups , " pick a backup file to load (or ' q ' to cancel): " , 15 , SETTINGS . get ( " rainbows " , False ) , " backup files found: " )
2018-03-22 03:34:34 +00:00
if choice is not False :
imports = core . process_backup ( os . path . join ( config . BACKUPS , backups [ choice ] ) )
for feel in imports :
2018-03-22 16:55:04 +00:00
print ( " importing {entry} " . format ( entry = " - " . join ( util . parse_date ( feel ) ) ) )
subprocess . call ( [ " mv " , feel , config . MAIN_FEELS ] )
2018-03-22 03:34:34 +00:00
time . sleep ( .01 )
2018-03-17 02:38:01 +00:00
2018-03-22 22:43:45 +00:00
core . load_files ( )
2018-03-22 03:34:34 +00:00
tempdir = os . path . join ( config . BACKUPS , os . path . splitext ( os . path . splitext ( os . path . basename ( backups [ choice ] ) ) [ 0 ] ) [ 0 ] , " entries " )
2018-03-17 02:38:01 +00:00
2018-03-22 17:30:32 +00:00
time . sleep ( .5 )
print ( " ... \n " )
2018-03-22 16:55:04 +00:00
if len ( os . listdir ( tempdir ) ) == 0 :
2018-03-22 17:30:32 +00:00
os . rmdir ( tempdir )
2018-03-22 03:34:34 +00:00
print ( " congrats! your feels archive has been unloaded. " )
else :
print ( """ \
i ' ve unloaded as much as i can, but there are still some feels i didn ' t copy
over . this is probably because you have current feels on the same days , and i
didn ' t want to overwrite them.
2018-03-17 02:38:01 +00:00
2018-03-22 03:34:34 +00:00
you can check out the leftover feels yourself at :
2018-03-17 01:53:52 +00:00
2018-03-22 03:34:34 +00:00
{ directory } """ .format(directory=tempdir))
else :
return
input ( " \n \n press <enter> to go back to managing your feels. \n \n " )
2018-03-17 01:53:52 +00:00
return
2018-03-22 17:46:41 +00:00
def bury_feels ( ) :
""" queries for a feel to bury, then calls the feels burying handler.
"""
2018-03-23 03:39:07 +00:00
feel = input ( config . bury_feels_prompt )
2018-03-22 21:07:07 +00:00
if feel in util . BACKS :
return
print ( " ... " )
time . sleep ( 0.1 )
print ( """ \
here ' s a preview of that feel. press <q> when you ' re done reviewing !
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """ )
if subprocess . call ( [ " less " , os . path . join ( config . MAIN_FEELS , feel + " .txt " ) ] ) :
redraw ( " burying feels " )
print ( """ \
sorry , i couldn ' t find feels for {date} !
please try again , or type < q > to cancel .
""" .format(date=feel))
return delete_feels ( )
print ( """
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
feels burying is irreversible ! if you ' re sure you want to bury this feel,
type the date again to confirm , or ' q ' to cancel .
""" )
confirm = input ( " [ {feeldate} ]> " . format ( feeldate = feel ) )
if confirm == feel :
print ( " ... " )
time . sleep ( 0.5 )
core . bury_feel ( feel + " .txt " )
print ( " feels buried! " )
else :
print ( " burying canceled! " )
ans = util . input_yn ( """ do you want to bury a different feel? please enter """ )
if ans :
redraw ( " burying feels " )
return bury_feels ( )
else :
print ( " okay! please come back any time if you want to bury your feels! " )
input ( " \n \n press <enter> to go back to managing your feels. \n \n " )
redraw ( )
2018-03-22 17:46:41 +00:00
return
2016-05-11 03:54:44 +00:00
def show_credits ( ) :
2016-05-23 02:42:31 +00:00
'''
prints author acknowledgements and commentary
'''
2016-05-11 03:54:44 +00:00
2018-03-12 00:17:20 +00:00
print ( config . credits )
2018-02-23 20:28:25 +00:00
input ( " \n \n press <enter> to go back home. \n \n " )
2016-05-11 03:54:44 +00:00
redraw ( )
return
## handlers
2018-03-16 02:41:22 +00:00
def write_entry ( entry = os . path . join ( config . MAIN_FEELS , " test.txt " ) ) :
2016-05-23 02:42:31 +00:00
'''
main feels - recording handler
'''
2016-05-11 03:54:44 +00:00
2018-03-12 00:17:20 +00:00
entered = input ( config . recording )
2016-05-15 04:22:05 +00:00
2016-05-11 03:54:44 +00:00
if entered :
entryFile = open ( entry , " a " )
entryFile . write ( " \n " + entered + " \n " )
entryFile . close ( )
2016-05-31 07:20:15 +00:00
subprocess . call ( [ SETTINGS . get ( " editor " ) , entry ] )
2016-05-20 03:35:34 +00:00
left = " "
2018-03-12 00:17:20 +00:00
core . load_files ( )
2018-02-28 22:29:10 +00:00
if SETTINGS . get ( " post as nopub " ) :
2018-02-28 18:16:51 +00:00
core . toggle_nopub ( os . path . basename ( entry ) )
else :
if core . publishing ( ) :
2018-03-16 02:41:22 +00:00
core . write_html ( " index.html " )
left = " posted to {url} /index.html \n \n > " . format (
2018-02-28 18:16:51 +00:00
url = " / " . join (
[ config . LIVE + config . USER ,
str ( SETTINGS . get ( " publish dir " ) ) ] ) )
if SETTINGS . get ( ' gopher ' ) :
2018-03-16 02:41:22 +00:00
gopher . publish_gopher ( ' feels ' , core . FILES )
left + = " also posted to your ~/public_gopher! \n \n > "
2018-02-28 18:16:51 +00:00
2018-03-12 00:17:20 +00:00
#core.load_files()
2018-03-16 02:41:22 +00:00
redraw ( left + " thanks for sharing your feels! " )
2016-05-20 03:35:34 +00:00
2016-05-11 03:54:44 +00:00
return
2018-01-03 00:13:38 +00:00
def list_nopubs ( user ) :
2016-10-10 21:53:02 +00:00
'''
handler for toggling nopub on individual entries
'''
2018-01-03 00:00:02 +00:00
metas , owner = generate_feels_list ( user )
if len ( metas ) > 0 :
2018-01-03 01:12:43 +00:00
return set_nopubs ( metas , user , " publishing status of your feels: " )
2018-01-03 00:00:02 +00:00
else :
redraw ( " no feels recorded by ~ " + user )
2018-01-03 01:12:43 +00:00
def set_nopubs ( metas , user , prompt ) :
2018-01-03 00:00:02 +00:00
""" displays a list of entries for pub/nopub toggling.
"""
2018-03-12 02:30:10 +00:00
if core . publishing ( ) :
nopub_note = " "
else :
nopub_note = """ \
( since you ' re not publishing your entries, these settings don ' t really matter ;
none of your feels will be viewable outside of this server ) """
print ( nopub_note + " \n " )
2018-01-03 01:12:43 +00:00
entries = [ ]
for entry in metas :
pub = " "
if core . nopub ( entry [ 0 ] ) :
pub = " (nopub) "
entries . append ( " " + entry [ 4 ] + " ( " + p . no ( " word " , entry [ 2 ] ) + " ) " + " \t " + pub )
2018-01-03 00:57:26 +00:00
2018-03-22 21:38:21 +00:00
choice = menu_handler ( entries , " pick an entry from the list to toggle nopub status, or type ' q ' to go back: " , 10 , SETTINGS . get ( " rainbows " , False ) , prompt + " \n \n " + nopub_note )
2018-01-03 00:00:02 +00:00
if choice is not False :
2018-01-03 00:13:38 +00:00
target = os . path . basename ( metas [ choice ] [ 0 ] )
2018-01-03 00:57:26 +00:00
action = core . toggle_nopub ( target )
2018-01-03 00:00:02 +00:00
redraw ( prompt )
2018-01-03 05:38:16 +00:00
if SETTINGS [ " gopher " ] :
gopher . publish_gopher ( ' feels ' , core . get_files ( ) )
2018-01-03 01:12:43 +00:00
return set_nopubs ( metas , user , prompt )
2018-01-03 00:00:02 +00:00
else :
redraw ( )
return
2016-10-10 21:53:02 +00:00
2016-05-22 04:45:04 +00:00
def send_feedback ( entered , subject = " none " ) :
2016-05-23 02:42:31 +00:00
'''
main feedback / bug report handler
'''
2016-05-11 03:54:44 +00:00
2016-05-15 04:22:05 +00:00
message = " "
2016-05-11 03:54:44 +00:00
temp = tempfile . NamedTemporaryFile ( )
2016-05-15 04:22:05 +00:00
if entered :
msgFile = open ( temp . name , " a " )
msgFile . write ( entered + " \n " )
msgFile . close ( )
2016-05-11 03:54:44 +00:00
subprocess . call ( [ SETTINGS [ " editor " ] , temp . name ] )
2016-05-15 04:22:05 +00:00
message = open ( temp . name , ' r ' ) . read ( )
2016-10-10 21:53:02 +00:00
if message :
id = " # " + util . genID ( 3 )
mail = MIMEText ( message )
2017-11-21 06:02:10 +00:00
mail [ ' To ' ] = config . FEEDBOX
mail [ ' From ' ] = config . USER + " @tilde.town "
2016-10-10 21:53:02 +00:00
mail [ ' Subject ' ] = " " . join ( [ " [ttbp] " , subject , id ] )
m = os . popen ( " /usr/sbin/sendmail -t -oi " , ' w ' )
m . write ( mail . as_string ( ) )
m . close ( )
exit = """ \
2016-05-15 04:22:05 +00:00
thanks for writing ! for your reference , it ' s been recorded
> as """ + " " .join([subject, id])+ """ . i ' ll try to respond to you soon. \
2016-10-10 21:53:02 +00:00
"""
else :
exit = """ \
i didn ' t send your blank message. if you made a mistake, please try
running through the feedback option again ! \
"""
return exit
2016-05-11 03:54:44 +00:00
2016-05-23 02:42:31 +00:00
def list_entries ( metas , entries , prompt ) :
'''
2018-01-03 00:00:02 +00:00
displays a list of entries for reading selection , allowing user to select
one for display .
2016-05-23 02:42:31 +00:00
'''
2016-05-04 15:00:28 +00:00
2018-01-02 06:21:48 +00:00
choice = menu_handler ( entries , " pick an entry from the list, or type ' q ' to go back: " , 10 , SETTINGS . get ( " rainbows " , False ) , prompt )
2016-05-09 02:59:48 +00:00
if choice is not False :
2016-05-05 00:04:16 +00:00
2017-12-31 16:52:56 +00:00
redraw ( " now reading ~ {user} ' s feels on {date} \n > press <q> to return to feels list. \n \n " . format ( user = metas [ choice ] [ 5 ] ,
date = metas [ choice ] [ 4 ] ) )
2016-05-05 00:04:16 +00:00
2016-05-09 02:59:48 +00:00
show_entry ( metas [ choice ] [ 0 ] )
redraw ( prompt )
2016-05-05 00:04:16 +00:00
2016-05-23 02:42:31 +00:00
return list_entries ( metas , entries , prompt )
2016-05-09 02:59:48 +00:00
else :
redraw ( )
return
2016-05-05 00:04:16 +00:00
def show_entry ( filename ) :
2016-05-23 02:42:31 +00:00
'''
call less on passed in filename
'''
2016-05-05 00:04:16 +00:00
subprocess . call ( [ " less " , filename ] )
return
def view_feed ( ) :
2016-05-23 02:42:31 +00:00
'''
generate and display list of most recent global entries
'''
2016-05-05 00:04:16 +00:00
feedList = [ ]
2016-05-31 07:20:15 +00:00
for townie in core . find_ttbps ( ) :
2016-05-05 00:04:16 +00:00
entryDir = os . path . join ( " /home " , townie , " .ttbp " , " entries " )
2018-02-25 05:16:37 +00:00
try :
filenames = os . listdir ( entryDir )
except OSError :
filenames = [ ]
2016-05-15 04:22:05 +00:00
2016-05-05 00:04:16 +00:00
for entry in filenames :
2017-12-31 16:52:56 +00:00
## hardcoded display cutoff at 30 days
2017-11-07 17:19:35 +00:00
if core . valid ( entry ) :
2017-11-26 02:39:58 +00:00
year = int ( entry [ 0 : 4 ] )
month = int ( entry [ 4 : 6 ] )
day = int ( entry [ 6 : 8 ] )
datecheck = datetime . date ( year , month , day )
displayCutoff = datetime . date . today ( ) - datetime . timedelta ( days = 30 )
if datecheck > displayCutoff :
2017-11-07 17:19:35 +00:00
feedList . append ( os . path . join ( entryDir , entry ) )
2016-05-05 00:22:14 +00:00
2016-05-05 00:04:16 +00:00
metas = core . meta ( feedList )
metas . sort ( key = lambda entry : entry [ 3 ] )
metas . reverse ( )
2016-05-05 00:22:14 +00:00
2016-05-05 00:04:16 +00:00
entries = [ ]
for entry in metas [ 0 : 10 ] :
pad = " "
if len ( entry [ 5 ] ) < 8 :
pad = " \t "
2017-12-31 16:52:56 +00:00
entries . append ( " ~ {user} {pad} \t on {date} ( {wordcount} ) " . format (
user = entry [ 5 ] , pad = pad , date = entry [ 3 ] ,
wordcount = p . no ( " word " , entry [ 2 ] ) ) )
2016-05-05 00:04:16 +00:00
2016-10-10 21:53:02 +00:00
list_entries ( metas , entries , " most recent global entries: " )
2016-05-04 15:00:28 +00:00
2016-05-03 17:14:53 +00:00
redraw ( )
2016-05-05 00:04:16 +00:00
2016-05-03 17:14:53 +00:00
return
2016-05-15 04:22:05 +00:00
2016-05-31 07:20:15 +00:00
def graffiti_handler ( ) :
2016-05-23 02:42:31 +00:00
'''
2016-05-31 07:20:15 +00:00
Main graffiti handler .
2016-05-23 02:42:31 +00:00
'''
2016-05-05 00:04:16 +00:00
2017-11-21 06:02:10 +00:00
if os . path . isfile ( config . WALL_LOCK ) :
2017-12-31 16:52:56 +00:00
redraw ( " sorry, {friend} , but someone ' s there right now. try again in a few! " . format ( friend = chatter . say ( " friend " ) ) )
2016-05-20 03:35:34 +00:00
else :
2017-11-21 06:02:10 +00:00
subprocess . call ( [ " touch " , config . WALL_LOCK ] )
2016-05-31 07:20:15 +00:00
redraw ( )
print ( """ \
the graffiti wall is a world - writeable text file . anyone can
scribble on it ; anyone can move or delete things . please be
considerate of your neighbors when writing on it .
2016-05-20 03:35:34 +00:00
2016-05-31 07:20:15 +00:00
no one will be able to visit the wall while you are here , so don ' t
worry about overwriting someone else ' s work. anything you do to the
wall will be recorded if you save the file , and you can cancel
your changes by exiting without saving .
2016-05-20 03:35:34 +00:00
2016-05-31 07:20:15 +00:00
""" )
2018-02-23 20:28:25 +00:00
input ( " press <enter> to visit the wall \n \n " )
2017-11-21 06:02:10 +00:00
subprocess . call ( [ SETTINGS . get ( " editor " ) , config . WALL ] )
subprocess . call ( [ " rm " , config . WALL_LOCK ] )
2016-05-31 07:20:15 +00:00
redraw ( " thanks for visiting the graffiti wall! " )
2016-05-20 03:35:34 +00:00
2016-05-31 07:20:15 +00:00
## misc helpers
2016-05-20 03:35:34 +00:00
2018-02-28 17:23:34 +00:00
def toggle_pub_default ( ) :
""" setup helper for setting default publish privacy (does not apply
retroactively ) . """
2018-02-28 22:29:10 +00:00
if SETTINGS . get ( " post as nopub " , False ) is True :
2018-02-28 17:23:34 +00:00
( nopub , will ) = ( " (nopub) " , " won ' t " )
else :
( nopub , will ) = ( " public " , " will " )
if SETTINGS . get ( " publishing " , False ) is True :
publishing = " "
else :
publishing = """ \
since you ' re currently not publishing your posts to html/gopher, this setting
won ' t affect the visibility of your posts. however, the option is still here if
you ' d like to change it.
"""
print ( """
DEFAULT POST PRIVACY
your entries are set to automatically post as { nopub } . this means they { will } be
posted to your world - visible pages at first ( which you can always change after
the fact . )
this setting only affects subsequent posts ; it does not apply retroactively .
{ publishing } """ .format(nopub=nopub, will=will, publishing=publishing))
ans = util . input_yn ( """ \
would you like to change this behavior ?
please enter """ )
if ans :
2018-02-28 22:29:10 +00:00
return not SETTINGS . get ( " post as nopub " )
2018-02-28 17:23:34 +00:00
else :
2018-02-28 22:29:10 +00:00
return SETTINGS . get ( " post as nopub " )
2018-02-28 17:23:34 +00:00
2018-01-02 06:21:48 +00:00
def toggle_rainbows ( ) :
""" setup helper for rainbow toggling
"""
if SETTINGS . get ( " rainbows " , False ) is True :
status = " enabled "
else :
status = " disabled "
print ( " \n RAINBOW MENU TOGGLING " )
print ( " rainbow menus are currently {status} " . format ( status = status ) )
publish = util . input_yn ( """ \
would you like to have rainbow menus ?
please enter \
""" )
return publish
2016-05-20 03:35:34 +00:00
def select_editor ( ) :
2016-05-23 02:42:31 +00:00
'''
setup helper for editor selection
'''
2016-05-20 03:35:34 +00:00
2017-12-31 16:52:56 +00:00
print ( " \n TEXT EDITOR SELECTION " )
2017-12-06 03:50:45 +00:00
print ( " your current editor is: " + SETTINGS . get ( " editor " ) )
2018-01-02 06:21:48 +00:00
util . print_menu ( EDITORS , SETTINGS . get ( " rainbows " , False ) )
2017-12-06 03:50:45 +00:00
choice = util . list_select ( EDITORS , " pick your favorite text editor, or type ' q ' to go back: " )
2016-10-10 21:53:02 +00:00
if choice is False :
2017-12-06 03:50:45 +00:00
# if selection is canceled, return either previously set editor or default
return SETTINGS . get ( " editor " , EDITORS [ 0 ] )
2016-05-20 03:35:34 +00:00
return EDITORS [ int ( choice ) ]
def select_publish_dir ( ) :
2016-05-23 02:42:31 +00:00
'''
setup helper for publish directory selection
'''
2016-05-20 03:35:34 +00:00
2017-12-31 16:52:56 +00:00
if not core . publishing ( ) :
return None
2016-05-20 03:35:34 +00:00
current = SETTINGS . get ( " publish dir " )
republish = False
2017-12-31 16:52:56 +00:00
print ( " \n UPDATING HTML PATH " )
2016-05-20 03:35:34 +00:00
if current :
2017-11-21 06:02:10 +00:00
print ( " \n current publish dir: \t " + os . path . join ( config . PUBLIC , SETTINGS [ " publish dir " ] ) )
2016-05-20 03:35:34 +00:00
republish = True
2018-02-23 20:28:25 +00:00
choice = input ( " \n where do you want your blog published? (leave blank to use default \" blog \" ) " )
2016-05-20 03:35:34 +00:00
if not choice :
choice = " blog "
2017-11-21 06:02:10 +00:00
publishDir = os . path . join ( config . PUBLIC , choice )
2016-05-20 03:35:34 +00:00
while os . path . exists ( publishDir ) :
2018-03-12 00:17:20 +00:00
second = input ( """
{ pDir } already exists !
2016-05-23 02:42:31 +00:00
2016-05-20 03:35:34 +00:00
setting this as your publishing directory means this program may
delete or overwrite file there !
2016-05-23 02:42:31 +00:00
2016-05-20 03:35:34 +00:00
if you ' re sure you want to use it, hit <enter> to confirm.
2018-03-12 00:29:02 +00:00
otherwise , pick another location : """ .format(pDir=publishDir))
2016-05-23 02:42:31 +00:00
2016-05-20 03:35:34 +00:00
if second == " " :
break
choice = second
2017-11-21 06:02:10 +00:00
publishDir = os . path . join ( config . PUBLIC , choice )
2016-05-20 03:35:34 +00:00
return choice
def select_publishing ( ) :
2016-05-23 02:42:31 +00:00
'''
setup helper for toggling publishing
'''
2016-05-20 03:35:34 +00:00
2016-05-31 07:20:15 +00:00
publish = util . input_yn ( """ \
2017-12-31 16:52:56 +00:00
SETTING UP PUBLISHING
2016-05-20 03:35:34 +00:00
do you want to publish your feels online ?
if yes , your feels will be published to a directory of your choice in
your public_html . i ' ll confirm the location of that directory in a
moment .
if not , your feels will only be readable from within the tilde . town
network . if you already have a publishing directory , i ' ll remove it for
you ( don ' t worry, your written entries will still be saved!)
you can change this option any time .
please enter \
""" )
return publish
def unpublish ( ) :
2017-12-31 18:40:20 +00:00
''' remove all published entries in html and gopher.
2016-05-23 02:42:31 +00:00
'''
2017-12-31 18:40:20 +00:00
global SETTINGS
2017-11-21 06:02:10 +00:00
directory = SETTINGS . get ( " publish dir " )
2017-12-31 18:40:20 +00:00
2017-11-21 06:39:38 +00:00
if directory :
2017-11-21 06:02:10 +00:00
publishDir = os . path . join ( config . PUBLIC , directory )
2018-03-22 17:40:34 +00:00
if os . path . exists ( publishDir ) :
subprocess . call ( [ " rm " , " -rf " , publishDir ] )
2018-03-23 01:59:19 +00:00
subprocess . call ( [ " rm " , " -rf " , config . WWW ] )
make_publish_dir ( SETTINGS . get ( " publish dir " ) )
2018-03-22 22:43:45 +00:00
#SETTINGS.update({"publish dir": None})
2016-05-20 03:35:34 +00:00
2017-12-31 18:40:20 +00:00
if SETTINGS . get ( " gopher " ) :
2018-03-23 01:59:19 +00:00
gopher . unpublish ( )
2017-12-31 18:40:20 +00:00
2016-05-20 03:35:34 +00:00
def update_publishing ( ) :
2016-05-23 02:42:31 +00:00
'''
updates publishing directory if user is publishing . otherwise , wipe it .
'''
2016-05-20 03:35:34 +00:00
global SETTINGS
2016-05-31 07:20:15 +00:00
if core . publishing ( ) :
2016-05-20 03:35:34 +00:00
oldDir = SETTINGS . get ( " publish dir " )
newDir = select_publish_dir ( )
SETTINGS . update ( { " publish dir " : newDir } )
if oldDir :
2017-11-21 06:02:10 +00:00
subprocess . call ( [ " rm " , os . path . join ( config . PUBLIC , oldDir ) ] )
2016-05-20 03:35:34 +00:00
make_publish_dir ( newDir )
core . load_files ( )
2018-03-22 22:43:45 +00:00
#core.write_html("index.html")
2016-05-20 03:35:34 +00:00
else :
unpublish ( )
2016-06-15 02:39:03 +00:00
core . load ( SETTINGS )
2018-03-23 01:59:19 +00:00
def make_publish_dir ( publish_dir ) :
2016-05-23 02:42:31 +00:00
'''
setup helper to create publishing directory
'''
2016-05-20 03:35:34 +00:00
2017-11-21 06:02:10 +00:00
if not os . path . exists ( config . WWW ) :
subprocess . call ( [ " mkdir " , config . WWW ] )
subprocess . call ( [ " ln " , " -s " , os . path . join ( config . USER_CONFIG , " style.css " ) , os . path . join ( config . WWW , " style.css " ) ] )
subprocess . call ( [ " touch " , os . path . join ( config . WWW , " index.html " ) ] )
index = open ( os . path . join ( config . WWW , " index.html " ) , " w " )
2016-05-20 03:35:34 +00:00
index . write ( " <h1>ttbp blog placeholder</h1> " )
index . close ( )
2018-03-23 01:59:19 +00:00
if core . publishing ( ) :
live = os . path . join ( config . PUBLIC , publish_dir )
if os . path . exists ( live ) :
subprocess . call ( [ " rm " , live ] )
subprocess . call ( [ " ln " , " -s " , config . WWW , live ] )
2016-05-20 03:35:34 +00:00
2018-03-23 01:59:19 +00:00
return " \n \t publishing to " + config . LIVE + config . USER + " / " + SETTINGS . get ( " publish dir " ) + " / \n \n "
2016-05-20 03:35:34 +00:00
2018-03-23 01:59:19 +00:00
else :
return " "
#print("\n\tpublishing to "+config.LIVE+config.USER+"/"+SETTINGS.get("publish dir")+"/\n\n")
2016-05-20 03:35:34 +00:00
2017-12-31 16:52:56 +00:00
def update_gopher ( ) :
'''
helper for toggling gopher settings
'''
# TODO for now i'm hardcoding where people's gopher stuff is generated. if
# there is demand for this to be configurable we can expose that.
if SETTINGS . get ( " gopher " ) :
gopher . setup_gopher ( ' feels ' )
2018-01-03 05:38:16 +00:00
gopher . publish_gopher ( " feels " , core . get_files ( ) )
else :
subprocess . call ( [ " rm " , config . GOPHER_PATH ] )
2017-12-31 16:52:56 +00:00
redraw ( " gopher publishing set to {gopher} " . format ( gopher = SETTINGS . get ( " gopher " ) ) )
2016-05-23 02:42:31 +00:00
##### PATCHING UTILITIES
2016-05-20 03:35:34 +00:00
2018-01-02 06:21:48 +00:00
def user_up_to_date ( ) :
2016-05-23 02:42:31 +00:00
'''
checks to see if current user is up to the same version as system
'''
2016-05-20 03:35:34 +00:00
2017-11-21 06:02:10 +00:00
versionFile = os . path . join ( config . PATH , " version " )
2016-05-20 03:35:34 +00:00
if not os . path . exists ( versionFile ) :
2016-05-27 03:59:04 +00:00
return False
2016-05-20 03:35:34 +00:00
ver = open ( versionFile , " r " ) . read ( )
2016-05-23 02:42:31 +00:00
if ver == __version__ :
2016-05-20 03:35:34 +00:00
return True
return False
2018-01-02 06:21:48 +00:00
def update_user_version ( ) :
2016-05-23 02:42:31 +00:00
'''
2017-12-31 16:52:56 +00:00
updates user to current version , printing relevant release notes and
stepping through new features .
2016-05-23 02:42:31 +00:00
'''
2016-05-20 03:35:34 +00:00
global SETTINGS
2017-11-21 06:02:10 +00:00
versionFile = os . path . join ( config . PATH , " version " )
2016-05-20 03:35:34 +00:00
print ( " ttbp had some updates! " )
2016-05-23 02:42:31 +00:00
print ( " \n give me a second to update you to version " + __version__ + " ... \n " )
2016-05-20 15:06:42 +00:00
time . sleep ( 1 )
print ( " ... " )
2018-03-22 17:30:32 +00:00
time . sleep ( 0.5 )
2016-05-20 03:35:34 +00:00
2016-05-31 07:20:15 +00:00
userVersion = " "
2018-01-02 06:21:48 +00:00
( x , y , z ) = [ 0 , 0 , 0 ]
2016-05-31 07:20:15 +00:00
2016-05-20 15:06:42 +00:00
if not os . path . isfile ( versionFile ) :
2018-01-02 06:21:48 +00:00
# updates from 0.8.5 to 0.8.6, before versionfile existed
2016-05-20 03:35:34 +00:00
# change style.css location
2016-09-08 02:05:38 +00:00
if core . publishing ( ) :
2017-11-21 06:02:10 +00:00
if os . path . isfile ( os . path . join ( config . WWW , " style.css " ) ) :
subprocess . call ( [ " mv " , os . path . join ( config . WWW , " style.css " ) , config . USER_CONFIG ] )
2016-05-20 03:35:34 +00:00
2016-09-08 02:05:38 +00:00
# change www symlink
2017-11-21 06:02:10 +00:00
if os . path . exists ( config . WWW ) :
subprocess . call ( [ " rm " , config . WWW ] )
2016-09-08 02:29:12 +00:00
2017-11-21 06:02:10 +00:00
subprocess . call ( [ " mkdir " , config . WWW ] )
2016-05-20 03:35:34 +00:00
2017-11-21 06:02:10 +00:00
subprocess . call ( [ " ln " , " -s " , os . path . join ( config . USER_CONFIG , " style.css " ) , os . path . join ( config . WWW , " style.css " ) ] )
2016-05-20 03:35:34 +00:00
2017-11-21 06:02:10 +00:00
publishDir = os . path . join ( config . PUBLIC , SETTINGS . get ( " publish dir " ) )
2016-09-08 02:05:38 +00:00
if os . path . exists ( publishDir ) :
subprocess . call ( [ " rm " , " -rf " , publishDir ] )
2016-06-15 02:39:03 +00:00
2017-11-21 06:02:10 +00:00
subprocess . call ( [ " ln " , " -s " , config . WWW , os . path . join ( config . PUBLIC , SETTINGS . get ( " publish dir " ) ) ] )
2016-05-20 03:35:34 +00:00
2016-09-08 02:05:38 +00:00
# repopulate html files
core . load_files ( )
2018-03-22 22:43:45 +00:00
#core.write_html("index.html")
2016-05-20 03:35:34 +00:00
# add publishing setting
print ( " \n new feature! \n " )
SETTINGS . update ( { " publishing " : select_publishing ( ) } )
update_publishing ( )
2017-11-21 06:02:10 +00:00
ttbprc = open ( config . TTBPRC , " w " )
2016-05-20 15:06:42 +00:00
ttbprc . write ( json . dumps ( SETTINGS , sort_keys = True , indent = 2 , separators = ( ' , ' , ' : ' ) ) )
ttbprc . close ( )
else : # version at least 0.8.6
2016-05-31 07:20:15 +00:00
userVersion = open ( versionFile , " r " ) . read ( ) . rstrip ( )
2018-01-02 06:21:48 +00:00
x , y , z = [ int ( num ) for num in userVersion . split ( " . " ) ]
2016-05-23 02:42:31 +00:00
2016-05-31 07:20:15 +00:00
# from 0.8.6
2016-05-23 02:42:31 +00:00
if userVersion == " 0.8.6 " :
2016-05-20 15:06:42 +00:00
print ( " \n resetting your publishing settings... \n " )
SETTINGS . update ( { " publishing " : select_publishing ( ) } )
update_publishing ( )
2017-11-21 06:02:10 +00:00
ttbprc = open ( config . TTBPRC , " w " )
2016-05-20 15:06:42 +00:00
ttbprc . write ( json . dumps ( SETTINGS , sort_keys = True , indent = 2 , separators = ( ' , ' , ' : ' ) ) )
ttbprc . close ( )
2016-05-20 03:35:34 +00:00
2017-12-05 01:29:28 +00:00
# from earlier than 0.10.1
2018-01-02 06:21:48 +00:00
if y < 10 :
2017-12-05 01:29:28 +00:00
# select gopher
print ( " [ NEW FEATURE ] " )
print ( """
* thanks to help from ~ vilmibm , ttbp now supports publishing to gopher !
* if you enable gopher publishing , feels will automatically publish to
gopher : / / tilde . town / 1 / ~ """ +config.USER+ """ / feels
""" )
SETTINGS . update ( { ' gopher ' : gopher . select_gopher ( ) } )
2017-12-06 04:00:21 +00:00
if SETTINGS . get ( ' gopher ' ) :
print ( " opting into gopher: " + str ( SETTINGS [ ' gopher ' ] ) )
gopher . setup_gopher ( ' feels ' )
else :
print ( " okay, passing on gopher for now. this option is available in settings if you change \n your mind! " )
2017-12-05 01:29:28 +00:00
2018-01-03 04:31:17 +00:00
if y < 11 :
# set rainbow menu for 0.11.0
2018-01-02 06:21:48 +00:00
print ( " [ NEW FEATURE ] " )
SETTINGS . update ( { " rainbows " : toggle_rainbows ( ) } )
2018-02-28 22:29:10 +00:00
if z < 2 :
# set default option for 0.11.2
# print("default nopub: false")
SETTINGS . update ( { " post as nopub " : False } )
save_settings ( )
2018-03-11 23:57:54 +00:00
if z < 3 :
# update permalink css
style = open ( os . path . join ( config . USER_CONFIG , ' style.css ' ) , ' r ' ) . read ( )
if " permalink " not in style :
print ( " adding new css... " )
with open ( os . path . join ( config . USER_CONFIG , ' style.css ' ) , ' a ' ) as f :
f . write ( """
. entry p . permalink {
font - size : .6 em ;
font - color : #808080;
text - align : right ;
} """ )
2016-06-10 01:18:34 +00:00
print ( """
2016-06-15 02:39:03 +00:00
you ' re all good to go, " " " +chatter.say( " friend " )+ " " " ! please contact ~endorphant if
2017-12-31 16:52:56 +00:00
something strange happened to you during this update .
2016-06-10 01:18:34 +00:00
""" )
2016-05-20 03:35:34 +00:00
2018-02-25 05:16:37 +00:00
if y < 10 :
2017-12-05 01:29:28 +00:00
# version 0.10.1 patch notes
2017-12-31 17:21:05 +00:00
print ( config . UPDATES [ " 0.10.1 " ] )
2017-12-31 16:52:56 +00:00
2018-01-03 04:31:17 +00:00
if y < 11 :
2018-02-25 05:16:37 +00:00
# version 0.11.0 patch notes
2018-01-03 04:31:17 +00:00
print ( config . UPDATES [ " 0.11.0 " ] )
2018-01-02 06:21:48 +00:00
2018-02-25 05:16:37 +00:00
if y < 11 or z < 1 :
# version 0.11.1 patch notes
print ( config . UPDATES [ " 0.11.1 " ] )
2018-02-28 22:29:10 +00:00
if y < 11 or z < 2 :
# version 0.11.2 patch notes
print ( config . UPDATES [ " 0.11.2 " ] )
2018-03-11 23:57:54 +00:00
if y < 11 or z < 3 :
# version 0.11.3 patch notes
print ( config . UPDATES [ " 0.11.3 " ] )
2018-03-22 21:38:21 +00:00
if y < 12 :
# version 0.12.0 patch notes
print ( config . UPDATES [ " 0.12.0 " ] )
2017-12-31 17:28:42 +00:00
confirm = " "
2017-12-31 17:31:09 +00:00
while confirm not in ( " x " , " <x> " , " X " , " <X> " ) :
2018-02-23 20:28:25 +00:00
confirm = input ( " \n please type <x> when you ' ve finished reading about the updates! " )
2017-12-31 17:28:42 +00:00
2018-02-25 05:16:37 +00:00
print ( " \n \n " )
2017-12-31 16:52:56 +00:00
open ( versionFile , " w " ) . write ( __version__ )
2016-05-20 03:35:34 +00:00
2016-05-05 00:04:16 +00:00
#####
2016-05-22 04:45:04 +00:00
if __name__ == ' __main__ ' :
2017-12-31 16:52:56 +00:00
sys . exit ( main ( ) )