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
|
use_embedded_content = False
|
||||||
language = 'hr'
|
language = 'hr'
|
||||||
publication_type = 'newsportal'
|
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 = """
|
extra_css = """
|
||||||
body{font-family: Geneva,Arial,Helvetica,Swiss,sans-serif }
|
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||||
h1{font-family: Georgia,serif}
|
@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}
|
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'})]
|
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']
|
remove_attributes=['border', 'lang']
|
||||||
|
|
||||||
feeds = [(u'Vijesti', u'http://www.novilist.hr/rss/feed/sve.xml')]
|
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):
|
def print_version(self, url):
|
||||||
return url.replace('http://www.novilist.hr/','http://www.novilist.hr/layout/set/print/')
|
return url.replace('http://www.novilist.hr/','http://www.novilist.hr/layout/set/print/')
|
||||||
|
|
||||||
|
@ -572,6 +572,44 @@ class CanonicalFragmentIdentifier
|
|||||||
null
|
null
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
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
|
||||||
|
rect = r.getClientRects()[0]
|
||||||
|
|
||||||
|
x = (point.a*rect.left + (1-point.a)*rect.right)
|
||||||
|
y = (rect.top + rect.bottom)/2
|
||||||
|
[x, y] = viewport_to_document(x, y, r.startContainer.ownerDocument)
|
||||||
|
else
|
||||||
|
node = point.node
|
||||||
|
r = node.getBoundingClientRect()
|
||||||
|
[x, y] = viewport_to_document(r.left, r.top, node.ownerDocument)
|
||||||
|
if typeof(point.x) == 'number' and node.offsetWidth
|
||||||
|
x += (point.x*node.offsetWidth)/100
|
||||||
|
if typeof(point.y) == 'number' and node.offsetHeight
|
||||||
|
y += (point.y*node.offsetHeight)/100
|
||||||
|
|
||||||
|
if dist(viewport_to_document(ox, oy), [x, y]) > 50
|
||||||
|
cfi = null
|
||||||
|
|
||||||
|
return cfi
|
||||||
|
|
||||||
at_current: () -> # {{{
|
at_current: () -> # {{{
|
||||||
[winx, winy] = window_scroll_pos()
|
[winx, winy] = window_scroll_pos()
|
||||||
[winw, winh] = [window.innerWidth, window.innerHeight]
|
[winw, winh] = [window.innerWidth, window.innerHeight]
|
||||||
@ -585,44 +623,12 @@ class CanonicalFragmentIdentifier
|
|||||||
minx = max(-winx, -winw)
|
minx = max(-winx, -winw)
|
||||||
maxx = winw
|
maxx = winw
|
||||||
|
|
||||||
dist = (p1, p2) ->
|
x_loop = (cury) =>
|
||||||
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
|
|
||||||
rect = r.getClientRects()[0]
|
|
||||||
|
|
||||||
x = (point.a*rect.left + (1-point.a)*rect.right)
|
|
||||||
y = (rect.top + rect.bottom)/2
|
|
||||||
[x, y] = viewport_to_document(x, y, r.startContainer.ownerDocument)
|
|
||||||
else
|
|
||||||
node = point.node
|
|
||||||
r = node.getBoundingClientRect()
|
|
||||||
[x, y] = viewport_to_document(r.left, r.top, node.ownerDocument)
|
|
||||||
if typeof(point.x) == 'number' and node.offsetWidth
|
|
||||||
x += (point.x*node.offsetWidth)/100
|
|
||||||
if typeof(point.y) == 'number' and node.offsetHeight
|
|
||||||
y += (point.y*node.offsetHeight)/100
|
|
||||||
|
|
||||||
if dist(viewport_to_document(ox, oy), [x, y]) > 50
|
|
||||||
cfi = null
|
|
||||||
|
|
||||||
return cfi
|
|
||||||
|
|
||||||
x_loop = (cury) ->
|
|
||||||
for direction in [-1, 1]
|
for direction in [-1, 1]
|
||||||
delta = deltax * direction
|
delta = deltax * direction
|
||||||
curx = 0
|
curx = 0
|
||||||
until (direction < 0 and curx < minx) or (direction > 0 and curx > maxx)
|
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
|
if cfi
|
||||||
return cfi
|
return cfi
|
||||||
curx += delta
|
curx += delta
|
||||||
|
@ -67,6 +67,8 @@ class PagedDisplay
|
|||||||
###
|
###
|
||||||
|
|
||||||
constructor: () ->
|
constructor: () ->
|
||||||
|
if not this instanceof arguments.callee
|
||||||
|
throw new Error('PagedDisplay constructor called as function')
|
||||||
this.set_geometry()
|
this.set_geometry()
|
||||||
this.page_width = 0
|
this.page_width = 0
|
||||||
this.screen_width = 0
|
this.screen_width = 0
|
||||||
@ -122,12 +124,22 @@ class PagedDisplay
|
|||||||
bs.setProperty('min-height', '0')
|
bs.setProperty('min-height', '0')
|
||||||
bs.setProperty('max-height', 'none')
|
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,
|
# Ensure that the top margin is correct, otherwise for some documents,
|
||||||
# webkit lays out the body with a lot of space on top
|
# webkit lays out the body with a lot of space on top
|
||||||
brect = document.body.getBoundingClientRect()
|
brect = document.body.getBoundingClientRect()
|
||||||
if brect.top > this.margin_top
|
if brect.top > this.margin_top
|
||||||
bs.setProperty('margin-top', (this.margin_top - brect.top)+'px')
|
bs.setProperty('margin-top', (this.margin_top - brect.top)+'px')
|
||||||
brect = document.body.getBoundingClientRect()
|
|
||||||
this.in_paged_mode = true
|
this.in_paged_mode = true
|
||||||
this.current_margin_side = sm
|
this.current_margin_side = sm
|
||||||
return sm
|
return sm
|
||||||
@ -213,11 +225,11 @@ class PagedDisplay
|
|||||||
# most column in the viewport is the column containing the start of the
|
# 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.
|
# element and that the scroll position is at the start of the column.
|
||||||
elem = document.getElementById(name)
|
elem = document.getElementById(name)
|
||||||
if !elem
|
if not elem
|
||||||
elems = document.getElementsByName(name)
|
elems = document.getElementsByName(name)
|
||||||
if elems
|
if elems
|
||||||
elem = elems[0]
|
elem = elems[0]
|
||||||
if !elem
|
if not elem
|
||||||
return
|
return
|
||||||
elem.scrollIntoView()
|
elem.scrollIntoView()
|
||||||
if this.in_paged_mode
|
if this.in_paged_mode
|
||||||
@ -249,12 +261,47 @@ class PagedDisplay
|
|||||||
window.scrollTo(0, y)
|
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?
|
if window?
|
||||||
window.paged_display = new PagedDisplay()
|
window.paged_display = new PagedDisplay()
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# css pagebreak rules
|
|
||||||
# CFI and bookmarks
|
|
||||||
# Go to reference positions
|
# Go to reference positions
|
||||||
# Indexing
|
# Indexing
|
||||||
# Resizing of images
|
# Resizing of images
|
||||||
|
@ -205,7 +205,7 @@ class Document(QWebPage): # {{{
|
|||||||
return self.anchor_positions
|
return self.anchor_positions
|
||||||
|
|
||||||
def switch_to_paged_mode(self, onresize=False):
|
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.
|
# 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
|
# Without this webkit renders the final column with no margin, as the
|
||||||
# columns extend beyond the boundaries (and margin) of body
|
# columns extend beyond the boundaries (and margin) of body
|
||||||
@ -294,7 +294,7 @@ class Document(QWebPage): # {{{
|
|||||||
self.mainFrame().setScrollPosition(QPoint(x, y))
|
self.mainFrame().setScrollPosition(QPoint(x, y))
|
||||||
|
|
||||||
def jump_to_anchor(self, anchor):
|
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):
|
def element_ypos(self, elem):
|
||||||
ans, ok = elem.evaluateJavaScript('$(this).offset().top').toInt()
|
ans, ok = elem.evaluateJavaScript('$(this).offset().top').toInt()
|
||||||
@ -340,8 +340,12 @@ class Document(QWebPage): # {{{
|
|||||||
def scroll_fraction(self):
|
def scroll_fraction(self):
|
||||||
def fget(self):
|
def fget(self):
|
||||||
if self.in_paged_mode:
|
if self.in_paged_mode:
|
||||||
return self.javascript('paged_display.current_pos()',
|
return self.javascript('''
|
||||||
typ='float')
|
ans = 0.0;
|
||||||
|
if (window.paged_display) {
|
||||||
|
ans = window.paged_display.current_pos();
|
||||||
|
}
|
||||||
|
ans;''', typ='float')
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
return abs(float(self.ypos)/(self.height-self.window_height))
|
return abs(float(self.ypos)/(self.height-self.window_height))
|
||||||
@ -922,6 +926,8 @@ class DocumentView(QWebView): # {{{
|
|||||||
direction, typ), typ='int')
|
direction, typ), typ='int')
|
||||||
if loc > -1:
|
if loc > -1:
|
||||||
self.document.scroll_to(x=loc, y=0)
|
self.document.scroll_to(x=loc, y=0)
|
||||||
|
if self.manager is not None:
|
||||||
|
self.manager.scrolled(self.scroll_fraction)
|
||||||
return
|
return
|
||||||
|
|
||||||
if event.delta() < -14:
|
if event.delta() < -14:
|
||||||
|
@ -19,13 +19,10 @@ class PagePosition(object):
|
|||||||
ans = None
|
ans = None
|
||||||
res = self.document.mainFrame().evaluateJavaScript('''
|
res = self.document.mainFrame().evaluateJavaScript('''
|
||||||
ans = 'undefined';
|
ans = 'undefined';
|
||||||
try {
|
if (window.paged_display) {
|
||||||
ans = window.cfi.at_current();
|
ans = window.paged_display.current_cfi();
|
||||||
if (!ans) ans = 'undefined';
|
if (!ans) ans = 'undefined';
|
||||||
} catch (err) {
|
|
||||||
window.console.log(err);
|
|
||||||
}
|
}
|
||||||
window.console.log("Viewport cfi: " + ans);
|
|
||||||
ans;
|
ans;
|
||||||
''')
|
''')
|
||||||
if res.isValid() and not res.isNull() and res.type() == res.String:
|
if res.isValid() and not res.isNull() and res.type() == res.String:
|
||||||
|
@ -93,7 +93,8 @@ class CheckLibrary(object):
|
|||||||
|
|
||||||
lib = self.src_library_path
|
lib = self.src_library_path
|
||||||
for auth_dir in os.listdir(lib):
|
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
|
continue
|
||||||
auth_path = os.path.join(lib, auth_dir)
|
auth_path = os.path.join(lib, auth_dir)
|
||||||
# First check: author must be a directory
|
# First check: author must be a directory
|
||||||
|
@ -73,7 +73,7 @@ class DBPrefs(dict):
|
|||||||
|
|
||||||
def write_serialized(self, library_path):
|
def write_serialized(self, library_path):
|
||||||
try:
|
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:
|
with open(to_filename, "wb") as f:
|
||||||
f.write(json.dumps(self, indent=2, default=to_json))
|
f.write(json.dumps(self, indent=2, default=to_json))
|
||||||
except:
|
except:
|
||||||
@ -82,7 +82,8 @@ class DBPrefs(dict):
|
|||||||
|
|
||||||
def read_serialized(self, library_path):
|
def read_serialized(self, library_path):
|
||||||
try:
|
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:
|
with open(from_filename, "rb") as f:
|
||||||
self.clear()
|
self.clear()
|
||||||
d = json.load(f, object_hook=from_json)
|
d = json.load(f, object_hook=from_json)
|
||||||
@ -92,7 +93,8 @@ class DBPrefs(dict):
|
|||||||
self.db.conn.execute(
|
self.db.conn.execute(
|
||||||
'INSERT INTO preferences (key,val) VALUES (?,?)', (k, raw))
|
'INSERT INTO preferences (key,val) VALUES (?,?)', (k, raw))
|
||||||
self.db.conn.commit()
|
self.db.conn.commit()
|
||||||
|
self.clear()
|
||||||
self.update(d)
|
self.update(d)
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
@ -113,8 +113,8 @@ class Restore(Thread):
|
|||||||
def load_preferences(self):
|
def load_preferences(self):
|
||||||
self.progress_callback(None, 1)
|
self.progress_callback(None, 1)
|
||||||
self.progress_callback('Starting restore preferences', 0)
|
self.progress_callback('Starting restore preferences', 0)
|
||||||
dbpath = os.path.join(self.src_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.json')
|
ndbpath = os.path.join(self.library_path, 'metadata_db_prefs_backup.json')
|
||||||
if not os.path.exists(dbpath):
|
if not os.path.exists(dbpath):
|
||||||
self.progress_callback('Cannot restore preferences. Backup file not found.', 1)
|
self.progress_callback('Cannot restore preferences. Backup file not found.', 1)
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user