| 1 | #!/usr/bin/env python |
|---|
| 2 | # -*- coding: utf-8 -*- |
|---|
| 3 | # |
|---|
| 4 | # Copyright (C) 2005-2006 Insecure.Com LLC. |
|---|
| 5 | # Copyright (C) 2007-2008 Adriano Monteiro Marques |
|---|
| 6 | # |
|---|
| 7 | # Author: Adriano Monteiro Marques <adriano@umitproject.org> |
|---|
| 8 | # |
|---|
| 9 | # This program is free software; you can redistribute it and/or modify |
|---|
| 10 | # it under the terms of the GNU General Public License as published by |
|---|
| 11 | # the Free Software Foundation; either version 2 of the License, or |
|---|
| 12 | # (at your option) any later version. |
|---|
| 13 | # |
|---|
| 14 | # This program is distributed in the hope that it will be useful, |
|---|
| 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 17 | # GNU General Public License for more details. |
|---|
| 18 | # |
|---|
| 19 | # You should have received a copy of the GNU General Public License |
|---|
| 20 | # along with this program; if not, write to the Free Software |
|---|
| 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 22 | |
|---|
| 23 | import re |
|---|
| 24 | import os |
|---|
| 25 | |
|---|
| 26 | from types import StringTypes |
|---|
| 27 | from ConfigParser import NoSectionError, NoOptionError, DuplicateSectionError |
|---|
| 28 | |
|---|
| 29 | from umitCore.Paths import Path |
|---|
| 30 | from umitCore.ScanProfileConf import scan_profile_file |
|---|
| 31 | from umitCore.UmitLogging import log |
|---|
| 32 | from umitCore.UmitConfigParser import UmitConfigParser |
|---|
| 33 | from umitCore.I18N import _ |
|---|
| 34 | |
|---|
| 35 | class UmitConf(object): |
|---|
| 36 | def __init__(self): |
|---|
| 37 | self.parser = Path.config_parser |
|---|
| 38 | |
|---|
| 39 | def save_changes(self): |
|---|
| 40 | self.parser.save_changes() |
|---|
| 41 | |
|---|
| 42 | def get_colored_diff(self): |
|---|
| 43 | try: |
|---|
| 44 | cd = self.parser.get('diff', 'colored_diff') |
|---|
| 45 | if cd == "False" or \ |
|---|
| 46 | cd == "false" or \ |
|---|
| 47 | cd == "0" or \ |
|---|
| 48 | cd == "" or \ |
|---|
| 49 | cd == False: |
|---|
| 50 | return False |
|---|
| 51 | return True |
|---|
| 52 | except: |
|---|
| 53 | return True |
|---|
| 54 | |
|---|
| 55 | def set_colored_diff(self, enable): |
|---|
| 56 | if not self.parser.has_section('diff'): |
|---|
| 57 | self.parser.add_section('diff') |
|---|
| 58 | |
|---|
| 59 | self.parser.set('diff', 'colored_diff', str(enable)) |
|---|
| 60 | |
|---|
| 61 | def get_diff_mode(self): |
|---|
| 62 | try: return self.parser.get('diff', 'diff_mode') |
|---|
| 63 | except: return "compare" |
|---|
| 64 | |
|---|
| 65 | def set_diff_mode(self, diff_mode): |
|---|
| 66 | if not self.parser.has_section('diff'): |
|---|
| 67 | self.parser.add_section('diff') |
|---|
| 68 | |
|---|
| 69 | self.parser.set('diff', 'diff_mode', diff_mode) |
|---|
| 70 | |
|---|
| 71 | colored_diff = property(get_colored_diff, set_colored_diff) |
|---|
| 72 | diff_mode = property(get_diff_mode, set_diff_mode) |
|---|
| 73 | |
|---|
| 74 | |
|---|
| 75 | class SearchConfig(UmitConfigParser, object): |
|---|
| 76 | def __init__(self): |
|---|
| 77 | self.parser = Path.config_parser |
|---|
| 78 | |
|---|
| 79 | self.section_name = "search" |
|---|
| 80 | if not self.parser.has_section(self.section_name): |
|---|
| 81 | self.create_section() |
|---|
| 82 | |
|---|
| 83 | def save_changes(self): |
|---|
| 84 | self.parser.save_changes() |
|---|
| 85 | |
|---|
| 86 | def create_section(self): |
|---|
| 87 | self.parser.add_section(self.section_name) |
|---|
| 88 | self.directory = "" |
|---|
| 89 | self.file_extension = "usr" |
|---|
| 90 | self.save_time = "60;Days" |
|---|
| 91 | self.store_results = True |
|---|
| 92 | self.search_db = True |
|---|
| 93 | |
|---|
| 94 | def _get_it(self, p_name, default): |
|---|
| 95 | return self.parser.get(self.section_name, p_name, default) |
|---|
| 96 | |
|---|
| 97 | def _set_it(self, p_name, value): |
|---|
| 98 | self.parser.set(self.section_name, p_name, value) |
|---|
| 99 | |
|---|
| 100 | def boolean_sanity(self, attr): |
|---|
| 101 | if attr == True or \ |
|---|
| 102 | attr == "True" or \ |
|---|
| 103 | attr == "true" or \ |
|---|
| 104 | attr == "1": |
|---|
| 105 | |
|---|
| 106 | return 1 |
|---|
| 107 | |
|---|
| 108 | return 0 |
|---|
| 109 | |
|---|
| 110 | def get_directory(self): |
|---|
| 111 | return self._get_it("directory", "") |
|---|
| 112 | |
|---|
| 113 | def set_directory(self, directory): |
|---|
| 114 | self._set_it("directory", directory) |
|---|
| 115 | |
|---|
| 116 | def get_file_extension(self): |
|---|
| 117 | return self._get_it("file_extension", "usr").split(";") |
|---|
| 118 | |
|---|
| 119 | def set_file_extension(self, file_extension): |
|---|
| 120 | if type(file_extension) == type([]): |
|---|
| 121 | self._set_it("file_extension", ";".join(file_extension)) |
|---|
| 122 | elif type(file_extension) in StringTypes: |
|---|
| 123 | self._set_it("file_extension", file_extension) |
|---|
| 124 | |
|---|
| 125 | def get_save_time(self): |
|---|
| 126 | return self._get_it("save_time", "60;Days").split(";") |
|---|
| 127 | |
|---|
| 128 | def set_save_time(self, save_time): |
|---|
| 129 | if type(save_time) == type([]): |
|---|
| 130 | self._set_it("save_time", ";".join(save_time)) |
|---|
| 131 | elif type(save_time) in StringTypes: |
|---|
| 132 | self._set_it("save_time", save_time) |
|---|
| 133 | |
|---|
| 134 | def get_store_results(self): |
|---|
| 135 | return self.boolean_sanity(self._get_it("store_results", True)) |
|---|
| 136 | |
|---|
| 137 | def set_store_results(self, store_results): |
|---|
| 138 | self._set_it("store_results", self.boolean_sanity(store_results)) |
|---|
| 139 | |
|---|
| 140 | def get_search_db(self): |
|---|
| 141 | return self.boolean_sanity(self._get_it("search_db", True)) |
|---|
| 142 | |
|---|
| 143 | def set_search_db(self, search_db): |
|---|
| 144 | self._set_it("search_db", self.boolean_sanity(search_db)) |
|---|
| 145 | |
|---|
| 146 | def get_converted_save_time(self): |
|---|
| 147 | try: |
|---|
| 148 | return int(self.save_time[0]) * self.time_list[self.save_time[1]] |
|---|
| 149 | except: |
|---|
| 150 | # If something goes wrong, return a save time of 60 days |
|---|
| 151 | return 60 * 60 * 24 * 60 |
|---|
| 152 | |
|---|
| 153 | def get_time_list(self): |
|---|
| 154 | # Time as key, seconds a value |
|---|
| 155 | return {_("Hours"): 60 * 60, |
|---|
| 156 | _("Days"): 60 * 60 * 24, |
|---|
| 157 | _("Weeks"): 60 * 60 * 24 * 7, |
|---|
| 158 | _("Months"): 60 * 60 * 24 * 7 * 30, |
|---|
| 159 | _("Years"): 60 * 60 * 24 * 7 * 30 * 12, |
|---|
| 160 | _("Minutes"): 60, |
|---|
| 161 | _("Seconds"): 1} |
|---|
| 162 | |
|---|
| 163 | directory = property(get_directory, set_directory) |
|---|
| 164 | file_extension = property(get_file_extension, set_file_extension) |
|---|
| 165 | save_time = property(get_save_time, set_save_time) |
|---|
| 166 | store_results = property(get_store_results, set_store_results) |
|---|
| 167 | search_db = property(get_search_db, set_search_db) |
|---|
| 168 | converted_save_time = property(get_converted_save_time) |
|---|
| 169 | time_list = property(get_time_list) |
|---|
| 170 | |
|---|
| 171 | |
|---|
| 172 | class Profile(UmitConfigParser, object): |
|---|
| 173 | def __init__(self, user_profile=None, *args): |
|---|
| 174 | UmitConfigParser.__init__(self, *args) |
|---|
| 175 | |
|---|
| 176 | if not user_profile: |
|---|
| 177 | user_profile = scan_profile_file |
|---|
| 178 | |
|---|
| 179 | fconf = open(user_profile, 'r') |
|---|
| 180 | self.readfp(fconf, user_profile) |
|---|
| 181 | |
|---|
| 182 | fconf.close() |
|---|
| 183 | del(fconf) |
|---|
| 184 | |
|---|
| 185 | self.attributes = {} |
|---|
| 186 | |
|---|
| 187 | def _get_it(self, profile, attribute): |
|---|
| 188 | if self._verify_profile(profile): |
|---|
| 189 | return self.get(profile, attribute) |
|---|
| 190 | return "" |
|---|
| 191 | |
|---|
| 192 | def _set_it(self, profile, attribute, value=''): |
|---|
| 193 | if self._verify_profile(profile): |
|---|
| 194 | return self.set(profile, attribute, value) |
|---|
| 195 | |
|---|
| 196 | def add_profile(self, profile_name, **attributes): |
|---|
| 197 | log.debug(">>> Add Profile '%s': %s" % (profile_name, attributes)) |
|---|
| 198 | try: |
|---|
| 199 | self.add_section(profile_name) |
|---|
| 200 | except DuplicateSectionError: |
|---|
| 201 | return None |
|---|
| 202 | |
|---|
| 203 | for attr in attributes: |
|---|
| 204 | if attr != "options": |
|---|
| 205 | self._set_it(profile_name, attr, attributes[attr]) |
|---|
| 206 | |
|---|
| 207 | options = attributes["options"] |
|---|
| 208 | if isinstance(options, basestring): |
|---|
| 209 | self._set_it(profile_name, "options", options) |
|---|
| 210 | # Assuming there are no values for these options |
|---|
| 211 | options = {} |
|---|
| 212 | elif isinstance(options, dict): |
|---|
| 213 | self._set_it(profile_name, "options", ",".join(options.keys())) |
|---|
| 214 | |
|---|
| 215 | for opt in options: |
|---|
| 216 | if options[opt]: |
|---|
| 217 | self._set_it(profile_name, opt, options[opt]) |
|---|
| 218 | self.save_changes() |
|---|
| 219 | |
|---|
| 220 | def remove_profile(self, profile_name): |
|---|
| 221 | try: self.remove_section(profile_name) |
|---|
| 222 | except: pass |
|---|
| 223 | self.save_changes() |
|---|
| 224 | |
|---|
| 225 | def _verify_profile(self, profile_name): |
|---|
| 226 | if profile_name not in self.sections(): |
|---|
| 227 | return False |
|---|
| 228 | return True |
|---|
| 229 | |
|---|
| 230 | class CommandProfile (Profile, object): |
|---|
| 231 | def __init__(self, user_profile=''): |
|---|
| 232 | if not user_profile: |
|---|
| 233 | user_profile = scan_profile_file |
|---|
| 234 | |
|---|
| 235 | Profile.__init__(self, user_profile) |
|---|
| 236 | |
|---|
| 237 | def get_command(self, profile): |
|---|
| 238 | return self._get_it(profile, 'command') |
|---|
| 239 | |
|---|
| 240 | def get_hint(self, profile): |
|---|
| 241 | return self._get_it(profile, 'hint') |
|---|
| 242 | |
|---|
| 243 | def get_description(self, profile): |
|---|
| 244 | return self._get_it(profile, 'description') |
|---|
| 245 | |
|---|
| 246 | def get_annotation(self, profile): |
|---|
| 247 | return self._get_it(profile, 'annotation') |
|---|
| 248 | |
|---|
| 249 | def get_options(self, profile): |
|---|
| 250 | dic = {} |
|---|
| 251 | options_result = self._get_it(profile, 'options') |
|---|
| 252 | if options_result.strip()=='': |
|---|
| 253 | return dic |
|---|
| 254 | |
|---|
| 255 | for opt in options_result.split(','): |
|---|
| 256 | try: |
|---|
| 257 | dic[unicode(opt.strip())] = self._get_it(profile, opt) |
|---|
| 258 | except NoOptionError: |
|---|
| 259 | dic[unicode(opt.strip())] = None |
|---|
| 260 | return dic |
|---|
| 261 | |
|---|
| 262 | def set_command(self, profile, command=''): |
|---|
| 263 | self._set_it(profile, 'command', command) |
|---|
| 264 | |
|---|
| 265 | def set_hint(self, profile, hint=''): |
|---|
| 266 | self._set_it(profile, 'hint', hint) |
|---|
| 267 | |
|---|
| 268 | def set_description(self, profile, description=''): |
|---|
| 269 | self._set_it(profile, 'description', description) |
|---|
| 270 | |
|---|
| 271 | def set_annotation (self, profile, annotation=''): |
|---|
| 272 | self._set_it(profile, 'annotation', annotation) |
|---|
| 273 | |
|---|
| 274 | def set_options(self, profile, options={}): |
|---|
| 275 | for opt in options: |
|---|
| 276 | if options[opt]: |
|---|
| 277 | self._set_it(profile, opt, options[opt]) |
|---|
| 278 | self._set_it(profile, 'options', ",".join(options.keys())) |
|---|
| 279 | |
|---|
| 280 | def get_profile(self, profile_name): |
|---|
| 281 | return {'profile':profile_name, \ |
|---|
| 282 | 'command':self.get_command(profile_name), \ |
|---|
| 283 | 'hint':self.get_hint(profile_name), \ |
|---|
| 284 | 'description':self.get_description(profile_name), \ |
|---|
| 285 | 'annotation':self.get_annotation(profile_name),\ |
|---|
| 286 | 'options':self.get_options(profile_name)} |
|---|
| 287 | |
|---|
| 288 | |
|---|
| 289 | class NmapOutputHighlight(object): |
|---|
| 290 | setts = ["bold", "italic", "underline", "text", "highlight", "regex"] |
|---|
| 291 | |
|---|
| 292 | def __init__(self): |
|---|
| 293 | self.parser = Path.config_parser |
|---|
| 294 | |
|---|
| 295 | def save_changes(self): |
|---|
| 296 | self.parser.save_changes() |
|---|
| 297 | |
|---|
| 298 | def __get_it(self, p_name): |
|---|
| 299 | property_name = "%s_highlight" % p_name |
|---|
| 300 | |
|---|
| 301 | try: |
|---|
| 302 | return self.sanity_settings([self.parser.get(property_name, |
|---|
| 303 | prop, |
|---|
| 304 | True) \ |
|---|
| 305 | for prop in self.setts]) |
|---|
| 306 | except: |
|---|
| 307 | settings = [] |
|---|
| 308 | prop_settings = self.default_highlights[p_name] |
|---|
| 309 | settings.append(prop_settings["bold"]) |
|---|
| 310 | settings.append(prop_settings["italic"]) |
|---|
| 311 | settings.append(prop_settings["underline"]) |
|---|
| 312 | settings.append(prop_settings["text"]) |
|---|
| 313 | settings.append(prop_settings["highlight"]) |
|---|
| 314 | settings.append(prop_settings["regex"]) |
|---|
| 315 | |
|---|
| 316 | self.__set_it(p_name, settings) |
|---|
| 317 | |
|---|
| 318 | return self.sanity_settings(settings) |
|---|
| 319 | |
|---|
| 320 | def __set_it(self, property_name, settings): |
|---|
| 321 | property_name = "%s_highlight" % property_name |
|---|
| 322 | settings = self.sanity_settings(list(settings)) |
|---|
| 323 | |
|---|
| 324 | [self.parser.set(property_name, self.setts[pos], settings[pos]) \ |
|---|
| 325 | for pos in xrange(len(settings))] |
|---|
| 326 | |
|---|
| 327 | def sanity_settings(self, settings): |
|---|
| 328 | """This method tries to convert insane settings to sanity ones ;-) |
|---|
| 329 | If user send a True, "True" or "true" value, for example, it tries to |
|---|
| 330 | convert then to the integer 1. |
|---|
| 331 | Same to False, "False", etc. |
|---|
| 332 | |
|---|
| 333 | Sequence: [bold, italic, underline, text, highlight, regex] |
|---|
| 334 | """ |
|---|
| 335 | #log.debug(">>> Sanitize %s" % str(settings)) |
|---|
| 336 | |
|---|
| 337 | settings[0] = self.boolean_sanity(settings[0]) |
|---|
| 338 | settings[1] = self.boolean_sanity(settings[1]) |
|---|
| 339 | settings[2] = self.boolean_sanity(settings[2]) |
|---|
| 340 | |
|---|
| 341 | tuple_regex = "[\(\[]\s?(\d+)\s?,\s?(\d+)\s?,\s?(\d+)\s?[\)\]]" |
|---|
| 342 | if type(settings[3]) == type(""): |
|---|
| 343 | settings[3] = [int(t) \ |
|---|
| 344 | for t in re.findall(tuple_regex, settings[3])[0]] |
|---|
| 345 | |
|---|
| 346 | if type(settings[4]) == type(""): |
|---|
| 347 | settings[4]= [int(h) \ |
|---|
| 348 | for h in re.findall(tuple_regex, settings[4])[0]] |
|---|
| 349 | |
|---|
| 350 | return settings |
|---|
| 351 | |
|---|
| 352 | def boolean_sanity(self, attr): |
|---|
| 353 | if attr == True or attr == "True" or attr == "true" or attr == "1": |
|---|
| 354 | return 1 |
|---|
| 355 | return 0 |
|---|
| 356 | |
|---|
| 357 | def get_date(self): |
|---|
| 358 | return self.__get_it("date") |
|---|
| 359 | |
|---|
| 360 | def set_date(self, settings): |
|---|
| 361 | self.__set_it("date", settings) |
|---|
| 362 | |
|---|
| 363 | def get_hostname(self): |
|---|
| 364 | return self.__get_it("hostname") |
|---|
| 365 | |
|---|
| 366 | def set_hostname(self, settings): |
|---|
| 367 | self.__set_it("hostname", settings) |
|---|
| 368 | |
|---|
| 369 | def get_ip(self): |
|---|
| 370 | return self.__get_it("ip") |
|---|
| 371 | |
|---|
| 372 | def set_ip(self, settings): |
|---|
| 373 | self.__set_it("ip", settings) |
|---|
| 374 | |
|---|
| 375 | def get_port_list(self): |
|---|
| 376 | return self.__get_it("port_list") |
|---|
| 377 | |
|---|
| 378 | def set_port_list(self, settings): |
|---|
| 379 | self.__set_it("port_list", settings) |
|---|
| 380 | |
|---|
| 381 | def get_open_port(self): |
|---|
| 382 | return self.__get_it("open_port") |
|---|
| 383 | |
|---|
| 384 | def set_open_port(self, settings): |
|---|
| 385 | self.__set_it("open_port", settings) |
|---|
| 386 | |
|---|
| 387 | def get_closed_port(self): |
|---|
| 388 | return self.__get_it("closed_port") |
|---|
| 389 | |
|---|
| 390 | def set_closed_port(self, settings): |
|---|
| 391 | self.__set_it("closed_port", settings) |
|---|
| 392 | |
|---|
| 393 | def get_filtered_port(self): |
|---|
| 394 | return self.__get_it("filtered_port") |
|---|
| 395 | |
|---|
| 396 | def set_filtered_port(self, settings): |
|---|
| 397 | self.__set_it("filtered_port", settings) |
|---|
| 398 | |
|---|
| 399 | def get_details(self): |
|---|
| 400 | return self.__get_it("details") |
|---|
| 401 | |
|---|
| 402 | def set_details(self, settings): |
|---|
| 403 | self.__set_it("details", settings) |
|---|
| 404 | |
|---|
| 405 | def get_enable(self): |
|---|
| 406 | enable = True |
|---|
| 407 | try: |
|---|
| 408 | enable = self.parser.get("output_highlight", "enable_highlight") |
|---|
| 409 | except NoSectionError: |
|---|
| 410 | self.parser.set("output_highlight", "enable_highlight", str(True)) |
|---|
| 411 | |
|---|
| 412 | if enable == "False" or enable == "0" or enable == "": |
|---|
| 413 | return False |
|---|
| 414 | return True |
|---|
| 415 | |
|---|
| 416 | def set_enable(self, enable): |
|---|
| 417 | if enable == False or enable == "0" or enable is None or enable == "": |
|---|
| 418 | self.parser.set("output_highlight", "enable_highlight", str(False)) |
|---|
| 419 | else: |
|---|
| 420 | self.parser.set("output_highlight", "enable_highlight", str(True)) |
|---|
| 421 | |
|---|
| 422 | date = property(get_date, set_date) |
|---|
| 423 | hostname = property(get_hostname, set_hostname) |
|---|
| 424 | ip = property(get_ip, set_ip) |
|---|
| 425 | port_list = property(get_port_list, set_port_list) |
|---|
| 426 | open_port = property(get_open_port, set_open_port) |
|---|
| 427 | closed_port = property(get_closed_port, set_closed_port) |
|---|
| 428 | filtered_port = property(get_filtered_port, set_filtered_port) |
|---|
| 429 | details = property(get_details, set_details) |
|---|
| 430 | enable = property(get_enable, set_enable) |
|---|
| 431 | |
|---|
| 432 | # These settings are made when there is nothing set yet. They set |
|---|
| 433 | # the "factory" default to highlight colors |
|---|
| 434 | default_highlights = {"date":{"bold":str(True), |
|---|
| 435 | "italic":str(False), |
|---|
| 436 | "underline":str(False), |
|---|
| 437 | "text":[0, 0, 0], |
|---|
| 438 | "highlight":[65535, 65535, 65535], |
|---|
| 439 | "regex":"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s.{1,4}"}, |
|---|
| 440 | "hostname":{"bold":str(True), |
|---|
| 441 | "italic":str(True), |
|---|
| 442 | "underline":str(True), |
|---|
| 443 | "text":[0, 111, 65535], |
|---|
| 444 | "highlight":[65535, 65535, 65535], |
|---|
| 445 | "regex":"(\w{2,}://)*\w{2,}\.\w{2,}(\.\w{2,})*(/[\w{2,}]*)*"}, |
|---|
| 446 | "ip":{"bold":str(True), |
|---|
| 447 | "italic":str(False), |
|---|
| 448 | "underline":str(False), |
|---|
| 449 | "text":[0, 0, 0], |
|---|
| 450 | "highlight":[65535, 65535, 65535], |
|---|
| 451 | "regex":"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"}, |
|---|
| 452 | "port_list":{"bold":str(True), |
|---|
| 453 | "italic":str(False), |
|---|
| 454 | "underline":str(False), |
|---|
| 455 | "text":[0, 1272, 28362], |
|---|
| 456 | "highlight":[65535, 65535, 65535], |
|---|
| 457 | "regex":"PORT\s+STATE\s+SERVICE(\s+VERSION)?[^\n]*"}, |
|---|
| 458 | "open_port":{"bold":str(True), |
|---|
| 459 | "italic":str(False), |
|---|
| 460 | "underline":str(False), |
|---|
| 461 | "text":[0, 41036, 2396], |
|---|
| 462 | "highlight":[65535, 65535, 65535], |
|---|
| 463 | "regex":"\d{1,5}/.{1,5}\s+open\s+.*"}, |
|---|
| 464 | "closed_port":{"bold":str(False), |
|---|
| 465 | "italic":str(False), |
|---|
| 466 | "underline":str(False), |
|---|
| 467 | "text":[65535, 0, 0], |
|---|
| 468 | "highlight":[65535, 65535, 65535], |
|---|
| 469 | "regex":"\d{1,5}/.{1,5}\s+closed\s+.*"}, |
|---|
| 470 | "filtered_port":{"bold":str(False), |
|---|
| 471 | "italic":str(False), |
|---|
| 472 | "underline":str(False), |
|---|
| 473 | "text":[38502, 39119, 0], |
|---|
| 474 | "highlight":[65535, 65535, 65535], |
|---|
| 475 | "regex":"\d{1,5}/.{1,5}\s+filtered\s+.*"}, |
|---|
| 476 | "details":{"bold":str(True), |
|---|
| 477 | "italic":str(False), |
|---|
| 478 | "underline":str(True), |
|---|
| 479 | "text":[0, 0, 0], |
|---|
| 480 | "highlight":[65535, 65535, 65535], |
|---|
| 481 | "regex":"^(\w{2,}[\s]{,3}){,4}:"}} |
|---|
| 482 | |
|---|
| 483 | class DiffColors(object): |
|---|
| 484 | def __init__(self): |
|---|
| 485 | self.parser = Path.config_parser |
|---|
| 486 | self.section_name = "diff_colors" |
|---|
| 487 | |
|---|
| 488 | def save_changes(self): |
|---|
| 489 | self.parser.save_changes() |
|---|
| 490 | |
|---|
| 491 | def __get_it(self, p_name): |
|---|
| 492 | return self.sanity_settings(self.parser.get(self.section_name, p_name)) |
|---|
| 493 | |
|---|
| 494 | def __set_it(self, property_name, settings): |
|---|
| 495 | settings = self.sanity_settings(settings) |
|---|
| 496 | self.parser.set(self.section_name, property_name, settings) |
|---|
| 497 | |
|---|
| 498 | def sanity_settings(self, settings): |
|---|
| 499 | log.debug(">>> Sanitize %s" % str(settings)) |
|---|
| 500 | |
|---|
| 501 | tuple_regex = "[\(\[]\s?(\d+)\s?,\s?(\d+)\s?,\s?(\d+)\s?[\)\]]" |
|---|
| 502 | if type(settings) == type(""): |
|---|
| 503 | settings = [int(t) for t in re.findall(tuple_regex, settings)[0]] |
|---|
| 504 | |
|---|
| 505 | return settings |
|---|
| 506 | |
|---|
| 507 | def get_unchanged(self): |
|---|
| 508 | return self.__get_it("unchanged") |
|---|
| 509 | |
|---|
| 510 | def set_unchanged(self, settings): |
|---|
| 511 | self.__set_it("unchanged", settings) |
|---|
| 512 | |
|---|
| 513 | def get_added(self): |
|---|
| 514 | return self.__get_it("added") |
|---|
| 515 | |
|---|
| 516 | def set_added(self, settings): |
|---|
| 517 | self.__set_it("added", settings) |
|---|
| 518 | |
|---|
| 519 | def get_modified(self): |
|---|
| 520 | return self.__get_it("modified") |
|---|
| 521 | |
|---|
| 522 | def set_modified(self, settings): |
|---|
| 523 | self.__set_it("modified", settings) |
|---|
| 524 | |
|---|
| 525 | def get_not_present(self): |
|---|
| 526 | return self.__get_it("not_present") |
|---|
| 527 | |
|---|
| 528 | def set_not_present(self, settings): |
|---|
| 529 | self.__set_it("not_present", settings) |
|---|
| 530 | |
|---|
| 531 | unchanged = property(get_unchanged, set_unchanged) |
|---|
| 532 | added = property(get_added, set_added) |
|---|
| 533 | modified = property(get_modified, set_modified) |
|---|
| 534 | not_present = property(get_not_present, set_not_present) |
|---|
| 535 | |
|---|
| 536 | class Plugins(object): |
|---|
| 537 | def __init__(self): |
|---|
| 538 | self.parser = Path.config_parser |
|---|
| 539 | self.section_name = "plugins" |
|---|
| 540 | self.separator = os.pathsep |
|---|
| 541 | |
|---|
| 542 | if not self.parser.has_section(self.section_name): |
|---|
| 543 | self.create_section() |
|---|
| 544 | |
|---|
| 545 | def save_changes(self): |
|---|
| 546 | self.parser.save_changes() |
|---|
| 547 | |
|---|
| 548 | def create_section(self): |
|---|
| 549 | from os.path import join |
|---|
| 550 | self.paths = [join(Path.config_dir, "plugins")] |
|---|
| 551 | self.plugins = "" |
|---|
| 552 | |
|---|
| 553 | def __get_it(self, p_name): |
|---|
| 554 | value = None |
|---|
| 555 | |
|---|
| 556 | try: |
|---|
| 557 | try: |
|---|
| 558 | value = self.parser.get(self.section_name, p_name) |
|---|
| 559 | except: |
|---|
| 560 | pass |
|---|
| 561 | finally: |
|---|
| 562 | return self.sanity_settings(value) |
|---|
| 563 | |
|---|
| 564 | def __set_it(self, property_name, settings): |
|---|
| 565 | settings = self.sanity_settings(settings) |
|---|
| 566 | self.parser.set(self.section_name, property_name, settings) |
|---|
| 567 | |
|---|
| 568 | def sanity_settings(self, settings): |
|---|
| 569 | # FIXME: more sensed :D |
|---|
| 570 | if not settings: |
|---|
| 571 | return "" |
|---|
| 572 | return settings |
|---|
| 573 | |
|---|
| 574 | def get_paths(self): |
|---|
| 575 | return filter(None, self.__get_it("paths").split(self.separator)) |
|---|
| 576 | |
|---|
| 577 | def set_paths(self, settings): |
|---|
| 578 | self.__set_it("paths", self.separator.join(settings)) |
|---|
| 579 | |
|---|
| 580 | def get_plugins(self): |
|---|
| 581 | return filter(None, self.__get_it("plugins").split(self.separator)) |
|---|
| 582 | |
|---|
| 583 | def set_plugins(self, settings): |
|---|
| 584 | self.__set_it("plugins", self.separator.join(settings)) |
|---|
| 585 | |
|---|
| 586 | paths = property(get_paths, set_paths) |
|---|
| 587 | plugins = property(get_plugins, set_plugins) |
|---|
| 588 | |
|---|
| 589 | # Exceptions |
|---|
| 590 | class ProfileNotFound: |
|---|
| 591 | def __init__ (self, profile): |
|---|
| 592 | self.profile = profile |
|---|
| 593 | def __str__ (self): |
|---|
| 594 | return "No profile named '"+self.profile+"' found!" |
|---|
| 595 | |
|---|
| 596 | class ProfileCouldNotBeSaved: |
|---|
| 597 | def __init__ (self, profile): |
|---|
| 598 | self.profile = profile |
|---|
| 599 | def __str__ (self): |
|---|
| 600 | return "Profile named '"+self.profile+"' could not be saved!" |
|---|
| 601 | |
|---|
| 602 | |
|---|
| 603 | if __name__ == "__main__": |
|---|
| 604 | pass |
|---|