Changeset 4946 for branch/QuickScan
- Timestamp:
- 06/29/09 18:05:30 (4 years ago)
- Location:
- branch/QuickScan
- Files:
-
- 1 added
- 28 modified
-
. (modified) (1 prop)
-
higwidgets/higrichlists.py (modified) (9 diffs)
-
install_scripts/common.py (modified) (1 diff)
-
source-plugins/context-menu/setup.py (modified) (2 diffs)
-
source-plugins/dummy-working/setup.py (modified) (2 diffs)
-
source-plugins/flow-analyzer/setup.py (modified) (2 diffs)
-
source-plugins/flow-analyzer/sources/main.py (modified) (1 diff)
-
source-plugins/localized-example/setup.py (modified) (2 diffs)
-
source-plugins/notifier/setup.py (modified) (2 diffs)
-
source-plugins/system-info-consumer/setup.py (modified) (2 diffs)
-
source-plugins/system-info/setup.py (modified) (2 diffs)
-
source-plugins/tabber/setup.py (modified) (2 diffs)
-
source-plugins/terminal-pad/setup.py (modified) (2 diffs)
-
source-plugins/testcase/setup.py (modified) (2 diffs)
-
source-plugins/throbber/setup.py (modified) (2 diffs)
-
source-plugins/tray-icon/setup.py (modified) (3 diffs)
-
source-plugins/umit-console/setup.py (modified) (2 diffs)
-
umit/core/UmitDB.py (modified) (1 diff)
-
umit/core/qs/DataHandler.py (added)
-
umit/core/qs/ImportData.py (modified) (5 diffs)
-
umit/gui/MainWindow.py (modified) (3 diffs)
-
umit/gui/qs/Main.py (modified) (5 diffs)
-
umit/gui/radialnet/RadialNet.py (modified) (1 diff)
-
umit/plugin/Containers.py (modified) (19 diffs)
-
umit/plugin/Engine.py (modified) (7 diffs)
-
umit/plugin/Network.py (modified) (4 diffs)
-
umit/plugin/PluginPage.py (modified) (27 diffs)
-
umit/plugin/Update.py (modified) (19 diffs)
-
umit/plugin/Window.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branch/QuickScan
- Property svnmerge-integrated changed from /trunk:1-4792 to /trunk:1-4937
-
branch/QuickScan/higwidgets/higrichlists.py
r4243 r4946 90 90 91 91 return True 92 92 93 93 def do_realize(self): 94 94 gtk.EventBox.do_realize(self) … … 99 99 (evt.type == gtk.gdk._2BUTTON_PRESS) and \ 100 100 (self.tree.change_selection(self)): 101 101 102 102 self.active = True 103 103 self.emit('clicked') … … 162 162 self.enabled = self._reader.enabled 163 163 self.connect('activate', self.__on_activate) 164 164 165 165 self.show_all() 166 166 167 167 self.progressbar.hide() 168 168 self.box_act.hide() 169 self. include_button.hide()169 self.versions_button.hide() 170 170 171 171 def __create_widgets(self): … … 174 174 self.label = gtk.Label('') 175 175 self.label.set_ellipsize(pango.ELLIPSIZE_END) 176 177 self.include_button = gtk.CheckButton(_('Include update')) 176 177 self.versions_model = gtk.ListStore(str, str) 178 self.versions_button = gtk.ComboBox(self.versions_model) 179 180 rend = gtk.CellRendererPixbuf() 181 self.versions_button.pack_start(rend, False) 182 self.versions_button.add_attribute(rend, 'stock-id', 0) 183 184 rend = gtk.CellRendererText() 185 self.versions_button.pack_end(rend) 186 self.versions_button.add_attribute(rend, 'text', 1) 178 187 179 188 self.img_play = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, \ … … 197 206 198 207 vbox = gtk.VBox(False, 2) 199 208 200 209 mhbox = gtk.HBox(False, 2) 201 210 self.label.set_alignment(0, 0.5) 202 211 203 212 mhbox.pack_start(self.label) 204 mhbox.pack_start(self.include_button, False, False) 205 213 214 minibox = gtk.VBox() 215 minibox.pack_start(self.versions_button, False, False, 0) 216 217 mhbox.pack_start(minibox, False, False) 218 206 219 vbox.pack_start(mhbox) 207 220 vbox.pack_start(self.progressbar, False, False, 0) … … 285 298 def get_message(self): 286 299 return self._message 287 300 288 301 def set_message(self, value): 289 302 """ 290 303 If not defined don't update 291 304 """ 292 305 293 306 if value is not None: 294 307 self._message = value 295 308 296 309 # Used to update the label 297 310 self.enabled = self.enabled … … 314 327 self.progressbar.set_text('%d %%' % int(val * 100)) 315 328 self.progressbar.show() 316 329 317 330 def get_include(self): 318 331 if self._show_include: 319 return self.include_button.get_active() 332 id = self.versions_button.get_active() -1 333 334 if id >= 0: 335 return True 320 336 else: 321 337 return False 322 338 323 339 def set_include(self, value): 324 340 self._show_include = value 325 341 326 342 if value: 327 self. include_button.show()328 else: 329 self. include_button.hide()343 self.versions_button.show() 344 else: 345 self.versions_button.hide() 330 346 331 347 def get_activatable(self): … … 365 381 366 382 gtk.ScrolledWindow.__init__(self) 367 383 368 384 self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) 369 385 self.set_shadow_type(gtk.SHADOW_ETCHED_IN) … … 413 429 414 430 self.vbox.foreach(remove, self.vbox) 415 431 416 432 def get_rows(self): 417 433 return len(self.vbox) -
branch/QuickScan/install_scripts/common.py
r4386 r4946 7 7 BIN_DIRNAME = 'bin' 8 8 UMIT_MAIN = os.path.join(BIN_DIRNAME, 'umit') 9 9 UMIT_SCHEDULER = os.path.join(BIN_DIRNAME, 'umit_scheduler.py') 10 10 # These directories are relative to the installation or dist directory 11 11 # Ex: python setup.py install --prefix=/tmp/umit -
branch/QuickScan/source-plugins/context-menu/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='Context menu', 25 25 version='1.0', 26 author='Francesco Piccinno', 27 url='http://snippets.pornosecurity.org', 26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 license=['GPL'], 29 copyright=['(C) 2009 Adriano Monteiro Marques'], 28 30 start_file='main', 29 provide s='=context-menu-1.0',31 provide=['=context-menu-1.0'], 30 32 description='a context menu for host list', 31 33 scripts=['sources/main.py'], -
branch/QuickScan/source-plugins/dummy-working/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='dummy-working', 25 25 version='1.0', 26 author='Francesco Piccinno', 27 url='http://snippets.pornosecurity.org', 28 update='http://localhost/~stack/plugins/dummywork', 26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 update=['http://localhost/~stack/plugins/dummywork'], 29 license=['GPL'], 30 copyright=['(C) 2009 Adriano Monteiro Marques'], 29 31 scripts=['sources/main.py'], 30 32 start_file="main", 31 33 data_files=[('data', ['dist/logo.png'])], 32 provide s='=dummy-1.0',34 provide=['=dummy-1.0'], 33 35 description='a dummy plugin (working)', 34 36 package_dir={'dummy' : 'sources/dummy'}, -
branch/QuickScan/source-plugins/flow-analyzer/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='Flow Analyzer', 25 25 version='1.0', 26 author= 'Francesco Piccinno',27 url='http:// snippets.pornosecurity.org',26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 28 start_file='main', 29 provide s='=flow-analyzer-1.0',29 provide=['=flow-analyzer-1.0'], 30 30 description='a simple plugin that analyze parsed XML file from nmap', 31 license=['GPL'], 32 copyright=['(C) 2009 Adriano Monteiro Marques'], 31 33 scripts=['sources/main.py'], 32 34 data_files=[('data', ['dist/logo.png'])], -
branch/QuickScan/source-plugins/flow-analyzer/sources/main.py
r4255 r4946 46 46 paned.pack2(scroll(self.text2)) 47 47 48 message = "Not yet avai able. Try to start a scan!"48 message = "Not yet available. Try to start a scan!" 49 49 50 50 self.text1.get_buffer().set_text(message) -
branch/QuickScan/source-plugins/localized-example/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 33 33 name='Localize-Example', 34 34 version='1.0', 35 author= 'Francesco Piccinno',36 url='http:// snippets.pornosecurity.org',35 author=['Francesco Piccinno'], 36 url='http://blog.archpwn.org', 37 37 scripts=['sources/main.py'], 38 38 start_file="main", 39 39 data_files=[('data', ['dist/logo.png'])] + mo_files, 40 provide s='=localize-1.0',40 provide=['=localize-1.0'], 41 41 description='a localized plugin for testing', 42 license=['GPL'], 43 copyright=['(C) 2009 Adriano Monteiro Marques'], 42 44 output='Localize.ump' 43 45 ) -
branch/QuickScan/source-plugins/notifier/setup.py
r4592 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='Notifier', 25 25 version='0.1', 26 author= 'Francesco Piccinno',26 author=['Francesco Piccinno'], 27 27 url='http://blog.archpwn.org', 28 28 start_file='main', 29 need s='>=tray-2.0',29 need=['>=tray-2.0'], 30 30 description='This plugin will warn you trough ballons or notification that a scan has finished', 31 license=['GPL'], 32 copyright=['(C) 2009 Adriano Monteiro Marques'], 31 33 data_files=[('data', ['dist/logo.png'])], 32 34 scripts=['sources/main.py'], -
branch/QuickScan/source-plugins/system-info-consumer/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='SystemInfo-Consumer', 25 25 version='0.1', 26 author= 'Francesco Piccinno',27 url='http:// snippets.pornosecurity.org',26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 28 start_file='main', 29 need s='>=SystemInfo-0.1',29 need=['>=SystemInfo-0.1'], 30 30 description='A plugin that use SystemInfo <i>calls</i>', 31 license=['GPL'], 32 copyright=['(C) 2009 Adriano Monteiro Marques'], 31 33 data_files=[('data', ['dist/logo.png'])], 32 34 scripts=['sources/main.py'], -
branch/QuickScan/source-plugins/system-info/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='SystemInfo', 25 25 version='0.1', 26 author= 'Francesco Piccinno',27 url='http:// snippets.pornosecurity.org',28 update= 'http://localhost/~stack/plugins/systeminfo',26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 update=['http://localhost/mia/', 'http://localhost/'], 29 29 start_file='main', 30 provide s='>=SystemInfo-1.0',30 provide=['>=SystemInfo-1.0'], 31 31 description='A plugin that provides info about the system', 32 license=['GPL'], 33 copyright=['(C) 2009 Adriano Monteiro Marques'], 32 34 scripts=['sources/main.py'], 33 35 data_files=[('data', ['dist/logo.png'])], -
branch/QuickScan/source-plugins/tabber/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 134 134 name='Tabber', 135 135 version='1.0', 136 author= 'Francesco Piccinno (code ripped from PIDA)',137 url='http:// snippets.pornosecurity.org',136 author=['Francesco Piccinno (code ripped from PIDA)'], 137 url='http://blog.archpwn.org', 138 138 start_file='main', 139 provide s='=Tabber-1.0',139 provide=['=Tabber-1.0'], 140 140 description='Tabber provides docking functionality to UMIT UI (code ripped from PIDA)', 141 license=['GPL'], 142 copyright=['(C) 2009 Adriano Monteiro Marques'], 141 143 data_files=[('data', ['dist/logo.png'])], 142 144 scripts=['sources/main.py'], -
branch/QuickScan/source-plugins/terminal-pad/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='Terminal', 25 25 version='1.0', 26 author= 'Francesco Piccinno',27 url='http:// snippets.pornosecurity.org',26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 28 start_file='main', 29 provide s='=terminal-1.0',29 provide=['=terminal-1.0'], 30 30 description='A simple terminal page for UMIT (vte)', 31 license=['GPL'], 32 copyright=['(C) 2009 Adriano Monteiro Marques'], 31 33 scripts=['sources/main.py'], 32 34 data_files=[('data', ['dist/logo.png'])], -
branch/QuickScan/source-plugins/testcase/setup.py
r4746 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 124 124 name='TestCase', 125 125 version='1.0', 126 author='Francesco Piccinno', 126 author=['Francesco Piccinno'], 127 license=['GPL'], 128 copyright=['(C) 2009 Adriano Monteiro Marques'], 127 129 url='http://blog.archpwn.org', 128 130 scripts=['sources/main.py'], -
branch/QuickScan/source-plugins/throbber/setup.py
r4592 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Francesco Piccinno3 # Copyright (C) 2009 Francesco Piccinno 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='ThrobberAnimation', 25 25 version='1.0', 26 author= 'Francesco Piccinno',26 author=['Francesco Piccinno'], 27 27 url='http://blog.archpwn.org', 28 28 scripts=['sources/main.py'], 29 29 start_file="main", 30 30 data_files=[('data', ['dist/logo.png', 'dist/throbber-16.gif'])], 31 provide s='=ThrobberAnimation-1.0',31 provide=['=ThrobberAnimation-1.0'], 32 32 description='This plugin adds a throbber that\'s showed when a scan is running.', 33 license= "GPL",34 copyright= "(C) 2009 - Francesco Piccinno",33 license=["GPL"], 34 copyright=["(C) 2009 - Francesco Piccinno"], 35 35 output='throbberanimation.ump' 36 36 ) -
branch/QuickScan/source-plugins/tray-icon/setup.py
r4592 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='Tray Icon', 25 25 version='2.0', 26 author= 'Francesco Piccinno',26 author=['Francesco Piccinno'], 27 27 url='http://blog.archpwn.org', 28 28 start_file='main', 29 provide s='=tray-2.0',29 provide=['=tray-2.0'], 30 30 description='A simple tray icon for Umit', 31 31 scripts=['sources/main.py'], … … 33 33 package_dir={'notification' : 'sources/notification'}, 34 34 packages=['notification'], 35 license='GPL', 35 license=['GPL'], 36 copyright=['(C) 2009 Adrian Monteiro Marques'], 36 37 output='TrayIcon.ump' 37 38 ) -
branch/QuickScan/source-plugins/umit-console/setup.py
r4255 r4946 1 1 #!/usr/bin/env python 2 2 # -*- coding: utf-8 -*- 3 # Copyright (C) 200 8Adriano Monteiro Marques3 # Copyright (C) 2009 Adriano Monteiro Marques 4 4 # 5 5 # Author: Francesco Piccinno <stack.box@gmail.com> … … 24 24 name='Umit Console', 25 25 version='1.0', 26 author= 'Francesco Piccinno',27 url='http:// snippets.pornosecurity.org',26 author=['Francesco Piccinno'], 27 url='http://blog.archpwn.org', 28 28 start_file='main', 29 need s='>=Tabber-1.0',29 need=['>=Tabber-1.0'], 30 30 description='a Python console for UMIT interacting', 31 license=['GPL'], 32 copyright=['(C) 2009 Adriano Monteiro Marques'], 31 33 scripts=['sources/main.py'], 32 34 package_dir={'console' : 'sources/console'}, -
branch/QuickScan/umit/core/UmitDB.py
r4479 r4946 23 23 24 24 try: 25 from hashlib import md5 25 import hashlib 26 class digest: 27 def __init__(self, dig, hash): 28 self._dig = dig 29 self._hash = hash 30 def hexdigest(self): 31 self._hash.hexdigest() 32 33 class md5new: 34 def __init__(self): 35 pass 36 def new(self,arg): 37 m = hashlib.new('md5') 38 m.update(arg) 39 return digest(m.digest(), m) 40 md5 = md5new() 26 41 except ImportError: 27 42 # Python 2.4 28 43 import md5 29 30 44 31 45 from umit.core.I18N import _ -
branch/QuickScan/umit/core/qs/ImportData.py
r4937 r4946 23 23 import gtk 24 24 25 from tempfile import TemporaryFile 26 25 27 #TODO: implement logging 26 28 … … 32 34 from umit.core.OptionsConf import options_file 33 35 from umit.core.NmapOptions import NmapOptions 36 from umit.core.NmapParser import NmapParser 34 37 from umit.core.ScanProfileConf import scan_profile_file 35 36 from umit.core import UmitDB37 38 38 39 except ImportError, e: … … 47 48 def __init__(self): 48 49 #path hard-coded to test 49 Path.set_umit_conf(os.path.dirname("/home/cassiano/.umit/")) 50 #Path.set_umit_conf(os.path.dirname("/home/cassiano/.umit/")) 51 Path.set_umit_conf(os.path.dirname(sys.argv[0])) 52 Path.set_running_path(os.path.abspath(os.path.dirname(sys.argv[0]))) 50 53 self.r_scans = RecentScans() 51 54 self.t_list = TargetList() … … 72 75 73 76 def get_from_db(self): 77 """Getting results from database""" 78 from umit.core.UmitDB import UmitDB # -> ugly.. :| 74 79 db = UmitDB() 75 a = db.get_scans() 80 81 for scan in db.get_scans(): 82 83 #creating temporary file to store nmap xml 84 temp_file = TemporaryFile() 85 temp_file.write(scan.nmap_xml_output) 86 temp_file.seek(0) 87 88 try: 89 parsed = NmapParser() 90 parsed.set_xml_file(temp_file.read()) 91 parsed.parse() 92 93 # Remove temporary file reference 94 parsed.nmap_xml_file = "" 95 temp_file.close() 96 except IOError, e: 97 raise(e) 76 98 77 99 def get_profiles(self): … … 97 119 98 120 if __name__ == "__main__": 99 a = Data() 100 b = 0121 a = Data() 122 a.get_from_db() 101 123 # print a.get_nmap_options() 102 124 # print a.get_nmap_command_option('List Scan') -
branch/QuickScan/umit/gui/MainWindow.py
r4789 r4946 57 57 from umit.gui.Help import show_help 58 58 59 from umit.core.Paths import Path 59 from umit.core.Paths import Path, check_access 60 60 from umit.core.RecentScans import recent_scans 61 61 from umit.core.UmitLogging import log … … 119 119 self._create_toolbar() 120 120 self._create_scan_notebook() 121 self._verify_access_write() 121 122 self._verify_root() 122 123 … … 144 145 if not root: 145 146 non_root = NonRootWarning() 147 148 def _verify_access_write(self): 149 if (not check_access(Path.config_file, os.R_OK and os.W_OK )): 150 error_text = _('''You do not have access to config files!\nPlease run Umit as root or change permissions %s 151 ''' % Path.config_dir) 152 153 d = HIGAlertDialog(message_format=_('Permission Denied'), 154 secondary_text=error_text) 155 d.run() 156 sys.exit(0) 146 157 147 158 def _get_running_ni(self): -
branch/QuickScan/umit/gui/qs/Main.py
r4937 r4946 47 47 48 48 #TODO: i18n! 49 #TODO: Fix the umit conf issue50 49 #TODO: Fix the paths of modules issue 51 50 52 51 def __init__(self): 52 Path.set_umit_conf(os.path.dirname(sys.argv[0])) 53 Path.set_running_path(os.path.abspath(os.path.dirname(sys.argv[0]))) 53 54 MainWindow.__init__(self) 54 55 self.set_title("Quick Scan") … … 60 61 61 62 self.liststore = gtk.ListStore(str) 62 63 Path.set_umit_conf(os.path.dirname("/home/cassiano/.umit/"))64 63 65 64 def is_root(self): … … 84 83 pass 85 84 85 completion.set_match_func(self.match_func) 86 86 completion.set_model(self.liststore) 87 87 self.entry.set_completion(completion) … … 101 101 self.vbox.show() 102 102 self.show_all() 103 104 def match_func(self, completion, key, iter): 105 model = completion.get_model() 106 try: 107 r = model[iter][0].startswith(self.entry.get_text().split()[1]) 108 except: 109 r = model[iter][0].startswith(self.entry.get_text().split()[0]) 110 111 return r 103 112 104 113 def match_results(self, completion, model, iter): 105 text_output = " "114 text_output = "Ok" 106 115 self.buffer.set_text(text_output) 107 116 self.vbox.pack_end(self.result_text, False, False, 0) … … 122 131 except OSError, msg: 123 132 raise(msg) 124 125 133 126 #TODO: separar os resultados no completion, implementando a segmentação da busca127 134 128 135 if __name__ == "__main__": 129 136 a = Main() 137 # a.run_scan(Path.nmap_command_path, "-v", "localhost") 130 138 a.run() 131 139 gtk.main() -
branch/QuickScan/umit/gui/radialnet/RadialNet.py
r4794 r4946 3 3 # Copyright (C) 2007 Adriano Monteiro Marques 4 4 # 5 <<<<<<< .working 5 6 # Author: João Paulo de Souza Medeiros <ignotus21@gmail.com> 7 ======= 8 # Author: Joao Paulo de Souza Medeiros <ignotus21@gmail.com> 9 >>>>>>> .merge-right.r4935 6 10 # 7 11 # This program is free software; you can redistribute it and/or modify -
branch/QuickScan/umit/plugin/Containers.py
r4746 r4946 21 21 import os 22 22 import os.path 23 import sys 23 24 24 25 from fnmatch import fnmatch 25 26 from zipfile import ZipFile, BadZipfile, ZIP_DEFLATED 26 from xml.dom.minidom import parseString, getDOMImplementation 27 28 from StringIO import StringIO 29 30 from xml.sax import handler, make_parser 31 from xml.sax.saxutils import XMLGenerator 32 from xml.sax.xmlreader import AttributesImpl 33 27 34 from tempfile import mktemp 28 35 … … 55 62 import shutil 56 63 57 # FIXME: add others fields58 FIELDS = (59 "url",60 "conflicts",61 "provides",62 "needs",63 "type",64 "start_file",65 "name",66 "version", # only a convenient field67 "description",68 "author",69 "license",70 "artist",71 "copyright",72 "update"73 )74 75 64 SIGNATURE = "UmitPlugin" 65 66 class ManifestObject(object): 67 def __init__(self): 68 69 # Ok here we're using list object because py2.5 seems to not support 70 # index() for tuple. Stupid 2.5 :) 71 72 self.elements = [ 73 ['name', 'version', 'description', 'url'], 74 ['start_file', 'update'], 75 ['provide', 'need', 'conflict'], 76 ['license', 'copyright', 'author', 77 'contributor', 'translator', 'artist'] 78 ] 79 80 self.containers = [SIGNATURE, 'runtime', 'deptree', 'credits'] 81 82 self.name = '' 83 self.version = '' 84 self.description = '' 85 self.url = '' 86 87 self.start_file = '' 88 self.update = [] 89 90 self.provide = [] 91 self.need = [] 92 self.conflict = [] 93 94 self.license = [] 95 self.copyright = [] 96 self.author = [] 97 self.contributor = [] 98 self.translator = [] 99 self.artist = [] 100 101 self.attr_type = '' 102 103 def check_validity(self, use_print=False): 104 """ 105 Checks the fields presents and validity 106 107 @return True if it's ok 108 """ 109 110 # This fields should be present and not null 111 fields = ('name', 'version', 'description', 'url', 'start_file', 112 'license', 'copyright', 'author') 113 114 for element in fields: 115 if not getattr(self, element, None): 116 txt = 'Element named %s should not be null.' % (element) 117 118 if use_print: 119 print txt 120 else: 121 log.warning(txt) 122 123 return False 124 125 return True 126 127 def get_provides(self): return self.provide 128 def get_conflicts(self): return self.conflict 129 def get_needs(self): return self.need 130 131 provides = property(get_provides) 132 conflicts = property(get_conflicts) 133 needs = property(get_needs) 134 135 class ManifestLoader(handler.ContentHandler, ManifestObject): 136 def __init__(self): 137 ManifestObject.__init__(self) 138 139 self.element_idx = 0 140 self.parsing_pass = -1 141 self.current_element = None 142 self.data = None 143 144 def startElement(self, name, attrs): 145 try: 146 self.element_idx = self.elements[self.parsing_pass].index(name) 147 self.current_element = \ 148 self.elements[self.parsing_pass][self.element_idx] 149 150 except IndexError: 151 log.debug('Element named `%s` is not in %s' % \ 152 (name, self.elements[self.parsing_pass])) 153 154 except ValueError: 155 try: 156 idx = self.containers.index(name) 157 158 if self.parsing_pass < idx: 159 self.parsing_pass = idx 160 else: 161 log.warning('Element `%s` is not valid at this point. ' \ 162 'Should compare before %s' % (name, 163 self.containers[self.parsing_pass])) 164 165 if self.parsing_pass == 0: 166 if type in attrs.keys(): 167 self.attr_type = attrs.get('type') 168 else: 169 self.attr_type = 'ui' 170 171 except ValueError: 172 log.debug('Element named `%s` not excepted.' % name) 173 174 def characters(self, ch): 175 if not self.current_element: 176 return 177 178 if not self.data: 179 self.data = ch 180 else: 181 self.data += ch 182 183 def endElement(self, name): 184 if self.current_element == name: 185 try: 186 attr = getattr(self, name) 187 188 if isinstance(attr, basestring): 189 setattr(self, name, self.data) 190 elif isinstance(attr, list): 191 attr.append(self.data) 192 finally: 193 self.current_element = None 194 self.data = None 195 196 class ManifestWriter(object): 197 def startElement(self, names, attrs): 198 self.depth_idx += 1 199 self.writer.characters(' ' * self.depth_idx) 200 self.writer.startElement(names, attrs) 201 202 def endElement(self, name): 203 self.writer.endElement(name) 204 self.writer.characters('\n') 205 self.depth_idx -= 1 206 207 def __init__(self, manifest): 208 assert isinstance(manifest, ManifestObject) 209 210 self.output = StringIO() 211 self.depth_idx = -1 212 self.manifest = manifest 213 self.writer = XMLGenerator(self.output, 'utf-8') 214 self.writer.startDocument() 215 216 attr_vals = { 217 'xmlns' : 'http://www.umitproject.org', 218 'xsi:schemaLocation' : 'http://www.umitproject.org UmitPlugins.xsd', 219 'xmlns:xsi' : 'http://www.w3.org/2001/XMLSchema-instance', 220 'type' : manifest.attr_type or 'ui' 221 } 222 223 self.startElement('UmitPlugin', AttributesImpl(attr_vals)), 224 self.writer.characters('\n') 225 226 # First phase saving 227 for elem in manifest.elements[0]: 228 self.add_element(elem) 229 230 # Runtime block 231 self.startElement('runtime', {}) 232 self.writer.characters('\n') 233 234 self.add_element('start_file') 235 self.add_element('update') 236 237 self.writer.characters(' ' * self.depth_idx) 238 self.endElement('runtime') 239 240 # Deptree block 241 if manifest.provide or manifest.need or manifest.conflict: 242 self.startElement('deptree', {}) 243 self.writer.characters('\n') 244 245 self.add_element('provide') 246 self.add_element('need') 247 self.add_element('conflict') 248 249 self.writer.characters(' ' * self.depth_idx) 250 self.endElement('deptree') 251 252 # Credits block 253 self.startElement('credits', {}) 254 self.writer.characters('\n') 255 256 for elem in manifest.elements[3]: 257 self.add_element(elem) 258 259 self.writer.characters(' ' * self.depth_idx) 260 self.endElement('credits') 261 262 self.endElement('UmitPlugin') 263 self.writer.endDocument() 264 265 def add_element(self, name): 266 value = getattr(self.manifest, name, None) 267 268 if not value: 269 return 270 271 if isinstance(value, basestring): 272 self.startElement(name, {}) 273 self.writer.characters(value) 274 self.endElement(name) 275 elif isinstance(value, list): 276 for item in value: 277 self.startElement(name, {}) 278 self.writer.characters(item) 279 self.endElement(name) 280 281 def get_output(self): 282 return self.output.getvalue() 76 283 77 284 class BadPlugin(Exception): … … 79 286 pass 80 287 81 class PluginReader( object):288 class PluginReader(ManifestLoader): 82 289 def __init__(self, file): 290 ManifestLoader.__init__(self) 291 83 292 self.path = file 84 293 self.enabled = False … … 88 297 try: 89 298 self.file = ZipFile(file, "r") 90 except BadZipfile:299 except: 91 300 raise BadPlugin("Not a valid umit plugin format") 92 301 93 302 if not self.parse_manifest(): 94 303 raise BadPlugin("Not a valid umit plugin manifest") 95 304 96 305 if not self.check_validity(): 97 306 raise BadPlugin("Validation phase not passed") … … 103 312 """ 104 313 Parse the Manifest.xml inside the zip file and set the fields 105 314 106 315 @return 107 316 False if the Manifest is not in the proper format 108 317 True if everything is ok 109 318 """ 110 319 111 320 try: 112 data = self.file.read("Manifest.xml") 113 doc = parseString(data) 114 except Exception: 321 # TODO: add validation of the manifest 322 323 # Py2.5 doesn't have open on ZipFile object 324 fileobj = StringIO(self.file.read('Manifest.xml')) 325 326 parser = make_parser() 327 parser.setContentHandler(self) 328 329 parser.parse(fileobj) 330 except Exception, err: 331 log.debug('Exception in parse_manifest(): %s' % str(err)) 115 332 return False 116 117 if doc.documentElement.tagName != SIGNATURE: 118 return False 119 120 for field in FIELDS: 121 setattr(self, field, "") 122 123 for node in doc.documentElement.childNodes: 124 if node.nodeName in FIELDS and node.firstChild: 125 if node.nodeName in ('needs', 'provides', 'conflicts'): 126 # Convert to list 127 data = node.firstChild.data 128 setattr(self, node.nodeName, \ 129 data.replace(" ", "").split(",")) 130 else: 131 setattr(self, node.nodeName, node.firstChild.data) 132 333 133 334 return True 134 335 … … 141 342 except Exception, err: 142 343 return 143 144 def check_validity(self): 145 """ 146 Checks the fields presents and validity 147 148 @return True if it's ok 149 """ 150 # TODO: implement me! 151 152 return True 153 344 154 345 def __repr__(self): 155 346 #FIXME: that … … 161 352 try: 162 353 # TODO: eliminate the mktemp workaround 163 354 164 355 name = mktemp('.png') 165 356 f = open(name, 'wb') … … 170 361 171 362 p = gtk.gdk.pixbuf_new_from_file_at_size(name, w, h) 172 363 173 364 os.remove(name) 174 365 … … 213 404 214 405 return ret 215 406 216 407 def extract_file(self, zip_path, keep_path=False): 217 408 if zip_path not in self.file.namelist(): … … 288 479 @return a catalog on success or None 289 480 """ 290 481 291 482 # We foreach inside locale dir and find a proper dir 292 483 293 484 try: 294 485 import gettext … … 304 495 if LANG is None: 305 496 LANG = "en_US" 306 307 # FIXME: is the '/' os indipendent? 497 308 498 dir_lst = filter( \ 309 499 lambda x: x.startswith("locale/") and x.endswith("%s.mo" % mofile), \ … … 313 503 314 504 avaiable_langs = [] 315 505 316 506 for dirname in dir_lst: 317 507 t = dirname.split("/") … … 319 509 if len(t) < 3: 320 510 continue 321 511 322 512 avaiable_langs.append(t[-2]) 323 513 … … 331 521 self.file.read("locale/%s/%s.mo" % (req, mofile)) \ 332 522 )) 333 523 334 524 return None 335 525 336 class PluginWriter( object):526 class PluginWriter(ManifestObject): 337 527 def __init__(self, **fields): 528 ManifestObject.__init__(self) 529 338 530 # Set to None and filter out the unused fields 339 340 for i in FIELDS: 341 setattr(self, i, "") 342 531 532 FIELDS = ('name', 'version', 'description', 'url', 'start_file', 533 'update', 'provide', 'need', 'conflict', 'license', 534 'copyright', 'author', 'contributor', 'translator', 'artist') 535 536 # Filter out fields that are not related to the schema 537 343 538 for i in fields: 344 539 if i in FIELDS: 345 540 setattr(self, i, fields[i]) 346 347 for i in FIELDS: 348 print "Field %s setted to %s" % (i, getattr(self, i)) 349 541 542 if not self.check_validity(use_print=True): 543 print "!! Manifest could not be created." 544 sys.exit(-1) 545 350 546 dirs = { 351 547 'bin' : '*', … … 354 550 'locale' : '*' 355 551 } 356 552 357 553 self.file = ZipFile(fields['output'], "w", ZIP_DEFLATED) 358 554 … … 363 559 364 560 os.chdir("..") 365 366 self.file.writestr("Manifest.xml", self.create_manifest()) 561 562 writer = ManifestWriter(self) 563 self.file.writestr('Manifest.xml', writer.get_output()) 367 564 self.file.close() 368 565 369 566 print ">> Plugin %s created." % fields['output'] 370 567 371 568 def dir_foreach(self, dir, pattern): 372 569 "Add files contained in dir and that pass the pattern validation phase." … … 375 572 if not files: 376 573 continue 377 574 378 575 for file in files: 379 576 if not fnmatch(file, pattern): … … 381 578 382 579 print "Adding file %s %s %s" % (path, file, dir) 383 580 384 581 self.file.write(os.path.join(path, file), 385 582 os.path.join(path, file)) 386 583 387 584 def create_manifest(self): 388 585 """ 389 586 Create a Manifest.xml file 390 587 391 588 @return an xml manifest as string 392 589 """ 393 590 doc = getDOMImplementation().createDocument(None, SIGNATURE, None) 394 591 395 592 for field in FIELDS: 396 593 node = doc.createElement(field) 397 594 node.appendChild(doc.createTextNode(getattr(self, field))) 398 595 doc.documentElement.appendChild(node) 399 596 400 597 print "Manifest.xml created" 401 598 return doc.toxml() … … 452 649 shutil.rmtree('build') 453 650 shutil.rmtree('output') 651 652 if __name__ == "__main__": 653 parser = make_parser() 654 loader = ManifestLoader() 655 parser.setContentHandler(loader) 656 parser.parse(open('test.xml')) 657 loader.dump() -
branch/QuickScan/umit/plugin/Engine.py
r4494 r4946 51 51 {} 52 52 """ 53 53 54 54 def __init__(self, path): 55 55 """ … … 75 75 for file in os.listdir(self.path): 76 76 path = os.path.join(self.path, file) 77 77 78 78 if file.endswith(".ump") and \ 79 79 os.path.isfile(path): … … 144 144 145 145 log.debug("Path.config_dir placed under %s" % Path.config_dir) 146 146 147 147 dest_dir = os.path.join(Path.config_dir, 'plugins') 148 148 temp_dir = os.path.join(Path.config_dir, 'plugins-temp') 149 149 down_dir = os.path.join(Path.config_dir, 'plugins-download') 150 150 151 151 for file in os.listdir(temp_dir): 152 152 try: … … 169 169 os.remove(dst_name) 170 170 171 log.debug("Installing new plugin from update: %s" % dst_name) 172 171 173 os.rename(path, dst_name) 172 174 … … 283 285 """ 284 286 Load a plugin 285 287 286 288 @param reader a PluginReader 287 289 @param force True to not check depends … … 305 307 log.debug(">>> Removing plugin from autoload") 306 308 lst.remove(path) 307 309 308 310 self.plugins.plugins = lst 309 311 … … 311 313 except PluginException, err: 312 314 return (False, err) 313 315 314 316 def uninstall_plugin(self, reader): 315 317 """ 316 318 Low level uninstall procedure 317 319 318 320 @param reader a PluginReader 319 321 @return True if ok or False 320 322 """ 321 323 322 324 try: 323 325 os.remove(reader.get_path()) -
branch/QuickScan/umit/plugin/Network.py
r4240 r4946 47 47 func(*args, **kwargs) 48 48 except Exception, err: 49 log.error(_('>>> safecall(): Ignoring exception %s') % err) 49 log.error(_('>>> safecall(): Ignoring exception %s -> %s (%s, %s)')\ 50 % (err, func, args, kwargs)) 50 51 return proxy 51 52 … … 63 64 64 65 self.args = obj.args 65 66 66 67 # FIXME: check this 67 68 if isinstance(obj, urllib2.HTTPError): 68 69 self.reason = '%d %s' % (obj.code, obj.msg) 69 70 else: 70 self.reason = obj.reason 71 try: 72 self.reason = obj.reason 73 except: 74 self.reason = str(obj) 71 75 72 76 class StartNetException(NetException): … … 106 110 @param udata the additional data to pass to the callback 107 111 """ 108 112 109 113 log.debug(_(">>> Calling get_url() for %s") % url) 110 114 … … 150 154 m.update("".join(udata)) 151 155 print "MD5", m.hexdigest() 152 156 153 157 return 154 158 -
branch/QuickScan/umit/plugin/PluginPage.py
r4240 r4946 31 31 32 32 from umit.plugin.Core import Core 33 from umit.plugin.Update import FILE_GETTING, FILE_CHECKING 33 from umit.plugin.Atoms import Version 34 from umit.plugin.Update import FILE_GETTING, FILE_CHECKING, FILE_ERROR 34 35 from umit.plugin.Update import LATEST_GETTED, LATEST_ERROR, LATEST_GETTING 35 36 … … 43 44 self.__create_widgets() 44 45 self.__pack_widgets() 45 46 46 47 self.install_updates_btn.hide() 47 48 … … 62 63 self.restart_btn = \ 63 64 HIGButton(_('Restart UMIT'), gtk.STOCK_REFRESH) 64 65 65 66 def __pack_widgets(self): 66 67 self.hbbox.pack_start(self.find_updates_btn) … … 68 69 self.hbbox.pack_start(self.install_updates_btn) 69 70 self.hbbox.pack_start(self.restart_btn) 70 71 71 72 self.pack_start(self.richlist) 72 73 self.pack_start(self.hbbox, False, False, 0) 73 74 74 75 self.find_updates_btn.connect('clicked', self.__on_find_updates) 75 76 self.install_updates_btn.connect('clicked', self.__on_install_updates) … … 78 79 79 80 self.show_all() 80 81 81 82 def clear(self, include_loaded=True): 82 83 if include_loaded: … … 140 141 "Called when the user click on the restart button" 141 142 142 # TODO: implement me 143 log.critical("Restart is not implemented!") 143 Core().mainwindow.emit('delete-event', None) 144 144 145 145 def __on_skip_updates(self, widget): … … 151 151 152 152 self.p_window.toolbar.unset_status() 153 self.p_window.animated_bar.label = \ 154 _('Update skipped') 153 154 if self.restart_btn.flags() & gtk.VISIBLE: 155 # That callback is called from a self.___on_install_updates 156 157 self.restart_btn.hide() 158 self.p_window.animated_bar.label = \ 159 _('Rembember to restart UMIT to use new version of plugins.') 160 161 else: 162 self.p_window.animated_bar.label = \ 163 _('Update skipped') 164 155 165 self.p_window.animated_bar.start_animation(True) 156 166 … … 160 170 161 171 self.menu_enabled = True 162 172 163 173 def __on_install_updates(self, widget): 164 174 """ … … 174 184 if obj.status != LATEST_GETTED: 175 185 self.richlist.remove_row(obj.object) 176 186 continue 187 177 188 if obj.object.show_include: 178 189 lst.append(obj) 179 190 180 191 obj.object.show_include = False 181 192 193 # Reset indexes 194 obj.last_update_idx = 0 195 obj.selected_update_idx = obj.object.versions_button.get_active()-1 196 182 197 self.install_updates_btn.set_sensitive(False) 183 198 self.skip_install_btn.set_sensitive(False) … … 191 206 ) 192 207 gobject.timeout_add(300, self.__refresh_row_download) 193 208 194 209 def __refresh_row_download(self): 195 210 """ … … 199 214 200 215 working = False 201 216 202 217 for obj in self.p_window.update_eng.list: 203 218 obj.lock.acquire() … … 207 222 obj.status == FILE_CHECKING: 208 223 working = True 209 224 210 225 row = obj.object 211 226 row.message = obj.label … … 213 228 finally: 214 229 obj.lock.release() 215 230 216 231 if not working: 217 232 233 errors = '' 234 218 235 for obj in self.p_window.update_eng.list: 219 236 row = obj.object 220 237 row.message = obj.label 221 238 row.progress = None 222 239 240 if not errors and obj.status == FILE_ERROR: 241 errors = ' but with <b>some errors</b>' 242 223 243 # Only warn the user about changes take effects on restart 224 244 # on restart just move the plugins stored in home directory 225 245 # in the proper location 226 246 227 247 self.p_window.animated_bar.label = \ 228 _('Update phase complete . Now restart ' \229 'UMIT to changes make effects.') 248 _('Update phase complete%s. Now restart ' \ 249 'UMIT to changes make effects.') % errors 230 250 self.p_window.animated_bar.start_animation(True) 231 251 232 252 self.p_window.toolbar.unset_status() 233 253 234 254 self.install_updates_btn.hide() 235 self.skip_install_btn.hide() 255 256 # Let the user to choose to restart or not UMIT 257 self.skip_install_btn.set_sensitive(True) 236 258 237 259 self.restart_btn.show() 238 260 239 261 return working 240 262 241 263 def __on_find_updates(self, widget): 242 264 """ … … 250 272 self.find_updates_btn.set_sensitive(False) 251 273 self.menu_enabled = False 252 274 253 275 lst = [] 254 276 … … 268 290 269 291 self.p_window.animated_bar.label = \ 270 _("No plugins provide s update url. Cannot procede.")292 _("No plugins provide an update URL. Cannot proceed.") 271 293 self.p_window.animated_bar.image = gtk.STOCK_DIALOG_ERROR 272 294 self.p_window.animated_bar.start_animation(True) … … 292 314 gobject.timeout_add(300, self.__update_rich_list) 293 315 316 def __query_tooltip_versions_button(self, widget, x, y, keyboard_tip, \ 317 tooltip, obj): 318 319 idx = obj.object.versions_button.get_active() - 1 320 321 if idx >= 0: 322 desc = obj.updates[idx].description 323 324 if desc: 325 tooltip.set_markup(desc) 326 tooltip.set_icon_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_MENU) 327 return True 328 329 return False 330 294 331 def __update_rich_list(self): 295 332 """ … … 299 336 300 337 working = False 301 338 302 339 for upd_obj in self.p_window.update_eng.list: 303 340 upd_obj.lock.acquire() … … 307 344 if upd_obj.status == LATEST_GETTING: 308 345 working = True 309 346 310 347 # Update the row 311 348 row = upd_obj.object … … 313 350 finally: 314 351 upd_obj.lock.release() 315 352 316 353 # No locking from here we have finished 317 354 … … 320 357 self.p_window.update_eng.stop() 321 358 self.find_updates_btn.set_sensitive(True) 322 359 323 360 lst = filter( \ 324 361 lambda x: (x.status == LATEST_GETTED) and (x) or (None),\ … … 329 366 self.p_window.update_eng.list \ 330 367 ) 331 368 332 369 if not lst and not elst: 333 370 self.p_window.toolbar.unset_status() … … 336 373 _('<b>No updates found</b>') 337 374 self.p_window.animated_bar.start_animation(True) 338 375 339 376 self.richlist.clear() 340 377 self.populate() … … 358 395 row = obj.object 359 396 active = (obj.status == LATEST_GETTED) 360 397 361 398 if active: 399 obj.last_update_idx = 0 362 400 row.show_include = True 401 402 log.debug("Connecting 'query-tooltip' for %s" % obj) 403 404 # The tooltip is showed and hidden continuously 405 row.versions_button.props.has_tooltip = True 406 row.versions_button.connect( 407 'query-tooltip', 408 self.__query_tooltip_versions_button, obj 409 ) 410 411 row.versions_model.clear() 412 413 row.versions_model.append([ 414 gtk.STOCK_CANCEL, _("Skip") 415 ]) 416 417 for update in obj.updates: 418 cur_v = Version(row.reader.version) 419 new_v = Version(update.version) 420 421 if new_v > cur_v: 422 row.versions_model.append([ 423 gtk.STOCK_GO_UP, _("Update to %s") % \ 424 update.version 425 ]) 426 elif new_v == cur_v: 427 row.versions_model.append([ 428 gtk.STOCK_REFRESH, _("Reinstall %s") % \ 429 update.version 430 ]) 431 else: 432 row.versions_model.append([ 433 gtk.STOCK_GO_DOWN, _("Downgrade to %s") % \ 434 update.version 435 ]) 436 437 row.versions_button.set_active(0) 363 438 row.message = obj.label 364 439 else: 365 440 row.saturate = True 366 441 367 442 if lst: 368 443 self.install_updates_btn.show() 369 444 370 445 self.find_updates_btn.hide() 371 446 self.skip_install_btn.show() 372 447 373 448 return working 374 449 375 450 def __on_row_popup(self, row, evt): 376 451 "Popup menu" … … 476 551 if r == gtk.RESPONSE_YES: 477 552 r, err = self.p_window.engine.unload_plugin(row.reader) 478 553 479 554 if not r: 480 555 d = dialog( \ … … 501 576 502 577 row.activatable = False 503 578 504 579 if self.p_window.engine.uninstall_plugin(row.reader): 505 580 del row … … 508 583 else: 509 584 row.activatable = True 510 585 511 586 self.p_window.animated_bar.label = \ 512 587 _('Unable to uninstall %s plugin.') % row.reader … … 515 590 def __on_row_preference(self, widget, row): 516 591 "Preference button callback" 517 592 518 593 if not self.p_window.engine.tree.show_preferences(row.reader): 519 594 self.p_window.animated_bar.label = \ -
branch/QuickScan/umit/plugin/Update.py
r4240 r4946 22 22 try: 23 23 from hashlib import md5 24 from hashlib import sha1 as sha 24 25 except ImportError: 25 26 from md5 import md5 27 from sha import sha 26 28 27 29 from threading import RLock 28 30 from tempfile import mkstemp 31 from StringIO import StringIO 29 32 from xml.dom.minidom import parseString 30 33 … … 47 50 FILE_CHECKING = 7 48 51 49 class UpdateObject(object): 52 from xml.sax import handler, make_parser 53 54 class Update(object): 55 def __init__(self, version, description, url, integrity): 56 self.version, self.description, self.url, self.integrity = \ 57 version, description, url, integrity 58 59 class UpdateObject(handler.ContentHandler): 50 60 def __init__(self, obj): 61 self.data = '' 62 self.parse_phase = 0 63 self.updates = [] 64 65 self.version = '' 66 self.description = '' 67 self.url = [] 68 self.integrity = {} 69 51 70 self.buffer = [] 52 71 53 72 self.status = STATUS_IDLE 54 73 55 74 self.label = None 56 75 self.fract = None 57 58 self.url = None 59 self.version = None 60 self.hash = None 61 76 62 77 self.object = obj 63 78 64 79 self.fd = None 65 80 66 81 self.size = None 67 82 self.total = None 68 83 84 self.last_update_idx = 0 85 self.selected_update_idx = -1 86 69 87 # Simple lock for sync 70 88 self.lock = RLock() 71 89 72 90 def parse_latest_file(self): 73 """ 74 @return url, version or None, None on error 75 """ 76 77 try: 78 doc = parseString("".join(self.buffer)) 79 80 if doc.documentElement.tagName != 'UmitPluginUpdate': 81 raise Exception("Not valid xml file.") 82 83 url, version, hash = None, None, None 84 85 for node in doc.documentElement.childNodes: 86 if node.nodeName == 'update-uri': 87 url = node.firstChild.data 88 if node.nodeName == 'version': 89 version = node.firstChild.data 90 if node.nodeName == 'md5': 91 hash = node.firstChild.data 92 93 return url, version, hash 94 except Exception, exc: 95 log.warning("__parse_xml: %s" % exc) 96 return None, None, None 97 91 parser = make_parser() 92 parser.setContentHandler(self) 93 parser.parse(StringIO("".join(self.buffer))) 94 95 def startElement(self, name, attrs): 96 if name == 'UmitPluginUpdate' and self.parse_phase == 0: 97 self.parse_phase = 1 98 elif name == 'update' and self.parse_phase == 1: 99 self.parse_phase = 2 100 elif name in ('version', 'description', 'url') and \ 101 self.parse_phase == 2: 102 103 self.parse_phase = 3 104 elif name == 'integrity' and self.parse_phase == 2 and \ 105 'type' in attrs.keys() and 'value' in attrs.keys(): 106 107 self.integrity[attrs.get('type')] = attrs.get('value') 108 else: 109 self.data = '' 110 111 def characters(self, ch): 112 if self.parse_phase == 3: 113 self.data += ch 114 115 def endElement(self, name): 116 if name in ('version', 'description', 'url'): 117 val = getattr(self, name, None) 118 119 if isinstance(val, basestring): 120 setattr(self, name, self.data) 121 elif isinstance(val, list): 122 val.append(self.data) 123 124 elif name == 'update': 125 if self.version and self.url: 126 self.updates.append(Update(self.version, self.description, 127 self.url, self.integrity)) 128 129 self.version = '' 130 self.description = '' 131 self.url = [] 132 self.integrity = {} 133 self.parse_phase = 1 134 self.data = '' 135 else: 136 self.parse_phase -= 1 137 self.data = '' 98 138 99 139 class UpdateEngine(object): … … 107 147 self.static_lst = None 108 148 self.updating = False 109 149 110 150 def stop(self): 111 151 "Mark as stopped" … … 127 167 128 168 self.__process_next() 129 169 130 170 self.updating = True 131 171 132 172 def start_download(self): 133 173 """ … … 145 185 146 186 self.__process_next_download() 147 187 148 188 self.updating = True 149 189 150 190 def __process_next_download(self): 151 191 """ … … 155 195 if not self.update_lst: 156 196 return 157 197 158 198 obj = self.update_lst.pop(0) 159 199 160 200 try: 161 201 user_dir = os.path.join(Path.config_dir) 162 202 filename = os.path.basename(obj.object.reader.get_path()) 163 203 164 204 obj.fd = open(mkstemp(".part", filename, \ 165 205 os.path.join(user_dir, "plugins-download"))[1], "wb+") 166 167 Network.get_url(obj.url, self.__process_plugin, obj) 206 207 Network.get_url( 208 # Maybe too long string? :P 209 obj.updates[obj.selected_update_idx].url[obj.last_update_idx], 210 self.__process_plugin, obj 211 ) 168 212 except Exception, err: 169 213 obj.status = FILE_ERROR 170 214 obj.label = err 171 215 obj.fract = None 172 216 173 217 self.__process_next_download() 174 218 219 def __remove_file(self, obj): 220 try: 221 obj.fd.close() 222 os.remove(obj.fd.name) 223 except: 224 log.error('Error while removing temp %s file' % obj.fd.name) 225 175 226 def __process_plugin(self, file, data, exc, obj): 176 227 """ … … 182 233 183 234 try: 184 obj.status = FILE_ERROR 185 obj.label = exc.reason 186 obj.fract = 1 187 235 if obj.last_update_idx + 1 < \ 236 len(obj.updates[obj.selected_update_idx].url): 237 238 obj.last_update_idx += 1 239 240 obj.status = FILE_GETTING 241 obj.label = _('Cycling to next update url. Waiting...') 242 else: 243 obj.status = FILE_ERROR 244 obj.label = _('Download failed: %s') % str(exc.reason) 245 obj.fract = 1 246 247 self.__remove_file(obj) 248 188 249 self.__process_next_download() 189 250 return 190 251 finally: 191 252 obj.lock.release() 192 253 193 254 elif isinstance(exc, StopNetException): 194 if obj.hash: 255 #TODO: CHECK THIS 256 if obj.updates[obj.selected_update_idx].integrity: 195 257 196 258 data = "" … … 200 262 obj.label = _('Checking validity ...') 201 263 obj.status = FILE_CHECKING 202 264 203 265 obj.fd.flush() 204 266 obj.fd.seek(0) … … 207 269 finally: 208 270 obj.lock.release() 209 271 210 272 # Not locked it could freeze the ui 211 hasher = md5(data) 212 273 md5_hash = sha_hash = None 274 sums = obj.updates[obj.selected_update_idx].integrity 275 276 if 'md5' in sums: 277 md5_hash = md5(data) 278 if 'sha1' in sums: 279 sha_hash = sha(data) 280 213 281 obj.lock.acquire() 214 282 215 283 try: 216 if hasher.hexdigest() == obj.hash: 284 if (md5_hash and md5_hash.hexdigest() == sums['md5']) or \ 285 (sha_hash and sha_hash.hexdigest() == sums['sha1']): 286 217 287 obj.label = _('Updated. Restart to take effect') 218 288 obj.status = FILE_GETTED … … 231 301 finally: 232 302 obj.lock.release() 233 303 234 304 obj.lock.acquire() 235 305 … … 239 309 finally: 240 310 obj.lock.release() 241 311 242 312 try: 243 313 if obj.status == FILE_ERROR: … … 249 319 # TODO: add more sensed control? 250 320 pass 251 321 252 322 self.__process_next() 253 323 254 324 elif isinstance(exc, StartNetException): 255 325 obj.lock.acquire() … … 262 332 except: 263 333 pass 264 334 265 335 obj.label = _('Downloading ...') 266 336 finally: … … 272 342 obj.fract = float(obj.size) / float(obj.total) 273 343 obj.fd.write(data) 274 344 275 345 def __process_next(self): 276 346 """ … … 280 350 if not self.update_lst: 281 351 return 282 352 283 353 obj = self.update_lst.pop(0) 284 Network.get_url("%s/latest.xml" % obj.object.reader.update, \ 354 obj.label = _('Downloading update information...') 355 356 Network.get_url("%s/latest.xml" % \ 357 obj.object.reader.update[obj.last_update_idx], \ 285 358 self.__process_manifest, obj) 286 359 … … 295 368 296 369 try: 297 obj.status = LATEST_ERROR 298 obj.label = _('Cannot find newer version (%s)') % exc.reason 299 370 if obj.last_update_idx + 1 < len(obj.object.reader.update): 371 obj.last_update_idx += 1 372 373 obj.status = LATEST_GETTING 374 obj.label = _('Cycling to next update url. Waiting...') 375 376 self.update_lst.append(obj) 377 elif isinstance(exc, ErrorNetException): 378 obj.status = LATEST_ERROR 379 obj.label = _('Cannot find newer version (%s)') % exc.reason 380 300 381 self.__process_next() 301 382 return 302 383 finally: 303 384 obj.lock.release() 304 385 305 386 elif isinstance(exc, StopNetException): 306 url, version, hash = obj.parse_latest_file() 307 308 new_v = Version(version) 309 cur_v = Version(obj.object.reader.version) 310 387 try: 388 obj.parse_latest_file() 389 except Exception, exc: 390 391 if obj.last_update_idx + 1 < len(obj.object.reader.update): 392 obj.last_update_idx += 1 393 394 obj.status = LATEST_GETTING 395 obj.label = _('Cycling to next update url. Waiting...') 396 397 self.update_lst.append(obj) 398 else: 399 obj.status = LATEST_ERROR 400 obj.label = _('Cannot find newer version (%s)') % str(exc) 401 402 self.__process_next() 403 return 404 405 version = None 311 406 type = -1 # -1 no action / 0 update / 1 downgrade 312 407 313 if new_v > cur_v: 314 type = 0 315 elif cur_v < new_v: 316 type = 1 408 # If we have only 1 update.. 409 if len(obj.updates) == 1: 410 version = obj.updates[0].version 411 412 new_v = Version(version) 413 cur_v = Version(obj.object.reader.version) 414 415 if new_v > cur_v: 416 type = 0 417 elif cur_v < new_v: 418 type = 1 317 419 318 420 obj.lock.acquire() 319 421 320 422 try: 321 if url and version and type >= 0:423 if obj.updates: 322 424 323 425 # We check if the path is the plugins in config_dir … … 330 432 obj.status = LATEST_ERROR 331 433 332 if not type: 333 obj.label = _('Version %s avaiable but need manual update.') % version 334 else: 335 obj.label = _('Version %s avaiable but need manual downgrade.') % version 434 if type == -1: 435 obj.label = _('Various versions available but require manual intervention.') 436 elif type == 0: 437 obj.label = _('Version %s available but need manual update.') % version 438 elif type == 1: 439 obj.label = _('Version %s available but need manual downgrade.') % version 336 440 else: 337 441 obj.status = LATEST_GETTED 338 obj.label = _('Version %s avaiable.') % version339 340 obj.version = version341 obj.url = url342 obj.hash = hash 442 if type == -1: 443 obj.label = _('Various versions available') 444 else: 445 obj.label = _('Version %s available.') % version 446 343 447 else: 344 448 obj.status = LATEST_ERROR … … 355 459 elif not exc: 356 460 obj.buffer.append(data) 357 461 358 462 def get_list(self): 359 463 "Getter for list" 360 464 return self.static_lst 361 465 362 466 def set_list(self, value): 363 467 "Setter for list" 364 468 lst = [] 365 469 366 470 for iter in value: 367 471 if isinstance(iter, UpdateObject): … … 369 473 else: 370 474 lst.append(UpdateObject(iter)) 371 475 372 476 self.update_lst = lst 373 477 self.static_lst = tuple(self.update_lst) 374 478 375 479 list = property(get_list, set_list) 480 481 if __name__ == "__main__": 482 parser = make_parser() 483 loader = UpdateObject(1) 484 parser.setContentHandler(loader) 485 parser.parse(open('test.xml')) 486 print loader.updates -
branch/QuickScan/umit/plugin/Window.py
r4240 r4946 19 19 20 20 import gtk 21 import os.path 21 22 22 23 from higwidgets.higwindows import HIGWindow … … 29 30 from PluginPage import PluginPage 30 31 32 from umit.core.Paths import Path 31 33 from umit.plugin.Update import UpdateEngine 32 34 from umit.plugin.Engine import PluginEngine … … 47 49 self.set_position(gtk.WIN_POS_CENTER) 48 50 self.set_size_request(600, 400) 51 self.set_icon_from_file(os.path.join(Path.icons_dir, "umit_16.ico")) 49 52 50 53 self.__create_widgets() … … 97 100 self.plug_page.skip_install_btn.hide() 98 101 self.plug_page.restart_btn.hide() 99 102 100 103 self.connect('delete-event', self.__on_delete_event) 101 104 … … 109 112 self.plug_page.populate() 110 113 self.path_page.populate() 111 114 112 115 def __on_switch_page(self, widget, id): 113 116 self.notebook.set_current_page(id)
