Compare commits

...

6 Commits

2 changed files with 84 additions and 17 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@
# Config files # Config files
settings.conf settings.conf
# Other
**/

View File

@ -1,14 +1,23 @@
import configparser import configparser
from requests import get from requests import get
from feedgen.feed import FeedGenerator
import datetime
import os import os
import re
import json import json
import sys import sys
# osSafeName() convertes a string to an OS safe name.
def osSafeName(name):
return re.sub(r'[^a-zA-Z0-9 -]', '', name).lower().replace(' ', '-').replace('--', '-')
class AudibleBook(object): class AudibleBook(object):
def __init__(self, filePath, activationBytes): def __init__(self, filePath, activationBytes, targetDir):
self.filePath = filePath self.filePath = filePath
self.activationBytes = activationBytes self.activationBytes = activationBytes
self.targetDir = targetDir
self.convertedFilePath=''
self.metadata = json.loads(os.popen('ffprobe -i {} -show_format \ self.metadata = json.loads(os.popen('ffprobe -i {} -show_format \
-print_format json'.format(filePath)).read())['format']['tags'] -print_format json'.format(filePath)).read())['format']['tags']
self.chapters = json.loads(os.popen('ffprobe -i {} -print_format json \ self.chapters = json.loads(os.popen('ffprobe -i {} -print_format json \
@ -31,10 +40,39 @@ class AudibleBook(object):
def getTitle(self): def getTitle(self):
return self.getMetadata()['title'] return self.getMetadata()['title']
def getAuthor(self):
return self.getMetadata()['artist']
def setTargetDir(self, targetDir):
self.targetDir = targetDir
def removeDRM(self, fileName): def removeDRM(self, fileName):
os.system('ffmpeg -activation_bytes {} -i {} -c copy "{}.m4b"' filePath = '{}/{}.m4b'.format(self.targetDir, fileName)
.format(self.activationBytes, self.filePath, fileName)) if not os.path.exists(filePath):
print('test') os.system('ffmpeg -activation_bytes {} -i {} -c copy "{}"'
.format(self.activationBytes, self.filePath, filePath))
self.convertedFilePath = filePath
def splitChapters(self):
for c in self.getChapters():
start=c['start_time']
end=c['end_time']
title=c['tags']['title']
outFilePath = '{}-{}.m4a'.format(os.path.splitext(self.convertedFilePath)[0],
osSafeName(title))
if not os.path.exists(outFilePath):
os.system('ffmpeg -i {} -acodec copy -vcodec copy -ss {} -t {} {}'.
format(self.convertedFilePath, start, end, outFilePath))
def getCover(self):
outFilePath = '{}/cover.jpg'.format(self.targetDir)
if not os.path.exists(outFilePath):
os.system('ffmpeg -i {} -an -vcodec copy {}'.
format(self.convertedFilePath, outFilePath))
def deleteConverted(self):
if self.convertedFilePath is not '' and os.path.exists(self.configFilePath):
os.remove(self.convertedFilePath)
# getHash() returns the hash of a given file. # getHash() returns the hash of a given file.
def getHash(filePath): def getHash(filePath):
@ -60,6 +98,8 @@ def createConfig(configFilePath, filePath):
configFilePath='./settings.conf' configFilePath='./settings.conf'
audibleBookPath=sys.argv[1] audibleBookPath=sys.argv[1]
serverURL=sys.argv[2]
targetDir='./audiobooks'
# Check if config file exists and creates one if needed. # Check if config file exists and creates one if needed.
if not os.path.exists(configFilePath): if not os.path.exists(configFilePath):
@ -71,17 +111,41 @@ configParser = configparser.RawConfigParser()
configParser.read_string(configString) configParser.read_string(configString)
activationBytes=configParser.get('Settings', 'activationBytes') activationBytes=configParser.get('Settings', 'activationBytes')
book = AudibleBook(audibleBookPath, activationBytes) book = AudibleBook(audibleBookPath, activationBytes, targetDir)
name = osSafeName(book.getTitle())
outputDir = '{}/{}'.format(targetDir, name)
if not os.path.exists(outputDir):
os.makedirs(outputDir)
book.setTargetDir(outputDir)
rssFilePath='{}/rss.xml'.format(outputDir)
if not os.path.exists(rssFilePath):
book.removeDRM(name)
book.splitChapters()
book.getCover()
fg = FeedGenerator()
fg.id(name)
fg.title(book.getTitle())
fg.author( {'name': book.getAuthor()} )
fg.link( href='https://audible.com', rel='alternate' )
fg.logo('{}/{}/cover.jpg'.format(serverURL, name))
fg.subtitle(book.getMetadata()['copyright'])
fg.language('en')
count = 0
for c in book.getChapters(): for c in book.getChapters():
start=c['start'] key = osSafeName(c['tags']['title'])
end=c['end'] fe = fg.add_entry()
title=c['tags']['title'] fe.id(key)
print(start, end, title) fe.title(c['tags']['title'])
#os.system('ffmpeg -i {} -acodec copy -vcodec copy -ss {} -t {} OUTFILE-{}.m4a'.format(filePath, start, end, title)) fe.link(href='{0}/{1}/{1}-{2}.m4a'.format(serverURL, name, key))
fe.enclosure('{0}/{1}/{1}-{2}.m4a'.format(serverURL, name, key), 0, 'audio')
fe.published(datetime.datetime(int(book.getMetadata()['date']), 6, 1, 0, count, tzinfo=datetime.timezone.utc))
print(book.getTitle()) count += 1
rssfeed = fg.rss_str(pretty=True)
fg.rss_file(rssFilePath)
book.deleteConverted()