REFACTOR: ITEM REVOLUTION #91
This commit is contained in:
158
media/file.py
158
media/file.py
@ -0,0 +1,158 @@
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from io import BytesIO
|
||||
import base64
|
||||
import hashlib
|
||||
import mutagen
|
||||
from PIL import Image
|
||||
import json
|
||||
|
||||
import util
|
||||
import variables as var
|
||||
from media.item import BaseItem
|
||||
import constants
|
||||
|
||||
'''
|
||||
type : file
|
||||
id
|
||||
path
|
||||
title
|
||||
artist
|
||||
duration
|
||||
thumbnail
|
||||
user
|
||||
'''
|
||||
|
||||
class FileItem(BaseItem):
|
||||
def __init__(self, bot, path, from_dict=None):
|
||||
if not from_dict:
|
||||
super().__init__(bot)
|
||||
self.path = path
|
||||
self.title = ""
|
||||
self.artist = "??"
|
||||
self.thumbnail = None
|
||||
if self.path:
|
||||
self.id = hashlib.md5(path.encode()).hexdigest()
|
||||
if os.path.exists(self.uri()):
|
||||
self._get_info_from_tag()
|
||||
self.ready = "yes"
|
||||
else:
|
||||
super().__init__(bot, from_dict)
|
||||
self.path = from_dict['path']
|
||||
self.title = from_dict['title']
|
||||
self.artist = from_dict['artist']
|
||||
self.thumbnail = from_dict['thumbnail']
|
||||
if not self.validate():
|
||||
self.ready = "failed"
|
||||
|
||||
self.type = "file"
|
||||
|
||||
def uri(self):
|
||||
return var.music_folder + self.path
|
||||
|
||||
def is_ready(self):
|
||||
return True
|
||||
|
||||
def validate(self):
|
||||
if not os.path.exists(self.uri()):
|
||||
self.log.info(
|
||||
"file: music file missed for %s" % self.format_debug_string())
|
||||
self.send_client_message(constants.strings('file_missed', file=self.path))
|
||||
return False
|
||||
|
||||
self.ready = "yes"
|
||||
return True
|
||||
|
||||
def _get_info_from_tag(self):
|
||||
match = re.search("(.+)\.(.+)", self.uri())
|
||||
assert match is not None
|
||||
|
||||
file_no_ext = match[1]
|
||||
ext = match[2]
|
||||
|
||||
try:
|
||||
im = None
|
||||
path_thumbnail = file_no_ext + ".jpg"
|
||||
if os.path.isfile(path_thumbnail):
|
||||
im = Image.open(path_thumbnail)
|
||||
|
||||
if ext == "mp3":
|
||||
# title: TIT2
|
||||
# artist: TPE1, TPE2
|
||||
# album: TALB
|
||||
# cover artwork: APIC:
|
||||
tags = mutagen.File(self.uri())
|
||||
if 'TIT2' in tags:
|
||||
self.title = tags['TIT2'].text[0]
|
||||
if 'TPE1' in tags: # artist
|
||||
self.artist = tags['TPE1'].text[0]
|
||||
|
||||
if im is None:
|
||||
if "APIC:" in tags:
|
||||
im = Image.open(BytesIO(tags["APIC:"].data))
|
||||
|
||||
elif ext == "m4a" or ext == "m4b" or ext == "mp4" or ext == "m4p":
|
||||
# title: ©nam (\xa9nam)
|
||||
# artist: ©ART
|
||||
# album: ©alb
|
||||
# cover artwork: covr
|
||||
tags = mutagen.File(self.uri())
|
||||
if '©nam' in tags:
|
||||
self.title = tags['©nam'][0]
|
||||
if '©ART' in tags: # artist
|
||||
self.artist = tags['©ART'][0]
|
||||
|
||||
if im is None:
|
||||
if "covr" in tags:
|
||||
im = Image.open(BytesIO(tags["covr"][0]))
|
||||
|
||||
if im:
|
||||
self.thumbnail = self._prepare_thumbnail(im)
|
||||
except:
|
||||
pass
|
||||
|
||||
if not self.title:
|
||||
self.title = os.path.basename(file_no_ext)
|
||||
|
||||
def _prepare_thumbnail(self, im):
|
||||
im.thumbnail((100, 100), Image.ANTIALIAS)
|
||||
buffer = BytesIO()
|
||||
im = im.convert('RGB')
|
||||
im.save(buffer, format="JPEG")
|
||||
return base64.b64encode(buffer.getvalue()).decode('utf-8')
|
||||
|
||||
def to_dict(self):
|
||||
dict = super().to_dict()
|
||||
dict['type'] = 'file'
|
||||
dict['path'] = self.path
|
||||
dict['title'] = self.title
|
||||
dict['artist'] = self.artist
|
||||
dict['thumbnail'] = self.thumbnail
|
||||
return dict
|
||||
|
||||
def format_debug_string(self):
|
||||
return "[file] {artist} - {title} ({path})".format(
|
||||
title=self.title,
|
||||
artist=self.artist,
|
||||
path=self.path
|
||||
)
|
||||
|
||||
def format_song_string(self, user):
|
||||
return constants.strings("file_item",
|
||||
title=self.title,
|
||||
artist=self.artist,
|
||||
user=user
|
||||
)
|
||||
|
||||
def format_current_playing(self, user):
|
||||
display = constants.strings("now_playing", item=self.format_song_string(user))
|
||||
if self.thumbnail:
|
||||
thumbnail_html = '<img width="80" src="data:image/jpge;base64,' + \
|
||||
self.thumbnail + '"/>'
|
||||
display += "<br />" + thumbnail_html
|
||||
|
||||
return display
|
||||
|
||||
def display_type(self):
|
||||
return constants.strings("file")
|
||||
|
Reference in New Issue
Block a user