Fix trailing whitespaces in files
This commit is contained in:
parent
1af089219f
commit
d8195f0fd8
46 changed files with 240 additions and 241 deletions
|
@ -19,36 +19,36 @@ QUEUE = "airtime-uploads"
|
|||
|
||||
""" A message listener class that waits for messages from Airtime through RabbitMQ
|
||||
notifying us about new uploads.
|
||||
|
||||
|
||||
This is probably the most important class in this application. It connects
|
||||
to RabbitMQ (or an AMQP server) and listens for messages that notify us
|
||||
when a user uploads a new file to Airtime, either through the web interface
|
||||
or via FTP (on Airtime Pro). When we get a notification, we spawn a child
|
||||
process that extracts the uploaded audio file's metadata and moves it into
|
||||
Airtime's music library directory. Lastly, the extracted metadata is
|
||||
Airtime's music library directory. Lastly, the extracted metadata is
|
||||
reported back to the Airtime web application.
|
||||
|
||||
|
||||
There's a couple of Very Important technical details and constraints that you
|
||||
need to know if you're going to work on this code:
|
||||
|
||||
1) airtime_analyzer is designed so it doesn't have to run on the same
|
||||
|
||||
1) airtime_analyzer is designed so it doesn't have to run on the same
|
||||
computer as the web server. It just needs access to your Airtime library
|
||||
folder (stor).
|
||||
folder (stor).
|
||||
2) airtime_analyzer is multi-tenant - One process can be used for many
|
||||
Airtime instances. It's designed NOT to know about whether it's running
|
||||
in a single tenant or multi-tenant environment. All the information it
|
||||
in a single tenant or multi-tenant environment. All the information it
|
||||
needs to import a file into an Airtime instance is passed in via those
|
||||
RabbitMQ messages.
|
||||
3) We're using a "topic exchange" for the new upload notification RabbitMQ
|
||||
messages. This means if we run several airtime_analyzer processes on
|
||||
messages. This means if we run several airtime_analyzer processes on
|
||||
different computers, RabbitMQ will do round-robin dispatching of the
|
||||
file notification. This is cheap, easy load balancing and
|
||||
redundancy for us. You can even run multiple airtime_analyzer processes
|
||||
on one machine if you want.
|
||||
4) We run the actual work (metadata analysis and file moving) in a separate
|
||||
child process so that if it crashes, we can stop RabbitMQ from resending
|
||||
the file notification message to another airtime_analyzer process (NACK),
|
||||
which would otherwise cause cascading failure. We also do this so that we
|
||||
the file notification message to another airtime_analyzer process (NACK),
|
||||
which would otherwise cause cascading failure. We also do this so that we
|
||||
can report the problem file to the Airtime web interface ("import failed").
|
||||
|
||||
So that is a quick overview of the design constraints for this application, and
|
||||
|
@ -164,10 +164,10 @@ class MessageListener:
|
|||
api_key = ""
|
||||
file_prefix = ""
|
||||
|
||||
""" Spin up a worker process. We use the multiprocessing module and multiprocessing.Queue
|
||||
""" Spin up a worker process. We use the multiprocessing module and multiprocessing.Queue
|
||||
to pass objects between the processes so that if the analyzer process crashes, it does not
|
||||
take down the rest of the daemon and we NACK that message so that it doesn't get
|
||||
propagated to other airtime_analyzer daemons (eg. running on other servers).
|
||||
take down the rest of the daemon and we NACK that message so that it doesn't get
|
||||
propagated to other airtime_analyzer daemons (eg. running on other servers).
|
||||
We avoid cascading failure this way.
|
||||
"""
|
||||
try:
|
||||
|
@ -208,8 +208,8 @@ class MessageListener:
|
|||
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
""" If ANY exception happens while processing a file, we're going to NACK to the
|
||||
messaging server and tell it to remove the message from the queue.
|
||||
""" If ANY exception happens while processing a file, we're going to NACK to the
|
||||
messaging server and tell it to remove the message from the queue.
|
||||
(NACK is a negative acknowledgement. We could use ACK instead, but this might come
|
||||
in handy in the future.)
|
||||
Exceptions in this context are unexpected, unhandled errors. We try to recover
|
||||
|
|
|
@ -216,7 +216,7 @@ class StatusReporter:
|
|||
# r = requests.Request(method='PUT', url=callback_url, data=put_payload,
|
||||
# auth=requests.auth.HTTPBasicAuth(api_key, ''))
|
||||
"""
|
||||
r = requests.Request(method='PUT', url=callback_url, data=put_payload,
|
||||
r = requests.Request(method='PUT', url=callback_url, data=put_payload,
|
||||
auth=requests.auth.HTTPBasicAuth(api_key, ''))
|
||||
|
||||
StatusReporter._send_http_request(r)
|
||||
|
@ -235,11 +235,11 @@ class StatusReporter:
|
|||
StatusReporter._ipc_queue.put(r.prepare())
|
||||
"""
|
||||
|
||||
"""
|
||||
"""
|
||||
# Encode the audio metadata as json and post it back to the callback_url
|
||||
put_payload = json.dumps(audio_metadata)
|
||||
logging.debug("sending http put with payload: " + put_payload)
|
||||
r = requests.put(callback_url, data=put_payload,
|
||||
r = requests.put(callback_url, data=put_payload,
|
||||
auth=requests.auth.HTTPBasicAuth(api_key, ''),
|
||||
timeout=StatusReporter._HTTP_REQUEST_TIMEOUT)
|
||||
logging.debug("HTTP request returned status: " + str(r.status_code))
|
||||
|
@ -266,7 +266,7 @@ class StatusReporter:
|
|||
put_payload = json.dumps(audio_metadata)
|
||||
# logging.debug("sending http put with payload: " + put_payload)
|
||||
"""
|
||||
r = requests.put(callback_url, data=put_payload,
|
||||
r = requests.put(callback_url, data=put_payload,
|
||||
auth=requests.auth.HTTPBasicAuth(api_key, ''),
|
||||
timeout=StatusReporter._HTTP_REQUEST_TIMEOUT)
|
||||
"""
|
||||
|
|
|
@ -16,27 +16,27 @@ post_file() {
|
|||
mv "${file_path}" "${stripped_file_path}"
|
||||
file_path="${stripped_file_path}"
|
||||
filename="${file_path##*/}"
|
||||
|
||||
|
||||
airtime_conf_path=/etc/airtime/airtime.conf
|
||||
|
||||
|
||||
|
||||
#instance_path will look like 1/1384, for example
|
||||
http_path=$(grep base_url ${airtime_conf_path} | awk '{print $3;}' )
|
||||
http_port=$(grep base_port ${airtime_conf_path} | awk '{print $3;}' )
|
||||
|
||||
http_port=$(grep base_port ${airtime_conf_path} | awk '{print $3;}' )
|
||||
|
||||
#post request url - http://bananas.airtime.pro/rest/media, for example
|
||||
url=http://
|
||||
url+=$http_path
|
||||
url+=:
|
||||
url+=$http_port
|
||||
url+=/rest/media
|
||||
|
||||
|
||||
api_key=$(grep api_key ${airtime_conf_path} | awk '{print $3;}' )
|
||||
|
||||
|
||||
api_key=$(grep api_key ${airtime_conf_path} | awk '{print $3;}' )
|
||||
|
||||
# -f is needed to make curl fail if there's an HTTP error code
|
||||
# -L is needed to follow redirects! (just in case)
|
||||
until curl -fL --max-time 30 $url -u $api_key":" -X POST -F "file=@${file_path}"
|
||||
until curl -fL --max-time 30 $url -u $api_key":" -X POST -F "file=@${file_path}"
|
||||
do
|
||||
retry_count=$[$retry_count+1]
|
||||
if [ $retry_count -ge $max_retry ]; then
|
||||
|
|
|
@ -21,8 +21,8 @@ if ($argc <= 1)
|
|||
exit();
|
||||
}
|
||||
|
||||
$message = $argv[1];
|
||||
|
||||
$message = $argv[1];
|
||||
|
||||
$connection = new AMQPConnection(HOST, PORT, USER, PASS, VHOST);
|
||||
if (!isset($connection))
|
||||
{
|
||||
|
@ -31,10 +31,10 @@ if (!isset($connection))
|
|||
}
|
||||
|
||||
$channel = $connection->channel();
|
||||
|
||||
|
||||
// declare/create the queue
|
||||
$channel->queue_declare($queue, false, true, false, false);
|
||||
|
||||
|
||||
// declare/create the exchange as a topic exchange.
|
||||
$channel->exchange_declare($exchange, $exchangeType, false, true, false);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
post_file() {
|
||||
file_path=${1}
|
||||
filename="${file_path##*/}"
|
||||
|
||||
|
||||
#kill process after 30 minutes (360*5=30 minutes)
|
||||
max_retry=10
|
||||
retry_count=0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
|
||||
elsif bitrate == 32 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
|
||||
|
|
|
@ -16,7 +16,7 @@ def notify_stream(m)
|
|||
#escaping the apostrophe, and then starting a new string right after it. This is why we use 3 apostrophes.
|
||||
json_str = string.replace(pattern="'",(fun (s) -> "'\''"), json_str)
|
||||
command = "timeout --signal=KILL 45 pyponotify --webstream='#{json_str}' --media-id=#{!current_dyn_id} &"
|
||||
|
||||
|
||||
if !current_dyn_id != "-1" then
|
||||
log(command)
|
||||
system(command)
|
||||
|
@ -24,7 +24,7 @@ def notify_stream(m)
|
|||
end
|
||||
|
||||
# A function applied to each metadata chunk
|
||||
def append_title(m) =
|
||||
def append_title(m) =
|
||||
log("Using stream_format #{!stream_metadata_type}")
|
||||
|
||||
if list.mem_assoc("mapped", m) then
|
||||
|
@ -82,9 +82,9 @@ end
|
|||
|
||||
|
||||
# Define a transition that fades out the
|
||||
# old source, adds a single, and then
|
||||
# old source, adds a single, and then
|
||||
# plays the new source
|
||||
def to_live(old,new) =
|
||||
def to_live(old,new) =
|
||||
# Fade out old source
|
||||
old = fade.final(old)
|
||||
# Compose this in sequence with
|
||||
|
@ -233,7 +233,7 @@ def clear_queue(s)
|
|||
end
|
||||
|
||||
def set_dynamic_source_id(id) =
|
||||
current_dyn_id := id
|
||||
current_dyn_id := id
|
||||
string_of(!current_dyn_id)
|
||||
end
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ end
|
|||
# cue cut fix for liquidsoap <1.2.2
|
||||
#
|
||||
# This was most likely broken on 1.1.1 (debian) as well.
|
||||
#
|
||||
#
|
||||
# adapted from https://github.com/savonet/liquidsoap/issues/390#issuecomment-277562081
|
||||
#
|
||||
def fix_cue_in(~cue_in_metadata='liq_cue_in', m) =
|
||||
|
@ -80,9 +80,9 @@ def create_source()
|
|||
sources := list.append([l], !sources)
|
||||
server.register(namespace="queues",
|
||||
"s#{!source_id}_skip",
|
||||
fun (s) -> begin log("queues.s#{!source_id}_skip")
|
||||
clear_queue(l)
|
||||
"Done"
|
||||
fun (s) -> begin log("queues.s#{!source_id}_skip")
|
||||
clear_queue(l)
|
||||
"Done"
|
||||
end)
|
||||
source_id := !source_id + 1
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%mp3(bitrate = 24, stereo = true), !source))
|
||||
else
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
source := add(normalize=false, [amplify(0.00001, noise()), !source])
|
||||
end
|
||||
|
||||
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
||||
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%vorbis(quality=-0.1, channels = 2), !source))
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%opus(bitrate = 24, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
|
||||
elsif bitrate == 32 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
|
||||
|
|
|
@ -16,7 +16,7 @@ def notify_stream(m)
|
|||
#escaping the apostrophe, and then starting a new string right after it. This is why we use 3 apostrophes.
|
||||
json_str = string.replace(pattern="'",(fun (s) -> "'\''"), json_str)
|
||||
command = "timeout --signal=KILL 45 pyponotify --webstream='#{json_str}' --media-id=#{!current_dyn_id} &"
|
||||
|
||||
|
||||
if !current_dyn_id != "-1" then
|
||||
log(command)
|
||||
system(command)
|
||||
|
@ -24,7 +24,7 @@ def notify_stream(m)
|
|||
end
|
||||
|
||||
# A function applied to each metadata chunk
|
||||
def append_title(m) =
|
||||
def append_title(m) =
|
||||
log("Using stream_format #{!stream_metadata_type}")
|
||||
|
||||
if list.mem_assoc("mapped", m) then
|
||||
|
@ -82,9 +82,9 @@ end
|
|||
|
||||
|
||||
# Define a transition that fades out the
|
||||
# old source, adds a single, and then
|
||||
# old source, adds a single, and then
|
||||
# plays the new source
|
||||
def to_live(old,new) =
|
||||
def to_live(old,new) =
|
||||
# Fade out old source
|
||||
old = fade.final(old)
|
||||
# Compose this in sequence with
|
||||
|
@ -233,7 +233,7 @@ def clear_queue(s)
|
|||
end
|
||||
|
||||
def set_dynamic_source_id(id) =
|
||||
current_dyn_id := id
|
||||
current_dyn_id := id
|
||||
string_of(!current_dyn_id)
|
||||
end
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ end
|
|||
# cue cut fix for liquidsoap <1.2.2
|
||||
#
|
||||
# This was most likely broken on 1.1.1 (debian) as well.
|
||||
#
|
||||
#
|
||||
# adapted from https://github.com/savonet/liquidsoap/issues/390#issuecomment-277562081
|
||||
#
|
||||
def fix_cue_in(~cue_in_metadata='liq_cue_in', m) =
|
||||
|
@ -80,9 +80,9 @@ def create_source()
|
|||
sources := list.append([l], !sources)
|
||||
server.register(namespace="queues",
|
||||
"s#{!source_id}_skip",
|
||||
fun (s) -> begin log("queues.s#{!source_id}_skip")
|
||||
clear_queue(l)
|
||||
"Done"
|
||||
fun (s) -> begin log("queues.s#{!source_id}_skip")
|
||||
clear_queue(l)
|
||||
"Done"
|
||||
end)
|
||||
source_id := !source_id + 1
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%mp3(bitrate = 24, stereo = true), !source))
|
||||
else
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
source := add(normalize=false, [amplify(0.00001, noise()), !source])
|
||||
end
|
||||
|
||||
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
||||
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%vorbis(quality=-0.1, channels = 2), !source))
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%opus(bitrate = 24, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
|
||||
elsif bitrate == 32 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%mp3(bitrate = 24, stereo = true), !source))
|
||||
else
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
source := add(normalize=false, [amplify(0.00001, noise()), !source])
|
||||
end
|
||||
|
||||
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
||||
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%vorbis(quality=-0.1, channels = 2), !source))
|
||||
else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
if bitrate == 24 then
|
||||
if bitrate == 24 then
|
||||
if stereo then
|
||||
ignore(output_stereo(%opus(bitrate = 24, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue