easy_install kind of works
This commit is contained in:
parent
53b95d7c80
commit
ddb36e59b9
|
@ -6,6 +6,7 @@ run
|
||||||
*.wsgi
|
*.wsgi
|
||||||
nbproject
|
nbproject
|
||||||
settings_local.py
|
settings_local.py
|
||||||
|
settings.py
|
||||||
.idea
|
.idea
|
||||||
*.iml
|
*.iml
|
||||||
env
|
env
|
||||||
|
@ -17,3 +18,6 @@ load
|
||||||
askbot/skins/default/media/js/flot
|
askbot/skins/default/media/js/flot
|
||||||
askbot/skins/common/media/js/closure/google-closure
|
askbot/skins/common/media/js/closure/google-closure
|
||||||
askbot/fixtures
|
askbot/fixtures
|
||||||
|
*.egg
|
||||||
|
dist
|
||||||
|
*.egg-info
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
include ez_setup.py
|
||||||
|
recursive-include askbot *
|
||||||
|
recursive-exclude askbot *.pyc
|
||||||
|
recursive-exclude .git
|
||||||
|
prune dist
|
7
README
7
README
|
@ -1,9 +1,10 @@
|
||||||
This is Askbot project - open source Q&A system
|
This is Askbot project - open source Q&A system, like StackOverflow, Yahoo Answers and some others
|
||||||
|
|
||||||
Demo site is http://askbot.org
|
Demo site is http://askbot.org
|
||||||
|
|
||||||
All documentation is in the directory forum/doc
|
All documentation is in the directory askbot/doc
|
||||||
|
|
||||||
askbot-devel repository is open to anyone who wants to help develop Askbot - just drop us a note
|
askbot-devel repository is open to anyone who wants to help develop Askbot - just drop us a note
|
||||||
|
|
||||||
Askbot is based on code of CNPROG, originally created by Mike Chen and Sailing Cai and some code written for OSQA
|
Askbot is based on code of CNPROG, originally created by Mike Chen
|
||||||
|
and Sailing Cai and some code written for OSQA
|
||||||
|
|
|
@ -39,7 +39,7 @@ from askbot.conf import settings as askbot_settings
|
||||||
import types
|
import types
|
||||||
import re
|
import re
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from recaptcha_django import ReCaptchaField
|
from askbot.deps.recaptcha_django import ReCaptchaField
|
||||||
from askbot.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
|
from askbot.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
|
||||||
EXTERNAL_LOGIN_APP = settings.LOAD_EXTERNAL_LOGIN_APP()
|
EXTERNAL_LOGIN_APP = settings.LOAD_EXTERNAL_LOGIN_APP()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 38
|
||||||
|
/svn/!svn/ver/6/trunk/recaptcha_django
|
||||||
|
END
|
||||||
|
middleware.py
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 52
|
||||||
|
/svn/!svn/ver/2/trunk/recaptcha_django/middleware.py
|
||||||
|
END
|
||||||
|
__init__.py
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 50
|
||||||
|
/svn/!svn/ver/6/trunk/recaptcha_django/__init__.py
|
||||||
|
END
|
|
@ -0,0 +1,52 @@
|
||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
6
|
||||||
|
http://recaptcha-django.googlecode.com/svn/trunk/recaptcha_django
|
||||||
|
http://recaptcha-django.googlecode.com/svn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2009-12-12T22:16:04.511967Z
|
||||||
|
6
|
||||||
|
xdissent
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
af963488-c9ea-11dd-a8b6-f5aca7b582bb
|
||||||
|
|
||||||
|
middleware.py
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-06-13T21:04:19.000000Z
|
||||||
|
3cf99bc9362dde824315288bfbfadb1a
|
||||||
|
2008-12-14T15:07:18.967792Z
|
||||||
|
2
|
||||||
|
xdissent
|
||||||
|
|
||||||
|
__init__.py
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-06-13T21:04:19.000000Z
|
||||||
|
a0c7720be84083264fcdfbf35f031062
|
||||||
|
2009-12-12T22:16:04.511967Z
|
||||||
|
6
|
||||||
|
xdissent
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
8
|
|
@ -0,0 +1,76 @@
|
||||||
|
"""
|
||||||
|
recaptcha-django
|
||||||
|
|
||||||
|
ReCAPTCHA (Completely Automated Public Turing test to tell Computers and
|
||||||
|
Humans Apart - while helping digitize books, newspapers, and old time radio
|
||||||
|
shows) module for django
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.forms import Widget, Field, ValidationError
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils.translation import get_language, ugettext_lazy as _
|
||||||
|
from django.utils.html import conditional_escape
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
from recaptcha.client import captcha
|
||||||
|
|
||||||
|
|
||||||
|
HUMAN_ERRORS = {
|
||||||
|
'unknown': _(u'Unknown error.'),
|
||||||
|
'invalid-site-public-key': _(u'ReCAPTCHA is wrongly configured.'),
|
||||||
|
'invalid-site-private-key': _(u'ReCAPTCHA is wrongly configured.'),
|
||||||
|
'invalid-request-cookie': _(u'Bad reCAPTCHA challenge parameter.'),
|
||||||
|
'incorrect-captcha-sol': _(u'The CAPTCHA solution was incorrect.'),
|
||||||
|
'verify-params-incorrect': _(u'Bad reCAPTCHA verification parameters.'),
|
||||||
|
'invalid-referrer': _(u'Provided reCAPTCHA API keys are not valid for this domain.'),
|
||||||
|
'recaptcha-not-reachable': _(u'ReCAPTCHA could not be reached.')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ReCaptchaWidget(Widget):
|
||||||
|
"""
|
||||||
|
A Widget that renders a ReCAPTCHA form
|
||||||
|
"""
|
||||||
|
options = ['theme', 'lang', 'custom_theme_widget', 'tabindex']
|
||||||
|
|
||||||
|
def render(self, name, value, attrs=None):
|
||||||
|
final_attrs = self.build_attrs(attrs)
|
||||||
|
error = final_attrs.get('error', None)
|
||||||
|
html = captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY, error=error)
|
||||||
|
options = u',\n'.join([u'%s: "%s"' % (k, conditional_escape(v)) \
|
||||||
|
for k, v in final_attrs.items() if k in self.options])
|
||||||
|
return mark_safe(u"""<script type="text/javascript">
|
||||||
|
var RecaptchaOptions = {
|
||||||
|
%s
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
%s
|
||||||
|
""" % (options, html))
|
||||||
|
|
||||||
|
|
||||||
|
def value_from_datadict(self, data, files, name):
|
||||||
|
"""
|
||||||
|
Generates Widget value from data dictionary.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return {'challenge': data['recaptcha_challenge_field'],
|
||||||
|
'response': data['recaptcha_response_field'],
|
||||||
|
'ip': data['recaptcha_ip_field']}
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
class ReCaptchaField(Field):
|
||||||
|
"""
|
||||||
|
Field definition for a ReCAPTCHA
|
||||||
|
"""
|
||||||
|
widget = ReCaptchaWidget
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
if value is None:
|
||||||
|
raise ValidationError(_('Invalid request'))
|
||||||
|
resp = captcha.submit(value.get('challenge', None),
|
||||||
|
value.get('response', None),
|
||||||
|
settings.RECAPTCHA_PRIVATE_KEY,
|
||||||
|
value.get('ip', None))
|
||||||
|
if not resp.is_valid:
|
||||||
|
self.widget.attrs['error'] = resp.error_code
|
||||||
|
raise ValidationError(HUMAN_ERRORS.get(resp.error_code, _(u'Unknown error.')))
|
|
@ -0,0 +1,12 @@
|
||||||
|
class ReCaptchaMiddleware(object):
|
||||||
|
"""
|
||||||
|
A tiny middleware to automatically add IP address to ReCaptcha
|
||||||
|
POST requests
|
||||||
|
"""
|
||||||
|
def process_request(self, request):
|
||||||
|
if request.method == 'POST' and \
|
||||||
|
'recaptcha_challenge_field' in request.POST and \
|
||||||
|
'recaptcha_ip_field' not in request.POST:
|
||||||
|
data = request.POST.copy()
|
||||||
|
data['recaptcha_ip_field'] = request.META['REMOTE_ADDR']
|
||||||
|
request.POST = data
|
|
@ -0,0 +1,80 @@
|
||||||
|
"""
|
||||||
|
recaptcha-django
|
||||||
|
|
||||||
|
ReCAPTCHA (Completely Automated Public Turing test to tell Computers and
|
||||||
|
Humans Apart - while helping digitize books, newspapers, and old time radio
|
||||||
|
shows) module for django
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.forms import Widget, Field, ValidationError
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils.translation import get_language, ugettext_lazy as _
|
||||||
|
from django.utils.html import conditional_escape
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
from recaptcha.client import captcha
|
||||||
|
from askbot.conf import settings as askbot_settings
|
||||||
|
|
||||||
|
|
||||||
|
HUMAN_ERRORS = {
|
||||||
|
'unknown': _(u'Unknown error.'),
|
||||||
|
'invalid-site-public-key': _(u'ReCAPTCHA is wrongly configured.'),
|
||||||
|
'invalid-site-private-key': _(u'ReCAPTCHA is wrongly configured.'),
|
||||||
|
'invalid-request-cookie': _(u'Bad reCAPTCHA challenge parameter.'),
|
||||||
|
'incorrect-captcha-sol': _(u'The CAPTCHA solution was incorrect.'),
|
||||||
|
'verify-params-incorrect': _(u'Bad reCAPTCHA verification parameters.'),
|
||||||
|
'invalid-referrer': _(u'Provided reCAPTCHA API keys are not valid for this domain.'),
|
||||||
|
'recaptcha-not-reachable': _(u'ReCAPTCHA could not be reached.')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ReCaptchaWidget(Widget):
|
||||||
|
"""
|
||||||
|
A Widget that renders a ReCAPTCHA form
|
||||||
|
"""
|
||||||
|
options = ['theme', 'lang', 'custom_theme_widget', 'tabindex']
|
||||||
|
|
||||||
|
def render(self, name, value, attrs=None):
|
||||||
|
final_attrs = self.build_attrs(attrs)
|
||||||
|
error = final_attrs.get('error', None)
|
||||||
|
html = captcha.displayhtml(
|
||||||
|
askbot_settings.RECAPTCHA_PUBLIC_KEY,
|
||||||
|
error=error
|
||||||
|
)
|
||||||
|
options = u',\n'.join([u'%s: "%s"' % (k, conditional_escape(v)) \
|
||||||
|
for k, v in final_attrs.items() if k in self.options])
|
||||||
|
return mark_safe(u"""<script type="text/javascript">
|
||||||
|
var RecaptchaOptions = {
|
||||||
|
%s
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
%s
|
||||||
|
""" % (options, html))
|
||||||
|
|
||||||
|
|
||||||
|
def value_from_datadict(self, data, files, name):
|
||||||
|
"""
|
||||||
|
Generates Widget value from data dictionary.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return {'challenge': data['recaptcha_challenge_field'],
|
||||||
|
'response': data['recaptcha_response_field'],
|
||||||
|
'ip': data['recaptcha_ip_field']}
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
class ReCaptchaField(Field):
|
||||||
|
"""
|
||||||
|
Field definition for a ReCAPTCHA
|
||||||
|
"""
|
||||||
|
widget = ReCaptchaWidget
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
if value is None:
|
||||||
|
raise ValidationError(_('Invalid request'))
|
||||||
|
resp = captcha.submit(value.get('challenge', None),
|
||||||
|
value.get('response', None),
|
||||||
|
askbot_settings.RECAPTCHA_PRIVATE_KEY,
|
||||||
|
value.get('ip', None))
|
||||||
|
if not resp.is_valid:
|
||||||
|
self.widget.attrs['error'] = resp.error_code
|
||||||
|
raise ValidationError(HUMAN_ERRORS.get(resp.error_code, _(u'Unknown error.')))
|
|
@ -0,0 +1,11 @@
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 26
|
||||||
|
/svn/!svn/ver/2/trunk/docs
|
||||||
|
END
|
||||||
|
overview.txt
|
||||||
|
K 25
|
||||||
|
svn:wc:ra_dav:version-url
|
||||||
|
V 39
|
||||||
|
/svn/!svn/ver/2/trunk/docs/overview.txt
|
||||||
|
END
|
|
@ -0,0 +1,40 @@
|
||||||
|
8
|
||||||
|
|
||||||
|
dir
|
||||||
|
6
|
||||||
|
http://recaptcha-django.googlecode.com/svn/trunk/docs
|
||||||
|
http://recaptcha-django.googlecode.com/svn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2008-12-14T15:07:18.967792Z
|
||||||
|
2
|
||||||
|
xdissent
|
||||||
|
|
||||||
|
|
||||||
|
svn:special svn:externals svn:needs-lock
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
af963488-c9ea-11dd-a8b6-f5aca7b582bb
|
||||||
|
|
||||||
|
overview.txt
|
||||||
|
file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2010-06-13T21:04:19.000000Z
|
||||||
|
c99e6eadb3fe754f0fdfd181b80ffbe4
|
||||||
|
2008-12-14T15:07:18.967792Z
|
||||||
|
2
|
||||||
|
xdissent
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
8
|
|
@ -0,0 +1 @@
|
||||||
|
TODO: add docs
|
|
@ -0,0 +1 @@
|
||||||
|
TODO: add docs
|
|
@ -0,0 +1,12 @@
|
||||||
|
class ReCaptchaMiddleware(object):
|
||||||
|
"""
|
||||||
|
A tiny middleware to automatically add IP address to ReCaptcha
|
||||||
|
POST requests
|
||||||
|
"""
|
||||||
|
def process_request(self, request):
|
||||||
|
if request.method == 'POST' and \
|
||||||
|
'recaptcha_challenge_field' in request.POST and \
|
||||||
|
'recaptcha_ip_field' not in request.POST:
|
||||||
|
data = request.POST.copy()
|
||||||
|
data['recaptcha_ip_field'] = request.META['REMOTE_ADDR']
|
||||||
|
request.POST = data
|
|
@ -7,7 +7,7 @@ from django.utils.translation import ungettext
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from askbot.utils.forms import NextUrlField, UserNameField
|
from askbot.utils.forms import NextUrlField, UserNameField
|
||||||
from recaptcha_django import ReCaptchaField
|
from askbot.deps.recaptcha_django import ReCaptchaField
|
||||||
from askbot.conf import settings as askbot_settings
|
from askbot.conf import settings as askbot_settings
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
#todo: this file is currently not in use
|
|
||||||
import os
|
|
||||||
from askbot.deps.livesettings import ConfigurationGroup, IntegerValue, config_register
|
|
||||||
|
|
||||||
INSTALLED_APPS = ['askbot']
|
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = [
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware',
|
|
||||||
'askbot.middleware.pagesize.QuestionsPageSizeMiddleware',
|
|
||||||
'askbot.middleware.cancel.CancelActionMiddleware',
|
|
||||||
'django.middleware.transaction.TransactionMiddleware',
|
|
||||||
]
|
|
||||||
|
|
||||||
TEMPLATE_LOADERS = [
|
|
||||||
'django.template.loaders.filesystem.load_template_source',
|
|
||||||
'django.template.loaders.app_directories.load_template_source',
|
|
||||||
'askbot.modules.module_templates_loader',
|
|
||||||
'askbot.skins.load_template_source',
|
|
||||||
]
|
|
||||||
|
|
||||||
TEMPLATE_CONTEXT_PROCESSORS = [
|
|
||||||
'django.core.context_processors.request',
|
|
||||||
'askbot.context.application_settings',
|
|
||||||
'askbot.user_messages.context_processors.user_messages',
|
|
||||||
'django.core.context_processors.auth',
|
|
||||||
]
|
|
||||||
|
|
||||||
TEMPLATE_DIRS = [
|
|
||||||
os.path.join(os.path.dirname(__file__),'skins').replace('\\','/'),
|
|
||||||
]
|
|
||||||
|
|
||||||
def setup_django_settings(settings):
|
|
||||||
|
|
||||||
if (hasattr(settings, 'DEBUG') and getattr(settings, 'DEBUG')):
|
|
||||||
try:
|
|
||||||
import debug_toolbar
|
|
||||||
INSTALLED_APPS.append('debug_toolbar')
|
|
||||||
MIDDLEWARE_CLASSES.append('debug_toolbar.middleware.DebugToolbarMiddleware')
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
settings.INSTALLED_APPS = set(settings.INSTALLED_APPS) | set(INSTALLED_APPS)
|
|
||||||
settings.MIDDLEWARE_CLASSES = set(settings.MIDDLEWARE_CLASSES) | set(MIDDLEWARE_CLASSES)
|
|
||||||
settings.TEMPLATE_LOADERS = set(settings.TEMPLATE_LOADERS) | set(TEMPLATE_LOADERS)
|
|
||||||
settings.TEMPLATE_CONTEXT_PROCESSORS = set(settings.TEMPLATE_CONTEXT_PROCESSORS) | set(TEMPLATE_CONTEXT_PROCESSORS)
|
|
||||||
settings.TEMPLATE_DIRS = set(settings.TEMPLATE_DIRS) | set(TEMPLATE_DIRS)
|
|
||||||
|
|
||||||
|
|
||||||
class AskbotConfigGroup(ConfigurationGroup):
|
|
||||||
def __init__(self, key, name, *arg, **kwarg):
|
|
||||||
super(AskbotConfigGroup, self).__init__(key, name, *arg,**kwarg)
|
|
||||||
self.item_count = 0
|
|
||||||
def new_int_setting(self, key, value, description):
|
|
||||||
self.item_count += 1
|
|
||||||
setting = config_register(IntegerValue(
|
|
||||||
self,
|
|
||||||
key,
|
|
||||||
default=value,
|
|
||||||
description=description,
|
|
||||||
ordering=self.item_count
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return setting
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
# Django settings for ASKBOT enabled project.
|
||||||
|
import os.path
|
||||||
|
import logging
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
INTERNAL_IPS = ('127.0.0.1',)
|
||||||
|
|
||||||
|
ADMINS = (
|
||||||
|
('Your Name', 'your_email@domain.com'),
|
||||||
|
)
|
||||||
|
|
||||||
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
|
DATABASE_ENGINE = 'mysql' # only mysql is supported, more will be in the near future
|
||||||
|
DATABASE_NAME = 'junk' # Or path to database file if using sqlite3.
|
||||||
|
DATABASE_USER = 'junk' # Not used with sqlite3.
|
||||||
|
DATABASE_PASSWORD = 'secret' # Not used with sqlite3.
|
||||||
|
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
|
||||||
|
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||||
|
|
||||||
|
#mail server settings
|
||||||
|
SERVER_EMAIL = ''
|
||||||
|
DEFAULT_FROM_EMAIL = ''
|
||||||
|
EMAIL_HOST_USER = ''
|
||||||
|
EMAIL_HOST_PASSWORD = ''
|
||||||
|
EMAIL_SUBJECT_PREFIX = '[ASKBOT] '
|
||||||
|
EMAIL_HOST='askbot.org'
|
||||||
|
EMAIL_PORT='25'
|
||||||
|
EMAIL_USE_TLS=False
|
||||||
|
|
||||||
|
# Local time zone for this installation. Choices can be found here:
|
||||||
|
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||||
|
# although not all choices may be available on all operating systems.
|
||||||
|
# On Unix systems, a value of None will cause Django to use the same
|
||||||
|
# timezone as the operating system.
|
||||||
|
# If running in a Windows environment this must be set to the same as your
|
||||||
|
# system time zone.
|
||||||
|
TIME_ZONE = 'America/Chicago'
|
||||||
|
|
||||||
|
# Language code for this installation. All choices can be found here:
|
||||||
|
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
SITE_ID = 1
|
||||||
|
|
||||||
|
# If you set this to False, Django will make some optimizations so as not
|
||||||
|
# to load the internationalization machinery.
|
||||||
|
USE_I18N = True
|
||||||
|
LANGUAGE_CODE = 'en'
|
||||||
|
|
||||||
|
# Absolute path to the directory that holds media.
|
||||||
|
# Example: "/home/media/media.lawrence.com/"
|
||||||
|
MEDIA_ROOT = ''
|
||||||
|
|
||||||
|
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||||
|
# trailing slash if there is a path component (optional in other cases).
|
||||||
|
# Examples: "http://media.lawrence.com", "http://example.com/media/"
|
||||||
|
MEDIA_URL = ''
|
||||||
|
|
||||||
|
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||||
|
# trailing slash.
|
||||||
|
# Examples: "http://foo.com/media/", "/media/".
|
||||||
|
ADMIN_MEDIA_PREFIX = '/admin/media/'
|
||||||
|
|
||||||
|
# Make up some unique string, and don't share it with anybody.
|
||||||
|
SECRET_KEY = 'sdljdfjkldsflsdjkhsjkldgjlsdgfs s '
|
||||||
|
|
||||||
|
# List of callables that know how to import templates from various sources.
|
||||||
|
TEMPLATE_LOADERS = (
|
||||||
|
'django.template.loaders.filesystem.load_template_source',
|
||||||
|
'django.template.loaders.app_directories.load_template_source',
|
||||||
|
#below is askbot stuff for this tuple
|
||||||
|
'askbot.skins.loaders.load_template_source',
|
||||||
|
#'django.template.loaders.eggs.load_template_source',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
MIDDLEWARE_CLASSES = (
|
||||||
|
#'django.middleware.gzip.GZipMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
#'django.middleware.locale.LocaleMiddleware',
|
||||||
|
#'django.middleware.cache.UpdateCacheMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
#'django.middleware.cache.FetchFromCacheMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
#'django.middleware.sqlprint.SqlPrintingMiddleware',
|
||||||
|
|
||||||
|
#below is askbot stuff for this tuple
|
||||||
|
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware',
|
||||||
|
'askbot.middleware.pagesize.QuestionsPageSizeMiddleware',
|
||||||
|
'askbot.middleware.cancel.CancelActionMiddleware',
|
||||||
|
#'askbot.deps.recaptcha_django.middleware.ReCaptchaMiddleware',
|
||||||
|
'django.middleware.transaction.TransactionMiddleware',
|
||||||
|
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||||
|
'askbot.middleware.view_log.ViewLogMiddleware',
|
||||||
|
'askbot.middleware.spaceless.SpacelessMiddleware',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
ROOT_URLCONF = os.path.basename(os.path.dirname(__file__)) + '.urls'
|
||||||
|
|
||||||
|
|
||||||
|
#UPLOAD SETTINGS
|
||||||
|
FILE_UPLOAD_TEMP_DIR = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'tmp'
|
||||||
|
).replace('\\','/')
|
||||||
|
|
||||||
|
FILE_UPLOAD_HANDLERS = (
|
||||||
|
'django.core.files.uploadhandler.MemoryFileUploadHandler',
|
||||||
|
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
|
||||||
|
)
|
||||||
|
ALLOW_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
|
||||||
|
ALLOW_MAX_FILE_SIZE = 1024 * 1024 #result in bytes
|
||||||
|
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||||
|
|
||||||
|
|
||||||
|
TEMPLATE_DIRS = (
|
||||||
|
#specific to askbot
|
||||||
|
os.path.join(os.path.dirname(__file__),'askbot','skins').replace('\\','/'),
|
||||||
|
)
|
||||||
|
|
||||||
|
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||||
|
'django.core.context_processors.request',
|
||||||
|
'askbot.context.application_settings',
|
||||||
|
#'django.core.context_processors.i18n',
|
||||||
|
'askbot.user_messages.context_processors.user_messages',#must be before auth
|
||||||
|
'django.core.context_processors.auth', #this is required for admin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
INSTALLED_APPS = (
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.sites',
|
||||||
|
|
||||||
|
#all of these are needed for the askbot
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.humanize',
|
||||||
|
'django.contrib.sitemaps',
|
||||||
|
'debug_toolbar',
|
||||||
|
'askbot',
|
||||||
|
'askbot.deps.django_authopenid',
|
||||||
|
#'askbot.importers.stackexchange', #se loader
|
||||||
|
'south',
|
||||||
|
'askbot.deps.livesettings',
|
||||||
|
'keyedcache',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#setup memcached for production use!
|
||||||
|
#see http://docs.djangoproject.com/en/1.1/topics/cache/ for details
|
||||||
|
CACHE_BACKEND = 'locmem://'
|
||||||
|
#If you use memcache you may want to uncomment the following line to enable memcached based sessions
|
||||||
|
#SESSION_ENGINE = 'django.contrib.sessions.backends.cache_db'
|
||||||
|
|
||||||
|
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
||||||
|
|
||||||
|
#this needs to go
|
||||||
|
USE_EXTERNAL_LEGACY_LOGIN = False #DO NOT USE, and do not delete this line, will be removed later
|
||||||
|
if 'USE_EXTERNAL_LEGACY_LOGIN' in locals() and USE_EXTERNAL_LEGACY_LOGIN:
|
||||||
|
INSTALLED_APPS += (EXTERNAL_LEGACY_LOGIN_MODULE,)
|
||||||
|
|
||||||
|
if 'EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_BACKEND' in locals():
|
||||||
|
AUTHENTICATION_BACKENDS += (EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_BACKEND,)
|
||||||
|
if 'EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_MIDDLEWARE' in locals():
|
||||||
|
MIDDLEWARE_CLASSES += (EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_MIDDLEWARE,)
|
||||||
|
def LOAD_EXTERNAL_LOGIN_APP():
|
||||||
|
return __import__(EXTERNAL_LEGACY_LOGIN_MODULE, [], [], ['api','forms','views'])
|
||||||
|
else:
|
||||||
|
LOAD_EXTERNAL_LOGIN_APP = lambda: None
|
||||||
|
|
||||||
|
|
||||||
|
#logging settings
|
||||||
|
LOG_FILENAME = 'askbot.log'
|
||||||
|
logging.basicConfig(
|
||||||
|
filename=os.path.join(os.path.dirname(__file__), 'log', LOG_FILENAME),
|
||||||
|
level=logging.DEBUG,
|
||||||
|
format='%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
|
||||||
|
)
|
||||||
|
|
||||||
|
###########################
|
||||||
|
#
|
||||||
|
# this will allow running your forum with url like http://site.com/forum
|
||||||
|
#
|
||||||
|
# FORUM_SCRIPT_ALIAS = 'forum/'
|
||||||
|
#
|
||||||
|
FORUM_SCRIPT_ALIAS = '' #no leading slash, default = '' empty string
|
||||||
|
_ = lambda v:v #fake translation function for the login url
|
||||||
|
LOGIN_URL = '/%s%s%s' % (FORUM_SCRIPT_ALIAS,_('account/'),_('signin/'))
|
|
@ -11,7 +11,7 @@ urlpatterns = patterns('',
|
||||||
(r'^%s' % settings.FORUM_SCRIPT_ALIAS, include('askbot.urls')),
|
(r'^%s' % settings.FORUM_SCRIPT_ALIAS, include('askbot.urls')),
|
||||||
(r'^admin/', include(admin.site.urls)),
|
(r'^admin/', include(admin.site.urls)),
|
||||||
(r'^cache/', include('keyedcache.urls')),
|
(r'^cache/', include('keyedcache.urls')),
|
||||||
(r'^settings/', include('livesettings.urls')),
|
(r'^settings/', include('askbot.deps.livesettings.urls')),
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'rosetta' in settings.INSTALLED_APPS:
|
if 'rosetta' in settings.INSTALLED_APPS:
|
|
@ -1,9 +0,0 @@
|
||||||
This directory contains source javascript files
|
|
||||||
written with Google Closure library
|
|
||||||
|
|
||||||
* to start developing with closure here, run (Unix shell) script
|
|
||||||
setup-closure.sh (if your environment does not like the script
|
|
||||||
please take a look what's inside and replicate it for your system)
|
|
||||||
* please don't commit closure sources to our repo
|
|
||||||
i.e. add this line to .gitignore
|
|
||||||
forum/skins/common/media/js/closure/google-closure
|
|
|
@ -1,12 +0,0 @@
|
||||||
svn checkout http://closure-library.googlecode.com/svn/trunk/ google-closure
|
|
||||||
mkdir google-closure/tools
|
|
||||||
mkdir google-closure/tools/compiler
|
|
||||||
cd google-closure/tools/compiler
|
|
||||||
wget http://closure-compiler.googlecode.com/files/compiler-latest.zip
|
|
||||||
unzip compiler-latest.zip
|
|
||||||
cd ../../..
|
|
||||||
mkdir google-closure/tools/soy
|
|
||||||
cd google-closure/tools/soy
|
|
||||||
wget http://closure-templates.googlecode.com/files/closure-templates-for-javascript-latest.zip
|
|
||||||
unzip closure-templates-for-javascript-latest.zip
|
|
||||||
cd ../../
|
|
|
@ -692,7 +692,7 @@ blockquote {
|
||||||
|
|
||||||
.boxC {
|
.boxC {
|
||||||
background: white /*#cacdc6; /*f9f7ed;*/
|
background: white /*#cacdc6; /*f9f7ed;*/
|
||||||
padding: 10px;
|
padding: 10px 10px 10px 15px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
/*
|
/*
|
||||||
border-top: 1px solid #eeeeec;
|
border-top: 1px solid #eeeeec;
|
||||||
|
@ -832,7 +832,7 @@ conflicts with WMD!
|
||||||
|
|
||||||
.tags a {
|
.tags a {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 10px;
|
font-size: 11px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: #333;
|
color: #333;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -2658,3 +2658,7 @@ p.signup_p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img.gravatar {
|
||||||
|
margin:2px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
from django.template.loaders import filesystem
|
from django.template.loaders import filesystem
|
||||||
import os.path
|
import os.path
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
@ -12,14 +12,21 @@ from askbot.conf import settings as askbot_settings
|
||||||
#note - Django template loaders use method django.utils._os.safe_join
|
#note - Django template loaders use method django.utils._os.safe_join
|
||||||
#to work on unicode file paths
|
#to work on unicode file paths
|
||||||
#here it is ignored because it is assumed that we won't use unicode paths
|
#here it is ignored because it is assumed that we won't use unicode paths
|
||||||
|
ASKBOT_SKIN_COLLECTION_DIR = os.path.dirname(__file__)
|
||||||
|
|
||||||
def load_template_source(name, dirs=None):
|
def load_template_source(name, dirs=None):
|
||||||
|
if dirs is None:
|
||||||
|
dirs = (ASKBOT_SKIN_COLLECTION_DIR, )
|
||||||
|
else:
|
||||||
|
dirs += (ASKBOT_SKIN_COLLECTION_DIR, )
|
||||||
|
|
||||||
try:
|
try:
|
||||||
#todo: move this to top after splitting out get_skin_dirs()
|
#todo: move this to top after splitting out get_skin_dirs()
|
||||||
tname = os.path.join(askbot_settings.ASKBOT_DEFAULT_SKIN,'templates',name)
|
tname = os.path.join(askbot_settings.ASKBOT_DEFAULT_SKIN,'templates',name)
|
||||||
return filesystem.load_template_source(tname,dirs)
|
return filesystem.load_template_source(tname,dirs)
|
||||||
except:
|
except:
|
||||||
tname = os.path.join('default','templates',name)
|
tname = os.path.join('default','templates',name)
|
||||||
|
print tname
|
||||||
return filesystem.load_template_source(tname,dirs)
|
return filesystem.load_template_source(tname,dirs)
|
||||||
load_template_source.is_usable = True
|
load_template_source.is_usable = True
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,284 @@
|
||||||
|
#!python
|
||||||
|
"""Bootstrap setuptools installation
|
||||||
|
|
||||||
|
If you want to use setuptools in your package's setup.py, just include this
|
||||||
|
file in the same directory with it, and add this to the top of your setup.py::
|
||||||
|
|
||||||
|
from ez_setup import use_setuptools
|
||||||
|
use_setuptools()
|
||||||
|
|
||||||
|
If you want to require a specific version of setuptools, set a download
|
||||||
|
mirror, or use an alternate download directory, you can do so by supplying
|
||||||
|
the appropriate options to ``use_setuptools()``.
|
||||||
|
|
||||||
|
This file can also be run as a script to install or upgrade setuptools.
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
DEFAULT_VERSION = "0.6c11"
|
||||||
|
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
|
||||||
|
|
||||||
|
md5_data = {
|
||||||
|
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
|
||||||
|
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
|
||||||
|
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
|
||||||
|
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
|
||||||
|
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
|
||||||
|
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
|
||||||
|
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
|
||||||
|
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
|
||||||
|
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
|
||||||
|
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
|
||||||
|
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
|
||||||
|
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
|
||||||
|
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
|
||||||
|
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
|
||||||
|
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
|
||||||
|
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
|
||||||
|
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
|
||||||
|
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
|
||||||
|
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
|
||||||
|
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
|
||||||
|
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
|
||||||
|
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
|
||||||
|
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
|
||||||
|
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
|
||||||
|
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
|
||||||
|
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
|
||||||
|
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
|
||||||
|
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
|
||||||
|
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
|
||||||
|
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
|
||||||
|
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
|
||||||
|
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
|
||||||
|
'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
|
||||||
|
'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
|
||||||
|
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
|
||||||
|
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
|
||||||
|
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
|
||||||
|
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
|
||||||
|
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
|
||||||
|
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
|
||||||
|
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
|
||||||
|
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
|
||||||
|
}
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
try: from hashlib import md5
|
||||||
|
except ImportError: from md5 import md5
|
||||||
|
|
||||||
|
def _validate_md5(egg_name, data):
|
||||||
|
if egg_name in md5_data:
|
||||||
|
digest = md5(data).hexdigest()
|
||||||
|
if digest != md5_data[egg_name]:
|
||||||
|
print >>sys.stderr, (
|
||||||
|
"md5 validation of %s failed! (Possible download problem?)"
|
||||||
|
% egg_name
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def use_setuptools(
|
||||||
|
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||||
|
download_delay=15
|
||||||
|
):
|
||||||
|
"""Automatically find/download setuptools and make it available on sys.path
|
||||||
|
|
||||||
|
`version` should be a valid setuptools version number that is available
|
||||||
|
as an egg for download under the `download_base` URL (which should end with
|
||||||
|
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
|
||||||
|
it is not already available. If `download_delay` is specified, it should
|
||||||
|
be the number of seconds that will be paused before initiating a download,
|
||||||
|
should one be required. If an older version of setuptools is installed,
|
||||||
|
this routine will print a message to ``sys.stderr`` and raise SystemExit in
|
||||||
|
an attempt to abort the calling script.
|
||||||
|
"""
|
||||||
|
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
|
||||||
|
def do_download():
|
||||||
|
egg = download_setuptools(version, download_base, to_dir, download_delay)
|
||||||
|
sys.path.insert(0, egg)
|
||||||
|
import setuptools; setuptools.bootstrap_install_from = egg
|
||||||
|
try:
|
||||||
|
import pkg_resources
|
||||||
|
except ImportError:
|
||||||
|
return do_download()
|
||||||
|
try:
|
||||||
|
pkg_resources.require("setuptools>="+version); return
|
||||||
|
except pkg_resources.VersionConflict, e:
|
||||||
|
if was_imported:
|
||||||
|
print >>sys.stderr, (
|
||||||
|
"The required version of setuptools (>=%s) is not available, and\n"
|
||||||
|
"can't be installed while this script is running. Please install\n"
|
||||||
|
" a more recent version first, using 'easy_install -U setuptools'."
|
||||||
|
"\n\n(Currently using %r)"
|
||||||
|
) % (version, e.args[0])
|
||||||
|
sys.exit(2)
|
||||||
|
else:
|
||||||
|
del pkg_resources, sys.modules['pkg_resources'] # reload ok
|
||||||
|
return do_download()
|
||||||
|
except pkg_resources.DistributionNotFound:
|
||||||
|
return do_download()
|
||||||
|
|
||||||
|
def download_setuptools(
|
||||||
|
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
|
||||||
|
delay = 15
|
||||||
|
):
|
||||||
|
"""Download setuptools from a specified location and return its filename
|
||||||
|
|
||||||
|
`version` should be a valid setuptools version number that is available
|
||||||
|
as an egg for download under the `download_base` URL (which should end
|
||||||
|
with a '/'). `to_dir` is the directory where the egg will be downloaded.
|
||||||
|
`delay` is the number of seconds to pause before an actual download attempt.
|
||||||
|
"""
|
||||||
|
import urllib2, shutil
|
||||||
|
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
|
||||||
|
url = download_base + egg_name
|
||||||
|
saveto = os.path.join(to_dir, egg_name)
|
||||||
|
src = dst = None
|
||||||
|
if not os.path.exists(saveto): # Avoid repeated downloads
|
||||||
|
try:
|
||||||
|
from distutils import log
|
||||||
|
if delay:
|
||||||
|
log.warn("""
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
This script requires setuptools version %s to run (even to display
|
||||||
|
help). I will attempt to download it for you (from
|
||||||
|
%s), but
|
||||||
|
you may need to enable firewall access for this script first.
|
||||||
|
I will start the download in %d seconds.
|
||||||
|
|
||||||
|
(Note: if this machine does not have network access, please obtain the file
|
||||||
|
|
||||||
|
%s
|
||||||
|
|
||||||
|
and place it in this directory before rerunning this script.)
|
||||||
|
---------------------------------------------------------------------------""",
|
||||||
|
version, download_base, delay, url
|
||||||
|
); from time import sleep; sleep(delay)
|
||||||
|
log.warn("Downloading %s", url)
|
||||||
|
src = urllib2.urlopen(url)
|
||||||
|
# Read/write all in one block, so we don't create a corrupt file
|
||||||
|
# if the download is interrupted.
|
||||||
|
data = _validate_md5(egg_name, src.read())
|
||||||
|
dst = open(saveto,"wb"); dst.write(data)
|
||||||
|
finally:
|
||||||
|
if src: src.close()
|
||||||
|
if dst: dst.close()
|
||||||
|
return os.path.realpath(saveto)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv, version=DEFAULT_VERSION):
|
||||||
|
"""Install or upgrade setuptools and EasyInstall"""
|
||||||
|
try:
|
||||||
|
import setuptools
|
||||||
|
except ImportError:
|
||||||
|
egg = None
|
||||||
|
try:
|
||||||
|
egg = download_setuptools(version, delay=0)
|
||||||
|
sys.path.insert(0,egg)
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
return main(list(argv)+[egg]) # we're done here
|
||||||
|
finally:
|
||||||
|
if egg and os.path.exists(egg):
|
||||||
|
os.unlink(egg)
|
||||||
|
else:
|
||||||
|
if setuptools.__version__ == '0.0.1':
|
||||||
|
print >>sys.stderr, (
|
||||||
|
"You have an obsolete version of setuptools installed. Please\n"
|
||||||
|
"remove it from your system entirely before rerunning this script."
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
req = "setuptools>="+version
|
||||||
|
import pkg_resources
|
||||||
|
try:
|
||||||
|
pkg_resources.require(req)
|
||||||
|
except pkg_resources.VersionConflict:
|
||||||
|
try:
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
except ImportError:
|
||||||
|
from easy_install import main
|
||||||
|
main(list(argv)+[download_setuptools(delay=0)])
|
||||||
|
sys.exit(0) # try to force an exit
|
||||||
|
else:
|
||||||
|
if argv:
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
main(argv)
|
||||||
|
else:
|
||||||
|
print "Setuptools version",version,"or greater has been installed."
|
||||||
|
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
|
||||||
|
|
||||||
|
def update_md5(filenames):
|
||||||
|
"""Update our built-in md5 registry"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
for name in filenames:
|
||||||
|
base = os.path.basename(name)
|
||||||
|
f = open(name,'rb')
|
||||||
|
md5_data[base] = md5(f.read()).hexdigest()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
data = [" %r: %r,\n" % it for it in md5_data.items()]
|
||||||
|
data.sort()
|
||||||
|
repl = "".join(data)
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
srcfile = inspect.getsourcefile(sys.modules[__name__])
|
||||||
|
f = open(srcfile, 'rb'); src = f.read(); f.close()
|
||||||
|
|
||||||
|
match = re.search("\nmd5_data = {\n([^}]+)}", src)
|
||||||
|
if not match:
|
||||||
|
print >>sys.stderr, "Internal error!"
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
src = src[:match.start(1)] + repl + src[match.end(1):]
|
||||||
|
f = open(srcfile,'w')
|
||||||
|
f.write(src)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
|
||||||
|
update_md5(sys.argv[2:])
|
||||||
|
else:
|
||||||
|
main(sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,329 +0,0 @@
|
||||||
"""A full cache system written on top of Django's rudimentary one."""
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.cache import cache
|
|
||||||
from django.utils.encoding import smart_str
|
|
||||||
from django.utils.hashcompat import md5_constructor
|
|
||||||
from keyedcache.utils import is_string_like, is_list_or_tuple
|
|
||||||
import cPickle as pickle
|
|
||||||
import logging
|
|
||||||
import types
|
|
||||||
|
|
||||||
log = logging.getLogger('keyedcache')
|
|
||||||
|
|
||||||
CACHED_KEYS = {}
|
|
||||||
CACHE_CALLS = 0
|
|
||||||
CACHE_HITS = 0
|
|
||||||
KEY_DELIM = "::"
|
|
||||||
REQUEST_CACHE = {'enabled' : False}
|
|
||||||
try:
|
|
||||||
CACHE_PREFIX = settings.CACHE_PREFIX
|
|
||||||
except AttributeError:
|
|
||||||
CACHE_PREFIX = str(settings.SITE_ID)
|
|
||||||
log.warn("No CACHE_PREFIX found in settings, using SITE_ID. Please update your settings to add a CACHE_PREFIX")
|
|
||||||
|
|
||||||
try:
|
|
||||||
CACHE_TIMEOUT = settings.CACHE_TIMEOUT
|
|
||||||
except AttributeError:
|
|
||||||
CACHE_TIMEOUT = 0
|
|
||||||
log.warn("No CACHE_TIMEOUT found in settings, so we used 0, disabling the cache system. Please update your settings to add a CACHE_TIMEOUT and avoid this warning.")
|
|
||||||
|
|
||||||
_CACHE_ENABLED = CACHE_TIMEOUT > 0
|
|
||||||
|
|
||||||
class CacheWrapper(object):
|
|
||||||
def __init__(self, val, inprocess=False):
|
|
||||||
self.val = val
|
|
||||||
self.inprocess = inprocess
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.val)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return repr(self.val)
|
|
||||||
|
|
||||||
def wrap(cls, obj):
|
|
||||||
if isinstance(obj, cls):
|
|
||||||
return obj
|
|
||||||
else:
|
|
||||||
return cls(obj)
|
|
||||||
|
|
||||||
wrap = classmethod(wrap)
|
|
||||||
|
|
||||||
class MethodNotFinishedError(Exception):
|
|
||||||
def __init__(self, f):
|
|
||||||
self.func = f
|
|
||||||
|
|
||||||
|
|
||||||
class NotCachedError(Exception):
|
|
||||||
def __init__(self, k):
|
|
||||||
self.key = k
|
|
||||||
|
|
||||||
class CacheNotRespondingError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def cache_delete(*keys, **kwargs):
|
|
||||||
removed = []
|
|
||||||
if cache_enabled():
|
|
||||||
global CACHED_KEYS
|
|
||||||
log.debug('cache_delete')
|
|
||||||
children = kwargs.pop('children',False)
|
|
||||||
|
|
||||||
if (keys or kwargs):
|
|
||||||
key = cache_key(*keys, **kwargs)
|
|
||||||
|
|
||||||
if CACHED_KEYS.has_key(key):
|
|
||||||
del CACHED_KEYS[key]
|
|
||||||
removed.append(key)
|
|
||||||
|
|
||||||
cache.delete(key)
|
|
||||||
|
|
||||||
if children:
|
|
||||||
key = key + KEY_DELIM
|
|
||||||
children = [x for x in CACHED_KEYS.keys() if x.startswith(key)]
|
|
||||||
for k in children:
|
|
||||||
del CACHED_KEYS[k]
|
|
||||||
cache.delete(k)
|
|
||||||
removed.append(k)
|
|
||||||
else:
|
|
||||||
key = "All Keys"
|
|
||||||
deleteneeded = _cache_flush_all()
|
|
||||||
|
|
||||||
removed = CACHED_KEYS.keys()
|
|
||||||
|
|
||||||
if deleteneeded:
|
|
||||||
for k in CACHED_KEYS:
|
|
||||||
cache.delete(k)
|
|
||||||
|
|
||||||
CACHED_KEYS = {}
|
|
||||||
|
|
||||||
if removed:
|
|
||||||
log.debug("Cache delete: %s", removed)
|
|
||||||
else:
|
|
||||||
log.debug("No cached objects to delete for %s", key)
|
|
||||||
|
|
||||||
return removed
|
|
||||||
|
|
||||||
|
|
||||||
def cache_delete_function(func):
|
|
||||||
return cache_delete(['func', func.__name__, func.__module__], children=True)
|
|
||||||
|
|
||||||
def cache_enabled():
|
|
||||||
global _CACHE_ENABLED
|
|
||||||
return _CACHE_ENABLED
|
|
||||||
|
|
||||||
def cache_enable(state=True):
|
|
||||||
global _CACHE_ENABLED
|
|
||||||
_CACHE_ENABLED=state
|
|
||||||
|
|
||||||
def _cache_flush_all():
|
|
||||||
if is_memcached_backend():
|
|
||||||
cache._cache.flush_all()
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def cache_function(length=CACHE_TIMEOUT):
|
|
||||||
"""
|
|
||||||
A variant of the snippet posted by Jeff Wheeler at
|
|
||||||
http://www.djangosnippets.org/snippets/109/
|
|
||||||
|
|
||||||
Caches a function, using the function and its arguments as the key, and the return
|
|
||||||
value as the value saved. It passes all arguments on to the function, as
|
|
||||||
it should.
|
|
||||||
|
|
||||||
The decorator itself takes a length argument, which is the number of
|
|
||||||
seconds the cache will keep the result around.
|
|
||||||
|
|
||||||
It will put a temp value in the cache while the function is
|
|
||||||
processing. This should not matter in most cases, but if the app is using
|
|
||||||
threads, you won't be able to get the previous value, and will need to
|
|
||||||
wait until the function finishes. If this is not desired behavior, you can
|
|
||||||
remove the first two lines after the ``else``.
|
|
||||||
"""
|
|
||||||
def decorator(func):
|
|
||||||
def inner_func(*args, **kwargs):
|
|
||||||
if not cache_enabled():
|
|
||||||
value = func(*args, **kwargs)
|
|
||||||
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
value = cache_get('func', func.__name__, func.__module__, args, kwargs)
|
|
||||||
|
|
||||||
except NotCachedError, e:
|
|
||||||
# This will set a temporary value while ``func`` is being
|
|
||||||
# processed. When using threads, this is vital, as otherwise
|
|
||||||
# the function can be called several times before it finishes
|
|
||||||
# and is put into the cache.
|
|
||||||
funcwrapper = CacheWrapper(".".join([func.__module__, func.__name__]), inprocess=True)
|
|
||||||
cache_set(e.key, value=funcwrapper, length=length, skiplog=True)
|
|
||||||
value = func(*args, **kwargs)
|
|
||||||
cache_set(e.key, value=value, length=length)
|
|
||||||
|
|
||||||
except MethodNotFinishedError, e:
|
|
||||||
value = func(*args, **kwargs)
|
|
||||||
|
|
||||||
return value
|
|
||||||
return inner_func
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def cache_get(*keys, **kwargs):
|
|
||||||
if kwargs.has_key('default'):
|
|
||||||
default_value = kwargs.pop('default')
|
|
||||||
use_default = True
|
|
||||||
else:
|
|
||||||
use_default = False
|
|
||||||
|
|
||||||
key = cache_key(keys, **kwargs)
|
|
||||||
|
|
||||||
if not cache_enabled():
|
|
||||||
raise NotCachedError(key)
|
|
||||||
else:
|
|
||||||
global CACHE_CALLS, CACHE_HITS, REQUEST_CACHE
|
|
||||||
CACHE_CALLS += 1
|
|
||||||
if CACHE_CALLS == 1:
|
|
||||||
cache_require()
|
|
||||||
|
|
||||||
obj = None
|
|
||||||
tid = -1
|
|
||||||
if REQUEST_CACHE['enabled']:
|
|
||||||
tid = cache_get_request_uid()
|
|
||||||
if tid > -1:
|
|
||||||
try:
|
|
||||||
obj = REQUEST_CACHE[tid][key]
|
|
||||||
log.debug('Got from request cache: %s', key)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if obj == None:
|
|
||||||
obj = cache.get(key)
|
|
||||||
|
|
||||||
if obj and isinstance(obj, CacheWrapper):
|
|
||||||
CACHE_HITS += 1
|
|
||||||
CACHED_KEYS[key] = True
|
|
||||||
log.debug('got cached [%i/%i]: %s', CACHE_CALLS, CACHE_HITS, key)
|
|
||||||
if obj.inprocess:
|
|
||||||
raise MethodNotFinishedError(obj.val)
|
|
||||||
|
|
||||||
cache_set_request(key, obj, uid=tid)
|
|
||||||
|
|
||||||
return obj.val
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
del CACHED_KEYS[key]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if use_default:
|
|
||||||
return default_value
|
|
||||||
|
|
||||||
raise NotCachedError(key)
|
|
||||||
|
|
||||||
|
|
||||||
def cache_set(*keys, **kwargs):
|
|
||||||
"""Set an object into the cache."""
|
|
||||||
if cache_enabled():
|
|
||||||
global CACHED_KEYS, REQUEST_CACHE
|
|
||||||
obj = kwargs.pop('value')
|
|
||||||
length = kwargs.pop('length', CACHE_TIMEOUT)
|
|
||||||
skiplog = kwargs.pop('skiplog', False)
|
|
||||||
|
|
||||||
key = cache_key(keys, **kwargs)
|
|
||||||
val = CacheWrapper.wrap(obj)
|
|
||||||
if not skiplog:
|
|
||||||
log.debug('setting cache: %s', key)
|
|
||||||
cache.set(key, val, length)
|
|
||||||
CACHED_KEYS[key] = True
|
|
||||||
if REQUEST_CACHE['enabled']:
|
|
||||||
cache_set_request(key, val)
|
|
||||||
|
|
||||||
def _hash_or_string(key):
|
|
||||||
if is_string_like(key) or isinstance(key, (types.IntType, types.LongType, types.FloatType)):
|
|
||||||
return smart_str(key)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
#if it has a PK, use it.
|
|
||||||
return str(key._get_pk_val())
|
|
||||||
except AttributeError:
|
|
||||||
return md5_hash(key)
|
|
||||||
|
|
||||||
def cache_contains(*keys, **kwargs):
|
|
||||||
key = cache_key(keys, **kwargs)
|
|
||||||
return CACHED_KEYS.has_key(key)
|
|
||||||
|
|
||||||
def cache_key(*keys, **pairs):
|
|
||||||
"""Smart key maker, returns the object itself if a key, else a list
|
|
||||||
delimited by ':', automatically hashing any non-scalar objects."""
|
|
||||||
|
|
||||||
if is_string_like(keys):
|
|
||||||
keys = [keys]
|
|
||||||
|
|
||||||
if is_list_or_tuple(keys):
|
|
||||||
if len(keys) == 1 and is_list_or_tuple(keys[0]):
|
|
||||||
keys = keys[0]
|
|
||||||
else:
|
|
||||||
keys = [md5_hash(keys)]
|
|
||||||
|
|
||||||
if pairs:
|
|
||||||
keys = list(keys)
|
|
||||||
klist = pairs.keys()
|
|
||||||
klist.sort()
|
|
||||||
for k in klist:
|
|
||||||
keys.append(k)
|
|
||||||
keys.append(pairs[k])
|
|
||||||
|
|
||||||
key = KEY_DELIM.join([_hash_or_string(x) for x in keys])
|
|
||||||
prefix = CACHE_PREFIX + KEY_DELIM
|
|
||||||
if not key.startswith(prefix):
|
|
||||||
key = prefix+key
|
|
||||||
return key.replace(" ", ".")
|
|
||||||
|
|
||||||
def md5_hash(obj):
|
|
||||||
pickled = pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL)
|
|
||||||
return md5_constructor(pickled).hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def is_memcached_backend():
|
|
||||||
try:
|
|
||||||
return cache._cache.__module__.endswith('memcache')
|
|
||||||
except AttributeError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def cache_require():
|
|
||||||
"""Error if keyedcache isn't running."""
|
|
||||||
if cache_enabled():
|
|
||||||
key = cache_key('require_cache')
|
|
||||||
cache_set(key,value='1')
|
|
||||||
v = cache_get(key, default = '0')
|
|
||||||
if v != '1':
|
|
||||||
raise CacheNotRespondingError()
|
|
||||||
else:
|
|
||||||
log.debug("Cache responding OK")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def cache_clear_request(uid):
|
|
||||||
"""Clears all locally cached elements with that uid"""
|
|
||||||
global REQUEST_CACHE
|
|
||||||
try:
|
|
||||||
del REQUEST_CACHE[uid]
|
|
||||||
log.debug('cleared request cache: %s', uid)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def cache_use_request_caching():
|
|
||||||
global REQUEST_CACHE
|
|
||||||
REQUEST_CACHE['enabled'] = True
|
|
||||||
|
|
||||||
def cache_get_request_uid():
|
|
||||||
from threaded_multihost import threadlocals
|
|
||||||
return threadlocals.get_thread_variable('request_uid', -1)
|
|
||||||
|
|
||||||
def cache_set_request(key, val, uid=None):
|
|
||||||
if uid == None:
|
|
||||||
uid = cache_get_request_uid()
|
|
||||||
|
|
||||||
if uid>-1:
|
|
||||||
global REQUEST_CACHE
|
|
||||||
if not uid in REQUEST_CACHE:
|
|
||||||
REQUEST_CACHE[uid] = {key:val}
|
|
||||||
else:
|
|
||||||
REQUEST_CACHE[uid][key] = val
|
|
Binary file not shown.
|
@ -1,40 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the Satchmo package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2008-03-22 15:10+0100\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Start"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Cachestatistik"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr ""
|
|
||||||
|
|
Binary file not shown.
|
@ -1,40 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the Satchmo package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2007-12-31 00:49-0600\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr ""
|
|
||||||
|
|
Binary file not shown.
|
@ -1,69 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# Jacques Moulin <jacques@tpi.be>, 2008.
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2008-11-02 16:11+0100\n"
|
|
||||||
"PO-Revision-Date: 2008-11-02 17:51+0100\n"
|
|
||||||
"Last-Translator: Jacques Moulin <jacques@tpi.be>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"X-Poedit-Language: French\n"
|
|
||||||
"X-Poedit-SourceCharset: utf-8\n"
|
|
||||||
|
|
||||||
#: views.py:16
|
|
||||||
msgid "Yes"
|
|
||||||
msgstr "Oui"
|
|
||||||
|
|
||||||
#: views.py:17
|
|
||||||
msgid "No"
|
|
||||||
msgstr "Non"
|
|
||||||
|
|
||||||
#: views.py:21
|
|
||||||
msgid "Key to delete"
|
|
||||||
msgstr "Clé à effacer"
|
|
||||||
|
|
||||||
#: views.py:22
|
|
||||||
msgid "Include Children?"
|
|
||||||
msgstr "Inclure les enfants?"
|
|
||||||
|
|
||||||
#: views.py:23
|
|
||||||
msgid "Delete all keys?"
|
|
||||||
msgstr "Effacer toutes les clés?"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html.py:6
|
|
||||||
#: templates/keyedcache/stats.html.py:6
|
|
||||||
#: templates/keyedcache/view.html.py:6
|
|
||||||
#: templates/keyedcache/delete.html.py:6
|
|
||||||
#: templates/keyedcache/stats.html.py:6
|
|
||||||
#: templates/keyedcache/view.html.py:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Accueil"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html.py:7
|
|
||||||
#: templates/keyedcache/view.html.py:7
|
|
||||||
#: templates/keyedcache/delete.html.py:7
|
|
||||||
#: templates/keyedcache/view.html.py:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html.py:8
|
|
||||||
#: templates/keyedcache/delete.html.py:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Vider le cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html.py:7
|
|
||||||
#: templates/keyedcache/stats.html.py:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Statut du cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html.py:8
|
|
||||||
#: templates/keyedcache/view.html.py:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Voir le cache"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,60 +0,0 @@
|
||||||
# translation of Satchmo
|
|
||||||
# Copyright (C) 2008 The Satchmo Project
|
|
||||||
# This file is distributed under the same license as the Satchmo package.
|
|
||||||
#
|
|
||||||
# Aviv Greenberg <avivgr@gmail.com>, 2008.
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: django\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2009-03-13 23:01+0200\n"
|
|
||||||
"PO-Revision-Date: 2009-03-13 16:04\n"
|
|
||||||
"Last-Translator: Aviv Greenberg <avivgr@gmail.com>\n"
|
|
||||||
"Language-Team: <en@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"X-Generator: KBabel 1.11.4\n"
|
|
||||||
"X-Translated-Using: django-rosetta 0.4.0\n"
|
|
||||||
|
|
||||||
#: views.py:16
|
|
||||||
msgid "Yes"
|
|
||||||
msgstr "כן"
|
|
||||||
|
|
||||||
#: views.py:17
|
|
||||||
msgid "No"
|
|
||||||
msgstr "לא"
|
|
||||||
|
|
||||||
#: views.py:21
|
|
||||||
msgid "Key to delete"
|
|
||||||
msgstr "מפתח שיש למחוק"
|
|
||||||
|
|
||||||
#: views.py:22
|
|
||||||
msgid "Include Children?"
|
|
||||||
msgstr "כלול ילדים?"
|
|
||||||
|
|
||||||
#: views.py:23
|
|
||||||
msgid "Delete all keys?"
|
|
||||||
msgstr "מחק את כל המפתחות?"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6 templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "בית"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7 templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "זכרון מטמון"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "מחק זכרון מטמון"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "סטטיסטיקת זכרון מטמון"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "הצג זכרון מטמון"
|
|
Binary file not shown.
|
@ -1,68 +0,0 @@
|
||||||
# translation of django.po to Italiano
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
#
|
|
||||||
# costantino giuliodori <costantino.giuliodori@gmail.com>, 2007.
|
|
||||||
# Alessandro Ronchi <alessandro.ronchi@soasi.com>, 2008.
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: django\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2008-09-27 09:16-0700\n"
|
|
||||||
"PO-Revision-Date: 2008-09-30 13:13+0200\n"
|
|
||||||
"Last-Translator: Alessandro Ronchi <alessandro.ronchi@soasi.com>\n"
|
|
||||||
"Language-Team: Italiano <it@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"X-Generator: KBabel 1.11.4\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1\n"
|
|
||||||
|
|
||||||
#: views.py:16
|
|
||||||
msgid "Yes"
|
|
||||||
msgstr "Si"
|
|
||||||
|
|
||||||
#: views.py:17
|
|
||||||
msgid "No"
|
|
||||||
msgstr "No"
|
|
||||||
|
|
||||||
#: views.py:21
|
|
||||||
msgid "Key to delete"
|
|
||||||
msgstr "Chiave da eliminare"
|
|
||||||
|
|
||||||
#: views.py:22
|
|
||||||
# translated = "Slug"
|
|
||||||
msgid "Include Children?"
|
|
||||||
msgstr "Includi i figli?"
|
|
||||||
|
|
||||||
#: views.py:23
|
|
||||||
msgid "Delete all keys?"
|
|
||||||
msgstr "Elimina tutte le chiavi?"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Pagina iniziale"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
# translated = "Prodotto sottotipi"
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
# translated = "Cache"
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Elimina Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
# translated = "Elimina cache"
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Statistiche Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
# translated = "Statistiche di cache"
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Viste Cache"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,40 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the Satchmo package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2007-12-31 00:49-0600\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "홈"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "캐쉬"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "캐쉬 삭제"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "캐쉬 상태"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "캐쉬 보기"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,60 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2008-09-03 18:10+0200\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: <jerzyk@jerzyk.com>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: views.py:16
|
|
||||||
msgid "Yes"
|
|
||||||
msgstr "Tak"
|
|
||||||
|
|
||||||
#: views.py:17
|
|
||||||
msgid "No"
|
|
||||||
msgstr "Nie"
|
|
||||||
|
|
||||||
#: views.py:21
|
|
||||||
msgid "Key to delete"
|
|
||||||
msgstr "Identyfikator do usunięcia"
|
|
||||||
|
|
||||||
#: views.py:22
|
|
||||||
msgid "Include Children?"
|
|
||||||
msgstr "Czy razem z dziećmi?"
|
|
||||||
|
|
||||||
#: views.py:23
|
|
||||||
msgid "Delete all keys?"
|
|
||||||
msgstr "Usunąć wszystkie identyfikatory?"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Strona startowa"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Wyczyść pamięć podręczną"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Statystyka pamięci podręcznej"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Podgląd pamięci podręcznej"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,61 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# Terry Laundos Aguiar <terry@s1solucoes.com.br>, 2008.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2008-09-05 23:50-0300\n"
|
|
||||||
"PO-Revision-Date: 2008-09-05 23:51-0300\n"
|
|
||||||
"Last-Translator: Terry Laundos Aguiar <terry@s1solucoes.com.br>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: views.py:16
|
|
||||||
msgid "Yes"
|
|
||||||
msgstr "Sim"
|
|
||||||
|
|
||||||
#: views.py:17
|
|
||||||
msgid "No"
|
|
||||||
msgstr "Não"
|
|
||||||
|
|
||||||
#: views.py:21
|
|
||||||
msgid "Key to delete"
|
|
||||||
msgstr "Chave para apagar"
|
|
||||||
|
|
||||||
#: views.py:22
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Include Children?"
|
|
||||||
msgstr "Incluir imagens?"
|
|
||||||
|
|
||||||
#: views.py:23
|
|
||||||
msgid "Delete all keys?"
|
|
||||||
msgstr "Apagar todas as chaves?"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Inicial"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Apagar cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Estatísticas de cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Exibição de cache"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,40 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the Satchmo package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Satchmo\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2007-12-31 00:49-0600\n"
|
|
||||||
"PO-Revision-Date: 2009-03-02 15:50+0300\n"
|
|
||||||
"Last-Translator: Данил Семеленов <danil.mail@gmail.com>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Language-Team: \n"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Кеш"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Очистка кеша"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Статистика кеша"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Просмотр кеша"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,44 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# N.L. <kotorinl@yahoo.co.uk>, 2008.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Satchmo svn\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2008-04-30 23:40+0200\n"
|
|
||||||
"PO-Revision-Date: 2008-04-30 23:35+0100\n"
|
|
||||||
"Last-Translator: N.L. <kotorinl@yahoo.co.uk>\n"
|
|
||||||
"Language-Team: Group\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"X-Poedit-Language: Swedish\n"
|
|
||||||
"X-Poedit-Basepath: ../../../\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
||||||
"X-Poedit-Country: SWEDEN\n"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Hem"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Radera Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Cache-statistik"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Visa Cache"
|
|
||||||
|
|
Binary file not shown.
|
@ -1,42 +0,0 @@
|
||||||
# Satchmo Translation Package
|
|
||||||
# Copyright (C) 2008 Satchmo Project
|
|
||||||
# This file is distributed under the same license as the Satchmo package.
|
|
||||||
# Selin Çuhadar <selincuhadar@gmail.com>, 2008.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Satchmo\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2007-12-31 00:49-0600\n"
|
|
||||||
"PO-Revision-Date: 2008-06-09 18:18+0200\n"
|
|
||||||
"Last-Translator: Selin Çuhadar <selincuhadar@gmail.com>\n"
|
|
||||||
"Language-Team: Turkish <selincuhadar@gmail.com>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"X-Poedit-Country: TURKEY\n"
|
|
||||||
"X-Poedit-SourceCharset: utf-8\n"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:6
|
|
||||||
#: templates/keyedcache/stats.html:6
|
|
||||||
#: templates/keyedcache/view.html:6
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "Ev"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:7
|
|
||||||
#: templates/keyedcache/view.html:7
|
|
||||||
msgid "Cache"
|
|
||||||
msgstr "Cache"
|
|
||||||
|
|
||||||
#: templates/keyedcache/delete.html:8
|
|
||||||
msgid "Cache Delete"
|
|
||||||
msgstr "Cache'yi Sil"
|
|
||||||
|
|
||||||
#: templates/keyedcache/stats.html:7
|
|
||||||
msgid "Cache Stats"
|
|
||||||
msgstr "Cache İstatistikleri"
|
|
||||||
|
|
||||||
#: templates/keyedcache/view.html:8
|
|
||||||
msgid "Cache View"
|
|
||||||
msgstr "Cache'yi Göster"
|
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
import keyedcache
|
|
||||||
import logging
|
|
||||||
|
|
||||||
log = logging.getLogger('keyedcache')
|
|
||||||
|
|
||||||
class CachedObjectMixin(object):
|
|
||||||
"""Provides basic object keyedcache for any objects using this as a mixin."""
|
|
||||||
|
|
||||||
def cache_delete(self, *args, **kwargs):
|
|
||||||
key = self.cache_key(*args, **kwargs)
|
|
||||||
log.debug("clearing cache for %s", key)
|
|
||||||
keyedcache.cache_delete(key, children=True)
|
|
||||||
|
|
||||||
def cache_get(self, *args, **kwargs):
|
|
||||||
key = self.cache_key(*args, **kwargs)
|
|
||||||
return keyedcache.cache_get(key)
|
|
||||||
|
|
||||||
def cache_key(self, *args, **kwargs):
|
|
||||||
keys = [self.__class__.__name__, self]
|
|
||||||
keys.extend(args)
|
|
||||||
return keyedcache.cache_key(keys, **kwargs)
|
|
||||||
|
|
||||||
def cache_reset(self):
|
|
||||||
self.cache_delete()
|
|
||||||
self.cache_set()
|
|
||||||
|
|
||||||
def cache_set(self, *args, **kwargs):
|
|
||||||
val = kwargs.pop('value', self)
|
|
||||||
key = self.cache_key(*args, **kwargs)
|
|
||||||
keyedcache.cache_set(key, value=val)
|
|
||||||
|
|
||||||
def is_cached(self, *args, **kwargs):
|
|
||||||
return keyedcache.is_cached(self.cache_key(*args, **kwargs))
|
|
||||||
|
|
||||||
def find_by_id(cls, groupkey, objectid, raises=False):
|
|
||||||
"""A helper function to look up an object by id"""
|
|
||||||
ob = None
|
|
||||||
try:
|
|
||||||
ob = keyedcache.cache_get(groupkey, objectid)
|
|
||||||
except keyedcache.NotCachedError, e:
|
|
||||||
try:
|
|
||||||
ob = cls.objects.get(pk=objectid)
|
|
||||||
keyedcache.cache_set(e.key, value=ob)
|
|
||||||
|
|
||||||
except cls.DoesNotExist:
|
|
||||||
log.debug("No such %s: %s", groupkey, objectid)
|
|
||||||
if raises:
|
|
||||||
raise cls.DoesNotExist
|
|
||||||
|
|
||||||
return ob
|
|
||||||
|
|
||||||
|
|
||||||
def find_by_key(cls, groupkey, key, raises=False):
|
|
||||||
"""A helper function to look up an object by key"""
|
|
||||||
ob = None
|
|
||||||
try:
|
|
||||||
ob = keyedcache.cache_get(groupkey, key)
|
|
||||||
except keyedcache.NotCachedError, e:
|
|
||||||
try:
|
|
||||||
ob = cls.objects.get(key__exact=key)
|
|
||||||
keyedcache.cache_set(e.key, value=ob)
|
|
||||||
|
|
||||||
except cls.DoesNotExist:
|
|
||||||
log.debug("No such %s: %s", groupkey, key)
|
|
||||||
if raises:
|
|
||||||
raise
|
|
||||||
|
|
||||||
return ob
|
|
||||||
|
|
||||||
def find_by_slug(cls, groupkey, slug, raises=False):
|
|
||||||
"""A helper function to look up an object by slug"""
|
|
||||||
ob = None
|
|
||||||
try:
|
|
||||||
ob = keyedcache.cache_get(groupkey, slug)
|
|
||||||
except keyedcache.NotCachedError, e:
|
|
||||||
try:
|
|
||||||
ob = cls.objects.get(slug__exact=slug)
|
|
||||||
keyedcache.cache_set(e.key, value=ob)
|
|
||||||
|
|
||||||
except cls.DoesNotExist:
|
|
||||||
log.debug("No such %s: %s", groupkey, slug)
|
|
||||||
if raises:
|
|
||||||
raise
|
|
||||||
|
|
||||||
return ob
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
{% extends "admin/base_site.html" %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block breadcrumbs %}{% if not is_popup %}
|
|
||||||
<div class="breadcrumbs">
|
|
||||||
<a href="/admin/">{% trans "Home" %}</a> ›
|
|
||||||
<a href="{% url keyedcache_view %}">{% trans "Cache" %}</a> ›
|
|
||||||
{% trans "Cache Delete" %}
|
|
||||||
</div>
|
|
||||||
{% endif %}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<p>[<a href="{% url keyedcache_stats %}">Cache Stats</a>] [<a href="{% url keyedcache_view %}">View Cache</a>]</p>
|
|
||||||
<h1>Delete From Cache</h1>
|
|
||||||
<form method="POST" action="{% url keyedcache_delete %}">
|
|
||||||
{{ form.as_p }}
|
|
||||||
<input type="submit"/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
|
@ -1,20 +0,0 @@
|
||||||
{% extends "admin/base_site.html" %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block breadcrumbs %}{% if not is_popup %}
|
|
||||||
<div class="breadcrumbs">
|
|
||||||
<a href="/admin/">{% trans "Home" %}</a> ›
|
|
||||||
{% trans "Cache Stats" %}
|
|
||||||
</div>
|
|
||||||
{% endif %}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<p>[<a href="{% url keyedcache_view %}">View Cache</a>] [<a href="{% url keyedcache_delete %}">Delete from Cache</a>]
|
|
||||||
<h1>Cache Stats</h1>
|
|
||||||
<p>Backend: {{ cache_backend }} ({% if cache_running %}running{% else %}down{% endif %})</p>
|
|
||||||
<p>Timeout: {{ cache_time }}</p>
|
|
||||||
<p>Keys in cache: {{ cache_count }}</p>
|
|
||||||
<p>Cache Calls: {{ cache_calls }}</p>
|
|
||||||
<p>Cache Hits: {{ cache_hits }}</p>
|
|
||||||
<p>Cache Hit Rate: {{ hit_rate }}%</p>
|
|
||||||
{% endblock %}
|
|
|
@ -1,17 +0,0 @@
|
||||||
{% extends "admin/base_site.html" %}
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block breadcrumbs %}{% if not is_popup %}
|
|
||||||
<div class="breadcrumbs">
|
|
||||||
<a href="/admin/">{% trans "Home" %}</a> ›
|
|
||||||
<a href="{% url keyedcache_view %}">{% trans "Cache" %}</a> ›
|
|
||||||
{% trans "Cache View" %}
|
|
||||||
</div>
|
|
||||||
{% endif %}{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<p>[<a href="{% url keyedcache_stats %}">Cache Stats</a>] [<a href="{% url keyedcache_delete %}">Delete from Cache</a>]
|
|
||||||
<h1>Cache Keys</h1>
|
|
||||||
<p style="font-size:82%;">{% for key in cached_keys %}{{ key }}, {% endfor %}
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
|
@ -1,150 +0,0 @@
|
||||||
import keyedcache
|
|
||||||
import random
|
|
||||||
from django.test import TestCase
|
|
||||||
import time
|
|
||||||
|
|
||||||
CACHE_HIT=0
|
|
||||||
|
|
||||||
def cachetest(a,b,c):
|
|
||||||
global CACHE_HIT
|
|
||||||
CACHE_HIT += 1
|
|
||||||
r = [random.randrange(0,1000) for x in range(0,3)]
|
|
||||||
ret = [r, a + r[0], b + r[1], c + r[2]]
|
|
||||||
return ret
|
|
||||||
|
|
||||||
cachetest = keyedcache.cache_function(2)(cachetest)
|
|
||||||
|
|
||||||
class DecoratorTest(TestCase):
|
|
||||||
|
|
||||||
def testCachePut(self):
|
|
||||||
d = cachetest(1,2,3)
|
|
||||||
self.assertEqual(CACHE_HIT,1)
|
|
||||||
|
|
||||||
d2 = cachetest(1,2,3)
|
|
||||||
self.assertEqual(CACHE_HIT,1)
|
|
||||||
self.assertEqual(d, d2)
|
|
||||||
|
|
||||||
seeds = d[0]
|
|
||||||
self.assertEqual(seeds[0] + 1, d[1])
|
|
||||||
self.assertEqual(seeds[1] + 2, d[2])
|
|
||||||
self.assertEqual(seeds[2] + 3, d[3])
|
|
||||||
|
|
||||||
time.sleep(3)
|
|
||||||
d3 = cachetest(1,2,3)
|
|
||||||
self.assertEqual(CACHE_HIT,2)
|
|
||||||
self.assertNotEqual(d, d3)
|
|
||||||
|
|
||||||
def testDeleteCachedFunction(self):
|
|
||||||
orig = cachetest(10,20,30)
|
|
||||||
keyedcache.cache_delete_function(cachetest)
|
|
||||||
after = cachetest(10,20,30)
|
|
||||||
self.assertNotEqual(orig,keyedcache)
|
|
||||||
|
|
||||||
class CachingTest(TestCase):
|
|
||||||
|
|
||||||
def testCacheGetFail(self):
|
|
||||||
try:
|
|
||||||
keyedcache.cache_get('x')
|
|
||||||
self.fail('should have raised NotCachedError')
|
|
||||||
except keyedcache.NotCachedError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def testCacheGetOK(self):
|
|
||||||
one = [1,2,3,4]
|
|
||||||
keyedcache.cache_set('ok', value=one, length=2)
|
|
||||||
two = keyedcache.cache_get('ok')
|
|
||||||
self.assertEqual(one, two)
|
|
||||||
|
|
||||||
time.sleep(5)
|
|
||||||
try:
|
|
||||||
three = keyedcache.cache_get('ok')
|
|
||||||
self.fail('should have raised NotCachedError, got %s' % three)
|
|
||||||
except keyedcache.NotCachedError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def testCacheGetDefault(self):
|
|
||||||
chk = keyedcache.cache_get('default',default='-')
|
|
||||||
self.assertEqual(chk, '-')
|
|
||||||
|
|
||||||
|
|
||||||
def testDelete(self):
|
|
||||||
keyedcache.cache_set('del', value=True)
|
|
||||||
|
|
||||||
for x in range(0,10):
|
|
||||||
keyedcache.cache_set('del', 'x', x, value=True)
|
|
||||||
for y in range(0,5):
|
|
||||||
keyedcache.cache_set('del', 'x', x, 'y', y, value=True)
|
|
||||||
|
|
||||||
# check to make sure all the values are in the cache
|
|
||||||
self.assert_(keyedcache.cache_get('del', default=False))
|
|
||||||
for x in range(0,10):
|
|
||||||
self.assert_(keyedcache.cache_get('del', 'x', x, default=False))
|
|
||||||
for y in range(0,5):
|
|
||||||
self.assert_(keyedcache.cache_get('del', 'x', x, 'y', y, default=False))
|
|
||||||
|
|
||||||
# try to delete just one
|
|
||||||
killed = keyedcache.cache_delete('del','x',1)
|
|
||||||
self.assertEqual([keyedcache.CACHE_PREFIX + "::del::x::1"], killed)
|
|
||||||
self.assertFalse(keyedcache.cache_get('del', 'x', 1, default=False))
|
|
||||||
|
|
||||||
# but the others are still there
|
|
||||||
self.assert_(keyedcache.cache_get('del', 'x', 2, default=False))
|
|
||||||
|
|
||||||
# now kill all of del::x::1
|
|
||||||
killed = keyedcache.cache_delete('del','x', 1, children=True)
|
|
||||||
for y in range(0,5):
|
|
||||||
self.assertFalse(keyedcache.cache_get('del', 'x', 1, 'y', y, default=False))
|
|
||||||
|
|
||||||
# but del::x::2 and children are there
|
|
||||||
self.assert_(keyedcache.cache_get('del','x',2,'y',1, default=False))
|
|
||||||
|
|
||||||
# kill the rest
|
|
||||||
killed = keyedcache.cache_delete('del', children=True)
|
|
||||||
self.assertFalse(keyedcache.cache_get('del',default=False))
|
|
||||||
for x in range(0,10):
|
|
||||||
self.assertFalse(keyedcache.cache_get('del', 'x', x, default=False))
|
|
||||||
for y in range(0,5):
|
|
||||||
self.assertFalse(keyedcache.cache_get('del', 'x', x, 'y', y, default=False))
|
|
||||||
|
|
||||||
|
|
||||||
class TestCacheDisable(TestCase):
|
|
||||||
|
|
||||||
def testDisable(self):
|
|
||||||
keyedcache.cache_set('disabled', value=False)
|
|
||||||
v = keyedcache.cache_get('disabled')
|
|
||||||
self.assertEqual(v, False)
|
|
||||||
|
|
||||||
keyedcache.cache_enable(False)
|
|
||||||
keyedcache.cache_set('disabled', value=True)
|
|
||||||
try:
|
|
||||||
keyedcache.cache_get('disabled')
|
|
||||||
self.fail('should have raised NotCachedError')
|
|
||||||
except keyedcache.NotCachedError, nce:
|
|
||||||
key = keyedcache.cache_key('disabled')
|
|
||||||
self.assertEqual(nce.key, key)
|
|
||||||
|
|
||||||
keyedcache.cache_enable()
|
|
||||||
v2 = keyedcache.cache_get('disabled')
|
|
||||||
# should still be False, since the cache was disabled
|
|
||||||
self.assertEqual(v2, False)
|
|
||||||
|
|
||||||
class TestKeyMaker(TestCase):
|
|
||||||
|
|
||||||
def testSimpleKey(self):
|
|
||||||
v = keyedcache.cache_key('test')
|
|
||||||
self.assertEqual(v, keyedcache.CACHE_PREFIX + '::test')
|
|
||||||
|
|
||||||
def testDualKey(self):
|
|
||||||
v = keyedcache.cache_key('test', 2)
|
|
||||||
self.assertEqual(v, keyedcache.CACHE_PREFIX + '::test::2')
|
|
||||||
|
|
||||||
def testPairedKey(self):
|
|
||||||
v = keyedcache.cache_key('test', more='yes')
|
|
||||||
self.assertEqual(v, keyedcache.CACHE_PREFIX + '::test::more::yes')
|
|
||||||
|
|
||||||
def testPairedDualKey(self):
|
|
||||||
v = keyedcache.cache_key('test', 3, more='yes')
|
|
||||||
self.assertEqual(v, keyedcache.CACHE_PREFIX + '::test::3::more::yes')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
"""Causes the keyedcache to also use a first-level cache in memory - this can cut 30-40% of memcached calls.
|
|
||||||
|
|
||||||
To enable, add this to some models.py file in an app::
|
|
||||||
|
|
||||||
from keyedcache import threaded
|
|
||||||
threaded.start_listening()
|
|
||||||
|
|
||||||
"""
|
|
||||||
from threaded_multihost import threadlocals
|
|
||||||
from django.core.signals import request_started, request_finished
|
|
||||||
from keyedcache import cache_clear_request, cache_use_request_caching
|
|
||||||
import random
|
|
||||||
import logging
|
|
||||||
log = logging.getLogger('keyedcache.threaded')
|
|
||||||
|
|
||||||
def set_request_uid(sender, *args, **kwargs):
|
|
||||||
"""Puts a unique id into the thread"""
|
|
||||||
tid = random.randrange(1,10000000)
|
|
||||||
threadlocals.set_thread_variable('request_uid', tid)
|
|
||||||
#log.debug('request UID: %s', tid)
|
|
||||||
|
|
||||||
def clear_request_uid(sender, *args, **kwargs):
|
|
||||||
"""Removes the thread cache for this request"""
|
|
||||||
tid = threadlocals.get_thread_variable('request_uid', -1)
|
|
||||||
if tid > -1:
|
|
||||||
cache_clear_request(tid)
|
|
||||||
|
|
||||||
def start_listening():
|
|
||||||
log.debug('setting up threaded keyedcache')
|
|
||||||
cache_use_request_caching()
|
|
||||||
request_started.connect(set_request_uid)
|
|
||||||
request_finished.connect(clear_request_uid)
|
|
|
@ -1,10 +0,0 @@
|
||||||
"""
|
|
||||||
URLConf for Caching app
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django.conf.urls.defaults import patterns
|
|
||||||
urlpatterns = patterns('keyedcache.views',
|
|
||||||
(r'^$', 'stats_page', {}, 'keyedcache_stats'),
|
|
||||||
(r'^view/$', 'view_page', {}, 'keyedcache_view'),
|
|
||||||
(r'^delete/$', 'delete_page', {}, 'keyedcache_delete'),
|
|
||||||
)
|
|
|
@ -1,14 +0,0 @@
|
||||||
import types
|
|
||||||
|
|
||||||
def is_string_like(maybe):
|
|
||||||
"""Test value to see if it acts like a string"""
|
|
||||||
try:
|
|
||||||
maybe+""
|
|
||||||
except TypeError:
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
|
|
||||||
def is_list_or_tuple(maybe):
|
|
||||||
return isinstance(maybe, (types.TupleType, types.ListType))
|
|
|
@ -1,103 +0,0 @@
|
||||||
from django import forms
|
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib.auth.decorators import user_passes_test
|
|
||||||
from django.http import HttpResponseRedirect
|
|
||||||
from django.shortcuts import render_to_response
|
|
||||||
from django.template import RequestContext
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
import keyedcache
|
|
||||||
import logging
|
|
||||||
|
|
||||||
log = logging.getLogger('keyedcache.views')
|
|
||||||
|
|
||||||
YN = (
|
|
||||||
('Y', _('Yes')),
|
|
||||||
('N', _('No')),
|
|
||||||
)
|
|
||||||
|
|
||||||
class CacheDeleteForm(forms.Form):
|
|
||||||
tag = forms.CharField(label=_('Key to delete'), required=False)
|
|
||||||
children = forms.ChoiceField(label=_('Include Children?'), choices=YN, initial="Y")
|
|
||||||
kill_all = forms.ChoiceField(label=_('Delete all keys?'), choices=YN, initial="Y")
|
|
||||||
|
|
||||||
def delete_cache(self):
|
|
||||||
|
|
||||||
data = self.cleaned_data
|
|
||||||
if data['kill_all'] == "Y":
|
|
||||||
keyedcache.cache_delete()
|
|
||||||
result = "Deleted all keys"
|
|
||||||
elif data['tag']:
|
|
||||||
keyedcache.cache_delete(data['tag'], children=data['children'])
|
|
||||||
if data['children'] == "Y":
|
|
||||||
result = "Deleted %s and children" % data['tag']
|
|
||||||
else:
|
|
||||||
result = "Deleted %s" % data['tag']
|
|
||||||
else:
|
|
||||||
result = "Nothing selected to delete"
|
|
||||||
|
|
||||||
log.debug(result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def stats_page(request):
|
|
||||||
calls = keyedcache.CACHE_CALLS
|
|
||||||
hits = keyedcache.CACHE_HITS
|
|
||||||
|
|
||||||
if (calls and hits):
|
|
||||||
rate = float(keyedcache.CACHE_HITS)/keyedcache.CACHE_CALLS*100
|
|
||||||
else:
|
|
||||||
rate = 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
running = keyedcache.cache_require()
|
|
||||||
|
|
||||||
except keyedcache.CacheNotRespondingError:
|
|
||||||
running = False
|
|
||||||
|
|
||||||
ctx = RequestContext(request, {
|
|
||||||
'cache_count' : len(keyedcache.CACHED_KEYS),
|
|
||||||
'cache_running' : running,
|
|
||||||
'cache_time' : settings.CACHE_TIMEOUT,
|
|
||||||
'cache_backend' : settings.CACHE_BACKEND,
|
|
||||||
'cache_calls' : keyedcache.CACHE_CALLS,
|
|
||||||
'cache_hits' : keyedcache.CACHE_HITS,
|
|
||||||
'hit_rate' : "%02.1f" % rate
|
|
||||||
})
|
|
||||||
|
|
||||||
return render_to_response('keyedcache/stats.html', context_instance=ctx)
|
|
||||||
|
|
||||||
stats_page = user_passes_test(lambda u: u.is_authenticated() and u.is_staff, login_url='/accounts/login/')(stats_page)
|
|
||||||
|
|
||||||
def view_page(request):
|
|
||||||
keys = keyedcache.CACHED_KEYS.keys()
|
|
||||||
|
|
||||||
keys.sort()
|
|
||||||
|
|
||||||
ctx = RequestContext(request, {
|
|
||||||
'cached_keys' : keys,
|
|
||||||
})
|
|
||||||
|
|
||||||
return render_to_response('keyedcache/view.html', context_instance=ctx)
|
|
||||||
|
|
||||||
view_page = user_passes_test(lambda u: u.is_authenticated() and u.is_staff, login_url='/accounts/login/')(view_page)
|
|
||||||
|
|
||||||
def delete_page(request):
|
|
||||||
log.debug("delete_page")
|
|
||||||
if request.method == "POST":
|
|
||||||
form = CacheDeleteForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
log.debug('delete form valid')
|
|
||||||
results = form.delete_cache()
|
|
||||||
return HttpResponseRedirect('../')
|
|
||||||
else:
|
|
||||||
log.debug("Errors in form: %s", form.errors)
|
|
||||||
else:
|
|
||||||
log.debug("new form")
|
|
||||||
form = CacheDeleteForm()
|
|
||||||
|
|
||||||
ctx = RequestContext(request, {
|
|
||||||
'form' : form,
|
|
||||||
})
|
|
||||||
|
|
||||||
return render_to_response('keyedcache/delete.html', context_instance=ctx)
|
|
||||||
|
|
||||||
delete_page = user_passes_test(lambda u: u.is_authenticated() and u.is_staff, login_url='/accounts/login/')(delete_page)
|
|
98
settings.py
98
settings.py
|
@ -1,98 +0,0 @@
|
||||||
# encoding:utf-8
|
|
||||||
# Django settings for lanai project.
|
|
||||||
import os.path
|
|
||||||
import sys
|
|
||||||
|
|
||||||
SITE_ID = 1
|
|
||||||
|
|
||||||
ADMIN_MEDIA_PREFIX = '/admin/media/'
|
|
||||||
SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
|
|
||||||
# List of callables that know how to import templates from various sources.
|
|
||||||
TEMPLATE_LOADERS = (
|
|
||||||
'django.template.loaders.filesystem.load_template_source',
|
|
||||||
'django.template.loaders.app_directories.load_template_source',
|
|
||||||
|
|
||||||
#below is askbot stuff for this tuple
|
|
||||||
'askbot.skins.loaders.load_template_source',#askbot stuff
|
|
||||||
# 'django.template.loaders.eggs.load_template_source',
|
|
||||||
)
|
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = (
|
|
||||||
#'django.middleware.gzip.GZipMiddleware',
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
#'django.middleware.locale.LocaleMiddleware',
|
|
||||||
#'django.middleware.cache.UpdateCacheMiddleware',
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
|
||||||
#'django.middleware.cache.FetchFromCacheMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
#'django.middleware.sqlprint.SqlPrintingMiddleware',
|
|
||||||
|
|
||||||
#below is askbot stuff for this tuple
|
|
||||||
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware',
|
|
||||||
'askbot.middleware.pagesize.QuestionsPageSizeMiddleware',
|
|
||||||
'askbot.middleware.cancel.CancelActionMiddleware',
|
|
||||||
#'recaptcha_django.middleware.ReCaptchaMiddleware',
|
|
||||||
'django.middleware.transaction.TransactionMiddleware',
|
|
||||||
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
|
||||||
'askbot.middleware.view_log.ViewLogMiddleware',
|
|
||||||
'askbot.middleware.spaceless.SpacelessMiddleware',
|
|
||||||
)
|
|
||||||
|
|
||||||
#all of these are necessary for the askbot and absend in default settings.py
|
|
||||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
|
||||||
'django.core.context_processors.request',
|
|
||||||
'askbot.context.application_settings',
|
|
||||||
#'django.core.context_processors.i18n',
|
|
||||||
'askbot.user_messages.context_processors.user_messages',#must be before auth
|
|
||||||
'django.core.context_processors.auth', #this is required for admin
|
|
||||||
)
|
|
||||||
|
|
||||||
ROOT_URLCONF = 'urls'
|
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
|
||||||
#specific to askbot
|
|
||||||
os.path.join(os.path.dirname(__file__),'askbot','skins').replace('\\','/'),
|
|
||||||
)
|
|
||||||
|
|
||||||
#UPLOAD SETTINGS
|
|
||||||
FILE_UPLOAD_TEMP_DIR = os.path.join(os.path.dirname(__file__), 'tmp').replace('\\','/')
|
|
||||||
FILE_UPLOAD_HANDLERS = ("django.core.files.uploadhandler.MemoryFileUploadHandler",
|
|
||||||
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
|
|
||||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
|
||||||
|
|
||||||
# User settings
|
|
||||||
from settings_local import *
|
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
|
||||||
'django.contrib.auth',
|
|
||||||
'django.contrib.contenttypes',
|
|
||||||
'django.contrib.sessions',
|
|
||||||
'django.contrib.sites',
|
|
||||||
|
|
||||||
#all of these are needed for the askbot
|
|
||||||
'django.contrib.admin',
|
|
||||||
'django.contrib.humanize',
|
|
||||||
'django.contrib.sitemaps',
|
|
||||||
'debug_toolbar',
|
|
||||||
'askbot',
|
|
||||||
'askbot.deps.django_authopenid',
|
|
||||||
#'askbot.importers.stackexchange', #se loader
|
|
||||||
'south',
|
|
||||||
'askbot.deps.livesettings',
|
|
||||||
'keyedcache',
|
|
||||||
)
|
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
|
||||||
|
|
||||||
#this needs to go
|
|
||||||
if 'USE_EXTERNAL_LEGACY_LOGIN' in locals() and USE_EXTERNAL_LEGACY_LOGIN:
|
|
||||||
INSTALLED_APPS += (EXTERNAL_LEGACY_LOGIN_MODULE,)
|
|
||||||
|
|
||||||
if 'EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_BACKEND' in locals():
|
|
||||||
AUTHENTICATION_BACKENDS += (EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_BACKEND,)
|
|
||||||
if 'EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_MIDDLEWARE' in locals():
|
|
||||||
MIDDLEWARE_CLASSES += (EXTERNAL_LEGACY_LOGIN_AUTHENTICATION_MIDDLEWARE,)
|
|
||||||
def LOAD_EXTERNAL_LOGIN_APP():
|
|
||||||
return __import__(EXTERNAL_LEGACY_LOGIN_MODULE, [], [], ['api','forms','views'])
|
|
||||||
else:
|
|
||||||
LOAD_EXTERNAL_LOGIN_APP = lambda: None
|
|
|
@ -1,105 +0,0 @@
|
||||||
# encoding:utf-8
|
|
||||||
import os.path
|
|
||||||
from django.utils.translation import ugettext as _
|
|
||||||
|
|
||||||
SITE_SRC_ROOT = os.path.dirname(__file__)
|
|
||||||
LOG_FILENAME = 'askbot.log'
|
|
||||||
|
|
||||||
#for logging
|
|
||||||
import logging
|
|
||||||
logging.basicConfig(
|
|
||||||
filename=os.path.join(SITE_SRC_ROOT, 'log', LOG_FILENAME),
|
|
||||||
level=logging.DEBUG,
|
|
||||||
format='%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
|
|
||||||
)
|
|
||||||
|
|
||||||
#ADMINS and MANAGERS
|
|
||||||
ADMINS = (('Forum Admin', 'forum@example.com'),)
|
|
||||||
MANAGERS = ADMINS
|
|
||||||
|
|
||||||
#DEBUG SETTINGS
|
|
||||||
DEBUG = False
|
|
||||||
TEMPLATE_DEBUG = DEBUG
|
|
||||||
INTERNAL_IPS = ('127.0.0.1',)
|
|
||||||
|
|
||||||
DATABASE_NAME = '' # Or path to database file if using sqlite3.
|
|
||||||
DATABASE_USER = '' # Not used with sqlite3.
|
|
||||||
DATABASE_PASSWORD = '' # Not used with sqlite3.
|
|
||||||
DATABASE_ENGINE = '' #mysql, etc
|
|
||||||
DATABASE_HOST = ''
|
|
||||||
DATABASE_PORT = ''
|
|
||||||
|
|
||||||
#setup memcached for production use!
|
|
||||||
#see http://docs.djangoproject.com/en/1.1/topics/cache/ for details
|
|
||||||
CACHE_BACKEND = 'locmem://'
|
|
||||||
|
|
||||||
#If you use memcache you may want to uncomment the following line to enable memcached based sessions
|
|
||||||
#SESSION_ENGINE = 'django.contrib.sessions.backends.cache_db'
|
|
||||||
# for user upload
|
|
||||||
|
|
||||||
ALLOW_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
|
|
||||||
# unit byte
|
|
||||||
ALLOW_MAX_FILE_SIZE = 1024 * 1024
|
|
||||||
|
|
||||||
#email server settings
|
|
||||||
SERVER_EMAIL = ''
|
|
||||||
DEFAULT_FROM_EMAIL = ''
|
|
||||||
EMAIL_HOST_USER = ''
|
|
||||||
EMAIL_HOST_PASSWORD = ''
|
|
||||||
EMAIL_SUBJECT_PREFIX = '[ASKBOT] '
|
|
||||||
EMAIL_HOST='askbot.org'
|
|
||||||
EMAIL_PORT='25'
|
|
||||||
EMAIL_USE_TLS=False
|
|
||||||
|
|
||||||
#HACK - anonymous user email - for email-less users
|
|
||||||
ANONYMOUS_USER_EMAIL = 'anonymous@askbot.org'
|
|
||||||
|
|
||||||
#LOCALIZATIONS
|
|
||||||
TIME_ZONE = 'America/New_York'
|
|
||||||
|
|
||||||
###########################
|
|
||||||
#
|
|
||||||
# this will allow running your forum with url like http://site.com/forum
|
|
||||||
#
|
|
||||||
# FORUM_SCRIPT_ALIAS = 'forum/'
|
|
||||||
#
|
|
||||||
FORUM_SCRIPT_ALIAS = '' #no leading slash, default = '' empty string
|
|
||||||
|
|
||||||
|
|
||||||
#OTHER SETTINGS
|
|
||||||
APP_TITLE = u'ASKBOT: Open Source Q&A Forum'
|
|
||||||
APP_SHORT_NAME = u'ASKBOT'
|
|
||||||
APP_KEYWORDS = u'ASKBOT,CNPROG,forum,community'
|
|
||||||
APP_DESCRIPTION = u'Ask and answer questions.'
|
|
||||||
APP_INTRO = u'<p>Ask and answer questions, make the world better!</p>'
|
|
||||||
APP_COPYRIGHT = 'Copyright ASKBOT, 2009. Some rights reserved under creative commons license.'
|
|
||||||
LOGIN_URL = '/%s%s%s' % (FORUM_SCRIPT_ALIAS,'account/','signin/')
|
|
||||||
GREETING_URL = LOGIN_URL #may be url of "faq" page or "about", etc
|
|
||||||
|
|
||||||
USE_I18N = True
|
|
||||||
LANGUAGE_CODE = 'en'
|
|
||||||
EMAIL_VALIDATION = 'off' #string - on|off
|
|
||||||
MIN_USERNAME_LENGTH = 1
|
|
||||||
EMAIL_UNIQUE = False
|
|
||||||
APP_URL = 'http://askbot.org' #used by email notif system and RSS
|
|
||||||
GOOGLE_SITEMAP_CODE = ''
|
|
||||||
GOOGLE_ANALYTICS_KEY = ''
|
|
||||||
WIKI_ON = True
|
|
||||||
FEEDBACK_SITE_URL = None #None or url
|
|
||||||
EDITABLE_SCREEN_NAME = False #True or False - can user change screen name?
|
|
||||||
|
|
||||||
DJANGO_VERSION = 1.1
|
|
||||||
RESOURCE_REVISION=4
|
|
||||||
|
|
||||||
#please get these at recaptcha.net
|
|
||||||
RECAPTCHA_PRIVATE_KEY='...'
|
|
||||||
RECAPTCHA_PUBLIC_KEY='...'
|
|
||||||
ASKBOT_DEFAULT_SKIN = 'default'
|
|
||||||
|
|
||||||
|
|
||||||
#Facebook settings
|
|
||||||
USE_FB_CONNECT=False
|
|
||||||
FB_API_KEY='' #your api key from facebook
|
|
||||||
FB_SECRET='' #your application secret
|
|
||||||
|
|
||||||
USE_EXTERNAL_LEGACY_LOGIN = False #DO NOT USE, and do not delete this line, will be removed later
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import ez_setup
|
||||||
|
ez_setup.use_setuptools()
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name = "askbot",
|
||||||
|
version = "0.6.0",
|
||||||
|
packages = find_packages(),
|
||||||
|
author = 'Evgeny.Fadeev',
|
||||||
|
author_email = 'evgeny.fadeev@gmail.com',
|
||||||
|
license = 'GPLv3',
|
||||||
|
keywords = 'forum, community, wiki, Q&A',
|
||||||
|
url = 'http://askbot.org',
|
||||||
|
include_package_data = True,
|
||||||
|
install_requires = [
|
||||||
|
'django==1.1.2',
|
||||||
|
'django-debug-toolbar==0.7.0',
|
||||||
|
'South',
|
||||||
|
'recaptcha-client',
|
||||||
|
'markdown2',
|
||||||
|
'html5lib',
|
||||||
|
'python-openid',
|
||||||
|
'django-keyedcache',
|
||||||
|
'mysql-python',
|
||||||
|
],
|
||||||
|
long_description = """Open Source Question and Answer forum.
|
||||||
|
Based on CNPROG project by Mike Chen and Sailing Cai, project
|
||||||
|
is inspired by StackOverflow.
|
||||||
|
""",
|
||||||
|
)
|
Reference in New Issue