-
Notifications
You must be signed in to change notification settings - Fork 3
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 5a16ec1
Showing
21 changed files
with
337 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,5 @@ | ||
*.swp | ||
*.pyc | ||
static/lasana/css | ||
uploads/* | ||
dbfile |
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 @@ | ||
Copyright (c) 2012 ntrrgc | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
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,4 @@ | ||
Lasaña, a temporary file hosting service | ||
======================================== | ||
|
||
This is a WIP, but feel free to dig in source. |
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,7 @@ | ||
from django.contrib import admin | ||
from . models import Meal | ||
|
||
class MealAdmin(admin.ModelAdmin): | ||
pass | ||
|
||
admin.site.register(Meal, MealAdmin) |
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,14 @@ | ||
from django.forms import Form, FileField, IntegerField, ChoiceField | ||
|
||
from . models import Meal | ||
|
||
class MealCreateForm(Form): | ||
file = FileField() | ||
expires_in = ChoiceField(choices=( | ||
(1, "1 minute"), | ||
(30, "30 minutes"), | ||
(60, "1 hour"), | ||
(180, "3 hours"), | ||
(60*24, "1 day"), | ||
(60*24*7, "1 week"), | ||
), initial=30) |
Empty file.
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,18 @@ | ||
from django.core.management.base import BaseCommand, CommandError | ||
|
||
from lasana.models import Meal | ||
|
||
class Command(BaseCommand): | ||
args = '<meal_id meal_id>' | ||
help = 'Deletes the meal with the specified id' | ||
|
||
def handle(self, *args, **options): | ||
for meal_id in args: | ||
try: | ||
meal = Meal.objects.get(id=int(meal_id)) | ||
except Meal.DoesNotExist: | ||
raise CommandError('Meal "%s" does not exist' % meal_id) | ||
|
||
meal.delete() | ||
|
||
self.stdout.write('Successfully deleted meal "%s"\n' % meal_id) |
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,22 @@ | ||
from django.core.management.base import BaseCommand, CommandError | ||
|
||
from lasana.models import Meal | ||
|
||
from django.utils import timezone | ||
|
||
class Command(BaseCommand): | ||
args = '' | ||
help = 'Deletes expired meals' | ||
|
||
def handle(self, *args, **options): | ||
now = timezone.now() | ||
old_meals = Meal.objects.all().order_by("expiration_time") | ||
|
||
for meal in old_meals: | ||
if meal.is_expired(now): | ||
meal_id = meal.id | ||
|
||
meal.delete() | ||
self.stdout.write('Thrown away expired meal "%d"\n' % meal_id) | ||
else: | ||
break |
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,40 @@ | ||
from django.db.models import Model, CharField, FileField, DateTimeField | ||
|
||
from django.conf import settings | ||
|
||
from django.utils import timezone | ||
|
||
import string | ||
import random | ||
|
||
class Meal(Model): | ||
id_length = 4 | ||
id = CharField(max_length=id_length, db_index=True, primary_key=True) | ||
file = FileField(upload_to=settings.LASANA_UPLOAD_ROOT) | ||
expiration_time = DateTimeField(db_index=True) | ||
|
||
def generate_auto_id(self): | ||
#Theoretically, we can have up to 46656 meals, but having 10k would be enough to worry | ||
if Meal.objects.count() > 10000: | ||
raise "Too much meals" | ||
|
||
while True: | ||
random_string = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(4)) | ||
if len(Meal.objects.filter(id=random_string)) == 0: | ||
self.id = random_string | ||
return self.id | ||
|
||
def is_expired(self, now=None): | ||
if not now: | ||
now = timezone.now() | ||
return now > self.expiration_time | ||
|
||
class Meta: | ||
ordering = ['expiration_time'] | ||
|
||
def __unicode__(self): | ||
now = timezone.now() | ||
if now > self.expiration_time: | ||
return "%s, expired for %s" % (self.file.url, now - self.expiration_time) | ||
else: | ||
return "%s, expires in %s" % (self.file.url, self.expiration_time - now) |
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,24 @@ | ||
from django.http import HttpResponse, Http404 | ||
from django.conf import settings | ||
import os | ||
|
||
from django.conf import settings | ||
|
||
#For no-XSendfile approach | ||
from django.core.servers.basehttp import FileWrapper | ||
|
||
def send(request, file): | ||
if not file: | ||
raise Http404 | ||
|
||
if settings.LASANA_USE_X_SENDFILE: | ||
response = HttpResponse() | ||
response['Content-Disposition'] = 'filename=%s' % os.path.basename(file.name) | ||
response['X-Sendfile'] = file.path | ||
return response | ||
else: | ||
response = HttpResponse(FileWrapper(file)) | ||
response['Content-Disposition'] = 'filename=%s' % os.path.basename(file.name) | ||
del response['content-type'] #let the web server guess | ||
response['Content-Length'] = file.size | ||
return response |
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,64 @@ | ||
@import url(http://fonts.googleapis.com/css?family=Donegal+One) | ||
|
||
$body_font: 'Donegal One', serif | ||
$content_width: 600px | ||
$content_border_color: #ff912f | ||
|
||
body | ||
background: #fff8da | ||
font-family: $body_font | ||
font-size: 18px | ||
|
||
h1, #miau | ||
text-align: center | ||
|
||
#content | ||
border: 5px dotted $content_border_color | ||
width: $content_width | ||
margin-left: auto | ||
margin-right: auto | ||
padding: 30px | ||
|
||
form | ||
width: 100% | ||
display: table | ||
border-collapse: separate | ||
border-spacing: 2px | ||
border-top: 1px solid lightgray | ||
border-left: 1px solid lightgray | ||
border-right: 1px solid black | ||
border-bottom: 1px solid black | ||
|
||
form > .field | ||
display: table-row | ||
|
||
form > .field > .cell | ||
display: table-cell | ||
border-top: 1px solid black | ||
border-left: 1px solid black | ||
border-right: 1px solid lightgray | ||
border-bottom: 1px solid lightgray | ||
padding: 10px 10px | ||
text-align: left | ||
|
||
#lasagna_url_field | ||
box-sizing: border-box | ||
width: 100% | ||
border: 1px solid $content_border_color | ||
padding: 3px | ||
font-family: $body_font | ||
font-size: 36px | ||
|
||
#copyright_footer | ||
padding-top: 50px | ||
width: $content_width | ||
margin: 0 auto | ||
|
||
hr | ||
width: $content_width | ||
border: 0 | ||
border-top: 2px solid $content_border_color | ||
|
||
#copyright_footer_note | ||
font-size: 70% | ||
text-align: center |
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,21 @@ | ||
{% load staticfiles %}<!DOCTYPE HTML> | ||
<html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>{% block title %}Lasaña{% endblock %}</title> | ||
<link rel="stylesheet" href="{% static 'lasana/css/stylesheet.css' %}" /> | ||
</head> | ||
<body> | ||
<h1>Lasaña</h1> | ||
<div id="content"> | ||
{% block content %} | ||
{% endblock %} | ||
</div> | ||
<div id="copyright_footer"> | ||
<hr/> | ||
<div id="copyright_footer_note"> | ||
{% include "lasana/copyright_footer_note.html" %} | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
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,4 @@ | ||
© John Titor 2036 | ||
<span style="color: #737373"> | ||
Redefine <em>'templates/lasana/copyright_footer_note.html'</em> to edit this note. | ||
</span> |
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,11 @@ | ||
{% extends "lasana/base.html" %} | ||
|
||
{% block content %} | ||
<p>Share this lasagna:</p> | ||
<input id="lasagna_url_field" type="text" readonly value="{{ meal_serve_absolute_url }}"/> | ||
<script> | ||
<!-- Select URL --> | ||
document.getElementById("lasagna_url_field").select() | ||
</script> | ||
<p><a href="{% url meal-create %}">Store more</a></p> | ||
{% endblock %} |
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,14 @@ | ||
{% extends "lasana/base.html" %} | ||
|
||
{% block content %} | ||
<form enctype="multipart/form-data" action="" method="POST"> | ||
{% for field in form %} | ||
<div class="field"> | ||
<div class="cell">{{ field.label_tag }}</div> | ||
<div class="cell">{{ field }}{{ field.errors }}</div> | ||
</div> | ||
{% endfor %} | ||
{% csrf_token %} | ||
<input type="submit" value="Put in the fridge"/> | ||
</form> | ||
{% endblock %} |
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,16 @@ | ||
""" | ||
This file demonstrates writing tests using the unittest module. These will pass | ||
when you run "manage.py test". | ||
Replace this with more appropriate tests for your application. | ||
""" | ||
|
||
from django.test import TestCase | ||
|
||
|
||
class SimpleTest(TestCase): | ||
def test_basic_addition(self): | ||
""" | ||
Tests that 1 + 1 always equals 2. | ||
""" | ||
self.assertEqual(1 + 1, 2) |
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,8 @@ | ||
from django.conf.urls import patterns, include, url | ||
|
||
from . import views | ||
|
||
urlpatterns = patterns('', | ||
url(r'^$', views.MealCreateView.as_view(), name='meal-create'), | ||
url(r'^(?P<meal_id>[A-Z0-9]+)/$', views.MealServeView.as_view(), name='meal-serve'), | ||
) |
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,58 @@ | ||
from django.views.generic.edit import CreateView, FormView | ||
from django.views.generic.base import View, TemplateResponse | ||
|
||
from . models import Meal | ||
from . forms import MealCreateForm | ||
from . sendfile import send | ||
|
||
from django.shortcuts import render | ||
from django.http import HttpResponse, HttpResponseRedirect | ||
|
||
from django.core.urlresolvers import reverse, reverse_lazy | ||
|
||
from datetime import timedelta | ||
from django.utils import timezone | ||
|
||
class MealCreateView(FormView): | ||
template_name = "lasana/meal_form.html" | ||
form_class = MealCreateForm | ||
|
||
def form_valid(self, form): | ||
expires_in = int(form.cleaned_data['expires_in']) | ||
file = form.cleaned_data['file'] | ||
|
||
expiration_time = timezone.now() + timedelta(minutes=expires_in) | ||
|
||
meal = Meal(file=file, expiration_time=expiration_time) | ||
meal.generate_auto_id() | ||
meal.save() | ||
|
||
meal_serve_url = reverse('meal-serve', kwargs={'meal_id': meal.id}) | ||
meal_serve_absolute_url = self.request.build_absolute_uri(meal_serve_url) | ||
|
||
return TemplateResponse(self.request, | ||
"lasana/meal_create_success.html", | ||
context={'meal': meal, | ||
'meal_serve_absolute_url': meal_serve_absolute_url}) | ||
|
||
|
||
class MealServeView(View): | ||
def get(self, request, *args, **kwargs): | ||
#if there is no such meal, redirect to main page | ||
meal_iter = Meal.objects.filter(id=kwargs['meal_id']) | ||
if len(meal_iter) != 1: | ||
return self.no_meal() | ||
|
||
meal = meal_iter[0] | ||
|
||
#if meal is there, but has expired, throw it away and redirect to main page too | ||
if meal.is_expired(): | ||
meal.delete() | ||
return self.no_meal() | ||
else: | ||
#else, serve the meal | ||
file = meal_iter[0].file | ||
return send(request, file) | ||
|
||
def no_meal(self): | ||
return HttpResponseRedirect(reverse('meal-create')) |