edgware/edgware/files/models.py

240 lines
7.0 KiB
Python
Executable File

from django.db import models
from tagging.fields import TagField
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, getFileType
from django.core.files.base import ContentFile
import operator
from django.db.models import Q
from ox.text import smartSplit
from sorl.thumbnail import get_thumbnail
#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]
def extFileName(filename):
r = filename.rindex('.') + 1
return filename[r:]
def splitSearch(string):
ret = []
for s in smartSplit(string):
word = s.replace("'", "").replace('"', '')
ret.append(word)
return ret
MIME_TYPES = (
('jpg', 'Image'),
('png', 'Image'),
('ogv', 'Video'),
('mp3', 'Audio (mp3)'),
('ogg', 'Audio (Ogg)'),
('txt', 'Text'),
('oth', 'Other'),
('hid', 'Hidden'),
)
TYPE_CHOICES = (
('', '---'),
('image', 'Image'),
('audio', 'Audio'),
('text', 'Text'),
('video', 'Video'),
('other', 'Other'),
)
class Folder(models.Model):
name = models.CharField(max_length=1024)
relative_path = models.CharField(max_length=2048)
parent = models.ForeignKey("Folder")
category = models.ForeignKey("Category")
def get_full_path(self):
return join(UPLOAD_ROOT, self.category.folder_name, self.relative_path)
def get_children(self):
return Folder.objects.filter(parent=self)
def has_parent(self):
if self.name == self.category.folder_name:
return False
else:
return True
def get_files(self):
return File.objects.filter(folder=self)
def get_dict(self):
return {
'files': self.get_files(),
'folders': self.get_children(),
'parent': self.parent,
'name': self.name,
'fullPath': self.fullPath
}
class File(models.Model):
file = models.FileField('File', upload_to=UPLOAD_ROOT, max_length=1024)
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)
done = models.BooleanField(default=False)
description = models.TextField(blank=True)
tags = TagField("Tags", help_text="Enter as many tags as you like, separated by commas")
userID = models.ForeignKey(User)
file_date = models.DateField("Date", blank=True, null=True)
added = models.DateField("Date Added", auto_now_add=True)
categories = models.ManyToManyField('Category', verbose_name='Studies')
# type = models.ForeignKey('Type', verbose_name='File Type')
type = models.CharField(max_length=255, choices=TYPE_CHOICES)
ext = models.CharField(max_length=100, blank=True)
oshash = models.CharField(max_length=128, blank=True, db_index=True)
# folder = models.ForeignKey("Folder")
info = models.CharField(max_length=1024, blank=True, null=True)
fts_fields = ['title', 'description']
@classmethod
def filter_category(kls, category_id, qset):
return qset.filter(categories=category_id)
@classmethod
def filter_type(kls, typ, qset):
return qset.filter(type__iexact=typ)
@classmethod
def fts(kls, search, qset):
terms = splitSearch(search)
qobjects = []
for t in terms:
for f in kls.fts_fields:
qstring = f + '__icontains'
qobject = Q(**{qstring:t})
qobjects.append(qobject)
return qset.filter(reduce(operator.or_, qobjects))
def get_dict(self):
#FIXME
try:
url = self.file.url
if self.type.lower() == 'image':
thumbnail = get_thumbnail(open(self.file.path), "400x300", crop='center', quality=60).url
else:
thumbnail = ''
except:
url = ''
thumbnail = ''
studies = [{'id': s.id, 'name': s.name} for s in self.categories.all()]
return {
'id': self.id,
'url': url,
'thumbnail': thumbnail,
'title': self.title,
'description': self.description,
'type': self.type,
'studies': studies
}
def save_chunk(self, chunk, name='data.bin'):
if not self.done:
if not self.file:
self.file.save(name, ContentFile(chunk))
self.title = name
self.save()
else:
f = open(self.file.path, 'a')
f.write(chunk)
f.close()
return True
return False
@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:].lower()
typ = getFileType(path, ext)
django_file_path = join(path.replace(MEDIA_ROOT, "")[1:])
f = cls(file=django_file_path, full_path=path, title=title, description=description, ext=ext, type=typ, oshash=oshash, info=info)
f.userID = user
f.save()
f.categories.add(category)
# f.save()
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 str(self.file)
def move_to(self, study):
self.categories.clear()
self.categories.add(study)
self.save()
return self
class Category(models.Model):
name = models.CharField(max_length=255)
groups = models.ManyToManyField(Group, null=True)
# folder_name = models.CharField(max_length=512)
def __unicode__(self):
return self.name
class Meta:
ordering = ['name']
verbose_name = 'Study'
verbose_name_plural = 'Studies'
class Type(models.Model):
name = models.CharField(max_length=255)
mime = models.CharField(choices=MIME_TYPES, verbose_name="Type of File", blank=True, null=True, max_length=20)
# mim = models.ChoiceField(choices=MIME_TYPES)
def __unicode__(self):
return "%s - %s" % (self.name, self.mime)
class Meta:
verbose_name = 'File Type'
verbose_name_plural = 'File Types'
post_save.connect(convertFile, sender=File)