Skip to content

Commit

Permalink
Merge pull request #13 from sashacmc/structure-upgrade
Browse files Browse the repository at this point in the history
Structure upgrade and refactoring
  • Loading branch information
sashacmc authored Jul 8, 2024
2 parents 9cbf186 + b75bd8d commit a2f82fc
Show file tree
Hide file tree
Showing 16 changed files with 241 additions and 211 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/build-debian-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Build Debian Package

on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Build Debian package
run: |
sudo apt-get update
sudo apt-get install -y devscripts debhelper curl
# Ensure you have the necessary build dependencies
sudo apt-get build-dep .
# Build the Debian package
debuild -us -uc -b
- name: Create artifact directory
run: mkdir -p artifacts

- name: Move Debian package to artifact directory
run: mv ../*.deb artifacts/

- name: Test Debian package installation
run: |
sudo apt install -y pip python3-exif python3-progressbar exiftran python3-psutil
sudo pip install PyExifTool
sudo dpkg -i artifacts/*.deb
sudo systemctl enable photo-importer.service
sudo systemctl restart photo-importer.service
sudo systemctl status photo-importer.service
photo-importer -h
- name: Upload Debian package as artifact
uses: actions/upload-artifact@v2
with:
name: debian-package
path: artifacts/*.deb
24 changes: 24 additions & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Pylint

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
pip install .
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py') --disable missing-function-docstring,missing-module-docstring,missing-class-docstring,broad-exception-caught
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ sudo pip install photo-importer
#### Installing as debian package
```bash
debuild -b
sudo dpkg -i ../photo-importer_1.2.0_all.deb
sudo apt install pip python3-exif python3-progressbar exiftran python3-psutil
sudo pip install PyExifTool
sudo dpkg -i ../photo-importer_1.2.5_all.deb
```
#### Installing via setup.py
```bash
Expand Down
7 changes: 7 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
photo-importer (1.2.5) stable; urgency=medium

* Package refactoring
* Code cleanup

-- Alexander Bushnev <[email protected]> Tue, 09 Jul 2024 00:24:52 +0200

photo-importer (1.2.4) stable; urgency=medium

* Add time_shift options
Expand Down
2 changes: 1 addition & 1 deletion debian/compat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9
10
4 changes: 2 additions & 2 deletions photo_importer/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import configparser


class Config(object):
class Config:
DEFAULT_CONFIG_FILES = (
os.path.expanduser('~/.photo-importer.cfg'),
'/etc/photo-importer.cfg',
Expand Down Expand Up @@ -66,7 +66,7 @@ def __create_if_not_exists(self):
if os.path.exists(self.DEFAULT_CONFIG_FILES[0]):
return

with open(self.DEFAULT_CONFIG_FILES[0], 'w') as conffile:
with open(self.DEFAULT_CONFIG_FILES[0], 'w', encoding='utf-8') as conffile:
self.__config.write(conffile)

def __getitem__(self, sect):
Expand Down
73 changes: 34 additions & 39 deletions photo_importer/fileprop.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/usr/bin/python3
# pylint: disable=too-many-arguments

import os
import re
import stat
import time
import logging
import exiftool
import datetime
import exiftool


IGNORE = 0
Expand All @@ -16,7 +17,7 @@
GARBAGE = 4


class FileProp(object):
class FileProp:
DATE_REGEX = [
(
re.compile(r'\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}'),
Expand Down Expand Up @@ -59,8 +60,6 @@ class FileProp(object):
IGNORE: 'file_ext_ignore',
}

EXT_TO_TYPE = {}

DATE_TAGS = [
'EXIF:DateTimeOriginal',
'H264:DateTimeOriginal',
Expand All @@ -70,8 +69,8 @@ class FileProp(object):
'EXIF:CreateDate',
]

def __init__(self, config):
self.__config = config
def __init__(self, conf):
self.__config = conf
self.__prepare_ext_to_type()
self.__out_list = set()
self.__exiftool = exiftool.ExifToolHelper()
Expand All @@ -80,38 +79,38 @@ def __del__(self):
self.__exiftool.terminate()

def __prepare_ext_to_type(self):
self.EXT_TO_TYPE = {}
self.ext_to_type = {}
for tp, cfg in self.FILE_EXT_CFG.items():
for ext in self.__config['main'][cfg].split(','):
ext = '.' + ext.lower()
if ext in self.EXT_TO_TYPE:
logging.fatal('Double ext: ' + ext)
self.EXT_TO_TYPE[ext] = tp
if ext in self.ext_to_type:
logging.fatal('Double ext: %s', ext)
self.ext_to_type[ext] = tp

def __type_by_ext(self, ext):
try:
return self.EXT_TO_TYPE[ext]
return self.ext_to_type[ext]
except KeyError:
logging.warning('Unknown ext: ' + ext)
logging.warning('Unknown ext: %s', ext)
return IGNORE

def __time(self, fullname, name, tp):
if tp not in (IMAGE, VIDEO, AUDIO):
return None

for src in self.__config['main'][self.TIME_SRC_CFG[tp]].split(','):
time = None
ftime = None
if src == 'exif':
time = self.__time_by_exif(fullname)
ftime = self.__time_by_exif(fullname)
elif src == 'name':
time = self.__time_by_name(name)
ftime = self.__time_by_name(name)
elif src == 'attr':
time = self.__time_by_attr(fullname)
ftime = self.__time_by_attr(fullname)
else:
raise Exception('Wrong time_src: ' + src)
raise UserWarning(f'Wrong time_src: {src}')

if time:
return time
if ftime:
return ftime

return None

Expand All @@ -120,11 +119,11 @@ def __time_by_name(self, fname):
mat = exp.findall(fname)
if len(mat):
try:
time = datetime.datetime.strptime(mat[0], fs)
if time.year < 1990 or time.year > 2100:
ftime = datetime.datetime.strptime(mat[0], fs)
if ftime.year < 1990 or ftime.year > 2100:
continue

return time
return ftime
except ValueError:
pass
return None
Expand All @@ -140,34 +139,32 @@ def __time_by_exif(self, fullname):
md = md[0:pos]
return datetime.datetime.strptime(md, '%Y:%m:%d %H:%M:%S')

logging.warning(
'time by exif (%s) not found tags count: %s'
% (fullname, len(metadata))
)
logging.warning('time by exif (%s) not found tags count: %s', fullname, len(metadata))
for tag, val in metadata.items():
logging.debug('%s: %s' % (tag, val))
return None
logging.debug('%s: %s', tag, val)
except Exception as ex:
logging.warning('time by exif (%s) exception: %s' % (fullname, ex))
logging.warning('time by exif (%s) exception: %s', fullname, ex)
return None

def __time_by_attr(self, fullname):
try:
return datetime.datetime.fromtimestamp(
time.mktime(time.localtime(os.stat(fullname)[stat.ST_MTIME]))
)
except (FileNotFoundError, KeyError) as ex:
logging.warning('time by attr (%s) exception: %s' % (fullname, ex))
logging.warning('time by attr (%s) exception: %s', fullname, ex)
return None

def __calc_orig_name(self, fname):
if not int(self.__config['main']['add_orig_name']):
return ''
for exp, fs in self.DATE_REGEX:
for exp, _ in self.DATE_REGEX:
mat = exp.findall(fname)
if len(mat):
return ''
return '_' + self.SPACE_REGEX.sub('_', fname)

def _out_name_full(self, path, out_name, ext):
def out_name_full(self, path, out_name, ext):
res = os.path.join(path, out_name) + ext

i = 1
Expand Down Expand Up @@ -206,11 +203,11 @@ def get(self, fullname):
return FilePropRes(self, tp, ftime, path, ext, out_name, ok)


class FilePropRes(object):
def __init__(self, prop_ptr, tp, time, path, ext, out_name, ok):
class FilePropRes:
def __init__(self, prop_ptr, tp, ftime, path, ext, out_name, ok):
self.__prop_ptr = prop_ptr
self.__type = tp
self.__time = time
self.__time = ftime
self.__path = path
self.__ext = ext
self.__out_name = out_name
Expand Down Expand Up @@ -238,9 +235,7 @@ def out_name_full(self, path=None):
if path is None:
path = self.__path

return self.__prop_ptr._out_name_full(
path, self.__out_name, self.__ext
)
return self.__prop_ptr.out_name_full(path, self.__out_name, self.__ext)


if __name__ == '__main__':
Expand All @@ -251,7 +246,7 @@ def out_name_full(self, path=None):
from photo_importer import log
from photo_importer import config

log.initLogger(None, logging.DEBUG)
log.init_logger(None, logging.DEBUG)

fp = FileProp(config.Config()).get(sys.argv[1])
print(fp.type(), fp.time(), fp.ok())
5 changes: 3 additions & 2 deletions photo_importer/fileprop_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/usr/bin/python3
# pylint: disable=too-many-public-methods

import unittest
import datetime

from . import config
from . import fileprop
from photo_importer import config
from photo_importer import fileprop


class TestFileProp(unittest.TestCase):
Expand Down
Loading

0 comments on commit a2f82fc

Please sign in to comment.