fix packaging

This commit is contained in:
cremesk 2019-07-23 17:51:00 +02:00
parent 446c70306b
commit 4e2cdd9973
Signed by: creme
GPG Key ID: C147C3B7FBDF08D0
11 changed files with 719 additions and 1147 deletions

View File

@ -1,5 +1,3 @@
include ttbp/config/defaults/*.txt
include ttbp/config/defaults/style.css
include ttbp/config/defaults/header.txt
include ttbp/config/defaults/footer.txt
include ttbp/config/banner-beta.txt
include doc/manual.html

View File

@ -51,8 +51,8 @@ by creating files with any date you want.)</em></p>
<li>you can use <a href="https://daringfireball.net/projects/markdown/syntax">markdown</a></li>
<li>you can use html</li>
<li>you can also put things between <code>&lt;!-- comments --&gt;</code> to have them show up
in the feed but not render in a browser (but people can still read
them with view-source)</li>
in the feed but not render in a browser (but people can still read
them with view-source)</li>
</ul>
<h3>reading other feels</h3>
<p>the <code>browse global feels</code> feature shows the ten most recent entries that anyone
@ -68,6 +68,20 @@ world-viewable way! please be respectful about having access to other people's
feels, and do not copy/repeat any information without getting their explicit
permission. envs.net operates on a high level of mutual trust, and <code>ttbp</code> is
designed to give individuals control over their content.</p>
<h3>subscribing to users</h3>
<p>the <code>visit your subscriptions</code> feature lets you view recent entries from a list
of users you've subscribed to, as well as manage your subscription list. your
list is saved to <code>~/.ttbp/config/subs</code>, which gets automatically updated when
you add or remove subscriptions from ttbp.</p>
<p>your subscription list is private; this means no one other than you can see who
you're following. subscription view only shows the 50 most recent entries from
your subscribe list; if you want to see more entries from an individual, you
can navigate to their entries in `check out your neighbors from the main
menu.</p>
<h3>privacy</h3>
<p>when you start your ttbp, you have the option of publishing or not publishing
your blog.</p>
@ -79,8 +93,8 @@ entries through the ttbp interface, or by directly accessing your
directory.</p>
<p>if you opt to publish, the program creates a directory <code>~/.ttbp/www</code> where it
stores all html files it generates, and symlinks this from your <code>~/public_html</code>
with your chosen blog directory. your blog will also be listed on the <a href="https://envs.net/ttbp">main ttbp
page</a>.</p>
with your chosen blog directory. </p>
<p>you can also opt to publish to gopher, and the program will automatically
generate a gophermap of your feels.</p>
<p>you can set publishing status on individual entries, or bury individual feels;
@ -91,46 +105,46 @@ these are all actions you can perform manually from the command line, but doing
them from within the program can help keep your files properly linked up.</p>
<ul>
<li><strong>read over feels</strong>--a list of all your entries, which you can open and
read like any other feel</li>
read like any other feel</li>
<li><strong>modify feels publishing</strong>--this lets you toggle privacy on individual
posts. entries marked <code>(nopub)</code> will not get written to html or gopher,
and toggling them from this menu will immediately publish or unpublish
that entry (if you're not publishing your posts at all, these settings
won't matter, since your feels will never show up outside of envs.net)</li>
posts. entries marked <code>(nopub)</code> will not get written to html or gopher,
and toggling them from this menu will immediately publish or unpublish
that entry (if you're not publishing your posts at all, these settings
won't matter, since your feels will never show up outside of tilde.team)</li>
<li><strong>backup your feels</strong>--makes a .tar.gz of all your entries, saving one
copy to <code>~/.ttbp/backups/</code> with the current date, and a second copy to
your home directory for safekeeping.</li>
copy to <code>~/.ttbp/backups/</code> with the current date, and a second copy to
your home directory for safekeeping.</li>
<li><strong>import a feels backup</strong>--unpacks a backup file into your current feels
list. this tool checks the <code>~/.ttbp/backups</code> directory for archives, and
expects a file created by the above backup utility. if it detects any file
collisions, it will preserve your current live copy and leave the backup
verison in a temp directory, and notify you that this happened. also, any
entries that were previously marked as <code>(nopub)</code> will retain their nopub
status.</li>
list. this tool checks the <code>~/.ttbp/backups</code> directory for archives, and
expects a file created by the above backup utility. if it detects any file
collisions, it will preserve your current live copy and leave the backup
verison in a temp directory, and notify you that this happened. also, any
entries that were previously marked as <code>(nopub)</code> will retain their nopub
status.</li>
<li><strong>bury some feels</strong>--hides individual feels from viewing; entries are
moved to <code>~/.ttbp/buried</code> (and marked with a unique timestamp to prevent
file collision) with permissions set to 600, meaning no one except you
will be able to open that file. these entries are also hidden from your
own view from <code>read over feels</code>, and you'll have to open the files from
the command line if you want to see them. this is intended to be a
permament action, so you'll be asked to type the entry date once to load
the feel, then shown a preview of that feel, and then type the date again
to confirm burying.</li>
moved to <code>~/.ttbp/buried</code> (and marked with a unique timestamp to prevent
file collision) with permissions set to 600, meaning no one except you
will be able to open that file. these entries are also hidden from your
own view from <code>read over feels</code>, and you'll have to open the files from
the command line if you want to see them. this is intended to be a
permament action, so you'll be asked to type the entry date once to load
the feel, then shown a preview of that feel, and then type the date again
to confirm burying.</li>
<li><strong>delete feels by day</strong>--<em>permanently removes individual entries</em>,
including deleting published html/gopher files if needed. this action is
not recoverable, unless you have a backup to restore; you'll be asked to
type the entry date once to load the feel, then shown a preview of that
feel, and then type the date again to confirm deletion.</li>
including deleting published html/gopher files if needed. this action is
not recoverable, unless you have a backup to restore; you'll be asked to
type the entry date once to load the feel, then shown a preview of that
feel, and then type the date again to confirm deletion.</li>
<li><strong>purge all feels</strong>--<em>permanently removes all feels</em>, including deleting
all published html/gopher files if needed. this action is not recoverable,
unless you have a backup to restore. you'll be asked to type a
one-time-use purge code to confirm this action.</li>
all published html/gopher files if needed. this action is not recoverable,
unless you have a backup to restore. you'll be asked to type a
one-time-use purge code to confirm this action.</li>
<li><strong>wipe feels account</strong>--<em>permanently removes all data associated with
feels</em>, including deleting any published hmtl/gopher files and removing
your <code>~/.ttbp</code> directory. any backups that you have in <code>~/.ttbp/backups</code>
will also be deleted with this action (which is why the backup function
makes a second copy for safekeeping in your home directory). you will no
longer show up in any lists as a user.</li>
feels</em>, including deleting any published hmtl/gopher files and removing
your <code>~/.ttbp</code> directory. any backups that you have in <code>~/.ttbp/backups</code>
will also be deleted with this action (which is why the backup function
makes a second copy for safekeeping in your home directory). you will no
longer show up in any lists as a user.</li>
</ul>
<h3>settings</h3>
<p>the settings menu lets you change specific options for handling your feels and
@ -139,11 +153,11 @@ using the interface.</p>
<li><strong>editor</strong>--set your text editor</li>
<li><strong>gopher</strong>--opt in or out of automatically posting to gopher</li>
<li><strong>post as nopub</strong>--set whether posts default to being published or not
published (if you're not publishing your feels, this doesn't matter)</li>
published (if you're not publishing your feels, this doesn't matter)</li>
<li><strong>publish dir</strong>--set the directory under you <code>public_html</code> where feels will be
published (if you're not publishing your feels, this defaults to <code>None</code>)</li>
published (if you're not publishing your feels, this defaults to <code>None</code>)</li>
<li><strong>publishing</strong>--opt in or out of automatically publishing entries to a
world-readable html page</li>
world-readable html page</li>
<li><strong>rainbows</strong>--opt in or out of having multicolored menu text</li>
</ul>
<h3>changing your page layout</h3>
@ -154,19 +168,21 @@ your ~/.ttbp directory entirely. <strong>you might want to back up your
~/.ttbp/entries directory before you do this.</strong></p>
<ul>
<li>to modify your stylesheet, edit your ~/.ttbp/config/style.css</li>
<li>to modify the page header, edit your ~/.ttbp/config/header.txt</li>
<li>to modify the page header, edit your ~/.ttbp/config/header.txt
<ul>
<li>there's a place marked off in the default header where you can safely put
custom HTML elements!</li>
custom HTML elements!</li>
</ul></li>
<li>to modify the page footer, edit your ~/.ttbp/config/footer.txt</li>
</ul>
<h3>general tips/troubleshooting</h3>
<ul>
<li>if the date looks like it's ahead or behind, it's because you haven't set
your local timezone yet. here are some
<a href="http://www.cyberciti.biz/faq/linux-unix-set-tz-environment-variable/">timezone setting instructions</a></li>
your local timezone yet. here are some
<a href="http://www.cyberciti.biz/faq/linux-unix-set-tz-environment-variable/">timezone setting instructions</a></li>
<li>the feels burying tool will effectively clear your post for the day; you can
use this feature to start a fresh entry on a particular day by burying the
current day's feels and then editing a new file</li>
use this feature to start a fresh entry on a particular day by burying the
current day's feels and then editing a new file</li>
</ul>
<h3>future features</h3>
<p>these are a few ideas being kicked around, or under active development:</p>
@ -200,4 +216,4 @@ or open a github issue and i'll get back to you as soon as i can.</p>
<li>~vilmibm, packaging help and gopher support</li>
<li>~sanqui, the bug swatter</li>
<li>~sinacutie, for css updates</li>
</ul>
</ul>

View File

@ -93,6 +93,19 @@ feels, and do not copy/repeat any information without getting their explicit
permission. envs.net operates on a high level of mutual trust, and `ttbp` is
designed to give individuals control over their content.
### subscribing to users
the `visit your subscriptions` feature lets you view recent entries from a list
of users you've subscribed to, as well as manage your subscription list. your
list is saved to `~/.ttbp/config/subs`, which gets automatically updated when
you add or remove subscriptions from ttbp.
your subscription list is private; this means no one other than you can see who
you're following. subscription view only shows the 50 most recent entries from
your subscribe list; if you want to see more entries from an individual, you
can navigate to their entries in `check out your neighbors from the main
menu.
### privacy
when you start your ttbp, you have the option of publishing or not publishing

View File

@ -1,24 +1,32 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
from setuptools import setup
setup(
name="ttbp",
version="0.12.2",
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",
name='ttbp',
version='0.12.2',
description='command line social blogging tool used on tilde.team',
url='https://github.com/envs-net/ttbp',
author='~endorphant',
author_email='endorphant@tilde.town',
license='MIT',
classifiers=[
"Topic :: Artistic Software",
"License :: OSI Approved :: MIT License",
'Topic :: Artistic Software',
'License :: OSI Approved :: MIT License',
],
keywords="blog",
packages=["ttbp", "ttbp/config"],
install_requires=["inflect==0.2.5", "mistune==0.8.1", "colorama==0.3.9", "six"],
include_package_data=True,
entry_points={
"console_scripts": ["feels = ttbp.ttbp:main", "ttbp = ttbp.ttbp:main"]
keywords='blog',
packages=setuptools.find_packages(),
install_requires = [
'inflect==0.2.5',
'mistune==0.8.1',
'colorama==0.3.9',
'six'
],
include_package_data = True,
entry_points = {
'console_scripts': [
'feels = ttbp.ttbp:main',
'ttbp = ttbp.ttbp:main',
]
},
)

View File

@ -3,7 +3,7 @@ import os
import random
DEFAULT_LANG = {
"greet": [
"greet":[
"hi",
"hey",
"howdy",
@ -12,55 +12,58 @@ DEFAULT_LANG = {
"good day",
"good evening",
"welcome back",
"nice to see you",
"nice to see you"
],
"bye": [
"bye":[
"see you later, space cowboy",
"bye, teammate",
"until next time, friend",
"come back whenever",
"come back whenever"
],
"friend": ["friend", "pal", "buddy", "teammate"],
"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",
},
"friend":[
"friend",
"pal",
"buddy",
"teammate"
],
"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:
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)

View File

@ -3,20 +3,20 @@ import os
import sys
import time
from .. import util
import ttbp.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__)
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")
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/global'):
raise Exception('bad system state: /var/global does not exist.')
if not os.path.isdir(VAR):
os.mkdir(VAR)
@ -24,7 +24,7 @@ if not os.path.isdir(VAR):
if not os.path.isdir(VAR_WWW):
os.mkdir(VAR_WWW)
LIVE = "https://envs.net/~"
LIVE = 'https://envs.net/~'
FEEDBOX = "sudoers@envs.net"
USERFILE = os.path.join(VAR, "users.txt")
GRAFF_DIR = os.path.join(VAR, "graffiti")
@ -36,7 +36,7 @@ if not os.path.isdir(GRAFF_DIR):
## Defaults
DEFAULT_HEADER = """
DEFAULT_HEADER = '''
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
@ -58,9 +58,9 @@ DEFAULT_HEADER = """
</div>
<div id="tlogs">
""".lstrip()
'''.lstrip()
DEFAULT_FOOTER = """
DEFAULT_FOOTER = '''
</div>
<!-- Button DarkLight-->
<div class="button_darklight">
@ -75,32 +75,32 @@ DEFAULT_FOOTER = """
</body>
</html>
""".lstrip()
'''.lstrip()
with open(os.path.join(INSTALL_PATH, "config", "defaults", "style.css")) as f:
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")
GOPHER_ENTRIES = os.path.join(PATH, "gopher")
GOPHER_PATH = os.path.join(USER_HOME, "public_gopher", "feels")
USER_CONFIG = os.path.join(PATH, "config")
TTBPRC = os.path.join(USER_CONFIG, "ttbprc")
MAIN_FEELS = os.path.join(PATH, "entries")
BURIED_FEELS = os.path.join(PATH, "buried")
NOPUB = os.path.join(USER_CONFIG, "nopub")
BACKUPS = os.path.join(PATH, "backups")
SUBS = os.path.join(USER_CONFIG, "subs")
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')
GOPHER_ENTRIES = os.path.join(PATH, 'gopher')
GOPHER_PATH = os.path.join(USER_HOME, 'public_gopher', 'feels')
USER_CONFIG = os.path.join(PATH, 'config')
TTBPRC = os.path.join(USER_CONFIG, 'ttbprc')
MAIN_FEELS = os.path.join(PATH, 'entries')
BURIED_FEELS = os.path.join(PATH, 'buried')
NOPUB = os.path.join(USER_CONFIG, 'nopub')
BACKUPS = os.path.join(PATH, 'backups')
SUBS = os.path.join(USER_CONFIG, 'subs')
## UI
BANNER = """
BANNER = '''
___________________________________________________________
| |
| ____ ____ ____ _ ____ ____ _ _ ____ _ _ _ ____ |
@ -109,9 +109,9 @@ ___________________________________________________________
| <gan jue; to feel> ver 0.12.2 |
| envs.net edition |
|__________________________________________________________|
""".lstrip()
'''.lstrip()
# ~ u n s t a b l e e x p e r i m e n t a l b r a n c h ~
# '''.lstrip()
#'''.lstrip()
## page texts
@ -140,7 +140,7 @@ other contributors:
~sinacutie, for css updates
if you have ideas for ttbp, you are welcome to contact me to discuss them;
please send me tildemail or open an issue. i am not a very experienced
please send me mail or open a github issue. i am not a very experienced
developer, and ttbp is one of my first public-facing projects, so i appreciate
your patience while i learn how to be a better developer!
@ -160,14 +160,12 @@ these.
press <enter> to begin recording your feels in your chosen text
editor.
""".format(
today=time.strftime("%d %B %Y")
)
""".format(today=time.strftime("%d %B %Y"))
bury_feels_prompt = """\
burying a feel removes it from view, including your own. buried feels are
stashed in a private directory at:
{buried_dir}
you can visit your feels there from the command line, but no one else can view
@ -178,9 +176,7 @@ command line to view your buried feels)
which day's feels do you want to bury?
YYYYMMDD (or 'q' to cancel)> """.format(
buried_dir=BURIED_FEELS
)
YYYYMMDD (or 'q' to cancel)> """.format(buried_dir=BURIED_FEELS)
account_wipe_prompt = """\
warning! ! ! this action is irreversible!!!
@ -214,34 +210,34 @@ figure it out!
## update announcements
UPDATES = {
"0.9.0": """
"0.9.0": """
ver. 0.9.0 features:
* browsing other people's feels from neighbor view
* documentation browser""",
"0.9.1": """
"0.9.1": """
ver 0.9.1 features:
* graffiti wall """,
"0.9.2": """
"0.9.2": """
ver 0.9.2 features:
* paginated entry view
* improved entry listing performance so it should
be less sluggish (for now)
* expanded menu for viewing your own feels (further features to be implemented) """,
"0.9.3": """
"0.9.3": """
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 """,
"0.10.1": """
"0.10.1": """
~[version 0.10.1 features]~
* 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/~{user}/feels
gopher://tilde.team/1/~{user}/feels
* if you don't know what gopher is, it's fine to opt-out; ask around on
irc if you'd like to learn more!
* the settings menu has been reworked to be less clunky""",
"0.11.0": """
"0.11.0": """
~[version 0.11.0 update]~
* rainbow menus are now an option! please message ~endorphant (with
@ -264,14 +260,14 @@ version 0.9.3 features:
* ~login created centralfeels, which is an opt-in collection of
html-published feels; create a blank file called '.centralfeels' in
your home directory if you'd like to be included!""",
"0.11.1": """
"0.11.1": """
~[version 0.11.1 update]~
* a quick patch to correct a directory listing error, nothing too
exciting
* general PSA: feel free to use the github repo for bugs/feature requests:
https://github.com/modgethanc/ttbp/issues""",
"0.11.2": """
"0.11.2": """
~[version 0.11.2 update]~
* added a new option to allow setting entries to default to either public or
@ -279,7 +275,7 @@ version 0.9.3 features:
already publishing to html/gopher, but is available either way!
you can find this option under 'settings' as 'post as nopub'.""",
"0.11.3": """
"0.11.3": """
~[version 0.11.3 update]~
* thanks to ~sinacutie, you can now set custom css for the permalink text
@ -287,7 +283,7 @@ version 0.9.3 features:
your current css file, and shouldn't change the appearance of your page.
if you're not using custom css, don't worry about this!""",
"0.12.0": """
"0.12.0": """
~[version 0.12.0 update]~
a lot of new stuff this time! from the main menu, option (1) is now called
@ -320,11 +316,11 @@ version 0.9.3 features:
and wants to kick some spare change my way; this is a labor of love, and i'm
happy to work on it regardless :)
""",
"0.12.1": """
"0.12.1":"""
~[version 0.12.1 update]~
new feature: "visit your subscriptions"
* view recent entries from a list of townies you've subscribed to
* view recent entries from a list of teammates you've subscribed to
* subscription list is private; no one else can see who you're following
* add/remove users from the subscription menu
@ -337,7 +333,7 @@ version 0.9.3 features:
keep feelin' together <3
""",
"0.12.2": """
"0.12.2":"""
~[version 0.12.2 update]~
bug fix: ~epicmorphism helped out with fixing the pagination bug! now, when
@ -350,5 +346,5 @@ version 0.9.3 features:
feel on!
~endo
""",
"""
}

View File

@ -1,11 +1,13 @@
#!/usr/bin/python
"""
'''
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)
forked for envs.net by ~creme (creme@envs.net)
core.py:
this is a core handler for some ttbp standalone/output functions
@ -30,7 +32,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
the complete codebase is available at:
https://github.com/modgethanc/ttbp
"""
and
https://github.com/envs-net/ttbp
'''
import os
import time
@ -39,10 +43,7 @@ import re
import mistune
import json
from . import chatter
from . import config
from . import gopher
from . import util
from ttbp import config, chatter, gopher, util
FEED = os.path.join("/var", "global", "ttbp", "public_html", "index.html")
SETTINGS = {}
@ -52,11 +53,10 @@ FOOTER = ""
FILES = []
NOPUBS = []
def load(ttbprc={}):
"""
'''
get all them globals set up!!
"""
'''
global HEADER
global FOOTER
@ -69,17 +69,15 @@ def load(ttbprc={}):
load_nopubs()
load_files()
def reload_ttbprc(ttbprc={}):
"""
'''
reloads new ttbprc into current session
"""
'''
global SETTINGS
SETTINGS = ttbprc
def get_files(feelsdir=config.MAIN_FEELS):
"""Returns a list of user's feels in the given directory (defaults to main
feels dir)"""
@ -98,15 +96,14 @@ def get_files(feelsdir=config.MAIN_FEELS):
return files
def load_files(feelsdir=config.MAIN_FEELS):
"""
'''
file loader
* reads user's nopub file
* calls get_files() to load all files for given directory
* re-renders main html file and/or gopher if needed
"""
'''
global FILES
@ -115,9 +112,8 @@ def load_files(feelsdir=config.MAIN_FEELS):
if publishing():
write_html("index.html")
if SETTINGS.get("gopher"):
gopher.publish_gopher("feels", FILES)
if SETTINGS.get('gopher'):
gopher.publish_gopher('feels', FILES)
def load_nopubs():
"""Load a list of the user's nopub entries.
@ -134,26 +130,20 @@ def load_nopubs():
return len(NOPUBS)
## html outputting
def write_html(outurl="default.html"):
"""
'''
main page renderer
* takes everything currently in FILES and writes a single non-paginated html
file
* calls write_page() on each file to make permalinks
"""
'''
outfile = open(os.path.join(config.WWW, outurl), "w")
outfile.write(
"<!--generated by the envs.net blogging platform on "
+ time.strftime("%d %B %y")
+ "\nhttps://envs.net/ttbp/-->\n\n"
)
outfile.write("<!--generated by the envs.net blogging platform on "+time.strftime("%d %B %y")+"\nhttp://envs.net/ttbp/-->\n\n")
for line in HEADER:
outfile.write(line)
@ -172,29 +162,20 @@ def write_html(outurl="default.html"):
outfile.close()
return os.path.join(
config.LIVE + config.USER,
os.path.basename(os.path.realpath(config.WWW)),
outurl,
)
return os.path.join(config.LIVE+config.USER,os.path.basename(os.path.realpath(config.WWW)),outurl)
def write_page(filename):
"""
'''
permalink generator
* makes a page out of a single entry for permalinking, using filename/date as
url
"""
'''
outurl = os.path.join(config.WWW, "".join(util.parse_date(filename)) + ".html")
outurl = os.path.join(config.WWW, "".join(util.parse_date(filename))+".html")
outfile = open(outurl, "w")
outfile.write(
"<!--generated by the envs.net blogging platform on "
+ time.strftime("%d %B %y")
+ "\nhttps://envs.net/ttbp/-->\n\n"
)
outfile.write("<!--generated by the envs.net blogging platform on "+time.strftime("%d %B %y")+"\nhttp://envs.net/ttbp/-->\n\n")
for line in HEADER:
outfile.write(line)
@ -213,32 +194,21 @@ def write_page(filename):
return outurl
def write_entry(filename):
"""
'''
entry text generator
* dump given file into entry format by parsing file as markdown
* return as list of strings
"""
'''
date = util.parse_date(filename)
entry = [
'\t\t<p><a name="' + date[0] + date[1] + date[2] + '"></a><br /><br /></p>\n',
'\t\t<div class="entry">\n',
'\t\t\t<h5><a href="#'
+ date[0]
+ date[1]
+ date[2]
+ '">'
+ date[2]
+ "</a> "
+ chatter.month(date[1])
+ " "
+ date[0]
+ "</h5>\n"
# "\t\t\t<P>"
"\t\t<p><a name=\""+date[0]+date[1]+date[2]+"\"></a><br /><br /></p>\n",
"\t\t<div class=\"entry\">\n",
"\t\t\t<h5><a href=\"#"+date[0]+date[1]+date[2]+"\">"+date[2]+"</a> "+chatter.month(date[1])+" "+date[0]+"</h5>\n"
#"\t\t\t<P>"
]
raw = []
@ -248,41 +218,33 @@ def write_entry(filename):
raw.append(line)
rawfile.close()
entry.append(
"\t\t\t" + mistune.markdown("".join(raw), escape=False, hard_wrap=False)
)
entry.append("\t\t\t"+mistune.markdown("".join(raw), escape=False, hard_wrap=False))
# for line in raw:
# entry.append(line+"\t\t\t")
# if line == "\n":
# entry.append("</p>\n\t\t\t<p>")
#for line in raw:
#entry.append(line+"\t\t\t")
#if line == "\n":
# entry.append("</p>\n\t\t\t<p>")
# entry.append("</p>\n")
entry.append(
'\t\t\t<p class="permalink"><a href="'
+ "".join(date)
+ '.html">permalink</a></p>\n'
)
#entry.append("</p>\n")
entry.append("\t\t\t<p class=\"permalink\"><a href=\""+"".join(date)+".html\">permalink</a></p>\n")
entry.append("\n\t\t</div>\n")
return entry
def write_global_feed(blogList):
"""
'''
main ttbp index printer
* sources README.md for documentation
* takes incoming list of formatted blog links for all publishing blogs and
prints to blog feed
"""
'''
try:
try:
outfile = open(FEED, "w")
## header
outfile.write(
"""\
outfile.write("""\
<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">
<html>
<head>
@ -308,39 +270,25 @@ def write_global_feed(blogList):
)
## docs
outfile.write(
"""\
<div class="docs">"""
)
outfile.write(
mistune.markdown(
open(os.path.join(config.INSTALL_PATH, "..", "README.md"), "r").read()
)
)
outfile.write(
"""\
</div>"""
)
outfile.write("""\
<div class="docs">""")
outfile.write(mistune.markdown(open(os.path.join(config.INSTALL_PATH, "..", "README.md"), "r").read()))
outfile.write("""\
</div>""")
## feed
outfile.write(
"""\
outfile.write("""\
<p>&nbsp;</p>
<div class=\"feed\">
<h3>live feels-sharing:</h3>
<ul>"""
)
<ul>""")
for blog in blogList:
outfile.write(
"""
<li>"""
+ blog
+ """</li>\
"""
)
outfile.write("""
<li>"""+blog+"""</li>\
""")
## footer
outfile.write(
"""
outfile.write("""
</ul>
</div>
<!-- Button DarkLight-->
@ -356,20 +304,17 @@ def write_global_feed(blogList):
</body>
</html>
"""
)
""")
outfile.close()
# subprocess.call(['chmod', 'a+w', FEED])
#subprocess.call(['chmod', 'a+w', FEED])
except FileNotFoundError:
pass
## misc helpers
def meta(entries=FILES):
"""
def meta(entries = FILES):
'''
metadata generator
* takes a list of filenames and returns a 2d list:
@ -381,58 +326,50 @@ def meta(entries=FILES):
[5] author
* sorted in reverse date order by [4]
"""
'''
meta = []
for filename in entries:
mtime = os.path.getmtime(filename)
try:
wc = int(
subprocess.check_output(
["wc", "-w", filename], stderr=subprocess.STDOUT
).split()[0]
)
except subprocess.CalledProcessError:
wc = "???"
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(mtime))
date = "-".join(util.parse_date(filename))
author = os.path.split(
os.path.split(os.path.split(os.path.split(filename)[0])[0])[0]
)[1]
mtime = os.path.getmtime(filename)
try:
wc = int(subprocess.check_output(["wc","-w",filename], stderr=subprocess.STDOUT).split()[0])
except subprocess.CalledProcessError:
wc = "???"
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(mtime))
date = "-".join(util.parse_date(filename))
author = os.path.split(os.path.split(os.path.split(os.path.split(filename)[0])[0])[0])[1]
meta.append([filename, mtime, wc, timestamp, date, author])
meta.append([filename, mtime, wc, timestamp, date, author])
# meta.sort(key = lambda filename:filename[4])
# meta.reverse()
#meta.sort(key = lambda filename:filename[4])
#meta.reverse()
return meta
def valid(filename):
"""
'''
filename validator
* check if the filename is YYYYMMDD.txt
"""
'''
filesplit = os.path.splitext(os.path.basename(filename))
if filesplit[1] != ".txt":
return False
pattern = "^((19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|1\d|2\d|3[01])$"
pattern = '^((19|20)\d{2})(0[1-9]|1[0-2])(0[1-9]|1\d|2\d|3[01])$'
if not re.match(pattern, filesplit[0]):
return False
return True
def find_ttbps():
"""
'''
returns a list of users with a ttbp by checking for a valid ttbprc
"""
'''
users = []
@ -442,11 +379,10 @@ def find_ttbps():
return users
def publishing(username=config.USER):
"""
'''
checks .ttbprc for whether or not user opted for www publishing
"""
'''
ttbprc = {}
@ -454,17 +390,14 @@ def publishing(username=config.USER):
ttbprc = SETTINGS
else:
ttbprc = json.load(
open(os.path.join("/home", username, ".ttbp", "config", "ttbprc"))
)
ttbprc = json.load(open(os.path.join("/home", username, ".ttbp", "config", "ttbprc")))
return ttbprc.get("publishing")
def www_neighbors():
"""
'''
takes a list of users with publiishing turned on and prepares it for www output
"""
'''
userList = []
@ -472,13 +405,11 @@ def www_neighbors():
if not publishing(user):
continue
userRC = json.load(
open(os.path.join("/home", user, ".ttbp", "config", "ttbprc"))
)
userRC = json.load(open(os.path.join("/home", user, ".ttbp", "config", "ttbprc")))
url = ""
if userRC["publish dir"]:
url = config.LIVE + user + "/" + userRC["publish dir"]
url = config.LIVE+user+"/"+userRC["publish dir"]
lastfile = ""
try:
@ -492,21 +423,15 @@ def www_neighbors():
if lastfile:
last = os.path.getctime(lastfile)
timestamp = (
time.strftime("%Y-%m-%d at %H:%M", time.localtime(last))
+ " (utc"
+ time.strftime("%z")[0]
+ time.strftime("%z")[2]
+ ")"
)
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(last)) + " (utc"+time.strftime("%z")[0]+time.strftime("%z")[2]+")"
else:
timestamp = ""
last = 0
userList.append(['<a href="' + url + '">~' + user + "</a> " + timestamp, last])
userList.append(["<a href=\""+url+"\">~"+user+"</a> "+timestamp, last])
# sort user by most recent entry
userList.sort(key=lambda userdata: userdata[1])
userList.sort(key = lambda userdata:userdata[1])
userList.reverse()
sortedUsers = []
for user in userList:
@ -514,15 +439,13 @@ def www_neighbors():
write_global_feed(sortedUsers)
def nopub(filename):
"""
'''
checks to see if given filename is in user's NOPUB
"""
'''
return os.path.basename(filename) in NOPUBS
def toggle_nopub(filename):
"""toggles pub/nopub status for the given filename
@ -540,52 +463,38 @@ def toggle_nopub(filename):
NOPUBS.append(filename)
unpublish_feel(filename)
nopub_file = open(config.NOPUB, "w")
nopub_file.write(
"""\
nopub_file = open(config.NOPUB, 'w')
nopub_file.write("""\
# files that don't get published html/gopher. this file is
# generated by ttbp; editing it directly may result in unexpected
# behavior. if you have problems, back up this file, delete it, and
# rebuild it from ttbp.\n"""
)
# rebuild it from ttbp.\n""")
for entry in NOPUBS:
nopub_file.write(entry + "\n")
nopub_file.write(entry+"\n")
nopub_file.close()
load_files()
return action
def bury_feel(filename):
"""buries given filename; this removes the feel from any publicly-readable
location, and moves the textfile to user's private feels directory.
timestring will be added to the filename to disambiguate and prevent
filename collisions.
creates buried feels dir if it doesn't exist.
regenerates feels list and republishes."""
if not os.path.exists(config.BURIED_FEELS):
os.mkdir(config.BURIED_FEELS)
subprocess.call(["chmod", "700", config.BURIED_FEELS])
buryname = (
os.path.splitext(os.path.basename(filename))[0]
+ "-"
+ str(int(time.time()))
+ ".txt"
)
buryname = os.path.splitext(os.path.basename(filename))[0]+"-"+str(int(time.time()))+".txt"
subprocess.call(
[
"mv",
os.path.join(config.MAIN_FEELS, filename),
os.path.join(config.BURIED_FEELS, buryname),
]
)
subprocess.call(["mv", os.path.join(config.MAIN_FEELS, filename), os.path.join(config.BURIED_FEELS, buryname)])
subprocess.call(["chmod", "600", os.path.join(config.BURIED_FEELS, buryname)])
if publishing():
@ -595,7 +504,6 @@ def bury_feel(filename):
return os.path.join(config.BURIED_FEELS, buryname)
def delete_feel(filename):
"""deletes given filename; removes the feel from publicly-readable
locations, then deletes the original file."""
@ -606,21 +514,18 @@ def delete_feel(filename):
unpublish_feel(filename)
load_files(config.MAIN_FEELS)
def unpublish_feel(filename):
"""takes given filename and removes it from public_html and gopher_html, if
those locations exists. afterwards, regenerate index files appropriately."""
live_html = os.path.join(
config.WWW, os.path.splitext(os.path.basename(filename))[0] + ".html"
)
live_html = os.path.join(config.WWW,
os.path.splitext(os.path.basename(filename))[0]+".html")
if os.path.exists(live_html):
subprocess.call(["rm", live_html])
live_gopher = os.path.join(config.GOPHER_PATH, filename)
if os.path.exists(live_gopher):
subprocess.call(["rm", live_gopher])
def process_backup(filename):
"""takes given filename and unpacks it into a temp directory, then returns a
list of filenames with collisions filtered out.
@ -651,7 +556,6 @@ def process_backup(filename):
imported.sort()
return imported
def import_feels(backups):
"""takes a list of filepaths and copies those to current main feels.
@ -665,11 +569,10 @@ def import_feels(backups):
#############
#############
def test():
load()
metaTest = meta()
for x in metaTest:
print(x)
print(x)

View File

@ -6,10 +6,7 @@ import os
import time
import subprocess
from . import util
from . import config
# from .core import parse_date
from ttbp import util, config
GOPHER_PROMPT = """
@ -42,7 +39,7 @@ GOPHERMAP_HEADER = """
this file is automatically generated by ttbp.
0(about ttbp)\t/~endorphant/ttbp.txt\ttilde.town\t70
0(about ttbp)\t/ttbp.txt\tenvs.net\t70
1(back to user's home)\t/~{user}
entries:
@ -53,39 +50,32 @@ entries:
def select_gopher():
return util.input_yn(GOPHER_PROMPT)
def publish_gopher(gopher_path, entry_filenames):
"""This function (re)generates a user's list of feels posts in their gopher
directory and their gophermap."""
entry_filenames = entry_filenames[
:
] # force a copy since this might be shared state in core.py
ttbp_gopher = os.path.join(os.path.expanduser("~/public_gopher"), gopher_path)
entry_filenames = entry_filenames[:] # force a copy since this might be shared state in core.py
ttbp_gopher = os.path.join(
os.path.expanduser('~/public_gopher'),
gopher_path)
if not os.path.isdir(ttbp_gopher):
print(
"\n\tERROR: something is wrong. your gopher directory is missing. re-enable gopher publishing from the settings menu to fix this up!"
)
print('\n\tERROR: something is wrong. your gopher directory is missing. re-enable gopher publishing from the settings menu to fix this up!')
return
with open(os.path.join(ttbp_gopher, "gophermap"), "w") as gophermap:
gophermap.write(GOPHERMAP_HEADER.format(user=getpass.getuser()))
with open(os.path.join(ttbp_gopher, 'gophermap'), 'w') as gophermap:
gophermap.write(GOPHERMAP_HEADER.format(
user=getpass.getuser()))
for entry_filename in entry_filenames:
filename = os.path.basename(entry_filename)
gopher_entry_symlink = os.path.join(
ttbp_gopher, os.path.basename(entry_filename)
)
gopher_entry_symlink = os.path.join(ttbp_gopher, os.path.basename(entry_filename))
if not os.path.exists(gopher_entry_symlink):
subprocess.call(["ln", "-s", entry_filename, gopher_entry_symlink])
label = "-".join(util.parse_date(entry_filename))
gophermap.write(
"0{file_label}\t{filename}\n".format(
file_label=label, filename=filename
)
)
gophermap.write('0{file_label}\t{filename}\n'.format(
file_label=label,
filename=filename))
def setup_gopher(gopher_path):
"""Given a path relative to ~/public_gopher, this function:
@ -96,7 +86,7 @@ def setup_gopher(gopher_path):
It doesn't create a gophermap as that is left to the publish_gopher
function.
"""
public_gopher = os.path.expanduser("~/public_gopher")
public_gopher = os.path.expanduser('~/public_gopher')
if not os.path.isdir(public_gopher):
"""
@ -108,9 +98,7 @@ def setup_gopher(gopher_path):
ttbp_gopher = os.path.join(public_gopher, gopher_path)
if os.path.isdir(ttbp_gopher):
print(
"\n\tERROR: gopher path is already set up. quitting so we don't overwrite anything."
)
print("\n\tERROR: gopher path is already set up. quitting so we don't overwrite anything.")
return
gopher_entries = os.path.join(os.path.expanduser("~/.ttbp"), "gopher")
@ -119,7 +107,6 @@ def setup_gopher(gopher_path):
subprocess.call(["ln", "-s", gopher_entries, ttbp_gopher])
def unpublish():
"""blanks all gopher things and recreates the directories."""

File diff suppressed because it is too large Load Diff

View File

@ -3,4 +3,4 @@
import core
core.load()
print("\n blog updated at " + core.write("index.html") + "\n")
print("\n blog updated at "+core.write("index.html")+"\n")

View File

@ -1,6 +1,6 @@
#!/usr/bin/python
"""
'''
util.py: frequently used terminal and text processing utilities
copyright (c) 2016 ~endorphant (endorphant@tilde.town)
@ -22,7 +22,7 @@ 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.
"""
'''
import random
import time
from six.moves import input
@ -32,29 +32,20 @@ import colorama
import inflect
## misc globals
BACKS = ["back", "b", "q", "<q>"]
NAVS = ["u", "d"]
BACKS = ['back', 'b', 'q', '<q>']
NAVS = ['u', 'd']
## color stuff
colorama.init()
textcolors = [
colorama.Fore.RED,
colorama.Fore.GREEN,
colorama.Fore.YELLOW,
colorama.Fore.BLUE,
colorama.Fore.MAGENTA,
colorama.Fore.WHITE,
colorama.Fore.CYAN,
]
textcolors = [ colorama.Fore.RED, colorama.Fore.GREEN, colorama.Fore.YELLOW, colorama.Fore.BLUE, colorama.Fore.MAGENTA, colorama.Fore.WHITE, colorama.Fore.CYAN]
lastcolor = colorama.Fore.RESET
p = inflect.engine()
def set_rainbow():
"""
'''
prints a random terminal color code
"""
'''
global lastcolor
@ -66,19 +57,17 @@ def set_rainbow():
print(color)
def reset_color():
"""
'''
prints terminal color code reset
"""
'''
print(colorama.Fore.RESET)
def attach_rainbow():
"""
'''
returns a random terminal color code, presumably to be 'attached' to a string
"""
'''
global lastcolor
@ -89,27 +78,24 @@ def attach_rainbow():
lastcolor = color
return color
def attach_reset():
"""
'''
returns terminal color code reset, presumably to be 'attached' to a string
"""
'''
return colorama.Style.RESET_ALL
def hilight(text):
"""
'''
takes a string and highlights it on return
"""
return colorama.Style.BRIGHT + text + colorama.Style.NORMAL
'''
return colorama.Style.BRIGHT+text+colorama.Style.NORMAL
def rainbow(txt):
"""
'''
Takes a string and makes every letter a different color.
"""
'''
rainbow = ""
for letter in txt:
@ -119,15 +105,14 @@ def rainbow(txt):
return rainbow
def pretty_time(time):
"""
'''
human-friendly time formatter
takes an integer number of seconds and returns a phrase that describes it,
using the largest possible figure, rounded down (ie, time=604 returns '10
minutes', not '10 minutes, 4 seconds' or '604 seconds')
"""
'''
m, s = divmod(time, 60)
if m > 0:
@ -151,28 +136,26 @@ def pretty_time(time):
else:
return p.no("second", s)
def genID(digits=5):
"""
'''
returns a string-friendly string of digits, which can start with 0
"""
'''
id = ""
x = 0
x = 0
while x < digits:
id += str(random.randint(0, 9))
id += str(random.randint(0,9))
x += 1
return id
def print_menu(menu, rainbow=False):
"""
'''
A pretty menu handler that takes an incoming lists of
options and prints them nicely.
Set rainbow=True for colorized menus.
"""
'''
i = 0
for x in menu:
@ -182,24 +165,23 @@ def print_menu(menu, rainbow=False):
line.append("\t[ ")
if i < 10:
line.append(" ")
line.append(str(i) + " ] " + x)
line.append(str(i)+" ] "+x)
line.append(attach_reset())
print("".join(line))
i += 1
def list_select(options, prompt):
"""
'''
Given a list and query prompt, returns either False as an
eject flag, or an integer index of the list Catches cancel
option from list defined by BACKS; otherwise, retries on
ValueError or IndexError.
"""
'''
ans = ""
invalid = True
choice = input("\n" + prompt)
choice = input("\n"+prompt)
if choice in BACKS:
return False
@ -219,14 +201,13 @@ def list_select(options, prompt):
return ans
def input_yn(query):
"""
'''
Given a query, returns boolean True or False by processing y/n input
"""
'''
try:
ans = input(query + " [y/n] ")
ans = input(query+" [y/n] ")
except KeyboardInterrupt:
input_yn(query)
@ -235,9 +216,8 @@ def input_yn(query):
return ans == "y"
def parse_date(file):
"""
'''
parses date out of pre-validated filename
* assumes a filename of YYYYMMDD.txt
@ -245,7 +225,7 @@ def parse_date(file):
[0] 'YYYY'
[1] 'MM'
[2] 'DD'
"""
'''
rawdate = os.path.splitext(os.path.basename(file))[0]