Beispiel #1
0
    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)
Beispiel #2
0
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())
Beispiel #3
0
    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
Beispiel #4
0
    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)
Beispiel #5
0
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)
Beispiel #6
0
    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()
Beispiel #7
0
    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
Beispiel #8
0
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())
Beispiel #9
0
    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)
Beispiel #10
0
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
Beispiel #11
0
    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
Beispiel #12
0
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
Beispiel #13
0
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)
Beispiel #14
0
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())
Beispiel #15
0
    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()
Beispiel #16
0
    def getPath(self, relative=False):
        guid = self.getGuid()

        if relative:
            return Path(guid.guid[-2:]) / guid.guid
        return getRoot() / guid.guid[-2:] / guid.guid
Beispiel #17
0
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,
        }