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