Skip to content

Commit

Permalink
Merge pull request #11 from nitely/future
Browse files Browse the repository at this point in the history
v0.1.1
  • Loading branch information
nitely-throwaway777 committed Jun 9, 2014
2 parents 3766404 + d2f15b1 commit 65a7311
Show file tree
Hide file tree
Showing 98 changed files with 1,589 additions and 1,687 deletions.
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,20 @@ Check out the [example](https://github.com/nitely/Spirit/tree/master/example) pr

In short:

Add `spirit`, `djconfig` and `haystack` to your *INSTALLED_APPS*

Add `url(r'^', include('spirit.urls', namespace="spirit", app_name="spirit")),` to your *urls.py*

Add `from spirit.settings import *` to the top of your *settings.py* file,
otherwise you will have to setup all django's related constants (Middlewares, Login_url, etc)
otherwise you will have to setup all django's related constants (Installed_apps, Middlewares, Login_url, etc)

Run:

python pip install -r requirements.txt
pip install -r requirements.txt
python manage.py syncdb
python manage.py loaddata spirit_init
python manage.py createcachetable spirit_cache
python manage.py collectstatic

> *Note:*
> **Note:**
>
> You will need to setup a search engine,
> Spirit is configured to work with [Woosh](https://bitbucket.org/mchaput/whoosh/wiki/Home) by default.
Expand Down
9 changes: 6 additions & 3 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
* Unsubscribe on notifications list
* Unread: mark all as read, unsubscribe
* NestedModelChoiceField for multiple choice (search)
* NestedModelChoiceField for multiple choice (search), add *----* as initial
* 'User has leave or has joined the conversation' comment on private topics, dont send notification.
* Ocultar quote anidado (ej: max tres niveles, y ocultar el tercero con js [...])
* Diff entre comentarios en historial (js)
Expand All @@ -24,14 +24,17 @@
* Moderation section: flags, topics
* User groups (permissions)
* >> add @username on reply
* >> allow mods to create topics on closed categories


Template
* profile, add rank mod/admin, add topic title to comments
* profile, add rank mod/admin
* admin: flag detail delete comment, detail add topic title
* admin: add nav to detail templates
* Notifications: show all/unread link
* Emojis popup selector


Readme
* add note about translations and fuzziness
* add note about translations and fuzziness
* update: rebuild_index (search) command
19 changes: 18 additions & 1 deletion example/local_settings_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# DO NOT USE IT IN PRODUCTION

import os
import sys


DEBUG = True
Expand Down Expand Up @@ -34,4 +35,20 @@
'django.contrib.auth.hashers.MD5PasswordHasher',
)

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

TESTING = 'test' in sys.argv

if TESTING:
# Keep templates in memory
TEMPLATE_LOADERS = (
('django.template.loaders.cached.Loader', (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)),
)
else:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
18 changes: 6 additions & 12 deletions example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,8 @@

# Application definition

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'spirit',
'haystack',
'djconfig',
#'debug_toolbar'
INSTALLED_APPS += (
# 'myapp',
)

ROOT_URLCONF = 'example.urls'
Expand Down Expand Up @@ -82,6 +72,10 @@

STATIC_URL = '/static/'

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
Expand Down
5 changes: 5 additions & 0 deletions example/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static

# Uncomment the next two lines to enable the django admin:
from django.contrib import admin
Expand All @@ -22,3 +24,6 @@
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)

if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Django>=1.6,<1.7
django-haystack>=2.1,<2.2
whoosh>=2.5,<2.6
Markdown>=2.3,<2.4
Pillow>=2.4,<2.5
django-infinite-scroll-pagination>=0.1,<0.2
django-djconfig>=0.1.3,<0.2
django-debug-toolbar
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

setup(
name='django-spirit',
version='0.1',
version='0.1.1',
description='Spirit is a Python based forum powered by Django.',
author='Esteban Castro Borsani',
author_email='[email protected]',
Expand Down
2 changes: 1 addition & 1 deletion spirit/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.1'
__version__ = '0.1.1'
9 changes: 6 additions & 3 deletions spirit/forms/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def clean_parent(self):

if parent and has_childrens:
raise forms.ValidationError(_("The category you are updating "
"can not has a parent since it has childrens"))
"can not have a parent since it has childrens"))

return parent

Expand All @@ -66,5 +66,8 @@ def save(self, commit=True):

class BasicConfigForm(ConfigForm):

site_name = forms.CharField(initial="Spirit")
site_description = forms.CharField(initial="", max_length=75)
site_name = forms.CharField(initial="Spirit", label=_("site name"))
site_description = forms.CharField(initial="", label=_("site description"), max_length=75, required=False)
template_footer = forms.CharField(initial="", label=_("footer snippet"), required=False,
widget=forms.Textarea(attrs={'rows': 2, }),
help_text=_("This gets rendered just before the footer in your template."))
48 changes: 47 additions & 1 deletion spirit/forms/comment.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
#-*- coding: utf-8 -*-

import hashlib
import os

from markdown import Markdown

from django import forms
from django.conf import settings
from django.utils.translation import ugettext as _
from django.utils.image import Image

from spirit.models.comment import Comment
from spirit.models.topic import Topic
from spirit import utils


class CommentForm(forms.ModelForm):
Expand Down Expand Up @@ -55,4 +60,45 @@ def save(self):
comments_list = list(comments)
topic = self.cleaned_data['topic']
comments.update(topic=topic)
return comments_list
return comments_list


class CommentImageForm(forms.Form):

image = forms.ImageField()

def __init__(self, user=None, *args, **kwargs):
super(CommentImageForm, self).__init__(*args, **kwargs)
self.user = user

def clean_image(self):
image = self.cleaned_data["image"]

if Image.open(image).format.lower() not in settings.ST_ALLOWED_UPLOAD_IMAGE_FORMAT:
raise forms.ValidationError(_("Unsupported file format. Supported formats are %s."
% ", ".join(settings.ST_ALLOWED_UPLOAD_IMAGE_FORMAT)))

image.seek(0)
return image

def save(self):
image = self.cleaned_data["image"]
hash = hashlib.md5(image.read()).hexdigest()
name, ext = os.path.splitext(image.name)

# Remove the extension if not allowed
if ext and ext[1:].lower() not in settings.ST_ALLOWED_UPLOAD_IMAGE_EXT:
ext = ""

image.name = u"".join((hash, ext.lower()))
upload_to = os.path.join('spirit', 'images', str(self.user.pk))
image.url = os.path.join(settings.MEDIA_URL, upload_to, image.name).replace("\\", "/")
media_path = os.path.join(settings.MEDIA_ROOT, upload_to)
utils.mkdir_p(media_path)

with open(os.path.join(media_path, image.name), "wb") as fh:
image.seek(0)
fh.write(image.read())
image.close()

return image
14 changes: 13 additions & 1 deletion spirit/forms/comment_bookmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,16 @@ class BookmarkForm(forms.ModelForm):

class Meta:
model = CommentBookmark
fields = ['comment_number', ]
fields = ['comment_number', ]

def __init__(self, user=None, topic=None, *args, **kwargs):
super(BookmarkForm, self).__init__(*args, **kwargs)
self.user = user
self.topic = topic

def save(self, commit=True):
comment_number = self.cleaned_data['comment_number']

# Bookmark is created/updated on topic view.
CommentBookmark.objects.filter(user=self.user, topic=self.topic)\
.update(comment_number=comment_number)
4 changes: 0 additions & 4 deletions spirit/forms/topic.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#-*- coding: utf-8 -*-

from django import forms
from django.conf import settings
from django.utils import timezone
from django.utils.text import slugify
from django.utils.translation import ugettext as _

from ..utils.forms import NestedModelChoiceField
Expand Down Expand Up @@ -44,6 +41,5 @@ def clean_category(self):
def save(self, commit=True):
if not self.instance.pk:
self.instance.user = self.user
self.instance.slug = slugify(self.cleaned_data["title"])

return super(TopicForm, self).save(commit)
2 changes: 0 additions & 2 deletions spirit/forms/topic_private.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from django import forms
from django.utils.translation import ugettext as _
from django.utils.text import slugify
from django.contrib.auth import get_user_model
from django.conf import settings

Expand Down Expand Up @@ -30,7 +29,6 @@ def save(self, commit=True):
if not self.instance.pk:
self.instance.user = self.user
self.instance.category = Category.objects.get(pk=settings.ST_TOPIC_PRIVATE_CATEGORY_PK)
self.instance.slug = slugify(self.cleaned_data["title"])

return super(TopicForPrivateForm, self).save(commit)

Expand Down
2 changes: 0 additions & 2 deletions spirit/forms/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django import forms
from django.utils.translation import ugettext as _
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.utils.text import slugify
from django.contrib.auth import get_user_model


Expand Down Expand Up @@ -39,7 +38,6 @@ def clean_username(self):
raise forms.ValidationError(_("The username is taken."))

def save(self, commit=True):
self.instance.slug = slugify(self.cleaned_data["username"])
self.instance.is_active = False
return super(RegistrationForm, self).save(commit)

Expand Down
22 changes: 7 additions & 15 deletions spirit/managers/topic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,9 @@ def for_public(self):
return self._for_all()\
.filter(category__is_private=False)

def for_open(self):
return self._for_all()\
.filter(Q(category__parent=None) | Q(category__parent__is_closed=False),
category__is_closed=False,
is_closed=False)

def for_public_open(self):
return self.for_open()\
.filter(category__is_private=False)
return self.for_public()\
.filter(is_closed=False)

def for_category(self, category):
if category.is_subcategory:
Expand Down Expand Up @@ -56,12 +50,10 @@ def for_update_or_404(self, pk, user):
pk=pk,
user=user)

def for_access_or_404(self, pk, user):
# todo: remove
return get_object_or_404(self.for_open(),
Q(category__is_private=False) | Q(topics_private__user=user),
pk=pk)

def for_access(self, user):
return self._for_all()\
.filter(Q(category__is_private=False) | Q(topics_private__user=user))
.filter(Q(category__is_private=False) | Q(topics_private__user=user))

def for_access_open(self, user):
return self.for_access(user)\
.filter(is_closed=False)
Loading

0 comments on commit 65a7311

Please sign in to comment.