Merge branch 'master' of github.com:modgethanc/ttbp
commit
198bde8ed3
268
README.html
268
README.html
|
@ -1,160 +1,204 @@
|
|||
<p><em>a command-line based blogging platform running on tilde.town</em></p>
|
||||
|
||||
<p><code>ttbp</code> stands for "tilde.town blogging platform", the original working name for
|
||||
this project.</p>
|
||||
|
||||
<p><img src="http://tilde.town/~endorphant/ttbp/screenshots/ttbp-main.png" alt="ttbp main menu screenshot" /></p>
|
||||
|
||||
<p><img src="http://tilde.town/~endorphant/ttbp/screenshots/ttbp-entries.png" alt="ttbp entries view screenshot" /></p>
|
||||
|
||||
<p><img src="http://tilde.town/~endorphant/ttbp/screenshots/ttbp-compose.png" alt="ttbp compose view screenshot" /></p>
|
||||
|
||||
<p><img alt="ttbp main menu screenshot" src="http://tilde.town/~endorphant/ttbp/screenshots/ttbp-main.png" /></p>
|
||||
<p><img alt="ttbp entries view screenshot" src="http://tilde.town/~endorphant/ttbp/screenshots/ttbp-entries.png" /></p>
|
||||
<p><img alt="ttbp compose view screenshot" src="http://tilde.town/~endorphant/ttbp/screenshots/ttbp-compose.png" /></p>
|
||||
<p><code>ttbp</code> runs from the command line, providing a hub for writing personal blog
|
||||
posts and reading posts written by other users of tilde.town. it's a little bit
|
||||
like livejournal or dreamwidth or tumblr. you can opt to publish your posts to
|
||||
a public html file hosted on your tilde page, or keep all your entries private
|
||||
to the tilde.town server.</p>
|
||||
|
||||
like livejournal or dreamwidth or tumblr. you can opt to publish your posts to a
|
||||
public html file hosted on your tilde page, to tilde.town's gopher server, or
|
||||
keep all your entries private to the tilde.town server.</p>
|
||||
<p>to use, run <code>feels</code> while logged in to tilde.town</p>
|
||||
|
||||
<p>(<code>feels</code> is a tilde.town specific command; if you're running this locally, or on
|
||||
a different server, run <code>ttbp</code> from the command line)</p>
|
||||
|
||||
<h3 id="quickstart">QUICK START</h3>
|
||||
|
||||
<p>this is a project that runs on tilde.town, so all users of this program are
|
||||
expected to operate under the tilde.town <a href="http://tilde.town/wiki/conduct.html">code of
|
||||
conduct</a>. content/personal issues should be
|
||||
worked out according to the CoC, with support from the <a href="http://tilde.town/wiki/administration/index.html">administrative
|
||||
team</a> if needed.</p>
|
||||
<h3>QUICK START</h3>
|
||||
<p>no coding or html experience is necessary to get started. just log in to your
|
||||
tilde.town account and enter:</p>
|
||||
|
||||
<p><code>feels</code></p>
|
||||
|
||||
<p>ttbp will ask you a few questions to get you started. after that, writing and
|
||||
reading entries all happen within the program.</p>
|
||||
|
||||
<p>that's it!</p>
|
||||
|
||||
<h3 id="support">SUPPORT</h3>
|
||||
|
||||
<h3>support</h3>
|
||||
<p>if you're having trouble getting started, or run into program errors or strange
|
||||
behavior, please send internal tilde.town mail to ~endorphant and i'll try to
|
||||
sort things out!</p>
|
||||
|
||||
<h3 id="writingentries">writing entries</h3>
|
||||
|
||||
<p>entries are recorded as plaintext files in your ~/.ttbp/entries
|
||||
directory. you can edit them there directly, or fix old entries, or
|
||||
delete entries.</p>
|
||||
|
||||
<p><em>warning</em>: changing old entries might cause strange things to
|
||||
happen with timestamps. the main program looks at the filename
|
||||
first for setting the date, then the last modified time to sort
|
||||
recent posts. it expects YYYMMDD.txt as the filename; anything else
|
||||
won't show up as a valid entry. yes, this means you can post things out
|
||||
of date order by creating files with any date you want.</p>
|
||||
|
||||
<h4 id="generalentrywritingnotes">general entry-writing notes</h4>
|
||||
|
||||
<p>there's also a function from the main menu that lets you send feedback/inquiries
|
||||
to me directly; this uses internal tilde.town mail, which is what i'll respond
|
||||
to.</p>
|
||||
<h3>writing entries</h3>
|
||||
<p>entries are recorded as plaintext files in your <code>~/.ttbp/entries</code> directory.
|
||||
<code>ttbp</code> will use your selected editor to open and write files; each day is its
|
||||
own entry, like a diary page. at midnight for whatever timezone you've set for
|
||||
your user account on tilde.town, you'll get a fresh entry. if you don't write
|
||||
any feels on a particular day, no entries will show up there.</p>
|
||||
<p>when you save and quit the text editor, your entry will automatically propagate
|
||||
to the global feels list; if you've opted to publish your feels to html/gopher,
|
||||
those files will update immediately. you can always go back to the current day's
|
||||
entry and edit/add as you'd like, but older entries will not be available for
|
||||
editing from <code>ttbp</code>.</p>
|
||||
<p><em>(since files are just stored as plaintext in your directory, it's possible to
|
||||
edit and move old entries directly from the command line. however, changing old
|
||||
entries might cause strange things to happen with timestamps. the main program
|
||||
looks at the filename first for setting the date, then the last modified time to
|
||||
sort recent posts. it expects YYYMMDD.txt as the filename; anything else won't
|
||||
show up as a valid entry. yes, this means you can post things out of date order
|
||||
by creating files with any date you want.)</em></p>
|
||||
<h4>general entry-writing notes</h4>
|
||||
<ul>
|
||||
<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><!-- comments --></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 id="privacy">privacy</h3>
|
||||
|
||||
<h3>reading other feels</h3>
|
||||
<p>the <code>browse global feels</code> feature shows the ten most recent entries that anyone
|
||||
has written on ttbp. this list is only accessible from within tilde.town,
|
||||
although individual entries may be posted to html or gopher.</p>
|
||||
<p>you can also pull up a list of a single user's feels through <code>check out your
|
||||
neighbors</code>, which displays all users who are writing on <code>ttbp</code> based on their
|
||||
most recently updated entry, and a link to their public html blog if they've
|
||||
opted to publish their posts.</p>
|
||||
<p><strong>please note!</strong> entries written on <code>ttbp</code> should be considered sensitive,
|
||||
private information, even if a particular user is publishing entries in a
|
||||
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. tilde.town operates on a high level of mutual trust, and <code>ttbp</code> is
|
||||
designed to give individuals control over their content.</p>
|
||||
<h3>privacy</h3>
|
||||
<p>when you start your ttbp, you have the option of publishing or not publishing
|
||||
your blog.</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://tilde.town/~endorphant/ttbp">main ttbp page</a>.</p>
|
||||
|
||||
<p>if you opt to not publish, your entires will never be accessible from outside
|
||||
of the tilde.town network; other tilde.town users will still be able to read
|
||||
your entries through the ttbp interface, or by directly accessing your
|
||||
<p>if you opt to not publish, your entires will never be accessible from outside of
|
||||
the tilde.town network; other tilde.town users will still be able to read your
|
||||
entries through the ttbp interface, or by directly accessing your
|
||||
<code>~/.ttbp/entries</code> directory.</p>
|
||||
|
||||
<p>if you want to further protect your entries, you can <code>chmod 700</code> your entries
|
||||
directory.</p>
|
||||
|
||||
<h3 id="changingyourpagelayout">changing your page layout</h3>
|
||||
|
||||
<p>you can modify how your blog looks by editing the stylesheet or
|
||||
header and footer files. the program sets you up with basic
|
||||
default. if you break your page somehow, you can force the program to
|
||||
regenerate your configuration by deleting your ~/.ttbp directory entirely.
|
||||
<strong>you might want to back up your ~/.ttbp/entries directory before you do
|
||||
this.</strong></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://tilde.town/~endorphant/ttbp">main ttbp
|
||||
page</a>.</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;
|
||||
see "data management" below for details.</p>
|
||||
<h3>data management</h3>
|
||||
<p>the <code>manage your feels</code> menu provides several tools for organizing your feels.
|
||||
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>to modify your stylesheet, edit your ~/.ttbp/config/style.css
|
||||
|
||||
|
||||
<li><strong>read over feels</strong>--a list of all your entries, which you can open and
|
||||
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 tilde.town)</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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
</ul>
|
||||
<h3>settings</h3>
|
||||
<p>the settings menu lets you change specific options for handling your feels and
|
||||
using the interface.</p>
|
||||
<ul>
|
||||
<li>(future feature: having multiple stylesheets you can select)</li></ul>
|
||||
</li>
|
||||
|
||||
<li>to modify the page header, edit your ~/.ttbp/config/header.txt
|
||||
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<li><strong>publishing</strong>--opt in or out of automatically publishing entries to a
|
||||
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>
|
||||
<p>you can modify how your blog looks by editing the stylesheet or header and
|
||||
footer files. the program sets you up with basic default. if you break your page
|
||||
somehow, you can force the program to regenerate your configuration by deleting
|
||||
your ~/.ttbp directory entirely. <strong>you might want to back up your
|
||||
~/.ttbp/entries directory before you do this.</strong></p>
|
||||
<ul>
|
||||
<li>you might note that there's a place marked off in the default header where
|
||||
you can safely put custom HTML elements!</li></ul>
|
||||
</li>
|
||||
|
||||
<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>there's a place marked off in the default header where you can safely put
|
||||
custom HTML elements!</li>
|
||||
<li>to modify the page footer, edit your ~/.ttbp/config/footer.txt</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="generaltipstroubleshooting">general tips/troubleshooting</h3>
|
||||
|
||||
<h3>general tips/troubleshooting</h3>
|
||||
<ul>
|
||||
<li>add <code>alias ttbp="~endorphant/bin/ttbp"</code> to your .bash_aliases for fewer keystrokes</li>
|
||||
|
||||
<li>(similarly, <code>alias ttbp-beta="~endorphant/bin/ttbp-beta"</code>)</li>
|
||||
|
||||
<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>
|
||||
</ul>
|
||||
|
||||
<h3 id="futurefeatures">future features</h3>
|
||||
|
||||
<h3>future features</h3>
|
||||
<p>these are a few ideas being kicked around, or under active development:</p>
|
||||
|
||||
<ul>
|
||||
<li>better entry privacy/publish control options</li>
|
||||
|
||||
<li>stylesheet/theme selector</li>
|
||||
|
||||
<li>responding to entries</li>
|
||||
|
||||
<li>paginated list view</li>
|
||||
|
||||
<li>better entry display within ttbp</li>
|
||||
<li>better entry display within ttbp (currently just offloads to <code>less</code>)</li>
|
||||
<li>buried feels browser</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="dependencies">dependencies</h3>
|
||||
|
||||
<p>other ideas are listed on github as
|
||||
<a href="https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A" title="upcoming+features">upcoming features</a> or <a href="https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A" title="feature+request">feature requests</a>!</p>
|
||||
<h3>dependencies</h3>
|
||||
<p>(this section is only relevant if you plan on forking the repo and running an
|
||||
instance of this yourself)</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://pypi.python.org/pypi/mistune">mistune</a></li>
|
||||
|
||||
<li><a href="https://pypi.python.org/pypi/inflect">inflect</a></li>
|
||||
<li><a href="https://pypi.python.org/pypi/six">six</a></li>
|
||||
</ul>
|
||||
|
||||
<h3 id="contributing">contributing</h3>
|
||||
|
||||
<h3>contributing</h3>
|
||||
<p>please check out my <a href="https://github.com/modgethanc/ttbp/blob/master/.github/CONTRIBUTING.md">contributor
|
||||
guidelines</a>
|
||||
on github if you'd like to get involved with development!</p>
|
||||
|
||||
<p>if you find any bugs or strange behavior, please message me locally on tildemail
|
||||
or open a github issue and i'll get back to you as soon as i can.</p>
|
||||
|
||||
<p>if you're interested in helping with the code, please drop me some tildemail!</p>
|
||||
<p>if you're interested in helping with the code, please drop me some tildemail!</p>
|
||||
<p>i accept tips for development work on
|
||||
<a href="https://liberapay.com/modgethanc">liberapay</a></p>
|
||||
<h3>contributor shout-outs</h3>
|
||||
<p>thanks to:</p>
|
||||
<ul>
|
||||
<li>~vilmibm, packaging help and gopher support</li>
|
||||
<li>~sanqui, the bug swatter</li>
|
||||
<li>~sinacutie, for css updates</li>
|
||||
</ul>
|
196
README.md
196
README.md
|
@ -11,14 +11,18 @@ this project.
|
|||
|
||||
`ttbp` runs from the command line, providing a hub for writing personal blog
|
||||
posts and reading posts written by other users of tilde.town. it's a little bit
|
||||
like livejournal or dreamwidth or tumblr. you can opt to publish your posts to
|
||||
a public html file hosted on your tilde page, or keep all your entries private
|
||||
to the tilde.town server.
|
||||
like livejournal or dreamwidth or tumblr. you can opt to publish your posts to a
|
||||
public html file hosted on your tilde page, to tilde.town's gopher server, or
|
||||
keep all your entries private to the tilde.town server.
|
||||
|
||||
to use, run `feels` while logged in to tilde.town
|
||||
|
||||
(`feels` is a tilde.town specific command; if you're running this locally, or on
|
||||
a different server, run `ttbp` from the command line)
|
||||
this is a project that runs on tilde.town, so all users of this program are
|
||||
expected to operate under the tilde.town [code of
|
||||
conduct](http://tilde.town/wiki/conduct.html). content/personal issues should be
|
||||
worked out according to the CoC, with support from the [administrative
|
||||
team](http://tilde.town/wiki/administration/index.html) if needed.
|
||||
|
||||
|
||||
### QUICK START
|
||||
|
||||
|
@ -32,84 +36,184 @@ reading entries all happen within the program.
|
|||
|
||||
that's it!
|
||||
|
||||
### SUPPORT
|
||||
### support
|
||||
|
||||
if you're having trouble getting started, or run into program errors or strange
|
||||
behavior, please send internal tilde.town mail to ~endorphant and i'll try to
|
||||
sort things out!
|
||||
|
||||
there's also a function from the main menu that lets you send feedback/inquiries
|
||||
to me directly; this uses internal tilde.town mail, which is what i'll respond
|
||||
to.
|
||||
|
||||
### writing entries
|
||||
|
||||
entries are recorded as plaintext files in your ~/.ttbp/entries
|
||||
directory. you can edit them there directly, or fix old entries, or
|
||||
delete entries.
|
||||
entries are recorded as plaintext files in your `~/.ttbp/entries` directory.
|
||||
`ttbp` will use your selected editor to open and write files; each day is its
|
||||
own entry, like a diary page. at midnight for whatever timezone you've set for
|
||||
your user account on tilde.town, you'll get a fresh entry. if you don't write
|
||||
any feels on a particular day, no entries will show up there.
|
||||
|
||||
*warning*: changing old entries might cause strange things to
|
||||
happen with timestamps. the main program looks at the filename
|
||||
first for setting the date, then the last modified time to sort
|
||||
recent posts. it expects YYYMMDD.txt as the filename; anything else
|
||||
won't show up as a valid entry. yes, this means you can post things out
|
||||
of date order by creating files with any date you want.
|
||||
when you save and quit the text editor, your entry will automatically propagate
|
||||
to the global feels list; if you've opted to publish your feels to html/gopher,
|
||||
those files will update immediately. you can always go back to the current day's
|
||||
entry and edit/add as you'd like, but older entries will not be available for
|
||||
editing from `ttbp`.
|
||||
|
||||
*(since files are just stored as plaintext in your directory, it's possible to
|
||||
edit and move old entries directly from the command line. however, changing old
|
||||
entries might cause strange things to happen with timestamps. the main program
|
||||
looks at the filename first for setting the date, then the last modified time to
|
||||
sort recent posts. it expects YYYMMDD.txt as the filename; anything else won't
|
||||
show up as a valid entry. yes, this means you can post things out of date order
|
||||
by creating files with any date you want.)*
|
||||
|
||||
#### general entry-writing notes
|
||||
|
||||
* you can use [markdown](https://daringfireball.net/projects/markdown/syntax)
|
||||
* you can use html
|
||||
* you can also put things between `<!-- comments -->` to have them show up
|
||||
in the feed but not render in a browser (but people can still read
|
||||
them with view-source)
|
||||
in the feed but not render in a browser (but people can still read
|
||||
them with view-source)
|
||||
|
||||
### reading other feels
|
||||
|
||||
the `browse global feels` feature shows the ten most recent entries that anyone
|
||||
has written on ttbp. this list is only accessible from within tilde.town,
|
||||
although individual entries may be posted to html or gopher.
|
||||
|
||||
you can also pull up a list of a single user's feels through `check out your
|
||||
neighbors`, which displays all users who are writing on `ttbp` based on their
|
||||
most recently updated entry, and a link to their public html blog if they've
|
||||
opted to publish their posts.
|
||||
|
||||
**please note!** entries written on `ttbp` should be considered sensitive,
|
||||
private information, even if a particular user is publishing entries in a
|
||||
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. tilde.town operates on a high level of mutual trust, and `ttbp` is
|
||||
designed to give individuals control over their content.
|
||||
|
||||
### privacy
|
||||
|
||||
when you start your ttbp, you have the option of publishing or not publishing
|
||||
your blog.
|
||||
|
||||
if you opt to publish, the program creates a directory `~/.ttbp/www`
|
||||
where it stores all html files it generates, and symlinks this from your
|
||||
`~/public_html` with your chosen blog directory. your blog will also be listed
|
||||
on the [main ttbp page](https://tilde.town/~endorphant/ttbp).
|
||||
|
||||
if you opt to not publish, your entires will never be accessible from outside
|
||||
of the tilde.town network; other tilde.town users will still be able to read
|
||||
your entries through the ttbp interface, or by directly accessing your
|
||||
if you opt to not publish, your entires will never be accessible from outside of
|
||||
the tilde.town network; other tilde.town users will still be able to read your
|
||||
entries through the ttbp interface, or by directly accessing your
|
||||
`~/.ttbp/entries` directory.
|
||||
|
||||
if you want to further protect your entries, you can `chmod 700` your entries
|
||||
directory.
|
||||
|
||||
if you opt to publish, the program creates a directory `~/.ttbp/www` where it
|
||||
stores all html files it generates, and symlinks this from your `~/public_html`
|
||||
with your chosen blog directory. your blog will also be listed on the [main ttbp
|
||||
page](https://tilde.town/~endorphant/ttbp).
|
||||
|
||||
you can also opt to publish to gopher, and the program will automatically
|
||||
generate a gophermap of your feels.
|
||||
|
||||
you can set publishing status on individual entries, or bury individual feels;
|
||||
see "data management" below for details.
|
||||
|
||||
### data management
|
||||
|
||||
the `manage your feels` menu provides several tools for organizing your feels.
|
||||
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.
|
||||
|
||||
* **read over feels**--a list of all your entries, which you can open and
|
||||
read like any other feel
|
||||
* **modify feels publishing**--this lets you toggle privacy on individual
|
||||
posts. entries marked `(nopub)` 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.town)
|
||||
* **backup your feels**--makes a .tar.gz of all your entries, saving one
|
||||
copy to `~/.ttbp/backups/` with the current date, and a second copy to
|
||||
your home directory for safekeeping.
|
||||
* **import a feels backup**--unpacks a backup file into your current feels
|
||||
list. this tool checks the `~/.ttbp/backups` 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 `(nopub)` will retain their nopub
|
||||
status.
|
||||
* **bury some feels**--hides individual feels from viewing; entries are
|
||||
moved to `~/.ttbp/buried` (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 `read over feels`, 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.
|
||||
* **delete feels by day**--*permanently removes individual entries*,
|
||||
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.
|
||||
* **purge all feels**--*permanently removes all feels*, 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.
|
||||
* **wipe feels account**--*permanently removes all data associated with
|
||||
feels*, including deleting any published hmtl/gopher files and removing
|
||||
your `~/.ttbp` directory. any backups that you have in `~/.ttbp/backups`
|
||||
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.
|
||||
|
||||
### settings
|
||||
|
||||
the settings menu lets you change specific options for handling your feels and
|
||||
using the interface.
|
||||
|
||||
* **editor**--set your text editor
|
||||
* **gopher**--opt in or out of automatically posting to gopher
|
||||
* **post as nopub**--set whether posts default to being published or not
|
||||
published (if you're not publishing your feels, this doesn't matter)
|
||||
* **publish dir**--set the directory under you `public_html` where feels will be
|
||||
published (if you're not publishing your feels, this defaults to `None`)
|
||||
* **publishing**--opt in or out of automatically publishing entries to a
|
||||
world-readable html page
|
||||
* **rainbows**--opt in or out of having multicolored menu text
|
||||
|
||||
### changing your page layout
|
||||
|
||||
you can modify how your blog looks by editing the stylesheet or
|
||||
header and footer files. the program sets you up with basic
|
||||
default. if you break your page somehow, you can force the program to
|
||||
regenerate your configuration by deleting your ~/.ttbp directory entirely.
|
||||
**you might want to back up your ~/.ttbp/entries directory before you do
|
||||
this.**
|
||||
you can modify how your blog looks by editing the stylesheet or header and
|
||||
footer files. the program sets you up with basic default. if you break your page
|
||||
somehow, you can force the program to regenerate your configuration by deleting
|
||||
your ~/.ttbp directory entirely. **you might want to back up your
|
||||
~/.ttbp/entries directory before you do this.**
|
||||
|
||||
* to modify your stylesheet, edit your ~/.ttbp/config/style.css
|
||||
* (future feature: having multiple stylesheets you can select)
|
||||
* to modify the page header, edit your ~/.ttbp/config/header.txt
|
||||
* you might note that there's a place marked off in the default header where
|
||||
you can safely put custom HTML elements!
|
||||
* there's a place marked off in the default header where you can safely put
|
||||
custom HTML elements!
|
||||
* to modify the page footer, edit your ~/.ttbp/config/footer.txt
|
||||
|
||||
### general tips/troubleshooting
|
||||
|
||||
* add `alias ttbp="~endorphant/bin/ttbp"` to your .bash_aliases for fewer keystrokes
|
||||
* (similarly, `alias ttbp-beta="~endorphant/bin/ttbp-beta"`)
|
||||
* if the date looks like it's ahead or behind, it's because you haven't set
|
||||
your local timezone yet. here are some
|
||||
[timezone setting instructions](http://www.cyberciti.biz/faq/linux-unix-set-tz-environment-variable/)
|
||||
* 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
|
||||
|
||||
### future features
|
||||
|
||||
these are a few ideas being kicked around, or under active development:
|
||||
|
||||
* better entry privacy/publish control options
|
||||
* stylesheet/theme selector
|
||||
* responding to entries
|
||||
* paginated list view
|
||||
* better entry display within ttbp
|
||||
* better entry display within ttbp (currently just offloads to `less`)
|
||||
* buried feels browser
|
||||
|
||||
other ideas are listed on github as
|
||||
[upcoming features](https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A"upcoming+features") or [feature requests](https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A"feature+request")!
|
||||
|
||||
### dependencies
|
||||
|
||||
|
@ -118,6 +222,7 @@ instance of this yourself)
|
|||
|
||||
* [mistune](https://pypi.python.org/pypi/mistune)
|
||||
* [inflect](https://pypi.python.org/pypi/inflect)
|
||||
* [six](https://pypi.python.org/pypi/six)
|
||||
|
||||
### contributing
|
||||
|
||||
|
@ -129,3 +234,14 @@ if you find any bugs or strange behavior, please message me locally on tildemail
|
|||
or open a github issue and i'll get back to you as soon as i can.
|
||||
|
||||
if you're interested in helping with the code, please drop me some tildemail!
|
||||
|
||||
i accept tips for development work on
|
||||
[liberapay](https://liberapay.com/modgethanc)
|
||||
|
||||
### contributor shout-outs
|
||||
|
||||
thanks to:
|
||||
|
||||
* ~vilmibm, packaging help and gopher support
|
||||
* ~sanqui, the bug swatter
|
||||
* ~sinacutie, for css updates
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
<h1>FEELS MANUAL</h1>
|
||||
<p><code>ttbp</code> stands for "tilde.town blogging platform", the original working name for
|
||||
this project. the complete codebase is available on
|
||||
<a href="https://github.com/modgethanc/ttbp">github</a>.</p>
|
||||
<p><code>ttbp</code> runs from the command line, providing a hub for writing personal blog
|
||||
posts and reading posts written by other users of tilde.town. it's a little bit
|
||||
like livejournal or dreamwidth or tumblr. you can opt to publish your posts to a
|
||||
public html file hosted on your tilde page, to tilde.town's gopher server, or
|
||||
keep all your entries private to the tilde.town server.</p>
|
||||
<p>this is a project that runs on tilde.town, so all users of this program are
|
||||
expected to operate under the tilde.town <a href="http://tilde.town/wiki/conduct.html">code of
|
||||
conduct</a>. content/personal issues should be
|
||||
worked out according to the CoC, with support from the <a href="http://tilde.town/wiki/administration/index.html">administrative
|
||||
team</a> if needed.</p>
|
||||
<h3>support</h3>
|
||||
<p>if you're having trouble getting started, or run into program errors or strange
|
||||
behavior, please send internal tilde.town mail to ~endorphant and i'll try to
|
||||
sort things out!</p>
|
||||
<p>there's also a function from the main menu that lets you send feedback/inquiries
|
||||
to me directly; this uses internal tilde.town mail, which is what i'll respond
|
||||
to.</p>
|
||||
<h3>writing entries</h3>
|
||||
<p>entries are recorded as plaintext files in your <code>~/.ttbp/entries</code> directory.
|
||||
<code>ttbp</code> will use your selected editor to open and write files; each day is its
|
||||
own entry, like a diary page. at midnight for whatever timezone you've set for
|
||||
your user account on tilde.town, you'll get a fresh entry. if you don't write
|
||||
any feels on a particular day, no entries will show up there.</p>
|
||||
<p>when you save and quit the text editor, your entry will automatically propagate
|
||||
to the global feels list; if you've opted to publish your feels to html/gopher,
|
||||
those files will update immediately. you can always go back to the current day's
|
||||
entry and edit/add as you'd like, but older entries will not be available for
|
||||
editing from <code>ttbp</code>.</p>
|
||||
<p><em>(since files are just stored as plaintext in your directory, it's possible to
|
||||
edit and move old entries directly from the command line. however, changing old
|
||||
entries might cause strange things to happen with timestamps. the main program
|
||||
looks at the filename first for setting the date, then the last modified time to
|
||||
sort recent posts. it expects YYYMMDD.txt as the filename; anything else won't
|
||||
show up as a valid entry. yes, this means you can post things out of date order
|
||||
by creating files with any date you want.)</em></p>
|
||||
<h4>general entry-writing notes</h4>
|
||||
<ul>
|
||||
<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><!-- comments --></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>
|
||||
</ul>
|
||||
<h3>reading other feels</h3>
|
||||
<p>the <code>browse global feels</code> feature shows the ten most recent entries that anyone
|
||||
has written on ttbp. this list is only accessible from within tilde.town,
|
||||
although individual entries may be posted to html or gopher.</p>
|
||||
<p>you can also pull up a list of a single user's feels through <code>check out your
|
||||
neighbors</code>, which displays all users who are writing on <code>ttbp</code> based on their
|
||||
most recently updated entry, and a link to their public html blog if they've
|
||||
opted to publish their posts.</p>
|
||||
<p><strong>please note!</strong> entries written on <code>ttbp</code> should be considered sensitive,
|
||||
private information, even if a particular user is publishing entries in a
|
||||
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. tilde.town operates on a high level of mutual trust, and <code>ttbp</code> is
|
||||
designed to give individuals control over their content.</p>
|
||||
<h3>privacy</h3>
|
||||
<p>when you start your ttbp, you have the option of publishing or not publishing
|
||||
your blog.</p>
|
||||
<p>if you opt to not publish, your entires will never be accessible from outside of
|
||||
the tilde.town network; other tilde.town users will still be able to read your
|
||||
entries through the ttbp interface, or by directly accessing your
|
||||
<code>~/.ttbp/entries</code> directory.</p>
|
||||
<p>if you want to further protect your entries, you can <code>chmod 700</code> your entries
|
||||
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://tilde.town/~endorphant/ttbp">main ttbp
|
||||
page</a>.</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;
|
||||
see "data management" below for details.</p>
|
||||
<h3>data management</h3>
|
||||
<p>the <code>manage your feels</code> menu provides several tools for organizing your feels.
|
||||
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>
|
||||
<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 tilde.town)</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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
</ul>
|
||||
<h3>settings</h3>
|
||||
<p>the settings menu lets you change specific options for handling your feels and
|
||||
using the interface.</p>
|
||||
<ul>
|
||||
<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>
|
||||
<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>
|
||||
<li><strong>publishing</strong>--opt in or out of automatically publishing entries to a
|
||||
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>
|
||||
<p>you can modify how your blog looks by editing the stylesheet or header and
|
||||
footer files. the program sets you up with basic default. if you break your page
|
||||
somehow, you can force the program to regenerate your configuration by deleting
|
||||
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>there's a place marked off in the default header where you can safely put
|
||||
custom HTML elements!</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>
|
||||
<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>
|
||||
</ul>
|
||||
<h3>future features</h3>
|
||||
<p>these are a few ideas being kicked around, or under active development:</p>
|
||||
<ul>
|
||||
<li>stylesheet/theme selector</li>
|
||||
<li>better entry display within ttbp (currently just offloads to <code>less</code>)</li>
|
||||
<li>buried feels browser</li>
|
||||
</ul>
|
||||
<p>other ideas are listed on github as
|
||||
<a href="https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A" title="upcoming+features">upcoming features</a> or <a href="https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A" title="feature+request">feature requests</a>!</p>
|
|
@ -0,0 +1,196 @@
|
|||
# FEELS MANUAL #
|
||||
|
||||
`ttbp` stands for "tilde.town blogging platform", the original working name for
|
||||
this project. the complete codebase is available on
|
||||
[github](https://github.com/modgethanc/ttbp).
|
||||
|
||||
`ttbp` runs from the command line, providing a hub for writing personal blog
|
||||
posts and reading posts written by other users of tilde.town. it's a little bit
|
||||
like livejournal or dreamwidth or tumblr. you can opt to publish your posts to a
|
||||
public html file hosted on your tilde page, to tilde.town's gopher server, or
|
||||
keep all your entries private to the tilde.town server.
|
||||
|
||||
this is a project that runs on tilde.town, so all users of this program are
|
||||
expected to operate under the tilde.town [code of
|
||||
conduct](http://tilde.town/wiki/conduct.html). content/personal issues should be
|
||||
worked out according to the CoC, with support from the [administrative
|
||||
team](http://tilde.town/wiki/administration/index.html) if needed.
|
||||
|
||||
### support
|
||||
|
||||
if you're having trouble getting started, or run into program errors or strange
|
||||
behavior, please send internal tilde.town mail to ~endorphant and i'll try to
|
||||
sort things out!
|
||||
|
||||
there's also a function from the main menu that lets you send feedback/inquiries
|
||||
to me directly; this uses internal tilde.town mail, which is what i'll respond
|
||||
to.
|
||||
|
||||
### writing entries
|
||||
|
||||
entries are recorded as plaintext files in your `~/.ttbp/entries` directory.
|
||||
`ttbp` will use your selected editor to open and write files; each day is its
|
||||
own entry, like a diary page. at midnight for whatever timezone you've set for
|
||||
your user account on tilde.town, you'll get a fresh entry. if you don't write
|
||||
any feels on a particular day, no entries will show up there.
|
||||
|
||||
when you save and quit the text editor, your entry will automatically propagate
|
||||
to the global feels list; if you've opted to publish your feels to html/gopher,
|
||||
those files will update immediately. you can always go back to the current day's
|
||||
entry and edit/add as you'd like, but older entries will not be available for
|
||||
editing from `ttbp`.
|
||||
|
||||
*(since files are just stored as plaintext in your directory, it's possible to
|
||||
edit and move old entries directly from the command line. however, changing old
|
||||
entries might cause strange things to happen with timestamps. the main program
|
||||
looks at the filename first for setting the date, then the last modified time to
|
||||
sort recent posts. it expects YYYMMDD.txt as the filename; anything else won't
|
||||
show up as a valid entry. yes, this means you can post things out of date order
|
||||
by creating files with any date you want.)*
|
||||
|
||||
#### general entry-writing notes
|
||||
|
||||
* you can use [markdown](https://daringfireball.net/projects/markdown/syntax)
|
||||
* you can use html
|
||||
* you can also put things between `<!-- comments -->` to have them show up
|
||||
in the feed but not render in a browser (but people can still read them with
|
||||
view-source)
|
||||
|
||||
### reading other feels
|
||||
|
||||
the `browse global feels` feature shows the ten most recent entries that anyone
|
||||
has written on ttbp. this list is only accessible from within tilde.town,
|
||||
although individual entries may be posted to html or gopher.
|
||||
|
||||
you can also pull up a list of a single user's feels through `check out your
|
||||
neighbors`, which displays all users who are writing on `ttbp` based on their
|
||||
most recently updated entry, and a link to their public html blog if they've
|
||||
opted to publish their posts.
|
||||
|
||||
**please note!** entries written on `ttbp` should be considered sensitive,
|
||||
private information, even if a particular user is publishing entries in a
|
||||
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. tilde.town operates on a high level of mutual trust, and `ttbp` is
|
||||
designed to give individuals control over their content.
|
||||
|
||||
### privacy
|
||||
|
||||
when you start your ttbp, you have the option of publishing or not publishing
|
||||
your blog.
|
||||
|
||||
if you opt to not publish, your entires will never be accessible from outside of
|
||||
the tilde.town network; other tilde.town users will still be able to read your
|
||||
entries through the ttbp interface, or by directly accessing your
|
||||
`~/.ttbp/entries` directory.
|
||||
|
||||
if you want to further protect your entries, you can `chmod 700` your entries
|
||||
directory.
|
||||
|
||||
if you opt to publish, the program creates a directory `~/.ttbp/www` where it
|
||||
stores all html files it generates, and symlinks this from your `~/public_html`
|
||||
with your chosen blog directory. your blog will also be listed on the [main ttbp
|
||||
page](https://tilde.town/~endorphant/ttbp).
|
||||
|
||||
you can also opt to publish to gopher, and the program will automatically
|
||||
generate a gophermap of your feels.
|
||||
|
||||
you can set publishing status on individual entries, or bury individual feels;
|
||||
see "data management" below for details.
|
||||
|
||||
### data management
|
||||
|
||||
the `manage your feels` menu provides several tools for organizing your feels.
|
||||
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.
|
||||
|
||||
* **read over feels**--a list of all your entries, which you can open and
|
||||
read like any other feel
|
||||
* **modify feels publishing**--this lets you toggle privacy on individual
|
||||
posts. entries marked `(nopub)` 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.town)
|
||||
* **backup your feels**--makes a .tar.gz of all your entries, saving one
|
||||
copy to `~/.ttbp/backups/` with the current date, and a second copy to
|
||||
your home directory for safekeeping.
|
||||
* **import a feels backup**--unpacks a backup file into your current feels
|
||||
list. this tool checks the `~/.ttbp/backups` 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 `(nopub)` will retain their nopub
|
||||
status.
|
||||
* **bury some feels**--hides individual feels from viewing; entries are
|
||||
moved to `~/.ttbp/buried` (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 `read over feels`, 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.
|
||||
* **delete feels by day**--*permanently removes individual entries*,
|
||||
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.
|
||||
* **purge all feels**--*permanently removes all feels*, 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.
|
||||
* **wipe feels account**--*permanently removes all data associated with
|
||||
feels*, including deleting any published hmtl/gopher files and removing
|
||||
your `~/.ttbp` directory. any backups that you have in `~/.ttbp/backups`
|
||||
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.
|
||||
|
||||
### settings
|
||||
|
||||
the settings menu lets you change specific options for handling your feels and
|
||||
using the interface.
|
||||
|
||||
* **editor**--set your text editor
|
||||
* **gopher**--opt in or out of automatically posting to gopher
|
||||
* **post as nopub**--set whether posts default to being published or not
|
||||
published (if you're not publishing your feels, this doesn't matter)
|
||||
* **publish dir**--set the directory under you `public_html` where feels will be
|
||||
published (if you're not publishing your feels, this defaults to `None`)
|
||||
* **publishing**--opt in or out of automatically publishing entries to a
|
||||
world-readable html page
|
||||
* **rainbows**--opt in or out of having multicolored menu text
|
||||
|
||||
### changing your page layout
|
||||
|
||||
you can modify how your blog looks by editing the stylesheet or header and
|
||||
footer files. the program sets you up with basic default. if you break your page
|
||||
somehow, you can force the program to regenerate your configuration by deleting
|
||||
your ~/.ttbp directory entirely. **you might want to back up your
|
||||
~/.ttbp/entries directory before you do this.**
|
||||
|
||||
* to modify your stylesheet, edit your ~/.ttbp/config/style.css
|
||||
* to modify the page header, edit your ~/.ttbp/config/header.txt
|
||||
* there's a place marked off in the default header where you can safely put
|
||||
custom HTML elements!
|
||||
* to modify the page footer, edit your ~/.ttbp/config/footer.txt
|
||||
|
||||
### general tips/troubleshooting
|
||||
|
||||
* if the date looks like it's ahead or behind, it's because you haven't set
|
||||
your local timezone yet. here are some
|
||||
[timezone setting instructions](http://www.cyberciti.biz/faq/linux-unix-set-tz-environment-variable/)
|
||||
* 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
|
||||
|
||||
### future features
|
||||
|
||||
these are a few ideas being kicked around, or under active development:
|
||||
|
||||
* stylesheet/theme selector
|
||||
* better entry display within ttbp (currently just offloads to `less`)
|
||||
* buried feels browser
|
||||
|
||||
other ideas are listed on github as
|
||||
[upcoming features](https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A"upcoming+features") or [feature requests](https://github.com/modgethanc/ttbp/issues?q=is%3Aissue+is%3Aopen+label%3A"feature+request")!
|
2
setup.py
2
setup.py
|
@ -4,7 +4,7 @@ from setuptools import setup
|
|||
|
||||
setup(
|
||||
name='ttbp',
|
||||
version='0.11.2',
|
||||
version='0.12.0',
|
||||
description='command line social blogging tool used on tilde.town',
|
||||
url='https://github.com/modgethanc/ttbp',
|
||||
author='~endorphant',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import absolute_import
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from .. import util
|
||||
|
||||
|
@ -67,11 +68,14 @@ 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')
|
||||
USER_DATA = os.path.join(PATH, 'entries')
|
||||
NOPUB = os.path.join(USER_CONFIG, "nopub")
|
||||
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')
|
||||
|
||||
## UI
|
||||
|
||||
|
@ -82,9 +86,102 @@ ___________________________________________________________
|
|||
| ____ ____ ____ _ ____ ____ _ _ ____ _ _ _ ____ |
|
||||
| |___ |___ |___ | [__ |___ |\ | | __ | |\ | |___ |
|
||||
| | |___ |___ |___ ___] |___ | \| |__] | | \| |___ |
|
||||
| ver 0.11.2 (rainbows) |
|
||||
| <gan jue; to feel> ver 0.12.0 |
|
||||
|__________________________________________________________|
|
||||
'''.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()
|
||||
|
||||
## page texts
|
||||
|
||||
intro_prompt = """
|
||||
i don't recognize you, stranger. let's make friends.
|
||||
|
||||
the feels engine is an internal blogging platform on tilde.town. it assists you
|
||||
in recording your feels, giving you the option to publish to html or gopher, and
|
||||
read the feels of other users on tilde.town.
|
||||
|
||||
press <enter> to set up an account, or <ctrl-c> to quit.
|
||||
""".lstrip()
|
||||
|
||||
credits = """
|
||||
ttbp was written for tilde.town by ~endorphant in python. the codebase is
|
||||
publicly available on github at https://github.com/modgethanc/ttbp
|
||||
|
||||
tips for development are accepted at https://liberapay.com/modgethanc/
|
||||
|
||||
other contributors:
|
||||
~vilmibm, packaging help and gopher support
|
||||
~sanqui, the bug swatter
|
||||
~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 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!
|
||||
|
||||
i'd love to hear about your ideas and brainstorm about new features!
|
||||
|
||||
thanks to everyone who reads, listens, writes, and feels."""
|
||||
|
||||
recording = """
|
||||
feels will be recorded for today, {today}.
|
||||
|
||||
if you've already started recording feels for this day, you
|
||||
can pick up where you left off.
|
||||
|
||||
you can write your feels in plaintext, markdown, html, or a mixture of
|
||||
these.
|
||||
|
||||
press <enter> to begin recording your feels in your chosen text
|
||||
editor.
|
||||
|
||||
""".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
|
||||
those files.
|
||||
|
||||
(a buried feels browser is in the works; for now, you'll have to use the
|
||||
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)
|
||||
|
||||
account_wipe_prompt = """\
|
||||
warning! ! ! this action is irreversible!!!
|
||||
|
||||
this tool will remove your entire presence from the feels engine. this includes
|
||||
all posts, settings, and published html/gopher feels. you will no longer be
|
||||
listed anywhere as a user here.
|
||||
|
||||
there is no way for me to help you recover any part of your feels acccount. i
|
||||
respect your need to do this from time to time, so please be sure you're ready!
|
||||
|
||||
i recommend that you make a backup of your feels and stash them somewhere safe,
|
||||
just in case a future version of you still wants to look them over."""
|
||||
|
||||
feels_purge_prompt = """\
|
||||
warning! ! ! this action is irreversible!!!
|
||||
|
||||
there is no way for me to help you recover your feels if you purge them all. i
|
||||
respect your need to do this from time to time, so please be sure you're ready!
|
||||
|
||||
i recommend that you make a backup of your feels and stash them somewhere safe,
|
||||
just in case a future version of you still wants to look them over.
|
||||
"""
|
||||
|
||||
mystery_error = """\
|
||||
sorry, something went wrong! please try to address the error and try again.
|
||||
if you need help, ask in IRC or send mail to ~endorphant and we'll try to
|
||||
figure it out!
|
||||
""".lstrip()
|
||||
|
||||
## update announcements
|
||||
|
||||
|
@ -152,6 +249,47 @@ version 0.9.3 features:
|
|||
* added a new option to allow setting entries to default to either public or
|
||||
non-public on posting; this option only really makes sense if you're
|
||||
already publishing to html/gopher, but is available either way!
|
||||
|
||||
you can find this option under 'settings' as 'post as nopub'."""
|
||||
|
||||
you can find this option under 'settings' as 'post as nopub'.""",
|
||||
"0.11.3": """
|
||||
~[version 0.11.3 update]~
|
||||
|
||||
* thanks to ~sinacutie, you can now set custom css for the permalink text
|
||||
styling on your html page. the default permalink style has been added to
|
||||
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": """
|
||||
~[version 0.12.0 update]~
|
||||
|
||||
a lot of new stuff this time! from the main menu, option (1) is now called
|
||||
"manage your feels", which contains an expanded set of tools for organizing
|
||||
your feels:
|
||||
* read over feels (a list of all your entries)
|
||||
* modify feels publishing (toggle privacy on individual entries)
|
||||
* backup your feels (makes a .tar.gz of all your entries)
|
||||
* import a feels backup (unpacks a backup into your feels)
|
||||
* bury some feels (hide individual entries from view)
|
||||
* delete feels by day (permanently remove individual entries)
|
||||
* purge all feels (permanently remove all entries)
|
||||
* wipe feels account (permanently remove everything associated with
|
||||
ttbp)
|
||||
|
||||
each of these tools has expanded descriptions and instructions from the
|
||||
menu, so check them out if you're curious! all of the irreversibl data
|
||||
management actions have confirmation actions, so it's easy to cancel if you
|
||||
accidentally access a tool.
|
||||
|
||||
also, i've updated the documentation file to reflect recent feature changes,
|
||||
including some more details about how things work under the hood, and some
|
||||
clarifications on how existing features work. please give it a read through
|
||||
if you have a chance, and let me know if there's anything else i can
|
||||
improve!
|
||||
|
||||
lastly, i just wanted to mention that i do accept tips for my dev work at
|
||||
https://liberapay.com/modgethanc/ but there's no pressure to donate at all,
|
||||
i'm just making this option available for anyone whose financially stable
|
||||
and wants to kick some spare change my way; this is a labor of love, and i'm
|
||||
happy to work on it regardless :)
|
||||
"""
|
||||
}
|
||||
|
|
|
@ -28,6 +28,12 @@ body {
|
|||
padding: 1em;
|
||||
}
|
||||
|
||||
.entry p.permalink {
|
||||
font-size: .6em;
|
||||
font-color: #808080;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.entry h5 {
|
||||
text-align: right;
|
||||
margin-top: .2em;
|
||||
|
|
159
ttbp/core.py
159
ttbp/core.py
|
@ -41,6 +41,8 @@ import json
|
|||
|
||||
from . import chatter
|
||||
from . import config
|
||||
from . import gopher
|
||||
from . import util
|
||||
|
||||
FEED = os.path.join("/home", "endorphant", "public_html", "ttbp", "index.html")
|
||||
SETTINGS = {}
|
||||
|
@ -75,40 +77,42 @@ def reload_ttbprc(ttbprc={}):
|
|||
|
||||
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)"""
|
||||
|
||||
def get_files():
|
||||
"""Returns a list of user's feels."""
|
||||
files = []
|
||||
for filename in os.listdir(config.USER_DATA):
|
||||
for filename in os.listdir(feelsdir):
|
||||
if nopub(filename):
|
||||
link = os.path.join(config.WWW,
|
||||
os.path.splitext(
|
||||
os.path.basename(filename))[0]+".html")
|
||||
if os.path.exists(link):
|
||||
subprocess.call(["rm", link])
|
||||
continue
|
||||
filename = os.path.join(config.USER_DATA, filename)
|
||||
if os.path.isfile(filename) and valid(filename):
|
||||
files.append(filename)
|
||||
unpublish_feel(filename)
|
||||
else:
|
||||
filename = os.path.join(feelsdir, filename)
|
||||
if os.path.isfile(filename) and valid(filename):
|
||||
files.append(filename)
|
||||
|
||||
files.sort()
|
||||
files.reverse()
|
||||
|
||||
return files
|
||||
|
||||
|
||||
def load_files():
|
||||
def load_files(feelsdir=config.MAIN_FEELS):
|
||||
'''
|
||||
file loader
|
||||
|
||||
* reads user's nopub file
|
||||
* loads all valid filenames that are not excluded in nopub to global files list
|
||||
* calls get_files() to load all files for given directory
|
||||
* re-renders main html file and/or gopher if needed
|
||||
'''
|
||||
|
||||
global FILES
|
||||
|
||||
load_nopubs()
|
||||
FILES = get_files()
|
||||
FILES = get_files(feelsdir)
|
||||
|
||||
if publishing():
|
||||
write_html("index.html")
|
||||
if SETTINGS.get('gopher'):
|
||||
gopher.publish_gopher('feels', FILES)
|
||||
|
||||
def load_nopubs():
|
||||
"""Load a list of the user's nopub entries.
|
||||
|
@ -127,7 +131,7 @@ def load_nopubs():
|
|||
|
||||
## html outputting
|
||||
|
||||
def write(outurl="default.html"):
|
||||
def write_html(outurl="default.html"):
|
||||
'''
|
||||
main page renderer
|
||||
|
||||
|
@ -167,7 +171,7 @@ def write_page(filename):
|
|||
url
|
||||
'''
|
||||
|
||||
outurl = os.path.join(config.WWW, "".join(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 tilde.town blogging platform on "+time.strftime("%d %B %y")+"\nhttp://tilde.town/~endorphant/ttbp/-->\n\n")
|
||||
|
@ -197,7 +201,7 @@ def write_entry(filename):
|
|||
* return as list of strings
|
||||
'''
|
||||
|
||||
date = parse_date(filename)
|
||||
date = util.parse_date(filename)
|
||||
|
||||
entry = [
|
||||
"\t\t<p><a name=\""+date[0]+date[1]+date[2]+"\"></a><br /><br /></p>\n",
|
||||
|
@ -207,7 +211,7 @@ def write_entry(filename):
|
|||
]
|
||||
|
||||
raw = []
|
||||
rawfile = open(os.path.join(config.USER_DATA, filename), "r")
|
||||
rawfile = open(os.path.join(config.MAIN_FEELS, filename), "r")
|
||||
|
||||
for line in rawfile:
|
||||
raw.append(line)
|
||||
|
@ -221,7 +225,7 @@ def write_entry(filename):
|
|||
# entry.append("</p>\n\t\t\t<p>")
|
||||
|
||||
#entry.append("</p>\n")
|
||||
entry.append("\t\t\t<p style=\"font-size:.6em; font-color:#808080; text-align: right;\"><a href=\""+"".join(date)+".html\">permalink</a></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
|
||||
|
@ -316,7 +320,7 @@ def meta(entries = FILES):
|
|||
except subprocess.CalledProcessError:
|
||||
wc = "???"
|
||||
timestamp = time.strftime("%Y-%m-%d at %H:%M", time.localtime(mtime))
|
||||
date = "-".join(parse_date(filename))
|
||||
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])
|
||||
|
@ -345,23 +349,6 @@ def valid(filename):
|
|||
|
||||
return True
|
||||
|
||||
def parse_date(file):
|
||||
'''
|
||||
parses date out of pre-validated filename
|
||||
|
||||
* assumes a filename of YYYYMMDD.txt
|
||||
* returns a list:
|
||||
[0] 'YYYY'
|
||||
[1] 'MM'
|
||||
[2] 'DD'
|
||||
'''
|
||||
|
||||
rawdate = os.path.splitext(os.path.basename(file))[0]
|
||||
|
||||
date = [rawdate[0:4], rawdate[4:6], rawdate[6:]]
|
||||
|
||||
return date
|
||||
|
||||
def find_ttbps():
|
||||
'''
|
||||
returns a list of users with a ttbp by checking for a valid ttbprc
|
||||
|
@ -457,12 +444,7 @@ def toggle_nopub(filename):
|
|||
NOPUBS.remove(filename)
|
||||
else:
|
||||
NOPUBS.append(filename)
|
||||
live_html = os.path.join(config.WWW, filename.split(".")[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])
|
||||
unpublish_feel(filename)
|
||||
|
||||
nopub_file = open(config.NOPUB, 'w')
|
||||
nopub_file.write("""\
|
||||
|
@ -478,6 +460,93 @@ def toggle_nopub(filename):
|
|||
|
||||
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"
|
||||
|
||||
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():
|
||||
unpublish_feel(filename)
|
||||
|
||||
load_files()
|
||||
|
||||
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."""
|
||||
|
||||
feel = os.path.join(config.MAIN_FEELS, filename)
|
||||
if os.path.exists(feel):
|
||||
subprocess.call(["rm", feel])
|
||||
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")
|
||||
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.
|
||||
|
||||
ignores any invalidly named files or files that already exist, to avoid
|
||||
clobbering current feels. ignored files are left in the archive directory
|
||||
for the user to manually sort out."""
|
||||
|
||||
backup_dir = os.path.splitext(os.path.splitext(os.path.basename(filename))[0])[0]
|
||||
backup_path = os.path.join(config.BACKUPS, backup_dir)
|
||||
|
||||
if not os.path.exists(backup_path):
|
||||
subprocess.call(["mkdir", backup_path])
|
||||
|
||||
subprocess.call(["chmod", "700", backup_path])
|
||||
subprocess.call(["tar", "-C", backup_path, "-xf", filename])
|
||||
backup_entries = os.path.join(backup_path, "entries")
|
||||
|
||||
backups = os.listdir(backup_entries)
|
||||
current = os.listdir(config.MAIN_FEELS)
|
||||
|
||||
imported = []
|
||||
|
||||
for feel in backups:
|
||||
if os.path.basename(feel) not in current:
|
||||
imported.append(os.path.join(backup_entries, feel))
|
||||
|
||||
imported.sort()
|
||||
return imported
|
||||
|
||||
def import_feels(backups):
|
||||
"""takes a list of filepaths and copies those to current main feels.
|
||||
|
||||
this does not check for collisions.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
#############
|
||||
#############
|
||||
|
|
|
@ -7,7 +7,8 @@ import time
|
|||
import subprocess
|
||||
|
||||
from . import util
|
||||
from .core import parse_date
|
||||
from . import config
|
||||
#from .core import parse_date
|
||||
|
||||
GOPHER_PROMPT = """
|
||||
|
||||
|
@ -73,7 +74,7 @@ def publish_gopher(gopher_path, entry_filenames):
|
|||
if not os.path.exists(gopher_entry_symlink):
|
||||
subprocess.call(["ln", "-s", entry_filename, gopher_entry_symlink])
|
||||
|
||||
label = "-".join(parse_date(entry_filename))
|
||||
label = "-".join(util.parse_date(entry_filename))
|
||||
gophermap.write('0{file_label}\t{filename}\n'.format(
|
||||
file_label=label,
|
||||
filename=filename))
|
||||
|
@ -107,3 +108,11 @@ def setup_gopher(gopher_path):
|
|||
os.makedirs(gopher_entries)
|
||||
|
||||
subprocess.call(["ln", "-s", gopher_entries, ttbp_gopher])
|
||||
|
||||
def unpublish():
|
||||
"""blanks all gopher things and recreates the directories."""
|
||||
|
||||
subprocess.call(["rm", "-rf", config.GOPHER_PATH])
|
||||
subprocess.call(["rm", "-rf", config.GOPHER_ENTRIES])
|
||||
os.mkdir(config.GOPHER_ENTRIES)
|
||||
subprocess.call(["ln", "-s", config.GOPHER_ENTRIES, config.GOPHER_PATH])
|
||||
|
|
664
ttbp/ttbp.py
664
ttbp/ttbp.py
|
@ -34,6 +34,7 @@ https://github.com/modgethanc/ttbp
|
|||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import subprocess
|
||||
import time
|
||||
|
@ -50,7 +51,7 @@ from . import chatter
|
|||
from . import gopher
|
||||
from . import util
|
||||
|
||||
__version__ = "0.11.2"
|
||||
__version__ = "0.12.0"
|
||||
__author__ = "endorphant <endorphant@tilde.town)"
|
||||
|
||||
p = inflect.engine()
|
||||
|
@ -73,6 +74,7 @@ DEFAULT_SETTINGS = {
|
|||
"gopher": False,
|
||||
"publishing": False,
|
||||
"rainbows": False,
|
||||
"post as nopub": False,
|
||||
}
|
||||
|
||||
## user globals
|
||||
|
@ -81,7 +83,8 @@ SETTINGS = {
|
|||
"publish dir": None,
|
||||
"gopher": False,
|
||||
"publishing": False,
|
||||
"rainbows": False
|
||||
"rainbows": False,
|
||||
"post as nopub": False,
|
||||
}
|
||||
|
||||
## ttbp specific utilities
|
||||
|
@ -247,10 +250,7 @@ def init():
|
|||
"""
|
||||
|
||||
try:
|
||||
input("""
|
||||
i don't recognize you, stranger. let's make friends.
|
||||
|
||||
press <enter> to begin, or <ctrl-c> to get out of here.""")
|
||||
input(config.intro_prompt)
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nthanks for checking in! i'll always be here.\n\n")
|
||||
quit()
|
||||
|
@ -259,7 +259,7 @@ press <enter> to begin, or <ctrl-c> to get out of here.""")
|
|||
|
||||
time.sleep(1)
|
||||
print("...")
|
||||
time.sleep(1)
|
||||
time.sleep(.5)
|
||||
|
||||
## record user in source list
|
||||
users = open(config.USERFILE, 'a')
|
||||
|
@ -272,7 +272,7 @@ press <enter> to begin, or <ctrl-c> to get out of here.""")
|
|||
print("\ngenerating feels at {path}...".format(path=config.PATH).rstrip())
|
||||
subprocess.call(["mkdir", config.PATH])
|
||||
subprocess.call(["mkdir", config.USER_CONFIG])
|
||||
subprocess.call(["mkdir", config.USER_DATA])
|
||||
subprocess.call(["mkdir", config.MAIN_FEELS])
|
||||
|
||||
versionFile = os.path.join(config.PATH, "version")
|
||||
open(versionFile, "w").write(__version__)
|
||||
|
@ -291,13 +291,21 @@ press <enter> to begin, or <ctrl-c> to get out of here.""")
|
|||
f.write(config.DEFAULT_STYLE)
|
||||
|
||||
## run user-interactive setup and load core engine
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
print("done setting up feels!")
|
||||
print("\nthese are the default settings. you can change any of them now, or change them later at any time!!")
|
||||
setup()
|
||||
core.load(SETTINGS)
|
||||
|
||||
input("\nyou're all good to go, "+chatter.say("friend")+"! hit <enter> to continue.\n\n")
|
||||
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")))
|
||||
|
||||
return ""
|
||||
|
||||
def gen_header():
|
||||
|
@ -406,7 +414,7 @@ def setup_repair():
|
|||
save_settings()
|
||||
|
||||
print("...")
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
input("\nyou're all good to go, "+chatter.say("friend")+"! hit <enter> to continue.\n\n")
|
||||
|
||||
def setup():
|
||||
|
@ -436,68 +444,74 @@ def setup():
|
|||
redraw(EJECT)
|
||||
return SETTINGS
|
||||
|
||||
if choice in QUITS:
|
||||
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("\nyou're all good to go, {friend}! hit <enter> to continue.\n\n".format(friend=chatter.say("friend")))
|
||||
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()
|
||||
else:
|
||||
redraw("now changing your settings. press <ctrl-c> if you didn't mean to do this.")
|
||||
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("\nyou're all good to go, {friend}! hit <enter> to continue.\n\n".format(friend=chatter.say("friend")))
|
||||
redraw()
|
||||
|
||||
return SETTINGS
|
||||
|
||||
def save_settings():
|
||||
"""
|
||||
Save current settings.
|
||||
|
@ -516,7 +530,7 @@ def main_menu():
|
|||
|
||||
menuOptions = [
|
||||
"record your feels",
|
||||
"review your feels",
|
||||
"manage your feels",
|
||||
"check out your neighbors",
|
||||
"browse global feels",
|
||||
"scribble some graffiti",
|
||||
|
@ -537,18 +551,13 @@ def main_menu():
|
|||
if choice == '0':
|
||||
redraw()
|
||||
today = time.strftime("%Y%m%d")
|
||||
write_entry(os.path.join(config.USER_DATA, today+".txt"))
|
||||
write_entry(os.path.join(config.MAIN_FEELS, today+".txt"))
|
||||
core.www_neighbors()
|
||||
elif choice == '1':
|
||||
if core.publishing():
|
||||
intro = "here are some options for reviewing your feels:"
|
||||
redraw(intro)
|
||||
review_menu(intro)
|
||||
core.load_files()
|
||||
core.write("index.html")
|
||||
else:
|
||||
redraw("your recorded feels, listed by date:")
|
||||
view_feels(config.USER)
|
||||
intro = "here are some options for managing your feels:"
|
||||
redraw(intro)
|
||||
review_menu(intro)
|
||||
core.load_files()
|
||||
elif choice == '2':
|
||||
users = core.find_ttbps()
|
||||
prompt = "the following {usercount} {are} recording feels on ttbp:".format(
|
||||
|
@ -571,7 +580,7 @@ def main_menu():
|
|||
redraw()
|
||||
show_credits()
|
||||
elif choice == '8':
|
||||
subprocess.call(["lynx", os.path.join(config.INSTALL_PATH, "..", "README.html")])
|
||||
subprocess.call(["lynx", os.path.join(config.INSTALL_PATH, "..", "doc", "manual.html")])
|
||||
redraw()
|
||||
elif choice in QUITS:
|
||||
return stop()
|
||||
|
@ -614,26 +623,72 @@ def review_menu(intro=""):
|
|||
|
||||
menuOptions = [
|
||||
"read over feels",
|
||||
"modify feels publishing"
|
||||
"modify feels publishing",
|
||||
"backup your feels",
|
||||
"import a feels backup",
|
||||
"bury some feels",
|
||||
"delete feels by day",
|
||||
"purge all feels",
|
||||
"wipe feels account"
|
||||
]
|
||||
|
||||
util.print_menu(menuOptions, SETTINGS.get("rainbows", False))
|
||||
|
||||
choice = util.list_select(menuOptions, "what would you like to do with your feels? (or 'back' to return home) ")
|
||||
choice = util.list_select(menuOptions, "what would you like to do with your feels? (or 'q' to return home) ")
|
||||
|
||||
top = ""
|
||||
hasfeels = len(os.listdir(config.MAIN_FEELS)) > 0
|
||||
nofeels = "you don't have any feels to work with, "+chatter.say("friend")+"\n\n> "
|
||||
|
||||
if choice is not False:
|
||||
if choice == 0:
|
||||
redraw("your recorded feels, listed by date:")
|
||||
view_feels(config.USER)
|
||||
if hasfeels:
|
||||
redraw("your recorded feels, listed by date:")
|
||||
view_feels(config.USER)
|
||||
else:
|
||||
top = nofeels
|
||||
elif choice == 1:
|
||||
redraw("publishing status of your feels:")
|
||||
list_nopubs(config.USER)
|
||||
if hasfeels:
|
||||
redraw("publishing status of your feels:")
|
||||
list_nopubs(config.USER)
|
||||
else:
|
||||
top = nofeels
|
||||
elif choice == 2:
|
||||
if hasfeels:
|
||||
redraw("FEELS BACKUP")
|
||||
backup_feels()
|
||||
else:
|
||||
top = nofeels
|
||||
elif choice == 3:
|
||||
redraw("loading feels backup")
|
||||
load_backup()
|
||||
elif choice == 4:
|
||||
if hasfeels:
|
||||
redraw("burying feels")
|
||||
bury_feels()
|
||||
else:
|
||||
top = nofeels
|
||||
elif choice == 5:
|
||||
if hasfeels:
|
||||
redraw("deleting feels")
|
||||
delete_feels()
|
||||
else:
|
||||
top = nofeels
|
||||
elif choice == 6:
|
||||
if hasfeels:
|
||||
redraw("!!!PURGING ALL FEELS!!!")
|
||||
purge_feels()
|
||||
else:
|
||||
top = nofeels
|
||||
elif choice == 7:
|
||||
redraw("!!! WIPING FEELS ACCOUNT !!!")
|
||||
wipe_account()
|
||||
else:
|
||||
redraw()
|
||||
return
|
||||
|
||||
redraw(intro)
|
||||
return review_menu()
|
||||
redraw(top+intro)
|
||||
return review_menu(intro)
|
||||
|
||||
def view_neighbors(users, prompt):
|
||||
'''
|
||||
|
@ -694,7 +749,7 @@ def view_neighbors(users, prompt):
|
|||
sortedUsers.append(user[0])
|
||||
userIndex.append(user[2])
|
||||
|
||||
choice = menu_handler(sortedUsers, "pick a townie to browse their feels, or type 'back' or 'q' to go home: ", 15, SETTINGS.get("rainbows", False), prompt)
|
||||
choice = menu_handler(sortedUsers, "pick a townie to browse their feels, or type 'q' to go home: ", 15, SETTINGS.get("rainbows", False), prompt)
|
||||
|
||||
if choice is not False:
|
||||
redraw("~{user}'s recorded feels, listed by date: \n".format(user=userIndex[choice]))
|
||||
|
@ -708,7 +763,6 @@ def view_feels(townie):
|
|||
'''
|
||||
generates a list of all feels by given townie and displays in
|
||||
date order; allows selection of one feel to read.
|
||||
|
||||
'''
|
||||
|
||||
metas, owner = generate_feels_list(townie)
|
||||
|
@ -733,7 +787,7 @@ def generate_feels_list(user):
|
|||
showpub = False
|
||||
|
||||
if user == config.USER:
|
||||
entryDir = config.USER_DATA
|
||||
entryDir = config.MAIN_FEELS
|
||||
owner = "your"
|
||||
if core.publishing():
|
||||
showpub = True
|
||||
|
@ -749,29 +803,320 @@ def generate_feels_list(user):
|
|||
|
||||
return metas, owner
|
||||
|
||||
def backup_feels():
|
||||
"""creates a tar.gz of user's entries directory"""
|
||||
|
||||
backupfile = os.path.join(os.path.expanduser('~'), "feels-backup-"+time.strftime("%Y%m%d-%H%M%S")+".tar.gz")
|
||||
|
||||
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"]):
|
||||
subprocess.call(["chmod", "600", backupfile])
|
||||
if not os.path.exists(config.BACKUPS):
|
||||
subprocess.call(["mkdir", config.BACKUPS])
|
||||
subprocess.call(["chmod", "700", config.BACKUPS])
|
||||
subprocess.call(["cp", backupfile, config.BACKUPS])
|
||||
print("\nbackup saved! i also put a copy at {backup_dir} for you.".format(backup_dir = config.BACKUPS))
|
||||
else:
|
||||
print(config.mystery_error)
|
||||
else:
|
||||
print("no problem, {friend}; come back whenever if you want a backup!".format(friend=chatter.say("friend")))
|
||||
|
||||
input("\n\npress <enter> to go back to managing your feels.\n\n")
|
||||
redraw()
|
||||
|
||||
return
|
||||
|
||||
def delete_feels():
|
||||
"""handles deleting feels one at a time"""
|
||||
|
||||
feel = input("""which day's feels do you want to load for deletion?
|
||||
|
||||
YYYYMMDD (or 'q' to cancel)> """)
|
||||
|
||||
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("deleting 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 deletion is irreversible! if you're sure you want to delete 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.delete_feel(feel+".txt")
|
||||
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\npress <enter> to go back to managing your feels.\n\n")
|
||||
redraw()
|
||||
|
||||
return
|
||||
|
||||
|
||||
def purge_feels():
|
||||
"""handles deleting all feels"""
|
||||
|
||||
print(config.feels_purge_prompt)
|
||||
|
||||
print("...")
|
||||
time.sleep(0.5)
|
||||
print("...loading feels...")
|
||||
time.sleep(1)
|
||||
print("...")
|
||||
|
||||
feelscount = len(os.listdir(config.MAIN_FEELS))
|
||||
|
||||
if feelscount > 0:
|
||||
purgecode = util.genID(5)
|
||||
|
||||
print("""
|
||||
|
||||
i've loaded up all {count} of your feels for purging. if you're ready, carefully
|
||||
type the following purge code:
|
||||
_________
|
||||
| |
|
||||
| {purgecode} |
|
||||
|_______|
|
||||
""".format(purgecode=purgecode, count=feelscount))
|
||||
|
||||
ans = input("(leave blank or type anything else to cancel) > ")
|
||||
|
||||
if ans == purgecode:
|
||||
print("...")
|
||||
time.sleep(0.5)
|
||||
unpublish()
|
||||
|
||||
if not subprocess.call(["rm", "-rf", config.MAIN_FEELS]):
|
||||
subprocess.call(["mkdir", config.MAIN_FEELS])
|
||||
core.load_files()
|
||||
print("ALL FEELS PURGED! you're ready to start fresh!")
|
||||
else:
|
||||
print(config.mystery_error)
|
||||
else:
|
||||
print("\nfeels purge canceled! you're welcome to come back again.")
|
||||
else:
|
||||
print("you don't have any feels to purge, "+chatter.say("friend"))
|
||||
|
||||
input("\n\npress <enter> to go back to managing your feels.\n\n")
|
||||
redraw()
|
||||
|
||||
return
|
||||
|
||||
def wipe_account():
|
||||
"""handles wiping feels account"""
|
||||
|
||||
print(config.account_wipe_prompt)
|
||||
|
||||
print("...")
|
||||
time.sleep(0.5)
|
||||
print("...packaging up all your feels...")
|
||||
time.sleep(1)
|
||||
print("...")
|
||||
purgecode = util.genID(5)
|
||||
|
||||
print("""
|
||||
your account is all packed up! if you're ready, carefully type the following
|
||||
purge code:
|
||||
_________
|
||||
| |
|
||||
| {purgecode} |
|
||||
|_______|
|
||||
""".format(purgecode=purgecode))
|
||||
|
||||
ans = input("(leave blank or type anything else to cancel) > ")
|
||||
|
||||
if ans == purgecode:
|
||||
print("...")
|
||||
time.sleep(0.5)
|
||||
unpublish()
|
||||
|
||||
if core.publishing():
|
||||
publishDir = os.path.join(config.PUBLIC, SETTINGS.get("publish dir"))
|
||||
make_publish_dir(publishDir)
|
||||
|
||||
|
||||
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\npress <enter> to exit the feels engine.\n\n")
|
||||
sys.exit(stop())
|
||||
else:
|
||||
print(config.mystery_error)
|
||||
else:
|
||||
print("\naccount deletion canceled! you're welcome to come back again.")
|
||||
|
||||
input("\n\npress <enter> to go back to managing your feels.\n\n")
|
||||
redraw()
|
||||
|
||||
return
|
||||
|
||||
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))
|
||||
|
||||
time.sleep(.5)
|
||||
print("...\n")
|
||||
|
||||
backups = []
|
||||
|
||||
try:
|
||||
for filename in os.listdir(config.BACKUPS):
|
||||
if "feels-backup" in filename and ".tar" in filename:
|
||||
backups.append(filename)
|
||||
except FileNotFoundError:
|
||||
subprocess.call(["mkdir", config.BACKUPS])
|
||||
|
||||
if len(backups) < 1:
|
||||
print("""
|
||||
sorry, i didn't find any feels backups! if you have a backup file handy, please
|
||||
move it to {directory} and try running this tool again.\
|
||||
""".format(directory=config.BACKUPS))
|
||||
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:")
|
||||
|
||||
if choice is not False:
|
||||
imports = core.process_backup(os.path.join(config.BACKUPS, backups[choice]))
|
||||
for feel in imports:
|
||||
print("importing {entry}".format(entry="-".join(util.parse_date(feel))))
|
||||
subprocess.call(["mv", feel, config.MAIN_FEELS])
|
||||
time.sleep(.01)
|
||||
|
||||
core.load_files()
|
||||
|
||||
tempdir = os.path.join(config.BACKUPS, os.path.splitext(os.path.splitext(os.path.basename(backups[choice]))[0])[0], "entries")
|
||||
|
||||
time.sleep(.5)
|
||||
print("...\n")
|
||||
|
||||
if len(os.listdir(tempdir)) == 0:
|
||||
os.rmdir(tempdir)
|
||||
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.
|
||||
|
||||
you can check out the leftover feels yourself at:
|
||||
|
||||
{directory}""".format(directory=tempdir))
|
||||
else:
|
||||
return
|
||||
|
||||
input("\n\npress <enter> to go back to managing your feels.\n\n")
|
||||
return
|
||||
|
||||
def bury_feels():
|
||||
"""queries for a feel to bury, then calls the feels burying handler.
|
||||
"""
|
||||
|
||||
feel = input(config.bury_feels_prompt)
|
||||
|
||||
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\npress <enter> to go back to managing your feels.\n\n")
|
||||
redraw()
|
||||
|
||||
return
|
||||
|
||||
def show_credits():
|
||||
'''
|
||||
prints author acknowledgements and commentary
|
||||
'''
|
||||
|
||||
print("""
|
||||
ttbp was written for tilde.town by ~endorphant in python. the codebase is
|
||||
publicly available on github at https://github.com/modgethanc/ttbp
|
||||
|
||||
other contributors:
|
||||
~vilmibm, packaging help and gopher support
|
||||
~sanqui, the bug swatter
|
||||
|
||||
if you have ideas for ttbp, you are welcome to contact me to discuss them;
|
||||
please send me tildemail 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!
|
||||
|
||||
i'd love to hear about your ideas and brainstorm about new features!
|
||||
|
||||
thanks to everyone who reads, listens, writes, and feels.\
|
||||
""")
|
||||
|
||||
print(config.credits)
|
||||
input("\n\npress <enter> to go back home.\n\n")
|
||||
redraw()
|
||||
|
||||
|
@ -779,24 +1124,12 @@ thanks to everyone who reads, listens, writes, and feels.\
|
|||
|
||||
## handlers
|
||||
|
||||
def write_entry(entry=os.path.join(config.USER_DATA, "test.txt")):
|
||||
def write_entry(entry=os.path.join(config.MAIN_FEELS, "test.txt")):
|
||||
'''
|
||||
main feels-recording handler
|
||||
'''
|
||||
|
||||
entered = input("""
|
||||
feels will be recorded for today, {today}.
|
||||
|
||||
if you've already started recording feels for this day, you
|
||||
can pick up where you left off.
|
||||
|
||||
you can write your feels in plaintext, markdown, html, or a mixture of
|
||||
these.
|
||||
|
||||
press <enter> to begin recording your feels in your chosen text
|
||||
editor.
|
||||
|
||||
""".format(today=time.strftime("%d %B %Y")))
|
||||
entered = input(config.recording)
|
||||
|
||||
if entered:
|
||||
entryFile = open(entry, "a")
|
||||
|
@ -806,22 +1139,24 @@ editor.
|
|||
|
||||
left = ""
|
||||
|
||||
core.load_files()
|
||||
|
||||
if SETTINGS.get("post as nopub"):
|
||||
core.toggle_nopub(os.path.basename(entry))
|
||||
else:
|
||||
if core.publishing():
|
||||
core.write("index.html")
|
||||
left = "posted to {url}/index.html\n\n>".format(
|
||||
core.write_html("index.html")
|
||||
left = "posted to {url}/index.html\n\n> ".format(
|
||||
url="/".join(
|
||||
[config.LIVE+config.USER,
|
||||
str(SETTINGS.get("publish dir"))]))
|
||||
|
||||
if SETTINGS.get('gopher'):
|
||||
gopher.publish_gopher('feels', core.get_files())
|
||||
left += " also posted to your ~/public_gopher!\n"
|
||||
gopher.publish_gopher('feels', core.FILES)
|
||||
left += "also posted to your ~/public_gopher!\n\n> "
|
||||
|
||||
core.load_files()
|
||||
redraw(left + " thanks for sharing your feels!")
|
||||
#core.load_files()
|
||||
redraw(left + "thanks for sharing your feels!")
|
||||
|
||||
return
|
||||
|
||||
|
@ -841,6 +1176,14 @@ def set_nopubs(metas, user, prompt):
|
|||
"""displays a list of entries for pub/nopub toggling.
|
||||
"""
|
||||
|
||||
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")
|
||||
|
||||
entries = []
|
||||
for entry in metas:
|
||||
pub = ""
|
||||
|
@ -848,14 +1191,13 @@ def set_nopubs(metas, user, prompt):
|
|||
pub = "(nopub)"
|
||||
entries.append(""+entry[4]+" ("+p.no("word", entry[2])+") "+"\t"+pub)
|
||||
|
||||
choice = menu_handler(entries, "pick an entry from the list, or type 'q' to go back: ", 10, SETTINGS.get("rainbows", False), prompt)
|
||||
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)
|
||||
|
||||
if choice is not False:
|
||||
target = os.path.basename(metas[choice][0])
|
||||
action = core.toggle_nopub(target)
|
||||
redraw(prompt)
|
||||
|
||||
core.write("index.html")
|
||||
if SETTINGS["gopher"]:
|
||||
gopher.publish_gopher('feels', core.get_files())
|
||||
|
||||
|
@ -1107,14 +1449,14 @@ def select_publish_dir():
|
|||
|
||||
publishDir = os.path.join(config.PUBLIC, choice)
|
||||
while os.path.exists(publishDir):
|
||||
second = input("\n"+publishDir+"""\
|
||||
already exists!
|
||||
second = input("""
|
||||
{pDir} already exists!
|
||||
|
||||
setting this as your publishing directory means this program may
|
||||
delete or overwrite file there!
|
||||
|
||||
if you're sure you want to use it, hit <enter> to confirm.
|
||||
otherwise, pick another location: """)
|
||||
otherwise, pick another location: """.format(pDir=publishDir))
|
||||
|
||||
if second == "":
|
||||
break
|
||||
|
@ -1159,11 +1501,14 @@ def unpublish():
|
|||
|
||||
if directory:
|
||||
publishDir = os.path.join(config.PUBLIC, directory)
|
||||
subprocess.call(["rm", publishDir])
|
||||
if os.path.exists(publishDir):
|
||||
subprocess.call(["rm", "-rf", publishDir])
|
||||
subprocess.call(["rm", "-rf", config.WWW])
|
||||
make_publish_dir(SETTINGS.get("publish dir"))
|
||||
#SETTINGS.update({"publish dir": None})
|
||||
|
||||
if SETTINGS.get("gopher"):
|
||||
SETTINGS.update({"gopher": False})
|
||||
subprocess.call(["rm", config.GOPHER_PATH])
|
||||
gopher.unpublish()
|
||||
|
||||
def update_publishing():
|
||||
'''
|
||||
|
@ -1180,14 +1525,13 @@ def update_publishing():
|
|||
subprocess.call(["rm", os.path.join(config.PUBLIC, oldDir)])
|
||||
make_publish_dir(newDir)
|
||||
core.load_files()
|
||||
core.write("index.html")
|
||||
#core.write_html("index.html")
|
||||
else:
|
||||
unpublish()
|
||||
SETTINGS.update({"publish dir": None})
|
||||
|
||||
core.load(SETTINGS)
|
||||
|
||||
def make_publish_dir(dir):
|
||||
def make_publish_dir(publish_dir):
|
||||
'''
|
||||
setup helper to create publishing directory
|
||||
'''
|
||||
|
@ -1200,13 +1544,18 @@ def make_publish_dir(dir):
|
|||
index.write("<h1>ttbp blog placeholder</h1>")
|
||||
index.close()
|
||||
|
||||
publishDir = os.path.join(config.PUBLIC, dir)
|
||||
if os.path.exists(publishDir):
|
||||
subprocess.call(["rm", publishDir])
|
||||
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, publishDir])
|
||||
subprocess.call(["ln", "-s", config.WWW, live])
|
||||
|
||||
print("\n\tpublishing to "+config.LIVE+config.USER+"/"+SETTINGS.get("publish dir")+"/\n\n")
|
||||
return "\n\tpublishing to "+config.LIVE+config.USER+"/"+SETTINGS.get("publish dir")+"/\n\n"
|
||||
|
||||
else:
|
||||
return ""
|
||||
#print("\n\tpublishing to "+config.LIVE+config.USER+"/"+SETTINGS.get("publish dir")+"/\n\n")
|
||||
|
||||
def update_gopher():
|
||||
'''
|
||||
|
@ -1255,7 +1604,7 @@ def update_user_version():
|
|||
|
||||
time.sleep(1)
|
||||
print("...")
|
||||
time.sleep(1)
|
||||
time.sleep(0.5)
|
||||
|
||||
userVersion = ""
|
||||
(x, y, z) = [0, 0, 0]
|
||||
|
@ -1284,7 +1633,7 @@ def update_user_version():
|
|||
|
||||
# repopulate html files
|
||||
core.load_files()
|
||||
core.write("index.html")
|
||||
#core.write_html("index.html")
|
||||
|
||||
# add publishing setting
|
||||
print("\nnew feature!\n")
|
||||
|
@ -1335,6 +1684,19 @@ def update_user_version():
|
|||
SETTINGS.update({"post as nopub": False})
|
||||
save_settings()
|
||||
|
||||
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: .6em;
|
||||
font-color: #808080;
|
||||
text-align: right;
|
||||
}""")
|
||||
|
||||
print("""
|
||||
you're all good to go, """+chatter.say("friend")+"""! please contact ~endorphant if
|
||||
something strange happened to you during this update.
|
||||
|
@ -1356,6 +1718,14 @@ something strange happened to you during this update.
|
|||
# version 0.11.2 patch notes
|
||||
print(config.UPDATES["0.11.2"])
|
||||
|
||||
if y < 11 or z < 3:
|
||||
# version 0.11.3 patch notes
|
||||
print(config.UPDATES["0.11.3"])
|
||||
|
||||
if y < 12:
|
||||
# version 0.12.0 patch notes
|
||||
print(config.UPDATES["0.12.0"])
|
||||
|
||||
confirm = ""
|
||||
|
||||
while confirm not in ("x", "<x>", "X", "<X>"):
|
||||
|
|
21
ttbp/util.py
21
ttbp/util.py
|
@ -26,12 +26,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
import random
|
||||
import time
|
||||
from six.moves import input
|
||||
import os
|
||||
|
||||
import colorama
|
||||
import inflect
|
||||
|
||||
## misc globals
|
||||
BACKS = ['back', 'b', 'q']
|
||||
BACKS = ['back', 'b', 'q', '<q>']
|
||||
NAVS = ['u', 'd']
|
||||
|
||||
## color stuff
|
||||
|
@ -214,3 +215,21 @@ def input_yn(query):
|
|||
ans = input("'y' or 'n' please: ")
|
||||
|
||||
return ans == "y"
|
||||
|
||||
def parse_date(file):
|
||||
'''
|
||||
parses date out of pre-validated filename
|
||||
|
||||
* assumes a filename of YYYYMMDD.txt
|
||||
* returns a list:
|
||||
[0] 'YYYY'
|
||||
[1] 'MM'
|
||||
[2] 'DD'
|
||||
'''
|
||||
|
||||
rawdate = os.path.splitext(os.path.basename(file))[0]
|
||||
|
||||
date = [rawdate[0:4], rawdate[4:6], rawdate[6:]]
|
||||
|
||||
return date
|
||||
|
||||
|
|
Loading…
Reference in New Issue