forked from django-bft/django-bft
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bfb64b2
Showing
89 changed files
with
6,531 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.pyc | ||
*.pyc | ||
*.egg-info | ||
build | ||
dist | ||
.DS_Store |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
include README.rst LICENCE | ||
recursive-include bft *.py | ||
recursive-include bft/templates * | ||
recursive-include bft/static * | ||
recursive-include docs/source * | ||
recursive-include docs/build/html * | ||
include docs/Makefile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.. include:: docs/source/index.rst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
VERSION = (0, 1, 0) | ||
__version__ = '.'.join(map(str, VERSION)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import app_settings | ||
from django.core.urlresolvers import reverse | ||
from django.contrib import admin | ||
from forms import EmailForm, FileForm, SubmissionForm | ||
from models import Submission, Email, File, FileArchive | ||
import os | ||
|
||
#global callables | ||
def delete_row(obj): | ||
return '<a href="%s/delete">Delete</a>' % obj.id | ||
delete_row.allow_tags = True | ||
delete_row.short_description = 'Delete' | ||
|
||
def edit_row(obj): | ||
return '<a href="%s">Edit</a>' % obj.id | ||
edit_row.short_description = 'Edit' | ||
edit_row.allow_tags = True | ||
|
||
def file_url(obj): | ||
url = reverse('file', args=(obj.slug,)) | ||
return '<a href="%s%s">%s</a>' % (url, os.path.basename(obj.file_upload.name), url) | ||
file_url.short_description = 'File URL' | ||
file_url.allow_tags = True | ||
|
||
def submission_url(obj): | ||
url = reverse('files', args=(obj.slug,)) | ||
return '<a href="%s">%s</a>' % (url, url) | ||
submission_url.short_description = 'Submission URL' | ||
submission_url.allow_tags = True | ||
|
||
def submission_admin_url(obj): | ||
url = reverse('admin:bft_submission_change', args=(obj.submission,)) | ||
return '<a href="%s">%s</a>' % (url, obj.submission) | ||
submission_admin_url.short_description = 'Submission' | ||
submission_admin_url.allow_tags = True | ||
|
||
def attached_files(obj): | ||
files = File.objects.filter(submission=obj.id) | ||
if files: | ||
file_list = [] | ||
for file in files: | ||
file_list.append('<a href="/%s/%s">%s</a>' % (file.slug, | ||
os.path.basename(file.file_upload.name), file.slug)) | ||
return ' '.join(file_list) | ||
else: | ||
return None | ||
attached_files.allow_tags = True | ||
|
||
def attached_submission_date(obj): | ||
return obj.submission.submit_date | ||
attached_submission_date.short_description = 'Upload Date' | ||
|
||
def submission_fields(): | ||
if app_settings.RANDOM_PASS: | ||
return ('type', 'email_address', 'is_archived', 'email_sent') | ||
else: | ||
return ('type', 'email_address', 'password', 'is_archived', 'email_sent') | ||
|
||
|
||
#inlines | ||
class EmailInline(admin.StackedInline): | ||
model = Email | ||
form = EmailForm | ||
fields = ('first_name', 'last_name', 'recipients', 'message') | ||
|
||
class FileInline(admin.StackedInline): | ||
model = File | ||
form = FileForm | ||
extra = 3 | ||
|
||
#admin views | ||
class SubmissionAdmin(admin.ModelAdmin): | ||
class Media: | ||
js = ( | ||
'https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', | ||
'/static/scripts/admin.js', | ||
) | ||
|
||
list_filter = ('type', 'submit_date') | ||
search_fields = ['email_address', 'slug', 'submit_ip', 'file__slug', 'email__recipients'] | ||
fields = submission_fields() | ||
list_display = ('id', submission_url, 'type', 'email_address', 'password', | ||
attached_files, 'submit_date', 'submit_ip', 'browser_meta', delete_row, edit_row) | ||
inlines = [EmailInline, FileInline] | ||
form = SubmissionForm | ||
|
||
def save_model(self, request, obj, form, change): | ||
obj.submit_ip = request.META['REMOTE_ADDR'] | ||
obj.save() | ||
|
||
|
||
class FileAdmin(admin.ModelAdmin): | ||
list_display = ('id', file_url, submission_admin_url, 'file_upload', | ||
'file_size', attached_submission_date, delete_row, edit_row) | ||
search_fields = ['file_upload', 'slug', 'submission__pk', 'submission__email_address'] | ||
|
||
form = FileForm | ||
|
||
class FileArchiveAdmin(admin.ModelAdmin): | ||
list_display = ('delete_date', 'submit_date', submission_admin_url, 'file_upload', delete_row) | ||
|
||
list_filter = ('submit_date', 'delete_date') | ||
search_fields = ['file_upload', 'submission__pk'] | ||
|
||
admin.site.register(Submission, SubmissionAdmin) | ||
admin.site.register(File, FileAdmin) | ||
admin.site.register(FileArchive, FileArchiveAdmin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Location of file uploads relative to MEDIA_ROOT | ||
# Do not put a trailing slash! | ||
FILE_UPLOAD_DIR = 'files' | ||
|
||
# Do not exceed 2 GB, your web server will not like you! | ||
# This used on the client (flash player) to enforce size limit | ||
MAX_UPLOAD_SIZE = 1073741824 #1GB | ||
|
||
# This setting is used my the management commands to | ||
# delete files. Follow documentation to setup a cron job for this. | ||
UPLOAD_EXPIRATION_DAYS = 7 | ||
|
||
# Set to have Django try to enforce MAX_UPLOAD_SIZE | ||
# It is far better to enforce this using the web server (Apache) | ||
# An example would be: | ||
# LimitRequestBody 1073741824 | ||
# ErrorDocument 413 http://servername/413error/ | ||
VALIDATE_UPLOAD_SIZE = True | ||
|
||
# Feedback form | ||
SHOW_FEEDBACK = True | ||
|
||
# General settings | ||
APP_NAME = 'BFT' | ||
REPLY_EMAIL = '' | ||
USE_FLASH = True | ||
|
||
# Captcha settings | ||
USE_RECAPTCHA = False | ||
RECAPTCHA_SUBNET = '' | ||
RECAPTCHA_PUB_KEY = '' | ||
RECAPTCHA_PRIVATE_KEY = '' | ||
|
||
# Slug generator settings | ||
# This is used to randomize the file and file list urls | ||
RANDOMSLUG_CHARS = "bcdfghjklmnpqrstvwxyz2346789" | ||
RANDOMSLUG_CHAR_NO = 5 | ||
|
||
# If used, then passwords will not be encrypted regardless. | ||
RANDOM_PASS = False | ||
|
||
# Use this to encrypt non random passwords | ||
# RANDOM_PASS must be False for this to work. | ||
ENCRYPT_PASS = True | ||
|
||
# Used to generate a random password | ||
RANDOMPASS_CHARS = 'bcdfghjklmnpqrstvwxyz2346789' | ||
RANDOMPASS_CHAR_NO = 8 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from bft import app_settings | ||
from django.conf import settings | ||
from django.core.urlresolvers import reverse | ||
|
||
def bft(request): | ||
|
||
abs_static_url = "http%s://%s%s" % ( | ||
's' if request.is_secure() else None, | ||
request.META['SERVER_NAME'], | ||
settings.STATIC_URL[1:] | ||
) | ||
|
||
# Show the password field if RANDOM_PASS is False: | ||
show_password_input = False if app_settings.RANDOM_PASS else True | ||
|
||
return { | ||
'app_name' : app_settings.APP_NAME, | ||
'use_flash' : app_settings.USE_FLASH, | ||
'expiry_days' : app_settings.UPLOAD_EXPIRATION_DAYS, | ||
'reply_email' : app_settings.REPLY_EMAIL, | ||
'show_feedback' : app_settings.SHOW_FEEDBACK, | ||
'feedback_url' : reverse('feedback'), | ||
'show_password_input' : show_password_input, | ||
'abs_static_url' : abs_static_url | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from django import forms | ||
from models import Email, File, Submission | ||
from bft.app_settings import RANDOMPASS_CHAR_NO | ||
|
||
TYPE_CHOICES = ( | ||
('link', 'Link'), | ||
('email', 'Email'), | ||
) | ||
|
||
class EmailForm(forms.ModelForm): | ||
first_name = forms.CharField(error_messages={'required':'Please enter your first name.'}) | ||
last_name = forms.CharField(error_messages={'required':'Please enter your last name.'}) | ||
recipients = forms.CharField( | ||
error_messages={'required':'Please enter the recipient(s) email separated by commas.'}, | ||
widget=forms.Textarea, | ||
help_text="Enter a set of email addresses separated by commas" | ||
) | ||
message = forms.CharField(error_messages={'required':'Please enter a message.'}, widget=forms.Textarea) | ||
|
||
class Meta: | ||
exclude = ('submission',) | ||
model = Email | ||
|
||
class FileForm(forms.ModelForm): | ||
class Meta: | ||
model = File | ||
|
||
class SubmissionForm(forms.ModelForm): | ||
type = forms.ChoiceField(choices=TYPE_CHOICES) | ||
email_address = forms.CharField(error_messages={'required':'Please enter a valid email address.'}) | ||
password = forms.CharField( | ||
error_messages={'min_length':'Please ensure that your password is at least 8 characters in length.'}, | ||
widget = forms.PasswordInput, | ||
min_length = RANDOMPASS_CHAR_NO, | ||
help_text = "Enter a password that contains at least 8 characters.", | ||
required = False | ||
) | ||
|
||
class Meta: | ||
model = Submission | ||
|
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from datetime import datetime, timedelta | ||
from django.conf import settings | ||
from django.core.management.base import BaseCommand | ||
from sys import stdout | ||
import os | ||
|
||
class Command(BaseCommand): | ||
""" | ||
Cron Job that deletes clean up the temp files directory | ||
""" | ||
|
||
def handle(self, *args, **options): | ||
path = "%s/tmp/" % settings.BASE_DIR | ||
|
||
datediff = datetime.today() - timedelta(days=1) | ||
|
||
try: | ||
if os.path.isdir(path): | ||
|
||
files = os.listdir(path) | ||
|
||
for file in files: | ||
|
||
fullpath = os.path.join(path, file) | ||
|
||
if os.path.isfile(fullpath) and (datetime.fromtimestamp(os.path.getmtime(fullpath)) < datediff): | ||
os.remove(fullpath) | ||
|
||
stdout.write('Temp files have been deleted.\n') | ||
|
||
except: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from bft.app_settings import APP_NAME | ||
from bft.models import Submission, File | ||
from django.core.mail import mail_admins | ||
from django.core.management.base import BaseCommand | ||
from optparse import make_option | ||
from sys import stdout | ||
|
||
class Command(BaseCommand): | ||
""" | ||
Cron Job that checks uploads that are past the expiration period and removes them from the system. | ||
""" | ||
|
||
option_list = BaseCommand.option_list + ( | ||
make_option('--mailadmins', '-M', dest='mailadmins', default=None, | ||
help='Use this option to email admins of any files that were deleted.'), | ||
) | ||
|
||
def handle(self, *args, **options): | ||
deleted_files = [] | ||
|
||
submissions = Submission.objects.get_expired_submissions() | ||
|
||
for submission in submissions: | ||
files = File.objects.filter(submission=submission) | ||
|
||
for file in files: | ||
deleted_files.append(file.file_upload.url) | ||
file.delete() | ||
|
||
submission.is_archived = True | ||
submission.save() | ||
|
||
message = ''' | ||
The following files have expired and deleted: | ||
''' | ||
if deleted_files: | ||
body = "%s%s" % (message, '\n'.join(file for file in deleted_files)) | ||
|
||
if options['mailadmins']: | ||
mail_admins('[%s] File cleanup summary' % APP_NAME, body) | ||
|
||
stdout.write(body + '\n') | ||
else: | ||
stdout.write('No expired files were deleted.\n') |
Oops, something went wrong.