示例#1
0
文件: save.py 项目: kba/calibre
def save_container(container, path):
    temp = PersistentTemporaryFile(prefix=('_' if iswindows else '.'),
                                   suffix=os.path.splitext(path)[1],
                                   dir=os.path.dirname(path))
    if hasattr(os, 'fchmod'):
        # Ensure file permissions and owner information is preserved
        fno = temp.fileno()
        try:
            st = os.stat(path)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
            # path may not exist if we are saving a copy, in which case we use
            # the metadata from the original book
            st = os.stat(container.path_to_ebook)
        os.fchmod(fno, st.st_mode)
        try:
            os.fchown(fno, st.st_uid, st.st_gid)
        except EnvironmentError as err:
            if err.errno != errno.EPERM:
                # ignore chown failure as user could be editing file belonging
                # to a different user, in which case we really cant do anything
                # about it short of making the file update non-atomic
                raise

    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#2
0
def get_cover(metadata):
    cdir = os.path.join(cache_dir(), 'icon-theme-covers')
    try:
        os.makedirs(cdir)
    except EnvironmentError as e:
        if e.errno != errno.EEXIST:
            raise

    def path(ext):
        return os.path.join(cdir, metadata['name'] + '.' + ext)

    etag_file, cover_file = map(path, 'etag jpg'.split())

    def safe_read(path):
        try:
            with open(path, 'rb') as f:
                return f.read()
        except EnvironmentError as e:
            if e.errno != errno.ENOENT:
                raise
        return b''

    etag, cached = safe_read(etag_file), safe_read(cover_file)
    etag = etag.decode('utf-8')
    cached, etag = download_cover(metadata['cover-url'], etag, cached)
    if cached:
        aname = cover_file + '.atomic'
        with open(aname, 'wb') as f:
            f.write(cached)
        atomic_rename(aname, cover_file)
    if etag:
        with open(etag_file, 'wb') as f:
            f.write(as_bytes(etag))
    return cached or b''
示例#3
0
文件: save.py 项目: Nashova/calibre
def save_container(container, path):
    temp = PersistentTemporaryFile(
        prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
    if hasattr(os, 'fchmod'):
        # Ensure file permissions and owner information is preserved
        fno = temp.fileno()
        try:
            st = os.stat(path)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
            # path may not exist if we are saving a copy, in which case we use
            # the metadata from the original book
            st = os.stat(container.path_to_ebook)
        os.fchmod(fno, st.st_mode)
        os.fchown(fno, st.st_uid, st.st_gid)

    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#4
0
def atomic_write(name, raw):
    bdir, bname = os.path.dirname(
        os.path.abspath(name)), os.path.basename(name)
    tname = ('_' if iswindows else '.') + bname
    with open(os.path.join(bdir, tname), 'wb') as f:
        f.write(raw)
    atomic_rename(f.name, name)
示例#5
0
文件: save.py 项目: Cykooz/calibre
def save_container(container, path):
    temp = PersistentTemporaryFile(
        prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
    if hasattr(os, 'fchmod'):
        # Ensure file permissions and owner information is preserved
        fno = temp.fileno()
        try:
            st = os.stat(path)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
            # path may not exist if we are saving a copy, in which case we use
            # the metadata from the original book
            st = os.stat(container.path_to_ebook)
        os.fchmod(fno, st.st_mode)
        try:
            os.fchown(fno, st.st_uid, st.st_gid)
        except EnvironmentError as err:
            if err.errno != errno.EPERM:
                # ignore chown failure as user could be editing file belonging
                # to a different user, in which case we really cant do anything
                # about it short of making the file update non-atomic
                raise

    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#6
0
 def write_result(self, res):
     if self.write_result_to:
         with tempfile.NamedTemporaryFile(dir=os.path.dirname(self.write_result_to), delete=False) as f:
             src = f.name
             f.write(str(res).encode('utf-8'))
             f.flush()
         atomic_rename(src, self.write_result_to)
示例#7
0
文件: img.py 项目: foolsh/calibre
def run_optimizer(file_path, cmd, as_filter=False, input_data=None):
    file_path = os.path.abspath(file_path)
    cwd = os.path.dirname(file_path)
    fd, outfile = tempfile.mkstemp(dir=cwd)
    try:
        if as_filter:
            outf = os.fdopen(fd, 'wb')
        else:
            os.close(fd)
        iname, oname = os.path.basename(file_path), os.path.basename(outfile)
        def repl(q, r):
            cmd[cmd.index(q)] = r
        if not as_filter:
            repl(True, iname), repl(False, oname)
        if iswindows:
            # subprocess in python 2 cannot handle unicode strings that are not
            # encodeable in mbcs, so we fail here, where it is more explicit,
            # instead.
            cmd = [x.encode('mbcs') if isinstance(x, type('')) else x for x in cmd]
            if isinstance(cwd, type('')):
                cwd = cwd.encode('mbcs')
        stdin = subprocess.PIPE if as_filter else None
        stderr = subprocess.PIPE if as_filter else subprocess.STDOUT
        creationflags = 0x08 if iswindows else 0
        p = subprocess.Popen(cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=stderr, stdin=stdin, creationflags=creationflags)
        stderr = p.stderr if as_filter else p.stdout
        if as_filter:
            src = input_data or open(file_path, 'rb')
            def copy(src, dest):
                try:
                    shutil.copyfileobj(src, dest)
                finally:
                    src.close(), dest.close()
            inw = Thread(name='CopyInput', target=copy, args=(src, p.stdin))
            inw.daemon = True
            inw.start()
            outw = Thread(name='CopyOutput', target=copy, args=(p.stdout, outf))
            outw.daemon = True
            outw.start()
        raw = force_unicode(stderr.read())
        if p.wait() != 0:
            return raw
        else:
            try:
                sz = os.path.getsize(outfile)
            except EnvironmentError:
                sz = 0
            if sz < 1:
                return raw
            shutil.copystat(file_path, outfile)
            atomic_rename(outfile, file_path)
    finally:
        try:
            os.remove(outfile)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
示例#8
0
文件: save.py 项目: kutanari/calibre
def save_container(container, path):
    temp = PersistentTemporaryFile(
        prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#9
0
def create_file_copy(ctx, rd, prefix, library_id, book_id, ext, mtime, copy_func, extra_etag_data=''):
    ''' We cannot copy files directly from the library folder to the output
    socket, as this can potentially lock the library for an extended period. So
    instead we copy out the data from the library folder into a temp folder. We
    make sure to only do this copy once, using the previous copy, if there have
    been no changes to the data for the file since the last copy. '''
    global rename_counter

    # Avoid too many items in a single directory for performance
    base = os.path.join(rd.tdir, 'fcache', (('%x' % book_id)[-3:]))
    if iswindows:
        base = '\\\\?\\' + os.path.abspath(base)  # Ensure fname is not too long for windows' API

    bname = '%s-%s-%x.%s' % (prefix, library_id, book_id, ext)
    if '\\' in bname or '/' in bname:
        raise ValueError('File components must not contain path separators')
    fname = os.path.join(base, bname)
    used_cache = 'no'

    with lock:
        previous_mtime = mtimes.get(bname)
        if previous_mtime is None or previous_mtime < mtime:
            if previous_mtime is not None:
                # File exists and may be open, so we cannot change its
                # contents, as that would lead to corrupted downloads in any
                # clients that are currently downloading the file.
                if iswindows:
                    # On windows in order to re-use bname, we have to rename it
                    # before deleting it
                    rename_counter += 1
                    dname = os.path.join(base, '_%x' % rename_counter)
                    atomic_rename(fname, dname)
                    os.remove(dname)
                else:
                    os.remove(fname)
            ans = open_for_write(fname)
            mtimes[bname] = mtime
            copy_func(ans)
            ans.seek(0)
        else:
            try:
                ans = share_open(fname, 'rb')
                used_cache = 'yes'
            except EnvironmentError as err:
                if err.errno != errno.ENOENT:
                    raise
                ans = open_for_write(fname)
                mtimes[bname] = mtime
                copy_func(ans)
                ans.seek(0)
        if ctx.testing:
            rd.outheaders['Used-Cache'] = used_cache
            rd.outheaders['Tempfile'] = hexlify(fname.encode('utf-8'))
        return rd.filesystem_file_with_custom_etag(ans, prefix, library_id, book_id, mtime, extra_etag_data)
示例#10
0
def create_file_copy(ctx, rd, prefix, library_id, book_id, ext, mtime, copy_func, extra_etag_data=''):
    ''' We cannot copy files directly from the library folder to the output
    socket, as this can potentially lock the library for an extended period. So
    instead we copy out the data from the library folder into a temp folder. We
    make sure to only do this copy once, using the previous copy, if there have
    been no changes to the data for the file since the last copy. '''
    global rename_counter

    # Avoid too many items in a single directory for performance
    base = os.path.join(rd.tdir, 'fcache', (('%x' % book_id)[-3:]))
    if iswindows:
        base = '\\\\?\\' + os.path.abspath(base)  # Ensure fname is not too long for windows' API

    bname = '%s-%s-%x.%s' % (prefix, library_id, book_id, ext)
    if '\\' in bname or '/' in bname:
        raise ValueError('File components must not contain path separators')
    fname = os.path.join(base, bname)
    used_cache = 'no'

    with lock:
        previous_mtime = mtimes.get(bname)
        if previous_mtime is None or previous_mtime < mtime:
            if previous_mtime is not None:
                # File exists and may be open, so we cannot change its
                # contents, as that would lead to corrupted downloads in any
                # clients that are currently downloading the file.
                if iswindows:
                    # On windows in order to re-use bname, we have to rename it
                    # before deleting it
                    rename_counter += 1
                    dname = os.path.join(base, '_%x' % rename_counter)
                    atomic_rename(fname, dname)
                    os.remove(dname)
                else:
                    os.remove(fname)
            ans = open_for_write(fname)
            mtimes[bname] = mtime
            copy_func(ans)
            ans.seek(0)
        else:
            try:
                ans = share_open(fname, 'rb')
                used_cache = 'yes'
            except EnvironmentError as err:
                if err.errno != errno.ENOENT:
                    raise
                ans = open_for_write(fname)
                mtimes[bname] = mtime
                copy_func(ans)
                ans.seek(0)
        if ctx.testing:
            rd.outheaders['Used-Cache'] = used_cache
            rd.outheaders['Tempfile'] = hexlify(fname.encode('utf-8'))
        return rd.filesystem_file_with_custom_etag(ans, prefix, library_id, book_id, mtime, extra_etag_data)
示例#11
0
def create_file_copy(ctx, rd, prefix, library_id, book_id, ext, mtime, copy_func, extra_etag_data=""):
    """ We cannot copy files directly from the library folder to the output
    socket, as this can potentially lock the library for an extended period. So
    instead we copy out the data from the library folder into a temp folder. We
    make sure to only do this copy once, using the previous copy, if there have
    been no changes to the data for the file since the last copy. """
    global rename_counter

    # Avoid too many items in a single directory for performance
    base = os.path.join(rd.tdir, "fcache", (("%x" % book_id)[-3:]))
    if iswindows:
        base = "\\\\?\\" + os.path.abspath(base)  # Ensure fname is not too long for windows' API

    bname = "%s-%s-%x.%s" % (prefix, library_id, book_id, ext)
    if "\\" in bname or "/" in bname:
        raise ValueError("File components must not contain path separators")
    fname = os.path.join(base, bname)
    used_cache = "no"

    with lock:
        previous_mtime = mtimes.get(bname)
        if previous_mtime is None or previous_mtime < mtime:
            if previous_mtime is not None:
                # File exists and may be open, so we cannot change its
                # contents, as that would lead to corrupted downloads in any
                # clients that are currently downloading the file.
                if iswindows:
                    # On windows in order to re-use bname, we have to rename it
                    # before deleting it
                    rename_counter += 1
                    dname = os.path.join(base, "_%x" % rename_counter)
                    atomic_rename(fname, dname)
                    os.remove(dname)
                else:
                    os.remove(fname)
            try:
                ans = share_open(fname, "w+b")
            except EnvironmentError:
                try:
                    os.makedirs(base)
                except EnvironmentError:
                    pass
                ans = share_open(fname, "w+b")
            mtimes[bname] = mtime
            copy_func(ans)
            ans.seek(0)
        else:
            ans = share_open(fname, "rb")
            used_cache = "yes"
        if ctx.testing:
            rd.outheaders["Used-Cache"] = used_cache
            rd.outheaders["Tempfile"] = hexlify(fname.encode("utf-8"))
        return rd.filesystem_file_with_custom_etag(ans, prefix, library_id, book_id, mtime, extra_etag_data)
示例#12
0
 def rollover(self):
     if self.max_size is None or self.current_pos <= self.max_size:
         return
     self.stream.close()
     for i in xrange(self.history - 1, 0, -1):
         try:
             atomic_rename('%s.%d' % (self.filename, i), '%s.%d' % (self.filename, i+1))
         except EnvironmentError as e:
             if e.errno != errno.ENOENT:  # the source of the rename does not exist
                 raise
     atomic_rename(self.filename, '%s.%d' % (self.filename, 1))
     self.set_output()
示例#13
0
文件: save.py 项目: siebert/calibre
def save_container(container, path):
    temp = PersistentTemporaryFile(prefix=('_' if iswindows else '.'),
                                   suffix=os.path.splitext(path)[1],
                                   dir=os.path.dirname(path))
    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#14
0
def save_container(container, path):
    if container.is_dir:
        return save_dir_container(container, path)
    temp = PersistentTemporaryFile(prefix=('_' if iswindows else '.'),
                                   suffix=os.path.splitext(path)[1],
                                   dir=os.path.dirname(path))
    if hasattr(os, 'fchmod'):
        # Ensure file permissions and owner information is preserved
        fno = temp.fileno()
        st = None
        try:
            st = os.stat(path)
        except OSError as err:
            if err.errno != errno.ENOENT:
                raise
            # path may not exist if we are saving a copy, in which case we use
            # the metadata from the original book
            try:
                st = os.stat(container.path_to_ebook)
            except OSError as err:
                if err.errno != errno.ENOENT:
                    raise
                # Somebody deleted the original file
        if st is not None:
            try:
                os.fchmod(fno, st.st_mode)
            except OSError as err:
                if err.errno != errno.EPERM:
                    raise
                raise OSError(
                    'Failed to change permissions of {} to {} ({}), with error: {}. Most likely the {} directory has a restrictive umask'
                    .format(temp.name, oct(st.st_mode),
                            format_permissions(st.st_mode),
                            errno.errorcode[err.errno],
                            os.path.dirname(temp.name)))
            try:
                os.fchown(fno, st.st_uid, st.st_gid)
            except OSError as err:
                if err.errno not in (errno.EPERM, errno.EACCES):
                    # ignore chown failure as user could be editing file belonging
                    # to a different user, in which case we really can't do anything
                    # about it short of making the file update non-atomic
                    raise

    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#15
0
 def rollover(self):
     if self.max_size is None or self.current_pos <= self.max_size:
         return
     self.stream.close()
     for i in xrange(self.history - 1, 0, -1):
         try:
             atomic_rename('%s.%d' % (self.filename, i),
                           '%s.%d' % (self.filename, i + 1))
         except EnvironmentError as e:
             if e.errno != errno.ENOENT:  # the source of the rename does not exist
                 raise
     atomic_rename(self.filename, '%s.%d' % (self.filename, 1))
     self.set_output()
示例#16
0
def main(path_to_html, tdir, image_format='jpeg'):
    if image_format not in ('jpeg', 'png'):
        raise ValueError('Image format must be either jpeg or png')
    must_use_qt()
    path_to_html = os.path.abspath(path_to_html)
    os.chdir(tdir)
    renderer = Render()
    renderer.start_load(path_to_html)
    ret = QApplication.instance().exec_()
    if ret == 0:
        page_images('rendered.pdf', image_format=image_format)
        ext = {'jpeg': 'jpg'}.get(image_format, image_format)
        atomic_rename('page-images-1.' + ext, 'rendered.' + image_format)
    return ret == 0
示例#17
0
文件: save.py 项目: Gondulf/calibre
 def do_save(self, tdir, container):
     temp = None
     try:
         path = container.path_to_ebook
         temp = PersistentTemporaryFile(
             prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
         temp.close()
         temp = temp.name
         container.commit(temp)
         atomic_rename(temp, path)
     finally:
         if temp and os.path.exists(temp):
             os.remove(temp)
         shutil.rmtree(tdir, ignore_errors=True)
示例#18
0
文件: save.py 项目: Gondulf/calibre
 def do_save(self, tdir, container):
     temp = None
     try:
         path = container.path_to_ebook
         temp = PersistentTemporaryFile(prefix=('_' if iswindows else '.'),
                                        suffix=os.path.splitext(path)[1],
                                        dir=os.path.dirname(path))
         temp.close()
         temp = temp.name
         container.commit(temp)
         atomic_rename(temp, path)
     finally:
         if temp and os.path.exists(temp):
             os.remove(temp)
         shutil.rmtree(tdir, ignore_errors=True)
示例#19
0
文件: save.py 项目: JimmXinu/calibre
def save_container(container, path):
    if container.is_dir:
        return save_dir_container(container, path)
    temp = PersistentTemporaryFile(
        prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
    if hasattr(os, 'fchmod'):
        # Ensure file permissions and owner information is preserved
        fno = temp.fileno()
        st = None
        try:
            st = os.stat(path)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
            # path may not exist if we are saving a copy, in which case we use
            # the metadata from the original book
            try:
                st = os.stat(container.path_to_ebook)
            except EnvironmentError as err:
                if err.errno != errno.ENOENT:
                    raise
                # Somebody deleted the original file
        if st is not None:
            try:
                os.fchmod(fno, st.st_mode)
            except EnvironmentError as err:
                if err.errno != errno.EPERM:
                    raise
                raise EnvironmentError('Failed to change permissions of %s to %s (%s), with error: %s. Most likely the %s directory has a restrictive umask' % (
                    temp.name, oct(st.st_mode), format_permissions(st.st_mode), errno.errorcode[err.errno], os.path.dirname(temp.name)))
            try:
                os.fchown(fno, st.st_uid, st.st_gid)
            except EnvironmentError as err:
                if err.errno not in (errno.EPERM, errno.EACCES):
                    # ignore chown failure as user could be editing file belonging
                    # to a different user, in which case we really cant do anything
                    # about it short of making the file update non-atomic
                    raise

    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#20
0
def save_reading_rates(key, rates):
    existing = get_existing_reading_rates()
    existing.pop(key, None)
    existing[key] = rates
    while len(existing) > 50:
        expired = next(iter(existing))
        del existing[expired]
    ddata = json.dumps(existing, indent=2).encode('utf-8')
    path = reading_rates_path()
    try:
        with tempfile.NamedTemporaryFile(dir=os.path.dirname(path),
                                         delete=False) as f:
            f.write(ddata)
        atomic_rename(f.name, path)
    except Exception:
        import traceback
        traceback.print_exc()
示例#21
0
def save_container(container, path):
    temp = PersistentTemporaryFile(
        prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path))
    if hasattr(os, 'fchmod'):
        # Ensure file permissions and owner information is preserved
        fno = temp.fileno()
        st = os.stat(path)
        os.fchmod(fno, st.st_mode)
        os.fchown(fno, st.st_uid, st.st_gid)

    temp.close()
    temp = temp.name
    try:
        container.commit(temp)
        atomic_rename(temp, path)
    finally:
        if os.path.exists(temp):
            os.remove(temp)
示例#22
0
文件: debug.py 项目: zwlistu/calibre
def reinit_db(dbpath):
    from contextlib import closing
    from calibre import as_unicode
    from calibre.ptempfile import TemporaryFile
    from calibre.utils.filenames import atomic_rename
    # We have to use sqlite3 instead of apsw as apsw has no way to discard
    # problematic statements
    import sqlite3
    from calibre.library.sqlite import do_connect
    with TemporaryFile(suffix='_tmpdb.db',
                       dir=os.path.dirname(dbpath)) as tmpdb:
        with closing(do_connect(dbpath)) as src, closing(
                do_connect(tmpdb)) as dest:
            dest.execute(
                'create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)'
            )
            dest.commit()
            uv = int(src.execute('PRAGMA user_version;').fetchone()[0])
            dump = src.iterdump()
            last_restore_error = None
            while True:
                try:
                    statement = next(dump)
                except StopIteration:
                    break
                except sqlite3.OperationalError as e:
                    prints('Failed to dump a line:', as_unicode(e))
                if last_restore_error:
                    prints('Failed to restore a line:', last_restore_error)
                    last_restore_error = None
                try:
                    dest.execute(statement)
                except sqlite3.OperationalError as e:
                    last_restore_error = as_unicode(e)
                    # The dump produces an extra commit at the end, so
                    # only print this error if there are more
                    # statements to be restored
            dest.execute('PRAGMA user_version=%d;' % uv)
            dest.commit()
        atomic_rename(tmpdb, dbpath)
    prints('Database successfully re-initialized')
示例#23
0
文件: debug.py 项目: nvdnkpr/calibre
def reinit_db(dbpath):
    from contextlib import closing
    from calibre import as_unicode
    from calibre.ptempfile import TemporaryFile
    from calibre.utils.filenames import atomic_rename

    # We have to use sqlite3 instead of apsw as apsw has no way to discard
    # problematic statements
    import sqlite3
    from calibre.library.sqlite import do_connect

    with TemporaryFile(suffix="_tmpdb.db", dir=os.path.dirname(dbpath)) as tmpdb:
        with closing(do_connect(dbpath)) as src, closing(do_connect(tmpdb)) as dest:
            dest.execute("create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)")
            dest.commit()
            uv = int(src.execute("PRAGMA user_version;").fetchone()[0])
            dump = src.iterdump()
            last_restore_error = None
            while True:
                try:
                    statement = next(dump)
                except StopIteration:
                    break
                except sqlite3.OperationalError as e:
                    prints("Failed to dump a line:", as_unicode(e))
                if last_restore_error:
                    prints("Failed to restore a line:", last_restore_error)
                    last_restore_error = None
                try:
                    dest.execute(statement)
                except sqlite3.OperationalError as e:
                    last_restore_error = as_unicode(e)
                    # The dump produces an extra commit at the end, so
                    # only print this error if there are more
                    # statements to be restored
            dest.execute("PRAGMA user_version=%d;" % uv)
            dest.commit()
        atomic_rename(tmpdb, dbpath)
    prints("Database successfully re-initialized")
示例#24
0
def safe_copy(src, destpath):
    tpath = destpath + '-temp'
    with open(tpath, 'wb') as dest:
        shutil.copyfileobj(src, dest)
    atomic_rename(tpath, destpath)
示例#25
0
文件: img.py 项目: timpalpant/calibre
def run_optimizer(file_path, cmd, as_filter=False, input_data=None):
    file_path = os.path.abspath(file_path)
    cwd = os.path.dirname(file_path)
    ext = os.path.splitext(file_path)[1]
    if not ext or len(ext) > 10 or not ext.startswith("."):
        ext = ".jpg"
    fd, outfile = tempfile.mkstemp(dir=cwd, suffix=ext)
    try:
        if as_filter:
            outf = os.fdopen(fd, "wb")
        else:
            os.close(fd)
        iname, oname = os.path.basename(file_path), os.path.basename(outfile)

        def repl(q, r):
            cmd[cmd.index(q)] = r

        if not as_filter:
            repl(True, iname), repl(False, oname)
        if iswindows:
            # subprocess in python 2 cannot handle unicode strings that are not
            # encodeable in mbcs, so we fail here, where it is more explicit,
            # instead.
            cmd = [x.encode("mbcs") if isinstance(x, type("")) else x for x in cmd]
            if isinstance(cwd, type("")):
                cwd = cwd.encode("mbcs")
        stdin = subprocess.PIPE if as_filter else None
        stderr = subprocess.PIPE if as_filter else subprocess.STDOUT
        creationflags = 0x08 if iswindows else 0
        p = subprocess.Popen(
            cmd, cwd=cwd, stdout=subprocess.PIPE, stderr=stderr, stdin=stdin, creationflags=creationflags
        )
        stderr = p.stderr if as_filter else p.stdout
        if as_filter:
            src = input_data or open(file_path, "rb")

            def copy(src, dest):
                try:
                    shutil.copyfileobj(src, dest)
                finally:
                    src.close(), dest.close()

            inw = Thread(name="CopyInput", target=copy, args=(src, p.stdin))
            inw.daemon = True
            inw.start()
            outw = Thread(name="CopyOutput", target=copy, args=(p.stdout, outf))
            outw.daemon = True
            outw.start()
        raw = force_unicode(stderr.read())
        if p.wait() != 0:
            return raw
        else:
            if as_filter:
                outw.join(60.0), inw.join(60.0)
            try:
                sz = os.path.getsize(outfile)
            except EnvironmentError:
                sz = 0
            if sz < 1:
                return "%s returned a zero size image" % cmd[0]
            shutil.copystat(file_path, outfile)
            atomic_rename(outfile, file_path)
    finally:
        try:
            os.remove(outfile)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
        try:
            os.remove(outfile + ".bak")  # optipng creates these files
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
示例#26
0
 def atomic_write(name, content):
     name = os.path.join(base, name)
     tname = name + '.tmp'
     with lopen(tname, 'wb') as f:
         f.write(content)
     atomic_rename(tname, name)
示例#27
0
def run_optimizer(file_path, cmd, as_filter=False, input_data=None):
    file_path = os.path.abspath(file_path)
    cwd = os.path.dirname(file_path)
    ext = os.path.splitext(file_path)[1]
    if not ext or len(ext) > 10 or not ext.startswith('.'):
        ext = '.jpg'
    fd, outfile = tempfile.mkstemp(dir=cwd, suffix=ext)
    try:
        if as_filter:
            outf = os.fdopen(fd, 'wb')
        else:
            os.close(fd)
        iname, oname = os.path.basename(file_path), os.path.basename(outfile)

        def repl(q, r):
            cmd[cmd.index(q)] = r

        if not as_filter:
            repl(True, iname), repl(False, oname)
        if iswindows:
            # subprocess in python 2 cannot handle unicode strings that are not
            # encodeable in mbcs, so we fail here, where it is more explicit,
            # instead.
            cmd = [
                x.encode('mbcs') if isinstance(x, type('')) else x for x in cmd
            ]
            if isinstance(cwd, type('')):
                cwd = cwd.encode('mbcs')
        stdin = subprocess.PIPE if as_filter else None
        stderr = subprocess.PIPE if as_filter else subprocess.STDOUT
        creationflags = 0x08 if iswindows else 0
        p = subprocess.Popen(cmd,
                             cwd=cwd,
                             stdout=subprocess.PIPE,
                             stderr=stderr,
                             stdin=stdin,
                             creationflags=creationflags)
        stderr = p.stderr if as_filter else p.stdout
        if as_filter:
            src = input_data or open(file_path, 'rb')

            def copy(src, dest):
                try:
                    shutil.copyfileobj(src, dest)
                finally:
                    src.close(), dest.close()

            inw = Thread(name='CopyInput', target=copy, args=(src, p.stdin))
            inw.daemon = True
            inw.start()
            outw = Thread(name='CopyOutput',
                          target=copy,
                          args=(p.stdout, outf))
            outw.daemon = True
            outw.start()
        raw = force_unicode(stderr.read())
        if p.wait() != 0:
            return raw
        else:
            if as_filter:
                outw.join(60.0), inw.join(60.0)
            try:
                sz = os.path.getsize(outfile)
            except EnvironmentError:
                sz = 0
            if sz < 1:
                return '%s returned a zero size image' % cmd[0]
            shutil.copystat(file_path, outfile)
            atomic_rename(outfile, file_path)
    finally:
        try:
            os.remove(outfile)
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
        try:
            os.remove(outfile + '.bak')  # optipng creates these files
        except EnvironmentError as err:
            if err.errno != errno.ENOENT:
                raise
示例#28
0
def atomic_write(name, raw):
    bdir, bname = os.path.dirname(os.path.abspath(name)), os.path.basename(name)
    tname = ('_' if iswindows else '.') + bname
    with open(os.path.join(bdir, tname), 'wb') as f:
        f.write(raw)
    atomic_rename(f.name, name)
示例#29
0
 def atomic_write(name, content):
     name = os.path.join(base, name)
     tname = name + '.tmp'
     with lopen(tname, 'wb') as f:
         f.write(content)
     atomic_rename(tname, name)
示例#30
0
def safe_copy(src, destpath):
    tpath = destpath + '-temp'
    with open(tpath, 'wb') as dest:
        shutil.copyfileobj(src, dest)
    atomic_rename(tpath, destpath)