Initial commit

This commit is contained in:
Kevin Alberts 2018-05-21 21:55:20 +02:00
commit 1544855377
Signed by: Kurocon
GPG key ID: BCD496FEBA0C6BC1
20 changed files with 743 additions and 0 deletions

0
photos/__init__.py Normal file
View file

10
photos/admin.py Normal file
View file

@ -0,0 +1,10 @@
from django.contrib import admin
from django.contrib.admin import ModelAdmin
from photos.models import Photo
@admin.register(Photo)
class PhotoAdmin(ModelAdmin):
fields = ('image_tag', 'added_on')
readonly_fields = ('image_tag', 'added_on')

5
photos/apps.py Normal file
View file

@ -0,0 +1,5 @@
from django.apps import AppConfig
class PhotosConfig(AppConfig):
name = 'photos'

View file

@ -0,0 +1,22 @@
# Generated by Django 2.0.5 on 2018-05-21 18:53
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Photo',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('photo', models.ImageField(upload_to='photos')),
('added_on', models.DateTimeField(auto_now_add=True)),
],
),
]

View file

17
photos/models.py Normal file
View file

@ -0,0 +1,17 @@
from django.conf import settings
from django.db import models
from django.utils.safestring import mark_safe
class Photo(models.Model):
photo = models.ImageField(upload_to="photos")
added_on = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
from django.urls import reverse
return "{}{}".format(settings.BASE_URL, reverse("show", kwargs={'pk': self.id}))
def image_tag(self):
return mark_safe('<img src="{}" />'.format(self.get_absolute_url()))
image_tag.short_description = 'Image'

File diff suppressed because one or more lines are too long

BIN
photos/static/loader.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

58
photos/static/photo.css Normal file
View file

@ -0,0 +1,58 @@
body {
background-color: #ddd;
padding: 0.5em;
text-align: center;
font-family: "Helvetica Neueu", "Helvetica", "Arial", sans;
}
button, input, #loader {
display: none;
}
input {
width: 300px;
}
#camera {
display: inline-block;
background-color: #eee;
width: 1280px;
height: 650px;
margin: 0.5em;
}
#camera .placeholder {
padding: 0.5em;
}
#snapshots {
height: 150px;
margin: 0.5em 0;
padding: 3px;
border: 1px solid #aaa;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}
#snapshots canvas, #snapshots img {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
height: 100%;
margin-left: 3px;
border: 3px solid transparent;
}
#snapshots .selected {
border: 3px solid #000;
}
button, #upload_status, #upload_result, #loader {
margin: 0.5em;
}

153
photos/static/photo.js Normal file
View file

@ -0,0 +1,153 @@
$(function() {
if (window.JpegCamera) {
var camera; // Initialized at the end
//var url = "https://isonzeinterndronken.nl/11bt/photos.json/";
var url = "http://localhost:8000/new/";
var update_stream_stats = function(stats) {
$("#stream_stats").html(
"Mean luminance = " + stats.mean +
"; Standard Deviation = " + stats.std);
setTimeout(function() {camera.get_stats(update_stream_stats);}, 1000);
};
var take_snapshots = function(count) {
var snapshot = camera.capture();
if (JpegCamera.canvas_supported()) {
snapshot.get_canvas(add_snapshot);
}
else {
// <canvas> is not supported in this browser. We'll use anonymous
// graphic instead.
var image = document.createElement("img");
image.src = "no_canvas_photo.jpg";
setTimeout(function() {add_snapshot.call(snapshot, image)}, 1);
}
if (count > 1) {
setTimeout(function() {take_snapshots(count - 1);}, 500);
}
};
var add_snapshot = function(element) {
$(element).data("snapshot", this).addClass("item");
var $container = $("#snapshots").append(element);
var $camera = $("#camera");
var camera_ratio = $camera.innerWidth() / $camera.innerHeight();
var height = $container.height()
element.style.height = "" + height + "px";
element.style.width = "" + Math.round(camera_ratio * height) + "px";
var scroll = $container[0].scrollWidth - $container.innerWidth();
$container.animate({
scrollLeft: scroll
}, 200);
clear_upload_data();
$("#loader").show();
snapshot = $(element).data("snapshot");
snapshot.upload({api_url: url}).done(upload_done).fail(upload_fail);
};
var select_snapshot = function () {
$(".item").removeClass("selected");
var snapshot = $(this).addClass("selected").data("snapshot");
};
var clear_upload_data = function() {
$("#upload_status, #upload_result").html("");
};
var upload_snapshot = function() {
var api_url = $("#api_url").val();
if (!api_url.length) {
$("#upload_status").html("Please provide URL for the upload");
return;
}
clear_upload_data();
$("#loader").show();
$("#upload_snapshot").prop("disabled", true);
var snapshot = $(".item.selected").data("snapshot");
snapshot.upload({api_url: url}).done(upload_done).fail(upload_fail);
};
var upload_done = function(response) {
$("#upload_snapshot").prop("disabled", false);
$("#loader").hide();
$("#upload_status").html("Upload successful");
$("#upload_result").html(response);
};
var upload_fail = function(code, error, response) {
$("#upload_snapshot").prop("disabled", false);
$("#loader").hide();
$("#upload_status").html(
"Upload failed with status " + code + " (" + error + ")");
$("#upload_result").html(response);
};
var discard_snapshot = function() {
var element = $(".item.selected").removeClass("item selected");
var next = element.nextAll(".item").first();
if (!next.size()) {
next = element.prevAll(".item").first();
}
if (next.size()) {
next.addClass("selected");
next.data("snapshot").show();
}
else {
hide_snapshot_controls();
}
element.data("snapshot").discard();
element.hide("slow", function() {$(this).remove()});
};
var show_stream = function() {
$(this).hide();
$(".item").removeClass("selected");
hide_snapshot_controls();
clear_upload_data();
camera.show_stream();
};
var hide_snapshot_controls = function() {
$("#discard_snapshot, #upload_snapshot, #api_url").hide();
$("#upload_result, #upload_status").html("");
$("#show_stream").hide();
};
$("#take_snapshots").click(function() {take_snapshots(1);});
$("#snapshots").on("click", ".item", select_snapshot);
$("#upload_snapshot").click(upload_snapshot);
$("#discard_snapshot").click(discard_snapshot);
$("#show_stream").click(show_stream);
$(document).on("keypress", function (e) {
take_snapshots(1);
});
var options = {
}
camera = new JpegCamera("#camera", options).ready(function(info) {
//$("#take_snapshots").show();
$("#camera_info").html(
"Camera resolution: " + info.video_width + "x" + info.video_height);
this.get_stats(update_stream_stats);
});
}
});

43
photos/static/tags Normal file

File diff suppressed because one or more lines are too long

3
photos/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

43
photos/views.py Normal file
View file

@ -0,0 +1,43 @@
import io
import os
from PIL import Image
from django.conf import settings
from django.core.files.storage import default_storage
from django.http import JsonResponse, Http404, HttpResponse
from django.shortcuts import render
from django.utils.datetime_safe import datetime
from django.views.decorators.http import require_POST
from photos.models import Photo
def index(request):
return render(request, 'index.html')
def show(request, pk):
try:
photo = Photo.objects.get(pk=pk)
with open(photo.photo.path, "rb") as f:
return HttpResponse(f.read(), content_type="image/jpeg")
except Photo.DoesNotExist:
raise Http404()
def photo_list(request):
return JsonResponse([{
'id': p.id,
'created_at': str(p.added_on),
'updated_at': str(p.added_on),
'url': p.get_absolute_url(),
} for p in Photo.objects.all().order_by('-id')], safe=False)
@require_POST
def file_upload(request):
save_path = os.path.join(settings.MEDIA_ROOT, 'photos', "{}.jpg".format(datetime.now()))
path = default_storage.save(save_path, request)
photo = Photo.objects.create(photo=path)
return JsonResponse({'picture': photo.id})