Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Lastsamurai26 patch 1 #14

Merged
merged 3 commits into from
Aug 31, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 51 additions & 29 deletions radiorec.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,24 @@
import stat
import sys
import threading
import urllib.request
import urllib3
import logging
import time
logging.basicConfig(level=logging.DEBUG)

def print_time():
return time.strftime("%Y-%m-%d %H:%M:%S")

def check_duration(value):
try:
value = int(value)
except ValueError:
raise argparse.ArgumentTypeError(
'Duration must be a positive integer.')
'Duration in minutes must be a positive integer.')

if value < 1:
raise argparse.ArgumentTypeError(
'Duration must be a positive integer.')
'Duration in minutes must be a positive integer.')
else:
return value

Expand All @@ -60,14 +65,21 @@ def read_settings(args):
config.read_file(open(settings_base_dir + 'settings.ini'))
except FileNotFoundError as err:
print(str(err))
print('Please copy/create the settings file to/in the appropriate '
'location.')
print('Please copy/create the settings file to/in the appropriate location.')
sys.exit()
return dict(config.items())


def record_worker(stoprec, streamurl, target_dir, args):
conn = urllib.request.urlopen(streamurl)
pool = urllib3.PoolManager()
conn = pool.request('GET',streamurl, preload_content=False)
conn.auto_close = False
if conn.status != 200:
conn.release_conn()
time.sleep(10)
verboseprint(print_time() + " ... Waited to return for retry bcof status " + str(conn.status))
return

cur_dt_string = datetime.datetime.now().strftime('%Y-%m-%dT%H_%M_%S')
filename = target_dir + os.sep + cur_dt_string + "_" + args.station
if args.name:
Expand All @@ -86,15 +98,16 @@ def record_worker(stoprec, streamurl, target_dir, args):
print('Unknown content type "' + content_type + '". Assuming mp3.')
filename += '.mp3'

with open(filename, "wb") as target:
verboseprint(print_time() + " ... Writing to: " + filename + ", Content-Type: " + conn.getheader('Content-Type'))
with open(filename, 'wb') as target:
if args.public:
verboseprint('Apply public write permissions (Linux only)')
os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP |
stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH)
verboseprint('Recording ' + args.station + '...')
os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH)
while(not stoprec.is_set() and not conn.closed):
target.write(conn.read(1024))

verboseprint(print_time() + " ... Connection closed = " + str(conn.closed))
conn.release_conn()

def record(args):
settings = read_settings(args)
Expand All @@ -109,24 +122,38 @@ def record(args):
sys.exit()
if streamurl.endswith('.m3u'):
verboseprint('Seems to be an M3U playlist. Trying to parse...')
with urllib.request.urlopen(streamurl) as remotefile:
pool = urllib3.PoolManager()
with pool.request('GET',streamurl) as remotefile:
for line in remotefile:
if not line.decode('utf-8').startswith('#') and len(line) > 1:
tmpstr = line.decode('utf-8')
break
streamurl = tmpstr
verboseprint('stream url: ' + streamurl)
target_dir = os.path.expandvars(settings['GLOBAL']['target_dir'])
stoprec = threading.Event()

recthread = threading.Thread(target=record_worker,
args=(stoprec, streamurl, target_dir, args))
recthread.setDaemon(True)
recthread.start()
recthread.join(args.duration * 60)

if(recthread.is_alive):
stoprec.set()
verboseprint(print_time() + " ... Stream URL: " + streamurl)
target_dir = os.path.expandvars(settings['GLOBAL']['target_dir'])
started_at = time.time()
should_end_at = started_at + (args.duration * 60)
remaining = (args.duration * 60)

# as long as recording is supposed to run
while time.time() < should_end_at:
stoprec = threading.Event()
recthread = threading.Thread(target=record_worker, args=(stoprec, streamurl, target_dir, args))
recthread.setDaemon(True)
recthread.start()
verboseprint(print_time() + " ... Started thread " + str(recthread) + " timeout: " + str(remaining / 60) + " min")
recthread.join(remaining)
verboseprint(print_time() + " ... Came out of rec thread again")

if(recthread.is_alive):
stoprec.set()
verboseprint(print_time() + " ... Called stoprec.set()")
else:
verboseprint(print_time() + " ... recthread.is_alive = False")

remaining = should_end_at - time.time()
verboseprint(print_time() + " ... Remaining: " + str(remaining / 60) + ", Threads: " + str(threading.activeCount()))


def list(args):
Expand All @@ -136,10 +163,7 @@ def list(args):


def main():
parser = argparse.ArgumentParser(description='This program records '
'internet radio streams. It is free '
'software and comes with ABSOLUTELY NO '
'WARRANTY.')
parser = argparse.ArgumentParser(description='This program records internet radio streams. It is free software and comes with ABSOLUTELY NO WARRANTY.')
subparsers = parser.add_subparsers(help='sub-command help')
parser_record = subparsers.add_parser('record', help='Record a station')
parser_record.add_argument('station', type=str,
Expand All @@ -160,9 +184,7 @@ def main():
parser_record.set_defaults(func=record)
parser_list = subparsers.add_parser('list', help='List all known stations')
parser_list.set_defaults(func=list)
parser_list.add_argument(
'-s', '--settings', nargs='?', type=str,
help="specify alternative location for settings.ini")
parser_list.add_argument('-s', '--settings', nargs='?', type=str, help="specify alternative location for settings.ini")

if not len(sys.argv) > 1:
print('Error: No argument specified.\n')
Expand Down