Skip to content

Commit

Permalink
Initial commit of LifeFlow files from SVN to Git.
Browse files Browse the repository at this point in the history
  • Loading branch information
lethain committed Jun 1, 2008
1 parent e1343f5 commit b81caf7
Show file tree
Hide file tree
Showing 133 changed files with 13,257 additions and 0 deletions.
33 changes: 33 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@


* Added new dynamic context in markup.lifeflowmarkup:
1. [previous] -> link to previous entry, if one exists
2. [next] -> link to next entry, if one exists
3. [series nth] -> link to @nth entry of current series (starts with 1)
4. [series slug nth] -> link to @nth entry in series with @slug
(starts with 1, not 0)
5. [file markdown_name_of_resource] -> link to file stored in a Resource
6. [f markdown_name_of_resource] -> shortcut for file

* Substantial reworking and refactoring of markup/lifeflowmarkup.py

## R66
* Major refactoring of markup handings by LifeFlow.
1. Created the *markup* folder, where all markup files now live.
2. Restored a pristine Python-Markdown 0.9 file
3. Moved all code syntax highlighting parts into markup/code.py
4. Moved the Dynamic Blog Context bits into markup/lifeflowmarkup.py
5. Added lifeflowmarkup.render() function for rendering any combination of MarkDown and rendering code, Dynamic Blog Context, and footnotes.
6. Added relevant tests to tests.py.

* Added new dynamic context in markup/lifeflowmarkup:
1.[author] -> /author/ if 0 or >2 authors, otherwise to the authors bio page
2. [tag slug] -> /tag/slug/
3. [comment pk] -> page returned by get_absolute_url by comment with @pk
4. [project slug] => /project/slug/

## R64
* Added new static context in Lifeflowmarkup: comments, projects, series, tags
* Renamed Markdownpp to Lifeflowmarkup due to terms of license.

R60
66 changes: 66 additions & 0 deletions HELP
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@


## Using LifeFlowMarkUp

[markdown]: http://daringfireball.net/projects/markdown/syntax
[pygments]: http://www.pygments.com/

LifeFlowMarkUp is a superset of MarkDown. It has two types of additions not found in [MarkDown][markdown]: syntax additions, and blog-specific context.

### Additions to Syntax

At this time there is only one addition to the syntax. Its purpose is to provide code syntax highlighting support.

It looks like this:

@@ python
def __unicode__(self):
return u"My name is %s" % self.name
@@

On the opening line you place two apersands (@), followed by the alias for a lexer in the Pygments package.


## Dynamic Blog Context

A great deal of LifeFlow's design is the result of three observations:

1. MarkDown makes writing a lot more fun (and quicker).
2. Linking things together adds a lot of value to posts.
3. Writing the same reference links over in different posts is frustrating (Don't Repeat Yourself should apply to writing blog entries as well as programming!).

Out of these observations, Dynamic Blog Context, or DBC was concieved.

DBC is essentially a battery of automatically generated references that you can use when writing your blog entries. You may find yourself writing a lot of throw away references to link to a certain tag of yours, or to a certain project. You may get annoyed having to figure out the link to the previous blog entry, or remembering the link to the first entry in some blog series.

Dynamic Blog Context does its best to make this all better.

Lets take a look at an example:

Please take a look [at my articles about Japan][tag japan].

The magic here (such as it is) is that this *just works*, instead of having to write it out like this

[tag japan]: /tags/japan/
Please take a look [at my articles about Japan][tag japan].

Its a pleasant convenience, and helps abstract your entries from the specific URLs and implementation details of your blog. Using DBC you could rearrange your blog, but you just have to resave your entries (DBC is computed at save), and they would update.

A number of more tags are in the work (they are quite simple, and I am working on a way to allow users to contribute their own without breaking their SVN checkout, at the moment you can just add more by looking in lifeflow/markup/lifeflowmarkup.py, but its likely that code will be getting cleaned up somehow in the near future)--[please check the project page for the update to date details][project lifeflow]--but take a look at the currently available DBC.

1. [tag slug] - creates a link to the tag with @slug
2. [comment pk] - creates a link to the comment with @pk (works with comments posted on any entry)
3. [project slug] - creates a link to the project with @slug
4. [author] - creates a link to the authors's biography page if there is one author, if there are more or less authors then it creates a link to the /author/ page.
5. [comments] - creates a link to the comment division for the current entry
6. [projects] - creates a link to the /projects/ page
7. [series] - creates a link to the /articles/ page
8. [tags] - creates a link to the site's tag cloud

The others on the way (probably tonight):

1. [previous]
2. [series number_of_entry]
3. [series slug number_of_entry]

There are undoubtedly other places where Dynamic Blog Context would be appropriate, and I am open to suggestions about where those places may be. Let me know if you have any good ideas!
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License

Copyright (c) 2008 Will Larson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
54 changes: 54 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

### Teach Dynamic Blog Context the distinction between projects and entries

Relevant code in lifeflow/markup/lifeflowmarkup.py


### Considering enabling footnotes by default for entries (need to figure out how they work first)

Relevant code in lifeflow/models.py (and lifeflow/markup/lifeflowmarkup.py)


### Add Link model for storing frequently used references for MarkDown

Relevant code in lifeflow/models.py


### No specified author then about specifies to /author/

Relevant code in lifeflow/context.py


### Dynamic Blog Context work for image links

At the moment DBC only works for reference links, not reference image links. Changing this should be a minor regex fix. Something like r"!?" somewhere in markup/lifeflowmarkup

Relevant code in lifeflow/markup/lifeflowmarkup.py:

LifeflowPreprocessor.run()


### Improve tag cloud implementation

The current tag cloud implementation crashes the database over and over. Its pretty atrocious. Just need to throw in some easy caching and its performance should increase dramatically.

Relevant code in lifeflow/models.py:

Tag


### Improve Entry & Project resaving technique

(I think the recent focus and implementation of Dynamic Blog Context may allow for this issue to partially or wholly disappear, depending)

At the moment both Entry and Project instances need to know their ManyToMany instances before they can properly render themselves (specifically, they need to know the resources that have been assigned to them, so they can create markdown references to refer to them).

The current way of handling this is simply having a signal that resaves each model a few seconds after its first save (with some checking to prevent infinite loops). This is sloppy, to say the least.

A relatively easy *possible improvement* would be to implement a queue that objects that require resaving are place upon. Save them one at a time. Still a bit ackward, but would guarantee a successful save (eventually), which isn't necessary guaranteed at the moment. This is mostly a hypothetical issue, *but it can rear its ugly head when you attempt to do mass editing via the shell*.

Relevant code in lifeflow/models.py:

Entry.save
Project.save
resave_object
29 changes: 29 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Import any enabled modules as specified in the settings.py
file for the project.
"""

import imp
import sys
from django.conf import settings


def import_module(name, globals=None, locals=None, fromlist=None):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass

# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.

_, pathname, description = imp.find_module("lifeflow")
path = u"%s/mods/%s" % (pathname, name)
return imp.load_module(name, None, path, description)


for mod in getattr(settings, u"LIFEFLOW_MODS", ()):
import_module(mod)

Binary file added comments/.DS_Store
Binary file not shown.
Empty file added comments/__init__.py
Empty file.
102 changes: 102 additions & 0 deletions comments/akismet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/python

__version__ = "0.3"
__date__ = "2005-12-01"
__author__ = "David Lynch (kemayo AT Google's mail service DOT com)"
__copyright__ = "Copyright 2005, David Lynch"
__license__ = "Python"
__history__ = """
0.3 - 20051205 - Cleaned up __post.
0.2 - 20051201 - Added documentation, and tweaked the circumstances where an error
will be thrown.
0.1 - 20051201 - Initial release. Everything pretty much works. Probably.
"""

import httplib
from urllib import urlencode

USERAGENT = ""
AKISMET_URL = "rest.akismet.com"
AKISMET_PORT = 80

class AkismetError(Exception):
def __init__(self, response, statuscode):
self.response = response
self.statuscode = statuscode
def __str__(self):
return repr(self.value)

def __post(request, host, path, port = 80):
connection = httplib.HTTPConnection(host, port)
connection.request("POST", path, request,
{"User-Agent":"%s | %s/%s" % (USERAGENT,"Akistmet.py", __version__),
"Content-type":"application/x-www-form-urlencoded"})
response = connection.getresponse()

return response.read(), response.status

def verify_key(key, blog):
"""Find out whether a given WordPress.com API key is valid.
Required parameters:
key: A WordPress.com API key.
blog: URL of the front page of the site comments will be submitted to.
Returns True if a valid key, False if invalid.
"""
response, status = __post("key=%s&blog=%s" % (key,blog), AKISMET_URL, "/1.1/verify-key", AKISMET_PORT)

if response == "valid":
return True
elif response == "invalid":
return False
else:
raise AkismetError(response, status)

def comment_check(key, blog, user_ip, user_agent, **other):
"""Submit a comment to find out whether Akismet thinks that it's spam.
Required parameters:
key: A valid WordPress.com API key, as tested with verify_key().
blog: URL of the front page of the site the comment will appear on.
user_ip: IP address of the being which submitted the comment.
user_agent: User agent reported by said being.
Suggested "other" keys: "permalink", "referrer", "comment_type", "comment_author",
"comment_author_email", "comment_author_url", "comment_content", and any other HTTP
headers sent from the client.
More detail on what should be submitted is available at:
http://akismet.com/development/api/
Returns True if spam, False if ham. Throws an AkismetError if the server says
anything unexpected.
"""

request = {'blog': blog, 'user_ip': user_ip, 'user_agent': user_agent}
request.update(other)
response, status = __post(urlencode(request), "%s.%s" % (key,AKISMET_URL), "/1.1/comment-check", AKISMET_PORT)

if response == "true":
return True
elif response == "false":
return False
else:
raise AkismetError(response, status)

def submit_spam(key, blog, user_ip, user_agent, **other):
"""Report a false negative to Akismet.
Same arguments as comment_check.
Doesn't return anything. Throws an AkismetError if the server says anything.
"""
request = {'blog': blog, 'user_ip': user_ip, 'user_agent': user_agent}
request.update(other)
response, status = __post(urlencode(request), "%s.%s" % (key,AKISMET_URL), "/1.1/submit-spam", AKISMET_PORT)
if status != 200 or response != "":
raise AkismetError(response, status)

def submit_ham(key, blog, user_ip, user_agent, **other):
"""Report a false positive to Akismet.
Same arguments as comment_check.
Doesn't return anything. Throws an AkismetError if the server says anything.
"""
request = {'blog': blog, 'user_ip': user_ip, 'user_agent': user_agent}
request.update(other)
response, status = __post(urlencode(request), "%s.%s" % (key,AKISMET_URL), "/1.1/submit-ham", AKISMET_PORT)
if status != 200 or response != "":
raise AkismetError(response, status)
Binary file added comments/captcha/.DS_Store
Binary file not shown.
Empty file added comments/captcha/__init__.py
Empty file.

0 comments on commit b81caf7

Please sign in to comment.