import os.path import struct import re from hashlib import md5 from datetime import datetime, timedelta from django.core.urlresolvers import reverse from django.contrib.auth.models import User from django.db import models vertex_pattern = re.compile(r'vertex\s+([0-9.e+-]+)\s+([0-9.e+-]+)\s+([0-9.e+-]+)') def safe_upload_path(base_dir): def generate_path(instance, filename): ext = os.path.splitext(filename)[1] md5sum = md5() md5sum.update(instance.name + str(datetime.now()) + filename) randomname = md5sum.hexdigest() return os.path.join(base_dir,'%s%s' % (randomname, ext)) return generate_path class Geometry(models.Model): HOUR = 0 DAY = 1 WEEK = 2 MONTH = 3 FORERVER = 4 EXPIRATION_CHOICES = ((HOUR, 'one hour'), (DAY, 'one day'), (WEEK, 'one week'), (MONTH, 'one month'), (FORERVER, 'forever')) DELTAS = { HOUR : timedelta(hours = 1), DAY : timedelta(days = 1), WEEK : timedelta(weeks = 1), MONTH : timedelta(weeks = 4)} name = models.CharField(max_length = 128) description = models.TextField(blank=True) user = models.ForeignKey(User, blank=True, null=True) date = models.DateTimeField(auto_now_add=True) expiration = models.IntegerField(default = 0, choices = EXPIRATION_CHOICES) public = models.BooleanField(default=True) polycount = models.IntegerField(blank=True, default=0) width = models.FloatField(blank=True, default=0) depth = models.FloatField(blank=True, default=0) height = models.FloatField(blank=True, default=0) file = models.FileField(upload_to=safe_upload_path('models')) sourcefile = models.FileField(upload_to=safe_upload_path('sources'), blank=True) def get_absolute_url(self): return reverse('geometry_details', kwargs={'id' : self.pk}) @classmethod def get_latest(cls): return cls.objects.all().filter(public = True).order_by('-date')[:10] def get_expiration_date(self): for expiration in [self.HOUR, self.DAY, self.WEEK, self.MONTH]: if self.expiration == expiration: return self.date + self.DELTAS[expiration] return None def _generate_meta_infos(self): print "Generating metainfos %s" % self.name self.file.open() count = 0 min_coord = [None,None,None] max_coord = [None,None,None] if self.file.read(5) != "solid": print "binary" #Skip header self.file.seek(80) count = struct.unpack("i",self.file.read(4))[0] done = False for pos in range(0,count): #Skip normal (3 * 32bit) self.file.seek(self.file.tell()+3*4) #Loop over each coordinate for vert in range(0,3): # Loop over each coordinate for i in range(0,3): x = struct.unpack("