too many changes to enumerate, sorry. working state. now to break it again..

This commit is contained in:
sanj 2010-07-27 06:02:02 +05:30
parent b7ad384456
commit cc6b01d938
11 changed files with 173 additions and 42 deletions

View File

@ -5,6 +5,7 @@ from django.contrib.comments.signals import comment_was_posted
import simplejson
from django.core.mail import send_mail
import os
from os.path import join
from PIL import Image
from django.template import Template, Context
from django.template.loader import get_template
@ -64,7 +65,7 @@ class Link(models.Model):
class ProductType(models.Model):
name = models.CharField(max_length=255)
aspect_ratio = models.FloatField(default=0.707, help_text="Default 0.707 as per http://en.wikipedia.org/wiki/Paper_size")
print_width = models.IntegerField(help_text="Unit: mm")
print_width = models.IntegerField(default=210, help_text="Default: A4 (210mm) Unit: mm")
def __unicode__(self):
return self.name
@ -148,6 +149,7 @@ For image_resize, prop = 'image_resize'
class Revision(models.Model):
article = models.ForeignKey("Article")
page = models.ForeignKey("Page")
user = models.ForeignKey(User)
box_type = models.CharField(max_length=100)
box_id = models.IntegerField()
prop = models.CharField(max_length=100)
@ -158,7 +160,7 @@ class Revision(models.Model):
def saveRevision(r):
page = Page.objects.get(pk=r['page_id'])
article = page.article
rev = Revision(article=article, page=page, box_type=r['box_type'], box_id=r['box_id'], prop=r['prop'], old_val=r['old_val'], new_val=r['new_val'], uuid=r['uuid'])
rev = Revision(article=article, page=page, user=r.user, box_type=r['box_type'], box_id=r['box_id'], prop=r['prop'], old_val=r['old_val'], new_val=r['new_val'], uuid=r['uuid'])
rev.save()
return rev.id
@ -389,7 +391,7 @@ class TextBox(models.Model):
background_color = models.CharField(max_length=16)
border_style = models.CharField(max_length=16)
border_width = models.IntegerField()
# direction = models.CharField(max_length=8)
direction = models.CharField(max_length=8)
# line_height = models.IntegerField(blank=True, null=True)
# letter_spacing = models.IntegerField(blank=True, null=True)
# word_spacing = models.IntegerField(blank=True, null=True)
@ -423,7 +425,7 @@ class TextBox(models.Model):
'left': addPx(self.left),
'z-index': self.z_index,
'opacity': self.opacity,
# 'direction': self.direction,
'direction': self.direction,
'border-style': self.border_style,
'border-width': addPx(self.border_width),
'border-color': self.border_color,
@ -538,16 +540,18 @@ class ImageBox(models.Model):
This function returns the filename of the highest res original dimensions file, converted to jpeg
"""
def original_print(self):
'''
basePath = "media/images/original/"
filename = os.path.basename(str(self.file.file))
if extFileName(filename) != 'jpg':
f = baseFileName(filename) + ".jpg"
else:
f = filename
return basePath + f
'''
return str(self.file.file)
def crop(self, x1, y1, x2, y2, width, height):
original_image = Image.open(MEDIA_ROOT + "/" + self.actual_unresized())
original_image = Image.open(join(MEDIA_ROOT, self.actual_unresized()))
original_width = original_image.size[0]
original_height = original_image.size[1]
current_width = self.width
@ -577,16 +581,17 @@ class ImageBox(models.Model):
return self
def cropped_fname(self):
filename = baseFileName(os.path.basename(self.original_print()))
cropped_fname = "%s_%d_%d_%d_%d.jpg" % (filename, self.crop_x1, self.crop_y1, self.crop_x2, self.crop_y2)
filename = os.path.splitext(os.path.basename(self.original_print()))[0]
cropped_fname = "%s_%d_%d_%d_%d.%s" % (filename, self.crop_x1, self.crop_y1, self.crop_x2, self.crop_y2, self.file.ext)
return cropped_fname
def cropped_path(self):
return MEDIA_ROOT + "/media/images/cropped/" + self.cropped_fname()
return os.path.dirname(str(self.file.file))
# return MEDIA_ROOT + "/media/images/cropped/" + self.cropped_fname()
def actual_unresized(self):
if self.is_cropped:
return "media/images/cropped/" + self.cropped_fname()
return join(self.cropped_path(), self.cropped_fname())
else:
return self.original_print()
@ -653,7 +658,7 @@ def comments_notify(sender, **kwargs):
img_id = comment.content_object.id
url = "http://edgwareroad.org/slider/%d" % (img_id)
message = "Page: %s \n Name: %s \n Email: %s \n Comment: %s" % (url, name, email, content)
send_mail("New comment on edgwareroad.org", message, "do_not_reply@edgwareroad.org", ["hello@edgwareroad.org"])
send_mail("New comment on edgwareroad.org", message, "do_not_reply@edgwareroad.org", ["hello@edgwareroad.org", "sanjaybhangar@gmail.com"])
# f = open("/home/sanj/tmp/edgeTest.txt", "w")
# f.write(message)
return True

View File

@ -17,6 +17,7 @@ from settings import MEDIA_ROOT
from PIL import Image
import os
from print_pdf import print_url_list
from settings import SITE_BASE
@login_required
def editor(request):
@ -127,6 +128,7 @@ def imagebox_crop(request):
old_value = json.dumps({'path': thisBox.get_path(), 'height': thisBox.height, 'width': thisBox.width})
thisBox.crop(int(o['x1']), int(o['y1']), int(o['x2']), int(o['y2']), o['width'], o['height'])
revision_id = saveRevision({
'user': request.user,
'box_id': thisBox.id,
'box_type': 'image',
'prop': 'image_crop',
@ -161,6 +163,7 @@ def textbox_new(request):
box.set_css(prop, val)
box.save()
revision_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'text',
'prop': 'new_box',
@ -189,6 +192,7 @@ def textbox_update_css(request):
old_value = box.get_css(prop)
box.set_css(prop, val)
revision_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'text',
'prop': prop,
@ -218,6 +222,7 @@ def textbox_set_html(request):
box.html = html
box.save()
revision_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'text',
'prop': 'html',
@ -239,6 +244,7 @@ def textbox_delete(request):
box.is_displayed = False
box.save()
rev_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'text',
'prop': 'delete_box',
@ -263,6 +269,7 @@ def imagebox_new(request):
box.set_css(prop, val)
box.save()
revision_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'image',
'prop': 'new_box',
@ -289,6 +296,7 @@ def imagebox_update_css(request):
old_value = box.get_css(prop)
box.set_css(prop, val)
revision_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'image',
'prop': prop,
@ -322,6 +330,7 @@ def imagebox_resize(request):
box.save()
resizedPath = box.get_path()
revision_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'image',
'prop': 'image_resize',
@ -349,6 +358,7 @@ def imagebox_delete(request):
box.is_displayed = False
box.save()
rev_id = saveRevision({
'user': request.user,
'box_id': box.id,
'box_type': 'image',
'prop': 'delete_box',
@ -421,7 +431,7 @@ def category_json(request):
'media_id': media_id
}
rList.append(d)
j = json.dumps(rList)
j = json.dumps({'resources': rList})
return HttpResponse(j, mimetype="application/json")
else:
return False
@ -527,7 +537,7 @@ def page_pdf(request):
print_width_mm = article.product.typ.print_width
print_height_mm = int(print_width_mm // article.product.typ.aspect_ratio)
output_path = MEDIA_ROOT + "/pdf/tmpPDF" + article_id + page_id + ".pdf"
cmd = "wkhtmltopdf --page-width %d --page-height %d 'http://edgwareroad.org/edit/view_article/%s/?m=%f&p=%s' '%s'" % (print_width_mm, print_height_mm, article_id, m, page_id,output_path,)
cmd = "wkhtmltopdf --page-width %d --page-height %d '%s/edit/view_article/%s/?m=%f&p=%s' '%s'" % (print_width_mm, print_height_mm, SITE_BASE, article_id, m, page_id,output_path,)
os.system(cmd)
return HttpResponseRedirect(output_path.replace(MEDIA_ROOT, "/static"))
@ -555,10 +565,26 @@ def product_pdf(request):
m = product.get_print_multiplier(dpi)
url_list = []
for p in pages:
url = "http://edgwareroad.org/edit/view_article/%d/?m=%f&p=%d'" % (p.article.id, m, p.id)
url = SITE_BASE + "/edit/view_article/%d/?m=%f&p=%d'" % (p.article.id, m, p.id)
url_list.append(url)
output_path = MEDIA_ROOT + "/pdf/" + self.title + ".pdf"
pdf_path = print_url_list(url_list, width, height, output_path)
output_path = MEDIA_ROOT + "/pdf/" + product.title + ".pdf"
pdf_path = print_url_list(url_list, width_mm, height_mm, output_path)
return HttpResponseRedirect(pdf_path.replace(MEDIA_ROOT, "/static"))
def article_pdf(request):
a_id = request.GET['id']
article = get_object_or_404_json(Article, pk=a_id)
dpi = request.GET.get('dpi', 150)
width_mm = request.GET.get('width', article.product.typ.print_width)
height_mm = int(width_mm // product.typ.aspect_ratio)
pages = Page.objects.filter(article=article)
m = article.get_print_multiplier(dpi)
url_list = []
for p in pages:
url = SITE_BASE + "/edit/view_article/%d/?m=%f&p=%d'" % (p.article.id, m, p.id)
url_list.append(url)
output_path = MEDIA_ROOT + "/pdf/" + article.name + "_" + str(article.current_revision()) + ".pdf"
pdf_path = print_url_list(url_list, width_mm, height_mm, output_path)
return HttpResponseRedirect(pdf_path.replace(MEDIA_ROOT, "/static"))
def article_json(request):
@ -580,6 +606,7 @@ def new_page(request):
p.page_no = last_page_no + 1
p.save()
rev_id = saveRevision({
'user': request.user,
'box_id': 0,
'box_type': 'page',
'prop': 'new_page',
@ -597,7 +624,9 @@ def new_page(request):
@login_required_json
def delete_page(request):
page = get_object_or_404_json(Page, id=request.GET['id'])
page.delete()
rev_id = saveRevision({
'user': request.user,
'box_id': 0,
'box_type': 'page',
'prop': 'delete_page',

View File

@ -8,6 +8,7 @@ class filesForm(forms.ModelForm):
file = forms.FileField(label='Upload File',
required=False,
widget=FirefoggInput({'passthrough': True}))
exclude = ('info',)
class Meta:
model = File

View File

@ -16,6 +16,8 @@ def toJpg(f):
return
def toOgg(f):
if f.ext == 'ogg':
return
output_path = "%s/media/audio/%s" % (MEDIA_ROOT, e.models.baseFileName(os.path.basename(f.file.path)) + ".ogg",)
cmd = "ffmpeg2theora -o '%s' --no-skeleton --novideo '%s'" % (output_path, f.file.path,)
os.system(cmd)
@ -28,6 +30,8 @@ def toTxt(f):
# print f.file
def toOgv(f):
if f.ext == 'ogv':
return
output_path = "%s/media/video/%s" % (MEDIA_ROOT, e.models.baseFileName(os.path.basename(f.file.path)) + ".ogv",)
if e.models.extFileName(str(f.file)).lower() == 'ogv' or e.models.extFileName(str(f.file)).lower() == 'ogg':
cmd = "cp %s %s" % (f.file.path, output_path)
@ -44,7 +48,7 @@ def ignoreFile(f):
#This function is called from the post_save signal, receives kwargs['instance'] as a File instance
def convertFile(**kwargs):
fn = {
'jpg': toJpg,
'jpg': ignoreFile,
'mp3': toOgg,
'txt': ignoreFile,
'ogv': toOgv,

View File

@ -4,9 +4,13 @@ from oxdjango.fields import DictField
from tagging.models import Tag
from django.contrib.auth.models import User, Group, Permission
import os
from os.path import join
from convert import convertFile
from django.db.models.signals import post_save
from settings import UPLOAD_ROOT, MEDIA_ROOT
from utils.add_file import hashFile, fileInfo
#FIXME: The following two functions are ridiculous. please remove and clean up all references to them.
def baseFileName(filename):
r = filename.rindex('.')
return filename[0:r]
@ -19,7 +23,8 @@ def extFileName(filename):
MIME_TYPES = (
('jpg', 'Image'),
('ogv', 'Video'),
('mp3', 'Audio'),
('mp3', 'Audio (mp3)'),
('ogg', 'Audio (Ogg)'),
('txt', 'Text'),
('oth', 'Other'),
('hid', 'Hidden'),
@ -32,7 +37,7 @@ class Folder(models.Model):
category = models.ForeignKey("Category")
def get_full_path(self):
return join(UPLOAD_ROOT, category.folder_name, parent.
return join(UPLOAD_ROOT, self.category.folder_name, self.relative_path)
def get_children(self):
return Folder.objects.filter(parent=self)
@ -57,7 +62,8 @@ class Folder(models.Model):
class File(models.Model):
file = models.FileField('File', upload_to='files')
file = models.FileField('File', upload_to=UPLOAD_ROOT)
full_path = models.CharField(max_length=2048, blank=True, db_index=True) #makes it more efficient to retrieve a file by path instead of using self.file.path
title = models.CharField(max_length=255)
description = models.TextField(blank=True)
tags = TagField("Tags", help_text="Enter as many tags as you like, separated by commas")
@ -66,25 +72,62 @@ class File(models.Model):
added = models.DateField("Date Added", auto_now_add=True)
categories = models.ManyToManyField('Category', verbose_name='Studies')
type = models.ForeignKey('Type', verbose_name='File Type')
folder = models.ForeignKey("Folder")
info = DictField(blank=True, null=True)
ext = models.CharField(max_length=100, blank=True)
oshash = models.CharField(max_length=128, blank=True, db_index=True)
# folder = models.ForeignKey("Folder")
info = DictField(blank=True)
@classmethod
def add_from_path(cls, category, user, path, **kwargs):
if cls.objects.filter(full_path=path).count() > 0:
#Do update checking here. For now, we move on if it already exists in db
return False
info = fileInfo(path)
oshash = hashFile(path)
dirname = os.path.dirname(path)
filename = os.path.basename(path)
title = kwargs.get("title", filename)
description = kwargs.get("description", "")
ext = os.path.splitext(filename)[1][1:]
django_file_path = UPLOAD_ROOT.replace(MEDIA_ROOT, "")[1:]
f = cls(file=django_file_path, full_path=path, title=title, description=description, ext=ext, oshash=oshash, info=info)
f.userID = user
f.save()
f.categories.append(category)
f.save_m2m()
return f
@classmethod
def addFiles(cls, category, user, folder_name):
path = join(UPLOAD_ROOT, folder_name)
# spider(path, addFile, category=category)
for dirpath, dirnames, filenames in os.walk(path):
if filenames:
# prefix = dirpath[len(path)+1:]
for filename in filenames:
if not filename.startswith('._') and not filename in ('.DS_Store', ):
cls.add_from_path(category, user, join(dirpath, filename))
# print dirpath + " + " + filename
def __unicode__(self):
return self.title
def original_print(self):
'''
basePath = "media/images/original/"
filename = os.path.basename(str(self.file.url))
if extFileName(filename).lower() != 'jpg':
f = baseFileName(filename) + ".jpg"
else:
f = filename
return basePath + f
'''
return str(self.file)
class Category(models.Model):
name = models.CharField(max_length=255)
groups = models.ManyToManyField(Group, null=True)
folder_name = models.CharField(max_length=512)
# folder_name = models.CharField(max_length=512)
def __unicode__(self):
return self.name

View File

@ -13,6 +13,7 @@ LOGGING_OUTPUT_ENABLED = True
INTERNAL_IPS = ('127.0.0.1',)
PROJECT_PATH = os.path.dirname(__file__)
SITE_BASE = "http://localhost:8000"
ADMINS = (
# ('Your Name', 'your_email@domain.com'),
@ -49,7 +50,7 @@ USE_I18N = True
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = join(PROJECT_PATH, 'static')
UPLOAD_ROOT = join(MEDIA_ROOT, 'media', 'studies')
UPLOAD_ROOT_RELATIVE = UPLOAD_ROOT.replace(MEDIA_ROOT, "")[1:]
# 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/"
@ -72,6 +73,8 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.csrf.CsrfResponseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
@ -99,9 +102,10 @@ INSTALLED_APPS = (
'django_extensions',
'django.contrib.flatpages',
'debug_toolbar',
'south',
# 'south',
'django.contrib.comments',
'sorl.thumbnail',
# 'utils',
# 'django_firefogg',
)

View File

@ -8,13 +8,16 @@ CKEDITOR.editorConfig = function( config )
config.toolbar_Basic =
[
['Bold', 'Italic', '-', 'FontSize', 'TextColor', 'JustifyLeft','JustifyCenter','JustifyRight']
['Bold', 'Italic', '-', 'FontSize', 'Font', 'TextColor', 'JustifyLeft','JustifyCenter','JustifyRight']
];
config.toolbar_Min =
[
];
config.contentsCss = '/static/css/fonts.css';
config.font_names = "Berlin Safari;SG Grotesque;Tallys;GraublauWeb;Fontin;Tagesschrift;";
// Define changes to default configuration here. For example:
// config.language = 'fr';

View File

@ -231,7 +231,7 @@ p {
left: 4px;
}
#searchSelect {
.binSelect {
width: 208px;
font-size: 12px;
margin-left: 7px;

View File

@ -1,3 +1,4 @@
@font-face {
font-family: GraublauWeb;
src: url(/static/fonts/GraublauWeb.otf) format("opentype");
@ -19,7 +20,29 @@
src: url(/static/fonts/YanoneTagesschrift.ttf) format("truetype");
}
@font-face {
font-family: "Berlin Safari";
src: url(/static/fonts/berlinsafari.ttf) format("truetype");
}
@font-face {
font-family: "SG Grotesque";
src: url('/static/fonts/SG Grotesque.otf' format("opentype");
}
@font-face {
font-family: "SG Grotesque";
src: url('/static/fonts/SG Grotesque Bold.otf' format("opentype");
font-weight: bold;
}
@font-face {
font-family: "SG Grotesque";
src: url('/static/fonts/SG Grotesque Italic.otf' format("opentype");
font-weight: italic;
}
body {
font-size: 14px;
}

View File

@ -16,6 +16,7 @@ var loadArticle = function(id) {
});
}
//is used by the poller to call itself 1 second in the future. not sure why im doing this. FIXME: function name at least?
function delayedRecursion(time) {
// console.log("delayed recursion called" + time);
POLLER = setTimeout(startPoller, time);
@ -103,6 +104,7 @@ function handleRevision(json) {
var val = toPx(json.new_val);
}
d[json.prop] = val;
//dont try and animate properties like 'transparent', it will fail.
if (d[json.prop] == 'transparent' || json.old_val == 'transparent') {
box.jq.css(d);
} else {
@ -145,9 +147,11 @@ $(document).ready(function() {
$('.prevPage').click(function() {
edgeBin.prevPage();
});
$('.nextPage').click(function() {
edgeBin.nextPage();
});
$('.searchBin').keyup(function() {
edgeBin.searchString($(this).val());
});
@ -340,6 +344,7 @@ Canvas.prototype.toObj = function() {
// console.log(json);
}
//this function is not used. FIXME: remove
Canvas.prototype.save = function() {
var that = this;
var url = "/editor/canvas/save/";
@ -798,7 +803,7 @@ Bin.prototype.loadCategory = function(catid) {
this.jq.find('.resource').remove();
this.resources = [];
$.getJSON("/edit/category/json/", {'id': catid}, function(json) {
var resources = json;
var resources = json.resources;
for (r in resources) {
if (resources.hasOwnProperty(r)) {
thisResource = new Resource(resources[r], r);
@ -810,6 +815,13 @@ Bin.prototype.loadCategory = function(catid) {
});
};
Bin.prototype.loadResources = function(url, params) {
var that = this;
this.jq.find('.resource').remove();
this.resources = [];
}
Bin.prototype.searchString = function(str) {
var that = this;
@ -1158,7 +1170,7 @@ function replaceDiv( div ) {
// })
console.log(div);
// console.log(div);
// alert($(div).attr('classname'));
height = parseInt($(div).css('height')) - 6;
height = toPx(height);
@ -1230,7 +1242,7 @@ $(".box").live("click", function(e){
var box = $(this).find('*').getBox().jq;
var boxObj = $(this).find('*').getBox();
if ($(".properties").length == 0) {
console.log($(this).attr('class'))
// console.log($(this).attr('class'))
if ($(this).hasClass("textBox")) {
$('body').append(tmpl('tmpl_textbox_properties', {}));
}

View File

@ -205,11 +205,18 @@
</div>
</div>
<div id="addElements">
<select id="searchSelect" name="searchSelect">
<select id="searchSelect" class="binSelect" name="searchSelect">
<option value="0">Choose a Study</option>
{% for c in categories %}
<option value="{{c.id}}">{{c.name}}</option>
{% endfor %}
</select><br />
<select id="typeSelect" class="binSelect" name="typeSelect">
<option value="0">Chose a Type</option>
<option value="images">Images</option>
<option value="audio">Audio</option>
<option value="video">Video</option>
<option value="text">Text</option>
</select>
<div style="clear:both;"></div>
<div class="navControls">