mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
CSV catalog pluggin remove \n and \r\n in comments
This commit is contained in:
commit
a68fb07c41
@ -1,24 +1,31 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
xmlns:cc="http://web.resource.org/cc/"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
width="128"
|
width="128"
|
||||||
height="128"
|
height="128"
|
||||||
id="svg1307"
|
id="svg1307"
|
||||||
sodipodi:version="0.32"
|
sodipodi:version="0.32"
|
||||||
inkscape:version="0.43"
|
inkscape:version="0.47 r22583"
|
||||||
version="1.0"
|
version="1.0"
|
||||||
sodipodi:docbase="/home/pinheiro/Documents/pics/new oxygen/svg"
|
sodipodi:docname="donate.svg">
|
||||||
sodipodi:docname="love.svg">
|
|
||||||
<defs
|
<defs
|
||||||
id="defs1309">
|
id="defs1309">
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="0 : 64 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="128 : 64 : 1"
|
||||||
|
inkscape:persp3d-origin="64 : 42.666667 : 1"
|
||||||
|
id="perspective44" />
|
||||||
<linearGradient
|
<linearGradient
|
||||||
inkscape:collect="always"
|
inkscape:collect="always"
|
||||||
id="linearGradient2231">
|
id="linearGradient2231">
|
||||||
@ -180,8 +187,8 @@
|
|||||||
inkscape:pageopacity="0.0"
|
inkscape:pageopacity="0.0"
|
||||||
inkscape:pageshadow="2"
|
inkscape:pageshadow="2"
|
||||||
inkscape:zoom="7.851329"
|
inkscape:zoom="7.851329"
|
||||||
inkscape:cx="92.691163"
|
inkscape:cx="60.937831"
|
||||||
inkscape:cy="92.473338"
|
inkscape:cy="61.488995"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
@ -189,10 +196,11 @@
|
|||||||
guidetolerance="0.1px"
|
guidetolerance="0.1px"
|
||||||
showguides="true"
|
showguides="true"
|
||||||
inkscape:guide-bbox="true"
|
inkscape:guide-bbox="true"
|
||||||
inkscape:window-width="1106"
|
inkscape:window-width="1680"
|
||||||
inkscape:window-height="958"
|
inkscape:window-height="997"
|
||||||
inkscape:window-x="597"
|
inkscape:window-x="-4"
|
||||||
inkscape:window-y="25">
|
inkscape:window-y="30"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
position="32.487481"
|
position="32.487481"
|
||||||
@ -245,26 +253,19 @@
|
|||||||
id="path2276"
|
id="path2276"
|
||||||
d="M 50.892799,3.2812959 L 50.892799,0.48658747 L 50.892799,3.2812959 z "
|
d="M 50.892799,3.2812959 L 50.892799,0.48658747 L 50.892799,3.2812959 z "
|
||||||
style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
|
style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
|
||||||
<path
|
|
||||||
sodipodi:type="arc"
|
|
||||||
style="opacity:0.38139535;fill:url(#radialGradient3297);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
|
|
||||||
id="path3289"
|
|
||||||
sodipodi:cx="63.912209"
|
|
||||||
sodipodi:cy="115.70919"
|
|
||||||
sodipodi:rx="63.912209"
|
|
||||||
sodipodi:ry="12.641975"
|
|
||||||
d="M 127.82442 115.70919 A 63.912209 12.641975 0 1 1 0,115.70919 A 63.912209 12.641975 0 1 1 127.82442 115.70919 z"
|
|
||||||
transform="matrix(1,0,0,0.416667,0,74.87151)" />
|
|
||||||
<path
|
<path
|
||||||
style="fill:url(#radialGradient2335);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="fill:url(#radialGradient2335);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
d="M 35.325021,6.2016208 C 32.278871,6.2210338 29.045555,6.6687791 25.645673,7.6089386 C 5.9380713,13.058619 0.404709,29.342113 5.3805953,48.506873 C 12.126047,74.487157 36.855395,101.02725 64.150803,115.92895 L 64.150803,116.02417 C 64.162016,116.00826 64.173539,115.99248 64.184766,115.97656 C 64.195995,115.99248 64.207516,116.00826 64.218732,116.02417 L 64.218732,115.92895 C 90.473794,101.59521 116.24349,74.487157 122.98895,48.506873 C 127.96481,29.342113 122.43148,13.058619 102.72386,7.6089386 C 83.422254,2.2715258 69.549778,12.840101 64.184766,27.183808 C 59.764775,15.366673 49.572303,6.1108179 35.325021,6.2016208 z "
|
d="M 35.325021,6.2016208 C 32.278871,6.2210338 29.045555,6.6687791 25.645673,7.6089386 C 5.9380713,13.058619 0.404709,29.342113 5.3805953,48.506873 C 12.126047,74.487157 36.855395,101.02725 64.150803,115.92895 L 64.150803,116.02417 C 64.162016,116.00826 64.173539,115.99248 64.184766,115.97656 C 64.195995,115.99248 64.207516,116.00826 64.218732,116.02417 L 64.218732,115.92895 C 90.473794,101.59521 116.24349,74.487157 122.98895,48.506873 C 127.96481,29.342113 122.43148,13.058619 102.72386,7.6089386 C 83.422254,2.2715258 69.549778,12.840101 64.184766,27.183808 C 59.764775,15.366673 49.572303,6.1108179 35.325021,6.2016208 z "
|
||||||
id="path2245"
|
id="path2245"
|
||||||
sodipodi:nodetypes="cssccsccsscc" />
|
sodipodi:nodetypes="cssccsccsscc" />
|
||||||
|
<g
|
||||||
|
id="g2850">
|
||||||
<path
|
<path
|
||||||
id="path2369"
|
sodipodi:nodetypes="cssccsccsscc"
|
||||||
d="M 35.325021,6.2016208 C 32.278871,6.2210338 29.045555,6.6687791 25.645673,7.6089386 C 5.9380713,13.058619 0.404709,29.342113 5.3805953,48.506873 C 12.126047,74.487157 37.113186,101.16799 64.150803,115.92895 L 64.150803,116.02417 C 64.162016,116.00826 64.173539,115.99248 64.184766,115.97656 C 64.195995,115.99248 64.207516,116.00826 64.218732,116.02417 L 64.218732,115.92895 C 90.398445,101.63635 116.24349,74.487157 122.98895,48.506873 C 127.96481,29.342113 122.43148,13.058619 102.72386,7.6089386 C 83.422254,2.2715258 69.549778,12.840101 64.184766,27.183808 C 59.764775,15.366673 49.572303,6.1108179 35.325021,6.2016208 z "
|
|
||||||
style="opacity:0.4713115;fill:url(#linearGradient2379);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="opacity:0.4713115;fill:url(#linearGradient2379);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
sodipodi:nodetypes="cssccsccsscc" />
|
d="M 35.325021,6.2016208 C 32.278871,6.2210338 29.045555,6.6687791 25.645673,7.6089386 C 5.9380713,13.058619 0.404709,29.342113 5.3805953,48.506873 C 12.126047,74.487157 37.113186,101.16799 64.150803,115.92895 L 64.150803,116.02417 C 64.162016,116.00826 64.173539,115.99248 64.184766,115.97656 C 64.195995,115.99248 64.207516,116.00826 64.218732,116.02417 L 64.218732,115.92895 C 90.398445,101.63635 116.24349,74.487157 122.98895,48.506873 C 127.96481,29.342113 122.43148,13.058619 102.72386,7.6089386 C 83.422254,2.2715258 69.549778,12.840101 64.184766,27.183808 C 59.764775,15.366673 49.572303,6.1108179 35.325021,6.2016208 z "
|
||||||
|
id="path2369" />
|
||||||
|
</g>
|
||||||
<path
|
<path
|
||||||
style="opacity:0.1762295;fill:url(#linearGradient2331);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
style="opacity:0.1762295;fill:url(#linearGradient2331);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.29999995;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
d="M 34.451605,6.2067207 C 31.659392,6.2976073 28.7301,6.7682297 25.648957,7.6202497 C 7.7889432,12.559022 1.5815371,26.389172 4.2759909,43.204304 C 27.13595,75.72273 65.297627,95.42612 91.41193,91.971053 C 105.43169,77.948778 119.04939,63.70497 122.99185,48.520401 C 127.96773,29.355639 122.42255,13.069929 102.71494,7.6202497 C 83.413331,2.2828362 69.546961,12.850845 64.181949,27.194552 C 59.761957,15.377418 49.555176,6.1159177 35.307894,6.2067207 C 35.022317,6.2085406 34.740456,6.1973187 34.451605,6.2067207 z "
|
d="M 34.451605,6.2067207 C 31.659392,6.2976073 28.7301,6.7682297 25.648957,7.6202497 C 7.7889432,12.559022 1.5815371,26.389172 4.2759909,43.204304 C 27.13595,75.72273 65.297627,95.42612 91.41193,91.971053 C 105.43169,77.948778 119.04939,63.70497 122.99185,48.520401 C 127.96773,29.355639 122.42255,13.069929 102.71494,7.6202497 C 83.413331,2.2828362 69.546961,12.850845 64.181949,27.194552 C 59.761957,15.377418 49.555176,6.1159177 35.307894,6.2067207 C 35.022317,6.2085406 34.740456,6.1973187 34.451605,6.2067207 z "
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -1,234 +1,176 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://web.resource.org/cc/"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
version="1.0"
|
version="1.0"
|
||||||
id="Livello_1"
|
|
||||||
width="128"
|
width="128"
|
||||||
height="128"
|
height="128"
|
||||||
viewBox="0 0 139 139"
|
viewBox="0 0 139 139"
|
||||||
overflow="visible"
|
id="Livello_1"
|
||||||
enable-background="new 0 0 139 139"
|
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
sodipodi:version="0.32"
|
style="overflow:visible"><defs
|
||||||
inkscape:version="0.45+devel"
|
|
||||||
sodipodi:docname="system-help.svgz"
|
|
||||||
inkscape:output_extension="org.inkscape.output.svgz.inkscape"
|
|
||||||
style="overflow:visible"><metadata
|
|
||||||
id="metadata3164"><rdf:RDF><cc:Work
|
|
||||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
|
||||||
id="defs3162"><filter
|
id="defs3162"><filter
|
||||||
inkscape:collect="always"
|
|
||||||
x="-0.132641"
|
x="-0.132641"
|
||||||
width="1.265282"
|
|
||||||
y="-0.34752154"
|
y="-0.34752154"
|
||||||
|
width="1.265282"
|
||||||
height="1.6950431"
|
height="1.6950431"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
id="filter3547"><feGaussianBlur
|
id="filter3547"><feGaussianBlur
|
||||||
inkscape:collect="always"
|
id="feGaussianBlur3549"
|
||||||
stdDeviation="2.7512044"
|
stdDeviation="2.7512044" /></filter><filter
|
||||||
id="feGaussianBlur3549" /></filter><filter
|
color-interpolation-filters="sRGB"
|
||||||
inkscape:collect="always"
|
|
||||||
id="filter5097"><feGaussianBlur
|
id="filter5097"><feGaussianBlur
|
||||||
inkscape:collect="always"
|
id="feGaussianBlur5099"
|
||||||
stdDeviation="2.32"
|
stdDeviation="2.32" /></filter><filter
|
||||||
id="feGaussianBlur5099" /></filter><filter
|
|
||||||
inkscape:collect="always"
|
|
||||||
x="-0.143268"
|
x="-0.143268"
|
||||||
width="1.286536"
|
|
||||||
y="-0.072184406"
|
y="-0.072184406"
|
||||||
|
width="1.286536"
|
||||||
height="1.1443688"
|
height="1.1443688"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
id="filter5125"><feGaussianBlur
|
id="filter5125"><feGaussianBlur
|
||||||
inkscape:collect="always"
|
id="feGaussianBlur5127"
|
||||||
stdDeviation="1.91024"
|
stdDeviation="1.91024" /></filter></defs>
|
||||||
id="feGaussianBlur5127" /></filter></defs><sodipodi:namedview
|
|
||||||
inkscape:window-height="697"
|
|
||||||
inkscape:window-width="1024"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
guidetolerance="10.0"
|
|
||||||
gridtolerance="10.0"
|
|
||||||
objecttolerance="10.0"
|
|
||||||
borderopacity="1.0"
|
|
||||||
bordercolor="#666666"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
id="base"
|
|
||||||
inkscape:zoom="2.9352518"
|
|
||||||
inkscape:cx="99.496726"
|
|
||||||
inkscape:cy="69.329657"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:current-layer="Livello_1"
|
|
||||||
height="128px"
|
|
||||||
width="128px" />
|
|
||||||
<filter
|
<filter
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
id="AI_Sfocatura_4">
|
id="AI_Sfocatura_4">
|
||||||
<feGaussianBlur
|
<feGaussianBlur
|
||||||
stdDeviation="4"
|
id="feGaussianBlur3096"
|
||||||
id="feGaussianBlur3096" />
|
stdDeviation="4" />
|
||||||
</filter>
|
</filter>
|
||||||
<filter
|
<filter
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
id="AI_Sfocatura_2">
|
id="AI_Sfocatura_2">
|
||||||
<feGaussianBlur
|
<feGaussianBlur
|
||||||
stdDeviation="2"
|
id="feGaussianBlur3099"
|
||||||
id="feGaussianBlur3099" />
|
stdDeviation="2" />
|
||||||
</filter>
|
</filter>
|
||||||
<radialGradient
|
<radialGradient
|
||||||
id="XMLID_12_"
|
|
||||||
cx="69.600098"
|
cx="69.600098"
|
||||||
cy="69.576698"
|
cy="69.576698"
|
||||||
r="58"
|
r="58"
|
||||||
gradientTransform="matrix(1,0,0,-0.1823,0,134.8566)"
|
id="XMLID_12_"
|
||||||
gradientUnits="userSpaceOnUse">
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1,0,0,-0.1823,0,134.8566)">
|
||||||
<stop
|
<stop
|
||||||
offset="0"
|
id="stop3102"
|
||||||
style="stop-color:#000000"
|
style="stop-color:#000000;stop-opacity:1"
|
||||||
id="stop3102" />
|
offset="0" />
|
||||||
<stop
|
<stop
|
||||||
offset="1"
|
id="stop3104"
|
||||||
style="stop-color:#000000;stop-opacity:0;"
|
style="stop-color:#000000;stop-opacity:0"
|
||||||
id="stop3104" />
|
offset="1" />
|
||||||
</radialGradient>
|
</radialGradient>
|
||||||
<circle
|
<circle
|
||||||
sodipodi:ry="58"
|
cx="69.599998"
|
||||||
sodipodi:rx="58"
|
|
||||||
sodipodi:cy="69.599998"
|
|
||||||
sodipodi:cx="69.599998"
|
|
||||||
style="opacity:0.7;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter5097)"
|
|
||||||
id="circle5091"
|
|
||||||
r="58"
|
|
||||||
cy="69.599998"
|
cy="69.599998"
|
||||||
cx="69.599998"
|
r="58"
|
||||||
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)" /><ellipse
|
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)"
|
||||||
cx="69.599998"
|
id="circle5091"
|
||||||
cy="122.173"
|
style="opacity:0.7;fill:#000000;fill-opacity:1;stroke:none;filter:url(#filter5097)" />
|
||||||
rx="58"
|
|
||||||
ry="10.573"
|
|
||||||
id="ellipse3106"
|
|
||||||
style="opacity:0.6;fill:url(#XMLID_12_)"
|
|
||||||
sodipodi:cx="69.599998"
|
|
||||||
sodipodi:cy="122.173"
|
|
||||||
sodipodi:rx="58"
|
|
||||||
sodipodi:ry="10.573"
|
|
||||||
transform="translate(-9.9998474e-2,1.9102535)" />
|
|
||||||
|
|
||||||
<radialGradient
|
<radialGradient
|
||||||
id="XMLID_13_"
|
|
||||||
cx="69.600098"
|
cx="69.600098"
|
||||||
cy="69.600098"
|
cy="69.600098"
|
||||||
r="58"
|
r="58"
|
||||||
|
id="XMLID_13_"
|
||||||
gradientUnits="userSpaceOnUse">
|
gradientUnits="userSpaceOnUse">
|
||||||
<stop
|
<stop
|
||||||
offset="0.6154"
|
id="stop3113"
|
||||||
style="stop-color:#EEEEEE"
|
style="stop-color:#eeeeee;stop-opacity:1"
|
||||||
id="stop3113" />
|
offset="0.61540002" />
|
||||||
<stop
|
<stop
|
||||||
offset="0.8225"
|
id="stop3115"
|
||||||
style="stop-color:#DDDDDD"
|
style="stop-color:#dddddd;stop-opacity:1"
|
||||||
id="stop3115" />
|
offset="0.82249999" />
|
||||||
<stop
|
<stop
|
||||||
offset="1"
|
id="stop3117"
|
||||||
style="stop-color:#FFFFFF"
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
id="stop3117" />
|
offset="1" />
|
||||||
</radialGradient>
|
</radialGradient>
|
||||||
<circle
|
<circle
|
||||||
cx="69.599998"
|
cx="69.599998"
|
||||||
cy="69.599998"
|
cy="69.599998"
|
||||||
r="58"
|
r="58"
|
||||||
|
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)"
|
||||||
id="circle3119"
|
id="circle3119"
|
||||||
style="fill:url(#XMLID_13_)"
|
style="fill:url(#XMLID_13_)" />
|
||||||
sodipodi:cx="69.599998"
|
|
||||||
sodipodi:cy="69.599998"
|
|
||||||
sodipodi:rx="58"
|
|
||||||
sodipodi:ry="58"
|
|
||||||
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)" />
|
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="XMLID_14_"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
x1="27.6001"
|
x1="27.6001"
|
||||||
y1="69.600098"
|
y1="69.600098"
|
||||||
x2="111.6001"
|
x2="111.6001"
|
||||||
y2="69.600098"
|
y2="69.600098"
|
||||||
|
id="XMLID_14_"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
gradientTransform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)">
|
gradientTransform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)">
|
||||||
<stop
|
<stop
|
||||||
offset="0"
|
id="stop3122"
|
||||||
style="stop-color:#2A94EC"
|
style="stop-color:#2a94ec;stop-opacity:1"
|
||||||
id="stop3122" />
|
offset="0" />
|
||||||
<stop
|
<stop
|
||||||
offset="1"
|
id="stop3124"
|
||||||
style="stop-color:#0057AE"
|
style="stop-color:#0057ae;stop-opacity:1"
|
||||||
id="stop3124" />
|
offset="1" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<path
|
<path
|
||||||
d="M 26.062502,67.328127 C 26.062502,92.477355 46.522651,112.9375 71.671877,112.9375 C 96.821104,112.9375 117.28125,92.477355 117.28125,67.328127 C 117.28125,42.178901 96.821104,21.718753 71.671877,21.718753 C 46.522651,21.718753 26.062502,42.178901 26.062502,67.328127 z"
|
d="m 26.062502,67.328127 c 0,25.149228 20.460149,45.609373 45.609375,45.609373 25.149227,0 45.609373,-20.460145 45.609373,-45.609373 0,-25.149226 -20.460146,-45.609374 -45.609373,-45.609374 -25.149226,0 -45.609375,20.460148 -45.609375,45.609374 z"
|
||||||
id="path3126"
|
id="path3126"
|
||||||
style="fill:url(#XMLID_14_)" />
|
style="fill:url(#XMLID_14_)" />
|
||||||
<g
|
<g
|
||||||
|
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)"
|
||||||
id="circle22111"
|
id="circle22111"
|
||||||
cy="92"
|
style="opacity:0.3;filter:url(#filter3547)">
|
||||||
rx="36"
|
|
||||||
ry="36"
|
|
||||||
cx="343.99899"
|
|
||||||
enable-background="new "
|
|
||||||
style="opacity:0.3;filter:url(#filter3547)"
|
|
||||||
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)">
|
|
||||||
<path
|
<path
|
||||||
d="M 77.041,104.759 C 63.767,106.115 50.122,103.11 46.565,98.042 C 43.007,92.976 50.885,87.768 64.16,86.41 C 77.434,85.054 91.079,88.058 94.637,93.126 C 98.193,98.194 90.315,103.401 77.041,104.759 z"
|
d="M 77.041,104.759 C 63.767,106.115 50.122,103.11 46.565,98.042 43.007,92.976 50.885,87.768 64.16,86.41 c 13.274,-1.356 26.919,1.648 30.477,6.716 3.556,5.068 -4.322,10.275 -17.596,11.633 z"
|
||||||
id="path3129"
|
id="path3129"
|
||||||
style="fill:#a8dde0" />
|
style="fill:#a8dde0" />
|
||||||
</g>
|
</g>
|
||||||
<linearGradient
|
<linearGradient
|
||||||
id="circle16776_1_"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
x1="135.5601"
|
x1="135.5601"
|
||||||
y1="417.66461"
|
y1="417.66461"
|
||||||
x2="161.87621"
|
x2="161.87621"
|
||||||
y2="417.66461"
|
y2="417.66461"
|
||||||
|
id="circle16776_1_"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
gradientTransform="matrix(0,1.7280523,1.7280523,0,-650.07477,-218.71693)">
|
gradientTransform="matrix(0,1.7280523,1.7280523,0,-650.07477,-218.71693)">
|
||||||
<stop
|
<stop
|
||||||
offset="0"
|
id="stop3132"
|
||||||
style="stop-color:#FFFFFF"
|
style="stop-color:#ffffff;stop-opacity:1"
|
||||||
id="stop3132" />
|
offset="0" />
|
||||||
<stop
|
<stop
|
||||||
offset="1"
|
id="stop3134"
|
||||||
style="stop-color:#ffffff;stop-opacity:0;"
|
style="stop-color:#ffffff;stop-opacity:0"
|
||||||
id="stop3134" />
|
offset="1" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
<path
|
<path
|
||||||
|
d="m 71.671877,24.06655 c -21.383195,0 -39.252297,14.70468 -43.558039,34.283047 8.584336,7.792687 24.872313,-3.99082 43.558039,-3.99082 18.685727,0 34.974783,11.783507 43.558033,3.99082 C 110.92417,38.77123 93.056158,24.06655 71.671877,24.06655 z"
|
||||||
id="circle16776"
|
id="circle16776"
|
||||||
enable-background="new "
|
|
||||||
d="M 71.671877,24.06655 C 50.288682,24.06655 32.41958,38.77123 28.113838,58.349597 C 36.698174,66.142284 52.986151,54.358777 71.671877,54.358777 C 90.357604,54.358777 106.64666,66.142284 115.22991,58.349597 C 110.92417,38.77123 93.056158,24.06655 71.671877,24.06655 z"
|
|
||||||
style="opacity:0.8;fill:url(#circle16776_1_)" />
|
style="opacity:0.8;fill:url(#circle16776_1_)" />
|
||||||
<g
|
<g
|
||||||
id="g3137"
|
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)"
|
||||||
transform="matrix(1.0859375,0,0,1.0859375,-3.9093733,-8.2531233)">
|
id="g3137">
|
||||||
<defs
|
<defs
|
||||||
id="defs3139"><path
|
id="defs3139"><path
|
||||||
id="XMLID_10_"
|
d="m 27.6,69.6 c 0,23.159 18.841,42 42,42 23.159,0 42,-18.841 42,-42 0,-23.159 -18.841,-42 -42,-42 -23.159,0 -42,18.841 -42,42 z"
|
||||||
d="M 27.6,69.6 C 27.6,92.759 46.441,111.6 69.6,111.6 C 92.759,111.6 111.6,92.759 111.6,69.6 C 111.6,46.441 92.759,27.6 69.6,27.6 C 46.441,27.6 27.6,46.441 27.6,69.6 z" /></defs>
|
id="XMLID_10_" /></defs>
|
||||||
<clipPath
|
<clipPath
|
||||||
id="XMLID_6_">
|
id="XMLID_6_">
|
||||||
<use
|
<use
|
||||||
xlink:href="#XMLID_10_"
|
|
||||||
id="use3143"
|
id="use3143"
|
||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="139"
|
width="139"
|
||||||
height="139" />
|
height="139"
|
||||||
|
xlink:href="#XMLID_10_" />
|
||||||
</clipPath>
|
</clipPath>
|
||||||
<g
|
<g
|
||||||
clip-path="url(#XMLID_6_)"
|
clip-path="url(#XMLID_6_)"
|
||||||
id="g3145"
|
id="g3145"
|
||||||
style="filter:url(#AI_Sfocatura_2)">
|
style="filter:url(#AI_Sfocatura_2)">
|
||||||
<path
|
<path
|
||||||
d="M 27.6,69.6 C 27.6,92.759 46.441,111.6 69.6,111.6 C 92.759,111.6 111.6,92.759 111.6,69.6 C 111.6,46.441 92.759,27.6 69.6,27.6 C 46.441,27.6 27.6,46.441 27.6,69.6 z"
|
d="m 27.6,69.6 c 0,23.159 18.841,42 42,42 23.159,0 42,-18.841 42,-42 0,-23.159 -18.841,-42 -42,-42 -23.159,0 -42,18.841 -42,42 z"
|
||||||
id="path3147"
|
id="path3147"
|
||||||
style="fill:none;stroke:#00316e;stroke-width:2" />
|
style="fill:none;stroke:#00316e;stroke-width:2" />
|
||||||
</g>
|
</g>
|
||||||
@ -240,30 +182,22 @@
|
|||||||
transform="matrix(1.0859375,0,0,1.1113796,-3.201342,-9.3177223)"
|
transform="matrix(1.0859375,0,0,1.1113796,-3.201342,-9.3177223)"
|
||||||
id="g5119"
|
id="g5119"
|
||||||
style="fill:#00316e;filter:url(#filter5125)"><path
|
style="fill:#00316e;filter:url(#filter5125)"><path
|
||||||
style="fill:#00316e"
|
d="m 63.37,80.089 -0.178,-2.343 c -0.18,-4.598 1.248,-9.284 5.259,-14.062 2.853,-3.424 5.169,-6.398 5.169,-9.463 0,-3.064 -2.049,-5.227 -6.418,-5.318 -3.029,0 -6.506,0.992 -8.913,2.614 l -2.941,-9.733 c 3.208,-1.894 8.467,-3.696 14.885,-3.696 11.677,0 17.115,6.58 17.115,13.97 0,6.939 -4.279,11.357 -7.667,15.231 -3.209,3.605 -4.635,7.121 -4.546,11.177 l 0,1.622 -11.765,0 0,0.001 z"
|
||||||
d="M 63.37,80.089 L 63.192,77.746 C 63.012,73.148 64.44,68.462 68.451,63.684 C 71.304,60.26 73.62,57.286 73.62,54.221 C 73.62,51.157 71.571,48.994 67.202,48.903 C 64.173,48.903 60.696,49.895 58.289,51.517 L 55.348,41.784 C 58.556,39.89 63.815,38.088 70.233,38.088 C 81.91,38.088 87.348,44.668 87.348,52.058 C 87.348,58.997 83.069,63.415 79.681,67.289 C 76.472,70.894 75.046,74.41 75.135,78.466 L 75.135,80.088 L 63.37,80.088 L 63.37,80.089 z"
|
id="path5121"
|
||||||
id="path5121" /><circle
|
style="fill:#00316e" /><circle
|
||||||
style="fill:#00316e"
|
|
||||||
sodipodi:ry="8"
|
|
||||||
sodipodi:rx="8"
|
|
||||||
sodipodi:cy="93.599998"
|
|
||||||
sodipodi:cx="69.599998"
|
|
||||||
cx="69.599998"
|
cx="69.599998"
|
||||||
cy="93.599998"
|
cy="93.599998"
|
||||||
r="8"
|
r="8"
|
||||||
id="circle5123" /></g><g
|
id="circle5123"
|
||||||
id="g5101"
|
style="fill:#00316e" /></g><g
|
||||||
transform="matrix(1.0859375,0,0,1.0859375,-3.201342,-8.2531233)"><path
|
transform="matrix(1.0859375,0,0,1.0859375,-3.201342,-8.2531233)"
|
||||||
|
id="g5101"><path
|
||||||
|
d="m 63.37,80.089 -0.178,-2.343 c -0.18,-4.598 1.248,-9.284 5.259,-14.062 2.853,-3.424 5.169,-6.398 5.169,-9.463 0,-3.064 -2.049,-5.227 -6.418,-5.318 -3.029,0 -6.506,0.992 -8.913,2.614 l -2.941,-9.733 c 3.208,-1.894 8.467,-3.696 14.885,-3.696 11.677,0 17.115,6.58 17.115,13.97 0,6.939 -4.279,11.357 -7.667,15.231 -3.209,3.605 -4.635,7.121 -4.546,11.177 l 0,1.622 -11.765,0 0,0.001 z"
|
||||||
id="path3157"
|
id="path3157"
|
||||||
d="M 63.37,80.089 L 63.192,77.746 C 63.012,73.148 64.44,68.462 68.451,63.684 C 71.304,60.26 73.62,57.286 73.62,54.221 C 73.62,51.157 71.571,48.994 67.202,48.903 C 64.173,48.903 60.696,49.895 58.289,51.517 L 55.348,41.784 C 58.556,39.89 63.815,38.088 70.233,38.088 C 81.91,38.088 87.348,44.668 87.348,52.058 C 87.348,58.997 83.069,63.415 79.681,67.289 C 76.472,70.894 75.046,74.41 75.135,78.466 L 75.135,80.088 L 63.37,80.088 L 63.37,80.089 z"
|
|
||||||
style="fill:#ffffff" /><circle
|
style="fill:#ffffff" /><circle
|
||||||
id="circle3159"
|
|
||||||
r="8"
|
|
||||||
cy="93.599998"
|
|
||||||
cx="69.599998"
|
cx="69.599998"
|
||||||
sodipodi:cx="69.599998"
|
cy="93.599998"
|
||||||
sodipodi:cy="93.599998"
|
r="8"
|
||||||
sodipodi:rx="8"
|
id="circle3159"
|
||||||
sodipodi:ry="8"
|
|
||||||
style="fill:#ffffff" /></g>
|
style="fill:#ffffff" /></g>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 6.3 KiB |
BIN
resources/images/lt.png
Normal file
BIN
resources/images/lt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
BIN
resources/images/news/elpais_impreso.png
Normal file
BIN
resources/images/news/elpais_impreso.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 717 B |
86
resources/recipes/elpais_impreso.recipe
Normal file
86
resources/recipes/elpais_impreso.recipe
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
www.elpais.com/diario/
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre import strftime
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class ElPaisImpresa(BasicNewsRecipe):
|
||||||
|
title = 'El País - edicion impresa'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'el periodico global en Español'
|
||||||
|
publisher = 'EDICIONES EL PAIS, S.L.'
|
||||||
|
category = 'news, politics,Spain,actualidad,noticias,informacion,videos,fotografias,audios,graficos,nacional,internacional,deportes,economia,tecnologia,cultura,gente,television,sociedad,opinion,blogs,foros,chats,encuestas,entrevistas,participacion'
|
||||||
|
no_stylesheets = True
|
||||||
|
encoding = 'latin1'
|
||||||
|
use_embedded_content = False
|
||||||
|
language = 'es'
|
||||||
|
publication_type = 'newspaper'
|
||||||
|
masthead_url = 'http://www.elpais.com/im/tit_logo_global.gif'
|
||||||
|
index = 'http://www.elpais.com/diario/'
|
||||||
|
extra_css = ' p{text-align: justify} body{ text-align: left; font-family: Georgia,"Times New Roman",Times,serif } h2{font-family: Arial,Helvetica,sans-serif} img{margin-bottom: 0.4em} '
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'Internacional' , index + u'internacional/' )
|
||||||
|
,(u'España' , index + u'espana/' )
|
||||||
|
,(u'Economia' , index + u'economia/' )
|
||||||
|
,(u'Opinion' , index + u'opinion/' )
|
||||||
|
,(u'Viñetas' , index + u'vineta/' )
|
||||||
|
,(u'Sociedad' , index + u'sociedad/' )
|
||||||
|
,(u'Cultura' , index + u'cultura/' )
|
||||||
|
,(u'Tendencias' , index + u'tendencias/' )
|
||||||
|
,(u'Gente' , index + u'gente/' )
|
||||||
|
,(u'Obituarios' , index + u'obituarios/' )
|
||||||
|
,(u'Deportes' , index + u'deportes/' )
|
||||||
|
,(u'Pantallas' , index + u'radioytv/' )
|
||||||
|
,(u'Ultima' , index + u'ultima/' )
|
||||||
|
,(u'Educacion' , index + u'educacion/' )
|
||||||
|
,(u'Saludo' , index + u'salud/' )
|
||||||
|
,(u'Ciberpais' , index + u'ciberpais/' )
|
||||||
|
,(u'EP3' , index + u'ep3/' )
|
||||||
|
,(u'Cine' , index + u'cine/' )
|
||||||
|
,(u'Babelia' , index + u'babelia/' )
|
||||||
|
,(u'El viajero' , index + u'viajero/' )
|
||||||
|
,(u'Negocios' , index + u'negocios/' )
|
||||||
|
,(u'Domingo' , index + u'domingo/' )
|
||||||
|
,(u'El Pais semanal' , index + u'eps/' )
|
||||||
|
,(u'Quadern Catalunya' , index + u'quadern-catalunya/' )
|
||||||
|
]
|
||||||
|
|
||||||
|
keep_only_tags=[dict(attrs={'class':['cabecera_noticia','contenido_noticia']})]
|
||||||
|
remove_attributes=['width','height']
|
||||||
|
remove_tags=[dict(name='link')]
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
totalfeeds = []
|
||||||
|
lfeeds = self.get_feeds()
|
||||||
|
for feedobj in lfeeds:
|
||||||
|
feedtitle, feedurl = feedobj
|
||||||
|
self.report_progress(0, _('Fetching feed')+' %s...'%(feedtitle if feedtitle else feedurl))
|
||||||
|
articles = []
|
||||||
|
soup = self.index_to_soup(feedurl)
|
||||||
|
for item in soup.findAll('a',attrs={'class':['g19r003','g19i003','g17r003','g17i003']}):
|
||||||
|
url = 'http://www.elpais.com' + item['href'].rpartition('/')[0]
|
||||||
|
title = self.tag_to_string(item)
|
||||||
|
date = strftime(self.timefmt)
|
||||||
|
articles.append({
|
||||||
|
'title' :title
|
||||||
|
,'date' :date
|
||||||
|
,'url' :url
|
||||||
|
,'description':''
|
||||||
|
})
|
||||||
|
totalfeeds.append((feedtitle, articles))
|
||||||
|
return totalfeeds
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
return url + '?print=1'
|
@ -4,29 +4,27 @@ from calibre import __appname__
|
|||||||
|
|
||||||
class GoogleReader(BasicNewsRecipe):
|
class GoogleReader(BasicNewsRecipe):
|
||||||
title = 'Google Reader'
|
title = 'Google Reader'
|
||||||
description = 'This recipe downloads feeds you have tagged from your Google Reader account.'
|
description = 'This recipe fetches from your Google Reader account unread Starred items and unread Feeds you have placed in a folder via the manage subscriptions feature.'
|
||||||
needs_subscription = True
|
needs_subscription = True
|
||||||
__author__ = 'davec'
|
__author__ = 'davec, rollercoaster, Starson17'
|
||||||
base_url = 'http://www.google.com/reader/atom/'
|
base_url = 'http://www.google.com/reader/atom/'
|
||||||
max_articles_per_feed = 50
|
oldest_article = 365
|
||||||
|
max_articles_per_feed = 250
|
||||||
get_options = '?n=%d&xt=user/-/state/com.google/read' % max_articles_per_feed
|
get_options = '?n=%d&xt=user/-/state/com.google/read' % max_articles_per_feed
|
||||||
use_embedded_content = True
|
use_embedded_content = True
|
||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser(self)
|
||||||
|
|
||||||
if self.username is not None and self.password is not None:
|
if self.username is not None and self.password is not None:
|
||||||
request = urllib.urlencode([('Email', self.username), ('Passwd', self.password),
|
request = urllib.urlencode([('Email', self.username), ('Passwd', self.password),
|
||||||
('service', 'reader'), ('source', __appname__)])
|
('service', 'reader'), ('accountType', 'HOSTED_OR_GOOGLE'), ('source', __appname__)])
|
||||||
response = br.open('https://www.google.com/accounts/ClientLogin', request)
|
response = br.open('https://www.google.com/accounts/ClientLogin', request)
|
||||||
sid = re.search('SID=(\S*)', response.read()).group(1)
|
auth = re.search('Auth=(\S*)', response.read()).group(1)
|
||||||
|
|
||||||
cookies = mechanize.CookieJar()
|
cookies = mechanize.CookieJar()
|
||||||
br = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
|
br = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
|
||||||
cookies.set_cookie(mechanize.Cookie(None, 'SID', sid, None, False, '.google.com', True, True, '/', True, False, None, True, '', '', None))
|
br.addheaders = [('Authorization', 'GoogleLogin auth='+auth)]
|
||||||
return br
|
return br
|
||||||
|
|
||||||
|
|
||||||
def get_feeds(self):
|
def get_feeds(self):
|
||||||
feeds = []
|
feeds = []
|
||||||
soup = self.index_to_soup('http://www.google.com/reader/api/0/tag/list')
|
soup = self.index_to_soup('http://www.google.com/reader/api/0/tag/list')
|
||||||
|
@ -3,10 +3,10 @@ from calibre.web.feeds.recipes import BasicNewsRecipe
|
|||||||
from calibre import __appname__
|
from calibre import __appname__
|
||||||
|
|
||||||
class GoogleReaderUber(BasicNewsRecipe):
|
class GoogleReaderUber(BasicNewsRecipe):
|
||||||
title = 'Google Reader Uber'
|
title = 'Google Reader uber'
|
||||||
description = 'This recipe downloads all unread feedsfrom your Google Reader account.'
|
description = 'Fetches all feeds from your Google Reader account including the uncategorized items.'
|
||||||
needs_subscription = True
|
needs_subscription = True
|
||||||
__author__ = 'rollercoaster, davec'
|
__author__ = 'davec, rollercoaster, Starson17'
|
||||||
base_url = 'http://www.google.com/reader/atom/'
|
base_url = 'http://www.google.com/reader/atom/'
|
||||||
oldest_article = 365
|
oldest_article = 365
|
||||||
max_articles_per_feed = 250
|
max_articles_per_feed = 250
|
||||||
@ -14,20 +14,17 @@ class GoogleReaderUber(BasicNewsRecipe):
|
|||||||
use_embedded_content = True
|
use_embedded_content = True
|
||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser(self)
|
||||||
|
|
||||||
if self.username is not None and self.password is not None:
|
if self.username is not None and self.password is not None:
|
||||||
request = urllib.urlencode([('Email', self.username), ('Passwd', self.password),
|
request = urllib.urlencode([('Email', self.username), ('Passwd', self.password),
|
||||||
('service', 'reader'), ('source', __appname__)])
|
('service', 'reader'), ('accountType', 'HOSTED_OR_GOOGLE'), ('source', __appname__)])
|
||||||
response = br.open('https://www.google.com/accounts/ClientLogin', request)
|
response = br.open('https://www.google.com/accounts/ClientLogin', request)
|
||||||
sid = re.search('SID=(\S*)', response.read()).group(1)
|
auth = re.search('Auth=(\S*)', response.read()).group(1)
|
||||||
|
|
||||||
cookies = mechanize.CookieJar()
|
cookies = mechanize.CookieJar()
|
||||||
br = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
|
br = mechanize.build_opener(mechanize.HTTPCookieProcessor(cookies))
|
||||||
cookies.set_cookie(mechanize.Cookie(None, 'SID', sid, None, False, '.google.com', True, True, '/', True, False, None, True, '', '', None))
|
br.addheaders = [('Authorization', 'GoogleLogin auth='+auth)]
|
||||||
return br
|
return br
|
||||||
|
|
||||||
|
|
||||||
def get_feeds(self):
|
def get_feeds(self):
|
||||||
feeds = []
|
feeds = []
|
||||||
soup = self.index_to_soup('http://www.google.com/reader/api/0/tag/list')
|
soup = self.index_to_soup('http://www.google.com/reader/api/0/tag/list')
|
||||||
|
34
resources/recipes/waco_tribune.recipe
Normal file
34
resources/recipes/waco_tribune.recipe
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1278773519(BasicNewsRecipe):
|
||||||
|
title = u'Waco Tribune Herald'
|
||||||
|
__author__ = 'rty'
|
||||||
|
pubisher = 'A Robinson Media Company'
|
||||||
|
description = 'Waco, Texas, Newspaper'
|
||||||
|
category = 'News, Texas, Waco'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'News', u'http://www.wacotrib.com/news/index.rss2'),
|
||||||
|
(u'Sports', u'http://www.wacotrib.com/sports/index.rss2'),
|
||||||
|
(u'AccessWaco', u'http://www.wacotrib.com/accesswaco/index.rss2'),
|
||||||
|
(u'Opinions', u'http://www.wacotrib.com/opinion/index.rss2')
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_javascript = True
|
||||||
|
use_embedded_content = False
|
||||||
|
no_stylesheets = True
|
||||||
|
language = 'en'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
conversion_options = {'linearize_tables':True}
|
||||||
|
masthead_url = 'http://media.wacotrib.com/designimages/wacotrib_logo.jpg'
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':'twoColumn left'}),
|
||||||
|
]
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='div', attrs={'class':'right blueLinks'}),
|
||||||
|
]
|
||||||
|
remove_tags_after = [
|
||||||
|
dict(name='div', attrs={'class':'dottedRule'}),
|
||||||
|
]
|
@ -30,7 +30,8 @@ class ANDROID(USBMS):
|
|||||||
0x18d1 : { 0x4e11 : [0x0100, 0x226], 0x4e12: [0x0100, 0x226]},
|
0x18d1 : { 0x4e11 : [0x0100, 0x226], 0x4e12: [0x0100, 0x226]},
|
||||||
|
|
||||||
# Samsung
|
# Samsung
|
||||||
0x04e8 : { 0x681d : [0x0222, 0x0400], 0x681c : [0x0222, 0x0224]},
|
0x04e8 : { 0x681d : [0x0222, 0x0400],
|
||||||
|
0x681c : [0x0222, 0x0224, 0x0400]},
|
||||||
|
|
||||||
# Acer
|
# Acer
|
||||||
0x502 : { 0x3203 : [0x0100]},
|
0x502 : { 0x3203 : [0x0100]},
|
||||||
@ -70,6 +71,16 @@ class ANDROID(USBMS):
|
|||||||
dirs = [x.strip() for x in dirs.split(',')]
|
dirs = [x.strip() for x in dirs.split(',')]
|
||||||
self.EBOOK_DIR_MAIN = dirs
|
self.EBOOK_DIR_MAIN = dirs
|
||||||
|
|
||||||
|
def get_main_ebook_dir(self, for_upload=False):
|
||||||
|
dirs = self.EBOOK_DIR_MAIN
|
||||||
|
if not for_upload:
|
||||||
|
def aldiko_tweak(x):
|
||||||
|
return 'eBooks' if x == 'eBooks/import' else x
|
||||||
|
if isinstance(dirs, basestring):
|
||||||
|
dirs = [dirs]
|
||||||
|
dirs = list(map(aldiko_tweak, dirs))
|
||||||
|
return dirs
|
||||||
|
|
||||||
class S60(USBMS):
|
class S60(USBMS):
|
||||||
|
|
||||||
name = 'S60 driver'
|
name = 'S60 driver'
|
||||||
|
@ -2586,14 +2586,20 @@ class ITUNES(DriverBase):
|
|||||||
if metadata.series and self.settings().read_metadata:
|
if metadata.series and self.settings().read_metadata:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" using Series name as Genre")
|
self.log.info(" using Series name as Genre")
|
||||||
|
|
||||||
|
# Format the index as a sort key
|
||||||
|
index = metadata.series_index
|
||||||
|
integer = int(index)
|
||||||
|
fraction = index-integer
|
||||||
|
series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
|
||||||
if lb_added:
|
if lb_added:
|
||||||
lb_added.sort_name.set("%s %04f" % (metadata.series, metadata.series_index))
|
lb_added.sort_name.set("%s %s" % (metadata.series, series_index))
|
||||||
lb_added.genre.set(metadata.series)
|
lb_added.genre.set(metadata.series)
|
||||||
lb_added.episode_ID.set(metadata.series)
|
lb_added.episode_ID.set(metadata.series)
|
||||||
lb_added.episode_number.set(metadata.series_index)
|
lb_added.episode_number.set(metadata.series_index)
|
||||||
|
|
||||||
if db_added:
|
if db_added:
|
||||||
db_added.sort_name.set("%s %04f" % (metadata.series, metadata.series_index))
|
db_added.sort_name.set("%s %s" % (metadata.series, series_index))
|
||||||
db_added.genre.set(metadata.series)
|
db_added.genre.set(metadata.series)
|
||||||
db_added.episode_ID.set(metadata.series)
|
db_added.episode_ID.set(metadata.series)
|
||||||
db_added.episode_number.set(metadata.series_index)
|
db_added.episode_number.set(metadata.series_index)
|
||||||
@ -2658,8 +2664,13 @@ class ITUNES(DriverBase):
|
|||||||
if metadata.series and self.settings().read_metadata:
|
if metadata.series and self.settings().read_metadata:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" using Series name as Genre")
|
self.log.info(" using Series name as Genre")
|
||||||
|
# Format the index as a sort key
|
||||||
|
index = metadata.series_index
|
||||||
|
integer = int(index)
|
||||||
|
fraction = index-integer
|
||||||
|
series_index = '%04d%%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
|
||||||
if lb_added:
|
if lb_added:
|
||||||
lb_added.SortName = "%s %04f" % (metadata.series, metadata.series_index)
|
lb_added.SortName = "%s %s" % (metadata.series, series_index)
|
||||||
lb_added.Genre = metadata.series
|
lb_added.Genre = metadata.series
|
||||||
lb_added.EpisodeID = metadata.series
|
lb_added.EpisodeID = metadata.series
|
||||||
try:
|
try:
|
||||||
@ -2667,7 +2678,7 @@ class ITUNES(DriverBase):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if db_added:
|
if db_added:
|
||||||
db_added.SortName = "%s %04f" % (metadata.series, metadata.series_index)
|
db_added.SortName = "%s %s" % (metadata.series, series_index)
|
||||||
db_added.Genre = metadata.series
|
db_added.Genre = metadata.series
|
||||||
db_added.EpisodeID = metadata.series
|
db_added.EpisodeID = metadata.series
|
||||||
try:
|
try:
|
||||||
|
@ -10,10 +10,10 @@ from base64 import b64decode
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from calibre import prints, guess_type
|
from calibre import prints, guess_type, isbytestring
|
||||||
from calibre.devices.errors import DeviceError
|
from calibre.devices.errors import DeviceError
|
||||||
from calibre.devices.usbms.driver import debug_print
|
from calibre.devices.usbms.driver import debug_print
|
||||||
from calibre.constants import DEBUG
|
from calibre.constants import DEBUG, preferred_encoding
|
||||||
from calibre.ebooks.chardet import xml_to_unicode
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from calibre.ebooks.metadata import authors_to_string, title_sort
|
from calibre.ebooks.metadata import authors_to_string, title_sort
|
||||||
|
|
||||||
@ -473,6 +473,13 @@ class XMLCache(object):
|
|||||||
# if the case of a tie, and hope it is right.
|
# if the case of a tie, and hope it is right.
|
||||||
timestamp = os.path.getmtime(path)
|
timestamp = os.path.getmtime(path)
|
||||||
rec_date = record.get('date', None)
|
rec_date = record.get('date', None)
|
||||||
|
|
||||||
|
def clean(x):
|
||||||
|
if isbytestring(x):
|
||||||
|
x = x.decode(preferred_encoding, 'replace')
|
||||||
|
x.replace(u'\0', '')
|
||||||
|
return x
|
||||||
|
|
||||||
if not getattr(book, '_new_book', False): # book is not new
|
if not getattr(book, '_new_book', False): # book is not new
|
||||||
if strftime(timestamp, zone=time.gmtime) == rec_date:
|
if strftime(timestamp, zone=time.gmtime) == rec_date:
|
||||||
gtz_count += 1
|
gtz_count += 1
|
||||||
@ -486,19 +493,19 @@ class XMLCache(object):
|
|||||||
tz = time.gmtime
|
tz = time.gmtime
|
||||||
debug_print("Using GMT TZ for new book", book.lpath)
|
debug_print("Using GMT TZ for new book", book.lpath)
|
||||||
date = strftime(timestamp, zone=tz)
|
date = strftime(timestamp, zone=tz)
|
||||||
record.set('date', date)
|
record.set('date', clean(date))
|
||||||
|
|
||||||
record.set('size', str(os.stat(path).st_size))
|
record.set('size', clean(str(os.stat(path).st_size)))
|
||||||
title = book.title if book.title else _('Unknown')
|
title = book.title if book.title else _('Unknown')
|
||||||
record.set('title', title)
|
record.set('title', clean(title))
|
||||||
ts = book.title_sort
|
ts = book.title_sort
|
||||||
if not ts:
|
if not ts:
|
||||||
ts = title_sort(title)
|
ts = title_sort(title)
|
||||||
record.set('titleSorter', ts)
|
record.set('titleSorter', clean(ts))
|
||||||
if self.use_author_sort and book.author_sort is not None:
|
if self.use_author_sort and book.author_sort is not None:
|
||||||
record.set('author', book.author_sort)
|
record.set('author', clean(book.author_sort))
|
||||||
else:
|
else:
|
||||||
record.set('author', authors_to_string(book.authors))
|
record.set('author', clean(authors_to_string(book.authors)))
|
||||||
ext = os.path.splitext(path)[1]
|
ext = os.path.splitext(path)[1]
|
||||||
if ext:
|
if ext:
|
||||||
ext = ext[1:].lower()
|
ext = ext[1:].lower()
|
||||||
@ -506,7 +513,7 @@ class XMLCache(object):
|
|||||||
if mime is None:
|
if mime is None:
|
||||||
mime = guess_type('a.'+ext)[0]
|
mime = guess_type('a.'+ext)[0]
|
||||||
if mime is not None:
|
if mime is not None:
|
||||||
record.set('mime', mime)
|
record.set('mime', clean(mime))
|
||||||
if 'sourceid' not in record.attrib:
|
if 'sourceid' not in record.attrib:
|
||||||
record.set('sourceid', '1')
|
record.set('sourceid', '1')
|
||||||
if 'id' not in record.attrib:
|
if 'id' not in record.attrib:
|
||||||
|
@ -98,6 +98,9 @@ class LinuxScanner(object):
|
|||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
ans = set([])
|
ans = set([])
|
||||||
|
if not self.ok:
|
||||||
|
raise RuntimeError('DeviceScanner requires the /sys filesystem to work.')
|
||||||
|
|
||||||
for x in os.listdir(self.base):
|
for x in os.listdir(self.base):
|
||||||
base = os.path.join(self.base, x)
|
base = os.path.join(self.base, x)
|
||||||
ven = os.path.join(base, 'idVendor')
|
ven = os.path.join(base, 'idVendor')
|
||||||
@ -145,8 +148,6 @@ class DeviceScanner(object):
|
|||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
if isosx and osx_scanner is None:
|
if isosx and osx_scanner is None:
|
||||||
raise RuntimeError('The Python extension usbobserver must be available on OS X.')
|
raise RuntimeError('The Python extension usbobserver must be available on OS X.')
|
||||||
if islinux and not linux_scanner.ok:
|
|
||||||
raise RuntimeError('DeviceScanner requires the /sys filesystem to work.')
|
|
||||||
self.scanner = win_scanner if iswindows else osx_scanner if isosx else linux_scanner
|
self.scanner = win_scanner if iswindows else osx_scanner if isosx else linux_scanner
|
||||||
self.devices = []
|
self.devices = []
|
||||||
|
|
||||||
|
@ -732,7 +732,7 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
|
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
|
||||||
|
|
||||||
def get_main_ebook_dir(self):
|
def get_main_ebook_dir(self, for_upload=False):
|
||||||
return self.EBOOK_DIR_MAIN
|
return self.EBOOK_DIR_MAIN
|
||||||
|
|
||||||
def _sanity_check(self, on_card, files):
|
def _sanity_check(self, on_card, files):
|
||||||
@ -750,7 +750,7 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
path = os.path.join(self._card_b_prefix,
|
path = os.path.join(self._card_b_prefix,
|
||||||
*(self.EBOOK_DIR_CARD_B.split('/')))
|
*(self.EBOOK_DIR_CARD_B.split('/')))
|
||||||
else:
|
else:
|
||||||
candidates = self.get_main_ebook_dir()
|
candidates = self.get_main_ebook_dir(for_upload=True)
|
||||||
if isinstance(candidates, basestring):
|
if isinstance(candidates, basestring):
|
||||||
candidates = [candidates]
|
candidates = [candidates]
|
||||||
candidates = [
|
candidates = [
|
||||||
|
@ -28,7 +28,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QComboBox" name="opt_chapter_mark"/>
|
<widget class="QComboBox" name="opt_chapter_mark">
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="opt_remove_first_image">
|
<widget class="QCheckBox" name="opt_remove_first_image">
|
||||||
|
@ -43,6 +43,15 @@
|
|||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>500</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -10,9 +10,10 @@ from functools import partial
|
|||||||
|
|
||||||
from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \
|
from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \
|
||||||
QDate, QGroupBox, QVBoxLayout, QPlainTextEdit, QSizePolicy, \
|
QDate, QGroupBox, QVBoxLayout, QPlainTextEdit, QSizePolicy, \
|
||||||
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, SIGNAL
|
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, SIGNAL, \
|
||||||
|
QPushButton
|
||||||
|
|
||||||
from calibre.utils.date import qt_to_dt
|
from calibre.utils.date import qt_to_dt, now
|
||||||
from calibre.gui2.widgets import TagsLineEdit, EnComboBox
|
from calibre.gui2.widgets import TagsLineEdit, EnComboBox
|
||||||
from calibre.gui2 import UNDEFINED_QDATE
|
from calibre.gui2 import UNDEFINED_QDATE
|
||||||
from calibre.utils.config import tweaks
|
from calibre.utils.config import tweaks
|
||||||
@ -132,20 +133,30 @@ class DateEdit(QDateEdit):
|
|||||||
|
|
||||||
def focusInEvent(self, x):
|
def focusInEvent(self, x):
|
||||||
self.setSpecialValueText('')
|
self.setSpecialValueText('')
|
||||||
|
QDateEdit.focusInEvent(self, x)
|
||||||
|
|
||||||
def focusOutEvent(self, x):
|
def focusOutEvent(self, x):
|
||||||
self.setSpecialValueText(_('Undefined'))
|
self.setSpecialValueText(_('Undefined'))
|
||||||
|
QDateEdit.focusOutEvent(self, x)
|
||||||
|
|
||||||
|
def set_to_today(self):
|
||||||
|
self.setDate(now())
|
||||||
|
|
||||||
class DateTime(Base):
|
class DateTime(Base):
|
||||||
|
|
||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent),
|
cm = self.col_metadata
|
||||||
DateEdit(parent)]
|
self.widgets = [QLabel('&'+cm['name']+':', parent), DateEdit(parent),
|
||||||
|
QLabel(''), QPushButton(_('Set \'%s\' to today')%cm['name'], parent)]
|
||||||
w = self.widgets[1]
|
w = self.widgets[1]
|
||||||
w.setDisplayFormat('dd MMM yyyy')
|
format = cm['display'].get('date_format','')
|
||||||
|
if not format:
|
||||||
|
format = 'dd MMM yyyy'
|
||||||
|
w.setDisplayFormat(format)
|
||||||
w.setCalendarPopup(True)
|
w.setCalendarPopup(True)
|
||||||
w.setMinimumDate(UNDEFINED_QDATE)
|
w.setMinimumDate(UNDEFINED_QDATE)
|
||||||
w.setSpecialValueText(_('Undefined'))
|
w.setSpecialValueText(_('Undefined'))
|
||||||
|
self.widgets[3].clicked.connect(w.set_to_today)
|
||||||
|
|
||||||
def setter(self, val):
|
def setter(self, val):
|
||||||
if val is None:
|
if val is None:
|
||||||
|
@ -765,6 +765,7 @@ class DeviceMixin(object): # {{{
|
|||||||
self.book_details.reset_info()
|
self.book_details.reset_info()
|
||||||
self.location_view.setCurrentIndex(self.location_view.model().index(0))
|
self.location_view.setCurrentIndex(self.location_view.model().index(0))
|
||||||
self.refresh_ondevice_info (device_connected = False)
|
self.refresh_ondevice_info (device_connected = False)
|
||||||
|
self.tool_bar.device_status_changed(bool(connected))
|
||||||
|
|
||||||
def info_read(self, job):
|
def info_read(self, job):
|
||||||
'''
|
'''
|
||||||
|
@ -334,7 +334,6 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
|
|
||||||
def __init__(self, parent, library_view, server=None):
|
def __init__(self, parent, library_view, server=None):
|
||||||
ResizableDialog.__init__(self, parent)
|
ResizableDialog.__init__(self, parent)
|
||||||
self.ICON_SIZES = {0:QSize(48, 48), 1:QSize(32,32), 2:QSize(24,24)}
|
|
||||||
self._category_model = CategoryModel()
|
self._category_model = CategoryModel()
|
||||||
|
|
||||||
self.category_view.currentChanged = self.category_current_changed
|
self.category_view.currentChanged = self.category_current_changed
|
||||||
@ -389,10 +388,6 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
self.add_custcol_button.clicked.connect(self.add_custcol)
|
self.add_custcol_button.clicked.connect(self.add_custcol)
|
||||||
self.edit_custcol_button.clicked.connect(self.edit_custcol)
|
self.edit_custcol_button.clicked.connect(self.edit_custcol)
|
||||||
|
|
||||||
icons = config['toolbar_icon_size']
|
|
||||||
self.toolbar_button_size.setCurrentIndex(0 if icons == self.ICON_SIZES[0] else 1 if icons == self.ICON_SIZES[1] else 2)
|
|
||||||
self.show_toolbar_text.setChecked(config['show_text_in_toolbar'])
|
|
||||||
|
|
||||||
output_formats = sorted(available_output_formats())
|
output_formats = sorted(available_output_formats())
|
||||||
output_formats.remove('oeb')
|
output_formats.remove('oeb')
|
||||||
for f in output_formats:
|
for f in output_formats:
|
||||||
@ -845,8 +840,6 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
|
|
||||||
must_restart = self.apply_custom_column_changes()
|
must_restart = self.apply_custom_column_changes()
|
||||||
|
|
||||||
config['toolbar_icon_size'] = self.ICON_SIZES[self.toolbar_button_size.currentIndex()]
|
|
||||||
config['show_text_in_toolbar'] = bool(self.show_toolbar_text.isChecked())
|
|
||||||
config['separate_cover_flow'] = bool(self.separate_cover_flow.isChecked())
|
config['separate_cover_flow'] = bool(self.separate_cover_flow.isChecked())
|
||||||
config['disable_tray_notification'] = not self.systray_notifications.isChecked()
|
config['disable_tray_notification'] = not self.systray_notifications.isChecked()
|
||||||
p = {0:'normal', 1:'high', 2:'low'}[self.priority.currentIndex()]
|
p = {0:'normal', 1:'high', 2:'low'}[self.priority.currentIndex()]
|
||||||
|
@ -422,54 +422,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0" colspan="2">
|
<item row="10" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
|
||||||
<property name="title">
|
|
||||||
<string>Toolbar</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QComboBox" name="toolbar_button_size">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Large</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Medium</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Small</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Button size in toolbar</string>
|
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>toolbar_button_size</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="show_toolbar_text">
|
|
||||||
<property name="text">
|
|
||||||
<string>Show &text in toolbar buttons</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="0" colspan="2">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
@ -176,12 +176,6 @@ class ToolbarMixin(object): # {{{
|
|||||||
def show_help(self, *args):
|
def show_help(self, *args):
|
||||||
open_url(QUrl('http://calibre-ebook.com/user_manual'))
|
open_url(QUrl('http://calibre-ebook.com/user_manual'))
|
||||||
|
|
||||||
def read_toolbar_settings(self):
|
|
||||||
self.tool_bar.setIconSize(config['toolbar_icon_size'])
|
|
||||||
self.tool_bar.setToolButtonStyle(
|
|
||||||
Qt.ToolButtonTextUnderIcon if \
|
|
||||||
config['show_text_in_toolbar'] else \
|
|
||||||
Qt.ToolButtonIconOnly)
|
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
from PyQt4.Qt import QIcon, Qt, QWidget, QAction, QToolBar, QSize, QVariant, \
|
from PyQt4.Qt import QIcon, Qt, QWidget, QAction, QToolBar, QSize, QVariant, \
|
||||||
QAbstractListModel, QFont, QApplication, QPalette, pyqtSignal, QToolButton, \
|
QAbstractListModel, QFont, QApplication, QPalette, pyqtSignal, QToolButton, \
|
||||||
QModelIndex, QListView, QAbstractButton, QPainter, QPixmap, QColor, \
|
QModelIndex, QListView, QAbstractButton, QPainter, QPixmap, QColor, \
|
||||||
@ -13,41 +15,11 @@ from PyQt4.Qt import QIcon, Qt, QWidget, QAction, QToolBar, QSize, QVariant, \
|
|||||||
from calibre.constants import __appname__, filesystem_encoding
|
from calibre.constants import __appname__, filesystem_encoding
|
||||||
from calibre.gui2.search_box import SearchBox2, SavedSearchBox
|
from calibre.gui2.search_box import SearchBox2, SavedSearchBox
|
||||||
from calibre.gui2.throbber import ThrobbingButton
|
from calibre.gui2.throbber import ThrobbingButton
|
||||||
from calibre.gui2 import NONE
|
from calibre.gui2 import NONE, config
|
||||||
from calibre.gui2.widgets import ComboBoxWithHelp
|
from calibre.gui2.widgets import ComboBoxWithHelp
|
||||||
from calibre import human_readable
|
from calibre import human_readable
|
||||||
|
|
||||||
class ToolBar(QToolBar): # {{{
|
ICON_SIZE = 48
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
QToolBar.__init__(self, parent)
|
|
||||||
self.setContextMenuPolicy(Qt.PreventContextMenu)
|
|
||||||
self.setMovable(False)
|
|
||||||
self.setFloatable(False)
|
|
||||||
self.setOrientation(Qt.Horizontal)
|
|
||||||
self.setAllowedAreas(Qt.TopToolBarArea|Qt.BottomToolBarArea)
|
|
||||||
self.setIconSize(QSize(48, 48))
|
|
||||||
self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
|
||||||
|
|
||||||
def add_actions(self, *args):
|
|
||||||
self.left_space = QWidget(self)
|
|
||||||
self.left_space.setSizePolicy(QSizePolicy.Expanding,
|
|
||||||
QSizePolicy.Minimum)
|
|
||||||
self.addWidget(self.left_space)
|
|
||||||
for action in args:
|
|
||||||
if action is None:
|
|
||||||
self.addSeparator()
|
|
||||||
else:
|
|
||||||
self.addAction(action)
|
|
||||||
self.right_space = QWidget(self)
|
|
||||||
self.right_space.setSizePolicy(QSizePolicy.Expanding,
|
|
||||||
QSizePolicy.Minimum)
|
|
||||||
self.addWidget(self.right_space)
|
|
||||||
|
|
||||||
def contextMenuEvent(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
# Location View {{{
|
# Location View {{{
|
||||||
|
|
||||||
@ -191,14 +163,15 @@ class LocationView(QListView):
|
|||||||
self.setTabKeyNavigation(True)
|
self.setTabKeyNavigation(True)
|
||||||
self.setProperty("showDropIndicator", True)
|
self.setProperty("showDropIndicator", True)
|
||||||
self.setSelectionMode(self.SingleSelection)
|
self.setSelectionMode(self.SingleSelection)
|
||||||
self.setIconSize(QSize(40, 40))
|
self.setIconSize(QSize(ICON_SIZE, ICON_SIZE))
|
||||||
self.setMovement(self.Static)
|
self.setMovement(self.Static)
|
||||||
self.setFlow(self.LeftToRight)
|
self.setFlow(self.LeftToRight)
|
||||||
self.setGridSize(QSize(175, 90))
|
self.setGridSize(QSize(175, ICON_SIZE))
|
||||||
self.setViewMode(self.ListMode)
|
self.setViewMode(self.ListMode)
|
||||||
self.setWordWrap(True)
|
self.setWordWrap(True)
|
||||||
self.setObjectName("location_view")
|
self.setObjectName("location_view")
|
||||||
self.setMaximumHeight(74)
|
self.setMaximumSize(QSize(600, ICON_SIZE+16))
|
||||||
|
self.setMinimumWidth(400)
|
||||||
|
|
||||||
def eject_clicked(self, *args):
|
def eject_clicked(self, *args):
|
||||||
self.unmount_device.emit()
|
self.unmount_device.emit()
|
||||||
@ -207,6 +180,10 @@ class LocationView(QListView):
|
|||||||
self.model().count = new_count
|
self.model().count = new_count
|
||||||
self.model().reset()
|
self.model().reset()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def book_count(self):
|
||||||
|
return self.model().count
|
||||||
|
|
||||||
def current_changed(self, current, previous):
|
def current_changed(self, current, previous):
|
||||||
if current.isValid():
|
if current.isValid():
|
||||||
i = current.row()
|
i = current.row()
|
||||||
@ -248,12 +225,15 @@ class EjectButton(QAbstractButton):
|
|||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QAbstractButton.__init__(self, parent)
|
QAbstractButton.__init__(self, parent)
|
||||||
self.mouse_over = False
|
self.mouse_over = False
|
||||||
|
self.setMouseTracking(True)
|
||||||
|
|
||||||
def enterEvent(self, event):
|
def enterEvent(self, event):
|
||||||
self.mouse_over = True
|
self.mouse_over = True
|
||||||
|
QAbstractButton.enterEvent(self, event)
|
||||||
|
|
||||||
def leaveEvent(self, event):
|
def leaveEvent(self, event):
|
||||||
self.mouse_over = False
|
self.mouse_over = False
|
||||||
|
QAbstractButton.leaveEvent(self, event)
|
||||||
|
|
||||||
def paintEvent(self, event):
|
def paintEvent(self, event):
|
||||||
painter = QPainter(self)
|
painter = QPainter(self)
|
||||||
@ -344,33 +324,84 @@ class SearchBar(QWidget): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class LocationBar(ToolBar): # {{{
|
class ToolBar(QToolBar): # {{{
|
||||||
|
|
||||||
def __init__(self, actions, donate, location_view, parent=None):
|
def __init__(self, actions, donate, location_view, parent=None):
|
||||||
ToolBar.__init__(self, parent)
|
QToolBar.__init__(self, parent)
|
||||||
|
self.setContextMenuPolicy(Qt.PreventContextMenu)
|
||||||
for ac in actions:
|
self.setMovable(False)
|
||||||
self.addAction(ac)
|
self.setFloatable(False)
|
||||||
|
self.setOrientation(Qt.Horizontal)
|
||||||
self.addWidget(location_view)
|
self.setAllowedAreas(Qt.TopToolBarArea|Qt.BottomToolBarArea)
|
||||||
self.w = QWidget()
|
self.setIconSize(QSize(ICON_SIZE, ICON_SIZE))
|
||||||
self.w.setLayout(QVBoxLayout())
|
|
||||||
self.w.layout().addWidget(donate)
|
|
||||||
donate.setAutoRaise(True)
|
|
||||||
donate.setCursor(Qt.PointingHandCursor)
|
|
||||||
self.addWidget(self.w)
|
|
||||||
self.setIconSize(QSize(50, 50))
|
|
||||||
self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
|
||||||
|
|
||||||
def button_for_action(self, ac):
|
self.showing_device = False
|
||||||
b = QToolButton(self)
|
self.all_actions = actions
|
||||||
b.setDefaultAction(ac)
|
self.donate = donate
|
||||||
for x in ('ToolTip', 'StatusTip', 'WhatsThis'):
|
self.location_view = location_view
|
||||||
getattr(b, 'set'+x)(b.text())
|
self.d_widget = QWidget()
|
||||||
|
self.d_widget.setLayout(QVBoxLayout())
|
||||||
|
self.d_widget.layout().addWidget(donate)
|
||||||
|
donate.setAutoRaise(True)
|
||||||
|
donate.setCursor(Qt.PointingHandCursor)
|
||||||
|
self.build_bar()
|
||||||
|
|
||||||
|
def contextMenuEvent(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def device_status_changed(self, connected):
|
||||||
|
self.showing_device = connected
|
||||||
|
self.build_bar()
|
||||||
|
|
||||||
|
def build_bar(self):
|
||||||
|
order_field = 'device' if self.showing_device else 'normal'
|
||||||
|
o = attrgetter(order_field+'_order')
|
||||||
|
sepvals = [2] if self.showing_device else [1]
|
||||||
|
sepvals += [3]
|
||||||
|
actions = [x for x in self.all_actions if o(x) > -1]
|
||||||
|
actions.sort(cmp=lambda x,y : cmp(o(x), o(y)))
|
||||||
|
self.clear()
|
||||||
|
for x in actions:
|
||||||
|
self.addAction(x)
|
||||||
|
ch = self.widgetForAction(x)
|
||||||
|
ch.setCursor(Qt.PointingHandCursor)
|
||||||
|
ch.setAutoRaise(True)
|
||||||
|
|
||||||
|
if x.action_name == 'choose_library':
|
||||||
|
self.location_action = self.addWidget(self.location_view)
|
||||||
|
self.choose_action = x
|
||||||
|
if config['show_donate_button']:
|
||||||
|
self.addWidget(self.d_widget)
|
||||||
|
if x.action_name not in ('choose_library', 'help'):
|
||||||
|
ch.setPopupMode(ch.MenuButtonPopup)
|
||||||
|
|
||||||
|
|
||||||
|
for x in actions:
|
||||||
|
if x.separator_before in sepvals:
|
||||||
|
self.insertSeparator(x)
|
||||||
|
|
||||||
|
|
||||||
|
self.location_action.setVisible(self.showing_device)
|
||||||
|
self.choose_action.setVisible(not self.showing_device)
|
||||||
|
|
||||||
|
def count_changed(self, new_count):
|
||||||
|
text = _('%d books')%new_count
|
||||||
|
a = self.choose_action
|
||||||
|
a.setText(text)
|
||||||
|
|
||||||
|
def resizeEvent(self, ev):
|
||||||
|
style = Qt.ToolButtonTextUnderIcon
|
||||||
|
if self.size().width() < 1260:
|
||||||
|
style = Qt.ToolButtonIconOnly
|
||||||
|
self.setToolButtonStyle(style)
|
||||||
|
QToolBar.resizeEvent(self, ev)
|
||||||
|
|
||||||
return b
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
class Action(QAction):
|
||||||
|
pass
|
||||||
|
|
||||||
class MainWindowMixin(object):
|
class MainWindowMixin(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -385,12 +416,19 @@ class MainWindowMixin(object):
|
|||||||
self.centralwidget.setLayout(self._central_widget_layout)
|
self.centralwidget.setLayout(self._central_widget_layout)
|
||||||
self.resize(1012, 740)
|
self.resize(1012, 740)
|
||||||
self.donate_button = ThrobbingButton(self.centralwidget)
|
self.donate_button = ThrobbingButton(self.centralwidget)
|
||||||
self.donate_button.set_normal_icon_size(64, 64)
|
self.donate_button.set_normal_icon_size(ICON_SIZE, ICON_SIZE)
|
||||||
|
|
||||||
# Actions {{{
|
# Actions {{{
|
||||||
|
|
||||||
def ac(name, text, icon, shortcut=None, tooltip=None):
|
all_actions = []
|
||||||
action = QAction(QIcon(I(icon)), text, self)
|
|
||||||
|
def ac(normal_order, device_order, separator_before,
|
||||||
|
name, text, icon, shortcut=None, tooltip=None):
|
||||||
|
action = Action(QIcon(I(icon)), text, self)
|
||||||
|
action.normal_order = normal_order
|
||||||
|
action.device_order = device_order
|
||||||
|
action.separator_before = separator_before
|
||||||
|
action.action_name = name
|
||||||
text = tooltip if tooltip else text
|
text = tooltip if tooltip else text
|
||||||
action.setToolTip(text)
|
action.setToolTip(text)
|
||||||
action.setStatusTip(text)
|
action.setStatusTip(text)
|
||||||
@ -400,56 +438,46 @@ class MainWindowMixin(object):
|
|||||||
if shortcut:
|
if shortcut:
|
||||||
action.setShortcut(shortcut)
|
action.setShortcut(shortcut)
|
||||||
setattr(self, 'action_'+name, action)
|
setattr(self, 'action_'+name, action)
|
||||||
|
all_actions.append(action)
|
||||||
|
|
||||||
ac('add', _('Add books'), 'add_book.svg', _('A'))
|
ac(0, 7, 0, 'add', _('Add books'), 'add_book.svg', _('A'))
|
||||||
ac('del', _('Remove books'), 'trash.svg', _('Del'))
|
ac(1, 1, 0, 'edit', _('Edit metadata'), 'edit_input.svg', _('E'))
|
||||||
ac('edit', _('Edit meta info'), 'edit_input.svg', _('E'))
|
ac(2, 2, 3, 'convert', _('Convert books'), 'convert.svg', _('C'))
|
||||||
ac('merge', _('Merge book records'), 'merge_books.svg', _('M'))
|
ac(3, 3, 0, 'view', _('View'), 'view.svg', _('V'))
|
||||||
ac('sync', _('Send to device'), 'sync.svg')
|
ac(4, 4, 3, 'choose_library', _('%d books')%0, 'lt.png',
|
||||||
ac('save', _('Save to disk'), 'save.svg', _('S'))
|
tooltip=_('Choose calibre library to work with'))
|
||||||
ac('news', _('Fetch news'), 'news.svg', _('F'))
|
ac(5, 5, 3, 'news', _('Fetch news'), 'news.svg', _('F'))
|
||||||
ac('convert', _('Convert books'), 'convert.svg', _('C'))
|
ac(6, 6, 0, 'save', _('Save to disk'), 'save.svg', _('S'))
|
||||||
ac('view', _('View'), 'view.svg', _('V'))
|
ac(7, 0, 0, 'sync', _('Send to device'), 'sync.svg')
|
||||||
ac('open_containing_folder', _('Open containing folder'),
|
ac(8, 8, 3, 'del', _('Remove books'), 'trash.svg', _('Del'))
|
||||||
|
ac(9, 9, 3, 'help', _('Help'), 'help.svg', _('F1'), _("Browse the calibre User Manual"))
|
||||||
|
ac(10, 10, 0, 'preferences', _('Preferences'), 'config.svg', _('Ctrl+P'))
|
||||||
|
|
||||||
|
ac(-1, -1, 0, 'merge', _('Merge book records'), 'merge_books.svg', _('M'))
|
||||||
|
ac(-1, -1, 0, 'open_containing_folder', _('Open containing folder'),
|
||||||
'document_open.svg')
|
'document_open.svg')
|
||||||
ac('show_book_details', _('Show book details'),
|
ac(-1, -1, 0, 'show_book_details', _('Show book details'),
|
||||||
'dialog_information.svg')
|
'dialog_information.svg')
|
||||||
ac('books_by_same_author', _('Books by same author'),
|
ac(-1, -1, 0, 'books_by_same_author', _('Books by same author'),
|
||||||
'user_profile.svg')
|
'user_profile.svg')
|
||||||
ac('books_in_this_series', _('Books in this series'),
|
ac(-1, -1, 0, 'books_in_this_series', _('Books in this series'),
|
||||||
'books_in_series.svg')
|
'books_in_series.svg')
|
||||||
ac('books_by_this_publisher', _('Books by this publisher'),
|
ac(-1, -1, 0, 'books_by_this_publisher', _('Books by this publisher'),
|
||||||
'publisher.png')
|
'publisher.png')
|
||||||
ac('books_with_the_same_tags', _('Books with the same tags'),
|
ac(-1, -1, 0, 'books_with_the_same_tags', _('Books with the same tags'),
|
||||||
'tags.svg')
|
'tags.svg')
|
||||||
ac('preferences', _('Preferences'), 'config.svg', _('Ctrl+P'))
|
|
||||||
ac('help', _('Help'), 'help.svg', _('F1'), _("Browse the calibre User Manual"))
|
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
self.tool_bar = ToolBar(self)
|
|
||||||
self.addToolBar(Qt.BottomToolBarArea, self.tool_bar)
|
|
||||||
self.tool_bar.add_actions(self.action_convert, self.action_view,
|
|
||||||
None, self.action_edit, None,
|
|
||||||
self.action_save, self.action_del,
|
|
||||||
None,
|
|
||||||
self.action_help, None, self.action_preferences)
|
|
||||||
|
|
||||||
self.location_view = LocationView(self.centralwidget)
|
self.location_view = LocationView(self.centralwidget)
|
||||||
self.search_bar = SearchBar(self)
|
self.search_bar = SearchBar(self)
|
||||||
self.location_bar = LocationBar([self.action_add, self.action_sync,
|
self.tool_bar = ToolBar(all_actions, self.donate_button, self.location_view, self)
|
||||||
self.action_news], self.donate_button, self.location_view, self)
|
self.addToolBar(Qt.TopToolBarArea, self.tool_bar)
|
||||||
self.addToolBar(Qt.TopToolBarArea, self.location_bar)
|
|
||||||
|
|
||||||
l = self.centralwidget.layout()
|
l = self.centralwidget.layout()
|
||||||
l.addWidget(self.search_bar)
|
l.addWidget(self.search_bar)
|
||||||
|
|
||||||
for ch in list(self.tool_bar.children()) + list(self.location_bar.children()):
|
|
||||||
if isinstance(ch, QToolButton):
|
|
||||||
ch.setCursor(Qt.PointingHandCursor)
|
|
||||||
ch.setAutoRaise(True)
|
|
||||||
if ch is not self.donate_button:
|
|
||||||
ch.setPopupMode(ch.MenuButtonPopup)
|
|
||||||
|
|
||||||
|
|
||||||
|
def read_toolbar_settings(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class DateDelegate(QStyledItemDelegate): # {{{
|
|||||||
|
|
||||||
def displayText(self, val, locale):
|
def displayText(self, val, locale):
|
||||||
d = val.toDate()
|
d = val.toDate()
|
||||||
if d == UNDEFINED_QDATE:
|
if d <= UNDEFINED_QDATE:
|
||||||
return ''
|
return ''
|
||||||
return format_date(d.toPyDate(), 'dd MMM yyyy')
|
return format_date(d.toPyDate(), 'dd MMM yyyy')
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class PubDateDelegate(QStyledItemDelegate): # {{{
|
|||||||
|
|
||||||
def displayText(self, val, locale):
|
def displayText(self, val, locale):
|
||||||
d = val.toDate()
|
d = val.toDate()
|
||||||
if d == UNDEFINED_QDATE:
|
if d <= UNDEFINED_QDATE:
|
||||||
return ''
|
return ''
|
||||||
format = tweaks['gui_pubdate_display_format']
|
format = tweaks['gui_pubdate_display_format']
|
||||||
if format is None:
|
if format is None:
|
||||||
@ -194,7 +194,7 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
|
|||||||
|
|
||||||
def displayText(self, val, locale):
|
def displayText(self, val, locale):
|
||||||
d = val.toDate()
|
d = val.toDate()
|
||||||
if d == UNDEFINED_QDATE:
|
if d <= UNDEFINED_QDATE:
|
||||||
return ''
|
return ''
|
||||||
return format_date(d.toPyDate(), self.format)
|
return format_date(d.toPyDate(), self.format)
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
|
|||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
def setModelData(self, editor, model, index):
|
||||||
val = editor.date()
|
val = editor.date()
|
||||||
if val == UNDEFINED_QDATE:
|
if val <= UNDEFINED_QDATE:
|
||||||
val = None
|
val = None
|
||||||
model.setData(index, QVariant(val), Qt.EditRole)
|
model.setData(index, QVariant(val), Qt.EditRole)
|
||||||
|
|
||||||
|
@ -1216,7 +1216,9 @@ class DeviceBooksModel(BooksModel): # {{{
|
|||||||
return done
|
return done
|
||||||
|
|
||||||
def set_editable(self, editable):
|
def set_editable(self, editable):
|
||||||
self.editable = editable
|
# Cannot edit if metadata is sent on connect. Reason: changes will
|
||||||
|
# revert to what is in the library on next connect.
|
||||||
|
self.editable = editable and prefs['manage_device_metadata']!='on_connect'
|
||||||
|
|
||||||
def set_search_restriction(self, s):
|
def set_search_restriction(self, s):
|
||||||
pass
|
pass
|
||||||
|
@ -13,6 +13,7 @@ class SearchRestrictionMixin(object):
|
|||||||
self.search_restriction.setSizeAdjustPolicy(self.search_restriction.AdjustToMinimumContentsLengthWithIcon)
|
self.search_restriction.setSizeAdjustPolicy(self.search_restriction.AdjustToMinimumContentsLengthWithIcon)
|
||||||
self.search_restriction.setMinimumContentsLength(10)
|
self.search_restriction.setMinimumContentsLength(10)
|
||||||
self.search_restriction.setStatusTip(self.search_restriction.toolTip())
|
self.search_restriction.setStatusTip(self.search_restriction.toolTip())
|
||||||
|
self.search_count.setText(_("(all books)"))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Adding and deleting books while restricted creates a complexity. When added,
|
Adding and deleting books while restricted creates a complexity. When added,
|
||||||
|
@ -167,8 +167,6 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, ToolbarMixin, # {{{
|
|||||||
self.eject_action = self.system_tray_menu.addAction(
|
self.eject_action = self.system_tray_menu.addAction(
|
||||||
QIcon(I('eject.svg')), _('&Eject connected device'))
|
QIcon(I('eject.svg')), _('&Eject connected device'))
|
||||||
self.eject_action.setEnabled(False)
|
self.eject_action.setEnabled(False)
|
||||||
if not config['show_donate_button']:
|
|
||||||
self.donate_button.setVisible(False)
|
|
||||||
self.addAction(self.quit_action)
|
self.addAction(self.quit_action)
|
||||||
self.action_restart = QAction(_('&Restart'), self)
|
self.action_restart = QAction(_('&Restart'), self)
|
||||||
self.addAction(self.action_restart)
|
self.addAction(self.action_restart)
|
||||||
@ -220,8 +218,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, ToolbarMixin, # {{{
|
|||||||
|
|
||||||
if self.system_tray_icon.isVisible() and opts.start_in_tray:
|
if self.system_tray_icon.isVisible() and opts.start_in_tray:
|
||||||
self.hide_windows()
|
self.hide_windows()
|
||||||
|
for t in (self.location_view, self.tool_bar):
|
||||||
self.library_view.model().count_changed_signal.connect \
|
self.library_view.model().count_changed_signal.connect \
|
||||||
(self.location_view.count_changed)
|
(t.count_changed)
|
||||||
if not gprefs.get('quick_start_guide_added', False):
|
if not gprefs.get('quick_start_guide_added', False):
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
mi = MetaInformation(_('Calibre Quick Start Guide'), ['John Schember'])
|
mi = MetaInformation(_('Calibre Quick Start Guide'), ['John Schember'])
|
||||||
@ -274,8 +273,6 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, ToolbarMixin, # {{{
|
|||||||
SIGNAL('start_recipe_fetch(PyQt_PyObject)'),
|
SIGNAL('start_recipe_fetch(PyQt_PyObject)'),
|
||||||
self.download_scheduled_recipe, Qt.QueuedConnection)
|
self.download_scheduled_recipe, Qt.QueuedConnection)
|
||||||
|
|
||||||
self.location_view.setCurrentIndex(self.location_view.model().index(0))
|
|
||||||
|
|
||||||
self.keyboard_interrupt.connect(self.quit, type=Qt.QueuedConnection)
|
self.keyboard_interrupt.connect(self.quit, type=Qt.QueuedConnection)
|
||||||
AddAction.__init__(self)
|
AddAction.__init__(self)
|
||||||
|
|
||||||
|
@ -209,13 +209,13 @@ class ResultCache(SearchQueryParser):
|
|||||||
if query == 'false':
|
if query == 'false':
|
||||||
for item in self._data:
|
for item in self._data:
|
||||||
if item is None: continue
|
if item is None: continue
|
||||||
if item[loc] is None or item[loc] == UNDEFINED_DATE:
|
if item[loc] is None or item[loc] <= UNDEFINED_DATE:
|
||||||
matches.add(item[0])
|
matches.add(item[0])
|
||||||
return matches
|
return matches
|
||||||
if query == 'true':
|
if query == 'true':
|
||||||
for item in self._data:
|
for item in self._data:
|
||||||
if item is None: continue
|
if item is None: continue
|
||||||
if item[loc] is not None and item[loc] != UNDEFINED_DATE:
|
if item[loc] is not None and item[loc] > UNDEFINED_DATE:
|
||||||
matches.add(item[0])
|
matches.add(item[0])
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Greg Riker <griker at hotmail.com>'
|
__copyright__ = '2010, Greg Riker <griker at hotmail.com>'
|
||||||
|
|
||||||
import datetime, htmlentitydefs, os, re, shutil
|
import datetime, htmlentitydefs, os, re, shutil, codecs
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
@ -96,17 +96,20 @@ class CSV_XML(CatalogPlugin):
|
|||||||
fields = self.get_output_fields(opts)
|
fields = self.get_output_fields(opts)
|
||||||
|
|
||||||
if self.fmt == 'csv':
|
if self.fmt == 'csv':
|
||||||
outfile = open(path_to_output, 'w')
|
outfile = codecs.open(path_to_output, 'w', 'utf8')
|
||||||
|
|
||||||
# Output the field headers
|
# Output the field headers
|
||||||
outfile.write(u'%s\n' % u','.join(fields))
|
outfile.write(u'%s\n' % u','.join(fields))
|
||||||
|
|
||||||
# Output the entry fields
|
# Output the entry fields
|
||||||
for entry in data:
|
for entry in data:
|
||||||
outstr = ''
|
outstr = []
|
||||||
for (x, field) in enumerate(fields):
|
for field in fields:
|
||||||
item = entry[field]
|
item = entry[field]
|
||||||
if field == 'formats':
|
if item is None:
|
||||||
|
outstr.append('""')
|
||||||
|
continue
|
||||||
|
elif field == 'formats':
|
||||||
fmt_list = []
|
fmt_list = []
|
||||||
for format in item:
|
for format in item:
|
||||||
fmt_list.append(format.rpartition('.')[2].lower())
|
fmt_list.append(format.rpartition('.')[2].lower())
|
||||||
@ -118,19 +121,13 @@ class CSV_XML(CatalogPlugin):
|
|||||||
item = u'%s' % re.sub(r'[\D]', '', item)
|
item = u'%s' % re.sub(r'[\D]', '', item)
|
||||||
elif field in ['pubdate', 'timestamp']:
|
elif field in ['pubdate', 'timestamp']:
|
||||||
item = isoformat(item)
|
item = isoformat(item)
|
||||||
|
elif field == 'comments':
|
||||||
|
item = item.replace(u'\r\n',u' ')
|
||||||
|
item = item.replace(u'\n',u' ')
|
||||||
|
|
||||||
#Format the line
|
outstr.append(u'"%s"' % unicode(item).replace('"','""'))
|
||||||
if x < len(fields) - 1:
|
|
||||||
if item is not None:
|
outfile.write(u','.join(outstr) + u'\n')
|
||||||
outstr += u'"%s",' % unicode(item).replace('"','""')
|
|
||||||
else:
|
|
||||||
outstr += '"",'
|
|
||||||
else:
|
|
||||||
if item is not None:
|
|
||||||
outstr += u'"%s"\n' % unicode(item).replace('"','""')
|
|
||||||
else:
|
|
||||||
outstr += '""\n'
|
|
||||||
outfile.write(outstr.encode('utf-8'))
|
|
||||||
outfile.close()
|
outfile.close()
|
||||||
|
|
||||||
elif self.fmt == 'xml':
|
elif self.fmt == 'xml':
|
||||||
@ -269,7 +266,6 @@ class BIBTEX(CatalogPlugin):
|
|||||||
|
|
||||||
def run(self, path_to_output, opts, db, notification=DummyReporter()):
|
def run(self, path_to_output, opts, db, notification=DummyReporter()):
|
||||||
|
|
||||||
import codecs
|
|
||||||
from types import StringType, UnicodeType
|
from types import StringType, UnicodeType
|
||||||
|
|
||||||
from calibre.library.save_to_disk import preprocess_template
|
from calibre.library.save_to_disk import preprocess_template
|
||||||
|
Loading…
x
Reference in New Issue
Block a user