Last active
October 3, 2015 02:56
-
-
Save thatarchguy/e7353eefbbc5ae1c6996 to your computer and use it in GitHub Desktop.
whatcd scripts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/local/bin/node | |
var fs = require('fs'), | |
request = require('request'), | |
readline = require('readline'); | |
var request = request.defaults({jar: true}), | |
rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout | |
}); | |
rl.question("Username: ", function(user) { | |
rl.question("Password: ", function(pass) { | |
request.post('https://what.cd/login.php', {form:{username: user, password: pass}}, function(error, response, content) { | |
getPage(1, 7); | |
rl.close(); | |
}); | |
}); | |
}); | |
function getPage(page, pages) { | |
console.log('Getting torrent listing page ' + page); | |
request('https://what.cd/torrents.php?freetorrent=1&page=' + page, function(err, res, body) { | |
var torrents = body.match(/torrents.php\?action=download.*torrent_pass=[a-z0-9]*/g); | |
console.log('Parsing page ' + page); | |
for (var i = 0; i < torrents.length; i++) { | |
torrents[i] = 'https://what.cd/'.concat(torrents[i].replace(/&/g, '&')); | |
} | |
console.log('Downloading torrents from page ' + page); | |
getTorrents(torrents, 0); | |
if (page < pages) { | |
getPage(page + 1, pages); | |
} | |
}); | |
} | |
function getTorrents(torrents, i) { | |
request(torrents[i], function(err, res, body) { | |
fs.exists(res.headers['content-disposition'].match(/\".*\"/)[0].slice(1,-9) + '.' + res.request.req.path.match(/id=[0-9]*/)[0].slice(3) + '.torrent', function(exists) { | |
if(!exists) { | |
request(torrents[i]).pipe(fs.createWriteStream(res.headers['content-disposition'].match(/\".*\"/)[0].slice(1,-9) + '.' + res.request.req.path.match(/id=[0-9]*/)[0].slice(3) + '.torrent', {mode: 0770})) | |
} | |
}) | |
}) | |
if (i < torrents.length - 1) { | |
getTorrents(torrents, i + 1); | |
} | |
} | |
process.on('uncaughtException', function(err) { | |
console.log("WARNING: Error downloading torrent"); | |
console.log(err); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
############################################################## | |
# whatmp3 - Convert FLAC to mp3, create what.cd torrent. | |
# Created by shardz (logik.li), demonstar55, and The_Creator | |
############################################################## | |
import os | |
import re | |
import fnmatch | |
import shutil | |
from optparse import OptionParser | |
import threading | |
VERSION = "3.6" | |
### BEGIN CONFIGURATION ### | |
# Output folder unless specified: ("/home/user/Desktop/") | |
#output = os.path.join(os.environ['HOME'], "Desktop/") | |
output = os.getcwd() | |
# Separate torrent output folder (defaults to output): | |
torrent_dir = output | |
# Do you want to move additional files (.jpg, .log, etc)? | |
moveother = 1 | |
# Do you want to zeropad tracknumbers? (1 => 01, 2 => 02 ...) | |
zeropad = 1 | |
# Do you want to dither FLACs to 16/44 before encoding? | |
dither = 0 | |
# Specify tracker ("http://tracker.what.cd:34000/") | |
tracker = "http://tracker.what.cd:34000/" | |
# Specify torrent passkey | |
passkey = "" | |
# Max number of threads (ex: Normal: 1, Dual-core = 2, Hyperthreaded Dual-core = 4) | |
max_threads = 1 | |
# Default encoding options | |
enc_options = { | |
'320': {'enc': 'lame', 'opts': '-q 0 -b 320 --ignore-tag-errors'}, | |
'V0': {'enc': 'lame', 'opts': '-q 0 -V 0 --vbr-new --ignore-tag-errors'}, | |
'V2': {'enc': 'lame', 'opts': '-q 0 -V 2 --vbr-new --ignore-tag-errors'}, | |
'Q8': {'enc': 'oggenc', 'opts': '-q 8'}, | |
'AAC': {'enc': 'neroAacEnc', 'opts': '-br 320000'}, | |
'ALAC': {'enc': 'ffmpeg', 'opts': '-i - -acodec alac'}, | |
'FLAC': {'enc': 'flac', 'opts': '--best'} | |
} | |
### END CONFIGURATION ### | |
codecs = [] | |
# os.system() and os.popen() have issues with ` | |
def escape_backtick(pattern): | |
pattern = re.sub('`', '\`', pattern) | |
return pattern | |
def escape_quote(pattern): | |
pattern = re.sub('"', '\\"', pattern) | |
return pattern | |
def escape_percent(pattern): | |
pattern = re.sub('%', '%%', pattern) | |
return pattern | |
class Transcode(threading.Thread): | |
def __init__(self, file, flacdir, mp3_dir, codec, options, cv): | |
threading.Thread.__init__(self) | |
self.file = file | |
self.flacdir = flacdir | |
self.mp3_dir = mp3_dir | |
self.codec = codec | |
self.options = options | |
self.cv = cv | |
def run(self): | |
tags = {} | |
for tag in ('TITLE', 'ALBUM', 'ARTIST', 'TRACKNUMBER', 'GENRE', 'COMMENT', 'DATE'): | |
tagcommand = 'metaflac --show-tag=' + escape_quote(tag) + ' "' + escape_quote(self.file) + '"' | |
temp = re.sub('\S.*=', '', os.popen(escape_backtick(tagcommand)).read().rstrip()) | |
tags.update({tag:temp}) | |
del temp | |
if self.options.zeropad and len(tags['TRACKNUMBER']) == 1: | |
tags['TRACKNUMBER'] = '0' + tags['TRACKNUMBER'] | |
mp3_filename = re.sub(re.escape(self.flacdir), self.mp3_dir, self.file) | |
mp3_filename = re.sub('\.flac$', '', mp3_filename) | |
if not os.path.exists(os.path.dirname(mp3_filename)): | |
os.makedirs(os.path.dirname(mp3_filename)) | |
flac_command = '' | |
mp3_filename = escape_percent(mp3_filename) # string % (params) will break on filenames including an unescaped % character | |
if enc_options[self.codec]['enc'] == 'lame': | |
if self.options.skip_genre: | |
flac_command = 'lame -S %s --tt "%s" --tl "%s" --ta "%s" --tn "%s" --ty "%s" --add-id3v2 - "%s.mp3" 2>&1' | |
else: | |
flac_command = 'lame -S %s --tt "%s" --tl "%s" --ta "%s" --tn "%s" --tg "%s" --ty "%s" --add-id3v2 - "%s.mp3" 2>&1' | |
elif enc_options[self.codec]['enc'] == 'oggenc': | |
flac_command = 'oggenc -Q %s -t "%s" -l "%s" -a "%s" -N "%s" -G "%s" -d "%s" -o "%s.ogg" - 2>&1' | |
elif enc_options[self.codec]['enc'] == 'ffmpeg': | |
flac_command = 'ffmpeg %s -metadata title="%s" -metadata album="%s" -metadata author="%s" -metadata track="%s" -metadata genre="%s" -metadata date="%s" "%s.m4a" 2>&1' | |
elif enc_options[self.codec]['enc'] == 'neroAacEnc': | |
flac_command = 'neroAacEnc %s -if - -of "%s.m4a" 2>&1 && neroAacTag "%s.m4a" -meta:title="%s" -meta:album="%s" -meta:artist="%s" -meta:track="%s" -meta:genre="%s" -meta:year="%s"' | |
elif enc_options[self.codec]['enc'] == 'flac': | |
flac_command = 'flac %s -s -T "TITLE=%s" -T "ALBUM=%s" -T "ARTIST=%s" -T "TRACKNUMBER=%s" -T "GENRE=%s" -T "DATE=%s" -o "%s.flac" - 2>&1' | |
if self.options.dither: | |
flac_command = 'sox -t wav - -b 16 -t wav - rate 44100 dither | ' + flac_command | |
flac_command = 'flac -dc -- "' + escape_percent(escape_quote(self.file)) + '" | ' + flac_command | |
if enc_options[self.codec]['enc'] == 'neroAacEnc': | |
flac_command = flac_command % (escape_quote(enc_options[self.codec]['opts']), escape_quote(mp3_filename), escape_quote(mp3_filename), escape_quote(tags['TITLE']), escape_quote(tags['ALBUM']), escape_quote(tags['ARTIST']), escape_quote(tags['TRACKNUMBER']), escape_quote(tags['GENRE']), escape_quote(tags['DATE'])) | |
else: | |
genre_tag = (escape_quote(tags['GENRE']),) | |
if enc_options[self.codec]['enc'] == 'lame' and self.options.skip_genre: | |
genre_tag = () | |
params = (escape_quote(enc_options[self.codec]['opts']), escape_quote(tags['TITLE']), escape_quote(tags['ALBUM']), escape_quote(tags['ARTIST']), escape_quote(tags['TRACKNUMBER'])) + genre_tag + (escape_quote(tags['DATE']), escape_quote(mp3_filename)) | |
flac_command = flac_command % params | |
if self.options.verbose: | |
print(escape_backtick(flac_command)) | |
os.system(escape_backtick(flac_command)) | |
self.cv.acquire() | |
self.cv.notify_all() | |
self.cv.release() | |
return 0 | |
def add_enc_option(option, opt, value, parser): | |
codecs.append(opt[2:]) | |
def main(): | |
# Parse options and arguments | |
usage_text = "%prog [options] [--320 --V2 --Q8 --AAC ...] /path/to/FLAC" | |
info_text = "Depends on flac, metaflac, mktorrent, and optionally oggenc, lame, neroAacEnc, neroAacTag, mp3gain, aacgain, vorbisgain, and sox." | |
parser = OptionParser(usage=usage_text, version="%prog " + VERSION, epilog=info_text) | |
parser.add_option('-v', '--verbose', action='store_true', dest='verbose', default=False, help='increase verbosity (Default: False)') | |
parser.add_option('-n', '--notorrent', action='store_true', dest='notorrent', default=False, help='will not create a torrent after conversion (Default: False)') | |
parser.add_option('--nolog', action='store_true', dest='nolog', default=False, help='will not move log files after conversion (Default: False)') | |
parser.add_option('--nocue', action='store_true', dest='nocue', default=False, help='will not move cue files after conversion (Default: False)') | |
parser.add_option('--nodate', action='store_true', dest='nodate', default=False, help='do not write the creation date to the .torrent file (Default: False)') | |
parser.add_option('--skipgenre', action='store_true', dest='skip_genre', default=False, help='do not insert a genre tag in MP3 files (Default: False)') | |
parser.add_option('-m', '--moveother', action='store_true', dest='moveother', default=moveother, help='move additional files (Default: True)') | |
parser.add_option('-p', '--passkey', dest='passkey', default=passkey, help='tracker PASSKEY', metavar='PASSKEY') | |
parser.add_option('-t', '--tracker', dest='tracker', default=tracker, help='tracker URL (Default: "http://tracker.what.cd:34000/")', metavar='URL') | |
parser.add_option('-o', '--output', dest='output', default=output, help='set the output PATH', metavar='PATH') | |
parser.add_option('--torrent-dir', dest='torrent_dir', default=torrent_dir, help='set independent torrent output directory') | |
parser.add_option('-z', '--zeropad', action='store_true', dest='zeropad', default=zeropad, help='zeropad track numbers (Default: True)') | |
parser.add_option('-r', '--replaygain', action='store_true', dest='replaygain', default=False, help='add ReplayGain to new files (Default: False)') | |
parser.add_option('-d', '--dither', action='store_true', dest='dither', default=dither, help='dither FLACs to 16/44 before encoding (Default: False)') | |
parser.add_option('--threads', type="int", dest='max_threads', default=max_threads, help='set number of threads THREADS (Default: 1)', metavar='THREADS') | |
parser.add_option('-c', '--original', action='store_true', dest='original', default=False, help='create a torrent for the original FLAC') | |
for enc_opt in enc_options.keys(): | |
parser.add_option("--" + enc_opt, action="callback", callback=add_enc_option, help='convert to %s' % (enc_opt)) | |
(options, flacdirs) = parser.parse_args() | |
if len(flacdirs) < 1: | |
parser.error("Incorrect number of arguments") | |
if not options.output.endswith('/'): | |
options.output += '/' | |
if len(codecs) == 0 and not options.original: | |
print('You need to provide at least one format to transcode to (320, V0, Q8 ...)') | |
exit() | |
for flacdir in flacdirs: | |
flacdir = os.path.abspath(flacdir) | |
flacfiles = [] | |
for dirpath, dirs, files in os.walk(flacdir, topdown=False): | |
for name in files: | |
if fnmatch.fnmatch(name, '*.flac') or fnmatch.fnmatch(name, '*.FLAC'): | |
flacfiles.append(os.path.join(dirpath, name)) | |
if options.original: | |
print('Working with FLAC...') | |
if options.output and options.passkey and options.tracker and not options.notorrent: | |
if options.verbose: print('Creating torrent...') | |
torrent_command = 'mktorrent -p -a %s/announce -o "%s.torrent" "%s"' % (options.tracker + options.passkey, escape_quote(options.output + os.path.basename(flacdir)), escape_quote(flacdir)) | |
if options.nodate: | |
torrent_command += ' -d' | |
if options.verbose: print(escape_backtick(torrent_command)) | |
os.system(escape_backtick(torrent_command)) | |
print('Finished working with FLAC') | |
for codec in codecs: | |
mp3_dir = options.output + os.path.basename(flacdir) | |
if 'FLAC' in flacdir: | |
mp3_dir = re.sub(re.compile('FLAC', re.I), codec, mp3_dir) | |
else: | |
mp3_dir = mp3_dir + " (" + codec + ")" | |
if not os.path.exists(mp3_dir): | |
os.makedirs(mp3_dir) | |
print('Encoding with ' + codec + ' started...') | |
threads = [] | |
cv = threading.Condition() | |
for file in flacfiles: | |
cv.acquire() | |
while((threading.activeCount() == options.max_threads + 1) or (options.max_threads == 0 and threading.activeCount() == 2)): | |
cv.wait() | |
cv.release() | |
t=Transcode(file, flacdir, mp3_dir, codec, options, cv) | |
t.start() | |
threads.append(t) | |
for t in threads: | |
t.join() | |
print('\nEncoding with ' + codec + ' finished.') | |
if options.moveother: | |
if options.verbose: print('Moving other files...') | |
for dirpath, dirs, files in os.walk(flacdir, topdown=False): | |
for name in files: | |
if options.nolog and fnmatch.fnmatch(name, '*.log'): | |
continue | |
if options.nocue and fnmatch.fnmatch(name, '*.cue'): | |
continue | |
if not fnmatch.fnmatch(name, '*.flac') and not fnmatch.fnmatch(name, '*.m3u'): | |
d = re.sub(re.escape(flacdir), mp3_dir, dirpath) | |
if not os.path.exists(d): | |
os.makedirs(d) | |
shutil.copy(os.path.join(dirpath, name), d) | |
if options.replaygain and enc_options[codec]['enc'] != 'flac': | |
if options.verbose: print('Applying replay gain...') | |
for dirpath, dirs, files in os.walk(mp3_dir, topdown=False): | |
for name in dirs: | |
if enc_options[codec]['enc'] == 'lame': | |
os.system(escape_backtick('mp3gain -q -c -s i "' + os.path.join(dirpath, name) + '"/*.mp3')) | |
if enc_options[codec]['enc'] == 'oggenc': | |
os.system(escape_backtick('vorbisgain -qafrs "' + os.path.join(dirpath, name) + '"/*.ogg')) | |
if enc_options[codec]['enc'] == 'neroAacEnc': | |
os.system(escape_backtick('aacgain -q -c "' + os.path.join(dirpath, name) + '"/*.m4a')) | |
if options.output and options.passkey and options.tracker and not options.notorrent: | |
if options.verbose: print('Creating torrent...') | |
torrent_command = 'mktorrent -p -a %s/announce -o "%s.torrent" "%s"' % (options.tracker + options.passkey, escape_backtick(os.path.join(options.torrent_dir, os.path.basename(mp3_dir))), mp3_dir) | |
if options.nodate: | |
torrent_command += ' -d' | |
if options.verbose: print(escape_backtick(torrent_command)) | |
os.system(escape_backtick(torrent_command)) | |
if options.verbose: print('All done with ' + flacdir + ' ...') | |
return 0 | |
if __name__ == '__main__': | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment