def generateThumbnail(self): """Generates a square thumbnail""" source = getRoot() / self.source.name thumbnail = source.parent / '_{}.jpg'.format(source.namebase) # -- Save thumbnail and put into queue poster = source.parent / '__{}.jpg'.format(source.namebase) cmd = [ FROG_FFMPEG, '-i', str(source), '-vframes', '1', str(thumbnail), '-y' ] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) proc.communicate() image = pilImage.open(thumbnail) image.save(poster) self.poster = poster.replace(getRoot(), '') # Resize width, height = squareCropDimensions(self.width, self.height) image.thumbnail((width, height), pilImage.ANTIALIAS) # Crop from center box = cropBox(*image.size) image = image.crop(box) # save self.thumbnail = thumbnail.replace(getRoot(), '') image.save(thumbnail)
def post(request): res = Result() config = SiteConfig.getSiteConfig() try: data = json.loads(request.body)["body"] config.name = data.get("name", config.name) config.link = data.get("link", config.link) config.enable_likes = data.get("enable_likes", config.enable_likes) if data.get("default_gallery"): gallery = Gallery.objects.get(pk=data["default_gallery"]) config.default_gallery = gallery except RawPostDataException: if request.FILES.get("favicon"): dest = getRoot() / "favicon.ico" handle_uploaded_file(dest, request.FILES["favicon"]) config.favicon = "favicon.ico" if request.FILES.get("icon"): dest = getRoot() / request.FILES["icon"].name handle_uploaded_file(dest, request.FILES["icon"]) config.favicon = request.FILES["icon"].name config.save() res.append(SiteConfig.getSiteConfig().json()) return JsonResponse(res.asDict())
def getFiles(self): path = self.getPath() allfiles = path.files() thumb = Path(self.thumbnail.name).name.replace(self.hash, self.title).replace( '\\', '/') source = Path(self.source.name).name.replace(self.hash, self.title).replace( '\\', '/') files = {} files[thumb] = getRoot() + self.thumbnail.name files[source] = getRoot() + self.source.name if not files[thumb].exists(): del files[thumb] if not files[source].exists(): del files[source] for file_ in allfiles: if not re.findall('([0-9A-Za-z]{40}\.\w+)', file_): files[file_.name] = file_.replace('\\', '/') return files
def generateThumbnail(self): """Generates a square thumbnail""" image = pilImage.open(getRoot() / self.source.name) box, width, height = cropBox(self.width, self.height) # Resize image.thumbnail((width, height), pilImage.ANTIALIAS) # Crop from center box = cropBox(*image.size)[0] image = image.crop(box) # save self.thumbnail = self.source.name.replace(self.hash, '{0}{1}'.format('_' * 3, self.hash)) image.save(getRoot() / self.thumbnail.name)
def post(request): data = json.loads(request.body)["body"] name = data["domain"].replace(".", "_").replace("-", "_") quota = data["quota"] created = False client = Client.objects.filter(schema_name=name) if client: client = client[0] else: client = Client(schema_name=name, name=name, space_quota=quota) client.save() created = True if not client.domains.count(): domain = Domain() domain.domain = data["domain"] domain.tenant = client domain.is_primary = True domain.save() with tenant_context(client): if created: # Create superuser call_command("createsuperuser", username="******", email="admin@{}".format(data["domain"]), interactive=False) # Run Fixtures call_command("loaddata", "initial_data.json", app="frog") item = client.toJson() item['image'] = None item['image_count'] = Image.objects.all().count() item['video_count'] = Video.objects.all().count() item['site_config'] = None item['managers'] = [] item['user_count'] = User.objects.all().count() item['history'] = [] item['space_used'] = math.ceil( getFolderSize(getRoot()) / float(1 << 27)) item['tenant_created'] = created staticroot = pathlib.Path(getRoot()) if not staticroot.exists(): staticroot.mkdir(parents=True) res = item return JsonResponse(res)
def export(self, hashVal, hashPath, tags=None, galleries=None): """""" self.source = hashPath.replace('\\', '/').replace(getRoot(), '') galleries = galleries or [] tags = tags or [] self.generateThumbnail() for gal in galleries: g = Gallery.objects.get(pk=int(gal)) g.marmosets.add(self) for tag in g.tags.all(): self.tags.add(tag) self.tagArtist() for tagName in tags: tag = Tag.objects.get_or_create(name=tagName)[0] self.tags.add(tag) if not self.guid: self.guid = self.getGuid().guid # -- Posix paths only self.source = self.source.name.replace('\\', '/') self.save()
def info(self): cmd = [ FROG_FFPROBE, '-select_streams', 'v:0', '-show_entries', 'stream=width,height,codec_name,duration,avg_frame_rate', '-of', 'json', getRoot() / self.source.file.name ] try: output = subprocess.check_output(cmd) except subprocess.CalledProcessError as err: output = '' rawdata = json.loads(output) framerates = rawdata['streams'][0]['avg_frame_rate'].split('/') if len(framerates) == 2: framerate = int(framerates[0]) / (int(framerates[1]) or 1) else: framerate = int(framerates[0]) data = { 'width': rawdata['streams'][0]['width'], 'height': rawdata['streams'][0]['height'], 'framerate': framerate or 30, 'codec': rawdata['streams'][0]['codec_name'].lower(), 'duration': float(rawdata['streams'][0]['duration']), } return data
def post(request): res = Result() data = json.loads(request.POST["body"]) tag = Tag.objects.get(name=data['tag']) badge = Badge.objects.get_or_create(tag=tag)[0] if request.FILES.get("image"): incomingfilename = pathlib.Path(request.FILES["image"].name) filename = '{}{}'.format(tag.name, incomingfilename.suffix) dest = getRoot() / "badges" / filename if not dest.parent.exists(): dest.parent.makedirs_p() handle_uploaded_file(dest, request.FILES["image"]) badge.image = "badges/{}".format(filename) if badge: badge.save() res.append(badge.json()) else: res.isError = True res.message = "No badge found" return JsonResponse(res.asDict())
def convert_video(self, item): video = item.video # -- Set the video to processing LOGGER.info("Processing video: %s" % video.guid) item.status = VideoQueue.PROCESSING item.message = "Processing video..." item.save() sourcepath = getRoot() / video.source.name # -- Get the video information videodata = video.info() isH264 = "h264" in videodata["codec"] and sourcepath.ext == ".mp4" tempfile = path.Path(FROG_VIDEO_TEMP) / "{}.mp4".format(video.hash) outfile = sourcepath.parent / "{}.mp4".format(video.hash) # -- Further processing is needed if not h264 or needs to be scrubbable if isH264: # -- No further processing video.video = video.source.name else: LOGGER.info("Converting video: %s" % video.guid) item.message = "Converting to MP4..." item.save() args = FROG_FFMPEG_ARGS cmd = [FROG_FFMPEG, "-i", str(sourcepath)] width = (item.video.width - 1 if item.video.width % 2 else item.video.width) height = (item.video.height - 1 if item.video.height % 2 else item.video.height) if width != item.video.width or height != item.video.height: cmd += [ "-filter:v", "crop={0}:{1}:0:0".format(width, height), ] cmd += args.format(*QUALITY[self._quality]).split(" ") cmd += [str(tempfile)] LOGGER.debug(cmd) subprocess.call(cmd) video.video = outfile.replace("\\", "/").replace(ROOT, "") shutil.move(tempfile, outfile) # -- Set the video to the result item.delete() video.save() if self._emailuser: # -- Email User emailUser(video)
def media(request): obj = { "MEDIA_URL": settings.MEDIA_URL, "MEDIA_ROOT": getRoot(), "isAjax": request.is_ajax(), "plugins": PluginContext, "build": BUILD, "SITE_URL": FROG_SITE_URL, } return obj
def export(self, hashVal, hashPath, tags=None, galleries=None): """ The export function needs to: - Move source image to asset folder - Rename to guid.ext - Save thumbnail, video_thumbnail, and MP4 versions. If the source is already h264, then only transcode the thumbnails """ self.source = hashPath.replace('\\', '/').replace(getRoot(), '') galleries = galleries or [] tags = tags or [] # -- Get info videodata = self.info() self.width = videodata['width'] self.height = videodata['height'] self.framerate = videodata['framerate'] self.duration = videodata['duration'] self.generateThumbnail() for gal in galleries: g = Gallery.objects.get(pk=int(gal)) g.videos.add(self) for tag in g.tags.all(): self.tags.add(tag) self.tagArtist() for tagName in tags: tag = Tag.objects.get_or_create(name=tagName)[0] self.tags.add(tag) if not self.guid: self.guid = self.getGuid().guid # -- Posix paths only self.source = self.source.name.replace('\\', '/') self.poster = self.poster.name.replace('\\', '/') self.thumbnail = self.thumbnail.name.replace('\\', '/') self.save() # -- Set the temp video while processing queuedvideo = VideoQueue.objects.get_or_create(video=self)[0] queuedvideo.save() try: item = VideoQueue() item.video = self item.save() except IntegrityError: # -- Already queued pass
def media(request): obj = { 'MEDIA_URL': settings.MEDIA_URL, 'MEDIA_ROOT': getRoot(), 'isAjax': request.is_ajax(), 'plugins': PluginContext, 'build': BUILD, 'SITE_URL': FROG_SITE_URL, } print obj return obj
def get(request): res = {"items": []} for client in Client.objects.exclude(schema_name="public"): with tenant_context(client): image = Image.objects.first() siteconfig = SiteConfig.objects.first() numdays = 7 today = datetime.datetime.today() last_30_days = today - datetime.timedelta(numdays) week_history = Image.objects.filter( created__gte=last_30_days).extra(select={ 'day': 'date(created)' }).values('day').annotate(dcount=Count('created')) history = [ today - datetime.timedelta(days=_) for _ in range(numdays) ] hist = [0 for _ in range(numdays)] for i, _ in enumerate(history): for obj in week_history: if obj['day'].day == _.day: hist[i] = obj['dcount'] item = client.toJson() item['image'] = image.json() if image else None item['image_count'] = Image.objects.all().count() item['video_count'] = Video.objects.all().count() item['site_config'] = siteconfig.json() if siteconfig else None try: item['managers'] = json.loads( serializers.serialize( "json", Group.objects.get(name="managers").user_set.all())) except: item['managers'] = [] item['user_count'] = User.objects.all().count() item['history'] = hist item['space_used'] = math.ceil( getFolderSize(getRoot()) / float(1 << 27)) res["items"].append(item) return JsonResponse(res)
def upload(request): res = Result() uploadfile = request.FILES.get("file") if uploadfile: filename = uploadfile.name path = request.POST.get("path", None) if path: foreignPath = path.replace("'", '"') else: foreignPath = filename galleries = request.POST.get("galleries", "1").split(",") tags = [ _.strip() for _ in request.POST.get("tags", "").split(",") if _ ] title = request.POST.get("title") description = request.POST.get("description", "") force = request.POST.get("force") try: username = request.POST.get("user", False) if username: user = User.objects.get(username=username) else: user = request.user uniqueName = request.POST.get("uid", Piece.getUniqueID(foreignPath, user)) if galleries and Gallery.objects.filter( pk__in=[int(g) for g in galleries], uploads=False): raise PermissionDenied() extension = Path(filename).ext.lower() if extension in FILE_TYPES["image"]: model = Image elif extension in FILE_TYPES["video"]: model = Video elif extension in FILE_TYPES["marmoset"]: model = Marmoset else: raise MediaTypeError( "{} is not a supported file type".format(extension)) obj, created = model.objects.get_or_create(unique_id=uniqueName, defaults={ "author": user, "hidden": False }) guid = obj.getGuid() hashVal = getHashForFile(uploadfile) if hashVal == obj.hash and not force: for gal in galleries: g = Gallery.objects.get(pk=int(gal)) obj.gallery_set.add(g) res.append(obj.json()) res.message = "Files were the same" return JsonResponse(res.asDict()) objPath = getRoot() / guid.guid[-2:] / guid.guid / filename hashPath = objPath.parent / hashVal + objPath.ext if not objPath.parent.exists(): objPath.parent.makedirs() # Save uploaded files to asset folder for key, uploadfile in request.FILES.items(): if key == "file": handle_uploaded_file(hashPath, uploadfile) else: dest = objPath.parent / uploadfile.name handle_uploaded_file(dest, uploadfile) if key == "thumbnail": thumbnail = saveAsPng(dest) # Resize image = pilImage.open(thumbnail) width, height = squareCropDimensions(*image.size) image.thumbnail((width, height), pilImage.ANTIALIAS) # Crop from center box = cropBox(*image.size) image.crop(box).save(thumbnail) obj.custom_thumbnail = obj.getPath( True) / thumbnail.name obj.save() obj.hash = hashVal obj.foreign_path = foreignPath obj.title = title or objPath.namebase obj.description = description obj.export(hashVal, hashPath, tags=tags, galleries=galleries) res.append(obj.json()) except MediaTypeError as err: res.isError = True res.message = str(err) return JsonResponse(res.asDict()) else: res.isError = True res.message = "No file found" return JsonResponse(res.asDict())
def export(self, hashVal=None, hashPath=None, tags=None, galleries=None): """ The export function needs to: - Move source image to asset folder - Rename to guid.ext - Save thumbnail, small, and image versions """ hashVal = hashVal or self.hash hashPath = hashPath or self.parent / hashVal + self.ext source = hashPath.replace('\\', '/').replace(getRoot(), '') galleries = galleries or [] tags = tags or [] imagefile = getRoot() / source if imagefile.ext == '.psd': psd = psd_tools.PSDImage.load(imagefile) workImage = psd.as_PIL() else: workImage = pilImage.open(imagefile) self.source = source if imagefile.ext in ('.tif', '.tiff', '.psd', '.tga'): png = imagefile.parent / '{}.png'.format(imagefile.namebase) workImage.save(png) workImage = pilImage.open(png) imagefile.move(imagefile.replace(self.hash, self.title)) self.source = png.replace(getRoot(), '') # -- Panoramic Check self.panoramic = 'GPano' in workImage.info.get('XML:com.adobe.xmp', '') if not self.panoramic: try: self.panoramic = any('gpano' in str(_[1]).lower() for _ in workImage.applist) except AttributeError: pass maxsize = PANORAMIC_MAX if self.panoramic else FROG_IMAGE_SIZE_CAP if workImage.size[0] > maxsize or workImage.size[1] > maxsize: workImage.thumbnail((maxsize, maxsize), pilImage.ANTIALIAS) self.image = self.source.name.replace(hashVal, '_{}'.format(hashVal)) workImage.save(getRoot() + self.image.name) else: self.image = self.source self.generateThumbnail() for gal in galleries: g = Gallery.objects.get(pk=int(gal)) g.images.add(self) for tag in g.tags.all(): self.tags.add(tag) self.tagArtist() for tagName in tags: tag = Tag.objects.get_or_create(name=tagName)[0] self.tags.add(tag) if not self.guid: self.guid = self.getGuid().guid # -- Posix paths only self.source = self.source.name.replace('\\', '/') self.image = self.image.name.replace('\\', '/') self.thumbnail = self.thumbnail.name.replace('\\', '/') self.save()
def getPath(self, relative=False): guid = self.getGuid() if relative: return Path(guid.guid[-2:]) / guid.guid return getRoot() / guid.guid[-2:] / guid.guid
except AttributeError: raise ImproperlyConfigured, 'FROG_SITE_URL is required' gQueue = Queue.Queue() gVideoThread = VideoThread(gQueue) gVideoThread.start() DefaultPrefs = { 'backgroundColor': '000000', 'tileCount': 6, 'batchSize': 300, 'includeImage': True, 'includeVideo': True, } ROOT = getRoot() class Tag(models.Model): name = models.CharField(max_length=255, unique=True) parent = models.ForeignKey('self', blank=True, null=True) artist = models.BooleanField(default=False) def __unicode__(self): return self.name def json(self): obj = { 'id': self.id, 'name': self.name, }