Changed logo

This commit is contained in:
Keplyx 2018-05-06 21:47:33 +02:00
parent 6a964693f4
commit a56f159378
9 changed files with 934 additions and 151 deletions

View file

@ -39,8 +39,7 @@
}
.sidenav a:hover {
color: #c5af86;
text-shadow: 0 0 5px #c5af86;
color: #1a5dad;
margin-left: 20px;
}

View file

@ -97,16 +97,7 @@ a {
}
a:hover, a:focus {
text-shadow: 0 0 4px #cccccc;
}
footer a {
color: #F2F2F2;
text-decoration: underline;
}
em, cite {
font-style: italic;
text-shadow: 0 0 4px #1a5dad;
}
strong {
@ -205,7 +196,16 @@ Full-Width Styles
#menu_title {
border-bottom: none;
margin-left: 30px;
line-height: 40px;
height: 40px;
margin: 5px;
}
#menu_icon {
width: 40px;
height: 40px;
padding: 0;
margin: 5px;
}
#title {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1,523 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="256"
height="256"
viewBox="0 0 256 256"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="logo-site-accueil.svg"
inkscape:export-filename="/home/keplyx/Downloads/logo-site-acceuil.png"
inkscape:export-xdpi="11.25"
inkscape:export-ydpi="11.25">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="99.511853"
inkscape:cy="134.6611"
inkscape:document-units="px"
inkscape:current-layer="layer4"
showgrid="false"
units="px"
inkscape:object-paths="false"
inkscape:object-nodes="false"
inkscape:window-width="1600"
inkscape:window-height="835"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Space"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-796.36216)"
style="display:inline">
<path
style="opacity:1;fill:#1a5dad;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4136"
sodipodi:type="arc"
sodipodi:cx="128"
sodipodi:cy="924.36218"
sodipodi:rx="128"
sodipodi:ry="128"
sodipodi:start="0"
sodipodi:end="6.2831172"
d="M 256,924.36218 A 128,128 0 0 1 128.00218,1052.3622 128,128 0 0 1 7.4217411e-8,924.36654 128,128 0 0 1 127.99346,796.36218 128,128 0 0 1 256,924.35346"
sodipodi:open="true" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-5"
sodipodi:type="arc"
sodipodi:cx="180.31223"
sodipodi:cy="830.1286"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 182.52193,830.1286 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20974,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-2"
sodipodi:type="arc"
sodipodi:cx="140.91628"
sodipodi:cy="1028.1185"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 143.12598,1028.1185 a 2.2097089,2.0834396 0 0 1 -2.20967,2.0835 2.2097089,2.0834396 0 0 1 -2.20974,-2.0834 2.2097089,2.0834396 0 0 1 2.20959,-2.0835 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-9"
sodipodi:type="arc"
sodipodi:cx="31.31473"
sodipodi:cy="966.87805"
sodipodi:rx="1.1995564"
sodipodi:ry="1.1995561"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 32.514286,966.87805 a 1.1995564,1.1995561 0 0 1 -1.199535,1.19956 1.1995564,1.1995561 0 0 1 -1.199578,-1.19952 1.1995564,1.1995561 0 0 1 1.199494,-1.19959 1.1995564,1.1995561 0 0 1 1.199619,1.19947" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-1"
sodipodi:type="arc"
sodipodi:cx="81.317284"
sodipodi:cy="999.83423"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 83.526993,999.83423 a 2.2097089,2.0834396 0 0 1 -2.209671,2.08347 2.2097089,2.0834396 0 0 1 -2.209747,-2.0834 2.2097089,2.0834396 0 0 1 2.209593,-2.08351 2.2097089,2.0834396 0 0 1 2.209825,2.08329" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-27"
sodipodi:type="arc"
sodipodi:cx="109.62693"
sodipodi:cy="826.52917"
sodipodi:rx="4.7097092"
sodipodi:ry="4.6727252"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 114.33664,826.52917 a 4.7097092,4.6727252 0 0 1 -4.70963,4.67273 4.7097092,4.6727252 0 0 1 -4.70979,-4.67256 4.7097092,4.6727252 0 0 1 4.70946,-4.67289 4.7097092,4.6727252 0 0 1 4.70996,4.6724" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-0"
sodipodi:type="arc"
sodipodi:cx="227.01909"
sodipodi:cy="885.80426"
sodipodi:rx="3.4597089"
sodipodi:ry="2.9762967"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 230.4788,885.80426 a 3.4597089,2.9762967 0 0 1 -3.45965,2.9763 3.4597089,2.9762967 0 0 1 -3.45977,-2.9762 3.4597089,2.9762967 0 0 1 3.45953,-2.9764 3.4597089,2.9762967 0 0 1 3.45989,2.97609" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-93"
sodipodi:type="arc"
sodipodi:cx="204.05081"
sodipodi:cy="996.80377"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 206.26052,996.80377 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.2096,-2.08351 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-62"
sodipodi:type="arc"
sodipodi:cx="234.86047"
sodipodi:cy="893.76819"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 237.07018,893.76819 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.2096,-2.08351 2.2097089,2.0834396 0 0 1 2.20982,2.08329" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-8"
sodipodi:type="arc"
sodipodi:cx="166.17009"
sodipodi:cy="820.0271"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 168.3798,820.0271 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.08329" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-7"
sodipodi:type="arc"
sodipodi:cx="114.14724"
sodipodi:cy="809.42047"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 116.35695,809.42047 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-92"
sodipodi:type="arc"
sodipodi:cx="85.806946"
sodipodi:cy="832.86322"
sodipodi:rx="1.3168519"
sodipodi:ry="1.3691539"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 87.123798,832.86322 a 1.3168519,1.3691539 0 0 1 -1.316829,1.36915 1.3168519,1.3691539 0 0 1 -1.316875,-1.3691 1.3168519,1.3691539 0 0 1 1.316783,-1.3692 1.3168519,1.3691539 0 0 1 1.316921,1.36905" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-02"
sodipodi:type="arc"
sodipodi:cx="56.063465"
sodipodi:cy="824.06769"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 58.273174,824.06769 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.209748,-2.08337 2.2097089,2.0834396 0 0 1 2.209593,-2.08351 2.2097089,2.0834396 0 0 1 2.209825,2.08329" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-75"
sodipodi:type="arc"
sodipodi:cx="54.757446"
sodipodi:cy="886.44592"
sodipodi:rx="1.4954232"
sodipodi:ry="1.3245111"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 56.252869,886.44592 a 1.4954232,1.3245111 0 0 1 -1.495397,1.32451 1.4954232,1.3245111 0 0 1 -1.495449,-1.32446 1.4954232,1.3245111 0 0 1 1.495345,-1.32456 1.4954232,1.3245111 0 0 1 1.495501,1.32442" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-89"
sodipodi:type="arc"
sodipodi:cx="19.697975"
sodipodi:cy="937.20477"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 21.907684,937.20477 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.209748,-2.08336 2.2097089,2.0834396 0 0 1 2.209593,-2.08352 2.2097089,2.0834396 0 0 1 2.209825,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-73"
sodipodi:type="arc"
sodipodi:cx="62.685478"
sodipodi:cy="982.07513"
sodipodi:rx="4.1739945"
sodipodi:ry="3.6905825"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 66.859473,982.07513 a 4.1739945,3.6905825 0 0 1 -4.173922,3.69059 4.1739945,3.6905825 0 0 1 -4.174067,-3.69046 4.1739945,3.6905825 0 0 1 4.173776,-3.69071 4.1739945,3.6905825 0 0 1 4.174213,3.69033" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-612"
sodipodi:type="arc"
sodipodi:cx="43.436558"
sodipodi:cy="1007.4104"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 45.646267,1007.4104 a 2.2097089,2.0834396 0 0 1 -2.209671,2.0834 2.2097089,2.0834396 0 0 1 -2.209747,-2.0833 2.2097089,2.0834396 0 0 1 2.209593,-2.0835 2.2097089,2.0834396 0 0 1 2.209825,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-94"
sodipodi:type="arc"
sodipodi:cx="221.2234"
sodipodi:cy="956.90277"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 223.43311,956.90277 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20974,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-78"
sodipodi:type="arc"
sodipodi:cx="250.01276"
sodipodi:cy="929.6286"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 252.22247,929.6286 a 2.2097089,2.0834396 0 0 1 -2.20968,2.08344 2.2097089,2.0834396 0 0 1 -2.20974,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-4"
sodipodi:type="arc"
sodipodi:cx="223.24371"
sodipodi:cy="904.87988"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 225.45342,904.87988 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08336 2.2097089,2.0834396 0 0 1 2.2096,-2.08352 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-50"
sodipodi:type="arc"
sodipodi:cx="191.4239"
sodipodi:cy="969.52966"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 193.63361,969.52966 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20974,-2.08336 2.2097089,2.0834396 0 0 1 2.20959,-2.08352 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-36"
sodipodi:type="arc"
sodipodi:cx="146.47212"
sodipodi:cy="1006.9053"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 148.68183,1006.9053 a 2.2097089,2.0834396 0 0 1 -2.20967,2.0834 2.2097089,2.0834396 0 0 1 -2.20975,-2.0834 2.2097089,2.0834396 0 0 1 2.2096,-2.0835 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-10"
sodipodi:type="arc"
sodipodi:cx="110.92738"
sodipodi:cy="1022.3101"
sodipodi:rx="1.38896"
sodipodi:ry="1.3258252"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 112.31634,1022.3101 a 1.38896,1.3258252 0 0 1 -1.38893,1.3258 1.38896,1.3258252 0 0 1 -1.38899,-1.3257 1.38896,1.3258252 0 0 1 1.38889,-1.3259 1.38896,1.3258252 0 0 1 1.38903,1.3257" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-20"
sodipodi:type="arc"
sodipodi:cx="170.21071"
sodipodi:cy="845.78595"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 172.42042,845.78595 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.08329" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-615"
sodipodi:type="arc"
sodipodi:cx="141.92644"
sodipodi:cy="810.93573"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 144.13615,810.93573 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.08329" />
<path
style="opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-54"
sodipodi:type="arc"
sodipodi:cx="143.44167"
sodipodi:cy="828.61334"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 145.65137,828.61334 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20974,-2.08336 2.2097089,2.0834396 0 0 1 2.20959,-2.08352 2.2097089,2.0834396 0 0 1 2.20982,2.0833" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-27-7"
sodipodi:type="arc"
sodipodi:cx="159.28572"
sodipodi:cy="867.005"
sodipodi:rx="4.7097092"
sodipodi:ry="4.6727252"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 163.99543,867.005 a 4.7097092,4.6727252 0 0 1 -4.70963,4.67273 4.7097092,4.6727252 0 0 1 -4.70979,-4.67256 4.7097092,4.6727252 0 0 1 4.70946,-4.67289 4.7097092,4.6727252 0 0 1 4.70996,4.6724" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-50-3"
sodipodi:type="arc"
sodipodi:cx="76.071426"
sodipodi:cy="869.505"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 78.281135,869.505 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.209748,-2.08336 2.2097089,2.0834396 0 0 1 2.209594,-2.08351 2.2097089,2.0834396 0 0 1 2.209824,2.08329" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-50-38"
sodipodi:type="arc"
sodipodi:cx="131.07143"
sodipodi:cy="846.29071"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 133.28114,846.29071 a 2.2097089,2.0834396 0 0 1 -2.20968,2.08344 2.2097089,2.0834396 0 0 1 -2.20974,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.0833" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-50-37"
sodipodi:type="arc"
sodipodi:cx="117.14286"
sodipodi:cy="879.14789"
sodipodi:rx="2.2097089"
sodipodi:ry="2.0834396"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 119.35257,879.14789 a 2.2097089,2.0834396 0 0 1 -2.20967,2.08344 2.2097089,2.0834396 0 0 1 -2.20975,-2.08337 2.2097089,2.0834396 0 0 1 2.20959,-2.08351 2.2097089,2.0834396 0 0 1 2.20983,2.08329" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-75-4"
sodipodi:type="arc"
sodipodi:cx="121.42857"
sodipodi:cy="862.36218"
sodipodi:rx="1.4954232"
sodipodi:ry="1.3245111"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 122.924,862.36218 a 1.4954232,1.3245111 0 0 1 -1.4954,1.32451 1.4954232,1.3245111 0 0 1 -1.49545,-1.32446 1.4954232,1.3245111 0 0 1 1.49535,-1.32456 1.4954232,1.3245111 0 0 1 1.4955,1.32442" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-75-9"
sodipodi:type="arc"
sodipodi:cx="203.57143"
sodipodi:cy="964.14789"
sodipodi:rx="1.4954232"
sodipodi:ry="1.3245111"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 205.06685,964.14789 a 1.4954232,1.3245111 0 0 1 -1.4954,1.32451 1.4954232,1.3245111 0 0 1 -1.49545,-1.32447 1.4954232,1.3245111 0 0 1 1.49535,-1.32455 1.4954232,1.3245111 0 0 1 1.4955,1.32442" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-75-0"
sodipodi:type="arc"
sodipodi:cx="137.5"
sodipodi:cy="988.43359"
sodipodi:rx="1.4954232"
sodipodi:ry="1.3245111"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 138.99542,988.43359 a 1.4954232,1.3245111 0 0 1 -1.49539,1.32451 1.4954232,1.3245111 0 0 1 -1.49545,-1.32446 1.4954232,1.3245111 0 0 1 1.49534,-1.32456 1.4954232,1.3245111 0 0 1 1.4955,1.32442" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-75-98"
sodipodi:type="arc"
sodipodi:cx="100"
sodipodi:cy="976.29071"
sodipodi:rx="1.4954232"
sodipodi:ry="1.3245111"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 101.49542,976.29071 a 1.4954232,1.3245111 0 0 1 -1.49539,1.32451 1.4954232,1.3245111 0 0 1 -1.495453,-1.32446 1.4954232,1.3245111 0 0 1 1.495345,-1.32456 1.4954232,1.3245111 0 0 1 1.495498,1.32442" />
<path
style="display:inline;opacity:1;fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4227-75-8"
sodipodi:type="arc"
sodipodi:cx="95.35714"
sodipodi:cy="875.93359"
sodipodi:rx="1.4954232"
sodipodi:ry="1.3245111"
sodipodi:start="0"
sodipodi:end="6.2831155"
sodipodi:open="true"
d="m 96.852563,875.93359 a 1.4954232,1.3245111 0 0 1 -1.495397,1.32451 1.4954232,1.3245111 0 0 1 -1.49545,-1.32446 1.4954232,1.3245111 0 0 1 1.495345,-1.32456 1.4954232,1.3245111 0 0 1 1.495502,1.32442" />
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="Text"
style="display:inline">
<g
style="font-style:normal;font-weight:normal;font-size:50px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="text4175">
<path
d="m 25.065313,158.24001 26.91,0 0,-4.41 -6.03,-0.45 -1.44,-1.44 0,-47.97 1.44,-1.26 6.03,-0.45 0,-4.410005 -26.91,0 0,4.410005 5.94,0.45 1.44,1.26 0,47.97 -1.44,1.44 -5.94,0.45 0,4.41 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:90px;font-family:'Bitstream Charter';-inkscape-font-specification:'Bitstream Charter Bold';fill:#ffffff;fill-opacity:1"
id="path4182" />
<path
d="m 56.521719,158.24001 20.52,0 0,-4.32 -5.58,-0.72 -1.44,-1.62 0,-41.67 31.140001,48.33 10.08,0 0,-53.73 1.53,-1.71 5.31,-0.72 0,-4.230005 -20.520001,0 0,4.230005 5.490001,0.72 1.62,1.71 0,38.52 -27.540001,-42.75 0,-2.430005 -20.7,0 0,4.410005 5.76,0.45 1.26,1.26 0,47.61 -1.62,1.62 -5.31,0.72 0,4.32 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:90px;font-family:'Bitstream Charter';-inkscape-font-specification:'Bitstream Charter Bold';fill:#ffffff;fill-opacity:1"
id="path4184" />
<path
d="m 124.88234,156.26001 c 5.58,1.98 11.61,2.97 17.37,2.97 14.76,0 23.85,-7.74 23.85,-18.45 0,-5.31 -2.88,-10.17 -8.1,-13.5 -5.31,-3.42 -10.08,-4.77 -12.87,-6.48 -4.77,-2.88 -7.29,-5.58 -7.29,-9.72 0,-4.95 4.05,-8.55 10.62,-8.55 2.88,0 4.95,0.45 6.57,1.26 l 1.26,1.26 1.53,9.36 6.48,0 0,-14.580005 c -5.67,-1.98 -11.34,-3.06 -16.92,-3.06 -12.87,0 -21.24,7.740005 -21.24,17.730005 0,4.41 2.16,8.82 6.3,12.33 3.96,3.33 8.19,4.86 11.79,6.66 6.39,3.24 9.63,6.48 9.63,11.34 0,4.95 -4.32,8.55 -11.61,8.55 -2.79,0 -5.4,-0.45 -7.92,-1.26 l -1.17,-1.35 -1.44,-10.8 -6.84,0 0,16.29 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:90px;font-family:'Bitstream Charter';-inkscape-font-specification:'Bitstream Charter Bold';fill:#ffffff;fill-opacity:1"
id="path4186" />
<path
d="m 195.47469,97.220005 -20.34,55.800005 -5.4,0.81 0,4.41 19.35,0 0,-4.41 -5.67,-0.63 -0.9,-1.17 5.4,-15.21 19.62,0 5.4,15.3 -0.63,1.17 -5.67,0.54 0,4.41 24.3,0 0,-4.41 -5.31,-0.9 -20.7,-55.710005 -9.45,0 z m 1.98,12.330005 8.01,22.23 -15.84,0 7.83,-22.23 z"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:90px;font-family:'Bitstream Charter';-inkscape-font-specification:'Bitstream Charter Bold';fill:#ffffff;fill-opacity:1"
id="path4188" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="Arrow"
style="display:inline">
<path
transform="translate(0,-796.36216)"
style="display:inline;fill:#ee293d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 56.256042,955.37352 c -1.788821,1.72421 -6.479393,5.71015 -8.319307,7.30206 -5.728828,4.95664 -8.633783,7.69767 -4.752714,9.75827 2.659233,0.87145 9.333609,-0.54674 18.283086,-2.7909 24.574431,-6.16224 55.665463,-19.67511 74.978983,-30.34391 28.63169,-16.96002 26.40944,-16.81685 50.33035,-38.90049 6.15304,-8.33938 7.19968,-11.75273 4.47997,-15.08021 -1.85686,-2.27181 -12.48373,-0.71207 -17.79249,0.54824 -3.96667,0.94169 -12.94896,4.31889 -15.24258,4.24354 2.94511,-1.56322 6.23872,-3.82429 13.256,-6.0794 6.38188,-1.61881 18.89802,-4.61707 22.50377,-0.82506 3.76842,3.96309 4.29147,8.20736 -1.17178,16.05756 -20.76234,20.82694 -18.11365,22.9806 -54.07923,44.22174 -27.17477,14.51591 -48.940102,22.86785 -76.030392,30.51488 -10.135364,1.77776 -21.920892,5.06128 -26.365944,-0.91933 -0.09011,-5.50888 1.546606,-7.94692 8.967672,-12.64518 5.7232,-3.62335 8.105111,-3.97946 10.954606,-5.06181 z"
id="path4436"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscsccssccsccccsc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -70,12 +70,12 @@ manager.on('swipe', function(e) {
// Animate hamburger on hover
hamburger.hover(function(){
$("#bar1").css("background-color", "#c5af86");
$("#bar2-1").css("background-color", "#73b795");
$("#bar2-2").css("background-color", "#73b795");
$("#bar1").css("background-color", "#1a5dad");
$("#bar2-1").css("background-color", "#ee293d");
$("#bar2-2").css("background-color", "#ee293d");
$("#bar2-1").css("left", "-5px");
$("#bar2-2").css("right", "-5px");
$("#bar3").css("background-color", "#c5af86");
$("#bar3").css("background-color", "#1a5dad");
}, function(){
$("#bar1").css("background-color", "white");
$("#bar2-1").css("background-color", "white");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -5,5 +5,6 @@
<div id="bar2-2"></div>
<div id="bar3"></div>
</div>
<h4 id="menu_title">INSA Toulouse 2018</h4>
<img src="assets/images/logo-site-accueil.svg" id="menu_icon">
<h5 id="menu_title">Toulouse 2018</h5>
</div>

View file

@ -181,7 +181,7 @@ function getTotalPhotoCount($path)
function isValidImage($imagePath)
{
$ext = pathinfo($imagePath, PATHINFO_EXTENSION);
return !is_dir($imagePath) && ($ext == "jpg" || $ext == "jpeg" || $ext == "png");
return !is_dir($imagePath) && ($ext == "jpg" || $ext == "JPG" || $ext == "jpeg" || $ext == "JPEG" || $ext == "png" || $ext == "PNG");
}
/**

View file

@ -1,156 +1,416 @@
#!/usr/bin/python
#!/usr/bin/python3
import os
import sys
from zipfile import ZipFile, ZIP_DEFLATED
from PIL import Image
from PyQt5.QtCore import QThreadPool, Qt, pyqtSlot
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMainWindow, QAction, QDesktopWidget, QWidget, QFrame, QLineEdit, QListWidget, QVBoxLayout, \
QLabel, QPushButton, QGridLayout, QMessageBox, QFileDialog, QDialog, QTabWidget, QApplication, QCheckBox, \
QProgressBar
from compresser import Compresser
from scanner import Scanner
from utils import create_file_dialog
def get_images(path):
"""
get images in the folder specified and all its sub folders (hidden and empty folders are ignored)
class MainWindow(QMainWindow):
:param path: directory to get images in
:return: images list
"""
file_list = []
for root, dirs, files in os.walk(path):
if is_directory_valid(root, files):
for fn in files:
if is_file_valid_image(fn):
file_list.append(os.path.join(root, fn))
return file_list
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(1000, 600)
self.center()
self.main_widget = MainWidgets()
self.setCentralWidget(self.main_widget)
self.create_menu_bar()
self.setWindowTitle('Compression de Photos')
self.setWindowIcon(QIcon('icon.png'))
def create_menu_bar(self):
main_menu = self.menuBar()
file_menu = main_menu.addMenu("Fichier")
help_menu = main_menu.addMenu("Aide")
exit_button = QAction('Quitter', self)
exit_button.setShortcut('Ctrl+Q')
exit_button.setStatusTip('Quitter le logiciel')
exit_button.triggered.connect(self.close)
file_menu.addAction(exit_button)
about_button = QAction('À Propos', self)
about_button.setShortcut('Ctrl+H')
about_button.setStatusTip('Voir les informations du logiciel')
about_button.triggered.connect(self.display_help_dialog)
help_menu.addAction(about_button)
def center(self):
rectangle = self.frameGeometry()
center_point = QDesktopWidget().availableGeometry().center()
rectangle.moveCenter(center_point)
self.move(rectangle.topLeft())
def display_help_dialog(self):
dialog = HelpDialog(self)
dialog.exec_()
dialog.deleteLater()
def compress_images(images):
"""
Compress images to a 140x105 format, cropping in the middle if needed
:param images: list o images paths to compress
:return:
"""
size = 140, 105 # 4/3 format
print("Creating thumbnails", end="")
for current_img in images:
print(".", end="")
# If height is higher we resize vertically, if not we resize horizontally
img = Image.open(current_img)
# Get current and desired ratio for the images
img_ratio = img.size[0] / float(img.size[1])
ratio = size[0] / float(size[1])
# The image is scaled/cropped vertically or horizontally depending on the ratio
if ratio > img_ratio:
img = img.resize((size[0], round(size[0] * img.size[1] / img.size[0])), Image.BILINEAR)
# Crop in the middle
box = (0, round((img.size[1] - size[1]) / 2), img.size[0], round((img.size[1] + size[1]) / 2))
img = img.crop(box)
elif ratio < img_ratio:
img = img.resize((round(size[1] * img.size[0] / img.size[1]), size[1]), Image.BILINEAR)
# Crop in the middle
box = (round((img.size[0] - size[0]) / 2), 0, round((img.size[0] + size[0]) / 2), img.size[1])
img = img.crop(box)
class MainWidgets(QWidget):
def __init__(self):
super().__init__()
self.dir_select_group = QFrame()
self.dir_path_line_edit = QLineEdit(os.path.dirname(__file__))
self.dir_selection_button = QPushButton("Selectionner")
self.dir_thumb_path_line_edit = QLineEdit(os.path.dirname(__file__) + "_thumb")
self.dir_thumb_selection_button = QPushButton("Selectionner")
self.scan_progress_bar = QProgressBar()
self.scan_progress_text = QLabel("Scan")
self.dir_list_group = QFrame()
self.directories_list = QListWidget()
self.scan_button = QPushButton("Scanner")
self.stop_scan_button = QPushButton("Stop")
self.compress_button = QPushButton("Compresser")
self.stop_compress_button = QPushButton("Stop")
self.list_title = QLabel("0 images dans 0 dossiers :")
self.delete_button = QPushButton("Enlever sélectionné")
self.enable_zip_radio_button = QCheckBox("Créer .zip")
self.enable_thumb_radio_button = QCheckBox("Créer miniatures")
self.enable_compress_radio_button = QCheckBox("Compresser photos")
self.compress_progress_bar = QProgressBar()
self.compress_progress_text = QLabel("Compression")
self.zip_progress_bar = QProgressBar()
self.zip_progress_text = QLabel("Création de .zip")
self.thumb_progress_bar = QProgressBar()
self.thumb_progress_text = QLabel("Création de miniatures")
self.image_list = []
self.main_layout = QGridLayout()
self.scanner = Scanner("")
self.compresser = Compresser([], [], "", "", True, True, True)
self.thread_pool = QThreadPool()
self.init_ui()
def init_ui(self):
self.setLayout(self.main_layout)
subtitle = QLabel("Cet utilitaire permet de créer un fichier compressé des images du dossier sélectionné (et "
"tout ses sous dossiers)\nainsi que la miniatures de images présentes")
subtitle.setAlignment(Qt.AlignCenter)
y = 0
self.main_layout.addWidget(subtitle, y, 0, 1, 20)
y += 1
self.main_layout.addWidget(QLabel("Dossier parent :"), y, 0, 1, 1)
self.dir_path_line_edit.textChanged.connect(self.directories_list.clear)
self.main_layout.addWidget(self.dir_path_line_edit, y, 1, 1, 18)
self.dir_selection_button.clicked.connect(self.open_dir)
self.main_layout.addWidget(self.dir_selection_button, y, 19, 1, 1)
y += 1
self.main_layout.addWidget(QLabel("Dossier miniatures :"), y, 0, 1, 1)
self.dir_thumb_path_line_edit.textChanged.connect(self.directories_list.clear)
self.main_layout.addWidget(self.dir_thumb_path_line_edit, y, 1, 1, 18)
self.dir_thumb_selection_button.clicked.connect(self.open_thumb_dir)
self.main_layout.addWidget(self.dir_thumb_selection_button, y, 19, 1, 1)
y += 1
self.scan_button.clicked.connect(self.scan_click)
self.main_layout.addWidget(self.scan_button, y, 5, 1, 10)
self.stop_scan_button.clicked.connect(self.stop_scan)
self.stop_scan_button.setEnabled(False)
self.main_layout.addWidget(self.stop_scan_button, y, 15, 1, 1)
y += 1
self.main_layout.addWidget(self.scan_progress_text, y, 0, 1, 20)
self.scan_progress_bar.setTextVisible(False)
y += 1
self.main_layout.addWidget(self.scan_progress_bar, y, 0, 1, 20)
y += 1
self.main_layout.addWidget(self.list_title, y, 0, 1, 20)
y += 1
self.main_layout.addWidget(self.directories_list, y, 0, 10, 19)
self.delete_button.clicked.connect(self.dir_list_delete_selected)
self.main_layout.addWidget(self.delete_button, y, 19, 1, 1)
y += 1
self.enable_compress_radio_button.toggled.connect(self.set_compress_enabled)
self.enable_compress_radio_button.setChecked(True)
self.main_layout.addWidget(self.enable_compress_radio_button, y, 19, 1, 1)
y += 1
self.enable_zip_radio_button.toggled.connect(self.set_zip_enabled)
self.enable_zip_radio_button.setChecked(True)
self.main_layout.addWidget(self.enable_zip_radio_button, y, 19, 1, 1)
y += 1
self.enable_thumb_radio_button.toggled.connect(self.set_thumb_enabled)
self.enable_thumb_radio_button.setChecked(True)
self.main_layout.addWidget(self.enable_thumb_radio_button, y, 19, 1, 1)
y += 7
self.compress_button.clicked.connect(self.compress_click)
self.main_layout.addWidget(self.compress_button, y, 5, 1, 10)
self.stop_compress_button.clicked.connect(self.stop_compress)
self.stop_compress_button.setEnabled(False)
self.main_layout.addWidget(self.stop_compress_button, y, 15, 1, 1)
y += 1
self.main_layout.addWidget(self.compress_progress_text, y, 0, 1, 20)
y += 1
self.compress_progress_bar.setTextVisible(False)
self.main_layout.addWidget(self.compress_progress_bar, y, 0, 1, 20)
y += 1
self.main_layout.addWidget(self.zip_progress_text, y, 0, 1, 20)
y += 1
self.zip_progress_bar.setTextVisible(False)
self.main_layout.addWidget(self.zip_progress_bar, y, 0, 1, 20)
y += 1
self.main_layout.addWidget(self.thumb_progress_text, y, 0, 1, 20)
y += 1
self.thumb_progress_bar.setTextVisible(False)
self.main_layout.addWidget(self.thumb_progress_bar, y, 0, 1, 20)
def dir_list_delete_selected(self):
for selected_item in self.directories_list.selectedItems():
self.directories_list.takeItem(self.directories_list.row(selected_item))
def get_dir_list(self):
items = []
for index in range(self.directories_list.count()):
items.append(self.directories_list.item(index).text())
return items
def set_compress_enabled(self, enabled):
self.compress_progress_bar.setHidden(not enabled)
self.compress_progress_text.setEnabled(enabled)
def set_zip_enabled(self, enabled):
self.zip_progress_bar.setHidden(not enabled)
self.zip_progress_text.setEnabled(enabled)
def set_thumb_enabled(self, enabled):
self.thumb_progress_bar.setHidden(not enabled)
self.thumb_progress_text.setEnabled(enabled)
def set_ui_enabled(self, enabled, is_scan):
self.dir_path_line_edit.setEnabled(enabled)
self.dir_thumb_path_line_edit.setEnabled(enabled)
self.stop_compress_button.setEnabled(enabled)
self.stop_scan_button.setEnabled(enabled)
self.compress_button.setEnabled(enabled)
self.scan_button.setEnabled(enabled)
self.delete_button.setEnabled(enabled)
self.enable_zip_radio_button.setEnabled(enabled)
self.enable_compress_radio_button.setEnabled(enabled)
self.enable_thumb_radio_button.setEnabled(enabled)
self.dir_selection_button.setEnabled(enabled)
self.dir_thumb_selection_button.setEnabled(enabled)
self.stop_scan_button.setEnabled((not enabled) and is_scan)
self.stop_compress_button.setEnabled((not enabled) and (not is_scan))
def scan_click(self):
self.directories_list.clear()
# Start scan thread
self.set_ui_enabled(False, True)
self.scanner = Scanner(self.dir_path_line_edit.text())
self.scanner.signals.scanned_dir_signal.connect(self.add_dir_to_list)
self.scanner.signals.scan_finished_signal.connect(self.scan_finished)
self.scanner.signals.scanned_dir_finished.connect(self.reset_progress_scan)
self.scanner.signals.scanned_images_signal.connect(self.add_progress_scan)
self.scanner.signals.new_scan_task_started.connect(self.scan_progress_text.setText)
self.thread_pool.start(self.scanner)
def stop_scan(self):
self.scanner.stop()
def add_dir_to_list(self, directory):
self.directories_list.addItem(directory)
def scan_finished(self, dir_list, image_list):
self.set_ui_enabled(True, True)
self.image_list = image_list
self.list_title.setText(
str(len(self.image_list)) + " images dans " + str(len(self.get_dir_list())) + " dossiers :")
self.reset_progress_compress()
self.reset_progress_zip()
self.reset_progress_thumb()
if self.scanner.is_aborted():
QMessageBox.warning(self, "Scan Annulé", "Scan des dossiers stoppé\n" + str(len(dir_list)) + " dossier et "
+ str(len(self.image_list)) + " images trouvés")
else:
img = img.resize((size[0], size[1]), Image.BILINEAR)
# If the scale is the same, we do not need to crop
filename = get_new_path(current_img)
if not os.path.exists(os.path.dirname(filename)):
try:
os.makedirs(os.path.dirname(filename))
except OSError:
sys.exit("Fatal : Directory '" + os.path.dirname(filename) + "' does not exist and cannot be created")
QMessageBox.information(self, "Scan Terminé",
"Scan des dossiers terminé\n" + str(len(dir_list)) + " dossier et "
+ str(len(self.image_list)) + " images trouvés")
img.save(filename, "JPEG")
print("done")
print("Thumbnails saved in 'photos_thumb' directory")
def compress_click(self):
if self.directories_list.count() == 0:
QMessageBox.warning(self, "Erreur", "Aucun dossier trouvé\nVeuillez vérifier le dossier parent")
elif (not self.enable_compress_radio_button.checkState()) and (not self.enable_zip_radio_button.checkState()) \
and (not self.enable_thumb_radio_button.checkState()):
QMessageBox.warning(self, "Erreur", "Aucune action sélectionnée")
else:
self.show_confirmation_dialog()
def show_confirmation_dialog(self):
msg = str(len(self.get_dir_list())) + " dossiers contenant " + str(len(self.image_list)) + \
" images selectionnés\n\nActions à réaliser :"
if self.enable_compress_radio_button.checkState():
msg += "\nCompression des images"
if self.enable_zip_radio_button.checkState():
msg += "\nCréation de .zip"
if self.enable_thumb_radio_button.checkState():
msg += "\nCréation de miniatures"
msg += "\n\nÊtes-vous sûr de vouloir continuer ?"
confirmation_dialog = QMessageBox.question(self, 'Confirmation', msg,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if confirmation_dialog == QMessageBox.Yes:
# Start compress thread
self.reset_progress_compress()
self.reset_progress_zip()
self.reset_progress_thumb()
self.set_ui_enabled(False, False)
self.compresser = Compresser(self.get_dir_list(), self.image_list, self.dir_path_line_edit.text(),
self.dir_thumb_path_line_edit.text(),
self.enable_compress_radio_button.checkState(),
self.enable_zip_radio_button.checkState(),
self.enable_thumb_radio_button.checkState())
self.compresser.signals.finished_signal.connect(self.compress_finished)
self.compresser.signals.new_compress_task_started.connect(self.compress_progress_text.setText)
self.compresser.signals.new_zip_task_started.connect(self.zip_progress_text.setText)
self.compresser.signals.new_thumb_task_started.connect(self.thumb_progress_text.setText)
self.compresser.signals.compress_done.connect(self.add_progress_compress)
self.compresser.signals.zip_done.connect(self.add_progress_zip)
self.compresser.signals.thumb_done.connect(self.add_progress_thumb)
self.thread_pool.start(self.compresser)
def stop_compress(self):
self.compresser.stop()
def reset_progress_scan(self):
self.scan_progress_text.setText("Scan")
self.scan_progress_bar.setMinimum(0)
self.scan_progress_bar.setMaximum(len(self.get_dir_list()))
self.scan_progress_bar.setValue(0)
def reset_progress_compress(self):
self.compress_progress_text.setText("Compression")
self.compress_progress_bar.setMinimum(0)
self.compress_progress_bar.setMaximum(len(self.image_list))
self.compress_progress_bar.setValue(0)
def reset_progress_zip(self):
self.zip_progress_text.setText("Création de .zip")
self.zip_progress_bar.setMinimum(0)
self.zip_progress_bar.setMaximum(len(self.get_dir_list()))
self.zip_progress_bar.setValue(0)
def reset_progress_thumb(self):
self.thumb_progress_text.setText("Création de miniatures")
self.thumb_progress_bar.setMinimum(0)
self.thumb_progress_bar.setMaximum(len(self.image_list))
self.thumb_progress_bar.setValue(0)
def add_progress_scan(self):
self.scan_progress_bar.setValue(self.scan_progress_bar.value() + 1)
def add_progress_compress(self):
self.compress_progress_bar.setValue(self.compress_progress_bar.value() + 1)
def add_progress_zip(self):
self.zip_progress_bar.setValue(self.zip_progress_bar.value() + 1)
def add_progress_thumb(self):
self.thumb_progress_bar.setValue(self.thumb_progress_bar.value() + 1)
def compress_finished(self):
self.set_ui_enabled(True, False)
if self.compresser.is_aborted():
QMessageBox.warning(self, "Annulé", "Compression stoppée")
else:
QMessageBox.information(self, "Terminé", "Compression terminée")
def open_dir(self):
dialog = create_file_dialog()
dialog.selectFile(self.dir_path_line_edit.text())
if dialog.exec_():
self.dir_path_line_edit.setText(dialog.selectedFiles()[0])
def open_thumb_dir(self):
dialog = create_file_dialog()
dialog.selectFile(self.dir_thumb_path_line_edit.text())
if dialog.exec_():
self.dir_thumb_path_line_edit.setText(dialog.selectedFiles()[0])
def get_new_path(img):
"""
Replace the original path to the thumbnail one (replace 'photos' by 'photos_thumb')
:param img: original path
:return: modified path
"""
return img.replace("/photos/", "/photos_thumb/", 1)
class HelpDialog(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.resize(300, 100)
self.main_layout = QVBoxLayout()
self.setLayout(self.main_layout)
title = QLabel("Compression de photos")
font = title.font()
font.setBold(True)
font.setPixelSize(20)
title.setFont(font)
title.setAlignment(Qt.AlignCenter)
self.main_layout.addWidget(title)
def zip_dir(path):
"""
Compress images in the specified directory and sub-directories
Create one zip per folder
self.tabs = QTabWidget()
self.tab1 = QWidget()
self.tab2 = QWidget()
:param path: directory to get files in
:return:
"""
for root, dirs, files in os.walk(path):
if is_directory_valid(root, files):
print("Compressing '" + root + "'", end="")
with ZipFile(os.path.join(root, get_current_dir(root)) + ".zip", "w", ZIP_DEFLATED) as zip_file:
for fn in files:
if not fn.endswith("zip") and is_file_valid_image(fn):
print(".", end="")
absolute_file_name = os.path.join(root, fn)
zippped_file_name = absolute_file_name[len(root)+len(os.sep):] # XXX: relative path
zip_file.write(absolute_file_name, zippped_file_name)
print("done")
print("COMPRESSION FINISHED")
self.tabs.addTab(self.tab1, "À Propos")
self.tabs.addTab(self.tab2, "Librairies")
self.create_about_tab()
self.create_libs_tab()
self.main_layout.addWidget(self.tabs)
def create_about_tab(self):
self.tab1.layout = QVBoxLayout(self)
author = QLabel("(c) 2018 Arnaud VERGNET")
author.setAlignment(Qt.AlignCenter)
self.tab1.layout.addWidget(author)
def is_directory_valid(path, files):
"""
Check if the given path is not hidden or without images
:param files: files in the folder
:param path: Path to check
:return: True if path contains a hidden folder or is empty, False otherwise
"""
directories = path.split(os.sep)
valid = len(files) > 0
for dn in directories: # check if directory or one of its parent are not hidden
if dn.startswith(".") or not valid:
valid = False
break
if valid:
valid_files = []
for fn in files: # check if directory contains valid images
if is_file_valid_image(fn):
valid_files.append(fn)
valid = len(valid_files) > 0
return valid
github = QLabel("Disponible sur GitHub sous license GPLv3")
github.setAlignment(Qt.AlignCenter)
self.tab1.layout.addWidget(github)
gh_link = QLabel()
gh_link.setOpenExternalLinks(True)
gh_link.setText("<a href='https://github.com/Keplyx'>https://github.com/Keplyx</a>")
gh_link.setAlignment(Qt.AlignCenter)
self.tab1.layout.addWidget(gh_link)
self.tab1.setLayout(self.tab1.layout)
def is_file_valid_image(file):
return file.endswith("png") or file.endswith("jpg") or file.endswith("jpeg")
def create_libs_tab(self):
self.tab2.layout = QVBoxLayout(self)
qt_lib = QLabel("Qt5")
qt_lib.setAlignment(Qt.AlignCenter)
self.tab2.layout.addWidget(qt_lib)
python_lib = QLabel("python3 avec PyQt5")
python_lib.setAlignment(Qt.AlignCenter)
self.tab2.layout.addWidget(python_lib)
def get_current_dir(path):
"""
Get the name of the current directory
:param path: Path to search the name in
:return: directory name
"""
return os.path.basename(os.path.normpath(path))
self.tab2.setLayout(self.tab2.layout)
def get_confirmation(path):
"""
Tell the user which folders will be compressed, and asks for confirmation
:param path: Root path for search
:return: True if user confirmed, False otherwise
"""
print("The following folders will be compressed (hidden and empty folders are ignored):")
for root, dirs, files in os.walk(path):
if is_directory_valid(root, files):
print(root)
confirmation = input("Are you sure you want to proceed? [Y/n]")
return confirmation == "Y" or confirmation == "y"
@pyqtSlot()
def on_click(self):
for currentQTableWidgetItem in self.tableWidget.selectedItems():
print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())
if __name__ == '__main__':
# Get path from arguments or use the script's path
if len(sys.argv) > 1:
directory = sys.argv[1]
else:
directory = os.path.dirname(os.path.realpath(__file__))
if get_confirmation(directory):
zip_dir(directory)
compress_images(get_images(directory))
else:
print("Compression aborted")
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())