def runTest(self): '''Test Page object''' TestPath.runTest(self) tree = ParseTree().fromstring('''\ <zim-tree> <link href='foo:bar'>foo:bar</link> <link href='bar'>bar</link> </zim-tree> ''' ) page = Page(Path('Foo')) page.readonly = False page.set_parsetree(tree) links = list(page.get_links()) self.assertEqual(links, [ ('page', 'foo:bar', {}), ('page', 'bar', {}), ] ) self.assertEqual(page.get_parsetree().tostring(), tree.tostring()) # ensure we didn't change the tree # TODO test get / set parse tree with and without source tree = ParseTree().fromstring('<zim-tree></zim-tree>') self.assertFalse(tree.hascontent) page.set_parsetree(tree) self.assertFalse(page.hascontent)
def deserialize_parse_tree(register_buf, content_buf, iter, data, length, create_tags, user_data): notebook, path = user_data tree = ParseTree().fromstring(data) tree.resolve_images(notebook, path) content_buf.insert_parsetree(iter, tree, interactive=True) return True
def testMain(self): '''Test Page object''' TestPath.runTest(self) tree = ParseTree().fromstring('''\ <zim-tree> <link href='foo:bar'>foo:bar</link> <link href='bar'>bar</link> <tag name='baz'>@baz</tag> </zim-tree> ''' ) page = self.generator('Foo') page.set_parsetree(tree) links = list(page.get_links()) self.assertEqual(links, [ ('page', 'foo:bar', {}), ('page', 'bar', {}), ] ) tags = list(page.get_tags()) self.assertEqual(tags, [ ('baz', {'name': 'baz'}), ]) self.assertEqual(page.get_parsetree().tostring(), tree.tostring()) # ensure we didn't change the tree # TODO test get / set parse tree with and without source tree = ParseTree().fromstring('<zim-tree></zim-tree>') self.assertFalse(tree.hascontent) page.set_parsetree(tree) self.assertFalse(page.hascontent)
def main(orig_file, notebook_path): assert(os.path.isdir(notebook_path)) assert(os.path.isfile(orig_file)) dumper = get_format('wiki').Dumper() parser = get_format('wiki').Parser() text = open(orig_file).read() parsetree = parser.parse(text) newtree = ParseTree().fromstring("<zim-tree></zim-tree>") for para in parsetree.findall('p'): p = Element("p") for node in flatten_list(para, para): p.append(node) newtree.getroot().extend(p) # new todo list text = ''.join(dumper.dump(newtree)).encode('utf-8') tomorrow = date.today() + timedelta(1) directory = os.path.join(notebook_path, "Calendar", str("%04d" % tomorrow.year), str("%02d" % tomorrow.month)) filename = "%02d.txt" % tomorrow.day if (not os.path.exists(directory)): os.makedirs(directory) # write tasks to tomorrow page. with open(os.path.join(directory, filename), 'a+') as the_file: the_file.write(text) # update original wiki page. text = ''.join(dumper.dump(parsetree) ).encode('utf-8') with open(orig_file, 'w') as the_file: the_file.write(text)
def testRenamePageDialogWithHeadingChanges(self): '''Test RenamePageDialog's heading auto-change option depending on whether we have a changed heading or not. ''' tree = ParseTree().fromstring('<zim-tree></zim-tree>') tree.set_heading("bar") self.ui.page = Page(Path("Test:foo:bar"), parsetree=tree) self.ui.notebook.get_page = lambda path: self.ui.page dialog = zim.gui.RenamePageDialog(self.ui, path=Path("Test:foo:bar")) self.assertTrue(dialog.form['head']) tree.set_heading("different") dialog = zim.gui.RenamePageDialog(self.ui, path=Path("Test:foo:bar")) self.assertFalse(dialog.form['head'])
def testSortListItems(self): from zim.formats import ParseTree template = '<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<zim-tree><p><ul>%s</ul></p></zim-tree>' tree = ParseTree().fromstring( template % '<li>B list item</li><li>C list item</li><li>A list item</li>') self.buffer.set_parsetree(tree) self.select_range(0, 42) self.extension.sort_selected_lines() tree = self.buffer.get_parsetree() self.assertEqual( tree.tostring(), template % '<li bullet="*">A list item</li><li bullet="*">B list item</li><li bullet="*">C list item</li>' )
def _link_tree(links, notebook, path): # Convert a list of links (of any type) into a parsetree #~ print 'LINKS: ', links #~ print 'NOTEBOOK and PATH:', notebook, path builder = TreeBuilder() builder.start('zim-tree') for i in range(len(links)): if i > 0: builder.data(' ') link = links[i] type = link_type(link) isimage = False if type == 'file': try: file = File(link) isimage = file.isimage() except: pass logger.debug('Pasting link: %s (type: %s, isimage: %s)', link, type, isimage) if isimage: src = notebook.relative_filepath(file, path) or file.uri builder.start('img', {'src': src}) builder.end('img') elif link.startswith('@'): # FIXME - is this ever used ?? builder.start('tag', {'name': links[i][1:]}) builder.data(links[i]) builder.end('tag') else: if type == 'page': href = Path(notebook.cleanup_pathname(link)) # Assume links are always absolute link = notebook.relative_link(path, href) or link elif type == 'file': file = File(link) # Assume links are always URIs link = notebook.relative_filepath(file, path) or file.uri builder.start('link', {'href': link}) builder.data(link) builder.end('link') builder.end('zim-tree') tree = ParseTree(builder.close()) tree.resolve_images(notebook, path) tree.decode_urls() return tree
def new_parsetree_from_xml(xml): # For some reason this does not work with cElementTree.XMLBuilder ... from xml.etree.ElementTree import XMLParser from zim.formats import ParseTree builder = XMLParser() builder.feed(xml) root = builder.close() return ParseTree(root)
def testPageSource(self): from zim.newfs.mock import MockFile, MockFolder file = MockFile('/mock/test/page.txt') folder = MockFile('/mock/test/page/') page = Page(Path('Foo'), False, file, folder) self.assertFalse(page.readonly) self.assertFalse(page.hascontent) self.assertIsNone(page.ctime) self.assertIsNone(page.mtime) self.assertIsNone(page.get_parsetree()) page1 = Page(Path('Foo'), False, file, folder) self.assertTrue(page.isequal(page1)) tree = ParseTree().fromstring('''\ <zim-tree> <link href='foo:bar'>foo:bar</link> <link href='bar'>bar</link> <tag name='baz'>@baz</tag> </zim-tree> ''') page.set_parsetree(tree) page._store() self.assertTrue(file.exists()) self.assertTrue(page.hascontent) self.assertIsInstance(page.ctime, float) self.assertIsInstance(page.mtime, float) lines = file.readlines() self.assertEqual(lines[0], 'Content-Type: text/x-zim-wiki\n') self.assertEqual(lines[1][:11], 'Wiki-Format') self.assertEqual(lines[2][:13], 'Creation-Date') self.assertEqual(page.get_parsetree(), tree) self.assertTrue(page.isequal(page1)) self.assertTrue(page1.hascontent) self.assertIsInstance(page1.ctime, float) self.assertIsInstance(page1.mtime, float) self.assertIsNotNone(page1.get_parsetree()) file.write('foo 123') page.set_parsetree(tree) self.assertRaises(zim.newfs.FileChangedError, page._store) ### Custom header should be preserved file.writelines(lines[0:3] + ['X-Custom-Header: MyTest'] + lines[3:]) page = Page(Path('Foo'), False, file, folder) tree = page.get_parsetree() page.set_parsetree(tree) page._store() lines = file.readlines() self.assertEqual(lines[0], 'Content-Type: text/x-zim-wiki\n') self.assertEqual(lines[3], 'X-Custom-Header: MyTest\n')
def testModelFromData(self): notebook = self.setUpNotebook() page = notebook.get_page(Path('Test')) model = self.otype.model_from_data(notebook, page, {}, TABLE_WIKI_TEXT) builder = OldParseTreeBuilder() # XXX builder.start('zim-tree') self.otype.dump(builder, model) builder.end('zim-tree') tree = ParseTree(builder.close()) #self.assertEquals(list(tree.iter_tokens()), TABLE_TOKENS) -- XXX should work but doesn;t :( self.assertEquals(''.join(WikiDumper().dump(tree)), TABLE_WIKI_TEXT[1:-1])
def testDumpHtml(self): xml = '''\ <?xml version='1.0' encoding='utf-8'?> <zim-tree><object lang="python" linenumbers="false" type="code"> def foo(a, b): print "FOO", a >= b </object></zim-tree>''' tree = ParseTree().fromstring(xml) dumper = HtmlDumper(StubLinker()) html = dumper.dump(tree) #~ print '>>', html self.assertIn('\tprint "FOO", a >= b\n', html)
def testModelFromElement(self): tree = WikiParser().parse(TABLE_WIKI_TEXT) element = tree._etree.getroot().find('table') self.assertIsNotNone(element) model = self.otype.model_from_element(element.attrib, element) builder = OldParseTreeBuilder() # XXX builder.start('zim-tree') self.otype.dump(builder, model) builder.end('zim-tree') tree = ParseTree(builder.close()) #self.assertEquals(list(tree.iter_tokens()), TABLE_TOKENS) -- XXX should work but doesn;t :( self.assertEquals(''.join(WikiDumper().dump(tree)), TABLE_WIKI_TEXT[1:-1])
def testShouldAutochangeHeading(self): page = Page(Path("Foo")) page.readonly = False tree = ParseTree().fromstring('<zim-tree></zim-tree>') tree.set_heading("Foo") page.set_parsetree(tree) self.assertTrue(page.heading_matches_pagename()) tree.set_heading("Bar") page.set_parsetree(tree) self.assertFalse(page.heading_matches_pagename())
def _clicked(self, tv, event): pos_path = self.get_path_at_pos(int(event.x), int(event.y)) buffer = self.app_window.pageview.view.get_buffer() # paste link at current cursor if middle click if event.button == 2 and pos_path is not None: path, col, cellx, celly = pos_path page = Path(self.get_model()[path][0].decode('utf-8')) # make link xml = """<?xml version='1.0' encoding='utf-8'?>""" + \ """<zim-tree partial="True">""" + \ '<link href=":%(path)s">:%(disp)s</link> ' + \ '</zim-tree>' dispdict = {'path': page, 'disp': page} link = ParseTree().fromstring(xml % dispdict) # insert into current page buffer.insert_parsetree_at_cursor(link) self.window.get_parent().destroy()
def testShouldAutochangeHeading(self): from zim.newfs.mock import MockFile, MockFolder file = MockFile('/mock/test/page.txt') folder = MockFile('/mock/test/page/') page = Page(Path('Foo'), False, file, folder) tree = ParseTree().fromstring('<zim-tree></zim-tree>') tree.set_heading("Foo") page.set_parsetree(tree) self.assertTrue(page.heading_matches_pagename()) tree.set_heading("Bar") page.set_parsetree(tree) self.assertFalse(page.heading_matches_pagename())
def testPageSource(self): from zim.newfs.mock import MockFile, MockFolder file = MockFile('/mock/test/page.txt') folder = MockFile('/mock/test/page/') page = Page(Path('Foo'), False, file, folder) self.assertFalse(page.readonly) self.assertFalse(page.hascontent) self.assertIsNone(page.ctime) self.assertIsNone(page.mtime) self.assertIsNone(page.get_parsetree()) page1 = Page(Path('Foo'), False, file, folder) self.assertTrue(page.isequal(page1)) tree = ParseTree().fromstring('''\ <zim-tree> <link href='foo:bar'>foo:bar</link> <link href='bar'>bar</link> <tag name='baz'>@baz</tag> </zim-tree> ''') page.set_parsetree(tree) page._store() self.assertTrue(file.exists()) self.assertTrue(page.hascontent) self.assertIsInstance(page.ctime, float) self.assertIsInstance(page.mtime, float) self.assertEqual(page.get_parsetree(), tree) self.assertTrue(page.isequal(page1)) self.assertTrue(page1.hascontent) self.assertIsInstance(page1.ctime, float) self.assertIsInstance(page1.mtime, float) self.assertIsNotNone(page1.get_parsetree()) file.write('foo 123') page.set_parsetree(tree) self.assertRaises(zim.newfs.FileChangedError, page._store)
def testAPI(self): '''Test various notebook methods''' self.assertTrue( isinstance(self.notebook.get_home_page(), Page)) page1 = self.notebook.get_page(Path('Tree:foo')) page2 = self.notebook.get_page(Path('Tree:foo')) self.assertTrue(page1.valid) self.assertTrue(id(page2) == id(page1)) # check usage of weakref self.notebook.flush_page_cache(Path('Tree:foo')) page3 = self.notebook.get_page(Path('Tree:foo')) self.assertTrue(id(page3) != id(page1)) self.assertFalse(page1.valid) page = self.notebook.get_page(Path('Test:foo')) text = page.dump('plain') newtext = ['Some new content\n'] assert newtext != text self.assertEqual(page.dump('plain'), text) #~ page.parse('plain', newtext) #~ self.assertEqual(page.dump('plain'), newtext) #~ self.assertTrue(page.modified) #~ re = self.notebook.revert_page(page) #~ self.assertFalse(re) # no return value #~ self.assertEqual(page.dump('plain'), text) # object reverted #~ self.assertFalse(page.modified) self.notebook.flush_page_cache(page) page = self.notebook.get_page(page) # new object self.assertEqual(page.dump('plain'), text) page.parse('plain', newtext) self.assertEqual(page.dump('plain'), newtext) self.notebook.store_page(page) self.notebook.flush_page_cache(page) page = self.notebook.get_page(page) # new object self.assertEqual(page.dump('plain'), newtext) # ensure storing empty tree works emptytree = ParseTree() self.assertFalse(emptytree.hascontent) page.set_parsetree(emptytree) self.notebook.store_page(page)
def testRenamePageDialogWithHeadingChanges(self): '''Test RenamePageDialog's heading auto-change option depending on whether we have a changed heading or not. ''' from zim.newfs.mock import MockFile, MockFolder file = MockFile('/mock/test/page.txt') folder = MockFile('/mock/test/page/') page = Page(Path("Test:foo:bar"), False, file, folder) tree = ParseTree().fromstring('<zim-tree></zim-tree>') tree.set_heading("bar") page.set_parsetree(tree) self.ui.page = page self.ui.notebook.get_page = lambda path: self.ui.page dialog = zim.gui.RenamePageDialog(self.ui, path=Path("Test:foo:bar")) self.assertTrue(dialog.form['head']) tree.set_heading("different") dialog = zim.gui.RenamePageDialog(self.ui, path=Path("Test:foo:bar")) self.assertFalse(dialog.form['head'])
def parsetree_from_selectiondata(selectiondata, notebook=None, path=None): '''Function to get a parsetree based on the selectiondata contents if at all possible. Used by both copy-paste and drag-and-drop methods. The 'notebook' and optional 'path' arguments are used to format links relative to the page which is the target for the pasting or drop operation. For image data, the parameters notebook and page are used to save the image to the correct attachment folder and return a parsetree with the correct image link. @param selectiondata: a C{gtk.SelectionData} object @param notebook: a L{Notebook} object @param path: a L{Path} object @returns: a L{ParseTree} or C{None} ''' # TODO: check relative linking for all parsetrees !!! targetname = str(selectiondata.target) if targetname == PARSETREE_TARGET_NAME: return ParseTree().fromstring(selectiondata.data) elif targetname in (INTERNAL_PAGELIST_TARGET_NAME, PAGELIST_TARGET_NAME) \ or targetname in URI_TARGET_NAMES: links = unpack_urilist(selectiondata.data) return _link_tree(links, notebook, path) elif targetname in TEXT_TARGET_NAMES: # plain text parser should highlight urls etc. # FIXME some apps drop text/uri-list as a text/plain mimetype # try to catch this situation by a check here text = selectiondata.get_text() if text: return get_format('plain').Parser().parse(text.decode('utf-8'), partial=True) else: return None elif targetname in IMAGE_TARGET_NAMES: # save image pixbuf = selectiondata.get_pixbuf() if not pixbuf: return None dir = notebook.get_attachments_dir(path) if not dir.exists(): logger.debug("Creating attachment dir: %s", dir) dir.touch() format, extension = _get_image_info(targetname) if format is None or format == 'bmp': # default to png format # special casing bmp since many window apps use it internally # but is quite large to store, so compress by using png format, extension = 'png', 'png' file = dir.new_file('pasted_image.%s' % extension) logger.debug("Saving image from clipboard to %s", file) pixbuf.save(file.path, format) FS.emit('path-created', file) # notify version control links = [file.uri] return _link_tree(links, notebook, path) else: return None
def runTest(self): '''Test indexing''' # This is one big test instead of seperate sub tests because in the # subclass we generate a file based notebook in setUp, and we do not # want to do that many times #~ print self.__class__.__name__ self.index.update() #~ print '\n==== DB ====' #~ cursor = self.index.db.cursor() #~ cursor.execute('select * from pages') #~ for row in cursor: #~ print row #~ cursor.execute('select * from links') #~ for row in cursor: #~ print row # paths / ids path = self.index.lookup_path(Path('Test:foo:bar')) self.assertTrue(isinstance(path, IndexPath)) path = self.index.lookup_id(path.id) self.assertTrue(isinstance(path, IndexPath)) self.assertEqual(path.name, 'Test:foo:bar') # pages pagelist = list(self.index.list_pages(None)) self.assertTrue(len(pagelist) > 0) pagelist = list(self.index.list_pages(Path('Test'))) self.assertTrue(len(pagelist) > 0) for page in pagelist: self.assertTrue(page.name.startswith('Test:')) self.assertTrue(page.name.count(':') == 1) pagelist = list(self.index.list_pages(Path('Linking'))) self.assertTrue(Path('Linking:Dus') in pagelist) pagelist = list(self.index.list_pages(Path('Some:Non:Existing:Path'))) self.assertTrue(len(pagelist) == 0) # links forwlist = list(self.index.list_links(Path('Test:foo:bar'))) backlist = list( self.index.list_links(Path('Test:foo:bar'), LINK_DIR_BACKWARD)) bothlist = list( self.index.list_links(Path('Test:foo:bar'), LINK_DIR_BOTH)) for l in forwlist, backlist, bothlist: self.assertTrue(len(l) > 0) for link in l: self.assertTrue(isinstance(link, Link)) self.assertTrue(isinstance(link.source, IndexPath)) self.assertTrue(isinstance(link.href, IndexPath)) self.assertTrue(len(forwlist) + len(backlist) == len(bothlist)) n = self.index.n_list_links(Path('Test:foo:bar'), LINK_DIR_BACKWARD) self.assertEqual(n, len(backlist)) # tags taglist = list(self.index.list_tags(Path('Test:tags'))) self.assertTrue(len(taglist) == 11) for tag in taglist: self.assertTrue(isinstance(tag, IndexTag)) tagnames = [t.name for t in taglist] aretags = [ 'tags', 'beginning', 'end', 'tabs', 'verbatim', 'enumerations', 'encoding', 's', 'num6ers', 'wit', 'cr' ] nottags = ['places', 'links', 'captions', 'Headings', 'word'] for t in aretags: self.assertTrue(t in tagnames) for t in nottags: self.assertTrue(not t in tagnames) # cursor.row_count is not reliable - see docs def count_pages(db): c = db.cursor() c.execute('select id from pages') r = c.fetchall() return len(r) def dump_db(db): c = db.cursor() c.execute('select * from pages') text = '' for row in c: # HACK iterating of sqlite3.Row objects only supported for python 2.6 myrow = [] for i in range(len(row)): myrow.append(row[i]) text += ', '.join(map(str, myrow)) + '\n' return text # repeat update() to check if update is stable manifest = len(self.notebook.testdata_manifest) self.assertTrue(count_pages(self.index.db) >= manifest) origdb = dump_db(self.index.db) self.index.update() self.assertEqual(dump_db(self.index.db), origdb) # indexkey for path in (Path('Test'), Path('Test:foo')): indexpath = self.index.lookup_path(path) self.assertEqual(indexpath.contentkey, self.notebook.get_page_indexkey(path)) self.assertEqual(indexpath.childrenkey, self.notebook.get_pagelist_indexkey(path)) # other functions path = self.index.get_unique_path(Path('non-existing-path')) self.assertEqual(path, Path('non-existing-path')) path = self.index.get_unique_path(Path('Test:foo')) self.assertEqual(path, Path('Test:foo_1')) # get_previous / get_next page = list(self.index.list_pages(None))[0] seen = 0 while page: seen = max(seen, page.name.count(':')) page = self.index.get_next(page) self.assertTrue(seen >= 2) page = list(self.index.list_pages(None))[-1] seen = 0 while page: seen = max(seen, page.name.count(':')) page = self.index.get_previous(page) self.assertTrue(seen >= 2) # now go through the flush loop self.index.flush() self.assertEqual(count_pages(self.index.db), 1) self.index.update() self.assertEqual(dump_db(self.index.db), origdb) # now index only part of the tree - and repeat self.index.flush() self.assertEqual(count_pages(self.index.db), 1) self.index.update(Path('Test')) self.assertTrue(count_pages(self.index.db) > 2) partdb = dump_db(self.index.db) self.index.update(Path('Test')) self.assertEqual(dump_db(self.index.db), partdb) # Index whole tree again self.index.update() # Check cleanup path = Path('New:Nested:Path') self.index.touch(path) parent = self.index.lookup_path(path.parent) self.assertTrue(parent and parent.haschildren) self.index.delete(path) parent = self.index.lookup_path(path.parent) self.assertTrue(parent is None) # Check cleanup for links links = [ link.href for link in self.index.list_links(Path('roundtrip')) ] for p in ('foo:bar', 'Bar'): self.assertTrue(Path(p) in links) path = self.index.lookup_path(Path('foo:bar')) self.assertTrue(path) # Check for tag indexing tags = [tag.name for tag in self.index.list_tags(Path('roundtrip'))] for t in ('foo', 'bar'): self.assertTrue(t in tags) tagged = list(self.index.list_tagged_pages(t)) self.assertTrue(Path('roundtrip') in tagged) tree = ParseTree().fromstring( '<zim-tree><link href=":foo:bar">:foo:bar</link></zim-tree>') page = self.notebook.get_page(Path('roundtrip')) page.set_parsetree(tree) self.notebook.store_page(page) path = self.index.lookup_path(Path('Bar')) self.assertTrue(path is None) path = self.index.lookup_path(Path('foo:bar')) self.assertTrue(path) self.notebook.delete_page(Path('roundtrip')) path = self.index.lookup_path(Path('foo:bar')) self.assertTrue(path is None) # Check get_page_index() to double check stable sorting def check_index(path): for i, child in enumerate(self.index.list_pages(path)): index = self.index.get_page_index(child) #~ print 'INDEX', i, child, '-->', index self.assertTrue(index == i, 'Index mismatch for %s' % child) if child.haschildren: check_index(child) # recurs check_index(Path(':'))
def parsetree_from_selectiondata(selectiondata, notebook=None, path=None, text_format='plain'): '''Function to get a parsetree based on the selectiondata contents if at all possible. Used by both copy-paste and drag-and-drop methods. The 'notebook' and optional 'path' arguments are used to format links relative to the page which is the target for the pasting or drop operation. For image data, the parameters notebook and page are used to save the image to the correct attachment folder and return a parsetree with the correct image link. @param selectiondata: a C{Gtk.SelectionData} object @param notebook: a L{Notebook} object @param path: a L{Path} object @param text_format: format to parse pasted text, as a special case - "verbatim" will wrap content in VERBARIM_BLOCK or VERBATIM element based on the content - "verbatim-pre" will wrap the content in a VERBATIM_BLOCK element and - "verbatim-code" will wrap the content in a VERBATIM element @returns: a L{ParseTree} or C{None} ''' # TODO: check relative linking for all parsetrees !!! targetname = selectiondata.get_target().name() if targetname == PARSETREE_TARGET_NAME: return ParseTree().fromstring(selectiondata.get_data()) elif targetname in (INTERNAL_PAGELIST_TARGET_NAME, PAGELIST_TARGET_NAME) \ or targetname in URI_TARGET_NAMES: links = selectiondata.get_uris() return _link_tree(links, notebook, path) elif targetname in TEXT_TARGET_NAMES: # plain text parser should highlight urls etc. # FIXME some apps drop text/uri-list as a text/plain mimetype # try to catch this situation by a check here text = selectiondata.get_text() if text: if text_format in ('verbatim', 'verbatim-pre', 'verbatim-code'): if text_format == 'verbatim': tag_name = 'pre' if '\n' in text else 'code' else: tag_name = text_format[9:] builder = ParseTreeBuilder(partial=True) builder.start('zim-tree', {}) builder.start(tag_name, {}) builder.text(text) builder.end(tag_name) builder.end('zim-tree') return builder.get_parsetree() else: return get_format(text_format).Parser().parse(text, partial=True) else: return None elif targetname in IMAGE_TARGET_NAMES: # save image pixbuf = selectiondata.get_pixbuf() if not pixbuf: return None dir = notebook.get_attachments_dir(path) assert isinstance(dir, LocalFolder) or hasattr( dir, '_folder') and isinstance(dir._folder, LocalFolder) # XXX: assert we have local path - HACK to deal with FilesAttachmentFolder if not dir.exists(): logger.debug("Creating attachment dir: %s", dir) dir.touch() format, extension = _get_image_info(targetname) if format is None or format == 'bmp': # default to png format # special casing bmp since many window apps use it internally # but is quite large to store, so compress by using png format, extension = 'png', 'png' file = dir.new_file('pasted_image.%s' % extension) logger.debug("Saving image from clipboard to %s", file) pixbuf.savev(file.path, format, [], []) FS.emit('path-created', file) # notify version control links = [file.uri] return _link_tree(links, notebook, path) else: return None
def testManipulate(self): '''Test moving and deleting pages in the memory store''' # Check we can get / store a page page = self.store.get_page(Path('Test:foo')) self.assertTrue(page.get_parsetree()) self.assertTrue('Foo' in ''.join(page.dump('plain'))) self.assertFalse(page.modified) wikitext = tests.WikiTestData.get('roundtrip') page.parse('wiki', wikitext) self.assertEqual(''.join(page.dump('wiki')), wikitext) self.assertTrue(page.modified) self.store.store_page(page) self.assertFalse(page.modified) self.assertEqual(''.join(page.dump('wiki')), wikitext) page = self.store.get_page(Path('Test:foo')) self.assertEqual(''.join(page.dump('wiki')), wikitext) page = self.store.get_page(Path('Test:foo')) text = page.dump('plain') newtext = ['Some new content\n'] assert newtext != text self.assertEqual(page.dump('plain'), text) page.parse('plain', newtext) self.assertEqual(page.dump('plain'), newtext) self.assertTrue(page.modified) re = self.store.revert_page(page) self.assertFalse(re) # no return value self.assertEqual(page.dump('plain'), text) # object reverted self.assertFalse(page.modified) # no longer modified page = self.store.get_page(page) # new object self.assertEqual(page.dump('plain'), text) page.parse('plain', newtext) self.assertEqual(page.dump('plain'), newtext) self.store.store_page(page) page = self.store.get_page(page) # new object self.assertEqual(page.dump('plain'), newtext) # check revert page triggers ui object page._ui_object = tests.MockObject() self.store.revert_page(page) self.assertEqual(page._ui_object.mock_calls[-1][0], 'set_parsetree') if hasattr(page, 'source') and isinstance(page.source, File): # check revert also works when the actual file changed # (and not trigger mtime check failure) from tests.fs import modify_file_mtime, FilterOverWriteWarning page = self.store.get_page(Path('Test:foo')) text = page.dump('plain') newtext = ['Foo bar baz\n'] othertext = ['Dus ja\n'] assert newtext != text assert othertext != text page.parse('plain', newtext) modify_file_mtime(page.source.path, lambda p: open(p, 'w').writelines(othertext)) with FilterOverWriteWarning(): self.assertRaises(FileWriteError, self.store.store_page, page) self.store.revert_page(page) self.assertEqual(page.dump('plain'), othertext) page.parse('plain', newtext) self.store.store_page(page) page = self.store.get_page(page) # new object self.assertEqual(page.dump('plain'), newtext) # check test setup OK for path in (Path('Test:BAR'), Path('NewPage')): page = self.store.get_page(path) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) # check errors self.assertRaises(LookupError, self.store.move_page, Path('NewPage'), Path('Test:BAR')) self.assertRaises(PageExistsError, self.store.move_page, Path('Test:foo'), Path('TaskList')) for oldpath, newpath in ( (Path('Test:foo'), Path('Test:BAR')), (Path('TaskList'), Path('NewPage:Foo:Bar:Baz')), ): page = self.store.get_page(oldpath) text = page.dump('wiki') self.assertTrue(page.haschildren) #~ print ascii_page_tree(self.store) self.store.move_page(oldpath, newpath) #~ print ascii_page_tree(self.store) # newpath should exist and look like the old one page = self.store.get_page(newpath) self.assertTrue(page.haschildren) self.assertEqual(page.dump('wiki'), text) # oldpath should be deleted page = self.store.get_page(oldpath) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) # let's delete the newpath again page = self.store.get_page(newpath) self.assertTrue(self.store.delete_page(page)) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) page = self.store.get_page(newpath) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) # delete again should silently fail self.assertFalse(self.store.delete_page(newpath)) # check cleaning up works OK page = self.store.get_page(Path('NewPage')) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) # check case-sensitive move self.store.move_page(Path('utf8'), Path('UTF8')) page = self.store.get_page(Path('utf8')) # self.assertFalse(page.haschildren) - fails on case-insensitive FS self.assertFalse( Path('utf8') in list(self.store.get_pagelist(Path(':')))) self.assertTrue( Path('UTF8') in list(self.store.get_pagelist(Path(':')))) newpage = self.store.get_page(Path('UTF8')) self.assertTrue(newpage.haschildren) self.assertFalse(newpage == page) # TODO here we only move dir case insensitive - also test file # check hascontents page = self.store.get_page(Path('NewPage')) tree = ParseTree().fromstring('<zim-tree></zim-tree>') self.assertFalse(tree.hascontent) page.set_parsetree(tree) self.assertFalse(page.hascontent) self.store.store_page(page) page = self.store.get_page(Path('NewPage')) self.assertFalse(page.hascontent) # check trashing trashing = True try: page = self.store.get_page(Path('TrashMe')) self.assertTrue(page.haschildren) self.assertTrue(page.hascontent) self.store.trash_page(page) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) page = self.store.get_page(Path('TrashMe')) self.assertFalse(page.haschildren) self.assertFalse(page.hascontent) except TrashNotSupportedError: trashing = False print '(trashing not supported for this store)' self.assertTrue(page.haschildren) self.assertTrue(page.hascontent) page = self.store.get_page(Path('TrashMe')) self.assertTrue(page.haschildren) self.assertTrue(page.hascontent) page = self.store.get_page(Path('NonExistingPage')) if trashing: # fail silently for non-existing page self.assertFalse(self.store.trash_page(page)) else: # check error consistent self.assertRaises(TrashNotSupportedError, self.store.trash_page, page)