| 1 | #!/usr/bin/env python |
|---|
| 2 | # -*- coding: utf-8 -*- |
|---|
| 3 | import sys, string, xml.dom.minidom, os |
|---|
| 4 | try: |
|---|
| 5 | import gtk |
|---|
| 6 | import gobject |
|---|
| 7 | except: |
|---|
| 8 | sys.exit(1) |
|---|
| 9 | |
|---|
| 10 | # this class represent the whole bookmarks list |
|---|
| 11 | class bookmarks_store : |
|---|
| 12 | |
|---|
| 13 | # bts_name is a string arg. It will be used to have |
|---|
| 14 | # differents bookmarks for differents protocols. |
|---|
| 15 | def __init__(self, bts_name, listing) : |
|---|
| 16 | self.bmark_file ="bookmarks_%s.xml" %(bts_name) |
|---|
| 17 | #listing is : Title of the bookmarks, description of the search |
|---|
| 18 | # search method : |
|---|
| 19 | # 1- bug number |
|---|
| 20 | # 2- simple search |
|---|
| 21 | # 3- package search |
|---|
| 22 | # 4- advanced search |
|---|
| 23 | |
|---|
| 24 | self.listing = listing |
|---|
| 25 | self.bts_name = bts_name |
|---|
| 26 | self.root = listing.append(None, (bts_name, "", bts_name)) |
|---|
| 27 | |
|---|
| 28 | # rows-reordered signal not sent |
|---|
| 29 | # but I let this code here, don't know why. |
|---|
| 30 | def reorder_callback(treemodel, path, itera, new_order): |
|---|
| 31 | self.sync_file() |
|---|
| 32 | # Funny ! rows-reordered is not sent but we can |
|---|
| 33 | # use the rows-deleted signal as well. |
|---|
| 34 | def deleted_callback(treemodel, path): |
|---|
| 35 | self.sync_file() |
|---|
| 36 | self.listing.connect("rows-reordered", reorder_callback) |
|---|
| 37 | self.listing.connect("row-deleted", deleted_callback) |
|---|
| 38 | |
|---|
| 39 | if os.path.exists(self.bmark_file) : |
|---|
| 40 | if self.import_file(self.bmark_file) == 0 : |
|---|
| 41 | print "Bookmarks not in a valid format." |
|---|
| 42 | print "Please remove the %s file" %self.bmark_file |
|---|
| 43 | else : |
|---|
| 44 | doc = xml.dom.minidom.Document() |
|---|
| 45 | store = doc.createElement("store") |
|---|
| 46 | doc.appendChild(store) |
|---|
| 47 | #here we can put hardcoded default |
|---|
| 48 | # |
|---|
| 49 | #then we create the file |
|---|
| 50 | f = open(self.bmark_file, mode='a+') |
|---|
| 51 | f.write(doc.toxml().encode("utf-8")) |
|---|
| 52 | f.close() |
|---|
| 53 | |
|---|
| 54 | def import_file(self,zefile) : |
|---|
| 55 | #programmation défensive needed ici !!! |
|---|
| 56 | # !!!!!!!! |
|---|
| 57 | f = open(zefile,mode='r') |
|---|
| 58 | # sanitize the pretty XML |
|---|
| 59 | stringed = f.read().replace('\n','').replace('\t','') |
|---|
| 60 | try : |
|---|
| 61 | doc = xml.dom.minidom.parseString(stringed) |
|---|
| 62 | except : |
|---|
| 63 | return 0 |
|---|
| 64 | for bmark in doc.getElementsByTagName("bookmark") : |
|---|
| 65 | title = bmark.getAttribute("title") |
|---|
| 66 | self.listing.insert_before(self.root, None, (title, bmark.toxml(), self.bts_name)) |
|---|
| 67 | return 1 |
|---|
| 68 | |
|---|
| 69 | def open_file(self,zefile) : |
|---|
| 70 | #programmation défensive needed ici !!! |
|---|
| 71 | # !!!!!!!! |
|---|
| 72 | array=[] |
|---|
| 73 | f = open(zefile,mode='r') |
|---|
| 74 | # sanitize the pretty XML |
|---|
| 75 | stringed = f.read().replace('\n','').replace('\t','') |
|---|
| 76 | try : |
|---|
| 77 | doc = xml.dom.minidom.parseString(stringed) |
|---|
| 78 | except : |
|---|
| 79 | return array |
|---|
| 80 | for bmark in doc.getElementsByTagName("bookmark") : |
|---|
| 81 | array.append(bmark.toxml()) |
|---|
| 82 | return array |
|---|
| 83 | |
|---|
| 84 | def add(self,args) : |
|---|
| 85 | #do not forget to also add the bookmarks to |
|---|
| 86 | #the stored bookmarks. (sync with storage) |
|---|
| 87 | doc2 = xml.dom.minidom.parseString(args) |
|---|
| 88 | bmark = doc2.getElementsByTagName("bookmark")[0] |
|---|
| 89 | title = bmark.getAttribute("title") |
|---|
| 90 | self.listing.insert_before(self.root, None, (title, args, self.bts_name)) |
|---|
| 91 | self.sync_file() |
|---|
| 92 | |
|---|
| 93 | def delete(self, to_delete) : |
|---|
| 94 | #do not forget to also remove the bookmarks from |
|---|
| 95 | #the stored bookmarks. (sync with storage) |
|---|
| 96 | if self._is_bookmark(to_delete): |
|---|
| 97 | self.listing.remove(to_delete) |
|---|
| 98 | self.sync_file() |
|---|
| 99 | |
|---|
| 100 | def rename(self, to_rename, new_name) : |
|---|
| 101 | if self._is_bookmark(to_delete): |
|---|
| 102 | self.listing[to_rename][0]=new_name |
|---|
| 103 | self.sync_file() |
|---|
| 104 | |
|---|
| 105 | def _is_bookmark(self, iter): |
|---|
| 106 | return self.listing.get_value(iter, 1) |
|---|
| 107 | |
|---|
| 108 | def sync_file(self) : |
|---|
| 109 | doc = xml.dom.minidom.Document() |
|---|
| 110 | store = doc.createElement("store") |
|---|
| 111 | doc.appendChild(store) |
|---|
| 112 | for i in self.listing[self.listing.get_path(self.root)].iterchildren() : |
|---|
| 113 | doc2 = xml.dom.minidom.parseString(i[1]) |
|---|
| 114 | bmark = doc2.getElementsByTagName("bookmark")[0] |
|---|
| 115 | bmark.setAttribute("title",i[0].strip()) |
|---|
| 116 | store.appendChild(bmark) |
|---|
| 117 | #it's maybe not optimal to open/close the file each time we sync |
|---|
| 118 | # but I'm not sure that those operations are so frequent |
|---|
| 119 | # might be changed in the future. |
|---|
| 120 | f = open(self.bmark_file, mode='w+') |
|---|
| 121 | f.write(doc.toprettyxml().encode("utf-8")) |
|---|
| 122 | f.close() |
|---|
| 123 | |
|---|
| 124 | # this is a lonely bookmark in the store |
|---|
| 125 | class bookmark : |
|---|
| 126 | # constructor take the path to the bug in the store. |
|---|
| 127 | def __init__(self,path,descr,bts) : |
|---|
| 128 | zbug = 0 |
|---|
| 129 | zsearch = '' |
|---|
| 130 | zproduct = '' |
|---|
| 131 | ztitle = '' |
|---|
| 132 | if path != None : |
|---|
| 133 | zetuple = path.get_selection().get_selected() |
|---|
| 134 | #cursor = path.get_cursor() |
|---|
| 135 | #print zetuple |
|---|
| 136 | #print cursor |
|---|
| 137 | string = zetuple[0].get_value(zetuple[1],1) |
|---|
| 138 | else : |
|---|
| 139 | string = descr |
|---|
| 140 | doc2 = xml.dom.minidom.parseString(string) |
|---|
| 141 | bmark = doc2.getElementsByTagName("bookmark")[0] |
|---|
| 142 | zmethod = int(bmark.getAttribute("type")) |
|---|
| 143 | if zmethod == 1: |
|---|
| 144 | # besoin de programmation défensive ici FIXME |
|---|
| 145 | #bug = int(zetuple[0].get_value(zetuple[1],2)) |
|---|
| 146 | element = bmark.getElementsByTagName("bug")[0] |
|---|
| 147 | zbug = int(element.childNodes[0].nodeValue) |
|---|
| 148 | elif zmethod == 2: |
|---|
| 149 | s_element = bmark.getElementsByTagName("search")[0] |
|---|
| 150 | zsearch = s_element.childNodes[0].nodeValue |
|---|
| 151 | elif zmethod == 3: |
|---|
| 152 | s_element = bmark.getElementsByTagName("search") |
|---|
| 153 | p_element = bmark.getElementsByTagName("product")[0] |
|---|
| 154 | zproduct = p_element.childNodes[0].nodeValue |
|---|
| 155 | if len(s_element) == 0 : |
|---|
| 156 | zsearch = None |
|---|
| 157 | else : |
|---|
| 158 | zsearch = s_element[0].childNodes[0].nodeValue |
|---|
| 159 | self.bug = str(zbug) |
|---|
| 160 | self.method = zmethod |
|---|
| 161 | self.search = zsearch |
|---|
| 162 | self.product = zproduct |
|---|
| 163 | self.title = bmark.getAttribute("title") |
|---|
| 164 | self.bts = bts |
|---|
| 165 | |
|---|
| 166 | def get_method(self) : |
|---|
| 167 | return self.method |
|---|
| 168 | |
|---|
| 169 | def get_bug(self) : |
|---|
| 170 | return self.bug |
|---|
| 171 | |
|---|
| 172 | def get_search(self) : |
|---|
| 173 | return self.search |
|---|
| 174 | |
|---|
| 175 | def get_product(self) : |
|---|
| 176 | return self.product |
|---|
| 177 | |
|---|
| 178 | def get_title(self) : |
|---|
| 179 | return self.title |
|---|