Chris Pomeroy
2023-11-30 1bc382c0c65a3721982861d16abdeeecd651320e
aaxConvert.py
@@ -1,24 +1,26 @@
#!/usr/bin/env python
#!/usr/bin/env -S python -u
import argparse
import os
import glob
import subprocess
import shlex
import json
import re
import requests
import unicodedata
from querysubsonic import findalbumbyname
from time import sleep
import sys
from queryAudiobookServer import findalbumbyname
# arguments
# activation_key, file name, codec(default to mp3)
parser = argparse.ArgumentParser()
parser.add_argument("-s","--single", help="Use this option to create a single file. This is false by default", action="store_true")
parser.add_argument("-d","--dpath", help="Use this to set the destination path. Otherwise I will use the current directory")
parser.add_argument("-v", "--verbose", help="Send output to stdout", action="store_true")
parser.add_argument("filename", help="Filename to convert, or directory to look in")
parser.add_argument("-s", "--single", help="Use this option to create a single\
                     file. This is false by default", action="store_true")
parser.add_argument("-d", "--dpath", help="Use this to set the destination\
                    path. Otherwise I will use the current directory")
parser.add_argument("-v", "--verbose", help="Send output to stdout",
                    action="store_true")
parser.add_argument("filename", help="Filename to convert, or directory to\
                     look in")
args = parser.parse_args()
@@ -44,49 +46,71 @@
def getmetadata(aaxfile):
    ret = subprocess.check_output(["ffprobe", "-v", "info", "-hide_banner", "-show_format", "-show_chapters", "-print_format", "json", os.path.abspath(aaxfile)])
    mdata = json.loads(ret)
    # Returns the metadata from an aax file
    ret = subprocess.run(["ffprobe", "-v", "info", "-hide_banner",
                          "-show_format", "-show_chapters",
                          "-print_format", "json",
                          os.path.abspath(aaxfile)], capture_output=True)
    mdata = json.loads(ret.stdout)
    aret = ret.stderr.decode().split('\n')[0]
    mdata["checksum"] = aret.split()[-1]
    return mdata
def getmetabitrate():
    # Return the bitrate of the media
    bit_rate = metadata['format']['bit_rate']
    return bit_rate[:2]
def getmetacopyright():
    copyright = unicodedata.normalize('NFKD', metadata['format']['tag']['copyright']).encode('ascii','ignore')
    # Return normalized copyright data
    copyright = normalize_data(metadata['format']['tags']['copyright'])
    return copyright
def getmetadatatags(key):
    # get specific data
    tag = cleantag(metadata['format']['tags'][key])
    return tag
    tag = metadata['format']['tags'][key]
    return " ".join(tag.split())
def normalize_data(data):
    # Return a normalized title
    data = data.replace(" ", "_")
    pattern = re.compile('\W')
    return re.sub(pattern, '', data)
def reencode(aaxfile, outpath):
    # decrypt and reencode to mp3
    command = ("ffmpeg -loglevel error {} -activation_bytes {} -i {} -vn -codec:a libmp3lame -ab {}k -map_metadata -1 "
               "-metadata \"title={}\" -metadata 'artist={}' -metadata 'album_artist={}' -metadata \"album={}\" -metadata 'date={}' "
               "-metadata track=1/1 -metadata 'genre={}' -metadata 'copyright={}' \"{}\" " ).format(stats, act_byte,aaxfile,getmetabitrate(),
                                                                                           getmetadatatags('title'), getmetadatatags('artist'),
                                                                                           getmetadatatags('album_artist'), getmetadatatags('album'),
                                                                                           getmetadatatags('date'), getmetadatatags('genre'),
                                                                                           getmetacopyright(),outpath)
    command = (
        "ffmpeg -loglevel error {} -activation_bytes {} -i"
        " {} -vn -codec:a libmp3lame -ab {}k -map_metadata -1"
        "-metadata \"title={}\" -metadata 'artist={}' -metadata"
        " 'album_artist={}' -metadata \"album={}\" -metadata 'date={}' "
        "-metadata track=1/1 -metadata 'genre={}' -metadata "
        "'copyright={}' \"{}\" ").format(
            stats, act_byte, aaxfile, getmetabitrate(),
            getmetadatatags('title'), getmetadatatags('artist'),
            getmetadatatags('album_artist'), getmetadatatags('album'),
            getmetadatatags('date'), getmetadatatags('genre'),
            getmetacopyright(), outpath)
    if args.verbose:
        print(command)
        process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
        while True:
            output = process.stdout.readline()
            if output == '' and process.poll() is not None:
                break
            if output:
                print(output.strip())
        rc = process.poll()
        process = subprocess.run(command, shell=True, capture_output=True)
        # while True:
        #     output = process.stdout.readline()
        #     if output == '' and process.poll() is not None:
        #         break
        #     if output:
        #         print(output.strip())
        rc = process.stdout
        return rc
    else:
        process = subprocess.call(shlex.split(command))
    return
        process = subprocess.run(command, shell=True)
    return
def getchaptercount():
@@ -101,70 +125,67 @@
        if i['id'] == cid:
            return i[key]
def movetochapters(path, outpath, chapter, title, start,end):
def movetochapters(path, outpath, chapter, title, start, end):
    # Creating individual chapters
    outfile = "{}/Ch - {} {}.mp3".format(outpath, chapter, title)
    outfile = "{}/Ch-{}_{}.mp3".format(
        outpath, chapter, title.replace(' ', '_')
    )
    command = "ffmpeg -loglevel error {} -i \"{}\" -ss {} -to {} -codec:a copy -metadata 'track={}' \"{}\"".format(stats, path,
                                                                                                               start, end,
                                                                                                               chapter, outfile)
                                                                                                                   start, end,
                                                                                                                   chapter, outfile)
    if args.verbose:
        print(command)
        process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
        while True:
            output = process.stdout.readline()
            if output == '' and process.poll() is not None:
                break
            if output:
                print(output.strip())
        process = subprocess.run(command, shell=True, capture_output=True)
        # while True:
        #     output = process.stdout.readline()
        #     if output == '' and process.poll() is not None:
        #         break
        #     if output:
        #         print(output.strip())
        rc = process.poll()
        return rc
    else:
        process = subprocess.call(shlex.split(command))
        process = subprocess.run(command, shell=True)
    return
def getcoverart(path,outpath):
def getcoverart(path, outpath):
    # Pull the coverart from the file
    command = "ffmpeg -loglevel error -activation_bytes {} -i \"{}\" -an -codec:v copy \"{}/cover.jpg\"".format(act_byte,
                                                                                                               path, outpath)
                                                                                                                path, outpath)
    if args.verbose:
        print(command)
    process = subprocess.call(shlex.split(command))
        subprocess.run(command, shell=True)
    return
def filechecksum(aaxfile):
    ret = subprocess.Popen(["ffprobe", "-v", "info", "-hide_banner", os.path.abspath(aaxfile)], stderr=subprocess.PIPE)
    grep = subprocess.Popen(["grep", "checksum"], stdin=ret.stderr, stdout=subprocess.PIPE)
    awk = subprocess.Popen(["awk", " { print $8 } "], stdin=grep.stdout, stdout=subprocess.PIPE)
    hashsum,out = awk.communicate()
    hashsum = hashsum.strip('\n')
    return hashsum
def getcorrectkey(aaxfile):
    hex = filechecksum(aaxfile)
    payload = hex
    recovery = 3
    while recovery != 0:
      r = requests.post('http://x86-docker01:8080/function/checkkey', payload, verify=False, timeout=None)
      if r.status_code == 200:
          key = r.text
          recovery = 0
          return key
      else:
          print('Checkkey function is down please wait')
          recovery = recovery - 1
          sleep(5)
def getcorrectkey():
    # request the key for the checksum
    try:
        r = requests.post('http://faas.darkurthe.net/function/checkkey',
                          metadata['checksum'], verify=False, timeout=None)
        return r.text.strip()
    except requests.exceptions.HTTPError as err:
        raise err
for rfile in glob.glob(args.filename):
    if rfile.find("aax") != -1 and os.path.isfile(rfile):
        metadata = getmetadata(rfile)
        album = getmetadatatags('album')
        #See if we got it already
        if (findalbumbyname(album) == False):
            artist = getmetadatatags('artist')
            title = getmetadatatags('title')
            act_byte = getcorrectkey(rfile)
def findalbumbyname_stub(album):
    return False
if args.filename.find("aax"):
    rfile = args.filename
    metadata = getmetadata(rfile)
    album = getmetadatatags('album')
    # See if we got it already
    if not findalbumbyname(album):
        artist = normalize_data(getmetadatatags('artist'))
        title = normalize_data(getmetadatatags('title'))
        act_byte = getcorrectkey()
        if act_byte is None or act_byte == '':
            sys.exit(f"Can't continue with this file {rfile}")
        else:
            ddir = "%s/%s/%s" % (path, artist, title)
            single_file_path = "/processing/%s.mp3" % (title)
            if not os.path.exists(ddir):
@@ -174,13 +195,15 @@
            if mode == 'chapter':
                chapter = 0
                numchapters = getchaptercount()
                while (numchapters > 0 ):
                while (numchapters > 0):
                    cstart = getchaptermetadata(chapter, 'start_time')
                    cend = getchaptermetadata(chapter, 'end_time')
                    chapter += 1
                    numchapters -= 1
                    schap = str(chapter).zfill(2)
                    movetochapters(single_file_path, ddir, schap, title, cstart,cend)
                    movetochapters(single_file_path, ddir, schap, title,
                                   cstart, cend)
                os.remove(single_file_path)
            getcoverart(rfile, ddir)
    else:
        print('We have that book already')