mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Merge from trunk
This commit is contained in:
commit
6df958d070
@ -20,10 +20,12 @@ class NoviList_Portal_hr(BasicNewsRecipe):
|
||||
use_embedded_content = False
|
||||
language = 'hr'
|
||||
publication_type = 'newsportal'
|
||||
masthead_url = 'http://www.novilist.hr/design/novilist/images/logo-print.gif'
|
||||
masthead_url = 'http://www.novilist.hr/extension/novilist/design/novilist/images/logo-print.gif'
|
||||
extra_css = """
|
||||
body{font-family: Geneva,Arial,Helvetica,Swiss,sans-serif }
|
||||
h1{font-family: Georgia,serif}
|
||||
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||
@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)}
|
||||
body{font-family: Geneva,Arial,Helvetica,Swiss,sans1,sans-serif }
|
||||
h1{font-family: Georgia,serif1,serif}
|
||||
img{display:block; margin-bottom: 0.4em; margin-top: 0.4em}
|
||||
"""
|
||||
|
||||
@ -39,11 +41,22 @@ class NoviList_Portal_hr(BasicNewsRecipe):
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'id':'content'})]
|
||||
|
||||
remove_tags = [dict(name=['meta', 'link', 'iframe', 'embed', 'object'])]
|
||||
remove_tags = [
|
||||
dict(name=['meta', 'link', 'iframe', 'embed', 'object']),
|
||||
dict(name='div', attrs={'class':lambda x: x and 'embed-object' in x.split()})
|
||||
]
|
||||
remove_attributes=['border', 'lang']
|
||||
|
||||
feeds = [(u'Vijesti', u'http://www.novilist.hr/rss/feed/sve.xml')]
|
||||
|
||||
def get_article_url(self, article):
|
||||
url = BasicNewsRecipe.get_article_url(self, article)
|
||||
filter = ['/Foto/','/Informator/']
|
||||
for item in filter:
|
||||
if item in url:
|
||||
return None
|
||||
return url
|
||||
|
||||
def print_version(self, url):
|
||||
return url.replace('http://www.novilist.hr/','http://www.novilist.hr/layout/set/print/')
|
||||
|
||||
|
@ -572,29 +572,22 @@ class CanonicalFragmentIdentifier
|
||||
null
|
||||
# }}}
|
||||
|
||||
at_current: () -> # {{{
|
||||
[winx, winy] = window_scroll_pos()
|
||||
[winw, winh] = [window.innerWidth, window.innerHeight]
|
||||
max = Math.max
|
||||
winw = max(winw, 400)
|
||||
winh = max(winh, 600)
|
||||
deltay = Math.floor(winh/50)
|
||||
deltax = Math.floor(winw/25)
|
||||
miny = max(-winy, -winh)
|
||||
maxy = winh
|
||||
minx = max(-winx, -winw)
|
||||
maxx = winw
|
||||
at_point: (ox, oy) ->
|
||||
# The CFI at the specified point. Different to at() in that this method
|
||||
# returns null if there is an error, and also calculates a point from
|
||||
# the CFI and returns null if the calculated point is far from the
|
||||
# original point.
|
||||
|
||||
dist = (p1, p2) ->
|
||||
Math.sqrt(Math.pow(p1[0]-p2[0], 2), Math.pow(p1[1]-p2[1], 2))
|
||||
|
||||
get_cfi = (ox, oy) ->
|
||||
try
|
||||
cfi = window.cfi.at(ox, oy)
|
||||
point = window.cfi.point(cfi)
|
||||
catch err
|
||||
cfi = null
|
||||
|
||||
|
||||
if cfi
|
||||
if point.range != null
|
||||
r = point.range
|
||||
@ -617,12 +610,25 @@ class CanonicalFragmentIdentifier
|
||||
|
||||
return cfi
|
||||
|
||||
x_loop = (cury) ->
|
||||
at_current: () -> # {{{
|
||||
[winx, winy] = window_scroll_pos()
|
||||
[winw, winh] = [window.innerWidth, window.innerHeight]
|
||||
max = Math.max
|
||||
winw = max(winw, 400)
|
||||
winh = max(winh, 600)
|
||||
deltay = Math.floor(winh/50)
|
||||
deltax = Math.floor(winw/25)
|
||||
miny = max(-winy, -winh)
|
||||
maxy = winh
|
||||
minx = max(-winx, -winw)
|
||||
maxx = winw
|
||||
|
||||
x_loop = (cury) =>
|
||||
for direction in [-1, 1]
|
||||
delta = deltax * direction
|
||||
curx = 0
|
||||
until (direction < 0 and curx < minx) or (direction > 0 and curx > maxx)
|
||||
cfi = get_cfi(curx, cury)
|
||||
cfi = this.at_point(curx, cury)
|
||||
if cfi
|
||||
return cfi
|
||||
curx += delta
|
||||
|
@ -67,6 +67,8 @@ class PagedDisplay
|
||||
###
|
||||
|
||||
constructor: () ->
|
||||
if not this instanceof arguments.callee
|
||||
throw new Error('PagedDisplay constructor called as function')
|
||||
this.set_geometry()
|
||||
this.page_width = 0
|
||||
this.screen_width = 0
|
||||
@ -122,12 +124,22 @@ class PagedDisplay
|
||||
bs.setProperty('min-height', '0')
|
||||
bs.setProperty('max-height', 'none')
|
||||
|
||||
# Convert page-breaks to column-breaks
|
||||
for sheet in document.styleSheets
|
||||
for rule in sheet.rules
|
||||
if rule.type == 1 # CSSStyleRule
|
||||
for prop in ['page-break-before', 'page-break-after', 'page-break-inside']
|
||||
val = rule.style.getPropertyValue(prop)
|
||||
if val
|
||||
cprop = '-webkit-column-' + prop.substr(5)
|
||||
priority = rule.style.getPropertyPriority(prop)
|
||||
rule.style.setProperty(cprop, val, priority)
|
||||
|
||||
# Ensure that the top margin is correct, otherwise for some documents,
|
||||
# webkit lays out the body with a lot of space on top
|
||||
brect = document.body.getBoundingClientRect()
|
||||
if brect.top > this.margin_top
|
||||
bs.setProperty('margin-top', (this.margin_top - brect.top)+'px')
|
||||
brect = document.body.getBoundingClientRect()
|
||||
this.in_paged_mode = true
|
||||
this.current_margin_side = sm
|
||||
return sm
|
||||
@ -213,11 +225,11 @@ class PagedDisplay
|
||||
# most column in the viewport is the column containing the start of the
|
||||
# element and that the scroll position is at the start of the column.
|
||||
elem = document.getElementById(name)
|
||||
if !elem
|
||||
if not elem
|
||||
elems = document.getElementsByName(name)
|
||||
if elems
|
||||
elem = elems[0]
|
||||
if !elem
|
||||
if not elem
|
||||
return
|
||||
elem.scrollIntoView()
|
||||
if this.in_paged_mode
|
||||
@ -249,12 +261,47 @@ class PagedDisplay
|
||||
window.scrollTo(0, y)
|
||||
)
|
||||
|
||||
current_cfi: () ->
|
||||
# The Conformal Fragment Identifier at the current position, returns
|
||||
# null if it could not be calculated. Requires the cfi.coffee library.
|
||||
ans = null
|
||||
if not window.cfi?
|
||||
return ans
|
||||
if this.in_paged_mode
|
||||
c = this.current_column_location()
|
||||
for x in [c, c-this.page_width, c+this.page_width]
|
||||
# Try the current column, the previous column and the next
|
||||
# column. Each column is tried from top to bottom.
|
||||
[left, right] = [x, x + this.page_width]
|
||||
if left < 0 or right > document.body.scrollWidth
|
||||
continue
|
||||
deltax = Math.floor(this.page_width/25)
|
||||
deltay = Math.floor(window.innerHeight/25)
|
||||
cury = this.margin_top
|
||||
until cury >= (window.innerHeight - this.margin_bottom)
|
||||
curx = left + this.current_margin_side
|
||||
until curx >= (right - this.current_margin_side)
|
||||
cfi = window.cfi.at_point(curx-window.pageXOffset, cury-window.pageYOffset)
|
||||
if cfi
|
||||
log('Viewport cfi:', cfi)
|
||||
return cfi
|
||||
curx += deltax
|
||||
cury += deltay
|
||||
else
|
||||
try
|
||||
ans = window.cfi.at_current()
|
||||
if not ans
|
||||
ans = null
|
||||
catch err
|
||||
log(err)
|
||||
if ans
|
||||
log('Viewport cfi:', ans)
|
||||
return ans
|
||||
|
||||
if window?
|
||||
window.paged_display = new PagedDisplay()
|
||||
|
||||
# TODO:
|
||||
# css pagebreak rules
|
||||
# CFI and bookmarks
|
||||
# Go to reference positions
|
||||
# Indexing
|
||||
# Resizing of images
|
||||
|
@ -205,7 +205,7 @@ class Document(QWebPage): # {{{
|
||||
return self.anchor_positions
|
||||
|
||||
def switch_to_paged_mode(self, onresize=False):
|
||||
side_margin = self.javascript('paged_display.layout()', typ=int)
|
||||
side_margin = self.javascript('window.paged_display.layout()', typ=int)
|
||||
# Setup the contents size to ensure that there is a right most margin.
|
||||
# Without this webkit renders the final column with no margin, as the
|
||||
# columns extend beyond the boundaries (and margin) of body
|
||||
@ -294,7 +294,7 @@ class Document(QWebPage): # {{{
|
||||
self.mainFrame().setScrollPosition(QPoint(x, y))
|
||||
|
||||
def jump_to_anchor(self, anchor):
|
||||
self.javascript('paged_display.jump_to_anchor("%s")'%anchor)
|
||||
self.javascript('window.paged_display.jump_to_anchor("%s")'%anchor)
|
||||
|
||||
def element_ypos(self, elem):
|
||||
ans, ok = elem.evaluateJavaScript('$(this).offset().top').toInt()
|
||||
@ -340,8 +340,12 @@ class Document(QWebPage): # {{{
|
||||
def scroll_fraction(self):
|
||||
def fget(self):
|
||||
if self.in_paged_mode:
|
||||
return self.javascript('paged_display.current_pos()',
|
||||
typ='float')
|
||||
return self.javascript('''
|
||||
ans = 0.0;
|
||||
if (window.paged_display) {
|
||||
ans = window.paged_display.current_pos();
|
||||
}
|
||||
ans;''', typ='float')
|
||||
else:
|
||||
try:
|
||||
return abs(float(self.ypos)/(self.height-self.window_height))
|
||||
@ -922,6 +926,8 @@ class DocumentView(QWebView): # {{{
|
||||
direction, typ), typ='int')
|
||||
if loc > -1:
|
||||
self.document.scroll_to(x=loc, y=0)
|
||||
if self.manager is not None:
|
||||
self.manager.scrolled(self.scroll_fraction)
|
||||
return
|
||||
|
||||
if event.delta() < -14:
|
||||
|
@ -19,13 +19,10 @@ class PagePosition(object):
|
||||
ans = None
|
||||
res = self.document.mainFrame().evaluateJavaScript('''
|
||||
ans = 'undefined';
|
||||
try {
|
||||
ans = window.cfi.at_current();
|
||||
if (window.paged_display) {
|
||||
ans = window.paged_display.current_cfi();
|
||||
if (!ans) ans = 'undefined';
|
||||
} catch (err) {
|
||||
window.console.log(err);
|
||||
}
|
||||
window.console.log("Viewport cfi: " + ans);
|
||||
ans;
|
||||
''')
|
||||
if res.isValid() and not res.isNull() and res.type() == res.String:
|
||||
|
@ -93,7 +93,8 @@ class CheckLibrary(object):
|
||||
|
||||
lib = self.src_library_path
|
||||
for auth_dir in os.listdir(lib):
|
||||
if self.ignore_name(auth_dir) or auth_dir == 'metadata.db':
|
||||
if self.ignore_name(auth_dir) or auth_dir in {'metadata.db',
|
||||
'metadata_db_prefs_backup.json'}:
|
||||
continue
|
||||
auth_path = os.path.join(lib, auth_dir)
|
||||
# First check: author must be a directory
|
||||
|
@ -73,7 +73,7 @@ class DBPrefs(dict):
|
||||
|
||||
def write_serialized(self, library_path):
|
||||
try:
|
||||
to_filename = os.path.join(library_path, 'metadata_db_prefs.json')
|
||||
to_filename = os.path.join(library_path, 'metadata_db_prefs_backup.json')
|
||||
with open(to_filename, "wb") as f:
|
||||
f.write(json.dumps(self, indent=2, default=to_json))
|
||||
except:
|
||||
@ -82,7 +82,8 @@ class DBPrefs(dict):
|
||||
|
||||
def read_serialized(self, library_path):
|
||||
try:
|
||||
from_filename = os.path.join(library_path, 'metadata_db_prefs.json')
|
||||
from_filename = os.path.join(library_path,
|
||||
'metadata_db_prefs_backup.json')
|
||||
with open(from_filename, "rb") as f:
|
||||
self.clear()
|
||||
d = json.load(f, object_hook=from_json)
|
||||
@ -92,6 +93,7 @@ class DBPrefs(dict):
|
||||
self.db.conn.execute(
|
||||
'INSERT INTO preferences (key,val) VALUES (?,?)', (k, raw))
|
||||
self.db.conn.commit()
|
||||
self.clear()
|
||||
self.update(d)
|
||||
except:
|
||||
import traceback
|
||||
|
@ -113,8 +113,8 @@ class Restore(Thread):
|
||||
def load_preferences(self):
|
||||
self.progress_callback(None, 1)
|
||||
self.progress_callback('Starting restore preferences', 0)
|
||||
dbpath = os.path.join(self.src_library_path, 'metadata_db_prefs.json')
|
||||
ndbpath = os.path.join(self.library_path, 'metadata_db_prefs.json')
|
||||
dbpath = os.path.join(self.src_library_path, 'metadata_db_prefs_backup.json')
|
||||
ndbpath = os.path.join(self.library_path, 'metadata_db_prefs_backup.json')
|
||||
if not os.path.exists(dbpath):
|
||||
self.progress_callback('Cannot restore preferences. Backup file not found.', 1)
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user