Import track working
This commit is contained in:
parent
3b4cf5320d
commit
73e728177e
@ -5,9 +5,10 @@ from config import Config
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pydub import AudioSegment
|
from pydub import AudioSegment
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
# from tinytag import TinyTag
|
from tinytag import TinyTag # type: ignore
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
# from typing import Dict, Optional, Union
|
# from typing import Dict, Optional, Union
|
||||||
|
from typing import Dict, Union
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# def ask_yes_no(title: str, question: str) -> bool:
|
# def ask_yes_no(title: str, question: str) -> bool:
|
||||||
@ -74,21 +75,20 @@ def get_audio_segment(path: str) -> Optional[AudioSegment]:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
#
|
|
||||||
# def get_tags(path: str) -> Dict[str, Union[str, int]]:
|
def get_tags(path: str) -> Dict[str, Union[str, int]]:
|
||||||
# """
|
"""
|
||||||
# Return a dictionary of title, artist, duration-in-milliseconds and path.
|
Return a dictionary of title, artist, duration-in-milliseconds and path.
|
||||||
# """
|
"""
|
||||||
#
|
|
||||||
# tag: TinyTag = TinyTag.get(path)
|
tag = TinyTag.get(path)
|
||||||
#
|
|
||||||
# d = dict(
|
return dict(
|
||||||
# title=tag.title,
|
title=tag.title,
|
||||||
# artist=tag.artist,
|
artist=tag.artist,
|
||||||
# duration=int(round(tag.duration, Config.MILLISECOND_SIGFIGS) * 1000),
|
duration=int(round(tag.duration, Config.MILLISECOND_SIGFIGS) * 1000),
|
||||||
# path=path
|
path=path
|
||||||
# )
|
)
|
||||||
# return d
|
|
||||||
|
|
||||||
|
|
||||||
def get_relative_date(past_date: datetime, reference_date: datetime = None) \
|
def get_relative_date(past_date: datetime, reference_date: datetime = None) \
|
||||||
|
|||||||
107
app/models.py
107
app/models.py
@ -82,7 +82,8 @@ class NoteColours(Base):
|
|||||||
# session.flush()
|
# session.flush()
|
||||||
#
|
#
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_all(cls, session: Session) -> Optional[List["NoteColours"]]:
|
# def get_all(cls, session: Session) ->
|
||||||
|
# Optional[List["NoteColours"]]:
|
||||||
# """Return all records"""
|
# """Return all records"""
|
||||||
#
|
#
|
||||||
# return session.query(cls).all()
|
# return session.query(cls).all()
|
||||||
@ -286,7 +287,8 @@ class Playlists(Base):
|
|||||||
# def remove_track(self, session: Session, row: int) -> None:
|
# def remove_track(self, session: Session, row: int) -> None:
|
||||||
# log.debug(f"Playlist.remove_track({self.id=}, {row=})")
|
# log.debug(f"Playlist.remove_track({self.id=}, {row=})")
|
||||||
#
|
#
|
||||||
# # Refresh self first (this is necessary when calling remove_track
|
# # Refresh self first (this is necessary when calling
|
||||||
|
# remove_track
|
||||||
# # multiple times before session.commit())
|
# # multiple times before session.commit())
|
||||||
# session.refresh(self)
|
# session.refresh(self)
|
||||||
# # Get tracks collection for this playlist
|
# # Get tracks collection for this playlist
|
||||||
@ -508,7 +510,6 @@ class Tracks(Base):
|
|||||||
silence_at = Column(Integer, index=False)
|
silence_at = Column(Integer, index=False)
|
||||||
path = Column(String(2048), index=False, nullable=False)
|
path = Column(String(2048), index=False, nullable=False)
|
||||||
mtime = Column(Float, index=True)
|
mtime = Column(Float, index=True)
|
||||||
# lastplayed = Column(DateTime, index=True, default=None)
|
|
||||||
playlistrows = relationship("PlaylistRows", back_populates="track")
|
playlistrows = relationship("PlaylistRows", back_populates="track")
|
||||||
playlists = association_proxy("playlistrows", "playlist")
|
playlists = association_proxy("playlistrows", "playlist")
|
||||||
playdates = relationship("Playdates", back_populates="track")
|
playdates = relationship("Playdates", back_populates="track")
|
||||||
@ -519,31 +520,31 @@ class Tracks(Base):
|
|||||||
f"artist={self.artist}, path={self.path}>"
|
f"artist={self.artist}, path={self.path}>"
|
||||||
)
|
)
|
||||||
|
|
||||||
# def __init__(
|
def __init__(
|
||||||
# self,
|
self,
|
||||||
# session: Session,
|
session: Session,
|
||||||
# path: str,
|
path: str,
|
||||||
# title: Optional[str] = None,
|
title: Optional[str] = None,
|
||||||
# artist: Optional[str] = None,
|
artist: Optional[str] = None,
|
||||||
# duration: int = 0,
|
duration: int = 0,
|
||||||
# start_gap: int = 0,
|
start_gap: int = 0,
|
||||||
# fade_at: Optional[int] = None,
|
fade_at: Optional[int] = None,
|
||||||
# silence_at: Optional[int] = None,
|
silence_at: Optional[int] = None,
|
||||||
# mtime: Optional[float] = None,
|
mtime: Optional[float] = None,
|
||||||
# lastplayed: Optional[datetime] = None,
|
lastplayed: Optional[datetime] = None,
|
||||||
# ) -> None:
|
) -> None:
|
||||||
# self.path = path
|
self.path = path
|
||||||
# self.title = title
|
self.title = title
|
||||||
# self.artist = artist
|
self.artist = artist
|
||||||
# self.duration = duration
|
self.duration = duration
|
||||||
# self.start_gap = start_gap
|
self.start_gap = start_gap
|
||||||
# self.fade_at = fade_at
|
self.fade_at = fade_at
|
||||||
# self.silence_at = silence_at
|
self.silence_at = silence_at
|
||||||
# self.mtime = mtime
|
self.mtime = mtime
|
||||||
# self.lastplayed = lastplayed
|
self.lastplayed = lastplayed
|
||||||
#
|
|
||||||
# session.add(self)
|
session.add(self)
|
||||||
# session.flush()
|
session.commit()
|
||||||
#
|
#
|
||||||
# @staticmethod
|
# @staticmethod
|
||||||
# def get_all_paths(session) -> List[str]:
|
# def get_all_paths(session) -> List[str]:
|
||||||
@ -556,23 +557,21 @@ class Tracks(Base):
|
|||||||
# """Return a list of all tracks"""
|
# """Return a list of all tracks"""
|
||||||
#
|
#
|
||||||
# return session.query(cls).all()
|
# return session.query(cls).all()
|
||||||
#
|
|
||||||
# @classmethod
|
@classmethod
|
||||||
# def get_or_create(cls, session: Session, path: str) -> "Tracks":
|
def get_or_create(cls, session: Session, path: str) -> "Tracks":
|
||||||
# """
|
"""
|
||||||
# If a track with path exists, return it;
|
If a track with path exists, return it;
|
||||||
# else created new track and return it
|
else created new track and return it
|
||||||
# """
|
"""
|
||||||
#
|
|
||||||
# log.debug(f"Tracks.get_or_create({path=})")
|
try:
|
||||||
#
|
track = session.query(cls).filter(cls.path == path).one()
|
||||||
# try:
|
except NoResultFound:
|
||||||
# track = session.query(cls).filter(cls.path == path).one()
|
track = Tracks(session, path)
|
||||||
# except NoResultFound:
|
|
||||||
# track = Tracks(session, path)
|
return track
|
||||||
#
|
|
||||||
# return track
|
|
||||||
#
|
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_by_filename(cls, session: Session, filename: str) \
|
# def get_by_filename(cls, session: Session, filename: str) \
|
||||||
# -> Optional["Tracks"]:
|
# -> Optional["Tracks"]:
|
||||||
@ -591,22 +590,26 @@ class Tracks(Base):
|
|||||||
# return None
|
# return None
|
||||||
#
|
#
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_by_path(cls, session: Session, path: str) -> List["Tracks"]:
|
# def get_by_path(cls, session: Session, path: str) ->
|
||||||
|
# List["Tracks"]:
|
||||||
# """
|
# """
|
||||||
# Return track with passee path, or None.
|
# Return track with passee path, or None.
|
||||||
# """
|
# """
|
||||||
#
|
#
|
||||||
# log.debug(f"Tracks.get_track_from_path({path=})")
|
# log.debug(f"Tracks.get_track_from_path({path=})")
|
||||||
#
|
#
|
||||||
# return session.query(Tracks).filter(Tracks.path == path).first()
|
# return session.query(Tracks).filter(Tracks.path ==
|
||||||
|
# path).first()
|
||||||
#
|
#
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_by_id(cls, session: Session, track_id: int) -> Optional["Tracks"]:
|
# def get_by_id(cls, session: Session, track_id: int) ->
|
||||||
|
# Optional["Tracks"]:
|
||||||
# """Return track or None"""
|
# """Return track or None"""
|
||||||
#
|
#
|
||||||
# try:
|
# try:
|
||||||
# log.debug(f"Tracks.get_track(track_id={track_id})")
|
# log.debug(f"Tracks.get_track(track_id={track_id})")
|
||||||
# track = session.query(Tracks).filter(Tracks.id == track_id).one()
|
# track = session.query(Tracks).filter(Tracks.id ==
|
||||||
|
# track_id).one()
|
||||||
# return track
|
# return track
|
||||||
# except NoResultFound:
|
# except NoResultFound:
|
||||||
# log.error(f"get_track({track_id}): not found")
|
# log.error(f"get_track({track_id}): not found")
|
||||||
@ -635,10 +638,12 @@ class Tracks(Base):
|
|||||||
# log.debug(f"Tracks.remove_path({path=})")
|
# log.debug(f"Tracks.remove_path({path=})")
|
||||||
#
|
#
|
||||||
# try:
|
# try:
|
||||||
# session.query(Tracks).filter(Tracks.path == path).delete()
|
# session.query(Tracks).filter(Tracks.path ==
|
||||||
|
# path).delete()
|
||||||
# session.flush()
|
# session.flush()
|
||||||
# except IntegrityError as exception:
|
# except IntegrityError as exception:
|
||||||
# log.error(f"Can't remove track with {path=} ({exception=})")
|
# log.error(f"Can't remove track with {path=}
|
||||||
|
# ({exception=})")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search_artists(cls, session: Session, text: str) -> List["Tracks"]:
|
def search_artists(cls, session: Session, text: str) -> List["Tracks"]:
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
from log import log
|
from log import log
|
||||||
# import argparse
|
# import argparse
|
||||||
import sys
|
import sys
|
||||||
# import threading
|
import threading
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
# from typing import Callable, Dict, List, Optional, Tuple
|
# from typing import Callable, Dict, List, Optional, Tuple
|
||||||
@ -20,13 +20,13 @@ from PyQt5.QtWidgets import (
|
|||||||
QLineEdit,
|
QLineEdit,
|
||||||
QListWidgetItem,
|
QListWidgetItem,
|
||||||
QMainWindow,
|
QMainWindow,
|
||||||
# QMessageBox,
|
QMessageBox,
|
||||||
)
|
)
|
||||||
#
|
|
||||||
from dbconfig import engine, Session
|
from dbconfig import engine, Session
|
||||||
import helpers
|
import helpers
|
||||||
import music
|
import music
|
||||||
#
|
|
||||||
from models import (
|
from models import (
|
||||||
Base,
|
Base,
|
||||||
Playdates,
|
Playdates,
|
||||||
@ -42,7 +42,7 @@ from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist # type: ignore
|
|||||||
from ui.downloadcsv_ui import Ui_DateSelect # type: ignore
|
from ui.downloadcsv_ui import Ui_DateSelect # type: ignore
|
||||||
from config import Config
|
from config import Config
|
||||||
from ui.main_window_ui import Ui_MainWindow # type: ignore
|
from ui.main_window_ui import Ui_MainWindow # type: ignore
|
||||||
# from utilities import create_track_from_file, update_db
|
from utilities import create_track_from_file # , update_db
|
||||||
|
|
||||||
|
|
||||||
class TrackData:
|
class TrackData:
|
||||||
@ -164,7 +164,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
lambda: self.tabPlaylist.currentWidget().search_next())
|
lambda: self.tabPlaylist.currentWidget().search_next())
|
||||||
self.actionFind_previous.triggered.connect(
|
self.actionFind_previous.triggered.connect(
|
||||||
lambda: self.tabPlaylist.currentWidget().search_previous())
|
lambda: self.tabPlaylist.currentWidget().search_previous())
|
||||||
# self.actionImport.triggered.connect(self.import_track)
|
self.actionImport.triggered.connect(self.import_track)
|
||||||
self.actionInsertSectionHeader.triggered.connect(self.insert_header)
|
self.actionInsertSectionHeader.triggered.connect(self.insert_header)
|
||||||
self.actionInsertTrack.triggered.connect(self.insert_track)
|
self.actionInsertTrack.triggered.connect(self.insert_track)
|
||||||
self.actionMoveSelected.triggered.connect(self.move_selected)
|
self.actionMoveSelected.triggered.connect(self.move_selected)
|
||||||
@ -173,7 +173,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
self.actionPlay_next.triggered.connect(self.play_next)
|
self.actionPlay_next.triggered.connect(self.play_next)
|
||||||
self.actionSearch.triggered.connect(self.search_playlist)
|
self.actionSearch.triggered.connect(self.search_playlist)
|
||||||
self.actionSelect_next_track.triggered.connect(self.select_next_row)
|
self.actionSelect_next_track.triggered.connect(self.select_next_row)
|
||||||
# self.actionSelect_played_tracks.triggered.connect(self.select_played)
|
|
||||||
self.actionSelect_previous_track.triggered.connect(
|
self.actionSelect_previous_track.triggered.connect(
|
||||||
self.select_previous_row)
|
self.select_previous_row)
|
||||||
self.actionMoveUnplayed.triggered.connect(self.move_unplayed)
|
self.actionMoveUnplayed.triggered.connect(self.move_unplayed)
|
||||||
@ -419,63 +418,60 @@ class Window(QMainWindow, Ui_MainWindow):
|
|||||||
with Session() as session:
|
with Session() as session:
|
||||||
for i in range(self.tabPlaylist.count()):
|
for i in range(self.tabPlaylist.count()):
|
||||||
self.tabPlaylist.widget(i).update_display(session)
|
self.tabPlaylist.widget(i).update_display(session)
|
||||||
#
|
|
||||||
# def import_track(self) -> None:
|
def import_track(self) -> None:
|
||||||
# """Import track file"""
|
"""Import track file"""
|
||||||
#
|
|
||||||
# dlg = QFileDialog()
|
dlg = QFileDialog()
|
||||||
# dlg.setFileMode(QFileDialog.ExistingFiles)
|
dlg.setFileMode(QFileDialog.ExistingFiles)
|
||||||
# dlg.setViewMode(QFileDialog.Detail)
|
dlg.setViewMode(QFileDialog.Detail)
|
||||||
# dlg.setDirectory(Config.IMPORT_DESTINATION)
|
dlg.setDirectory(Config.IMPORT_DESTINATION)
|
||||||
# dlg.setNameFilter("Music files (*.flac *.mp3)")
|
dlg.setNameFilter("Music files (*.flac *.mp3)")
|
||||||
#
|
|
||||||
# if dlg.exec_():
|
if not dlg.exec_():
|
||||||
# with Session() as session:
|
return
|
||||||
# txt: str = ""
|
|
||||||
# new_tracks = []
|
with Session() as session:
|
||||||
# for fname in dlg.selectedFiles():
|
txt = ""
|
||||||
# tags = helpers.get_tags(fname)
|
new_tracks = []
|
||||||
# new_tracks.append((fname, tags))
|
for fname in dlg.selectedFiles():
|
||||||
# title = tags['title']
|
tags = helpers.get_tags(fname)
|
||||||
# artist = tags['artist']
|
new_tracks.append((fname, tags))
|
||||||
# possible_matches = Tracks.search_titles(session, title)
|
title = tags['title']
|
||||||
# if possible_matches:
|
artist = tags['artist']
|
||||||
# txt += 'Similar to new track '
|
possible_matches = Tracks.search_titles(session, title)
|
||||||
# txt += f'"{title}" by "{artist} ({fname})":\n\n'
|
if possible_matches:
|
||||||
# for track in possible_matches:
|
txt += 'Similar to new track '
|
||||||
# txt += f' "{track.title}" by {track.artist}'
|
txt += f'"{title}" by "{artist} ({fname})":\n\n'
|
||||||
# txt += f' ({track.path})\n'
|
for track in possible_matches:
|
||||||
# txt += "\n"
|
txt += f' "{track.title}" by {track.artist}'
|
||||||
# # Check whether to proceed if there were potential matches
|
txt += f' ({track.path})\n\n'
|
||||||
# if txt:
|
txt += "\n"
|
||||||
# txt += "Proceed with import?"
|
# Check whether to proceed if there were potential matches
|
||||||
# result = QMessageBox.question(self,
|
txt += "Proceed with import?"
|
||||||
# "Possible duplicates",
|
result = QMessageBox.question(self,
|
||||||
# txt,
|
"Possible duplicates",
|
||||||
# QMessageBox.Ok,
|
txt,
|
||||||
# QMessageBox.Cancel
|
QMessageBox.Ok,
|
||||||
# )
|
QMessageBox.Cancel
|
||||||
# if result == QMessageBox.Cancel:
|
)
|
||||||
# return
|
if result == QMessageBox.Cancel:
|
||||||
#
|
return
|
||||||
# # Import in separate thread
|
|
||||||
# thread = threading.Thread(target=self._import_tracks,
|
# Import in separate thread
|
||||||
# args=(new_tracks,))
|
thread = threading.Thread(target=self._import_tracks,
|
||||||
# thread.start()
|
args=(new_tracks,))
|
||||||
#
|
thread.start()
|
||||||
# def _import_tracks(self, tracks: list):
|
|
||||||
# """
|
def _import_tracks(self, tracks: list):
|
||||||
# Import passed files. Don't use parent session as that may be invalid
|
"""
|
||||||
# by the time we need it.
|
Create track objects from passed files and add to visible playlist
|
||||||
# """
|
"""
|
||||||
#
|
|
||||||
# with Session() as session:
|
with Session() as session:
|
||||||
# for (fname, tags) in tracks:
|
for (fname, tags) in tracks:
|
||||||
# track = create_track_from_file(session, fname, tags=tags)
|
track = create_track_from_file(session, fname, tags=tags)
|
||||||
# # Add to playlist on screen
|
self.visible_playlist_tab().insert_track(session, track)
|
||||||
# # If we don't specify "repaint=False", playlist will
|
|
||||||
# # also be saved to database
|
|
||||||
# self.visible_playlist_tab().insert_track(session, track)
|
|
||||||
|
|
||||||
def load_last_playlists(self) -> None:
|
def load_last_playlists(self) -> None:
|
||||||
"""Load the playlists that were open when the last session closed"""
|
"""Load the playlists that were open when the last session closed"""
|
||||||
|
|||||||
@ -579,9 +579,16 @@ class PlaylistTab(QTableWidget):
|
|||||||
self._set_unreadable_row(row)
|
self._set_unreadable_row(row)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# This is a section header so make empty items (row
|
# This is a section header so it must have note text
|
||||||
# background won't be coloured without items present). Any
|
if row_data.note is None:
|
||||||
# notes should displayed starting in column 0
|
log.debug(
|
||||||
|
f"insert_row({row_data=}) with no track_id and no note"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Make empty items (row background won't be coloured without
|
||||||
|
# items present). Any notes should displayed starting in
|
||||||
|
# column 0
|
||||||
for i in range(2, len(columns) - 1):
|
for i in range(2, len(columns) - 1):
|
||||||
self.setItem(row, i, QTableWidgetItem())
|
self.setItem(row, i, QTableWidgetItem())
|
||||||
notes_item = QTableWidgetItem(row_data.note)
|
notes_item = QTableWidgetItem(row_data.note)
|
||||||
|
|||||||
185
app/utilities.py
185
app/utilities.py
@ -1,27 +1,24 @@
|
|||||||
# #!/usr/bin/env python
|
# #!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# import argparse
|
# import argparse
|
||||||
# import os
|
import os
|
||||||
# import shutil
|
import shutil
|
||||||
# import tempfile
|
import tempfile
|
||||||
#
|
|
||||||
# import helpers
|
from config import Config
|
||||||
# from config import Config
|
from helpers import (
|
||||||
# from helpers import (
|
fade_point,
|
||||||
# fade_point,
|
get_audio_segment,
|
||||||
# get_audio_segment,
|
get_tags,
|
||||||
# get_tags,
|
leading_silence,
|
||||||
# leading_silence,
|
trailing_silence,
|
||||||
# trailing_silence,
|
)
|
||||||
# )
|
|
||||||
# from log import log.debug, log.info
|
# from log import log.debug, log.info
|
||||||
# from models import Notes, Playdates, Session, Tracks
|
# from models import Notes, Playdates, Session, Tracks
|
||||||
# from mutagen.flac import FLAC
|
from models import Tracks
|
||||||
# from mutagen.mp3 import MP3
|
from mutagen.flac import FLAC
|
||||||
# from pydub import effects
|
from mutagen.mp3 import MP3
|
||||||
#
|
from pydub import effects
|
||||||
# # Globals (I know)
|
|
||||||
# messages = []
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# def main():
|
# def main():
|
||||||
@ -53,79 +50,83 @@
|
|||||||
# log.info("No action specified")
|
# log.info("No action specified")
|
||||||
#
|
#
|
||||||
# log.debug("Finished")
|
# log.debug("Finished")
|
||||||
#
|
|
||||||
#
|
|
||||||
# def create_track_from_file(session, path, normalise=None, tags=None):
|
def create_track_from_file(session, path, normalise=None, tags=None):
|
||||||
# """
|
"""
|
||||||
# Create track in database from passed path, or update database entry
|
Create track in database from passed path, or update database entry
|
||||||
# if path already in database.
|
if path already in database.
|
||||||
#
|
|
||||||
# Return track.
|
Return track.
|
||||||
# """
|
"""
|
||||||
#
|
|
||||||
# if not tags:
|
if not tags:
|
||||||
# t = get_tags(path)
|
t = get_tags(path)
|
||||||
# else:
|
else:
|
||||||
# t = tags
|
t = tags
|
||||||
#
|
|
||||||
# track = Tracks.get_or_create(session, path)
|
track = Tracks.get_or_create(session, path)
|
||||||
# track.title = t['title']
|
track.title = t['title']
|
||||||
# track.artist = t['artist']
|
track.artist = t['artist']
|
||||||
# audio = get_audio_segment(path)
|
audio = get_audio_segment(path)
|
||||||
# track.duration = len(audio)
|
track.duration = len(audio)
|
||||||
# track.start_gap = leading_silence(audio)
|
track.start_gap = leading_silence(audio)
|
||||||
# track.fade_at = round(fade_point(audio) / 1000,
|
track.fade_at = round(fade_point(audio) / 1000,
|
||||||
# Config.MILLISECOND_SIGFIGS) * 1000
|
Config.MILLISECOND_SIGFIGS) * 1000
|
||||||
# track.silence_at = round(trailing_silence(audio) / 1000,
|
track.silence_at = round(trailing_silence(audio) / 1000,
|
||||||
# Config.MILLISECOND_SIGFIGS) * 1000
|
Config.MILLISECOND_SIGFIGS) * 1000
|
||||||
# track.mtime = os.path.getmtime(path)
|
track.mtime = os.path.getmtime(path)
|
||||||
# session.commit()
|
session.commit()
|
||||||
#
|
|
||||||
# if normalise or normalise is None and Config.NORMALISE_ON_IMPORT:
|
if normalise or normalise is None and Config.NORMALISE_ON_IMPORT:
|
||||||
# # Check type
|
# Check type
|
||||||
# ftype = os.path.splitext(path)[1][1:]
|
ftype = os.path.splitext(path)[1][1:]
|
||||||
# if ftype not in ['mp3', 'flac']:
|
if ftype not in ['mp3', 'flac']:
|
||||||
# log.info(f"File type {ftype} not implemented")
|
log.info(f"File type {ftype} not implemented")
|
||||||
# return track
|
return track
|
||||||
#
|
|
||||||
# # Get current file gid, uid and permissions
|
# Get current file gid, uid and permissions
|
||||||
# stats = os.stat(path)
|
stats = os.stat(path)
|
||||||
# try:
|
try:
|
||||||
# # Copy original file
|
# Copy original file
|
||||||
# fd, temp_path = tempfile.mkstemp()
|
fd, temp_path = tempfile.mkstemp()
|
||||||
# shutil.copyfile(path, temp_path)
|
shutil.copyfile(path, temp_path)
|
||||||
# except Exception as err:
|
except Exception as err:
|
||||||
# log.debug(f"songdb.create_track_from_file({path}): err1: {repr(err)}")
|
log.debug(
|
||||||
# return
|
f"utilities.create_track_from_file({path}): err1: {repr(err)}"
|
||||||
#
|
)
|
||||||
# # Overwrite original file with normalised output
|
return
|
||||||
# normalised = effects.normalize(audio)
|
|
||||||
# try:
|
# Overwrite original file with normalised output
|
||||||
# normalised.export(path, format=os.path.splitext(path)[1][1:])
|
normalised = effects.normalize(audio)
|
||||||
# # Fix up permssions and ownership
|
try:
|
||||||
# os.chown(path, stats.st_uid, stats.st_gid)
|
normalised.export(path, format=os.path.splitext(path)[1][1:])
|
||||||
# os.chmod(path, stats.st_mode)
|
# Fix up permssions and ownership
|
||||||
# # Copy tags
|
os.chown(path, stats.st_uid, stats.st_gid)
|
||||||
# if ftype == 'flac':
|
os.chmod(path, stats.st_mode)
|
||||||
# tag_handler = FLAC
|
# Copy tags
|
||||||
# elif ftype == 'mp3':
|
if ftype == 'flac':
|
||||||
# tag_handler = MP3
|
tag_handler = FLAC
|
||||||
# else:
|
elif ftype == 'mp3':
|
||||||
# return track
|
tag_handler = MP3
|
||||||
# src = tag_handler(temp_path)
|
else:
|
||||||
# dst = tag_handler(path)
|
return track
|
||||||
# for tag in src:
|
src = tag_handler(temp_path)
|
||||||
# dst[tag] = src[tag]
|
dst = tag_handler(path)
|
||||||
# dst.save()
|
for tag in src:
|
||||||
# except Exception as err:
|
dst[tag] = src[tag]
|
||||||
# log.debug(f"songdb.create_track_from_file({path}): err2: {repr(err)}")
|
dst.save()
|
||||||
# # Restore original file
|
except Exception as err:
|
||||||
# shutil.copyfile(path, temp_path)
|
log.debug(
|
||||||
# finally:
|
f"utilities.create_track_from_file({path}): err2: {repr(err)}"
|
||||||
# if os.path.exists(temp_path):
|
)
|
||||||
# os.remove(temp_path)
|
# Restore original file
|
||||||
#
|
shutil.copyfile(path, temp_path)
|
||||||
# return track
|
finally:
|
||||||
|
if os.path.exists(temp_path):
|
||||||
|
os.remove(temp_path)
|
||||||
|
|
||||||
|
return track
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# def full_update_db(session):
|
# def full_update_db(session):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user