Permalink
Browse files

Merge branch 'devel'

  • Loading branch information...
2 parents 968c308 + ceea384 commit 6f1d9082b57c17b4e355635dbc8df1c6797b225e James committed Aug 9, 2011
Showing with 9,066 additions and 7,624 deletions.
  1. +1 −1 .gitignore
  2. +13 −12 .zfproject.xml
  3. +4 −0 CREDITS
  4. +71 −2 Changelog
  5. +101 −36 LICENSE_3RD_PARTY
  6. +1 −1 VERSION
  7. +1 −0 airtime_mvc/application/Bootstrap.php
  8. +2 −1 airtime_mvc/application/configs/ACL.php
  9. +14 −0 airtime_mvc/application/configs/classmap-airtime-conf.php
  10. +1 −5 airtime_mvc/application/configs/conf.php
  11. +26 −14 airtime_mvc/application/configs/constants.php
  12. +6 −0 airtime_mvc/application/configs/navigation.php
  13. +289 −65 airtime_mvc/application/controllers/ApiController.php
  14. +55 −52 airtime_mvc/application/controllers/LibraryController.php
  15. +4 −1 airtime_mvc/application/controllers/LoginController.php
  16. +74 −0 airtime_mvc/application/controllers/NowplayingController.php
  17. +3 −3 airtime_mvc/application/controllers/PlaylistController.php
  18. +11 −2 airtime_mvc/application/controllers/PluploadController.php
  19. +136 −12 airtime_mvc/application/controllers/PreferenceController.php
  20. +49 −18 airtime_mvc/application/controllers/ScheduleController.php
  21. +85 −50 airtime_mvc/application/forms/AddShowWhen.php
  22. +1 −1 airtime_mvc/application/forms/AddShowWho.php
  23. +2 −1 airtime_mvc/application/forms/AddUser.php
  24. +11 −4 airtime_mvc/application/forms/EditAudioMD.php
  25. +5 −4 airtime_mvc/application/forms/GeneralPreferences.php
  26. +1 −2 airtime_mvc/application/forms/PlaylistMetadata.php
  27. +5 −2 airtime_mvc/application/forms/Preferences.php
  28. +147 −0 airtime_mvc/application/forms/RegisterAirtime.php
  29. +151 −0 airtime_mvc/application/forms/SupportPreferences.php
  30. +51 −0 airtime_mvc/application/forms/WatchedDirPreferences.php
  31. +2 −2 airtime_mvc/application/layouts/scripts/library.phtml
  32. +8 −2 airtime_mvc/application/models/Dashboard.php
  33. +30 −0 airtime_mvc/application/models/DateHelper.php
  34. +312 −0 airtime_mvc/application/models/MusicDir.php
  35. +97 −45 airtime_mvc/application/models/Nowplaying.php
  36. +29 −6 airtime_mvc/application/models/Playlist.php
  37. +179 −1 airtime_mvc/application/models/Preference.php
  38. +34 −5 airtime_mvc/application/models/RabbitMq.php
  39. +51 −20 airtime_mvc/application/models/Schedule.php
  40. +61 −3 airtime_mvc/application/models/Shows.php
  41. +423 −1,384 airtime_mvc/application/models/StoredFile.php
  42. +67 −3 airtime_mvc/application/models/Users.php
  43. +18 −0 airtime_mvc/application/models/airtime/CcCountry.php
  44. +18 −0 airtime_mvc/application/models/airtime/CcCountryPeer.php
  45. +18 −0 airtime_mvc/application/models/airtime/CcCountryQuery.php
  46. +18 −0 airtime_mvc/application/models/airtime/CcMusicDirs.php
  47. +18 −0 airtime_mvc/application/models/airtime/CcMusicDirsPeer.php
  48. +18 −0 airtime_mvc/application/models/airtime/CcMusicDirsQuery.php
  49. +52 −0 airtime_mvc/application/models/airtime/map/CcCountryTableMap.php
  50. +3 −0 airtime_mvc/application/models/airtime/map/CcFilesTableMap.php
  51. +55 −0 airtime_mvc/application/models/airtime/map/CcMusicDirsTableMap.php
  52. +2 −1 airtime_mvc/application/models/airtime/map/CcScheduleTableMap.php
  53. +708 −0 airtime_mvc/application/models/airtime/om/BaseCcCountry.php
  54. +735 −0 airtime_mvc/application/models/airtime/om/BaseCcCountryPeer.php
  55. +196 −0 airtime_mvc/application/models/airtime/om/BaseCcCountryQuery.php
  56. +540 −244 airtime_mvc/application/models/airtime/om/BaseCcFiles.php
  57. +408 −13 airtime_mvc/application/models/airtime/om/BaseCcFilesPeer.php
  58. +171 −0 airtime_mvc/application/models/airtime/om/BaseCcFilesQuery.php
  59. +941 −0 airtime_mvc/application/models/airtime/om/BaseCcMusicDirs.php
  60. +747 −0 airtime_mvc/application/models/airtime/om/BaseCcMusicDirsPeer.php
  61. +285 −0 airtime_mvc/application/models/airtime/om/BaseCcMusicDirsQuery.php
  62. +79 −0 airtime_mvc/application/models/airtime/om/BaseCcSchedule.php
  63. +387 −0 airtime_mvc/application/models/airtime/om/BaseCcSchedulePeer.php
  64. +68 −0 airtime_mvc/application/models/airtime/om/BaseCcScheduleQuery.php
  65. +25 −0 airtime_mvc/application/models/airtime/om/BaseCcShowInstances.php
  66. +25 −0 airtime_mvc/application/models/airtime/om/BaseCcSubjs.php
  67. +31 −0 airtime_mvc/application/models/airtime/om/CcFiles.php
  68. +48 −0 airtime_mvc/application/models/airtime/om/CcPlaylist.php
  69. +81 −0 airtime_mvc/application/models/airtime/om/CcPlaylistcontents.php
  70. +19 −0 airtime_mvc/application/models/airtime/om/Common.php
  71. +2 −2 airtime_mvc/application/models/tests/populator.php
  72. 0 airtime_mvc/{library/getid3/tmp/.keepme → application/views/scripts/api/list-all-files.phtml}
  73. +1 −1 airtime_mvc/application/views/scripts/dashboard/help.phtml
  74. +9 −2 airtime_mvc/application/views/scripts/form/preferences.phtml
  75. +3 −2 airtime_mvc/application/views/scripts/form/preferences_general.phtml
  76. +159 −0 airtime_mvc/application/views/scripts/form/preferences_support.phtml
  77. +52 −0 airtime_mvc/application/views/scripts/form/preferences_watched_dirs.phtml
  78. +175 −0 airtime_mvc/application/views/scripts/form/register-dialog.phtml
  79. +16 −27 airtime_mvc/application/views/scripts/library/get-file-meta-data.ajax.phtml
  80. +1 −0 airtime_mvc/application/views/scripts/library/index.phtml
  81. +1 −0 airtime_mvc/application/views/scripts/nowplaying/index.phtml
  82. +3 −1 airtime_mvc/application/views/scripts/playlist/new.phtml
  83. +8 −5 airtime_mvc/application/views/scripts/playlist/update.phtml
  84. +4 −0 airtime_mvc/application/views/scripts/preference/directory-config.phtml
  85. +1 −1 airtime_mvc/application/views/scripts/schedule/index.phtml
  86. +1 −1 airtime_mvc/application/views/scripts/user/add-user.phtml
  87. +0 −1 airtime_mvc/build/airtime.conf
  88. +1 −1 airtime_mvc/build/build.properties
  89. +19 −0 airtime_mvc/build/schema.xml
  90. +239 −0 airtime_mvc/build/sql/defaultdata.sql
  91. +43 −0 airtime_mvc/build/sql/schema.sql
  92. +0 −89 airtime_mvc/library/getid3/bin/autogen.sh
  93. +0 −47 airtime_mvc/library/getid3/configure
  94. +0 −135 airtime_mvc/library/getid3/etc/Makefile.in
  95. +0 −40 airtime_mvc/library/getid3/etc/configure.ac
  96. +0 −1,140 airtime_mvc/library/getid3/etc/doxygen.config
  97. +0 −222 airtime_mvc/library/getid3/var/extension.cache.dbm.php
  98. +0 −171 airtime_mvc/library/getid3/var/extension.cache.mysql.php
  99. +0 −1,309 airtime_mvc/library/getid3/var/getid3.lib.php
  100. +0 −1,398 airtime_mvc/library/getid3/var/getid3.php
  101. +0 −271 airtime_mvc/library/getid3/var/module.archive.gzip.php
  102. +0 −52 airtime_mvc/library/getid3/var/module.archive.rar.php
  103. +0 −97 airtime_mvc/library/getid3/var/module.archive.szip.php
  104. +0 −175 airtime_mvc/library/getid3/var/module.archive.tar.php
  105. +0 −416 airtime_mvc/library/getid3/var/module.archive.zip.php
Sorry, we could not display the entire diff because too many files (427) changed.
View
2 .gitignore
@@ -1,5 +1,5 @@
.*
*.pyc
/files
-python_apps/pypo/liquidsoap/liquidsoap
+python_apps/pypo/liquidsoap_bin/liquidsoap
build/build.properties
View
25 .zfproject.xml
@@ -127,6 +127,7 @@
<formFile formName="AddShowAbsoluteRebroadcastDates"/>
<formFile formName="SoundcloudPreferences"/>
<formFile formName="GeneralPreferences"/>
+ <formFile formName="WatchedDirPreferences"/>
</formsDirectory>
<layoutsDirectory enabled="false"/>
<modelsDirectory>
@@ -378,18 +379,18 @@
<testApplicationDirectory>
<testApplicationBootstrapFile filesystemName="bootstrap.php"/>
<testApplicationControllerDirectory>
- <testApplicationControllerFile filesystemName="PlaylistControllerTest.php"/>
- <testApplicationControllerFile filesystemName="LibraryControllerTest.php"/>
- <testApplicationControllerFile filesystemName="PluploadControllerTest.php"/>
- <testApplicationControllerFile filesystemName="SearchControllerTest.php"/>
- <testApplicationControllerFile filesystemName="LoginControllerTest.php"/>
- <testApplicationControllerFile filesystemName="ScheduleControllerTest.php"/>
- <testApplicationControllerFile filesystemName="ApiControllerTest.php"/>
- <testApplicationControllerFile filesystemName="UserControllerTest.php"/>
- <testApplicationControllerFile filesystemName="NowplayingControllerTest.php"/>
- <testApplicationControllerFile filesystemName="PreferenceControllerTest.php"/>
- <testApplicationControllerFile filesystemName="DashboardControllerTest.php"/>
- <testApplicationControllerFile filesystemName="RecorderControllerTest.php"/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
+ <testApplicationControllerFile/>
</testApplicationControllerDirectory>
</testApplicationDirectory>
<testLibraryDirectory>
View
4 CREDITS
@@ -2,6 +2,10 @@
CREDITS
=======
+Version 1.9.0
+-------------
+Same as previous version.
+
Version 1.8.2
-------------
Welcome to James Moon!
View
73 Changelog
@@ -1,4 +1,72 @@
-1.8.2 - May 25, 2011
+1.9.0 - August 9, 2011
+
+The cool stuff:
+ * New file storage system.
+ - 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
+ 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
+ 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
+ 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
+ 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!
+ - Output to Shoutcast. Now both Shoutcast and Icecast are supported.
+ - 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
+ faster install.
+ - 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
+ total time since the beginning of the playlist for each song.
+ - "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
+ 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
+ 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
+ Python or PHP configurations. The python libraries needed for Airtime are
+ now contained in a local Python virtualenv, and the PHP config variables
+ are set in the Apache virtualhost and .htaccess files.
+ - Message indicating import status is now displayed on Playlist Builder
+ page( above the search box).
+
+ * Bug fixes:
+ - 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
+ mp3 files (thanks to mutagen developers for the patch!)
+
+1.8.2 - June 8, 2011
Highlights:
* Improvements:
- You can now download audio files from the search screen and from the "Show Content" screen.
@@ -23,7 +91,8 @@ Highlights:
- Fixed problem with Record Check box occasionally being greyed-out when creating new show
- Fixed a problem with default genre not being applied to recorded shows
- Fixed a problem where shows repeating bi-weekly or monthly did not update properly when edited.
-
+ - Fixed problem when a user changed the name of a recorded show right before it started playing would cause the recorded audio not to be linked to the show.
+ - and many more...
1.8.1 - May 2, 2011
* Fixed issue where an track's progress bar would keep updating, even if the track was no longer playing.
View
137 LICENSE_3RD_PARTY
@@ -1,78 +1,73 @@
This application uses the following 3rd Party software:
-------------
+----------------------
+Common Non-linked Code
+----------------------
+ * Linux (Ubuntu & Debian)
+
+ * RabbitMQ (works with version 1.7.2 and above)
+ - What is it: Interprocess Message Passing with Queuing
+ - Web site: http://www.rabbitmq.com/
+ - License: Mozilla Public License (http://www.rabbitmq.com/mpl.html)
+
+ * monit
+ - What is it: Monitors processes and restarts them if they die
+ - Web site: http://mmonit.com/monit/
+ - License: GPLv3
+
+-----------
+Airtime Web
+-----------
Linked code:
-------------
* Zend Framework 1.10.3
+ - What is it: Framework for PHP web apps
- Web site: http://framework.zend.com/
- License: New BSD license
- Compatible with GPLv3: Yes
* PEAR
+ - What is it: PHP library
- Notes: We only use the PEAR base class PEAR_Error, in the "PEAR" PEAR library.
- License: New BSD License
- Compatible with GPLv3? Yes.
- * GetID3
- - Web site: http://getid3.sourceforge.net/
- - License: GPLv2
- - Compatible with GPLv3? Yes
-
* Propel ORM
+ - What is it: Maps DB data into PHP objects
- Web site: http://www.propelorm.org/
- License: MIT/Expat License
- Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
* Phing
+ - What is it: PHP project build system
- Web site: http://phing.info/trac/
- Note: Only used for development, not needed to run Airtime.
- License: LGPLv3
- * Soundcloud php api wrapper
- - Web site: https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php
- - License: MIT
- - Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
-
- * Kombu
- - Web site: http://pypi.python.org/pypi/kombu/
- - License: New BSD
- - Compatible with GPLv3? Yes.
-
* PHP-AMQPLIB
+ - What is it: PHP library to interact with RabbitMQ
- Web site: https://github.com/tnc/php-amqplib
- License: LGPLv2.1
- Compatible with GPLv3? Yes
-----------------
-Non-linked code:
-----------------
- * Linux
+ * Soundcloud PHP API wrapper
+ - What is it: PHP library to upload to SoundCloud
+ - Web site: https://github.com/mptre/php-soundcloud/blob/master/Services/Soundcloud.php
+ - License: MIT
+ - Compatible with the GPL: Yes. See http://www.gnu.org/licenses/license-list.html
+Non-linked code:
* Apache Web Server 2.2
- Web site: http://httpd.apache.org/
+ - License: Apache 2.0. See http://httpd.apache.org/docs/2.2/license.html
* PostgreSQL 8.4
- Web site: http://www.postgresql.org/
- - License: The PostgreSQL License. See http://www.opensource.org/licenses/postgresql
+ - License: The PostgreSQL License. See http://www.postgresql.org/about/licence
* PHP 5.3
- Web site: http://www.php.net/
- License: The PHP License. See http://www.php.net/license/3_01.txt
- * Python 2.6
- - Web site: http://www.python.org/
- - License: PSF License. See http://docs.python.org/license.html
-
- * Liquidsoap (pre-release of 1.0)
- - Web site: http://savonet.sourceforge.net/
- - License: GPLv2
-
- * mp3cut from the package poc-streamer
-
- * ecasound 2.7.2
- - Web site: http://www.eca.cx/ecasound/
- - License: GPLv2
-
* jQuery
- Web site: http://jquery.com/
- License: MIT and GPL. See http://jquery.org/license
@@ -106,5 +101,75 @@ Non-linked code:
- Web site: http://fgelinas.com/code/timepicker/
- License: Dual licensed under the MIT or GPL Version 2 licenses.
+ * Data Tables
+ - Web site: http://www.datatables.net/
+ - License: GPLv2 or BSD 3-Clause
+
+ * Server Browse
+ - Web site: http://code.google.com/p/jq-serverbrowse/
+ - License: BSD 2-Clause
+
+-------------
+Media-Monitor
+-------------
+Linked code:
+ * Mutagen
+ - What is it: Parser of audio file metadata
+ - Web site: http://code.google.com/p/mutagen/
+ - License: GPLv2-only
+
+ * Kombu
+ - What is it: Python interface to RabbitMQ
+ - Web site: http://pypi.python.org/pypi/kombu/
+ - License: New BSD
+ - Compatible with GPLv3? Yes.
+
+ * pyinotify
+ - Python interface to inotify
+ - Web site: https://github.com/seb-m/pyinotify
+ - License: MIT
+
+Non-linked code:
+ * Python 2.6
+ - Web site: http://www.python.org/
+ - License: PSF License. See http://docs.python.org/license.html
+
+-------------
+Show Recorder
+-------------
+Linked code:
+ * Kombu
+ - What is it: Python interface to RabbitMQ
+ - Web site: http://pypi.python.org/pypi/kombu/
+ - License: New BSD
+ - Compatible with GPLv3? Yes.
+
+Non-linked code:
+ * Python 2.6
+ - Web site: http://www.python.org/
+ - License: PSF License. See http://docs.python.org/license.html
+
+ * ecasound 2.7.2
+ - What is it: Records audio from line-in
+ - Web site: http://www.eca.cx/ecasound/
+ - License: GPLv2
+
+----
+Pypo
+----
+Linked code:
+ * Kombu
+ - Web site: http://pypi.python.org/pypi/kombu/
+ - License: New BSD
+ - Compatible with GPLv3? Yes.
+
+Non-linked code:
+ * Python 2.6
+ - Web site: http://www.python.org/
+ - License: PSF License. See http://docs.python.org/license.html
+
+ * Liquidsoap (pre-release of 1.0)
+ - Web site: http://savonet.sourceforge.net/
+ - License: GPLv2
View
2 VERSION
@@ -1,2 +1,2 @@
PRODUCT_ID=Airtime
-PRODUCT_RELEASE=1.8.2
+PRODUCT_RELEASE=1.9.0
View
1 airtime_mvc/application/Bootstrap.php
@@ -16,6 +16,7 @@
require_once 'DB.php';
require_once 'Soundcloud.php';
+require_once 'MusicDir.php';
require_once 'Playlist.php';
require_once 'StoredFile.php';
require_once 'Schedule.php';
View
3 airtime_mvc/application/configs/ACL.php
@@ -6,7 +6,8 @@
$ccAcl->addRole(new Zend_Acl_Role('G'))
->addRole(new Zend_Acl_Role('H'), 'G')
- ->addRole(new Zend_Acl_Role('A'), 'H');
+ ->addRole(new Zend_Acl_Role('P'), 'H')
+ ->addRole(new Zend_Acl_Role('A'), 'P');
$ccAcl->add(new Zend_Acl_Resource('library'))
->add(new Zend_Acl_Resource('index'))
View
14 airtime_mvc/application/configs/classmap-airtime-conf.php
@@ -8,6 +8,13 @@
'BaseCcAccessPeer' => 'airtime/om/BaseCcAccessPeer.php',
'BaseCcAccess' => 'airtime/om/BaseCcAccess.php',
'BaseCcAccessQuery' => 'airtime/om/BaseCcAccessQuery.php',
+ 'CcMusicDirsTableMap' => 'airtime/map/CcMusicDirsTableMap.php',
+ 'CcMusicDirsPeer' => 'airtime/CcMusicDirsPeer.php',
+ 'CcMusicDirs' => 'airtime/CcMusicDirs.php',
+ 'CcMusicDirsQuery' => 'airtime/CcMusicDirsQuery.php',
+ 'BaseCcMusicDirsPeer' => 'airtime/om/BaseCcMusicDirsPeer.php',
+ 'BaseCcMusicDirs' => 'airtime/om/BaseCcMusicDirs.php',
+ 'BaseCcMusicDirsQuery' => 'airtime/om/BaseCcMusicDirsQuery.php',
'CcFilesTableMap' => 'airtime/map/CcFilesTableMap.php',
'CcFilesPeer' => 'airtime/CcFilesPeer.php',
'CcFiles' => 'airtime/CcFiles.php',
@@ -106,4 +113,11 @@
'BaseCcSubjsPeer' => 'airtime/om/BaseCcSubjsPeer.php',
'BaseCcSubjs' => 'airtime/om/BaseCcSubjs.php',
'BaseCcSubjsQuery' => 'airtime/om/BaseCcSubjsQuery.php',
+ 'CcCountryTableMap' => 'airtime/map/CcCountryTableMap.php',
+ 'CcCountryPeer' => 'airtime/CcCountryPeer.php',
+ 'CcCountry' => 'airtime/CcCountry.php',
+ 'CcCountryQuery' => 'airtime/CcCountryQuery.php',
+ 'BaseCcCountryPeer' => 'airtime/om/BaseCcCountryPeer.php',
+ 'BaseCcCountry' => 'airtime/om/BaseCcCountry.php',
+ 'BaseCcCountryQuery' => 'airtime/om/BaseCcCountryQuery.php',
);
View
6 airtime_mvc/application/configs/conf.php
@@ -65,11 +65,7 @@ public static function loadConfig($CC_CONFIG) {
$CC_CONFIG['baseUrl'] = $values['general']['base_url'];
$CC_CONFIG['basePort'] = $values['general']['base_port'];
-
- $CC_CONFIG['baseFilesDir'] = $values['general']['base_files_dir'];
- // main directory for storing binary media files
- $CC_CONFIG['storageDir'] = $values['general']['base_files_dir']."/stor";
-
+
// Database config
$CC_CONFIG['dsn']['username'] = $values['database']['dbuser'];
$CC_CONFIG['dsn']['password'] = $values['database']['dbpass'];
View
40 airtime_mvc/application/configs/constants.php
@@ -1,22 +1,34 @@
<?php
-define('AIRTIME_VERSION', '1.8.2');
+define('AIRTIME_VERSION', '1.9.0');
define('AIRTIME_COPYRIGHT_DATE', '2010-2011');
define('AIRTIME_REST_VERSION', '1.1');
-// Metadata Keys
-define('UI_MDATA_KEY_TITLE', 'dc:title');
-define('UI_MDATA_KEY_CREATOR', 'dc:creator');
-define('UI_MDATA_KEY_SOURCE', 'dc:source');
-define('UI_MDATA_KEY_DURATION', 'dcterms:extent');
-define('UI_MDATA_KEY_URL', 'ls:url');
-define('UI_MDATA_KEY_FORMAT', 'dc:format');
-define('UI_MDATA_KEY_DESCRIPTION', 'dc:description');
-define('UI_MDATA_KEY_CHANNELS', 'ls:channels');
-define('UI_MDATA_KEY_SAMPLERATE', 'ls:samplerate');
-define('UI_MDATA_KEY_BITRATE', 'ls:bitrate');
-define('UI_MDATA_KEY_ENCODER', 'ls:encoder');
-define('UI_MDATA_KEY_FILENAME', 'ls:filename');
+// Metadata Keys for files
+define('MDATA_KEY_FILEPATH', 'filepath');
+define('MDATA_KEY_MD5', 'md5');
+define('MDATA_KEY_TITLE', 'track_title');
+define('MDATA_KEY_CREATOR', 'artist_name');
+define('MDATA_KEY_SOURCE', 'album_title');
+define('MDATA_KEY_DURATION', 'length');
+define('MDATA_KEY_MIME', 'mime');
+define('MDATA_KEY_FTYPE', 'ftype');
+define('MDATA_KEY_URL', 'info_url');
+define('MDATA_KEY_GENRE', 'genre');
+define('MDATA_KEY_MOOD', 'mood');
+define('MDATA_KEY_LABEL', 'label');
+define('MDATA_KEY_COMPOSER', 'composer');
+define('MDATA_KEY_DESCRIPTION', 'description');
+define('MDATA_KEY_SAMPLERATE', 'sample_rate');
+define('MDATA_KEY_BITRATE', 'bit_rate');
+define('MDATA_KEY_ENCODER', 'encoded_by');
+define('MDATA_KEY_ISRC', 'isrc_number');
+define('MDATA_KEY_COPYRIGHT', 'copyright');
+define('MDATA_KEY_YEAR', 'year');
+define('MDATA_KEY_BPM', 'bpm');
+define('MDATA_KEY_TRACKNUMBER', 'track_number');
+define('MDATA_KEY_CONDUCTOR', 'conductor');
+define('MDATA_KEY_LANGUAGE', 'language');
define('UI_MDATA_VALUE_FORMAT_FILE', 'File');
define('UI_MDATA_VALUE_FORMAT_STREAM', 'live stream');
View
6 airtime_mvc/application/configs/navigation.php
@@ -52,6 +52,12 @@
'controller' => 'user',
'action' => 'add-user',
'resource' => 'user'
+ ),
+ array(
+ 'label' => 'Manage Media Folders',
+ 'module' => 'default',
+ 'controller' => 'Preference',
+ 'action' => 'directory-config'
)
)
),
View
354 airtime_mvc/application/controllers/ApiController.php
@@ -9,8 +9,16 @@ public function init()
$context = $this->_helper->getHelper('contextSwitch');
$context->addActionContext('version', 'json')
->addActionContext('recorded-shows', 'json')
+ ->addActionContext('upload-file', 'json')
->addActionContext('upload-recorded', 'json')
+ ->addActionContext('media-monitor-setup', 'json')
+ ->addActionContext('media-item-status', 'json')
->addActionContext('reload-metadata', 'json')
+ ->addActionContext('list-all-files', 'json')
+ ->addActionContext('list-all-watched-dirs', 'json')
+ ->addActionContext('add-watched-dir', 'json')
+ ->addActionContext('remove-watched-dir', 'json')
+ ->addActionContext('set-storage-dir', 'json')
->initContext();
}
@@ -20,7 +28,7 @@ public function indexAction()
}
/**
- * Returns Airtime version. i.e "1.7.0 alpha"
+ * Returns Airtime version. i.e "1.7.0-beta"
*
* First checks to ensure the correct API key was
* supplied, then returns AIRTIME_VERSION as defined
@@ -52,7 +60,7 @@ public function versionAction()
* Allows remote client to download requested media file.
*
* @return void
- * The given value increased by the increment amount.
+ *
*/
public function getMediaAction()
{
@@ -63,57 +71,74 @@ public function getMediaAction()
$this->_helper->viewRenderer->setNoRender(true);
$api_key = $this->_getParam('api_key');
- $download = $this->_getParam('download');
+ $download = ("true" == $this->_getParam('download'));
- if(!in_array($api_key, $CC_CONFIG["apiKey"]))
+ $logger = Logging::getLogger();
+
+ if(!in_array($api_key, $CC_CONFIG["apiKey"]) &&
+ is_null(Zend_Auth::getInstance()->getStorage()->read()))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
- exit;
+ $logger->info("401 Unauthorized");
+ return;
}
$filename = $this->_getParam("file");
$file_id = substr($filename, 0, strpos($filename, "."));
if (ctype_alnum($file_id) && strlen($file_id) == 32) {
$media = StoredFile::RecallByGunid($file_id);
if ($media != null && !PEAR::isError($media)) {
- $filepath = $media->getRealFilePath();
- if(!is_file($filepath))
- {
- header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
- //print 'Resource in database, but not in storage. Sorry.';
- exit;
- }
+ $filepath = $media->getFilePath();
+ if(is_file($filepath)){
+ // possibly use fileinfo module here in the future.
+ // http://www.php.net/manual/en/book.fileinfo.php
+ $ext = pathinfo($filename, PATHINFO_EXTENSION);
+ if ($ext == "ogg")
+ header("Content-Type: audio/ogg");
+ else if ($ext == "mp3")
+ header("Content-Type: audio/mpeg");
+ if ($download){
+ //path_info breaks up a file path into seperate pieces of informaiton.
+ //We just want the basename which is the file name with the path
+ //information stripped away. We are using Content-Disposition to specify
+ //to the browser what name the file should be saved as.
+ //
+ // By james.moon:
+ // I'm removing pathinfo() since it strips away UTF-8 characters.
+ // Using manualy parsing
+ $full_path = $media->getPropelOrm()->getDbFilepath();
+ $file_base_name = strrchr($full_path, '/');
+ $file_base_name = substr($file_base_name, 1);
+ header('Content-Disposition: attachment; filename="'.$file_base_name.'"');
+ }
+ header("Content-Length: " . filesize($filepath));
+
+ // !! binary mode !!
+ $fp = fopen($filepath, 'rb');
+ //We can have multiple levels of output buffering. Need to
+ //keep looping until all have been disabled!!!
+ //http://www.php.net/manual/en/function.ob-end-flush.php
+ while (@ob_end_flush());
- // possibly use fileinfo module here in the future.
- // http://www.php.net/manual/en/book.fileinfo.php
- $ext = pathinfo($filename, PATHINFO_EXTENSION);
- if ($ext == "ogg")
- header("Content-Type: audio/ogg");
- else if ($ext == "mp3")
- header("Content-Type: audio/mpeg");
- if ($download){
- header('Content-Disposition: attachment; filename="'.$media->getName().'"');
+ fpassthru($fp);
+ fclose($fp);
+
+ //make sure to exit here so that no other output is sent.
+ exit;
+ } else {
+ $logger->err('Resource in database, but not in storage: "'.$filepath.'"');
}
- header("Content-Length: " . filesize($filepath));
-
- // !! binary mode !!
- $fp = fopen($filepath, 'rb');
-
- //We can have multiple levels of output buffering. Need to
- //keep looping until all have been disabled!!!
- //http://www.php.net/manual/en/function.ob-end-flush.php
- while (@ob_end_flush());
-
- fpassthru($fp);
- fclose($fp);
-
- return;
+ } else {
+ $logger->err('$media != null && !PEAR::isError($media)');
}
+ } else {
+ $logger->err('ctype_alnum($file_id) && strlen($file_id) == 32');
}
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
- exit;
+ $logger->info("404 Not Found");
+ return;
}
public function liveInfoAction()
@@ -282,6 +307,24 @@ public function recordedShowsAction()
}
}
+ public function uploadFileAction()
+ {
+ global $CC_CONFIG;
+
+ $api_key = $this->_getParam('api_key');
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
+ }
+
+ $upload_dir = ini_get("upload_tmp_dir");
+ StoredFile::uploadFile($upload_dir);
+ $fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
+ StoredFile::copyFileToStor($upload_dir, $fileName);
+ }
+
public function uploadRecordedAction()
{
global $CC_CONFIG;
@@ -293,18 +336,24 @@ public function uploadRecordedAction()
print 'You are not allowed to access this resource.';
exit;
}
-
+
+ //this file id is the recording for this show instance.
+ $show_instance_id = $this->_getParam('showinstanceid');
+ $file_id = $this->_getParam('fileid');
+
+ $this->view->fileid = $file_id;
+ $this->view->showinstanceid = $show_instance_id;
+
+
$showCanceled = false;
- $show_instance = $this->_getParam('show_instance');
-
- $upload_dir = ini_get("upload_tmp_dir");
- $file = StoredFile::uploadFile($upload_dir);
-
- $show_name = "";
+ $file = StoredFile::Recall($file_id);
+ //$show_instance = $this->_getParam('show_instance');
+
+ $show_name = null;
try {
- $show_inst = new ShowInstance($show_instance);
-
- $show_inst->setRecordedFile($file->getId());
+ $show_inst = new ShowInstance($show_instance_id);
+
+ $show_inst->setRecordedFile($file_id);
$show_name = $show_inst->getName();
$show_genre = $show_inst->getGenre();
$show_start_time = $show_inst->getShowStart();
@@ -317,12 +366,19 @@ public function uploadRecordedAction()
//the library), now lets just return.
$showCanceled = true;
}
-
- $tmpTitle = !(empty($show_name))?$show_name."-":"";
- $tmpTitle .= $file->getName();
-
- $file->setMetadataValue(UI_MDATA_KEY_TITLE, $tmpTitle);
-
+
+ if (isset($show_name)) {
+ $tmpTitle = "$show_name-$show_start_time";
+ $tmpTitle = str_replace(" ", "-", $tmpTitle);
+ }
+ else {
+ $tmpTitle = $file->getName();
+ }
+
+ $file->setMetadataValue('MDATA_KEY_TITLE', $tmpTitle);
+ $file->setMetadataValue('MDATA_KEY_CREATOR', "Airtime Show Recorder");
+ $file->setMetadataValue('MDATA_KEY_TRACKNUMBER', null);
+
if (!$showCanceled && Application_Model_Preference::GetDoSoundCloudUpload())
{
for ($i=0; $i<$CC_CONFIG['soundcloud-connection-retries']; $i++) {
@@ -335,7 +391,7 @@ public function uploadRecordedAction()
try {
$soundcloud = new ATSoundcloud();
- $soundcloud_id = $soundcloud->uploadTrack($file->getRealFilePath(), $tmpTitle, $description, $tags, $show_start_time, $show_genre);
+ $soundcloud_id = $soundcloud->uploadTrack($file->getFilePath(), $tmpTitle, $description, $tags, $show_start_time, $show_genre);
$show_inst->setSoundCloudFileId($soundcloud_id);
break;
}
@@ -350,37 +406,205 @@ public function uploadRecordedAction()
}
}
- $this->view->id = $file->getId();
+ $this->view->id = $file_id;
+
+ }
+
+ public function mediaMonitorSetupAction() {
+ global $CC_CONFIG;
+
+ // disable the view and the layout
+ $this->view->layout()->disableLayout();
+ $this->_helper->viewRenderer->setNoRender(true);
+
+ $api_key = $this->_getParam('api_key');
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
+ }
+
+ $this->view->stor = MusicDir::getStorDir()->getDirectory();
}
public function reloadMetadataAction() {
+ global $CC_CONFIG;
+
+ $request = $this->getRequest();
+ $api_key = $request->getParam('api_key');
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
+ }
+
+ $mode = $request->getParam('mode');
+ $params = $request->getParams();
+ $md = array();
+ //extract all file metadata params from the request.
+ foreach ($params as $key => $value) {
+ if (preg_match('/^MDATA_KEY/', $key)) {
+ $md[$key] = $value;
+ }
+ }
+
+ // update import timestamp
+ Application_Model_Preference::SetImportTimestamp();
+
+ if ($mode == "create") {
+ $filepath = $md['MDATA_KEY_FILEPATH'];
+ $filepath = str_replace("\\", "", $filepath);
+
+ $file = StoredFile::RecallByFilepath($filepath);
+
+ if (is_null($file)) {
+ $file = StoredFile::Insert($md);
+ }
+ else {
+ $this->view->error = "File already exists in Airtime.";
+ return;
+ }
+ }
+ else if ($mode == "modify") {
+ $filepath = $md['MDATA_KEY_FILEPATH'];
+ $filepath = str_replace("\\", "", $filepath);
+ $file = StoredFile::RecallByFilepath($filepath);
+
+ //File is not in database anymore.
+ if (is_null($file)) {
+ $this->view->error = "File does not exist in Airtime.";
+ return;
+ }
+ //Updating a metadata change.
+ else {
+ $file->setMetadata($md);
+ }
+ }
+ else if ($mode == "moved") {
+ $md5 = $md['MDATA_KEY_MD5'];
+ $file = StoredFile::RecallByMd5($md5);
+
+ if (is_null($file)) {
+ $this->view->error = "File doesn't exist in Airtime.";
+ return;
+ }
+ else {
+ $filepath = $md['MDATA_KEY_FILEPATH'];
+ $filepath = str_replace("\\", "", $filepath);
+ $file->setFilePath($filepath);
+ //$file->setMetadata($md);
+ }
+ }
+ else if ($mode == "delete") {
+ $filepath = $md['MDATA_KEY_FILEPATH'];
+ $filepath = str_replace("\\", "", $filepath);
+ $file = StoredFile::RecallByFilepath($filepath);
+
+ if (is_null($file)) {
+ $this->view->error = "File doesn't exist in Airtime.";
+ return;
+ }
+ else {
+ $file->delete();
+ }
+ }
+ $this->view->id = $file->getId();
+ }
+
+ public function listAllFilesAction() {
global $CC_CONFIG;
- $api_key = $this->_getParam('api_key');
+ $request = $this->getRequest();
+ $api_key = $request->getParam('api_key');
if (!in_array($api_key, $CC_CONFIG["apiKey"]))
{
header('HTTP/1.0 401 Unauthorized');
print 'You are not allowed to access this resource.';
exit;
}
+ $dir_id = $request->getParam('dir_id');
- $md = $this->_getParam('md');
+ $this->view->files = StoredFile::listAllFiles($dir_id);
+ }
- $file = StoredFile::Recall(null, $md['gunid']);
- if (PEAR::isError($file) || is_null($file)) {
- $this->view->response = "File not in Airtime's Database";
- return;
+ public function listAllWatchedDirsAction() {
+ global $CC_CONFIG;
+
+ $request = $this->getRequest();
+ $api_key = $request->getParam('api_key');
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
}
- $res = $file->replaceDbMetadata($md);
+ $result = array();
- if (PEAR::isError($res)) {
- $this->view->response = "Metadata Change Failed";
+ $arrWatchedDirs = MusicDir::getWatchedDirs();
+ $storDir = MusicDir::getStorDir();
+
+ $result[$storDir->getId()] = $storDir->getDirectory();
+
+ foreach ($arrWatchedDirs as $watchedDir){
+ $result[$watchedDir->getId()] = $watchedDir->getDirectory();
}
- else {
- $this->view->response = "Success!";
+
+ $this->view->dirs = $result;
+ }
+
+ public function addWatchedDirAction() {
+ global $CC_CONFIG;
+
+ $request = $this->getRequest();
+ $api_key = $request->getParam('api_key');
+ $path = base64_decode($request->getParam('path'));
+
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
}
+
+ $this->view->msg = MusicDir::addWatchedDir($path);
+ }
+
+ public function removeWatchedDirAction() {
+ global $CC_CONFIG;
+
+ $request = $this->getRequest();
+ $api_key = $request->getParam('api_key');
+ $path = base64_decode($request->getParam('path'));
+
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
+ }
+
+ $this->view->msg = MusicDir::removeWatchedDir($path);
+ }
+
+ public function setStorageDirAction() {
+ global $CC_CONFIG;
+
+ $request = $this->getRequest();
+ $api_key = $request->getParam('api_key');
+ $path = base64_decode($request->getParam('path'));
+
+ if (!in_array($api_key, $CC_CONFIG["apiKey"]))
+ {
+ header('HTTP/1.0 401 Unauthorized');
+ print 'You are not allowed to access this resource.';
+ exit;
+ }
+
+ $this->view->msg = MusicDir::setStorDir($path);
}
}
View
107 airtime_mvc/application/controllers/LibraryController.php
@@ -28,6 +28,7 @@ public function indexAction()
$this->view->headScript()->appendFile($baseUrl.'/js/jplayer/jquery.jplayer.min.js');
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/js/jquery.dataTables.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/dataTables.pluginAPI.js','text/javascript');
+ $this->view->headScript()->appendFile($baseUrl.'/js/datatables/plugin/dataTables.fnSetFilteringDelay.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/library/library.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/library/advancedsearch.js','text/javascript');
@@ -54,18 +55,23 @@ public function contextMenuAction()
$id = $this->_getParam('id');
$type = $this->_getParam('type');
+ $request = $this->getRequest();
+ $baseUrl = $request->getBaseUrl();
$params = '/format/json/id/#id#/type/#type#';
$paramsPop = str_replace('#id#', $id, $params);
$paramsPop = str_replace('#type#', $type, $paramsPop);
+ $userInfo = Zend_Auth::getInstance()->getStorage()->read();
+ $user = new User($userInfo->id);
+
$pl_sess = $this->pl_sess;
if($type === "au") {
if(isset($pl_sess->id)) {
- $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/add-item'.$params, 'callback' => 'window["setSPLContent"]'),
+ $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/add-item'.$params, 'callback' => 'window["setSPLContent"]'),
'title' => 'Add to Playlist');
}
@@ -78,13 +84,16 @@ public function contextMenuAction()
$file_id = $this->_getParam('id', null);
$file = StoredFile::Recall($file_id);
- $url = $file->getFileURL().'/api_key/'.$CC_CONFIG["apiKey"][0].'/download/true';
+ $url = $file->getRelativeFileUrl($baseUrl).'/api_key/'.$CC_CONFIG["apiKey"][0].'/download/true';
$menu[] = array('action' => array('type' => 'gourl', 'url' => $url),
'title' => 'Download');
- $menu[] = array('action' => array('type' => 'fn',
- 'callback' => "window['confirmDeleteAudioClip']('$paramsPop')"),
- 'title' => 'Delete');
+
+ if ($user->isAdmin()) {
+ $menu[] = array('action' => array('type' => 'fn',
+ 'callback' => "window['confirmDeleteAudioClip']('$paramsPop')"),
+ 'title' => 'Delete');
+ }
}
else if($type === "pl") {
@@ -118,35 +127,51 @@ public function contextMenuAction()
public function deleteAction()
{
$id = $this->_getParam('id');
-
- if (!is_null($id)) {
- $file = StoredFile::Recall($id);
-
- if (PEAR::isError($file)) {
- $this->view->message = $file->getMessage();
- return;
+ $userInfo = Zend_Auth::getInstance()->getStorage()->read();
+ $user = new User($userInfo->id);
+
+ if ($user->isAdmin()) {
+
+ if (!is_null($id)) {
+ $file = StoredFile::Recall($id);
+
+ if (PEAR::isError($file)) {
+ $this->view->message = $file->getMessage();
+ return;
+ }
+ else if(is_null($file)) {
+ $this->view->message = "file doesn't exist";
+ return;
+ }
+
+ $res = $file->delete();
+
+ if (PEAR::isError($res)) {
+ $this->view->message = $res->getMessage();
+ return;
+ }
+ else {
+ $res = settype($res, "integer");
+ $data = array("filepath" => $file->getFilePath(), "delete" => $res);
+ RabbitMq::SendMessageToMediaMonitor("file_delete", $data);
+ }
}
- else if(is_null($file)) {
- $this->view->message = "file doesn't exist";
- return;
- }
-
- $res = $file->delete();
- if (PEAR::isError($res)) {
- $this->view->message = $res->getMessage();
- return;
- }
+ $this->view->id = $id;
}
-
- $this->view->id = $id;
}
public function contentsAction()
{
$post = $this->getRequest()->getPost();
$datatables = StoredFile::searchFilesForPlaylistBuilder($post);
+ //format clip lengh to 1 decimal
+ foreach($datatables["aaData"] as &$data){
+ $sec = Playlist::playlistTimeToSeconds($data[5]);
+ $data[5] = Playlist::secondsToPlaylistTime($sec);
+ }
+
die(json_encode($datatables));
}
@@ -162,18 +187,17 @@ public function editFileMdAction()
if ($form->isValid($request->getPost())) {
$formdata = $form->getValues();
- $file->replaceDbMetadata($formdata);
+ $file->setDbColMetadata($formdata);
+
+ $data = $file->getMetadata();
- $data = $formdata;
- $data['filepath'] = $file->getRealFilePath();
- //wait for 1.9.0 release
- //RabbitMq::SendFileMetaData($data);
+ RabbitMq::SendMessageToMediaMonitor("md_update", $data);
$this->_helper->redirector('index');
}
}
- $form->populate($file->md);
+ $form->populate($file->getDbColMetadata());
$this->view->form = $form;
}
@@ -185,7 +209,7 @@ public function getFileMetaDataAction()
if($type == "au") {
$file = StoredFile::Recall($id);
$this->view->type = $type;
- $this->view->md = $file->md;
+ $this->view->md = $file->getMetadata();
}
else if($type == "pl") {
$file = Playlist::Recall($id);
@@ -195,25 +219,4 @@ public function getFileMetaDataAction()
}
}
-
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
View
5 airtime_mvc/application/controllers/LoginController.php
@@ -49,7 +49,10 @@ public function indexAction()
//the default storage is a session with namespace Zend_Auth
$authStorage = $auth->getStorage();
$authStorage->write($userInfo);
-
+
+ $tempSess = new Zend_Session_Namespace("referrer");
+ $tempSess->referrer = 'login';
+
$this->_redirect('Nowplaying');
}
else
View
74 airtime_mvc/application/controllers/NowplayingController.php
@@ -7,6 +7,8 @@ public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('get-data-grid-data', 'json')
+ ->addActionContext('register', 'json')
+ ->addActionContext('remindme', 'json')
->initContext();
}
@@ -18,6 +20,62 @@ public function indexAction()
$this->view->headScript()->appendFile($baseUrl.'/js/datatables/js/jquery.dataTables.min.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/nowplayingdatagrid.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/nowview.js','text/javascript');
+
+ $refer_sses = new Zend_Session_Namespace('referrer');
+ $userInfo = Zend_Auth::getInstance()->getStorage()->read();
+ $user = new User($userInfo->id);
+
+ if ($request->isPost()) {
+ $form = new Application_Form_RegisterAirtime();
+
+ $values = $request->getPost();
+ if ($values["Publicise"] != 1){
+ Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
+ // unset session
+ Zend_Session::namespaceUnset('referrer');
+ }
+ else if ($values["Publicise"] == '1' && $form->isValid($values)) {
+ Application_Model_Preference::SetHeadTitle($values["stnName"], $this->view);
+ Application_Model_Preference::SetPhone($values["Phone"]);
+ Application_Model_Preference::SetEmail($values["Email"]);
+ Application_Model_Preference::SetStationWebSite($values["StationWebSite"]);
+ Application_Model_Preference::SetPublicise($values["Publicise"]);
+
+ $form->Logo->receive();
+ $imagePath = $form->Logo->getFileName();
+
+ Application_Model_Preference::SetStationCountry($values["Country"]);
+ Application_Model_Preference::SetStationCity($values["City"]);
+ Application_Model_Preference::SetStationDescription($values["Description"]);
+ Application_Model_Preference::SetStationLogo($imagePath);
+ Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]);
+ // unset session
+ Zend_Session::namespaceUnset('referrer');
+ }else{
+ var_dump($form->getMessages());
+ $logo = Application_Model_Preference::GetStationLogo();
+ if($logo){
+ $this->view->logoImg = $logo;
+ }
+ $this->view->dialog = $form;
+ $this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/register.js','text/javascript');
+ }
+ }else{
+ //popup if previous page was login
+ if($refer_sses->referrer == 'login' && Application_Model_Nowplaying::ShouldShowPopUp()
+ && !Application_Model_Preference::GetSupportFeedback() && $user->isAdmin()){
+
+ $form = new Application_Form_RegisterAirtime();
+
+
+ $logo = Application_Model_Preference::GetStationLogo();
+ if($logo){
+ $this->view->logoImg = $logo;
+ }
+ $this->view->dialog = $form;
+ $this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/register.js','text/javascript');
+ }
+ }
}
public function getDataGridDataAction()
@@ -43,6 +101,22 @@ public function dayViewAction()
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/nowplayingdatagrid.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/nowplaying/dayview.js','text/javascript');
}
+
+ public function remindmeAction()
+ {
+ // unset session
+ Zend_Session::namespaceUnset('referrer');
+ $now = date("Y-m-d H:i:s");
+ Application_Model_Preference::SetRemindMeDate($now);
+ die();
+ }
+
+ public function donotshowregistrationpopupAction()
+ {
+ // unset session
+ Zend_Session::namespaceUnset('referrer');
+ die();
+ }
}
View
6 airtime_mvc/application/controllers/PlaylistController.php
@@ -113,8 +113,8 @@ public function metadataAction()
$this->changePlaylist($pl_id);
$pl = $this->getPlaylist();
- $title = $pl->getPLMetaData(UI_MDATA_KEY_TITLE);
- $desc = $pl->getPLMetaData(UI_MDATA_KEY_DESCRIPTION);
+ $title = $pl->getPLMetaData("dc:title");
+ $desc = $pl->getPLMetaData("dc:description");
$data = array( 'title' => $title, 'description' => $desc);
$form->populate($data);
@@ -130,7 +130,7 @@ public function metadataAction()
$pl->setName($title);
if(isset($description)) {
- $pl->setPLMetaData(UI_MDATA_KEY_DESCRIPTION, $description);
+ $pl->setPLMetaData("dc:description", $description);
}
$this->view->pl = $pl;
View
13 airtime_mvc/application/controllers/PluploadController.php
@@ -7,6 +7,7 @@ public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('upload', 'json')
+ ->addActionContext('copyfile', 'json')
->initContext();
}
@@ -25,9 +26,17 @@ public function indexAction()
public function uploadAction()
{
$upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
- $file = StoredFile::uploadFile($upload_dir);
+ StoredFile::uploadFile($upload_dir);
- die('{"jsonrpc" : "2.0", "id" : '.$file->getId().' }');
+ die('{"jsonrpc" : "2.0"}');
+ }
+
+ public function copyfileAction(){
+ $upload_dir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
+ $filename = $this->_getParam('name');
+ StoredFile::copyFileToStor($upload_dir, $filename);
+
+ die('{"jsonrpc" : "2.0"}');
}
}
View
148 airtime_mvc/application/controllers/PreferenceController.php
@@ -6,6 +6,15 @@ class PreferenceController extends Zend_Controller_Action
public function init()
{
/* Initialize action controller here */
+ $ajaxContext = $this->_helper->getHelper('AjaxContext');
+ $ajaxContext/*->addActionContext('register', 'json')
+ ->addActionContext('remindme', 'json')*/
+ ->addActionContext('server-browse', 'json')
+ ->addActionContext('change-stor-directory', 'json')
+ ->addActionContext('reload-watch-directory', 'json')
+ ->addActionContext('remove-watch-directory', 'json')
+ ->addActionContext('is-import-in-progress', 'json')
+ ->initContext();
}
public function indexAction()
@@ -15,34 +24,149 @@ public function indexAction()
$this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/preferences.js','text/javascript');
$this->view->statusMsg = "";
-
+
$form = new Application_Form_Preferences();
-
+
if ($request->isPost()) {
-
if ($form->isValid($request->getPost())) {
-
$values = $form->getValues();
-
- Application_Model_Preference::SetHeadTitle($values["preferences_general"]["stationName"], $this->view);
- Application_Model_Preference::SetDefaultFade($values["preferences_general"]["stationDefaultFade"]);
+
+ Application_Model_Preference::SetHeadTitle($values["preferences_general"]["stationName"], $this->view);
+ Application_Model_Preference::SetDefaultFade($values["preferences_general"]["stationDefaultFade"]);
Application_Model_Preference::SetStreamLabelFormat($values["preferences_general"]["streamFormat"]);
Application_Model_Preference::SetAllow3rdPartyApi($values["preferences_general"]["thirdPartyApi"]);
- Application_Model_Preference::SetDoSoundCloudUpload($values["preferences_soundcloud"]["UseSoundCloud"]);
+ Application_Model_Preference::SetDoSoundCloudUpload($values["preferences_soundcloud"]["UseSoundCloud"]);
Application_Model_Preference::SetSoundCloudUser($values["preferences_soundcloud"]["SoundCloudUser"]);
- Application_Model_Preference::SetSoundCloudPassword($values["preferences_soundcloud"]["SoundCloudPassword"]);
+ Application_Model_Preference::SetSoundCloudPassword($values["preferences_soundcloud"]["SoundCloudPassword"]);
Application_Model_Preference::SetSoundCloudTags($values["preferences_soundcloud"]["SoundCloudTags"]);
Application_Model_Preference::SetSoundCloudGenre($values["preferences_soundcloud"]["SoundCloudGenre"]);
Application_Model_Preference::SetSoundCloudTrackType($values["preferences_soundcloud"]["SoundCloudTrackType"]);
- Application_Model_Preference::SetSoundCloudLicense($values["preferences_soundcloud"]["SoundCloudLicense"]);
-
+
+ Application_Model_Preference::SetSoundCloudLicense($values["preferences_soundcloud"]["SoundCloudLicense"]);
+
+ Application_Model_Preference::SetPhone($values["preferences_support"]["Phone"]);
+ Application_Model_Preference::SetEmail($values["preferences_support"]["Email"]);
+ Application_Model_Preference::SetStationWebSite($values["preferences_support"]["StationWebSite"]);
+ Application_Model_Preference::SetSupportFeedback($values["preferences_support"]["SupportFeedback"]);
+ Application_Model_Preference::SetPublicise($values["preferences_support"]["Publicise"]);
+
+ $form->getSubForm('preferences_support')->Logo->receive();
+ $imagePath = $form->getSubForm('preferences_support')->Logo->getFileName();
+
+ Application_Model_Preference::SetStationCountry($values["preferences_support"]["Country"]);
+ Application_Model_Preference::SetStationCity($values["preferences_support"]["City"]);
+ Application_Model_Preference::SetStationDescription($values["preferences_support"]["Description"]);
+ Application_Model_Preference::SetStationLogo($imagePath);
+
$this->view->statusMsg = "<div class='success'>Preferences updated.</div>";
}
}
-
+ $logo = Application_Model_Preference::GetStationLogo();
+ if($logo){
+ $this->view->logoImg = $logo;
+ }
$this->view->form = $form;
}
+
+ public function directoryConfigAction()
+ {
+ $request = $this->getRequest();
+ $baseUrl = $request->getBaseUrl();
+
+ $this->view->headScript()->appendFile($baseUrl.'/js/serverbrowse/serverbrowser.js','text/javascript');
+ $this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/musicdirs.js','text/javascript');
+
+ $watched_dirs_pref = new Application_Form_WatchedDirPreferences();
+
+ $this->view->form = $watched_dirs_pref;
+ }
+
+ public function serverBrowseAction()
+ {
+ $request = $this->getRequest();
+ $path = $request->getParam("path", null);
+
+ $result = array();
+
+ if(is_null($path))
+ {
+ $element = array();
+ $element["name"] = "path should be specified";
+ $element["isFolder"] = false;
+ $element["isError"] = true;
+ $result[$path] = $element;
+ }
+ else
+ {
+ $path = $path.'/';
+ $handle = opendir($path);
+ while (false !== ($file = readdir($handle))) {
+ if ($file != "." && $file != "..") {
+ //only show directories that aren't private.
+ if (is_dir($path.$file) && substr($file, 0, 1) != ".") {
+ $element = array();
+ $element["name"] = $file;
+ $element["isFolder"] = true;
+ $element["isError"] = false;
+ $result[$file] = $element;
+ }
+ }
+ }
+ }
+ ksort($result);
+ //returns format serverBrowse is looking for.
+ die(json_encode($result));
+ }
+
+ public function changeStorDirectoryAction()
+ {
+ $chosen = $this->getRequest()->getParam("dir");
+ $element = $this->getRequest()->getParam("element");
+ $watched_dirs_form = new Application_Form_WatchedDirPreferences();
+
+ $res = MusicDir::setStorDir($chosen);
+ if($res['code'] != 0){
+ $watched_dirs_form->populate(array('storageFolder' => $chosen));
+ $watched_dirs_form->getElement($element)->setErrors(array($res['error']));
+ }
+
+ $this->view->subform = $watched_dirs_form->render();
+ }
+
+ public function reloadWatchDirectoryAction()
+ {
+ $chosen = $this->getRequest()->getParam("dir");
+ $element = $this->getRequest()->getParam("element");
+ $watched_dirs_form = new Application_Form_WatchedDirPreferences();
+
+ $res = MusicDir::addWatchedDir($chosen);
+ if($res['code'] != 0){
+ $watched_dirs_form->populate(array('watchedFolder' => $chosen));
+ $watched_dirs_form->getElement($element)->setErrors(array($res['error']));
+ }
+
+ $this->view->subform = $watched_dirs_form->render();
+ }
+
+ public function removeWatchDirectoryAction()
+ {
+ $chosen = $this->getRequest()->getParam("dir");
+
+ $dir = MusicDir::removeWatchedDir($chosen);
+
+ $watched_dirs_form = new Application_Form_WatchedDirPreferences();
+ $this->view->subform = $watched_dirs_form->render();
+ }
+
+ public function isImportInProgressAction(){
+ $now = time();
+ $res = false;
+ if(Application_Model_Preference::GetImportTimestamp()+10 > $now){
+ $res = true;
+ }
+ die(json_encode($res));
+ }
}
View
67 airtime_mvc/application/controllers/ScheduleController.php
@@ -59,6 +59,7 @@ public function indexAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
$this->view->isAdmin = $user->isAdmin();
+ $this->view->isProgramManager = $user->isUserType('P');
}
public function eventFeedAction()
@@ -68,7 +69,7 @@ public function eventFeedAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if($user->isAdmin())
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)))
$editable = true;
else
$editable = false;
@@ -85,7 +86,7 @@ public function moveShowAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if($user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$show = new ShowInstance($showInstanceId);
$error = $show->moveShow($deltaDay, $deltaMin);
}
@@ -104,7 +105,7 @@ public function resizeShowAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if($user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$show = new ShowInstance($showInstanceId);
$error = $show->resizeShow($deltaDay, $deltaMin);
}
@@ -120,7 +121,7 @@ public function deleteShowAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if($user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$show = new ShowInstance($showInstanceId);
$show->deleteShow();
}
@@ -155,7 +156,7 @@ public function uploadToSoundCloudAction()
try {
$soundcloud = new ATSoundcloud();
- $soundcloud_id = $soundcloud->uploadTrack($file->getRealFilePath(), $file->getName(), $description, $tags, $show_start_time, $show_genre);
+ $soundcloud_id = $soundcloud->uploadTrack($file->getFilePath(), $file->getName(), $description, $tags, $show_start_time, $show_genre);
$show_inst->setSoundCloudFileId($soundcloud_id);
$this->view->soundcloud_id = $soundcloud_id;
break;
@@ -182,10 +183,10 @@ public function makeContextMenuAction()
$show = new ShowInstance($id);
$params = '/format/json/id/#id#';
-
+
if (strtotime($today_timestamp) < strtotime($show->getShowStart())) {
- if (($user->isHost($show->getShowId()) || $user->isAdmin()) && !$show->isRecorded() && !$show->isRebroadcast()) {
+ if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST),$show->getShowId()) && !$show->isRecorded() && !$show->isRebroadcast()) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/schedule-show-dialog'.$params,
'callback' => 'window["buildScheduleDialog"]'), 'title' => 'Add / Remove Content');
@@ -213,15 +214,15 @@ public function makeContextMenuAction()
if (strtotime($show->getShowStart()) <= strtotime($today_timestamp) &&
strtotime($today_timestamp) < strtotime($show->getShowEnd()) &&
- $user->isAdmin()) {
+ $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$menu[] = array('action' => array('type' => 'fn',
'callback' => "window['confirmCancelShow']($id)"),
'title' => 'Cancel Current Show');
}
if (strtotime($today_timestamp) < strtotime($show->getShowStart())) {
- if ($user->isAdmin()) {
+ if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$menu[] = array('action' => array('type' => 'ajax', 'url' => '/Schedule/edit-show/format/json/id/'.$id,
'callback' => 'window["beginEditShow"]'), 'title' => 'Edit Show');
@@ -231,7 +232,7 @@ public function makeContextMenuAction()
'callback' => 'window["scheduleRefetchEvents"]'), 'title' => 'Delete This Instance and All Following');
}
}
-
+
//returns format jjmenu is looking for.
die(json_encode($menu));
}
@@ -250,7 +251,7 @@ public function scheduleShowAction()
$user = new User($userInfo->id);
$show = new ShowInstance($showInstanceId);
- if($user->isHost($show->getShowId()) || $user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST),$show->getShowId())) {
$show->scheduleShow(array($plId));
}
@@ -269,7 +270,7 @@ public function clearShowAction()
$user = new User($userInfo->id);
$show = new ShowInstance($showInstanceId);
- if($user->isHost($show->getShowId()) || $user->isAdmin())
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST),$show->getShowId()))
$show->clearShow();
}
@@ -284,6 +285,11 @@ public function findPlaylistsAction()
$show = new ShowInstance($this->sched_sess->showInstanceId);
$playlists = $show->searchPlaylistsForShow($post);
+ foreach( $playlists['aaData'] as &$data){
+ // calling two functions to format time to 1 decimal place
+ $sec = Playlist::playlistTimeToSeconds($data[4]);
+ $data[4] = Playlist::secondsToPlaylistTime($sec);
+ }
//for datatables
die(json_encode($playlists));
@@ -299,7 +305,7 @@ public function removeGroupAction()
$user = new User($userInfo->id);
$show = new ShowInstance($showInstanceId);
- if($user->isHost($show->getShowId()) || $user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER, UTYPE_HOST),$show->getShowId())) {
$show->removeGroupFromShow($group_id);
}
@@ -377,7 +383,7 @@ public function editShowAction()
{
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if(!$user->isAdmin()) {
+ if(!$user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
return;
}
@@ -422,7 +428,9 @@ public function editShowAction()
$formWhen->populate(array('add_show_start_date' => $show->getStartDate(),
'add_show_start_time' => DateHelper::removeSecondsFromTime($show->getStartTime()),
- 'add_show_duration' => $show->getDuration(),
+ 'add_show_end_date_no_repeat' => $show->getEndDate(),
+ 'add_show_end_time' => DateHelper::removeSecondsFromTime($show->getEndTime()),
+ 'add_show_duration' => $show->getDuration(true),
'add_show_repeats' => $show->isRepeating() ? 1 : 0));
if ($show->isStartDateTimeInPast()){
@@ -541,6 +549,29 @@ public function addShowAction()
$when = $formWhen->checkReliantFields($data, $startDateModified);
}
+
+ //The way the following code works is that is parses the hour and
+ //minute from a string with the format "1h 20m" or "2h" or "36m".
+ //So we are detecting whether an hour or minute value exists via strpos
+ //and then parse appropriately. A better way to do this in the future is
+ //actually pass the format from javascript in the format hh:mm so we don't
+ //have to do this extra String parsing.
+ $hPos = strpos($data["add_show_duration"], 'h');
+ $mPos = strpos($data["add_show_duration"], 'm');
+
+ $hValue = 0;
+ $mValue = 0;
+
+ if($hPos !== false){
+ $hValue = trim(substr($data["add_show_duration"], 0, $hPos));
+ }
+ if($mPos !== false){
+ $hPos = $hPos === FALSE ? 0 : $hPos+1;
+ $mValue = trim(substr($data["add_show_duration"], $hPos, -1 ));
+ }
+
+ $data["add_show_duration"] = $hValue.":".$mValue;
+
if($data["add_show_repeats"]) {
$repeats = $formRepeats->isValid($data);
if($repeats) {
@@ -597,7 +628,7 @@ public function addShowAction()
if ($what && $when && $repeats && $who && $style && $record && $rebroadAb && $rebroad) {
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if ($user->isAdmin()) {
+ if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
Show::create($data);
}
@@ -635,7 +666,7 @@ public function cancelShowAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if($user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$showInstanceId = $this->_getParam('id');
$showInstance = new ShowInstance($showInstanceId);
@@ -650,7 +681,7 @@ public function cancelCurrentShowAction()
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
$user = new User($userInfo->id);
- if($user->isAdmin()) {
+ if($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) {
$showInstanceId = $this->_getParam('id');
$show = new ShowInstance($showInstanceId);
$show->clearShow();
View
135 airtime_mvc/application/forms/AddShowWhen.php
@@ -5,50 +5,78 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm
public function init()
{
-
- //$this->setDisableLoadDefaultDecorators(true);
- //$this->removeDecorator('DtDdWrapper');
-
- // Add start date element
- $this->addElement('text', 'add_show_start_date', array(
- 'label' => 'Date Start:',
- 'class' => 'input_text',
- 'required' => true,
- 'value' => date("Y-m-d"),
- 'filters' => array('StringTrim'),
- 'validators' => array(
- 'NotEmpty',
- array('date', false, array('YYYY-MM-DD'))
- )
- ));
-
- // Add start time element
- $this->addElement('text', 'add_show_start_time', array(
-