Subversion Repositories basico

Compare Revisions

Ignore whitespace Rev 12 → Rev 76

/tags/REL-0.2/basico/data/icons/notask.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/tags/REL-0.2/basico/data/icons/notask.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/delete.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/delete.png
===================================================================
--- REL-0.2/basico/data/icons/delete.png (nonexistent)
+++ REL-0.2/basico/data/icons/delete.png (revision 76)
/REL-0.2/basico/data/icons/delete.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/fingerprint.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/fingerprint.png
===================================================================
--- REL-0.2/basico/data/icons/fingerprint.png (nonexistent)
+++ REL-0.2/basico/data/icons/fingerprint.png (revision 76)
/REL-0.2/basico/data/icons/fingerprint.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/sapnote.svg
===================================================================
--- REL-0.2/basico/data/icons/sapnote.svg (nonexistent)
+++ REL-0.2/basico/data/icons/sapnote.svg (revision 76)
@@ -0,0 +1,393 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ 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"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+ width="48px"
+ height="48px"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="sapnote.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.1">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective85" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" />
+ <stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient6715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <linearGradient
+ id="linearGradient2994">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2996" />
+ <stop
+ style="stop-color:#c9c9c9;stop-opacity:1;"
+ offset="1"
+ id="stop2998" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2974">
+ <stop
+ style="stop-color:#c1c1c1;stop-opacity:1;"
+ offset="0"
+ id="stop2976" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="1"
+ id="stop2978" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2966">
+ <stop
+ style="stop-color:#ffd1d1;stop-opacity:1;"
+ offset="0"
+ id="stop2968" />
+ <stop
+ id="stop3006"
+ offset="0.5"
+ style="stop-color:#ff1d1d;stop-opacity:1;" />
+ <stop
+ style="stop-color:#6f0000;stop-opacity:1;"
+ offset="1"
+ id="stop2970" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2919">
+ <stop
+ style="stop-color:#a3a4a0;stop-opacity:1;"
+ offset="0"
+ id="stop2921" />
+ <stop
+ style="stop-color:#888a85;stop-opacity:1;"
+ offset="1"
+ id="stop2923" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2873">
+ <stop
+ style="stop-color:#939393;stop-opacity:1;"
+ offset="0"
+ id="stop2875" />
+ <stop
+ style="stop-color:#424242;stop-opacity:1;"
+ offset="1"
+ id="stop2877" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2865">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2867" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2869" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2855">
+ <stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="0"
+ id="stop2857" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop2859" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2855"
+ id="linearGradient2861"
+ x1="21.043484"
+ y1="42.83337"
+ x2="14.283642"
+ y2="6.8333683"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.137871,0.000000,0.000000,1.000000,-2.660884,0.000000)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2865"
+ id="radialGradient2871"
+ cx="23.5625"
+ cy="40.4375"
+ fx="23.5625"
+ fy="40.4375"
+ r="19.5625"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.348243,0.000000,26.35543)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2873"
+ id="linearGradient2879"
+ x1="26.612417"
+ y1="28.083368"
+ x2="26.228401"
+ y2="42.83337"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2919"
+ id="linearGradient2925"
+ x1="6"
+ y1="7.5624999"
+ x2="40.984375"
+ y2="7.5624999"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2865"
+ id="radialGradient3010"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.348243,1.439818e-16,26.35543)"
+ cx="23.5625"
+ cy="40.4375"
+ fx="23.5625"
+ fy="40.4375"
+ r="19.5625" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#c4a000"
+ fill="#edd400"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="14.928934"
+ inkscape:cy="27.682247"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1600"
+ inkscape:window-height="814"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:title></dc:title>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ transform="matrix(2.417561e-2,0,0,2.086758e-2,45.12765,40.1536)"
+ id="g6707">
+ <rect
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect6709"
+ width="1339.6335"
+ height="478.35718"
+ x="-1559.2523"
+ y="-150.69685" />
+ <path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ id="path6711"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path6713"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <path
+ style="color:#000000;fill:url(#linearGradient2861);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2879);stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 7.1638699,4.5063726 L 39.813122,4.5063726 C 40.575699,4.5063726 41.189615,5.0388241 41.189615,5.7002099 C 41.189615,5.7002099 43.590945,39.868907 43.590945,39.868907 C 43.590945,39.868907 43.603403,42.216529 43.603403,42.216529 C 43.603403,42.877915 42.989488,43.410366 42.226911,43.410366 L 4.750081,43.410366 C 3.9875042,43.410366 3.3735887,42.877915 3.3735887,42.216529 L 3.3624173,40.049613 L 5.7873775,5.7002099 C 5.7873775,5.0388241 6.4012931,4.5063726 7.1638699,4.5063726 z "
+ id="rect1975"
+ sodipodi:nodetypes="ccccccccccc" />
+ <path
+ transform="matrix(0.616613,0.000000,0.000000,0.440367,10.61425,13.94266)"
+ d="M 43.125 40.4375 A 19.5625 6.8125 0 1 1 4,40.4375 A 19.5625 6.8125 0 1 1 43.125 40.4375 z"
+ sodipodi:ry="6.8125"
+ sodipodi:rx="19.5625"
+ sodipodi:cy="40.4375"
+ sodipodi:cx="23.5625"
+ id="path3008"
+ style="opacity:0.31578944;color:#000000;fill:url(#radialGradient3010);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <rect
+ style="opacity:1;color:#000000;fill:#a4a4a4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect2851"
+ width="39.048077"
+ height="3.0714951"
+ x="3.9770372"
+ y="39.868271"
+ rx="0.67937863"
+ ry="0.67937863" />
+ <path
+ style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 3.9267507,40.442796 C 3.9267507,40.442796 4.0776125,39.912466 4.6307727,39.868272 L 42.195375,39.868272 C 42.949684,39.868272 42.999971,40.619573 42.999971,40.619573 C 42.999971,40.619573 43.02357,39 41.7161,39 L 5.3042159,39 C 4.2984702,39.088388 3.9267507,39.779883 3.9267507,40.442796 z "
+ id="path2853"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient2925);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 6.25,5.7343749 L 6,10.125 C 6,10.125 6.3125,8.9999999 7,8.9999999 L 40.125,8.9999999 C 40.828125,8.9843749 40.859375,9.3124999 40.984375,9.8281249 C 40.984375,9.8281249 40.734375,5.9531249 40.734375,5.9531249 C 40.703125,5.4062499 40.515625,4.9999999 39.953125,4.9999999 L 7.0625,4.9999999 C 6.609375,4.9999999 6.296875,5.3437499 6.25,5.7343749 z "
+ id="path2915"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccccccc"
+ id="path2917"
+ d="M 7.8126474,5.5404503 L 38.944983,5.5404503 C 39.66702,5.5404503 40.2483,5.3883462 40.2483,6.014572 C 40.2483,6.014572 42.521973,39.023077 42.521973,39.023077 C 42.521973,39.023077 42.622156,41.732033 42.622156,41.732033 C 42.622156,42.358259 42.48282,42.376269 41.760782,42.376269 L 4.8620444,42.376269 C 4.4493662,42.376269 4.4426114,42.269871 4.4426114,41.864615 L 4.4320338,39.194177 L 6.7280807,6.045822 C 6.7280807,5.4195962 7.09061,5.5404503 7.8126474,5.5404503 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.43859649" />
+ <g
+ id="g2941">
+ <rect
+ y="12"
+ x="9"
+ height="1"
+ width="29"
+ id="rect2927"
+ style="opacity:0.28070175;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect2929"
+ width="29"
+ height="1"
+ x="9"
+ y="14.981792" />
+ <rect
+ y="18.003939"
+ x="9"
+ height="1"
+ width="13"
+ id="rect2931"
+ style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect2933"
+ width="29"
+ height="1"
+ x="9"
+ y="22.985731" />
+ <rect
+ y="26.007877"
+ x="9"
+ height="1"
+ width="29"
+ id="rect2935"
+ style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <rect
+ style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect2937"
+ width="29"
+ height="1"
+ x="9"
+ y="29.030024" />
+ <rect
+ y="32.05217"
+ x="9"
+ height="1"
+ width="8"
+ id="rect2939"
+ style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ </g>
+</svg>
Index: REL-0.2/basico/data/icons/description.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/description.png
===================================================================
--- REL-0.2/basico/data/icons/description.png (nonexistent)
+++ REL-0.2/basico/data/icons/description.png (revision 76)
/REL-0.2/basico/data/icons/description.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/database.py
===================================================================
--- REL-0.2/basico/database.py (nonexistent)
+++ REL-0.2/basico/database.py (revision 76)
@@ -0,0 +1,391 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: database.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Database service
+
+import os
+from os.path import basename
+#~ import sys
+#~ import time
+import json
+import glob
+#~ import shutil
+#~ import traceback
+#~ from shutil import which
+from cgi import escape
+
+from .env import LPATH
+from .service import Service
+
+SEP = os.path.sep
+
+class Database(Service):
+ def initialize(self):
+ '''
+ Setup AppLogic Service
+ '''
+ self.sapnotes = {}
+ self.stats = {}
+ self.stats['maincomp'] = {}
+ self.stats['cats'] = {}
+ self.stats['component'] = set()
+ self.stats['category'] = set()
+ self.stats['priority'] = set()
+ self.stats['type'] = set()
+ self.stats['version'] = set()
+ #~ self.stats['releaseon'] = set()
+ #~ self.rebuild_from_dir()
+
+
+ def store(self, sapnote, html):
+ DB_DIR = self.get_var('DB', 'local')
+ FSAPNOTE = DB_DIR + sapnote + '.xml'
+
+ try:
+ f = open(FSAPNOTE, 'w')
+ f.write(html)
+ f.close()
+ self.log.debug("\tSAP Note %s stored in %s" % (sapnote, FSAPNOTE))
+ except Exception as error:
+ self.log.error(error)
+
+
+ def rebuild_from_dir(self, path=None):
+ db = self.get_service('DB')
+ DB_DIR = self.get_var('DB', 'local')
+
+ #~ FSAPNOTE = DB_DIR + sid + '.xml'
+ if path is None:
+ path = DB_DIR
+
+ files = glob.glob("%s%s*.xml" % (DB_DIR, SEP))
+ sap = self.app.get_service('SAP')
+ for filename in files:
+ self.log.debug("Filename: %s" % filename)
+ sid = basename(filename)[0:-4]
+ self.log.debug("SAP Note Id: %s" % sid)
+
+ valid = False
+ if db.is_stored(sid):
+ self.log.debug("\tSAP Note %s will be analyzed again" % sid)
+ content = db.get_sapnote_content(sid)
+ sapnote = sap.analyze_sapnote_metadata(sid, content)
+ if len(sapnote) > 0:
+ db = self.get_service('DB')
+ db.add(sapnote)
+ db.store(sid, content)
+ valid = True
+
+ cb =self.app.get_service('Callbacks')
+ cb.refresh_view()
+
+
+ def get_sapnote_content(self, sid):
+ DB_DIR = self.get_var('DB', 'local')
+ FSAPNOTE = DB_DIR + sid + '.xml'
+ content = open(FSAPNOTE, 'r').read()
+ return content
+
+
+ def is_stored(self, sid):
+ DB_DIR = self.get_var('DB', 'local')
+ fsapnote = DB_DIR + sid + '.xml'
+ stored = os.path.exists(fsapnote)
+ #~ self.log.debug("\tSAP Note %s stored in database? %s" % (sid, stored))
+
+ return stored
+
+
+ def build_stats(self, bag=None):
+ if bag is None:
+ bag = self.sapnotes
+ self.dstats = {}
+ self.compstats = {}
+ alltasks = set()
+
+ for sid in bag:
+ # tasks
+ try:
+ tasks = self.sapnotes[sid]['tasks']
+ for task in tasks:
+ alltasks.add(task)
+ except: pass
+ self.tasks = self.app.get_service('Tasks')
+ self.tasks.save_tasks_from_stats(alltasks)
+
+ # components
+ compkey = self.sapnotes[sid]['componentkey']
+ comptxt = self.sapnotes[sid]['componenttxt']
+ #~ self.log.debug("%s -> %s -> %s" % (sid, compkey, comptxt))
+ component = escape("%s (%s)" % (compkey, comptxt))
+ sep = compkey.find('-')
+ if sep > 0:
+ maincomp = compkey[0:sep]
+ else:
+ maincomp = compkey
+
+ # categories
+ category = escape(self.sapnotes[sid]['category'])
+ try:
+ cont = self.stats['cats'][category]
+ self.stats['cats'][category] = cont + 1
+ except:
+ self.stats['cats'][category] = 1
+
+ # Build all (sub)keys from given component key
+ # useful for display stats with pygal
+ compkeys = compkey.split('-')
+ total = len(compkeys)
+ key = ''
+ i = 0
+ for subkey in compkeys:
+ key = key + '-' + subkey
+ if key[:1] == '-':
+ key = key[1:]
+
+ # update stats
+ try:
+ count = self.compstats[key]
+ self.compstats[key] = count + 1
+ except Exception as error:
+ self.compstats[key] = 1
+
+ try:
+ cont = self.stats['maincomp'][maincomp]
+ self.stats['maincomp'][maincomp] = cont + 1
+ except:
+ self.stats['maincomp'][maincomp] = 1
+
+ category = escape(self.sapnotes[sid]['category'])
+ priority = escape(self.sapnotes[sid]['priority'])
+ ntype = escape(self.sapnotes[sid]['type'])
+ version = escape(self.sapnotes[sid]['version'])
+ releaseon = escape(self.sapnotes[sid]['releaseon'])
+ self.stats['component'].add(component)
+ self.stats['category'].add(category)
+ self.stats['priority'].add(priority)
+ self.stats['type'].add(ntype)
+ self.stats['version'].add(version)
+ #~ self.stats['releaseon'].add(releaseon)
+ #~ self.stats[''].add(version)
+ #~ self.log.debug(self.compstats)
+ #~ self.log.debug("==")
+ #~ self.log.debug(self.stats)
+ #~ self.log.debug(self.stats['maincomp'])
+
+
+ def get_stats(self):
+ return self.stats
+
+
+ def add(self, sapnote):
+ sid = sapnote['id']
+ self.sapnotes[sid] = sapnote
+
+
+ def add_list(self, sapnotes):
+ for sapnote in sapnotes:
+ sid = sapnote['id']
+ self.sapnotes[sid] = sapnote
+
+
+ def get_notes(self):
+ '''
+ Return all sapnotes
+ '''
+ return self.sapnotes
+
+
+ def get_total(self):
+ '''
+ Return total sapnotes
+ '''
+ return len(self.sapnotes)
+
+
+ def load_notes(self):
+ '''
+ If notes.json exists, load notes
+ '''
+ try:
+ fnotes = self.get_file('SAP')
+ with open(fnotes, 'r') as fp:
+ self.sapnotes = json.load(fp)
+ self.log.debug ("Loaded %d notes" % len(self.sapnotes))
+ except Exception as error:
+ self.log.info("SAP Notes database not found. Creating a new one")
+ self.save_notes()
+
+
+ def get_sapnote_metadata(self, sid):
+ try:
+ return self.sapnotes[sid]
+ except KeyError as error:
+ self.log.warning("SAP Note %s doesn't exist in the database" % sid)
+ return None
+
+ #~ def save_notes(self, filename='', bag={}):
+ #~ '''
+ #~ Save SAP Notes to file
+ #~ '''
+ #~ if len(filename) == 0:
+ #~ filename = self.get_file('SAP')
+ #~ bag = self.sapnotes
+
+ #~ fnotes = open(filename, 'w')
+ #~ json.dump(bag, fnotes)
+ #~ fnotes.close()
+ #~ self.log.info ("Saved %d notes to %s" % (len(bag), filename))
+
+
+ def save_notes(self, bag={}, export_path=None):
+ '''
+ Save SAP Notes to json database file
+ '''
+ if export_path is None:
+ export_path = self.get_file('SAP')
+
+ if len(bag) == 0:
+ bag = self.get_notes()
+
+ fdb = open(export_path, 'w')
+ json.dump(bag, fdb)
+ fdb.close()
+ self.log.info ("Saved %d notes to %s" % (len(bag), export_path))
+
+
+ def export(self, bag, export_path=None):
+ pass
+
+
+ def export_basico_package(self, bag, target):
+ self.save_notes(bag, target)
+ #~ TMP_DIR = LPATH['TMP']
+ #~ PKG_DIR = TMP_DIR + 'basico'
+ #~ BCO_SAPNOTES = PKG_DIR + SEP + 'sapnotes.json'
+ #~ TARGET = export_path + SEP + '.bco'
+
+ # 0 Delete temporary package dir
+ #~ try:
+ #~ shutil.rmtree(PKG_DIR)
+ #~ self.log.debug("Temporary package dir deleted: '%s'" % PKG_DIR)
+ #~ except: pass
+
+ # 1 Create temporary dir for building a basico package
+ #~ os.mkdir(PKG_DIR)
+ #~ self.log.debug("Temporary package dir created: '%s'" % PKG_DIR)
+
+ # 2 Export selected SAP Notes to basico package directory
+ #~ self.save_notes(bag, BCO_SAPNOTES)
+
+ # 3 Create Basico Package
+ #~ utils = self.get_service('Utils')
+ #~ utils.zip('basico_package', PKG_DIR)
+
+ # 4 Delete temporary dir
+ #~ shutil.rmtree(PKG_DIR)
+ #~ self.log.debug("Temporary package dir deleted: '%s'" % PKG_DIR)
+
+
+ def get_property_count(self, prop):
+ found = 0
+
+ store = self.get_notes()
+ for sid in store:
+ try:
+ store[sid][prop]
+ found += 1
+ except:
+ pass
+
+ return found
+
+
+ def get_linked_projects(self, sapnote):
+ try:
+ projects = self.sapnotes[sapnote]['projects']
+ except Exception as error:
+ projects = []
+
+ return projects
+
+
+ def get_linked_tasks(self, sapnote):
+ try:
+ tasks = self.sapnotes[sapnote]['tasks']
+ except Exception as error:
+ tasks = []
+ self.log.debug("Tasks: %s" % tasks)
+ return tasks
+
+
+ def link_to_task(self, sapnotes, tasks):
+ for sapnote in sapnotes:
+ try:
+ self.sapnotes[sapnote]['tasks'] = tasks
+ self.log.info("Linked SAP Note %s to task(s): %s" % (sapnote, tasks) )
+ except:
+ self.log.error(self.get_traceback())
+
+
+ def import_sapnotes(self, bag):
+ for sid in bag:
+ # Check if SAP Note exists in main database
+ found = self.get_sapnote_metadata(sid)
+ if found is None:
+ self.sapnotes[sid] = bag[sid]
+ else:
+ # Import only tasks
+ try:
+ imptasks = bag[sid]['tasks']
+ tasks = self.sapnotes[sid]['tasks']
+ tasks.extend(imptasks)
+ self.sapnotes[sid]['tasks'] = tasks
+ except Exception as error:
+ self.log.error(error)
+ pass
+ # Import other metadata
+
+
+ def set_bookmark(self, sapnotes):
+ for sapnote in sapnotes:
+ self.log.info("SAP Note %s bookmarked: True" % sapnote)
+ self.sapnotes[sapnote]['bookmark'] = True
+ self.save_notes()
+
+
+ def set_no_bookmark(self, sapnotes):
+ for sapnote in sapnotes:
+ self.log.info("SAP Note %s bookmarked: False" % sapnote)
+ self.sapnotes[sapnote]['bookmark'] = False
+ self.save_notes()
+
+
+ def is_bookmark(self, sapnote):
+ try:
+ return self.sapnotes[sapnote]['bookmark']
+ except:
+ return False
+
+
+ def delete(self, sapnote):
+ deleted = False
+ try:
+ del (self.sapnotes[sapnote])
+ deleted = True
+ except:
+ deleted = False
+
+ return deleted
+
+
+ def run(self):
+ self.load_notes()
+ self.build_stats()
+
+
+ def end(self):
+ self.save_notes()
+
Index: REL-0.2/basico/callbacks.py
===================================================================
--- REL-0.2/basico/callbacks.py (nonexistent)
+++ REL-0.2/basico/callbacks.py (revision 76)
@@ -0,0 +1,745 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: callbacks.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: UI and related callbacks service
+
+import os
+import csv
+import json
+import time
+import glob
+from os.path import basename
+from datetime import datetime
+
+import gi
+gi.require_version('Gtk', '3.0')
+gi.require_version('WebKit', '3.0')
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository.GdkPixbuf import Pixbuf
+from gi.repository import WebKit
+
+from concurrent.futures import ThreadPoolExecutor as Executor
+
+from .service import Service
+
+SEP = os.path.sep
+
+# PROPKEYS = CSV headers. SAP Note metadata
+PROPKEYS = ['id', 'title', 'type', 'componentkey',
+ 'componenttxt', 'category', 'priority', 'releaseon',
+ 'language', 'version']
+
+# Extend PROPKEYS with custom basico metadata
+PROPKEYS.extend (['Tasks', 'Bookmark'])
+
+class Callback(Service):
+ def initialize(self):
+ self.get_services()
+
+ def get_services(self):
+ self.gui = self.app.get_service('GUI')
+ self.uif = self.app.get_service("UIF")
+ self.sap = self.app.get_service('SAP')
+ self.tasks = self.app.get_service('Tasks')
+ self.alert = self.app.get_service('Notify')
+ #~ self.stats = self.app.get_service('Stats')
+ self.utils = self.app.get_service('Utils')
+
+ def execute_action(self, *args):
+ action = args[0]
+ action_name = action.get_name()
+ try:
+ callback = "self.%s()" % action_name.replace('-', '_')
+ return eval(callback)
+ except Exception as error:
+ self.log.error(error)
+ self.log.error("Callback for action '%s' not registered" % action_name)
+ raise
+
+
+ def actions_browse(self, *args):
+ SAP_NOTE_URL = self.sap.get_config_value('CNF_SAP_NOTE_URL')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ lurl = []
+ for sid in sapnotes:
+ url = SAP_NOTE_URL % sid
+ lurl.append(url)
+ self.log.debug("Browsing SAP Note %s" % sid)
+ self.utils.browse(lurl)
+
+
+ def actions_other_delete(self, *args):
+ db = self.get_service('DB')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ sapnotes.sort()
+ winroot = self.gui.get_widget('mainwinow')
+
+ dialog = Gtk.MessageDialog(winroot, 0, Gtk.MessageType.WARNING,
+ Gtk.ButtonsType.OK_CANCEL, "Are you sure?")
+ dialog.set_title("Deleting SAP Notes...")
+ dialog.set_modal(True)
+ dialog.set_transient_for(winroot)
+ dialog.format_secondary_text(
+ "These SAP Notes will be deleted:\n%s" % ', '.join(sapnotes))
+
+ response = dialog.run()
+ if response == Gtk.ResponseType.OK:
+ db = self.get_service('DB')
+ sapnotes = sapnoteview.get_selected_notes()
+ for sapnote in sapnotes:
+ db.delete(sapnote)
+ self.search_notes()
+ self.refresh_view()
+ self.alert.show('Delete', 'Selected SAP Notes deleted', 'information')
+ self.log.info("Selected SAP Notes deleted")
+ db.save_notes()
+ elif response == Gtk.ResponseType.CANCEL:
+ self.alert.show('Delete', 'Delete action canceled by user', 'warning')
+ self.log.info("Delete action canceled by user")
+
+ dialog.destroy()
+
+ return response
+
+
+ def show_properties(self, *args):
+ notebook = self.gui.get_widget('ntbOperations')
+ toggle = self.gui.get_widget('tgbShowManage')
+ notebook.set_current_page(0)
+ toggle.set_active(True)
+
+
+ def actions_manage_tasks(self, *args):
+ #~ sapnoteview = self.gui.get_widget('sapnoteview')
+ #~ try:
+ #~ sapnotes = sapnoteview.get_selected_notes()
+ #~ except:
+ #~ sapnote = ''
+ self.tasks.show_window(active=True)
+
+
+ def link_tasks_to_sapnotes(self, *args):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ tasks = self.tasks.get_selected()
+ self.sap.link_to_task(sapnotes, tasks)
+
+ def actions_bookmark(self, *args):
+ db = self.get_service('DB')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ self.log.debug("Action bookmark triggered for SAP Notes: %s" % sapnotes)
+ view = sapnoteview.get_view()
+ self.sap.set_bookmark(sapnotes)
+ db.save_notes()
+ self.refresh_view(view=view)
+ self.alert.show('Bookmarks', 'Selected SAP Notes bookmarked', 'information')
+
+
+ def actions_unbookmark(self, *args):
+ db = self.get_service('DB')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ self.log.debug("Action unbookmark triggered for SAP Notes: %s" % sapnotes)
+ self.sap.set_no_bookmark(sapnotes)
+ db.save_notes()
+ self.refresh_view(view='bookmarks')
+ self.alert.show('Bookmarks', 'Selected SAP Notes unbookmarked', 'information')
+
+
+ def actions_export_csv(self, *args):
+ db = self.get_service('DB')
+ rootwin = self.gui.get_widget('mainwndow')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ dialog = Gtk.FileChooserDialog("Save file", rootwin,
+ Gtk.FileChooserAction.SAVE,
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
+ response = dialog.run()
+
+ if response == Gtk.ResponseType.OK:
+ export_path = dialog.get_filename()
+ writer = csv.writer(open(export_path, 'w'), delimiter=';', quoting=csv.QUOTE_ALL)
+ csvrow = []
+
+ for key in PROPKEYS:
+ csvrow.append(key.capitalize())
+ writer.writerow(csvrow)
+
+ for tid in sapnotes:
+ sid = "0"*(10 - len(tid)) + tid
+ self.log.debug("Exporting SAP Note %s to CSV file" % sid)
+ csvrow = []
+ props = db.get_sapnote_metadata(sid)
+
+ for prop in PROPKEYS:
+ if prop == 'tasks':
+ tasks = ', '.join(props[prop])
+ csvrow.append(tasks)
+ else:
+ csvrow.append(props[prop])
+ writer.writerow(csvrow)
+ self.alert.show('Export', 'Selected SAP Notes exported successfully to CSV format', 'information')
+ self.log.info("Selected SAP Notes exported to CSV format: %s" % export_path)
+ else:
+ self.alert.show('Export', 'Export canceled by user', 'warning')
+ self.log.info("Export canceled by user")
+ dialog.destroy()
+
+
+ def actions_export_txt(self, *args):
+ rootwin = self.gui.get_widget('mainwndow')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ dialog = Gtk.FileChooserDialog("Save file", rootwin,
+ Gtk.FileChooserAction.SAVE,
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
+ response = dialog.run()
+
+ if response == Gtk.ResponseType.OK:
+ export_path = dialog.get_filename()
+ fout = open(export_path, 'w')
+ for sapnote in sapnotes:
+ fout.write("%s\n" % sapnote)
+ self.alert.show('Export', 'Selected SAP Notes exported successfully to TXT format', 'information')
+ self.log.info("Selected SAP Notes exported to TXT format: %s" % export_path)
+ else:
+ self.alert.show('Export', 'Export canceled by user', 'warning')
+ self.log.info("Export canceled by user")
+ dialog.destroy()
+
+
+ def actions_export_json(self, *args):
+ db = self.get_service('DB')
+ rootwin = self.gui.get_widget('mainwndow')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = sapnoteview.get_selected_notes()
+ dialog = Gtk.FileChooserDialog("Save file", rootwin,
+ Gtk.FileChooserAction.SELECT_FOLDER,
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
+ response = dialog.run()
+
+ if response == Gtk.ResponseType.OK:
+ export_path = dialog.get_filename()
+ bag = {}
+ for tid in sapnotes:
+ sid = "0"*(10 - len(tid)) + tid
+ sapnote = db.get_sapnote_metadata(sid)
+ bag[sid] = sapnote
+ now = datetime.now()
+ target = export_path + SEP + 'basico-%s.json' % now.strftime("%Y%m%d_%H%M%S")
+ db.export_basico_package(bag, target)
+ self.alert.show('Export', 'Selected SAP Notes exported successfully to JSON format', 'information')
+ self.log.info("Selected SAP Notes exported to JSON: %s" % target)
+ else:
+ self.alert.show('Export', 'Export canceled by user', 'warning')
+ self.log.info("Export canceled by user")
+ dialog.destroy()
+
+
+ def actions_import_json(self, *args):
+ self.import_notes_from_file()
+ #~ db = self.get_service('DB')
+ #~ rootwin = self.gui.get_widget('mainwndow')
+ #~ sapnoteview = self.gui.get_widget('sapnoteview')
+ #~ sapnotes = sapnoteview.get_selected_notes()
+ #~ dialog = Gtk.FileChooserDialog("Select Basico JSON file", rootwin,
+ #~ Gtk.FileChooserAction.OPEN,
+ #~ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+ #~ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
+ #~ response = dialog.run()
+
+ #~ if response == Gtk.ResponseType.OK:
+ #~ source = dialog.get_filename()
+ #~ try:
+ #~ with open(source, 'r') as fp:
+ #~ bag = json.load(fp)
+ #~ db.import(bag)
+ #~ self.log.debug ("Imported %d notes" % len(bag))
+ #~ except Exception as error:
+ #~ self.log.info("SAP Notes database not found. Creating a new one")
+ #~ self.save_notes()
+
+ #~ self.alert.show('Export', 'Selected SAP Notes exported successfully to JSON format', 'information')
+ #~ self.log.info("Selected SAP Notes exported to JSON: %s" % target)
+ #~ else:
+ #~ self.alert.show('Export', 'Export canceled by user', 'warning')
+ #~ self.log.info("Export canceled by user")
+ #~ dialog.destroy()
+
+
+
+ def actions_import_launchpad(self, *args):
+ self.show_addsapnotes_dialog()
+
+
+ def set_search_filter_key(self, key):
+ self.gui.set_key('cmbvalue', key)
+
+
+ def get_search_filter_key(self):
+ cmbvalue = self.gui.get_key('cmbvalue')
+
+
+ def set_search_term(self, term):
+ searchentry = self.gui.get_widget("stySearchInfo")
+ searchentry.set_text(term)
+
+
+ def search_notes(self, *args):
+ db = self.get_service('DB')
+ searchentry = self.gui.get_widget("stySearchInfo")
+ cmbvalue = self.gui.get_key('cmbvalue')
+ self.log.debug("Serch term: %s" % cmbvalue)
+ try:
+ term = searchentry.get_text()
+ except:
+ term = ''
+
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnotes = db.get_notes()
+ found = {}
+
+ if len(term) == 0:
+ self.current_notes = found = sapnotes
+ sapnoteview.populate(found)
+ sapnoteview.collapse()
+ self.log.debug("Displaying all database")
+ return
+
+ self.log.debug("Looking for '%s'" % term)
+ if cmbvalue == 'search':
+ for sid in sapnotes:
+ if term.upper() in sapnotes[sid]['title'].upper():
+ found[sid] = sapnotes[sid]
+ elif cmbvalue == 'project':
+ for sid in sapnotes:
+ try:
+ projects = sapnotes[sid]['projects']
+ for project in projects:
+ if term.upper() in project.upper():
+ found[sid] = sapnotes[sid]
+ except: pass
+ elif cmbvalue == 'task':
+ for sid in sapnotes:
+ try:
+ tasks = sapnotes[sid]['tasks']
+ for task in tasks:
+ if term.upper() in task.upper():
+ found[sid] = sapnotes[sid]
+ except: pass
+ elif cmbvalue == 'title':
+ for sid in sapnotes:
+ try:
+ title = sapnotes[sid]['title']
+ if term.upper() in title.upper():
+ found[sid] = sapnotes[sid]
+ except: pass
+ elif cmbvalue == 'priority':
+ for sid in sapnotes:
+ try:
+ priority = sapnotes[sid]['priority']
+ if term.upper() in priority.upper():
+ found[sid] = sapnotes[sid]
+ except: pass
+ elif cmbvalue == 'component':
+ for sid in sapnotes:
+ if term.upper() in sapnotes[sid]['componentkey'].upper():
+ found[sid] = sapnotes[sid]
+ elif cmbvalue == 'category':
+ for sid in sapnotes:
+ if term.upper() in sapnotes[sid]['category'].upper():
+ found[sid] = sapnotes[sid]
+ elif cmbvalue == 'type':
+ for sid in sapnotes:
+ if term.upper() in sapnotes[sid]['type'].upper():
+ found[sid] = sapnotes[sid]
+ elif cmbvalue == 'version':
+ for sid in sapnotes:
+ if term.upper() in sapnotes[sid]['version'].upper():
+ found[sid] = sapnotes[sid]
+ elif cmbvalue == 'id':
+ for sid in sapnotes:
+ if term in sid:
+ found[sid] = sapnotes[sid]
+ self.log.info("Term: '%s' (%d results)" % (term, len(found)))
+ self.current_notes = found
+ self.log.debug("Current Notes: %d" % len(self.current_notes))
+ sapnoteview.populate(found)
+
+
+ #~ def import_notes(self, entry):
+ #~ ntbimport = self.gui.get_widget('ntbAddSAPNotes')
+ #~ imptype = ntbimport.get_current_page() # 0 -> Download, 1 -> Import from file
+ #~ if imptype == 0:
+ #~ self.import_notes_from_sapnet()
+ #~ elif imptype == 1:
+ #~ self.import_notes_from_file()
+
+ def import_notes(self, entry):
+ self.import_notes_from_sapnet()
+
+
+ def import_notes_from_file(self):
+ db = self.get_service('DB')
+ notebook = self.gui.get_widget('notebook')
+ rootwin = self.gui.get_widget('mainwinow')
+
+ dialog = Gtk.FileChooserDialog("Select Basico JSON file", rootwin,
+ Gtk.FileChooserAction.OPEN,
+ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
+ Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
+ response = dialog.run()
+
+ if response == Gtk.ResponseType.OK:
+ source = dialog.get_filename()
+ try:
+ with open(source, 'r') as fp:
+ bag = json.load(fp)
+ db.import_sapnotes(bag)
+ self.log.info ("Imported %d notes from %s" % (len(bag), source))
+ except Exception as error:
+ self.log.info("SAP Notes database not found. Creating a new one")
+ self.save_notes()
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ self.current_notes = bag
+ sapnoteview.populate(bag)
+ db.save_notes()
+ self.refresh_view()
+ switch = self.gui.get_widget('schSelectNotesAllNone')
+ sapnoteview.select_all_none(switch, True)
+ sapnoteview.select_all_none(switch, False)
+ sapnoteview.expand_all()
+ else:
+ self.alert.show('Import', 'Nothing imported', 'error')
+ self.log.debug("Nothing imported")
+ dialog.destroy()
+
+ def import_notes_from_sapnet(self):
+ db = self.get_service('DB')
+ driver = self.get_service('Driver')
+
+ notebook = self.gui.get_widget('notebook')
+ winroot = self.gui.get_widget('mainwinow')
+ sapnotes = []
+ bag = set()
+ txtnotes = self.gui.get_widget('txtSAPNotes')
+ textbuffer = txtnotes.get_buffer()
+ istart, iend = textbuffer.get_bounds()
+ lines = textbuffer.get_text(istart, iend, False)
+
+ lines = lines.replace(' ', ',')
+ lines = lines.replace('\n', ',')
+ sapnotes.extend(lines.split(','))
+
+ for sapnote in sapnotes:
+ if len(sapnote.strip()) > 0:
+ bag.add(sapnote.strip())
+
+ self.log.debug("%d SAP Notes to be downloaded: %s" % (len(bag), ', '.join(list(bag))))
+
+ resnotes = {}
+
+ self.sap.start_fetching(len(bag))
+ dlbag = {}
+
+ # FIXME: max_workers = 1 = Threads disabled
+ with Executor(max_workers=1) as exe:
+ jobs = []
+ for sapnote in bag:
+ job = exe.submit(self.sap.fetch, sapnote)
+ jobs.append(job)
+
+ for job in jobs:
+ rc, sapnote = job.result()
+ self.log.debug("\tRC SAP Note %s: %s" % (sapnote, rc))
+ resnotes[sapnote] = rc
+ time.sleep(0.1)
+
+ driver.close()
+ self.sap.stop_fetching()
+ db.save_notes()
+ db.build_stats()
+
+ textbuffer.set_text("")
+ self.log.info("Task completed.")
+ notebook.set_current_page(0)
+ dialog = Gtk.MessageDialog(winroot, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Task completed")
+ msgrc = ""
+ ko = 0
+ ok = 0
+ for sapnote in resnotes:
+ rc = resnotes[sapnote]
+ if rc:
+ ok += 1
+ else:
+ ko += 1
+ msgrc += "Downloaded: %d\nErroneus: %d" % (ok, ko)
+ self.alert.show('Download', msgrc, 'information')
+ dlbag = {}
+ mysapnotes = db.get_notes()
+ erroneus = set()
+ for sid in bag:
+ sid = "0"*(10 - len(sid)) + sid
+ try:
+ dlbag[sid] = mysapnotes[sid]
+ except Exception as error:
+ self.log.error(error)
+ erroneus.add(sid)
+
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ self.current_notes = dlbag
+ #~ self.refresh_view()
+ self.refresh_and_clear_view()
+ sapnoteview.populate(dlbag)
+ sapnoteview.expand_all()
+ boxMenu = self.gui.get_widget('boxMenu')
+ boxMenu.show_all()
+
+
+ def stop_dl_notes(self, *args):
+ notebook = self.gui.get_widget('notebook')
+ txtSAPNotes = self.gui.get_widget('txtSAPNotes')
+ buffer = txtSAPNotes.get_buffer()
+ buffer.set_text("")
+ notebook.set_current_page(0)
+ self.refresh_view()
+ #~ self.alert.show('Download', 'Action canceled by user', 'warning')
+ boxMenu = self.gui.get_widget('boxMenu')
+ boxMenu.show_all()
+ self.refresh_and_clear_view()
+
+
+ def rebuild_database(self, *args):
+ self.log.debug("Rebuild database...")
+
+ db = self.get_service('DB')
+ DB_DIR = self.get_var('DB', 'local')
+
+ #~ FSAPNOTE = DB_DIR + sid + '.xml'
+ #~ if path is None:
+ #~ path = DB_DIR
+
+ files = glob.glob("%s%s*.xml" % (DB_DIR, SEP))
+ sap = self.app.get_service('SAP')
+ for filename in files:
+ self.log.debug("Filename: %s" % filename)
+ sid = basename(filename)[0:-4]
+ self.log.debug("SAP Note Id: %s" % sid)
+
+ valid = False
+ if db.is_stored(sid):
+ self.log.debug("\tSAP Note %s will be analyzed again" % sid)
+ content = db.get_sapnote_content(sid)
+ sapnote = sap.analyze_sapnote_metadata(sid, content)
+ if len(sapnote) > 0:
+ db = self.get_service('DB')
+ db.add(sapnote)
+ db.store(sid, content)
+ valid = True
+
+ self.refresh_view()
+
+ def refresh_and_clear_view(self, *args):
+ switch = self.gui.get_widget('schSelectNotesAllNone')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ self.set_search_filter_key('search')
+ self.set_search_term('')
+ self.search_notes()
+ self.refresh_view()
+ sapnoteview.select_all_none(switch, False)
+ sapnoteview.collapse()
+
+
+ def refresh_view(self, action=None, callback=None, view=None):
+ window = self.gui.get_widget('mainwindow')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ switch_expand = self.gui.get_widget('schExpandCollapse')
+ switch_select = self.gui.get_widget('schSelectNotesAllNone')
+ #~ active_ = switch.get_active()
+
+ if view is not None:
+ viewlabel = self.gui.get_widget('lblViewCurrent')
+ name = "<span size='20000'><b>%-10s</b></span>" % view.capitalize()
+ viewlabel.set_markup(name)
+ sapnoteview.set_view(view)
+ self.search_notes()
+ switch_expand.set_active(True)
+ switch_expand.set_active(False)
+ switch_select.set_active(False)
+ switch_select.set_active(True)
+ switch_select.set_active(False)
+ window.show_home_page()
+
+
+ def setup_menu_import(self):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ view = sapnoteview.get_view()
+
+ ### ACTIONS POPOVER
+ app = self.gui.get_app()
+
+ ## Action Menu
+ actions_menu = Gio.Menu()
+
+ # Import submenu
+ #~ actions_import_submenu = Gio.Menu()
+ # Import Basico Package
+ actions_menu.append_item(self.uif.create_item('Import Basico Package', 'app.actions-import-basico', 'document-open'))
+ #~ app.add_action(self.uif.create_action("actions-import-basico"))
+
+ # Import from JSON file
+ actions_menu.append_item(self.uif.create_item('Import JSON file', 'app.actions-import-json', 'document-open'))
+ app.add_action(self.uif.create_action("actions-import-json"))
+
+ #~ Import from SAP Launchpad
+ actions_menu.append_item(self.uif.create_item('Import SAP Notes from SAP Launchpad', 'app.actions-import-launchpad', 'download'))
+ app.add_action(self.uif.create_action("actions-import-launchpad"))
+
+ #~ actions_menu.append_submenu('Import', actions_import_submenu)
+
+ # MnuButton valid with any modern version of Gtk (?> 3.10)
+ btnactions = self.gui.get_widget('mnuBtnImport')
+ btnactions.set_always_show_image(True)
+ btnactions.set_property("use-popover", True)
+ btnactions.set_menu_model(actions_menu)
+
+
+ def setup_menu_actions(self):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ view = sapnoteview.get_view()
+
+ ### ACTIONS POPOVER
+ app = self.gui.get_app()
+
+ ## Action Menu
+ actions_menu = Gio.Menu()
+
+ #~ # Browse SAP Notes
+ actions_menu.append_item(self.uif.create_item('Browse SAP Note(s)', 'app.actions-browse', 'browse'))
+ app.add_action(self.uif.create_action("actions-browse"))
+
+ if view == 'bookmarks':
+ #~ Unbookmark SAP Note(s) items
+ actions_menu.append_item(self.uif.create_item('Unbookmark SAP Note(s)', 'app.actions-unbookmark', 'bookmark'))
+ app.add_action(self.uif.create_action("actions-unbookmark"))
+ else:
+ #~ Bookmark SAP Note(s) items
+ actions_menu.append_item(self.uif.create_item('Bookmark SAP Note(s)', 'app.actions-bookmark', 'bookmark'))
+ app.add_action(self.uif.create_action("actions-bookmark"))
+
+ # Manage task
+ actions_menu.append_item(self.uif.create_item('Manage tasks', 'app.actions-manage-tasks', 'tasks'))
+ app.add_action(self.uif.create_action("actions-manage-tasks"))
+
+ # Export submenu
+ actions_export_submenu = Gio.Menu()
+
+ #~ Export to JSON
+ actions_export_submenu.append_item(self.uif.create_item('Export as JSON', 'app.actions-export-json', 'document-save'))
+ app.add_action(self.uif.create_action("actions-export-json"))
+ #~ Export to CSV
+ actions_export_submenu.append_item(self.uif.create_item('Export as CSV', 'app.actions-export-csv', 'document-save'))
+ app.add_action(self.uif.create_action("actions-export-csv"))
+ #~ Export to TXT
+ actions_export_submenu.append_item(self.uif.create_item('Export to plaint text', 'app.actions-export-txt', 'document-save'))
+ app.add_action(self.uif.create_action("actions-export-txt"))
+ #~ Export to BCO
+ #~ actions_export_submenu.append_item(self.uif.create_item('Export as Basico Package Object (BCO)', 'app.actions-export-bco', 'document-save'))
+ #~ app.add_action(self.uif.create_action("actions-export-bco"))
+ actions_menu.append_submenu('Export', actions_export_submenu)
+ #~ actions_menu.append_section('Export', actions_export_submenu)
+
+ # Refresh SAP Notes
+ #~ actions_menu.append_item(self.uif.create_item('Refresh selected SAP Notes', 'app.actions-other-refresh', 'refresh'))
+ #~ app.add_action(self.uif.create_action("actions-other-refresh"))
+
+ # Delete SAP Notes
+ actions_menu.append_item(self.uif.create_item('Delete selected SAP Notes', 'app.actions-other-delete', 'delete'))
+ app.add_action(self.uif.create_action("actions-other-delete"))
+
+ # MnuButton valid with any modern version of Gtk (?> 3.10)
+ btnactions = self.gui.get_widget('mnuBtnActions')
+ btnactions.set_always_show_image(True)
+ btnactions.set_property("use-popover", True)
+ btnactions.set_menu_model(actions_menu)
+
+
+ def show_addsapnotes_dialog(self, *args):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnoteview.set_view('download')
+ notebook = self.gui.get_widget('notebook')
+ boxMenu = self.gui.get_widget('boxMenu')
+ boxMenu.hide()
+ notebook.set_current_page(1)
+
+
+ def default_preferences(self, *args):
+ prefs = self.get_service('Settings')
+ gui = self.get_service('GUI')
+ settings = prefs.get_default_settings()
+ for key in settings:
+ widget = gui.get_widget(key)
+ widget.set_text(str(settings[key]))
+
+ self.config[self.section] = settings
+ self.save_config()
+ self.log.debug("Settings reverted to default")
+
+
+ def apply_preferences(self, *args):
+ self.sap.apply_preferences()
+ notebook = self.gui.get_widget('notebook')
+ notebook.set_current_page(0)
+ self.refresh_view(view='tasks')
+ self.alert.show('Settings', 'SAP preferences saved', 'information')
+
+
+ def update_components_stats(self, *args):
+ statsviewer = self.gui.get_widget('scrStatsViewer')
+ view = WebKit.WebView()
+ chart = self.stats.build_pie_maincomp()
+ view.load_string(chart, 'text/html', 'UTF-8','/')
+ self.gui.swap_widget(statsviewer, view)
+
+
+ def update_categories_stats(self, *args):
+ statsviewer = self.gui.get_widget('scrStatsViewer')
+ view = WebKit.WebView()
+ chart = self.stats.build_pie_categories()
+ view.load_string(chart, 'text/html', 'UTF-8','/')
+ self.gui.swap_widget(statsviewer, view)
+
+
+ def check_task_link_button_status(self):
+ tasks = self.get_service('Tasks')
+ button = self.gui.get_widget('btnLinkTasksApply')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+
+ tasks_selected = len(tasks.get_selected()) > 0
+ notes_selected = len(sapnoteview.get_selected_notes()) > 0
+ if tasks_selected and notes_selected:
+ #~ button.set_no_show_all(False)
+ #~ button.show_all()
+ button.set_sensitive(True)
+ self.log.debug("Task link button enabled")
+ else:
+ #~ button.hide()
+ #~ button.set_no_show_all(True)
+ button.set_sensitive(False)
+ self.log.debug("Task link button disabled")
+
+
+ def test(self, *args):
+ self.log.debug(args)
+
+
Index: REL-0.2/basico/data/icons/wait.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/wait.png
===================================================================
--- REL-0.2/basico/data/icons/wait.png (nonexistent)
+++ REL-0.2/basico/data/icons/wait.png (revision 76)
/REL-0.2/basico/data/icons/wait.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/edit.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/edit.png
===================================================================
--- REL-0.2/basico/data/icons/edit.png (nonexistent)
+++ REL-0.2/basico/data/icons/edit.png (revision 76)
/REL-0.2/basico/data/icons/edit.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/ui/basico.ui
===================================================================
--- REL-0.2/basico/data/ui/basico.ui (nonexistent)
+++ REL-0.2/basico/data/ui/basico.ui (revision 76)
@@ -0,0 +1,2367 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0
+
+Copyright (C) 2016-2017
+
+This file is part of Basico.
+
+Basico is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Basico is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Basico. If not, see <http://www.gnu.org/licenses/>.
+
+Author: Tomás Vírseda <tomasvirseda@gmail.com>
+
+-->
+<interface domain="basico">
+ <requires lib="gtk+" version="3.18"/>
+ <!-- interface-license-type gplv3 -->
+ <!-- interface-name Basico -->
+ <!-- interface-description Basico UI XML file -->
+ <!-- interface-copyright 2016-2017 -->
+ <!-- interface-authors Tom\303\241s V\303\255rseda <tomasvirseda@gmail.com> -->
+ <object class="GtkWindow" id="window">
+ <property name="can_focus">False</property>
+ <property name="window_position">center-on-parent</property>
+ <property name="urgency_hint">True</property>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox" id="mainbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="margin_top">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="boxMenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">6</property>
+ <property name="vexpand">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkBox" id="box45">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkMenuButton" id="mnuBtnViews">
+ <property name="width_request">250</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox" id="box29">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="imgViewCurrent">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-select-color</property>
+ <property name="icon_size">5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="lblViewCurrent">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;View&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="mnuBtnActions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="use_popover">False</property>
+ <child>
+ <object class="GtkBox" id="box28">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="lblSelectedNotes">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;0 SAP Notes selected&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">center</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkBox" id="box5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="btnRefreshSAPNoteView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox" id="box21">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkImage" id="imgBtnRefresh">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-refresh</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box51">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkMenuButton" id="mnuBtnImport">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="use_popover">False</property>
+ <child>
+ <object class="GtkImage" id="imgMnuBtnImport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon_size">6</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box54">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkToggleButton" id="tgbSearch">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgBtnSearch">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-find</property>
+ <property name="icon_size">6</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box20">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkToggleButton" id="tgbShowManage">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgBtnShowManage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-execute</property>
+ <property name="icon_size">6</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnShowProperties">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox" id="box3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkImage" id="imgBtnShowProps">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-info</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnShowStats">
+ <property name="visible">False</property>
+ <property name="no_show_all">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox" id="box7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkImage" id="imgBtnStats">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-missing-image</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box48">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkBox" id="box52">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Selection</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="schSelectNotesAllNone">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box53">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Expand/Collapse</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSwitch" id="schExpandCollapse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="separator7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">8</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkBox" id="box46">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="btnSettings">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgBtnSettings">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-preferences</property>
+ <property name="icon_size">5</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">11</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box19">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkButton" id="btnAbout">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgBtnAbout">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-about</property>
+ <property name="icon_size">5</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">12</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box27">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkButton" id="btnQuit">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgBtnQuit">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-quit</property>
+ <property name="icon_size">5</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">13</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRevealer" id="revSearch">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="transition_type">crossfade</property>
+ <child>
+ <object class="GtkBox" id="box49">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkComboBox" id="cmbSearchInfo">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="focus_on_click">False</property>
+ <property name="popup_fixed_width">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSearchEntry" id="stySearchInfo">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ <property name="truncate_multiline">True</property>
+ <property name="primary_icon_name">edit-find-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkNotebook" id="notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <child>
+ <object class="GtkPaned" id="hpnNotesManager">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">600</property>
+ <property name="position_set">True</property>
+ <property name="wide_handle">True</property>
+ <child>
+ <object class="GtkBox" id="box6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_right">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="notesbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">out</property>
+ <child>
+ <object class="GtkViewport" id="notesbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="boxPropsWidget">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkNotebook" id="ntbOperations">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_left">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="tab_pos">bottom</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkImage" id="imgPropsTitle">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="stock">gtk-missing-image</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;SAP Note details&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="boxProps">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Metadata</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box36">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="cntBoxTasks">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkButton" id="btnLinkTasksApply">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">False</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-connect</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Link SAP Notes to selected tasks&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkViewport" id="boxTasks">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box37">
+ <property name="name">0</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="etyTaskName">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box38">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="btnAddTask">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="use_stock">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnDelTask">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="use_stock">True</property>
+ <property name="always_show_image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Tasks</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Projects</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">SAP Notes Manager</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="boxOperations">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="box17">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box59">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox" id="box11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;span size='30000'&gt;Download SAP Notes&lt;/span&gt;
+&lt;i&gt;Write down some SAP Notes ID (comma-separated or one per line)&lt;/i&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">center</property>
+ <property name="lines">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">spread</property>
+ <child>
+ <object class="GtkButton" id="btnStopDlNotes">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">False</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox" id="box14">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="stock">gtk-cancel</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Cancel&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnStartDlNotes">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkBox" id="box13">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="stock">gtk-apply</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label23">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Accept&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="txtSAPNotes">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">SAP Notes Downloader</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box16">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkBox" id="box18">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkExpander" id="expander1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="expanded">True</property>
+ <child>
+ <object class="GtkAlignment" id="alignment11">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">24</property>
+ <property name="right_padding">6</property>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="row_homogeneous">True</property>
+ <child>
+ <object class="GtkEntry" id="CNF_SAP_LOGIN">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CNF_SAP_LOGOUT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CNF_SAP_ODATA_NOTES">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CNF_SAP_NOTE_URL">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">&lt;b&gt;SAP Note URL&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">&lt;b&gt;OData SAP Notes Service&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">&lt;b&gt;Logout page&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">&lt;b&gt;Login page&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">&lt;b&gt;Connection Timeout&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="CNF_SAP_CONN_TIMEOUT">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="hexpand">False</property>
+ <property name="max_length">4</property>
+ <property name="width_chars">4</property>
+ <property name="input_purpose">digits</property>
+ <property name="climb_rate">1</property>
+ <property name="snap_to_ticks">True</property>
+ <property name="numeric">True</property>
+ <property name="value">5</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkBox" id="box25">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"> &lt;big&gt;&lt;b&gt;SAP preferences&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkExpander">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="expanded">True</property>
+ <child>
+ <object class="GtkAlignment">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">6</property>
+ <property name="left_padding">24</property>
+ <property name="right_padding">6</property>
+ <child>
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <property name="row_homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="label30">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="label" translatable="yes">&lt;b&gt;Firefox Profile directory&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="CNF_FF_PROFILE_DIR">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label12">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes"> &lt;big&gt;&lt;b&gt;Firefox preferences&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="btnPrefsSAPReset">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkBox" id="box23">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-revert-to-saved</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Reset to default</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnPrefsSAPCancel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkBox" id="box44">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-cancel</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Cancel changes</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnPrefsSAPApply">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <child>
+ <object class="GtkBox" id="box24">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="image8">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-apply</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Apply changes</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Preferences</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkRadioButton" id="rbnBackup">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-go-down</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;span size='30000'&gt;&lt;b&gt;Backup&lt;/b&gt;&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="rbnRestore">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">False</property>
+ <property name="group">rbnBackup</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-go-up</property>
+ <property name="icon_size">6</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;span size='30000'&gt;&lt;b&gt;Restore&lt;/b&gt;&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">24</property>
+ <child>
+ <object class="GtkRevealer" id="revBackup">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="transition_type">slide-left</property>
+ <property name="reveal_child">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Perform Full Backup&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes">&lt;big&gt;Create a backup for all resources saved:
+ - SAP Notes
+ - Metadata
+ - Bookmarks
+ - Comments
+ - Settings
+
+&lt;i&gt;Take into account that no login credentials are saved. All logon details are handled by your webbrowser.
+The only private data to be considered are your comments.&lt;/i&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">fill</property>
+ <property name="selectable">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;Perform Partial Backup&lt;/b&gt;&lt;/big&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="label" translatable="yes">Backup only those items you are interested in:</property>
+ <property name="use_markup">True</property>
+ <property name="justify">fill</property>
+ <property name="selectable">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;b&gt;SAP Notes&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;b&gt;Tasks&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;b&gt;Projects&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="draw_indicator">True</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">&lt;b&gt;Comments&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Backup and Restore</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box55">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="box26">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkBox" id="box31">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <property name="homogeneous">True</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="btnStatsByCompMain">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgStatsByCompMain">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-missing-image</property>
+ <property name="icon_size">6</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnStatsByCategory">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgStatsByCategory">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-missing-image</property>
+ <property name="icon_size">6</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnStatsByCompMain2">
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage" id="imgStatsByCompMain2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-missing-image</property>
+ <property name="icon_size">6</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrStatsViewer">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox" id="scrStatsViewer3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Stats</property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkProgressBar" id="pgbMain">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="show_text">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
Index: REL-0.2/basico/data/icons/power.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/power.png
===================================================================
--- REL-0.2/basico/data/icons/power.png (nonexistent)
+++ REL-0.2/basico/data/icons/power.png (revision 76)
/REL-0.2/basico/data/icons/power.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/refresh.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/refresh.png
===================================================================
--- REL-0.2/basico/data/icons/refresh.png (nonexistent)
+++ REL-0.2/basico/data/icons/refresh.png (revision 76)
/REL-0.2/basico/data/icons/refresh.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/stats.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/stats.png
===================================================================
--- REL-0.2/basico/data/icons/stats.png (nonexistent)
+++ REL-0.2/basico/data/icons/stats.png (revision 76)
/REL-0.2/basico/data/icons/stats.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/component.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/component.png
===================================================================
--- REL-0.2/basico/data/icons/component.png (nonexistent)
+++ REL-0.2/basico/data/icons/component.png (revision 76)
/REL-0.2/basico/data/icons/component.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/bsearch.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/bsearch.png
===================================================================
--- REL-0.2/basico/data/icons/bsearch.png (nonexistent)
+++ REL-0.2/basico/data/icons/bsearch.png (revision 76)
/REL-0.2/basico/data/icons/bsearch.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/about.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/about.png
===================================================================
--- REL-0.2/basico/data/icons/about.png (nonexistent)
+++ REL-0.2/basico/data/icons/about.png (revision 76)
/REL-0.2/basico/data/icons/about.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/import.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/import.png
===================================================================
--- REL-0.2/basico/data/icons/import.png (nonexistent)
+++ REL-0.2/basico/data/icons/import.png (revision 76)
/REL-0.2/basico/data/icons/import.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/type.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/type.png
===================================================================
--- REL-0.2/basico/data/icons/type.png (nonexistent)
+++ REL-0.2/basico/data/icons/type.png (revision 76)
/REL-0.2/basico/data/icons/type.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/subwindow.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/subwindow.png
===================================================================
--- REL-0.2/basico/data/icons/subwindow.png (nonexistent)
+++ REL-0.2/basico/data/icons/subwindow.png (revision 76)
/REL-0.2/basico/data/icons/subwindow.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/components.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/components.png
===================================================================
--- REL-0.2/basico/data/icons/components.png (nonexistent)
+++ REL-0.2/basico/data/icons/components.png (revision 76)
/REL-0.2/basico/data/icons/components.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/bookmarks.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/bookmarks.png
===================================================================
--- REL-0.2/basico/data/icons/bookmarks.png (nonexistent)
+++ REL-0.2/basico/data/icons/bookmarks.png (revision 76)
/REL-0.2/basico/data/icons/bookmarks.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/settings.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/settings.png
===================================================================
--- REL-0.2/basico/data/icons/settings.png (nonexistent)
+++ REL-0.2/basico/data/icons/settings.png (revision 76)
/REL-0.2/basico/data/icons/settings.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/chart.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/chart.png
===================================================================
--- REL-0.2/basico/data/icons/chart.png (nonexistent)
+++ REL-0.2/basico/data/icons/chart.png (revision 76)
/REL-0.2/basico/data/icons/chart.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/task.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/task.png
===================================================================
--- REL-0.2/basico/data/icons/task.png (nonexistent)
+++ REL-0.2/basico/data/icons/task.png (revision 76)
/REL-0.2/basico/data/icons/task.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/bookmark.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/bookmark.png
===================================================================
--- REL-0.2/basico/data/icons/bookmark.png (nonexistent)
+++ REL-0.2/basico/data/icons/bookmark.png (revision 76)
/REL-0.2/basico/data/icons/bookmark.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/chronologic.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/chronologic.png
===================================================================
--- REL-0.2/basico/data/icons/chronologic.png (nonexistent)
+++ REL-0.2/basico/data/icons/chronologic.png (revision 76)
/REL-0.2/basico/data/icons/chronologic.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/download.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/download.png
===================================================================
--- REL-0.2/basico/data/icons/download.png (nonexistent)
+++ REL-0.2/basico/data/icons/download.png (revision 76)
/REL-0.2/basico/data/icons/download.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/sapnote.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/sapnote.png
===================================================================
--- REL-0.2/basico/data/icons/sapnote.png (nonexistent)
+++ REL-0.2/basico/data/icons/sapnote.png (revision 76)
/REL-0.2/basico/data/icons/sapnote.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/category.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/category.png
===================================================================
--- REL-0.2/basico/data/icons/category.png (nonexistent)
+++ REL-0.2/basico/data/icons/category.png (revision 76)
/REL-0.2/basico/data/icons/category.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/priority.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/priority.png
===================================================================
--- REL-0.2/basico/data/icons/priority.png (nonexistent)
+++ REL-0.2/basico/data/icons/priority.png (revision 76)
/REL-0.2/basico/data/icons/priority.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/tasks.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/tasks.png
===================================================================
--- REL-0.2/basico/data/icons/tasks.png (nonexistent)
+++ REL-0.2/basico/data/icons/tasks.png (revision 76)
/REL-0.2/basico/data/icons/tasks.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/details.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/details.png
===================================================================
--- REL-0.2/basico/data/icons/details.png (nonexistent)
+++ REL-0.2/basico/data/icons/details.png (revision 76)
/REL-0.2/basico/data/icons/details.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/application-vnd.oasis.opendocument.chart.svg
===================================================================
--- REL-0.2/basico/data/icons/application-vnd.oasis.opendocument.chart.svg (nonexistent)
+++ REL-0.2/basico/data/icons/application-vnd.oasis.opendocument.chart.svg (revision 76)
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg id="svg3396" xmlns="http://www.w3.org/2000/svg" height="24" width="24" version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs id="defs3398">
+ <linearGradient id="linearGradient2620" y2="609.51" gradientUnits="userSpaceOnUse" x2="302.86" gradientTransform="matrix(.035207 0 0 .0082353 -.72485 18.981)" y1="366.65" x1="302.86">
+ <stop id="stop5050" style="stop-opacity:0" offset="0"/>
+ <stop id="stop5056" offset=".5"/>
+ <stop id="stop5052" style="stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient2617" xlink:href="#linearGradient5060" gradientUnits="userSpaceOnUse" cy="486.65" cx="605.71" gradientTransform="matrix(-.012049 0 0 .0082353 10.761 18.981)" r="117.14"/>
+ <linearGradient id="linearGradient5060">
+ <stop id="stop5062" offset="0"/>
+ <stop id="stop5064" style="stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <radialGradient id="radialGradient2614" xlink:href="#linearGradient5060" gradientUnits="userSpaceOnUse" cy="486.65" cx="605.71" gradientTransform="matrix(.012049 0 0 .0082353 13.239 18.981)" r="117.14"/>
+ <linearGradient id="linearGradient2610" y2="2.9062" gradientUnits="userSpaceOnUse" x2="-51.786" gradientTransform="matrix(.39221 0 0 .44736 29.199 -1.2387)" y1="50.786" x1="-51.786">
+ <stop id="stop3106" style="stop-color:#aaa" offset="0"/>
+ <stop id="stop3108" style="stop-color:#c8c8c8" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient2608" y2="47.013" gradientUnits="userSpaceOnUse" x2="25.132" gradientTransform="matrix(.48572 0 0 .47803 .34283 -.70595)" y1=".98521" x1="25.132">
+ <stop id="stop3602" style="stop-color:#f4f4f4" offset="0"/>
+ <stop id="stop3604" style="stop-color:#dbdbdb" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient2604" y2="46.017" gradientUnits="userSpaceOnUse" x2="24" gradientTransform="matrix(.45454 0 0 .46512 1.0909 .33723)" y1="1.425" x1="24">
+ <stop id="stop3213" style="stop-color:#fff" offset="0"/>
+ <stop id="stop3215" style="stop-color:#fff;stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient2597" y2="5.4565" gradientUnits="userSpaceOnUse" x2="36.358" gradientTransform="matrix(.47785 0 0 .55248 .37225 -.076128)" y1="8.059" x1="32.892">
+ <stop id="stop8591" style="stop-color:#fefefe" offset="0"/>
+ <stop id="stop8593" style="stop-color:#cbcbcb" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3972">
+ <stop id="stop3974" style="stop-color:#fff" offset="0"/>
+ <stop id="stop3976" style="stop-color:#fff;stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3683" y2="44.866" gradientUnits="userSpaceOnUse" x2="34" gradientTransform="matrix(.77839 0 0 1.0095 -17.855 -22.298)" y1="13.682" x1="34">
+ <stop id="stop2266" style="stop-color:#d7e866" offset="0"/>
+ <stop id="stop2268" style="stop-color:#8cab2a" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3685" y2="38.031" xlink:href="#linearGradient3972" gradientUnits="userSpaceOnUse" x2="34.644" gradientTransform="matrix(.60089 0 0 .91190 -11.056 -18.672)" y1="26" x1="34.644"/>
+ <linearGradient id="linearGradient3691" y2="44.866" gradientUnits="userSpaceOnUse" x2="34" gradientTransform="matrix(.77839 0 0 1.0095 -13.855 -20.298)" y1="13.682" x1="34">
+ <stop id="stop3995" style="stop-color:#a3c0d0" offset="0"/>
+ <stop id="stop4001" style="stop-color:#427da1" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3693" y2="38.031" xlink:href="#linearGradient3972" gradientUnits="userSpaceOnUse" x2="34.644" gradientTransform="matrix(.60089 0 0 .91190 -7.0557 -16.672)" y1="26" x1="34.644"/>
+ <linearGradient id="linearGradient3699" y2="44.866" gradientUnits="userSpaceOnUse" x2="34" gradientTransform="matrix(.77839 0 0 1.0095 -9.8545 -18.298)" y1="13.682" x1="34">
+ <stop id="stop4170" style="stop-color:#f8cd70" offset="0"/>
+ <stop id="stop4172" style="stop-color:#d99a11" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3701" y2="38.031" xlink:href="#linearGradient3972" gradientUnits="userSpaceOnUse" x2="34.644" gradientTransform="matrix(.60089 0 0 .91190 -3.0557 -14.672)" y1="26" x1="34.644"/>
+ <linearGradient id="linearGradient3709" y2="7.273" gradientUnits="userSpaceOnUse" x2="12.388" y1="19.507" x1="12.685">
+ <stop id="stop2492" style="stop-color:#2e4a5a" offset="0"/>
+ <stop id="stop2494" style="stop-color:#6e8796" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3717" y2="4.8811" gradientUnits="userSpaceOnUse" x2="7.7546" gradientTransform="translate(1)" y1="20.119" x1="7.9047">
+ <stop id="stop3928" style="stop-color:#5d8430" offset="0"/>
+ <stop id="stop3930" style="stop-color:#6d9a38" offset="1"/>
+ </linearGradient>
+ </defs>
+ <g id="layer1">
+ <rect id="rect2879" style="opacity:.15;fill:url(#linearGradient2620)" height="2" width="17" y="22" x="3.5"/>
+ <path id="path2881" style="opacity:.15;fill:url(#radialGradient2617)" d="m3.5 22v1.9999c-0.6205 0.004-1.5-0.448-1.5-1s0.6924-1 1.5-1z"/>
+ <path id="path2883" style="opacity:.15;fill:url(#radialGradient2614)" d="m20.5 22v1.9999c0.62047 0.0038 1.5-0.44807 1.5-1.0001 0-0.552-0.6924-0.99982-1.5-0.99982z"/>
+ <path id="path4160" style="stroke-linejoin:round;stroke:url(#linearGradient2610);stroke-width:.99992;fill:url(#linearGradient2608)" d="m3.5 0.49996h11.5c0.683 0.2373 4.541 3.1281 5.5 5 0 5.7292 0.000039 11.271 0.000039 17h-17v-22z"/>
+ <rect id="rect3980" style="opacity:.3" rx=".93798" ry="0" height="1" width="12.194" y="19.5" x="6.4482"/>
+ <path id="path2435" style="opacity:0.24;stroke:url(#linearGradient2604);fill:none" d="m19.5 5.677v15.823h-15v-20h10.394"/>
+ <path id="path3370" style="opacity:.2;fill-rule:evenodd" d="m14.075 1c1.1563 0.32877 0.33906 4.6144 0.33906 4.6144s4.5154-0.42774 5.6077 1.195c1.489 2.2122-0.068-0.6352-0.173-0.8217-0.756-1.3401-3.867-4.5471-5.046-4.9412-0.088-0.0295-0.283-0.0465-0.728-0.0465z"/>
+ <path id="path4474" style="fill:url(#linearGradient2597);fill-rule:evenodd" d="m14 1c1.5262 0 1 4 1 4s4.9921-0.45326 4.9921 2c0-0.59774 0.05575-1.4784-0.06407-1.6559-0.839-1.243-3.744-3.8619-4.798-4.2976-0.086-0.0356-0.686-0.0465-1.13-0.0465z"/>
+ <path id="path3677" style="stroke:url(#linearGradient3717);stroke-linecap:square;fill:url(#linearGradient3683)" d="m9.5 5.5v14h-2v-14h2z"/>
+ <path id="path3681" style="opacity:.4;stroke-width:.98028;stroke:url(#linearGradient3685);stroke-linecap:square;fill:none" d="m8.4919 6.4901 0.043377 8.067"/>
+ <path id="path3687" style="stroke:url(#linearGradient3709);stroke-linecap:square;fill:url(#linearGradient3691)" d="m13.5 7.5v12h-2v-12h2z"/>
+ <path id="path3689" style="opacity:.4;stroke-width:.98028;stroke:url(#linearGradient3693);stroke-linecap:square;fill:none" d="m12.492 8.4901 0.04338 8.067"/>
+ <path id="path3695" style="stroke:#c57a41;stroke-linecap:square;fill:url(#linearGradient3699)" d="m17.5 9.5v10h-2v-10h2z"/>
+ <path id="path3697" style="opacity:.4;stroke-width:.98028;stroke:url(#linearGradient3701);stroke-linecap:square;fill:none" d="m16.492 10.49 0.04338 8.067"/>
+ </g>
+</svg>
Index: REL-0.2/basico/data/icons/libpeas-plugin.svg
===================================================================
--- REL-0.2/basico/data/icons/libpeas-plugin.svg (nonexistent)
+++ REL-0.2/basico/data/icons/libpeas-plugin.svg (revision 76)
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg id="svg1" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="48" width="48" version="1.0" y="0" x="0" xmlns:cc="http://web.resource.org/cc/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <metadata id="metadata162">
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title>Plug-in</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:date/>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/"/>
+ <dc:identifier/>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>plugin</rdf:li>
+ <rdf:li>plug-in</rdf:li>
+ <rdf:li>extension</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
+ <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
+ <cc:requires rdf:resource="http://web.resource.org/cc/SourceCode"/>
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs id="defs3">
+ <linearGradient id="linearGradient3782">
+ <stop id="stop3784" offset="0"/>
+ <stop id="stop3786" style="stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3772">
+ <stop id="stop3774" style="stop-opacity:0" offset="0"/>
+ <stop id="stop3780" offset=".5"/>
+ <stop id="stop3776" style="stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient2860" y2="57.75" gradientUnits="userSpaceOnUse" x2="44.375" y1="4.8232" x1="17.537">
+ <stop id="stop2856" style="stop-color:#fff" offset="0"/>
+ <stop id="stop2858" style="stop-color:#fff;stop-opacity:0" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient2870" y2="-11.761" gradientUnits="userSpaceOnUse" x2="30.936" gradientTransform="matrix(1.3077 0 0 1.2994 -21.308 -16.64)" y1="44.294" x1="30.936">
+ <stop id="stop2866" style="stop-color:#8ae234" offset="0"/>
+ <stop id="stop2868" style="stop-color:#4e9a06" offset="1"/>
+ </linearGradient>
+ <linearGradient id="linearGradient3836" y2="43.495" xlink:href="#linearGradient3772" gradientUnits="userSpaceOnUse" x2="30.992" gradientTransform="matrix(.58333 0 0 1.1429 13.167 -6.7143)" y1="46.987" x1="30.992"/>
+ <radialGradient id="radialGradient3838" xlink:href="#linearGradient3782" gradientUnits="userSpaceOnUse" cy="45" cx="34" gradientTransform="matrix(2 0 0 1.3333 -35 -15)" r="1.5"/>
+ <radialGradient id="radialGradient3840" xlink:href="#linearGradient3782" gradientUnits="userSpaceOnUse" cy="45" cx="34" gradientTransform="matrix(2 0 0 1.3333 -97.5 -105)" r="1.5"/>
+ <linearGradient id="linearGradient3842" y2="43.495" xlink:href="#linearGradient3772" gradientUnits="userSpaceOnUse" x2="30.992" gradientTransform="matrix(0.75 0 0 1.1429 19.5 -6.7143)" y1="46.987" x1="30.992"/>
+ <radialGradient id="radialGradient3844" xlink:href="#linearGradient3782" gradientUnits="userSpaceOnUse" cy="45" cx="34" gradientTransform="matrix(2 0 0 1.3333 -23 -15)" r="1.5"/>
+ <radialGradient id="radialGradient3846" xlink:href="#linearGradient3782" gradientUnits="userSpaceOnUse" cy="45" cx="34" gradientTransform="matrix(2 0 0 1.3333 -108.5 -105)" r="1.5"/>
+ <linearGradient id="linearGradient3124" y2="89" gradientUnits="userSpaceOnUse" x2="52" y1="-13.5" x1="6">
+ <stop id="stop3120" style="stop-color:#fff" offset="0"/>
+ <stop id="stop3122" style="stop-color:#fff;stop-opacity:0" offset="1"/>
+ </linearGradient>
+ </defs>
+ <g id="layer2">
+ <g id="g3826" style="opacity:.5" transform="matrix(1.4211 0 0 1.125 -24.658 -8.875)">
+ <rect id="rect2872" style="color:black;fill:url(#linearGradient3836)" height="4" width="3.5" y="43" x="29.5"/>
+ <rect id="rect3762" style="color:black;fill:url(#radialGradient3838)" height="4" width="3" y="43" x="33"/>
+ <rect id="rect3790" style="color:black;fill:url(#radialGradient3840)" transform="scale(-1)" height="4" width="3" y="-47" x="-29.5"/>
+ </g>
+ <g id="g3831" style="opacity:.5" transform="matrix(1.3333 0 0 1.125 -22 -8.875)">
+ <rect id="rect3814" style="color:black;fill:url(#linearGradient3842)" height="4" width="4.5" y="43" x="40.5"/>
+ <rect id="rect3816" style="color:black;fill:url(#radialGradient3844)" height="4" width="3" y="43" x="45"/>
+ <rect id="rect3818" style="color:black;fill:url(#radialGradient3846)" transform="scale(-1)" height="4" width="3" y="-47" x="-40.5"/>
+ </g>
+ <path id="path2848" style="color:black;stroke-dashoffset:1.5;stroke:#4e9a06;stroke-linecap:square;fill:url(#linearGradient2870)" d="m27 3.5c-1.308 0-4.5 0.9896-4.5 3.5 0 1.3208 1.029 2.9159 1 5.5h-9v12c-2.656 0.041-4.6514-3.041-6-3-2.5252 0.078-3 2.79-3 4.089 0 3.898 1.4736 4.901 4 4.911 1.839 0 1.772-1.041 5-1v13h10c0-3.248-3-3.9-3-6.5 0-1.949 1.038-2.5 3-2.5 3.189 0 6 0.4 6 3 0 1.598-1 3.401-1 6h10v-16c-3.999 0-4.5 2-6.5 2-2.526 0-4.5-1.602-4.5-5.5 0-2 1.474-3.5 4-3.5 2.615 0 2.346 2 7 2v-9h-11c-0.047-3.1871 3.018-4.5476 3-6.5-0.043-2.51-2.538-2.5-4.5-2.5z"/>
+ <path id="path2852" style="color:black;stroke-dashoffset:1.5;stroke:url(#linearGradient2860);stroke-linecap:square;stroke-width:.76925;fill:none" d="m37 16.5c-0.311 0-1.098 0.121-1.656 0.406-0.559 0.286-0.844 0.56-0.844 1.094 0 0.173 0.205 0.78 0.469 1.562 0.264 0.783 0.544 1.769 0.531 2.938 0 0.552-0.448 1-1 1h-6v8c0 0.552-0.448 1-1 1-1.358 0.021-2.402-0.65-3.188-1.188-0.392-0.268-0.721-0.506-0.968-0.656-0.247-0.149-0.395-0.154-0.313-0.156-0.634 0.02-0.902 0.278-1.156 0.688-0.254 0.409-0.375 1.002-0.375 1.312 0 1.381 0.276 2.148 0.562 2.5 0.287 0.352 0.642 0.497 1.438 0.5 0.459 0 0.576-0.12 1.156-0.406 0.581-0.286 1.47-0.611 2.844-0.594 0.552 0 1 0.448 1 1v9h4.812c-0.141-0.376-0.35-0.717-0.624-1.094-0.484-0.664-1.188-1.572-1.188-2.906 0-0.972 0.392-1.874 1.094-2.375 0.701-0.501 1.545-0.625 2.406-0.625 1.287 0 2.535 0.11 3.594 0.594 1.058 0.484 1.906 1.562 1.906 2.906 0 0.886-0.322 1.586-0.562 2.281-0.133 0.383-0.168 0.817-0.25 1.219h5.812v-9.844c-0.693 0.081-1.474 0.134-1.906 0.282-0.66 0.225-1.24 0.549-2.094 0.562-1.148 0.021-2.271-0.316-3-1.219-0.729-0.902-1-2.162-1-3.781 0-0.689 0.175-1.571 0.688-2.406 0.512-0.836 1.501-1.594 2.812-1.594 1.333 0 2.143 0.742 2.75 1.188 0.433 0.318 0.977 0.525 1.75 0.656v-4.844h-7c-0.552 0-1-0.448-1-1-0.022-1.507 0.622-2.609 1.156-3.406s0.847-1.3 0.844-1.594c-0.011-0.627-0.127-0.617-0.562-0.781-0.436-0.165-1.203-0.219-1.938-0.219z" transform="matrix(1.3006 0 0 1.2994 48.839 -16.64)"/>
+ <path id="path2227" style="opacity:.7;color:black;stroke-dashoffset:1.5;stroke:url(#linearGradient3124);stroke-linecap:square;fill:none" d="m27 4.5c-0.403 0-1.471 0.2013-2.25 0.6562-0.779 0.455-1.25 1.0109-1.25 1.8438 0 0.8034 1.032 2.6469 1 5.5 0.001 0.266-0.104 0.52-0.292 0.708s-0.442 0.293-0.708 0.292h-8v11c0.001 0.266-0.104 0.52-0.292 0.708s-0.442 0.293-0.708 0.292c-1.717 0.026-3.053-0.927-4.094-1.719-0.5203-0.396-0.9886-0.76-1.3435-1-0.3549-0.239-0.5803-0.28-0.5313-0.281-0.9079 0.028-1.2701 0.397-1.5937 1.031s-0.4375 1.534-0.4375 2.063c0 1.823 0.3492 2.752 0.7812 3.218 0.4321 0.467 1.0859 0.683 2.2188 0.688 0.732 0 0.912-0.155 1.594-0.438 0.682-0.282 1.685-0.584 3.406-0.562 0.266-0.001 0.52 0.104 0.708 0.292s0.293 0.442 0.292 0.708v12h7.781c-0.208-0.681-0.53-1.246-1.031-1.844-0.731-0.871-1.75-1.973-1.75-3.656 0-1.151 0.365-2.183 1.156-2.781 0.792-0.598 1.77-0.719 2.844-0.719 1.636 0 3.227 0.078 4.562 0.594 0.668 0.257 1.297 0.635 1.75 1.218 0.454 0.584 0.688 1.358 0.688 2.188 0 1.692-0.618 3.197-0.844 5h7.844v-13.875c-1.092 0.132-1.885 0.399-2.5 0.75-0.804 0.459-1.668 1.125-3 1.125-1.474 0-2.919-0.508-3.938-1.625-1.018-1.117-1.562-2.758-1.562-4.875 0-1.245 0.48-2.433 1.375-3.25s2.165-1.25 3.625-1.25c1.562 0 2.485 0.701 3.25 1.156 0.606 0.361 1.427 0.629 2.75 0.75v-6.906h-10c-0.266 0.001-0.52-0.104-0.708-0.292s-0.293-0.442-0.292-0.708c-0.028-1.915 0.898-3.2888 1.688-4.3125 0.789-1.0237 1.316-1.7346 1.312-2.1875-0.008-0.4625-0.122-0.6772-0.25-0.8438-0.128-0.1665-0.315-0.2957-0.625-0.4062-0.621-0.221-1.643-0.25-2.625-0.25z"/>
+ </g>
+</svg>
Index: REL-0.2/basico/data/icons/tags.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/tags.png
===================================================================
--- REL-0.2/basico/data/icons/tags.png (nonexistent)
+++ REL-0.2/basico/data/icons/tags.png (revision 76)
/REL-0.2/basico/data/icons/tags.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/export-txt.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/export-txt.png
===================================================================
--- REL-0.2/basico/data/icons/export-txt.png (nonexistent)
+++ REL-0.2/basico/data/icons/export-txt.png (revision 76)
/REL-0.2/basico/data/icons/export-txt.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/basico.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/basico.png
===================================================================
--- REL-0.2/basico/data/icons/basico.png (nonexistent)
+++ REL-0.2/basico/data/icons/basico.png (revision 76)
/REL-0.2/basico/data/icons/basico.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/idea.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/idea.png
===================================================================
--- REL-0.2/basico/data/icons/idea.png (nonexistent)
+++ REL-0.2/basico/data/icons/idea.png (revision 76)
/REL-0.2/basico/data/icons/idea.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/project.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/project.png
===================================================================
--- REL-0.2/basico/data/icons/project.png (nonexistent)
+++ REL-0.2/basico/data/icons/project.png (revision 76)
/REL-0.2/basico/data/icons/project.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/export-csv.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/export-csv.png
===================================================================
--- REL-0.2/basico/data/icons/export-csv.png (nonexistent)
+++ REL-0.2/basico/data/icons/export-csv.png (revision 76)
/REL-0.2/basico/data/icons/export-csv.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/res/user_agents.txt
===================================================================
--- REL-0.2/basico/data/res/user_agents.txt (nonexistent)
+++ REL-0.2/basico/data/res/user_agents.txt (revision 76)
@@ -0,0 +1,899 @@
+"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
+"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)"
+"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)"
+"Mozilla/4.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)"
+"Mozilla/1.22 (compatible; MSIE 10.0; Windows 3.1)"
+"Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))"
+"Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; InfoPath.3; MS-RTC LM 8; .NET4.0C; .NET4.0E)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 4.0; Tablet PC 2.0; InfoPath.3; .NET4.0C; .NET4.0E)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/11.0.696.57)"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205"
+"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; chromeframe/11.0.696.57)"
+"Mozilla/5.0 ( ; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"
+"Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 5.1; Trident/5.0)"
+"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 7.1; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C)"
+"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; AskTB5.5)"
+"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2; .NET4.0C; .NET4.0E)"
+"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C)"
+"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; FDM; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; Tablet PC 2.0)"
+"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)"
+"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)"
+"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 2.0.50727)"
+"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
+"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.0; Trident/4.0; InfoPath.1; SV1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 3.0.04506.30)"
+"Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.0; Trident/4.0; FBSMTWB; .NET CLR 2.0.34861; .NET CLR 3.0.3746.3218; .NET CLR 3.5.33652; msn OptimizedIE8;ENUS)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.3; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 3.0)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; msn OptimizedIE8;ZHCN)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; InfoPath.3; .NET4.0C; .NET4.0E) chromeframe/8.0.552.224"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; .NET4.0C; .NET4.0E; Zune 4.7; InfoPath.3)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8; .NET4.0C; .NET4.0E; Zune 4.7)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MS-RTC LM 8)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; Zune 4.0)"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; MS-RTC LM 8; Zune 4.7)"
+"Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre"
+"Mozilla/5.0 (X11; Linux x86_64; rv:2.2a1pre) Gecko/20100101 Firefox/4.2a1pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.2a1pre) Gecko/20110324 Firefox/4.2a1pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.2a1pre) Gecko/20110323 Firefox/4.2a1pre"
+"Mozilla/5.0 (X11; Linux x86_64; rv:2.0b9pre) Gecko/20110111 Firefox/4.0b9pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b9pre) Gecko/20101228 Firefox/4.0b9pre"
+"Mozilla/5.0 (Windows NT 5.1; rv:2.0b9pre) Gecko/20110105 Firefox/4.0b9pre"
+"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b8pre) Gecko/20101114 Firefox/4.0b8pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101213 Firefox/4.0b8pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101128 Firefox/4.0b8pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b8pre) Gecko/20101114 Firefox/4.0b8pre"
+"Mozilla/5.0 (Windows NT 5.1; rv:2.0b8pre) Gecko/20101127 Firefox/4.0b8pre"
+"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b8) Gecko/20100101 Firefox/4.0b8"
+"Mozilla/5.0 (Windows NT 6.1; rv:2.0b7pre) Gecko/20100921 Firefox/4.0b7pre"
+"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b7) Gecko/20101111 Firefox/4.0b7"
+"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b7) Gecko/20100101 Firefox/4.0b7"
+"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre"
+"Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre"
+"Mozilla/5.0 (X11; Linux x86_64; rv:2.0b4) Gecko/20100818 Firefox/4.0b4"
+"Mozilla/5.0 (X11; Linux i686; rv:2.0b3pre) Gecko/20100731 Firefox/4.0b3pre"
+"Mozilla/5.0 (Windows NT 5.2; rv:2.0b13pre) Gecko/20110304 Firefox/4.0b13pre"
+"Mozilla/5.0 (Windows NT 5.1; rv:2.0b13pre) Gecko/20110223 Firefox/4.0b13pre"
+"Mozilla/5.0 (X11; Linux i686; rv:2.0b12pre) Gecko/20110204 Firefox/4.0b12pre"
+"Mozilla/5.0 (X11; Linux i686; rv:2.0b12pre) Gecko/20100101 Firefox/4.0b12pre"
+"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b11pre) Gecko/20110128 Firefox/4.0b11pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110131 Firefox/4.0b11pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110129 Firefox/4.0b11pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b11pre) Gecko/20110128 Firefox/4.0b11pre"
+"Mozilla/5.0 (Windows NT 6.1; rv:2.0b11pre) Gecko/20110126 Firefox/4.0b11pre"
+"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b11pre) Gecko/20110126 Firefox/4.0b11pre"
+"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b10pre) Gecko/20110118 Firefox/4.0b10pre"
+"Mozilla/5.0 (Windows NT 6.1; rv:2.0b10pre) Gecko/20110113 Firefox/4.0b10pre"
+"Mozilla/5.0 (X11; Linux i686; rv:2.0b10) Gecko/20100101 Firefox/4.0b10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:2.0b10) Gecko/20110126 Firefox/4.0b10"
+"Mozilla/5.0 (Windows NT 6.1; rv:2.0b10) Gecko/20110126 Firefox/4.0b10"
+"Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:2.0) Gecko/20110307 Firefox/4.0"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:2.0) Gecko/20110404 Fedora/16-dev Firefox/4.0"
+"Mozilla/5.0 (X11; Arch Linux i686; rv:2.0) Gecko/20110321 Firefox/4.0"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20110319 Firefox/4.0"
+"Mozilla/5.0 (Windows NT 6.1; rv:1.9) Gecko/20100101 Firefox/4.0"
+"Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8"
+"Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8"
+"Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8"
+"Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.3a5pre) Gecko/20100526 Firefox/3.7a5pre"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20091218 Firefox 3.6b5"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20090428 Firefox/3.6a1pre"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20090405 Firefox/3.6a1pre"
+"Mozilla/5.0 (X11; U; Linux i686; ru-RU; rv:1.9.2a1pre) Gecko/20090405 Ubuntu/9.04 (jaunty) Firefox/3.6a1pre"
+"Mozilla/5.0 (Windows; Windows NT 5.1; es-ES; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre"
+"Mozilla/5.0 (Windows; Windows NT 5.1; en-US; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.2a1pre) Gecko/20090402 Firefox/3.6a1pre (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100915 Gentoo Firefox/3.6.9"
+"Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.2.9) Gecko/20100913 Firefox/3.6.9"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729; .NET CLR 4.0.20506)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-GB; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9"
+"Mozilla/5.0 (X11; U; OpenBSD i386; en-US; rv:1.9.2.8) Gecko/20101230 Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100804 Gentoo Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100723 SUSE/3.6.8-0.1.1 Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.8) Gecko/20100722 Ubuntu/10.04 (lucid) Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux i686; fi-FI; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.8) Gecko/20100727 Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.9.2.8) Gecko/20100725 Gentoo Firefox/3.6.8"
+"Mozilla/5.0 (X11; U; FreeBSD i386; de-CH; rv:1.9.2.8) Gecko/20100729 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-BR; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.8) Gecko/20100722 AskTbADAP/3.9.1.14019 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; he; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.8) Gecko/20100722 Firefox 3.6.8 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0C)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.8) Gecko/20100722 Firefox 3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.3) Gecko/20121221 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-TW; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0E"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100809 Fedora/3.6.7-1.fc14 Firefox/3.6.7"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100723 Fedora/3.6.7-1.fc13 Firefox/3.6.7"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.7) Gecko/20100726 CentOS/3.6-3.el5.centos Firefox/3.6.7"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.7 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.0"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-PT; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729; .NET4.0E)"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.4) Gecko/20100614 Ubuntu/10.04 (lucid) Firefox/3.6.4"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100625 Gentoo Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-TW; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.0 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100503 Firefox/3.6.4 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; nb-NO; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3pre) Gecko/20100405 Firefox/3.6.3plugin1 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.3) Gecko/20100403 Fedora/3.6.3-4.fc13 Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100403 Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.3) Gecko/20100401 SUSE/3.6.3-1.1 Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux i686; ko-KR; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100404 Ubuntu/10.04 (lucid) Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3"
+"Mozilla/5.0 (X11; U; Linux AMD64; en-US; rv:1.9.2.3) Gecko/20100403 Ubuntu/10.10 (maverick) Firefox/3.6.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.0 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ca; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 GTB7.0"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.2) Gecko/20100316 AskTbSPC2/3.9.1.14019 Firefox/3.6.2"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 GTB6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 ( .NET CLR 3.0.04506.648)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2 ( .NET CLR 3.0.04506.30)"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.7; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10pre) Gecko/20100902 Ubuntu/9.10 (karmic) Firefox/3.6.1pre"
+"Mozilla/5.0 (X11; U; Linux x86_64; ja-JP; rv:1.9.2.16) Gecko/20110323 Ubuntu/10.10 (maverick) Firefox/3.6.16"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.16) Gecko/20110323 Ubuntu/9.10 (karmic) Firefox/3.6.16 FirePHP/0.5"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16 ( .NET CLR 3.5.30729; .NET4.0E)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.1.13) Gecko/20100914 Firefox/3.6.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.16) Gecko/20110319 AskTbUTR/3.11.3.15590 Firefox/3.6.16"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.16pre) Gecko/20110304 Ubuntu/10.10 (maverick) Firefox/3.6.15pre"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110303 Ubuntu/10.04 (lucid) Firefox/3.6.15 FirePHP/0.5"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.15) Gecko/20110330 CentOS/3.6-1.el5.centos Firefox/3.6.15"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15 ( .NET CLR 3.5.30729; .NET4.0C) FirePHP/0.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.15) Gecko/20110303 AskTbBT4/3.11.3.15590 Firefox/3.6.15 ( .NET CLR 3.5.30729; .NET4.0C)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14pre) Gecko/20110105 Firefox/3.6.14pre"
+"Mozilla/5.0 (X11; U; Linux armv7l; en-US; rv:1.9.2.14) Gecko/20110224 Firefox/3.6.14 MB860/Version.0.43.3.MB860.AmericaMovil.en.MX"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-AU; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.14) Gecko/20110218 Firefox/3.6.14 GTB7.1 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; nb-NO; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.13) Gecko/20110103 Fedora/3.6.13-1.fc14 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101223 Gentoo Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101219 Gentoo Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Red Hat/3.6-3.el4 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101206 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-NZ; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.13) Gecko/20101206 Ubuntu/9.10 (karmic) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-GB; rv:1.9.2.13) Gecko/20101206 Red Hat/3.6-2.el5 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; da-DK; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux MIPS32 1074Kf CPS QuadCore; en-US; rv:1.9.2.13) Gecko/20110103 Fedora/3.6.13-1.fc14 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux i686; pt-BR; rv:1.9.2.13) Gecko/20101209 Fedora/3.6.13-1.fc13 Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.2.13) Gecko/20101206 Ubuntu/9.10 (karmic) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.13) Gecko/20101209 CentOS/3.6-2.el5.centos Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13"
+"Mozilla/5.0 (X11; U; NetBSD i386; en-US; rv:1.9.2.12) Gecko/20101030 Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux x86_64; es-MX; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.04 (lucid) Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.2.12) Gecko/20101027 Fedora/3.6.12-1.fc13 Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.2.12) Gecko/20101026 SUSE/3.6.12-0.7.1 Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.12) Gecko/20101102 Gentoo Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.12) Gecko/20101102 Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux ppc; fr; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux i686; ko-KR; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.12) Gecko/20101027 Fedora/3.6.12-1.fc13 Firefox/3.6.12"
+"Mozilla/5.0 (X11; FreeBSD x86_64; rv:2.0) Gecko/20100101 Firefox/3.6.12"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729; .NET4.0E)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 (.NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; .NET CLR 3.5.21022)"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; de; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 GTB5"
+"Mozilla/5.0 (X11; U; Linux x86_64; ru; rv:1.9.2.11) Gecko/20101028 CentOS/3.6-2.el5.centos Firefox/3.6.11"
+"Mozilla/5.0 (X11; U; Linux armv7l; en-GB; rv:1.9.2.3pre) Gecko/20100723 Firefox/3.6.11"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; ru; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.2.11) Gecko/20101012 Firefox/3.6.11 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; pt-BR; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; el-GR; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; es-AR; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100915 Ubuntu/9.04 (jaunty) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.11) Gecko/20101013 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; en-CA; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100915 Ubuntu/9.10 (karmic) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.10) Gecko/20100914 SUSE/3.6.10-0.3.1 Firefox/3.6.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ro; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; nl; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.1) Gecko/20100122 firefox/3.6.1"
+"Mozilla/5.0(Windows; U; Windows NT 7.0; rv:1.9.2) Gecko/20100101 Firefox/3.6"
+"Mozilla/5.0(Windows; U; Windows NT 5.2; rv:1.9.2) Gecko/20100101 Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100222 Ubuntu/10.04 (lucid) Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100130 Gentoo Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2) Gecko/20100308 Ubuntu/10.04 (lucid) Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2pre) Gecko/20100312 Ubuntu/9.04 (jaunty) Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100128 Gentoo Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100115 Ubuntu/10.04 (lucid) Firefox/3.6"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 FirePHP/0.4"
+"Mozilla/5.0 (X11; Linux i686; rv:2.0) Gecko/20100101 Firefox/3.6"
+"Mozilla/5.0 (X11; FreeBSD i686) Firefox/3.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU; rv:1.9.2) Gecko/20100105 MRA 5.6 (build 03278) Firefox/3.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; lt; rv:1.9.2) Gecko/20100115 Firefox/3.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a3pre) Gecko/20100306 Firefox3.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.8) Gecko/20100806 Firefox/3.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6;MEGAUPLOAD 1.0"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ar; rv:1.9.2) Gecko/20100115 Firefox/3.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2) Gecko/20100105 Firefox/3.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2) Gecko/20100115 Firefox/3.6 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b5pre) Gecko/20090517 Firefox/3.5b4pre (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b4pre) Gecko/20090409 Firefox/3.5b4pre"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b4pre) Gecko/20090401 Firefox/3.5b4pre"
+"Mozilla/5.0 (X11; U; Linux i686; nl-NL; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 GTB5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; fr; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4 GTB5"
+"Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-2.fc12 Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9 GTB7.0"
+"Mozilla/5.0 (X11; U; Linux x86_64; es-CL; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux i686; hu-HU; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-1.fc12 Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1 Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100315 Ubuntu/9.10 (karmic) Firefox/3.5.9"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.4) Gecko/20091028 Ubuntu/9.10 (karmic) Firefox/3.5.9"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; tr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; et; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; es-ES; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.5.9 (de)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.0 (.NET CLR 3.0.30618)"
+"Mozilla/5.0 (X11; U; Linux x86_64; ru; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc11 Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100318 Gentoo Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux i686; es-AR; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8"
+"Mozilla/5.0 (X11; U; FreeBSD i386; ja-JP; rv:1.9.1.8) Gecko/20100305 Firefox/3.5.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; sl; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729) FirePHP/0.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB6"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB7.0 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100305 Gentoo Firefox/3.5.7"
+"Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7"
+"Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.7) Gecko/20091222 SUSE/3.5.7-1.1.1 Firefox/3.5.7"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; fr; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.0.04506.648)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; fa; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 MRA 5.5 (build 02842) Firefox/3.5.7 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20100117 Gentoo Firefox/3.5.6"
+"Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20091216 Fedora/3.5.6-1.fc11 Firefox/3.5.6 GTB6"
+"Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.6) Gecko/20091201 SUSE/3.5.6-1.1.1 Firefox/3.5.6 GTB6"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.6) Gecko/20100118 Gentoo Firefox/3.5.6"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6 GTB6"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6 GTB7.0"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091201 SUSE/3.5.6-1.1.1 Firefox/3.5.6"
+"Mozilla/5.0 (X11; U; Linux i686; cs-CZ; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6"
+"Mozilla/5.0 (X11; U; Linux i686; ca; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; id; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.4 (build 02647) Firefox/3.5.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.5 (build 02842) Firefox/3.5.6 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.5 (build 02842) Firefox/3.5.6"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 GTB6 (.NET CLR 3.5.30729) FBSMTWB"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729) FBSMTWB"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.5"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8pre) Gecko/20091227 Ubuntu/9.10 (karmic) Firefox/3.5.5"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.5) Gecko/20091114 Gentoo Firefox/3.5.5"
+"Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; uk; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.5) Gecko/Firefox/3.5.5"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091102 MRA 5.5 (build 02842) Firefox/3.5.5"
+"Mozilla/5.0 (Windows NT 5.1; U; zh-cn; rv:1.8.1) Gecko/20091102 Firefox/3.5.5"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; pl; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 FBSMTWB"
+"Mozilla/5.0 (X11; U; Linux x86_64; ja; rv:1.9.1.4) Gecko/20091016 SUSE/3.5.4-1.1.2 Firefox/3.5.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 (.NET CLR 3.5.30729) FBSMTWB"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.4) Gecko/20091007 Firefox/3.5.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 ( .NET CLR 3.5.30729; .NET4.0E)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.4) Gecko/20091007 Firefox/3.5.4"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.3pre"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090914 Slackware/13.0_stable Firefox/3.5.3"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3"
+"Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3"
+"Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.3) Gecko/20090919 Firefox/3.5.3"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.3) Gecko/20090912 Gentoo Firefox/3.5.3 FirePHP/0.3"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 GTB5"
+"Mozilla/5.0 (X11; U; FreeBSD i386; ru-RU; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.5.3;MEGAUPLOAD 1.0 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ko; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; fi; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 2.0.50727; .NET CLR 3.0.30618; .NET CLR 3.5.21022; .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; bg; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; pl; rv:1.9.1.2) Gecko/20090911 Slackware Firefox/3.5.2"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.2) Gecko/20090803 Slackware Firefox/3.5.2"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.2) Gecko/20090803 Firefox/3.5.2 Slackware"
+"Mozilla/5.0 (X11; U; Linux i686; ru-RU; rv:1.9.1.2) Gecko/20090804 Firefox/3.5.2"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2) Gecko/20090729 Slackware/13.0 Firefox/3.5.2"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (X11; U; Linux i686 (x86_64); fr; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB7.1 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; es-MX; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; uk; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 FirePHP/0.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.16) Gecko/20101130 AskTbMYC/3.9.1.14019 Firefox/3.5.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; it; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.16) Gecko/20101130 MRA 5.4 (build 02647) Firefox/3.5.16 ( .NET CLR 3.5.30729; .NET4.0C)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.16) Gecko/20101130 AskTbPLTV5/3.8.0.12304 Firefox/3.5.16 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16 GTB7.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.15) Gecko/20101027 Fedora/3.5.15-1.fc12 Firefox/3.5.15"
+"Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.15) Gecko/20101027 Fedora/3.5.15-1.fc12 Firefox/3.5.15"
+"Mozilla/5.0 (Windows; U; Windows NT 5.0; ru; rv:1.9.1.13) Gecko/20100914 Firefox/3.5.13"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.12) Gecko/2009070611 Firefox/3.5.12"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.12) Gecko/20100824 MRA 5.7 (build 03755) Firefox/3.5.12"
+"Mozilla/5.0 (X11; U; Linux; en-US; rv:1.9.1.11) Gecko/20100720 Firefox/3.5.11"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11 ( .NET CLR 3.5.30729; .NET4.0C)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.10) Gecko/20100504 Firefox/3.5.11 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.1.10) Gecko/20100506 SUSE/3.5.10-0.1.1 Firefox/3.5.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.10) Gecko/20100504 Firefox/3.5.10 GTB7.0 ( .NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux x86_64; rv:1.9.1.1) Gecko/20090716 Linux Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100524 Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Linux Mint/7 (Gloria) Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090716 Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090714 SUSE/3.5.1-1.1 Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux x86; rv:1.9.1.1) Gecko/20090716 Linux Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2pre) Gecko/20090729 Ubuntu/9.04 (jaunty) Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.1) Gecko/20090722 Gentoo Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.1) Gecko/20090714 SUSE/3.5.1-1.1 Firefox/3.5.1"
+"Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1) Gecko/20090720 Firefox/3.5.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; tr; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 4.0.20506)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 GTB5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11;U; Linux i686; en-GB; rv:1.9.1) Gecko/20090624 Ubuntu/9.04 (jaunty) Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1) Gecko/20090630 Firefox/3.5 GTB6"
+"Mozilla/5.0 (X11; U; Linux i686; ja; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.04 (jaunty) Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1) Gecko/20090624 Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.9.1) Gecko/20090624 Ubuntu/9.04 (jaunty) Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1) Gecko/20090701 Ubuntu/9.04 (jaunty) Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686; en-us; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.04 (jaunty) Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1) Gecko/20090624 Ubuntu/8.04 (hardy) Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1) Gecko/20090624 Firefox/3.5"
+"Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.9.1) Gecko/20090624 Firefox/3.5"
+"Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.1) Gecko/20090703 Firefox/3.5"
+"Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.0.10) Gecko/20090624 Firefox/3.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1) Gecko/20090612 Firefox/3.5 (.NET CLR 4.0.20506)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1) Gecko/20090612 Firefox/3.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 4.0.20506)"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1) Gecko/20090624 Firefox/3.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-TW; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)"
+"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.25 (KHTML, like Gecko) Chrome/12.0.706.0 Safari/534.25"
+"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24"
+"Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.702.0 Chrome/12.0.702.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/12.0.702.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/12.0.702.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.699.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.699.0 Safari/534.24"
+"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.698.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.697.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.43 Safari/534.24"
+"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24"
+"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.3 Safari/534.24"
+"Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.14 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.12 Safari/534.24"
+"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_6) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.12 Safari/534.24"
+"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.04 Chromium/11.0.696.0 Chrome/11.0.696.0 Safari/534.24"
+"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.0 Safari/534.24"
+"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.694.0 Safari/534.24"
+"Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.23 (KHTML, like Gecko) Chrome/11.0.686.3 Safari/534.23"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.21 (KHTML, like Gecko) Chrome/11.0.682.0 Safari/534.21"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.21 (KHTML, like Gecko) Chrome/11.0.678.0 Safari/534.21"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_7_0; en-US) AppleWebKit/534.21 (KHTML, like Gecko) Chrome/11.0.678.0 Safari/534.21"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20"
+"Mozilla/5.0 (Windows NT) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.669.0 Safari/534.20"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.19 (KHTML, like Gecko) Chrome/11.0.661.0 Safari/534.19"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.18 (KHTML, like Gecko) Chrome/11.0.661.0 Safari/534.18"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.18 (KHTML, like Gecko) Chrome/11.0.660.0 Safari/534.18"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.655.0 Safari/534.17"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.655.0 Safari/534.17"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.654.0 Safari/534.17"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/11.0.652.0 Safari/534.17"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.82 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux armv7l; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16"
+"Mozilla/5.0 (X11; U; FreeBSD x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16"
+"Mozilla/5.0 (X11; U; FreeBSD i386; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.133 Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.133 Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.127 Chrome/10.0.648.127 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.127 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ru-RU) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.11 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.0 Chrome/10.0.648.0 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.0 Chrome/10.0.648.0 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.0 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.642.0 Chrome/10.0.642.0 Safari/534.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.639.0 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.638.0 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.634.0 Safari/534.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.634.0 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 SUSE/10.0.626.0 (KHTML, like Gecko) Chrome/10.0.626.0 Safari/534.16"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Chrome/10.0.613.0 Safari/534.15"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.613.0 Chrome/10.0.613.0 Safari/534.15"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Ubuntu/10.04 Chromium/10.0.612.3 Chrome/10.0.612.3 Safari/534.15"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Chrome/10.0.612.1 Safari/534.15"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.15 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.611.0 Chrome/10.0.611.0 Safari/534.15"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.602.0 Safari/534.14"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/540.0 (KHTML,like Gecko) Chrome/9.1.0.0 Safari/540.0"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/540.0 (KHTML, like Gecko) Ubuntu/10.10 Chrome/9.1.0.0 Safari/540.0"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Ubuntu/10.10 Chromium/9.0.600.0 Chrome/9.0.600.0 Safari/534.14"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.600.0 Safari/534.14"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.599.0 Safari/534.13"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.84 Safari/534.13"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.44 Safari/534.13"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.19 Safari/534.13"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.15 Safari/534.13"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.15 Safari/534.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.0 Safari/534.13"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.596.0 Safari/534.13"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Ubuntu/10.04 Chromium/9.0.595.0 Chrome/9.0.595.0 Safari/534.13"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Ubuntu/9.10 Chromium/9.0.592.0 Chrome/9.0.592.0 Safari/534.13"
+"Mozilla/5.0 (X11; U; Windows NT 6; en-US) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/9.0.587.0 Safari/534.12"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/9.0.579.0 Safari/534.12"
+"Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US) AppleWebKit/534.12 (KHTML, like Gecko) Chrome/9.0.576.0 Safari/534.12"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/540.0 (KHTML, like Gecko) Ubuntu/10.10 Chrome/8.1.0.0 Safari/540.0"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.558.0 Safari/534.10"
+"Mozilla/5.0 (X11; U; CrOS i686 0.9.130; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.344 Safari/534.10"
+"Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.343 Safari/534.10"
+"Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.341 Safari/534.10"
+"Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.339 Safari/534.10"
+"Mozilla/5.0 (X11; U; CrOS i686 0.9.128; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.339"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Ubuntu/10.10 Chromium/8.0.552.237 Chrome/8.0.552.237 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.3 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/533.3"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.210 Safari/534.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.200 Safari/534.10"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.551.0 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.548.0 Safari/534.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.544.0 Safari/534.10"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/7.0.540.0 Safari/534.10"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.9 (KHTML, like Gecko) Chrome/7.0.531.0 Safari/534.9"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.8 (KHTML, like Gecko) Chrome/7.0.521.0 Safari/534.8"
+"Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.24 Safari/534.7"
+"Mozilla/5.0 (X11; U; Linux x86_64; fr-FR) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.6 (KHTML, like Gecko) Chrome/7.0.500.0 Safari/534.6"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; tr-TR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; fr-FR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; cs-CZ) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; zh-cn) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; zh-cn) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; sv-se) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; ko-kr) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; ja-jp) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; it-it) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-fr) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; es-es) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-us) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-gb) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; de-de) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; sv-SE) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; hu-HU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de-DE) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; it-IT) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/534.16+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-ch) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; de-de) AppleWebKit/534.15+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ar) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Android 2.2; Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-HK) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; tr-TR) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; nb-NO) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; zh-cn) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
+"Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5"
+"Mozilla/5.0 (iPod; U; CPU iPhone OS 4_2_1 like Mac OS X; he-il) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; fr; CPU iPhone OS 4_2_1 like Mac OS X; fr) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_1 like Mac OS X; zh-tw) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8G4 Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; pl-pl) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; fr-fr) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3 like Mac OS X; en-gb) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; nb-no) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; it-it) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; fr) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; fi-fi) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; fi-fi) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; th-th) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+"
+"Mozilla/5.0 (X11; U; Linux x86_64; en-ca) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/531.2+"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ja-JP) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; fr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; zh-cn) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ru-ru) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ko-kr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; it-it) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/534.1+ (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-au) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; el-gr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ca-es) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; zh-tw) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; it-it) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; fr-fr) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.0; en-en) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; nl-nl) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; de-de) AppleWebKit/533.16 (KHTML, like Gecko) Version/4.1 Safari/533.16"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_7; en-us) AppleWebKit/533.4 (KHTML, like Gecko) Version/4.1 Safari/533.4"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/526.9 (KHTML, like Gecko) Version/4.0dp1 Safari/526.8"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; tr) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; en) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; de) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081212 Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/526.9 (KHTML, like Gecko) Version/4.0dp1 Safari/526.8"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-gb) AppleWebKit/528.10+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_4; en-us) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_4; en-gb) AppleWebKit/528.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/526.11.2"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-gb) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; cs-CZ) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; da-dk) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ja-jp) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/533.4+ (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; de-de) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; ja-jp) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B5097d Safari/6531.22.7"
+"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"
+"Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10gin_lib.cc"
+"Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10"
+"Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/123"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-TW) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; ko-KR) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE) AppleWebKit/532+ (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; hu-hu) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us) AppleWebKit/531.21.11 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; ru-ru) AppleWebKit/533.2+ (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; de-at) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10"
+"Mozilla/5.0 (iPhone; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10"
+"Mozilla/5.0 (iPhone Simulator; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7D11 Safari/531.21.10"
+"Mozilla/5.0 (iPad; U; CPU OS 3_2_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/53"
+"Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; es-es) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10"
+"Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; es-es) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B360 Safari/531.21.10"
+"Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.1021.10gin_lib.cc"
+"Mozilla/5.0 (iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/532.0+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9.2009"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_8; en-us) AppleWebKit/532.0+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_1; nl-nl) AppleWebKit/532.3+ (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; fi-fi) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.3 Safari/531.21.10"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532+ (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-TW) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; pl-PL) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 5.2; de-DE) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19.1"
+"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_5_7; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/4.0.1 Safari/530.18"
+"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.1 Safari/530.18"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ru-RU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; ja-JP) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; hu-HU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; he-IL) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; he-IL) AppleWebKit/528+ (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-FR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; es-es) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 6.0; de-DE) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-BR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; nb-NO) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; fr-FR) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Mozilla/5.0 (Windows; U; Windows NT 5.1; fi-FI) AppleWebKit/528.16 (KHTML, like Gecko) Version/4.0 Safari/528.16"
+"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10"
+"Opera/9.80 (Windows NT 5.1; U; zh-tw) Presto/2.8.131 Version/11.10"
+"Opera/9.80 (X11; Linux x86_64; U; Ubuntu/10.10 (maverick); pl) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (X11; Linux i686; U; ja) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (X11; Linux i686; U; fr) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 6.1; U; sv) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 6.1; U; en-US) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 5.1; U;) Presto/2.7.62 Version/11.01"
+"Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.7.62 Version/11.01"
+"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101213 Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.7.62 Version/11.01"
+"Mozilla/5.0 (Windows NT 6.1; U; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01"
+"Mozilla/5.0 (Windows NT 6.1; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.01"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01"
+"Opera/9.80 (X11; Linux x86_64; U; pl) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (X11; Linux i686; U; it) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.37 Version/11.00"
+"Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 6.1; U; ko) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 6.1; U; en-GB) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 6.1 x64; U; en) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.7.39 Version/11.00"
+"Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.7.39 Version/11.00"
+"Opera/9.80 (Windows NT 5.1; U; MRA 5.5 (build 02842); ru) Presto/2.7.62 Version/11.00"
+"Opera/9.80 (Windows NT 5.1; U; it) Presto/2.7.62 Version/11.00"
+"Mozilla/5.0 (Windows NT 6.0; U; ja; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.00"
+"Mozilla/5.0 (Windows NT 5.1; U; pl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.00"
+"Mozilla/5.0 (Windows NT 5.1; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 11.00"
+"Mozilla/4.0 (compatible; MSIE 8.0; X11; Linux x86_64; pl) Opera 11.00"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; fr) Opera 11.00"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; ja) Opera 11.00"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; en) Opera 11.00"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; pl) Opera 11.00"
+"Opera/9.80 (Windows NT 6.1; U; pl) Presto/2.6.31 Version/10.70"
+"Mozilla/5.0 (Windows NT 5.2; U; ru; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.70"
+"Mozilla/5.0 (Windows NT 5.1; U; zh-cn; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.70"
+"Opera/9.80 (Windows NT 5.2; U; zh-cn) Presto/2.6.30 Version/10.63"
+"Opera/9.80 (Windows NT 5.2; U; en) Presto/2.6.30 Version/10.63"
+"Opera/9.80 (Windows NT 5.1; U; MRA 5.6 (build 03278); ru) Presto/2.6.30 Version/10.63"
+"Opera/9.80 (Windows NT 5.1; U; pl) Presto/2.6.30 Version/10.62"
+"Mozilla/5.0 (X11; Linux x86_64; U; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.62"
+"Mozilla/4.0 (compatible; MSIE 8.0; X11; Linux x86_64; de) Opera 10.62"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; en) Opera 10.62"
+"Opera/9.80 (X11; Linux i686; U; pl) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (X11; Linux i686; U; es-ES) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (Windows NT 6.0; U; it) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (Windows 98; U; de) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (Macintosh; Intel Mac OS X; U; nl) Presto/2.6.30 Version/10.61"
+"Opera/9.80 (X11; Linux i686; U; en) Presto/2.5.27 Version/10.60"
+"Opera/9.80 (Windows NT 6.0; U; nl) Presto/2.6.30 Version/10.60"
+"Opera/10.60 (Windows NT 5.1; U; zh-cn) Presto/2.6.30 Version/10.60"
+"Opera/10.60 (Windows NT 5.1; U; en-US) Presto/2.6.30 Version/10.60"
+"Opera/9.80 (X11; Linux i686; U; it) Presto/2.5.24 Version/10.54"
+"Opera/9.80 (X11; Linux i686; U; en-GB) Presto/2.5.24 Version/10.53"
+"Mozilla/5.0 (Windows NT 5.1; U; zh-cn; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53"
+"Mozilla/5.0 (Windows NT 5.1; U; Firefox/5.0; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53"
+"Mozilla/5.0 (Windows NT 5.1; U; Firefox/4.5; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53"
+"Mozilla/5.0 (Windows NT 5.1; U; Firefox/3.5; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53"
+"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; ko) Opera 10.53"
+"Opera/9.80 (Windows NT 6.1; U; fr) Presto/2.5.24 Version/10.52"
+"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.5.22 Version/10.51"
+"Opera/9.80 (Windows NT 6.0; U; cs) Presto/2.5.22 Version/10.51"
+"Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51"
+"Opera/9.80 (Linux i686; U; en) Presto/2.5.22 Version/10.51"
+"Mozilla/5.0 (Windows NT 6.1; U; en-GB; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.51"
+"Mozilla/5.0 (Linux i686; U; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.51"
+"Mozilla/4.0 (compatible; MSIE 8.0; Linux i686; en) Opera 10.51"
+"Opera/9.80 (Windows NT 6.1; U; zh-tw) Presto/2.5.22 Version/10.50"
+"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.5.22 Version/10.50"
+"Opera/9.80 (Windows NT 6.1; U; sk) Presto/2.6.22 Version/10.50"
+"Opera/9.80 (Windows NT 6.1; U; ja) Presto/2.5.22 Version/10.50"
+"Opera/9.80 (Windows NT 6.0; U; zh-cn) Presto/2.5.22 Version/10.50"
+"Opera/9.80 (Windows NT 5.1; U; sk) Presto/2.5.22 Version/10.50"
+"Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.5.22 Version/10.50"
+"Opera/10.50 (Windows NT 6.1; U; en-GB) Presto/2.2.2"
+"Opera/9.80 (S60; SymbOS; Opera Tablet/9174; U; en) Presto/2.7.81 Version/10.5"
+"Opera/9.80 (X11; U; Linux i686; en-US; rv:1.9.2.3) Presto/2.2.15 Version/10.10"
+"Opera/9.80 (X11; Linux x86_64; U; it) Presto/2.2.15 Version/10.10"
+"Opera/9.80 (Windows NT 6.1; U; de) Presto/2.2.15 Version/10.10"
+"Opera/9.80 (Windows NT 6.0; U; Gecko/20100115; pl) Presto/2.2.15 Version/10.10"
+"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.10"
+"Opera/9.80 (Windows NT 5.1; U; de) Presto/2.2.15 Version/10.10"
+"Opera/9.80 (Windows NT 5.1; U; cs) Presto/2.2.15 Version/10.10"
+"Mozilla/5.0 (Windows NT 6.0; U; tr; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 10.10"
+"Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686; de) Opera 10.10"
+"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.0; tr) Opera 10.10"
+"Opera/9.80 (X11; Linux x86_64; U; en-GB) Presto/2.2.15 Version/10.01"
+"Opera/9.80 (X11; Linux x86_64; U; en) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux x86_64; U; de) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; ru) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; pt-BR) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; pl) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; nb) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; en-GB) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; en) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; Debian; pl) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (X11; Linux i686; U; de) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.1; U; fi) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.1; U; de) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.1; U; cs) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.0; U; en) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 6.0; U; de) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 5.2; U; en) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 5.1; U; zh-cn) Presto/2.2.15 Version/10.00"
+"Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.2.15 Version/10.00"
\ No newline at end of file
Index: REL-0.2/basico/data/icons/annotation.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/annotation.png
===================================================================
--- REL-0.2/basico/data/icons/annotation.png (nonexistent)
+++ REL-0.2/basico/data/icons/annotation.png (revision 76)
/REL-0.2/basico/data/icons/annotation.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/export.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/export.png
===================================================================
--- REL-0.2/basico/data/icons/export.png (nonexistent)
+++ REL-0.2/basico/data/icons/export.png (revision 76)
/REL-0.2/basico/data/icons/export.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/basico.xcf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/basico.xcf
===================================================================
--- REL-0.2/basico/data/icons/basico.xcf (nonexistent)
+++ REL-0.2/basico/data/icons/basico.xcf (revision 76)
/REL-0.2/basico/data/icons/basico.xcf
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/plugin.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/plugin.png
===================================================================
--- REL-0.2/basico/data/icons/plugin.png (nonexistent)
+++ REL-0.2/basico/data/icons/plugin.png (revision 76)
/REL-0.2/basico/data/icons/plugin.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/browse.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/browse.png
===================================================================
--- REL-0.2/basico/data/icons/browse.png (nonexistent)
+++ REL-0.2/basico/data/icons/browse.png (revision 76)
/REL-0.2/basico/data/icons/browse.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/noproject.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/noproject.png
===================================================================
--- REL-0.2/basico/data/icons/noproject.png (nonexistent)
+++ REL-0.2/basico/data/icons/noproject.png (revision 76)
/REL-0.2/basico/data/icons/noproject.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/unbookmark.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/unbookmark.png
===================================================================
--- REL-0.2/basico/data/icons/unbookmark.png (nonexistent)
+++ REL-0.2/basico/data/icons/unbookmark.png (revision 76)
/REL-0.2/basico/data/icons/unbookmark.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/icons/export-basico.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: REL-0.2/basico/data/icons/export-basico.png
===================================================================
--- REL-0.2/basico/data/icons/export-basico.png (nonexistent)
+++ REL-0.2/basico/data/icons/export-basico.png (revision 76)
/REL-0.2/basico/data/icons/export-basico.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: REL-0.2/basico/data/desktop/basico.desktop
===================================================================
--- REL-0.2/basico/data/desktop/basico.desktop (nonexistent)
+++ REL-0.2/basico/data/desktop/basico.desktop (revision 76)
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Exec=basico
+Name=basico
+Comment=SAP Notes manager for SAP Consultants
+Icon=basico
+Categories=GTK;GNOME;Utility;
+StartupNotify=True
Index: REL-0.2/basico/sap.py
===================================================================
--- REL-0.2/basico/sap.py (nonexistent)
+++ REL-0.2/basico/sap.py (revision 76)
@@ -0,0 +1,207 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: sap.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: SAP service
+
+import time
+import traceback
+from shutil import which
+
+from .service import Service
+
+#~ ODATA_NOTE_URL = "https://launchpad.support.sap.com/services/odata/svt/snogwscorr/TrunkSet(SapNotesNumber='%s',Version='0',Language='E')" #$expand=LongText" #?$expand=LongText,RefTo,RefBy"
+ODATA_NOTE_URL = "https://launchpad.support.sap.com/services/odata/svt/snogwscorr/TrunkSet(SapNotesNumber='%s',Version='0',Language='en')"
+#~ ODATA_NOTE_URL = "https://launchpad.support.sap.com/services/odata/svt/snogwscorr/TrunkSet(SapNotesNumber='%s',Version='0',Language='E')?$expand=LongText,Languages,RefTo,RefBy"
+#~ ODATA_NOTE_URL = "https://launchpad.support.sap.com/services/odata/svt/snogwscorr/TrunkSet(SapNotesNumber='%s',Version='0',Language='E')?$expand=LongText,Languages,RefTo,RefBy"
+SAP_NOTE_URL = "https://launchpad.support.sap.com/#/notes/%s"
+SAP_NOTE_URL_PDF = "https://launchpad.support.sap.com/services/pdf/notes/%s/E"
+
+
+class SAP(Service):
+ def initialize(self):
+ '''
+ Setup AppLogic Service
+ '''
+ self.__init_config_section()
+
+
+ def __init_config_section(self):
+ prefs = self.get_service('Settings')
+ self.config = self.app.get_config()
+ if self.config.has_section(self.section):
+ options = self.config.options(self.section)
+ if len(options) == 0:
+ self.log.debug("Section %s empty. Initializing with default values" % self.section)
+ settings = prefs.get_default_settings()
+ self.config[self.section] = settings
+ self.log.debug("Default parameters loaded:")
+ for key in settings:
+ self.log.debug("\tKey: %s - Value: %s" % (key, settings[key]))
+ self.save_config()
+
+
+ def analyze_sapnote_metadata(self, sid, content):
+ '''
+ Get metadata details from SAP Note
+ '''
+ #~ self.log.debug("\t%s" % content)
+ try:
+ utils = self.get_service('Utils')
+ f = utils.feedparser_parse(content)
+ sid = f.entries[0].d_sapnotesnumber
+ sapnote = {}
+ sapnote['id'] = sid
+ sapnote['componentkey'] = f.entries[0].d_componentkey
+ comptxt = f.entries[0].d_componenttext
+ if comptxt == "Please use note 1433157 for finding the right component":
+ comptxt = ""
+ sapnote['componenttxt'] = comptxt
+ sapnote['category'] = f.entries[0].d_category_detail['value']
+ sapnote['language'] = f.entries[0].d_languagetext_detail['value']
+ sapnote['title'] = f.entries[0].d_title_detail['value']
+ sapnote['priority'] = f.entries[0].d_priority_detail['value']
+ sapnote['releaseon'] = f.entries[0].d_releasedon
+ sapnote['type'] = f.entries[0].d_type_detail['value']
+ sapnote['version'] = f.entries[0].d_version_detail['value']
+ sapnote['feedupdate'] = f.entries[0].updated
+ sapnote['bookmark'] = False
+ self.log.info ("\tSAP Note %s analyzed successfully" % sid)
+ except Exception as error:
+ sapnote = {}
+ self.log.error("\tError while analyzing data for SAP Note %s" % sid)
+ #~ self.log.error("\t%s" % error)
+
+ return sapnote
+
+
+ def fetch(self, sid):
+ db = self.get_service('DB')
+ valid = False
+ #~ self.log.debug("%3d/%3d - Fetching SAP Note %s" % (self.notes_fetched+1, self.notes_total, sid))
+
+ if not db.is_stored(sid):
+ self.log.debug("%3d/%3d - SAP Note %s must be downloaded" % (self.notes_fetched+1, self.notes_total, sid))
+ content = self.download(sid)
+ if len(content) > 0:
+ self.log.debug("%3d/%3d - SAP Note %s fetched" % (self.notes_fetched+1, self.notes_total, sid))
+ else:
+ self.log.debug("%3d/%3d - SAP Note %s not feched" % (self.notes_fetched+1, self.notes_total, sid))
+ else:
+ self.log.debug("%3d/%3d - SAP Note %s will be analyzed again" % (self.notes_fetched+1, self.notes_total, sid))
+ content = db.get_sapnote_content(sid)
+
+ self.fetched()
+
+ sapnote = self.analyze_sapnote_metadata(sid, content)
+ if len(sapnote) > 0:
+ db = self.get_service('DB')
+ db.add(sapnote)
+ db.store(sid, content)
+ valid = True
+
+ return valid, sid
+
+
+ def start_fetching(self, total):
+ self.notes_fetched = 0
+ self.notes_total = total
+
+
+ def fetched(self):
+ self.notes_fetched += 1
+
+
+ def stop_fetching(self):
+ self.notes_fetched = 0
+ self.notes_total = 0
+
+
+ def download(self, sapnote=None):
+ try:
+ driver = self.get_service('Driver')
+ #~ browser = driver.open()
+ #~ self.log.debug("\tDownloading SAP Note %s:" % sapnote)
+ #~ self.log.debug(ODATA_NOTE_URL % sapnote)
+ browser = driver.load(ODATA_NOTE_URL % sapnote)
+ time.sleep(5)
+ content = browser.page_source
+ #~ self.log.debug("\t%3d - SAP Note %s downloaded" % (sapnote, driver.)
+ #~ else:
+ #~ content = ''
+ except Exception as error:
+ #~ self.log.error("\tSAP Note %s coud not be downloaded" % sapnote)
+ self.log.error(error)
+ content = ''
+
+ return content
+
+
+ def get_linked_projects(self, sapnote):
+ try:
+ projects = self.sapnotes[sapnote]['projects']
+ except Exception as error:
+ projects = []
+
+ return projects
+
+
+ def get_linked_tasks(self, sapnote):
+ try:
+ tasks = self.sapnotes[sapnote]['tasks']
+ except Exception as error:
+ tasks = []
+ self.log.debug("Tasks: %s" % tasks)
+ return tasks
+
+
+ def link_to_task(self, sapnotes, tasks):
+ if len(sapnotes) == 0:
+ self.log.debug("No SAP Notes selected. No task will be linked.")
+ return
+
+ db = self.get_service('DB')
+ store = db.get_notes()
+
+ for tid in sapnotes:
+ sid = "0"*(10 - len(tid)) + tid
+ store[sid]['tasks'] = tasks
+ self.log.info("Linked SAP Note %s to task(s): %s" % (sid, tasks) )
+
+
+ def set_bookmark(self, bag):
+ db = self.get_service('DB')
+ sapnotes = db.get_notes()
+ mylist = []
+ for tid in bag:
+ sid = "0"*(10 - len(tid)) + tid
+ sapnotes[sid]['bookmark'] = True
+ mylist.append(sapnotes[sid])
+ self.log.info("SAP Note %s bookmarked" % sid)
+ db.add_list(mylist)
+
+
+ def set_no_bookmark(self, bag):
+ db = self.get_service('DB')
+ sapnotes = db.get_notes()
+ mylist = []
+ for tid in bag:
+ sid = "0"*(10 - len(tid)) + tid
+ sapnotes[sid]['bookmark'] = False
+ mylist.append(sapnotes[sid])
+ self.log.info("SAP Note %s unbookmarked" % sid)
+ db.add_list(mylist)
+
+
+ def is_bookmark(self, sapnote):
+ try:
+ return self.sapnotes[sapnote]['bookmark']
+ except:
+ return False
+
+
+ def run(self):
+ db = self.get_service('DB')
+ db.load_notes()
+ db.build_stats()
Index: REL-0.2/basico/basico.py
===================================================================
--- REL-0.2/basico/basico.py (nonexistent)
+++ REL-0.2/basico/basico.py (revision 76)
@@ -0,0 +1,258 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+# File: basico.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Main entry point por Basico app
+import os
+# -*- coding: utf-8 -*-
+import sys
+import codecs
+sys.stdout = codecs.getwriter("iso-8859-1")(sys.stdout, 'xmlcharrefreplace')
+import traceback as tb
+import imp
+import signal
+from pprint import pprint
+from os.path import abspath, sep as SEP
+from configparser import SafeConfigParser, ExtendedInterpolation
+# import urllib.request
+
+import selenium
+
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+
+from .utils import Utils
+from .log import get_logger
+from .gui import GUI
+from .iconmanager import IconManager
+from .sap import SAP
+from .settings import Settings
+from .uifuncs import UIFuncs
+from .menus import Menus
+from .projects import Projects
+from .tasks import Tasks
+from .plugins import Plugins
+from .callbacks import Callback
+from .notify import Notification
+#from .stats import Stats
+from .database import Database
+from .driver import SeleniumDriver
+from .env import ROOT, APP, LPATH, GPATH, FILE
+
+
+class Basico:
+ def __init__(self):
+ """Main class: the entry point for Basico.
+ It stands for Controller.
+ """
+
+ # Create local paths if they do not exist
+ for entry in LPATH:
+ if not os.path.exists(LPATH[entry]):
+ os.makedirs(LPATH[entry])
+
+
+ self.log = get_logger(self.__class__.__name__, FILE['LOG'])
+ #~ self.log.info("Starting Basico")
+
+ self.services = {}
+ try:
+ services = {
+ 'GUI' : GUI(),
+ 'Utils' : Utils(),
+ 'UIF' : UIFuncs(),
+ 'Menus' : Menus(),
+ 'SAP' : SAP(),
+ 'Settings' : Settings(),
+ 'Notify' : Notification(),
+ 'Tasks' : Tasks(),
+ 'IM' : IconManager(),
+ 'Plugins' : Plugins(),
+ 'Callbacks' : Callback(),
+ #'Stats' : Stats(),
+ 'DB' : Database(),
+ 'Driver' : SeleniumDriver()
+ }
+ self.register_services(services)
+ except Exception as error:
+ self.log.error(error)
+ raise
+
+
+ def setup(self):
+ """
+ Setup Basico Envrionment
+ Info about ConfigParser options:
+ https://docs.python.org/3/library/configparser.html#interpolation-of-values
+ https://docs.python.org/3/library/configparser.html#configparser.ConfigParser.optionxform
+ """
+ self.log.debug("Setting up Basico environment")
+ self.log.debug("Global path: %s" % GPATH['ROOT'])
+ self.log.debug("Local path: %s" % LPATH['ROOT'])
+
+ # Set up config
+ CONFIG_FILE = self.get_file('CNF')
+ self.config = SafeConfigParser(interpolation=ExtendedInterpolation())
+ self.config.optionxform = str
+
+ # Save config
+ if not os.path.exists(CONFIG_FILE):
+ self.log.debug('Configuration file not found. Creating a new one')
+ with open(CONFIG_FILE, 'w') as configfile:
+ self.config.write(configfile)
+ self.log.info('Config file initialited')
+
+
+ def get_config(self):
+ CONFIG_FILE = self.get_file('CNF')
+ self.config.read(CONFIG_FILE)
+
+ return self.config
+
+
+ def get_file(self, name):
+ try:
+ return FILE[name]
+ except:
+ self.log.error(self.get_traceback())
+
+
+ def get_app_info(self, var):
+ try:
+ return APP[var]
+ except:
+ return None
+
+
+ def get_var(self, name, scope='global'):
+ if scope == 'global':
+ return GPATH[name]
+ else:
+ return LPATH[name]
+
+
+ def list_services(self):
+ """Return a dictionary of services"""
+ return self.services
+
+
+ def get_service(self, name):
+ """Get/Start a registered service
+ @type name: name of the service
+ @param name: given a service name it returns the associated
+ class. If service was not running it is started.
+ """
+ try:
+ service = self.services[name]
+ if service.is_started():
+ return service
+ else:
+ service.start(self, name)
+ return service
+ except KeyError as service:
+ self.log.error("Service %s not registered or not found" % service)
+ raise
+
+
+ def register_services(self, services):
+ """Register a list of services
+ @type services: dict
+ @param services: a dictionary of name:class for each service
+ """
+ for name in services:
+ self.register_service(name, services[name])
+
+
+ def register_service(self, name, service):
+ """Register a new service
+ @type name: string
+ @param name: name of the service
+ @type service: class
+ @param service: class which contains the code
+ """
+ try:
+ self.services[name] = service
+ except Exception as error:
+ self.log.error(error)
+
+
+ def deregister_service(self, name):
+ """Deregister a running service
+ @type name: string
+ @param name: name of the service
+ """
+ self.services[name].end()
+ self.services[name] = None
+ self.log.debug("Service %s stopped" % name)
+
+
+ def check(self):
+ '''
+ Check Basico environment
+ '''
+ utils = self.get_service("Utils")
+ uif = self.get_service('UIF')
+ driver = self.get_service('Driver')
+
+ # Show Selenium version
+ self.log.debug("Selenium version: %s" % selenium.__version__)
+
+ # Check proper GTK version
+ GTK_VERSION = uif.check_gtk_version()
+
+ # Check Gecko webdrver
+ GECKO_DRIVER = driver.check()
+
+ run = GTK_VERSION and GECKO_DRIVER
+
+ if run:
+ self.log.info("Basico environment ready!")
+ return True
+ else:
+ self.log.error("Error(s) found checking Basico environment")
+ return False
+
+
+
+
+ def stop(self):
+ """For each service registered, it executes the 'end' method
+ (if any) to finalize them properly.
+ """
+
+ # Deregister all services loaded
+ self.deregister_service('GUI')
+ for name in self.services:
+ try:
+ if name != 'GUI':
+ self.deregister_service(name)
+ except Exception as error:
+ self.log.error(self.get_traceback())
+ raise
+
+ self.log.info("Basico finished")
+
+
+ def get_traceback(self):
+ return tb.format_exc()
+
+
+ def run(self):
+ try:
+ self.gui = self.get_service('GUI')
+ self.gui.run()
+ except:
+ self.log.error(self.get_traceback())
+
+
+def main():
+ #DOC: http://stackoverflow.com/questions/16410852/keyboard-interrupt-with-with-python-gtk
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
+ basico = Basico()
+ basico.setup()
+ ok = basico.check()
+ if ok:
+ basico.run()
+ sys.exit(0)
Index: REL-0.2/basico/stats.py
===================================================================
--- REL-0.2/basico/stats.py (nonexistent)
+++ REL-0.2/basico/stats.py (revision 76)
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: stats.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Stats service
+
+import pygal
+from pygal import Config
+
+from .service import Service
+
+
+class Stats(Service):
+ def initialize(self):
+ self.get_services()
+
+ def get_html(self, filename):
+ fin = open(filename, 'r')
+ html = fin.read()
+ fin.close()
+
+ return html
+
+
+ def get_services(self):
+ self.sap = self.app.get_service('SAP')
+
+ def build_pie_maincomp(self):
+ db = self.get_service('DB')
+ stats = db.get_stats()
+ CHART_FILE = self.app.get_var('TMP', 'local') + 'chart.svg'
+ config = Config()
+ config.show_legend = True
+ config.legend_at_bottom = True
+ config.print_values = True
+ config.print_values_position = 'top'
+ config.print_labels = True
+ #~ config.dynamic_print_values = True
+ config.human_readable = True
+ config.fill = True
+ #~ chart = pygal.XY(config)
+ pie_chart = pygal.HorizontalBar(config)
+ pie_chart.title = 'Main components used'
+ for key in stats['maincomp']:
+ value = stats['maincomp'][key]
+ label = "%s (%d)" % (key, value)
+ pie_chart.add(label, value)
+ pie_chart.render_to_file(CHART_FILE)
+
+ return self.get_html(CHART_FILE)
+
+
+ def build_pie_categories(self):
+ db = self.get_service('DB')
+ stats = db.get_stats()
+ CHART_FILE = self.app.get_var('TMP', 'local') + 'chart.svg'
+ config = Config()
+ config.show_legend = True
+ config.legend_at_bottom = True
+ config.print_values = True
+ config.print_values_position = 'top'
+ config.print_labels = True
+ #~ config.rounded_bars=20
+ #~ config.dynamic_print_values = True
+ config.human_readable = True
+ config.fill = True
+ #~ chart = pygal.XY(config)
+ pie_chart = pygal.HorizontalBar(config)
+ pie_chart.title = 'By categories'
+ for key in stats['cats']:
+ value = stats['cats'][key]
+ label = "%s (%d)" % (key, value)
+ pie_chart.add(label, value)
+ pie_chart.render_to_file(CHART_FILE)
+
+ return self.get_html(CHART_FILE)
Index: REL-0.2/basico/window.py
===================================================================
--- REL-0.2/basico/window.py (nonexistent)
+++ REL-0.2/basico/window.py (revision 76)
@@ -0,0 +1,555 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: window.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Gtk.ApplicationWindow implementation
+
+import os
+import stat
+import threading
+import time
+import platform
+
+import gi
+gi.require_version('Gtk', '3.0')
+gi.require_version('WebKit', '3.0')
+
+from gi.repository import GLib
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository import WebKit
+from gi.repository.GdkPixbuf import Pixbuf
+
+from .log import get_logger
+from .sapnoteview import SAPNoteView
+
+
+MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monospace'
+
+class GtkAppWindow(Gtk.ApplicationWindow):
+ def __init__(self, uiapp):
+ self.setup_controller(uiapp)
+ self.get_services()
+ self.gui.add_widget('uiapp', uiapp)
+ self.gui.set_key('cmbvalue', 'search')
+ self.settings = {}
+ self.settings['fullscreen'] = False
+ self.current_notes = {}
+
+ self.setup_window()
+ self.setup_widgets()
+ self.setup_app()
+
+
+ def setup_controller(self, uiapp):
+ self.uiapp = uiapp
+ self.controller = uiapp.get_controller()
+
+
+ def setup_app(self):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ searchentry = self.gui.get_widget("stySearchInfo")
+ viewlabel = self.gui.get_widget('lblViewCurrent')
+ try:
+ name = sapnoteview.get_view()
+ except:
+ name = 'components'
+ sapnoteview.set_view(name)
+ label = "<span size='20000'><b>%-10s</b></span>" % name.capitalize()
+ viewlabel.set_markup(label)
+ self.cb.refresh_view()
+ searchentry.set_text('')
+ self.cb.search_notes()
+ sapnoteview.check_states()
+
+
+ def setup_window(self):
+ app_title = self.controller.get_app_info('name')
+ Gtk.Window.__init__(self, title=app_title, application=self.uiapp)
+ self.gui.add_widget('mainwindow', self)
+ icon = self.im.get_icon('basico')
+ self.set_icon(icon)
+ # FIXME
+ # From docs: Don’t use this function. It sets the X xlib.Window
+ # System “class” and “name” hints for a window.
+ # But I have to do it or it doesn't shows the right title. ???
+ self.set_wmclass (app_title, app_title)
+ self.set_role(app_title)
+ self.set_default_size(1024, 728)
+ self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
+ #~ self.connect('destroy', Gtk.main_quit)
+ self.show_all()
+
+
+ def setup_menu_views(self):
+ # View label
+ self.gui.add_widget('lblViewCurrent')
+
+ ## Views Menu
+ views_menu = self.gui.add_widget('mnuviews', Gio.Menu())
+
+ # Last added view
+ #~ TODO
+ #~ views_menu.append_item(self.uif.create_item('View last added', 'app.view-lastadded', ''))
+ #~ self.app.add_action(self.uif.create_action("view-lastadded", self.cb_show_dlnotes_window))
+
+ # Most used view
+ #~ TODO
+ #~ views_menu.append_item(self.uif.create_item('View most used', 'app.view-mostused', ''))
+ #~ self.app.add_action(self.uif.create_action("view-mostused", self.cb_show_dlnotes_window))
+
+ # Tasks view
+ views_menu.append_item(self.uif.create_item('View by tasks', 'app.view-tasks', 'emblem-system'))
+ self.app.add_action(self.uif.create_action("view-tasks", self.cb.refresh_view, 'tasks'))
+
+ # Projects view
+ #~ views_menu.append_item(self.uif.create_item('View by projects', 'app.view-projects', ''))
+ #~ self.app.add_action(self.uif.create_action("view-projects", self.cb.refresh_view, 'projects'))
+
+ # Components view
+ views_menu.append_item(self.uif.create_item('View by components', 'app.view-components', ''))
+ self.app.add_action(self.uif.create_action("view-components", self.cb.refresh_view, 'components'))
+
+ # Component descriptions view
+ views_menu.append_item(self.uif.create_item('View by component description', 'app.view-component-descriptions', ''))
+ self.app.add_action(self.uif.create_action("view-component-descriptions", self.cb.refresh_view, 'description'))
+
+ # Bookmarks view
+ views_menu.append_item(self.uif.create_item('View bookmarks', 'app.view-bookmarks', ''))
+ self.app.add_action(self.uif.create_action("view-bookmarks", self.cb.refresh_view, 'bookmarks'))
+
+ # Category view
+ views_menu.append_item(self.uif.create_item('View categories', 'app.view-categories', ''))
+ self.app.add_action(self.uif.create_action("view-categories", self.cb.refresh_view, 'category'))
+
+ # Chronologic order view
+ views_menu.append_item(self.uif.create_item('View in chronologic order', 'app.chronologic-order', ''))
+ self.app.add_action(self.uif.create_action("chronologic-order", self.cb.refresh_view, 'chronologic'))
+
+ # Priority view
+ views_menu.append_item(self.uif.create_item('View by priority', 'app.view-priority', ''))
+ self.app.add_action(self.uif.create_action("view-priority", self.cb.refresh_view, 'priority'))
+
+ # SAP Note Type view
+ views_menu.append_item(self.uif.create_item('View by type', 'app.view-type', ''))
+ self.app.add_action(self.uif.create_action("view-type", self.cb.refresh_view, 'type'))
+
+ # Annotations view
+ #~ TODO
+ #~ views_menu.append_item(self.uif.create_item('View by annotations', 'app.view-annotations', ''))
+ #~ self.app.add_action(self.uif.create_action("view-annotations", self.cb_show_dlnotes_window))
+
+ # Set menu model in button
+ btnviews = self.gui.get_widget('mnuBtnViews')
+ btnviews.set_menu_model(views_menu)
+
+
+ def setup_menu_settings(self):
+ ### SETTINGS POPOVER
+ menu = Gio.Menu()
+ #~ self.gui.add_widget("menu", menu)
+ menu.append_item(self.uif.create_item('Fullscreen', 'app.settings-fullscreen', 'gtk-fullscreen'))
+ menu.append_item(self.uif.create_item('Rename current project', 'app.project-rename', 'preferences-desktop-personal'))
+ menu.append_item(self.uif.create_item('Refresh current project', 'app.project-refresh', 'view-refresh'))
+ menu.append_item(self.uif.create_item('Close current project', 'app.project-close', 'window-close'))
+ menu.append_item(self.uif.create_item('Delete current project', 'app.project-delete', 'list-remove'))
+ menu.append_item(self.uif.create_item('Export current project', 'app.project-delete', 'document-save-as'))
+ window = self.gui.get_window()
+ window.set_app_menu(menu)
+ app = self.gui.get_app()
+ app.add_action(self.uif.create_item("settings-fullscreen"))
+
+ #~ popover_action_group = Gio.SimpleActionGroup()
+ btnsettings = self.gui.get_widget("mnuBtnViews")
+ popover_settings = Gtk.Popover.new_from_model(btnsettings, menu)
+ popover_settings.set_position(Gtk.PositionType.BOTTOM)
+ btnsettings.connect('clicked', lambda _: popover_settings.show_all())
+
+
+ def setup_menus(self):
+ self.setup_menu_views()
+ #~ self.setup_menu_actions()
+ #~ self.setup_menu_settings()
+
+
+ def show_home_page(self, *args):
+ notebook = self.gui.get_widget('notebook')
+ notebook.set_current_page(0)
+
+
+ def show_settings_page(self, *args):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnoteview.set_view('settings')
+ notebook = self.gui.get_widget('notebook')
+ notebook.set_current_page(2)
+
+
+ def show_stats_page(self, *args):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnoteview.set_view('stats')
+ notebook = self.gui.get_widget('notebook')
+ notebook.set_current_page(4)
+
+
+ def show_browser_page(self, *args):
+ notebook = self.gui.get_widget('notebook')
+ notebook.set_current_page(1)
+
+
+ def show_search(self, *args):
+ revsearch = self.gui.get_widget('revSearch')
+ tgbsearch = self.gui.get_widget('tgbSearch')
+ if tgbsearch.get_active():
+ revsearch.set_reveal_child(True)
+ revsearch.set_no_show_all(False)
+ revsearch.show_all()
+ else:
+ revsearch.set_reveal_child(False)
+ revsearch.set_no_show_all(True)
+ revsearch.hide()
+
+
+ def hide_props_window(self):
+ hpnnotes = self.gui.get_widget('hpnNotesManager')
+ boxprops = self.gui.get_widget('boxPropsWidget')
+ size = hpnnotes.get_allocation()
+
+ boxprops.set_no_show_all(True)
+ boxprops.hide()
+ hpnnotes.set_position(size.width)
+
+
+ def show_props_window(self):
+ hpnnotes = self.gui.get_widget('hpnNotesManager')
+ boxprops = self.gui.get_widget('boxPropsWidget')
+ size = hpnnotes.get_allocation()
+
+ boxprops.set_no_show_all(False)
+ boxprops.show_all()
+ hpnnotes.show_all()
+ hpnnotes.set_position(size.width/5*3)
+
+
+ def switch_props_window(self, *args):
+ tgbprops = self.gui.get_widget('tgbShowManage')
+
+ if tgbprops.get_active():
+ self.show_props_window()
+ else:
+ self.hide_props_window()
+
+
+ def setup_widgets(self):
+ self.mainbox = self.gui.get_widget('mainbox')
+ self.mainbox.reparent(self)
+
+ statusbar = self.gui.get_widget('pgbMain')
+ statusbar.set_text("")
+ statusbar.set_show_text(True)
+ statusbar.set_fraction(0.0)
+ self.setup_menus()
+ #~ self.tasks.setup_widgets()
+ notesbox = self.gui.get_widget('notesbox')
+ sapnoteview = SAPNoteView(self.controller)
+ self.gui.add_widget('sapnoteview', sapnoteview)
+ self.gui.add_widget('combobox')
+ search = self.gui.add_widget('stySearchInfo')
+ #~ search.connect('search_changed', self.search_notes)
+ search.connect('activate', self.cb.search_notes)
+ self.setup_combobox_search()
+ self.swap_widget(notesbox, sapnoteview)
+
+
+ self.setup_props_window()
+
+
+ # Buttons
+ # Task link button
+ self.cb.check_task_link_button_status()
+
+ # button quit
+ image = self.gui.get_widget('imgBtnQuit')
+ icon = self.im.get_pixbuf_icon('power', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('btnQuit')
+ button.connect('clicked', self.gui.quit)
+
+ # button about
+ image = self.gui.get_widget('imgBtnAbout')
+ icon = self.im.get_pixbuf_icon('about', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('btnAbout')
+ button.connect('clicked', self.uiapp.cb_show_about)
+
+ # button settings
+ image = self.gui.get_widget('imgBtnSettings')
+ icon = self.im.get_pixbuf_icon('settings', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('btnSettings')
+ button.connect('clicked', self.show_settings_page)
+
+ # button stats
+ image = self.gui.get_widget('imgBtnStats')
+ icon = self.im.get_pixbuf_icon('chart', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('btnShowStats')
+ button.connect('clicked', self.show_stats_page)
+
+ # button show property details
+ image = self.gui.get_widget('imgBtnShowProps')
+ icon = self.im.get_pixbuf_icon('fingerprint', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('btnShowProperties')
+ button.connect('clicked', self.cb.show_properties)
+
+ # button show manage window
+ image = self.gui.get_widget('imgBtnShowManage')
+ icon = self.im.get_pixbuf_icon('subwindow', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('tgbShowManage')
+ button.connect('toggled', self.switch_props_window)
+
+ # button search
+ image = self.gui.get_widget('imgBtnSearch')
+ icon = self.im.get_pixbuf_icon('bsearch', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('tgbSearch')
+ button.connect('toggled', self.show_search)
+ revsearch = self.gui.get_widget('revSearch')
+ revsearch.hide()
+ revsearch.set_no_show_all(True)
+
+ # button import
+ image = self.gui.get_widget('imgMnuBtnImport')
+ icon = self.im.get_pixbuf_icon('import', 48, 48)
+ image.set_from_pixbuf(icon)
+ #~ button = self.gui.get_widget('mnuBtnImport')
+ #~ button.connect('toggled', self.switch_props_window)
+
+ # button refresh
+ image = self.gui.get_widget('imgBtnRefresh')
+ icon = self.im.get_pixbuf_icon('refresh', 48, 48)
+ image.set_from_pixbuf(icon)
+ button = self.gui.get_widget('btnRefreshSAPNoteView')
+ button.connect('clicked', self.cb.refresh_and_clear_view)
+
+
+ button = self.gui.get_widget('btnLinkTasksApply')
+ button.connect('clicked', self.cb.link_tasks_to_sapnotes)
+
+
+
+ btnaddnote = self.gui.get_widget('btnStartDlNotes')
+ btnaddnote.connect('clicked', self.cb.import_notes)
+
+
+
+ #~ btnShowAddSAPNotesDlg = self.gui.get_widget('btnShowAddSAPNotesDlg')
+ #~ btnShowAddSAPNotesDlg.connect('clicked', self.show_addsapnotes_dialog)
+
+ btnStopDlNotes = self.gui.get_widget('btnStopDlNotes')
+ btnStopDlNotes.connect('clicked', self.cb.stop_dl_notes)
+
+ #~ toggle= self.gui.get_widget('tgbFullScreen')
+ #~ toggle.connect('toggled', self.uif.fullscreen)
+ switch = self.gui.get_widget('schExpandCollapse')
+ switch.connect('state-set', sapnoteview.expand_collapse)
+ switch = self.gui.get_widget('schSelectNotesAllNone')
+ switch.connect('state-set', sapnoteview.select_all_none)
+
+
+ # Actions button
+ button = self.gui.get_widget('mnuBtnActions')
+
+ # Prefs for SAP module
+ button = self.gui.add_widget('btnPrefsSAPApply')
+ button.connect('clicked', self.cb.apply_preferences)
+
+ button = self.gui.add_widget('btnPrefsSAPCancel')
+ button.connect('clicked', self.cb.refresh_view)
+
+ button = self.gui.add_widget('btnPrefsSAPReset')
+ button.connect('clicked', self.cb.default_preferences)
+
+ # Notebook Import Widget
+ #~ ntbimport = self.gui.add_widget('ntbAddSAPNotes')
+
+ sap_settings = self.prefs.get_custom_settings()
+ for setting in sap_settings:
+ try:
+ widget = self.gui.add_widget(setting)
+ widget.set_text(sap_settings[setting])
+ except:
+ pass
+
+
+ # Stats
+ statsviewer = self.gui.add_widget('scrStatsViewer')
+
+ btnstats = self.gui.add_widget('btnStatsByCompMain')
+ btnstats.connect('clicked', self.cb.update_components_stats)
+ iconwdg = self.gui.add_widget('imgStatsByCompMain')
+ icon = self.im.get_pixbuf_icon('component', 64, 64)
+ iconwdg.set_from_pixbuf(icon)
+
+ btnstats = self.gui.add_widget('btnStatsByCategory')
+ btnstats.connect('clicked', self.cb.update_categories_stats)
+ iconwdg = self.gui.add_widget('imgStatsByCategory')
+ icon = self.im.get_pixbuf_icon('category', 64, 64)
+ iconwdg.set_from_pixbuf(icon)
+
+ self.hide_props_window()
+ self.show_all()
+ self.log.debug("GUI loaded")
+
+
+ def setup_props_window(self):
+ imgtitle = self.gui.get_widget('imgPropsTitle')
+ icon = self.im.get_icon('fingerprint', 48, 48)
+ imgtitle.set_from_pixbuf (icon)
+ model = Gtk.TreeStore(str, str)
+ trvprops = self.gui.add_widget('trvprops', Gtk.TreeView())
+ trvprops.set_model(model)
+
+ #~ ## key
+ #~ renderer = Gtk.CellRendererText()
+ #~ column = Gtk.TreeViewColumn('Id', renderer, text=0)
+ #~ column.set_visible(False)
+ #~ column.set_clickable(False)
+ #~ column.set_sort_indicator(False)
+ #~ trvprops.append_column(column)
+
+ # Property
+ renderer = Gtk.CellRendererText()
+ renderer.set_alignment(1.0, 0.5)
+ column = Gtk.TreeViewColumn('Property', renderer, markup=0)
+ column.set_visible(True)
+ column.set_expand(False)
+ column.set_clickable(True)
+ column.set_sort_indicator(True)
+ trvprops.append_column(column)
+
+ # Value
+ renderer = Gtk.CellRendererText()
+ renderer.set_alignment(0.0, 0.5)
+ column = Gtk.TreeViewColumn('Value', renderer, markup=1)
+ column.set_visible(True)
+ column.set_expand(True)
+ column.set_clickable(True)
+ column.set_sort_indicator(True)
+ trvprops.append_column(column)
+ trvprops.show_all()
+
+ trvprops.set_headers_visible(True)
+ trvprops.set_enable_search(True)
+ trvprops.set_grid_lines(Gtk.TreeViewGridLines.NONE)
+ trvprops.set_search_column(1)
+ #~ trvprops.connect('row-activated', self.double_click)
+ selection = trvprops.get_selection()
+ selection.set_mode(Gtk.SelectionMode.SINGLE)
+ #~ trvprops.set_search_entry(self.pname)
+
+ container = self.gui.get_widget('boxProps')
+ self.gui.swap_widget(container, trvprops)
+
+ def set_notes_manager_pane_position(self, pane, rectangle):
+ pass
+ #~ self.log.debug(type(pane.get_allocation()))
+ position = rectangle.width/5*3
+ pane.set_position(position)
+ self.log.debug("Pane position: %s" % position)
+
+
+
+ def __completion_func(self, completion, key, iter):
+ model = completion.get_model()
+ text = model.get_value(iter, 0)
+ if key.upper() in text.upper():
+ return True
+ return False
+
+
+ def setup_combobox_completions(self, key):
+ model = Gtk.ListStore(str)
+ search = self.gui.get_widget("stySearchInfo")
+ completion = Gtk.EntryCompletion()
+ completion.set_model(model)
+ completion.set_text_column(0)
+ completion.set_match_func(self.__completion_func)
+ search.set_completion(completion)
+
+ stats = self.db.get_stats()
+
+ try:
+ items = list(stats[key])
+ items.sort()
+ for item in items:
+ model.append([item])
+ except:
+ pass
+
+
+ def cb_combobox_changed(self, combobox):
+ model = combobox.get_model()
+ treeiter = combobox.get_active_iter()
+ key = model[treeiter][0]
+ self.gui.set_key('cmbvalue', key)
+ self.setup_combobox_completions(key)
+
+
+ def setup_combobox_search(self):
+ combobox = self.gui.get_widget('cmbSearchInfo')
+ model = Gtk.TreeStore(str, str)
+ combobox.set_model(model)
+
+ ## key
+ cell = Gtk.CellRendererText()
+ cell.set_visible(False)
+ combobox.pack_start(cell, True)
+ combobox.add_attribute(cell, 'text', 0)
+
+ ## value
+ cell = Gtk.CellRendererText()
+ cell.set_alignment(0.0, 0.5)
+ combobox.pack_start(cell, expand=False)
+ combobox.add_attribute(cell, 'markup', 1)
+ combobox.connect('changed', self.cb_combobox_changed)
+
+ model.append(None, ['search', 'Search in all database'])
+ model.append(None, ['project', 'Filter by project name'])
+ model.append(None, ['task', 'Filter by task name'])
+ model.append(None, ['component', 'Filter by component'])
+ model.append(None, ['category', 'Filter by category'])
+ model.append(None, ['type', 'Filter by type'])
+ model.append(None, ['id', 'Filter by Id'])
+ model.append(None, ['title', 'Filter by title'])
+ model.append(None, ['priority', 'Filter by priority'])
+ model.append(None, ['version', 'Filter by version'])
+ #~ model.append(None, ['released', 'Filter by release date'])
+
+ combobox.set_active(0)
+
+
+ def get_services(self):
+ """Load services to be used in this class
+ """
+ self.gui = self.controller.get_service("GUI")
+ self.app = self.gui.get_app()
+ LOG_FILE = self.controller.get_file('LOG')
+ self.log = get_logger('GtkAppWindow', LOG_FILE)
+ self.db = self.controller.get_service("DB")
+ self.uif = self.controller.get_service("UIF")
+ self.prefs = self.controller.get_service("Settings")
+ self.im = self.controller.get_service('IM')
+ self.cb = self.controller.get_service('Callbacks')
+ self.tasks = self.controller.get_service('Tasks')
+
+
+ def swap_widget(self, container, combobox):
+ """Shortcut to GUI.swap_widget method
+ """
+ self.gui.swap_widget(container, combobox)
Index: REL-0.2/basico/utils.py
===================================================================
--- REL-0.2/basico/utils.py (nonexistent)
+++ REL-0.2/basico/utils.py (revision 76)
@@ -0,0 +1,165 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: utils.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Generic functions service
+
+import os
+import sys
+import subprocess
+import tarfile
+import zipfile
+import shutil
+import urllib.request
+import requests
+import webbrowser
+import feedparser
+
+from .service import Service
+
+class Utils(Service):
+ def initialize(self):
+ self.uas = []
+
+
+ def browse(self, lurl):
+ if sys.platform in ['linux', 'linux2']:
+ browser = webbrowser.get('firefox')
+ elif sys.platform == 'win32':
+ browser = webbrowser.get('windows-default')
+
+ for url in lurl:
+ self.log.debug("Browsing URL: %s" % url)
+ browser.open_new_tab(url)
+
+
+ def which(self, program):
+ if sys.platform == 'win32':
+ program = program + '.exe'
+
+ def is_exe(fpath):
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+ fpath, fname = os.path.split(program)
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ path = path.strip('"')
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+
+ return None
+
+
+ def install_geckodriver(self):
+ """Get last version of Gecko webdriver from github"""
+ self.log.debug("OS Platform: %s" % sys.platform)
+ if sys.platform in ['linux', 'linux2']:
+ GECKO_SOURCE = "https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-linux64.tar.gz"
+ GECKO_TARGET = self.get_var('TMP', scope='local') + 'gecko.tar.gz'
+ elif sys.platform == 'win32':
+ GECKO_SOURCE = "https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-win64.zip"
+ GECKO_TARGET = self.get_var('TMP', scope='local') + 'gecko.zip'
+
+ GECKO_INSTALL_DIR = self.get_var('DRIVERS', 'local')
+
+
+ if os.path.exists(GECKO_TARGET):
+ self.log.debug("Gecko webdriver already downloaded")
+ downloaded = True
+ else:
+ downloaded = self.download('Gecko', GECKO_SOURCE, GECKO_TARGET)
+
+ if downloaded:
+ if sys.platform in ['linux', 'linux2']:
+ extracted = self.extract(GECKO_TARGET, GECKO_INSTALL_DIR, 'tar.gz')
+ elif sys.platform == 'win32':
+ extracted = self.extract(GECKO_TARGET, GECKO_INSTALL_DIR, 'zip')
+ if extracted:
+ self.log.debug("Gecko webdriver deployed successfully")
+ else:
+ self.log.error("Gecko could not be deployed")
+ self.log.error("Tip: maybe %s is corrupt. Delete it" % GECKO_TARGET)
+ #FIXME: stop application gracefully
+ exit(-1)
+
+
+ def download(self, prgname, source, target):
+ try:
+ self.log.debug ("Downloading %s from: %s" % (prgname, source))
+ response = requests.get(source, stream=True)
+ with open(target, 'wb') as out_file:
+ shutil.copyfileobj(response.raw, out_file)
+ del response
+ self.log.debug ("%s downloaded to %s" % (prgname, target))
+ return True
+ except Exception as error:
+ self.log.error(error)
+ return False
+
+
+ def extract(self, filename, target_path, protocol):
+ self.log.debug("Extracting %s to %s using protocol %s" % (filename, target_path, protocol))
+ if protocol in ['tar.gz', 'bz2']:
+ try:
+ tar = tarfile.open(filename, "r:*")
+ tar.extractall(target_path)
+ tar.close()
+ self.log.debug("Extracted successfully")
+ return True
+ except Exception as error:
+ self.log.error(error)
+ return False
+ elif protocol == 'zip':
+ try:
+ self.unzip(filename, target_path)
+ self.log.debug("Extracted successfully")
+ return True
+ except Exception as error:
+ self.log.error(error)
+ return False
+
+ def zip(self, filename, directory):
+ # http://stackoverflow.com/a/25650295
+ #~ make_archive(archive_name, 'gztar', root_dir)
+ res = shutil.make_archive(filename, 'gztar', directory)
+ self.log.debug("%s - %s" % (filename, directory))
+ self.log.debug("zip res: %s" % res)
+
+
+ def unzip(self, target, install_dir):
+ zip_archive = zipfile.ZipFile(target, "r")
+ zip_archive.extractall(path=install_dir)
+ zip_archive.close()
+
+
+ def get_firefox_profile_dir(self):
+ if sys.platform in ['linux', 'linux2']:
+ cmd = "ls -d /home/$USER/.mozilla/firefox/*.default/"
+ p = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
+ FF_PRF_DIR = p.communicate()[0][0:-2]
+ FF_PRF_DIR_DEFAULT = str(FF_PRF_DIR,'utf-8')
+ elif sys.platform == 'win32':
+ import glob
+ APPDATA = os.getenv('APPDATA')
+ FF_PRF_DIR = "%s\\Mozilla\\Firefox\\Profiles\\" % APPDATA
+ PATTERN = FF_PRF_DIR + "*default*"
+ FF_PRF_DIR_DEFAULT = glob.glob(PATTERN)[0]
+
+ return FF_PRF_DIR_DEFAULT
+
+
+ def feedparser_parse(self, thing):
+ try:
+ return feedparser.parse(thing)
+ except TypeError:
+ if 'drv_libxml2' in feedparser.PREFERRED_XML_PARSERS:
+ feedparser.PREFERRED_XML_PARSERS.remove('drv_libxml2')
+ return feedparser.parse(thing)
+ else:
+ self.log.error(self.get_traceback())
+ return None
Index: REL-0.2/basico/uiapp.py
===================================================================
--- REL-0.2/basico/uiapp.py (nonexistent)
+++ REL-0.2/basico/uiapp.py (revision 76)
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: uiapp.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Gtk.Application instance
+
+import os
+import sys
+import subprocess
+from datetime import datetime
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository.GdkPixbuf import Pixbuf
+from gi.repository import Pango
+from gi.repository import GLib
+from gi.repository import GObject
+from gi.repository import Gio
+
+from .service import Service
+from .window import GtkAppWindow
+from .log import get_logger
+from .env import FILE, APP
+
+class UIApp(Gtk.Application):
+ """
+ """
+ def __init__(self, controller):
+ Gtk.Application.__init__(self,
+ application_id="net.t00mlabs.basico",
+ flags=Gio.ApplicationFlags.FLAGS_NONE)
+ GLib.set_application_name("Basico")
+ GLib.set_prgname('basico')
+ self.log = get_logger(self.__class__.__name__, FILE['LOG'])
+ self.controller = controller
+ self.get_services()
+
+
+ def get_services(self):
+ self.gui = self.controller.get_service('GUI')
+ self.im = self.controller.get_service('IM')
+ self.cb = self.controller.get_service('Callbacks')
+
+
+ def do_activate(self):
+ self.window = GtkAppWindow(self)
+ self.window.connect("delete-event", self.gui.quit)
+ self.window.show()
+
+
+ def do_startup(self):
+ Gtk.Application.do_startup(self)
+
+ # show icons on the buttons
+ #~ settings = Gtk.Settings.get_default()
+ #~ DEPRECATED: settings.props.gtk_button_images = True
+
+ # actions that control the application: create, connect their
+ # signal to a callback method (see below), add the action to the
+ # application
+
+
+ def get_window(self):
+ return self
+
+
+ def get_controller(self):
+ return self.controller
+
+
+ def cb_hide_about(self, aboutdialog, user_data):
+ aboutdialog.destroy()
+
+
+ def cb_toggle_fullscreen(self, tgbutton, user_data=None):
+ if tgbutton.get_active():
+ self.window.fullscreen()
+ else:
+ self.window.unfullscreen()
+
+
+ def cb_show_about(self, *args):
+ DIR_ICONS = self.controller.get_var("ICONS")
+ CREDITS = self.controller.get_file("CREDITS")
+ rootwin = self.gui.get_widget('mainwindow')
+ version = APP['version']
+
+ aboutdialog = Gtk.AboutDialog()
+ aboutdialog.set_hide_titlebar_when_maximized(True)
+ icon_dlg = self.im.get_icon('basico', 96, 96)
+ applicense = Gtk.License(Gtk.License.GPL_3_0)
+ shortname = self.controller.get_app_info('short')
+ longname = self.controller.get_app_info('desc')
+ authors = self.controller.get_app_info('authors')
+ aboutdialog.set_logo(icon_dlg)
+ aboutdialog.set_icon(icon_dlg)
+ aboutdialog.set_comments(longname)
+ aboutdialog.set_version(version)
+ aboutdialog.set_copyright("Copyright \xa9 2016 Tomás Vírseda García")
+ aboutdialog.set_license_type(applicense)
+ aboutdialog.set_authors(authors)
+ aboutdialog.set_website("http://t00mlabs.net")
+ aboutdialog.set_website_label("t00mlabs Website")
+ aboutdialog.set_title("")
+ aboutdialog.connect("response", self.cb_hide_about)
+ aboutdialog.set_transient_for(rootwin)
+ aboutdialog.set_modal(True)
+ aboutdialog.show()
Index: REL-0.2/basico/gui.py
===================================================================
--- REL-0.2/basico/gui.py (nonexistent)
+++ REL-0.2/basico/gui.py (revision 76)
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: gui.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: GUI module
+
+import os
+import sys
+import subprocess
+
+from datetime import datetime
+
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository.GdkPixbuf import Pixbuf
+from gi.repository import Pango
+from gi.repository import GLib
+from gi.repository import GObject
+from gi.repository import Gio
+
+from .service import Service
+from .uiapp import UIApp
+
+
+class GUI(Service):
+ def initialize(self):
+ '''
+ Setup GUI Service
+ '''
+ # Invoke services
+ self.sap = self.app.get_service('SAP')
+
+ # Setup caches
+ self.widgets = {} # Widget name : Object
+ self.keys = {} # Key : Value; keys: doctype, property, values
+
+ # Setup Glade builder
+ self.setup_builder()
+
+
+ def run(self):
+ '''
+ Let GUI service start
+ '''
+ self.log.debug("Setting up GUI")
+ #~ Gdk.threads_init()
+
+ GObject.threads_init()
+ self.sap.run()
+ self.ui = UIApp(self.app)
+ self.ui.run()
+
+
+ def quit(self, *args):
+ '''
+ GUI destroyed
+ '''
+ self.app.stop()
+
+
+ def end(self):
+ '''
+ End GUI Service
+ '''
+ self.log.debug("GUI terminated")
+ self.ui.quit()
+
+
+ def setup_builder(self):
+ '''
+ Setup Gtk.Builder object
+ '''
+ DIR_UI = self.get_var('UI')
+ self.builder = Gtk.Builder()
+ self.builder.add_from_file(DIR_UI + 'basico.ui')
+
+
+ def get_builder(self):
+ '''
+ Return Gtk.Builder object
+ '''
+ return self.builder()
+
+
+ def swap_widget(self, parent, widget):
+ '''
+ Swap widget inside a container
+ '''
+ try:
+ child = parent.get_children()[0]
+ parent.remove(child)
+ parent.add(widget)
+ del (child)
+ except:
+ parent.add(widget)
+ widget.show_all()
+
+
+ def get_key(self, key):
+ '''
+ Return current value from var cache
+ '''
+ return self.keys[key]
+
+
+ def set_key(self, key, value):
+ '''
+ Set current value for var cache
+ '''
+ self.keys[key] = value
+
+
+ def add_widget(self, name, obj=None):
+ '''
+ Add widget to cache
+ '''
+ try:
+ if obj is not None:
+ self.widgets[name] = obj
+ else:
+ self.widgets[name] = self.builder.get_object(name)
+ return self.widgets[name]
+ except Exception as error:
+ self.log.error (self.get_traceback())
+ return None
+
+
+ def get_widget(self, name):
+ '''
+ Return widget from cache
+ '''
+ try:
+ return self.widgets[name]
+ except KeyError:
+ return self.add_widget(name)
+
+
+ def get_widgets(self):
+ return self.widgets
+
+
+ def get_app(self):
+ return self.ui
+
+
+ def get_window(self):
+ return self.ui.get_window()
/REL-0.2/basico/gui.py
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: REL-0.2/basico/plugins.py
===================================================================
--- REL-0.2/basico/plugins.py (nonexistent)
+++ REL-0.2/basico/plugins.py (revision 76)
@@ -0,0 +1,161 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: hooks.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: a simple plugin system based on hooks
+
+import os
+
+import pkg_resources
+
+from .service import Service
+
+ENTRYPOINT = 'basico.plugins'
+
+class Plugins(Service):
+ def initialize(self):
+ self.blacklist = set()
+ self.rebuild_plugins()
+ self.plugins = self.init_plugins()
+
+
+ def __len__(self):
+ return len(self.plugins)
+
+
+ def get_services(self):
+ pass
+
+
+ def rebuild_local_plugins(self):
+ #~ print GPATH['PLUGINS']
+ for plugindir in os.listdir(LPATH['PLUGINS']):
+ setupdir = LPATH['PLUGINS'] + '/' + plugindir
+ setupfile = LPATH['PLUGINS'] + '/' + plugindir + '/setup.py'
+ #~ print (setupfile)
+ if os.path.exists(setupfile):
+ cmd = "cd %s; python %s develop --install-dir .. -m" % (setupdir, setupfile)
+ (exitstatus, outtext) = commands.getstatusoutput(cmd)
+ if exitstatus != 0:
+ self.log.warning( "Plugin '%s' not available. Error: %d" % (plugindir, exitstatus) )
+ self.log.warning( outtext )
+
+
+ def rebuild_plugins(self):
+ DIR_PLUGINS = self.get_var('PLUGINS', 'local')
+ self.log.debug("Looking for plugins in: %s" % DIR_PLUGINS)
+ for plugindir in os.listdir(DIR_PLUGINS):
+ setupdir = DIR_PLUGINS + '/' + plugindir
+ setupfile = DIR_PLUGINS + '/' + plugindir + '/setup.py'
+ if os.path.exists(setupfile):
+ cmd = "cd %s; python3 %s develop --install-dir .. -m > /dev/null 2>&1" % (setupdir, setupfile)
+ exitstatus = os.system(cmd)
+ #~ (exitstatus, outtext) = commands.getstatusoutput(cmd)
+ self.log.debug(exitstatus)
+ if exitstatus != 0:
+ self.log.warning( "Plugin '%s' not available. Error: %d" % (plugindir, exitstatus) )
+ #~ self.log.warning( outtext )
+
+
+ def init_plugins(self):
+ """
+ Load local and system hooks.
+ """
+ DIR_PLUGINS = self.get_var('PLUGINS')
+ plugins = {}
+
+ # Load local plugins
+ pkg_resources.working_set.add_entry(DIR_PLUGINS)
+ pkg_env = pkg_resources.Environment([DIR_PLUGINS])
+ loaded = 0
+ for name in pkg_env:
+ egg = pkg_env[name][0]
+ egg.activate()
+ modules = []
+ for name in egg.get_entry_map(ENTRYPOINT):
+ try:
+ entry_point = egg.get_entry_info(ENTRYPOINT, name)
+ cls = entry_point.load()
+ cls.app = self.app
+ #~ print dir(cls)
+ if not hasattr(cls, 'capabilities'):
+ cls.capabilities = []
+ instance = cls()
+ for c in cls.capabilities:
+ plugins.setdefault(c, []).append(instance)
+ loaded = loaded + 1
+ except Exception as error:
+ self.log.warning( "Hook '%s': %s" % (name, error))
+ raise
+
+ self.log.debug("Plugin system initialited: %d plugins loaded" % loaded)
+ return plugins
+
+
+ def get_plugin_by_key(self, key):
+ for plugin in self.get_all_plugins():
+ if plugin.key == key:
+ return plugin
+
+ return None
+
+
+ def get_plugins_by_capability(self, capability):
+ try:
+ plist = []
+ for plugin in self.plugins.get(capability, []):
+ active = self.get_active(plugin.key)
+ if active:
+ plist.append(plugin)
+ return plist
+ #~ return self.plugins.get(capability, [])
+ except Exception as error:
+ self.log.error( error )
+
+
+ def get_all_plugins(self):
+ result = set()
+ for p in self.plugins.itervalues():
+ for plugin in p:
+ result.add(plugin)
+ return list(result)
+
+
+ def get_plugin_path(self, plugin_key):
+ DIR_PLUGINS = self.get_var('PLUGINS')
+ return DIR_PLUGINS + '/' + plugin_key
+
+
+ def get_active(self, plugin_key):
+ mark = self.get_disabled_mark(plugin_key)
+ if os.path.exists(mark):
+ return False
+ else:
+ return True
+
+
+ def disable(self, plugin_key):
+ try:
+ mark = self.get_disabled_mark(plugin_key)
+ open(mark, 'w').close()
+ self.blacklist.add(plugin_key)
+ except:
+ pass
+
+
+ def enable(self, plugin_key):
+ mark = self.get_disabled_mark(plugin_key)
+ try:
+ os.remove(mark)
+ self.blacklist.remove(plugin_key)
+ except:
+ pass
+
+
+ def get_disabled_mark(self, plugin_key):
+ return self.get_plugin_path(plugin_key) + '/DISABLED'
+
+
+ def get_blacklist(self):
+ return self.blacklist
/REL-0.2/basico/plugins.py
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: REL-0.2/setup.py
===================================================================
--- REL-0.2/setup.py (nonexistent)
+++ REL-0.2/setup.py (revision 76)
@@ -0,0 +1,152 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+# Authors: Tomás Vírseda <tomasvirseda@gmail.com>
+# Basico is a SAP Notes manager for SAP Consultants
+# Copyright (C) 2016-2017 Tomás Vírseda
+#
+# Basico is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Basico is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Basico. If not, see <http://www.gnu.org/licenses/gpl.html>
+
+import os
+import subprocess
+from setuptools import setup
+
+
+with open('README') as f:
+ long_description = f.read()
+
+def add_data():
+ try:
+ data_files = [
+ ('basico/share/applications', ['basico/data/desktop/basico.desktop']),
+ ('basico/data/res', ['basico/data/res/user_agents.txt']),
+ ('basico/data/icons',
+ [
+ 'basico/data/icons/about.png',
+ 'basico/data/icons/annotation.png',
+ 'basico/data/icons/bookmark.png',
+ 'basico/data/icons/browse.png',
+ 'basico/data/icons/category.png',
+ 'basico/data/icons/component.png',
+ 'basico/data/icons/delete.png',
+ 'basico/data/icons/noproject.png',
+ 'basico/data/icons/project.png',
+ 'basico/data/icons/sapnote.png',
+ 'basico/data/icons/notask.png',
+ 'basico/data/icons/tags.png',
+ 'basico/data/icons/task.png',
+ 'basico/data/icons/tasks.png',
+ 'basico/data/icons/chronologic.png',
+ 'basico/data/icons/description.png',
+ 'basico/data/icons/priority.png',
+ 'basico/data/icons/type.png',
+ 'basico/data/icons/chart.png',
+ 'basico/data/icons/stats.png',
+ 'basico/data/icons/details.png',
+ 'basico/data/icons/subwindow.png',
+ 'basico/data/icons/bsearch.png',
+ 'basico/data/icons/refresh.png',
+ 'basico/data/icons/power.png',
+ ]),
+ ('basico/data/ui', ['basico/data/ui/basico.ui']),
+ ('basico/data/share', []),
+ ("basico/data/share/docs",
+ [
+ 'AUTHORS',
+ 'LICENSE',
+ 'README',
+ 'INSTALL',
+ 'CREDITS',
+ 'Changelog'
+ ]),
+ ]
+
+ if not os.path.isdir('mo'):
+ os.mkdir('mo')
+ for pofile in os.listdir('po'):
+ if pofile.endswith('po'):
+ lang = pofile.strip('.po')
+ modir = os.path.join('mo', lang)
+ if not os.path.isdir(modir):
+ os.mkdir(modir)
+ mofile = os.path.join(modir, 'basico.mo')
+ subprocess.call('msgfmt {} -o {}'.format(os.path.join('po', pofile), mofile), shell=True)
+ data_files.append(['share/locale/{}/LC_MESSAGES/'.format(lang), [mofile]])
+ return data_files
+ except:
+ return []
+
+if os.name == 'posix':
+ data_files = add_data()
+else:
+ data_files = []
+
+try:
+ bcommit = subprocess.check_output("svn info", shell=True)
+ ucommit = bcommit.decode(encoding='UTF-8')
+ icommit = int(ucommit.split('\n')[6].split(':')[1])
+ dcommit = ucommit.split('\n')[11][19:29]
+except Exception as error:
+ print (error)
+ dcommit = 'None'
+ icommit = 0
+
+setup(
+ name='basico',
+ version='0.2',
+ author='Tomás Vírseda',
+ author_email='tomasvirseda@gmail.com',
+ url='http://subversion.t00mlabs.net/basico',
+ description='SAP Notes Manager for SAP Consultants',
+ long_description=long_description,
+ download_url = 'http://t00mlabs.net/downloads/basico-0.2.tar.gz',
+ license='GPLv3',
+ packages=['basico'],
+ # distutils does not support install_requires, but pip needs it to be
+ # able to automatically install dependencies
+ install_requires=[
+ 'pygal',
+ 'python-dateutil',
+ 'selenium',
+ 'feedparser',
+ 'requests',
+ ],
+ include_package_data=True,
+ data_files=data_files,
+ zip_safe=False,
+ platforms='any',
+ classifiers=[
+ 'Development Status :: 3 - Alpha',
+ 'Environment :: X11 Applications :: Gnome',
+ 'Environment :: X11 Applications :: GTK',
+ 'Intended Audience :: Information Technology',
+ 'Intended Audience :: Other Audience',
+ 'Intended Audience :: System Administrators',
+ 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
+ 'Natural Language :: English',
+ 'Operating System :: Microsoft :: Windows',
+ 'Operating System :: POSIX :: Linux',
+ 'Programming Language :: Python :: 3',
+ 'Topic :: Database :: Front-Ends',
+ 'Topic :: System :: Systems Administration',
+ 'Topic :: Utilities'
+ ],
+ entry_points={
+ #~ 'console_scripts': [
+ #~ 'basico = basico:main',
+ #~ ],
+ 'gui_scripts': [
+ 'basico = basico.basico:main',
+ ]
+ },
+)
Index: REL-0.2/README
===================================================================
--- REL-0.2/README (nonexistent)
+++ REL-0.2/README (revision 76)
@@ -0,0 +1,31 @@
+# Basico
+**SAP Notes Manager for SAP Consultants**
+
+
+## Description
+The main aim for this application is allow you to download the SAP Notes
+you are interested in, categorize them by tasks in order to have them at
+hand whenever you want and find them quickly.
+
+
+## Features
+* Download SAP Notes
+* Import SAP Notes from other people
+* Export SAP Notes to: plain text, CSV and, JSON format (useful if you
+ want to share your SAP Notes)
+* Bookmark those SAP Notes really interesting.
+* Browse SAP Notes in Launchpad
+
+
+## Installation
+Please, follow the [instructions](http://blog.t00mlabs.net/projects/basico/basico-installation) from this page
+
+
+## Authors
+Tomás Vírseda <tomasvirseda@gmail.com>
+
+
+## Contributors
+Many thanks to the following people, who have kindly help in this project:
+
+* Iliya Kuznetsov: ideas to deal with OData protocol and other useful info to start this project
Index: REL-0.2/CREDITS
===================================================================
--- REL-0.2/CREDITS (nonexistent)
+++ REL-0.2/CREDITS (revision 76)
@@ -0,0 +1,2 @@
+Icons (GPL);Web Design Creative;http://findicons.com/pack/2141/web_design_creatives
+Collaborations; your name here...;
Index: REL-0.2/basico/menus.py
===================================================================
--- REL-0.2/basico/menus.py (nonexistent)
+++ REL-0.2/basico/menus.py (revision 76)
@@ -0,0 +1,127 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: menus.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Menus service
+
+
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository.GdkPixbuf import Pixbuf
+
+from .service import Service
+
+class Menus(Service):
+ def initialize(self):
+ self.get_services()
+ self.uiapp = self.gui.get_widget('uiapp')
+ self.window = self.gui.get_widget('mainwindow')
+
+
+ def get_services(self):
+ self.gui = self.app.get_service('GUI')
+ self.sap = self.app.get_service('SAP')
+ self.cb = self.app.get_service('Callbacks')
+ self.tasks = self.gui.get_service('Tasks')
+ self.im = self.gui.get_service('IM')
+
+
+ def create_popup_menu_by_task(self, task):
+ menu = Gtk.Menu()
+ ICONS_DIR = self.get_var('ICONS')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+
+ item = Gtk.ImageMenuItem()
+ icon = self.im.get_image_icon('task', 24, 24)
+ item.set_image(icon)
+ item.set_always_show_image(True)
+ item.set_label("Select all SAP Notes on this task")
+ item.connect("activate", self.select_by_task, task, True)
+ menu.append(item)
+
+ item = Gtk.ImageMenuItem()
+ icon = self.im.get_image_icon('task', 24, 24)
+ item.set_image(icon)
+ item.set_always_show_image(True)
+ item.set_label("Unselect all SAP Notes on this task")
+ item.connect("activate", self.select_by_task, task, False)
+ menu.append(item)
+
+ return menu
+
+
+ def select_by_task(self, menuitem, task, active):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnoteview.select_by_task(task, active)
+
+
+ def create_popup_menu_by_sapnote(self, sid):
+ return None
+ #~ db = self.get_service('DB')
+ #~ sapnote = db.get_sapnote_metadata(sid)
+ #~ sapnoteview = self.gui.get_widget('sapnoteview')
+ #~ component = sapnote['componentkey']
+ #~ category = sapnote['category']
+ #~ ICONS_DIR = self.get_var('ICONS')
+
+ #~ menu = Gtk.Menu()
+
+ #~ item = Gtk.ImageMenuItem()
+ #~ icon = self.im.get_image_icon('component', 24, 24)
+ #~ item.set_image(icon)
+ #~ item.set_always_show_image(True)
+ #~ item.set_label("Select all SAP Notes with component %s" % component)
+ #~ item.connect("activate", self.select_by_component, component, True)
+ #~ menu.append(item)
+
+ #~ return menu
+
+
+ def create_popup_menu_by_component(self, component):
+ menu = Gtk.Menu()
+ ICONS_DIR = self.get_var('ICONS')
+ sapnoteview = self.gui.get_widget('sapnoteview')
+
+ item = Gtk.ImageMenuItem()
+ icon = self.im.get_image_icon('component', 24, 24)
+ item.set_image(icon)
+ item.set_always_show_image(True)
+ item.set_label("Select all SAP Notes on this component")
+ item.connect("activate", self.select_by_component, component, True)
+ menu.append(item)
+
+ item = Gtk.ImageMenuItem()
+ icon = self.im.get_image_icon('component', 24, 24)
+ item.set_image(icon)
+ item.set_always_show_image(True)
+ item.set_label("Unselect all SAP Notes on this component")
+ item.connect("activate", self.select_by_component, component, False)
+ menu.append(item)
+
+ return menu
+
+
+ def select_by_component(self, menuitem, component, active):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnoteview.select_by_component(component, active)
+
+
+ def create_item(self, name, action, icon):
+ item = Gio.MenuItem.new(name, action)
+ item.set_icon(Gio.ThemedIcon.new(icon))
+ return item
+
+
+ def create_action(self, name, callback=None):
+ action = Gio.SimpleAction.new(name, None)
+
+ if callback is None:
+ window = self.gui.get_widget('mainwindow')
+ action.connect('activate', window.action_clicked)
+ else:
+ action.connect('activate', callback)
+ return action
+
+
Index: REL-0.2/basico/uifuncs.py
===================================================================
--- REL-0.2/basico/uifuncs.py (nonexistent)
+++ REL-0.2/basico/uifuncs.py (revision 76)
@@ -0,0 +1,122 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: uifuncs.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Generic UI functions service
+
+
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository.GdkPixbuf import Pixbuf
+
+from .service import Service
+
+class UIFuncs(Service):
+ def initialize(self):
+ self.gui = self.app.get_service('GUI')
+ self.cb = self.app.get_service('Callbacks')
+ self.im = self.app.get_service('IM')
+
+
+ def get_gtk_version(self):
+ return Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version()
+
+
+ def check_gtk_version(self):
+ vmajor, vminor, vmicro = self.get_gtk_version()
+ self.log.debug("GTK+ Version: %d.%d.%d" % (vmajor, vminor, vmicro))
+
+ if vmajor == 3 and vminor >= 18:
+ self.log.debug("GTK+ version supported")
+ return True
+ else:
+ self.log.error("Please, install a modern version of GTK+ (>= 3.18)")
+ return False
+
+
+ def get_label(self, text, xalign=0.5, yalign=0.5):
+ label = Gtk.Label()
+ label.set_selectable(False)
+ label.set_markup(text)
+ label.props.xalign = xalign
+ label.props.yalign = yalign
+ label.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
+
+ return label
+
+
+ def get_separator(self, draw=False, expand=False):
+ separator = Gtk.SeparatorToolItem.new ()
+ separator.set_expand(expand)
+ separator.set_draw(draw)
+
+ return separator
+
+
+ def create_textview(self):
+ scrolledwindow = Gtk.ScrolledWindow()
+ scrolledwindow.set_hexpand(True)
+ scrolledwindow.set_vexpand(True)
+ scrolledwindow.set_shadow_type(Gtk.ShadowType.IN)
+ textview = Gtk.TextView()
+ textbuffer = textview.get_buffer()
+ textbuffer.set_text("This is some text inside of a Gtk.TextView. "
+ + "Select text and click one of the buttons 'bold', 'italic', "
+ + "or 'underline' to modify the text accordingly.")
+ scrolledwindow.add(textview)
+
+ return scrolledwindow
+
+
+ def get_box(self):
+ if Gtk.get_minor_version() < 14:
+ return Gtk.Alignment()
+ else:
+ return Gtk.Box()
+
+
+ def create_item(self, name, action, icon):
+ item = Gio.MenuItem.new(name, action)
+ if len(icon) > 0:
+ item.set_icon(Gio.ThemedIcon.new(icon))
+ #~ icon = self.im.get_themed_icon(icon)
+
+ return item
+
+
+ def create_action(self, name, callback=None, user_data=None):
+ action = Gio.SimpleAction.new(name, None)
+
+ if callback is None:
+ window = self.gui.get_widget('mainwindow')
+ action.connect('activate', self.cb.execute_action, user_data)
+ else:
+ action.connect('activate', callback, user_data)
+ return action
+
+
+ def message_dialog(self, head, body):
+ dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "%s" % head)
+ dialog.format_secondary_text("%s" % body)
+ dialog.run()
+ dialog.destroy()
+
+
+ def fullscreen(self, switch, do_fullscreen=None):
+ window = self.gui.get_widget('mainwindow')
+
+ if do_fullscreen is None:
+ #~ Get state from button:
+ toggle = self.gui.get_widget('tgbFullScreen')
+ do_fullscreen = toggle.get_active()
+
+ if do_fullscreen == True:
+ #~ window.fullscreen()
+ window.maximize()
+ else:
+ #~ window.unfullscreen()
+ window.unmaximize()
+
+
/REL-0.2/basico/uifuncs.py
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: REL-0.2/basico/log.py
===================================================================
--- REL-0.2/basico/log.py (nonexistent)
+++ REL-0.2/basico/log.py (revision 76)
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: log.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: log service
+
+from os.path import sep as SEP
+import logging
+
+
+def get_logger(name, LOG_FILE):
+ """Returns a new logger with personalized.
+ @param name: logger name
+ """
+ log = logging.getLogger(name)
+ log.setLevel(logging.DEBUG)
+
+ ## Redirect log to stdout
+ formatter = logging.Formatter("%(levelname)7s | %(lineno)4d |%(name)15s | %(asctime)s | %(message)s")
+ ch = logging.StreamHandler() # Create console handler and set level to debug
+ ch.setLevel(logging.DEBUG) # Set logging devel
+ ch.setFormatter(formatter) # add formatter to console handler
+ log.addHandler(ch) # add console handler to logger
+
+ # Redirect log to file
+ fh = logging.FileHandler(LOG_FILE)
+ fh.setFormatter(formatter)
+ fh.setLevel(logging.DEBUG) # Set logging devel
+ log.addHandler(fh) # add file handler to logger
+
+ return log
/REL-0.2/basico/log.py
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: REL-0.2/basico/preferences.py
===================================================================
--- REL-0.2/basico/preferences.py (nonexistent)
+++ REL-0.2/basico/preferences.py (revision 76)
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: preferences.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Preferences service
+
+
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository.GdkPixbuf import Pixbuf
+
+from .service import Service
+
+class Preferences(Service):
+ def initialize(self):
+ self.sap = self.get_service('SAP')
+ self.gui = self.app.get_service('GUI')
+
+ self.uiapp = self.gui.get_widget('uiapp')
Index: REL-0.2/tmp/bugs/sapnoteview01.txt
===================================================================
--- REL-0.2/tmp/bugs/sapnoteview01.txt (nonexistent)
+++ REL-0.2/tmp/bugs/sapnoteview01.txt (revision 76)
@@ -0,0 +1,20 @@
+ DEBUG | 326 | SAPNoteView | 2016-10-14 16:01:25,392 | View 'tasks' populated with 61 SAP Notes
+Traceback (most recent call last):
+ File "/usr/local/lib/python3.5/dist-packages/basico-0.2.dev0-py3.5.egg/basico/sapnoteview.py", line 543, in populate_by_tasks
+ cid = treepids[catkey]
+KeyError: 'notask--'
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+ File "/usr/local/lib/python3.5/dist-packages/basico-0.2.dev0-py3.5.egg/basico/callbacks.py", line 290, in import_notes
+ self.import_notes_from_sapnet()
+ File "/usr/local/lib/python3.5/dist-packages/basico-0.2.dev0-py3.5.egg/basico/callbacks.py", line 397, in import_notes_from_sapnet
+ sapnoteview.populate(dlbag)
+ File "/usr/local/lib/python3.5/dist-packages/basico-0.2.dev0-py3.5.egg/basico/sapnoteview.py", line 338, in populate
+ self.populate_by_tasks(sapnotes)
+ File "/usr/local/lib/python3.5/dist-packages/basico-0.2.dev0-py3.5.egg/basico/sapnoteview.py", line 545, in populate_by_tasks
+ node = self.get_node_category(sapnotes[sid])
+ File "/usr/local/lib/python3.5/dist-packages/basico-0.2.dev0-py3.5.egg/basico/sapnoteview.py", line 623, in get_node_category
+ node.append(category) # Component
+UnboundLocalError: local variable 'category' referenced before assignment
Index: REL-0.2/MANIFEST.in
===================================================================
--- REL-0.2/MANIFEST.in (nonexistent)
+++ REL-0.2/MANIFEST.in (revision 76)
@@ -0,0 +1,2 @@
+recursive-include basico/data *
+recursive-include po *.po
Index: REL-0.2/basico/driver.py
===================================================================
--- REL-0.2/basico/driver.py (nonexistent)
+++ REL-0.2/basico/driver.py (revision 76)
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: driver.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Selenium Driver service
+
+import os
+import selenium
+from selenium import webdriver
+from selenium.webdriver.support.wait import WebDriverWait
+from selenium import webdriver
+from selenium.webdriver.common.keys import Keys
+from selenium.common.exceptions import WebDriverException
+from selenium.common.exceptions import NoSuchElementException
+from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
+from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
+
+from .service import Service
+
+GECKODRIVER_URL = "https://github.com/mozilla/geckodriver/releases/download/v0.15.0/geckodriver-v0.15.0-linux64.tar.gz"
+
+class SeleniumDriver(Service):
+ def initialize(self):
+ self.driver = None
+
+
+ def open(self):
+ '''
+ In order to have selenium working with Firefox and be able to
+ get SAP Notes from launchpad.support.sap.com you must:
+ 1. Use a browser certificate (SAP Passport) in order to avoid
+ renewed logons.
+ You can apply for it at:
+ https://support.sap.com/support-programs-services/about/getting-started/passport.html
+ 2. Get certificate and import it into Firefox.
+ Open menu -> Preferences -> Advanced -> View Certificates
+ -> Your Certificates -> Import
+ 3. Trust this certificate (auto select)
+ 4. Check it. Visit some SAP Note url in Launchpad.
+ No credentials will be asked.
+ Launchpad must load target page successfully.
+ '''
+
+ if self.driver is None:
+ utils = self.get_service('Utils')
+ FIREFOX_PROFILE_DIR = utils.get_firefox_profile_dir()
+ FIREFOX_PROFILE = webdriver.FirefoxProfile(FIREFOX_PROFILE_DIR)
+ driver = webdriver.Firefox(FIREFOX_PROFILE)
+ self.driver = driver
+ self.log.debug("Webdriver initialited")
+
+ return self.driver
+
+
+ def close(self):
+ try:
+ self.driver.quit()
+ self.log.debug("\tWebdriver closed")
+ except:
+ self.log.debug("Webdriver already closed")
+ pass
+
+ self.driver = None
+
+
+
+ def load(self, URL):
+ driver = self.open()
+ driver.get(URL)
+ return driver
+
+
+ def check(self):
+ """
+ Check gecko webdriver
+ You must install geckodriver. It is mandatory
+ Yo can download it from:
+ https://github.com/mozilla/geckodriver/
+ Then, extract the binary and copy it to somewhere in your $PATH.
+ If OS is Linux: /usr/local/bin/geckodriver
+ If OS is Windows: C:\Windows\System32 or elsewhere.
+
+ Basico will try to do it for you.
+ """
+ utils = self.get_service('Utils')
+
+ # First, add BASICO OPT Path to $PATH
+ GECKO_INSTALL_DIR = self.get_var('DRIVERS', 'local')
+ os.environ["PATH"] += os.pathsep + GECKO_INSTALL_DIR
+ # Then, look for Geckodriver
+ GECKODRIVER = utils.which('geckodriver')
+
+ if not GECKODRIVER:
+ self.log.debug("Attempting to download and install it.")
+ utils.install_geckodriver()
+
+ GECKODRIVER = utils.which('geckodriver')
+ if GECKODRIVER is None:
+ self.log.warning("Gecko driver not found.")
+ return False
+ else:
+ self.log.debug("Gecko Webdriver found in: %s" % GECKODRIVER)
+ return True
+
+
+ def run(self):
+ pass
+
+
+ def quit(self):
+ self.close()
+
+
+ def end(self):
+ self.close()
+
+
Index: REL-0.2/basico/sapnoteview.py
===================================================================
--- REL-0.2/basico/sapnoteview.py (nonexistent)
+++ REL-0.2/basico/sapnoteview.py (revision 76)
@@ -0,0 +1,1704 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: sapnoteview.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: TreeView for SAP Notes
+
+from cgi import escape
+from enum import IntEnum
+from gi.repository import Gtk
+from gi.repository.GdkPixbuf import Pixbuf
+from gi.repository import Pango
+from datetime import datetime
+from dateutil import parser as dateparser
+#~ from bs4 import BeautifulSoup as BSHTML
+from .log import get_logger
+
+#~ Enum(value='Column', names=<...>, *, module='...', qualname='...', type=<mixed-in class>, start=1)
+#~ Column = Enum('Column', 'rowtype checkbox icon id title component category type priority language released', start=0)
+
+class Column(IntEnum):
+ rowtype = 0
+ checkbox = 1
+ icon = 2
+ component = 3
+ category = 4
+ type = 5
+ id = 6
+ title = 7
+ priority = 8
+ language = 9
+ released = 10
+
+
+class SAPNoteView(Gtk.TreeView):
+ def __init__(self, app):
+ self.app = app
+ LOG_FILE = self.app.get_file('LOG')
+ LOG_NAME = self.__class__.__name__
+ self.log = get_logger(LOG_NAME, LOG_FILE)
+ self.get_services()
+ self.toggled = 0
+ self.selected = set()
+ self.count = 0
+
+
+ # Setup treeview and model
+ Gtk.TreeView.__init__(self)
+ self.model = Gtk.TreeStore(
+ str, # RowType@RowId
+ bool, # CheckBox
+ Pixbuf, # Icon
+ str, # Component key
+ str, # Category
+ str, # Type
+ str, # SAP Note Id
+ str, # Title
+ str, # Priority
+ str, # Language
+ str # Release date
+ )
+ self.set_model(self.model)
+
+ # Setup columns
+ # RowType
+ renderer = Gtk.CellRendererText()
+ column = Gtk.TreeViewColumn('', renderer, text=Column.rowtype.value)
+ column.set_visible(False)
+ column.set_expand(False)
+ column.set_clickable(False)
+ column.set_sort_indicator(False)
+ self.append_column(column)
+
+ # Checkbox
+ renderer = Gtk.CellRendererToggle()
+ renderer.connect("toggled", self.on_cell_toggled)
+ self.column_checkbox = Gtk.TreeViewColumn('', renderer, active=1)
+ self.column_checkbox.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.column_checkbox.set_visible(True)
+ self.column_checkbox.set_expand(False)
+ self.column_checkbox.set_clickable(False)
+ self.column_checkbox.set_sort_indicator(False)
+ self.append_column(self.column_checkbox)
+ self.column_checkbox.set_cell_data_func(renderer, self.cell_data_func)
+
+ # Icon
+ renderer = Gtk.CellRendererPixbuf()
+ renderer.set_alignment(0.0, 0.5)
+ self.column_icon = Gtk.TreeViewColumn('', renderer, pixbuf=2)
+ self.column_icon.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.column_icon.set_visible(True)
+ self.column_icon.set_expand(False)
+ self.column_icon.set_clickable(False)
+ self.column_icon.set_sort_indicator(False)
+ self.append_column(self.column_icon)
+
+ # Component key
+ renderer = Gtk.CellRendererText()
+ #~ renderer.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
+ self.column_component = Gtk.TreeViewColumn('SAP Notes', renderer, markup=3)
+ self.column_component.set_visible(True)
+ #~ self.column_component.set_expand(True)
+ self.column_component.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.column_component.set_clickable(True)
+ self.column_component.set_sort_indicator(True)
+ self.column_component.set_sort_column_id(3)
+ self.column_component.set_sort_order(Gtk.SortType.ASCENDING)
+ self.column_component.set_expand(True)
+ self.append_column(self.column_component)
+ expander_column = self.column_component
+
+
+ # Category
+ renderer = Gtk.CellRendererText()
+ self.column_cat = Gtk.TreeViewColumn('Category', renderer, markup=4)
+ self.column_cat.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.column_cat.set_visible(False)
+ self.column_cat.set_expand(False)
+ self.column_cat.set_clickable(True)
+ self.column_cat.set_sort_indicator(True)
+ self.column_cat.set_sort_column_id(4)
+ self.column_cat.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(self.column_cat)
+
+ # Type
+ renderer = Gtk.CellRendererText()
+ column = Gtk.TreeViewColumn('Type', renderer, markup=5)
+ column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column.set_visible(False)
+ column.set_expand(False)
+ column.set_clickable(True)
+ column.set_sort_indicator(True)
+ column.set_sort_column_id(5)
+ column.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(column)
+
+ # SAP Note Id
+ renderer = Gtk.CellRendererText()
+ renderer.set_alignment(1.0, 0.5)
+ self.column_sid = Gtk.TreeViewColumn('SAP Note', renderer, markup=6)
+ self.column_sid.set_visible(False)
+ self.column_sid.set_expand(False)
+ self.column_sid.set_clickable(True)
+ self.column_sid.set_sort_indicator(True)
+ self.column_sid.set_sort_column_id(6)
+ self.column_sid.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(self.column_sid)
+
+ # Title
+ renderer = Gtk.CellRendererText()
+ renderer.set_property('ellipsize', Pango.EllipsizeMode.MIDDLE)
+ self.column_title = Gtk.TreeViewColumn('Title', renderer, markup=7)
+ self.column_title.set_visible(False)
+ self.column_title.set_expand(True)
+ self.column_title.set_clickable(True)
+ self.column_title.set_sort_indicator(True)
+ self.column_title.set_sort_column_id(7)
+ self.column_title.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(self.column_title)
+
+ # Priority
+ renderer = Gtk.CellRendererText()
+ self.column_priority = Gtk.TreeViewColumn('Priority', renderer, markup=8)
+ self.column_priority.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.column_priority.set_visible(True)
+ self.column_priority.set_expand(False)
+ self.column_priority.set_clickable(True)
+ self.column_priority.set_sort_indicator(True)
+ self.column_priority.set_sort_column_id(8)
+ self.column_priority.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(self.column_priority)
+
+ # Language
+ renderer = Gtk.CellRendererText()
+ column = Gtk.TreeViewColumn('Language', renderer, markup=9)
+ column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ column.set_visible(False)
+ column.set_expand(False)
+ column.set_clickable(True)
+ column.set_sort_indicator(True)
+ column.set_sort_column_id(9)
+ column.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(column)
+
+ # Release date
+ renderer = Gtk.CellRendererText()
+ self.column_rel = Gtk.TreeViewColumn('Released on', renderer, markup=10)
+ self.column_rel.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
+ self.column_rel.set_visible(False)
+ self.column_rel.set_expand(False)
+ self.column_rel.set_clickable(True)
+ self.column_rel.set_sort_indicator(True)
+ self.column_rel.set_sort_column_id(10)
+ self.column_rel.set_sort_order(Gtk.SortType.ASCENDING)
+ self.append_column(self.column_rel)
+
+ # TreeView common
+ #~ self.set_level_indentation(6)
+ self.set_can_focus(True)
+ self.set_headers_visible(False)
+ self.set_enable_search(True)
+ #~ self.set_rules_hint(True)
+ #~ self.set_expander_column(expander_column)
+ self.set_hover_selection(False)
+ self.set_grid_lines(Gtk.TreeViewGridLines.NONE)
+ self.set_search_entry(self.gui.get_widget('stySearchInfo'))
+ self.set_search_column(3)
+ #~ self.set_row_separator_func(self.row_separator_func)
+
+ # Selection
+ self.selection = self.get_selection()
+ self.selection.set_select_function(self.select_function)
+ #~ self.selection.set_mode(Gtk.SelectionMode.BROWSE)
+ self.selection.set_mode(Gtk.SelectionMode.SINGLE)
+
+ # Go live
+ self.connect('button_press_event', self.cb_button_press)
+ self.connect('row-activated', self.double_click)
+ self.connect('cursor-changed', self.row_changed)
+ self.show_all()
+
+
+ def cell_data_func(self, column, cell, store, iter, data=None):
+ """Do not show checkbox when row type is distinct of sapnote"""
+ row = store[iter][0]
+ row_type, key = row.split('@')
+
+ if row_type != 'sapnote':
+ cell.set_visible(False)
+ else:
+ cell.set_visible(True)
+
+
+ def select_function(self, selection, store, path, current):
+ return True
+
+ #~ This code works: only allow select rows of type 'sapnote'
+ #~ rowtype = store[path][0]
+ #~ if rowtype == 'sapnote':
+ #~ return True
+ #~ else:
+ #~ return False
+
+
+ #~ def row_separator_func(self, model, iter):
+ #~ """ Call user function to determine if this node is separator """
+ #~ if iter and model.iter_is_valid(iter):
+ #~ rowtype = model.get_value(iter, 0)
+ #~ if row<type == 'sapnote':
+ #~ return True
+ #~ else:
+ #~ return False
+ #~ self.log.debug("Row type: %s" % rowtype)
+ #~ return False
+ #~ return False
+
+
+ def get_services(self):
+ self.gui = self.app.get_service("GUI")
+ self.cb = self.app.get_service('Callbacks')
+ self.menu = self.app.get_service("Menus")
+ self.sap = self.app.get_service('SAP')
+ self.im = self.app.get_service('IM')
+ self.settings = self.app.get_service('Settings')
+ self.plugins = self.app.get_service('Plugins')
+ self.db = self.app.get_service('DB')
+
+
+ def row_changed(self, treeview):
+ #~ button = self.gui.get_widget('mnuBtnActions')
+ selected = set()
+ selection = treeview.get_selection()
+ model, treeiters = selection.get_selected_rows()
+ try:
+ row = model[treeiters[0]][0]
+ row_type, sid = row.split('@')
+ self.log.debug("Row Type: %s - Id: %s" % (row_type, sid))
+ except Exception as error:
+ return
+ #~ self.log.error(error)
+ #~ raise
+ #~ return
+
+ if row_type == 'sapnote':
+ trvprops = self.gui.get_widget('trvprops')
+ modelprops = trvprops.get_model()
+ #~ tid = model[treeiters[0]][Column.id.value]
+ #~ tid = BSHTML(tid, "lxml").text # clean Id by removing all tags.
+ #~ sid = "0"*(10 - len(tid)) + tid
+ sapnote = self.db.get_sapnote_metadata(sid)
+
+ modelprops.clear()
+ modelprops.append(None, ["<big><b>SAP Note Id</b></big>", "<big>%s</big>" % sid])
+ modelprops.append(None, ["<big><b>Title</b></big>", "<big>%s</big>" % sapnote['title']])
+ modelprops.append(None, ["<big><b>Version</b></big>", "<big>%s</big>" % sapnote['version']])
+ modelprops.append(None, ["<big><b>Component Key</b></big>", "<big>%s</big>" % sapnote['componentkey']])
+ modelprops.append(None, ["<big><b>Component Text</b></big>", "<big>%s</big>" % sapnote['componenttxt']])
+ modelprops.append(None, ["<big><b>Category</b></big>", "<big>%s</big>" % sapnote['category']])
+ modelprops.append(None, ["<big><b>Type</b></big>", "<big>%s</big>" % sapnote['type']])
+ modelprops.append(None, ["<big><b>Priority</b></big>", "<big>%s</big>" % sapnote['priority']])
+ modelprops.append(None, ["<big><b>Language</b></big>", "<big>%s</big>" % sapnote['language']])
+ modelprops.append(None, ["<big><b>Released</b></big>", "<big>%s</big>" % sapnote['releaseon']])
+ modelprops.append(None, ["<big><b>Downloaded</b></big>", "<big>%s</big>" % str(sapnote['feedupdate'])])
+ modelprops.append(None, ["<big><b>Bookmarked</b></big>", "<big>%s</big>" % str(sapnote['bookmark'])])
+ try:
+ # Not all sapnotes are linked to a task. Skip this field
+ tasks = self.app.get_service('Tasks')
+ ltasks = sapnote['tasks']
+ tasks.select(ltasks)
+ modelprops.append(None, ["<b>Tasks</b>", ', '.join(ltasks)])
+ self.log.debug("SAP Note %s activated" % sid)
+ except Exception as error:
+ pass
+ else:
+ tasks = self.app.get_service('Tasks')
+ tasks.clear()
+ tasks.show_window()
+
+
+ def double_click(self, treeview, row, col):
+ model = treeview.get_model()
+ row = model[row][0]
+ row_type, sid = row.split('@')
+ self.set_select_notes([sid])
+ #~ self.log.debug("Launching SAP Note %s in browser" % noteid)
+ self.cb.actions_browse()
+
+
+ def cb_button_press(self, treeview, event, data=None):
+ if event.button == 3:
+ x = int(event.x)
+ y = int(event.y)
+ time = event.time
+ pthinfo = self.get_path_at_pos(x,y)
+ if pthinfo is not None:
+ path,col,cellx,celly = pthinfo
+ self.grab_focus()
+ self.set_cursor(path,col,0)
+
+ model = treeview.get_model()
+ treeiter = model.get_iter(path)
+ #~ for n in range(9):
+ #~ self.log.debug("%d -> %s" % (n, model.get_value(treeiter, n)))
+ rowtype = model.get_value(treeiter, 0)
+ self.log.debug("Row type: %s" % rowtype)
+ if rowtype == 'task':
+ task = model.get_value(treeiter, 6)
+ self.popup_menu = self.menu.create_popup_menu_by_task(task)
+ elif rowtype == 'component':
+ comptitle = model.get_value(treeiter, 3)
+ self.log.debug(comptitle)
+ token = "</b></big>"
+ pos = comptitle.find(token)
+ component = comptitle[8:pos]
+ self.popup_menu = self.menu.create_popup_menu_by_component(component)
+ elif rowtype == 'sapnote':
+ sid = model.get_value(treeiter, 6)
+ self.popup_menu = self.menu.create_popup_menu_by_sapnote(sid)
+ else:
+ return False
+
+
+ #~ noteid = model.get_value(treeiter, 6)
+ #~ sapnote = self.sap.get_node(noteid)
+ #~ self.log.debug("Selected SAP Note: %s" % sapnote)
+ if self.popup_menu is not None:
+ self.popup_menu.show_all()
+ self.popup_menu.popup(None, None, None, None, event.button, event.time)
+ return True # event has been handled
+ else:
+ return False
+
+
+ def populate(self, sapnotes):
+ #~ self.column_icon.set_visible(True)
+ #~ self.column_component.set_visible(True)
+ #~ self.column_title.set_visible(False)
+ #~ self.column_cat.set_visible(False)
+
+ self.set_headers_visible(False)
+ self.column_sid.set_visible(False)
+ self.column_rel.set_visible(False)
+ self.column_priority.set_visible(False)
+ self.column_icon.set_visible(True)
+ self.column_checkbox.set_visible(True)
+
+ if self.view == 'components':
+ self.populate_by_components(sapnotes)
+ elif self.view == 'description':
+ self.populate_by_component_descriptions(sapnotes)
+ elif self.view == 'projects':
+ self.populate_by_projects(sapnotes)
+ elif self.view == 'tasks':
+ self.populate_by_tasks(sapnotes)
+ elif self.view == 'bookmarks':
+ self.populate_by_bookmarks(sapnotes)
+ elif self.view == 'tags':
+ self.populate_by_tags(sapnotes)
+ elif self.view == 'category':
+ self.populate_by_category(sapnotes)
+ elif self.view == 'chronologic':
+ self.populate_by_chronologic(sapnotes)
+ elif self.view == 'priority':
+ self.populate_by_priority(sapnotes)
+ elif self.view == 'type':
+ self.populate_by_type(sapnotes)
+ else:
+ self.populate_by_components(sapnotes)
+ # Save last populated list of sap notes
+ total = self.db.get_total()
+ notesid = set()
+ for sapnote in sapnotes:
+ notesid.add(sapnote)
+
+ if len(notesid) < total:
+ self.settings.set_config_value('Notes', ','.join(notesid))
+
+ self.log.debug("View '%s' populated with %d SAP Notes" % (self.view, len(sapnotes)))
+
+
+ def populate_by_bookmarks(self, sapnotes):
+ #~ self.log.debug('Populating bookmarks')
+ self.model.clear()
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(False)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(False)
+ self.column_title.set_visible(True)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+ self.column_component.set_title('Component')
+ icon_bookmark = self.im.get_icon('bookmark')
+
+ for sid in sapnotes:
+ try:
+ bookmark = sapnotes[sid]['bookmark'] # True or False
+ except:
+ bookmark = False
+
+ if bookmark:
+ sapnote = self.get_node_sapnote_bookmark(sapnotes[sid], sid)
+ self.model.append(None, sapnote)
+
+
+ def get_node_project(self, project, icon):
+ if project == '':
+ title = "<span size='18000'><b>No project assigned</b></span>"
+ else:
+ title = "<span size='18000'><b>%s</b></span>" % project
+
+ node = []
+ node.append('project@%s' % project)
+ node.append(0)
+ node.append(icon)
+ node.append(title) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ node.append("") # Release on
+ return node
+
+
+ def get_node_task(self, task, icon):
+ if task == '':
+ title = "<big><b>No task assigned</b></big>"
+ else:
+ title = "<big><b>%s</b></big>" % task
+
+ node = []
+ node.append('task@%s' % task)
+ node.append(0)
+ node.append(icon)
+ node.append(title) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ node.append("") # Release on
+ return node
+
+
+ def populate_by_projects(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+ icon_noproject = self.im.get_icon('noproject')
+ icon_project = self.im.get_icon('project')
+ icon_sapnote = self.im.get_icon('fingerprint')
+ icon_bookmark = self.im.get_icon('bookmark')
+ self.column_component.set_title('Projects')
+
+ if len(sapnotes) == 0:
+ return
+
+ node = self.get_node_project('', icon_noproject)
+ pid = self.model.append(None, node)
+ treepids['None'] = pid
+
+ notlinked = 0
+ for sid in sapnotes:
+ try:
+ projects = sapnotes[sid]['projects']
+ except:
+ projects = []
+
+
+ if len(projects) == 0:
+ #~ SAP Note not linked to any project
+ sapnote = self.get_node_sapnote(sapnotes[sid], sid)
+ self.model.append(treepids['None'], sapnote)
+ notlinked += 1
+ else:
+ #~ SAP Note linked to projects
+ for project in projects:
+ try:
+ pid = treepids[project]
+ except:
+ node = self.get_node_project(project, icon_project)
+ pid = self.model.append(None, node)
+ treepids[project] = pid
+
+ sapnote = self.get_node_sapnote(sapnotes[sid], sid)
+ self.model.append(pid, sapnote)
+
+ if notlinked == 0:
+ self.model.remove(treepids['None'])
+
+
+ def populate_by_tags(self, sapnotes):
+ pass
+ #~ for sid in sapnotes:
+ #~ tags = sapnotes[sid]['']
+
+ def populate_by_tasks(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+ icon_notask = self.im.get_icon('notask', 32, 32)
+ icon_task = self.im.get_icon('task', 32, 32)
+ icon_sapnote = self.im.get_icon('fingerprint', 32, 32)
+ icon_bookmark = self.im.get_icon('bookmark', 32, 32)
+ self.column_component.set_title('Tasks')
+ #~ self.column_icon.set_visible(False)
+ #~ self.column_sid.set_visible(True)
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(True)
+ self.column_title.set_visible(False)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+
+ if len(sapnotes) == 0:
+ return
+
+ #~ "No task assigned" node creation
+ node = self.get_node_task('', icon_notask)
+ pid = self.model.append(None, node)
+ treepids['None'] = pid
+
+ scomp = set()
+ dcomp = {}
+ taskset = set()
+ for sid in sapnotes:
+ try:
+ # setup components
+ compkey = escape(sapnotes[sid]['componentkey'])
+ comptxt = escape(sapnotes[sid]['componenttxt'])
+ scomp.add(compkey)
+ dcomp[compkey] = comptxt
+
+ # setup tasks
+ for task in sapnotes[sid]['tasks']:
+ taskset.add(task)
+ except: pass
+
+ lcomp = list(scomp)
+ lcomp.sort()
+
+ tasklist = []
+ tasklist.extend(taskset)
+ tasklist.sort()
+
+ for task in tasklist:
+ node = self.get_node_task(task, icon_task)
+ pid = self.model.append(None, node)
+ treepids[task] = pid
+
+ notask = 0
+ for sid in sapnotes:
+ #~ Get category
+ compkey = escape(sapnotes[sid]['componentkey'])
+ catname = escape(sapnotes[sid]['category'])
+
+
+ #~ Get tasks for this sapnote
+ try:
+ tasks = sapnotes[sid]['tasks']
+ except:
+ sapnotes[sid]['tasks'] = tasks = []
+
+
+ if len(tasks) == 0:
+ # Components in no-task node
+ cmpkey = "notask" + '-' + compkey
+ comptxt = dcomp[compkey]
+ try:
+ pid = treepids[cmpkey]
+ except:
+ node = self.get_node_component(compkey, comptxt)
+ pid = self.model.append(treepids['None'], node)
+ treepids[cmpkey] = pid
+
+ # Categories in no-task node
+ catkey = "notask" + '-' + compkey + '-' + catname
+ try:
+ cid = treepids[catkey]
+ except:
+ node = self.get_node_category(sapnotes[sid])
+ cid = self.model.append(pid, node)
+ treepids[catkey] = cid
+
+ #~ SAP Note not linked to any task
+ sapnote = self.get_node_sapnote_task(sapnotes[sid], sid)
+ self.model.append(cid, sapnote)
+ notask += 1
+ else:
+ #~ SAP Note linked to tasks
+ for task in sapnotes[sid]['tasks']:
+ # Components in task node
+ cmpkey = task + '-' + compkey
+ comptxt = dcomp[compkey]
+ pid = treepids[task]
+ sapnote = self.get_node_sapnote_task(sapnotes[sid], sid)
+ self.model.append(treepids[task], sapnote)
+
+ #~ "No task assigned" node deletion if no tasks at all
+ if notask == 0:
+ self.model.remove(treepids['None'])
+
+
+ def populate_by_priority(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(False)
+ self.column_title.set_visible(True)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+
+ if len(sapnotes) == 0:
+ return
+
+ scomp = set()
+ dcomp = {}
+ pset = set()
+
+ for sid in sapnotes:
+ try:
+ priority = sapnotes[sid]['priority']
+ pset.add(priority)
+ except: pass
+
+ plist = []
+ plist.extend(pset)
+ plist.sort()
+
+ for priority in plist:
+ node = self.get_node_priority(priority)
+ pid = self.model.append(None, node)
+ treepids[priority] = pid
+
+ for sid in sapnotes:
+ priority = sapnotes[sid]['priority']
+ pid = treepids[priority]
+ sapnote = self.get_node_sapnote(sapnotes[sid], sid)
+ self.model.append(pid, sapnote)
+
+
+ def populate_by_type(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(False)
+ self.column_title.set_visible(True)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+
+ if len(sapnotes) == 0:
+ return
+
+ scomp = set()
+ dcomp = {}
+ pset = set()
+
+ for sid in sapnotes:
+ try:
+ sntype = sapnotes[sid]['type']
+ pset.add(sntype)
+ except: pass
+
+ plist = []
+ plist.extend(pset)
+ plist.sort()
+
+ for sntype in plist:
+ node = self.get_node_type(sntype)
+ pid = self.model.append(None, node)
+ treepids[sntype] = pid
+
+ for sid in sapnotes:
+ sntype = sapnotes[sid]['type']
+ pid = treepids[sntype]
+ sapnote = self.get_node_sapnote_type(sapnotes[sid], sid)
+ self.model.append(pid, sapnote)
+
+
+
+ def populate_by_component_descriptions(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(True)
+ self.column_title.set_visible(False)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+
+ if len(sapnotes) == 0:
+ return
+
+ scomp = set()
+ dcomp = {}
+ pset = set()
+
+ for sid in sapnotes:
+ try:
+ comptxt = escape(sapnotes[sid]['componenttxt'])
+ pset.add(comptxt)
+ except: pass
+
+ plist = []
+ plist.extend(pset)
+ plist.sort()
+
+ for comptxt in plist:
+ node = self.get_node_component_desc(comptxt)
+ pid = self.model.append(None, node)
+ treepids[comptxt] = pid
+
+ for sid in sapnotes:
+ comptxt = escape(sapnotes[sid]['componenttxt'])
+ pid = treepids[comptxt]
+ sapnote = self.get_node_sapnote_component_desc(sapnotes[sid], sid)
+ self.model.append(pid, sapnote)
+
+
+ def populate_by_category(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+ icon_nocat = self.im.get_icon('notask')
+ icon_cat = self.im.get_icon('category')
+ icon_sapnote = self.im.get_icon('fingerprint')
+ icon_bookmark = self.im.get_icon('bookmark')
+ self.column_component.set_title('Categories')
+ #~ self.column_icon.set_visible(False)
+ #~ self.column_sid.set_visible(True)
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(True)
+ self.column_title.set_visible(False)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+
+ if len(sapnotes) == 0:
+ return
+
+ scomp = set()
+ dcomp = {}
+ catset = set()
+
+ for sid in sapnotes:
+ try:
+ cat = sapnotes[sid]['category']
+ catset.add(cat)
+ except: pass
+
+ catlist = []
+ catlist.extend(catset)
+ catlist.sort()
+
+ for cat in catlist:
+ node = self.get_node_category_view(cat)
+ pid = self.model.append(None, node)
+ treepids[cat] = pid
+
+ for sid in sapnotes:
+ category = sapnotes[sid]['category']
+ pid = treepids[category]
+ sapnote = self.get_node_sapnote_category(sapnotes[sid], sid)
+ self.model.append(pid, sapnote)
+
+
+ def populate_by_chronologic(self, sapnotes):
+ self.model.clear()
+ treepids = {}
+
+ self.column_component.set_title('Download date')
+ self.set_headers_visible(True)
+ self.column_sid.set_visible(True)
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(True)
+ self.column_title.set_visible(False)
+ self.column_title.set_expand(True)
+ self.column_priority.set_expand(False)
+ self.column_cat.set_visible(False)
+ self.column_sid.set_expand(False)
+
+ if len(sapnotes) == 0:
+ return
+
+ years = set()
+ months = set()
+ days = set()
+ for sid in sapnotes:
+ try:
+ downloaded = dateparser.parse(sapnotes[sid]['feedupdate'])
+ year = "%d" % downloaded.year
+ month = "%02d" % downloaded.month
+ day = "%02d" % downloaded.day
+ key_year = year
+ key_month = year + month
+ key_day = year + month + day
+ years.add(key_year)
+ months.add(key_month)
+ days.add(key_day)
+ except:
+ pass
+ years = list(years)
+ years.sort(reverse=True)
+ months = list(months)
+ months.sort(reverse=True)
+ days = list(days)
+ days.sort(reverse=True)
+
+ for key_year in years:
+ try:
+ treepids[key_year]
+ except:
+ adate = key_year + '0101'
+ downloaded = dateparser.parse(adate)
+ node = self.get_node_date_year(downloaded, key_year)
+ treepids[key_year] = self.model.append(None, node)
+
+ for key_month in months:
+ try:
+ treepids[key_month]
+ except:
+ adate = key_month + '01'
+ downloaded = dateparser.parse(adate)
+ node = self.get_node_date_month(downloaded, key_month)
+ key_year = key_month[0:4]
+ treepids[key_month] = self.model.append(treepids[key_year], node)
+
+ for key_day in days:
+ try:
+ treepids[key_day]
+ except:
+ downloaded = dateparser.parse(key_day)
+ key_month = key_day[0:6]
+ node = self.get_node_date_day(downloaded, key_day)
+ treepids[key_day] = self.model.append(treepids[key_month], node)
+
+ for sid in sapnotes:
+ downloaded = dateparser.parse(sapnotes[sid]['feedupdate'])
+ year = "%d" % downloaded.year
+ month = "%02d" % downloaded.month
+ day = "%02d" % downloaded.day
+ key_year = year
+ key_month = year + month
+ key_day = year + month + day
+ node = self.get_node_sapnote_chronologic(sapnotes[sid], sid)
+ #~ self.log.debug("KeyDay %s for SAP Note %s" % (treepids[key_day], sid))
+ self.model.append(treepids[key_day], node)
+
+ self.collapse_all()
+ self.expand_all()
+
+
+
+
+ def get_node_component(self, compkey, comptxt):
+ #~ compkey = escape(sapnote['componentkey'])
+ #~ comptxt = escape(sapnote['componenttxt'])
+ icon = self.im.get_icon('component', 32, 32)
+ node = []
+ if len(comptxt) > 0:
+ component = "<big><b>%s</b></big> (<i>%s</i>)" % (compkey, comptxt) # component
+ else:
+ component = "<big><b>%s</b></big>" % compkey
+
+ #~ component = "<big><b>%s</b></big>" % (compkey)
+ #~ component = "<span size='18000'><b>%s</b></span> <span size='12000'>(<i>%s</i>)</span>" % (compkey, comptxt)
+ node.append('component@%s' % compkey)
+ node.append(0)
+ node.append(icon)
+ node.append(component) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_category(self, sapnote):
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ catkey = compkey + '-' + catname
+ icon = self.im.get_icon('category', 32, 32)
+
+ if len(catname) == 0:
+ #~ catname = "<span size='12000'><b>No category assigned</b></span>"
+ catname = "\t<b>No category assigned</b>"
+ else:
+ #~ category = "<span size='15000'><b>%s</b></span>" % catname
+ category = "\t<b>%s</b>" % catname
+
+ node = []
+ node.append('category@%s' % catname)
+ node.append(0)
+ node.append(icon)
+ node.append(category) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_date_year(self, date, token_date):
+ title = "<span size='12000'><b>%s</b></span>" % token_date
+
+ node = []
+ node.append('date-year@%s' % token_date)
+ node.append(0)
+ node.append(None)
+ node.append(title) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_date_month(self, date, token_date):
+ title = "<span size='12000'><b>%s</b></span>" % date.strftime("%B")
+
+ node = []
+ node.append('date-month@%s' % token_date)
+ node.append(0)
+ node.append(None)
+ node.append(title) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_date_day(self, date, token_date):
+ title = "<span size='12000'><b>%s</b></span>" % date.strftime("%d - %A")
+
+ node = []
+ node.append('date-day@%s' % token_date)
+ node.append(0)
+ node.append(None)
+ node.append(title) # Component
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_priority(self, priority):
+ icon = None # self.im.get_icon('category', 32, 32)
+
+ if len(priority) == 0:
+ title = "<big><b>No priority assigned</b></big>"
+ else:
+ title = "<big><b>%s</b></big>" % priority
+
+ node = []
+ node.append('priority@%s' % priority)
+ node.append(0)
+ node.append(icon)
+ node.append(title) # Component # Category title
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_type(self, sntype):
+ icon = self.im.get_icon('type', 32, 32)
+
+ if len(sntype) == 0:
+ title = "<big><b>SAP Note type not found</b></big>"
+ else:
+ title = "<big><b>%s</b></big>" % sntype
+
+ node = []
+ node.append('sntype@%s' % sntype)
+ node.append(0)
+ node.append(icon)
+ node.append(title) # Component # Category title
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+
+ def get_node_component_desc(self, comptxt):
+ icon = self.im.get_icon('component', 32, 32)
+
+ if len(comptxt) == 0:
+ title = "<big><b>No component assigned</b></big>"
+ else:
+ title = "<big><b>%s</b></big>" % comptxt
+
+ node = []
+ node.append('component-desc@%s' % comptxt)
+ node.append(0)
+ node.append(icon)
+ node.append(title) # Component # Category title
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_category_view(self, category=''):
+ #~ compkey = escape(sapnote['componentkey'])
+ #~ catname = escape(sapnote['category'])
+ #~ catkey = compkey + '-' + catname
+ icon = None # self.im.get_icon('category', 32, 32)
+
+ if len(category) == 0:
+ #~ catname = "<span size='12000'><b>No category assigned</b></span>"
+ catname = "<big><b>No category assigned</b></big>"
+ else:
+ #~ category = "<span size='15000'><b>%s</b></span>" % catname
+ catname = "<big><b>%s</b></big>" % category
+
+ node = []
+ node.append('category@%s' % category)
+ node.append(0)
+ node.append(icon)
+ node.append(catname) # Component # Category title
+ node.append("") # Category
+ node.append("") # Type
+ node.append("") # Id
+ node.append("") # Title
+ node.append("") # Priority
+ node.append("") # Lang
+ #~ node.append("") # Version
+ node.append("") # Release on
+ return node
+
+
+ def get_node_sapnote_bookmark(self, sapnote, sid):
+ compkey = escape(sapnote['componentkey'])
+ icon_note = self.im.get_pixbuf_icon('fingerprint')
+ icon_fav = self.im.get_icon('bookmark')
+ compkey = escape(sapnote['componentkey'])
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ priority = "%s" % escape(sapnote['priority'])
+ released = dateparser.parse(sapnote['releaseon'])
+ released = released.strftime("%Y.%m.%d")
+ sid = "0"*(10 - len(sid)) + sid
+ title = "<big>%s</big>" % (escape(sapnote['title']))
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+ node.append(icon_fav) # 2. # Icon
+ node.append("%s" % compkey) # 3. # Component
+ node.append("%s" % catname) # 4. # Category
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+ node.append(title) # 7. # Title
+ node.append(priority) # 8. # Priority
+ node.append(sapnote['language']) # 9. # Lang
+ node.append(released) # 10. # Release date
+
+ return node
+
+
+ def get_node_sapnote_task(self, sapnote, sid):
+ compkey = escape(sapnote['componentkey'])
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ priority = "%s" % escape(sapnote['priority'])
+ released = dateparser.parse(sapnote['releaseon'])
+ released = released.strftime("%Y.%m.%d")
+ sid = "0"*(10 - len(sid)) + sid
+ title = "<big>%s</big>" % (escape(sapnote['title']))
+ bookmarked = sapnote['bookmark']
+
+ if bookmarked:
+ icon = self.im.get_icon('bookmark', 32, 32)
+ else:
+ icon = self.im.get_icon('fingerprint', 32, 32)
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+ node.append(icon) # 2. # Icon
+ node.append(title) # 3. # Component
+ node.append("") # 4. # Category
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+ node.append("") # 7. # Title
+ node.append(priority) # 8. # Priority
+ node.append(sapnote['language']) # 9. # Lang
+ node.append(released) # 10. # Release date
+
+ return node
+
+
+ def get_node_sapnote_type(self, sapnote, sid):
+ #~ compkey = escape(sapnote['componentkey'])
+ #~ compkey = escape(sapnote['componentkey'])
+ #~ catname = escape(sapnote['category'])
+ sntype = "%s" % escape(sapnote['type'])
+ #~ released = dateparser.parse(sapnote['releaseon'])
+ #~ released = released.strftime("%Y.%m.%d")
+ sid = "0"*(10 - len(sid)) + sid
+ title = "<big>%s</big>" % (escape(sapnote['title']))
+ bookmarked = sapnote['bookmark']
+
+ if bookmarked:
+ icon = self.im.get_icon('bookmark', 32, 32)
+ else:
+ icon = self.im.get_icon('fingerprint', 32, 32)
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+ node.append(icon) # 2. # Icon
+ node.append(title) # 3. # Component
+ node.append("") # 4. # Category
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+ node.append("") # 7. # Title
+ node.append("") # 8. # Priority
+ node.append(sapnote['language']) # 9. # Lang
+ node.append("") # 10. # Release date
+
+ return node
+
+
+ def get_node_sapnote_component_desc(self, sapnote, sid):
+ compkey = escape(sapnote['componentkey'])
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ priority = "%s" % escape(sapnote['priority'])
+ released = dateparser.parse(sapnote['releaseon'])
+ released = released.strftime("%Y.%m.%d")
+ sid = "0"*(10 - len(sid)) + sid
+ title = "<big>%s</big>" % (escape(sapnote['title']))
+ bookmarked = sapnote['bookmark']
+
+ if bookmarked:
+ icon = self.im.get_icon('bookmark', 32, 32)
+ else:
+ icon = self.im.get_icon('fingerprint', 32, 32)
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+ node.append(icon) # 2. # Icon
+ node.append(title) # 3. # Component
+ node.append("") # 4. # Category
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+ node.append("") # 7. # Title
+ node.append(priority) # 8. # Priority
+ node.append(sapnote['language']) # 9. # Lang
+ node.append(released) # 10. # Release date
+
+ return node
+
+
+ def get_node_sapnote_category(self, sapnote, sid):
+ compkey = escape(sapnote['componentkey'])
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ priority = "%s" % escape(sapnote['priority'])
+ released = dateparser.parse(sapnote['releaseon'])
+ released = released.strftime("%Y.%m.%d")
+ sid = "0"*(10 - len(sid)) + sid
+ title = "<big>%s</big>" % (escape(sapnote['title']))
+ bookmarked = sapnote['bookmark']
+
+ if bookmarked:
+ icon = self.im.get_icon('bookmark', 32, 32)
+ else:
+ icon = self.im.get_icon('fingerprint', 32, 32)
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+ node.append(icon) # 2. # Icon
+ node.append(title) # 3. # Component
+ node.append("") # 4. # Category
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+ node.append("") # 7. # Title
+ node.append(priority) # 8. # Priority
+ node.append(sapnote['language']) # 9. # Lang
+ node.append(released) # 10. # Release date
+
+ return node
+
+
+ def get_node_sapnote_chronologic(self, sapnote, sid):
+ compkey = escape(sapnote['componentkey'])
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ priority = "%s" % escape(sapnote['priority'])
+ released = dateparser.parse(sapnote['releaseon'])
+ released = released.strftime("%Y.%m.%d")
+ sid = "0"*(10 - len(sid)) + sid
+ title = "<big>%s</big>" % (escape(sapnote['title']))
+ bookmarked = sapnote['bookmark']
+
+ if bookmarked:
+ icon = self.im.get_icon('bookmark', 32, 32)
+ else:
+ icon = self.im.get_icon('fingerprint', 32, 32)
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+ node.append(icon) # 2. # Icon
+ node.append(title) # 3. # Component
+ node.append("") # 4. # Category
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+ node.append("") # 7. # Title
+ node.append(priority) # 8. # Priority
+ node.append(sapnote['language']) # 9. # Lang
+ node.append(released) # 10. # Release date
+
+ return node
+
+
+
+ def get_node_sapnote(self, sapnote, sid):
+ compkey = escape(sapnote['componentkey'])
+ icon_note = self.im.get_icon('fingerprint', 32, 32)
+ icon_fav = self.im.get_icon('bookmark', 32, 32)
+ compkey = escape(sapnote['componentkey'])
+ compkey = escape(sapnote['componentkey'])
+ catname = escape(sapnote['category'])
+ sid = "0"*(10 - len(sid)) + sid
+
+ # Get bookmark
+ try:
+ bookmark = sapnote['bookmark']
+ except Exception as error:
+ bookmark = False
+
+ # Get correct title
+ title = "%s" % (escape(sapnote['title']))
+
+ # Create row-node
+ node = []
+ node.append('sapnote@%s' % sid) # 0. # RowType
+ node.append(0) # 1. # CheckBox
+
+ # 2. # Icon
+ if bookmark:
+ node.append(icon_fav)
+ else:
+ node.append(icon_note)
+
+ # 3. # Component
+ if self.view == 'components':
+ node.append(title)
+ # 4. # Category
+ node.append("")
+ elif self.view == 'bookmarks':
+ node.append("%s" % compkey)
+ # 4. # Category
+ node.append("%s" % catname)
+ #~ node.append(catname)
+ elif self.view == 'tasks':
+ node.append("%s" % compkey)
+ # 4. # Category
+ node.append("%s" % catname)
+ #~ node.append(catname)
+ elif self.view == 'chronologic':
+ node.append("")
+ # 4. # Category
+ node.append("")
+ #~ node.append(catname)
+ elif self.view == 'category':
+ node.append("")
+ # 4. # Category
+ node.append("")
+ #~ node.append(catname)
+ elif self.view == 'description':
+ node.append("")
+ # 4. # Category
+ node.append("")
+ #~ node.append(catname)
+ else:
+ node.append(title)
+ # 4. # Category
+ node.append("")
+
+ node.append(sapnote['type']) # 5. # Type
+ node.append("<b>%s</b>" %sid) # 6. # Sap Note ID
+
+ # 7. # Title
+ if self.view == 'bookmarks':
+ node.append(title)
+ elif self.view == 'tasks':
+ node.append(title)
+ elif self.view == 'chronologic':
+ node.append(title)
+ elif self.view == 'category':
+ node.append(title)
+ elif self.view == 'description':
+ node.append(title)
+ else:
+ node.append("")
+
+ # 8. # Priority
+ priority = "%s" % escape(sapnote['priority'])
+ node.append(priority)
+
+ # 9. # Lang
+ node.append(sapnote['language'])
+
+ # 10. # Release date
+ released = dateparser.parse(sapnote['releaseon'])
+ node.append(released.strftime("%Y.%m.%d"))
+
+ return node
+
+
+ def populate_by_components(self, sapnotes, only_bookmarks=False):
+ self.log.debug('Populating by components')
+ self.model.clear()
+ self.treepids = {}
+ self.column_component.set_title('Components')
+ self.column_icon.set_visible(True)
+ self.column_component.set_visible(True)
+ self.column_component.set_expand(True)
+ self.column_title.set_visible(False)
+ self.column_sid.set_visible(True)
+ #~ self.column_title.set_visible(True)
+ self.set_headers_visible(True)
+ #~ self.set_grid_lines(Gtk.TreeViewGridLines.VERTICAL)
+
+ #~ self.column_title
+
+ if len(sapnotes) == 0:
+ return
+
+ scomp = set()
+ dcomp = {}
+
+ for sid in sapnotes:
+ compkey = escape(sapnotes[sid]['componentkey'])
+ comptxt = escape(sapnotes[sid]['componenttxt'])
+ scomp.add(compkey)
+ dcomp[compkey] = comptxt
+ lcomp = list(scomp)
+ lcomp.sort()
+
+ for compkey in lcomp:
+ #~ print (compkey)
+ subkeys = compkey.split('-')
+ ppid = None
+ for i in range(1, len(subkeys)+1):
+ key = ('-').join(subkeys[0:i])
+ try:
+ ppid = self.treepids[key]
+ #~ print ("\tSubkey found: %s" % key)
+ except:
+ if i == len(subkeys):
+ title = dcomp[compkey]
+ else:
+ title = ""
+ #~ title = key[key.rfind('-')+1:]
+ node = self.get_node_component(key, title)
+ ppid = self.model.append(ppid, node)
+ self.treepids[key] = ppid
+ #~ print ("\tSubkey added: %s" % key)
+
+
+ for sid in sapnotes:
+ #~ Gety component
+ compkey = escape(sapnotes[sid]['componentkey'])
+ pid = self.treepids[compkey]
+
+ #~ Get category
+ catname = escape(sapnotes[sid]['category'])
+ catkey = compkey + '-' + catname
+ try:
+ cid = self.treepids[catkey]
+ except:
+ node = self.get_node_category(sapnotes[sid])
+ cid = self.model.append(pid, node)
+ self.treepids[catkey] = cid
+
+ #~ Get SAP Note
+ if only_bookmarks:
+ try:
+ bookmark = sapnotes[sid]['bookmark'] # True or False
+ except:
+ bookmark = False
+
+ if bookmark:
+ node = self.get_node_sapnote(sapnotes[sid], sid)
+ self.model.append(cid, node)
+ else:
+ node = self.get_node_sapnote(sapnotes[sid], sid)
+ self.model.append(cid, node)
+
+
+ def changed(self, *args):
+ try:
+ model, treeiters = self.selection.get_selected_rows()
+ selected = set()
+ if len(treeiters) > 0:
+ for treeiter in treeiters:
+ if treeiter != None:
+ selected.add(model[treeiter][0])
+ except Exception as error:
+ self.log.error (self.get_traceback())
+
+
+ def on_cell_toggled(self, widget, path):
+ model = self.get_model()
+ rtype = model[path][0]
+
+ if rtype != 'component' and rtype != 'category':
+ model[path][1] = not model[path][1]
+ self.count = 0
+ self.check_states()
+
+ self.cb.check_task_link_button_status()
+ #FIXME:
+ #(basico:10248): Gtk-WARNING **: Failed to set text from markup
+ # due to error parsing markup: Error en la lÝnea 1: La entidad
+ # no termina con un punto y coma; probablemente utiliz¾ el
+ # carßcter "&" sin la intenci¾n de indicar una entidad, escape
+ #el signo "&" como &amp;
+
+
+ def check_states(self):
+ lblSelectedNotes = self.gui.get_widget('lblSelectedNotes')
+ self.selected = set()
+
+ def traverse_treeview(model, path, iter, user_data=None):
+ row = model.get_value(iter, 0)
+ row_type, key = row.split('@')
+ if row_type == 'component':
+ # select everything (categories and notes)
+ #~ component = rtype = model.get_value(iter, 3)
+ #~ ce = component.find('</b></big>')
+ compkey = key #component[8:ce]
+ elif row_type == 'category':
+ # select all notes under that category
+ #~ category = rtype = model.get_value(iter, 3)
+ #~ ce = category.find("</b></big>")
+ catkey = key # category[9:ce]
+
+ toggled = model.get_value(iter, 1)
+ if toggled:
+ self.count += 1
+ #~ title = model.get_value(iter, 3)
+ #~ tid = model.get_value(iter, 6)
+ #~ sid = BSHTML(tid, "lxml").text
+ self.selected.add(key)
+ return False
+
+ model = self.get_model()
+ model.foreach(traverse_treeview)
+ lblSelectedNotes.set_markup('<big>%d of %d\nSAP Notes selected</big>' % (len(self.selected), self.db.get_total()))
+ actions = self.gui.get_widget('mnuBtnActions')
+ if (len(self.selected)) > 0:
+ actions.set_sensitive(True)
+ self.cb.setup_menu_actions()
+ else:
+ actions.set_sensitive(False)
+
+ self.cb.setup_menu_import()
+
+
+ def set_select_notes(self, sapnotes):
+ self.selected = set()
+ for sapnote in sapnotes:
+ self.selected.add(sapnote)
+
+
+ def get_selected_notes(self):
+ bag = list(self.selected)
+ bag.sort()
+ self.log.debug("Selected SAP Notes: %s" % ', '.join(bag))
+ return bag
+
+
+ def get_view(self):
+ if self.view is None:
+ return 'components'
+
+ return self.view
+
+
+ def set_view(self, view):
+ settings = self.app.get_service('Settings')
+
+ if view is None:
+ view = settings.get_config_value('View')
+
+ # Save view to settings
+ if view not in ['settings', 'download']:
+ self.view = view
+ settings = self.app.get_service('Settings')
+ settings.set_config_value('View', view)
+
+ # Change icon
+ iconview = self.gui.get_widget('imgViewCurrent')
+ if view == 'settings':
+ iconname = 'gtk-preferences'
+ elif view == 'download':
+ iconname = 'download'
+ else:
+ iconname = view
+
+ icon = self.im.get_pixbuf_icon(iconname, 48, 48)
+ iconview.set_from_pixbuf(icon)
+
+ # Change label
+ viewlabel = self.gui.get_widget('lblViewCurrent')
+ name = "<span size='20000'><b>%-10s</b></span>" % view.capitalize()
+ viewlabel.set_markup(name)
+
+
+
+ def expand(self):
+ switch = self.gui.get_widget('schExpandCollapse')
+ switch.set_active(True)
+
+ def collapse(self):
+ switch = self.gui.get_widget('schExpandCollapse')
+ switch.set_active(False)
+
+ def expand_collapse(self, switch, active):
+ if active:
+ self.expand_all()
+ else:
+ self.collapse_all()
+
+
+ def select_all_none(self, switch, active):
+ model = self.get_model()
+
+ def traverse_treeview(model, path, iter, user_data=None):
+ row = model.get_value(iter, 0)
+ row_type, sid = row.split('@')
+ if row_type == 'sapnote':
+ model.set_value(iter, 1, active)
+
+ return False
+
+ model.foreach(traverse_treeview, active)
+ self.check_states()
+
+
+ def select_by_component(self, component_target, active):
+ model = self.get_model()
+ #~ self.log.debug("Component target: %s" % component_target)
+
+ def traverse_treeview(model, path, iter, user_data=None):
+ row = model.get_value(iter, 0)
+ row_type, sid = row.split('@')
+ if row_type == 'sapnote':
+ tid = model.get_value(iter, 6)
+ sid = "0"*(10 - len(tid)) + tid
+ self.log.debug(sid)
+ sapnote = self.db.get_sapnote_metadata(sid)
+ component_source = sapnote['componentkey']
+ #~ self.log.debug("Component source: %s - Component target: %s" % (component_source, component_target))
+ if component_source == component_target:
+ model.set_value(iter, 1, active)
+
+ return False
+
+ model.foreach(traverse_treeview, True)
+ self.check_states()
+
+
+ def select_by_task(self, task_target, active):
+ model = self.get_model()
+
+ def traverse_treeview(model, path, iter, user_data=None):
+ row = model.get_value(iter, 0)
+ row_type, sid = row.split('@')
+ if row_type == 'sapnote':
+ sid = model.get_value(iter, 6)
+ sapnote = self.db.get_sapnote_metadata(sid)
+ tasks_source = sapnote['tasks']
+
+ if task_target in tasks_source:
+ model.set_value(iter, 1, active)
+ else:
+ if len(task_target) == 0 and len(tasks_source) == 0:
+ model.set_value(iter, 1, active)
+
+ return False
+
+ model.foreach(traverse_treeview, True)
+ self.check_states()
Index: REL-0.2/basico/settings.py
===================================================================
--- REL-0.2/basico/settings.py (nonexistent)
+++ REL-0.2/basico/settings.py (revision 76)
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: settings.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Settings service
+
+
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository.GdkPixbuf import Pixbuf
+
+from .service import Service
+
+# Default settings for SAP module
+LOGIN_PAGE_URL = "https://accounts.sap.com"
+LOGOUT_PAGE_URL = "https://accounts.sap.com/ui/logout"
+ODATA_NOTE_URL = "https://launchpad.support.sap.com/services/odata/svt/snogwscorr/TrunkSet(SapNotesNumber='%s',Version='0',Language='E')" #$expand=LongText" #?$expand=LongText,RefTo,RefBy"
+SAP_NOTE_URL = "https://launchpad.support.sap.com/#/notes/%s"
+SAP_NOTE_URL_PDF = "https://launchpad.support.sap.com/services/pdf/notes/%s/E"
+TIMEOUT = 5
+
+
+class Settings(Service):
+ def initialize(self):
+ view = self.get_config_value('View')
+ self.log.debug("View: %s" % view)
+
+ def get_default_settings(self):
+ settings = {}
+ # Deprecated as Basico uses now login with SAP Passport
+ #~ settings['CNF_SAP_SUser'] = 'SXXXXXXXXXX'
+ #~ settings['CNF_SAP_SPass'] = 'MyP455w0rD'
+ utils = self.get_service('Utils')
+ settings['CNF_SAP_LOGIN'] = LOGIN_PAGE_URL
+ settings['CNF_SAP_LOGOUT'] = LOGOUT_PAGE_URL
+ settings['CNF_SAP_ODATA_NOTES'] = ODATA_NOTE_URL
+ settings['CNF_SAP_NOTE_URL'] = SAP_NOTE_URL
+ settings['CNF_SAP_CONN_TIMEOUT'] = TIMEOUT
+ settings['CNF_FF_PROFILE_DIR'] = utils.get_firefox_profile_dir()
+
+ return settings
+
+
+ def get_custom_settings(self):
+ sap = self.get_service('SAP')
+ utils = self.get_service('Utils')
+
+ settings = {}
+ settings['CNF_SAP_LOGIN'] = sap.get_config_value('CNF_SAP_LOGIN')
+ settings['CNF_SAP_LOGOUT'] = sap.get_config_value('CNF_SAP_LOGOUT')
+ settings['CNF_SAP_ODATA_NOTES'] = sap.get_config_value('CNF_SAP_ODATA_NOTES')
+ settings['CNF_SAP_NOTE_URL'] = sap.get_config_value('CNF_SAP_NOTE_URL')
+ settings['CNF_SAP_CONN_TIMEOUT'] = sap.get_config_value('CNF_SAP_CONN_TIMEOUT')
+ settings['CNF_FF_PROFILE_DIR'] = sap.get_config_value('CNF_FF_PROFILE_DIR')
+
+ return settings
Index: REL-0.2/basico/projects.py
===================================================================
--- REL-0.2/basico/projects.py (nonexistent)
+++ REL-0.2/basico/projects.py (revision 76)
@@ -0,0 +1,241 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: projects.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Projects service
+
+
+from gi.repository import Gtk
+from gi.repository.GdkPixbuf import Pixbuf
+from gi.repository import Pango
+from datetime import datetime
+from dateutil import parser as dateparser
+
+from .service import Service
+
+
+class Projects(Service):
+ def initialize(self):
+ self.get_services()
+ self.setup_window()
+
+
+ def setup_window(self):
+ # setup widgets
+ self.window = self.gui.add_widget('winProjects')
+ self.parent = self.gui.get_widget('mainwindow')
+ self.window.set_transient_for(self.parent)
+ self.pname = self.gui.add_widget('etyProjectName')
+ self.pname.connect('activate', self.add_project)
+ self.boxproj = self.gui.add_widget('boxProjects')
+ self.btnadd = self.gui.add_widget('btnAddProject')
+ self.btnadd.connect('clicked', self.add_project)
+ self.btndel = self.gui.add_widget('btnDelProject')
+ self.btndel.connect('clicked', self.delete_project)
+ self.btncancel = self.gui.add_widget('btnCancelProjects')
+ self.btncancel.connect('clicked', self.hide_window)
+ self.btnaccept = self.gui.add_widget('btnAcceptProjects')
+ self.btnaccept.connect('clicked', self.link_to_project)
+ self.treeview = self.gui.add_widget('trvprojwin', Gtk.TreeView())
+ self.boxproj.add(self.treeview)
+ self.hide_window()
+
+ # setup model
+ model = Gtk.ListStore(
+ bool, # CheckBox
+ str # Project name
+ )
+ self.treeview.set_model(model)
+
+ # setup columns
+ # Checkbox
+ renderer = Gtk.CellRendererToggle()
+ renderer.connect("toggled", self.on_cell_toggled)
+ column = Gtk.TreeViewColumn('X', renderer, active=0)
+ column.set_visible(True)
+ column.set_expand(False)
+ column.set_clickable(False)
+ column.set_sort_indicator(False)
+ self.treeview.append_column(column)
+
+ # Project name
+ renderer = Gtk.CellRendererText()
+ column = Gtk.TreeViewColumn('Project name', renderer, text=1)
+ column.set_visible(True)
+ column.set_expand(True)
+ column.set_clickable(True)
+ column.set_sort_indicator(True)
+ self.treeview.append_column(column)
+
+ # Treeview features
+ self.treeview.set_headers_visible(True)
+ self.treeview.set_enable_search(True)
+ self.treeview.set_grid_lines(Gtk.TreeViewGridLines.HORIZONTAL)
+ self.treeview.set_search_column(1)
+ self.treeview.connect('row-activated', self.double_click)
+ selection = self.treeview.get_selection()
+ selection.set_mode(Gtk.SelectionMode.SINGLE)
+ self.treeview.set_search_entry(self.pname)
+
+
+ def delete_project(self, *args):
+ db = self.get_service('DB')
+ found = 0
+ selection = self.treeview.get_selection()
+ result = selection.get_selected()
+ if result: #result could be None
+ model, iter = result
+ project = model.get_value(iter, 1)
+ self.log.debug(project)
+ sapnotes = db.get_notes()
+ for sapnote in sapnotes:
+ projects = sapnotes[sapnote]['projects']
+ if project in projects:
+ found += 1
+ if found > 1:
+ self.log.debug("Project %s is still assigned to other SAP Notes" % project)
+ head = "Project could not be deleted"
+ body = "Project %s is still assigned to other SAP Notes" % project
+ self.uif.message_dialog(head , body)
+ else:
+ model.remove(iter)
+
+
+
+
+ def add_project(self, *args):
+ project = self.pname.get_text()
+ model = self.treeview.get_model()
+
+ found = False
+ for row in model:
+ if row[1].upper() == project.upper():
+ found = True
+
+ if not found and len(project) > 0:
+ model.append([False, project])
+
+ self.pname.set_text('')
+
+
+
+ def show_window(self, sapnote=None):
+ rootwin = self.gui.get_widget('mainwindow')
+ self.window.set_transient_for(rootwin)
+ self.load_projects(sapnote)
+ self.window.set_no_show_all(False)
+ self.window.show_all()
+
+ #~ if sapnote is not None:
+ #~ projects = self.sap.get_linked_projects(sapnote)
+ #~ self.log.debug("Projects for SAP Note %s: %s" % (sapnote, projects))
+ #~ dialog = Gtk.MessageDialog(self.parent, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Task completed")
+ #~ dialog.format_secondary_text("All SAP Notes were downloaded sucessfully.")
+ #~ dialog.run()
+ #~ dialog.destroy()
+
+ def hide_window(self, *args):
+ self.window.set_no_show_all(True)
+ self.window.hide()
+
+
+ def get_services(self):
+ self.gui = self.app.get_service("GUI")
+ self.sap = self.app.get_service('SAP')
+ self.uif = self.app.get_service('UIF')
+
+
+ def double_click(self, treeview, row, col):
+ model = treeview.get_model()
+ self.pname.set_text(model[row][1])
+
+
+ def populate(self, sapnotes):
+ model = self.treeview.get_model()
+ model.clear()
+ #~ model.append([bool, str])
+
+
+ def changed(self, *args):
+ try:
+ model, treeiters = self.selection.get_selected_rows()
+ selected = set()
+ if len(treeiters) > 0:
+ for treeiter in treeiters:
+ if treeiter != None:
+ selected.add(model[treeiter][0])
+ print (selected)
+
+ except Exception as error:
+ self.log.error (self.get_traceback())
+
+
+ def on_cell_toggled(self, widget, path):
+ model = self.treeview.get_model()
+ model[path][0] = not model[path][0]
+
+
+ def get_selected_notes(self):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ return sapnoteview.get_selected_notes()
+
+
+ def link_to_project(self, *args):
+ self.save_projects()
+ self.hide_window()
+ sapnotes = list(self.get_selected_notes())
+ model = self.treeview.get_model()
+ projects = []
+ for row in model:
+ link = row[0]
+ if link == True:
+ projects.append(row[1])
+
+ sapnotes.sort()
+ projects.sort()
+ self.log.debug('SAP Notes: %s' % sapnotes)
+ self.log.debug(' Projects: %s' % projects)
+ self.sap.link_to_project(sapnotes, projects)
+ sapnoteview = self.gui.get_widget('sapnoteview')
+ sapnoteview.refresh()
+
+
+ def get_all_projects(self):
+ projects = []
+ model = self.treeview.get_model()
+ for row in model:
+ projects.append(row[1])
+ projects.sort()
+
+ return projects
+
+
+ def load_projects(self, sapnote=''):
+ try:
+ projects = self.get_config_value('Projects').split(',')
+ except:
+ projects = []
+ model = self.treeview.get_model()
+ model.clear()
+
+ for project in projects:
+ if len(project) > 0:
+ if len(sapnote) > 0:
+ snprjs = self.sap.get_linked_projects(sapnote)
+ self.log.debug(snprjs)
+ if project in snprjs:
+ model.append([True, project])
+ else:
+ model.append([False, project])
+ else:
+ model.append([False, project])
+
+
+ def save_projects(self):
+ settings = {}
+ projects = self.get_all_projects()
+
+ settings['Projects'] = ','.join(projects)
+ self.config[self.section] = settings
+ self.save_config()
Index: REL-0.2/basico/i18n.py
===================================================================
--- REL-0.2/basico/i18n.py (nonexistent)
+++ REL-0.2/basico/i18n.py (revision 76)
@@ -0,0 +1,15 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+# File: i18nb.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: i18n module
+
+import os
+import gettext
+
+base_dir = os.path.abspath(os.path.dirname(__file__))
+d = '/usr/local/share' if 'local' in base_dir.split('/') else '/usr/share'
+gettext.bindtextdomain('genxword', os.path.join(d, 'locale'))
+gettext.textdomain('basico')
+_ = gettext.gettext
Index: REL-0.2/basico/__init__.py
===================================================================
--- REL-0.2/basico/__init__.py (nonexistent)
+++ REL-0.2/basico/__init__.py (revision 76)
@@ -0,0 +1,6 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+# File: __init__.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: basico module
Index: REL-0.2/INSTALL
===================================================================
--- REL-0.2/INSTALL (nonexistent)
+++ REL-0.2/INSTALL (revision 76)
@@ -0,0 +1,7 @@
+Please, follow the instructions from this page:
+
+# Get certificate
+https://support.sap.com/support-programs-services/about/getting-started/passport.html
+
+http://blog.t00mlabs.net/projects/basico/basico-installation
+
Index: REL-0.2/Changelog
===================================================================
--- REL-0.2/Changelog (nonexistent)
+++ REL-0.2/Changelog (revision 76)
@@ -0,0 +1,3 @@
+2016-05-30 Tomás Vírseda <tomasvirseda@gmail.com>
+
+ * Basico 0.1 released
Index: REL-0.2/basico/env.py
===================================================================
--- REL-0.2/basico/env.py (nonexistent)
+++ REL-0.2/basico/env.py (revision 76)
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: env.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Environment variables
+
+import sys
+import os
+from os.path import abspath, sep as SEP
+
+ROOT = abspath(sys.modules[__name__].__file__ + "/..")
+USER_DIR = os.path.expanduser('~')
+
+# App Info
+APP = {}
+APP['short'] = "basico"
+APP['name'] = "SAP Notes Manager for SAP Consultants"
+APP['desc'] = "SAP Notes Manager for SAP Consultants\n\nThe code is licensed under the terms of the GPL v3 so you're free to grab, extend, improve and fork the code as you want"
+APP['version'] = "0.2"
+APP['authors'] = ["Tomás Vírseda <t00m@t00mlabs.net>"]
+APP['documenters'] = ["Tomás Vírseda <t00m@t00mlabs.net>"]
+APP['email'] = "t00m@t00mlabs.net"
+
+# Local paths
+LPATH = {}
+LPATH['ROOT'] = USER_DIR + SEP + '.basico' + SEP
+LPATH['ETC'] = LPATH['ROOT'] + 'etc' + SEP
+LPATH['VAR'] = LPATH['ROOT'] + 'var' + SEP
+LPATH['PLUGINS'] = LPATH['VAR'] + 'plugins' + SEP
+LPATH['LOG'] = LPATH['VAR'] + 'logs' + SEP
+LPATH['TMP'] = LPATH['VAR'] + 'tmp' + SEP
+LPATH['DB'] = LPATH['VAR'] + 'db' + SEP
+LPATH['EXPORT'] = LPATH['VAR'] + 'export' + SEP
+LPATH['OPT'] = LPATH['ROOT'] + 'opt' + SEP
+LPATH['DRIVERS'] = LPATH['OPT'] + 'webdrivers' + SEP
+LPATH['RES'] = LPATH['ROOT'] + 'res' + SEP
+
+# Global paths
+GPATH = {}
+GPATH['ROOT'] = ROOT
+GPATH['DATA'] = GPATH['ROOT'] + SEP + 'data' + SEP
+GPATH['UI'] = GPATH['DATA'] + 'ui' + SEP
+GPATH['ICONS'] = GPATH['DATA'] + 'icons' + SEP
+GPATH['PLUGINS'] = GPATH['DATA'] + 'plugins' + SEP
+GPATH['SHARE'] = GPATH['DATA'] + 'share' + SEP
+GPATH['DOC'] = GPATH['SHARE'] + 'docs' + SEP
+GPATH['RES'] = GPATH['DATA'] + 'res' + SEP
+
+# Configuration, SAP Notes Database and Log files
+FILE = {}
+FILE['TASKS'] = LPATH['ETC'] + 'tasks.txt'
+FILE['CNF'] = LPATH['ETC'] + 'basico.ini'
+FILE['SAP'] = LPATH['DB'] + 'sapnotes.json'
+FILE['LOG'] = LPATH['LOG'] + 'basico.log'
+FILE['CREDITS'] = GPATH['DOC'] + 'CREDITS'
+
+# SAP related
+SAP = {}
+SAP['NOTE_URL'] = "https://launchpad.support.sap.com/#/notes/%s"
+SAP['ODATA_NOTE_URL'] = "https://launchpad.support.sap.com/services/odata/svt/snogwscorr/TrunkSet(SapNotesNumber='%s',Version='0',Language='E')" #$expand=LongText" #?$expand=LongText,RefTo,RefBy"
+
/REL-0.2/basico/env.py
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: REL-0.2/basico/tasks.py
===================================================================
--- REL-0.2/basico/tasks.py (nonexistent)
+++ REL-0.2/basico/tasks.py (revision 76)
@@ -0,0 +1,332 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: tasks.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Tasks service
+
+import os
+from gi.repository import Gtk
+from gi.repository.GdkPixbuf import Pixbuf
+from gi.repository import Pango
+from datetime import datetime
+from dateutil import parser as dateparser
+
+from .service import Service
+
+
+class Tasks(Service):
+ def initialize(self):
+ self.get_services()
+ self.setup_widgets()
+ self.__init_tasks_store()
+ self.load_tasks()
+
+
+ def __init_tasks_store(self):
+ TASKS_FILE = self.get_file('TASKS')
+ if not os.path.exists(TASKS_FILE):
+ self.log.info("Creating store for tasks: %s" % TASKS_FILE)
+ ftasks = open(TASKS_FILE, 'w')
+ ftasks.close()
+
+
+ def setup_widgets(self):
+ # setup widgets
+ self.window = self.gui.add_widget('boxProps')
+ self.pname = self.gui.add_widget('etyTaskName')
+ self.pname.connect('activate', self.add_task)
+ self.boxtask = self.gui.add_widget('boxTasks')
+ self.btnadd = self.gui.add_widget('btnAddTask')
+ self.btnadd.connect('clicked', self.add_task)
+ self.btndel = self.gui.add_widget('btnDelTask')
+ self.btndel.connect('clicked', self.delete_task)
+ self.treeview = Gtk.TreeView()
+ self.gui.add_widget('trvtaskwin', self.treeview)
+ self.gui.add_widget('boxAcceptCancelTasks')
+ self.boxtask.add(self.treeview)
+
+ # setup model
+ model = Gtk.ListStore(
+ bool, # CheckBox
+ str # Task name
+ )
+ self.treeview.set_model(model)
+
+ # setup columns
+ # Checkbox
+ renderer = Gtk.CellRendererToggle()
+ renderer.connect("toggled", self.on_cell_toggled)
+ column = Gtk.TreeViewColumn('', renderer, active=0)
+ column.set_visible(True)
+ column.set_expand(False)
+ column.set_clickable(False)
+ column.set_sort_indicator(False)
+ self.treeview.append_column(column)
+
+ # Task name
+ renderer = Gtk.CellRendererText()
+ column = Gtk.TreeViewColumn('Task name', renderer, text=1)
+ column.set_visible(True)
+ column.set_sort_column_id(1)
+ column.set_expand(True)
+ column.set_clickable(True)
+ column.set_sort_indicator(True)
+ self.treeview.append_column(column)
+
+ # Filters
+ #Creating the filter, feeding it with the liststore model
+ #~ self.task_filter = model.filter_new()
+ #setting the filter function, note that we're not using the
+ #~ self.task_filter.set_visible_func(self.task_filter_func)
+ #~ self.task_filter.set_visible_column(1)
+
+ # Treeview features
+ self.treeview.set_headers_visible(True)
+ self.treeview.set_enable_search(True)
+ self.treeview.set_grid_lines(Gtk.TreeViewGridLines.NONE)
+ self.treeview.set_search_column(1)
+ self.treeview.connect('row-activated', self.double_click)
+ selection = self.treeview.get_selection()
+ selection.set_mode(Gtk.SelectionMode.SINGLE)
+ self.treeview.set_search_entry(self.pname)
+
+
+ def clear(self):
+ model = self.treeview.get_model()
+ model.clear()
+
+
+ def set_model(self, model):
+ self.treeview.set_model(model)
+
+
+ # row task visibility
+ def task_row_visibility(self, model, iter, data):
+ entry = self.gui.get_widget('etyTaskName')
+ text = entry.get_text()
+
+ return text.upper() in model.get_value(iter, 1)
+
+
+ def task_filter_func(self, model, iter, data):
+ """Tests if the task in the row is the one in the filter"""
+ entry = self.gui.get_widget('etyTaskName')
+ task = entry.get_text()
+ task_row = model[iter][1]
+
+ if task.upper() in task_row.upper():
+ return True
+ else:
+ return False
+
+
+ def delete_task(self, *args):
+ db = self.app.get_service('DB')
+ found = 0
+ selection = self.treeview.get_selection()
+ result = selection.get_selected()
+ if result: #result could be None
+ model, iter = result
+ task = model.get_value(iter, 1)
+ sapnotes = db.get_notes()
+ for sapnote in sapnotes:
+ try:
+ tasks = sapnotes[sapnote]['tasks']
+ if task in tasks:
+ found += 1
+ except:
+ pass
+ if found > 1:
+ self.log.warning("Task %s is still assigned to other SAP Notes" % task)
+ head = "Task could not be deleted"
+ body = "Task %s is still assigned to other SAP Notes" % task
+ self.uif.message_dialog(head , body)
+ else:
+ model.remove(iter)
+ self.log.info("Task deleted: %s" % task)
+ self.save_tasks()
+
+
+
+ def add_task(self, *args):
+ task = self.pname.get_text()
+ model = self.treeview.get_model()
+
+ found = False
+ for row in model:
+ if row[1].upper() == task.upper():
+ self.log.info("Task already exists: %s" % task)
+ found = True
+
+ if not found and len(task) > 0:
+ model.append([False, task])
+ self.log.info("Task added: %s" % task)
+
+ self.pname.set_text('')
+ self.save_tasks()
+ self.load_tasks()
+
+
+
+ def show_window(self, sapnotes=[], active=None):
+ ntboperations = self.gui.get_widget('ntbOperations')
+ ntboperations.set_current_page(1)
+ winoper = self.gui.get_widget('tgbShowManage')
+ switch = winoper.get_active()
+ if active is None:
+ if switch is True:
+ active = True
+ else:
+ active = False
+ winoper.set_active(active)
+ self.load_tasks(sapnotes)
+
+
+ def get_services(self):
+ self.gui = self.app.get_service("GUI")
+ self.sap = self.app.get_service('SAP')
+ self.uif = self.app.get_service('UIF')
+ self.cb = self.app.get_service('Callbacks')
+ self.db = self.app.get_service('DB')
+
+
+ def double_click(self, treeview, row, col):
+ model = treeview.get_model()
+ self.pname.set_text(model[row][1])
+
+
+ def populate(self, sapnotes):
+ model = self.treeview.get_model()
+ model.clear()
+ #~ model.append([bool, str])
+
+
+ def changed(self, *args):
+ try:
+ model, treeiters = self.selection.get_selected_rows()
+ selected = set()
+ if len(treeiters) > 0:
+ for treeiter in treeiters:
+ if treeiter != None:
+ selected.add(model[treeiter][0])
+ print (selected)
+
+ except Exception as error:
+ self.log.error (self.get_traceback())
+
+
+ def select(self, tasks):
+ model = self.treeview.get_model()
+
+ def select_task(model, path, iter, user_data=None):
+ task = model.get_value(iter, 1)
+ if task in tasks:
+ model[path][0] = True
+ self.log.debug("Task '%s' switch to true" % task)
+ else:
+ model[path][0] = False
+ return False
+
+ model.foreach(select_task)
+
+
+ def on_cell_toggled(self, widget, path):
+ cb = self.get_service('Callbacks')
+ model = self.treeview.get_model()
+ model[path][0] = not model[path][0]
+ cb.check_task_link_button_status()
+ #~ button = self.gui.get_widget('btnLinkTasksApply')
+ #~ sapnoteview = self.gui.get_widget('sapnoteview')
+
+ #~ tasks_selected = len(self.get_selected()) > 0
+ #~ notes_selected = len(sapnoteview.get_selected_notes()) > 0
+ #~ if tasks_selected and notes_selected:
+ #~ button.set_no_show_all(False)
+ #~ button.show_all()
+ #~ else:
+ #~ button.hide()
+ #~ button.set_no_show_all(True)
+
+
+
+ def get_selected(self):
+ model = self.treeview.get_model()
+ tasks = set()
+
+ def traverse_treeview(model, path, iter, user_data=None):
+ toggled = model.get_value(iter, 0)
+ if toggled:
+ task = model.get_value(iter, 1)
+ tasks.add(task)
+ return False
+
+ model.foreach(traverse_treeview)
+ ltasks = list(tasks)
+ ltasks.sort()
+
+ #~ self.log.debug("Tasks selected: %s" % ', '.join(tasks))
+ return ltasks
+
+
+ #~ def get_selected_notes(self):
+ #~ sapnoteview = self.gui.get_widget('sapnoteview')
+ #~ return sapnoteview.get_selected_notes()
+
+
+ def link_to_task(self, *args):
+ sapnoteview = self.gui.get_widget('sapnoteview')
+
+ self.save_tasks()
+ sapnotes = list(sapnoteview.get_selected_notes())
+ model = self.treeview.get_model()
+ tasks = []
+ for row in model:
+ link = row[0]
+ if link == True:
+ tasks.append(row[1])
+
+ sapnotes.sort()
+ tasks.sort()
+ self.sap.link_to_task(sapnotes, tasks)
+ self.cb.refresh_view(view='tasks')
+
+
+ def get_all_tasks(self):
+ tasks = []
+ model = self.treeview.get_model()
+ for row in model:
+ tasks.append(row[1])
+ tasks.sort()
+
+ return tasks
+
+
+ def load_tasks(self, sapnotes=[]):
+ model = self.treeview.get_model()
+ TASKS_FILE = self.get_file('TASKS')
+ alltasks = open(TASKS_FILE, 'r').readlines()
+ model.clear()
+ alltasks.sort()
+ for task in alltasks:
+ model.append([False, task[0:-1]])
+
+
+ def save_tasks(self):
+ TASKS_FILE = self.get_file('TASKS')
+ tasks = self.get_all_tasks()
+
+ ftasks = open(TASKS_FILE, 'w')
+ for task in tasks:
+ ftasks.write("%s\n" % task)
+ self.log.info("Task saved: %s" % task)
+ ftasks.close()
+
+
+
+ def save_tasks_from_stats(self, alltasks):
+ settings = {}
+ tasks = ','.join(alltasks)
+ settings['Tasks'] = tasks
+ self.config[self.section] = settings
+ self.save_config()
Index: REL-0.2/basico/iconmanager.py
===================================================================
--- REL-0.2/basico/iconmanager.py (nonexistent)
+++ REL-0.2/basico/iconmanager.py (revision 76)
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: menus.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Icon manager service
+
+import os
+
+import pkg_resources
+
+from gi.repository import Gtk
+from gi.repository import Gio
+from gi.repository import Pango
+from gi.repository.GdkPixbuf import Pixbuf
+
+from .service import Service
+
+
+def resource_filename(file_name):
+ paths = map(
+ lambda path: os.path.join(path, file_name),
+ (
+ '/opt/extras.ubuntu.com/',
+ '/usr/local/',
+ '/usr/',
+ ),
+ )
+ for path in paths:
+ if os.path.isfile(path):
+ return path
+ return pkg_resources.resource_filename(
+ pkg_resources.Requirement.parse("basico"), file_name)
+
+
+class IconManager(Service):
+ def initialize(self):
+ APP_DIR_ICONS = self.app.get_var('ICONS')
+ self.icondict = {}
+ self.theme = Gtk.IconTheme.get_default()
+ self.theme.prepend_search_path (APP_DIR_ICONS)
+
+ def get_themed_icon(self, icon_name):
+ APP_DIR_ICONS = self.app.get_var('ICONS')
+ ICON = APP_DIR_ICONS + icon_name + '.png'
+ icon = Gio.ThemedIcon.new(ICON)
+
+ return icon
+
+
+
+ def get_icon(self, name, width=24, height=24):
+ key = "%s-%d-%d" % (name, width, height)
+
+ # Get icon from cache if exists or add a new one
+ try:
+ icon = self.icondict[key]
+ #~ print ("ICON TRY: %s: %s" % (type(icon), icon))
+ except:
+ #~ OLD WAY: icon = Pixbuf.new_from_file_at_scale(icon_name, width, height, True)
+ iconinfo = self.theme.lookup_icon(name, width, Gtk.IconLookupFlags.GENERIC_FALLBACK)
+ icon = iconinfo.load_icon()
+ #~ print ("ICON EXCEPT: %s: %s" % (type(icon), icon))
+ self.icondict[key] = icon
+ #~ icon = None
+ return icon
+
+
+ def get_pixbuf_icon(self, name, width=36, height=36):
+ key = "%s-%d-%d" % (name, width, height)
+
+ # Get icon from cache if exists or add a new one
+ try:
+ icon = self.icondict[key]
+ except:
+ icon = None
+ #~ OLD WAY: icon = Pixbuf.new_from_file_at_scale(icon_name, width, height, True)
+ #~ fout = open('icons.txt', 'w')
+ #~ for icon in self.theme.list_icons():
+ #~ fout.write('%s\n' % icon)
+ #~ fout.close()
+ if name in self.theme.list_icons():
+ return self.theme.load_icon(name, width, Gtk.IconLookupFlags.GENERIC_FALLBACK)
+ #~ if self.theme.has_icon(name):
+
+ #~ iconinfo = self.theme.lookup_icon(name, width, Gtk.IconLookupFlags.GENERIC_FALLBACK)
+ #~ icon = iconinfo.load_icon()
+ #~ self.icondict[key] = icon
+ return icon
+
+
+ def get_image_icon(self, name, width=36, height=36):
+ pixbuf = self.get_pixbuf_icon(name, width, height)
+ return Gtk.Image.new_from_pixbuf(pixbuf)
Index: REL-0.2/basico/notify.py
===================================================================
--- REL-0.2/basico/notify.py (nonexistent)
+++ REL-0.2/basico/notify.py (revision 76)
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: notify.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: notifications service
+
+import sys
+import gi
+gi.require_version('Notify', '0.7')
+from gi.repository import Notify
+
+from .service import Service
+
+
+class Notification(Service):
+ def initialize(self):
+ Notify.init('Basico')
+
+ def show(self, module, message, icon_name):
+ if sys.platform == 'win32':
+ # Windows does not support Notify
+ return
+ else:
+ icon = "dialog-%s" % icon_name # information | question | warning | error
+ notification = Notify.Notification.new (module, message, icon)
+ notification.show()
Index: REL-0.2/basico/service.py
===================================================================
--- REL-0.2/basico/service.py (nonexistent)
+++ REL-0.2/basico/service.py (revision 76)
@@ -0,0 +1,141 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: service.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Service class
+
+import sys
+
+from .log import get_logger
+
+
+class Service(object):
+ """
+ Service class is the base class for the rest of main classes used in
+ the application.
+ Different modules (GUI, Database, Ask, etc...) share same methods
+ which is useful to start/stop them, simplify logging and, comunicate
+ each other easily.
+ """
+
+ def __init__(self, app=None):
+ """Initialize Service instance
+ @type app: Basico instance
+ @param app: current Basico instance reference
+ """
+ self.started = False
+
+
+ def is_started(self):
+ """Return True or False if service is running / not running
+ """
+ return self.started
+
+
+ def start(self, app, logname=None):
+ """Start service.
+ Use initialize for writting a custom init method
+ @type app: basico
+ @param app: basico Class pointer.
+ @type logname: string
+ @param logname: name of associated logger. It is used aswell to
+ identify configuration section name
+ """
+ self.started = True
+ self.app = app
+ logfile = self.app.get_file('LOG')
+ self.log = get_logger(logname, logfile)
+ self.config = self.app.get_config()
+ self.section = logname
+ self.init_section(logname)
+
+ try:
+ self.initialize()
+ self.log.debug("Service %s loaded" % logname)
+ except Exception as error:
+ self.log.error (self.get_traceback())
+
+
+ def get_var(self, name, scope='global'):
+ return self.app.get_var(name, scope)
+
+
+ def get_app_info(self, name):
+ return self.app.get_app_info(name)
+
+
+ def get_file(self, name):
+ return self.app.get_file(name)
+
+
+ def end(self):
+ """End service
+ Use finalize for writting a custom end method
+ """
+ self.started = False
+ try:
+ self.finalize()
+ except Exception as error:
+ self.log.error (self.get_traceback())
+
+
+ def initialize(self):
+ """Initialize service.
+ All clases derived from Service class must implement this method
+ """
+ pass
+
+
+ def finalize(self):
+ """Finalize service.
+ All clases derived from Service class must implement this method
+ """
+ pass
+
+
+ def get_config_value(self, key):
+ """Get value for a given param in section for this service
+ @type param: string
+ @param param: parameter name
+ """
+ self.config = self.app.get_config()
+ if self.config.has_section(self.section):
+ if self.config.has_option(self.section, key):
+ return self.config.get(self.section, key)
+
+ return None
+
+
+ def set_config_value(self, key, value):
+ """Set value for a given param in section for this service
+ @type param: string
+ @param param: parameter name
+ @type value: string
+ @param param: new value for this parameter
+ """
+ self.config[self.section][key] = value
+ self.log.debug("CONFIG[%s][%s] = %s" % (self.section, key, value))
+ self.save_config()
+
+
+ def init_section(self, section):
+ """Check if section exists in config. If not, create it"""
+ if not self.config.has_section(section):
+ self.config.add_section(section)
+ self.log.debug("CONFIG[%s] section created" % section)
+ self.save_config()
+
+
+ def save_config(self):
+ CONFIG_FILE = self.get_file('CNF')
+ with open(CONFIG_FILE, 'w') as configfile:
+ self.config.write(configfile)
+
+
+ def get_traceback(self):
+ return self.app.get_traceback()
+
+
+ def get_service(self, name):
+ return self.app.get_service(name)
/REL-0.2/basico/service.py
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: REL-0.2/basico/browser.py
===================================================================
--- REL-0.2/basico/browser.py (nonexistent)
+++ REL-0.2/basico/browser.py (revision 76)
@@ -0,0 +1,425 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# File: browser.py
+# Author: Tomás Vírseda
+# License: GPL v3
+# Description: Browse module
+#~ Source code borrowed from:
+#~ https://raw.githubusercontent.com/jaka/browser2/master/browser2
+#~ https://github.com/jaka
+#~ but adapted to Gtk3
+
+from gettext import gettext as _
+
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import Pango
+from gi.repository import WebKit
+
+
+class BrowserPage(WebKit.WebView):
+
+ def __init__(self):
+ WebKit.WebView.__init__(self)
+ settings = self.get_settings()
+ settings.set_property('enable-developer-extras', True)
+ settings.set_property('enable-default-context-menu', True)
+
+ settings.set_property('default-encoding', 'utf-8')
+ settings.set_property('enable-private-browsing', True)
+ settings.set_property('enable-html5-local-storage', True)
+
+ # disable plugins, like Adobe Flash and Java
+ settings.set_property('enable-plugins', True)
+
+ # scale other content besides from text as well
+ self.set_full_content_zoom(True)
+
+class TabLabel(Gtk.HBox):
+ """A class for Tab labels"""
+
+ __gsignals__ = {
+ 'close': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_OBJECT,))
+ }
+
+ def __init__(self, title, scrolled_window):
+ """initialize the tab label"""
+
+ Gtk.HBox.__init__(self, False, 4)
+ self.title = title
+ self.scrolled_window = scrolled_window
+ self.label = Gtk.Label(title)
+ self.label.props.max_width_chars = 30
+ #~ self.label.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
+ self.label.set_alignment(0.0, 0.5)
+
+ close_image = Gtk.Image.new_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.MENU)
+ close_button = Gtk.Button()
+ close_button.set_relief(Gtk.ReliefStyle.NONE)
+ close_button.set_image(close_image)
+ close_button.connect('clicked', lambda x: self.emit('close', self.scrolled_window))
+
+ self.pack_start(self.label, True, True, 0)
+ self.pack_start(close_button, False, False, 0)
+
+ self.connect('style-set', self._tab_label_style_set)
+
+ def _tab_label_style_set(self, tab_label, style):
+ try:
+ context = tab_label.get_pango_context()
+ metrics = context.get_metrics(tab_label.style.font_desc, context.get_language())
+ char_width = metrics.get_approximate_digit_width()
+ (width, height) = Gtk.icon_size_lookup(Gtk.ICON_SIZE_MENU)
+ tab_label.set_size_request(10 * Pango.PIXELS(char_width) + 2 * width,
+ Pango.PIXELS(metrics.get_ascent() + metrics.get_descent()) + 4)
+ except: pass
+
+class ContentPane(Gtk.Notebook):
+
+ __gsignals__ = {
+ 'focus-entry': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ()),
+ 'update-title': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, (GObject.TYPE_OBJECT, GObject.TYPE_STRING, GObject.TYPE_STRING)),
+ }
+
+ def __init__(self, app):
+ """initialize the content pane"""
+ Gtk.Notebook.__init__(self)
+ self.app = app
+ self.props.scrollable = True
+ self.set_show_tabs(True)
+ self.popup_enable()
+ #~ self.set_property('homogeneous', True)
+ self.set_show_border(True)
+ self.connect('switch-page', self._switch_page)
+
+ self.show_all()
+ self._hovered_uri = None
+
+ def new_tab(self, url = None, show_new = True, web_view = None):
+ """Creates a new page in a new tab"""
+
+ if web_view:
+ browser = web_view
+ else:
+ browser = BrowserPage()
+
+ scrolled_window = Gtk.ScrolledWindow()
+ scrolled_window.props.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+ scrolled_window.props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC
+ scrolled_window.title = None
+ scrolled_window.url = None
+
+ browser.connect('title-changed', self._title_changed, scrolled_window)
+ browser.connect('load-committed', self._url_changed, scrolled_window)
+ browser.connect('load-finished', self._load_finished, scrolled_window)
+ browser.connect('hovering-over-link', self._hovering_over_link)
+
+ # disable file chooser
+ #~ browser.connect('run-file-chooser', returntrue)
+
+ # disable file transfering (downloading)
+ #~ browser.connect('download-requested', returntrue)
+
+ # disable printing
+ #~ browser.connect('print-requested', returntrue)
+
+ browser.connect('create-web-view', self._new_web_view_request)
+ browser.connect('button-press-event', self._on_button_press_event)
+
+ scrolled_window.add(browser)
+ scrolled_window.show_all()
+
+ label = TabLabel(url, scrolled_window)
+ label.connect('close', self.close_tab)
+ label.show_all()
+
+ new_tab_number = self.append_page(scrolled_window, label)
+ #~ self.set_tab_label_packing(scrolled_window, False, True, Gtk.PACK_START)
+ self.set_tab_label(scrolled_window, label)
+
+ #~ self.set_show_tabs(self.get_n_pages() > 1)
+ self.show_all()
+
+ if url:
+ scrolled_window.url = url
+ browser.load_uri(url)
+ else:
+ scrolled_window.title = "New Tab"
+ scrolled_window.url = ""
+ label.label.set_label("New Tab")
+
+ if show_new:
+ self.set_current_page(new_tab_number)
+ if not url:
+ self.emit('focus-entry')
+
+