Browse Source

Release: 8ad0730237

master
Dirk Alders 4 years ago
parent
commit
1c06aab615
6 changed files with 3136 additions and 2034 deletions
  1. 24
    2
      __init__.py
  2. 90
    67
      _testresults_/coverage.xml
  3. 3017
    1963
      _testresults_/unittest.json
  4. BIN
      _testresults_/unittest.pdf
  5. 1
    1
      convert.py
  6. 4
    1
      metadata.py

+ 24
- 2
__init__.py View File

24
 """
24
 """
25
 __DEPENDENCIES__ = []
25
 __DEPENDENCIES__ = []
26
 
26
 
27
+import io
27
 import logging
28
 import logging
28
-from PIL import Image, ImageEnhance
29
+from PIL import Image, ImageEnhance, ExifTags
29
 
30
 
30
 logger_name = 'MEDIA'
31
 logger_name = 'MEDIA'
31
 logger = logging.getLogger(logger_name)
32
 logger = logging.getLogger(logger_name)
106
         self._im = get_pil_image(media_instance)
107
         self._im = get_pil_image(media_instance)
107
         if self._im is None:
108
         if self._im is None:
108
             return False
109
             return False
110
+        try:
111
+            self._exif = dict(self._im._getexif().items())
112
+        except AttributeError:
113
+            self._exif = {}
114
+        if type(self._im) is not Image.Image:
115
+            self._im = self._im.copy()
116
+        logger.debug('loading image from %s', repr(media_instance))
109
         return True
117
         return True
110
 
118
 
111
     def save(self, full_path):
119
     def save(self, full_path):
119
                 im.save(fh, 'JPEG')
127
                 im.save(fh, 'JPEG')
120
         return True
128
         return True
121
 
129
 
130
+    def image_data(self):
131
+        im = self._im.copy().convert('RGB')
132
+        output = io.BytesIO()
133
+        im.save(output, format='JPEG')
134
+        return output.getvalue()
135
+
122
     def resize(self, max_size):
136
     def resize(self, max_size):
123
         if self._im is None:
137
         if self._im is None:
124
             logger.warning('No image available to be resized')
138
             logger.warning('No image available to be resized')
130
             self._im = self._im.resize((int(x * float(max_size) / xy_max), int(y * float(max_size) / xy_max)), Image.NEAREST).rotate(0)
144
             self._im = self._im.resize((int(x * float(max_size) / xy_max), int(y * float(max_size) / xy_max)), Image.NEAREST).rotate(0)
131
         return True
145
         return True
132
 
146
 
133
-    def rotate_by_orientation(self, orientation):
147
+    def rotate_by_orientation(self, orientation=None):
134
         if self._im is None:
148
         if self._im is None:
135
             logger.warning('No image available, rotation not possible')
149
             logger.warning('No image available, rotation not possible')
136
             return False
150
             return False
137
 
151
 
152
+        if orientation is None:
153
+            exif_tags = dict((v, k) for k, v in ExifTags.TAGS.items())
154
+            try:
155
+                orientation = self._exif[exif_tags['Orientation']]
156
+                logger.debug("No orientation given, orientation %s extract from exif data", repr(orientation))
157
+            except KeyError:
158
+                return False
159
+
138
         if orientation == ORIENTATION_HALF_ROTATED:
160
         if orientation == ORIENTATION_HALF_ROTATED:
139
             angle = 180
161
             angle = 180
140
         elif orientation == ORIENTATION_LEFT_ROTATED:
162
         elif orientation == ORIENTATION_LEFT_ROTATED:

+ 90
- 67
_testresults_/coverage.xml View File

1
 <?xml version="1.0" ?>
1
 <?xml version="1.0" ?>
2
-<coverage branch-rate="0.9643" branches-covered="81" branches-valid="84" complexity="0" line-rate="0.9759" lines-covered="324" lines-valid="332" timestamp="1580584174451" version="4.5">
2
+<coverage branch-rate="0.9667" branches-covered="87" branches-valid="90" complexity="0" line-rate="0.9775" lines-covered="347" lines-valid="355" timestamp="1580683820455" version="4.5">
3
 	<!-- Generated by coverage.py: https://coverage.readthedocs.io -->
3
 	<!-- Generated by coverage.py: https://coverage.readthedocs.io -->
4
 	<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
4
 	<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
5
 	<sources/>
5
 	<sources/>
6
 	<packages>
6
 	<packages>
7
-		<package branch-rate="0.9643" complexity="0" line-rate="0.9759" name=".user_data.data.dirk.prj.unittest.media.pylibs.media">
7
+		<package branch-rate="0.9667" complexity="0" line-rate="0.9775" name=".user_data.data.dirk.prj.unittest.media.pylibs.media">
8
 			<classes>
8
 			<classes>
9
-				<class branch-rate="0.9737" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/__init__.py" line-rate="0.9924" name="__init__.py">
9
+				<class branch-rate="0.9773" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/__init__.py" line-rate="0.9934" name="__init__.py">
10
 					<methods/>
10
 					<methods/>
11
 					<lines>
11
 					<lines>
12
 						<line hits="1" number="4"/>
12
 						<line hits="1" number="4"/>
13
 						<line hits="1" number="25"/>
13
 						<line hits="1" number="25"/>
14
 						<line hits="1" number="27"/>
14
 						<line hits="1" number="27"/>
15
 						<line hits="1" number="28"/>
15
 						<line hits="1" number="28"/>
16
-						<line hits="1" number="30"/>
16
+						<line hits="1" number="29"/>
17
 						<line hits="1" number="31"/>
17
 						<line hits="1" number="31"/>
18
-						<line hits="1" number="34"/>
19
-						<line hits="1" number="37"/>
20
-						<line hits="1" number="41"/>
18
+						<line hits="1" number="32"/>
19
+						<line hits="1" number="35"/>
20
+						<line hits="1" number="38"/>
21
 						<line hits="1" number="42"/>
21
 						<line hits="1" number="42"/>
22
 						<line hits="1" number="43"/>
22
 						<line hits="1" number="43"/>
23
 						<line hits="1" number="44"/>
23
 						<line hits="1" number="44"/>
40
 						<line hits="1" number="61"/>
40
 						<line hits="1" number="61"/>
41
 						<line hits="1" number="62"/>
41
 						<line hits="1" number="62"/>
42
 						<line hits="1" number="63"/>
42
 						<line hits="1" number="63"/>
43
-						<line hits="1" number="66"/>
43
+						<line hits="1" number="64"/>
44
 						<line hits="1" number="67"/>
44
 						<line hits="1" number="67"/>
45
 						<line hits="1" number="68"/>
45
 						<line hits="1" number="68"/>
46
-						<line hits="1" number="70"/>
47
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="72"/>
48
-						<line hits="1" number="73"/>
49
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="74"/>
50
-						<line hits="1" number="75"/>
51
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="76"/>
52
-						<line hits="1" number="77"/>
53
-						<line hits="1" number="79"/>
54
-						<line hits="1" number="82"/>
46
+						<line hits="1" number="69"/>
47
+						<line hits="1" number="71"/>
48
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="73"/>
49
+						<line hits="1" number="74"/>
50
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="75"/>
51
+						<line hits="1" number="76"/>
52
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="77"/>
53
+						<line hits="1" number="78"/>
54
+						<line hits="1" number="80"/>
55
 						<line hits="1" number="83"/>
55
 						<line hits="1" number="83"/>
56
 						<line hits="1" number="84"/>
56
 						<line hits="1" number="84"/>
57
 						<line hits="1" number="85"/>
57
 						<line hits="1" number="85"/>
58
 						<line hits="1" number="86"/>
58
 						<line hits="1" number="86"/>
59
 						<line hits="1" number="87"/>
59
 						<line hits="1" number="87"/>
60
-						<line hits="1" number="89"/>
60
+						<line hits="1" number="88"/>
61
 						<line hits="1" number="90"/>
61
 						<line hits="1" number="90"/>
62
 						<line hits="1" number="91"/>
62
 						<line hits="1" number="91"/>
63
 						<line hits="1" number="92"/>
63
 						<line hits="1" number="92"/>
64
 						<line hits="1" number="93"/>
64
 						<line hits="1" number="93"/>
65
-						<line hits="1" number="96"/>
65
+						<line hits="1" number="94"/>
66
 						<line hits="1" number="97"/>
66
 						<line hits="1" number="97"/>
67
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="98"/>
68
-						<line hits="1" number="99"/>
69
-						<line hits="1" number="101"/>
70
-						<line hits="1" number="103"/>
67
+						<line hits="1" number="98"/>
68
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="99"/>
69
+						<line hits="1" number="100"/>
70
+						<line hits="1" number="102"/>
71
 						<line hits="1" number="104"/>
71
 						<line hits="1" number="104"/>
72
-						<line hits="1" number="106"/>
73
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="107"/>
74
-						<line hits="1" number="108"/>
72
+						<line hits="1" number="105"/>
73
+						<line hits="1" number="107"/>
74
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="108"/>
75
 						<line hits="1" number="109"/>
75
 						<line hits="1" number="109"/>
76
+						<line hits="1" number="110"/>
76
 						<line hits="1" number="111"/>
77
 						<line hits="1" number="111"/>
77
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="112"/>
78
+						<line hits="1" number="112"/>
78
 						<line hits="1" number="113"/>
79
 						<line hits="1" number="113"/>
79
-						<line hits="1" number="114"/>
80
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="114"/>
81
+						<line hits="1" number="115"/>
80
 						<line hits="1" number="116"/>
82
 						<line hits="1" number="116"/>
81
 						<line hits="1" number="117"/>
83
 						<line hits="1" number="117"/>
82
-						<line hits="1" number="118"/>
83
 						<line hits="1" number="119"/>
84
 						<line hits="1" number="119"/>
84
-						<line hits="1" number="120"/>
85
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="120"/>
86
+						<line hits="1" number="121"/>
85
 						<line hits="1" number="122"/>
87
 						<line hits="1" number="122"/>
86
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="123"/>
87
 						<line hits="1" number="124"/>
88
 						<line hits="1" number="124"/>
88
 						<line hits="1" number="125"/>
89
 						<line hits="1" number="125"/>
90
+						<line hits="1" number="126"/>
89
 						<line hits="1" number="127"/>
91
 						<line hits="1" number="127"/>
90
 						<line hits="1" number="128"/>
92
 						<line hits="1" number="128"/>
91
-						<line hits="1" number="129"/>
92
 						<line hits="1" number="130"/>
93
 						<line hits="1" number="130"/>
93
 						<line hits="1" number="131"/>
94
 						<line hits="1" number="131"/>
95
+						<line hits="1" number="132"/>
94
 						<line hits="1" number="133"/>
96
 						<line hits="1" number="133"/>
95
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="134"/>
96
-						<line hits="1" number="135"/>
97
+						<line hits="1" number="134"/>
97
 						<line hits="1" number="136"/>
98
 						<line hits="1" number="136"/>
98
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="138"/>
99
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="137"/>
100
+						<line hits="1" number="138"/>
99
 						<line hits="1" number="139"/>
101
 						<line hits="1" number="139"/>
100
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="140"/>
101
 						<line hits="1" number="141"/>
102
 						<line hits="1" number="141"/>
102
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="142"/>
103
+						<line hits="1" number="142"/>
103
 						<line hits="1" number="143"/>
104
 						<line hits="1" number="143"/>
105
+						<line hits="1" number="144"/>
104
 						<line hits="1" number="145"/>
106
 						<line hits="1" number="145"/>
105
-						<line hits="1" number="146"/>
106
 						<line hits="1" number="147"/>
107
 						<line hits="1" number="147"/>
107
-						<line hits="1" number="148"/>
108
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="148"/>
108
 						<line hits="1" number="149"/>
109
 						<line hits="1" number="149"/>
109
-						<line hits="1" number="151"/>
110
-						<line hits="1" number="152"/>
110
+						<line hits="1" number="150"/>
111
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="152"/>
112
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="153"/>
111
 						<line hits="1" number="154"/>
113
 						<line hits="1" number="154"/>
112
-						<line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="158" number="155"/>
114
+						<line hits="1" number="155"/>
113
 						<line hits="1" number="156"/>
115
 						<line hits="1" number="156"/>
114
-						<line hits="0" number="158"/>
116
+						<line hits="1" number="157"/>
117
+						<line hits="1" number="158"/>
115
 						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="160"/>
118
 						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="160"/>
116
 						<line hits="1" number="161"/>
119
 						<line hits="1" number="161"/>
117
-						<line hits="1" number="162"/>
120
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="162"/>
121
+						<line hits="1" number="163"/>
122
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="164"/>
118
 						<line hits="1" number="165"/>
123
 						<line hits="1" number="165"/>
119
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="166"/>
120
 						<line hits="1" number="167"/>
124
 						<line hits="1" number="167"/>
121
 						<line hits="1" number="168"/>
125
 						<line hits="1" number="168"/>
126
+						<line hits="1" number="169"/>
122
 						<line hits="1" number="170"/>
127
 						<line hits="1" number="170"/>
123
-						<line hits="1" number="172"/>
128
+						<line hits="1" number="171"/>
124
 						<line hits="1" number="173"/>
129
 						<line hits="1" number="173"/>
125
 						<line hits="1" number="174"/>
130
 						<line hits="1" number="174"/>
126
 						<line hits="1" number="176"/>
131
 						<line hits="1" number="176"/>
127
-						<line hits="1" number="179"/>
128
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="181"/>
129
-						<line hits="1" number="182"/>
130
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="183"/>
132
+						<line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="180" number="177"/>
133
+						<line hits="1" number="178"/>
134
+						<line hits="0" number="180"/>
135
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="182"/>
136
+						<line hits="1" number="183"/>
131
 						<line hits="1" number="184"/>
137
 						<line hits="1" number="184"/>
132
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="185"/>
133
-						<line hits="1" number="186"/>
134
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="187"/>
135
-						<line hits="1" number="188"/>
136
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="189"/>
138
+						<line hits="1" number="187"/>
139
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="188"/>
140
+						<line hits="1" number="189"/>
137
 						<line hits="1" number="190"/>
141
 						<line hits="1" number="190"/>
138
 						<line hits="1" number="192"/>
142
 						<line hits="1" number="192"/>
139
-						<line hits="1" number="193"/>
143
+						<line hits="1" number="194"/>
140
 						<line hits="1" number="195"/>
144
 						<line hits="1" number="195"/>
141
 						<line hits="1" number="196"/>
145
 						<line hits="1" number="196"/>
142
 						<line hits="1" number="198"/>
146
 						<line hits="1" number="198"/>
147
+						<line hits="1" number="201"/>
148
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="203"/>
149
+						<line hits="1" number="204"/>
150
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="205"/>
151
+						<line hits="1" number="206"/>
152
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="207"/>
153
+						<line hits="1" number="208"/>
154
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="209"/>
155
+						<line hits="1" number="210"/>
156
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="211"/>
157
+						<line hits="1" number="212"/>
158
+						<line hits="1" number="214"/>
159
+						<line hits="1" number="215"/>
160
+						<line hits="1" number="217"/>
161
+						<line hits="1" number="218"/>
162
+						<line hits="1" number="220"/>
143
 					</lines>
163
 					</lines>
144
 				</class>
164
 				</class>
145
 				<class branch-rate="1" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/common.py" line-rate="1" name="common.py">
165
 				<class branch-rate="1" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/common.py" line-rate="1" name="common.py">
197
 						<line hits="1" number="35"/>
217
 						<line hits="1" number="35"/>
198
 					</lines>
218
 					</lines>
199
 				</class>
219
 				</class>
200
-				<class branch-rate="0.9667" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/metadata.py" line-rate="0.9808" name="metadata.py">
220
+				<class branch-rate="0.9667" complexity="0" filename="/user_data/data/dirk/prj/unittest/media/pylibs/media/metadata.py" line-rate="0.9811" name="metadata.py">
201
 					<methods/>
221
 					<methods/>
202
 					<lines>
222
 					<lines>
203
 						<line hits="1" number="1"/>
223
 						<line hits="1" number="1"/>
334
 						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="194"/>
354
 						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="194"/>
335
 						<line hits="1" number="195"/>
355
 						<line hits="1" number="195"/>
336
 						<line hits="1" number="196"/>
356
 						<line hits="1" number="196"/>
357
+						<line hits="1" number="197"/>
358
+						<line hits="1" number="198"/>
337
 						<line hits="1" number="199"/>
359
 						<line hits="1" number="199"/>
338
-						<line hits="1" number="200"/>
339
-						<line hits="1" number="201"/>
360
+						<line hits="1" number="202"/>
361
+						<line hits="1" number="203"/>
340
 						<line hits="1" number="204"/>
362
 						<line hits="1" number="204"/>
341
-						<line hits="1" number="205"/>
342
-						<line hits="1" number="206"/>
343
 						<line hits="1" number="207"/>
363
 						<line hits="1" number="207"/>
344
-						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="208"/>
364
+						<line hits="1" number="208"/>
345
 						<line hits="1" number="209"/>
365
 						<line hits="1" number="209"/>
346
 						<line hits="1" number="210"/>
366
 						<line hits="1" number="210"/>
347
-						<line hits="1" number="211"/>
367
+						<line branch="true" condition-coverage="100% (2/2)" hits="1" number="211"/>
348
 						<line hits="1" number="212"/>
368
 						<line hits="1" number="212"/>
349
 						<line hits="1" number="213"/>
369
 						<line hits="1" number="213"/>
350
 						<line hits="1" number="214"/>
370
 						<line hits="1" number="214"/>
351
-						<line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="215"/>
371
+						<line hits="1" number="215"/>
352
 						<line hits="1" number="216"/>
372
 						<line hits="1" number="216"/>
353
 						<line hits="1" number="217"/>
373
 						<line hits="1" number="217"/>
354
-						<line hits="1" number="218"/>
374
+						<line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="218"/>
375
+						<line hits="1" number="219"/>
376
+						<line hits="1" number="220"/>
355
 						<line hits="1" number="221"/>
377
 						<line hits="1" number="221"/>
356
-						<line hits="1" number="222"/>
357
-						<line hits="1" number="223"/>
358
 						<line hits="1" number="224"/>
378
 						<line hits="1" number="224"/>
379
+						<line hits="1" number="225"/>
380
+						<line hits="1" number="226"/>
381
+						<line hits="1" number="227"/>
359
 					</lines>
382
 					</lines>
360
 				</class>
383
 				</class>
361
 			</classes>
384
 			</classes>

+ 3017
- 1963
_testresults_/unittest.json
File diff suppressed because it is too large
View File


BIN
_testresults_/unittest.pdf View File


+ 1
- 1
convert.py View File

14
     if type(media_instance) == str:
14
     if type(media_instance) == str:
15
         ft = common.get_filetype(media_instance)
15
         ft = common.get_filetype(media_instance)
16
         if ft == common.FILETYPE_IMAGE:
16
         if ft == common.FILETYPE_IMAGE:
17
-            return Image.open(media_instance).copy()
17
+            return Image.open(media_instance)
18
         elif ft == common.FILETYPE_VIDEO:
18
         elif ft == common.FILETYPE_VIDEO:
19
             if platform.system() == 'Linux':
19
             if platform.system() == 'Linux':
20
                 cmd = 'ffmpeg -ss 0.5 -i "' + media_instance + '" -vframes 1 -f image2pipe pipe:1 2> /dev/null'
20
                 cmd = 'ffmpeg -ss 0.5 -i "' + media_instance + '" -vframes 1 -f image2pipe pipe:1 2> /dev/null'

+ 4
- 1
metadata.py View File

193
             p = value.find(c)
193
             p = value.find(c)
194
             if p >= 0:
194
             if p >= 0:
195
                 value = value[:p]
195
                 value = value[:p]
196
-    return int(value)
196
+    try:
197
+        return int(value)
198
+    except ValueError:
199
+        return None
197
 
200
 
198
 
201
 
199
 def __num_denum_conv__(data):
202
 def __num_denum_conv__(data):

Loading…
Cancel
Save