commit
b4b2b34158
|
@ -0,0 +1,3 @@
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
*.egg-info
|
|
@ -1,8 +0,0 @@
|
||||||
__________________________________________________________
|
|
||||||
| |
|
|
||||||
| the tilde.town |
|
|
||||||
| ____ ____ ____ _ ____ ____ _ _ ____ _ _ _ ____ |
|
|
||||||
| |___ |___ |___ | [__ |___ |\ | | __ | |\ | |___ |
|
|
||||||
| | |___ |___ |___ ___] |___ | \| |__] | | \| |___ |
|
|
||||||
| ver 0.9.2 (almost stable) |
|
|
||||||
|__________________________________________________________|
|
|
|
@ -25,6 +25,10 @@ TO-DO:
|
||||||
------
|
------
|
||||||
|
|
||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
|
ver 0.9.3
|
||||||
|
-packaging
|
||||||
|
-easier to contribute to
|
||||||
|
|
||||||
ver 0.9.2
|
ver 0.9.2
|
||||||
-paginated scrolling
|
-paginated scrolling
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='ttbp',
|
||||||
|
version='0.9.3',
|
||||||
|
description='command line social blogging tool used on tilde.town',
|
||||||
|
url='https://github.com/modgethanc/ttbp',
|
||||||
|
author='~endorphant',
|
||||||
|
author_email='endorphant@tilde.town',
|
||||||
|
license='MIT',
|
||||||
|
classifiers=[
|
||||||
|
'Topic :: Artistic Software',
|
||||||
|
'License :: OSI Approved :: MIT License',
|
||||||
|
],
|
||||||
|
keywords='blog',
|
||||||
|
packages=['ttbp'],
|
||||||
|
install_requires = [
|
||||||
|
'inflect==0.2.5',
|
||||||
|
'mistune==0.8.1',
|
||||||
|
'colorama==0.3.9',
|
||||||
|
],
|
||||||
|
include_package_data = True,
|
||||||
|
entry_points = {
|
||||||
|
'console_scripts': [
|
||||||
|
'feels = ttbp.ttbp:start',
|
||||||
|
'ttbp = ttbp.ttbp:start',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
)
|
|
@ -0,0 +1,69 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
|
||||||
|
DEFAULT_LANG = {
|
||||||
|
"greet":[
|
||||||
|
"hi",
|
||||||
|
"hey",
|
||||||
|
"howdy",
|
||||||
|
"good morning",
|
||||||
|
"good afternoon",
|
||||||
|
"good day",
|
||||||
|
"good evening",
|
||||||
|
"welcome back",
|
||||||
|
"nice to see you"
|
||||||
|
],
|
||||||
|
"bye":[
|
||||||
|
"see you later, space cowboy",
|
||||||
|
"bye, townie",
|
||||||
|
"until next time, friend",
|
||||||
|
"come back whenever"
|
||||||
|
],
|
||||||
|
"friend":[
|
||||||
|
"friend",
|
||||||
|
"pal",
|
||||||
|
"buddy",
|
||||||
|
"townie"
|
||||||
|
],
|
||||||
|
"months":{
|
||||||
|
"01":"january",
|
||||||
|
"02":"february",
|
||||||
|
"03":"march",
|
||||||
|
"04":"april",
|
||||||
|
"05":"may",
|
||||||
|
"06":"june",
|
||||||
|
"07":"july",
|
||||||
|
"08":"august",
|
||||||
|
"09":"september",
|
||||||
|
"10":"october",
|
||||||
|
"11":"november",
|
||||||
|
"12":"december"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.path.exists("/home/endorphant/lib/python/chatterlib.json"):
|
||||||
|
with open("/home/endorphant/lib/python/chatterlib.json", 'r') as f:
|
||||||
|
LANG = json.load(f)
|
||||||
|
else:
|
||||||
|
LANG = DEFAULT_LANG
|
||||||
|
|
||||||
|
def say(keyword):
|
||||||
|
'''
|
||||||
|
takes a keyword and randomly returns from language dictionary to match that keyword
|
||||||
|
|
||||||
|
returns None if keyword doesn't exist
|
||||||
|
|
||||||
|
TODO: validate keyword?
|
||||||
|
'''
|
||||||
|
|
||||||
|
return random.choice(LANG.get(keyword))
|
||||||
|
|
||||||
|
def month(num):
|
||||||
|
'''
|
||||||
|
takes a MM and returns lovercase full name of that month
|
||||||
|
|
||||||
|
TODO: validate num?
|
||||||
|
'''
|
||||||
|
|
||||||
|
return LANG["months"].get(num)
|
|
@ -0,0 +1,86 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from .. import util
|
||||||
|
|
||||||
|
## System config
|
||||||
|
|
||||||
|
# We refer to some package files (ie .css stuff), so we save a reference to the
|
||||||
|
# path.
|
||||||
|
INSTALL_PATH = os.path.dirname(sys.modules['ttbp'].__file__)
|
||||||
|
|
||||||
|
# We use this to store any persisted, global state.
|
||||||
|
VAR = '/var/global/ttbp'
|
||||||
|
VAR_WWW = os.path.join(VAR, 'www')
|
||||||
|
|
||||||
|
if not os.path.isdir('/var/global'):
|
||||||
|
raise Exception('bad system state: /var/global does not exist.')
|
||||||
|
|
||||||
|
if not os.path.isdir(VAR):
|
||||||
|
os.mkdir(VAR)
|
||||||
|
|
||||||
|
if not os.path.isdir(VAR_WWW):
|
||||||
|
os.mkdir(VAR_WWW)
|
||||||
|
|
||||||
|
LIVE = 'https://tilde.town/~'
|
||||||
|
FEEDBOX = "endorphant@tilde.town"
|
||||||
|
USERFILE = os.path.join(VAR, "users.txt")
|
||||||
|
GRAFF_DIR = os.path.join(VAR, "graffiti")
|
||||||
|
WALL = os.path.join(GRAFF_DIR, "wall.txt")
|
||||||
|
WALL_LOCK = os.path.join(GRAFF_DIR, ".lock")
|
||||||
|
|
||||||
|
if not os.path.isdir(GRAFF_DIR):
|
||||||
|
os.mkdir(GRAFF_DIR)
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
|
||||||
|
DEFAULT_HEADER = '''
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>$USER on TTBP</title>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="meta">
|
||||||
|
<h1><a href="#">~$USER</a>@<a href="/~endorphant/ttbp">TTBP</a></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="tlogs">
|
||||||
|
'''.lstrip()
|
||||||
|
|
||||||
|
DEFAULT_FOOTER = '''
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
'''.lstrip()
|
||||||
|
|
||||||
|
with open(os.path.join(INSTALL_PATH, 'config', 'defaults', 'style.css')) as f:
|
||||||
|
DEFAULT_STYLE = f.read()
|
||||||
|
|
||||||
|
|
||||||
|
## User config
|
||||||
|
|
||||||
|
USER = os.path.basename(os.path.expanduser('~'))
|
||||||
|
USER_HOME = os.path.expanduser('~')
|
||||||
|
PATH = os.path.join(USER_HOME, '.ttbp')
|
||||||
|
PUBLIC = os.path.join(USER_HOME, 'public_html')
|
||||||
|
WWW = os.path.join(PATH, 'www')
|
||||||
|
USER_CONFIG = os.path.join(PATH, 'config')
|
||||||
|
TTBPRC = os.path.join(USER_CONFIG, 'ttbprc')
|
||||||
|
USER_DATA = os.path.join(PATH, 'entries')
|
||||||
|
NOPUB = os.path.join(USER_CONFIG, "nopub")
|
||||||
|
|
||||||
|
## UI
|
||||||
|
|
||||||
|
BANNER = '''
|
||||||
|
__________________________________________________________
|
||||||
|
| |
|
||||||
|
| the tilde.town |
|
||||||
|
| ____ ____ ____ _ ____ ____ _ _ ____ _ _ _ ____ |
|
||||||
|
| |___ |___ |___ | [__ |___ |\ | | __ | |\ | |___ |
|
||||||
|
| | |___ |___ |___ ___] |___ | \| |__] | | \| |___ |
|
||||||
|
| ver 0.10.0 (almost stable) |
|
||||||
|
|__________________________________________________________|
|
||||||
|
'''.lstrip()
|
|
@ -39,19 +39,10 @@ import re
|
||||||
import mistune
|
import mistune
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import chatter
|
from . import chatter
|
||||||
|
from . import config
|
||||||
|
|
||||||
SOURCE = os.path.join("/home", "endorphant", "projects", "ttbp", "bin")
|
FEED = os.path.join(config.VAR_WWW, "index.html")
|
||||||
USER = os.path.basename(os.path.expanduser("~"))
|
|
||||||
PATH = os.path.join("/home", USER, ".ttbp")
|
|
||||||
|
|
||||||
LIVE = "http://tilde.town/~"
|
|
||||||
WWW = os.path.join(PATH, "www")
|
|
||||||
CONFIG = os.path.join(PATH, "config")
|
|
||||||
DATA = os.path.join(PATH, "entries")
|
|
||||||
FEED = os.path.join(SOURCE, "www", "index.html")
|
|
||||||
DOCS = os.path.join(SOURCE, "www", "help.html")
|
|
||||||
NOPUB = os.path.join(CONFIG, "nopub")
|
|
||||||
SETTINGS = {}
|
SETTINGS = {}
|
||||||
|
|
||||||
HEADER = ""
|
HEADER = ""
|
||||||
|
@ -67,8 +58,8 @@ def load(ttbprc={}):
|
||||||
global FOOTER
|
global FOOTER
|
||||||
global SETTINGS
|
global SETTINGS
|
||||||
|
|
||||||
HEADER = open(os.path.join(CONFIG, "header.txt")).read()
|
HEADER = open(os.path.join(config.USER_CONFIG, "header.txt")).read()
|
||||||
FOOTER = open(os.path.join(CONFIG, "footer.txt")).read()
|
FOOTER = open(os.path.join(config.USER_CONFIG, "footer.txt")).read()
|
||||||
SETTINGS = ttbprc
|
SETTINGS = ttbprc
|
||||||
|
|
||||||
load_files()
|
load_files()
|
||||||
|
@ -94,13 +85,13 @@ def load_files():
|
||||||
|
|
||||||
FILES = []
|
FILES = []
|
||||||
|
|
||||||
for filename in os.listdir(DATA):
|
for filename in os.listdir(config.USER_DATA):
|
||||||
if nopub(filename):
|
if nopub(filename):
|
||||||
link = os.path.join(WWW, os.path.splitext(os.path.basename(filename))[0]+".html")
|
link = os.path.join(config.WWW, os.path.splitext(os.path.basename(filename))[0]+".html")
|
||||||
if os.path.exists(link):
|
if os.path.exists(link):
|
||||||
subprocess.call(["rm", link])
|
subprocess.call(["rm", link])
|
||||||
continue
|
continue
|
||||||
filename = os.path.join(DATA, filename)
|
filename = os.path.join(config.USER_DATA, filename)
|
||||||
if os.path.isfile(filename) and valid(filename):
|
if os.path.isfile(filename) and valid(filename):
|
||||||
FILES.append(filename)
|
FILES.append(filename)
|
||||||
|
|
||||||
|
@ -119,7 +110,7 @@ def write(outurl="default.html"):
|
||||||
* calls write_page() on each file to make permalinks
|
* calls write_page() on each file to make permalinks
|
||||||
'''
|
'''
|
||||||
|
|
||||||
outfile = open(os.path.join(WWW, outurl), "w")
|
outfile = open(os.path.join(config.WWW, outurl), "w")
|
||||||
|
|
||||||
outfile.write("<!--generated by the tilde.town blogging platform on "+time.strftime("%d %B %y")+"\nhttp://tilde.town/~endorphant/ttbp/-->\n\n")
|
outfile.write("<!--generated by the tilde.town blogging platform on "+time.strftime("%d %B %y")+"\nhttp://tilde.town/~endorphant/ttbp/-->\n\n")
|
||||||
|
|
||||||
|
@ -140,7 +131,7 @@ def write(outurl="default.html"):
|
||||||
|
|
||||||
outfile.close()
|
outfile.close()
|
||||||
|
|
||||||
return os.path.join(LIVE+USER,os.path.basename(os.path.realpath(WWW)),outurl)
|
return os.path.join(config.LIVE+config.USER,os.path.basename(os.path.realpath(config.WWW)),outurl)
|
||||||
|
|
||||||
def write_page(filename):
|
def write_page(filename):
|
||||||
'''
|
'''
|
||||||
|
@ -150,7 +141,7 @@ def write_page(filename):
|
||||||
url
|
url
|
||||||
'''
|
'''
|
||||||
|
|
||||||
outurl = os.path.join(WWW, "".join(parse_date(filename))+".html")
|
outurl = os.path.join(config.WWW, "".join(parse_date(filename))+".html")
|
||||||
outfile = open(outurl, "w")
|
outfile = open(outurl, "w")
|
||||||
|
|
||||||
outfile.write("<!--generated by the tilde.town blogging platform on "+time.strftime("%d %B %y")+"\nhttp://tilde.town/~endorphant/ttbp/-->\n\n")
|
outfile.write("<!--generated by the tilde.town blogging platform on "+time.strftime("%d %B %y")+"\nhttp://tilde.town/~endorphant/ttbp/-->\n\n")
|
||||||
|
@ -190,7 +181,7 @@ def write_entry(filename):
|
||||||
]
|
]
|
||||||
|
|
||||||
raw = []
|
raw = []
|
||||||
rawfile = open(os.path.join(DATA, filename), "r")
|
rawfile = open(os.path.join(config.USER_DATA, filename), "r")
|
||||||
|
|
||||||
for line in rawfile:
|
for line in rawfile:
|
||||||
raw.append(line)
|
raw.append(line)
|
||||||
|
@ -244,7 +235,7 @@ def write_global_feed(blogList):
|
||||||
## docs
|
## docs
|
||||||
outfile.write("""\
|
outfile.write("""\
|
||||||
<div class="docs">""")
|
<div class="docs">""")
|
||||||
outfile.write(mistune.markdown(open(os.path.join(SOURCE, "..", "README.md"), "r").read()))
|
outfile.write(mistune.markdown(open(os.path.join(config.INSTALL_PATH, "..", "README.md"), "r").read()))
|
||||||
outfile.write("""\
|
outfile.write("""\
|
||||||
</div>""")
|
</div>""")
|
||||||
|
|
||||||
|
@ -354,14 +345,14 @@ def find_ttbps():
|
||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
def publishing(username = USER):
|
def publishing(username=config.USER):
|
||||||
'''
|
'''
|
||||||
checks .ttbprc for whether or not user opted for www publishing
|
checks .ttbprc for whether or not user opted for www publishing
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ttbprc = {}
|
ttbprc = {}
|
||||||
|
|
||||||
if username == USER:
|
if username == config.USER:
|
||||||
ttbprc = SETTINGS
|
ttbprc = SETTINGS
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -384,7 +375,7 @@ def www_neighbors():
|
||||||
|
|
||||||
url = ""
|
url = ""
|
||||||
if userRC["publish dir"]:
|
if userRC["publish dir"]:
|
||||||
url = LIVE+user+"/"+userRC["publish dir"]
|
url = config.LIVE+user+"/"+userRC["publish dir"]
|
||||||
|
|
||||||
lastfile = ""
|
lastfile = ""
|
||||||
files = os.listdir(os.path.join("/home", user, ".ttbp", "entries"))
|
files = os.listdir(os.path.join("/home", user, ".ttbp", "entries"))
|
||||||
|
@ -418,8 +409,8 @@ def nopub(filename):
|
||||||
|
|
||||||
exclude = []
|
exclude = []
|
||||||
|
|
||||||
if os.path.isfile(NOPUB):
|
if os.path.isfile(config.NOPUB):
|
||||||
for line in open(NOPUB, "r"):
|
for line in open(config.NOPUB, "r"):
|
||||||
exclude.append(line.rstrip())
|
exclude.append(line.rstrip())
|
||||||
|
|
||||||
return os.path.basename(filename) in exclude
|
return os.path.basename(filename) in exclude
|
|
@ -31,6 +31,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
the complete codebase is available at:
|
the complete codebase is available at:
|
||||||
https://github.com/modgethanc/ttbp
|
https://github.com/modgethanc/ttbp
|
||||||
'''
|
'''
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
@ -41,41 +42,26 @@ import json
|
||||||
from email.mime.text import MIMEText;
|
from email.mime.text import MIMEText;
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import core
|
|
||||||
import chatter
|
|
||||||
import inflect
|
import inflect
|
||||||
import util
|
|
||||||
|
|
||||||
__version__ = "0.9.2"
|
from . import config
|
||||||
|
from . import core
|
||||||
|
from . import chatter
|
||||||
|
from . import util
|
||||||
|
|
||||||
|
__version__ = "0.9.3"
|
||||||
__author__ = "endorphant <endorphant@tilde.town)"
|
__author__ = "endorphant <endorphant@tilde.town)"
|
||||||
|
|
||||||
## system globals
|
|
||||||
SOURCE = os.path.join("/home", "endorphant", "projects", "ttbp", "bin")
|
|
||||||
LIVE = "http://tilde.town/~"
|
|
||||||
FEEDBACK = os.path.join("/home", "endorphant", "ttbp-mail")
|
|
||||||
FEEDBOX = "endorphant@tilde.town"
|
|
||||||
USERFILE = os.path.join("/home", "endorphant", "projects", "ttbp", "users.txt")
|
|
||||||
GRAFF_DIR = os.path.join(SOURCE, "graffiti")
|
|
||||||
WALL = os.path.join(GRAFF_DIR, "wall.txt")
|
|
||||||
WALL_LOCK = os.path.join(GRAFF_DIR, ".lock")
|
|
||||||
|
|
||||||
p = inflect.engine()
|
p = inflect.engine()
|
||||||
|
|
||||||
## user globals
|
## user globals
|
||||||
USER = os.path.basename(os.path.expanduser("~"))
|
|
||||||
PATH = os.path.join("/home", USER, ".ttbp")
|
|
||||||
PUBLIC = os.path.join("/home", USER, "public_html")
|
|
||||||
WWW = os.path.join(PATH, "www")
|
|
||||||
CONFIG = os.path.join(PATH, "config")
|
|
||||||
TTBPRC = os.path.join(CONFIG, "ttbprc")
|
|
||||||
DATA = os.path.join(PATH, "entries")
|
|
||||||
SETTINGS = {
|
SETTINGS = {
|
||||||
"editor": "none",
|
"editor": "none",
|
||||||
"publish dir": False
|
"publish dir": False
|
||||||
}
|
}
|
||||||
|
|
||||||
## ui globals
|
## ui globals
|
||||||
BANNER = util.attach_rainbow()+open(os.path.join(SOURCE, "config", "banner.txt")).read()+util.attach_reset()
|
BANNER = util.attach_rainbow() + config.BANNER + util.attach_reset()
|
||||||
SPACER = "\n"
|
SPACER = "\n"
|
||||||
INVALID = "please pick a number from the list of options!\n\n"
|
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"
|
DUST = "sorry about the dust, but this part is still under construction. check back later!\n\n"
|
||||||
|
@ -229,14 +215,14 @@ def check_init():
|
||||||
|
|
||||||
print("\n\n")
|
print("\n\n")
|
||||||
if os.path.exists(os.path.join(os.path.expanduser("~"),".ttbp")):
|
if os.path.exists(os.path.join(os.path.expanduser("~"),".ttbp")):
|
||||||
print(chatter.say("greet")+", "+USER+".\n")
|
print(chatter.say("greet")+", "+config.USER+".\n")
|
||||||
|
|
||||||
'''
|
'''
|
||||||
## ttbprc validation
|
## ttbprc validation
|
||||||
while not os.path.isfile(TTBPRC):
|
while not os.path.isfile(config.TTBPRC):
|
||||||
setup_repair()
|
setup_repair()
|
||||||
try:
|
try:
|
||||||
SETTINGS = json.load(open(TTBPRC))
|
SETTINGS = json.load(open(config.TTBPRC))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
setup_repair()
|
setup_repair()
|
||||||
'''
|
'''
|
||||||
|
@ -279,28 +265,30 @@ press <enter> to begin, or <ctrl-c> to get out of here.
|
||||||
quit()
|
quit()
|
||||||
|
|
||||||
## record user in source list
|
## record user in source list
|
||||||
users = open(USERFILE, 'a')
|
users = open(config.USERFILE, 'a')
|
||||||
users.write(USER+"\n")
|
users.write(config.USER+"\n")
|
||||||
users.close()
|
users.close()
|
||||||
|
|
||||||
## make .ttbp directory structure
|
## make .ttbp directory structure
|
||||||
subprocess.call(["mkdir", PATH])
|
subprocess.call(["mkdir", config.PATH])
|
||||||
subprocess.call(["mkdir", CONFIG])
|
subprocess.call(["mkdir", config.USER_CONFIG])
|
||||||
subprocess.call(["mkdir", DATA])
|
subprocess.call(["mkdir", config.USER_DATA])
|
||||||
|
|
||||||
versionFile = os.path.join(PATH, "version")
|
versionFile = os.path.join(config.PATH, "version")
|
||||||
open(versionFile, "w").write(__version__)
|
open(versionFile, "w").write(__version__)
|
||||||
|
|
||||||
## create header file
|
## create header file
|
||||||
header = gen_header()
|
header = gen_header()
|
||||||
headerfile = open(os.path.join(CONFIG, "header.txt"), 'w')
|
headerfile = open(os.path.join(config.USER_CONFIG, "header.txt"), 'w')
|
||||||
for line in header:
|
for line in header:
|
||||||
headerfile.write(line)
|
headerfile.write(line)
|
||||||
headerfile.close()
|
headerfile.close()
|
||||||
|
|
||||||
## copy footer and default stylesheet
|
## copy footer and default stylesheet
|
||||||
subprocess.call(["cp", os.path.join(SOURCE, "config", "defaults", "footer.txt"), CONFIG])
|
with open(os.path.join(config.USER_CONFIG, 'footer.txt'), 'w') as f:
|
||||||
subprocess.call(["cp", os.path.join(SOURCE, "config", "defaults", "style.css"), CONFIG])
|
f.write(config.DEFAULT_FOOTER)
|
||||||
|
with open(os.path.join(config.USER_CONFIG, 'style.css'), 'w') as f:
|
||||||
|
f.write(config.DEFAULT_STYLE)
|
||||||
|
|
||||||
## run user-interactive setup and load core engine
|
## run user-interactive setup and load core engine
|
||||||
setup()
|
setup()
|
||||||
|
@ -321,12 +309,12 @@ def gen_header():
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<!--- this header automatically generated by ttbp initialization on """+time.strftime("%Y-%m-%d %h:m")+""" --->
|
<!--- this header automatically generated by ttbp initialization on """+time.strftime("%Y-%m-%d %h:m")+""" --->
|
||||||
<title>~"""+USER+""" on TTBP</title>
|
<title>~"""+config.USER+""" on TTBP</title>
|
||||||
<link rel=\"stylesheet\" href=\"style.css\" />
|
<link rel=\"stylesheet\" href=\"style.css\" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id=\"meta\">
|
<div id=\"meta\">
|
||||||
<h1><a href=\"index.html#\">~"""+USER+"""</a>@<a href=\"/~endorphant/ttbp\">TTBP</a></h1>
|
<h1><a href=\"index.html#\">~"""+config.USER+"""</a>@<a href=\"/~endorphant/ttbp\">TTBP</a></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!---put your custom html here-->
|
<!---put your custom html here-->
|
||||||
|
@ -345,11 +333,11 @@ def valid_setup():
|
||||||
|
|
||||||
global SETTINGS
|
global SETTINGS
|
||||||
|
|
||||||
if not os.path.isfile(TTBPRC):
|
if not os.path.isfile(config.TTBPRC):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
SETTINGS = json.load(open(TTBPRC))
|
SETTINGS = json.load(open(config.TTBPRC))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -357,10 +345,10 @@ def valid_setup():
|
||||||
if not SETTINGS.get("publish dir"):
|
if not SETTINGS.get("publish dir"):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not os.path.exists(WWW):
|
if not os.path.exists(config.WWW):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(WWW, SETTINGS.get("pubish dir"))):
|
if not os.path.exists(os.path.join(config.WWW, SETTINGS.get("pubish dir"))):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -396,7 +384,7 @@ def setup():
|
||||||
|
|
||||||
print("\n\ttext editor:\t" +SETTINGS.get("editor"))
|
print("\n\ttext editor:\t" +SETTINGS.get("editor"))
|
||||||
if core.publishing():
|
if core.publishing():
|
||||||
print("\tpublish dir:\t" +os.path.join(PUBLIC, str(SETTINGS.get("publish dir"))))
|
print("\tpublish dir:\t" +os.path.join(config.PUBLIC, str(SETTINGS.get("publish dir"))))
|
||||||
print("\tpubishing:\t"+str(SETTINGS.get("publishing"))+"\n")
|
print("\tpubishing:\t"+str(SETTINGS.get("publishing"))+"\n")
|
||||||
|
|
||||||
# editor selection
|
# editor selection
|
||||||
|
@ -410,10 +398,10 @@ def setup():
|
||||||
redraw("blog publishing: "+str(core.publishing()))
|
redraw("blog publishing: "+str(core.publishing()))
|
||||||
|
|
||||||
if core.publishing():
|
if core.publishing():
|
||||||
print("publish directory: ~"+USER+"/public_html/"+SETTINGS.get("publish dir"))
|
print("publish directory: ~"+config.USER+"/public_html/"+SETTINGS.get("publish dir"))
|
||||||
|
|
||||||
# save settings
|
# save settings
|
||||||
ttbprc = open(TTBPRC, "w")
|
ttbprc = open(config.TTBPRC, "w")
|
||||||
ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':')))
|
ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':')))
|
||||||
ttbprc.close()
|
ttbprc.close()
|
||||||
|
|
||||||
|
@ -452,7 +440,7 @@ def main_menu():
|
||||||
if choice == '0':
|
if choice == '0':
|
||||||
redraw()
|
redraw()
|
||||||
today = time.strftime("%Y%m%d")
|
today = time.strftime("%Y%m%d")
|
||||||
write_entry(os.path.join(DATA, today+".txt"))
|
write_entry(os.path.join(config.USER_DATA, today+".txt"))
|
||||||
core.www_neighbors()
|
core.www_neighbors()
|
||||||
elif choice == '1':
|
elif choice == '1':
|
||||||
if core.publishing():
|
if core.publishing():
|
||||||
|
@ -463,7 +451,7 @@ def main_menu():
|
||||||
core.write("index.html")
|
core.write("index.html")
|
||||||
else:
|
else:
|
||||||
redraw("your recorded feels, listed by date:")
|
redraw("your recorded feels, listed by date:")
|
||||||
view_feels(USER)
|
view_feels(config.USER)
|
||||||
elif choice == '2':
|
elif choice == '2':
|
||||||
users = core.find_ttbps()
|
users = core.find_ttbps()
|
||||||
prompt = "the following "+p.no("user", len(users))+" "+p.plural("is", len(users))+" recording feels on ttbp:"
|
prompt = "the following "+p.no("user", len(users))+" "+p.plural("is", len(users))+" recording feels on ttbp:"
|
||||||
|
@ -488,7 +476,7 @@ def main_menu():
|
||||||
redraw()
|
redraw()
|
||||||
show_credits()
|
show_credits()
|
||||||
elif choice == '8':
|
elif choice == '8':
|
||||||
subprocess.call(["lynx", os.path.join(SOURCE, "..", "README.html")])
|
subprocess.call(["lynx", os.path.join(config.INSTALL_PATH, "..", "README.html")])
|
||||||
redraw()
|
redraw()
|
||||||
elif choice in QUITS:
|
elif choice in QUITS:
|
||||||
return stop()
|
return stop()
|
||||||
|
@ -541,7 +529,7 @@ def review_menu(intro=""):
|
||||||
if choice is not False:
|
if choice is not False:
|
||||||
if choice == 0:
|
if choice == 0:
|
||||||
redraw("your recorded feels, listed by date:")
|
redraw("your recorded feels, listed by date:")
|
||||||
view_feels(USER)
|
view_feels(config.USER)
|
||||||
elif choice == 1:
|
elif choice == 1:
|
||||||
redraw("here's your current nopub status:")
|
redraw("here's your current nopub status:")
|
||||||
set_nopubs()
|
set_nopubs()
|
||||||
|
@ -568,7 +556,7 @@ def view_neighbors(users, prompt):
|
||||||
## retrieve publishing url, if it exists
|
## retrieve publishing url, if it exists
|
||||||
url="\t\t\t"
|
url="\t\t\t"
|
||||||
if userRC.get("publish dir"):
|
if userRC.get("publish dir"):
|
||||||
url = LIVE+user+"/"+userRC.get("publish dir")
|
url = config.LIVE+user+"/"+userRC.get("publish dir")
|
||||||
|
|
||||||
## find last entry
|
## find last entry
|
||||||
files = os.listdir(os.path.join("/home", user, ".ttbp", "entries"))
|
files = os.listdir(os.path.join("/home", user, ".ttbp", "entries"))
|
||||||
|
@ -628,8 +616,8 @@ def view_feels(townie):
|
||||||
filenames = []
|
filenames = []
|
||||||
showpub = False
|
showpub = False
|
||||||
|
|
||||||
if townie == USER:
|
if townie == config.USER:
|
||||||
entryDir = DATA
|
entryDir = config.USER_DATA
|
||||||
owner = "your"
|
owner = "your"
|
||||||
if core.publishing():
|
if core.publishing():
|
||||||
showpub = True
|
showpub = True
|
||||||
|
@ -683,7 +671,7 @@ thanks to everyone who reads, listens, writes, and feels.\
|
||||||
|
|
||||||
## handlers
|
## handlers
|
||||||
|
|
||||||
def write_entry(entry=os.path.join(DATA, "test.txt")):
|
def write_entry(entry=os.path.join(config.USER_DATA, "test.txt")):
|
||||||
'''
|
'''
|
||||||
main feels-recording handler
|
main feels-recording handler
|
||||||
'''
|
'''
|
||||||
|
@ -713,7 +701,7 @@ editor.
|
||||||
if core.publishing():
|
if core.publishing():
|
||||||
core.load_files()
|
core.load_files()
|
||||||
core.write("index.html")
|
core.write("index.html")
|
||||||
left = "posted to "+LIVE+USER+"/"+str(SETTINGS.get("publish dir"))+"/index.html\n\n>"
|
left = "posted to "+config.LIVE+config.USER+"/"+str(SETTINGS.get("publish dir"))+"/index.html\n\n>"
|
||||||
redraw(left + " thanks for sharing your feels!")
|
redraw(left + " thanks for sharing your feels!")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -743,8 +731,8 @@ def send_feedback(entered, subject="none"):
|
||||||
if message:
|
if message:
|
||||||
id = "#"+util.genID(3)
|
id = "#"+util.genID(3)
|
||||||
mail = MIMEText(message)
|
mail = MIMEText(message)
|
||||||
mail['To'] = FEEDBOX
|
mail['To'] = config.FEEDBOX
|
||||||
mail['From'] = USER+"@tilde.town"
|
mail['From'] = config.USER+"@tilde.town"
|
||||||
mail['Subject'] = " ".join(["[ttbp]", subject, id])
|
mail['Subject'] = " ".join(["[ttbp]", subject, id])
|
||||||
m = os.popen("/usr/sbin/sendmail -t -oi", 'w')
|
m = os.popen("/usr/sbin/sendmail -t -oi", 'w')
|
||||||
m.write(mail.as_string())
|
m.write(mail.as_string())
|
||||||
|
@ -836,10 +824,10 @@ def graffiti_handler():
|
||||||
Main graffiti handler.
|
Main graffiti handler.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if os.path.isfile(WALL_LOCK):
|
if os.path.isfile(config.WALL_LOCK):
|
||||||
redraw("sorry, "+chatter.say("friend")+", but someone's there right now. try again in a few!")
|
redraw("sorry, "+chatter.say("friend")+", but someone's there right now. try again in a few!")
|
||||||
else:
|
else:
|
||||||
subprocess.call(["touch", WALL_LOCK])
|
subprocess.call(["touch", config.WALL_LOCK])
|
||||||
redraw()
|
redraw()
|
||||||
print("""\
|
print("""\
|
||||||
the graffiti wall is a world-writeable text file. anyone can
|
the graffiti wall is a world-writeable text file. anyone can
|
||||||
|
@ -853,8 +841,8 @@ your changes by exiting without saving.
|
||||||
|
|
||||||
""")
|
""")
|
||||||
raw_input("press <enter> to visit the wall\n\n")
|
raw_input("press <enter> to visit the wall\n\n")
|
||||||
subprocess.call([SETTINGS.get("editor"), WALL])
|
subprocess.call([SETTINGS.get("editor"), config.WALL])
|
||||||
subprocess.call(["rm", WALL_LOCK])
|
subprocess.call(["rm", config.WALL_LOCK])
|
||||||
redraw("thanks for visiting the graffiti wall!")
|
redraw("thanks for visiting the graffiti wall!")
|
||||||
|
|
||||||
|
|
||||||
|
@ -884,14 +872,14 @@ def select_publish_dir():
|
||||||
republish = False
|
republish = False
|
||||||
|
|
||||||
if current:
|
if current:
|
||||||
print("\ncurrent publish dir:\t"+os.path.join(PUBLIC, SETTINGS["publish dir"]))
|
print("\ncurrent publish dir:\t"+os.path.join(config.PUBLIC, SETTINGS["publish dir"]))
|
||||||
republish = True
|
republish = True
|
||||||
|
|
||||||
choice = raw_input("\nwhere do you want your blog published? (leave blank to use default \"blog\") ")
|
choice = raw_input("\nwhere do you want your blog published? (leave blank to use default \"blog\") ")
|
||||||
if not choice:
|
if not choice:
|
||||||
choice = "blog"
|
choice = "blog"
|
||||||
|
|
||||||
publishDir = os.path.join(PUBLIC, choice)
|
publishDir = os.path.join(config.PUBLIC, choice)
|
||||||
while os.path.exists(publishDir):
|
while os.path.exists(publishDir):
|
||||||
second = raw_input("\n"+publishDir+"""\
|
second = raw_input("\n"+publishDir+"""\
|
||||||
already exists!
|
already exists!
|
||||||
|
@ -905,7 +893,7 @@ otherwise, pick another location: """)
|
||||||
if second == "":
|
if second == "":
|
||||||
break
|
break
|
||||||
choice = second
|
choice = second
|
||||||
publishDir = os.path.join(PUBLIC, choice)
|
publishDir = os.path.join(config.PUBLIC, choice)
|
||||||
|
|
||||||
return choice
|
return choice
|
||||||
|
|
||||||
|
@ -936,10 +924,9 @@ def unpublish():
|
||||||
'''
|
'''
|
||||||
remove user's published directory, if it exists. this should only remove the symlink in public_html.
|
remove user's published directory, if it exists. this should only remove the symlink in public_html.
|
||||||
'''
|
'''
|
||||||
|
directory = SETTINGS.get("publish dir")
|
||||||
dir = SETTINGS.get("publish dir")
|
if directory:
|
||||||
if dir:
|
publishDir = os.path.join(config.PUBLIC, directory)
|
||||||
publishDir = os.path.join(PUBLIC, dir)
|
|
||||||
subprocess.call(["rm", publishDir])
|
subprocess.call(["rm", publishDir])
|
||||||
|
|
||||||
def update_publishing():
|
def update_publishing():
|
||||||
|
@ -954,7 +941,7 @@ def update_publishing():
|
||||||
newDir = select_publish_dir()
|
newDir = select_publish_dir()
|
||||||
SETTINGS.update({"publish dir": newDir})
|
SETTINGS.update({"publish dir": newDir})
|
||||||
if oldDir:
|
if oldDir:
|
||||||
subprocess.call(["rm", os.path.join(PUBLIC, oldDir)])
|
subprocess.call(["rm", os.path.join(config.PUBLIC, oldDir)])
|
||||||
make_publish_dir(newDir)
|
make_publish_dir(newDir)
|
||||||
core.load_files()
|
core.load_files()
|
||||||
core.write("index.html")
|
core.write("index.html")
|
||||||
|
@ -969,21 +956,21 @@ def make_publish_dir(dir):
|
||||||
setup helper to create publishing directory
|
setup helper to create publishing directory
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if not os.path.exists(WWW):
|
if not os.path.exists(config.WWW):
|
||||||
subprocess.call(["mkdir", WWW])
|
subprocess.call(["mkdir", config.WWW])
|
||||||
subprocess.call(["ln", "-s", os.path.join(CONFIG, "style.css"), os.path.join(WWW, "style.css")])
|
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(WWW, "index.html")])
|
subprocess.call(["touch", os.path.join(config.WWW, "index.html")])
|
||||||
index = open(os.path.join(WWW, "index.html"), "w")
|
index = open(os.path.join(config.WWW, "index.html"), "w")
|
||||||
index.write("<h1>ttbp blog placeholder</h1>")
|
index.write("<h1>ttbp blog placeholder</h1>")
|
||||||
index.close()
|
index.close()
|
||||||
|
|
||||||
publishDir = os.path.join(PUBLIC, dir)
|
publishDir = os.path.join(config.PUBLIC, dir)
|
||||||
if os.path.exists(publishDir):
|
if os.path.exists(publishDir):
|
||||||
subprocess.call(["rm", publishDir])
|
subprocess.call(["rm", publishDir])
|
||||||
|
|
||||||
subprocess.call(["ln", "-s", WWW, publishDir])
|
subprocess.call(["ln", "-s", config.WWW, publishDir])
|
||||||
|
|
||||||
print("\n\tpublishing to "+LIVE+USER+"/"+SETTINGS.get("publish dir")+"/\n\n")
|
print("\n\tpublishing to "+config.LIVE+config.USER+"/"+SETTINGS.get("publish dir")+"/\n\n")
|
||||||
|
|
||||||
##### PATCHING UTILITIES
|
##### PATCHING UTILITIES
|
||||||
|
|
||||||
|
@ -992,7 +979,7 @@ def build_mismatch():
|
||||||
checks to see if user's last run build is the same as this session
|
checks to see if user's last run build is the same as this session
|
||||||
'''
|
'''
|
||||||
|
|
||||||
versionFile = os.path.join(PATH, "version")
|
versionFile = os.path.join(config.PATH, "version")
|
||||||
if not os.path.exists(versionFile):
|
if not os.path.exists(versionFile):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1018,7 +1005,7 @@ def switch_build(ver):
|
||||||
print("\nswitching you over to the "+build+" version...\n")
|
print("\nswitching you over to the "+build+" version...\n")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
print("...")
|
print("...")
|
||||||
versionFile = os.path.join(PATH, "version")
|
versionFile = os.path.join(config.PATH, "version")
|
||||||
open(versionFile, "w").write(ver)
|
open(versionFile, "w").write(ver)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
#print("\nall good!\n")
|
#print("\nall good!\n")
|
||||||
|
@ -1028,7 +1015,7 @@ def updated():
|
||||||
checks to see if current user is up to the same version as system
|
checks to see if current user is up to the same version as system
|
||||||
'''
|
'''
|
||||||
|
|
||||||
versionFile = os.path.join(PATH, "version")
|
versionFile = os.path.join(config.PATH, "version")
|
||||||
if not os.path.exists(versionFile):
|
if not os.path.exists(versionFile):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1046,7 +1033,7 @@ def update_version():
|
||||||
|
|
||||||
global SETTINGS
|
global SETTINGS
|
||||||
|
|
||||||
versionFile = os.path.join(PATH, "version")
|
versionFile = os.path.join(config.PATH, "version")
|
||||||
|
|
||||||
print("ttbp had some updates!")
|
print("ttbp had some updates!")
|
||||||
|
|
||||||
|
@ -1063,22 +1050,22 @@ def update_version():
|
||||||
|
|
||||||
# change style.css location
|
# change style.css location
|
||||||
if core.publishing():
|
if core.publishing():
|
||||||
if os.path.isfile(os.path.join(WWW, "style.css")):
|
if os.path.isfile(os.path.join(config.WWW, "style.css")):
|
||||||
subprocess.call(["mv", os.path.join(WWW, "style.css"), CONFIG])
|
subprocess.call(["mv", os.path.join(config.WWW, "style.css"), config.USER_CONFIG])
|
||||||
|
|
||||||
# change www symlink
|
# change www symlink
|
||||||
if os.path.exists(WWW):
|
if os.path.exists(config.WWW):
|
||||||
subprocess.call(["rm", WWW])
|
subprocess.call(["rm", config.WWW])
|
||||||
|
|
||||||
subprocess.call(["mkdir", WWW])
|
subprocess.call(["mkdir", config.WWW])
|
||||||
|
|
||||||
subprocess.call(["ln", "-s", os.path.join(CONFIG, "style.css"), os.path.join(WWW, "style.css")])
|
subprocess.call(["ln", "-s", os.path.join(config.USER_CONFIG, "style.css"), os.path.join(config.WWW, "style.css")])
|
||||||
|
|
||||||
publishDir = os.path.join(PUBLIC, SETTINGS.get("publish dir"))
|
publishDir = os.path.join(config.PUBLIC, SETTINGS.get("publish dir"))
|
||||||
if os.path.exists(publishDir):
|
if os.path.exists(publishDir):
|
||||||
subprocess.call(["rm", "-rf", publishDir])
|
subprocess.call(["rm", "-rf", publishDir])
|
||||||
|
|
||||||
subprocess.call(["ln", "-s", WWW, os.path.join(PUBLIC, SETTINGS.get("publish dir"))])
|
subprocess.call(["ln", "-s", config.WWW, os.path.join(config.PUBLIC, SETTINGS.get("publish dir"))])
|
||||||
|
|
||||||
# repopulate html files
|
# repopulate html files
|
||||||
core.load_files()
|
core.load_files()
|
||||||
|
@ -1088,7 +1075,7 @@ def update_version():
|
||||||
print("\nnew feature!\n")
|
print("\nnew feature!\n")
|
||||||
SETTINGS.update({"publishing":select_publishing()})
|
SETTINGS.update({"publishing":select_publishing()})
|
||||||
update_publishing()
|
update_publishing()
|
||||||
ttbprc = open(TTBPRC, "w")
|
ttbprc = open(config.TTBPRC, "w")
|
||||||
ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':')))
|
ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':')))
|
||||||
ttbprc.close()
|
ttbprc.close()
|
||||||
|
|
||||||
|
@ -1100,7 +1087,7 @@ def update_version():
|
||||||
print("\nresetting your publishing settings...\n")
|
print("\nresetting your publishing settings...\n")
|
||||||
SETTINGS.update({"publishing":select_publishing()})
|
SETTINGS.update({"publishing":select_publishing()})
|
||||||
update_publishing()
|
update_publishing()
|
||||||
ttbprc = open(TTBPRC, "w")
|
ttbprc = open(config.TTBPRC, "w")
|
||||||
ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':')))
|
ttbprc.write(json.dumps(SETTINGS, sort_keys=True, indent=2, separators=(',',':')))
|
||||||
ttbprc.close()
|
ttbprc.close()
|
||||||
|
|
||||||
|
@ -1111,6 +1098,9 @@ you're all good to go, """+chatter.say("friend")+"""! please contact ~endorphant
|
||||||
somehing strange happened to you during this update.
|
somehing strange happened to you during this update.
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
# TODO these conditionals will need to change if we increment the Y level
|
||||||
|
# to 10.
|
||||||
|
|
||||||
# show patch notes
|
# show patch notes
|
||||||
#if userVersion != "0.9.0" and userVersion != "0.9.0b":
|
#if userVersion != "0.9.0" and userVersion != "0.9.0b":
|
||||||
if userVersion[0:5] < "0.9.0":
|
if userVersion[0:5] < "0.9.0":
|
||||||
|
@ -1138,6 +1128,16 @@ ver 0.9.2 features:
|
||||||
* expanded menu for viewing your own feels (further
|
* expanded menu for viewing your own feels (further
|
||||||
features to be implemented)
|
features to be implemented)
|
||||||
""")
|
""")
|
||||||
|
if userVersion[0:5] < "0.9.3":
|
||||||
|
# version 0.9.3 patch notes
|
||||||
|
print()
|
||||||
|
print("""
|
||||||
|
version 0.9.3 features:
|
||||||
|
* ttbp is now packaged, making it easier to contribute to.
|
||||||
|
* things should otherwise be the same!
|
||||||
|
* check out https://github.com/modgethanc/ttbp if you'd like to contribute.
|
||||||
|
* takes advantage of new /var/global
|
||||||
|
""".lstrip())
|
||||||
|
|
||||||
#####
|
#####
|
||||||
|
|
|
@ -23,11 +23,11 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import inflect
|
|
||||||
import time
|
|
||||||
import random
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
import colorama
|
import colorama
|
||||||
|
import inflect
|
||||||
|
|
||||||
## misc globals
|
## misc globals
|
||||||
BACKS = ['back', 'b', 'q']
|
BACKS = ['back', 'b', 'q']
|
Loading…
Reference in New Issue