174 lines
4.8 KiB
Python
174 lines
4.8 KiB
Python
#!/usr/bin/env python3.6
|
|
# -*- coding: utf-8 -*-
|
|
# @Author: KevinMidboe
|
|
# @Date: 2017-11-01 15:57:23
|
|
# @Last Modified by: KevinMidboe
|
|
# @Last Modified time: 2017-12-22 12:07:18
|
|
|
|
import re
|
|
import os
|
|
import shutil
|
|
import logging
|
|
import colored
|
|
import configparser
|
|
|
|
from datetime import datetime
|
|
from colored import stylize
|
|
|
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
SYMBOLS = {
|
|
'customary' : ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'),
|
|
'customary_ext' : ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa',
|
|
'zetta', 'iotta'),
|
|
'iec' : ('BiB', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'),
|
|
'iec_ext' : ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi',
|
|
'zebi', 'yobi'),
|
|
}
|
|
|
|
__all__ = ('ColorizeFilter', )
|
|
logger = logging.getLogger('torrentSearch')
|
|
|
|
def getConfig():
|
|
"""
|
|
Read path and get configuartion file with site settings
|
|
:return: config settings read from 'config.ini'
|
|
:rtype: configparser.ConfigParser
|
|
"""
|
|
config = configparser.ConfigParser()
|
|
user_config_dir = os.path.expanduser("~") + "/.config/torrentSearch"
|
|
|
|
config_dir = os.path.join(user_config_dir, 'config.ini')
|
|
if not os.path.isfile(config_dir):
|
|
defaultConfig = os.path.join(BASE_DIR, 'default_config.ini')
|
|
logger.error('Missing config! Moved default_config.ini to {}.\nOpen this file and set all varaibles!'.format(config_dir))
|
|
os.makedirs(user_config_dir, exist_ok=True)
|
|
shutil.copyfile(defaultConfig, config_dir)
|
|
|
|
config.read(config_dir)
|
|
return config
|
|
|
|
class ColorizeFilter(logging.Filter):
|
|
"""
|
|
Class for setting specific colors to levels of severity for log output
|
|
"""
|
|
|
|
color_by_level = {
|
|
logging.DEBUG: 'yellow',
|
|
logging.WARNING: 'red',
|
|
logging.ERROR: 'red',
|
|
logging.INFO: 'white'
|
|
}
|
|
|
|
def filter(self, record):
|
|
record.raw_msg = record.msg
|
|
color = self.color_by_level.get(record.levelno)
|
|
if color:
|
|
record.msg = stylize(record.msg, colored.fg(color))
|
|
return True
|
|
|
|
def sanitize(string, ignore_characters=None, replace_characters=None):
|
|
"""
|
|
Sanitize a string to strip special characters.
|
|
|
|
:param str string: the string to sanitize.
|
|
:param set ignore_characters: characters to ignore.
|
|
:return: the sanitized string.
|
|
:rtype: str
|
|
|
|
"""
|
|
# only deal with strings
|
|
if string is None:
|
|
return
|
|
|
|
replace_characters = replace_characters or ''
|
|
|
|
ignore_characters = ignore_characters or set()
|
|
|
|
characters = ignore_characters
|
|
if characters:
|
|
string = re.sub(r'[%s]' % re.escape(''.join(characters)), replace_characters, string)
|
|
|
|
return string
|
|
|
|
def return_re_match(string, re_statement):
|
|
"""
|
|
Helper function for checking if a string contains a given regex statement
|
|
|
|
:param str string, str re_statement: string we want to check and regex string we
|
|
check for in string
|
|
:return: sanitized string of the match we found
|
|
:rtype: str
|
|
"""
|
|
if string is None:
|
|
return
|
|
|
|
m = re.search(re_statement, string)
|
|
# This is here for a edge case for piratebay torrent dates
|
|
if 'Y-day' in m.group():
|
|
return datetime.now().strftime('%m-%d %Y')
|
|
return sanitize(m.group(), '\xa0', ' ')
|
|
|
|
def representsInteger(str):
|
|
"""
|
|
Checks if a string only contains integers
|
|
|
|
:param str str: string we want to check only has integers
|
|
:return: if string only contains integers
|
|
:rtype: boolean
|
|
"""
|
|
try:
|
|
int(str)
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
|
|
def deHumansize(s):
|
|
"""
|
|
Attempts to guess the string format based on default symbols
|
|
set and return the corresponding bytes as an integer.
|
|
When unable to recognize the format ValueError is raised.
|
|
|
|
:param str s: human file size that we want to convert
|
|
:return: the guessed bytes in from the human file size
|
|
:rtype: int
|
|
"""
|
|
|
|
init = s
|
|
num = ""
|
|
while s and s[0:1].isdigit() or s[0:1] == '.':
|
|
num += s[0]
|
|
s = s[1:]
|
|
num = float(num)
|
|
letter = s.strip()
|
|
for name, sset in SYMBOLS.items():
|
|
if letter in sset:
|
|
break
|
|
else:
|
|
if letter == 'k':
|
|
# treat 'k' as an alias for 'K' as per: http://goo.gl/kTQMs
|
|
sset = SYMBOLS['customary']
|
|
letter = letter.upper()
|
|
else:
|
|
raise ValueError("can't interpret %r" % init)
|
|
prefix = {sset[0]:1}
|
|
for i, s in enumerate(sset[1:]):
|
|
prefix[s] = 1 << (i+1)*10
|
|
return int(num * prefix[letter])
|
|
|
|
def humansize(nbytes):
|
|
"""
|
|
Translates a size in bytes to a human readable size format
|
|
|
|
:param int nbytes: integer of size of torrent file
|
|
:return: size in bytes in a human readable format
|
|
:rtype: str
|
|
"""
|
|
suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
|
|
i = 0
|
|
while nbytes >= 1024 and i < len(suffixes)-1:
|
|
nbytes /= 1024.
|
|
i += 1
|
|
f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
|
|
return '{} {}'.format(f, suffixes[i])
|
|
|