1 |
cvs_id = "$Id$" |
cvs_id = "$Id$" |
2 |
|
|
3 |
import StringIO |
import StringIO |
|
import re |
|
4 |
|
|
5 |
import gobject |
import gobject |
6 |
import gtk |
import gtk |
8 |
import gtkhtml2 |
import gtkhtml2 |
9 |
import gnome.ui |
import gnome.ui |
10 |
import pango |
import pango |
|
import string |
|
11 |
import locale |
import locale |
12 |
from gtk import glade |
from gtk import glade |
13 |
|
|
14 |
import straw |
import straw |
15 |
from error import log, logparam |
from error import log, logparam |
|
import htmlentitydefs |
|
16 |
import time |
import time |
17 |
|
|
18 |
class ExceptionView: |
class ExceptionView: |
36 |
def write_stream(self, s): |
def write_stream(self, s): |
37 |
self.write(s) |
self.write(s) |
38 |
|
|
|
url_re = re.compile('^\w+://') |
|
|
def is_url(text): |
|
|
return url_re.match(text) |
|
|
|
|
39 |
class ItemView: |
class ItemView: |
40 |
def __init__(self, item_view_container): |
def __init__(self, item_view_container): |
41 |
widget_tree = glade.get_widget_tree(item_view_container) |
widget_tree = glade.get_widget_tree(item_view_container) |
182 |
ret.append(', %s %s' % (_("Page"), |
ret.append(', %s %s' % (_("Page"), |
183 |
item.publication_starting_page)) |
item.publication_starting_page)) |
184 |
ret.append('</p><p>') |
ret.append('</p><p>') |
185 |
if item.guid is not None and is_url(item.guid): |
if item.guid is not None and straw.utils.is_url(item.guid): |
186 |
ret.append('<a href="%s">%s >></a>' % |
ret.append('<a href="%s">%s >></a>' % |
187 |
(item.guid, _("Permanent link"))) |
(item.guid, _("Permanent link"))) |
188 |
elif item.link is not None: |
elif item.link is not None: |
201 |
va.set_value(new_value) |
va.set_value(new_value) |
202 |
return new_value > old_value |
return new_value > old_value |
203 |
|
|
|
def read_text(fragment, chars): |
|
|
"""Read chars cdata characters from html fragment fragment""" |
|
|
count = 0 |
|
|
in_tag = 0 |
|
|
in_attr = 0 |
|
|
in_entity = 0 |
|
|
res_len = 0 |
|
|
if fragment is None: |
|
|
return "" |
|
|
frag_len = len(fragment) |
|
|
i = -1 |
|
|
res = [] |
|
|
previous = None |
|
|
while res_len < chars and i < frag_len - 1: |
|
|
i += 1 |
|
|
current = fragment[i] |
|
|
if in_tag: |
|
|
if in_attr: |
|
|
if current == '"': |
|
|
in_attr = 0 |
|
|
else: |
|
|
if current == '"': |
|
|
in_attr = 1 |
|
|
elif current == '>': |
|
|
in_tag = 0 |
|
|
elif in_entity: |
|
|
res.append(current) |
|
|
if current == ';': |
|
|
in_entity = 0 |
|
|
previous = "" |
|
|
res_len += 1 |
|
|
else: |
|
|
if current == "<": |
|
|
in_tag = 1 |
|
|
elif current == "&": |
|
|
in_entity = 1 |
|
|
res.append("&") |
|
|
# avoid beginning whitespace, newlines and returns, and multiple |
|
|
# whitespaces |
|
|
elif len(res) or current not in string.whitespace: |
|
|
if current == '\n' or current == '\r': |
|
|
current = ' ' |
|
|
if current == previous == ' ': |
|
|
continue |
|
|
res.append(current) |
|
|
previous = current |
|
|
res_len += 1 |
|
|
return "".join(res) |
|
|
|
|
|
entity = re.compile(r'\&.\w*?\;') |
|
|
def convert_entities(text): |
|
|
def conv(ents): |
|
|
entities = htmlentitydefs.entitydefs |
|
|
ents = ents.group(0) |
|
|
ent_code = entities.get(ents[1:-1], None) |
|
|
if ent_code is not None: |
|
|
return unicode(ent_code, 'iso8859-1') |
|
|
else: |
|
|
if ents[1] == '#': |
|
|
code = ents[2:-1] |
|
|
base = 10 |
|
|
if code[0] == 'x': |
|
|
code = code[1:] |
|
|
base = 16 |
|
|
return unichr(int(code, base)) |
|
|
else: |
|
|
return |
|
|
|
|
|
in_entity = entity.search(text) |
|
|
if in_entity is None: |
|
|
return text |
|
|
else: |
|
|
# convert all entities found in text then return the converted text |
|
|
ctext = in_entity.re.sub(conv, text) |
|
|
return ctext |
|
|
|
|
|
html_tags = re.compile(r'\<.*?\>') |
|
|
def is_html(text): |
|
|
is_tag = html_tags.search(text) |
|
|
if is_tag: return 1 |
|
|
else: return 0 |
|
|
|
|
204 |
class ItemList: |
class ItemList: |
205 |
COLUMN_TITLE = 0 |
COLUMN_TITLE = 0 |
206 |
COLUMN_STICKY = 1 |
COLUMN_STICKY = 1 |
266 |
title = "" |
title = "" |
267 |
if item.title is not None and item.title != "": |
if item.title is not None and item.title != "": |
268 |
title = item.title.strip() |
title = item.title.strip() |
269 |
title = convert_entities(read_text(title, len(title))) |
title = straw.utils.convert_entities(straw.utils.read_text(title, len(title))) |
270 |
elif item.description is not None and item.description != "": |
elif item.description is not None and item.description != "": |
271 |
desc = read_text(item.description, 50) |
# read only 50 characters |
272 |
title = convert_entities(desc) |
desc = straw.utils.read_text(item.description, 50) |
273 |
|
title = straw.utils.convert_entities(desc) |
274 |
title += " ..." |
title += " ..." |
275 |
else: |
else: |
276 |
# empty title, empty description, let's not show it |
# empty title, empty description, let's not show it |
470 |
def display_feed(self, feed): |
def display_feed(self, feed): |
471 |
self._widget.show() |
self._widget.show() |
472 |
|
|
473 |
title = feed.channel_title |
title = straw.utils.convert_entities(feed.channel_title) |
474 |
self._title_display.set_text(title) |
self._title_display.set_text(title) |
475 |
if len(title): |
if len(title): |
476 |
self._title_display.show() |
self._title_display.show() |
480 |
description = feed.channel_description |
description = feed.channel_description |
481 |
size = len(description) |
size = len(description) |
482 |
if size: |
if size: |
483 |
if is_html(description): |
if straw.utils.is_html(description): |
484 |
description = read_text(description, size) |
description = straw.utils.read_text(description, size) |
485 |
self._description_display.set_text(description) |
self._description_display.set_text(description) |
486 |
self._description_display.show() |
self._description_display.show() |
487 |
else: |
else: |
539 |
if item.title is not None: |
if item.title is not None: |
540 |
title = item.title[:50] |
title = item.title[:50] |
541 |
if title == "": |
if title == "": |
542 |
title = read_text(item.description, 50) + "..." |
title = straw.utils.read_text(item.description, 50) + "..." |
543 |
model.set(iter, self.COLUMN_TITLE, title, |
model.set(iter, self.COLUMN_TITLE, title, |
544 |
self.COLUMN_FEED, item.feed.title, |
self.COLUMN_FEED, item.feed.title, |
545 |
self.COLUMN_ITEM, item) |
self.COLUMN_ITEM, item) |