16 import Preferences |
16 import Preferences |
17 |
17 |
18 |
18 |
19 __UrlRe = re.compile( |
19 __UrlRe = re.compile( |
20 r"""((?:http|ftp|https):\/\/[\w\-_]+(?:\.[\w\-_]+)+""" |
20 r"""((?:http|ftp|https):\/\/[\w\-_]+(?:\.[\w\-_]+)+""" |
21 r"""(?:[\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)""") |
21 r"""(?:[\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)""" |
|
22 ) |
22 __ColorRe = re.compile( |
23 __ColorRe = re.compile( |
23 r"""((?:\x03(?:0[0-9]|1[0-5]|[0-9])?(?:,(?:0[0-9]|1[0-5]|[0-9]))?)""" |
24 r"""((?:\x03(?:0[0-9]|1[0-5]|[0-9])?(?:,(?:0[0-9]|1[0-5]|[0-9]))?)""" |
24 r"""|\x02|\x03|\x13|\x15|\x16|\x17|\x1d|\x1f)""") |
25 r"""|\x02|\x03|\x13|\x15|\x16|\x17|\x1d|\x1f)""" |
|
26 ) |
25 |
27 |
26 |
28 |
27 def ircTimestamp(): |
29 def ircTimestamp(): |
28 """ |
30 """ |
29 Module method to generate a time stamp string. |
31 Module method to generate a time stamp string. |
30 |
32 |
31 @return time stamp (string) |
33 @return time stamp (string) |
32 """ |
34 """ |
33 if Preferences.getIrc("ShowTimestamps"): |
35 if Preferences.getIrc("ShowTimestamps"): |
34 if Preferences.getIrc("TimestampIncludeDate"): |
36 if Preferences.getIrc("TimestampIncludeDate"): |
35 if QApplication.isLeftToRight(): |
37 if QApplication.isLeftToRight(): |
36 f = "{0} {1}" |
38 f = "{0} {1}" |
37 else: |
39 else: |
38 f = "{1} {0}" |
40 f = "{1} {0}" |
39 formatString = f.format(Preferences.getIrc("DateFormat"), |
41 formatString = f.format( |
40 Preferences.getIrc("TimeFormat")) |
42 Preferences.getIrc("DateFormat"), Preferences.getIrc("TimeFormat") |
|
43 ) |
41 else: |
44 else: |
42 formatString = Preferences.getIrc("TimeFormat") |
45 formatString = Preferences.getIrc("TimeFormat") |
43 return '<font color="{0}">[{1}]</font> '.format( |
46 return '<font color="{0}">[{1}]</font> '.format( |
44 Preferences.getIrc("TimestampColour"), |
47 Preferences.getIrc("TimestampColour"), |
45 QTime.currentTime().toString(formatString)) |
48 QTime.currentTime().toString(formatString), |
|
49 ) |
46 else: |
50 else: |
47 return "" |
51 return "" |
48 |
52 |
49 |
53 |
50 def ircFilter(msg): |
54 def ircFilter(msg): |
51 """ |
55 """ |
52 Module method to make the message HTML compliant and detect URLs. |
56 Module method to make the message HTML compliant and detect URLs. |
53 |
57 |
54 @param msg message to process (string) |
58 @param msg message to process (string) |
55 @return processed message (string) |
59 @return processed message (string) |
56 """ |
60 """ |
57 # step 1: cleanup message |
61 # step 1: cleanup message |
58 msg = Utilities.html_encode(msg) |
62 msg = Utilities.html_encode(msg) |
59 |
63 |
60 # step 2: replace IRC formatting characters |
64 # step 2: replace IRC formatting characters |
61 openTags = [] |
65 openTags = [] |
62 parts = __ColorRe.split(msg) |
66 parts = __ColorRe.split(msg) |
63 msgParts = [] |
67 msgParts = [] |
64 for part in parts: |
68 for part in parts: |
65 if part == "\x02": # bold |
69 if part == "\x02": # bold |
66 if openTags and openTags[-1] == "b": |
70 if openTags and openTags[-1] == "b": |
67 msgParts.append("</" + openTags.pop(-1) + ">") |
71 msgParts.append("</" + openTags.pop(-1) + ">") |
68 else: |
72 else: |
69 msgParts.append("<b>") |
73 msgParts.append("<b>") |
70 openTags.append("b") |
74 openTags.append("b") |
74 msgParts.append("</" + openTags.pop(-1) + ">") |
78 msgParts.append("</" + openTags.pop(-1) + ">") |
75 else: |
79 else: |
76 continue |
80 continue |
77 else: |
81 else: |
78 continue |
82 continue |
79 elif part == "\x0f": # reset |
83 elif part == "\x0f": # reset |
80 while openTags: |
84 while openTags: |
81 msgParts.append("</" + openTags.pop(-1) + ">") |
85 msgParts.append("</" + openTags.pop(-1) + ">") |
82 elif part == "\x13": # strikethru |
86 elif part == "\x13": # strikethru |
83 if openTags and openTags[-1] == "s": |
87 if openTags and openTags[-1] == "s": |
84 msgParts.append("</" + openTags.pop(-1) + ">") |
88 msgParts.append("</" + openTags.pop(-1) + ">") |
85 else: |
89 else: |
86 msgParts.append("<s>") |
90 msgParts.append("<s>") |
87 openTags.append("s") |
91 openTags.append("s") |
88 elif part in ["\x15", "\x1f"]: # underline |
92 elif part in ["\x15", "\x1f"]: # underline |
89 if openTags and openTags[-1] == "u": |
93 if openTags and openTags[-1] == "u": |
90 msgParts.append("</" + openTags.pop(-1) + ">") |
94 msgParts.append("</" + openTags.pop(-1) + ">") |
91 else: |
95 else: |
92 msgParts.append("<u>") |
96 msgParts.append("<u>") |
93 openTags.append("u") |
97 openTags.append("u") |
94 elif part == "\x16": |
98 elif part == "\x16": |
95 # revert color not supported |
99 # revert color not supported |
96 continue |
100 continue |
97 elif part == "\x1d": # italic |
101 elif part == "\x1d": # italic |
98 if openTags and openTags[-1] == "i": |
102 if openTags and openTags[-1] == "i": |
99 msgParts.append("</" + openTags.pop(-1) + ">") |
103 msgParts.append("</" + openTags.pop(-1) + ">") |
100 else: |
104 else: |
101 msgParts.append("<i>") |
105 msgParts.append("<i>") |
102 openTags.append("i") |
106 openTags.append("i") |
103 elif part.startswith("\x03"): |
107 elif part.startswith("\x03"): |
104 if Preferences.getIrc("EnableIrcColours"): |
108 if Preferences.getIrc("EnableIrcColours"): |
105 colors = part[1:].split(",", 1) |
109 colors = part[1:].split(",", 1) |
106 if len(colors) == 1: |
110 if len(colors) == 1: |
107 # foreground color only |
111 # foreground color only |
108 tag = '<span style="color:{0}">'.format(Preferences.getIrc( |
112 tag = '<span style="color:{0}">'.format( |
109 "IrcColor{0}".format(int(colors[0])))) |
113 Preferences.getIrc("IrcColor{0}".format(int(colors[0]))) |
|
114 ) |
110 else: |
115 else: |
111 if colors[0]: |
116 if colors[0]: |
112 # foreground and background |
117 # foreground and background |
113 tag = ( |
118 tag = '<span style="background-color:{0};color={1}">'.format( |
114 '<span style="background-color:{0};color={1}">' |
119 Preferences.getIrc("IrcColor{0}".format(int(colors[0]))), |
115 .format(Preferences.getIrc( |
120 Preferences.getIrc("IrcColor{0}".format(int(colors[1]))), |
116 "IrcColor{0}".format(int(colors[0]))), |
|
117 Preferences.getIrc( |
|
118 "IrcColor{0}".format(int(colors[1])))) |
|
119 ) |
121 ) |
120 else: |
122 else: |
121 # background only |
123 # background only |
122 tag = '<span style="background-color:{0}">'.format( |
124 tag = '<span style="background-color:{0}">'.format( |
123 Preferences.getIrc( |
125 Preferences.getIrc("IrcColor{0}".format(int(colors[1]))) |
124 "IrcColor{0}".format(int(colors[1])))) |
126 ) |
125 msgParts.append(tag) |
127 msgParts.append(tag) |
126 openTags.append("span") |
128 openTags.append("span") |
127 else: |
129 else: |
128 continue |
130 continue |
129 else: |
131 else: |
130 msgParts.append(part) |
132 msgParts.append(part) |
131 msg = "".join(msgParts) |
133 msg = "".join(msgParts) |
132 |
134 |
133 # step 3: find http and https links |
135 # step 3: find http and https links |
134 parts = __UrlRe.split(msg) |
136 parts = __UrlRe.split(msg) |
135 msgParts = [] |
137 msgParts = [] |
136 for part in parts: |
138 for part in parts: |
137 if part.startswith(("http://", "https://", "ftp://")): |
139 if part.startswith(("http://", "https://", "ftp://")): |
138 msgParts.append('<a href="{0}" style="color:{1}">{0}</a>'.format( |
140 msgParts.append( |
139 part, Preferences.getIrc("HyperlinkColour"))) |
141 '<a href="{0}" style="color:{1}">{0}</a>'.format( |
|
142 part, Preferences.getIrc("HyperlinkColour") |
|
143 ) |
|
144 ) |
140 else: |
145 else: |
141 msgParts.append(part) |
146 msgParts.append(part) |
142 |
147 |
143 return "".join(msgParts) |
148 return "".join(msgParts) |
144 |
149 |
145 |
150 |
146 __channelModesDict = None |
151 __channelModesDict = None |
147 |
152 |
149 def __initChannelModesDict(): |
154 def __initChannelModesDict(): |
150 """ |
155 """ |
151 Private module function to initialize the channels modes dictionary. |
156 Private module function to initialize the channels modes dictionary. |
152 """ |
157 """ |
153 global __channelModesDict |
158 global __channelModesDict |
154 |
159 |
155 modesDict = { |
160 modesDict = { |
156 "a": QCoreApplication.translate("IrcUtilities", "anonymous"), |
161 "a": QCoreApplication.translate("IrcUtilities", "anonymous"), |
157 "b": QCoreApplication.translate("IrcUtilities", "ban mask"), |
162 "b": QCoreApplication.translate("IrcUtilities", "ban mask"), |
158 "c": QCoreApplication.translate("IrcUtilities", "no colors allowed"), |
163 "c": QCoreApplication.translate("IrcUtilities", "no colors allowed"), |
159 "e": QCoreApplication.translate("IrcUtilities", "ban exception mask"), |
164 "e": QCoreApplication.translate("IrcUtilities", "ban exception mask"), |
160 "i": QCoreApplication.translate("IrcUtilities", "invite only"), |
165 "i": QCoreApplication.translate("IrcUtilities", "invite only"), |
161 "k": QCoreApplication.translate("IrcUtilities", "password protected"), |
166 "k": QCoreApplication.translate("IrcUtilities", "password protected"), |
162 "l": QCoreApplication.translate("IrcUtilities", "user limit"), |
167 "l": QCoreApplication.translate("IrcUtilities", "user limit"), |
163 "m": QCoreApplication.translate("IrcUtilities", "moderated"), |
168 "m": QCoreApplication.translate("IrcUtilities", "moderated"), |
164 "n": QCoreApplication.translate("IrcUtilities", |
169 "n": QCoreApplication.translate("IrcUtilities", "no messages from outside"), |
165 "no messages from outside"), |
|
166 "p": QCoreApplication.translate("IrcUtilities", "private"), |
170 "p": QCoreApplication.translate("IrcUtilities", "private"), |
167 "q": QCoreApplication.translate("IrcUtilities", "quiet"), |
171 "q": QCoreApplication.translate("IrcUtilities", "quiet"), |
168 "r": QCoreApplication.translate("IrcUtilities", "reop channel"), |
172 "r": QCoreApplication.translate("IrcUtilities", "reop channel"), |
169 "s": QCoreApplication.translate("IrcUtilities", "secret"), |
173 "s": QCoreApplication.translate("IrcUtilities", "secret"), |
170 "t": QCoreApplication.translate("IrcUtilities", "topic protection"), |
174 "t": QCoreApplication.translate("IrcUtilities", "topic protection"), |