Merge from trunk

This commit is contained in:
Charles Haley 2010-06-28 09:32:48 +01:00
commit 24c8b1679b
39 changed files with 18874 additions and 15913 deletions

View File

@ -4,6 +4,53 @@
# for important features/bug fixes.
# Also, each release can have new and improved recipes.
- version: 0.7.6
date: 2010-06-28
new features:
- title: "Add support for the new firmware of the Azbooka"
tickets: [5994]
- title: "A few speedups for calibre startup, should add up to a few seconds of startup time on slower machines"
- title: "Support for the Sweem MM300"
- title: "Add keyboard shorcut for Download metadata and covers"
bug fixes:
- title: "Fix regression in 0.7.5 that broke conversion of malformed HTML files (like those Microsoft Word outputs)"
type: major
tickets: [5991]
- title: "Don't download tags from librarything, as the tagging there is not very good"
- title: "Add mimetype for FB2 so that it can be served by the content server"
tickets: [6011]
- title: "Ensure cover is not resized to less than the available space in the Edit Meta Information dialog"
tickets: [6001]
- title: "SONY driver: Only update collections when sending book to device for the first time"
- title: "calibre should now work on windows when the location for the library contains non-ascii characters"
tickets: [5983]
- title: "Cover browser once again distorts instead of cropping covers that have an incorrect aspect ratio"
- title: "ISBNDb metadata plugin: Fix bug causing only first page of results to be fetched"
- title: "Move iTunes driver to the bottom so that it doesn't interfere with device detection for people that have iphones and an ereader plugged in"
improved recipes:
- Houston Chronicle
- Hindu
- Times of India
- New York Times
new recipes:
- title: Winnipeg Sun
author: rty
- version: 0.7.5
date: 2010-06-25

View File

@ -2,7 +2,7 @@ from __future__ import with_statement
__license__ = 'GPL 3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
import re
import time
from calibre.web.feeds.news import BasicNewsRecipe
class TheHindu(BasicNewsRecipe):
@ -10,45 +10,41 @@ class TheHindu(BasicNewsRecipe):
language = 'en_IN'
oldest_article = 7
__author__ = 'Kovid Goyal and Sujata Raman'
__author__ = 'Kovid Goyal'
max_articles_per_feed = 100
no_stylesheets = True
remove_tags_before = {'name':'font', 'class':'storyhead'}
preprocess_regexps = [
(re.compile(r'<!-- story ends -->.*', re.DOTALL),
lambda match: '</body></html>'),
]
extra_css = '''
.storyhead{font-family:Arial,Helvetica,sans-serif; font-size:large; color:#000099;}
body{font-family:Verdana,Arial,Helvetica,sans-serif; font-size:x-small; text-align:left;}
'''
feeds = [
(u'Main - Front Page', u'http://www.hindu.com/rss/01hdline.xml'),
(u'Main - National', u'http://www.hindu.com/rss/02hdline.xml'),
(u'Main - International', u'http://www.hindu.com/rss/03hdline.xml'),
(u'Main - Opinion', u'http://www.hindu.com/rss/05hdline.xml'),
(u'Main - Business', u'http://www.hindu.com/rss/06hdline.xml'),
(u'Main - Sport', u'http://www.hindu.com/rss/07hdline.xml'),
(u'Main - Weather / Religion / Crossword / Cartoon',
u'http://www.hindu.com/rss/10hdline.xml'),
(u'Main - Engagements', u'http://www.hindu.com/rss/26hdline.xml'),
(u'Supplement - Literary Review',
u'http://www.hindu.com/rss/lrhdline.xml'),
(u'Supplement - Sunday Magazine',
u'http://www.hindu.com/rss/maghdline.xml'),
(u'Supplement - Open Page', u'http://www.hindu.com/rss/ophdline.xml'),
(u'Supplement - Business Review',
u'http://www.hindu.com/rss/bizhdline.xml'),
(u'Supplement - Book Review',
u'http://www.hindu.com/rss/brhdline.xml'),
(u'Supplement - Science & Technology',
u'http://www.hindu.com/rss/setahdline.xml')
]
keep_only_tags = [dict(id='content')]
remove_tags = [dict(attrs={'class':['article-links', 'breadcr']}),
dict(id=['email-section', 'right-column', 'printfooter'])]
extra_css = '.photo-caption { font-size: smaller }'
def postprocess_html(self, soup, first_fetch):
for t in soup.findAll(['table', 'tr', 'td','center']):
t.name = 'div'
return soup
def parse_index(self):
today = time.strftime('%Y-%m-%d')
soup = self.index_to_soup(
'http://www.thehindu.com/todays-paper/tp-index/?date=' + today)
div = soup.find(id='left-column')
feeds = []
current_section = None
current_articles = []
for x in div.findAll(['h3', 'div']):
if current_section and x.get('class', '') == 'tpaper':
a = x.find('a', href=True)
if a is not None:
current_articles.append({'url':a['href']+'?css=print',
'title':self.tag_to_string(a), 'date': '',
'description':''})
if x.name == 'h3':
if current_section and current_articles:
feeds.append((current_section, current_articles))
current_section = self.tag_to_string(x)
current_articles = []
return feeds

View File

@ -1,12 +1,15 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
import string, pprint
from calibre.web.feeds.news import BasicNewsRecipe
class HoustonChronicle(BasicNewsRecipe):
title = u'The Houston Chronicle'
description = 'News from Houston, Texas'
__author__ = 'Kovid Goyal and Sujata Raman'
__author__ = 'Kovid Goyal'
language = 'en'
timefmt = ' [%a, %d %b, %Y]'
no_stylesheets = True
@ -38,54 +41,23 @@ class HoustonChronicle(BasicNewsRecipe):
def parse_index(self):
soup = self.index_to_soup('http://www.chron.com/news/')
container = soup.find('table', attrs={'class':'body-columns'})
categories = ['news', 'sports', 'business', 'entertainment', 'life',
'travel']
feeds = []
current_section = 'Top Stories'
current_articles = []
self.log('\tFound section:', current_section)
for div in container.findAll('div'):
if div.get('class', None) == 'module-mast':
t = self.tag_to_string(div).replace(u'\xbb', '').strip()
if t and 'interactives' not in t:
if current_section and current_articles:
feeds.append((current_section, current_articles))
current_section = t
current_articles = []
self.log('\tFound section:', current_section)
elif div.get('storyid', False):
a = div.find('a', href=True)
if a:
title = self.tag_to_string(a)
url = a.get('href')
if title and url:
if url.startswith('/'):
url = 'http://www.chron.com'+url
self.log('\t\tFound article:', title)
self.log('\t\t\t', url)
current_articles.append({'title':title, 'url':url,
'date':'', 'description':''})
elif div.get('class', None) == 'columnbox' and \
'special' in current_section.lower():
a = div.find('a')
if a:
title = self.tag_to_string(a)
url = a.get('href')
if title and url:
if not url.startswith('/'): continue
url = 'http://www.chron.com'+url
self.log('\t\tFound article:', title)
self.log('\t\t\t', url)
a.extract()
desc = self.tag_to_string(div)
current_articles.append({'title':title, 'url':url,
'date':'', 'description':desc})
if current_section and current_articles:
feeds.append((current_section, current_articles))
for cat in categories:
articles = []
soup = self.index_to_soup('http://www.chron.com/%s/'%cat)
for elem in soup.findAll(comptype='story', storyid=True):
a = elem.find('a', href=True)
if a is None: continue
url = a['href']
if not url.startswith('http://'):
url = 'http://www.chron.com'+url
articles.append({'title':self.tag_to_string(a), 'url':url,
'description':'', 'date':''})
pprint.pprint(articles[-1])
if articles:
feeds.append((string.capwords(cat), articles))
return feeds

View File

@ -1,21 +1,16 @@
from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import BeautifulSoup
class TimesOfIndia(BasicNewsRecipe):
title = u'Times of India'
language = 'en_IN'
__author__ = 'Krittika Goyal'
__author__ = 'Kovid Goyal'
oldest_article = 1 #days
max_articles_per_feed = 25
remove_stylesheets = True
no_stylesheets = True
keep_only_tags = [dict(attrs={'class':'prttabl'})]
remove_tags = [
dict(name='iframe'),
dict(name='td', attrs={'class':'newptool1'}),
dict(name='div', attrs={'id':'newptool'}),
dict(name='ul', attrs={'class':'newtabcontent_tabs_new'}),
dict(name='b', text='Topics'),
dict(name='span', text=':'),
dict(style=lambda x: x and 'float' in x)
]
feeds = [
@ -42,13 +37,8 @@ class TimesOfIndia(BasicNewsRecipe):
('Most Read',
'http://timesofindia.indiatimes.com/rssfeedmostread.cms')
]
def print_version(self, url):
return url + '?prtpage=1'
def preprocess_html(self, soup):
heading = soup.find(name='h1', attrs={'class':'heading'})
td = heading.findParent(name='td')
td.extract()
soup = BeautifulSoup('<html><head><title>t</title></head><body></body></html>')
body = soup.find(name='body')
body.insert(0, td)
td.name = 'div'
return soup

View File

@ -30,6 +30,7 @@ mimetypes.add_type('application/epub+zip', '.epub')
mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs')
mimetypes.add_type('application/xhtml+xml', '.xhtml')
mimetypes.add_type('image/svg+xml', '.svg')
mimetypes.add_type('text/fb2+xml', '.fb2')
mimetypes.add_type('application/x-sony-bbeb', '.lrf')
mimetypes.add_type('application/x-sony-bbeb', '.lrx')
mimetypes.add_type('application/x-dtbncx+xml', '.ncx')

View File

@ -2,7 +2,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = 'calibre'
__version__ = '0.7.5'
__version__ = '0.7.6'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
import re

View File

@ -24,7 +24,7 @@ class N516(USBMS):
VENDOR_ID = [0x0525]
PRODUCT_ID = [0xa4a5]
BCD = [0x323, 0x326]
BCD = [0x323, 0x326, 0x327]
VENDOR_NAME = 'INGENIC'
WINDOWS_MAIN_MEM = '_FILE-STOR_GADGE'

View File

@ -298,8 +298,9 @@ class USBMS(CLI, Device):
# Clear the _new_book indication, as we are supposed to be done with
# adding books at this point
for blist in booklists:
for book in blist:
book._new_book = False
if blist is not None:
for book in blist:
book._new_book = False
self.report_progress(1.0, _('Sending metadata to device...'))
debug_print('USBMS: finished sync_booklists')

View File

@ -7,6 +7,7 @@ Fetch cover from LibraryThing.com based on ISBN number.
import sys, socket, os, re
from lxml import html
import mechanize
from calibre import browser, prints
from calibre.utils.config import OptionParser
@ -14,11 +15,17 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup
OPENLIBRARY = 'http://covers.openlibrary.org/b/isbn/%s-L.jpg?default=false'
class HeadRequest(mechanize.Request):
def get_method(self):
return 'HEAD'
def check_for_cover(isbn, timeout=5.):
br = browser()
br.set_handle_redirect(False)
try:
br.open_novisit(OPENLIBRARY%isbn, timeout=timeout)
br.open_novisit(HeadRequest(OPENLIBRARY%isbn), timeout=timeout)
return True
except Exception, e:
if callable(getattr(e, 'getcode', None)) and e.getcode() == 302:
return True
@ -126,10 +133,10 @@ def get_social_metadata(title, authors, publisher, isbn, username=None,
if match is not None:
si = float(match.group())
mi.series_index = si
tags = root.xpath('//div[@class="tags"]/span[@class="tag"]/a')
if tags:
mi.tags = [html.tostring(x, method='text', encoding=unicode) for x
in tags]
#tags = root.xpath('//div[@class="tags"]/span[@class="tag"]/a')
#if tags:
# mi.tags = [html.tostring(x, method='text', encoding=unicode) for x
# in tags]
span = root.xpath(
'//table[@class="wsltable"]/tr[@class="wslcontent"]/td[4]//span')
if span:

View File

@ -882,7 +882,7 @@ class Manifest(object):
"<?xml version='1.0' encoding='utf-8'?><o:p></o:p>",
'')
data = data.replace("<?xml version='1.0' encoding='utf-8'??>", '')
data = etree.fromstring(data)
data = etree.fromstring(data, parser=RECOVER_PARSER)
elif namespace(data.tag) != XHTML_NS:
# OEB_DOC_NS, but possibly others
ns = namespace(data.tag)

View File

@ -173,6 +173,7 @@ class Label(QLabel):
self.setTextFormat(Qt.RichText)
self.setText('')
self.setWordWrap(True)
self.setAlignment(Qt.AlignTop)
self.linkActivated.connect(self.link_activated)
self._link_clicked = False
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
@ -205,15 +206,15 @@ class BookInfo(QScrollArea):
rows = render_rows(data)
rows = u'\n'.join([u'<tr><td valign="top"><b>%s:</b></td><td valign="top">%s</td></tr>'%(k,t) for
k, t in rows])
comments = ''
if data.get(_('Comments'), '') not in ('', u'None'):
comments = data[_('Comments')]
comments = comments_to_html(comments)
if self.vertical:
if _('Comments') in data and data[_('Comments')]:
comments = comments_to_html(data[_('Comments')])
if comments:
rows += u'<tr><td colspan="2">%s</td></tr>'%comments
self.label.setText(u'<table>%s</table>'%rows)
else:
comments = ''
if _('Comments') in data:
comments = comments_to_html(data[_('Comments')])
left_pane = u'<table>%s</table>'%rows
right_pane = u'<div>%s</div>'%comments
self.label.setText(u'<table><tr><td valign="top" '

View File

@ -87,6 +87,9 @@ class MetadataWidget(Widget, Ui_Form):
if not pm.isNull():
self.cover.setPixmap(pm)
self.cover_data = cover
else:
self.cover.setPixmap(QPixmap(I('default_cover.svg')))
def initialize_combos(self):
self.initalize_authors()

View File

@ -20,36 +20,6 @@
<string>Book Cover</string>
</property>
<layout class="QGridLayout" name="_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="_3">
<item>
<widget class="ImageView" name="cover">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../../resources/images.qrc">:/images/book.svg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="opt_prefer_metadata_cover">
<property name="text">
<string>Use cover from &amp;source file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="_4">
<property name="spacing">
@ -101,6 +71,30 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="opt_prefer_metadata_cover">
<property name="text">
<string>Use cover from &amp;source file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="_3">
<item>
<widget class="ImageView" name="cover" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<zorder>opt_prefer_metadata_cover</zorder>
<zorder></zorder>
@ -308,11 +302,6 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ImageView</class>
<extends>QLabel</extends>
<header>widgets.h</header>
</customwidget>
<customwidget>
<class>EnLineEdit</class>
<extends>QLineEdit</extends>
@ -328,6 +317,12 @@
<extends>QLineEdit</extends>
<header>widgets.h</header>
</customwidget>
<customwidget>
<class>ImageView</class>
<extends>QWidget</extends>
<header>calibre/gui2/widgets.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>title</tabstop>

View File

@ -11,7 +11,7 @@ import re
import time
import traceback
from PyQt4.Qt import SIGNAL, QObject, QCoreApplication, Qt, QTimer, QThread, QDate, \
from PyQt4.Qt import SIGNAL, QObject, Qt, QTimer, QThread, QDate, \
QPixmap, QListWidgetItem, QDialog
from calibre.gui2 import error_dialog, file_icon_provider, dynamic, \
@ -25,7 +25,6 @@ from calibre.ebooks import BOOK_EXTENSIONS
from calibre.ebooks.metadata import string_to_authors, \
authors_to_string, check_isbn
from calibre.ebooks.metadata.library_thing import cover_from_isbn
from calibre import islinux, isfreebsd
from calibre.ebooks.metadata.meta import get_metadata
from calibre.utils.config import prefs, tweaks
from calibre.utils.date import qt_to_dt
@ -311,7 +310,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.formats.setAcceptDrops(True)
self.cover_changed = False
self.cpixmap = None
self.cover.setAcceptDrops(True)
self.pubdate.setMinimumDate(QDate(100,1,1))
pubdate_format = tweaks['gui_pubdate_display_format']
if pubdate_format is not None:
@ -399,11 +397,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.series.lineEdit().editingFinished.connect(self.increment_series_index)
self.show()
height_of_rest = self.frameGeometry().height() - self.cover.height()
width_of_rest = self.frameGeometry().width() - self.cover.width()
ag = QCoreApplication.instance().desktop().availableGeometry(self)
self.cover.MAX_HEIGHT = ag.height()-(25 if (islinux or isfreebsd) else 0)-height_of_rest
self.cover.MAX_WIDTH = ag.width()-(25 if (islinux or isfreebsd) else 0)-width_of_rest
pm = QPixmap()
if cover:
pm.loadFromData(cover)

View File

@ -576,22 +576,13 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="ImageView" name="cover">
<widget class="ImageView" name="cover" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
<verstretch>100</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../../resources/images.qrc">:/images/book.svg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -707,11 +698,6 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ImageView</class>
<extends>QLabel</extends>
<header>widgets.h</header>
</customwidget>
<customwidget>
<class>EnLineEdit</class>
<extends>QLineEdit</extends>
@ -732,6 +718,12 @@
<extends>QListWidget</extends>
<header location="global">calibre/gui2/widgets.h</header>
</customwidget>
<customwidget>
<class>ImageView</class>
<extends>QWidget</extends>
<header>calibre/gui2/widgets.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>title</tabstop>

View File

@ -13,7 +13,7 @@ from PyQt4.Qt import QListView, QIcon, QFont, QLabel, QListWidget, \
QRegExp, QSettings, QSize, QModelIndex, QSplitter, \
QAbstractButton, QPainter, QLineEdit, QComboBox, \
QMenu, QStringListModel, QCompleter, QStringList, \
QTimer
QTimer, QRect
from calibre.gui2 import NONE, error_dialog, pixmap_to_data, gprefs
@ -146,10 +146,15 @@ class FormatList(QListWidget):
return QListWidget.keyPressEvent(self, event)
class ImageView(QLabel):
class ImageView(QWidget):
MAX_WIDTH = 400
MAX_HEIGHT = 300
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self._pixmap = QPixmap(self)
self.setMinimumSize(QSize(150, 200))
self.setAcceptDrops(True)
# Drag 'n drop {{{
DROPABBLE_EXTENSIONS = IMAGE_EXTENSIONS
@classmethod
@ -186,13 +191,45 @@ class ImageView(QLabel):
def dragMoveEvent(self, event):
event.acceptProposedAction()
# }}}
def setPixmap(self, pixmap):
QLabel.setPixmap(self, pixmap)
width, height = fit_image(pixmap.width(), pixmap.height(), self.MAX_WIDTH, self.MAX_HEIGHT)[1:]
self.setMaximumWidth(width)
self.setMaximumHeight(height)
if not isinstance(pixmap, QPixmap):
raise TypeError('Must use a QPixmap')
self._pixmap = pixmap
self.updateGeometry()
self.update()
def pixmap(self):
return self._pixmap
def sizeHint(self):
if self._pixmap.isNull():
return self.minimumSize()
return self._pixmap.size()
def paintEvent(self, event):
QWidget.paintEvent(self, event)
pmap = self._pixmap
if pmap.isNull():
return
w, h = pmap.width(), pmap.height()
cw, ch = self.rect().width(), self.rect().height()
scaled, nw, nh = fit_image(w, h, cw, ch)
if scaled:
pmap = pmap.scaled(nw, nh, Qt.IgnoreAspectRatio,
Qt.SmoothTransformation)
w, h = pmap.width(), pmap.height()
x = int(abs(cw - w)/2.)
y = int(abs(ch - h)/2.)
target = QRect(x, y, w, h)
p = QPainter(self)
p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
p.drawPixmap(target, pmap)
p.end()
# Clipboard copy/paste # {{{
def contextMenuEvent(self, ev):
cm = QMenu(self)
copy = cm.addAction(_('Copy Image'))
@ -215,6 +252,7 @@ class ImageView(QLabel):
self.setPixmap(pmap)
self.emit(SIGNAL('cover_changed(PyQt_PyObject)'),
pixmap_to_data(pmap))
# }}}
class LocationModel(QAbstractListModel):

View File

@ -39,6 +39,11 @@ def comments_to_html(comments):
if not isinstance(comments, unicode):
comments = comments.decode(preferred_encoding, 'replace')
if '<' not in comments:
comments = prepare_string_for_xml(comments)
comments = comments.replace(u'\n', u'<br />')
return u'<p>%s</p>'%comments
# Hackish - ignoring sentences ending or beginning in numbers to avoid
# confusion with decimal points.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,19 +15,23 @@ if _dev_path is not None:
if not os.path.exists(_dev_path):
_dev_path = None
_path_cache = {}
def get_path(path, data=False):
global _dev_path
path = path.replace(os.sep, '/')
base = None
base = sys.resources_location
if _dev_path is not None:
if path in _path_cache:
return _path_cache[path]
if os.path.exists(os.path.join(_dev_path, *path.split('/'))):
base = _dev_path
if base is None:
base = sys.resources_location
path = os.path.join(base, *path.split('/'))
fpath = os.path.join(base, *path.split('/'))
if _dev_path is not None:
_path_cache[path] = fpath
if data:
return open(path, 'rb').read()
return path
return open(fpath, 'rb').read()
return fpath
def get_image_path(path, data=False):
return get_path('images/'+path, data=data)

View File

@ -96,19 +96,21 @@ class NewsItem(NewsTreeItem):
builtin, custom, scheduler_config, parent):
NewsTreeItem.__init__(self, builtin, custom, scheduler_config, parent)
self.urn, self.title = urn, title
self.icon = self.default_icon = None
self.default_icon = default_icon
if 'custom:' in self.urn:
self.icon = custom_icon
else:
icon = I('news/%s.png'%self.urn[8:])
if os.path.exists(icon):
self.icon = QVariant(QIcon(icon))
else:
self.icon = default_icon
def data(self, role):
if role == Qt.DisplayRole:
return QVariant(self.title)
if role == Qt.DecorationRole:
if self.icon is None:
icon = I('news/%s.png'%self.urn[8:])
if os.path.exists(icon):
self.icon = QVariant(QIcon(icon))
else:
self.icon = self.default_icon
return self.icon
return NONE