From 4bae11bb25a8e3c43118891d17fd8e981ecf8dc6 Mon Sep 17 00:00:00 2001 From: luxagraf Date: Fri, 23 May 2014 10:48:20 -0400 Subject: Refactored code to use PEP8/Pyflake coding styles and cleaned up cruft a bit --- app/cron/create_country_sidebar.py | 19 - app/cron/create_region_sidebar.py | 18 - app/cron/full_build.py | 33 -- app/cron/full_build.sh | 2 - app/cron/sync_links.py | 13 - app/cron/sync_photo_sets.py | 13 - app/cron/sync_photos.py | 12 - app/lib/ssl/__init__.py | 0 app/lib/ssl/middleware.py | 41 -- app/lib/templatetags/templatetags/get_latest.py | 1 - .../templatetags/templatetags/get_latest_pub.py | 1 - app/lib/utils/APIClients.py | 104 ---- app/lib/utils/__init__.py | 0 app/lib/utils/pinboard.py | 558 --------------------- app/lib/utils/strutils.py | 50 -- app/links/sync_links.py | 13 + app/photos/sync_photo_sets.py | 13 + app/photos/sync_photos.py | 12 + design/templates/archives/writing_date.html | 26 + design/templates/comments/base.html | 8 + design/templates/comments/comment.html | 32 ++ .../comments/comment_notification_email.txt | 20 + design/templates/comments/deleted.html | 21 + design/templates/comments/flagged.html | 21 + design/templates/comments/form.html | 18 + design/templates/comments/list.html | 14 + design/templates/comments/posted.html | 25 + design/templates/comments/preview.html | 30 ++ 28 files changed, 253 insertions(+), 865 deletions(-) delete mode 100644 app/cron/create_country_sidebar.py delete mode 100644 app/cron/create_region_sidebar.py delete mode 100644 app/cron/full_build.py delete mode 100755 app/cron/full_build.sh delete mode 100644 app/cron/sync_links.py delete mode 100644 app/cron/sync_photo_sets.py delete mode 100644 app/cron/sync_photos.py delete mode 100644 app/lib/ssl/__init__.py delete mode 100644 app/lib/ssl/middleware.py delete mode 100644 app/lib/templatetags/templatetags/get_latest.py delete mode 100644 app/lib/templatetags/templatetags/get_latest_pub.py delete mode 100644 app/lib/utils/APIClients.py delete mode 100644 app/lib/utils/__init__.py delete mode 100644 app/lib/utils/pinboard.py delete mode 100644 app/lib/utils/strutils.py create mode 100644 app/links/sync_links.py create mode 100644 app/photos/sync_photo_sets.py create mode 100644 app/photos/sync_photos.py create mode 100644 design/templates/archives/writing_date.html create mode 100644 design/templates/comments/base.html create mode 100644 design/templates/comments/comment.html create mode 100644 design/templates/comments/comment_notification_email.txt create mode 100644 design/templates/comments/deleted.html create mode 100644 design/templates/comments/flagged.html create mode 100644 design/templates/comments/form.html create mode 100644 design/templates/comments/list.html create mode 100644 design/templates/comments/posted.html create mode 100644 design/templates/comments/preview.html diff --git a/app/cron/create_country_sidebar.py b/app/cron/create_country_sidebar.py deleted file mode 100644 index f660c73..0000000 --- a/app/cron/create_country_sidebar.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys, os - -sys.path.append('/home/luxagraf/webapps/django1_1') -sys.path.append('/home/luxagraf/webapps/django1_1/luxagraf') -sys.path.append('/home/luxagraf/webapps/django1_1/luxagraf/apps') -sys.path.append('/home/luxagraf/webapps/django1_1/luxagraf/lib') -sys.path.append('/home/luxagraf/webapps/django1_1/lib/python2.5/') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' - -from django.template import Context -from django.template import loader -from django.conf import settings -from locations.models import Country,Region -c = Context({'country_list': Country.objects.filter(visited=True),}) -t = loader.render_to_string('includes/country_sidebar_template.html',c) -fpath = '%s%s' %(settings.PROJ_ROOT,'templates/includes/country_sidebar.html') -file = open(fpath, 'w') -file.write(t) -file.close() \ No newline at end of file diff --git a/app/cron/create_region_sidebar.py b/app/cron/create_region_sidebar.py deleted file mode 100644 index 77f2628..0000000 --- a/app/cron/create_region_sidebar.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys, os - -sys.path.append('/home/luxagraf/webapps/django1_1') -sys.path.append('/home/luxagraf/webapps/django1_1/luxagraf') -sys.path.append('/home/luxagraf/webapps/django1_1/luxagraf/apps') -sys.path.append('/home/luxagraf/webapps/django1_1/luxagraf/lib') -sys.path.append('/home/luxagraf/webapps/django1_1/lib/python2.5/') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' - -from django.template import Context,loader -from django.conf import settings -from locations.models import Region -c = Context({'region_list': Region.objects.all(),}) -t = loader.render_to_string('includes/regions_sidebar_template.html',c) -fpath = '%s%s' %(settings.PROJ_ROOT,'templates/includes/regions_sidebar.html') -file = open(fpath, 'w') -file.write(t) -file.close() \ No newline at end of file diff --git a/app/cron/full_build.py b/app/cron/full_build.py deleted file mode 100644 index e52d005..0000000 --- a/app/cron/full_build.py +++ /dev/null @@ -1,33 +0,0 @@ -import sys, os -from os.path import dirname, abspath - -PROJECT_ROOT = abspath(dirname(dirname(__file__))) - -sys.path.append(PROJECT_ROOT) -sys.path.append(PROJECT_ROOT+'/apps') -sys.path.append(PROJECT_ROOT+'/lib') -sys.path.append('/home/luxagraf/webapps/django1_3/lib/python2.7/') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' - -from build.base import BuildWriting,BuildMap,BuildPhotos,BuildAbout,BuildProjects,BuildSitemap,BuildContact - -b = BuildWriting() -b.build() - -b = BuildPhotos() -b.build() - -b = BuildMap() -b.build() - -b = BuildAbout() -b.build() - -b = BuildProjects() -b.build() - -b = BuildSitemap() -b.build() - -b = BuildContact() -b.build() \ No newline at end of file diff --git a/app/cron/full_build.sh b/app/cron/full_build.sh deleted file mode 100755 index c065d48..0000000 --- a/app/cron/full_build.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -python2.7 /home/luxagraf/webapps/django/luxagraf/cron/full_build.py \ No newline at end of file diff --git a/app/cron/sync_links.py b/app/cron/sync_links.py deleted file mode 100644 index cd1373d..0000000 --- a/app/cron/sync_links.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys, os -from os.path import dirname, abspath -PROJECT_ROOT = abspath(dirname(dirname(dirname(__file__))))+'/' -#PROJECT_ROOT = abspath(dirname(dirname(__file__))) -print PROJECT_ROOT -sys.path.append(PROJECT_ROOT) -sys.path.append(PROJECT_ROOT+'/app') -sys.path.append(PROJECT_ROOT+'/app/lib') -sys.path.append(PROJECT_ROOT+'/config') -sys.path.append('/home/luxagraf/apps/venv/bin/python2.7/') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.settings' -from links import retriever -retriever.sync_pinboard_links() diff --git a/app/cron/sync_photo_sets.py b/app/cron/sync_photo_sets.py deleted file mode 100644 index beac435..0000000 --- a/app/cron/sync_photo_sets.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys, os -from os.path import dirname, abspath -PROJECT_ROOT = abspath(dirname(dirname(dirname(__file__))))+'/' -#PROJECT_ROOT = abspath(dirname(dirname(__file__))) -print PROJECT_ROOT -sys.path.append(PROJECT_ROOT) -sys.path.append(PROJECT_ROOT+'/app') -sys.path.append(PROJECT_ROOT+'/app/lib') -sys.path.append(PROJECT_ROOT+'/config') -sys.path.append('/home/luxagraf/apps/venv/bin/python2.7/') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.settings' -from photos import retriever -retriever.sync_sets() diff --git a/app/cron/sync_photos.py b/app/cron/sync_photos.py deleted file mode 100644 index 634a2fc..0000000 --- a/app/cron/sync_photos.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys, os -from os.path import dirname, abspath -PROJECT_ROOT = abspath(dirname(dirname(dirname(__file__))))+'/' -#PROJECT_ROOT = abspath(dirname(dirname(__file__))) -sys.path.append(PROJECT_ROOT) -sys.path.append(PROJECT_ROOT+'/app') -sys.path.append(PROJECT_ROOT+'/app/lib') -sys.path.append(PROJECT_ROOT+'/config') -sys.path.append('/home/luxagraf/apps/venv/bin/python2.7/') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.settings' -from photos import retriever -retriever.sync_flickr_photos() diff --git a/app/lib/ssl/__init__.py b/app/lib/ssl/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/lib/ssl/middleware.py b/app/lib/ssl/middleware.py deleted file mode 100644 index 11e1076..0000000 --- a/app/lib/ssl/middleware.py +++ /dev/null @@ -1,41 +0,0 @@ -__license__ = "Python" -__copyright__ = "Copyright (C) 2007, Stephen Zabel" -__author__ = "Stephen Zabel - sjzabel@gmail.com" -__contributors__ = "Jay Parlar - parlar@gmail.com" - -from django.conf import settings -from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect, get_host - -SSL = 'SSL' - -class SSLRedirect: - - def process_view(self, request, view_func, view_args, view_kwargs): - if SSL in view_kwargs: - secure = view_kwargs[SSL] - del view_kwargs[SSL] - else: - secure = False - - if not secure == self._is_secure(request): - return self._redirect(request, secure) - - def _is_secure(self, request): - if request.is_secure(): - return True - - #Handle the Webfaction case until this gets resolved in the request.is_secure() - if 'HTTP_X_FORWARDED_SSL' in request.META: - return request.META['HTTP_X_FORWARDED_SSL'] == 'on' - - return False - - def _redirect(self, request, secure): - protocol = secure and "https" or "http" - newurl = "%s://%s%s" % (protocol,get_host(request),request.get_full_path()) - if settings.DEBUG and request.method == 'POST': - raise RuntimeError, \ - """Django can't perform a SSL redirect while maintaining POST data. - Please structure your views so that redirects only occur during GETs.""" - - return HttpResponsePermanentRedirect(newurl) \ No newline at end of file diff --git a/app/lib/templatetags/templatetags/get_latest.py b/app/lib/templatetags/templatetags/get_latest.py deleted file mode 100644 index 6c9f9fa..0000000 --- a/app/lib/templatetags/templatetags/get_latest.py +++ /dev/null @@ -1 +0,0 @@ -from django.template import Library, Node from django.db.models import get_model register = Library() class LatestContentNode(Node): def __init__(self, model, num, varname): self.num, self.varname = num, varname self.model = get_model(*model.split('.')) def render(self, context): context[self.varname] = self.model._default_manager.all()[:self.num] return '' def get_latest(parser, token): bits = token.contents.split() if len(bits) != 5: raise TemplateSyntaxError, "get_latest tag takes exactly four arguments" if bits[3] != 'as': raise TemplateSyntaxError, "third argument to get_latest tag must be 'as'" return LatestContentNode(bits[1], bits[2], bits[4]) get_latest = register.tag(get_latest) \ No newline at end of file diff --git a/app/lib/templatetags/templatetags/get_latest_pub.py b/app/lib/templatetags/templatetags/get_latest_pub.py deleted file mode 100644 index 151befa..0000000 --- a/app/lib/templatetags/templatetags/get_latest_pub.py +++ /dev/null @@ -1 +0,0 @@ -from django.template import Library, Node from django.db.models import get_model register = Library() class LatestContentNode(Node): def __init__(self, model, num, varname): self.num, self.varname = num, varname self.model = get_model(*model.split('.')) def render(self, context): context[self.varname] = self.model._default_manager.filter(status__exact=1)[:self.num] return '' def get_latest_pub(parser, token): bits = token.contents.split() if len(bits) != 5: raise TemplateSyntaxError, "get_latest tag takes exactly four arguments" if bits[3] != 'as': raise TemplateSyntaxError, "third argument to get_latest tag must be 'as'" return LatestContentNode(bits[1], bits[2], bits[4]) get_latest_pub = register.tag(get_latest_pub) \ No newline at end of file diff --git a/app/lib/utils/APIClients.py b/app/lib/utils/APIClients.py deleted file mode 100644 index 24ab97b..0000000 --- a/app/lib/utils/APIClients.py +++ /dev/null @@ -1,104 +0,0 @@ -# APIClients for grabbing data from popular web services -# By Scott Gilbertson -# Copyright is lame, take what you want, except for those portions noted - -# Dependencies: -import sys, urllib -import xml.etree.cElementTree as xml_parser - - -DEBUG = 0 - -""" -base class -- handles GoodReads.com, but works for any rss feed, just send an empty string for anything you don't need -""" -class APIClient: - def __init__(self, base_path, api_key): - self.api_key = api_key - self.base_path = base_path - - def __getattr__(self, method): - def method(_self=self, _method=method, **params): - url = "%s%s?%s&" % (self.base_path, self.api_key, urllib.urlencode(params)) - if DEBUG: print url - data = self.fetch(url) - return data - - return method - - def fetch(self, url): - u = urllib.FancyURLopener(None) - usock = u.open(url) - rawdata = usock.read() - if DEBUG: print rawdata - usock.close() - return xml_parser.fromstring(rawdata) - -""" - Extend APIClient to work with the ma.gnolia.com API - (http://wiki.ma.gnolia.com/Ma.gnolia_API) - Adds some error handling as well -""" -class MagnoliaError(Exception): - def __init__(self, code, message): - self.code = code - self.message = message - - def __str__(self): - return 'Magnolia Error %s: %s' % (self.code, self.message) - - -class MagnoliaClient(APIClient): - def __getattr__(self, method): - def method(_self=self, _method=method, **params): - url = "%s%s?%s&api_key=%s" % (self.base_path, _method, urllib.urlencode(params), self.api_key) - if DEBUG: print url - data = APIClient.fetch(self, url) - return data - return method - - -""" - Extend APIClient to work with the Flickr API - (http://www.flickr.com/services/api/) - Adds error handling as well -""" - -class FlickrError(Exception): - def __init__(self, code, message): - self.code = code - self.message = message - - def __str__(self): - return 'Flickr Error %s: %s' % (self.code, self.message) - -class FlickrClient(APIClient): - def __getattr__(self, method): - def method(_self=self, _method=method, **params): - _method = _method.replace("_", ".") - url = "%s?method=%s&%s&api_key=%s" % (self.base_path, _method, urllib.urlencode(params), self.api_key) - if DEBUG: print url - data = APIClient.fetch(self, url) - return data - return method - -class TumblrClient: - def __init__(self, base_path): - self.base_path = base_path - - def __getattr__(self, method): - def method(_self=self, _method=method, **params): - url = "%s" % (self.base_path) - if DEBUG: print url - data = self.fetch(url) - return data - - return method - - def fetch(self, url): - u = urllib.FancyURLopener(None) - usock = u.open(url) - rawdata = usock.read() - if DEBUG: print rawdata - usock.close() - return xml_parser.fromstring(rawdata) diff --git a/app/lib/utils/__init__.py b/app/lib/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/lib/utils/pinboard.py b/app/lib/utils/pinboard.py deleted file mode 100644 index e05935e..0000000 --- a/app/lib/utils/pinboard.py +++ /dev/null @@ -1,558 +0,0 @@ -#!/usr/bin/env python -"""Python-Pinboard - -Python module for access to pinboard via its API. -Recommended: Python 2.6 or later (untested on previous versions) - -This library was built on top of Paul Mucur's original work on the python-delicious -which was supported for python 2.3. Morgan became a contributor and ported this library -to pinboard.in when it was announced in December 2010 that delicious servers may be -shutting down. - -The port to pinboard resulted in the inclusion of gzip support - -""" - -__version__ = "1.0" -__license__ = "BSD" -__copyright__ = "Copyright 2011, Morgan Craft" -__author__ = "Morgan Craft " - -#TODO: -# Should text be properly escaped for XML? Or that not this module's -# responsibility? -# Create test suite - - -_debug = 0 - -# The user agent string sent to pinboard.in when making requests. If you are -# using this module in your own application, you should probably change this. -USER_AGENT = "Python-Pinboard/%s +http://morgancraft.com/service_layer/python-pinboard/" % __version__ - - -import urllib -import urllib2 -import sys -import re -import time -## added to handle gzip compression from server -import StringIO -import gzip - -from xml.dom import minidom -try: - StringTypes = basestring -except: - try: - # Python 2.2 does not have basestring - from types import StringTypes - except: - # Python 2.0 and 2.1 do not have StringTypes - from types import StringType, UnicodeType - StringTypes = None -try: - ListType = list - TupleType = tuple -except: - from types import ListType, TupleType - -# Taken from Mark Pilgrim's amazing Universal Feed Parser -# -try: - UserDict = dict -except NameError: - from UserDict import UserDict -try: - import datetime -except: - datetime = None - - -# The URL of the Pinboard API -PINBOARD_API = "https://api.pinboard.in/v1" -AUTH_HANDLER_REALM = 'API' -AUTH_HANDLER_URI = "https://api.pinboard.in/" - -def open(username, password): - """Open a connection to a pinboard.in account""" - return PinboardAccount(username, password) - -def connect(username, password): - """Open a connection to a pinboard.in account""" - return open(username, password) - - -# Custom exceptions - -class PinboardError(Exception): - """Error in the Python-Pinboard module""" - pass - -class ThrottleError(PinboardError): - """Error caused by pinboard.in throttling requests""" - def __init__(self, url, message): - self.url = url - self.message = message - def __str__(self): - return "%s: %s" % (self.url, self.message) - -class AddError(PinboardError): - """Error adding a post to pinboard.in""" - pass - -class DeleteError(PinboardError): - """Error deleting a post from pinboard.in""" - pass - -class BundleError(PinboardError): - """Error bundling tags on pinboard.in""" - pass - -class DeleteBundleError(PinboardError): - """Error deleting a bundle from pinboard.in""" - pass - -class RenameTagError(PinboardError): - """Error renaming a tag in pinboard.in""" - pass - -class DateParamsError(PinboardError): - '''Date params error''' - pass - -class PinboardAccount(UserDict): - """A pinboard.in account""" - - # Used to track whether all posts have been downloaded yet. - __allposts = 0 - __postschanged = 0 - - # Time of last request so that the one second limit can be enforced. - __lastrequest = None - - # Special methods - - def __init__(self, username, password): - UserDict.__init__(self) - # Authenticate the URL opener so that it can access Pinboard - if _debug: - sys.stderr.write("Initialising Pinboard Account object.\n") - auth_handler = urllib2.HTTPBasicAuthHandler() - auth_handler.add_password("API", "https://api.pinboard.in/", \ - username, password) - opener = urllib2.build_opener(auth_handler) - opener.addheaders = [("User-agent", USER_AGENT), ('Accept-encoding', 'gzip')] - urllib2.install_opener(opener) - if _debug: - sys.stderr.write("URL opener with HTTP authenticiation installed globally.\n") - - - if _debug: - sys.stderr.write("Time of last update loaded into class dictionary.\n") - - def __getitem__(self, key): - try: - return UserDict.__getitem__(self, key) - except KeyError: - if key == "tags": - return self.tags() - elif key == "dates": - return self.dates() - elif key == "posts": - return self.posts() - elif key == "bundles": - return self.bundles() - - def __setitem__(self, key, value): - if key == "posts": - if _debug: - sys.stderr.write("The value of posts has been changed.\n") - self.__postschanged = 1 - return UserDict.__setitem__(self, key, value) - - - def __request(self, url): - - # Make sure that it has been at least 1 second since the last - # request was made. If not, halt execution for approximately one - # seconds. - if self.__lastrequest and (time.time() - self.__lastrequest) < 2: - if _debug: - sys.stderr.write("It has been less than two seconds since the last request; halting execution for one second.\n") - time.sleep(1) - if _debug and self.__lastrequest: - sys.stderr.write("The delay between requests was %d.\n" % (time.time() - self.__lastrequest)) - self.__lastrequest = time.time() - if _debug: - sys.stderr.write("Opening %s.\n" % url) - - try: - ## for pinboard a gzip request is made - raw_xml = urllib2.urlopen(url) - compresseddata = raw_xml.read() - ## bing unpackaging gzipped stream buffer - compressedstream = StringIO.StringIO(compresseddata) - gzipper = gzip.GzipFile(fileobj=compressedstream) - xml = gzipper.read() - - except urllib2.URLError, e: - raise e - - self["headers"] = {} - for header in raw_xml.headers.headers: - (name, value) = header.split(": ") - self["headers"][name.lower()] = value[:-2] - if raw_xml.headers.status == "503": - raise ThrottleError(url, \ - "503 HTTP status code returned by pinboard.in") - if _debug: - sys.stderr.write("%s opened successfully.\n" % url) - return minidom.parseString(xml) - - - - - def posts(self, tag="", date="", todt="", fromdt="", count=0): - """Return pinboard.in bookmarks as a list of dictionaries. - - This should be used without arguments as rarely as possible by - combining it with the lastupdate attribute to only get all posts when - there is new content as it places a large load on the pinboard.in - servers. - - """ - query = {} - - ## if a date is passed then a ranged set of date params CANNOT be passed - if date and (todt or fromdt): - raise DateParamsError - - if not count and not date and not todt and not fromdt and not tag: - path = "all" - - # If attempting to load all of the posts from pinboard.in, and - # a previous download has been done, check to see if there has - # been an update; if not, then just return the posts stored - # inside the class. - if _debug: - sys.stderr.write("Checking to see if a previous download has been made.\n") - if not self.__postschanged and self.__allposts and \ - self.lastupdate() == self["lastupdate"]: - if _debug: - sys.stderr.write("It has; returning old posts instead.\n") - return self["posts"] - elif not self.__allposts: - if _debug: - sys.stderr.write("Making note of request for all posts.\n") - self.__allposts = 1 - elif date: - path = "get" - elif todt or fromdt: - path = "all" - else: - path = "recent" - if count: - query["count"] = count - if tag: - query["tag"] = tag - - ##todt - if todt and (isinstance(todt, ListType) or isinstance(todt, TupleType)): - query["todt"] = "-".join([str(x) for x in todt[:3]]) - elif todt and (todt and isinstance(todt, datetime.datetime) or \ - isinstance(todt, datetime.date)): - query["todt"] = "-".join([str(todt.year), str(todt.month), str(todt.day)]) - elif todt: - query["todt"] = todt - - ## fromdt - if fromdt and (isinstance(fromdt, ListType) or isinstance(fromdt, TupleType)): - query["fromdt"] = "-".join([str(x) for x in fromdt[:3]]) - elif fromdt and (fromdt and isinstance(fromdt, datetime.datetime) or \ - isinstance(fromdt, datetime.date)): - query["fromdt"] = "-".join([str(fromdt.year), str(fromdt.month), str(fromdt.day)]) - elif fromdt: - query["fromdt"] = fromdt - - if date and (isinstance(date, ListType) or isinstance(date, TupleType)): - query["dt"] = "-".join([str(x) for x in date[:3]]) - elif date and (datetime and isinstance(date, datetime.datetime) or \ - isinstance(date, datetime.date)): - query["dt"] = "-".join([str(date.year), str(date.month), str(date.day)]) - elif date: - query["dt"] = date - - postsxml = self.__request("%s/posts/%s?%s" % (PINBOARD_API, path, \ - urllib.urlencode(query))).getElementsByTagName("post") - posts = [] - if _debug: - sys.stderr.write("Parsing posts XML into a list of dictionaries.\n") - - # For each post, extract every attribute (splitting tags into sub-lists) - # and insert as a dictionary into the `posts` list. - for post in postsxml: - postdict = {} - for (name, value) in post.attributes.items(): - if name == u"tag": - name = u"tags" - value = value.split(" ") - if name == u"time": - postdict[u"time_parsed"] = time.strptime(value, "%Y-%m-%dT%H:%M:%SZ") - postdict[name] = value - if self.has_key("posts") and isinstance(self["posts"], ListType) \ - and postdict not in self["posts"]: - self["posts"].append(postdict) - posts.append(postdict) - if _debug: - sys.stderr.write("Inserting posts list into class attribute.\n") - if not self.has_key("posts"): - self["posts"] = posts - if _debug: - sys.stderr.write("Resetting marker so module doesn't think posts has been changed.\n") - self.__postschanged = 0 - return posts - - def tags(self): - """Return a dictionary of tags with the number of posts in each one""" - tagsxml = self.__request("%s/tags/get?" % \ - PINBOARD_API).getElementsByTagName("tag") - tags = [] - if _debug: - sys.stderr.write("Parsing tags XML into a list of dictionaries.\n") - for tag in tagsxml: - tagdict = {} - for (name, value) in tag.attributes.items(): - if name == u"tag": - name = u"name" - elif name == u"count": - value = int(value) - tagdict[name] = value - if self.has_key("tags") and isinstance(self["tags"], ListType) \ - and tagdict not in self["tags"]: - self["tags"].append(tagdict) - tags.append(tagdict) - if _debug: - sys.stderr.write("Inserting tags list into class attribute.\n") - if not self.has_key("tags"): - self["tags"] = tags - return tags - - def bundles(self): - """Return a dictionary of all bundles""" - bundlesxml = self.__request("%s/tags/bundles/all" % \ - PINBOARD_API).getElementsByTagName("bundle") - bundles = [] - if _debug: - sys.stderr.write("Parsing bundles XML into a list of dictionaries.\n") - for bundle in bundlesxml: - bundledict = {} - for (name, value) in bundle.attributes.items(): - bundledict[name] = value - if self.has_key("bundles") and isinstance(self["bundles"], ListType) \ - and bundledict not in self["bundles"]: - self["bundles"].append(bundledict) - bundles.append(bundledict) - if _debug: - sys.stderr.write("Inserting bundles list into class attribute.\n") - if not self.has_key("bundles"): - self["bundles"] = bundles - return bundles - - def dates(self, tag=""): - """Return a dictionary of dates with the number of posts at each date""" - if tag: - query = urllib.urlencode({"tag":tag}) - else: - query = "" - datesxml = self.__request("%s/posts/dates?%s" % \ - (PINBOARD_API, query)).getElementsByTagName("date") - dates = [] - if _debug: - sys.stderr.write("Parsing dates XML into a list of dictionaries.\n") - for date in datesxml: - datedict = {} - for (name, value) in date.attributes.items(): - if name == u"date": - datedict[u"date_parsed"] = time.strptime(value, "%Y-%m-%d") - elif name == u"count": - value = int(value) - datedict[name] = value - if self.has_key("dates") and isinstance(self["dates"], ListType) \ - and datedict not in self["dates"]: - self["dates"].append(datedict) - dates.append(datedict) - if _debug: - sys.stderr.write("Inserting dates list into class attribute.\n") - if not self.has_key("dates"): - self["dates"] = dates - return dates - - - # Methods to modify pinboard.in content - - def add(self, url, description, extended="", tags=(), date="", toread="no"): - """Add a new post to pinboard.in""" - query = {} - query["url"] = url - query ["description"] = description - query["toread"] = toread - if extended: - query["extended"] = extended - if tags and (isinstance(tags, TupleType) or isinstance(tags, ListType)): - query["tags"] = " ".join(tags) - elif tags and (StringTypes and isinstance(tags, StringTypes)) or \ - (not StringTypes and (isinstance(tags, StringType) or \ - isinstance(tags, UnicodeType))): - query["tags"] = tags - - # This is a rather rudimentary way of parsing date strings into - # ISO8601 dates: if the date string is shorter than the required - # 20 characters then it is assumed that it is a partial date - # such as "2005-3-31" or "2005-3-31T20:00" and it is split into a - # list along non-numerals. Empty elements are then removed - # and then this is passed to the tuple/list case where - # the tuple/list is padded with necessary 0s and then formatted - # into an ISO8601 date string. This does not take into account - # time zones. - if date and (StringTypes and isinstance(tags, StringTypes)) or \ - (not StringTypes and (isinstance(tags, StringType) or \ - isinstance(tags, UnicodeType))) and len(date) < 20: - date = re.split("\D", date) - while '' in date: - date.remove('') - if date and (isinstance(date, ListType) or isinstance(date, TupleType)): - date = list(date) - if len(date) > 2 and len(date) < 6: - for i in range(6 - len(date)): - date.append(0) - query["dt"] = "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ" % tuple(date) - elif date and (datetime and (isinstance(date, datetime.datetime) \ - or isinstance(date, datetime.date))): - query["dt"] = "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ" % date.utctimetuple()[:6] - elif date: - query["dt"] = date - try: - response = self.__request("%s/posts/add?%s" % (PINBOARD_API, \ - urllib.urlencode(query))) - if response.firstChild.getAttribute("code") != u"done": - raise AddError - if _debug: - sys.stderr.write("Post, %s (%s), added to pinboard.in\n" \ - % (description, url)) - except: - if _debug: - sys.stderr.write("Unable to add post, %s (%s), to pinboard.in\n" \ - % (description, url)) - - def bundle(self, bundle, tags): - """Bundle a set of tags together""" - query = {} - query["bundle"] = bundle - if tags and (isinstance(tags, TupleType) or isinstance(tags, ListType)): - query["tags"] = " ".join(tags) - elif tags and isinstance(tags, StringTypes): - query["tags"] = tags - try: - response = self.__request("%s/tags/bundles/set?%s" % (PINBOARD_API, \ - urllib.urlencode(query))) - if response.firstChild.getAttribute("code") != u"done": - raise BundleError - if _debug: - sys.stderr.write("Tags, %s, bundled into %s.\n" \ - % (repr(tags), bundle)) - except: - if _debug: - sys.stderr.write("Unable to bundle tags, %s, into %s to pinboard.in\n" \ - % (repr(tags), bundle)) - - def delete(self, url): - """Delete post from pinboard.in by its URL""" - try: - response = self.__request("%s/posts/delete?%s" % (PINBOARD_API, \ - urllib.urlencode({"url":url}))) - if response.firstChild.getAttribute("code") != u"done": - raise DeleteError - if _debug: - sys.stderr.write("Post, %s, deleted from pinboard.in\n" \ - % url) - except: - if _debug: - sys.stderr.write("Unable to delete post, %s, from pinboard.in\n" \ - % url) - - def delete_bundle(self, name): - """Delete bundle from pinboard.in by its name""" - try: - response = self.__request("%s/tags/bundles/delete?%s" % (PINBOARD_API, \ - urllib.urlencode({"bundle":name}))) - if response.firstChild.getAttribute("code") != u"done": - raise DeleteBundleError - if _debug: - sys.stderr.write("Bundle, %s, deleted from pinboard.in\n" \ - % name) - except: - if _debug: - sys.stderr.write("Unable to delete bundle, %s, from pinboard.in\n" \ - % name) - - def rename_tag(self, old, new): - """Rename a tag""" - query = {"old":old, "new":new} - try: - response = self.__request("%s/tags/rename?%s" % (PINBOARD_API, \ - urllib.urlencode(query))) - if response.firstChild.getAttribute("code") != u"done": - raise RenameTagError - if _debug: - sys.stderr.write("Tag, %s, renamed to %s\n" \ - % (old, new)) - except: - if _debug: - sys.stderr.write("Unable to rename %s tag to %s in pinboard.in\n" \ - % (old, new)) - -if __name__ == "__main__": - if sys.argv[1:][0] == '-v' or sys.argv[1:][0] == '--version': - print __version__ - -#REVISION HISTORY -## leaving as legacy for now, this should probably removed now for pinboard.in -#0.1 - 29/3/2005 - PEM - Initial version. -#0.2 - 30/3/2005 - PEM - Now using urllib's urlencode to handle query building -# and the class now extends dict (or failing that: UserDict). -#0.3 - 30/3/2005 - PEM - Rewrote doc strings and improved the metaphor that the -# account is a dictionary by adding posts, tags and dates to the account -# object when they are called. This has the added benefit of reducing -# requests to delicious as one need only call posts(), dates() and tags() -# once and they are stored inside the class instance until deletion. -#0.4 - 30/3/2005 - PEM - Added private __request method to handle URL requests -# to del.icio.us and implemented throttle detection. -#0.5 - 30/3/2005 - PEM - Now implements every part of the API specification -#0.6 - 30/3/2005 - PEM - Heavily vetted code to conform with PEP 8: use of -# isinstance(), use of `if var` and `if not var` instead of comparison to -# empty strings and changed all string delimiters to double primes for -# consistency. -#0.7 - 31/3/2005 - PEM - Made it so that when a fetching operation such as -# posts() or tags() is used, only new posts are added to the class dictionary -# in part to increase efficiency and to prevent, say, an all posts call of -# posts() being overwritten by a specific request such as posts(tag="ruby") -# Added more intelligent date handling for adding posts; will now attempt to -# format any *reasonable* string, tuple or list into an ISO8601 date. Also -# changed the command to get the lastupdate as it was convoluted. The -# all posts command now checks to see if del.icio.us has been updated since -# it was last called, again, this is to reduce the load on the servers and -# increase speed a little. Changed the version string to a pre-1.0 release -# Subversion-generated one because I am lazy. -#0.8 - 1/4/2005 - PEM - Improved intelligence of posts caching: will only -# re-download all posts if the posts attribute has been changed. Added -# the mandatory delay between requests of at least one second. Changed the -# crude string replace method to encode ampersands with a more intelligent -# regular expression. -#0.9 - 2/4/2005 - PEM - Now uses datetime objects when possible. -#0.10 - 4/4/2005 - PEM - Uses the time module when the datetime module is -# unavailable (such as versions of Python prior to 2.3). Now uses time -# tuples instead of datetime objects when outputting for compatibility and -# consistency. Time tuples are a new attribute: "date_parsed", with the -# original string format of the date (or datetime) in "date" etc. Now stores -# the headers of each request. diff --git a/app/lib/utils/strutils.py b/app/lib/utils/strutils.py deleted file mode 100644 index 368d3d8..0000000 --- a/app/lib/utils/strutils.py +++ /dev/null @@ -1,50 +0,0 @@ - -# -# String/unicode conversion utils. -# - -def safestr(s): - """ - Safely corerce *anything* to a string. If the object can't be str'd, an - empty string will be returned. - - You can (and I do) use this for really crappy unicode handling, but it's - a bit like killing a mosquito with a bazooka. - """ - if s is None: - return "" - if isinstance(s, unicode): - return s.encode('ascii', 'xmlcharrefreplace') - else: - try: - return str(s) - except: - return "" - -def safeint(s): - """Like safestr(), but always returns an int. Returns 0 on failure.""" - try: - return int(safestr(s)) - except ValueError: - return 0 - - -def convertentity(m): - import htmlentitydefs - """Convert a HTML entity into normal string (ISO-8859-1)""" - if m.group(1)=='#': - try: - return chr(int(m.group(2))) - except ValueError: - return '&#%s;' % m.group(2) - try: - return htmlentitydefs.entitydefs[m.group(2)] - except KeyError: - return '&%s;' % m.group(2) - -def unquotehtml(s): - import re - """Convert a HTML quoted string into normal string (ISO-8859-1). - - Works with &#XX; and with   > etc.""" - return re.sub(r'&(#?)(.+?);',convertentity,s) diff --git a/app/links/sync_links.py b/app/links/sync_links.py new file mode 100644 index 0000000..cd1373d --- /dev/null +++ b/app/links/sync_links.py @@ -0,0 +1,13 @@ +import sys, os +from os.path import dirname, abspath +PROJECT_ROOT = abspath(dirname(dirname(dirname(__file__))))+'/' +#PROJECT_ROOT = abspath(dirname(dirname(__file__))) +print PROJECT_ROOT +sys.path.append(PROJECT_ROOT) +sys.path.append(PROJECT_ROOT+'/app') +sys.path.append(PROJECT_ROOT+'/app/lib') +sys.path.append(PROJECT_ROOT+'/config') +sys.path.append('/home/luxagraf/apps/venv/bin/python2.7/') +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.settings' +from links import retriever +retriever.sync_pinboard_links() diff --git a/app/photos/sync_photo_sets.py b/app/photos/sync_photo_sets.py new file mode 100644 index 0000000..beac435 --- /dev/null +++ b/app/photos/sync_photo_sets.py @@ -0,0 +1,13 @@ +import sys, os +from os.path import dirname, abspath +PROJECT_ROOT = abspath(dirname(dirname(dirname(__file__))))+'/' +#PROJECT_ROOT = abspath(dirname(dirname(__file__))) +print PROJECT_ROOT +sys.path.append(PROJECT_ROOT) +sys.path.append(PROJECT_ROOT+'/app') +sys.path.append(PROJECT_ROOT+'/app/lib') +sys.path.append(PROJECT_ROOT+'/config') +sys.path.append('/home/luxagraf/apps/venv/bin/python2.7/') +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.settings' +from photos import retriever +retriever.sync_sets() diff --git a/app/photos/sync_photos.py b/app/photos/sync_photos.py new file mode 100644 index 0000000..634a2fc --- /dev/null +++ b/app/photos/sync_photos.py @@ -0,0 +1,12 @@ +import sys, os +from os.path import dirname, abspath +PROJECT_ROOT = abspath(dirname(dirname(dirname(__file__))))+'/' +#PROJECT_ROOT = abspath(dirname(dirname(__file__))) +sys.path.append(PROJECT_ROOT) +sys.path.append(PROJECT_ROOT+'/app') +sys.path.append(PROJECT_ROOT+'/app/lib') +sys.path.append(PROJECT_ROOT+'/config') +sys.path.append('/home/luxagraf/apps/venv/bin/python2.7/') +os.environ['DJANGO_SETTINGS_MODULE'] = 'settings.settings' +from photos import retriever +retriever.sync_flickr_photos() diff --git a/design/templates/archives/writing_date.html b/design/templates/archives/writing_date.html new file mode 100644 index 0000000..103d9df --- /dev/null +++ b/design/templates/archives/writing_date.html @@ -0,0 +1,26 @@ +{% extends 'base.html' %} +{% load typogrify_tags %} +{% load html5_datetime %} +{% block pagetitle %}{{block.super}}: Archive{% endblock %} +{% block bodyid %}id="archive"{%endblock%} +{% block primary %} +

How did you get here? You URL chopping maniac you. Right on.

+ +

{% if type == 'year' %}{{date}}, on luxagraf{%else%} Archive: {{date}} {% endif %}

{% if type == 'year' %} +
    {% regroup object_list by pub_date.month as entries_by_month %}{% for entries in entries_by_month %} +
  • {{ entries.list.0.pub_date|date:"F Y" }} + +
  • {% endfor %} +
{% else %} + + {% endif %} +{% endblock%} diff --git a/design/templates/comments/base.html b/design/templates/comments/base.html new file mode 100644 index 0000000..d4382ce --- /dev/null +++ b/design/templates/comments/base.html @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% block headtitle %}{% block title %}{% trans "Responses for page" %}{% endblock %}{% endblock %} + +{% block main %} +
+ {% block content %}{% endblock %} +
+{% endblock %} diff --git a/design/templates/comments/comment.html b/design/templates/comments/comment.html new file mode 100644 index 0000000..475775d --- /dev/null +++ b/design/templates/comments/comment.html @@ -0,0 +1,32 @@ +{% comment %} + Something that django.contrib.comments does not provide: + An individual template for a single comment, to easily be reused. + + This include is also used by the Ajax comments view. + The div id should be "c{id}", because the comment.get_absolute_url() points to it. + + NOTE: to override the displayed date format, don't replace this template. + Instead, define DATETIME_FORMAT in a locale file. Requires setting: + + FORMAT_MODULE_PATH = 'settings.locale' + + Then create 'settings/locale/XY/formats.py' with: + + DATETIME_FORMAT = '...' + + This should give you consistent dates across all views. +{% endcomment %} +{% load i18n %} +
+ {% if preview %}

{% trans "Preview of your comment" %}

{% endif %} +
+ {% if comment.url %}{%if comment.url == "http://lux.me/"%}{%else%}{% endif %}{% endif %} + {% if comment.name %}{{ comment.name }}{% else %}{% trans "Anonymous" %}{% endif %}{% comment %} + {% endcomment %}{% if comment.url %}{% endif %} + {% if not comment.is_public %}({% trans "moderated" %}){% endif %} + {% if USE_THREADEDCOMMENTS and not preview %}{% trans "reply" %}{% endif %} +
+ + +
{{ comment.comment|linebreaks }}
+
diff --git a/design/templates/comments/comment_notification_email.txt b/design/templates/comments/comment_notification_email.txt new file mode 100644 index 0000000..9dfb821 --- /dev/null +++ b/design/templates/comments/comment_notification_email.txt @@ -0,0 +1,20 @@ +{% load url from future %}{% autoescape off %}{% comment %} +{% endcomment %}A new comment has been posted on your site "{{ site }}, to the page entitled "{{ content_object }}". +Link to the page: http://{{ site.domain }}{{ content_object.get_absolute_url }} + +IP-address: 95.97.240.121{% if comment.title %} +Title: {{ comment.title }}{% endif %} +Name: {{ comment.user_name|default:comment.user }} +Email: {{ comment.user_email }} +Homepage: {{ comment.user_url }} +Moderated: {{ comment.is_public|yesno:'no,yes' }} + +Comment: +{{ comment.comment }} + +---- +You have the following options available: + View comment -- http://{{ site.domain }}{{ comment.get_absolute_url }} + Flag comment -- http://{{ site.domain }}{% url 'comments-flag' comment.pk %} + Delete comment -- http://{{ site.domain }}{% url 'comments-delete' comment.pk %} +{% endautoescape %} \ No newline at end of file diff --git a/design/templates/comments/deleted.html b/design/templates/comments/deleted.html new file mode 100644 index 0000000..c62a1ff --- /dev/null +++ b/design/templates/comments/deleted.html @@ -0,0 +1,21 @@ +{% extends "comments/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Thanks for removing" %}.{% endblock %} + +{% block extrahead %} + {{ block.super }} + +{% endblock %} + +{% block content %} +

{% trans "Thanks for removing the comment" %}

+

+ {% blocktrans %} + Thanks for taking the time to improve the quality of discussion on our site.
+ You will be sent back to the article... + {% endblocktrans %} +

+ +

{% trans "Back to the article" %}

+{% endblock %} diff --git a/design/templates/comments/flagged.html b/design/templates/comments/flagged.html new file mode 100644 index 0000000..bebc151 --- /dev/null +++ b/design/templates/comments/flagged.html @@ -0,0 +1,21 @@ +{% extends "comments/base.html" %} +{% load i18n %} + +{% block title %}{% trans "Thanks for flagging" %}.{% endblock %} + +{% block extrahead %} + {{ block.super }} + +{% endblock %} + +{% block content %} +

{% trans "Thanks for flagging the comment" %}

+

+ {% blocktrans %} + Thanks for taking the time to improve the quality of discussion on our site.
+ You will be sent back to the article... + {% endblocktrans %} +

+ +

{% trans "Back to the article" %}

+{% endblock %} diff --git a/design/templates/comments/form.html b/design/templates/comments/form.html new file mode 100644 index 0000000..f8bb18d --- /dev/null +++ b/design/templates/comments/form.html @@ -0,0 +1,18 @@ +{% load comments i18n crispy_forms_tags fluent_comments_tags %}{% load url from future %} + +{% if not form.target_object|comments_are_open %} +

{% trans "Comments are closed." %}

+{% else %} +
{% csrf_token %} + {% if next %}
{% endif %} + + {{ form|crispy }} + +
+ + + {% ajax_comment_tags %} +
+
+{% endif %} \ No newline at end of file diff --git a/design/templates/comments/list.html b/design/templates/comments/list.html new file mode 100644 index 0000000..c105279 --- /dev/null +++ b/design/templates/comments/list.html @@ -0,0 +1,14 @@ +{% comment %} + + Since we support both flat comments, and threadedcomments, + the 'fluent_comments_list' templatetag loads the proper template. + + It either loads: + - fluent_comments/templatetags/flat_html.html + - fluent_comments/templatetags/threaded_list.html + + Both reuse comments/comment.html eventually. + To style comments, consider overwriting that template. + +{% endcomment %} +{% load fluent_comments_tags %}{% fluent_comments_list %} diff --git a/design/templates/comments/posted.html b/design/templates/comments/posted.html new file mode 100644 index 0000000..e13288d --- /dev/null +++ b/design/templates/comments/posted.html @@ -0,0 +1,25 @@ +{% extends "comments/base.html" %}{% load i18n %} + +{% block title %}{% trans "Thanks for commenting" %}{% endblock %} + +{% block extrahead %} +{{ block.super }} + +{% endblock %} + +{% block content %} +

{% trans "Thanks for posting your comment" %}

+

+ {% blocktrans %} + We have received your comment, and posted it on the web site.
+ You will be sent back to the article... + {% endblocktrans %} +

+ + {# Use identical formatting to normal comment list #} +
+ {% include "comments/comment.html" %} +
+ +

{% trans "Back to the article" %}

+{% endblock %} diff --git a/design/templates/comments/preview.html b/design/templates/comments/preview.html new file mode 100644 index 0000000..663b5ca --- /dev/null +++ b/design/templates/comments/preview.html @@ -0,0 +1,30 @@ +{% extends "comments/base.html" %}{% load i18n crispy_forms_tags comments %} + +{% block title %}{% trans "Preview your comment" %}{% endblock %} + +{% block content %} +
{% csrf_token %} + {% if next %}
{% endif %} + + {% if form.errors %} +

{% blocktrans count form.errors|length as counter %}Please correct the error below{% plural %}Please correct the errors below{% endblocktrans %}

+ {% else %} +

{% trans "Preview of your comment" %}

+ +
{{ comment|linebreaks }}
+ +
+ +
+ +

{% trans "Or make changes" %}:

+ {% endif %} + + {{ form|crispy }} + +
+ + +
+
+{% endblock %} -- cgit v1.2.3-70-g09d2