Fix trailing whitespaces in files

This commit is contained in:
jo 2021-05-27 16:33:20 +02:00
parent 1af089219f
commit d8195f0fd8
46 changed files with 240 additions and 241 deletions

88
CREDITS
View File

@ -92,7 +92,7 @@ Martin Konecny (martin.konecny@sourcefabric.org)
James Moon (james.moon@sourcefabric.org)
Role: Software Developer
Denise Rigato (denise.rigato@sourcefabric.org)
Role: Software Developer
@ -124,7 +124,7 @@ Martin Konecny (martin.konecny@sourcefabric.org)
James Moon (james.moon@sourcefabric.org)
Role: Software Developer
Denise Rigato (denise.rigato@sourcefabric.org)
Role: Software Developer
@ -147,7 +147,7 @@ Naomi Aro (naomi.aro@sourcefabric.org)
James Moon (james.moon@sourcefabric.org)
Role: Software Developer
Denise Rigato (denise.rigato@sourcefabric.org)
Role: Software Developer
@ -198,7 +198,7 @@ Naomi Aro (naomi.aro@sourcefabric.org)
James Moon (james.moon@sourcefabric.org)
Role: Software Developer
Denise Rigato (denise.rigato@sourcefabric.org)
Role: Software Developer
@ -267,7 +267,7 @@ Martin Konecny (martin.konecny@sourcefabric.org)
James Moon (james.moon@sourcefabric.org)
Role: Software Developer
Yuchen Wang (yuchen.wang@sourcefabric.org)
Role: Software Developer
@ -350,10 +350,10 @@ Version 1.6.1
-------------
Same as previous version.
Version 1.6.0
Version 1.6.0
-------------
This version marks a major change to the project, completely replacing the
custom audio player with liquidsoap, dropping the custom desktop GUI, and
custom audio player with liquidsoap, dropping the custom desktop GUI, and
completely rewriting the web interface. The project has also been renamed
from "Campcaster" to "Airtime" for this release.
@ -361,11 +361,11 @@ Paul Baranowski (paul.baranowski@sourcefabric.org)
Role: Project Lead / Software Developer
Highlights:
- Integration and development of liquidsoap scheduler
- Separation of playlists from the scheduler
- Separation of playlists from the scheduler
Naomi Aro (naomi.aro@sourcefabric.org)
Role: Software Developer
Highlights:
Highlights:
- New User Interface
- Conversion to Propel DB backend
@ -397,44 +397,44 @@ generated radio station based in Basel, Switzerland powered by Campcaster. We ar
very grateful for their contributions, and specifically to Thomas Gilgen, Dirk Claes,
Rigzen Latshang and Fabiano Sidler.
Douglas Arellanes
Douglas Arellanes
- Tester and user feedback
Robin Gareus
Robin Gareus
- Packaging
Ferenc Gerlits
Ferenc Gerlits
- Studio GUI
Sebastian Göbel
Sebastian Göbel
- Web interface, storage server
Nebojsa Grujic
Nebojsa Grujic
- Scheduler, XML-RPC interface, Gstreamer plugins
Tomáš Hlava
Tomáš Hlava
- Bug fixes
Sava Tatić
Sava Tatić
- Manager
Version 1.3.0 - "Dakar"
-----------------------
Douglas Arellanes
Douglas Arellanes
- Tester and user feedback
Ferenc Gerlits
Ferenc Gerlits
- Studio GUI, scheduler, packaging
Sebastian Göbel
Sebastian Göbel
- Web interface
Tomáš Hlava
Tomáš Hlava
- Bug fixes
Sava Tatić
Sava Tatić
- Manager
@ -442,19 +442,19 @@ Version 1.2.0 - "Kotor"
-----------------------
In alphabetical order:
Douglas Arellanes
Douglas Arellanes
- Tester and user feedback
Paul Baranowski
Paul Baranowski
- Project manager, HTML UI, storage server
Ferenc Gerlits
Ferenc Gerlits
- Studio GUI, scheduler, packaging
Tomáš Hlava
Tomáš Hlava
- Bug fixes
Robert Klajn
- Superuser feedback
Mark Kretschmann
Robert Klajn
- Superuser feedback
Mark Kretschmann
- Audio player
Sava Tatić
Sava Tatić
- Manager
@ -462,40 +462,40 @@ Version 1.1.X - "Freetown"
--------------------------
In alphabetical order:
Douglas Arellanes
Douglas Arellanes
- Tester and user feedback
Paul Baranowski
Paul Baranowski
- Project manager, HTML UI, storage server, scheduler
János Csikós
János Csikós
- HTML UI
Ferenc Gerlits
Ferenc Gerlits
- Studio GUI, scheduler, packaging
Tomáš Hlava
Tomáš Hlava
- Storage server, network hub
Mark Kretschmann
Mark Kretschmann
- Audio player
Ákos Maróy
Ákos Maróy
- Architecture design, scheduler, audio player
Sava Tatić
- Manager
Version 1.0
-----------
The original Campcaster (LiveSupport) concept was drafted by Micz Flor. It was
fully developed by Robert Klajn, Douglas Arellanes, Ákos Maróy, and Sava Tatić.
The user interface has been designed by Charles Truett, based on the initial work
done by a team of his then-fellow Parsons School of Design students Turi McKinley,
Catalin Lazia and Sangita Shah. The team was led by then-head of the school's
The original Campcaster (LiveSupport) concept was drafted by Micz Flor. It was
fully developed by Robert Klajn, Douglas Arellanes, Ákos Maróy, and Sava Tatić.
The user interface has been designed by Charles Truett, based on the initial work
done by a team of his then-fellow Parsons School of Design students Turi McKinley,
Catalin Lazia and Sangita Shah. The team was led by then-head of the school's
Department of Digital Design Colleen Macklin, assisted by Kunal Jain.
In alphabetical order:
Douglas Arellanes
Michael Aschauer
Micz Flor
Michael Aschauer
Micz Flor
Ferenc Gerlits
Sebastian Göbel
Tomáš Hlava
Nadine Kokot
Ákos Maróy
Ákos Maróy
Sava Tatić
Charles Truett

View File

@ -49,14 +49,14 @@
* Much faster library import (Silan analyzer runs in background)
* Fixed zombie process sometimes being created
* Other
* Upgrade to Mutagen (tag reader) 1.21
* Upgrade to Mutagen (tag reader) 1.21
2.3.0 - Jan 21st, 2013
* New features
* Localization (Chinese, Czech, English, French, German, Italian, Korean,
Portuguese, Russian, Spanish)
* User management page for non-admin users
* Listener statistics (Icecast/Shoutcast)
* Listener statistics (Icecast/Shoutcast)
* Airtime no longer requires Apache document root
* Replay Gain offset in real-time
* Enable/disable replay gain
@ -113,7 +113,7 @@
* Playlist Builder should remember your position instead of resetting to the first page every time an operation was performed
* If Master or Live input source is disconnected, Airtime will no longer automatically switch off that source. This should allow the source to
reconnect and continue playback.
* Bug fixes
* Fixed playout engine sometimes not receiving new schedule which could result in dead air
* Fixed script timeout which caused Apache to become unresponsive
@ -174,7 +174,7 @@
* Fixed Airtime could stop automatically recording after 2 hours if the web interface isn't used.
* Fixed upgrading from 1.8.2 when the stor directory was a symlink would cause filenames to not be preserved.
* Fixed Day View in the Now Playing tab showed some items on incorrect days.
* Fixed problems with having an equal '=' sign as an icecast password
* Fixed problems with having an equal '=' sign as an icecast password
* Other
* Various optimizations to make Airtime feel snappier in the browser. Various views should
load much quicker.
@ -295,11 +295,11 @@
- Fixed pypo hanging if web server is unavailable
- Fixed items that were being dragged and dropped in the Playlist Builder
being obscured by other UI elements.
1.9.3 - August 26th, 2011
* Improvements
- It is now possible to upgrade your system while a show is playing.
Playout will be temporarily interrupted for about 5-10 seconds and then
Playout will be temporarily interrupted for about 5-10 seconds and then
playout will resume. Previously playout would not resume until the next
scheduled show.
* Fixes
@ -324,7 +324,7 @@
- Prevent users from doing a manual install of Airtime if they already have
the Debian package version installed
* Changes
- Support Settings moved to a separate page accessible by Admin user only.
- Support Settings moved to a separate page accessible by Admin user only.
1.9.0 - August 9, 2011
@ -333,20 +333,20 @@ The cool stuff:
- Human-readable file structure. The directory structure and file names on
disk are now human-readable. This means you can easily find files using
your file browser on your server.
- Magic file synchronization. Edits to your files are automatically
- Magic file synchronization. Edits to your files are automatically
noticed by Airtime. If you edit any files on disk, such as trimming the
length of a track, Airtime will automatically notice this and adjust the
playlist lengths and shows for that audio file.
- Auto-import and multiple-directory support. You can set any number of
directories to be watched by Airtime. Any new files you add to watched
- Auto-import and multiple-directory support. You can set any number of
directories to be watched by Airtime. Any new files you add to watched
directories will be automatically imported into Airtime, and any deleted
files will be automatically removed.
- The "airtime-import" command line tool can now set watched directories
- The "airtime-import" command line tool can now set watched directories
and change the storage directory.
- Graceful recovery from reboot. If the playout engine starts up and
detects that a show should be playing at the current time, it will skip
to the right point in the track and start playing. Previously, Airtime
would not play anything until the next show started. This also fixes a
to the right point in the track and start playing. Previously, Airtime
would not play anything until the next show started. This also fixes a
problem where the metadata on the stream was lost when a file had
cue-in/out values set. Thanks to the Liquidsoap developers for
implementing the ability to do all of this!
@ -354,28 +354,28 @@ The cool stuff:
- A new "Program Manager" role. A program manager can create shows but
can't change the preferences or modify users.
- No more rebooting after install! Airtime now uses standard SystemV initd
scripts instead of non-standard daemontools. This also makes for a much
scripts instead of non-standard daemontools. This also makes for a much
faster install.
- Frontend widgets are much easier to use and their theme can be modified
- Frontend widgets are much easier to use and their theme can be modified
with CSS (Click here for more info and installation instructions).
- Improved installation - only one command to install on Ubuntu!
* Improvements:
- Cumulative time shown on playlists. The Playlist Builder now shows the
- Cumulative time shown on playlists. The Playlist Builder now shows the
total time since the beginning of the playlist for each song.
- "End Time" instead of "Duration". In the Add/Edit Show dialog, we
- "End Time" instead of "Duration". In the Add/Edit Show dialog, we
replaced the "Duration" field with "End Time". Users reported that this
was a much more intuitive way to schedule the show. Duration is still
shown as a read-only field.
- Feedback & promotion system. Airtime now includes a way to send feedback
and promote your site on the Sourcefabric web page. This will greatly
enhance our ability to understand who is using the software, which in
turn will allow us to make appropriate features and receive grant
and promote your site on the Sourcefabric web page. This will greatly
enhance our ability to understand who is using the software, which in
turn will allow us to make appropriate features and receive grant
funding.
- The show recorder can now instantly cancel a show thanks to the use of
RabbitMQ.
- Only admins have the ability to delete files now.
- The playout engine now runs with a higher priority. This should help
- The playout engine now runs with a higher priority. This should help
prevent any problems with audio skipping.
- Airtime has been contained. It is now easier to run other apps on the
same system with Airtime because it no longer messes with the system-wide
@ -386,12 +386,12 @@ The cool stuff:
page( above the search box).
* Bug fixes:
- Fixed bug where you couldn't import a file with a name longer than 255
- Fixed bug where you couldn't import a file with a name longer than 255
characters.
- Fixed bug where searching an audio archive of 15K+ files was slow.
- Fixed bug where upgrading from more than one version back
(e.g. 1.8.0 -> 1.9.0) did not work.
- Fixed bug where the wrong file length was reported for very large CBR
- Fixed bug where the wrong file length was reported for very large CBR
mp3 files (thanks to mutagen developers for the patch!)
1.8.2 - June 8, 2011
@ -456,30 +456,30 @@ Highlights:
1.8.0 - April 19, 2011
* The biggest feature of this release is the ability to edit shows. You can
change everything from Name, Description, and URL, to repeat and
change everything from Name, Description, and URL, to repeat and
rebroadcast days. Show instances will be dynamically created or removed as
needed. Radio stations will be pleased to know they can now have up to
needed. Radio stations will be pleased to know they can now have up to
ten rebroadcast shows too.
* Airtimes calendar now looks, feels and performs better than ever. Loading
a station schedule is now five to eight times faster. In our tests of 1.7,
if the month calendar had shows scheduled for every hour of every day, it
a station schedule is now five to eight times faster. In our tests of 1.7,
if the month calendar had shows scheduled for every hour of every day, it
used to take 16 seconds to load. Now in 1.8 it takes two seconds.
* It is possible to have up to ten rebroadcast shows now, in 1.7 it was only
up to five.
* Airtimes new installation script has two options for increased install
flexibility: --preserve to keep your existing config files, or --overwrite
to replace your existing config files with new ones. Uninstall no longer
* Airtimes new installation script has two options for increased install
flexibility: --preserve to keep your existing config files, or --overwrite
to replace your existing config files with new ones. Uninstall no longer
removes Airtime config files or the music storage directory.
* New improved look & feel of the calendar (thanks to the "FullCalendar"
* New improved look & feel of the calendar (thanks to the "FullCalendar"
jQuery project).
* Installation now puts files in standard locations in the Linux file
* Installation now puts files in standard locations in the Linux file
hierarchy, which prepares the project to be accepted into Ubuntu and Debian.
Also because of our wish to be part of those projects, the default output
stream type is now OGG instead of MP3 -- due to MP3 licensing issues.
Also because of our wish to be part of those projects, the default output
stream type is now OGG instead of MP3 -- due to MP3 licensing issues.
This configuration can be changed in "/etc/airtime/liquidsoap.conf".
* You now have the ability to start and stop pypo and the show recorder from
the command line with the commands "airtime-pypo-start",
"airtime-pypo-stop", "airtime-show-recorder-start", and
* You now have the ability to start and stop pypo and the show recorder from
the command line with the commands "airtime-pypo-start",
"airtime-pypo-stop", "airtime-show-recorder-start", and
"airtime-show-recorder-stop".
* Bug fixes:
- CC-2192 Schedule sent to pypo is not sorted by start time.
@ -520,7 +520,7 @@ Highlights:
* Bug fixes:
- CC-2082 OGG stream dies after every song when using MPlayer
- CC-1894 Warn users about time zone differences or clock drift problems on
the server
the server
- CC-2058 Utilities are not in the system $PATH
- CC-2051 Unable to change user password
- CC-2030 Icon needed for Cue In/Out
@ -531,7 +531,7 @@ Bug fixes:
* CC-1973 Liquidsoap crashes after multi-day playout
* CC-1970 API key fix (Security fix) - Each time you run the install scripts,
a new API key is now generated.
* CC-1992 Editing metadata goes blank on 'submit'
* CC-1992 Editing metadata goes blank on 'submit'
* CC-1993 ui start time and song time unsynchronized
1.6.0 - Feb 14, 2011

View File

@ -7,5 +7,5 @@ To update the Airtime translations:
- Commit the updated files.
- Push to GitHub.
- Transifex will then pick up the updated files in about 24 hours, and they'll be available for translation there.
- After translators have updated strings, they'll be automatically downloaded and committed to our git repo by
- After translators have updated strings, they'll be automatically downloaded and committed to our git repo by
a script running here at Sourcefabric (contact Andrey).

View File

@ -1,13 +1,13 @@
<?PHP
/*
/*
The purpose of this script is to take a file from cc_files table, and insert it into
the schedule table. DB columns at the time of writing are
starts | ends | file_id | clip_length | fade_in | fade_out | cue_in | cue_out | media_item_played | instance_id
an example of data in this row is:
"9" | "2012-02-29 17:10:00" | "2012-02-29 17:15:05.037166" | 1 | "00:05:05.037166" | "00:00:00" | "00:00:00" | "00:00:00" | "00:05:05.037166" | FALSE | 5
@ -19,25 +19,25 @@ function query($conn, $query){
echo "Error executing query $query.\n";
exit(1);
}
return $result;
}
function getFileFromCcFiles($conn){
$query = "SELECT * from cc_files LIMIT 2";
$result = query($conn, $query);
$files = array();
while ($row = pg_fetch_array($result)) {
$files[] = $row;
}
if (count($files) == 0){
echo "Library is empty. Could not choose random file.";
exit(1);
}
return $files;
}
@ -60,7 +60,7 @@ function insertIntoCcShow($conn){
while ($row = pg_fetch_array($result)) {
$show_id = $row["currval"];
}
return $show_id;
}
@ -70,7 +70,7 @@ function insertIntoCcShowInstances($conn, $show_id, $starts, $ends, $files){
* Column values:
* starts | ends | show_id | record | rebroadcast | instance_id | file_id | time_filled | last_scheduled | modified_instance
* */
$nowDateTime = new DateTime("now", new DateTimeZone("UTC"));
$now = $nowDateTime->format("Y-m-d H:i:s");
@ -79,7 +79,7 @@ function insertIntoCcShowInstances($conn, $show_id, $starts, $ends, $files){
$values = "('$starts', '$ends', $show_id, 0, 0, NULL, NULL, TIMESTAMP '$ends' - TIMESTAMP '$starts', '$now', 'f')";
$query = "INSERT INTO cc_show_instances $columns values $values ";
echo $query.PHP_EOL;
$result = query($conn, $query);
$query = "SELECT currval('cc_show_instances_id_seq');";
@ -92,7 +92,7 @@ function insertIntoCcShowInstances($conn, $show_id, $starts, $ends, $files){
while ($row = pg_fetch_array($result)) {
$show_instance_id = $row["currval"];
}
return $show_instance_id;
}
@ -102,9 +102,9 @@ function insertIntoCcShowInstances($conn, $show_id, $starts, $ends, $files){
*/
function insertIntoCcSchedule($conn, $files, $show_instance_id, $p_starts, $p_ends){
$columns = "(starts, ends, file_id, clip_length, fade_in, fade_out, cue_in, cue_out, media_item_played, instance_id)";
$starts = $p_starts;
foreach($files as $file){
$endsDateTime = new DateTime($starts, new DateTimeZone("UTC"));
@ -115,9 +115,9 @@ function insertIntoCcSchedule($conn, $files, $show_instance_id, $p_starts, $p_en
$values = "('$starts', '$ends', $file[id], '$file[length]', '00:00:00', '00:00:00', '00:00:00', '$file[length]', 'f', $show_instance_id)";
$query = "INSERT INTO cc_schedule $columns VALUES $values";
echo $query.PHP_EOL;
$starts = $ends;
$result = query($conn, $query);
$result = query($conn, $query);
}
}
@ -131,7 +131,7 @@ function getEndTime($startDateTime, $p_files){
foreach ($p_files as $file){
$startDateTime->add(getDateInterval($file['length']));
}
return $startDateTime;
}
@ -142,7 +142,7 @@ function rabbitMqNotify(){
echo "Contacting $url".PHP_EOL;
$ch = curl_init($url);
curl_exec($ch);
curl_close($ch);
curl_close($ch);
}
$conn = pg_connect("host=localhost port=5432 dbname=airtime user=airtime password=airtime");
@ -152,9 +152,9 @@ if (!$conn) {
}
if (count($argv) > 1){
if ($argv[1] == "--clean"){
if ($argv[1] == "--clean"){
$tables = array("cc_schedule", "cc_show_instances", "cc_show");
foreach($tables as $table){
$query = "DELETE FROM $table";
echo $query.PHP_EOL;
@ -162,9 +162,9 @@ if (count($argv) > 1){
}
rabbitMqNotify();
exit(0);
} else {
} else {
$str = <<<EOD
This script schedules a file to play 30 seconds in the future. It
This script schedules a file to play 30 seconds in the future. It
modifies the database tables cc_schedule, cc_show_instances and cc_show.
You can clean up these tables using the --clean option.
EOD;
@ -178,7 +178,7 @@ $startDateTime = new DateTime("now + 30sec", new DateTimeZone("UTC"));
$starts = $startDateTime->format("Y-m-d H:i:s");
//$ends = $endDateTime->format("Y-m-d H:i:s");
$files = getFileFromCcFiles($conn);
$files = getFileFromCcFiles($conn);
$show_id = insertIntoCcShow($conn);
$endDateTime = getEndTime(clone $startDateTime, $files);

View File

@ -30,7 +30,7 @@ class AirtimeMediaMonitorBootstrap:
config = ConfigObj("/etc/airtime/airtime.conf")
self.api_client = apc.api_client_factory(config)
"""
"""
try:
logging.config.fileConfig("logging.cfg")
except Exception, e:

View File

@ -90,7 +90,7 @@ fi
rm -rf liquidsoap-full
git clone https://github.com/savonet/liquidsoap-full
cd liquidsoap-full
git checkout master
git checkout master
make init
make update

View File

@ -26,7 +26,7 @@ build_env () {
echo "Please use -u to assign sudo username before build environments."
exit 1
fi
echo "build_env $1"
#exec > >(tee ./liquidsoap_compile_logs/build_env_$1.log)
os=`echo $1 | awk '/(debian)/'`
@ -40,7 +40,7 @@ build_env () {
useradd tmp
echo "User tmp is created."
fi
apt-get update
apt-get --force-yes -y install debootstrap dchroot
echo [$1] > /etc/schroot/chroot.d/$1.conf
@ -87,7 +87,7 @@ compile_liq () {
else
mv ./liquidsoap-compile_logs/compile_liq_$1.log ./liquidsoap-compile_logs/fail_to_compile_liq_$1.log
fi
}
}
os_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_precise_32" "ubuntu_precise_64" "ubuntu_quantal_32" "ubuntu_quantal_64" "ubuntu_raring_32" "ubuntu_raring_64" "debian_squeeze_32" "debian_squeeze_64" "debian_wheezy_32" "debian_wheezy_64")
@ -147,7 +147,7 @@ do
compile_liq ${os_versions[$i]} | tee ./liquidsoap-compile_logs/compile_liq_${os_versions[$i]}.log
flag=0
fi
done
done
if [ $flag = 1 ];then
echo "Unsupported Platform from:"
for k in "${os_versions[@]}"

View File

@ -74,7 +74,7 @@ tar -czf $target_file \
--exclude dev_tools \
--exclude vendor/phing \
--exclude vendor/simplepie/simplepie/tests \
libretime-${suffix}
libretime-${suffix}
echo " Done"
popd

View File

@ -1,5 +1,5 @@
[merge "pofile"]
name = Gettext merge driver
driver = git merge-po %O %A %B

View File

@ -1,6 +1,6 @@
#!/bin/sh
#
# https://gist.github.com/mezis/1605647
# https://gist.github.com/mezis/1605647
# by Julien Letessier (mezis)
#
# Custom Git merge driver - merges PO files using msgcat(1)
@ -8,15 +8,15 @@
# - Install gettext
#
# - Place this script in your PATH
#
#
# - Add this to your .git/config :
#
# [merge "pofile"]
# name = Gettext merge driver
# driver = git merge-po %O %A %B
#
#
# - Add this to .gitattributes :
#
#
# *.po merge=pofile
# *.pot merge=pofile
#

View File

@ -5,7 +5,7 @@ if [[ $EUID -ne 0 ]]; then
fi
usage () {
echo "Use --enable <user> or --disable flag. Enable is to set up environment"
echo "Use --enable <user> or --disable flag. Enable is to set up environment"
echo "for specified user. --disable is to reset it back to pypo user"
}
@ -28,7 +28,7 @@ elif [ "$1" = "--disable" ]; then
echo "Changing ownership to user $1"
chmod 644 /etc/airtime/airtime.conf
chown -Rv $user:$user /var/tmp/airtime/pypo/
chmod -v a+r /etc/airtime/api_client.cfg
chmod -v a+r /etc/airtime/api_client.cfg
/etc/init.d/airtime-playout stop-liquidsoap

View File

@ -4,13 +4,13 @@
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<!-- Custom fonts, icons for this template -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" rel="stylesheet" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Merriweather:400,300,300italic,400italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'>
<!-- Custom styles for this template -->
<link href="/css/creative.min.css" rel="stylesheet">
<title>{{ site.title }} - {{ page.title }}</title>

View File

@ -1,6 +1,6 @@
<nav class="navbar navbar-expand-lg navbar-light fixed-top navbar-shrink" id="mainNav">
<div class="container">
<a class="navbar-brand js-scroll-trigger" href="/index">
<a class="navbar-brand js-scroll-trigger" href="/index">
{{ site.title }} </a>
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>

View File

@ -8,11 +8,11 @@
<script>
// Set a variable for our button element.
const scrollToTopButton = document.getElementById('js-top');
const scrollFunc = () => {
// Get the current scroll value
let y = window.scrollY;
// If the scroll value is greater than the window height, let's add a class to the scroll-to-top button to show it!
if (y > 0) {
scrollToTopButton.className = "top-link show";
@ -24,7 +24,7 @@
const scrollToTop = () => {
// Let's set a variable for the number of pixels we are from the top of the document.
const c = document.documentElement.scrollTop || document.body.scrollTop;
// If that number is greater than 0, we'll scroll back to 0, or the top of the document.
// We'll also animate that scroll with requestAnimationFrame:
// https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
@ -41,4 +41,3 @@
scrollToTop();
}
</script>

View File

@ -1,14 +1,14 @@
---
layout: default
---
<!-- Promo Section -->
<section class="bg-primary">
<div class="container">
<div class="d-flex mh-25rem pt-11 py-6">
<div class="align-self-center">
<h1 class="text-white font-weight-light mb-3">{{ page.title }}</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb breadcrumb-light">
<li class="breadcrumb-item"><a href="/">Home</a></li>
@ -20,7 +20,7 @@ layout: default
</div>
</div>
</div>
<!-- SVG BG -->
<svg class="position-absolute bottom-0 left-0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1920 323" enable-background="new 0 0 1920 323" xml:space="preserve">
<polygon fill="#ffffff" style="fill-opacity: .05;" points="-0.5,322.5 -0.5,121.5 658.3,212.3 "></polygon>

View File

@ -2,13 +2,13 @@
<html lang="en">
<head>
{% include head.html %}
</head>
<body id="page-top">
<!-- Navigation -->
{% include navbar.html %}
<!-- Scroll to Top link -->
<a class="top-link hide" href="" id="js-top">
<svg class="bi bi-arrow-up-circle-fill" width="4em" height="4em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
@ -16,9 +16,9 @@
</svg>
<span class="screen-reader-text">Back to top</span>
</a>
{{content}}
{% include footer.html %}
{% include scripts.html %}

View File

@ -1,7 +1,7 @@
---
layout: default
---
<style>
header.masthead {
padding-top: 10rem;
@ -27,7 +27,7 @@ layout: default
</div>
</div>
</header>
<!-- Features Block -->
<section id="features">
<div class="container">
@ -150,7 +150,7 @@ layout: default
</div>
</div>
</section>
<!-- "Our Biggest Fans" Section -->
<section class="" id="biggest-fans">
<div class="container text-center">

View File

@ -1,40 +1,40 @@
/*!
* Start Bootstrap - Libretime v1.0.0 ()
* Copyright 2013-2018
* Copyright 2013-2018
* Licensed under MIT (https://github.com/BlackrockDigital/libretime-website/blob/master/LICENSE)
*/
body,html{
width:100%;height:100%
}
body{
font-family:Merriweather,'Helvetica Neue',Arial,sans-serif;
padding-top: 57px;
}
hr{
max-width:auto;border-width:2px;border-color:#f05f40
}
hr.light{
border-color:#fff
}
img{
width:100%;
max-width: 600px;
}
a{
color:#f05f40;
-webkit-transition:all .2s;
transition:all .2s;
}
a:hover{
color:#f05f40
}
h1,h2,h3,h4,h5,h6{
font-family:'Open Sans','Helvetica Neue',Arial,sans-serif;
}
@ -58,34 +58,34 @@ th{
text-align: center;
color: white;
}
tr, td{
padding: 5px;
text-align: left;
border: 2px solid #f05f40
}
/* Theme Colors */
/* Theme Colors */
.bg-primary{
background-color:#f05f40!important
}
.bg-dark{
background-color:#212529!important
}
.footer-dark{
background-color:#212529!important;
padding:2rem 0
}
.text-faded{
color:rgba(255,255,255,.9)
}
div.text-footer{
text-align: center;
}
}
/* Changed padding */
section{padding:2rem 0}
@ -98,7 +98,7 @@ img::-moz-selection{color:#fff;background:0 0}
#mainNav{
border-bottom:1px solid rgba(33,37,41,.1);background-color:#fff;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif;-webkit-transition:all .2s;transition:all .2s
}
}
#mainNav .navbar-brand{
font-weight:700;
@ -106,7 +106,7 @@ img::-moz-selection{color:#fff;background:0 0}
color:#f05f40;
font-family:'Open Sans','Helvetica Neue',Arial,sans-serif
}
#mainNav .navbar-brand:focus,
#mainNav .navbar-brand:hover{color:#f05f40}
#mainNav .navbar-nav>li.nav-item>a.nav-link,
@ -123,7 +123,7 @@ img::-moz-selection{color:#fff;background:0 0}
@media (min-width:992px){
#mainNav{border-color:transparent;background-color:transparent
}
#mainNav .navbar-brand{color:rgba(255,255,255,.7)}
#mainNav .navbar-brand:focus,#mainNav .navbar-brand:hover{color:#fff}
#mainNav .navbar-nav>li.nav-item>a.nav-link{padding:.5rem 1rem}
@ -204,7 +204,7 @@ header.masthead p{font-weight:300}
.btn-primary:active,.btn-primary:focus{
-webkit-box-shadow:0 0 0 .2rem rgba(240,95,64,.5)!important;box-shadow:0 0 0 .2rem rgba(240,95,64,.5)!important
}
.btn-outline-full-width{border:1px solid #888;margin:5px;width:100%}
/* Blockquotes */
@ -215,12 +215,12 @@ font-size: .9rem;
margin: 10px;
padding: 10px 20px;
}
blockquote p {
margin: 0;
line-height: 25px;
}
blockquote .small {
display: block;
font-size: 80%;
@ -250,7 +250,7 @@ padding: 10px 20px;
bottom: 0;
right: 0;
display: inline-flex;
cursor: pointer;
align-items: center;
justify-content: center;
@ -266,7 +266,7 @@ padding: 10px 20px;
visibility: visible;
opacity: 1;
}
.hide {
visibility: hidden;
opacity: 0;
@ -283,12 +283,12 @@ padding: 10px 20px;
overflow: hidden;
word-wrap: normal !important;
clip: rect(1px, 1px, 1px, 1px);
&:focus {
display: block;
top: 5px;
left: 5px;
z-index: 100000;
z-index: 100000;
clip-path: none;
background-color: #eee;
padding: 15px 23px 14px;

View File

@ -139,4 +139,4 @@ title: Docs
</div>
</section>
</main>

View File

@ -8,7 +8,7 @@ title: Search
<div class="d-flex mh-25rem pt-11 py-6">
<div class="align-self-center">
<h1 class="text-white font-weight-light mb-3">{{ page.title }}</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb breadcrumb-light">
<li class="breadcrumb-item"><a href="/">Home</a></li>

View File

@ -22,7 +22,7 @@ echo "...Done"
set -e
###
# ! NOTE: If you run into errors resolving the archives when running apt-get update,
# ! NOTE: If you run into errors resolving the archives when running apt-get update,
# clear your /var/cache/lxc directory and retry.
###

View File

@ -31,7 +31,7 @@ patch -f /var/lib/pgsql/data/pg_hba.conf << EOD
--- pg_hba.conf.orig 2020-12-19 13:10:46.828960307 +0000
+++ pg_hba.conf 2020-12-19 13:11:37.356290128 +0000
@@ -78,10 +78,11 @@
# "local" is for Unix domain socket connections only
local all all peer
+local all all md5
@ -153,7 +153,7 @@ echo 'date.timezone=Europe/Zurich' >> /etc/php.d/timezone.ini
systemctl restart httpd
# icecast needs to be available to everyone
sed -i -e 's@<bind-address>127.0.0.1</bind-address>@<bind-address>0.0.0.0</bind-address>@' /etc/icecast.xml
sed -i -e 's@<bind-address>127.0.0.1</bind-address>@<bind-address>0.0.0.0</bind-address>@' /etc/icecast.xml
systemctl enable --now icecast
# let em use alsa

View File

@ -21,9 +21,9 @@ endobj
endobj
7 0 obj
<<
/AIMetaData 9 0 R /AIPrivateData1 10 0 R /AIPrivateData2 8 0 R /CreatorVersion 15
/ContainerVersion 9
/RoundtripVersion 15
/AIMetaData 9 0 R /AIPrivateData1 10 0 R /AIPrivateData2 8 0 R /CreatorVersion 15
/ContainerVersion 9
/RoundtripVersion 15
/NumBlock 2 >>
endobj
9 0 obj
@ -43,7 +43,7 @@ stream
%AI3_TileBox:0 0 246 -68
%AI3_TemplateBox:123 -34 123 -34
%AI3_DocumentPreview: None
%AI5_ArtSize: 246 68
%AI5_ArtSize: 246 68
%AI5_NumLayers: 1
%AI5_FileFormat 2.0
%AI9_ColorModel: 2

View File

@ -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

View File

@ -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)
"""

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -41,7 +41,7 @@ function exitIfNotRoot()
function printUsage($userMsg = "")
{
global $opts;
$msg = $opts->getUsageMessage();
if (strlen($userMsg)>0)
echo $userMsg;
@ -64,11 +64,11 @@ function viewSpecificLog($key){
} else printUsage();
}
function dumpAllLogs(){
function dumpAllLogs(){
$dateStr = gmdate("Y-m-d-H-i-s");
$dir = getcwd();
$filename = "$dir/airtime-log-all-$dateStr.tgz";
echo "Creating Airtime logs tgz file at $filename";
$command = "tar cfz $filename /var/log/airtime 2>/dev/null";
@ -82,7 +82,7 @@ function dumpSpecificLog($key){
$dateStr = gmdate("Y-m-d-H-i-s");
$dir = getcwd();
$filename = "$dir/airtime-log-$key-$dateStr.tgz";
echo "Creating Airtime logs tgz file at $filename";
$dir = dirname($log_files[$key]);
@ -104,7 +104,7 @@ function tailSpecificLog($key){
if (isKeyValid($key)){
echo "Tail $key log";
pcntl_exec(exec("which tail"), array("-F", $log_files[$key]));
pcntl_wait($status);
pcntl_wait($status);
} else printUsage();
}

View File

@ -4,7 +4,7 @@
# database and set appropriate tags to each MP3 file.
# Notes:
# 1 - Rivendell store files in .wav format, airtime uses .mp3 format
# 1 - Rivendell store files in .wav format, airtime uses .mp3 format
# 2 - WAV does not have Meta-tag support so all meta-tags need to be fetched from Rivendell database.