Files
gommi/lib/framework/util.py
2022-04-21 19:23:01 +09:00

218 lines
6.6 KiB
Python

# -*- coding: utf-8 -*-
#########################################################
# python
import os
import json
import traceback
import platform
import subprocess
# third-party
from sqlalchemy.ext.declarative import DeclarativeMeta
# sjva 공용
from framework import app, logger
#########################################################
class Util(object):
@staticmethod
def sizeof_fmt(num, suffix="Bytes"):
"""
파일크기, 다운로드 속도 표시시 사용
"""
for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]:
if abs(num) < 1024.0:
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, "Y", suffix)
@staticmethod
def db_list_to_dict(db_list):
"""
세팅DB에서 사용, (key, value) dict로 변환
"""
ret = {}
for item in db_list:
ret[item.key] = item.value
return ret
@staticmethod
def db_to_dict(db_list):
ret = []
for item in db_list:
ret.append(item.as_dict())
return ret
@staticmethod
def get_paging_info(count, current_page, page_size):
try:
paging = {}
paging["prev_page"] = True
paging["next_page"] = True
if current_page <= 10:
paging["prev_page"] = False
paging["total_page"] = int(count / page_size) + 1
if count % page_size == 0:
paging["total_page"] -= 1
paging["start_page"] = int((current_page - 1) / 10) * 10 + 1
paging["last_page"] = (
paging["total_page"]
if paging["start_page"] + 9 > paging["total_page"]
else paging["start_page"] + 9
)
if paging["last_page"] == paging["total_page"]:
paging["next_page"] = False
paging["current_page"] = current_page
paging["count"] = count
logger.debug(
"paging : c:%s %s %s %s %s %s",
count,
paging["total_page"],
paging["prev_page"],
paging["next_page"],
paging["start_page"],
paging["last_page"],
)
return paging
except Exception as exception:
logger.debug("Exception:%s", exception)
logger.debug(traceback.format_exc())
@staticmethod
def get_list_except_empty(source):
tmp = []
for _ in source:
if _.strip().startswith("#"):
continue
if _.strip() != "":
tmp.append(_.strip())
return tmp
@staticmethod
def save_from_dict_to_json(d, filename):
from tool_base import ToolUtil
ToolUtil.save_dict(d, filename)
# list형태
@staticmethod
def execute_command(command):
from tool_base import ToolSubprocess
return ToolSubprocess.execute_command_return(command)
@staticmethod
def change_text_for_use_filename(text):
from tool_base import ToolBaseFile
return ToolBaseFile.text_for_filename(text)
# 토렌트 인포에서 최대 크기 파일과 폴더명을 리턴한다
@staticmethod
def get_max_size_fileinfo(torrent_info):
try:
ret = {}
max_size = -1
max_filename = None
for t in torrent_info["files"]:
if t["size"] > max_size:
max_size = t["size"]
max_filename = str(t["path"])
t = max_filename.split("/")
ret["filename"] = t[-1]
if len(t) == 1:
ret["dirname"] = ""
elif len(t) == 2:
ret["dirname"] = t[0]
else:
ret["dirname"] = max_filename.replace(
"/%s" % ret["filename"], ""
)
ret["max_size"] = max_size
return ret
except Exception as exception:
logger.error("Exception:%s", exception)
logger.error(traceback.format_exc())
# 압축할 폴더 경로를 인자로 받음. 폴더명.zip 생성
@staticmethod
def makezip(zip_path, zip_extension="zip"):
import zipfile
try:
if os.path.isdir(zip_path):
zipfilename = os.path.join(
os.path.dirname(zip_path),
"%s.%s" % (os.path.basename(zip_path), zip_extension),
)
fantasy_zip = zipfile.ZipFile(zipfilename, "w")
for f in os.listdir(zip_path):
# if f.endswith('.jpg') or f.endswith('.png'):
src = os.path.join(zip_path, f)
fantasy_zip.write(
src,
os.path.basename(src),
compress_type=zipfile.ZIP_DEFLATED,
)
fantasy_zip.close()
import shutil
shutil.rmtree(zip_path)
return True
except Exception as exception:
logger.error("Exception:%s", exception)
logger.error(traceback.format_exc())
return False
@staticmethod
def make_apikey(url):
from framework import SystemModelSetting
url = url.format(ddns=SystemModelSetting.get("ddns"))
if SystemModelSetting.get_bool("auth_use_apikey"):
if url.find("?") == -1:
url += "?"
else:
url += "&"
url += "apikey=%s" % SystemModelSetting.get("auth_apikey")
return url
class SingletonClass(object):
__instance = None
@classmethod
def __getInstance(cls):
return cls.__instance
@classmethod
def instance(cls, *args, **kargs):
cls.__instance = cls(*args, **kargs)
cls.instance = cls.__getInstance
return cls.__instance
class AlchemyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj.__class__, DeclarativeMeta):
# an SQLAlchemy class
fields = {}
for field in [
x for x in dir(obj) if not x.startswith("_") and x != "metadata"
]:
data = obj.__getattribute__(field)
try:
json.dumps(
data
) # this will fail on non-encodable values, like other classes
fields[field] = data
except TypeError:
fields[field] = None
# a json-encodable dict
return fields
return json.JSONEncoder.default(self, obj)