Beispiel #1
0
    def separate(self, file_id):
        num_chunks = int(len(self.content) / CHUNK_SIZE)
        self.name_list = []

        if num_chunks > 0:
            last_index = 0
            for i in range(num_chunks):
                data = self.content[i * CHUNK_SIZE:(i + 1) * CHUNK_SIZE]
                checksum = get_sha1_hash(data)
                chunk_object = Chunk(checksum, file_id)
                self.name_list.append(chunk_object.get_filename())
                self.hash_list.append(checksum.upper())
                # compress chunks process
                buf = strIO()
                f = GzipFile(mode='wb', fileobj=buf)
                try:
                    f.write(data)
                finally:
                    f.close()
                chunk = buf.getvalue()

                self.chunks.append(chunk)
                last_index = i

            data = self.content[(last_index + 1) * CHUNK_SIZE:]
        else:
            data = self.content

        # FIXME: Do not repeat code, handle the last chunk differently
        if len(data) > 0:
            checksum = get_sha1_hash(data)
            chunk_object = Chunk(checksum, file_id)
            self.name_list.append(chunk_object.get_filename())
            self.hash_list.append(checksum.upper())
            buf = strIO()
            f = GzipFile(mode='wb', fileobj=buf)
            try:
                f.write(data)
            finally:
                f.close()
            chunk = buf.getvalue()

            self.chunks.append(chunk)
Beispiel #2
0
    def separate(self, file_id):
        num_chunks = int(len(self.content)/CHUNK_SIZE)
        self.name_list = []

        if num_chunks > 0:
            last_index = 0
            for i in range(num_chunks):
                data = self.content[i*CHUNK_SIZE:(i+1)*CHUNK_SIZE]
                checksum = get_sha1_hash(data)
                chunk_object = Chunk(checksum, file_id)
                self.name_list.append(chunk_object.get_filename())
                self.hash_list.append(checksum.upper())
                # compress chunks process
                buf = strIO()
                f = GzipFile(mode='wb', fileobj=buf)
                try:
                    f.write(data)
                finally:
                    f.close()
                chunk = buf.getvalue()

                self.chunks.append(chunk)
                last_index = i

            data = self.content[(last_index+1)*CHUNK_SIZE:]
        else:
            data = self.content

        # FIXME: Do not repeat code, handle the last chunk differently
        if len(data) > 0:
            checksum = get_sha1_hash(data)
            chunk_object = Chunk(checksum, file_id)
            self.name_list.append(chunk_object.get_filename())
            self.hash_list.append(checksum.upper())
            buf = strIO()
            f = GzipFile(mode='wb', fileobj=buf)
            try:
                f.write(data)
            finally:
                f.close()
            chunk = buf.getvalue()

            self.chunks.append(chunk)
Beispiel #3
0
def item(dirname):
    if dirname == "all":
        items = os.listdir(paths["dumpdir"])
    else:
        items = dirname.split(",")

    if len(items) == 1:
        itm = items[0]
        archive_path = os.path.join(paths["dumpdir"], itm)

        if not os.path.isfile(archive_path):
            abort(404)

        archive = open(archive_path)
        archive_size = os.path.getsize(archive_path)

        cd = "attachment; filename={0}".format(itm)

        return Response(archive.read(),
                        content_type="application/octet-stream",
                        headers={
                            "Content-length": archive_size,
                            "Content-Disposition": cd
                        },
                        direct_passthrough=True)

    # tar multiple files
    c = strIO()
    tarred = tarfile.open(fileobj=c, mode='w')
    for item_ in items:
        archive_path = os.path.join(paths["dumpdir"], item_)

        if not os.path.isfile(archive_path):
            abort(404)

        tarred.add(archive_path, arcname=item_)
    tarred.close()

    cd = "attachment; filename=fafdds-{0}.tar.gz".format(
        datetime.datetime.now().isoformat())

    return Response(c.getvalue(),
                    content_type="application/octet-stream",
                    headers={
                        "Content-length": c.tell(),
                        "Content-Disposition": cd
                    },
                    direct_passthrough=True)
Beispiel #4
0
def new(url_fname=None):
    """
    Handle dump dir archive uploads
    """

    form = NewDumpDirForm()
    if request.method in ["POST", "PUT"]:
        try:
            if request.method == "POST":
                if not form.validate() or form.file.name not in request.files:
                    raise InvalidUsage("Invalid form data.", 400)

                archive_file = request.files[form.file.name]
                archive_fname = archive_file.filename

            if request.method == "PUT":
                archive_file = strIO(request.stream.read())
                archive_fname = url_fname

            archive_file.seek(0, os.SEEK_END)
            archive_size = archive_file.tell()
            archive_file.seek(0)

            if not archive_size:
                raise InvalidUsage("Empty archive received", 400)

            if not check_filename(archive_fname):
                raise InvalidUsage("Wrong archive file name", 400)

            # sanitize input filename just to be sure
            archive_fname = secure_filename(archive_fname)

            if not os.path.exists(paths["dumpdir"]):
                raise InvalidUsage(
                    "That's embarrassing! We have some troubles"
                    " with deployment. Please try again later.", 500)

            count = 0
            try:
                count = sum(
                    1 for x in os.listdir(paths["dumpdir"])
                    if os.path.isfile(os.path.join(paths["dumpdir"], x)))

            except Exception as e:
                raise InvalidUsage(
                    "That's embarrassing! We have some troubles"
                    " with storage. Please try again later.", 500)

            if count >= int(config["dumpdir.cachedirectorycountquota"]):
                raise InvalidUsage(
                    "That's embarrassing! We have reached"
                    " the limit of uploaded archives."
                    " Please try again later.", 500)

            if archive_size > int(config["dumpdir.maxdumpdirsize"]):
                raise InvalidUsage("Dump dir archive is too large", 413)

            used_space = 0.0
            try:
                used_space = sum(
                    float(os.path.getsize(x))
                    for x in map(lambda f: os.path.join(paths["dumpdir"], f),
                                 os.listdir(paths["dumpdir"]))
                    if os.path.isfile(x))
            except Exception as e:
                raise InvalidUsage(
                    "That's embarrassing! We have some"
                    " troubles with disk space."
                    " Please try again later.", 500)

            quota = int(config["dumpdir.cachedirectorysizequota"])
            if (quota - archive_size) < used_space:
                raise InvalidUsage(
                    "That's embarrassing! We ran out"
                    " of disk space."
                    " Please try again later.", 500)

            fpath = os.path.join(paths["dumpdir"], archive_fname)

            if os.path.exists(fpath):
                raise InvalidUsage("Dump dir archive already exists.", 409)

            with open(fpath, 'w') as dest:
                dest.write(archive_file.read().decode("utf-8"))

            if request_wants_json():
                response = jsonify({"ok": "ok"})
                response.status_code = 201
                return response

            flash("Uploaded successfully.")
            return render_template("dumpdirs/new.html", form=form)

        except InvalidUsage as e:
            if e.status_code == 500:
                logger.error(e.message)
            elif e.status_code >= 400:
                logger.warning(e.message)

            if request_wants_json():
                response = jsonify({"error": e.message})
                response.status_code = e.status_code
                return response

            flash(e.message, "danger")
            return render_template("dumpdirs/new.html",
                                   form=form), e.status_code

    return render_template("dumpdirs/new.html", form=form)
Beispiel #5
0
def parse(source, mapper=dict):
    """
    Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a VDF)
    to a Python object.

    ``mapper`` specifies the Python object used after deserializetion. ``dict` is
    used by default. Alternatively, ``collections.OrderedDict`` can be used if you
    wish to preserve key order. Or any object that acts like a ``dict``.
    """
    if not issubclass(mapper, dict):
        raise TypeError("Expected mapper to be subclass of dict, got %s", type(mapper))
    if hasattr(source, "read"):
        fp = source
    elif isinstance(source, string_type):
        try:
            fp = unicodeIO(source)
        except TypeError:
            fp = strIO(source)
    else:
        raise TypeError("Expected source to be str or file-like object")

    # skip past BOMs
    fp.seek(bomlen(fp.read(10)))

    # init
    stack = [mapper()]
    expect_bracket = False

    re_keyvalue = re.compile(
        r'^("(?P<qkey>(?:\\.|[^\\"])+)"|(?P<key>[a-z0-9\-\_]+))'
        r"([ \t]*("
        r'"(?P<qval>(?:\\.|[^\\"])*)(?P<vq_end>")?'
        r"|(?P<val>[a-z0-9\-\_]+)"
        r"))?",
        flags=re.I,
    )

    for line in fp:
        line = line.lstrip()

        # skip empty and comment lines
        if line == "" or line[0] == "/":
            continue

        # one level deeper
        if line[0] == "{":
            expect_bracket = False
            continue

        if expect_bracket:
            raise SyntaxError("vdf.parse: expected openning bracket")

        # one level back
        if line[0] == "}":
            if len(stack) > 1:
                stack.pop()
                continue

            raise SyntaxError("vdf.parse: one too many closing parenthasis")

        # parse keyvalue pairs
        while True:
            match = re_keyvalue.match(line)

            if not match:
                raise SyntaxError("vdf.parse: invalid syntax")

            key = match.group("key") if match.group("qkey") is None else match.group("qkey")
            val = match.group("val") if match.group("qval") is None else match.group("qval")

            # we have a key with value in parenthesis, so we make a new dict obj (level deeper)
            if val is None:
                stack[-1][key] = mapper()
                stack.append(stack[-1][key])
                expect_bracket = True

            # we've matched a simple keyvalue pair, map it to the last dict obj in the stack
            else:
                # if the value is line consume one more line and try to match again,
                # until we get the KeyValue pair
                if match.group("vq_end") is None and match.group("qval") is not None:
                    line += next(fp)
                    continue

                stack[-1][key] = val

            # exit the loop
            break

    if len(stack) != 1:
        raise SyntaxError("vdf.parse: unclosed parenthasis or quotes")

    return stack.pop()
Beispiel #6
0
def parse(source, mapper=dict):
    """
    Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a VDF)
    to a Python object.

    ``mapper`` specifies the Python object used after deserializetion. ``dict` is
    used by default. Alternatively, ``collections.OrderedDict`` can be used if you
    wish to preserve key order. Or any object that acts like a ``dict``.
    """
    if not issubclass(mapper, dict):
        raise TypeError("Expected mapper to be subclass of dict, got %s", type(mapper))
    if hasattr(source, 'read'):
        fp = source
    elif isinstance(source, string_type):
        try:
            fp = unicodeIO(source)
        except TypeError:
            fp = strIO(source)
    else:
        raise TypeError("Expected source to be str or file-like object")

    # skip past BOMs
    fp.seek(bomlen(fp.read(10)))

    # init
    stack = [mapper()]
    expect_bracket = False

    re_keyvalue = re.compile(r'^("(?P<qkey>(?:\\.|[^\\"])+)"|(?P<key>[a-z0-9\-\_]+))'
                             r'([ \t]*('
                             r'"(?P<qval>(?:\\.|[^\\"])*)(?P<vq_end>")?'
                             r'|(?P<val>[a-z0-9\-\_]+)'
                             r'))?',
                             flags=re.I
                             )

    for line in fp:
        line = line.lstrip()

        # skip empty and comment lines
        if line == "" or line[0] == '/':
            continue

        # one level deeper
        if line[0] == "{":
            expect_bracket = False
            continue

        if expect_bracket:
            raise SyntaxError("vdf.parse: expected openning bracket")

        # one level back
        if line[0] == "}":
            if len(stack) > 1:
                stack.pop()
                continue

            raise SyntaxError("vdf.parse: one too many closing parenthasis")

        # parse keyvalue pairs
        while True:
            match = re_keyvalue.match(line)

            if not match:
                raise SyntaxError("vdf.parse: invalid syntax")

            key = match.group('key') if match.group('qkey') is None else match.group('qkey')
            val = match.group('val') if match.group('qval') is None else match.group('qval')

            # we have a key with value in parenthesis, so we make a new dict obj (level deeper)
            if val is None:
                stack[-1][key] = mapper()
                stack.append(stack[-1][key])
                expect_bracket = True

            # we've matched a simple keyvalue pair, map it to the last dict obj in the stack
            else:
                # if the value is line consume one more line and try to match again,
                # until we get the KeyValue pair
                if match.group('vq_end') is None and match.group('qval') is not None:
                    line += next(fp)
                    continue

                stack[-1][key] = val

            # exit the loop
            break

    if len(stack) != 1:
        raise SyntaxError("vdf.parse: unclosed parenthasis or quotes")

    return stack.pop()