Use upstream pymediainfo

Current pymediainfo versions load a DLL/so. Use a very thin
wrapper to make sure that the executable is used if the DLL
is not available.
This commit is contained in:
Bastian Germann 2018-10-07 02:24:29 +02:00
parent 4784cdf152
commit d1e1975394
3 changed files with 29 additions and 123 deletions

View File

@ -1,135 +1,39 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
# The MIT License ###############################################################################
# # OpenLP - Open Source Lyrics Projection #
# Copyright (c) 2010-2014, Patrick Altman <paltman@gmail.com> # --------------------------------------------------------------------------- #
# Copyright (c) 2016-2018, OpenLP Developers # Copyright (c) 2008-2018 OpenLP Developers #
# # --------------------------------------------------------------------------- #
# Permission is hereby granted, free of charge, to any person obtaining a copy # This program is free software; you can redistribute it and/or modify it #
# of this software and associated documentation files (the "Software"), to deal # under the terms of the GNU General Public License as published by the Free #
# in the Software without restriction, including without limitation the rights # Software Foundation; version 2 of the License. #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # #
# copies of the Software, and to permit persons to whom the Software is # This program is distributed in the hope that it will be useful, but WITHOUT #
# furnished to do so, subject to the following conditions: # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# The above copyright notice and this permission notice shall be included in # more details. #
# all copies or substantial portions of the Software. # #
# # You should have received a copy of the GNU General Public License along #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ###############################################################################
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# http://www.opensource.org/licenses/mit-license.php
""" """
The :mod:`~openlp.core.ui.media.mediainfo` module contains code to run mediainfo The :mod:`~openlp.core.ui.media.mediainfo` module contains code to run mediainfo
on a media file and obtain information related to the requested media. on a media file and obtain information related to the requested media.
""" """
import json from pymediainfo import MediaInfo
import os
from subprocess import check_output from subprocess import check_output
from bs4 import BeautifulSoup, NavigableString
ENV_DICT = os.environ
class Track(object):
def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except:
pass
return None
def __init__(self, xml_dom_fragment):
self.xml_dom_fragment = xml_dom_fragment
self.track_type = xml_dom_fragment.attrs['type']
for el in self.xml_dom_fragment.children:
if not isinstance(el, NavigableString):
node_name = el.name.lower().strip().strip('_')
if node_name == 'id':
node_name = 'track_id'
node_value = el.string
other_node_name = "other_%s" % node_name
if getattr(self, node_name) is None:
setattr(self, node_name, node_value)
else:
if getattr(self, other_node_name) is None:
setattr(self, other_node_name, [node_value, ])
else:
getattr(self, other_node_name).append(node_value)
for o in [d for d in self.__dict__.keys() if d.startswith('other_')]:
try:
primary = o.replace('other_', '')
setattr(self, primary, int(getattr(self, primary)))
except:
for v in getattr(self, o):
try:
current = getattr(self, primary)
setattr(self, primary, int(v))
getattr(self, o).append(current)
break
except:
pass
def __repr__(self):
return "<Track track_id='{0}', track_type='{1}'>".format(self.track_id, self.track_type)
def to_data(self):
data = {}
for k, v in self.__dict__.items():
if k != 'xml_dom_fragment':
data[k] = v
return data
class MediaInfoWrapper(object): class MediaInfoWrapper(object):
def __init__(self, xml):
self.xml_dom = xml
xml_types = (str,) # no unicode type in python3
if isinstance(xml, xml_types):
self.xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml)
@staticmethod @staticmethod
def parse_xml_data_into_dom(xml_data): def parse(filename):
return BeautifulSoup(xml_data, "xml") if MediaInfo.can_parse():
return MediaInfo.parse(filename)
@staticmethod else:
def parse(filename, environment=ENV_DICT):
xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', filename]) xml = check_output(['mediainfo', '-f', '--Output=XML', '--Inform=OLDXML', filename])
if not xml.startswith(b'<?xml'): if not xml.startswith(b'<?xml'):
xml = check_output(['mediainfo', '-f', '--Output=XML', filename]) xml = check_output(['mediainfo', '-f', '--Output=XML', filename])
xml_dom = MediaInfoWrapper.parse_xml_data_into_dom(xml) return MediaInfo(xml)
return MediaInfoWrapper(xml_dom)
def _populate_tracks(self):
if self.xml_dom is None:
return
for xml_track in self.xml_dom.Mediainfo.File.find_all("track"):
self._tracks.append(Track(xml_track))
@property
def tracks(self):
if not hasattr(self, "_tracks"):
self._tracks = []
if len(self._tracks) == 0:
self._populate_tracks()
return self._tracks
def to_data(self):
data = {'tracks': []}
for track in self.tracks:
data['tracks'].append(track.to_data())
return data
def to_json(self):
return json.dumps(self.to_data())

View File

@ -78,6 +78,7 @@ MODULES = [
'PyQt5.QtTest', 'PyQt5.QtTest',
'PyQt5.QtWebKit', 'PyQt5.QtWebKit',
'PyQt5.QtMultimedia', 'PyQt5.QtMultimedia',
'pymediainfo',
'sqlalchemy', 'sqlalchemy',
'alembic', 'alembic',
'sqlite3', 'sqlite3',

View File

@ -117,6 +117,7 @@ requires = [
'chardet', 'chardet',
'lxml', 'lxml',
'Mako', 'Mako',
'pymediainfo >= 2.1.6',
'PyQt5', 'PyQt5',
'QtAwesome', 'QtAwesome',
'requests', 'requests',