diff --git a/README.html b/README.html index 7e4a1d9..1bfca98 100644 --- a/README.html +++ b/README.html @@ -1,160 +1,204 @@
a command-line based blogging platform running on tilde.town
-ttbp
stands for "tilde.town blogging platform", the original working name for
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.
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. content/personal issues should be +worked out according to the CoC, with support from the administrative +team if needed.
+no coding or html experience is necessary to get started. just log in to your tilde.town account and enter:
-feels
ttbp will ask you a few questions to get you started. after that, writing and reading entries all happen within the program.
-that's it!
- -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!
- -entries are recorded as plaintext files in your ~/.ttbp/entries -directory. you can edit them there directly, or fix old entries, or -delete entries.
- -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.
- -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.
+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.)
+<!-- comments -->
to have them show up
-in the feed but not render in a browser (but people can still read
-them with view-source)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.
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.
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.
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.
- +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.
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.
+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.
(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)~/.ttbp/backups/
with the current date, and a second copy to
+ your home directory for safekeeping.~/.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.~/.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.~/.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.the settings menu lets you change specific options for handling your feels and +using the interface.
public_html
where feels will be
+ published (if you're not publishing your feels, this defaults to None
)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.
alias ttbp="~endorphant/bin/ttbp"
to your .bash_aliases for fewer keystrokesalias ttbp-beta="~endorphant/bin/ttbp-beta"
)these are a few ideas being kicked around, or under active development:
-less
)other ideas are listed on github as +upcoming features or feature requests!
+(this section is only relevant if you plan on forking the repo and running an instance of this yourself)
- - -please check out my contributor guidelines on github if you'd like to get involved with development!
-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!
\ No newline at end of file +if you're interested in helping with the code, please drop me some tildemail!
+i accept tips for development work on +liberapay
+thanks to:
+ttbp
stands for "tilde.town blogging platform", the original working name for
+this project. the complete codebase is available on
+github.
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. content/personal issues should be +worked out according to the CoC, with support from the administrative +team if needed.
+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.
+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.)
+<!-- comments -->
to have them show up
+ in the feed but not render in a browser (but people can still read them with
+ view-source)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.
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.
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.
+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.
(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)~/.ttbp/backups/
with the current date, and a second copy to
+ your home directory for safekeeping.~/.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.~/.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.~/.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.the settings menu lets you change specific options for handling your feels and +using the interface.
+public_html
where feels will be
+ published (if you're not publishing your feels, this defaults to None
)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.
+these are a few ideas being kicked around, or under active development:
+less
)other ideas are listed on github as +upcoming features or feature requests!
\ No newline at end of file diff --git a/doc/manual.md b/doc/manual.md new file mode 100644 index 0000000..a09ec22 --- /dev/null +++ b/doc/manual.md @@ -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 `` 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")! diff --git a/setup.py b/setup.py index 3d49f33..a6e251a 100644 --- a/setup.py +++ b/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', diff --git a/ttbp/config/__init__.py b/ttbp/config/__init__.py index 495f874..7a00748 100644 --- a/ttbp/config/__init__.py +++ b/ttbp/config/__init__.py @@ -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) | +|") #entry.append("
\n") - entry.append("\t\t\t\n") + entry.append("\t\t\t\n") entry.append("\n\t\t\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 + ############# ############# diff --git a/ttbp/gopher.py b/ttbp/gopher.py index 00cfffd..17f02a3 100644 --- a/ttbp/gopher.py +++ b/ttbp/gopher.py @@ -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]) diff --git a/ttbp/ttbp.py b/ttbp/ttbp.py index ebaea39..6ee3b26 100644 --- a/ttbp/ttbp.py +++ b/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__ = "endorphantwhen 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 typeto 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\npressto 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 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 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 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 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 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 typeto 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\npressto 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 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 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 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(" ttbp blog placeholder
") 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", " "): diff --git a/ttbp/util.py b/ttbp/util.py index 5168018..b7f5e62 100644 --- a/ttbp/util.py +++ b/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', ' '] 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 +