Skip to content

Commit

Permalink
support for qbittorrent v5.0 (#2001)
Browse files Browse the repository at this point in the history
* support for qbittorrent v5.0

* Remove py3.8 tests

* Add py 3.13 tests

* Update mediafile.py for Py3.13

* Create filetype.py

* Update link for NZBGet
  • Loading branch information
clinton-hall committed Nov 7, 2024
1 parent 470f611 commit bfbf1fb
Show file tree
Hide file tree
Showing 21 changed files with 2,827 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ nzbToMedia
==========

Provides an [efficient](https://github.com/clinton-hall/nzbToMedia/wiki/Efficient-on-demand-post-processing) way to handle postprocessing for [CouchPotatoServer](https://couchpota.to/ "CouchPotatoServer") and [SickBeard](http://sickbeard.com/ "SickBeard") (and its [forks](https://github.com/clinton-hall/nzbToMedia/wiki/Failed-Download-Handling-%28FDH%29#sick-beard-and-its-forks))
when using one of the popular NZB download clients like [SABnzbd](http://sabnzbd.org/ "SABnzbd") and [NZBGet](http://nzbget.sourceforge.net/ "NZBGet") on low performance systems like a NAS.
when using one of the popular NZB download clients like [SABnzbd](http://sabnzbd.org/ "SABnzbd") and [NZBGet](https://nzbget.com/ "NZBGet") on low performance systems like a NAS.
This script is based on sabToSickBeard (written by Nic Wolfe and supplied with SickBeard), with the support for NZBGet being added by [thorli](https://github.com/thorli "thorli") and further contributions by [schumi2004](https://github.com/schumi2004 "schumi2004") and [hugbug](https://sourceforge.net/apps/phpbb/nzbget/memberlist.php?mode=viewprofile&u=67 "hugbug").
Torrent suport added by [jkaberg](https://github.com/jkaberg "jkaberg") and [berkona](https://github.com/berkona "berkona")
Corrupt video checking, auto SickBeard fork determination and a whole lot of code improvement was done by [echel0n](https://github.com/echel0n "echel0n")
Expand Down
4 changes: 2 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ jobs:
vmImage: 'Ubuntu-latest'
strategy:
matrix:
Python38:
python.version: '3.8'
Python39:
python.version: '3.9'
Python310:
Expand All @@ -23,6 +21,8 @@ jobs:
python.version: '3.11'
Python312:
python.version: '3.12'
Python313:
python.version: '3.13'
maxParallel: 3

steps:
Expand Down
10 changes: 10 additions & 0 deletions libs/common/filetype/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import

from .filetype import * # noqa
from .helpers import * # noqa
from .match import * # noqa

# Current package semver version
__version__ = version = '1.2.0'
41 changes: 41 additions & 0 deletions libs/common/filetype/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import glob
from itertools import chain
from os.path import isfile

import filetype


def guess(path):
kind = filetype.guess(path)
if kind is None:
print('{}: File type determination failure.'.format(path))
else:
print('{}: {} ({})'.format(path, kind.extension, kind.mime))


def main():
import argparse

parser = argparse.ArgumentParser(
prog='filetype', description='Determine type of FILEs.'
)
parser.add_argument(
'file', nargs='+',
help='files, wildcard is supported'
)
parser.add_argument(
'-v', '--version', action='version',
version=f'%(prog)s {filetype.version}',
help='output version information and exit'
)

args = parser.parse_args()
items = chain.from_iterable(map(glob.iglob, args.file))
files = filter(isfile, items)

for file in files:
guess(file)


if __name__ == '__main__':
main()
98 changes: 98 additions & 0 deletions libs/common/filetype/filetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import

from .match import match
from .types import TYPES, Type

# Expose supported matchers types
types = TYPES


def guess(obj):
"""
Infers the type of the given input.
Function is overloaded to accept multiple types in input
and perform the needed type inference based on it.
Args:
obj: path to file, bytes or bytearray.
Returns:
The matched type instance. Otherwise None.
Raises:
TypeError: if obj is not a supported type.
"""
return match(obj) if obj else None


def guess_mime(obj):
"""
Infers the file type of the given input
and returns its MIME type.
Args:
obj: path to file, bytes or bytearray.
Returns:
The matched MIME type as string. Otherwise None.
Raises:
TypeError: if obj is not a supported type.
"""
kind = guess(obj)
return kind.mime if kind else kind


def guess_extension(obj):
"""
Infers the file type of the given input
and returns its RFC file extension.
Args:
obj: path to file, bytes or bytearray.
Returns:
The matched file extension as string. Otherwise None.
Raises:
TypeError: if obj is not a supported type.
"""
kind = guess(obj)
return kind.extension if kind else kind


def get_type(mime=None, ext=None):
"""
Returns the file type instance searching by
MIME type or file extension.
Args:
ext: file extension string. E.g: jpg, png, mp4, mp3
mime: MIME string. E.g: image/jpeg, video/mpeg
Returns:
The matched file type instance. Otherwise None.
"""
for kind in types:
if kind.extension == ext or kind.mime == mime:
return kind
return None


def add_type(instance):
"""
Adds a new type matcher instance to the supported types.
Args:
instance: Type inherited instance.
Returns:
None
"""
if not isinstance(instance, Type):
raise TypeError('instance must inherit from filetype.types.Type')

types.insert(0, instance)
140 changes: 140 additions & 0 deletions libs/common/filetype/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from .types import TYPES
from .match import (
image_match, font_match, document_match,
video_match, audio_match, archive_match
)


def is_extension_supported(ext):
"""
Checks if the given extension string is
one of the supported by the file matchers.
Args:
ext (str): file extension string. E.g: jpg, png, mp4, mp3
Returns:
True if the file extension is supported.
Otherwise False.
"""
for kind in TYPES:
if kind.extension == ext:
return True
return False


def is_mime_supported(mime):
"""
Checks if the given MIME type string is
one of the supported by the file matchers.
Args:
mime (str): MIME string. E.g: image/jpeg, video/mpeg
Returns:
True if the MIME type is supported.
Otherwise False.
"""
for kind in TYPES:
if kind.mime == mime:
return True
return False


def is_image(obj):
"""
Checks if a given input is a supported type image.
Args:
obj: path to file, bytes or bytearray.
Returns:
True if obj is a valid image. Otherwise False.
Raises:
TypeError: if obj is not a supported type.
"""
return image_match(obj) is not None


def is_archive(obj):
"""
Checks if a given input is a supported type archive.
Args:
obj: path to file, bytes or bytearray.
Returns:
True if obj is a valid archive. Otherwise False.
Raises:
TypeError: if obj is not a supported type.
"""
return archive_match(obj) is not None


def is_audio(obj):
"""
Checks if a given input is a supported type audio.
Args:
obj: path to file, bytes or bytearray.
Returns:
True if obj is a valid audio. Otherwise False.
Raises:
TypeError: if obj is not a supported type.
"""
return audio_match(obj) is not None


def is_video(obj):
"""
Checks if a given input is a supported type video.
Args:
obj: path to file, bytes or bytearray.
Returns:
True if obj is a valid video. Otherwise False.
Raises:
TypeError: if obj is not a supported type.
"""
return video_match(obj) is not None


def is_font(obj):
"""
Checks if a given input is a supported type font.
Args:
obj: path to file, bytes or bytearray.
Returns:
True if obj is a valid font. Otherwise False.
Raises:
TypeError: if obj is not a supported type.
"""
return font_match(obj) is not None


def is_document(obj):
"""
Checks if a given input is a supported type document.
Args:
obj: path to file, bytes or bytearray.
Returns:
True if obj is a valid document. Otherwise False.
Raises:
TypeError: if obj is not a supported type.
"""
return document_match(obj) is not None
Loading

0 comments on commit bfbf1fb

Please sign in to comment.