Skip to content

Commit c2e107e

Browse files
committed
WIP: GeoPy tags
1 parent 8e4acaf commit c2e107e

File tree

9 files changed

+67
-11
lines changed

9 files changed

+67
-11
lines changed

.envrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export PYTHONPATH="$PWD:$PYTHONPATH"
2+
export PATH="$PWD/.venv/bin:$PATH"

.idea/tempren.iml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ repos:
1919
rev: '5.13.2'
2020
hooks:
2121
- id: isort
22-
language_version: python3.8
22+
language_version: python3.11
2323
additional_dependencies:
2424
- toml
2525
- repo: https://github.com/awebdeveloper/pre-commit-stylelint
@@ -31,4 +31,4 @@ repos:
3131
rev: '24.8.0'
3232
hooks:
3333
- id: black
34-
language_version: python3.8
34+
language_version: python3.11

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ pymediainfo = {version = "^6.0.1", optional = true}
3535
isodate = "^0.6.1"
3636
gpxpy = "1.5.0"
3737
Pint = "^0.21.0"
38+
geopy = "^2.4.1"
3839

39-
[tool.poetry.dev-dependencies]
40-
pytest = "^7.4.4"
40+
[tool.poetry.group.dev.dependencies]
41+
pytest = "^8.3.5"
4142
pytest-cov = "^4.1"
4243
coverage = "^7.2.7"
4344
pre-commit = "^3.5"

tempren/discovery.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ def _is_base_class(klass: type):
4040

4141
def _visitor(module: ModuleType, klass: type):
4242
if not _is_base_class(klass):
43+
log.debug(f"{klass} has no valid base ({base_klass})")
4344
return
45+
4446
if module.__package__:
4547
category_name = CategoryName(module.__name__[len(module.__package__) + 1 :])
4648
else:
4749
category_name = CategoryName(module.__name__)
4850

51+
log.debug(f"Adding {klass} to {category_name} category")
4952
found_classes[category_name].append(klass)
5053

5154
visit_types_in_package(package, _visitor)
@@ -80,4 +83,5 @@ def visit_types_in_module(
8083

8184
for _, tag_class in inspect.getmembers(module):
8285
if isinstance(tag_class, type):
86+
log.debug(f"Found tag {tag_class}")
8387
visitor(module, tag_class)

tempren/tags/core.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,3 +463,13 @@ def process(self, file: File, context: Optional[str]) -> float:
463463
src_value = float(context) * self._src_unit
464464
dst_value = src_value.to(self._dst_unit)
465465
return dst_value.magnitude
466+
467+
468+
class NotTag(Tag):
469+
"""Negate truthfulness of provided context"""
470+
471+
require_context = True
472+
473+
def process(self, file: File, context: Optional[str]) -> bool:
474+
assert context is not None
475+
return not bool(context)

tempren/tags/geopy.py

Whitespace-only changes.

tempren/tags/image.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,20 @@ def process(self, file: File, context: Optional[str]) -> Any:
148148
exif_dict = piexif.load(str(file.absolute_path))
149149
for src in exif_dict.values():
150150
if isinstance(src, dict) and self.tag_id in src:
151-
return self._extract_value(src[self.tag_id])
151+
return self._extract_value(self.tag_type, src[self.tag_id])
152152
else:
153153
raise MissingMetadataError()
154154

155-
def _extract_value(self, tag_value):
156-
if self.tag_type in (TAG_TYPES.Rational, TAG_TYPES.SRational):
157-
return round(tag_value[0] / tag_value[1], 1)
158-
if self.tag_type == TAG_TYPES.Ascii:
155+
def _extract_value(self, tag_type, tag_value):
156+
if tag_type in (TAG_TYPES.Rational, TAG_TYPES.SRational):
157+
if isinstance(tag_value[0], tuple):
158+
return " ".join(str(self._extract_value(v)) for v in tag_value)
159+
else:
160+
if tag_value[1] == 1:
161+
return tag_value[0]
162+
else:
163+
return round(tag_value[0] / tag_value[1], 1)
164+
if tag_type == TAG_TYPES.Ascii:
159165
return tag_value.decode("ascii")
160166
return tag_value
161167

@@ -187,3 +193,16 @@ def _generate_exif_tag_list() -> Iterator[str]:
187193

188194
class ResolutionTagAlias(TagAlias):
189195
"""%Image.Width()x%Image.Height()"""
196+
197+
198+
class GpsPositionTag(ExifTag):
199+
"""Latitude and longitude of place where photo was taken"""
200+
201+
def configure(self):
202+
self.latitude_tag_id, self.latitude_tag_type = self._tag_name_to_id_type(
203+
"GpsLatitude"
204+
)
205+
206+
207+
class HasGpsPositionTagAlias(TagAlias):
208+
"""%Core.Not(){%Text.IsEmpty(){%Image.GpsPosition()}}"""

tempren/tags/text.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,26 @@ def configure(self, separator: str = " "): # type: ignore
209209
assert separator
210210
self.separator = separator
211211

212-
def process(self, file: File, context: Optional[str]) -> Any:
212+
def process(self, file: File, context: Optional[str]) -> str:
213213
assert context is not None
214214
return self._pattern.sub("".join((r"\1", self.separator, r"\2")), context)
215+
216+
217+
class IsEmptyTag(Tag):
218+
"""Check if passed context is empty"""
219+
220+
require_context = True
221+
222+
def process(self, file: File, context: Optional[str]) -> bool:
223+
assert context is not None
224+
return len(str(context)) == 0
225+
226+
227+
class LengthTag(Tag):
228+
"""Number of characters in provided context"""
229+
230+
require_context = True
231+
232+
def process(self, file: File, context: Optional[str]) -> int:
233+
assert context is not None
234+
return len(str(context))

0 commit comments

Comments
 (0)