def __init__(self, stream, logger): self.logger = logger src = stream.read() self.soup = BeautifulStoneSoup(xml_to_unicode(src)[0]) self.objects = {} for obj in self.soup.findAll(objid=True): self.objects[obj['objid']] = obj self.parsed_objects = {} self.first_pass() self.second_pass() self.third_pass() self.fourth_pass() self.fifth_pass()
def compile_ui(self): pat = re.compile(r'''(['"]):/images/([^'"]+)\1''') def sub(match): ans = 'I(%s%s%s)' % (match.group(1), match.group(2), match.group(1)) return ans # >>> Entry point self._log_location() compiled_forms = {} self._find_forms() # Cribbed from gui2.__init__:build_forms() for form in self.forms: with open(form) as form_file: soup = BeautifulStoneSoup(form_file.read()) property = soup.find('property', attrs={'name': 'windowTitle'}) string = property.find('string') window_title = string.renderContents() compiled_form = self._form_to_compiled_form(form) if (not os.path.exists(compiled_form) or os.stat(form).st_mtime > os.stat(compiled_form).st_mtime): if not os.path.exists(compiled_form): if self.verbose: self._log(' compiling %s' % form) else: if self.verbose: self._log(' recompiling %s' % form) os.remove(compiled_form) buf = cStringIO.StringIO() compileUi(form, buf) dat = buf.getvalue() dat = dat.replace('__appname__', 'calibre') dat = dat.replace('import images_rc', '') dat = re.compile( r'(?:QtGui.QApplication.translate|(?<!def )_translate)\(.+?,\s+"(.+?)(?<!\\)",.+?\)' ).sub(r'_("\1")', dat) dat = dat.replace('_("MMM yyyy")', '"MMM yyyy"') dat = pat.sub(sub, dat) with open(compiled_form, 'wb') as cf: cf.write(dat) compiled_forms[window_title] = compiled_form.rpartition( os.sep)[2].partition('.')[0] return compiled_forms
def __init__(self, stream=None): if not stream: return soup = BeautifulStoneSoup(stream.read()) container = soup.find(name=re.compile(r'container$', re.I)) if not container: raise OCFException("<container> element missing") if container.get('version', None) != '1.0': raise EPubException("unsupported version of OCF") rootfiles = container.find(re.compile(r'rootfiles$', re.I)) if not rootfiles: raise EPubException("<rootfiles/> element missing") for rootfile in rootfiles.findAll(re.compile(r'rootfile$', re.I)): try: self[rootfile['media-type']] = rootfile['full-path'] except KeyError: raise EPubException("<rootfile/> element malformed")
def __init__(self, stream, logger): self.logger = logger src = stream.read() self.soup = BeautifulStoneSoup(xml_to_unicode(src)[0], convertEntities=BeautifulStoneSoup.XML_ENTITIES, selfClosingTags=self.SELF_CLOSING_TAGS) self.objects = {} for obj in self.soup.findAll(objid=True): self.objects[obj['objid']] = obj self.parsed_objects = {} self.first_pass() self.second_pass() self.third_pass() self.fourth_pass() self.fifth_pass()
def rebuild_collections(self, booklist, oncard): ''' For each book in the booklist for the card oncard, remove it from all its current collections, then add it to the collections specified in device_collections. oncard is None for the main memory, carda for card A, cardb for card B, etc. booklist is the object created by the :method:`books` call above. This is called after the user edits the 'Collections' field in the Device view when Metadata management is set to 'Manual'. ''' self._log_location() command_name = "rebuild_collections" command_element = "rebuildcollections" command_soup = BeautifulStoneSoup(self.parent.COMMAND_XML.format( command_element, time.mktime(time.localtime()))) LOCAL_DEBUG = False if booklist: changed = 0 for book in booklist: if LOCAL_DEBUG: self._log("{0:7} {1}".format(book.in_library, book.title)) filename = self.parent.path_template.format(book.uuid) if filename not in self.parent.cached_books: for fn in self.parent.cached_books: if book.uuid and book.uuid == self.parent.cached_books[fn]['uuid']: if LOCAL_DEBUG: self._log("'%s' matched on uuid %s" % (book.title, book.uuid)) filename = fn break elif (book.title == self.parent.cached_books[fn]['title'] and book.authors == self.parent.cached_books[fn]['authors']): if LOCAL_DEBUG: self._log("'%s' matched on title/author" % book.title) filename = fn break else: self._log("ERROR: file %s not found in cached_books" % repr(filename)) continue cached_collections = self.parent.cached_books[filename]['device_collections'] if cached_collections != book.device_collections: # Append the changed book info to the command file book_tag = Tag(command_soup, 'book') book_tag['filename'] = filename book_tag['title'] = book.title book_tag['author'] = ', '.join(book.authors) book_tag['uuid'] = book.uuid collections_tag = Tag(command_soup, 'collections') for tag in book.device_collections: c_tag = Tag(command_soup, 'collection') c_tag.insert(0, tag) collections_tag.insert(0, c_tag) book_tag.insert(0, collections_tag) command_soup.manifest.insert(0, book_tag) # Update cache self.parent.cached_books[filename]['device_collections'] = book.device_collections changed += 1 if changed: # Stage the command file self.parent._stage_command_file(command_name, command_soup, show_command=self.parent.prefs.get('development_mode', False)) # Wait for completion self.parent._wait_for_command_completion(command_name) else: self._log("no collection changes detected cached_books <=> device books")