def _build_local_path():
            path = remote_db_path.split('/')[-1]
            if iswindows:
                from calibre.utils.filenames import shorten_components_to
                plen = len(self.temp_dir)
                path = ''.join(shorten_components_to(245-plen, [path]))

            full_path = os.path.join(self.temp_dir, path)
            return os.path.normpath(full_path)
Exemple #2
0
        def _build_local_path():
            path = remote_db_path.split('/')[-1]
            if iswindows:
                from calibre.utils.filenames import shorten_components_to
                plen = len(self.temp_dir)
                path = ''.join(shorten_components_to(245 - plen, [path]))

            full_path = os.path.join(self.temp_dir, path)
            return os.path.normpath(full_path)
Exemple #3
0
    def _localize_database_path(self, app_id, remote_db_path):
        '''
        Copy remote_db_path from iOS to local storage as needed
        '''
        self._log_location("app_id: '%s' remote_db_path: '%s'" %
                           (app_id, remote_db_path))

        # Mount app_id
        self.ios.mount_ios_app(app_id=app_id)

        local_db_path = None
        db_stats = {}

        if '*' in remote_db_path:
            # Find matching file based on wildcard
            f_els = os.path.basename(remote_db_path).split('*')
            prefix = f_els[0]
            suffix = f_els[1]
            files = self.ios.listdir(os.path.dirname(remote_db_path))
            for f in files:
                if f.startswith(prefix) and f.endswith(suffix):
                    remote_db_path = '/'.join(
                        [os.path.dirname(remote_db_path), f])
                    break

        db_stats = self.ios.stat(remote_db_path)
        if db_stats:
            path = remote_db_path.split('/')[-1]
            if iswindows:
                plen = len(self.temp_dir)
                path = ''.join(shorten_components_to(245 - plen, [path]))

            full_path = os.path.join(self.temp_dir, path)
            if os.path.exists(full_path):
                lfs = os.stat(full_path)
                if (int(db_stats['st_mtime']) == lfs.st_mtime
                        and int(db_stats['st_size']) == lfs.st_size):
                    local_db_path = full_path

            if not local_db_path:
                with open(full_path, 'wb') as out:
                    self.ios.copy_from_idevice(remote_db_path, out)
                local_db_path = out.name
        else:
            self._log_location("'%s' not found" % remote_db_path)
            raise DatabaseNotFoundException

        # Dismount ios
        self.ios.disconnect_idevice()
        return {'path': local_db_path, 'stats': db_stats}
        def _build_local_path():
            '''
            GoodReader stores individual dbs for each book, matching the folder and
            name structure in the Documents folder. Make a local version, renamed to .db
            '''
            path = remote_db_path.split('/')[-1]
            if iswindows:
                from calibre.utils.filenames import shorten_components_to
                plen = len(self.temp_dir)
                path = ''.join(shorten_components_to(245 - plen, [path]))

            full_path = os.path.join(self.temp_dir, path)
            base = os.path.splitext(full_path)[0]
            full_path = base + ".db"
            return os.path.normpath(full_path)
        def _build_local_path():
            '''
            GoodReader stores individual dbs for each book, matching the folder and
            name structure in the Documents folder. Make a local version, renamed to .db
            '''
            path = remote_db_path.split('/')[-1]
            if iswindows:
                from calibre.utils.filenames import shorten_components_to
                plen = len(self.temp_dir)
                path = ''.join(shorten_components_to(245-plen, [path]))

            full_path = os.path.join(self.temp_dir, path)
            base = os.path.splitext(full_path)[0]
            full_path = base + ".db"
            return os.path.normpath(full_path)
    def _localize_database_path(self, app_id, remote_db_path):
        '''
        Copy remote_db_path from iOS to local storage as needed
        '''
        self._log_location("app_id: '%s' remote_db_path: '%s'" % (app_id, remote_db_path))

        # Mount app_id
        self.ios.mount_ios_app(app_id=app_id)

        local_db_path = None
        db_stats = {}

        if '*' in remote_db_path:
            # Find matching file based on wildcard
            f_els = os.path.basename(remote_db_path).split('*')
            prefix = f_els[0]
            suffix = f_els[1]
            files = self.ios.listdir(os.path.dirname(remote_db_path))
            for f in files:
                if f.startswith(prefix) and f.endswith(suffix):
                    remote_db_path = '/'.join([os.path.dirname(remote_db_path),f])
                    break

        db_stats = self.ios.stat(remote_db_path)
        if db_stats:
            path = remote_db_path.split('/')[-1]
            if iswindows:
                plen = len(self.temp_dir)
                path = ''.join(shorten_components_to(245-plen, [path]))

            full_path = os.path.join(self.temp_dir, path)
            if os.path.exists(full_path):
                lfs = os.stat(full_path)
                if (int(db_stats['st_mtime']) == lfs.st_mtime and
                    int(db_stats['st_size']) == lfs.st_size):
                    local_db_path = full_path

            if not local_db_path:
                with open(full_path, 'wb') as out:
                    self.ios.copy_from_idevice(remote_db_path, out)
                local_db_path = out.name
        else:
            self._log_location("'%s' not found" % remote_db_path)
            raise DatabaseNotFoundException

        # Dismount ios
        self.ios.disconnect_idevice()
        return {'path': local_db_path, 'stats': db_stats}
    def prepare_addable_books(self, paths):
        """
        Given a list of paths, returns another list of paths. These paths
        point to addable versions of the books.

        If there is an error preparing a book, then instead of a path, the
        position in the returned list for that book should be a three tuple:
        (original_path, the exception instance, traceback)
        Modeled on calibre.devices.mtp.driver:prepare_addable_books() #304
        """
        from calibre import sanitize_file_name
        from calibre.ptempfile import PersistentTemporaryDirectory

        self._log_location()
        tdir = PersistentTemporaryDirectory("_prep_gr")
        ans = []
        for path in paths:
            if not self.ios.exists("/".join([self.documents_folder, path])):
                ans.append((path, "File not found", "File not found"))
                continue

            base = tdir
            if iswindows:
                from calibre.utils.filenames import shorten_components_to

                plen = len(base)
                bfn = path.split("/")[-1]
                dest = "".join(shorten_components_to(245 - plen, [bfn]))
            else:
                dest = path

            out_path = os.path.normpath(os.path.join(base, sanitize_file_name(dest)))
            with open(out_path, "wb") as out:
                try:
                    self.get_file(path, out)
                except Exception as e:
                    import traceback

                    ans.append((dest, e, traceback.format_exc()))
                else:
                    ans.append(out.name)

        return ans
Exemple #8
0
    def prepare_addable_books(self, paths):
        '''
        Given a list of paths, returns another list of paths. These paths
        point to addable versions of the books.

        If there is an error preparing a book, then instead of a path, the
        position in the returned list for that book should be a three tuple:
        (original_path, the exception instance, traceback)
        Modeled on calibre.devices.mtp.driver:prepare_addable_books() #304
        '''
        from calibre import sanitize_file_name
        from calibre.ptempfile import PersistentTemporaryDirectory

        self._log_location()
        tdir = PersistentTemporaryDirectory('_prep_gr')
        ans = []
        for path in paths:
            if not self.ios.exists('/'.join([self.documents_folder, path])):
                ans.append((path, 'File not found', 'File not found'))
                continue

            base = tdir
            if iswindows:
                from calibre.utils.filenames import shorten_components_to
                plen = len(base)
                bfn = path.split('/')[-1]
                dest = ''.join(shorten_components_to(245 - plen, [bfn]))
            else:
                dest = path

            out_path = os.path.normpath(
                os.path.join(base, sanitize_file_name(dest)))
            with open(out_path, 'wb') as out:
                try:
                    self.get_file(path, out)
                except Exception as e:
                    import traceback
                    ans.append((dest, e, traceback.format_exc()))
                else:
                    ans.append(out.name)

        return ans
Exemple #9
0
    def _localize_mobi(self, remote_path):
        '''
        Copy remote_path from iOS to local storage as needed
        '''
        self._log_location("remote_path: '%s'" % (remote_path))

        local_path = None
        path = remote_path.split('/')[-1]
        if iswindows:
            from calibre.utils.filenames import shorten_components_to
            plen = len(self.temp_dir)
            path = ''.join(shorten_components_to(245 - plen, [path]))

        full_path = os.path.join(self.temp_dir, path)
        full_path = os.path.normpath(full_path)

        with open(full_path, 'wb') as out:
            self.ios.copy_from_idevice(remote_path, out)
        local_path = out.name

        return local_path
    def _localize_pdf(self, remote_path):
        '''
        Copy remote_path from iOS to local storage as needed
        '''
        self._log_location("remote_path: '%s'" % (remote_path))

        local_path = None
        path = remote_path.split('/')[-1]
        if iswindows:
            from calibre.utils.filenames import shorten_components_to
            plen = len(self.temp_dir)
            path = ''.join(shorten_components_to(245-plen, [path]))

        full_path = os.path.join(self.temp_dir, path)
        full_path = os.path.normpath(full_path)

        with open(full_path, 'wb') as out:
            self.ios.copy_from_idevice(remote_path, out)
        local_path = out.name

        return local_path
Exemple #11
0
 def prepare_addable_books(self, paths):
     tdir = PersistentTemporaryDirectory('_prepare_mtp')
     ans = []
     for path in paths:
         try:
             f = self.filesystem_cache.resolve_mtp_id_path(path)
         except Exception as e:
             ans.append((path, e, traceback.format_exc()))
             continue
         base = os.path.join(tdir, '%s'%f.object_id)
         os.mkdir(base)
         name = f.name
         if iswindows:
             plen = len(base)
             name = ''.join(shorten_components_to(245-plen, [name]))
         with lopen(os.path.join(base, name), 'wb') as out:
             try:
                 self.get_mtp_file(f, out)
             except Exception as e:
                 ans.append((path, e, traceback.format_exc()))
             else:
                 ans.append(out.name)
     return ans
def get_components(template, mi, id, timefmt='%b %Y', length=250,
        sanitize_func=ascii_filename, replace_whitespace=False,
        to_lowercase=False, safe_format=True, last_has_extension=True,
        single_dir=False):
    tsorder = tweaks['save_template_title_series_sorting']
    format_args = FORMAT_ARGS.copy()
    format_args.update(mi.all_non_none_fields())
    if mi.title:
        if tsorder == 'strictly_alphabetic':
            v = mi.title
        else:
            # title_sort might be missing or empty. Check both conditions
            v = mi.get('title_sort', None)
            if not v:
                v = title_sort(mi.title, order=tsorder)
        format_args['title'] = v
    if mi.authors:
        format_args['authors'] = mi.format_authors()
        format_args['author'] = format_args['authors']
    if mi.tags:
        format_args['tags'] = mi.format_tags()
        if format_args['tags'].startswith('/'):
            format_args['tags'] = format_args['tags'][1:]
    else:
        format_args['tags'] = ''
    if mi.series:
        format_args['series'] = title_sort(mi.series, order=tsorder)
        if mi.series_index is not None:
            format_args['series_index'] = mi.format_series_index()
    else:
        template = re.sub(r'\{series_index[^}]*?\}', '', template)
    if mi.rating is not None:
        format_args['rating'] = mi.format_rating(divide_by=2.0)
    if mi.identifiers:
        format_args['identifiers'] = mi.format_field_extended('identifiers')[1]
    else:
        format_args['identifiers'] = ''

    if hasattr(mi.timestamp, 'timetuple'):
        format_args['timestamp'] = strftime(timefmt, mi.timestamp.timetuple())
    if hasattr(mi.pubdate, 'timetuple'):
        format_args['pubdate'] = strftime(timefmt, mi.pubdate.timetuple())
    if hasattr(mi, 'last_modified') and hasattr(mi.last_modified, 'timetuple'):
        format_args['last_modified'] = strftime(timefmt, mi.last_modified.timetuple())

    format_args['id'] = unicode_type(id)
    # Now format the custom fields
    custom_metadata = mi.get_all_user_metadata(make_copy=False)
    for key in custom_metadata:
        if key in format_args:
            cm = custom_metadata[key]
            if cm['datatype'] == 'series':
                format_args[key] = title_sort(format_args[key], order=tsorder)
                if key+'_index' in format_args:
                    format_args[key+'_index'] = fmt_sidx(format_args[key+'_index'])
            elif cm['datatype'] == 'datetime':
                format_args[key] = strftime(timefmt, as_local_time(format_args[key]).timetuple())
            elif cm['datatype'] == 'bool':
                format_args[key] = _('yes') if format_args[key] else _('no')
            elif cm['datatype'] == 'rating':
                format_args[key] = mi.format_rating(format_args[key],
                        divide_by=2.0)
            elif cm['datatype'] in ['int', 'float']:
                if format_args[key] != 0:
                    format_args[key] = unicode_type(format_args[key])
                else:
                    format_args[key] = ''
    if safe_format:
        components = Formatter().safe_format(template, format_args,
                                            'G_C-EXCEPTION!', mi)
    else:
        components = Formatter().unsafe_format(template, format_args, mi)
    components = [x.strip() for x in components.split('/')]
    components = [sanitize_func(x) for x in components if x]
    if not components:
        components = [unicode_type(id)]
    if to_lowercase:
        components = [x.lower() for x in components]
    if replace_whitespace:
        components = [re.sub(r'\s', '_', x) for x in components]

    if single_dir:
        components = components[-1:]
    return shorten_components_to(length, components, last_has_extension=last_has_extension)
Exemple #13
0
    def convert(self, oeb_book, output_path, input_plugin, opts, log):
        from lxml import etree
        from calibre.ebooks.oeb.base import OEB_IMAGES, SVG_MIME
        from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
        from calibre.utils.zipfile import ZipFile
        from calibre.utils.filenames import ascii_filename

        # HTML
        if opts.htmlz_css_type == 'inline':
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLInlineCSSizer
            OEB2HTMLizer = OEB2HTMLInlineCSSizer
        elif opts.htmlz_css_type == 'tag':
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLNoCSSizer
            OEB2HTMLizer = OEB2HTMLNoCSSizer
        else:
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLClassCSSizer as OEB2HTMLizer

        with TemporaryDirectory(u'_htmlz_output') as tdir:
            htmlizer = OEB2HTMLizer(log)
            html = htmlizer.oeb2html(oeb_book, opts)

            fname = u'index'
            if opts.htmlz_title_filename:
                from calibre.utils.filenames import shorten_components_to
                fname = shorten_components_to(100, (ascii_filename(unicode_type(oeb_book.metadata.title[0])),))[0]
            with open(os.path.join(tdir, fname+u'.html'), 'wb') as tf:
                if isinstance(html, unicode_type):
                    html = html.encode('utf-8')
                tf.write(html)

            # CSS
            if opts.htmlz_css_type == 'class' and opts.htmlz_class_style == 'external':
                with open(os.path.join(tdir, u'style.css'), 'wb') as tf:
                    tf.write(htmlizer.get_css(oeb_book))

            # Images
            images = htmlizer.images
            if images:
                if not os.path.exists(os.path.join(tdir, u'images')):
                    os.makedirs(os.path.join(tdir, u'images'))
                for item in oeb_book.manifest:
                    if item.media_type in OEB_IMAGES and item.href in images:
                        if item.media_type == SVG_MIME:
                            data = etree.tostring(item.data, encoding='unicode')
                        else:
                            data = item.data
                        fname = os.path.join(tdir, u'images', images[item.href])
                        with open(fname, 'wb') as img:
                            img.write(data)

            # Cover
            cover_path = None
            try:
                cover_data = None
                if oeb_book.metadata.cover:
                    term = oeb_book.metadata.cover[0].term
                    cover_data = oeb_book.guide[term].item.data
                if cover_data:
                    from calibre.utils.img import save_cover_data_to
                    cover_path = os.path.join(tdir, u'cover.jpg')
                    with lopen(cover_path, 'w') as cf:
                        cf.write('')
                    save_cover_data_to(cover_data, cover_path)
            except:
                import traceback
                traceback.print_exc()

            # Metadata
            with open(os.path.join(tdir, u'metadata.opf'), 'wb') as mdataf:
                opf = OPF(io.BytesIO(etree.tostring(oeb_book.metadata.to_opf1(), encoding='UTF-8')))
                mi = opf.to_book_metadata()
                if cover_path:
                    mi.cover = u'cover.jpg'
                mdataf.write(metadata_to_opf(mi))

            htmlz = ZipFile(output_path, 'w')
            htmlz.add_dir(tdir)
Exemple #14
0
    def convert(self, oeb_book, output_path, input_plugin, opts, log):
        from lxml import etree
        from calibre.ebooks.oeb.base import OEB_IMAGES, SVG_MIME
        from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
        from calibre.utils.zipfile import ZipFile
        from calibre.utils.filenames import ascii_filename

        # HTML
        if opts.htmlz_css_type == 'inline':
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLInlineCSSizer
            OEB2HTMLizer = OEB2HTMLInlineCSSizer
        elif opts.htmlz_css_type == 'tag':
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLNoCSSizer
            OEB2HTMLizer = OEB2HTMLNoCSSizer
        else:
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLClassCSSizer as OEB2HTMLizer

        with TemporaryDirectory(u'_htmlz_output') as tdir:
            htmlizer = OEB2HTMLizer(log)
            html = htmlizer.oeb2html(oeb_book, opts)

            fname = u'index'
            if opts.htmlz_title_filename:
                from calibre.utils.filenames import shorten_components_to
                fname = shorten_components_to(100, (ascii_filename(
                    unicode_type(oeb_book.metadata.title[0])), ))[0]
            with open(os.path.join(tdir, fname + u'.html'), 'wb') as tf:
                if isinstance(html, unicode_type):
                    html = html.encode('utf-8')
                tf.write(html)

            # CSS
            if opts.htmlz_css_type == 'class' and opts.htmlz_class_style == 'external':
                with open(os.path.join(tdir, u'style.css'), 'wb') as tf:
                    tf.write(htmlizer.get_css(oeb_book))

            # Images
            images = htmlizer.images
            if images:
                if not os.path.exists(os.path.join(tdir, u'images')):
                    os.makedirs(os.path.join(tdir, u'images'))
                for item in oeb_book.manifest:
                    if item.media_type in OEB_IMAGES and item.href in images:
                        if item.media_type == SVG_MIME:
                            data = unicode_type(
                                etree.tostring(item.data,
                                               encoding=unicode_type))
                        else:
                            data = item.data
                        fname = os.path.join(tdir, u'images',
                                             images[item.href])
                        with open(fname, 'wb') as img:
                            img.write(data)

            # Cover
            cover_path = None
            try:
                cover_data = None
                if oeb_book.metadata.cover:
                    term = oeb_book.metadata.cover[0].term
                    cover_data = oeb_book.guide[term].item.data
                if cover_data:
                    from calibre.utils.img import save_cover_data_to
                    cover_path = os.path.join(tdir, u'cover.jpg')
                    with lopen(cover_path, 'w') as cf:
                        cf.write('')
                    save_cover_data_to(cover_data, cover_path)
            except:
                import traceback
                traceback.print_exc()

            # Metadata
            with open(os.path.join(tdir, u'metadata.opf'), 'wb') as mdataf:
                opf = OPF(
                    io.BytesIO(
                        etree.tostring(oeb_book.metadata.to_opf1(),
                                       encoding='UTF-8')))
                mi = opf.to_book_metadata()
                if cover_path:
                    mi.cover = u'cover.jpg'
                mdataf.write(metadata_to_opf(mi))

            htmlz = ZipFile(output_path, 'w')
            htmlz.add_dir(tdir)
Exemple #15
0
def create_upload_path(mdata,
                       fname,
                       template,
                       sanitize,
                       prefix_path='',
                       path_type=os.path,
                       maxlen=250,
                       use_subdirs=True,
                       news_in_folder=True,
                       filename_callback=lambda x, y: x,
                       sanitize_path_components=lambda x: x):
    from calibre.library.save_to_disk import get_components, config
    from calibre.utils.filenames import shorten_components_to

    special_tag = None
    if mdata.tags:
        for t in mdata.tags:
            if t.startswith(_('News')) or t.startswith('/'):
                special_tag = t
                break

    if mdata.tags and _('News') in mdata.tags:
        try:
            p = mdata.pubdate
            date = (p.year, p.month, p.day)
        except:
            today = time.localtime()
            date = (today[0], today[1], today[2])
        template = "{title}_%d-%d-%d" % date

    fname = sanitize(fname)
    ext = path_type.splitext(fname)[1]

    opts = config().parse()
    if not isinstance(template, str):
        template = template.decode('utf-8')
    app_id = str(getattr(mdata, 'application_id', ''))
    id_ = mdata.get('id', fname)
    extra_components = get_components(template,
                                      mdata,
                                      id_,
                                      timefmt=opts.send_timefmt,
                                      length=maxlen - len(app_id) - 1,
                                      sanitize_func=sanitize,
                                      last_has_extension=False)
    if not extra_components:
        extra_components.append(sanitize(filename_callback(fname, mdata)))
    else:
        extra_components[-1] = sanitize(
            filename_callback(extra_components[-1] + ext, mdata))

    if extra_components[-1] and extra_components[-1][0] in ('.', '_'):
        extra_components[-1] = 'x' + extra_components[-1][1:]

    if special_tag is not None:
        name = extra_components[-1]
        extra_components = []
        tag = special_tag
        if tag.startswith(_('News')):
            if news_in_folder:
                extra_components.append('News')
        else:
            for c in tag.split('/'):
                c = sanitize(c)
                if not c:
                    continue
                extra_components.append(c)
        extra_components.append(name)

    if not use_subdirs:
        extra_components = extra_components[-1:]

    def remove_trailing_periods(x):
        ans = x
        while ans.endswith('.'):
            ans = ans[:-1].strip()
        if not ans:
            ans = 'x'
        return ans

    extra_components = list(map(remove_trailing_periods, extra_components))
    components = shorten_components_to(maxlen - len(prefix_path),
                                       extra_components)
    components = sanitize_path_components(components)
    if prefix_path:
        filepath = path_type.join(prefix_path, *components)
    else:
        filepath = path_type.join(*components)

    return filepath
Exemple #16
0
    def create_upload_path(self, path, mdata, fname, create_dirs=True):
        path = os.path.abspath(path)
        maxlen = self.MAX_PATH_LEN

        special_tag = None
        if mdata.tags:
            for t in mdata.tags:
                if t.startswith(_('News')) or t.startswith('/'):
                    special_tag = t
                    break

        settings = self.settings()
        template = self.save_template()
        if mdata.tags and _('News') in mdata.tags:
            try:
                p = mdata.pubdate
                date = (p.year, p.month, p.day)
            except:
                today = time.localtime()
                date = (today[0], today[1], today[2])
            template = "{title}_%d-%d-%d" % date
        use_subdirs = self.SUPPORTS_SUB_DIRS and settings.use_subdirs

        fname = sanitize(fname)
        ext = os.path.splitext(fname)[1]

        from calibre.library.save_to_disk import get_components
        from calibre.library.save_to_disk import config
        opts = config().parse()
        if not isinstance(template, unicode):
            template = template.decode('utf-8')
        app_id = str(getattr(mdata, 'application_id', ''))
        id_ = mdata.get('id', fname)
        extra_components = get_components(template,
                                          mdata,
                                          id_,
                                          timefmt=opts.send_timefmt,
                                          length=maxlen - len(app_id) - 1)
        if not extra_components:
            extra_components.append(
                sanitize(self.filename_callback(fname, mdata)))
        else:
            extra_components[-1] = sanitize(
                self.filename_callback(extra_components[-1] + ext, mdata))

        if extra_components[-1] and extra_components[-1][0] in ('.', '_'):
            extra_components[-1] = 'x' + extra_components[-1][1:]

        if special_tag is not None:
            name = extra_components[-1]
            extra_components = []
            tag = special_tag
            if tag.startswith(_('News')):
                if self.NEWS_IN_FOLDER:
                    extra_components.append('News')
            else:
                for c in tag.split('/'):
                    c = sanitize(c)
                    if not c: continue
                    extra_components.append(c)
            extra_components.append(name)

        if not use_subdirs:
            extra_components = extra_components[-1:]

        def remove_trailing_periods(x):
            ans = x
            while ans.endswith('.'):
                ans = ans[:-1].strip()
            if not ans:
                ans = 'x'
            return ans

        extra_components = list(map(remove_trailing_periods, extra_components))
        components = shorten_components_to(maxlen - len(path),
                                           extra_components)
        components = self.sanitize_path_components(components)
        filepath = os.path.join(path, *components)
        filedir = os.path.dirname(filepath)

        if create_dirs and not os.path.exists(filedir):
            os.makedirs(filedir)

        return filepath
Exemple #17
0
    def create_upload_path(self, path, mdata, fname, create_dirs=True):
        path = os.path.abspath(path)
        maxlen = self.MAX_PATH_LEN

        special_tag = None
        if mdata.tags:
            for t in mdata.tags:
                if t.startswith(_('News')) or t.startswith('/'):
                    special_tag = t
                    break

        settings = self.settings()
        template = self.save_template()
        if mdata.tags and _('News') in mdata.tags:
            try:
                p = mdata.pubdate
                date  = (p.year, p.month, p.day)
            except:
                today = time.localtime()
                date = (today[0], today[1], today[2])
            template = "{title}_%d-%d-%d" % date
        use_subdirs = self.SUPPORTS_SUB_DIRS and settings.use_subdirs

        fname = sanitize(fname)
        ext = os.path.splitext(fname)[1]

        from calibre.library.save_to_disk import get_components
        from calibre.library.save_to_disk import config
        opts = config().parse()
        if not isinstance(template, unicode):
            template = template.decode('utf-8')
        app_id = str(getattr(mdata, 'application_id', ''))
        id_ = mdata.get('id', fname)
        extra_components = get_components(template, mdata, id_,
                timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1)
        if not extra_components:
            extra_components.append(sanitize(self.filename_callback(fname,
                mdata)))
        else:
            extra_components[-1] = sanitize(self.filename_callback(extra_components[-1]+ext, mdata))

        if extra_components[-1] and extra_components[-1][0] in ('.', '_'):
            extra_components[-1] = 'x' + extra_components[-1][1:]

        if special_tag is not None:
            name = extra_components[-1]
            extra_components = []
            tag = special_tag
            if tag.startswith(_('News')):
                if self.NEWS_IN_FOLDER:
                    extra_components.append('News')
            else:
                for c in tag.split('/'):
                    c = sanitize(c)
                    if not c: continue
                    extra_components.append(c)
            extra_components.append(name)

        if not use_subdirs:
            extra_components = extra_components[-1:]

        def remove_trailing_periods(x):
            ans = x
            while ans.endswith('.'):
                ans = ans[:-1].strip()
            if not ans:
                ans = 'x'
            return ans

        extra_components = list(map(remove_trailing_periods, extra_components))
        components = shorten_components_to(maxlen - len(path), extra_components)
        components = self.sanitize_path_components(components)
        filepath = os.path.join(path, *components)
        filedir = os.path.dirname(filepath)

        if create_dirs and not os.path.exists(filedir):
            os.makedirs(filedir)

        return filepath
Exemple #18
0
def create_upload_path(mdata, fname, template, sanitize,
        prefix_path='',
        path_type=os.path,
        maxlen=250,
        use_subdirs=True,
        news_in_folder=True,
        filename_callback=lambda x, y:x,
        sanitize_path_components=lambda x: x
        ):
    from calibre.library.save_to_disk import get_components, config
    from calibre.utils.filenames import shorten_components_to

    special_tag = None
    if mdata.tags:
        for t in mdata.tags:
            if t.startswith(_('News')) or t.startswith('/'):
                special_tag = t
                break

    if mdata.tags and _('News') in mdata.tags:
        try:
            p = mdata.pubdate
            date  = (p.year, p.month, p.day)
        except:
            today = time.localtime()
            date = (today[0], today[1], today[2])
        template = u"{title}_%d-%d-%d" % date

    fname = sanitize(fname)
    ext = path_type.splitext(fname)[1]

    opts = config().parse()
    if not isinstance(template, unicode):
        template = template.decode('utf-8')
    app_id = str(getattr(mdata, 'application_id', ''))
    id_ = mdata.get('id', fname)
    extra_components = get_components(template, mdata, id_,
            timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1,
            sanitize_func=sanitize, last_has_extension=False)
    if not extra_components:
        extra_components.append(sanitize(filename_callback(fname,
            mdata)))
    else:
        extra_components[-1] = sanitize(filename_callback(extra_components[-1]+ext, mdata))

    if extra_components[-1] and extra_components[-1][0] in ('.', '_'):
        extra_components[-1] = 'x' + extra_components[-1][1:]

    if special_tag is not None:
        name = extra_components[-1]
        extra_components = []
        tag = special_tag
        if tag.startswith(_('News')):
            if news_in_folder:
                extra_components.append('News')
        else:
            for c in tag.split('/'):
                c = sanitize(c)
                if not c:
                    continue
                extra_components.append(c)
        extra_components.append(name)

    if not use_subdirs:
        extra_components = extra_components[-1:]

    def remove_trailing_periods(x):
        ans = x
        while ans.endswith('.'):
            ans = ans[:-1].strip()
        if not ans:
            ans = 'x'
        return ans

    extra_components = list(map(remove_trailing_periods, extra_components))
    components = shorten_components_to(maxlen - len(prefix_path), extra_components)
    components = sanitize_path_components(components)
    if prefix_path:
        filepath = path_type.join(prefix_path, *components)
    else:
        filepath = path_type.join(*components)

    return filepath
Exemple #19
0
def get_components(template, mi, id, timefmt='%b %Y', length=250,
        sanitize_func=ascii_filename, replace_whitespace=False,
        to_lowercase=False, safe_format=True):

    tsorder = tweaks['save_template_title_series_sorting']
    format_args = FORMAT_ARGS.copy()
    format_args.update(mi.all_non_none_fields())
    if mi.title:
        if tsorder == 'strictly_alphabetic':
            v = mi.title
        else:
            # title_sort might be missing or empty. Check both conditions
            v = mi.get('title_sort', None)
            if not v:
                v = title_sort(mi.title, order=tsorder)
        format_args['title'] = v
    if mi.authors:
        format_args['authors'] = mi.format_authors()
        format_args['author'] = format_args['authors']
    if mi.tags:
        format_args['tags'] = mi.format_tags()
        if format_args['tags'].startswith('/'):
            format_args['tags'] = format_args['tags'][1:]
    else:
        format_args['tags'] = ''
    if mi.series:
        format_args['series'] = title_sort(mi.series, order=tsorder)
        if mi.series_index is not None:
            format_args['series_index'] = mi.format_series_index()
    else:
        template = re.sub(r'\{series_index[^}]*?\}', '', template)
    if mi.rating is not None:
        format_args['rating'] = mi.format_rating(divide_by=2.0)
    if mi.identifiers:
        format_args['identifiers'] = mi.format_field_extended('identifiers')[1]
    else:
        format_args['identifiers'] = ''

    if hasattr(mi.timestamp, 'timetuple'):
        format_args['timestamp'] = strftime(timefmt, mi.timestamp.timetuple())
    if hasattr(mi.pubdate, 'timetuple'):
        format_args['pubdate'] = strftime(timefmt, mi.pubdate.timetuple())
    if hasattr(mi, 'last_modified') and hasattr(mi.last_modified, 'timetuple'):
        format_args['last_modified'] = strftime(timefmt, mi.last_modified.timetuple())

    format_args['id'] = str(id)
    # Now format the custom fields
    custom_metadata = mi.get_all_user_metadata(make_copy=False)
    for key in custom_metadata:
        if key in format_args:
            cm = custom_metadata[key]
            if cm['datatype'] == 'series':
                format_args[key] = title_sort(format_args[key], order=tsorder)
                if key+'_index' in format_args:
                    format_args[key+'_index'] = fmt_sidx(format_args[key+'_index'])
            elif cm['datatype'] == 'datetime':
                format_args[key] = strftime(timefmt, format_args[key].timetuple())
            elif cm['datatype'] == 'bool':
                format_args[key] = _('yes') if format_args[key] else _('no')
            elif cm['datatype'] == 'rating':
                format_args[key] = mi.format_rating(format_args[key],
                        divide_by=2.0)
            elif cm['datatype'] in ['int', 'float']:
                if format_args[key] != 0:
                    format_args[key] = unicode(format_args[key])
                else:
                    format_args[key] = ''
    if safe_format:
        components = Formatter().safe_format(template, format_args,
                                            'G_C-EXCEPTION!', mi)
    else:
        components = Formatter().unsafe_format(template, format_args, mi)
    components = [x.strip() for x in components.split('/')]
    components = [sanitize_func(x) for x in components if x]
    if not components:
        components = [str(id)]
    if to_lowercase:
        components = [x.lower() for x in components]
    if replace_whitespace:
        components = [re.sub(r'\s', '_', x) for x in components]

    return shorten_components_to(length, components)
Exemple #20
0
    def convert(self, oeb_book, output_path, input_plugin, opts, log):
        from lxml import etree
        from calibre.ebooks.oeb.base import OEB_IMAGES, SVG_MIME
        from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf
        from calibre.utils.zipfile import ZipFile
        from calibre.utils.filenames import ascii_filename

        # HTML
        if opts.htmlz_css_type == "inline":
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLInlineCSSizer

            OEB2HTMLizer = OEB2HTMLInlineCSSizer
        elif opts.htmlz_css_type == "tag":
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLNoCSSizer

            OEB2HTMLizer = OEB2HTMLNoCSSizer
        else:
            from calibre.ebooks.htmlz.oeb2html import OEB2HTMLClassCSSizer as OEB2HTMLizer

        with TemporaryDirectory("_htmlz_output") as tdir:
            htmlizer = OEB2HTMLizer(log)
            html = htmlizer.oeb2html(oeb_book, opts)

            fname = "index"
            if opts.htmlz_title_filename:
                from calibre.utils.filenames import shorten_components_to

                fname = shorten_components_to(100, (ascii_filename(unicode(oeb_book.metadata.title[0])),))[0]
            with open(os.path.join(tdir, fname + ".html"), "wb") as tf:
                if isinstance(html, unicode):
                    html = html.encode("utf-8")
                tf.write(html)

            # CSS
            if opts.htmlz_css_type == "class" and opts.htmlz_class_style == "external":
                with open(os.path.join(tdir, "style.css"), "wb") as tf:
                    tf.write(htmlizer.get_css(oeb_book))

            # Images
            images = htmlizer.images
            if images:
                if not os.path.exists(os.path.join(tdir, "images")):
                    os.makedirs(os.path.join(tdir, "images"))
                for item in oeb_book.manifest:
                    if item.media_type in OEB_IMAGES and item.href in images:
                        if item.media_type == SVG_MIME:
                            data = unicode(etree.tostring(item.data, encoding=unicode))
                        else:
                            data = item.data
                        fname = os.path.join(tdir, "images", images[item.href])
                        with open(fname, "wb") as img:
                            img.write(data)

            # Cover
            cover_path = None
            try:
                cover_data = None
                if oeb_book.metadata.cover:
                    term = oeb_book.metadata.cover[0].term
                    cover_data = oeb_book.guide[term].item.data
                if cover_data:
                    from calibre.utils.magick.draw import save_cover_data_to

                    cover_path = os.path.join(tdir, "cover.jpg")
                    with open(cover_path, "w") as cf:
                        cf.write("")
                    save_cover_data_to(cover_data, cover_path)
            except:
                import traceback

                traceback.print_exc()

            # Metadata
            with open(os.path.join(tdir, "metadata.opf"), "wb") as mdataf:
                opf = OPF(StringIO(etree.tostring(oeb_book.metadata.to_opf1())))
                mi = opf.to_book_metadata()
                if cover_path:
                    mi.cover = "cover.jpg"
                mdataf.write(metadata_to_opf(mi))

            htmlz = ZipFile(output_path, "w")
            htmlz.add_dir(tdir)