aboutsummaryrefslogtreecommitdiff
path: root/subsonic-main/src/main/java/net/sourceforge/subsonic
diff options
context:
space:
mode:
Diffstat (limited to 'subsonic-main/src/main/java/net/sourceforge/subsonic')
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/Logger.java231
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ChatService.java163
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtInfo.java43
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtService.java145
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsInfo.java53
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsService.java105
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/MultiService.java51
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NetworkStatus.java55
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingInfo.java98
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingService.java172
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueInfo.java174
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueService.java455
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistInfo.java90
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistService.java187
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ScanInfo.java43
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/StarService.java64
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TagService.java128
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TransferService.java49
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/UploadInfo.java52
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/cache/CacheFactory.java58
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/AdvancedSettingsCommand.java146
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/DonateCommand.java88
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/EnumHolder.java42
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/GeneralSettingsCommand.java184
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/MusicFolderSettingsCommand.java187
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/NetworkSettingsCommand.java92
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/PasswordSettingsCommand.java65
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/PersonalSettingsCommand.java215
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/PlayerSettingsCommand.java250
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/PodcastSettingsCommand.java66
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/SearchCommand.java135
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/command/UserSettingsCommand.java278
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AbstractChartController.java60
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AdvancedSettingsController.java91
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AllmusicController.java38
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarController.java82
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarUploadController.java141
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ChangeCoverArtController.java72
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/CoverArtController.java294
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DBController.java66
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DonateController.java74
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DownloadController.java453
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/EditTagsController.java194
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ExternalPlayerController.java179
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/GeneralSettingsController.java114
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HelpController.java80
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HomeController.java340
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ImportPlaylistController.java93
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/InternetRadioSettingsController.java116
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LeftController.java270
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LyricsController.java46
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/M3UController.java128
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MainController.java297
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MoreController.java89
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MultiController.java244
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MusicFolderSettingsController.java130
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NetworkSettingsController.java89
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NowPlayingController.java79
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PasswordSettingsController.java58
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PersonalSettingsController.java164
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayQueueController.java77
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayerSettingsController.java150
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlaylistController.java82
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastController.java152
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverAdminController.java102
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverController.java85
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastSettingsController.java67
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ProxyController.java68
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RESTController.java1983
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RandomPlayQueueController.java101
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ReloadFrame.java52
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RightController.java66
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SearchController.java106
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetMusicFileInfoController.java58
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetRatingController.java69
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SettingsController.java52
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareManagementController.java123
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareSettingsController.java161
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StarredController.java96
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusChartController.java149
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusController.java141
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StreamController.java419
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TopController.java84
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TranscodingSettingsController.java139
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java260
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserChartController.java145
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserSettingsController.java159
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/VideoPlayerController.java110
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/controller/WapController.java247
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AbstractDao.java127
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AlbumDao.java243
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ArtistDao.java161
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AvatarDao.java94
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/DaoHelper.java117
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/InternetRadioDao.java89
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MediaFileDao.java374
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MusicFolderDao.java91
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlayerDao.java194
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlaylistDao.java142
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PodcastDao.java165
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/RatingDao.java99
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ShareDao.java131
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/TranscodingDao.java123
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/UserDao.java352
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema.java66
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema25.java81
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema26.java110
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema27.java54
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema28.java110
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema29.java55
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema30.java56
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema31.java52
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema32.java93
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema33.java47
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema34.java53
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema35.java151
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema36.java48
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema37.java77
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema38.java54
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema40.java46
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema43.java65
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema45.java76
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema46.java87
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema47.java234
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Album.java166
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Artist.java95
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Avatar.java75
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/AvatarScheme.java52
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CacheElement.java65
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CoverArtScheme.java48
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/InternetRadio.java168
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFile.java449
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFileComparator.java99
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaLibraryStatistics.java62
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicFolder.java148
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicIndex.java167
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/NATPMPRouter.java61
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayQueue.java417
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Player.java338
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayerTechnology.java49
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Playlist.java141
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastChannel.java96
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastEpisode.java172
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastStatus.java29
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/RandomSearchCriteria.java70
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Router.java43
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SBBIRouter.java63
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchCriteria.java59
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchResult.java69
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Share.java100
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Theme.java42
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TranscodeScheme.java104
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Transcoding.java221
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TransferStatus.java303
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/User.java245
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/UserSettings.java328
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Version.java141
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/VideoTranscodingSettings.java50
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/domain/WeUPnPRouter.java56
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/filter/BootstrapVerificationFilter.java107
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ParameterDecodingFilter.java147
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/filter/RequestEncodingFilter.java54
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ResponseHeaderFilter.java57
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/i18n/SubsonicLocaleResolver.java104
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java63
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java154
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java150
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java205
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java124
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/SubsonicLdapBindAuthenticator.java131
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java50
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/security/RESTRequestParameterProcessingFilter.java246
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/AdService.java71
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/AudioScrobblerService.java331
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/JukeboxService.java206
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaFileService.java614
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaScannerService.java354
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/MusicIndexService.java250
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/NetworkService.java336
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlayerService.java317
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlaylistService.java426
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/PodcastService.java599
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/RatingService.java101
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/SearchService.java567
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/SecurityService.java303
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/ServiceLocator.java46
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/SettingsService.java1225
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/ShareService.java133
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/StatusService.java134
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java530
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/VersionService.java267
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/AudioPlayer.java207
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/PlayerTest.java75
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/DefaultMetaDataParser.java74
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/FFmpegParser.java170
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/JaudiotaggerParser.java296
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaData.java135
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParser.java162
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParserFactory.java51
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java77
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java76
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java67
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java207
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java72
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeResolver.java117
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeSource.java49
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItem.java51
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItemFactory.java47
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredOutputStream.java60
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/upload/UploadListener.java29
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/util/BoundedList.java71
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/util/FileUtil.java186
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/util/Pair.java54
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/util/StringUtil.java537
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/util/Util.java127
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java328
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/validator/DonateValidator.java51
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/validator/PasswordSettingsValidator.java45
-rw-r--r--subsonic-main/src/main/java/net/sourceforge/subsonic/validator/UserSettingsValidator.java91
219 files changed, 0 insertions, 34570 deletions
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/Logger.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/Logger.java
deleted file mode 100644
index 0e595458..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/Logger.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic;
-
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.util.*;
-import org.apache.commons.lang.exception.*;
-
-import java.io.*;
-import java.text.*;
-import java.util.*;
-
-/**
- * Logger implementation which logs to SUBSONIC_HOME/subsonic.log.
- * <br/>
- * Note: Third party logging libraries (such as log4j and Commons logging) are intentionally not
- * used. These libraries causes a lot of headache when deploying to some application servers
- * (for instance Jetty and JBoss).
- *
- * @author Sindre Mehus
- * @version $Revision: 1.1 $ $Date: 2005/05/09 19:58:26 $
- */
-public class Logger {
-
- private String category;
-
- private static List<Entry> entries = Collections.synchronizedList(new BoundedList<Entry>(50));
- private static PrintWriter writer;
-
- /**
- * Creates a logger for the given class.
- * @param clazz The class.
- * @return A logger for the class.
- */
- public static Logger getLogger(Class clazz) {
- return new Logger(clazz.getName());
- }
-
- /**
- * Creates a logger for the given namee.
- * @param name The name.
- * @return A logger for the name.
- */
- public static Logger getLogger(String name) {
- return new Logger(name);
- }
-
- /**
- * Returns the last few log entries.
- * @return The last few log entries.
- */
- public static Entry[] getLatestLogEntries() {
- return entries.toArray(new Entry[0]);
- }
-
- private Logger(String name) {
- int lastDot = name.lastIndexOf('.');
- if (lastDot == -1) {
- category = name;
- } else {
- category = name.substring(lastDot + 1);
- }
- }
-
- /**
- * Logs a debug message.
- * @param message The log message.
- */
- public void debug(Object message) {
- debug(message, null);
- }
-
- /**
- * Logs a debug message.
- * @param message The message.
- * @param error The optional exception.
- */
- public void debug(Object message, Throwable error) {
- add(Level.DEBUG, message, error);
- }
-
- /**
- * Logs an info message.
- * @param message The message.
- */
- public void info(Object message) {
- info(message, null);
- }
-
- /**
- * Logs an info message.
- * @param message The message.
- * @param error The optional exception.
- */
- public void info(Object message, Throwable error) {
- add(Level.INFO, message, error);
- }
-
- /**
- * Logs a warning message.
- * @param message The message.
- */
- public void warn(Object message) {
- warn(message, null);
- }
-
- /**
- * Logs a warning message.
- * @param message The message.
- * @param error The optional exception.
- */
- public void warn(Object message, Throwable error) {
- add(Level.WARN, message, error);
- }
-
- /**
- * Logs an error message.
- * @param message The message.
- */
- public void error(Object message) {
- error(message, null);
- }
-
- /**
- * Logs an error message.
- * @param message The message.
- * @param error The optional exception.
- */
- public void error(Object message, Throwable error) {
- add(Level.ERROR, message, error);
- }
-
- private void add(Level level, Object message, Throwable error) {
- Entry entry = new Entry(category, level, message, error);
- try {
- getPrintWriter().println(entry);
- } catch (IOException x) {
- System.err.println("Failed to write to subsonic.log.");
- x.printStackTrace();
- }
- entries.add(entry);
- }
-
- private static synchronized PrintWriter getPrintWriter() throws IOException {
- if (writer == null) {
- writer = new PrintWriter(new FileWriter(getLogFile(), false), true);
- }
- return writer;
- }
-
- public static File getLogFile() {
- File subsonicHome = SettingsService.getSubsonicHome();
- return new File(subsonicHome, "subsonic.log");
- }
-
- /**
- * Log level.
- */
- public enum Level {
- DEBUG, INFO, WARN, ERROR
- }
-
- /**
- * Log entry.
- */
- public static class Entry {
- private String category;
- private Date date;
- private Level level;
- private Object message;
- private Throwable error;
- private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
-
- public Entry(String category, Level level, Object message, Throwable error) {
- this.date = new Date();
- this.category = category;
- this.level = level;
- this.message = message;
- this.error = error;
- }
-
- public String getCategory() {
- return category;
- }
-
- public Date getDate() {
- return date;
- }
-
- public Level getLevel() {
- return level;
- }
-
- public Object getMessage() {
- return message;
- }
-
- public Throwable getError() {
- return error;
- }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append('[').append(DATE_FORMAT.format(date)).append("] ");
- buf.append(level).append(' ');
- buf.append(category).append(" - ");
- buf.append(message);
-
- if (error != null) {
- buf.append('\n').append(ExceptionUtils.getFullStackTrace(error));
- }
- return buf.toString();
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ChatService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ChatService.java
deleted file mode 100644
index 8905c8a6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ChatService.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.util.BoundedList;
-import org.apache.commons.lang.StringUtils;
-import org.directwebremoting.WebContext;
-import org.directwebremoting.WebContextFactory;
-
-import javax.servlet.http.HttpServletRequest;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Provides AJAX-enabled services for the chatting.
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class ChatService {
-
- private static final Logger LOG = Logger.getLogger(ChatService.class);
- private static final String CACHE_KEY = "1";
- private static final int MAX_MESSAGES = 10;
- private static final long TTL_MILLIS = 3L * 24L * 60L * 60L * 1000L; // 3 days.
-
- private final LinkedList<Message> messages = new BoundedList<Message>(MAX_MESSAGES);
- private SecurityService securityService;
-
- private long revision = System.identityHashCode(this);
-
- /**
- * Invoked by Spring.
- */
- public void init() {
- // Delete old messages every hour.
- ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
- Runnable runnable = new Runnable() {
- public void run() {
- removeOldMessages();
- }
- };
- executor.scheduleWithFixedDelay(runnable, 0L, 3600L, TimeUnit.SECONDS);
- }
-
- private synchronized void removeOldMessages() {
- long now = System.currentTimeMillis();
- for (Iterator<Message> iterator = messages.iterator(); iterator.hasNext();) {
- Message message = iterator.next();
- if (now - message.getDate().getTime() > TTL_MILLIS) {
- iterator.remove();
- revision++;
- }
- }
- }
-
- public synchronized void addMessage(String message) {
- WebContext webContext = WebContextFactory.get();
- doAddMessage(message, webContext.getHttpServletRequest());
- }
-
- public synchronized void doAddMessage(String message, HttpServletRequest request) {
-
- String user = securityService.getCurrentUsername(request);
- message = StringUtils.trimToNull(message);
- if (message != null && user != null) {
- messages.addFirst(new Message(message, user, new Date()));
- revision++;
- }
- }
-
- public synchronized void clearMessages() {
- messages.clear();
- revision++;
- }
-
- /**
- * Returns all messages, but only if the given revision is different from the
- * current revision.
- */
- public synchronized Messages getMessages(long revision) {
- if (this.revision != revision) {
- return new Messages(new ArrayList<Message>(messages), this.revision);
- }
- return null;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public static class Messages implements Serializable {
-
- private static final long serialVersionUID = -752602719879818165L;
- private final List<Message> messages;
- private final long revision;
-
- public Messages(List<Message> messages, long revision) {
- this.messages = messages;
- this.revision = revision;
- }
-
- public List<Message> getMessages() {
- return messages;
- }
-
- public long getRevision() {
- return revision;
- }
- }
-
- public static class Message implements Serializable {
-
- private static final long serialVersionUID = -1907101191518133712L;
- private final String content;
- private final String username;
- private final Date date;
-
- public Message(String content, String username, Date date) {
- this.content = content;
- this.username = username;
- this.date = date;
- }
-
- public String getContent() {
- return content;
- }
-
- public String getUsername() {
- return username;
- }
-
- public Date getDate() {
- return date;
- }
-
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtInfo.java
deleted file mode 100644
index c9160f26..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtInfo.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-/**
- * Contains info about cover art images for an album.
- *
- * @author Sindre Mehus
- */
-public class CoverArtInfo {
-
- private final String imagePreviewUrl;
- private final String imageDownloadUrl;
-
- public CoverArtInfo(String imagePreviewUrl, String imageDownloadUrl) {
- this.imagePreviewUrl = imagePreviewUrl;
- this.imageDownloadUrl = imageDownloadUrl;
- }
-
- public String getImagePreviewUrl() {
- return imagePreviewUrl;
- }
-
- public String getImageDownloadUrl() {
- return imageDownloadUrl;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtService.java
deleted file mode 100644
index 1c3642b6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/CoverArtService.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Provides AJAX-enabled services for changing cover art images.
- * <p/>
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class CoverArtService {
-
- private static final Logger LOG = Logger.getLogger(CoverArtService.class);
-
- private SecurityService securityService;
- private MediaFileService mediaFileService;
-
- /**
- * Downloads and saves the cover art at the given URL.
- *
- * @param albumId ID of the album in question.
- * @param url The image URL.
- * @return The error string if something goes wrong, <code>null</code> otherwise.
- */
- public String setCoverArtImage(int albumId, String url) {
- try {
- MediaFile mediaFile = mediaFileService.getMediaFile(albumId);
- saveCoverArt(mediaFile.getPath(), url);
- return null;
- } catch (Exception x) {
- LOG.warn("Failed to save cover art for album " + albumId, x);
- return x.toString();
- }
- }
-
- private void saveCoverArt(String path, String url) throws Exception {
- InputStream input = null;
- HttpClient client = new DefaultHttpClient();
-
- try {
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 20 * 1000); // 20 seconds
- HttpConnectionParams.setSoTimeout(client.getParams(), 20 * 1000); // 20 seconds
- HttpGet method = new HttpGet(url);
-
- HttpResponse response = client.execute(method);
- input = response.getEntity().getContent();
-
- // Attempt to resolve proper suffix.
- String suffix = "jpg";
- if (url.toLowerCase().endsWith(".gif")) {
- suffix = "gif";
- } else if (url.toLowerCase().endsWith(".png")) {
- suffix = "png";
- }
-
- // Check permissions.
- File newCoverFile = new File(path, "cover." + suffix);
- if (!securityService.isWriteAllowed(newCoverFile)) {
- throw new Exception("Permission denied: " + StringUtil.toHtml(newCoverFile.getPath()));
- }
-
- // If file exists, create a backup.
- backup(newCoverFile, new File(path, "cover.backup." + suffix));
-
- // Write file.
- IOUtils.copy(input, new FileOutputStream(newCoverFile));
-
- MediaFile mediaFile = mediaFileService.getMediaFile(path);
-
- // Rename existing cover file if new cover file is not the preferred.
- try {
- File coverFile = mediaFileService.getCoverArt(mediaFile);
- if (coverFile != null) {
- if (!newCoverFile.equals(coverFile)) {
- coverFile.renameTo(new File(coverFile.getCanonicalPath() + ".old"));
- LOG.info("Renamed old image file " + coverFile);
- }
- }
- } catch (Exception x) {
- LOG.warn("Failed to rename existing cover file.", x);
- }
-
- mediaFileService.refreshMediaFile(mediaFile);
-
- } finally {
- IOUtils.closeQuietly(input);
- client.getConnectionManager().shutdown();
- }
- }
-
- private void backup(File newCoverFile, File backup) {
- if (newCoverFile.exists()) {
- if (backup.exists()) {
- backup.delete();
- }
- if (newCoverFile.renameTo(backup)) {
- LOG.info("Backed up old image file to " + backup);
- } else {
- LOG.warn("Failed to create image file backup " + backup);
- }
- }
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsInfo.java
deleted file mode 100644
index b84ffe1f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsInfo.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-/**
- * Contains lyrics info for a song.
- *
- * @author Sindre Mehus
- */
-public class LyricsInfo {
-
- private final String lyrics;
- private final String artist;
- private final String title;
-
- public LyricsInfo() {
- this(null, null, null);
- }
-
- public LyricsInfo(String lyrics, String artist, String title) {
- this.lyrics = lyrics;
- this.artist = artist;
- this.title = title;
- }
-
- public String getLyrics() {
- return lyrics;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public String getTitle() {
- return title;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsService.java
deleted file mode 100644
index 45c039f7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/LyricsService.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.util.StringUtil;
-
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.BasicResponseHandler;
-import org.apache.http.params.HttpConnectionParams;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
-
-import java.io.IOException;
-import java.io.StringReader;
-
-/**
- * Provides AJAX-enabled services for retrieving song lyrics from chartlyrics.com.
- * <p/>
- * See http://www.chartlyrics.com/api.aspx for details.
- * <p/>
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class LyricsService {
-
- private static final Logger LOG = Logger.getLogger(LyricsService.class);
-
- /**
- * Returns lyrics for the given song and artist.
- *
- * @param artist The artist.
- * @param song The song.
- * @return The lyrics, never <code>null</code> .
- */
- public LyricsInfo getLyrics(String artist, String song) {
- LyricsInfo lyrics = new LyricsInfo();
- try {
-
- artist = StringUtil.urlEncode(artist);
- song = StringUtil.urlEncode(song);
-
- String url = "http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect?artist=" + artist + "&song=" + song;
- String xml = executeGetRequest(url);
-
- lyrics = parseSearchResult(xml);
-
- } catch (Exception x) {
- LOG.warn("Failed to get lyrics for song '" + song + "'.", x);
- }
- return lyrics;
- }
-
-
- private LyricsInfo parseSearchResult(String xml) throws Exception {
- SAXBuilder builder = new SAXBuilder();
- Document document = builder.build(new StringReader(xml));
-
- Element root = document.getRootElement();
- Namespace ns = root.getNamespace();
-
- String lyric = root.getChildText("Lyric", ns);
- String song = root.getChildText("LyricSong", ns);
- String artist = root.getChildText("LyricArtist", ns);
-
- return new LyricsInfo(lyric, artist, song);
- }
-
- private String executeGetRequest(String url) throws IOException {
- HttpClient client = new DefaultHttpClient();
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
- HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
- HttpGet method = new HttpGet(url);
- try {
-
- ResponseHandler<String> responseHandler = new BasicResponseHandler();
- return client.execute(method, responseHandler);
-
- } finally {
- client.getConnectionManager().shutdown();
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/MultiService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/MultiService.java
deleted file mode 100644
index 0c83e30f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/MultiService.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.service.NetworkService;
-
-/**
- * Provides miscellaneous AJAX-enabled services.
- * <p/>
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class MultiService {
-
- private static final Logger LOG = Logger.getLogger(MultiService.class);
- private NetworkService networkService;
-
- /**
- * Returns status for port forwarding and URL redirection.
- */
- public NetworkStatus getNetworkStatus() {
- NetworkService.Status portForwardingStatus = networkService.getPortForwardingStatus();
- NetworkService.Status urlRedirectionStatus = networkService.getURLRedirecionStatus();
- return new NetworkStatus(portForwardingStatus.getText(),
- portForwardingStatus.getDate(),
- urlRedirectionStatus.getText(),
- urlRedirectionStatus.getDate());
- }
-
- public void setNetworkService(NetworkService networkService) {
- this.networkService = networkService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NetworkStatus.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NetworkStatus.java
deleted file mode 100644
index 8634af26..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NetworkStatus.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import java.util.Date;
-
-/**
- * @author Sindre Mehus
- */
-public class NetworkStatus {
- private final String portForwardingStatusText;
- private final Date portForwardingStatusDate;
- private final String urlRedirectionStatusText;
- private final Date urlRedirectionStatusDate;
-
- public NetworkStatus(String portForwardingStatusText, Date portForwardingStatusDate,
- String urlRedirectionStatusText, Date urlRedirectionStatusDate) {
- this.portForwardingStatusText = portForwardingStatusText;
- this.portForwardingStatusDate = portForwardingStatusDate;
- this.urlRedirectionStatusText = urlRedirectionStatusText;
- this.urlRedirectionStatusDate = urlRedirectionStatusDate;
- }
-
- public String getPortForwardingStatusText() {
- return portForwardingStatusText;
- }
-
- public Date getPortForwardingStatusDate() {
- return portForwardingStatusDate;
- }
-
- public String getUrlRedirectionStatusText() {
- return urlRedirectionStatusText;
- }
-
- public Date getUrlRedirectionStatusDate() {
- return urlRedirectionStatusDate;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingInfo.java
deleted file mode 100644
index 520cfcab..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingInfo.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-/**
- * Details about what a user is currently listening to.
- *
- * @author Sindre Mehus
- */
-public class NowPlayingInfo {
-
- private final String username;
- private final String artist;
- private final String title;
- private final String tooltip;
- private final String streamUrl;
- private final String albumUrl;
- private final String lyricsUrl;
- private final String coverArtUrl;
- private final String coverArtZoomUrl;
- private final String avatarUrl;
- private final int minutesAgo;
-
- public NowPlayingInfo(String user, String artist, String title, String tooltip, String streamUrl, String albumUrl,
- String lyricsUrl, String coverArtUrl, String coverArtZoomUrl, String avatarUrl, int minutesAgo) {
- this.username = user;
- this.artist = artist;
- this.title = title;
- this.tooltip = tooltip;
- this.streamUrl = streamUrl;
- this.albumUrl = albumUrl;
- this.lyricsUrl = lyricsUrl;
- this.coverArtUrl = coverArtUrl;
- this.coverArtZoomUrl = coverArtZoomUrl;
- this.avatarUrl = avatarUrl;
- this.minutesAgo = minutesAgo;
- }
-
- public String getUsername() {
- return username;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getTooltip() {
- return tooltip;
- }
-
- public String getStreamUrl() {
- return streamUrl;
- }
-
- public String getAlbumUrl() {
- return albumUrl;
- }
-
- public String getLyricsUrl() {
- return lyricsUrl;
- }
-
- public String getCoverArtUrl() {
- return coverArtUrl;
- }
-
- public String getCoverArtZoomUrl() {
- return coverArtZoomUrl;
- }
-
- public String getAvatarUrl() {
- return avatarUrl;
- }
-
- public int getMinutesAgo() {
- return minutesAgo;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingService.java
deleted file mode 100644
index ef7922b4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/NowPlayingService.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.domain.AvatarScheme;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.MediaScannerService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.StatusService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.commons.lang.StringUtils;
-import org.directwebremoting.WebContext;
-import org.directwebremoting.WebContextFactory;
-
-import javax.servlet.http.HttpServletRequest;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides AJAX-enabled services for retrieving the currently playing file and directory.
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class NowPlayingService {
-
- private PlayerService playerService;
- private StatusService statusService;
- private SettingsService settingsService;
- private MediaScannerService mediaScannerService;
- private MediaFileService mediaFileService;
-
- /**
- * Returns details about what the current player is playing.
- *
- * @return Details about what the current player is playing, or <code>null</code> if not playing anything.
- */
- public NowPlayingInfo getNowPlayingForCurrentPlayer() throws Exception {
- WebContext webContext = WebContextFactory.get();
- Player player = playerService.getPlayer(webContext.getHttpServletRequest(), webContext.getHttpServletResponse());
- List<TransferStatus> statuses = statusService.getStreamStatusesForPlayer(player);
- List<NowPlayingInfo> result = convert(statuses);
-
- return result.isEmpty() ? null : result.get(0);
- }
-
- /**
- * Returns details about what all users are currently playing.
- *
- * @return Details about what all users are currently playing.
- */
- public List<NowPlayingInfo> getNowPlaying() throws Exception {
- return convert(statusService.getAllStreamStatuses());
- }
-
- /**
- * Returns media folder scanning status.
- */
- public ScanInfo getScanningStatus() {
- return new ScanInfo(mediaScannerService.isScanning(), mediaScannerService.getScanCount());
- }
-
- private List<NowPlayingInfo> convert(List<TransferStatus> statuses) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- String url = request.getRequestURL().toString();
- List<NowPlayingInfo> result = new ArrayList<NowPlayingInfo>();
- for (TransferStatus status : statuses) {
-
- Player player = status.getPlayer();
- File file = status.getFile();
-
- if (player != null && player.getUsername() != null && file != null) {
-
- String username = player.getUsername();
- UserSettings userSettings = settingsService.getUserSettings(username);
- if (!userSettings.isNowPlayingAllowed()) {
- continue;
- }
-
- MediaFile mediaFile = mediaFileService.getMediaFile(file);
- File coverArt = mediaFileService.getCoverArt(mediaFile);
-
- String artist = mediaFile.getArtist();
- String title = mediaFile.getTitle();
- String streamUrl = url.replaceFirst("/dwr/.*", "/stream?player=" + player.getId() + "&id=" + mediaFile.getId());
- String albumUrl = url.replaceFirst("/dwr/.*", "/main.view?id=" + mediaFile.getId());
- String lyricsUrl = url.replaceFirst("/dwr/.*", "/lyrics.view?artistUtf8Hex=" + StringUtil.utf8HexEncode(artist) +
- "&songUtf8Hex=" + StringUtil.utf8HexEncode(title));
- String coverArtUrl = coverArt == null ? null : url.replaceFirst("/dwr/.*", "/coverArt.view?size=48&id=" + mediaFile.getId());
- String coverArtZoomUrl = coverArt == null ? null : url.replaceFirst("/dwr/.*", "/coverArt.view?id=" + mediaFile.getId());
-
- String avatarUrl = null;
- if (userSettings.getAvatarScheme() == AvatarScheme.SYSTEM) {
- avatarUrl = url.replaceFirst("/dwr/.*", "/avatar.view?id=" + userSettings.getSystemAvatarId());
- } else if (userSettings.getAvatarScheme() == AvatarScheme.CUSTOM && settingsService.getCustomAvatar(username) != null) {
- avatarUrl = url.replaceFirst("/dwr/.*", "/avatar.view?username=" + username);
- }
-
- // Rewrite URLs in case we're behind a proxy.
- if (settingsService.isRewriteUrlEnabled()) {
- String referer = request.getHeader("referer");
- streamUrl = StringUtil.rewriteUrl(streamUrl, referer);
- albumUrl = StringUtil.rewriteUrl(albumUrl, referer);
- lyricsUrl = StringUtil.rewriteUrl(lyricsUrl, referer);
- coverArtUrl = StringUtil.rewriteUrl(coverArtUrl, referer);
- coverArtZoomUrl = StringUtil.rewriteUrl(coverArtZoomUrl, referer);
- avatarUrl = StringUtil.rewriteUrl(avatarUrl, referer);
- }
-
- String tooltip = StringUtil.toHtml(artist) + " &ndash; " + StringUtil.toHtml(title);
-
- if (StringUtils.isNotBlank(player.getName())) {
- username += "@" + player.getName();
- }
- artist = StringUtil.toHtml(StringUtils.abbreviate(artist, 25));
- title = StringUtil.toHtml(StringUtils.abbreviate(title, 25));
- username = StringUtil.toHtml(StringUtils.abbreviate(username, 25));
-
- long minutesAgo = status.getMillisSinceLastUpdate() / 1000L / 60L;
- if (minutesAgo < 60) {
- result.add(new NowPlayingInfo(username, artist, title, tooltip, streamUrl, albumUrl, lyricsUrl,
- coverArtUrl, coverArtZoomUrl, avatarUrl, (int) minutesAgo));
- }
- }
- }
-
- return result;
-
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaScannerService(MediaScannerService mediaScannerService) {
- this.mediaScannerService = mediaScannerService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueInfo.java
deleted file mode 100644
index e95ec1c8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueInfo.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import java.util.List;
-
-/**
- * The playlist of a player.
- *
- * @author Sindre Mehus
- */
-public class PlayQueueInfo {
-
- private final List<Entry> entries;
- private final int index;
- private final boolean stopEnabled;
- private final boolean repeatEnabled;
- private final boolean sendM3U;
- private final float gain;
-
- public PlayQueueInfo(List<Entry> entries, int index, boolean stopEnabled, boolean repeatEnabled, boolean sendM3U, float gain) {
- this.entries = entries;
- this.index = index;
- this.stopEnabled = stopEnabled;
- this.repeatEnabled = repeatEnabled;
- this.sendM3U = sendM3U;
- this.gain = gain;
- }
-
- public List<Entry> getEntries() {
- return entries;
- }
-
- public int getIndex() {
- return index;
- }
-
- public boolean isStopEnabled() {
- return stopEnabled;
- }
-
- public boolean isSendM3U() {
- return sendM3U;
- }
-
- public boolean isRepeatEnabled() {
- return repeatEnabled;
- }
-
- public float getGain() {
- return gain;
- }
-
- public static class Entry {
- private final int id;
- private final Integer trackNumber;
- private final String title;
- private final String artist;
- private final String album;
- private final String genre;
- private final Integer year;
- private final String bitRate;
- private final Integer duration;
- private final String durationAsString;
- private final String format;
- private final String contentType;
- private final String fileSize;
- private final boolean starred;
- private final String albumUrl;
- private final String streamUrl;
-
- public Entry(int id, Integer trackNumber, String title, String artist, String album, String genre, Integer year,
- String bitRate, Integer duration, String durationAsString, String format, String contentType, String fileSize,
- boolean starred, String albumUrl, String streamUrl) {
- this.id = id;
- this.trackNumber = trackNumber;
- this.title = title;
- this.artist = artist;
- this.album = album;
- this.genre = genre;
- this.year = year;
- this.bitRate = bitRate;
- this.duration = duration;
- this.durationAsString = durationAsString;
- this.format = format;
- this.contentType = contentType;
- this.fileSize = fileSize;
- this.starred = starred;
- this.albumUrl = albumUrl;
- this.streamUrl = streamUrl;
- }
-
- public int getId() {
- return id;
- }
-
- public Integer getTrackNumber() {
- return trackNumber;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public String getAlbum() {
- return album;
- }
-
- public String getGenre() {
- return genre;
- }
-
- public Integer getYear() {
- return year;
- }
-
- public String getBitRate() {
- return bitRate;
- }
-
- public String getDurationAsString() {
- return durationAsString;
- }
-
- public Integer getDuration() {
- return duration;
- }
-
- public String getFormat() {
- return format;
- }
-
- public String getContentType() {
- return contentType;
- }
-
- public String getFileSize() {
- return fileSize;
- }
-
- public boolean isStarred() {
- return starred;
- }
-
- public String getAlbumUrl() {
- return albumUrl;
- }
-
- public String getStreamUrl() {
- return streamUrl;
- }
- }
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueService.java
deleted file mode 100644
index 94f78aba..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlayQueueService.java
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.service.PlaylistService;
-import org.directwebremoting.WebContextFactory;
-import org.springframework.web.servlet.support.RequestContextUtils;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Provides AJAX-enabled services for manipulating the play queue of a player.
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class PlayQueueService {
-
- private PlayerService playerService;
- private JukeboxService jukeboxService;
- private TranscodingService transcodingService;
- private SettingsService settingsService;
- private MediaFileService mediaFileService;
- private SecurityService securityService;
- private MediaFileDao mediaFileDao;
- private net.sourceforge.subsonic.service.PlaylistService playlistService;
-
- /**
- * Returns the play queue for the player of the current user.
- *
- * @return The play queue.
- */
- public PlayQueueInfo getPlayQueue() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo start() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doStart(request, response);
- }
-
- public PlayQueueInfo doStart(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().setStatus(PlayQueue.Status.PLAYING);
- return convert(request, player, true);
- }
-
- public PlayQueueInfo stop() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doStop(request, response);
- }
-
- public PlayQueueInfo doStop(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().setStatus(PlayQueue.Status.STOPPED);
- return convert(request, player, true);
- }
-
- public PlayQueueInfo skip(int index) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doSkip(request, response, index, 0);
- }
-
- public PlayQueueInfo doSkip(HttpServletRequest request, HttpServletResponse response, int index, int offset) throws Exception {
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().setIndex(index);
- boolean serverSidePlaylist = !player.isExternalWithPlaylist();
- return convert(request, player, serverSidePlaylist, offset);
- }
-
- public PlayQueueInfo play(int id) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
-
- Player player = getCurrentPlayer(request, response);
- MediaFile file = mediaFileService.getMediaFile(id);
- List<MediaFile> files = mediaFileService.getDescendantsOf(file, true);
- return doPlay(request, player, files);
- }
-
- public PlayQueueInfo playPlaylist(int id) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
-
- List<MediaFile> files = playlistService.getFilesInPlaylist(id);
- Player player = getCurrentPlayer(request, response);
- return doPlay(request, player, files);
- }
-
- private PlayQueueInfo doPlay(HttpServletRequest request, Player player, List<MediaFile> files) throws Exception {
- if (player.isWeb()) {
- removeVideoFiles(files);
- }
- player.getPlayQueue().addFiles(false, files);
- player.getPlayQueue().setRandomSearchCriteria(null);
- return convert(request, player, true);
- }
-
- public PlayQueueInfo playRandom(int id, int count) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
-
- MediaFile file = mediaFileService.getMediaFile(id);
- List<MediaFile> randomFiles = getRandomChildren(file, count);
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().addFiles(false, randomFiles);
- player.getPlayQueue().setRandomSearchCriteria(null);
- return convert(request, player, true);
- }
-
- public PlayQueueInfo add(int id) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doAdd(request, response, new int[]{id});
- }
-
- public PlayQueueInfo doAdd(HttpServletRequest request, HttpServletResponse response, int[] ids) throws Exception {
- Player player = getCurrentPlayer(request, response);
- List<MediaFile> files = new ArrayList<MediaFile>(ids.length);
- for (int id : ids) {
- MediaFile ancestor = mediaFileService.getMediaFile(id);
- files.addAll(mediaFileService.getDescendantsOf(ancestor, true));
- }
- if (player.isWeb()) {
- removeVideoFiles(files);
- }
- player.getPlayQueue().addFiles(true, files);
- player.getPlayQueue().setRandomSearchCriteria(null);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo doSet(HttpServletRequest request, HttpServletResponse response, int[] ids) throws Exception {
- Player player = getCurrentPlayer(request, response);
- PlayQueue playQueue = player.getPlayQueue();
- MediaFile currentFile = playQueue.getCurrentFile();
- PlayQueue.Status status = playQueue.getStatus();
-
- playQueue.clear();
- PlayQueueInfo result = doAdd(request, response, ids);
-
- int index = currentFile == null ? -1 : playQueue.getFiles().indexOf(currentFile);
- playQueue.setIndex(index);
- playQueue.setStatus(status);
- return result;
- }
-
- public PlayQueueInfo clear() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doClear(request, response);
- }
-
- public PlayQueueInfo doClear(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().clear();
- boolean serverSidePlaylist = !player.isExternalWithPlaylist();
- return convert(request, player, serverSidePlaylist);
- }
-
- public PlayQueueInfo shuffle() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doShuffle(request, response);
- }
-
- public PlayQueueInfo doShuffle(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().shuffle();
- return convert(request, player, false);
- }
-
- public PlayQueueInfo remove(int index) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- return doRemove(request, response, index);
- }
-
- public PlayQueueInfo toggleStar(int index) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
-
- MediaFile file = player.getPlayQueue().getFile(index);
- String username = securityService.getCurrentUsername(request);
- boolean starred = mediaFileDao.getMediaFileStarredDate(file.getId(), username) != null;
- if (starred) {
- mediaFileDao.unstarMediaFile(file.getId(), username);
- } else {
- mediaFileDao.starMediaFile(file.getId(), username);
- }
- return convert(request, player, false);
- }
-
- public PlayQueueInfo doRemove(HttpServletRequest request, HttpServletResponse response, int index) throws Exception {
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().removeFileAt(index);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo removeMany(int[] indexes) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- for (int i = indexes.length - 1; i >= 0; i--) {
- player.getPlayQueue().removeFileAt(indexes[i]);
- }
- return convert(request, player, false);
- }
-
- public PlayQueueInfo up(int index) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().moveUp(index);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo down(int index) throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().moveDown(index);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo toggleRepeat() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().setRepeatEnabled(!player.getPlayQueue().isRepeatEnabled());
- return convert(request, player, false);
- }
-
- public PlayQueueInfo undo() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().undo();
- boolean serverSidePlaylist = !player.isExternalWithPlaylist();
- return convert(request, player, serverSidePlaylist);
- }
-
- public PlayQueueInfo sortByTrack() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().sort(PlayQueue.SortOrder.TRACK);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo sortByArtist() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().sort(PlayQueue.SortOrder.ARTIST);
- return convert(request, player, false);
- }
-
- public PlayQueueInfo sortByAlbum() throws Exception {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- player.getPlayQueue().sort(PlayQueue.SortOrder.ALBUM);
- return convert(request, player, false);
- }
-
- public void setGain(float gain) {
- jukeboxService.setGain(gain);
- }
-
-
- public String savePlaylist() {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- HttpServletResponse response = WebContextFactory.get().getHttpServletResponse();
- Player player = getCurrentPlayer(request, response);
- Locale locale = settingsService.getLocale();
- DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, locale);
-
- Date now = new Date();
- Playlist playlist = new Playlist();
- playlist.setUsername(securityService.getCurrentUsername(request));
- playlist.setCreated(now);
- playlist.setChanged(now);
- playlist.setPublic(false);
- playlist.setName(dateFormat.format(now));
-
- playlistService.createPlaylist(playlist);
- playlistService.setFilesInPlaylist(playlist.getId(), player.getPlayQueue().getFiles());
- return playlist.getName();
- }
-
- private List<MediaFile> getRandomChildren(MediaFile file, int count) throws IOException {
- List<MediaFile> children = mediaFileService.getDescendantsOf(file, false);
- removeVideoFiles(children);
-
- if (children.isEmpty()) {
- return children;
- }
- Collections.shuffle(children);
- return children.subList(0, Math.min(count, children.size()));
- }
-
- private void removeVideoFiles(List<MediaFile> files) {
- Iterator<MediaFile> iterator = files.iterator();
- while (iterator.hasNext()) {
- MediaFile file = iterator.next();
- if (file.isVideo()) {
- iterator.remove();
- }
- }
- }
-
- private PlayQueueInfo convert(HttpServletRequest request, Player player, boolean sendM3U) throws Exception {
- return convert(request, player, sendM3U, 0);
- }
-
- private PlayQueueInfo convert(HttpServletRequest request, Player player, boolean sendM3U, int offset) throws Exception {
- String url = request.getRequestURL().toString();
-
- if (sendM3U && player.isJukebox()) {
- jukeboxService.updateJukebox(player, offset);
- }
- boolean isCurrentPlayer = player.getIpAddress() != null && player.getIpAddress().equals(request.getRemoteAddr());
-
- boolean m3uSupported = player.isExternal() || player.isExternalWithPlaylist();
- sendM3U = player.isAutoControlEnabled() && m3uSupported && isCurrentPlayer && sendM3U;
- Locale locale = RequestContextUtils.getLocale(request);
-
- List<PlayQueueInfo.Entry> entries = new ArrayList<PlayQueueInfo.Entry>();
- PlayQueue playQueue = player.getPlayQueue();
- for (MediaFile file : playQueue.getFiles()) {
- String albumUrl = url.replaceFirst("/dwr/.*", "/main.view?id=" + file.getId());
- String streamUrl = url.replaceFirst("/dwr/.*", "/stream?player=" + player.getId() + "&id=" + file.getId());
-
- // Rewrite URLs in case we're behind a proxy.
- if (settingsService.isRewriteUrlEnabled()) {
- String referer = request.getHeader("referer");
- albumUrl = StringUtil.rewriteUrl(albumUrl, referer);
- streamUrl = StringUtil.rewriteUrl(streamUrl, referer);
- }
-
- String format = formatFormat(player, file);
- String username = securityService.getCurrentUsername(request);
- boolean starred = mediaFileService.getMediaFileStarredDate(file.getId(), username) != null;
- entries.add(new PlayQueueInfo.Entry(file.getId(), file.getTrackNumber(), file.getTitle(), file.getArtist(),
- file.getAlbumName(), file.getGenre(), file.getYear(), formatBitRate(file),
- file.getDurationSeconds(), file.getDurationString(), format, formatContentType(format),
- formatFileSize(file.getFileSize(), locale), starred, albumUrl, streamUrl));
- }
- boolean isStopEnabled = playQueue.getStatus() == PlayQueue.Status.PLAYING && !player.isExternalWithPlaylist();
- float gain = jukeboxService.getGain();
- return new PlayQueueInfo(entries, playQueue.getIndex(), isStopEnabled, playQueue.isRepeatEnabled(), sendM3U, gain);
- }
-
- private String formatFileSize(Long fileSize, Locale locale) {
- if (fileSize == null) {
- return null;
- }
- return StringUtil.formatBytes(fileSize, locale);
- }
-
- private String formatFormat(Player player, MediaFile file) {
- return transcodingService.getSuffix(player, file, null);
- }
-
- private String formatContentType(String format) {
- return StringUtil.getMimeType(format);
- }
-
- private String formatBitRate(MediaFile mediaFile) {
- if (mediaFile.getBitRate() == null) {
- return null;
- }
- if (mediaFile.isVariableBitRate()) {
- return mediaFile.getBitRate() + " Kbps vbr";
- }
- return mediaFile.getBitRate() + " Kbps";
- }
-
- private Player getCurrentPlayer(HttpServletRequest request, HttpServletResponse response) {
- return playerService.getPlayer(request, response);
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setJukeboxService(JukeboxService jukeboxService) {
- this.jukeboxService = jukeboxService;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistInfo.java
deleted file mode 100644
index 3fcbfb14..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistInfo.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import java.util.List;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Playlist;
-
-/**
- * The playlist of a player.
- *
- * @author Sindre Mehus
- */
-public class PlaylistInfo {
-
- private final Playlist playlist;
- private final List<Entry> entries;
-
- public PlaylistInfo(Playlist playlist, List<Entry> entries) {
- this.playlist = playlist;
- this.entries = entries;
- }
-
- public Playlist getPlaylist() {
- return playlist;
- }
-
- public List<Entry> getEntries() {
- return entries;
- }
-
- public static class Entry {
- private final int id;
- private final String title;
- private final String artist;
- private final String album;
- private final String durationAsString;
- private final boolean starred;
-
- public Entry(int id, String title, String artist, String album, String durationAsString, boolean starred) {
- this.id = id;
- this.title = title;
- this.artist = artist;
- this.album = album;
- this.durationAsString = durationAsString;
- this.starred = starred;
- }
-
- public int getId() {
- return id;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public String getAlbum() {
- return album;
- }
-
- public String getDurationAsString() {
- return durationAsString;
- }
-
- public boolean isStarred() {
- return starred;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistService.java
deleted file mode 100644
index d3bf854f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/PlaylistService.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-
-import javax.servlet.http.HttpServletRequest;
-
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.directwebremoting.WebContextFactory;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.SecurityService;
-
-/**
- * Provides AJAX-enabled services for manipulating playlists.
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class PlaylistService {
-
- private MediaFileService mediaFileService;
- private SecurityService securityService;
- private net.sourceforge.subsonic.service.PlaylistService playlistService;
- private MediaFileDao mediaFileDao;
- private SettingsService settingsService;
-
- public List<Playlist> getReadablePlaylists() {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- String username = securityService.getCurrentUsername(request);
- return playlistService.getReadablePlaylistsForUser(username);
- }
-
- public List<Playlist> getWritablePlaylists() {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- String username = securityService.getCurrentUsername(request);
- return playlistService.getWritablePlaylistsForUser(username);
- }
-
- public PlaylistInfo getPlaylist(int id) {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
-
- Playlist playlist = playlistService.getPlaylist(id);
- List<MediaFile> files = playlistService.getFilesInPlaylist(id);
-
- String username = securityService.getCurrentUsername(request);
- mediaFileService.populateStarredDate(files, username);
- return new PlaylistInfo(playlist, createEntries(files));
- }
-
- public List<Playlist> createEmptyPlaylist() {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- Locale locale = settingsService.getLocale();
- DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, locale);
-
- Date now = new Date();
- Playlist playlist = new Playlist();
- playlist.setUsername(securityService.getCurrentUsername(request));
- playlist.setCreated(now);
- playlist.setChanged(now);
- playlist.setPublic(false);
- playlist.setName(dateFormat.format(now));
-
- playlistService.createPlaylist(playlist);
- return getReadablePlaylists();
- }
-
- public void appendToPlaylist(int playlistId, List<Integer> mediaFileIds) {
- List<MediaFile> files = playlistService.getFilesInPlaylist(playlistId);
- for (Integer mediaFileId : mediaFileIds) {
- MediaFile file = mediaFileService.getMediaFile(mediaFileId);
- if (file != null) {
- files.add(file);
- }
- }
- playlistService.setFilesInPlaylist(playlistId, files);
- }
-
- private List<PlaylistInfo.Entry> createEntries(List<MediaFile> files) {
- List<PlaylistInfo.Entry> result = new ArrayList<PlaylistInfo.Entry>();
- for (MediaFile file : files) {
- result.add(new PlaylistInfo.Entry(file.getId(), file.getTitle(), file.getArtist(), file.getAlbumName(),
- file.getDurationString(), file.getStarredDate() != null));
- }
-
- return result;
- }
-
- public PlaylistInfo toggleStar(int id, int index) {
- HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
- String username = securityService.getCurrentUsername(request);
- List<MediaFile> files = playlistService.getFilesInPlaylist(id);
- MediaFile file = files.get(index);
-
- boolean starred = mediaFileDao.getMediaFileStarredDate(file.getId(), username) != null;
- if (starred) {
- mediaFileDao.unstarMediaFile(file.getId(), username);
- } else {
- mediaFileDao.starMediaFile(file.getId(), username);
- }
- return getPlaylist(id);
- }
-
- public PlaylistInfo remove(int id, int index) {
- List<MediaFile> files = playlistService.getFilesInPlaylist(id);
- files.remove(index);
- playlistService.setFilesInPlaylist(id, files);
- return getPlaylist(id);
- }
-
- public PlaylistInfo up(int id, int index) {
- List<MediaFile> files = playlistService.getFilesInPlaylist(id);
- if (index > 0) {
- MediaFile file = files.remove(index);
- files.add(index - 1, file);
- playlistService.setFilesInPlaylist(id, files);
- }
- return getPlaylist(id);
- }
-
- public PlaylistInfo down(int id, int index) {
- List<MediaFile> files = playlistService.getFilesInPlaylist(id);
- if (index < files.size() - 1) {
- MediaFile file = files.remove(index);
- files.add(index + 1, file);
- playlistService.setFilesInPlaylist(id, files);
- }
- return getPlaylist(id);
- }
-
- public void deletePlaylist(int id) {
- playlistService.deletePlaylist(id);
- }
-
- public PlaylistInfo updatePlaylist(int id, String name, String comment, boolean isPublic) {
- Playlist playlist = playlistService.getPlaylist(id);
- playlist.setName(name);
- playlist.setComment(comment);
- playlist.setPublic(isPublic);
- playlistService.updatePlaylist(playlist);
- return getPlaylist(id);
- }
-
- public void setPlaylistService(net.sourceforge.subsonic.service.PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ScanInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ScanInfo.java
deleted file mode 100644
index d984069e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/ScanInfo.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-/**
- * Media folder scanning status.
- *
- * @author Sindre Mehus
- */
-public class ScanInfo {
-
- private final boolean scanning;
- private final int count;
-
- public ScanInfo(boolean scanning, int count) {
- this.scanning = scanning;
- this.count = count;
- }
-
- public boolean isScanning() {
- return scanning;
- }
-
- public int getCount() {
- return count;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/StarService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/StarService.java
deleted file mode 100644
index 15ba359b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/StarService.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.SecurityService;
-import org.directwebremoting.WebContext;
-import org.directwebremoting.WebContextFactory;
-
-/**
- * Provides AJAX-enabled services for starring.
- * <p/>
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class StarService {
-
- private static final Logger LOG = Logger.getLogger(StarService.class);
-
- private SecurityService securityService;
- private MediaFileDao mediaFileDao;
-
- public void star(int id) {
- mediaFileDao.starMediaFile(id, getUser());
- }
-
- public void unstar(int id) {
- mediaFileDao.unstarMediaFile(id, getUser());
- }
-
- private String getUser() {
- WebContext webContext = WebContextFactory.get();
- User user = securityService.getCurrentUser(webContext.getHttpServletRequest());
- return user.getUsername();
- }
-
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TagService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TagService.java
deleted file mode 100644
index f7373b4e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TagService.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.metadata.MetaData;
-import net.sourceforge.subsonic.service.metadata.MetaDataParser;
-import net.sourceforge.subsonic.service.metadata.MetaDataParserFactory;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.StringUtils;
-
-/**
- * Provides AJAX-enabled services for editing tags in music files.
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class TagService {
-
- private static final Logger LOG = Logger.getLogger(TagService.class);
-
- private MetaDataParserFactory metaDataParserFactory;
- private MediaFileService mediaFileService;
-
- /**
- * Updated tags for a given music file.
- *
- * @param id The ID of the music file.
- * @param track The track number.
- * @param artist The artist name.
- * @param album The album name.
- * @param title The song title.
- * @param year The release year.
- * @param genre The musical genre.
- * @return "UPDATED" if the new tags were updated, "SKIPPED" if no update was necessary.
- * Otherwise the error message is returned.
- */
- public String setTags(int id, String track, String artist, String album, String title, String year, String genre) {
-
- track = StringUtils.trimToNull(track);
- artist = StringUtils.trimToNull(artist);
- album = StringUtils.trimToNull(album);
- title = StringUtils.trimToNull(title);
- year = StringUtils.trimToNull(year);
- genre = StringUtils.trimToNull(genre);
-
- Integer trackNumber = null;
- if (track != null) {
- try {
- trackNumber = new Integer(track);
- } catch (NumberFormatException x) {
- LOG.warn("Illegal track number: " + track, x);
- }
- }
-
- Integer yearNumber = null;
- if (year != null) {
- try {
- yearNumber = new Integer(year);
- } catch (NumberFormatException x) {
- LOG.warn("Illegal year: " + year, x);
- }
- }
-
- try {
-
- MediaFile file = mediaFileService.getMediaFile(id);
- MetaDataParser parser = metaDataParserFactory.getParser(file.getFile());
-
- if (!parser.isEditingSupported()) {
- return "Tag editing of " + FilenameUtils.getExtension(file.getPath()) + " files is not supported.";
- }
-
- MetaData existingMetaData = parser.getRawMetaData(file.getFile());
-
- if (StringUtils.equals(artist, existingMetaData.getArtist()) &&
- StringUtils.equals(album, existingMetaData.getAlbumName()) &&
- StringUtils.equals(title, existingMetaData.getTitle()) &&
- ObjectUtils.equals(yearNumber, existingMetaData.getYear()) &&
- StringUtils.equals(genre, existingMetaData.getGenre()) &&
- ObjectUtils.equals(trackNumber, existingMetaData.getTrackNumber())) {
- return "SKIPPED";
- }
-
- MetaData newMetaData = new MetaData();
- newMetaData.setArtist(artist);
- newMetaData.setAlbumName(album);
- newMetaData.setTitle(title);
- newMetaData.setYear(yearNumber);
- newMetaData.setGenre(genre);
- newMetaData.setTrackNumber(trackNumber);
- parser.setMetaData(file, newMetaData);
- mediaFileService.refreshMediaFile(file);
- return "UPDATED";
-
- } catch (Exception x) {
- LOG.warn("Failed to update tags for " + id, x);
- return x.getMessage();
- }
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setMetaDataParserFactory(MetaDataParserFactory metaDataParserFactory) {
- this.metaDataParserFactory = metaDataParserFactory;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TransferService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TransferService.java
deleted file mode 100644
index 19309348..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/TransferService.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.controller.*;
-import org.directwebremoting.*;
-
-import javax.servlet.http.*;
-
-/**
- * Provides AJAX-enabled services for retrieving the status of ongoing transfers.
- * This class is used by the DWR framework (http://getahead.ltd.uk/dwr/).
- *
- * @author Sindre Mehus
- */
-public class TransferService {
-
- /**
- * Returns info about any ongoing upload within the current session.
- * @return Info about ongoing upload.
- */
- public UploadInfo getUploadInfo() {
-
- HttpSession session = WebContextFactory.get().getSession();
- TransferStatus status = (TransferStatus) session.getAttribute(UploadController.UPLOAD_STATUS);
-
- if (status != null) {
- return new UploadInfo(status.getBytesTransfered(), status.getBytesTotal());
- }
- return new UploadInfo(0L, 0L);
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/UploadInfo.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/UploadInfo.java
deleted file mode 100644
index 47f9de99..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ajax/UploadInfo.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ajax;
-
-/**
- * Contains status for a file upload.
- *
- * @author Sindre Mehus
- */
-public class UploadInfo {
-
- private long bytesUploaded;
- private long bytesTotal;
-
- public UploadInfo(long bytesUploaded, long bytesTotal) {
- this.bytesUploaded = bytesUploaded;
- this.bytesTotal = bytesTotal;
- }
-
- /**
- * Returns the number of bytes uploaded.
- * @return The number of bytes uploaded.
- */
- public long getBytesUploaded() {
- return bytesUploaded;
- }
-
- /**
- * Returns the total number of bytes.
- * @return The total number of bytes.
- */
- public long getBytesTotal() {
- return bytesTotal;
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/cache/CacheFactory.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/cache/CacheFactory.java
deleted file mode 100644
index 00f656b1..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/cache/CacheFactory.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.cache;
-
-
-import java.io.File;
-
-import org.springframework.beans.factory.InitializingBean;
-
-import net.sf.ehcache.Cache;
-import net.sf.ehcache.CacheManager;
-import net.sf.ehcache.Ehcache;
-import net.sf.ehcache.config.Configuration;
-import net.sf.ehcache.config.ConfigurationFactory;
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.service.SettingsService;
-
-/**
- * Initializes Ehcache and creates caches.
- *
- * @author Sindre Mehus
- * @version $Id$
- */
-public class CacheFactory implements InitializingBean {
-
- private static final Logger LOG = Logger.getLogger(CacheFactory.class);
- private CacheManager cacheManager;
-
- public void afterPropertiesSet() throws Exception {
- Configuration configuration = ConfigurationFactory.parseConfiguration();
-
- // Override configuration to make sure cache is stored in Subsonic home dir.
- File cacheDir = new File(SettingsService.getSubsonicHome(), "cache");
- configuration.getDiskStoreConfiguration().setPath(cacheDir.getPath());
-
- cacheManager = CacheManager.create(configuration);
- }
-
- public Ehcache getCache(String name) {
- return cacheManager.getCache(name);
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/AdvancedSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/AdvancedSettingsCommand.java
deleted file mode 100644
index 6c87df51..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/AdvancedSettingsCommand.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.controller.AdvancedSettingsController;
-
-/**
- * Command used in {@link AdvancedSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class AdvancedSettingsCommand {
- private String downsampleCommand;
- private String coverArtLimit;
- private String downloadLimit;
- private String uploadLimit;
- private String streamPort;
- private boolean ldapEnabled;
- private String ldapUrl;
- private String ldapSearchFilter;
- private String ldapManagerDn;
- private String ldapManagerPassword;
- private boolean ldapAutoShadowing;
- private String brand;
- private boolean isReloadNeeded;
-
- public String getDownsampleCommand() {
- return downsampleCommand;
- }
-
- public void setDownsampleCommand(String downsampleCommand) {
- this.downsampleCommand = downsampleCommand;
- }
-
- public String getCoverArtLimit() {
- return coverArtLimit;
- }
-
- public void setCoverArtLimit(String coverArtLimit) {
- this.coverArtLimit = coverArtLimit;
- }
-
- public String getDownloadLimit() {
- return downloadLimit;
- }
-
- public void setDownloadLimit(String downloadLimit) {
- this.downloadLimit = downloadLimit;
- }
-
- public String getUploadLimit() {
- return uploadLimit;
- }
-
- public String getStreamPort() {
- return streamPort;
- }
-
- public void setStreamPort(String streamPort) {
- this.streamPort = streamPort;
- }
-
- public void setUploadLimit(String uploadLimit) {
- this.uploadLimit = uploadLimit;
- }
-
- public boolean isLdapEnabled() {
- return ldapEnabled;
- }
-
- public void setLdapEnabled(boolean ldapEnabled) {
- this.ldapEnabled = ldapEnabled;
- }
-
- public String getLdapUrl() {
- return ldapUrl;
- }
-
- public void setLdapUrl(String ldapUrl) {
- this.ldapUrl = ldapUrl;
- }
-
- public String getLdapSearchFilter() {
- return ldapSearchFilter;
- }
-
- public void setLdapSearchFilter(String ldapSearchFilter) {
- this.ldapSearchFilter = ldapSearchFilter;
- }
-
- public String getLdapManagerDn() {
- return ldapManagerDn;
- }
-
- public void setLdapManagerDn(String ldapManagerDn) {
- this.ldapManagerDn = ldapManagerDn;
- }
-
- public String getLdapManagerPassword() {
- return ldapManagerPassword;
- }
-
- public void setLdapManagerPassword(String ldapManagerPassword) {
- this.ldapManagerPassword = ldapManagerPassword;
- }
-
- public boolean isLdapAutoShadowing() {
- return ldapAutoShadowing;
- }
-
- public void setLdapAutoShadowing(boolean ldapAutoShadowing) {
- this.ldapAutoShadowing = ldapAutoShadowing;
- }
-
- public void setBrand(String brand) {
- this.brand = brand;
- }
-
- public String getBrand() {
- return brand;
- }
-
- public void setReloadNeeded(boolean reloadNeeded) {
- isReloadNeeded = reloadNeeded;
- }
-
- public boolean isReloadNeeded() {
- return isReloadNeeded;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/DonateCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/DonateCommand.java
deleted file mode 100644
index 04af0ff6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/DonateCommand.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.controller.DonateController;
-
-import java.util.Date;
-
-import org.apache.commons.lang.StringUtils;
-
-/**
- * Command used in {@link DonateController}.
- *
- * @author Sindre Mehus
- */
-public class DonateCommand {
-
- private String path;
- private String emailAddress;
- private String license;
- private Date licenseDate;
- private boolean licenseValid;
- private String brand;
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getEmailAddress() {
- return emailAddress;
- }
-
- public void setEmailAddress(String emailAddress) {
- this.emailAddress = StringUtils.trim(emailAddress);
- }
-
- public String getLicense() {
- return license;
- }
-
- public void setLicense(String license) {
- this.license = StringUtils.trim(license);
- }
-
- public Date getLicenseDate() {
- return licenseDate;
- }
-
- public void setLicenseDate(Date licenseDate) {
- this.licenseDate = licenseDate;
- }
-
- public boolean isLicenseValid() {
- return licenseValid;
- }
-
- public void setLicenseValid(boolean licenseValid) {
- this.licenseValid = licenseValid;
- }
-
- public String getBrand() {
- return brand;
- }
-
- public void setBrand(String brand) {
- this.brand = brand;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/EnumHolder.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/EnumHolder.java
deleted file mode 100644
index bb1fc5ff..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/EnumHolder.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-/**
- * Holds the name and description of an enum value.
- *
- * @author Sindre Mehus
- */
-public class EnumHolder {
- private String name;
- private String description;
-
- public EnumHolder(String name, String description) {
- this.name = name;
- this.description = description;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDescription() {
- return description;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/GeneralSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/GeneralSettingsCommand.java
deleted file mode 100644
index 2322a3bd..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/GeneralSettingsCommand.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.controller.GeneralSettingsController;
-import net.sourceforge.subsonic.domain.Theme;
-
-/**
- * Command used in {@link GeneralSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class GeneralSettingsCommand {
-
- private String musicFileTypes;
- private String videoFileTypes;
- private String coverArtFileTypes;
- private String index;
- private String ignoredArticles;
- private String shortcuts;
- private boolean sortAlbumsByYear;
- private boolean gettingStartedEnabled;
- private String welcomeTitle;
- private String welcomeSubtitle;
- private String welcomeMessage;
- private String loginMessage;
- private String localeIndex;
- private String[] locales;
- private String themeIndex;
- private Theme[] themes;
- private boolean isReloadNeeded;
-
- public String getMusicFileTypes() {
- return musicFileTypes;
- }
-
- public void setMusicFileTypes(String musicFileTypes) {
- this.musicFileTypes = musicFileTypes;
- }
-
- public String getVideoFileTypes() {
- return videoFileTypes;
- }
-
- public void setVideoFileTypes(String videoFileTypes) {
- this.videoFileTypes = videoFileTypes;
- }
-
- public String getCoverArtFileTypes() {
- return coverArtFileTypes;
- }
-
- public void setCoverArtFileTypes(String coverArtFileTypes) {
- this.coverArtFileTypes = coverArtFileTypes;
- }
-
- public String getIndex() {
- return index;
- }
-
- public void setIndex(String index) {
- this.index = index;
- }
-
- public String getIgnoredArticles() {
- return ignoredArticles;
- }
-
- public void setIgnoredArticles(String ignoredArticles) {
- this.ignoredArticles = ignoredArticles;
- }
-
- public String getShortcuts() {
- return shortcuts;
- }
-
- public void setShortcuts(String shortcuts) {
- this.shortcuts = shortcuts;
- }
-
- public String getWelcomeTitle() {
- return welcomeTitle;
- }
-
- public void setWelcomeTitle(String welcomeTitle) {
- this.welcomeTitle = welcomeTitle;
- }
-
- public String getWelcomeSubtitle() {
- return welcomeSubtitle;
- }
-
- public void setWelcomeSubtitle(String welcomeSubtitle) {
- this.welcomeSubtitle = welcomeSubtitle;
- }
-
- public String getWelcomeMessage() {
- return welcomeMessage;
- }
-
- public void setWelcomeMessage(String welcomeMessage) {
- this.welcomeMessage = welcomeMessage;
- }
-
- public String getLoginMessage() {
- return loginMessage;
- }
-
- public void setLoginMessage(String loginMessage) {
- this.loginMessage = loginMessage;
- }
-
- public String getLocaleIndex() {
- return localeIndex;
- }
-
- public void setLocaleIndex(String localeIndex) {
- this.localeIndex = localeIndex;
- }
-
- public String[] getLocales() {
- return locales;
- }
-
- public void setLocales(String[] locales) {
- this.locales = locales;
- }
-
- public String getThemeIndex() {
- return themeIndex;
- }
-
- public void setThemeIndex(String themeIndex) {
- this.themeIndex = themeIndex;
- }
-
- public Theme[] getThemes() {
- return themes;
- }
-
- public void setThemes(Theme[] themes) {
- this.themes = themes;
- }
-
- public boolean isReloadNeeded() {
- return isReloadNeeded;
- }
-
- public void setReloadNeeded(boolean reloadNeeded) {
- isReloadNeeded = reloadNeeded;
- }
-
- public boolean isSortAlbumsByYear() {
- return sortAlbumsByYear;
- }
-
- public void setSortAlbumsByYear(boolean sortAlbumsByYear) {
- this.sortAlbumsByYear = sortAlbumsByYear;
- }
-
- public boolean isGettingStartedEnabled() {
- return gettingStartedEnabled;
- }
-
- public void setGettingStartedEnabled(boolean gettingStartedEnabled) {
- this.gettingStartedEnabled = gettingStartedEnabled;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/MusicFolderSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/MusicFolderSettingsCommand.java
deleted file mode 100644
index 8fcfa72c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/MusicFolderSettingsCommand.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import java.io.File;
-import java.util.Date;
-import java.util.List;
-
-import net.sourceforge.subsonic.controller.MusicFolderSettingsController;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import org.apache.commons.lang.StringUtils;
-
-/**
- * Command used in {@link MusicFolderSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class MusicFolderSettingsCommand {
-
- private String interval;
- private String hour;
- private boolean scanning;
- private boolean fastCache;
- private boolean organizeByFolderStructure;
- private List<MusicFolderInfo> musicFolders;
- private MusicFolderInfo newMusicFolder;
- private boolean reload;
-
- public String getInterval() {
- return interval;
- }
-
- public void setInterval(String interval) {
- this.interval = interval;
- }
-
- public String getHour() {
- return hour;
- }
-
- public void setHour(String hour) {
- this.hour = hour;
- }
-
- public boolean isScanning() {
- return scanning;
- }
-
- public void setScanning(boolean scanning) {
- this.scanning = scanning;
- }
-
- public boolean isFastCache() {
- return fastCache;
- }
-
- public List<MusicFolderInfo> getMusicFolders() {
- return musicFolders;
- }
-
- public void setMusicFolders(List<MusicFolderInfo> musicFolders) {
- this.musicFolders = musicFolders;
- }
-
- public void setFastCache(boolean fastCache) {
- this.fastCache = fastCache;
- }
-
- public MusicFolderInfo getNewMusicFolder() {
- return newMusicFolder;
- }
-
- public void setNewMusicFolder(MusicFolderInfo newMusicFolder) {
- this.newMusicFolder = newMusicFolder;
- }
-
- public void setReload(boolean reload) {
- this.reload = reload;
- }
-
- public boolean isReload() {
- return reload;
- }
-
- public boolean isOrganizeByFolderStructure() {
- return organizeByFolderStructure;
- }
-
- public void setOrganizeByFolderStructure(boolean organizeByFolderStructure) {
- this.organizeByFolderStructure = organizeByFolderStructure;
- }
-
- public static class MusicFolderInfo {
-
- private Integer id;
- private String path;
- private String name;
- private boolean enabled;
- private boolean delete;
- private boolean existing;
-
- public MusicFolderInfo(MusicFolder musicFolder) {
- id = musicFolder.getId();
- path = musicFolder.getPath().getPath();
- name = musicFolder.getName();
- enabled = musicFolder.isEnabled();
- existing = musicFolder.getPath().exists() && musicFolder.getPath().isDirectory();
- }
-
- public MusicFolderInfo() {
- enabled = true;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public boolean isDelete() {
- return delete;
- }
-
- public void setDelete(boolean delete) {
- this.delete = delete;
- }
-
- public MusicFolder toMusicFolder() {
- String path = StringUtils.trimToNull(this.path);
- if (path == null) {
- return null;
- }
- File file = new File(path);
- String name = StringUtils.trimToNull(this.name);
- if (name == null) {
- name = file.getName();
- }
- return new MusicFolder(id, new File(path), name, enabled, new Date());
- }
-
- public boolean isExisting() {
- return existing;
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/NetworkSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/NetworkSettingsCommand.java
deleted file mode 100644
index d0ae2b07..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/NetworkSettingsCommand.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import java.util.Date;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class NetworkSettingsCommand {
-
- private boolean portForwardingEnabled;
- private boolean urlRedirectionEnabled;
- private String urlRedirectFrom;
- private int port;
- private boolean trial;
- private Date trialExpires;
- private boolean trialExpired;
-
- public void setPortForwardingEnabled(boolean portForwardingEnabled) {
- this.portForwardingEnabled = portForwardingEnabled;
- }
-
- public boolean isPortForwardingEnabled() {
- return portForwardingEnabled;
- }
-
- public boolean isUrlRedirectionEnabled() {
- return urlRedirectionEnabled;
- }
-
- public void setUrlRedirectionEnabled(boolean urlRedirectionEnabled) {
- this.urlRedirectionEnabled = urlRedirectionEnabled;
- }
-
- public String getUrlRedirectFrom() {
- return urlRedirectFrom;
- }
-
- public void setUrlRedirectFrom(String urlRedirectFrom) {
- this.urlRedirectFrom = urlRedirectFrom;
- }
-
- public int getPort() {
- return port;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public void setTrial(boolean trial) {
- this.trial = trial;
- }
-
- public boolean isTrial() {
- return trial;
- }
-
- public void setTrialExpires(Date trialExpires) {
- this.trialExpires = trialExpires;
- }
-
- public Date getTrialExpires() {
- return trialExpires;
- }
-
- public void setTrialExpired(boolean trialExpired) {
- this.trialExpired = trialExpired;
- }
-
- public boolean isTrialExpired() {
- return trialExpired;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PasswordSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PasswordSettingsCommand.java
deleted file mode 100644
index b9e5383c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PasswordSettingsCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.controller.*;
-
-/**
- * Command used in {@link PasswordSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class PasswordSettingsCommand {
- private String username;
- private String password;
- private String confirmPassword;
- private boolean ldapAuthenticated;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getConfirmPassword() {
- return confirmPassword;
- }
-
- public void setConfirmPassword(String confirmPassword) {
- this.confirmPassword = confirmPassword;
- }
-
- public boolean isLdapAuthenticated() {
- return ldapAuthenticated;
- }
-
- public void setLdapAuthenticated(boolean ldapAuthenticated) {
- this.ldapAuthenticated = ldapAuthenticated;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PersonalSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PersonalSettingsCommand.java
deleted file mode 100644
index 680d06e9..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PersonalSettingsCommand.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.controller.PersonalSettingsController;
-import net.sourceforge.subsonic.domain.Avatar;
-import net.sourceforge.subsonic.domain.Theme;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-
-import java.util.List;
-
-/**
- * Command used in {@link PersonalSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class PersonalSettingsCommand {
- private User user;
- private String localeIndex;
- private String[] locales;
- private String themeIndex;
- private Theme[] themes;
- private int avatarId;
- private List<Avatar> avatars;
- private Avatar customAvatar;
- private UserSettings.Visibility mainVisibility;
- private UserSettings.Visibility playlistVisibility;
- private boolean partyModeEnabled;
- private boolean showNowPlayingEnabled;
- private boolean showChatEnabled;
- private boolean nowPlayingAllowed;
- private boolean finalVersionNotificationEnabled;
- private boolean betaVersionNotificationEnabled;
- private boolean lastFmEnabled;
- private String lastFmUsername;
- private String lastFmPassword;
- private boolean isReloadNeeded;
-
- public User getUser() {
- return user;
- }
-
- public void setUser(User user) {
- this.user = user;
- }
-
- public String getLocaleIndex() {
- return localeIndex;
- }
-
- public void setLocaleIndex(String localeIndex) {
- this.localeIndex = localeIndex;
- }
-
- public String[] getLocales() {
- return locales;
- }
-
- public void setLocales(String[] locales) {
- this.locales = locales;
- }
-
- public String getThemeIndex() {
- return themeIndex;
- }
-
- public void setThemeIndex(String themeIndex) {
- this.themeIndex = themeIndex;
- }
-
- public Theme[] getThemes() {
- return themes;
- }
-
- public void setThemes(Theme[] themes) {
- this.themes = themes;
- }
-
- public int getAvatarId() {
- return avatarId;
- }
-
- public void setAvatarId(int avatarId) {
- this.avatarId = avatarId;
- }
-
- public List<Avatar> getAvatars() {
- return avatars;
- }
-
- public void setAvatars(List<Avatar> avatars) {
- this.avatars = avatars;
- }
-
- public Avatar getCustomAvatar() {
- return customAvatar;
- }
-
- public void setCustomAvatar(Avatar customAvatar) {
- this.customAvatar = customAvatar;
- }
-
- public UserSettings.Visibility getMainVisibility() {
- return mainVisibility;
- }
-
- public void setMainVisibility(UserSettings.Visibility mainVisibility) {
- this.mainVisibility = mainVisibility;
- }
-
- public UserSettings.Visibility getPlaylistVisibility() {
- return playlistVisibility;
- }
-
- public void setPlaylistVisibility(UserSettings.Visibility playlistVisibility) {
- this.playlistVisibility = playlistVisibility;
- }
-
- public boolean isPartyModeEnabled() {
- return partyModeEnabled;
- }
-
- public void setPartyModeEnabled(boolean partyModeEnabled) {
- this.partyModeEnabled = partyModeEnabled;
- }
-
- public boolean isShowNowPlayingEnabled() {
- return showNowPlayingEnabled;
- }
-
- public void setShowNowPlayingEnabled(boolean showNowPlayingEnabled) {
- this.showNowPlayingEnabled = showNowPlayingEnabled;
- }
-
- public boolean isShowChatEnabled() {
- return showChatEnabled;
- }
-
- public void setShowChatEnabled(boolean showChatEnabled) {
- this.showChatEnabled = showChatEnabled;
- }
-
- public boolean isNowPlayingAllowed() {
- return nowPlayingAllowed;
- }
-
- public void setNowPlayingAllowed(boolean nowPlayingAllowed) {
- this.nowPlayingAllowed = nowPlayingAllowed;
- }
-
- public boolean isFinalVersionNotificationEnabled() {
- return finalVersionNotificationEnabled;
- }
-
- public void setFinalVersionNotificationEnabled(boolean finalVersionNotificationEnabled) {
- this.finalVersionNotificationEnabled = finalVersionNotificationEnabled;
- }
-
- public boolean isBetaVersionNotificationEnabled() {
- return betaVersionNotificationEnabled;
- }
-
- public void setBetaVersionNotificationEnabled(boolean betaVersionNotificationEnabled) {
- this.betaVersionNotificationEnabled = betaVersionNotificationEnabled;
- }
-
- public boolean isLastFmEnabled() {
- return lastFmEnabled;
- }
-
- public void setLastFmEnabled(boolean lastFmEnabled) {
- this.lastFmEnabled = lastFmEnabled;
- }
-
- public String getLastFmUsername() {
- return lastFmUsername;
- }
-
- public void setLastFmUsername(String lastFmUsername) {
- this.lastFmUsername = lastFmUsername;
- }
-
- public String getLastFmPassword() {
- return lastFmPassword;
- }
-
- public void setLastFmPassword(String lastFmPassword) {
- this.lastFmPassword = lastFmPassword;
- }
-
- public boolean isReloadNeeded() {
- return isReloadNeeded;
- }
-
- public void setReloadNeeded(boolean reloadNeeded) {
- isReloadNeeded = reloadNeeded;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PlayerSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PlayerSettingsCommand.java
deleted file mode 100644
index 8331260d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PlayerSettingsCommand.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import java.util.Date;
-import java.util.List;
-
-import net.sourceforge.subsonic.controller.PlayerSettingsController;
-import net.sourceforge.subsonic.domain.CoverArtScheme;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayerTechnology;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-import net.sourceforge.subsonic.domain.Transcoding;
-
-/**
- * Command used in {@link PlayerSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class PlayerSettingsCommand {
- private String playerId;
- private String name;
- private String description;
- private String type;
- private Date lastSeen;
- private boolean isDynamicIp;
- private boolean isAutoControlEnabled;
- private String coverArtSchemeName;
- private String technologyName;
- private String transcodeSchemeName;
- private boolean transcodingSupported;
- private String transcodeDirectory;
- private List<Transcoding> allTranscodings;
- private int[] activeTranscodingIds;
- private EnumHolder[] technologyHolders;
- private EnumHolder[] transcodeSchemeHolders;
- private EnumHolder[] coverArtSchemeHolders;
- private Player[] players;
- private boolean isAdmin;
- private boolean isReloadNeeded;
-
- public String getPlayerId() {
- return playerId;
- }
-
- public void setPlayerId(String playerId) {
- this.playerId = playerId;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public Date getLastSeen() {
- return lastSeen;
- }
-
- public void setLastSeen(Date lastSeen) {
- this.lastSeen = lastSeen;
- }
-
- public boolean isDynamicIp() {
- return isDynamicIp;
- }
-
- public void setDynamicIp(boolean dynamicIp) {
- isDynamicIp = dynamicIp;
- }
-
- public boolean isAutoControlEnabled() {
- return isAutoControlEnabled;
- }
-
- public void setAutoControlEnabled(boolean autoControlEnabled) {
- isAutoControlEnabled = autoControlEnabled;
- }
-
- public String getCoverArtSchemeName() {
- return coverArtSchemeName;
- }
-
- public void setCoverArtSchemeName(String coverArtSchemeName) {
- this.coverArtSchemeName = coverArtSchemeName;
- }
-
- public String getTranscodeSchemeName() {
- return transcodeSchemeName;
- }
-
- public void setTranscodeSchemeName(String transcodeSchemeName) {
- this.transcodeSchemeName = transcodeSchemeName;
- }
-
- public boolean isTranscodingSupported() {
- return transcodingSupported;
- }
-
- public void setTranscodingSupported(boolean transcodingSupported) {
- this.transcodingSupported = transcodingSupported;
- }
-
- public String getTranscodeDirectory() {
- return transcodeDirectory;
- }
-
- public void setTranscodeDirectory(String transcodeDirectory) {
- this.transcodeDirectory = transcodeDirectory;
- }
-
- public List<Transcoding> getAllTranscodings() {
- return allTranscodings;
- }
-
- public void setAllTranscodings(List<Transcoding> allTranscodings) {
- this.allTranscodings = allTranscodings;
- }
-
- public int[] getActiveTranscodingIds() {
- return activeTranscodingIds;
- }
-
- public void setActiveTranscodingIds(int[] activeTranscodingIds) {
- this.activeTranscodingIds = activeTranscodingIds;
- }
-
- public EnumHolder[] getTechnologyHolders() {
- return technologyHolders;
- }
-
- public void setTechnologies(PlayerTechnology[] technologies) {
- technologyHolders = new EnumHolder[technologies.length];
- for (int i = 0; i < technologies.length; i++) {
- PlayerTechnology technology = technologies[i];
- technologyHolders[i] = new EnumHolder(technology.name(), technology.toString());
- }
- }
-
- public EnumHolder[] getTranscodeSchemeHolders() {
- return transcodeSchemeHolders;
- }
-
- public void setTranscodeSchemes(TranscodeScheme[] transcodeSchemes) {
- transcodeSchemeHolders = new EnumHolder[transcodeSchemes.length];
- for (int i = 0; i < transcodeSchemes.length; i++) {
- TranscodeScheme scheme = transcodeSchemes[i];
- transcodeSchemeHolders[i] = new EnumHolder(scheme.name(), scheme.toString());
- }
- }
-
- public EnumHolder[] getCoverArtSchemeHolders() {
- return coverArtSchemeHolders;
- }
-
- public void setCoverArtSchemes(CoverArtScheme[] coverArtSchemes) {
- coverArtSchemeHolders = new EnumHolder[coverArtSchemes.length];
- for (int i = 0; i < coverArtSchemes.length; i++) {
- CoverArtScheme scheme = coverArtSchemes[i];
- coverArtSchemeHolders[i] = new EnumHolder(scheme.name(), scheme.toString());
- }
- }
-
- public String getTechnologyName() {
- return technologyName;
- }
-
- public void setTechnologyName(String technologyName) {
- this.technologyName = technologyName;
- }
-
- public Player[] getPlayers() {
- return players;
- }
-
- public void setPlayers(Player[] players) {
- this.players = players;
- }
-
- public boolean isAdmin() {
- return isAdmin;
- }
-
- public void setAdmin(boolean admin) {
- isAdmin = admin;
- }
-
- public boolean isReloadNeeded() {
- return isReloadNeeded;
- }
-
- public void setReloadNeeded(boolean reloadNeeded) {
- isReloadNeeded = reloadNeeded;
- }
-
- /**
- * Holds the transcoding and whether it is active for the given player.
- */
- public static class TranscodingHolder {
- private Transcoding transcoding;
- private boolean isActive;
-
- public TranscodingHolder(Transcoding transcoding, boolean isActive) {
- this.transcoding = transcoding;
- this.isActive = isActive;
- }
-
- public Transcoding getTranscoding() {
- return transcoding;
- }
-
- public boolean isActive() {
- return isActive;
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PodcastSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PodcastSettingsCommand.java
deleted file mode 100644
index e6917ff4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/PodcastSettingsCommand.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.controller.PodcastSettingsController;
-
-/**
- * Command used in {@link PodcastSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class PodcastSettingsCommand {
-
- private String interval;
- private String folder;
- private String episodeRetentionCount;
- private String episodeDownloadCount;
-
- public String getInterval() {
- return interval;
- }
-
- public void setInterval(String interval) {
- this.interval = interval;
- }
-
- public String getFolder() {
- return folder;
- }
-
- public void setFolder(String folder) {
- this.folder = folder;
- }
-
- public String getEpisodeRetentionCount() {
- return episodeRetentionCount;
- }
-
- public void setEpisodeRetentionCount(String episodeRetentionCount) {
- this.episodeRetentionCount = episodeRetentionCount;
- }
-
- public String getEpisodeDownloadCount() {
- return episodeDownloadCount;
- }
-
- public void setEpisodeDownloadCount(String episodeDownloadCount) {
- this.episodeDownloadCount = episodeDownloadCount;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/SearchCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/SearchCommand.java
deleted file mode 100644
index 0dacfbd4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/SearchCommand.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.controller.*;
-
-import java.util.*;
-
-/**
- * Command used in {@link SearchController}.
- *
- * @author Sindre Mehus
- */
-public class SearchCommand {
-
- private String query;
- private List<MediaFile> artists;
- private List<MediaFile> albums;
- private List<MediaFile> songs;
- private boolean isIndexBeingCreated;
- private User user;
- private boolean partyModeEnabled;
- private Player player;
-
- public String getQuery() {
- return query;
- }
-
- public void setQuery(String query) {
- this.query = query;
- }
-
- public boolean isIndexBeingCreated() {
- return isIndexBeingCreated;
- }
-
- public void setIndexBeingCreated(boolean indexBeingCreated) {
- isIndexBeingCreated = indexBeingCreated;
- }
-
- public List<MediaFile> getArtists() {
- return artists;
- }
-
- public void setArtists(List<MediaFile> artists) {
- this.artists = artists;
- }
-
- public List<MediaFile> getAlbums() {
- return albums;
- }
-
- public void setAlbums(List<MediaFile> albums) {
- this.albums = albums;
- }
-
- public List<MediaFile> getSongs() {
- return songs;
- }
-
- public void setSongs(List<MediaFile> songs) {
- this.songs = songs;
- }
-
- public User getUser() {
- return user;
- }
-
- public void setUser(User user) {
- this.user = user;
- }
-
- public boolean isPartyModeEnabled() {
- return partyModeEnabled;
- }
-
- public void setPartyModeEnabled(boolean partyModeEnabled) {
- this.partyModeEnabled = partyModeEnabled;
- }
-
- public Player getPlayer() {
- return player;
- }
-
- public void setPlayer(Player player) {
- this.player = player;
- }
-
- public static class Match {
- private MediaFile mediaFile;
- private String title;
- private String album;
- private String artist;
-
- public Match(MediaFile mediaFile, String title, String album, String artist) {
- this.mediaFile = mediaFile;
- this.title = title;
- this.album = album;
- this.artist = artist;
- }
-
- public MediaFile getMediaFile() {
- return mediaFile;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getAlbum() {
- return album;
- }
-
- public String getArtist() {
- return artist;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/UserSettingsCommand.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/command/UserSettingsCommand.java
deleted file mode 100644
index ce185f7b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/command/UserSettingsCommand.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.command;
-
-import java.util.List;
-
-import net.sourceforge.subsonic.controller.*;
-import net.sourceforge.subsonic.domain.*;
-
-/**
- * Command used in {@link UserSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class UserSettingsCommand {
- private String username;
- private boolean isAdminRole;
- private boolean isDownloadRole;
- private boolean isUploadRole;
- private boolean isCoverArtRole;
- private boolean isCommentRole;
- private boolean isPodcastRole;
- private boolean isStreamRole;
- private boolean isJukeboxRole;
- private boolean isSettingsRole;
- private boolean isShareRole;
-
- private List<User> users;
- private boolean isAdmin;
- private boolean isPasswordChange;
- private boolean isNew;
- private boolean isDelete;
- private String password;
- private String confirmPassword;
- private String email;
- private boolean isLdapAuthenticated;
- private boolean isLdapEnabled;
-
- private String transcodeSchemeName;
- private EnumHolder[] transcodeSchemeHolders;
- private boolean transcodingSupported;
- private String transcodeDirectory;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public boolean isAdminRole() {
- return isAdminRole;
- }
-
- public void setAdminRole(boolean adminRole) {
- isAdminRole = adminRole;
- }
-
- public boolean isDownloadRole() {
- return isDownloadRole;
- }
-
- public void setDownloadRole(boolean downloadRole) {
- isDownloadRole = downloadRole;
- }
-
- public boolean isUploadRole() {
- return isUploadRole;
- }
-
- public void setUploadRole(boolean uploadRole) {
- isUploadRole = uploadRole;
- }
-
- public boolean isCoverArtRole() {
- return isCoverArtRole;
- }
-
- public void setCoverArtRole(boolean coverArtRole) {
- isCoverArtRole = coverArtRole;
- }
-
- public boolean isCommentRole() {
- return isCommentRole;
- }
-
- public void setCommentRole(boolean commentRole) {
- isCommentRole = commentRole;
- }
-
- public boolean isPodcastRole() {
- return isPodcastRole;
- }
-
- public void setPodcastRole(boolean podcastRole) {
- isPodcastRole = podcastRole;
- }
-
- public boolean isStreamRole() {
- return isStreamRole;
- }
-
- public void setStreamRole(boolean streamRole) {
- isStreamRole = streamRole;
- }
-
- public boolean isJukeboxRole() {
- return isJukeboxRole;
- }
-
- public void setJukeboxRole(boolean jukeboxRole) {
- isJukeboxRole = jukeboxRole;
- }
-
- public boolean isSettingsRole() {
- return isSettingsRole;
- }
-
- public void setSettingsRole(boolean settingsRole) {
- isSettingsRole = settingsRole;
- }
-
- public boolean isShareRole() {
- return isShareRole;
- }
-
- public void setShareRole(boolean shareRole) {
- isShareRole = shareRole;
- }
-
- public List<User> getUsers() {
- return users;
- }
-
- public void setUsers(List<User> users) {
- this.users = users;
- }
-
- public boolean isAdmin() {
- return isAdmin;
- }
-
- public void setAdmin(boolean admin) {
- isAdmin = admin;
- }
-
- public boolean isPasswordChange() {
- return isPasswordChange;
- }
-
- public void setPasswordChange(boolean passwordChange) {
- isPasswordChange = passwordChange;
- }
-
- public boolean isNew() {
- return isNew;
- }
-
- public void setNew(boolean isNew) {
- this.isNew = isNew;
- }
-
- public boolean isDelete() {
- return isDelete;
- }
-
- public void setDelete(boolean delete) {
- isDelete = delete;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getConfirmPassword() {
- return confirmPassword;
- }
-
- public void setConfirmPassword(String confirmPassword) {
- this.confirmPassword = confirmPassword;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public boolean isLdapAuthenticated() {
- return isLdapAuthenticated;
- }
-
- public void setLdapAuthenticated(boolean ldapAuthenticated) {
- isLdapAuthenticated = ldapAuthenticated;
- }
-
- public boolean isLdapEnabled() {
- return isLdapEnabled;
- }
-
- public void setLdapEnabled(boolean ldapEnabled) {
- isLdapEnabled = ldapEnabled;
- }
-
- public String getTranscodeSchemeName() {
- return transcodeSchemeName;
- }
-
- public void setTranscodeSchemeName(String transcodeSchemeName) {
- this.transcodeSchemeName = transcodeSchemeName;
- }
-
- public EnumHolder[] getTranscodeSchemeHolders() {
- return transcodeSchemeHolders;
- }
-
- public void setTranscodeSchemes(TranscodeScheme[] transcodeSchemes) {
- transcodeSchemeHolders = new EnumHolder[transcodeSchemes.length];
- for (int i = 0; i < transcodeSchemes.length; i++) {
- TranscodeScheme scheme = transcodeSchemes[i];
- transcodeSchemeHolders[i] = new EnumHolder(scheme.name(), scheme.toString());
- }
- }
-
- public boolean isTranscodingSupported() {
- return transcodingSupported;
- }
-
- public void setTranscodingSupported(boolean transcodingSupported) {
- this.transcodingSupported = transcodingSupported;
- }
-
- public String getTranscodeDirectory() {
- return transcodeDirectory;
- }
-
- public void setTranscodeDirectory(String transcodeDirectory) {
- this.transcodeDirectory = transcodeDirectory;
- }
-
- public void setUser(User user) {
- username = user == null ? null : user.getUsername();
- isAdminRole = user != null && user.isAdminRole();
- isDownloadRole = user != null && user.isDownloadRole();
- isUploadRole = user != null && user.isUploadRole();
- isCoverArtRole = user != null && user.isCoverArtRole();
- isCommentRole = user != null && user.isCommentRole();
- isPodcastRole = user != null && user.isPodcastRole();
- isStreamRole = user != null && user.isStreamRole();
- isJukeboxRole = user != null && user.isJukeboxRole();
- isSettingsRole = user != null && user.isSettingsRole();
- isShareRole = user != null && user.isShareRole();
- isLdapAuthenticated = user != null && user.isLdapAuthenticated();
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AbstractChartController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AbstractChartController.java
deleted file mode 100644
index f163f82d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AbstractChartController.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import org.springframework.web.servlet.support.*;
-import org.springframework.web.servlet.mvc.*;
-import org.springframework.ui.context.*;
-
-import javax.servlet.http.*;
-import java.awt.*;
-import java.util.*;
-
-/**
- * Abstract super class for controllers which generate charts.
- *
- * @author Sindre Mehus
- */
-public abstract class AbstractChartController implements Controller {
-
- /**
- * Returns the chart background color for the current theme.
- * @param request The servlet request.
- * @return The chart background color.
- */
- protected Color getBackground(HttpServletRequest request) {
- return getColor("backgroundColor", request);
- }
-
- /**
- * Returns the chart foreground color for the current theme.
- * @param request The servlet request.
- * @return The chart foreground color.
- */
- protected Color getForeground(HttpServletRequest request) {
- return getColor("textColor", request);
- }
-
- private Color getColor(String code, HttpServletRequest request) {
- Theme theme = RequestContextUtils.getTheme(request);
- Locale locale = RequestContextUtils.getLocale(request);
- String colorHex = theme.getMessageSource().getMessage(code, new Object[0], locale);
- return new Color(Integer.parseInt(colorHex, 16));
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AdvancedSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AdvancedSettingsController.java
deleted file mode 100644
index 0b43f4eb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AdvancedSettingsController.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.command.AdvancedSettingsCommand;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-import org.apache.commons.lang.StringUtils;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * Controller for the page used to administrate advanced settings.
- *
- * @author Sindre Mehus
- */
-public class AdvancedSettingsController extends SimpleFormController {
-
- private SettingsService settingsService;
-
- @Override
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- AdvancedSettingsCommand command = new AdvancedSettingsCommand();
- command.setCoverArtLimit(String.valueOf(settingsService.getCoverArtLimit()));
- command.setDownsampleCommand(settingsService.getDownsamplingCommand());
- command.setDownloadLimit(String.valueOf(settingsService.getDownloadBitrateLimit()));
- command.setUploadLimit(String.valueOf(settingsService.getUploadBitrateLimit()));
- command.setStreamPort(String.valueOf(settingsService.getStreamPort()));
- command.setLdapEnabled(settingsService.isLdapEnabled());
- command.setLdapUrl(settingsService.getLdapUrl());
- command.setLdapSearchFilter(settingsService.getLdapSearchFilter());
- command.setLdapManagerDn(settingsService.getLdapManagerDn());
- command.setLdapAutoShadowing(settingsService.isLdapAutoShadowing());
- command.setBrand(settingsService.getBrand());
-
- return command;
- }
-
- @Override
- protected void doSubmitAction(Object comm) throws Exception {
- AdvancedSettingsCommand command = (AdvancedSettingsCommand) comm;
-
- command.setReloadNeeded(false);
- settingsService.setDownsamplingCommand(command.getDownsampleCommand());
-
- try {
- settingsService.setCoverArtLimit(Integer.parseInt(command.getCoverArtLimit()));
- } catch (NumberFormatException x) { /* Intentionally ignored. */ }
- try {
- settingsService.setDownloadBitrateLimit(Long.parseLong(command.getDownloadLimit()));
- } catch (NumberFormatException x) { /* Intentionally ignored. */ }
- try {
- settingsService.setUploadBitrateLimit(Long.parseLong(command.getUploadLimit()));
- } catch (NumberFormatException x) { /* Intentionally ignored. */ }
- try {
- settingsService.setStreamPort(Integer.parseInt(command.getStreamPort()));
- } catch (NumberFormatException x) { /* Intentionally ignored. */ }
-
- settingsService.setLdapEnabled(command.isLdapEnabled());
- settingsService.setLdapUrl(command.getLdapUrl());
- settingsService.setLdapSearchFilter(command.getLdapSearchFilter());
- settingsService.setLdapManagerDn(command.getLdapManagerDn());
- settingsService.setLdapAutoShadowing(command.isLdapAutoShadowing());
-
- if (StringUtils.isNotEmpty(command.getLdapManagerPassword())) {
- settingsService.setLdapManagerPassword(command.getLdapManagerPassword());
- }
-
- settingsService.save();
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AllmusicController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AllmusicController.java
deleted file mode 100644
index 8b34f383..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AllmusicController.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.mvc.*;
-
-import javax.servlet.http.*;
-
-/**
- * Controller for the page which forwards to allmusic.com.
- *
- * @author Sindre Mehus
- */
-public class AllmusicController extends ParameterizableViewController {
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("album", request.getParameter("album"));
- return result;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarController.java
deleted file mode 100644
index 100fcedb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarController.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.Avatar;
-import net.sourceforge.subsonic.domain.AvatarScheme;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-import org.springframework.web.servlet.mvc.LastModified;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Controller which produces avatar images.
- *
- * @author Sindre Mehus
- */
-public class AvatarController implements Controller, LastModified {
-
- private SettingsService settingsService;
-
- public long getLastModified(HttpServletRequest request) {
- Avatar avatar = getAvatar(request);
- return avatar == null ? -1L : avatar.getCreatedDate().getTime();
- }
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Avatar avatar = getAvatar(request);
-
- if (avatar == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return null;
- }
-
- // TODO: specify caching filter.
-
- response.setContentType(avatar.getMimeType());
- response.getOutputStream().write(avatar.getData());
- return null;
- }
-
- private Avatar getAvatar(HttpServletRequest request) {
- String id = request.getParameter("id");
- if (id != null) {
- return settingsService.getSystemAvatar(Integer.parseInt(id));
- }
-
- String username = request.getParameter("username");
- if (username == null) {
- return null;
- }
-
- UserSettings userSettings = settingsService.getUserSettings(username);
- if (userSettings.getAvatarScheme() == AvatarScheme.SYSTEM) {
- return settingsService.getSystemAvatar(userSettings.getSystemAvatarId());
- }
- return settingsService.getCustomAvatar(username);
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarUploadController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarUploadController.java
deleted file mode 100644
index a22cd9a9..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/AvatarUploadController.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Avatar;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileItemFactory;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.imageio.ImageIO;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller which receives uploaded avatar images.
- *
- * @author Sindre Mehus
- */
-public class AvatarUploadController extends ParameterizableViewController {
-
- private static final Logger LOG = Logger.getLogger(AvatarUploadController.class);
- private static final int MAX_AVATAR_SIZE = 64;
-
- private SettingsService settingsService;
- private SecurityService securityService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- String username = securityService.getCurrentUsername(request);
-
- // Check that we have a file upload request.
- if (!ServletFileUpload.isMultipartContent(request)) {
- throw new Exception("Illegal request.");
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- FileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload upload = new ServletFileUpload(factory);
- List<?> items = upload.parseRequest(request);
-
- // Look for file items.
- for (Object o : items) {
- FileItem item = (FileItem) o;
-
- if (!item.isFormField()) {
- String fileName = item.getName();
- byte[] data = item.get();
-
- if (StringUtils.isNotBlank(fileName) && data.length > 0) {
- createAvatar(fileName, data, username, map);
- } else {
- map.put("error", new Exception("Missing file."));
- LOG.warn("Failed to upload personal image. No file specified.");
- }
- break;
- }
- }
-
- map.put("username", username);
- map.put("avatar", settingsService.getCustomAvatar(username));
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- private void createAvatar(String fileName, byte[] data, String username, Map<String, Object> map) throws IOException {
-
- BufferedImage image;
- try {
- image = ImageIO.read(new ByteArrayInputStream(data));
- if (image == null) {
- throw new Exception("Failed to decode incoming image: " + fileName + " (" + data.length + " bytes).");
- }
- int width = image.getWidth();
- int height = image.getHeight();
- String mimeType = StringUtil.getMimeType(FilenameUtils.getExtension(fileName));
-
- // Scale down image if necessary.
- if (width > MAX_AVATAR_SIZE || height > MAX_AVATAR_SIZE) {
- double scaleFactor = (double) MAX_AVATAR_SIZE / (double) Math.max(width, height);
- height = (int) (height * scaleFactor);
- width = (int) (width * scaleFactor);
- image = CoverArtController.scale(image, width, height);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ImageIO.write(image, "jpeg", out);
- data = out.toByteArray();
- mimeType = StringUtil.getMimeType("jpeg");
- map.put("resized", true);
- }
- Avatar avatar = new Avatar(0, fileName, new Date(), mimeType, width, height, data);
- settingsService.setCustomAvatar(avatar, username);
- LOG.info("Created avatar '" + fileName + "' (" + data.length + " bytes) for user " + username);
-
- } catch (Exception x) {
- LOG.warn("Failed to upload personal image: " + x, x);
- map.put("error", x);
- }
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ChangeCoverArtController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ChangeCoverArtController.java
deleted file mode 100644
index 94c88656..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ChangeCoverArtController.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.MediaFileService;
-
-/**
- * Controller for changing cover art.
- *
- * @author Sindre Mehus
- */
-public class ChangeCoverArtController extends ParameterizableViewController {
-
- private MediaFileService mediaFileService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- String artist = request.getParameter("artist");
- String album = request.getParameter("album");
- MediaFile dir = mediaFileService.getMediaFile(id);
-
- if (artist == null) {
- artist = dir.getArtist();
- }
- if (album == null) {
- album = dir.getAlbumName();
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("id", id);
- map.put("artist", artist);
- map.put("album", album);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
-
- return result;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/CoverArtController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/CoverArtController.java
deleted file mode 100644
index a5093024..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/CoverArtController.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.AlbumDao;
-import net.sourceforge.subsonic.dao.ArtistDao;
-import net.sourceforge.subsonic.domain.Album;
-import net.sourceforge.subsonic.domain.Artist;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.metadata.JaudiotaggerParser;
-import net.sourceforge.subsonic.util.FileUtil;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-import org.springframework.web.servlet.mvc.LastModified;
-
-import javax.imageio.ImageIO;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Controller which produces cover art images.
- *
- * @author Sindre Mehus
- */
-public class CoverArtController implements Controller, LastModified {
-
- public static final String ALBUM_COVERART_PREFIX = "al-";
- public static final String ARTIST_COVERART_PREFIX = "ar-";
-
- private static final Logger LOG = Logger.getLogger(CoverArtController.class);
-
- private SecurityService securityService;
- private MediaFileService mediaFileService;
- private ArtistDao artistDao;
- private AlbumDao albumDao;
-
- public long getLastModified(HttpServletRequest request) {
- try {
- File file = getImageFile(request);
- if (file == null) {
- return 0; // Request for the default image.
- }
- if (!FileUtil.exists(file)) {
- return -1;
- }
-
- return FileUtil.lastModified(file);
- } catch (Exception e) {
- return -1;
- }
- }
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- File file = getImageFile(request);
-
- if (file != null && !FileUtil.exists(file)) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return null;
- }
-
- // Check access.
- if (file != null && !securityService.isReadAllowed(file)) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return null;
- }
-
- // Send default image if no path is given. (No need to cache it, since it will be cached in browser.)
- Integer size = ServletRequestUtils.getIntParameter(request, "size");
- if (file == null) {
- sendDefault(size, response);
- return null;
- }
-
- // Optimize if no scaling is required.
- if (size == null) {
- sendUnscaled(file, response);
- return null;
- }
-
- // Send cached image, creating it if necessary.
- try {
- File cachedImage = getCachedImage(file, size);
- sendImage(cachedImage, response);
- } catch (IOException e) {
- sendDefault(size, response);
- }
-
- return null;
- }
-
- private File getImageFile(HttpServletRequest request) {
- String id = request.getParameter("id");
- if (id != null) {
- if (id.startsWith(ALBUM_COVERART_PREFIX)) {
- return getAlbumImage(Integer.valueOf(id.replace(ALBUM_COVERART_PREFIX, "")));
- }
- if (id.startsWith(ARTIST_COVERART_PREFIX)) {
- return getArtistImage(Integer.valueOf(id.replace(ARTIST_COVERART_PREFIX, "")));
- }
- return getMediaFileImage(Integer.valueOf(id));
- }
-
- String path = StringUtils.trimToNull(request.getParameter("path"));
- return path != null ? new File(path) : null;
- }
-
- private File getArtistImage(int id) {
- Artist artist = artistDao.getArtist(id);
- return artist == null || artist.getCoverArtPath() == null ? null : new File(artist.getCoverArtPath());
- }
-
- private File getAlbumImage(int id) {
- Album album = albumDao.getAlbum(id);
- return album == null || album.getCoverArtPath() == null ? null : new File(album.getCoverArtPath());
- }
-
- private File getMediaFileImage(int id) {
- MediaFile mediaFile = mediaFileService.getMediaFile(id);
- return mediaFile == null ? null : mediaFileService.getCoverArt(mediaFile);
- }
-
- private void sendImage(File file, HttpServletResponse response) throws IOException {
- InputStream in = new FileInputStream(file);
- try {
- IOUtils.copy(in, response.getOutputStream());
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- private void sendDefault(Integer size, HttpServletResponse response) throws IOException {
- InputStream in = null;
- try {
- in = getClass().getResourceAsStream("default_cover.jpg");
- BufferedImage image = ImageIO.read(in);
- if (size != null) {
- image = scale(image, size, size);
- }
- ImageIO.write(image, "jpeg", response.getOutputStream());
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- private void sendUnscaled(File file, HttpServletResponse response) throws IOException {
- InputStream in = null;
- try {
- in = getImageInputStream(file);
- IOUtils.copy(in, response.getOutputStream());
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- private File getCachedImage(File file, int size) throws IOException {
- String md5 = DigestUtils.md5Hex(file.getPath());
- File cachedImage = new File(getImageCacheDirectory(size), md5 + ".jpeg");
-
- // Is cache missing or obsolete?
- if (!cachedImage.exists() || FileUtil.lastModified(file) > cachedImage.lastModified()) {
- InputStream in = null;
- OutputStream out = null;
- try {
- in = getImageInputStream(file);
- out = new FileOutputStream(cachedImage);
- BufferedImage image = ImageIO.read(in);
- if (image == null) {
- throw new Exception("Unable to decode image.");
- }
-
- image = scale(image, size, size);
- ImageIO.write(image, "jpeg", out);
-
- } catch (Throwable x) {
- // Delete corrupt (probably empty) thumbnail cache.
- LOG.warn("Failed to create thumbnail for " + file, x);
- IOUtils.closeQuietly(out);
- cachedImage.delete();
- throw new IOException("Failed to create thumbnail for " + file + ". " + x.getMessage());
-
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- }
- }
- return cachedImage;
- }
-
- /**
- * Returns an input stream to the image in the given file. If the file is an audio file,
- * the embedded album art is returned.
- */
- private InputStream getImageInputStream(File file) throws IOException {
- JaudiotaggerParser parser = new JaudiotaggerParser();
- if (parser.isApplicable(file)) {
- MediaFile mediaFile = mediaFileService.getMediaFile(file);
- return new ByteArrayInputStream(parser.getImageData(mediaFile));
- } else {
- return new FileInputStream(file);
- }
- }
-
- private synchronized File getImageCacheDirectory(int size) {
- File dir = new File(SettingsService.getSubsonicHome(), "thumbs");
- dir = new File(dir, String.valueOf(size));
- if (!dir.exists()) {
- if (dir.mkdirs()) {
- LOG.info("Created thumbnail cache " + dir);
- } else {
- LOG.error("Failed to create thumbnail cache " + dir);
- }
- }
-
- return dir;
- }
-
- public static BufferedImage scale(BufferedImage image, int width, int height) {
- int w = image.getWidth();
- int h = image.getHeight();
- BufferedImage thumb = image;
-
- // For optimal results, use step by step bilinear resampling - halfing the size at each step.
- do {
- w /= 2;
- h /= 2;
- if (w < width) {
- w = width;
- }
- if (h < height) {
- h = height;
- }
-
- BufferedImage temp = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
- Graphics2D g2 = temp.createGraphics();
- g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
- RenderingHints.VALUE_INTERPOLATION_BILINEAR);
- g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
- g2.dispose();
-
- thumb = temp;
- } while (w != width);
-
- return thumb;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setArtistDao(ArtistDao artistDao) {
- this.artistDao = artistDao;
- }
-
- public void setAlbumDao(AlbumDao albumDao) {
- this.albumDao = albumDao;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DBController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DBController.java
deleted file mode 100644
index 17d06497..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DBController.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.dao.DaoHelper;
-import org.apache.commons.lang.exception.ExceptionUtils;
-import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.ColumnMapRowMapper;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for the DB admin page.
- *
- * @author Sindre Mehus
- */
-public class DBController extends ParameterizableViewController {
-
- private DaoHelper daoHelper;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- String query = request.getParameter("query");
- if (query != null) {
- map.put("query", query);
-
- try {
- List<?> result = daoHelper.getJdbcTemplate().query(query, new ColumnMapRowMapper());
- map.put("result", result);
- } catch (DataAccessException x) {
- map.put("error", ExceptionUtils.getRootCause(x).getMessage());
- }
- }
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setDaoHelper(DaoHelper daoHelper) {
- this.daoHelper = daoHelper;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DonateController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DonateController.java
deleted file mode 100644
index 144d3327..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DonateController.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.command.DonateCommand;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.validation.BindException;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Date;
-
-/**
- * Controller for the donation page.
- *
- * @author Sindre Mehus
- */
-public class DonateController extends SimpleFormController {
-
- private SettingsService settingsService;
-
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- DonateCommand command = new DonateCommand();
- command.setPath(request.getParameter("path"));
-
- command.setEmailAddress(settingsService.getLicenseEmail());
- command.setLicenseDate(settingsService.getLicenseDate());
- command.setLicenseValid(settingsService.isLicenseValid());
- command.setLicense(settingsService.getLicenseCode());
- command.setBrand(settingsService.getBrand());
-
- return command;
- }
-
- protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object com, BindException errors)
- throws Exception {
- DonateCommand command = (DonateCommand) com;
- Date now = new Date();
-
- settingsService.setLicenseCode(command.getLicense());
- settingsService.setLicenseEmail(command.getEmailAddress());
- settingsService.setLicenseDate(now);
- settingsService.save();
- settingsService.validateLicenseAsync();
-
- // Reflect changes in view. The validator has already validated the license.
- command.setLicenseValid(true);
- command.setLicenseDate(now);
-
- return new ModelAndView(getSuccessView(), errors.getModel());
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DownloadController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DownloadController.java
deleted file mode 100644
index 0125d3bb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/DownloadController.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.io.RangeOutputStream;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.StatusService;
-import net.sourceforge.subsonic.util.FileUtil;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.Util;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.math.LongRange;
-import org.apache.tools.zip.ZipEntry;
-import org.apache.tools.zip.ZipOutputStream;
-import org.springframework.web.bind.ServletRequestBindingException;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-import org.springframework.web.servlet.mvc.LastModified;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.CRC32;
-
-/**
- * A controller used for downloading files to a remote client. If the requested path refers to a file, the
- * given file is downloaded. If the requested path refers to a directory, the entire directory (including
- * sub-directories) are downloaded as an uncompressed zip-file.
- *
- * @author Sindre Mehus
- */
-public class DownloadController implements Controller, LastModified {
-
- private static final Logger LOG = Logger.getLogger(DownloadController.class);
-
- private PlayerService playerService;
- private StatusService statusService;
- private SecurityService securityService;
- private PlaylistService playlistService;
- private SettingsService settingsService;
- private MediaFileService mediaFileService;
-
- public long getLastModified(HttpServletRequest request) {
- try {
- MediaFile mediaFile = getSingleFile(request);
- if (mediaFile == null || mediaFile.isDirectory() || mediaFile.getChanged() == null) {
- return -1;
- }
- return mediaFile.getChanged().getTime();
- } catch (ServletRequestBindingException e) {
- return -1;
- }
- }
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- TransferStatus status = null;
- try {
-
- status = statusService.createDownloadStatus(playerService.getPlayer(request, response, false, false));
-
- MediaFile mediaFile = getSingleFile(request);
- String dir = request.getParameter("dir");
- Integer playlistId = ServletRequestUtils.getIntParameter(request, "playlist");
- String playerId = request.getParameter("player");
- int[] indexes = ServletRequestUtils.getIntParameters(request, "i");
-
- if (mediaFile != null) {
- response.setIntHeader("ETag", mediaFile.getId());
- response.setHeader("Accept-Ranges", "bytes");
- }
-
- LongRange range = StringUtil.parseRange(request.getHeader("Range"));
- if (range != null) {
- response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
- LOG.info("Got range: " + range);
- }
-
- if (mediaFile != null) {
- File file = mediaFile.getFile();
- if (!securityService.isReadAllowed(file)) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return null;
- }
-
- if (file.isFile()) {
- downloadFile(response, status, file, range);
- } else {
- downloadDirectory(response, status, file, range);
- }
- } else if (dir != null) {
- File file = new File(dir);
- if (!securityService.isReadAllowed(file)) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return null;
- }
- downloadFiles(response, status, file, indexes);
-
- } else if (playlistId != null) {
- List<MediaFile> songs = playlistService.getFilesInPlaylist(playlistId);
- downloadFiles(response, status, songs, null, range);
-
- } else if (playerId != null) {
- Player player = playerService.getPlayerById(playerId);
- PlayQueue playQueue = player.getPlayQueue();
- playQueue.setName("Playlist");
- downloadFiles(response, status, playQueue.getFiles(), indexes.length == 0 ? null : indexes, range);
- }
-
-
- } finally {
- if (status != null) {
- statusService.removeDownloadStatus(status);
- User user = securityService.getCurrentUser(request);
- securityService.updateUserByteCounts(user, 0L, status.getBytesTransfered(), 0L);
- }
- }
-
- return null;
- }
-
- private MediaFile getSingleFile(HttpServletRequest request) throws ServletRequestBindingException {
- String path = request.getParameter("path");
- if (path != null) {
- return mediaFileService.getMediaFile(path);
- }
- Integer id = ServletRequestUtils.getIntParameter(request, "id");
- if (id != null) {
- return mediaFileService.getMediaFile(id);
- }
- return null;
- }
-
- /**
- * Downloads a single file.
- *
- * @param response The HTTP response.
- * @param status The download status.
- * @param file The file to download.
- * @param range The byte range, may be <code>null</code>.
- * @throws IOException If an I/O error occurs.
- */
- private void downloadFile(HttpServletResponse response, TransferStatus status, File file, LongRange range) throws IOException {
- LOG.info("Starting to download '" + FileUtil.getShortPath(file) + "' to " + status.getPlayer());
- status.setFile(file);
-
- response.setContentType("application/x-download");
- response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + '\"');
- if (range == null) {
- Util.setContentLength(response, file.length());
- }
-
- copyFileToStream(file, RangeOutputStream.wrap(response.getOutputStream(), range), status, range);
- LOG.info("Downloaded '" + FileUtil.getShortPath(file) + "' to " + status.getPlayer());
- }
-
- /**
- * Downloads a collection of files within a directory.
- *
- * @param response The HTTP response.
- * @param status The download status.
- * @param dir The directory.
- * @param indexes Only download files with these indexes within the directory.
- * @throws IOException If an I/O error occurs.
- */
- private void downloadFiles(HttpServletResponse response, TransferStatus status, File dir, int[] indexes) throws IOException {
- String zipFileName = dir.getName() + ".zip";
- LOG.info("Starting to download '" + zipFileName + "' to " + status.getPlayer());
- status.setFile(dir);
-
- response.setContentType("application/x-download");
- response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + "\"");
-
- ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
- out.setMethod(ZipOutputStream.STORED); // No compression.
-
- List<MediaFile> allChildren = mediaFileService.getChildrenOf(dir, true, true, true);
- List<MediaFile> mediaFiles = new ArrayList<MediaFile>();
- for (int index : indexes) {
- mediaFiles.add(allChildren.get(index));
- }
-
- for (MediaFile mediaFile : mediaFiles) {
- zip(out, mediaFile.getParentFile(), mediaFile.getFile(), status, null);
- }
-
- out.close();
- LOG.info("Downloaded '" + zipFileName + "' to " + status.getPlayer());
- }
-
- /**
- * Downloads all files in a directory (including sub-directories). The files are packed together in an
- * uncompressed zip-file.
- *
- * @param response The HTTP response.
- * @param status The download status.
- * @param file The file to download.
- * @param range The byte range, may be <code>null</code>.
- * @throws IOException If an I/O error occurs.
- */
- private void downloadDirectory(HttpServletResponse response, TransferStatus status, File file, LongRange range) throws IOException {
- String zipFileName = file.getName() + ".zip";
- LOG.info("Starting to download '" + zipFileName + "' to " + status.getPlayer());
- response.setContentType("application/x-download");
- response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + '"');
-
- ZipOutputStream out = new ZipOutputStream(RangeOutputStream.wrap(response.getOutputStream(), range));
- out.setMethod(ZipOutputStream.STORED); // No compression.
-
- zip(out, file.getParentFile(), file, status, range);
- out.close();
- LOG.info("Downloaded '" + zipFileName + "' to " + status.getPlayer());
- }
-
- /**
- * Downloads the given files. The files are packed together in an
- * uncompressed zip-file.
- *
- * @param response The HTTP response.
- * @param status The download status.
- * @param files The files to download.
- * @param indexes Only download songs at these indexes. May be <code>null</code>.
- * @param range The byte range, may be <code>null</code>.
- * @throws IOException If an I/O error occurs.
- */
- private void downloadFiles(HttpServletResponse response, TransferStatus status, List<MediaFile> files, int[] indexes, LongRange range) throws IOException {
- if (indexes != null && indexes.length == 1) {
- downloadFile(response, status, files.get(indexes[0]).getFile(), range);
- return;
- }
-
- String zipFileName = "download.zip";
- LOG.info("Starting to download '" + zipFileName + "' to " + status.getPlayer());
- response.setContentType("application/x-download");
- response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + '"');
-
- ZipOutputStream out = new ZipOutputStream(RangeOutputStream.wrap(response.getOutputStream(), range));
- out.setMethod(ZipOutputStream.STORED); // No compression.
-
- List<MediaFile> filesToDownload = new ArrayList<MediaFile>();
- if (indexes == null) {
- filesToDownload.addAll(files);
- } else {
- for (int index : indexes) {
- try {
- filesToDownload.add(files.get(index));
- } catch (IndexOutOfBoundsException x) { /* Ignored */}
- }
- }
-
- for (MediaFile mediaFile : filesToDownload) {
- zip(out, mediaFile.getParentFile(), mediaFile.getFile(), status, range);
- }
-
- out.close();
- LOG.info("Downloaded '" + zipFileName + "' to " + status.getPlayer());
- }
-
- /**
- * Utility method for writing the content of a given file to a given output stream.
- *
- * @param file The file to copy.
- * @param out The output stream to write to.
- * @param status The download status.
- * @param range The byte range, may be <code>null</code>.
- * @throws IOException If an I/O error occurs.
- */
- private void copyFileToStream(File file, OutputStream out, TransferStatus status, LongRange range) throws IOException {
- LOG.info("Downloading '" + FileUtil.getShortPath(file) + "' to " + status.getPlayer());
-
- final int bufferSize = 16 * 1024; // 16 Kbit
- InputStream in = new BufferedInputStream(new FileInputStream(file), bufferSize);
-
- try {
- byte[] buf = new byte[bufferSize];
- long bitrateLimit = 0;
- long lastLimitCheck = 0;
-
- while (true) {
- long before = System.currentTimeMillis();
- int n = in.read(buf);
- if (n == -1) {
- break;
- }
- out.write(buf, 0, n);
-
- // Don't sleep if outside range.
- if (range != null && !range.containsLong(status.getBytesSkipped() + status.getBytesTransfered())) {
- status.addBytesSkipped(n);
- continue;
- }
-
- status.addBytesTransfered(n);
- long after = System.currentTimeMillis();
-
- // Calculate bitrate limit every 5 seconds.
- if (after - lastLimitCheck > 5000) {
- bitrateLimit = 1024L * settingsService.getDownloadBitrateLimit() /
- Math.max(1, statusService.getAllDownloadStatuses().size());
- lastLimitCheck = after;
- }
-
- // Sleep for a while to throttle bitrate.
- if (bitrateLimit != 0) {
- long sleepTime = 8L * 1000 * bufferSize / bitrateLimit - (after - before);
- if (sleepTime > 0L) {
- try {
- Thread.sleep(sleepTime);
- } catch (Exception x) {
- LOG.warn("Failed to sleep.", x);
- }
- }
- }
- }
- } finally {
- out.flush();
- IOUtils.closeQuietly(in);
- }
- }
-
- /**
- * Writes a file or a directory structure to a zip output stream. File entries in the zip file are relative
- * to the given root.
- *
- * @param out The zip output stream.
- * @param root The root of the directory structure. Used to create path information in the zip file.
- * @param file The file or directory to zip.
- * @param status The download status.
- * @param range The byte range, may be <code>null</code>.
- * @throws IOException If an I/O error occurs.
- */
- private void zip(ZipOutputStream out, File root, File file, TransferStatus status, LongRange range) throws IOException {
-
- // Exclude all hidden files starting with a "."
- if (file.getName().startsWith(".")) {
- return;
- }
-
- String zipName = file.getCanonicalPath().substring(root.getCanonicalPath().length() + 1);
-
- if (file.isFile()) {
- status.setFile(file);
-
- ZipEntry zipEntry = new ZipEntry(zipName);
- zipEntry.setSize(file.length());
- zipEntry.setCompressedSize(file.length());
- zipEntry.setCrc(computeCrc(file));
-
- out.putNextEntry(zipEntry);
- copyFileToStream(file, out, status, range);
- out.closeEntry();
-
- } else {
- ZipEntry zipEntry = new ZipEntry(zipName + '/');
- zipEntry.setSize(0);
- zipEntry.setCompressedSize(0);
- zipEntry.setCrc(0);
-
- out.putNextEntry(zipEntry);
- out.closeEntry();
-
- File[] children = FileUtil.listFiles(file);
- for (File child : children) {
- zip(out, root, child, status, range);
- }
- }
- }
-
- /**
- * Computes the CRC checksum for the given file.
- *
- * @param file The file to compute checksum for.
- * @return A CRC32 checksum.
- * @throws IOException If an I/O error occurs.
- */
- private long computeCrc(File file) throws IOException {
- CRC32 crc = new CRC32();
- InputStream in = new FileInputStream(file);
-
- try {
-
- byte[] buf = new byte[8192];
- int n = in.read(buf);
- while (n != -1) {
- crc.update(buf, 0, n);
- n = in.read(buf);
- }
-
- } finally {
- in.close();
- }
-
- return crc.getValue();
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/EditTagsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/EditTagsController.java
deleted file mode 100644
index 91492222..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/EditTagsController.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.service.metadata.MetaData;
-import net.sourceforge.subsonic.service.metadata.MetaDataParser;
-import net.sourceforge.subsonic.service.metadata.MetaDataParserFactory;
-import net.sourceforge.subsonic.service.metadata.JaudiotaggerParser;
-
-import org.apache.commons.io.FilenameUtils;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.mvc.*;
-
-import javax.servlet.http.*;
-import java.util.*;
-
-/**
- * Controller for the page used to edit MP3 tags.
- *
- * @author Sindre Mehus
- */
-public class EditTagsController extends ParameterizableViewController {
-
- private MetaDataParserFactory metaDataParserFactory;
- private MediaFileService mediaFileService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- MediaFile dir = mediaFileService.getMediaFile(id);
- List<MediaFile> files = mediaFileService.getChildrenOf(dir, true, false, true);
-
- Map<String, Object> map = new HashMap<String, Object>();
- if (!files.isEmpty()) {
- map.put("defaultArtist", files.get(0).getArtist());
- map.put("defaultAlbum", files.get(0).getAlbumName());
- map.put("defaultYear", files.get(0).getYear());
- map.put("defaultGenre", files.get(0).getGenre());
- }
- map.put("allGenres", JaudiotaggerParser.getID3V1Genres());
-
- List<Song> songs = new ArrayList<Song>();
- for (int i = 0; i < files.size(); i++) {
- songs.add(createSong(files.get(i), i));
- }
- map.put("id", id);
- map.put("songs", songs);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- private Song createSong(MediaFile file, int index) {
- MetaDataParser parser = metaDataParserFactory.getParser(file.getFile());
- MetaData metaData = parser.getRawMetaData(file.getFile());
-
- Song song = new Song();
- song.setId(file.getId());
- song.setFileName(FilenameUtils.getBaseName(file.getPath()));
- song.setTrack(metaData.getTrackNumber());
- song.setSuggestedTrack(index + 1);
- song.setTitle(metaData.getTitle());
- song.setSuggestedTitle(parser.guessTitle(file.getFile()));
- song.setArtist(metaData.getArtist());
- song.setAlbum(metaData.getAlbumName());
- song.setYear(metaData.getYear());
- song.setGenre(metaData.getGenre());
- return song;
- }
-
- public void setMetaDataParserFactory(MetaDataParserFactory metaDataParserFactory) {
- this.metaDataParserFactory = metaDataParserFactory;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- /**
- * Contains information about a single song.
- */
- public static class Song {
- private int id;
- private String fileName;
- private Integer suggestedTrack;
- private Integer track;
- private String suggestedTitle;
- private String title;
- private String artist;
- private String album;
- private Integer year;
- private String genre;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getFileName() {
- return fileName;
- }
-
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- public Integer getSuggestedTrack() {
- return suggestedTrack;
- }
-
- public void setSuggestedTrack(Integer suggestedTrack) {
- this.suggestedTrack = suggestedTrack;
- }
-
- public Integer getTrack() {
- return track;
- }
-
- public void setTrack(Integer track) {
- this.track = track;
- }
-
- public String getSuggestedTitle() {
- return suggestedTitle;
- }
-
- public void setSuggestedTitle(String suggestedTitle) {
- this.suggestedTitle = suggestedTitle;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public void setArtist(String artist) {
- this.artist = artist;
- }
-
- public String getAlbum() {
- return album;
- }
-
- public void setAlbum(String album) {
- this.album = album;
- }
-
- public Integer getYear() {
- return year;
- }
-
- public void setYear(Integer year) {
- this.year = year;
- }
-
- public String getGenre() {
- return genre;
- }
-
- public void setGenre(String genre) {
- this.genre = genre;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ExternalPlayerController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ExternalPlayerController.java
deleted file mode 100644
index d8d28f93..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ExternalPlayerController.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.ShareDao;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.Share;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.apache.commons.lang.RandomStringUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for the page used to play shared music (Twitter, Facebook etc).
- *
- * @author Sindre Mehus
- */
-public class ExternalPlayerController extends ParameterizableViewController {
-
- private static final Logger LOG = Logger.getLogger(ExternalPlayerController.class);
- private static final String GUEST_USERNAME = "guest";
-
- private SettingsService settingsService;
- private SecurityService securityService;
- private PlayerService playerService;
- private ShareDao shareDao;
- private MediaFileService mediaFileService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
-
- String pathInfo = request.getPathInfo();
-
- if (pathInfo == null || !pathInfo.startsWith("/")) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return null;
- }
-
- Share share = shareDao.getShareByName(pathInfo.substring(1));
- if (share == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return null;
- }
-
- if (share.getExpires() != null && share.getExpires().before(new Date())) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return null;
- }
-
- share.setLastVisited(new Date());
- share.setVisitCount(share.getVisitCount() + 1);
- shareDao.updateShare(share);
-
- List<MediaFile> songs = getSongs(share);
- List<File> coverArts = getCoverArts(songs);
-
- map.put("share", share);
- map.put("songs", songs);
- map.put("coverArts", coverArts);
-
- if (!coverArts.isEmpty()) {
- map.put("coverArt", coverArts.get(0));
- }
- map.put("redirectFrom", settingsService.getUrlRedirectFrom());
- map.put("player", getPlayer(request).getId());
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- private List<MediaFile> getSongs(Share share) throws IOException {
- List<MediaFile> result = new ArrayList<MediaFile>();
-
- for (String path : shareDao.getSharedFiles(share.getId())) {
- try {
- MediaFile file = mediaFileService.getMediaFile(path);
- if (file.getFile().exists()) {
- if (file.isDirectory()) {
- result.addAll(mediaFileService.getChildrenOf(file, true, false, true));
- } else {
- result.add(file);
- }
- }
- } catch (Exception x) {
- LOG.warn("Couldn't read file " + path);
- }
- }
- return result;
- }
-
- private List<File> getCoverArts(List<MediaFile> songs) throws IOException {
- List<File> result = new ArrayList<File>();
- for (MediaFile song : songs) {
- result.add(mediaFileService.getCoverArt(song));
- }
- return result;
- }
-
-
- private Player getPlayer(HttpServletRequest request) {
-
- // Create guest user if necessary.
- User user = securityService.getUserByName(GUEST_USERNAME);
- if (user == null) {
- user = new User(GUEST_USERNAME, RandomStringUtils.randomAlphanumeric(30), null);
- user.setStreamRole(true);
- securityService.createUser(user);
- }
-
- // Look for existing player.
- List<Player> players = playerService.getPlayersForUserAndClientId(GUEST_USERNAME, null);
- if (!players.isEmpty()) {
- return players.get(0);
- }
-
- // Create player if necessary.
- Player player = new Player();
- player.setIpAddress(request.getRemoteAddr());
- player.setUsername(GUEST_USERNAME);
- playerService.createPlayer(player);
-
- return player;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setShareDao(ShareDao shareDao) {
- this.shareDao = shareDao;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/GeneralSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/GeneralSettingsController.java
deleted file mode 100644
index e7b19b04..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/GeneralSettingsController.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.command.GeneralSettingsCommand;
-import net.sourceforge.subsonic.domain.Theme;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.Locale;
-
-/**
- * Controller for the page used to administrate general settings.
- *
- * @author Sindre Mehus
- */
-public class GeneralSettingsController extends SimpleFormController {
-
- private SettingsService settingsService;
-
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- GeneralSettingsCommand command = new GeneralSettingsCommand();
- command.setCoverArtFileTypes(settingsService.getCoverArtFileTypes());
- command.setIgnoredArticles(settingsService.getIgnoredArticles());
- command.setShortcuts(settingsService.getShortcuts());
- command.setIndex(settingsService.getIndexString());
- command.setMusicFileTypes(settingsService.getMusicFileTypes());
- command.setVideoFileTypes(settingsService.getVideoFileTypes());
- command.setSortAlbumsByYear(settingsService.isSortAlbumsByYear());
- command.setGettingStartedEnabled(settingsService.isGettingStartedEnabled());
- command.setWelcomeTitle(settingsService.getWelcomeTitle());
- command.setWelcomeSubtitle(settingsService.getWelcomeSubtitle());
- command.setWelcomeMessage(settingsService.getWelcomeMessage());
- command.setLoginMessage(settingsService.getLoginMessage());
-
- Theme[] themes = settingsService.getAvailableThemes();
- command.setThemes(themes);
- String currentThemeId = settingsService.getThemeId();
- for (int i = 0; i < themes.length; i++) {
- if (currentThemeId.equals(themes[i].getId())) {
- command.setThemeIndex(String.valueOf(i));
- break;
- }
- }
-
- Locale currentLocale = settingsService.getLocale();
- Locale[] locales = settingsService.getAvailableLocales();
- String[] localeStrings = new String[locales.length];
- for (int i = 0; i < locales.length; i++) {
- localeStrings[i] = locales[i].getDisplayName(locales[i]);
-
- if (currentLocale.equals(locales[i])) {
- command.setLocaleIndex(String.valueOf(i));
- }
- }
- command.setLocales(localeStrings);
-
- return command;
-
- }
-
- protected void doSubmitAction(Object comm) throws Exception {
- GeneralSettingsCommand command = (GeneralSettingsCommand) comm;
-
- int themeIndex = Integer.parseInt(command.getThemeIndex());
- Theme theme = settingsService.getAvailableThemes()[themeIndex];
-
- int localeIndex = Integer.parseInt(command.getLocaleIndex());
- Locale locale = settingsService.getAvailableLocales()[localeIndex];
-
- command.setReloadNeeded(!settingsService.getIndexString().equals(command.getIndex()) ||
- !settingsService.getIgnoredArticles().equals(command.getIgnoredArticles()) ||
- !settingsService.getShortcuts().equals(command.getShortcuts()) ||
- !settingsService.getThemeId().equals(theme.getId()) ||
- !settingsService.getLocale().equals(locale));
-
- settingsService.setIndexString(command.getIndex());
- settingsService.setIgnoredArticles(command.getIgnoredArticles());
- settingsService.setShortcuts(command.getShortcuts());
- settingsService.setMusicFileTypes(command.getMusicFileTypes());
- settingsService.setVideoFileTypes(command.getVideoFileTypes());
- settingsService.setCoverArtFileTypes(command.getCoverArtFileTypes());
- settingsService.setSortAlbumsByYear(command.isSortAlbumsByYear());
- settingsService.setGettingStartedEnabled(command.isGettingStartedEnabled());
- settingsService.setWelcomeTitle(command.getWelcomeTitle());
- settingsService.setWelcomeSubtitle(command.getWelcomeSubtitle());
- settingsService.setWelcomeMessage(command.getWelcomeMessage());
- settingsService.setLoginMessage(command.getLoginMessage());
- settingsService.setThemeId(theme.getId());
- settingsService.setLocale(locale);
- settingsService.save();
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HelpController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HelpController.java
deleted file mode 100644
index 4e0b0945..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HelpController.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.*;
-import net.sourceforge.subsonic.service.*;
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.mvc.*;
-
-import javax.servlet.http.*;
-import java.util.*;
-
-/**
- * Controller for the help page.
- *
- * @author Sindre Mehus
- */
-public class HelpController extends ParameterizableViewController {
-
- private VersionService versionService;
- private SettingsService settingsService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- if (versionService.isNewFinalVersionAvailable()) {
- map.put("newVersionAvailable", true);
- map.put("latestVersion", versionService.getLatestFinalVersion());
- } else if (versionService.isNewBetaVersionAvailable()) {
- map.put("newVersionAvailable", true);
- map.put("latestVersion", versionService.getLatestBetaVersion());
- }
-
- long totalMemory = Runtime.getRuntime().totalMemory();
- long freeMemory = Runtime.getRuntime().freeMemory();
-
- String serverInfo = request.getSession().getServletContext().getServerInfo() +
- ", java " + System.getProperty("java.version") +
- ", " + System.getProperty("os.name");
-
- map.put("brand", settingsService.getBrand());
- map.put("localVersion", versionService.getLocalVersion());
- map.put("buildDate", versionService.getLocalBuildDate());
- map.put("buildNumber", versionService.getLocalBuildNumber());
- map.put("serverInfo", serverInfo);
- map.put("usedMemory", totalMemory - freeMemory);
- map.put("totalMemory", totalMemory);
- map.put("logEntries", Logger.getLatestLogEntries());
- map.put("logFile", Logger.getLogFile());
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setVersionService(VersionService versionService) {
- this.versionService = versionService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HomeController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HomeController.java
deleted file mode 100644
index 49c95926..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/HomeController.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.MediaScannerService;
-import net.sourceforge.subsonic.service.RatingService;
-import net.sourceforge.subsonic.service.SearchService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for the home page.
- *
- * @author Sindre Mehus
- */
-public class HomeController extends ParameterizableViewController {
-
- private static final Logger LOG = Logger.getLogger(HomeController.class);
-
- private static final int DEFAULT_LIST_SIZE = 10;
- private static final int MAX_LIST_SIZE = 500;
- private static final int DEFAULT_LIST_OFFSET = 0;
- private static final int MAX_LIST_OFFSET = 5000;
-
- private SettingsService settingsService;
- private MediaScannerService mediaScannerService;
- private RatingService ratingService;
- private SecurityService securityService;
- private MediaFileService mediaFileService;
- private SearchService searchService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- User user = securityService.getCurrentUser(request);
- if (user.isAdminRole() && settingsService.isGettingStartedEnabled()) {
- return new ModelAndView(new RedirectView("gettingStarted.view"));
- }
-
- int listSize = DEFAULT_LIST_SIZE;
- int listOffset = DEFAULT_LIST_OFFSET;
- if (request.getParameter("listSize") != null) {
- listSize = Math.max(0, Math.min(Integer.parseInt(request.getParameter("listSize")), MAX_LIST_SIZE));
- }
- if (request.getParameter("listOffset") != null) {
- listOffset = Math.max(0, Math.min(Integer.parseInt(request.getParameter("listOffset")), MAX_LIST_OFFSET));
- }
-
- String listType = request.getParameter("listType");
- if (listType == null) {
- listType = "random";
- }
-
- List<Album> albums;
- if ("highest".equals(listType)) {
- albums = getHighestRated(listOffset, listSize);
- } else if ("frequent".equals(listType)) {
- albums = getMostFrequent(listOffset, listSize);
- } else if ("recent".equals(listType)) {
- albums = getMostRecent(listOffset, listSize);
- } else if ("newest".equals(listType)) {
- albums = getNewest(listOffset, listSize);
- } else if ("starred".equals(listType)) {
- albums = getStarred(listOffset, listSize, user.getUsername());
- } else if ("random".equals(listType)) {
- albums = getRandom(listSize);
- } else if ("alphabetical".equals(listType)) {
- albums = getAlphabetical(listOffset, listSize, true);
- } else {
- albums = Collections.emptyList();
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("albums", albums);
- map.put("welcomeTitle", settingsService.getWelcomeTitle());
- map.put("welcomeSubtitle", settingsService.getWelcomeSubtitle());
- map.put("welcomeMessage", settingsService.getWelcomeMessage());
- map.put("isIndexBeingCreated", mediaScannerService.isScanning());
- map.put("listType", listType);
- map.put("listSize", listSize);
- map.put("listOffset", listOffset);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- List<Album> getHighestRated(int offset, int count) {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile mediaFile : ratingService.getHighestRated(offset, count)) {
- Album album = createAlbum(mediaFile);
- if (album != null) {
- album.setRating((int) Math.round(ratingService.getAverageRating(mediaFile) * 10.0D));
- result.add(album);
- }
- }
- return result;
- }
-
- List<Album> getMostFrequent(int offset, int count) {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile mediaFile : mediaFileService.getMostFrequentlyPlayedAlbums(offset, count)) {
- Album album = createAlbum(mediaFile);
- if (album != null) {
- album.setPlayCount(mediaFile.getPlayCount());
- result.add(album);
- }
- }
- return result;
- }
-
- List<Album> getMostRecent(int offset, int count) {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile mediaFile : mediaFileService.getMostRecentlyPlayedAlbums(offset, count)) {
- Album album = createAlbum(mediaFile);
- if (album != null) {
- album.setLastPlayed(mediaFile.getLastPlayed());
- result.add(album);
- }
- }
- return result;
- }
-
- List<Album> getNewest(int offset, int count) throws IOException {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile file : mediaFileService.getNewestAlbums(offset, count)) {
- Album album = createAlbum(file);
- if (album != null) {
- Date created = file.getCreated();
- if (created == null) {
- created = file.getChanged();
- }
- album.setCreated(created);
- result.add(album);
- }
- }
- return result;
- }
-
- List<Album> getStarred(int offset, int count, String username) throws IOException {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile file : mediaFileService.getStarredAlbums(offset, count, username)) {
- Album album = createAlbum(file);
- if (album != null) {
- result.add(album);
- }
- }
- return result;
- }
-
- List<Album> getRandom(int count) throws IOException {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile file : searchService.getRandomAlbums(count)) {
- Album album = createAlbum(file);
- if (album != null) {
- result.add(album);
- }
- }
- return result;
- }
-
- List<Album> getAlphabetical(int offset, int count, boolean byArtist) throws IOException {
- List<Album> result = new ArrayList<Album>();
- for (MediaFile file : mediaFileService.getAlphabetialAlbums(offset, count, byArtist)) {
- Album album = createAlbum(file);
- if (album != null) {
- result.add(album);
- }
- }
- return result;
- }
-
- private Album createAlbum(MediaFile file) {
- Album album = new Album();
- album.setId(file.getId());
- album.setPath(file.getPath());
- try {
- resolveArtistAndAlbumTitle(album, file);
- resolveCoverArt(album, file);
- } catch (Exception x) {
- LOG.warn("Failed to create albumTitle list entry for " + file.getPath(), x);
- return null;
- }
- return album;
- }
-
- private void resolveArtistAndAlbumTitle(Album album, MediaFile file) throws IOException {
- album.setArtist(file.getArtist());
- album.setAlbumTitle(file.getAlbumName());
- }
-
- private void resolveCoverArt(Album album, MediaFile file) {
- album.setCoverArtPath(file.getCoverArtPath());
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaScannerService(MediaScannerService mediaScannerService) {
- this.mediaScannerService = mediaScannerService;
- }
-
- public void setRatingService(RatingService ratingService) {
- this.ratingService = ratingService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-
- /**
- * Contains info for a single album.
- */
- @Deprecated
- public static class Album {
- private String path;
- private String coverArtPath;
- private String artist;
- private String albumTitle;
- private Date created;
- private Date lastPlayed;
- private Integer playCount;
- private Integer rating;
- private int id;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getCoverArtPath() {
- return coverArtPath;
- }
-
- public void setCoverArtPath(String coverArtPath) {
- this.coverArtPath = coverArtPath;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public void setArtist(String artist) {
- this.artist = artist;
- }
-
- public String getAlbumTitle() {
- return albumTitle;
- }
-
- public void setAlbumTitle(String albumTitle) {
- this.albumTitle = albumTitle;
- }
-
- public Date getCreated() {
- return created;
- }
-
- public void setCreated(Date created) {
- this.created = created;
- }
-
- public Date getLastPlayed() {
- return lastPlayed;
- }
-
- public void setLastPlayed(Date lastPlayed) {
- this.lastPlayed = lastPlayed;
- }
-
- public Integer getPlayCount() {
- return playCount;
- }
-
- public void setPlayCount(Integer playCount) {
- this.playCount = playCount;
- }
-
- public Integer getRating() {
- return rating;
- }
-
- public void setRating(Integer rating) {
- this.rating = rating;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ImportPlaylistController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ImportPlaylistController.java
deleted file mode 100644
index 55e9b200..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ImportPlaylistController.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileItemFactory;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-
-/**
- * @author Sindre Mehus
- */
-public class ImportPlaylistController extends ParameterizableViewController {
-
- private static final long MAX_PLAYLIST_SIZE_MB = 5L;
-
- private SecurityService securityService;
- private PlaylistService playlistService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- try {
- if (ServletFileUpload.isMultipartContent(request)) {
-
- FileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload upload = new ServletFileUpload(factory);
- List<?> items = upload.parseRequest(request);
- for (Object o : items) {
- FileItem item = (FileItem) o;
-
- if ("file".equals(item.getFieldName()) && !StringUtils.isBlank(item.getName())) {
- if (item.getSize() > MAX_PLAYLIST_SIZE_MB * 1024L * 1024L) {
- throw new Exception("The playlist file is too large. Max file size is " + MAX_PLAYLIST_SIZE_MB + " MB.");
- }
- String playlistName = FilenameUtils.getBaseName(item.getName());
- String fileName = FilenameUtils.getName(item.getName());
- String format = StringUtils.lowerCase(FilenameUtils.getExtension(item.getName()));
- String username = securityService.getCurrentUsername(request);
- Playlist playlist = playlistService.importPlaylist(username, playlistName, fileName, format, item.getInputStream());
- map.put("playlist", playlist);
- }
- }
- }
- } catch (Exception e) {
- map.put("error", e.getMessage());
- }
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/InternetRadioSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/InternetRadioSettingsController.java
deleted file mode 100644
index 5ee7b799..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/InternetRadioSettingsController.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.InternetRadio;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Date;
-
-/**
- * Controller for the page used to administrate the set of internet radio/tv stations.
- *
- * @author Sindre Mehus
- */
-public class InternetRadioSettingsController extends ParameterizableViewController {
-
- private SettingsService settingsService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
-
- if (isFormSubmission(request)) {
- String error = handleParameters(request);
- map.put("error", error);
- if (error == null) {
- map.put("reload", true);
- }
- }
-
- ModelAndView result = super.handleRequestInternal(request, response);
- map.put("internetRadios", settingsService.getAllInternetRadios(true));
-
- result.addObject("model", map);
- return result;
- }
-
- /**
- * Determine if the given request represents a form submission.
- *
- * @param request current HTTP request
- * @return if the request represents a form submission
- */
- private boolean isFormSubmission(HttpServletRequest request) {
- return "POST".equals(request.getMethod());
- }
-
- private String handleParameters(HttpServletRequest request) {
- List<InternetRadio> radios = settingsService.getAllInternetRadios(true);
- for (InternetRadio radio : radios) {
- Integer id = radio.getId();
- String streamUrl = getParameter(request, "streamUrl", id);
- String homepageUrl = getParameter(request, "homepageUrl", id);
- String name = getParameter(request, "name", id);
- boolean enabled = getParameter(request, "enabled", id) != null;
- boolean delete = getParameter(request, "delete", id) != null;
-
- if (delete) {
- settingsService.deleteInternetRadio(id);
- } else {
- if (name == null) {
- return "internetradiosettings.noname";
- }
- if (streamUrl == null) {
- return "internetradiosettings.nourl";
- }
- settingsService.updateInternetRadio(new InternetRadio(id, name, streamUrl, homepageUrl, enabled, new Date()));
- }
- }
-
- String name = StringUtils.trimToNull(request.getParameter("name"));
- String streamUrl = StringUtils.trimToNull(request.getParameter("streamUrl"));
- String homepageUrl = StringUtils.trimToNull(request.getParameter("homepageUrl"));
- boolean enabled = StringUtils.trimToNull(request.getParameter("enabled")) != null;
-
- if (name != null && streamUrl != null) {
- settingsService.createInternetRadio(new InternetRadio(name, streamUrl, homepageUrl, enabled, new Date()));
- }
-
- return null;
- }
-
- private String getParameter(HttpServletRequest request, String name, Integer id) {
- return StringUtils.trimToNull(request.getParameter(name + "[" + id + "]"));
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LeftController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LeftController.java
deleted file mode 100644
index d273f0b9..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LeftController.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import net.sourceforge.subsonic.service.PlaylistService;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.LastModified;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.support.RequestContextUtils;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.InternetRadio;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MediaLibraryStatistics;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.MusicIndex;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.MediaScannerService;
-import net.sourceforge.subsonic.service.MusicIndexService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.util.FileUtil;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Controller for the left index frame.
- *
- * @author Sindre Mehus
- */
-public class LeftController extends ParameterizableViewController implements LastModified {
-
- private static final Logger LOG = Logger.getLogger(LeftController.class);
-
- // Update this time if you want to force a refresh in clients.
- private static final Calendar LAST_COMPATIBILITY_TIME = Calendar.getInstance();
- static {
- LAST_COMPATIBILITY_TIME.set(2012, Calendar.MARCH, 6, 0, 0, 0);
- LAST_COMPATIBILITY_TIME.set(Calendar.MILLISECOND, 0);
- }
-
- private MediaScannerService mediaScannerService;
- private SettingsService settingsService;
- private SecurityService securityService;
- private MediaFileService mediaFileService;
- private MusicIndexService musicIndexService;
- private PlayerService playerService;
- private PlaylistService playlistService;
-
- public long getLastModified(HttpServletRequest request) {
- saveSelectedMusicFolder(request);
-
- if (mediaScannerService.isScanning()) {
- return -1L;
- }
-
- long lastModified = LAST_COMPATIBILITY_TIME.getTimeInMillis();
- String username = securityService.getCurrentUsername(request);
-
- // When was settings last changed?
- lastModified = Math.max(lastModified, settingsService.getSettingsChanged());
-
- // When was music folder(s) on disk last changed?
- List<MusicFolder> allMusicFolders = settingsService.getAllMusicFolders();
- MusicFolder selectedMusicFolder = getSelectedMusicFolder(request);
- if (selectedMusicFolder != null) {
- File file = selectedMusicFolder.getPath();
- lastModified = Math.max(lastModified, FileUtil.lastModified(file));
- } else {
- for (MusicFolder musicFolder : allMusicFolders) {
- File file = musicFolder.getPath();
- lastModified = Math.max(lastModified, FileUtil.lastModified(file));
- }
- }
-
- // When was music folder table last changed?
- for (MusicFolder musicFolder : allMusicFolders) {
- lastModified = Math.max(lastModified, musicFolder.getChanged().getTime());
- }
-
- // When was internet radio table last changed?
- for (InternetRadio internetRadio : settingsService.getAllInternetRadios()) {
- lastModified = Math.max(lastModified, internetRadio.getChanged().getTime());
- }
-
- // When was user settings last changed?
- UserSettings userSettings = settingsService.getUserSettings(username);
- lastModified = Math.max(lastModified, userSettings.getChanged().getTime());
-
- return lastModified;
- }
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- saveSelectedMusicFolder(request);
- Map<String, Object> map = new HashMap<String, Object>();
-
- MediaLibraryStatistics statistics = mediaScannerService.getStatistics();
- Locale locale = RequestContextUtils.getLocale(request);
-
- String username = securityService.getCurrentUsername(request);
- List<MusicFolder> allMusicFolders = settingsService.getAllMusicFolders();
- MusicFolder selectedMusicFolder = getSelectedMusicFolder(request);
- List<MusicFolder> musicFoldersToUse = selectedMusicFolder == null ? allMusicFolders : Arrays.asList(selectedMusicFolder);
- String[] shortcuts = settingsService.getShortcutsAsArray();
- UserSettings userSettings = settingsService.getUserSettings(username);
-
- MusicFolderContent musicFolderContent = getMusicFolderContent(musicFoldersToUse);
-
- map.put("player", playerService.getPlayer(request, response));
- map.put("scanning", mediaScannerService.isScanning());
- map.put("musicFolders", allMusicFolders);
- map.put("selectedMusicFolder", selectedMusicFolder);
- map.put("radios", settingsService.getAllInternetRadios());
- map.put("shortcuts", getShortcuts(musicFoldersToUse, shortcuts));
- map.put("captionCutoff", userSettings.getMainVisibility().getCaptionCutoff());
- map.put("partyMode", userSettings.isPartyModeEnabled());
- map.put("organizeByFolderStructure", settingsService.isOrganizeByFolderStructure());
-
- if (statistics != null) {
- map.put("statistics", statistics);
- long bytes = statistics.getTotalLengthInBytes();
- long hours = statistics.getTotalDurationInSeconds() / 3600L;
- map.put("hours", hours);
- map.put("bytes", StringUtil.formatBytes(bytes, locale));
- }
-
- map.put("indexedArtists", musicFolderContent.getIndexedArtists());
- map.put("singleSongs", musicFolderContent.getSingleSongs());
- map.put("indexes", musicFolderContent.getIndexedArtists().keySet());
- map.put("user", securityService.getCurrentUser(request));
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- private void saveSelectedMusicFolder(HttpServletRequest request) {
- if (request.getParameter("musicFolderId") == null) {
- return;
- }
- int musicFolderId = Integer.parseInt(request.getParameter("musicFolderId"));
-
- // Note: UserSettings.setChanged() is intentionally not called. This would break browser caching
- // of the left frame.
- UserSettings settings = settingsService.getUserSettings(securityService.getCurrentUsername(request));
- settings.setSelectedMusicFolderId(musicFolderId);
- settingsService.updateUserSettings(settings);
- }
-
- /**
- * Returns the selected music folder, or <code>null</code> if all music folders should be displayed.
- */
- private MusicFolder getSelectedMusicFolder(HttpServletRequest request) {
- UserSettings settings = settingsService.getUserSettings(securityService.getCurrentUsername(request));
- int musicFolderId = settings.getSelectedMusicFolderId();
-
- return settingsService.getMusicFolderById(musicFolderId);
- }
-
- protected List<MediaFile> getSingleSongs(List<MusicFolder> folders) throws IOException {
- List<MediaFile> result = new ArrayList<MediaFile>();
- for (MusicFolder folder : folders) {
- MediaFile parent = mediaFileService.getMediaFile(folder.getPath(), true);
- result.addAll(mediaFileService.getChildrenOf(parent, true, false, true, true));
- }
- return result;
- }
-
- public List<MediaFile> getShortcuts(List<MusicFolder> musicFoldersToUse, String[] shortcuts) {
- List<MediaFile> result = new ArrayList<MediaFile>();
-
- for (String shortcut : shortcuts) {
- for (MusicFolder musicFolder : musicFoldersToUse) {
- File file = new File(musicFolder.getPath(), shortcut);
- if (FileUtil.exists(file)) {
- result.add(mediaFileService.getMediaFile(file, true));
- }
- }
- }
-
- return result;
- }
-
- public MusicFolderContent getMusicFolderContent(List<MusicFolder> musicFoldersToUse) throws Exception {
- SortedMap<MusicIndex, SortedSet<MusicIndex.Artist>> indexedArtists = musicIndexService.getIndexedArtists(musicFoldersToUse);
- List<MediaFile> singleSongs = getSingleSongs(musicFoldersToUse);
- return new MusicFolderContent(indexedArtists, singleSongs);
- }
-
- public void setMediaScannerService(MediaScannerService mediaScannerService) {
- this.mediaScannerService = mediaScannerService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setMusicIndexService(MusicIndexService musicIndexService) {
- this.musicIndexService = musicIndexService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public static class MusicFolderContent {
-
- private final SortedMap<MusicIndex, SortedSet<MusicIndex.Artist>> indexedArtists;
- private final List<MediaFile> singleSongs;
-
- public MusicFolderContent(SortedMap<MusicIndex, SortedSet<MusicIndex.Artist>> indexedArtists, List<MediaFile> singleSongs) {
- this.indexedArtists = indexedArtists;
- this.singleSongs = singleSongs;
- }
-
- public SortedMap<MusicIndex, SortedSet<MusicIndex.Artist>> getIndexedArtists() {
- return indexedArtists;
- }
-
- public List<MediaFile> getSingleSongs() {
- return singleSongs;
- }
-
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LyricsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LyricsController.java
deleted file mode 100644
index d47ad233..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/LyricsController.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.ModelAndView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Controller for the lyrics popup.
- *
- * @author Sindre Mehus
- */
-public class LyricsController extends ParameterizableViewController {
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- map.put("artist", request.getParameter("artist"));
- map.put("song", request.getParameter("song"));
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/M3UController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/M3UController.java
deleted file mode 100644
index bbd7a478..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/M3UController.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.TranscodingService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.List;
-
-/**
- * Controller which produces the M3U playlist.
- *
- * @author Sindre Mehus
- */
-public class M3UController implements Controller {
-
- private PlayerService playerService;
- private SettingsService settingsService;
- private TranscodingService transcodingService;
-
- private static final Logger LOG = Logger.getLogger(M3UController.class);
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- response.setContentType("audio/x-mpegurl");
- response.setCharacterEncoding(StringUtil.ENCODING_UTF8);
-
- Player player = playerService.getPlayer(request, response);
-
- String url = request.getRequestURL().toString();
- url = url.replaceFirst("play.m3u.*", "stream?");
-
- // Rewrite URLs in case we're behind a proxy.
- if (settingsService.isRewriteUrlEnabled()) {
- String referer = request.getHeader("referer");
- url = StringUtil.rewriteUrl(url, referer);
- }
-
- // Change protocol and port, if specified. (To make it work with players that don't support SSL.)
- int streamPort = settingsService.getStreamPort();
- if (streamPort != 0) {
- url = StringUtil.toHttpUrl(url, streamPort);
- LOG.info("Using non-SSL port " + streamPort + " in m3u playlist.");
- }
-
- if (player.isExternalWithPlaylist()) {
- createClientSidePlaylist(response.getWriter(), player, url);
- } else {
- createServerSidePlaylist(response.getWriter(), player, url);
- }
- return null;
- }
-
- private void createClientSidePlaylist(PrintWriter out, Player player, String url) throws Exception {
- out.println("#EXTM3U");
- List<MediaFile> result;
- synchronized (player.getPlayQueue()) {
- result = player.getPlayQueue().getFiles();
- }
- for (MediaFile mediaFile : result) {
- Integer duration = mediaFile.getDurationSeconds();
- if (duration == null) {
- duration = -1;
- }
- out.println("#EXTINF:" + duration + "," + mediaFile.getArtist() + " - " + mediaFile.getTitle());
- out.println(url + "player=" + player.getId() + "&id=" +mediaFile.getId() + "&suffix=." + transcodingService.getSuffix(player, mediaFile, null));
- }
- }
-
- private void createServerSidePlaylist(PrintWriter out, Player player, String url) throws IOException {
-
- url += "player=" + player.getId();
-
- // Get suffix of current file, e.g., ".mp3".
- String suffix = getSuffix(player);
- if (suffix != null) {
- url += "&suffix=." + suffix;
- }
-
- out.println("#EXTM3U");
- out.println("#EXTINF:-1,Subsonic");
- out.println(url);
- }
-
- private String getSuffix(Player player) {
- PlayQueue playQueue = player.getPlayQueue();
- return playQueue.isEmpty() ? null : transcodingService.getSuffix(player, playQueue.getFile(0), null);
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MainController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MainController.java
deleted file mode 100644
index 1d9e0a61..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MainController.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.CoverArtScheme;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.AdService;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.RatingService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Controller for the main page.
- *
- * @author Sindre Mehus
- */
-public class MainController extends ParameterizableViewController {
-
- private SecurityService securityService;
- private PlayerService playerService;
- private SettingsService settingsService;
- private RatingService ratingService;
- private MediaFileService mediaFileService;
- private AdService adService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- Player player = playerService.getPlayer(request, response);
- List<MediaFile> mediaFiles = getMediaFiles(request);
-
- if (mediaFiles.isEmpty()) {
- return new ModelAndView(new RedirectView("notFound.view"));
- }
-
- MediaFile dir = mediaFiles.get(0);
- if (dir.isFile()) {
- dir = mediaFileService.getParentOf(dir);
- }
-
- // Redirect if root directory.
- if (mediaFileService.isRoot(dir)) {
- return new ModelAndView(new RedirectView("home.view?"));
- }
-
- List<MediaFile> children = mediaFiles.size() == 1 ? mediaFileService.getChildrenOf(dir, true, true, true) : getMultiFolderChildren(mediaFiles);
- String username = securityService.getCurrentUsername(request);
- UserSettings userSettings = settingsService.getUserSettings(username);
-
- mediaFileService.populateStarredDate(dir, username);
- mediaFileService.populateStarredDate(children, username);
-
- map.put("dir", dir);
- map.put("ancestors", getAncestors(dir));
- map.put("children", children);
- map.put("artist", guessArtist(children));
- map.put("album", guessAlbum(children));
- map.put("player", player);
- map.put("user", securityService.getCurrentUser(request));
- map.put("multipleArtists", isMultipleArtists(children));
- map.put("visibility", userSettings.getMainVisibility());
- map.put("showAlbumYear", settingsService.isSortAlbumsByYear());
- map.put("updateNowPlaying", request.getParameter("updateNowPlaying") != null);
- map.put("partyMode", userSettings.isPartyModeEnabled());
- map.put("brand", settingsService.getBrand());
- if (!settingsService.isLicenseValid()) {
- map.put("ad", adService.getAd());
- }
-
- try {
- MediaFile parent = mediaFileService.getParentOf(dir);
- map.put("parent", parent);
- map.put("navigateUpAllowed", !mediaFileService.isRoot(parent));
- } catch (SecurityException x) {
- // Happens if Podcast directory is outside music folder.
- }
-
- Integer userRating = ratingService.getRatingForUser(username, dir);
- Double averageRating = ratingService.getAverageRating(dir);
-
- if (userRating == null) {
- userRating = 0;
- }
-
- if (averageRating == null) {
- averageRating = 0.0D;
- }
-
- map.put("userRating", 10 * userRating);
- map.put("averageRating", Math.round(10.0D * averageRating));
- map.put("starred", mediaFileService.getMediaFileStarredDate(dir.getId(), username) != null);
-
- CoverArtScheme scheme = player.getCoverArtScheme();
- if (scheme != CoverArtScheme.OFF) {
- List<MediaFile> coverArts = getCoverArts(dir, children);
- int size = coverArts.size() > 1 ? scheme.getSize() : scheme.getSize() * 2;
- map.put("coverArts", coverArts);
- map.put("coverArtSize", size);
- if (coverArts.isEmpty() && dir.isAlbum()) {
- map.put("showGenericCoverArt", true);
- }
- }
-
- setPreviousAndNextAlbums(dir, map);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- private List<MediaFile> getMediaFiles(HttpServletRequest request) {
- List<MediaFile> mediaFiles = new ArrayList<MediaFile>();
- for (String path : ServletRequestUtils.getStringParameters(request, "path")) {
- MediaFile mediaFile = mediaFileService.getMediaFile(path);
- if (mediaFile != null) {
- mediaFiles.add(mediaFile);
- }
- }
- for (int id : ServletRequestUtils.getIntParameters(request, "id")) {
- MediaFile mediaFile = mediaFileService.getMediaFile(id);
- if (mediaFile != null) {
- mediaFiles.add(mediaFile);
- }
- }
- return mediaFiles;
- }
-
- private String guessArtist(List<MediaFile> children) {
- for (MediaFile child : children) {
- if (child.isFile() && child.getArtist() != null) {
- return child.getArtist();
- }
- }
- return null;
- }
-
- private String guessAlbum(List<MediaFile> children) {
- for (MediaFile child : children) {
- if (child.isFile() && child.getArtist() != null) {
- return child.getAlbumName();
- }
- }
- return null;
- }
-
- private List<MediaFile> getCoverArts(MediaFile dir, List<MediaFile> children) throws IOException {
- int limit = settingsService.getCoverArtLimit();
- if (limit == 0) {
- limit = Integer.MAX_VALUE;
- }
-
- List<MediaFile> coverArts = new ArrayList<MediaFile>();
- if (dir.isAlbum() && dir.getCoverArtPath() != null) {
- coverArts.add(dir);
- } else {
- for (MediaFile child : children) {
- if (child.isAlbum()) {
- if (child.getCoverArtPath() != null) {
- coverArts.add(child);
- }
- if (coverArts.size() > limit) {
- break;
- }
- }
- }
- }
- return coverArts;
- }
-
- private List<MediaFile> getMultiFolderChildren(List<MediaFile> mediaFiles) throws IOException {
- List<MediaFile> result = new ArrayList<MediaFile>();
- for (MediaFile mediaFile : mediaFiles) {
- if (mediaFile.isFile()) {
- mediaFile = mediaFileService.getParentOf(mediaFile);
- }
- result.addAll(mediaFileService.getChildrenOf(mediaFile, true, true, true));
- }
- return result;
- }
-
- private List<MediaFile> getAncestors(MediaFile dir) throws IOException {
- LinkedList<MediaFile> result = new LinkedList<MediaFile>();
-
- try {
- MediaFile parent = mediaFileService.getParentOf(dir);
- while (parent != null && !mediaFileService.isRoot(parent)) {
- result.addFirst(parent);
- parent = mediaFileService.getParentOf(parent);
- }
- } catch (SecurityException x) {
- // Happens if Podcast directory is outside music folder.
- }
- return result;
- }
-
- private void setPreviousAndNextAlbums(MediaFile dir, Map<String, Object> map) throws IOException {
- MediaFile parent = mediaFileService.getParentOf(dir);
-
- if (dir.isAlbum() && !mediaFileService.isRoot(parent)) {
- List<MediaFile> sieblings = mediaFileService.getChildrenOf(parent, false, true, true);
-
- int index = sieblings.indexOf(dir);
- if (index > 0) {
- map.put("previousAlbum", sieblings.get(index - 1));
- }
- if (index < sieblings.size() - 1) {
- map.put("nextAlbum", sieblings.get(index + 1));
- }
- }
- }
-
- private boolean isMultipleArtists(List<MediaFile> children) {
- // Collect unique artist names.
- Set<String> artists = new HashSet<String>();
- for (MediaFile child : children) {
- if (child.getArtist() != null) {
- artists.add(child.getArtist().toLowerCase());
- }
- }
-
- // If zero or one artist, it is definitely not multiple artists.
- if (artists.size() < 2) {
- return false;
- }
-
- // Fuzzily compare artist names, allowing for some differences in spelling, whitespace etc.
- List<String> artistList = new ArrayList<String>(artists);
- for (String artist : artistList) {
- if (StringUtils.getLevenshteinDistance(artist, artistList.get(0)) > 3) {
- return true;
- }
- }
- return false;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setRatingService(RatingService ratingService) {
- this.ratingService = ratingService;
- }
-
- public void setAdService(AdService adService) {
- this.adService = adService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MoreController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MoreController.java
deleted file mode 100644
index f29cb346..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MoreController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Calendar;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-
-/**
- * Controller for the "more" page.
- *
- * @author Sindre Mehus
- */
-public class MoreController extends ParameterizableViewController {
-
- private SettingsService settingsService;
- private SecurityService securityService;
- private PlayerService playerService;
- private MediaFileService mediaFileService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- String uploadDirectory = null;
- List<MusicFolder> musicFolders = settingsService.getAllMusicFolders();
- if (musicFolders.size() > 0) {
- uploadDirectory = new File(musicFolders.get(0).getPath(), "Incoming").getPath();
- }
-
- Player player = playerService.getPlayer(request, response);
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- map.put("user", securityService.getCurrentUser(request));
- map.put("uploadDirectory", uploadDirectory);
- map.put("genres", mediaFileService.getGenres());
- map.put("currentYear", Calendar.getInstance().get(Calendar.YEAR));
- map.put("musicFolders", settingsService.getAllMusicFolders());
- map.put("clientSidePlaylist", player.isExternalWithPlaylist() || player.isWeb());
- map.put("brand", settingsService.getBrand());
- return result;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MultiController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MultiController.java
deleted file mode 100644
index 1d781565..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MultiController.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.RandomStringUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.params.HttpConnectionParams;
-import org.springframework.web.bind.ServletRequestBindingException;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Multi-controller used for simple pages.
- *
- * @author Sindre Mehus
- */
-public class MultiController extends MultiActionController {
-
- private static final Logger LOG = Logger.getLogger(MultiController.class);
-
- private SecurityService securityService;
- private SettingsService settingsService;
- private PlaylistService playlistService;
-
- public ModelAndView login(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- // Auto-login if "user" and "password" parameters are given.
- String username = request.getParameter("user");
- String password = request.getParameter("password");
- if (username != null && password != null) {
- username = StringUtil.urlEncode(username);
- password = StringUtil.urlEncode(password);
- return new ModelAndView(new RedirectView("j_acegi_security_check?j_username=" + username +
- "&j_password=" + password + "&_acegi_security_remember_me=checked"));
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("logout", request.getParameter("logout") != null);
- map.put("error", request.getParameter("error") != null);
- map.put("brand", settingsService.getBrand());
- map.put("loginMessage", settingsService.getLoginMessage());
-
- User admin = securityService.getUserByName(User.USERNAME_ADMIN);
- if (User.USERNAME_ADMIN.equals(admin.getPassword())) {
- map.put("insecure", true);
- }
-
- return new ModelAndView("login", "model", map);
- }
-
- public ModelAndView recover(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
- String usernameOrEmail = StringUtils.trimToNull(request.getParameter("usernameOrEmail"));
-
- if (usernameOrEmail != null) {
- User user = getUserByUsernameOrEmail(usernameOrEmail);
- if (user == null) {
- map.put("error", "recover.error.usernotfound");
- } else if (user.getEmail() == null) {
- map.put("error", "recover.error.noemail");
- } else {
- String password = RandomStringUtils.randomAlphanumeric(8);
- if (emailPassword(password, user.getUsername(), user.getEmail())) {
- map.put("sentTo", user.getEmail());
- user.setLdapAuthenticated(false);
- user.setPassword(password);
- securityService.updateUser(user);
- } else {
- map.put("error", "recover.error.sendfailed");
- }
- }
- }
-
- return new ModelAndView("recover", "model", map);
- }
-
- private boolean emailPassword(String password, String username, String email) {
- HttpClient client = new DefaultHttpClient();
- try {
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
- HttpConnectionParams.setSoTimeout(client.getParams(), 10000);
- HttpPost method = new HttpPost("http://subsonic.org/backend/sendMail.view");
-
- List<NameValuePair> params = new ArrayList<NameValuePair>();
- params.add(new BasicNameValuePair("from", "noreply@subsonic.org"));
- params.add(new BasicNameValuePair("to", email));
- params.add(new BasicNameValuePair("subject", "Subsonic Password"));
- params.add(new BasicNameValuePair("text",
- "Hi there!\n\n" +
- "You have requested to reset your Subsonic password. Please find your new login details below.\n\n" +
- "Username: " + username + "\n" +
- "Password: " + password + "\n\n" +
- "--\n" +
- "The Subsonic Team\n" +
- "subsonic.org"));
- method.setEntity(new UrlEncodedFormEntity(params, StringUtil.ENCODING_UTF8));
- client.execute(method);
- return true;
- } catch (Exception x) {
- LOG.warn("Failed to send email.", x);
- return false;
- } finally {
- client.getConnectionManager().shutdown();
- }
- }
-
- private User getUserByUsernameOrEmail(String usernameOrEmail) {
- if (usernameOrEmail != null) {
- User user = securityService.getUserByName(usernameOrEmail);
- if (user != null) {
- return user;
- }
- return securityService.getUserByEmail(usernameOrEmail);
- }
- return null;
- }
-
- public ModelAndView accessDenied(HttpServletRequest request, HttpServletResponse response) {
- return new ModelAndView("accessDenied");
- }
-
- public ModelAndView notFound(HttpServletRequest request, HttpServletResponse response) {
- return new ModelAndView("notFound");
- }
-
- public ModelAndView gettingStarted(HttpServletRequest request, HttpServletResponse response) {
- updatePortAndContextPath(request);
-
- if (request.getParameter("hide") != null) {
- settingsService.setGettingStartedEnabled(false);
- settingsService.save();
- return new ModelAndView(new RedirectView("home.view"));
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("runningAsRoot", "root".equals(System.getProperty("user.name")));
- return new ModelAndView("gettingStarted", "model", map);
- }
-
- public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
- updatePortAndContextPath(request);
- UserSettings userSettings = settingsService.getUserSettings(securityService.getCurrentUsername(request));
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("showRight", userSettings.isShowNowPlayingEnabled() || userSettings.isShowChatEnabled());
- map.put("brand", settingsService.getBrand());
- return new ModelAndView("index", "model", map);
- }
-
- public ModelAndView exportPlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- Playlist playlist = playlistService.getPlaylist(id);
- if (!playlistService.isReadAllowed(playlist, securityService.getCurrentUsername(request))) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return null;
-
- }
- response.setContentType("application/x-download");
- response.setHeader("Content-Disposition", "attachment; filename=\"" + StringUtil.fileSystemSafe(playlist.getName()) + ".m3u8\"");
-
- playlistService.exportPlaylist(id, response.getOutputStream());
- return null;
- }
-
- private void updatePortAndContextPath(HttpServletRequest request) {
-
- int port = Integer.parseInt(System.getProperty("subsonic.port", String.valueOf(request.getLocalPort())));
- int httpsPort = Integer.parseInt(System.getProperty("subsonic.httpsPort", "0"));
-
- String contextPath = request.getContextPath().replace("/", "");
-
- if (settingsService.getPort() != port) {
- settingsService.setPort(port);
- settingsService.save();
- }
- if (settingsService.getHttpsPort() != httpsPort) {
- settingsService.setHttpsPort(httpsPort);
- settingsService.save();
- }
- if (!ObjectUtils.equals(settingsService.getUrlRedirectContextPath(), contextPath)) {
- settingsService.setUrlRedirectContextPath(contextPath);
- settingsService.save();
- }
- }
-
- public ModelAndView test(HttpServletRequest request, HttpServletResponse response) {
- return new ModelAndView("test");
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MusicFolderSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MusicFolderSettingsController.java
deleted file mode 100644
index 8c002342..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/MusicFolderSettingsController.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.command.MusicFolderSettingsCommand;
-import net.sourceforge.subsonic.dao.AlbumDao;
-import net.sourceforge.subsonic.dao.ArtistDao;
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.service.MediaScannerService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Controller for the page used to administrate the set of music folders.
- *
- * @author Sindre Mehus
- */
-public class MusicFolderSettingsController extends SimpleFormController {
-
- private SettingsService settingsService;
- private MediaScannerService mediaScannerService;
- private ArtistDao artistDao;
- private AlbumDao albumDao;
- private MediaFileDao mediaFolderDao;
-
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- MusicFolderSettingsCommand command = new MusicFolderSettingsCommand();
-
- if (request.getParameter("scanNow") != null) {
- mediaScannerService.scanLibrary();
- }
- if (request.getParameter("expunge") != null) {
- expunge();
- }
-
- command.setInterval(String.valueOf(settingsService.getIndexCreationInterval()));
- command.setHour(String.valueOf(settingsService.getIndexCreationHour()));
- command.setFastCache(settingsService.isFastCacheEnabled());
- command.setOrganizeByFolderStructure(settingsService.isOrganizeByFolderStructure());
- command.setScanning(mediaScannerService.isScanning());
- command.setMusicFolders(wrap(settingsService.getAllMusicFolders(true, true)));
- command.setNewMusicFolder(new MusicFolderSettingsCommand.MusicFolderInfo());
- command.setReload(request.getParameter("reload") != null || request.getParameter("scanNow") != null);
- return command;
- }
-
- private void expunge() {
- artistDao.expunge();
- albumDao.expunge();
- mediaFolderDao.expunge();
- }
-
- private List<MusicFolderSettingsCommand.MusicFolderInfo> wrap(List<MusicFolder> musicFolders) {
- ArrayList<MusicFolderSettingsCommand.MusicFolderInfo> result = new ArrayList<MusicFolderSettingsCommand.MusicFolderInfo>();
- for (MusicFolder musicFolder : musicFolders) {
- result.add(new MusicFolderSettingsCommand.MusicFolderInfo(musicFolder));
- }
- return result;
- }
-
- @Override
- protected ModelAndView onSubmit(Object comm) throws Exception {
- MusicFolderSettingsCommand command = (MusicFolderSettingsCommand) comm;
-
- for (MusicFolderSettingsCommand.MusicFolderInfo musicFolderInfo : command.getMusicFolders()) {
- if (musicFolderInfo.isDelete()) {
- settingsService.deleteMusicFolder(musicFolderInfo.getId());
- } else {
- settingsService.updateMusicFolder(musicFolderInfo.toMusicFolder());
- }
- }
-
- MusicFolder newMusicFolder = command.getNewMusicFolder().toMusicFolder();
- if (newMusicFolder != null) {
- settingsService.createMusicFolder(newMusicFolder);
- }
-
- settingsService.setIndexCreationInterval(Integer.parseInt(command.getInterval()));
- settingsService.setIndexCreationHour(Integer.parseInt(command.getHour()));
- settingsService.setFastCacheEnabled(command.isFastCache());
- settingsService.setOrganizeByFolderStructure(command.isOrganizeByFolderStructure());
- settingsService.save();
-
- mediaScannerService.schedule();
- return new ModelAndView(new RedirectView(getSuccessView() + ".view?reload"));
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaScannerService(MediaScannerService mediaScannerService) {
- this.mediaScannerService = mediaScannerService;
- }
-
- public void setArtistDao(ArtistDao artistDao) {
- this.artistDao = artistDao;
- }
-
- public void setAlbumDao(AlbumDao albumDao) {
- this.albumDao = albumDao;
- }
-
- public void setMediaFolderDao(MediaFileDao mediaFolderDao) {
- this.mediaFolderDao = mediaFolderDao;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NetworkSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NetworkSettingsController.java
deleted file mode 100644
index 3807eb71..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NetworkSettingsController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.Date;
-import java.util.Random;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-
-import net.sourceforge.subsonic.command.NetworkSettingsCommand;
-import net.sourceforge.subsonic.service.NetworkService;
-import net.sourceforge.subsonic.service.SettingsService;
-
-/**
- * Controller for the page used to change the network settings.
- *
- * @author Sindre Mehus
- */
-public class NetworkSettingsController extends SimpleFormController {
-
- private static final long TRIAL_DAYS = 30L;
-
- private SettingsService settingsService;
- private NetworkService networkService;
-
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- NetworkSettingsCommand command = new NetworkSettingsCommand();
- command.setPortForwardingEnabled(settingsService.isPortForwardingEnabled());
- command.setUrlRedirectionEnabled(settingsService.isUrlRedirectionEnabled());
- command.setUrlRedirectFrom(settingsService.getUrlRedirectFrom());
- command.setPort(settingsService.getPort());
-
- Date trialExpires = settingsService.getUrlRedirectTrialExpires();
- command.setTrialExpires(trialExpires);
- command.setTrialExpired(trialExpires != null && trialExpires.before(new Date()));
- command.setTrial(trialExpires != null && !settingsService.isLicenseValid());
-
- return command;
- }
-
- protected void doSubmitAction(Object cmd) throws Exception {
- NetworkSettingsCommand command = (NetworkSettingsCommand) cmd;
-
- settingsService.setPortForwardingEnabled(command.isPortForwardingEnabled());
- settingsService.setUrlRedirectionEnabled(command.isUrlRedirectionEnabled());
- settingsService.setUrlRedirectFrom(StringUtils.lowerCase(command.getUrlRedirectFrom()));
-
- if (!settingsService.isLicenseValid() && settingsService.getUrlRedirectTrialExpires() == null) {
- Date expiryDate = new Date(System.currentTimeMillis() + TRIAL_DAYS * 24L * 3600L * 1000L);
- settingsService.setUrlRedirectTrialExpires(expiryDate);
- }
-
- if (settingsService.getServerId() == null) {
- Random rand = new Random(System.currentTimeMillis());
- settingsService.setServerId(String.valueOf(Math.abs(rand.nextLong())));
- }
-
- settingsService.save();
- networkService.initPortForwarding();
- networkService.initUrlRedirection(true);
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setNetworkService(NetworkService networkService) {
- this.networkService = networkService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NowPlayingController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NowPlayingController.java
deleted file mode 100644
index 79fe7c77..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/NowPlayingController.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.filter.ParameterDecodingFilter;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.StatusService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.AbstractController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-
-/**
- * Controller for showing what's currently playing.
- *
- * @author Sindre Mehus
- */
-public class NowPlayingController extends AbstractController {
-
- private PlayerService playerService;
- private StatusService statusService;
- private MediaFileService mediaFileService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Player player = playerService.getPlayer(request, response);
- List<TransferStatus> statuses = statusService.getStreamStatusesForPlayer(player);
-
- MediaFile current = statuses.isEmpty() ? null : mediaFileService.getMediaFile(statuses.get(0).getFile());
- MediaFile dir = current == null ? null : mediaFileService.getParentOf(current);
-
- String url;
- if (dir != null && !mediaFileService.isRoot(dir)) {
- url = "main.view?path" + ParameterDecodingFilter.PARAM_SUFFIX + "=" +
- StringUtil.utf8HexEncode(dir.getPath()) + "&updateNowPlaying=true";
- } else {
- url = "home.view";
- }
-
- return new ModelAndView(new RedirectView(url));
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PasswordSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PasswordSettingsController.java
deleted file mode 100644
index 8dd8d875..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PasswordSettingsController.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import org.springframework.web.servlet.mvc.*;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.command.*;
-import net.sourceforge.subsonic.domain.*;
-
-import javax.servlet.http.*;
-
-/**
- * Controller for the page used to change password.
- *
- * @author Sindre Mehus
- */
-public class PasswordSettingsController extends SimpleFormController {
-
- private SecurityService securityService;
-
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- PasswordSettingsCommand command = new PasswordSettingsCommand();
- User user = securityService.getCurrentUser(request);
- command.setUsername(user.getUsername());
- command.setLdapAuthenticated(user.isLdapAuthenticated());
- return command;
- }
-
- protected void doSubmitAction(Object comm) throws Exception {
- PasswordSettingsCommand command = (PasswordSettingsCommand) comm;
- User user = securityService.getUserByName(command.getUsername());
- user.setPassword(command.getPassword());
- securityService.updateUser(user);
-
- command.setPassword(null);
- command.setConfirmPassword(null);
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PersonalSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PersonalSettingsController.java
deleted file mode 100644
index 3bc3f7a5..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PersonalSettingsController.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import org.springframework.web.servlet.mvc.*;
-import org.apache.commons.lang.StringUtils;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.command.*;
-import net.sourceforge.subsonic.domain.*;
-
-import javax.servlet.http.*;
-import java.util.*;
-
-/**
- * Controller for the page used to administrate per-user settings.
- *
- * @author Sindre Mehus
- */
-public class PersonalSettingsController extends SimpleFormController {
-
- private SettingsService settingsService;
- private SecurityService securityService;
-
- @Override
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- PersonalSettingsCommand command = new PersonalSettingsCommand();
-
- User user = securityService.getCurrentUser(request);
- UserSettings userSettings = settingsService.getUserSettings(user.getUsername());
-
- command.setUser(user);
- command.setLocaleIndex("-1");
- command.setThemeIndex("-1");
- command.setAvatars(settingsService.getAllSystemAvatars());
- command.setCustomAvatar(settingsService.getCustomAvatar(user.getUsername()));
- command.setAvatarId(getAvatarId(userSettings));
- command.setPartyModeEnabled(userSettings.isPartyModeEnabled());
- command.setShowNowPlayingEnabled(userSettings.isShowNowPlayingEnabled());
- command.setShowChatEnabled(userSettings.isShowChatEnabled());
- command.setNowPlayingAllowed(userSettings.isNowPlayingAllowed());
- command.setMainVisibility(userSettings.getMainVisibility());
- command.setPlaylistVisibility(userSettings.getPlaylistVisibility());
- command.setFinalVersionNotificationEnabled(userSettings.isFinalVersionNotificationEnabled());
- command.setBetaVersionNotificationEnabled(userSettings.isBetaVersionNotificationEnabled());
- command.setLastFmEnabled(userSettings.isLastFmEnabled());
- command.setLastFmUsername(userSettings.getLastFmUsername());
- command.setLastFmPassword(userSettings.getLastFmPassword());
-
- Locale currentLocale = userSettings.getLocale();
- Locale[] locales = settingsService.getAvailableLocales();
- String[] localeStrings = new String[locales.length];
- for (int i = 0; i < locales.length; i++) {
- localeStrings[i] = locales[i].getDisplayName(locales[i]);
- if (locales[i].equals(currentLocale)) {
- command.setLocaleIndex(String.valueOf(i));
- }
- }
- command.setLocales(localeStrings);
-
- String currentThemeId = userSettings.getThemeId();
- Theme[] themes = settingsService.getAvailableThemes();
- command.setThemes(themes);
- for (int i = 0; i < themes.length; i++) {
- if (themes[i].getId().equals(currentThemeId)) {
- command.setThemeIndex(String.valueOf(i));
- break;
- }
- }
-
- return command;
- }
-
- @Override
- protected void doSubmitAction(Object comm) throws Exception {
- PersonalSettingsCommand command = (PersonalSettingsCommand) comm;
-
- int localeIndex = Integer.parseInt(command.getLocaleIndex());
- Locale locale = null;
- if (localeIndex != -1) {
- locale = settingsService.getAvailableLocales()[localeIndex];
- }
-
- int themeIndex = Integer.parseInt(command.getThemeIndex());
- String themeId = null;
- if (themeIndex != -1) {
- themeId = settingsService.getAvailableThemes()[themeIndex].getId();
- }
-
- String username = command.getUser().getUsername();
- UserSettings settings = settingsService.getUserSettings(username);
-
- settings.setLocale(locale);
- settings.setThemeId(themeId);
- settings.setPartyModeEnabled(command.isPartyModeEnabled());
- settings.setShowNowPlayingEnabled(command.isShowNowPlayingEnabled());
- settings.setShowChatEnabled(command.isShowChatEnabled());
- settings.setNowPlayingAllowed(command.isNowPlayingAllowed());
- settings.setMainVisibility(command.getMainVisibility());
- settings.setPlaylistVisibility(command.getPlaylistVisibility());
- settings.setFinalVersionNotificationEnabled(command.isFinalVersionNotificationEnabled());
- settings.setBetaVersionNotificationEnabled(command.isBetaVersionNotificationEnabled());
- settings.setLastFmEnabled(command.isLastFmEnabled());
- settings.setLastFmUsername(command.getLastFmUsername());
- settings.setSystemAvatarId(getSystemAvatarId(command));
- settings.setAvatarScheme(getAvatarScheme(command));
-
- if (StringUtils.isNotBlank(command.getLastFmPassword())) {
- settings.setLastFmPassword(command.getLastFmPassword());
- }
-
- settings.setChanged(new Date());
- settingsService.updateUserSettings(settings);
-
- command.setReloadNeeded(true);
- }
-
- private int getAvatarId(UserSettings userSettings) {
- AvatarScheme avatarScheme = userSettings.getAvatarScheme();
- return avatarScheme == AvatarScheme.SYSTEM ? userSettings.getSystemAvatarId() : avatarScheme.getCode();
- }
-
- private AvatarScheme getAvatarScheme(PersonalSettingsCommand command) {
- if (command.getAvatarId() == AvatarScheme.NONE.getCode()) {
- return AvatarScheme.NONE;
- }
- if (command.getAvatarId() == AvatarScheme.CUSTOM.getCode()) {
- return AvatarScheme.CUSTOM;
- }
- return AvatarScheme.SYSTEM;
- }
-
- private Integer getSystemAvatarId(PersonalSettingsCommand command) {
- int avatarId = command.getAvatarId();
- if (avatarId == AvatarScheme.NONE.getCode() ||
- avatarId == AvatarScheme.CUSTOM.getCode()) {
- return null;
- }
- return avatarId;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayQueueController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayQueueController.java
deleted file mode 100644
index 0074dda1..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayQueueController.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-
-/**
- * Controller for the playlist frame.
- *
- * @author Sindre Mehus
- */
-public class PlayQueueController extends ParameterizableViewController {
-
- private PlayerService playerService;
- private SecurityService securityService;
- private SettingsService settingsService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- User user = securityService.getCurrentUser(request);
- UserSettings userSettings = settingsService.getUserSettings(user.getUsername());
- Player player = playerService.getPlayer(request, response);
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("user", user);
- map.put("player", player);
- map.put("players", playerService.getPlayersForUserAndClientId(user.getUsername(), null));
- map.put("visibility", userSettings.getPlaylistVisibility());
- map.put("partyMode", userSettings.isPartyModeEnabled());
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayerSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayerSettingsController.java
deleted file mode 100644
index 813d94a5..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlayerSettingsController.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-
-import net.sourceforge.subsonic.command.PlayerSettingsCommand;
-import net.sourceforge.subsonic.domain.CoverArtScheme;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayerTechnology;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-import net.sourceforge.subsonic.domain.Transcoding;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.TranscodingService;
-
-/**
- * Controller for the player settings page.
- *
- * @author Sindre Mehus
- */
-public class PlayerSettingsController extends SimpleFormController {
-
- private PlayerService playerService;
- private SecurityService securityService;
- private TranscodingService transcodingService;
-
- @Override
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
-
- handleRequestParameters(request);
- List<Player> players = getPlayers(request);
-
- User user = securityService.getCurrentUser(request);
- PlayerSettingsCommand command = new PlayerSettingsCommand();
- Player player = null;
- String playerId = request.getParameter("id");
- if (playerId != null) {
- player = playerService.getPlayerById(playerId);
- } else if (!players.isEmpty()) {
- player = players.get(0);
- }
-
- if (player != null) {
- command.setPlayerId(player.getId());
- command.setName(player.getName());
- command.setDescription(player.toString());
- command.setType(player.getType());
- command.setLastSeen(player.getLastSeen());
- command.setDynamicIp(player.isDynamicIp());
- command.setAutoControlEnabled(player.isAutoControlEnabled());
- command.setCoverArtSchemeName(player.getCoverArtScheme().name());
- command.setTranscodeSchemeName(player.getTranscodeScheme().name());
- command.setTechnologyName(player.getTechnology().name());
- command.setAllTranscodings(transcodingService.getAllTranscodings());
- List<Transcoding> activeTranscodings = transcodingService.getTranscodingsForPlayer(player);
- int[] activeTranscodingIds = new int[activeTranscodings.size()];
- for (int i = 0; i < activeTranscodings.size(); i++) {
- activeTranscodingIds[i] = activeTranscodings.get(i).getId();
- }
- command.setActiveTranscodingIds(activeTranscodingIds);
- }
-
- command.setTranscodingSupported(transcodingService.isDownsamplingSupported(null));
- command.setTranscodeDirectory(transcodingService.getTranscodeDirectory().getPath());
- command.setCoverArtSchemes(CoverArtScheme.values());
- command.setTranscodeSchemes(TranscodeScheme.values());
- command.setTechnologies(PlayerTechnology.values());
- command.setPlayers(players.toArray(new Player[players.size()]));
- command.setAdmin(user.isAdminRole());
-
- return command;
- }
-
- @Override
- protected void doSubmitAction(Object comm) throws Exception {
- PlayerSettingsCommand command = (PlayerSettingsCommand) comm;
- Player player = playerService.getPlayerById(command.getPlayerId());
-
- player.setAutoControlEnabled(command.isAutoControlEnabled());
- player.setCoverArtScheme(CoverArtScheme.valueOf(command.getCoverArtSchemeName()));
- player.setDynamicIp(command.isDynamicIp());
- player.setName(StringUtils.trimToNull(command.getName()));
- player.setTranscodeScheme(TranscodeScheme.valueOf(command.getTranscodeSchemeName()));
- player.setTechnology(PlayerTechnology.valueOf(command.getTechnologyName()));
-
- playerService.updatePlayer(player);
- transcodingService.setTranscodingsForPlayer(player, command.getActiveTranscodingIds());
-
- command.setReloadNeeded(true);
- }
-
- private List<Player> getPlayers(HttpServletRequest request) {
- User user = securityService.getCurrentUser(request);
- String username = user.getUsername();
- List<Player> players = playerService.getAllPlayers();
- List<Player> authorizedPlayers = new ArrayList<Player>();
-
- for (Player player : players) {
- // Only display authorized players.
- if (user.isAdminRole() || username.equals(player.getUsername())) {
- authorizedPlayers.add(player);
- }
- }
- return authorizedPlayers;
- }
-
- private void handleRequestParameters(HttpServletRequest request) {
- if (request.getParameter("delete") != null) {
- playerService.removePlayerById(request.getParameter("delete"));
- } else if (request.getParameter("clone") != null) {
- playerService.clonePlayer(request.getParameter("clone"));
- }
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlaylistController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlaylistController.java
deleted file mode 100644
index 6b24a3c5..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PlaylistController.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Controller for the main page.
- *
- * @author Sindre Mehus
- */
-public class PlaylistController extends ParameterizableViewController {
-
- private SecurityService securityService;
- private PlaylistService playlistService;
- private SettingsService settingsService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- User user = securityService.getCurrentUser(request);
- String username = user.getUsername();
- UserSettings userSettings = settingsService.getUserSettings(username);
- Playlist playlist = playlistService.getPlaylist(id);
- if (playlist == null) {
- return new ModelAndView(new RedirectView("notFound.view"));
- }
-
- map.put("playlist", playlist);
- map.put("user", user);
- map.put("editAllowed", username.equals(playlist.getUsername()) || securityService.isAdmin(username));
- map.put("partyMode", userSettings.isPartyModeEnabled());
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastController.java
deleted file mode 100644
index dbc6854b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastController.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Controller for the page used to generate the Podcast XML file.
- *
- * @author Sindre Mehus
- */
-public class PodcastController extends ParameterizableViewController {
-
- private static final DateFormat RSS_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
- private PlaylistService playlistService;
- private SettingsService settingsService;
- private SecurityService securityService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- String url = request.getRequestURL().toString();
- String username = securityService.getCurrentUsername(request);
- List<Playlist> playlists = playlistService.getReadablePlaylistsForUser(username);
- List<Podcast> podcasts = new ArrayList<Podcast>();
-
- for (Playlist playlist : playlists) {
-
- List<MediaFile> songs = playlistService.getFilesInPlaylist(playlist.getId());
- if (songs.isEmpty()) {
- continue;
- }
- long length = 0L;
- for (MediaFile song : songs) {
- length += song.getFileSize();
- }
- String publishDate = RSS_DATE_FORMAT.format(playlist.getCreated());
-
- // Resolve content type.
- String suffix = songs.get(0).getFormat();
- String type = StringUtil.getMimeType(suffix);
-
- String enclosureUrl = url.replaceFirst("/podcast.*", "/stream?playlist=" + playlist.getId() + "&amp;suffix=." + suffix);
-
- // Rewrite URLs in case we're behind a proxy.
- if (settingsService.isRewriteUrlEnabled()) {
- String referer = request.getHeader("referer");
- url = StringUtil.rewriteUrl(url, referer);
- }
-
- // Change protocol and port, if specified. (To make it work with players that don't support SSL.)
- int streamPort = settingsService.getStreamPort();
- if (streamPort != 0) {
- enclosureUrl = StringUtil.toHttpUrl(enclosureUrl, streamPort);
- }
-
- podcasts.add(new Podcast(playlist.getName(), publishDate, enclosureUrl, length, type));
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
-
- ModelAndView result = super.handleRequestInternal(request, response);
- map.put("url", url);
- map.put("podcasts", podcasts);
-
- result.addObject("model", map);
- return result;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- /**
- * Contains information about a single Podcast.
- */
- public static class Podcast {
- private String name;
- private String publishDate;
- private String enclosureUrl;
- private long length;
- private String type;
-
- public Podcast(String name, String publishDate, String enclosureUrl, long length, String type) {
- this.name = name;
- this.publishDate = publishDate;
- this.enclosureUrl = enclosureUrl;
- this.length = length;
- this.type = type;
- }
-
- public String getName() {
- return name;
- }
-
- public String getPublishDate() {
- return publishDate;
- }
-
- public String getEnclosureUrl() {
- return enclosureUrl;
- }
-
- public long getLength() {
- return length;
- }
-
- public String getType() {
- return type;
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverAdminController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverAdminController.java
deleted file mode 100644
index c955e884..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverAdminController.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.PodcastEpisode;
-import net.sourceforge.subsonic.domain.PodcastStatus;
-import net.sourceforge.subsonic.service.PodcastService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.AbstractController;
-import org.springframework.web.servlet.view.RedirectView;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.List;
-
-/**
- * Controller for the "Podcast receiver" page.
- *
- * @author Sindre Mehus
- */
-public class PodcastReceiverAdminController extends AbstractController {
-
- private PodcastService podcastService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- handleParameters(request);
- return new ModelAndView(new RedirectView("podcastReceiver.view?expandedChannels=" + request.getParameter("expandedChannels")));
- }
-
- private void handleParameters(HttpServletRequest request) {
- if (request.getParameter("add") != null) {
- String url = request.getParameter("add");
- podcastService.createChannel(url);
- }
- if (request.getParameter("downloadChannel") != null ||
- request.getParameter("downloadEpisode") != null) {
- download(StringUtil.parseInts(request.getParameter("downloadChannel")),
- StringUtil.parseInts(request.getParameter("downloadEpisode")));
- }
- if (request.getParameter("deleteChannel") != null) {
- for (int channelId : StringUtil.parseInts(request.getParameter("deleteChannel"))) {
- podcastService.deleteChannel(channelId);
- }
- }
- if (request.getParameter("deleteEpisode") != null) {
- for (int episodeId : StringUtil.parseInts(request.getParameter("deleteEpisode"))) {
- podcastService.deleteEpisode(episodeId, true);
- }
- }
- if (request.getParameter("refresh") != null) {
- podcastService.refreshAllChannels(true);
- }
- }
-
- private void download(int[] channelIds, int[] episodeIds) {
- SortedSet<Integer> uniqueEpisodeIds = new TreeSet<Integer>();
- for (int episodeId : episodeIds) {
- uniqueEpisodeIds.add(episodeId);
- }
- for (int channelId : channelIds) {
- List<PodcastEpisode> episodes = podcastService.getEpisodes(channelId, false);
- for (PodcastEpisode episode : episodes) {
- uniqueEpisodeIds.add(episode.getId());
- }
- }
-
- for (Integer episodeId : uniqueEpisodeIds) {
- PodcastEpisode episode = podcastService.getEpisode(episodeId, false);
- if (episode != null && episode.getUrl() != null &&
- (episode.getStatus() == PodcastStatus.NEW ||
- episode.getStatus() == PodcastStatus.ERROR ||
- episode.getStatus() == PodcastStatus.SKIPPED)) {
-
- podcastService.downloadEpisode(episode);
- }
- }
- }
-
- public void setPodcastService(PodcastService podcastService) {
- this.podcastService = podcastService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverController.java
deleted file mode 100644
index 93640c22..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastReceiverController.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import net.sourceforge.subsonic.domain.PodcastChannel;
-import net.sourceforge.subsonic.domain.PodcastEpisode;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.PodcastService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Controller for the "Podcast receiver" page.
- *
- * @author Sindre Mehus
- */
-public class PodcastReceiverController extends ParameterizableViewController {
-
- private PodcastService podcastService;
- private SecurityService securityService;
- private SettingsService settingsService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
-
- Map<PodcastChannel, List<PodcastEpisode>> channels = new LinkedHashMap<PodcastChannel, List<PodcastEpisode>>();
- for (PodcastChannel channel : podcastService.getAllChannels()) {
- channels.put(channel, podcastService.getEpisodes(channel.getId(), false));
- }
-
- User user = securityService.getCurrentUser(request);
- UserSettings userSettings = settingsService.getUserSettings(user.getUsername());
-
- map.put("user", user);
- map.put("partyMode", userSettings.isPartyModeEnabled());
- map.put("channels", channels);
- map.put("expandedChannels", StringUtil.parseInts(request.getParameter("expandedChannels")));
- return result;
- }
-
- public void setPodcastService(PodcastService podcastService) {
- this.podcastService = podcastService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastSettingsController.java
deleted file mode 100644
index b6389616..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/PodcastSettingsController.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import org.springframework.web.servlet.mvc.SimpleFormController;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.PodcastService;
-import net.sourceforge.subsonic.command.PodcastSettingsCommand;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * Controller for the page used to administrate the Podcast receiver.
- *
- * @author Sindre Mehus
- */
-public class PodcastSettingsController extends SimpleFormController {
-
- private SettingsService settingsService;
- private PodcastService podcastService;
-
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- PodcastSettingsCommand command = new PodcastSettingsCommand();
-
- command.setInterval(String.valueOf(settingsService.getPodcastUpdateInterval()));
- command.setEpisodeRetentionCount(String.valueOf(settingsService.getPodcastEpisodeRetentionCount()));
- command.setEpisodeDownloadCount(String.valueOf(settingsService.getPodcastEpisodeDownloadCount()));
- command.setFolder(settingsService.getPodcastFolder());
- return command;
- }
-
- protected void doSubmitAction(Object comm) throws Exception {
- PodcastSettingsCommand command = (PodcastSettingsCommand) comm;
-
- settingsService.setPodcastUpdateInterval(Integer.parseInt(command.getInterval()));
- settingsService.setPodcastEpisodeRetentionCount(Integer.parseInt(command.getEpisodeRetentionCount()));
- settingsService.setPodcastEpisodeDownloadCount(Integer.parseInt(command.getEpisodeDownloadCount()));
- settingsService.setPodcastFolder(command.getFolder());
- settingsService.save();
-
- podcastService.schedule();
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPodcastService(PodcastService podcastService) {
- this.podcastService = podcastService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ProxyController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ProxyController.java
deleted file mode 100644
index 9535e059..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ProxyController.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.io.InputStream;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-
-/**
- * A proxy for external HTTP requests.
- *
- * @author Sindre Mehus
- */
-public class ProxyController implements Controller {
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String url = ServletRequestUtils.getRequiredStringParameter(request, "url");
-
- HttpClient client = new DefaultHttpClient();
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
- HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
- HttpGet method = new HttpGet(url);
-
- InputStream in = null;
- try {
- HttpResponse resp = client.execute(method);
- int statusCode = resp.getStatusLine().getStatusCode();
- if (statusCode != HttpStatus.SC_OK) {
- response.sendError(statusCode);
- } else {
- in = resp.getEntity().getContent();
- IOUtils.copy(in, response.getOutputStream());
- }
- } finally {
- IOUtils.closeQuietly(in);
- client.getConnectionManager().shutdown();
- }
- return null;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RESTController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RESTController.java
deleted file mode 100644
index 2d4fa73c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RESTController.java
+++ /dev/null
@@ -1,1983 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-
-import net.sourceforge.subsonic.ajax.PlayQueueService;
-import net.sourceforge.subsonic.domain.Playlist;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.bind.ServletRequestBindingException;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.ajax.ChatService;
-import net.sourceforge.subsonic.ajax.LyricsInfo;
-import net.sourceforge.subsonic.ajax.LyricsService;
-import net.sourceforge.subsonic.command.UserSettingsCommand;
-import net.sourceforge.subsonic.dao.AlbumDao;
-import net.sourceforge.subsonic.dao.ArtistDao;
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.Album;
-import net.sourceforge.subsonic.domain.Artist;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.MusicIndex;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayerTechnology;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.PodcastChannel;
-import net.sourceforge.subsonic.domain.PodcastEpisode;
-import net.sourceforge.subsonic.domain.RandomSearchCriteria;
-import net.sourceforge.subsonic.domain.SearchCriteria;
-import net.sourceforge.subsonic.domain.SearchResult;
-import net.sourceforge.subsonic.domain.Share;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.AudioScrobblerService;
-import net.sourceforge.subsonic.service.JukeboxService;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.PodcastService;
-import net.sourceforge.subsonic.service.RatingService;
-import net.sourceforge.subsonic.service.SearchService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.ShareService;
-import net.sourceforge.subsonic.service.StatusService;
-import net.sourceforge.subsonic.service.TranscodingService;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.XMLBuilder;
-
-import static net.sourceforge.subsonic.security.RESTRequestParameterProcessingFilter.decrypt;
-import static net.sourceforge.subsonic.util.XMLBuilder.Attribute;
-import static net.sourceforge.subsonic.util.XMLBuilder.AttributeSet;
-
-/**
- * Multi-controller used for the REST API.
- * <p/>
- * For documentation, please refer to api.jsp.
- *
- * @author Sindre Mehus
- */
-public class RESTController extends MultiActionController {
-
- private static final Logger LOG = Logger.getLogger(RESTController.class);
-
- private SettingsService settingsService;
- private SecurityService securityService;
- private PlayerService playerService;
- private MediaFileService mediaFileService;
- private TranscodingService transcodingService;
- private DownloadController downloadController;
- private CoverArtController coverArtController;
- private AvatarController avatarController;
- private UserSettingsController userSettingsController;
- private LeftController leftController;
- private HomeController homeController;
- private StatusService statusService;
- private StreamController streamController;
- private ShareService shareService;
- private PlaylistService playlistService;
- private ChatService chatService;
- private LyricsService lyricsService;
- private PlayQueueService playQueueService;
- private JukeboxService jukeboxService;
- private AudioScrobblerService audioScrobblerService;
- private PodcastService podcastService;
- private RatingService ratingService;
- private SearchService searchService;
- private MediaFileDao mediaFileDao;
- private ArtistDao artistDao;
- private AlbumDao albumDao;
-
- public void ping(HttpServletRequest request, HttpServletResponse response) throws Exception {
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
- }
-
- public void getLicense(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- String email = settingsService.getLicenseEmail();
- String key = settingsService.getLicenseCode();
- Date date = settingsService.getLicenseDate();
- boolean valid = settingsService.isLicenseValid();
-
- AttributeSet attributes = new AttributeSet();
- attributes.add("valid", valid);
- if (valid) {
- attributes.add("email", email);
- attributes.add("key", key);
- attributes.add("date", StringUtil.toISO8601(date));
- }
-
- builder.add("license", attributes, true);
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getMusicFolders(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("musicFolders", false);
-
- for (MusicFolder musicFolder : settingsService.getAllMusicFolders()) {
- AttributeSet attributes = new AttributeSet();
- attributes.add("id", musicFolder.getId());
- attributes.add("name", musicFolder.getName());
- builder.add("musicFolder", attributes, true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getIndexes(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- long ifModifiedSince = ServletRequestUtils.getLongParameter(request, "ifModifiedSince", 0L);
- long lastModified = leftController.getLastModified(request);
-
- if (lastModified <= ifModifiedSince) {
- builder.endAll();
- response.getWriter().print(builder);
- return;
- }
-
- builder.add("indexes", "lastModified", lastModified, false);
-
- List<MusicFolder> musicFolders = settingsService.getAllMusicFolders();
- Integer musicFolderId = ServletRequestUtils.getIntParameter(request, "musicFolderId");
- if (musicFolderId != null) {
- for (MusicFolder musicFolder : musicFolders) {
- if (musicFolderId.equals(musicFolder.getId())) {
- musicFolders = Arrays.asList(musicFolder);
- break;
- }
- }
- }
-
- List<MediaFile> shortcuts = leftController.getShortcuts(musicFolders, settingsService.getShortcutsAsArray());
- for (MediaFile shortcut : shortcuts) {
- builder.add("shortcut", true,
- new Attribute("name", shortcut.getName()),
- new Attribute("id", shortcut.getId()));
- }
-
- SortedMap<MusicIndex, SortedSet<MusicIndex.Artist>> indexedArtists = leftController.getMusicFolderContent(musicFolders).getIndexedArtists();
-
- for (Map.Entry<MusicIndex, SortedSet<MusicIndex.Artist>> entry : indexedArtists.entrySet()) {
- builder.add("index", "name", entry.getKey().getIndex(), false);
-
- for (MusicIndex.Artist artist : entry.getValue()) {
- for (MediaFile mediaFile : artist.getMediaFiles()) {
- if (mediaFile.isDirectory()) {
- builder.add("artist", true,
- new Attribute("name", artist.getName()),
- new Attribute("id", mediaFile.getId()));
- }
- }
- }
- builder.end();
- }
-
- // Add children
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
- List<MediaFile> singleSongs = leftController.getSingleSongs(musicFolders);
-
- for (MediaFile singleSong : singleSongs) {
- builder.add("child", createAttributesForMediaFile(player, singleSong, username), true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getArtists(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
- String username = securityService.getCurrentUsername(request);
-
- builder.add("artists", false);
-
- List<Artist> artists = artistDao.getAlphabetialArtists(0, Integer.MAX_VALUE);
- for (Artist artist : artists) {
- AttributeSet attributes = createAttributesForArtist(artist, username);
- builder.add("artist", attributes, true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- private AttributeSet createAttributesForArtist(Artist artist, String username) {
- AttributeSet attributes = new AttributeSet();
- attributes.add("id", artist.getId());
- attributes.add("name", artist.getName());
- if (artist.getCoverArtPath() != null) {
- attributes.add("coverArt", CoverArtController.ARTIST_COVERART_PREFIX + artist.getId());
- }
- attributes.add("albumCount", artist.getAlbumCount());
- attributes.add("starred", StringUtil.toISO8601(artistDao.getArtistStarredDate(artist.getId(), username)));
- return attributes;
- }
-
- public void getArtist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- String username = securityService.getCurrentUsername(request);
- Artist artist;
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- artist = artistDao.getArtist(id);
- if (artist == null) {
- throw new Exception();
- }
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.NOT_FOUND, "Artist not found.");
- return;
- }
-
- builder.add("artist", createAttributesForArtist(artist, username), false);
- for (Album album : albumDao.getAlbumsForArtist(artist.getName())) {
- builder.add("album", createAttributesForAlbum(album, username), true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- private AttributeSet createAttributesForAlbum(Album album, String username) {
- AttributeSet attributes;
- attributes = new AttributeSet();
- attributes.add("id", album.getId());
- attributes.add("name", album.getName());
- attributes.add("artist", album.getArtist());
- if (album.getArtist() != null) {
- Artist artist = artistDao.getArtist(album.getArtist());
- if (artist != null) {
- attributes.add("artistId", artist.getId());
- }
- }
- if (album.getCoverArtPath() != null) {
- attributes.add("coverArt", CoverArtController.ALBUM_COVERART_PREFIX + album.getId());
- }
- attributes.add("songCount", album.getSongCount());
- attributes.add("duration", album.getDurationSeconds());
- attributes.add("created", StringUtil.toISO8601(album.getCreated()));
- attributes.add("starred", StringUtil.toISO8601(albumDao.getAlbumStarredDate(album.getId(), username)));
-
- return attributes;
- }
-
- private AttributeSet createAttributesForPlaylist(Playlist playlist) {
- AttributeSet attributes;
- attributes = new AttributeSet();
- attributes.add("id", playlist.getId());
- attributes.add("name", playlist.getName());
- attributes.add("comment", playlist.getComment());
- attributes.add("owner", playlist.getUsername());
- attributes.add("public", playlist.isPublic());
- attributes.add("songCount", playlist.getFileCount());
- attributes.add("duration", playlist.getDurationSeconds());
- attributes.add("created", StringUtil.toISO8601(playlist.getCreated()));
- return attributes;
- }
-
- public void getAlbum(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- Album album;
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- album = albumDao.getAlbum(id);
- if (album == null) {
- throw new Exception();
- }
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.NOT_FOUND, "Album not found.");
- return;
- }
-
- builder.add("album", createAttributesForAlbum(album, username), false);
- for (MediaFile mediaFile : mediaFileDao.getSongsForAlbum(album.getArtist(), album.getName())) {
- builder.add("song", createAttributesForMediaFile(player, mediaFile, username) , true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getSong(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- MediaFile song;
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- song = mediaFileDao.getMediaFile(id);
- if (song == null || song.isDirectory()) {
- throw new Exception();
- }
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.NOT_FOUND, "Song not found.");
- return;
- }
-
- builder.add("song", createAttributesForMediaFile(player, song, username), true);
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getMusicDirectory(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- MediaFile dir;
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- dir = mediaFileService.getMediaFile(id);
- if (dir == null) {
- throw new Exception();
- }
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.NOT_FOUND, "Directory not found");
- return;
- }
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("directory", false,
- new Attribute("id", dir.getId()),
- new Attribute("name", dir.getName()));
-
- for (MediaFile child : mediaFileService.getChildrenOf(dir, true, true, true)) {
- AttributeSet attributes = createAttributesForMediaFile(player, child, username);
- builder.add("child", attributes, true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- @Deprecated
- public void search(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- String any = request.getParameter("any");
- String artist = request.getParameter("artist");
- String album = request.getParameter("album");
- String title = request.getParameter("title");
-
- StringBuilder query = new StringBuilder();
- if (any != null) {
- query.append(any).append(" ");
- }
- if (artist != null) {
- query.append(artist).append(" ");
- }
- if (album != null) {
- query.append(album).append(" ");
- }
- if (title != null) {
- query.append(title);
- }
-
- SearchCriteria criteria = new SearchCriteria();
- criteria.setQuery(query.toString().trim());
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "count", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "offset", 0));
-
- SearchResult result = searchService.search(criteria, SearchService.IndexType.SONG);
- builder.add("searchResult", false,
- new Attribute("offset", result.getOffset()),
- new Attribute("totalHits", result.getTotalHits()));
-
- for (MediaFile mediaFile : result.getMediaFiles()) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("match", attributes, true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void search2(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- builder.add("searchResult2", false);
-
- String query = request.getParameter("query");
- SearchCriteria criteria = new SearchCriteria();
- criteria.setQuery(StringUtils.trimToEmpty(query));
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "artistCount", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "artistOffset", 0));
- SearchResult artists = searchService.search(criteria, SearchService.IndexType.ARTIST);
- for (MediaFile mediaFile : artists.getMediaFiles()) {
- builder.add("artist", true,
- new Attribute("name", mediaFile.getName()),
- new Attribute("id", mediaFile.getId()));
- }
-
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "albumCount", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "albumOffset", 0));
- SearchResult albums = searchService.search(criteria, SearchService.IndexType.ALBUM);
- for (MediaFile mediaFile : albums.getMediaFiles()) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("album", attributes, true);
- }
-
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "songCount", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "songOffset", 0));
- SearchResult songs = searchService.search(criteria, SearchService.IndexType.SONG);
- for (MediaFile mediaFile : songs.getMediaFiles()) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("song", attributes, true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void search3(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- builder.add("searchResult3", false);
-
- String query = request.getParameter("query");
- SearchCriteria criteria = new SearchCriteria();
- criteria.setQuery(StringUtils.trimToEmpty(query));
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "artistCount", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "artistOffset", 0));
- SearchResult searchResult = searchService.search(criteria, SearchService.IndexType.ARTIST_ID3);
- for (Artist artist : searchResult.getArtists()) {
- builder.add("artist", createAttributesForArtist(artist, username), true);
- }
-
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "albumCount", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "albumOffset", 0));
- searchResult = searchService.search(criteria, SearchService.IndexType.ALBUM_ID3);
- for (Album album : searchResult.getAlbums()) {
- builder.add("album", createAttributesForAlbum(album, username), true);
- }
-
- criteria.setCount(ServletRequestUtils.getIntParameter(request, "songCount", 20));
- criteria.setOffset(ServletRequestUtils.getIntParameter(request, "songOffset", 0));
- searchResult = searchService.search(criteria, SearchService.IndexType.SONG);
- for (MediaFile song : searchResult.getMediaFiles()) {
- builder.add("song", createAttributesForMediaFile(player, song, username), true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getPlaylists(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- User user = securityService.getCurrentUser(request);
- String authenticatedUsername = user.getUsername();
- String requestedUsername = request.getParameter("username");
-
- if (requestedUsername == null) {
- requestedUsername = authenticatedUsername;
- } else if (!user.isAdminRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, authenticatedUsername + " is not authorized to get playlists for " + requestedUsername);
- return;
- }
-
- builder.add("playlists", false);
-
- for (Playlist playlist : playlistService.getReadablePlaylistsForUser(requestedUsername)) {
- List<String> sharedUsers = playlistService.getPlaylistUsers(playlist.getId());
- builder.add("playlist", createAttributesForPlaylist(playlist), sharedUsers.isEmpty());
- if (!sharedUsers.isEmpty()) {
- for (String username : sharedUsers) {
- builder.add("allowedUser", (Iterable<Attribute>) null, username, true);
- }
- builder.end();
- }
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getPlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
-
- Playlist playlist = playlistService.getPlaylist(id);
- if (playlist == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Playlist not found: " + id);
- return;
- }
- if (!playlistService.isReadAllowed(playlist, username)) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, "Permission denied for playlist " + id);
- return;
- }
- builder.add("playlist", createAttributesForPlaylist(playlist), false);
- for (String allowedUser : playlistService.getPlaylistUsers(playlist.getId())) {
- builder.add("allowedUser", (Iterable<Attribute>) null, allowedUser, true);
- }
- for (MediaFile mediaFile : playlistService.getFilesInPlaylist(id)) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("entry", attributes, true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void jukeboxControl(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request, true);
-
- User user = securityService.getCurrentUser(request);
- if (!user.isJukeboxRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, user.getUsername() + " is not authorized to use jukebox.");
- return;
- }
-
- try {
- boolean returnPlaylist = false;
- String action = ServletRequestUtils.getRequiredStringParameter(request, "action");
- if ("start".equals(action)) {
- playQueueService.doStart(request, response);
- } else if ("stop".equals(action)) {
- playQueueService.doStop(request, response);
- } else if ("skip".equals(action)) {
- int index = ServletRequestUtils.getRequiredIntParameter(request, "index");
- int offset = ServletRequestUtils.getIntParameter(request, "offset", 0);
- playQueueService.doSkip(request, response, index, offset);
- } else if ("add".equals(action)) {
- int[] ids = ServletRequestUtils.getIntParameters(request, "id");
- playQueueService.doAdd(request, response, ids);
- } else if ("set".equals(action)) {
- int[] ids = ServletRequestUtils.getIntParameters(request, "id");
- playQueueService.doSet(request, response, ids);
- } else if ("clear".equals(action)) {
- playQueueService.doClear(request, response);
- } else if ("remove".equals(action)) {
- int index = ServletRequestUtils.getRequiredIntParameter(request, "index");
- playQueueService.doRemove(request, response, index);
- } else if ("shuffle".equals(action)) {
- playQueueService.doShuffle(request, response);
- } else if ("setGain".equals(action)) {
- float gain = ServletRequestUtils.getRequiredFloatParameter(request, "gain");
- jukeboxService.setGain(gain);
- } else if ("get".equals(action)) {
- returnPlaylist = true;
- } else if ("status".equals(action)) {
- // No action necessary.
- } else {
- throw new Exception("Unknown jukebox action: '" + action + "'.");
- }
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
- Player jukeboxPlayer = jukeboxService.getPlayer();
- boolean controlsJukebox = jukeboxPlayer != null && jukeboxPlayer.getId().equals(player.getId());
- PlayQueue playQueue = player.getPlayQueue();
-
- List<Attribute> attrs = new ArrayList<Attribute>(Arrays.asList(
- new Attribute("currentIndex", controlsJukebox && !playQueue.isEmpty() ? playQueue.getIndex() : -1),
- new Attribute("playing", controlsJukebox && !playQueue.isEmpty() && playQueue.getStatus() == PlayQueue.Status.PLAYING),
- new Attribute("gain", jukeboxService.getGain()),
- new Attribute("position", controlsJukebox && !playQueue.isEmpty() ? jukeboxService.getPosition() : 0)));
-
- if (returnPlaylist) {
- builder.add("jukeboxPlaylist", attrs, false);
- List<MediaFile> result;
- synchronized (playQueue) {
- result = playQueue.getFiles();
- }
- for (MediaFile mediaFile : result) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("entry", attributes, true);
- }
- } else {
- builder.add("jukeboxStatus", attrs, false);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void createPlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request, true);
- String username = securityService.getCurrentUsername(request);
-
- try {
-
- Integer playlistId = ServletRequestUtils.getIntParameter(request, "playlistId");
- String name = request.getParameter("name");
- if (playlistId == null && name == null) {
- error(request, response, ErrorCode.MISSING_PARAMETER, "Playlist ID or name must be specified.");
- return;
- }
-
- Playlist playlist;
- if (playlistId != null) {
- playlist = playlistService.getPlaylist(playlistId);
- if (playlist == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Playlist not found: " + playlistId);
- return;
- }
- if (!playlistService.isWriteAllowed(playlist, username)) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, "Permission denied for playlist " + playlistId);
- return;
- }
- } else {
- playlist = new Playlist();
- playlist.setName(name);
- playlist.setCreated(new Date());
- playlist.setChanged(new Date());
- playlist.setPublic(false);
- playlist.setUsername(username);
- playlistService.createPlaylist(playlist);
- }
-
- List<MediaFile> songs = new ArrayList<MediaFile>();
- for (int id : ServletRequestUtils.getIntParameters(request, "songId")) {
- MediaFile song = mediaFileService.getMediaFile(id);
- if (song != null) {
- songs.add(song);
- }
- }
- playlistService.setFilesInPlaylist(playlist.getId(), songs);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void updatePlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request, true);
- String username = securityService.getCurrentUsername(request);
-
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "playlistId");
- Playlist playlist = playlistService.getPlaylist(id);
- if (playlist == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Playlist not found: " + id);
- return;
- }
- if (!playlistService.isWriteAllowed(playlist, username)) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, "Permission denied for playlist " + id);
- return;
- }
-
- String name = request.getParameter("name");
- if (name != null) {
- playlist.setName(name);
- }
- String comment = request.getParameter("comment");
- if (comment != null) {
- playlist.setComment(comment);
- }
- Boolean isPublic = ServletRequestUtils.getBooleanParameter(request, "public");
- if (isPublic != null) {
- playlist.setPublic(isPublic);
- }
- playlistService.updatePlaylist(playlist);
-
- // TODO: Add later
-// for (String usernameToAdd : ServletRequestUtils.getStringParameters(request, "usernameToAdd")) {
-// if (securityService.getUserByName(usernameToAdd) != null) {
-// playlistService.addPlaylistUser(id, usernameToAdd);
-// }
-// }
-// for (String usernameToRemove : ServletRequestUtils.getStringParameters(request, "usernameToRemove")) {
-// if (securityService.getUserByName(usernameToRemove) != null) {
-// playlistService.deletePlaylistUser(id, usernameToRemove);
-// }
-// }
- List<MediaFile> songs = playlistService.getFilesInPlaylist(id);
- boolean songsChanged = false;
-
- SortedSet<Integer> tmp = new TreeSet<Integer>();
- for (int songIndexToRemove : ServletRequestUtils.getIntParameters(request, "songIndexToRemove")) {
- tmp.add(songIndexToRemove);
- }
- List<Integer> songIndexesToRemove = new ArrayList<Integer>(tmp);
- Collections.reverse(songIndexesToRemove);
- for (Integer songIndexToRemove : songIndexesToRemove) {
- songs.remove(songIndexToRemove.intValue());
- songsChanged = true;
- }
- for (int songToAdd : ServletRequestUtils.getIntParameters(request, "songIdToAdd")) {
- MediaFile song = mediaFileService.getMediaFile(songToAdd);
- if (song != null) {
- songs.add(song);
- songsChanged = true;
- }
- }
- if (songsChanged) {
- playlistService.setFilesInPlaylist(id, songs);
- }
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void deletePlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request, true);
- String username = securityService.getCurrentUsername(request);
-
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- Playlist playlist = playlistService.getPlaylist(id);
- if (playlist == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Playlist not found: " + id);
- return;
- }
- if (!playlistService.isWriteAllowed(playlist, username)) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, "Permission denied for playlist " + id);
- return;
- }
- playlistService.deletePlaylist(id);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getAlbumList(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("albumList", false);
-
- try {
- int size = ServletRequestUtils.getIntParameter(request, "size", 10);
- int offset = ServletRequestUtils.getIntParameter(request, "offset", 0);
- size = Math.max(0, Math.min(size, 500));
- String type = ServletRequestUtils.getRequiredStringParameter(request, "type");
-
- List<HomeController.Album> albums;
- if ("highest".equals(type)) {
- albums = homeController.getHighestRated(offset, size);
- } else if ("frequent".equals(type)) {
- albums = homeController.getMostFrequent(offset, size);
- } else if ("recent".equals(type)) {
- albums = homeController.getMostRecent(offset, size);
- } else if ("newest".equals(type)) {
- albums = homeController.getNewest(offset, size);
- } else if ("starred".equals(type)) {
- albums = homeController.getStarred(offset, size, username);
- } else if ("alphabeticalByArtist".equals(type)) {
- albums = homeController.getAlphabetical(offset, size, true);
- } else if ("alphabeticalByName".equals(type)) {
- albums = homeController.getAlphabetical(offset, size, false);
- } else if ("random".equals(type)) {
- albums = homeController.getRandom(size);
- } else {
- throw new Exception("Invalid list type: " + type);
- }
-
- for (HomeController.Album album : albums) {
- MediaFile mediaFile = mediaFileService.getMediaFile(album.getPath());
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("album", attributes, true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getAlbumList2(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("albumList2", false);
-
- try {
- int size = ServletRequestUtils.getIntParameter(request, "size", 10);
- int offset = ServletRequestUtils.getIntParameter(request, "offset", 0);
- size = Math.max(0, Math.min(size, 500));
- String type = ServletRequestUtils.getRequiredStringParameter(request, "type");
- String username = securityService.getCurrentUsername(request);
-
- List<Album> albums;
- if ("frequent".equals(type)) {
- albums = albumDao.getMostFrequentlyPlayedAlbums(offset, size);
- } else if ("recent".equals(type)) {
- albums = albumDao.getMostRecentlyPlayedAlbums(offset, size);
- } else if ("newest".equals(type)) {
- albums = albumDao.getNewestAlbums(offset, size);
- } else if ("alphabeticalByArtist".equals(type)) {
- albums = albumDao.getAlphabetialAlbums(offset, size, true);
- } else if ("alphabeticalByName".equals(type)) {
- albums = albumDao.getAlphabetialAlbums(offset, size, false);
- } else if ("starred".equals(type)) {
- albums = albumDao.getStarredAlbums(offset, size, securityService.getCurrentUser(request).getUsername());
- } else if ("random".equals(type)) {
- albums = searchService.getRandomAlbumsId3(size);
- } else {
- throw new Exception("Invalid list type: " + type);
- }
- for (Album album : albums) {
- builder.add("album", createAttributesForAlbum(album, username), true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getRandomSongs(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("randomSongs", false);
-
- try {
- int size = ServletRequestUtils.getIntParameter(request, "size", 10);
- size = Math.max(0, Math.min(size, 500));
- String genre = ServletRequestUtils.getStringParameter(request, "genre");
- Integer fromYear = ServletRequestUtils.getIntParameter(request, "fromYear");
- Integer toYear = ServletRequestUtils.getIntParameter(request, "toYear");
- Integer musicFolderId = ServletRequestUtils.getIntParameter(request, "musicFolderId");
- RandomSearchCriteria criteria = new RandomSearchCriteria(size, genre, fromYear, toYear, musicFolderId);
-
- for (MediaFile mediaFile : searchService.getRandomSongs(criteria)) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("song", attributes, true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getVideos(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("videos", false);
- try {
- int size = ServletRequestUtils.getIntParameter(request, "size", Integer.MAX_VALUE);
- int offset = ServletRequestUtils.getIntParameter(request, "offset", 0);
-
- for (MediaFile mediaFile : mediaFileDao.getVideos(size, offset)) {
- builder.add("video", createAttributesForMediaFile(player, mediaFile, username), true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getNowPlaying(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("nowPlaying", false);
-
- for (TransferStatus status : statusService.getAllStreamStatuses()) {
-
- Player player = status.getPlayer();
- File file = status.getFile();
- if (player != null && player.getUsername() != null && file != null) {
-
- String username = player.getUsername();
- UserSettings userSettings = settingsService.getUserSettings(username);
- if (!userSettings.isNowPlayingAllowed()) {
- continue;
- }
-
- MediaFile mediaFile = mediaFileService.getMediaFile(file);
-
- long minutesAgo = status.getMillisSinceLastUpdate() / 1000L / 60L;
- if (minutesAgo < 60) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- attributes.add("username", username);
- attributes.add("playerId", player.getId());
- attributes.add("playerName", player.getName());
- attributes.add("minutesAgo", minutesAgo);
- builder.add("entry", attributes, true);
- }
- }
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- private AttributeSet createAttributesForMediaFile(Player player, MediaFile mediaFile, String username) {
- MediaFile parent = mediaFileService.getParentOf(mediaFile);
- AttributeSet attributes = new AttributeSet();
- attributes.add("id", mediaFile.getId());
- try {
- if (!mediaFileService.isRoot(parent)) {
- attributes.add("parent", parent.getId());
- }
- } catch (SecurityException x) {
- // Ignored.
- }
- attributes.add("title", mediaFile.getName());
- attributes.add("album", mediaFile.getAlbumName());
- attributes.add("artist", mediaFile.getArtist());
- attributes.add("isDir", mediaFile.isDirectory());
- attributes.add("coverArt", findCoverArt(mediaFile, parent));
- attributes.add("created", StringUtil.toISO8601(mediaFile.getCreated()));
- attributes.add("starred", StringUtil.toISO8601(mediaFileDao.getMediaFileStarredDate(mediaFile.getId(), username)));
- attributes.add("userRating", ratingService.getRatingForUser(username, mediaFile));
- attributes.add("averageRating", ratingService.getAverageRating(mediaFile));
-
- if (mediaFile.isFile()) {
- attributes.add("duration", mediaFile.getDurationSeconds());
- attributes.add("bitRate", mediaFile.getBitRate());
- attributes.add("track", mediaFile.getTrackNumber());
- attributes.add("discNumber", mediaFile.getDiscNumber());
- attributes.add("year", mediaFile.getYear());
- attributes.add("genre", mediaFile.getGenre());
- attributes.add("size", mediaFile.getFileSize());
- String suffix = mediaFile.getFormat();
- attributes.add("suffix", suffix);
- attributes.add("contentType", StringUtil.getMimeType(suffix));
- attributes.add("isVideo", mediaFile.isVideo());
- attributes.add("path", getRelativePath(mediaFile));
-
- if (mediaFile.getArtist() != null && mediaFile.getAlbumName() != null) {
- Album album = albumDao.getAlbum(mediaFile.getAlbumArtist(), mediaFile.getAlbumName());
- if (album != null) {
- attributes.add("albumId", album.getId());
- }
- }
- if (mediaFile.getArtist() != null) {
- Artist artist = artistDao.getArtist(mediaFile.getArtist());
- if (artist != null) {
- attributes.add("artistId", artist.getId());
- }
- }
- switch (mediaFile.getMediaType()) {
- case MUSIC:
- attributes.add("type", "music");
- break;
- case PODCAST:
- attributes.add("type", "podcast");
- break;
- case AUDIOBOOK:
- attributes.add("type", "audiobook");
- break;
- default:
- break;
- }
-
- if (transcodingService.isTranscodingRequired(mediaFile, player)) {
- String transcodedSuffix = transcodingService.getSuffix(player, mediaFile, null);
- attributes.add("transcodedSuffix", transcodedSuffix);
- attributes.add("transcodedContentType", StringUtil.getMimeType(transcodedSuffix));
- }
- }
- return attributes;
- }
-
- private Integer findCoverArt(MediaFile mediaFile, MediaFile parent) {
- MediaFile dir = mediaFile.isDirectory() ? mediaFile : parent;
- if (dir != null && dir.getCoverArtPath() != null) {
- return dir.getId();
- }
- return null;
- }
-
- private String getRelativePath(MediaFile musicFile) {
-
- String filePath = musicFile.getPath();
-
- // Convert slashes.
- filePath = filePath.replace('\\', '/');
-
- String filePathLower = filePath.toLowerCase();
-
- List<MusicFolder> musicFolders = settingsService.getAllMusicFolders(false, true);
- for (MusicFolder musicFolder : musicFolders) {
- String folderPath = musicFolder.getPath().getPath();
- folderPath = folderPath.replace('\\', '/');
- String folderPathLower = folderPath.toLowerCase();
-
- if (filePathLower.startsWith(folderPathLower)) {
- String relativePath = filePath.substring(folderPath.length());
- return relativePath.startsWith("/") ? relativePath.substring(1) : relativePath;
- }
- }
-
- return null;
- }
-
- public ModelAndView download(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- User user = securityService.getCurrentUser(request);
- if (!user.isDownloadRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, user.getUsername() + " is not authorized to download files.");
- return null;
- }
-
- long ifModifiedSince = request.getDateHeader("If-Modified-Since");
- long lastModified = downloadController.getLastModified(request);
-
- if (ifModifiedSince != -1 && lastModified != -1 && lastModified <= ifModifiedSince) {
- response.sendError(HttpServletResponse.SC_NOT_MODIFIED);
- return null;
- }
-
- if (lastModified != -1) {
- response.setDateHeader("Last-Modified", lastModified);
- }
-
- return downloadController.handleRequest(request, response);
- }
-
- public ModelAndView stream(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- User user = securityService.getCurrentUser(request);
- if (!user.isStreamRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, user.getUsername() + " is not authorized to play files.");
- return null;
- }
-
- streamController.handleRequest(request, response);
- return null;
- }
-
- public void scrobble(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- Player player = playerService.getPlayer(request, response);
-
- if (!settingsService.getUserSettings(player.getUsername()).isLastFmEnabled()) {
- error(request, response, ErrorCode.GENERIC, "Scrobbling is not enabled for " + player.getUsername() + ".");
- return;
- }
-
- try {
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- MediaFile file = mediaFileService.getMediaFile(id);
- if (file == null) {
- error(request, response, ErrorCode.NOT_FOUND, "File not found: " + id);
- return;
- }
- boolean submission = ServletRequestUtils.getBooleanParameter(request, "submission", true);
- audioScrobblerService.register(file, player.getUsername(), submission);
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- return;
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void star(HttpServletRequest request, HttpServletResponse response) throws Exception {
- starOrUnstar(request, response, true);
- }
-
- public void unstar(HttpServletRequest request, HttpServletResponse response) throws Exception {
- starOrUnstar(request, response, false);
- }
-
- private void starOrUnstar(HttpServletRequest request, HttpServletResponse response, boolean star) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- try {
- String username = securityService.getCurrentUser(request).getUsername();
- for (int id : ServletRequestUtils.getIntParameters(request, "id")) {
- MediaFile mediaFile = mediaFileDao.getMediaFile(id);
- if (mediaFile == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Media file not found: " + id);
- return;
- }
- if (star) {
- mediaFileDao.starMediaFile(id, username);
- } else {
- mediaFileDao.unstarMediaFile(id, username);
- }
- }
- for (int albumId : ServletRequestUtils.getIntParameters(request, "albumId")) {
- Album album = albumDao.getAlbum(albumId);
- if (album == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Album not found: " + albumId);
- return;
- }
- if (star) {
- albumDao.starAlbum(albumId, username);
- } else {
- albumDao.unstarAlbum(albumId, username);
- }
- }
- for (int artistId : ServletRequestUtils.getIntParameters(request, "artistId")) {
- Artist artist = artistDao.getArtist(artistId);
- if (artist == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Artist not found: " + artistId);
- return;
- }
- if (star) {
- artistDao.starArtist(artistId, username);
- } else {
- artistDao.unstarArtist(artistId, username);
- }
- }
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- return;
- }
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getStarred(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("starred", false);
- for (MediaFile artist : mediaFileDao.getStarredDirectories(0, Integer.MAX_VALUE, username)) {
- builder.add("artist", true,
- new Attribute("name", artist.getName()),
- new Attribute("id", artist.getId()));
- }
- for (MediaFile album : mediaFileDao.getStarredAlbums(0, Integer.MAX_VALUE, username)) {
- builder.add("album", createAttributesForMediaFile(player, album, username), true);
- }
- for (MediaFile song : mediaFileDao.getStarredFiles(0, Integer.MAX_VALUE, username)) {
- builder.add("song", createAttributesForMediaFile(player, song, username), true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getStarred2(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("starred2", false);
- for (Artist artist : artistDao.getStarredArtists(0, Integer.MAX_VALUE, username)) {
- builder.add("artist", createAttributesForArtist(artist, username), true);
- }
- for (Album album : albumDao.getStarredAlbums(0, Integer.MAX_VALUE, username)) {
- builder.add("album", createAttributesForAlbum(album, username), true);
- }
- for (MediaFile song : mediaFileDao.getStarredFiles(0, Integer.MAX_VALUE, username)) {
- builder.add("song", createAttributesForMediaFile(player, song, username), true);
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getPodcasts(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- builder.add("podcasts", false);
-
- for (PodcastChannel channel : podcastService.getAllChannels()) {
- AttributeSet channelAttrs = new AttributeSet();
- channelAttrs.add("id", channel.getId());
- channelAttrs.add("url", channel.getUrl());
- channelAttrs.add("status", channel.getStatus().toString().toLowerCase());
- channelAttrs.add("title", channel.getTitle());
- channelAttrs.add("description", channel.getDescription());
- channelAttrs.add("errorMessage", channel.getErrorMessage());
- builder.add("channel", channelAttrs, false);
-
- List<PodcastEpisode> episodes = podcastService.getEpisodes(channel.getId(), false);
- for (PodcastEpisode episode : episodes) {
- AttributeSet episodeAttrs = new AttributeSet();
-
- String path = episode.getPath();
- if (path != null) {
- MediaFile mediaFile = mediaFileService.getMediaFile(path);
- episodeAttrs.addAll(createAttributesForMediaFile(player, mediaFile, username));
- episodeAttrs.add("streamId", mediaFile.getId());
- }
-
- episodeAttrs.add("id", episode.getId()); // Overwrites the previous "id" attribute.
- episodeAttrs.add("status", episode.getStatus().toString().toLowerCase());
- episodeAttrs.add("title", episode.getTitle());
- episodeAttrs.add("description", episode.getDescription());
- episodeAttrs.add("publishDate", episode.getPublishDate());
-
- builder.add("episode", episodeAttrs, true);
- }
-
- builder.end(); // <channel>
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void getShares(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- User user = securityService.getCurrentUser(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- builder.add("shares", false);
- for (Share share : shareService.getSharesForUser(user)) {
- builder.add("share", createAttributesForShare(share), false);
-
- for (MediaFile mediaFile : shareService.getSharedFiles(share.getId())) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("entry", attributes, true);
- }
-
- builder.end();
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void createShare(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- Player player = playerService.getPlayer(request, response);
- String username = securityService.getCurrentUsername(request);
-
- User user = securityService.getCurrentUser(request);
- if (!user.isShareRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, user.getUsername() + " is not authorized to share media.");
- return;
- }
-
- if (!settingsService.isUrlRedirectionEnabled()) {
- error(request, response, ErrorCode.GENERIC, "Sharing is only supported for *.subsonic.org domain names.");
- return;
- }
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- try {
-
- List<MediaFile> files = new ArrayList<MediaFile>();
- for (int id : ServletRequestUtils.getRequiredIntParameters(request, "id")) {
- files.add(mediaFileService.getMediaFile(id));
- }
-
- // TODO: Update api.jsp
-
- Share share = shareService.createShare(request, files);
- share.setDescription(request.getParameter("description"));
- long expires = ServletRequestUtils.getLongParameter(request, "expires", 0L);
- if (expires != 0) {
- share.setExpires(new Date(expires));
- }
- shareService.updateShare(share);
-
- builder.add("shares", false);
- builder.add("share", createAttributesForShare(share), false);
-
- for (MediaFile mediaFile : shareService.getSharedFiles(share.getId())) {
- AttributeSet attributes = createAttributesForMediaFile(player, mediaFile, username);
- builder.add("entry", attributes, true);
- }
-
- builder.endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void deleteShare(HttpServletRequest request, HttpServletResponse response) throws Exception {
- try {
- request = wrapRequest(request);
- User user = securityService.getCurrentUser(request);
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
-
- Share share = shareService.getShareById(id);
- if (share == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Shared media not found.");
- return;
- }
- if (!user.isAdminRole() && !share.getUsername().equals(user.getUsername())) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, "Not authorized to delete shared media.");
- return;
- }
-
- shareService.deleteShare(id);
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void updateShare(HttpServletRequest request, HttpServletResponse response) throws Exception {
- try {
- request = wrapRequest(request);
- User user = securityService.getCurrentUser(request);
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
-
- Share share = shareService.getShareById(id);
- if (share == null) {
- error(request, response, ErrorCode.NOT_FOUND, "Shared media not found.");
- return;
- }
- if (!user.isAdminRole() && !share.getUsername().equals(user.getUsername())) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, "Not authorized to modify shared media.");
- return;
- }
-
- share.setDescription(request.getParameter("description"));
- String expiresString = request.getParameter("expires");
- if (expiresString != null) {
- long expires = Long.parseLong(expiresString);
- share.setExpires(expires == 0L ? null : new Date(expires));
- }
- shareService.updateShare(share);
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- private List<Attribute> createAttributesForShare(Share share) {
- List<Attribute> attributes = new ArrayList<Attribute>();
-
- attributes.add(new Attribute("id", share.getId()));
- attributes.add(new Attribute("url", shareService.getShareUrl(share)));
- attributes.add(new Attribute("username", share.getUsername()));
- attributes.add(new Attribute("created", StringUtil.toISO8601(share.getCreated())));
- attributes.add(new Attribute("visitCount", share.getVisitCount()));
- attributes.add(new Attribute("description", share.getDescription()));
- attributes.add(new Attribute("expires", StringUtil.toISO8601(share.getExpires())));
- attributes.add(new Attribute("lastVisited", StringUtil.toISO8601(share.getLastVisited())));
-
- return attributes;
- }
-
- public ModelAndView videoPlayer(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
-
- Map<String, Object> map = new HashMap<String, Object>();
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- MediaFile file = mediaFileService.getMediaFile(id);
-
- int timeOffset = ServletRequestUtils.getIntParameter(request, "timeOffset", 0);
- timeOffset = Math.max(0, timeOffset);
- Integer duration = file.getDurationSeconds();
- if (duration != null) {
- map.put("skipOffsets", VideoPlayerController.createSkipOffsets(duration));
- timeOffset = Math.min(duration, timeOffset);
- duration -= timeOffset;
- }
-
- map.put("id", request.getParameter("id"));
- map.put("u", request.getParameter("u"));
- map.put("p", request.getParameter("p"));
- map.put("c", request.getParameter("c"));
- map.put("v", request.getParameter("v"));
- map.put("video", file);
- map.put("maxBitRate", ServletRequestUtils.getIntParameter(request, "maxBitRate", VideoPlayerController.DEFAULT_BIT_RATE));
- map.put("duration", duration);
- map.put("timeOffset", timeOffset);
- map.put("bitRates", VideoPlayerController.BIT_RATES);
- map.put("autoplay", ServletRequestUtils.getBooleanParameter(request, "autoplay", true));
-
- ModelAndView result = new ModelAndView("rest/videoPlayer");
- result.addObject("model", map);
- return result;
- }
-
- public ModelAndView getCoverArt(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- return coverArtController.handleRequest(request, response);
- }
-
- public ModelAndView getAvatar(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- return avatarController.handleRequest(request, response);
- }
-
- public void changePassword(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- try {
-
- String username = ServletRequestUtils.getRequiredStringParameter(request, "username");
- String password = decrypt(ServletRequestUtils.getRequiredStringParameter(request, "password"));
-
- User authUser = securityService.getCurrentUser(request);
- if (!authUser.isAdminRole() && !username.equals(authUser.getUsername())) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, authUser.getUsername() + " is not authorized to change password for " + username);
- return;
- }
-
- User user = securityService.getUserByName(username);
- user.setPassword(password);
- securityService.updateUser(user);
-
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
-
- String username;
- try {
- username = ServletRequestUtils.getRequiredStringParameter(request, "username");
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- return;
- }
-
- User currentUser = securityService.getCurrentUser(request);
- if (!username.equals(currentUser.getUsername()) && !currentUser.isAdminRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, currentUser.getUsername() + " is not authorized to get details for other users.");
- return;
- }
-
- User requestedUser = securityService.getUserByName(username);
- if (requestedUser == null) {
- error(request, response, ErrorCode.NOT_FOUND, "No such user: " + username);
- return;
- }
-
- UserSettings userSettings = settingsService.getUserSettings(username);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- List<Attribute> attributes = Arrays.asList(
- new Attribute("username", requestedUser.getUsername()),
- new Attribute("email", requestedUser.getEmail()),
- new Attribute("scrobblingEnabled", userSettings.isLastFmEnabled()),
- new Attribute("adminRole", requestedUser.isAdminRole()),
- new Attribute("settingsRole", requestedUser.isSettingsRole()),
- new Attribute("downloadRole", requestedUser.isDownloadRole()),
- new Attribute("uploadRole", requestedUser.isUploadRole()),
- new Attribute("playlistRole", true), // Since 1.8.0
- new Attribute("coverArtRole", requestedUser.isCoverArtRole()),
- new Attribute("commentRole", requestedUser.isCommentRole()),
- new Attribute("podcastRole", requestedUser.isPodcastRole()),
- new Attribute("streamRole", requestedUser.isStreamRole()),
- new Attribute("jukeboxRole", requestedUser.isJukeboxRole()),
- new Attribute("shareRole", requestedUser.isShareRole())
- );
-
- builder.add("user", attributes, true);
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void createUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- User user = securityService.getCurrentUser(request);
- if (!user.isAdminRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, user.getUsername() + " is not authorized to create new users.");
- return;
- }
-
- try {
- UserSettingsCommand command = new UserSettingsCommand();
- command.setUsername(ServletRequestUtils.getRequiredStringParameter(request, "username"));
- command.setPassword(decrypt(ServletRequestUtils.getRequiredStringParameter(request, "password")));
- command.setEmail(ServletRequestUtils.getRequiredStringParameter(request, "email"));
- command.setLdapAuthenticated(ServletRequestUtils.getBooleanParameter(request, "ldapAuthenticated", false));
- command.setAdminRole(ServletRequestUtils.getBooleanParameter(request, "adminRole", false));
- command.setCommentRole(ServletRequestUtils.getBooleanParameter(request, "commentRole", false));
- command.setCoverArtRole(ServletRequestUtils.getBooleanParameter(request, "coverArtRole", false));
- command.setDownloadRole(ServletRequestUtils.getBooleanParameter(request, "downloadRole", false));
- command.setStreamRole(ServletRequestUtils.getBooleanParameter(request, "streamRole", true));
- command.setUploadRole(ServletRequestUtils.getBooleanParameter(request, "uploadRole", false));
- command.setJukeboxRole(ServletRequestUtils.getBooleanParameter(request, "jukeboxRole", false));
- command.setPodcastRole(ServletRequestUtils.getBooleanParameter(request, "podcastRole", false));
- command.setSettingsRole(ServletRequestUtils.getBooleanParameter(request, "settingsRole", true));
- command.setTranscodeSchemeName(ServletRequestUtils.getStringParameter(request, "transcodeScheme", TranscodeScheme.OFF.name()));
- command.setShareRole(ServletRequestUtils.getBooleanParameter(request, "shareRole", false));
-
- userSettingsController.createUser(command);
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void deleteUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- User user = securityService.getCurrentUser(request);
- if (!user.isAdminRole()) {
- error(request, response, ErrorCode.NOT_AUTHORIZED, user.getUsername() + " is not authorized to delete users.");
- return;
- }
-
- try {
- String username = ServletRequestUtils.getRequiredStringParameter(request, "username");
- securityService.deleteUser(username);
-
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
-
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- } catch (Exception x) {
- LOG.warn("Error in REST API.", x);
- error(request, response, ErrorCode.GENERIC, getErrorMessage(x));
- }
- }
-
- public void getChatMessages(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- XMLBuilder builder = createXMLBuilder(request, response, true);
-
- long since = ServletRequestUtils.getLongParameter(request, "since", 0L);
-
- builder.add("chatMessages", false);
-
- for (ChatService.Message message : chatService.getMessages(0L).getMessages()) {
- long time = message.getDate().getTime();
- if (time > since) {
- builder.add("chatMessage", true, new Attribute("username", message.getUsername()),
- new Attribute("time", time), new Attribute("message", message.getContent()));
- }
- }
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void addChatMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- try {
- chatService.doAddMessage(ServletRequestUtils.getRequiredStringParameter(request, "message"), request);
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- }
- }
-
- public void getLyrics(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- String artist = request.getParameter("artist");
- String title = request.getParameter("title");
- LyricsInfo lyrics = lyricsService.getLyrics(artist, title);
-
- XMLBuilder builder = createXMLBuilder(request, response, true);
- AttributeSet attributes = new AttributeSet();
- attributes.add("artist", lyrics.getArtist());
- attributes.add("title", lyrics.getTitle());
- builder.add("lyrics", attributes, lyrics.getLyrics(), true);
-
- builder.endAll();
- response.getWriter().print(builder);
- }
-
- public void setRating(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request = wrapRequest(request);
- try {
- Integer rating = ServletRequestUtils.getRequiredIntParameter(request, "rating");
- if (rating == 0) {
- rating = null;
- }
-
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- MediaFile mediaFile = mediaFileService.getMediaFile(id);
- if (mediaFile == null) {
- error(request, response, ErrorCode.NOT_FOUND, "File not found: " + id);
- return;
- }
-
- String username = securityService.getCurrentUsername(request);
- ratingService.setRatingForUser(username, mediaFile, rating);
-
- XMLBuilder builder = createXMLBuilder(request, response, true).endAll();
- response.getWriter().print(builder);
- } catch (ServletRequestBindingException x) {
- error(request, response, ErrorCode.MISSING_PARAMETER, getErrorMessage(x));
- }
- }
-
- private HttpServletRequest wrapRequest(HttpServletRequest request) {
- return wrapRequest(request, false);
- }
-
- private HttpServletRequest wrapRequest(final HttpServletRequest request, boolean jukebox) {
- final String playerId = createPlayerIfNecessary(request, jukebox);
- return new HttpServletRequestWrapper(request) {
- @Override
- public String getParameter(String name) {
- // Returns the correct player to be used in PlayerService.getPlayer()
- if ("player".equals(name)) {
- return playerId;
- }
-
- // Support old style ID parameters.
- if ("id".equals(name)) {
- return mapId(request.getParameter("id"));
- }
-
- return super.getParameter(name);
- }
- };
- }
-
- private String mapId(String id) {
- if (id == null || id.startsWith(CoverArtController.ALBUM_COVERART_PREFIX) ||
- id.startsWith(CoverArtController.ARTIST_COVERART_PREFIX) || StringUtils.isNumeric(id)) {
- return id;
- }
-
- try {
- String path = StringUtil.utf8HexDecode(id);
- MediaFile mediaFile = mediaFileService.getMediaFile(path);
- return String.valueOf(mediaFile.getId());
- } catch (Exception x) {
- return id;
- }
- }
-
- private String getErrorMessage(Exception x) {
- if (x.getMessage() != null) {
- return x.getMessage();
- }
- return x.getClass().getSimpleName();
- }
-
- private void error(HttpServletRequest request, HttpServletResponse response, ErrorCode code, String message) throws IOException {
- XMLBuilder builder = createXMLBuilder(request, response, false);
- builder.add("error", true,
- new XMLBuilder.Attribute("code", code.getCode()),
- new XMLBuilder.Attribute("message", message));
- builder.end();
- response.getWriter().print(builder);
- }
-
- private XMLBuilder createXMLBuilder(HttpServletRequest request, HttpServletResponse response, boolean ok) throws IOException {
- String format = ServletRequestUtils.getStringParameter(request, "f", "xml");
- boolean json = "json".equals(format);
- boolean jsonp = "jsonp".equals(format);
- XMLBuilder builder;
-
- response.setCharacterEncoding(StringUtil.ENCODING_UTF8);
-
- if (json) {
- builder = XMLBuilder.createJSONBuilder();
- response.setContentType("application/json");
- } else if (jsonp) {
- builder = XMLBuilder.createJSONPBuilder(request.getParameter("callback"));
- response.setContentType("text/javascript");
- } else {
- builder = XMLBuilder.createXMLBuilder();
- response.setContentType("text/xml");
- }
-
- builder.preamble(StringUtil.ENCODING_UTF8);
- builder.add("subsonic-response", false,
- new Attribute("xmlns", "http://subsonic.org/restapi"),
- new Attribute("status", ok ? "ok" : "failed"),
- new Attribute("version", StringUtil.getRESTProtocolVersion()));
- return builder;
- }
-
- private String createPlayerIfNecessary(HttpServletRequest request, boolean jukebox) {
- String username = request.getRemoteUser();
- String clientId = request.getParameter("c");
- if (jukebox) {
- clientId += "-jukebox";
- }
-
- List<Player> players = playerService.getPlayersForUserAndClientId(username, clientId);
-
- // If not found, create it.
- if (players.isEmpty()) {
- Player player = new Player();
- player.setIpAddress(request.getRemoteAddr());
- player.setUsername(username);
- player.setClientId(clientId);
- player.setName(clientId);
- player.setTechnology(jukebox ? PlayerTechnology.JUKEBOX : PlayerTechnology.EXTERNAL_WITH_PLAYLIST);
- playerService.createPlayer(player);
- players = playerService.getPlayersForUserAndClientId(username, clientId);
- }
-
- // Return the player ID.
- return !players.isEmpty() ? players.get(0).getId() : null;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-
- public void setDownloadController(DownloadController downloadController) {
- this.downloadController = downloadController;
- }
-
- public void setCoverArtController(CoverArtController coverArtController) {
- this.coverArtController = coverArtController;
- }
-
- public void setUserSettingsController(UserSettingsController userSettingsController) {
- this.userSettingsController = userSettingsController;
- }
-
- public void setLeftController(LeftController leftController) {
- this.leftController = leftController;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setStreamController(StreamController streamController) {
- this.streamController = streamController;
- }
-
- public void setChatService(ChatService chatService) {
- this.chatService = chatService;
- }
-
- public void setHomeController(HomeController homeController) {
- this.homeController = homeController;
- }
-
- public void setLyricsService(LyricsService lyricsService) {
- this.lyricsService = lyricsService;
- }
-
- public void setPlayQueueService(PlayQueueService playQueueService) {
- this.playQueueService = playQueueService;
- }
-
- public void setJukeboxService(JukeboxService jukeboxService) {
- this.jukeboxService = jukeboxService;
- }
-
- public void setAudioScrobblerService(AudioScrobblerService audioScrobblerService) {
- this.audioScrobblerService = audioScrobblerService;
- }
-
- public void setPodcastService(PodcastService podcastService) {
- this.podcastService = podcastService;
- }
-
- public void setRatingService(RatingService ratingService) {
- this.ratingService = ratingService;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-
- public void setShareService(ShareService shareService) {
- this.shareService = shareService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setAvatarController(AvatarController avatarController) {
- this.avatarController = avatarController;
- }
-
- public void setArtistDao(ArtistDao artistDao) {
- this.artistDao = artistDao;
- }
-
- public void setAlbumDao(AlbumDao albumDao) {
- this.albumDao = albumDao;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- public static enum ErrorCode {
-
- GENERIC(0, "A generic error."),
- MISSING_PARAMETER(10, "Required parameter is missing."),
- PROTOCOL_MISMATCH_CLIENT_TOO_OLD(20, "Incompatible Subsonic REST protocol version. Client must upgrade."),
- PROTOCOL_MISMATCH_SERVER_TOO_OLD(30, "Incompatible Subsonic REST protocol version. Server must upgrade."),
- NOT_AUTHENTICATED(40, "Wrong username or password."),
- NOT_AUTHORIZED(50, "User is not authorized for the given operation."),
- NOT_LICENSED(60, "The trial period for the Subsonic server is over. Please donate to get a license key. Visit subsonic.org for details."),
- NOT_FOUND(70, "Requested data was not found.");
-
- private final int code;
- private final String message;
-
- ErrorCode(int code, String message) {
- this.code = code;
- this.message = message;
- }
-
- public int getCode() {
- return code;
- }
-
- public String getMessage() {
- return message;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RandomPlayQueueController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RandomPlayQueueController.java
deleted file mode 100644
index a3738684..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RandomPlayQueueController.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.RandomSearchCriteria;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SearchService;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for the creating a random play queue.
- *
- * @author Sindre Mehus
- */
-public class RandomPlayQueueController extends ParameterizableViewController {
-
- private PlayerService playerService;
- private List<ReloadFrame> reloadFrames;
- private SearchService searchService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- int size = ServletRequestUtils.getRequiredIntParameter(request, "size");
- String genre = request.getParameter("genre");
- if (StringUtils.equalsIgnoreCase("any", genre)) {
- genre = null;
- }
-
- Integer fromYear = null;
- Integer toYear = null;
-
- String year = request.getParameter("year");
- if (!StringUtils.equalsIgnoreCase("any", year)) {
- String[] tmp = StringUtils.split(year);
- fromYear = Integer.parseInt(tmp[0]);
- toYear = Integer.parseInt(tmp[1]);
- }
-
- Integer musicFolderId = ServletRequestUtils.getRequiredIntParameter(request, "musicFolderId");
- if (musicFolderId == -1) {
- musicFolderId = null;
- }
-
- Player player = playerService.getPlayer(request, response);
- PlayQueue playQueue = player.getPlayQueue();
-
- RandomSearchCriteria criteria = new RandomSearchCriteria(size, genre, fromYear, toYear, musicFolderId);
- playQueue.addFiles(false, searchService.getRandomSongs(criteria));
-
- if (request.getParameter("autoRandom") != null) {
- playQueue.setRandomSearchCriteria(criteria);
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("reloadFrames", reloadFrames);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setReloadFrames(List<ReloadFrame> reloadFrames) {
- this.reloadFrames = reloadFrames;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ReloadFrame.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ReloadFrame.java
deleted file mode 100644
index 093b7fa1..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ReloadFrame.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-/**
- * Used in subsonic-servlet.xml to specify frame reloading.
- *
- * @author Sindre Mehus
- */
-public class ReloadFrame {
- private String frame;
- private String view;
-
- public ReloadFrame() {}
-
- public ReloadFrame(String frame, String view) {
- this.frame = frame;
- this.view = view;
- }
-
- public String getFrame() {
- return frame;
- }
-
- public void setFrame(String frame) {
- this.frame = frame;
- }
-
- public String getView() {
- return view;
- }
-
- public void setView(String view) {
- this.view = view;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RightController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RightController.java
deleted file mode 100644
index 405c2dc7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/RightController.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.dao.UserDao;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.SecurityService;
-
-/**
- * Controller for the right frame.
- *
- * @author Sindre Mehus
- */
-public class RightController extends ParameterizableViewController {
-
- private SettingsService settingsService;
- private SecurityService securityService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
- ModelAndView result = super.handleRequestInternal(request, response);
-
- UserSettings userSettings = settingsService.getUserSettings(securityService.getCurrentUsername(request));
- map.put("showNowPlaying", userSettings.isShowNowPlayingEnabled());
- map.put("showChat", userSettings.isShowChatEnabled());
- map.put("user", securityService.getCurrentUser(request));
-
- result.addObject("model", map);
- return result;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SearchController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SearchController.java
deleted file mode 100644
index 387ec7db..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SearchController.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang.StringUtils;
-import org.springframework.validation.BindException;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.SimpleFormController;
-
-import net.sourceforge.subsonic.command.SearchCommand;
-import net.sourceforge.subsonic.domain.SearchCriteria;
-import net.sourceforge.subsonic.domain.SearchResult;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.SearchService;
-
-/**
- * Controller for the search page.
- *
- * @author Sindre Mehus
- */
-public class SearchController extends SimpleFormController {
-
- private static final int MATCH_COUNT = 25;
-
- private SecurityService securityService;
- private SettingsService settingsService;
- private PlayerService playerService;
- private SearchService searchService;
-
- @Override
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- return new SearchCommand();
- }
-
- @Override
- protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object com, BindException errors)
- throws Exception {
- SearchCommand command = (SearchCommand) com;
-
- User user = securityService.getCurrentUser(request);
- UserSettings userSettings = settingsService.getUserSettings(user.getUsername());
- command.setUser(user);
- command.setPartyModeEnabled(userSettings.isPartyModeEnabled());
-
- String any = StringUtils.trimToNull(command.getQuery());
-
- if (any != null) {
-
- SearchCriteria criteria = new SearchCriteria();
- criteria.setCount(MATCH_COUNT);
- criteria.setQuery(any);
-
- SearchResult artists = searchService.search(criteria, SearchService.IndexType.ARTIST);
- command.setArtists(artists.getMediaFiles());
-
- SearchResult albums = searchService.search(criteria, SearchService.IndexType.ALBUM);
- command.setAlbums(albums.getMediaFiles());
-
- SearchResult songs = searchService.search(criteria, SearchService.IndexType.SONG);
- command.setSongs(songs.getMediaFiles());
-
- command.setPlayer(playerService.getPlayer(request, response));
- }
-
- return new ModelAndView(getSuccessView(), errors.getModel());
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetMusicFileInfoController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetMusicFileInfoController.java
deleted file mode 100644
index 8b3ebca7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetMusicFileInfoController.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.util.*;
-import net.sourceforge.subsonic.filter.ParameterDecodingFilter;
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.view.*;
-import org.springframework.web.servlet.mvc.*;
-
-import javax.servlet.http.*;
-
-/**
- * Controller for updating music file metadata.
- *
- * @author Sindre Mehus
- */
-public class SetMusicFileInfoController extends AbstractController {
-
- private MediaFileService mediaFileService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String path = request.getParameter("path");
- String action = request.getParameter("action");
-
- MediaFile mediaFile = mediaFileService.getMediaFile(path);
-
- if ("comment".equals(action)) {
- mediaFile.setComment(StringUtil.toHtml(request.getParameter("comment")));
- mediaFileService.updateMediaFile(mediaFile);
- }
-
- String url = "main.view?path" + ParameterDecodingFilter.PARAM_SUFFIX + "=" + StringUtil.utf8HexEncode(path);
- return new ModelAndView(new RedirectView(url));
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetRatingController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetRatingController.java
deleted file mode 100644
index aaeaa4a4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SetRatingController.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.util.*;
-import net.sourceforge.subsonic.filter.ParameterDecodingFilter;
-import org.springframework.web.bind.*;
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.mvc.*;
-import org.springframework.web.servlet.view.*;
-
-import javax.servlet.http.*;
-
-/**
- * Controller for updating music file ratings.
- *
- * @author Sindre Mehus
- */
-public class SetRatingController extends AbstractController {
-
- private RatingService ratingService;
- private SecurityService securityService;
- private MediaFileService mediaFileService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String path = request.getParameter("path");
- Integer rating = ServletRequestUtils.getIntParameter(request, "rating");
- if (rating == 0) {
- rating = null;
- }
-
- MediaFile mediaFile = mediaFileService.getMediaFile(path);
- String username = securityService.getCurrentUsername(request);
- ratingService.setRatingForUser(username, mediaFile, rating);
-
- String url = "main.view?path" + ParameterDecodingFilter.PARAM_SUFFIX + "=" + StringUtil.utf8HexEncode(path);
- return new ModelAndView(new RedirectView(url));
- }
-
- public void setRatingService(RatingService ratingService) {
- this.ratingService = ratingService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SettingsController.java
deleted file mode 100644
index ed0c21c5..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/SettingsController.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.service.*;
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.view.*;
-import org.springframework.web.servlet.mvc.*;
-
-import javax.servlet.http.*;
-
-/**
- * Controller for the main settings page.
- *
- * @author Sindre Mehus
- */
-public class SettingsController extends AbstractController {
-
- private SecurityService securityService;
-
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- User user = securityService.getCurrentUser(request);
-
- // Redirect to music folder settings if admin.
- String view = user.isAdminRole() ? "musicFolderSettings.view" : "personalSettings.view";
-
- return new ModelAndView(new RedirectView(view));
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareManagementController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareManagementController.java
deleted file mode 100644
index de2ea764..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareManagementController.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.*;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
-
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.Share;
-
-/**
- * Controller for sharing music on Twitter, Facebook etc.
- *
- * @author Sindre Mehus
- */
-public class ShareManagementController extends MultiActionController {
-
- private MediaFileService mediaFileService;
- private SettingsService settingsService;
- private ShareService shareService;
- private PlayerService playerService;
- private SecurityService securityService;
-
- public ModelAndView createShare(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- List<MediaFile> files = getMediaFiles(request);
- MediaFile dir = null;
- if (!files.isEmpty()) {
- dir = files.get(0);
- if (!dir.isAlbum()) {
- dir = mediaFileService.getParentOf(dir);
- }
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("urlRedirectionEnabled", settingsService.isUrlRedirectionEnabled());
- map.put("dir", dir);
- map.put("user", securityService.getCurrentUser(request));
- Share share = shareService.createShare(request, files);
- map.put("playUrl", shareService.getShareUrl(share));
-
- return new ModelAndView("createShare", "model", map);
- }
-
- private List<MediaFile> getMediaFiles(HttpServletRequest request) throws IOException {
- String dir = request.getParameter("dir");
- String playerId = request.getParameter("player");
-
- List<MediaFile> result = new ArrayList<MediaFile>();
-
- if (dir != null) {
- MediaFile album = mediaFileService.getMediaFile(dir);
- int[] indexes = ServletRequestUtils.getIntParameters(request, "i");
- if (indexes.length == 0) {
- return Arrays.asList(album);
- }
- List<MediaFile> children = mediaFileService.getChildrenOf(album, true, true, true);
- for (int index : indexes) {
- result.add(children.get(index));
- }
- } else if (playerId != null) {
- Player player = playerService.getPlayerById(playerId);
- PlayQueue playQueue = player.getPlayQueue();
- List<MediaFile> result1;
- synchronized (playQueue) {
- result1 = playQueue.getFiles();
- }
- result = result1;
- }
-
- return result;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setShareService(ShareService shareService) {
- this.shareService = shareService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareSettingsController.java
deleted file mode 100644
index 2b8a958a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/ShareSettingsController.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Share;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.ShareService;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for the page used to administrate the set of shared media.
- *
- * @author Sindre Mehus
- */
-public class ShareSettingsController extends ParameterizableViewController {
-
- private ShareService shareService;
- private SecurityService securityService;
- private MediaFileService mediaFileService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
-
- if (isFormSubmission(request)) {
- String error = handleParameters(request);
- map.put("error", error);
- }
-
- ModelAndView result = super.handleRequestInternal(request, response);
- map.put("shareBaseUrl", shareService.getShareBaseUrl());
- map.put("shareInfos", getShareInfos(request));
- map.put("user", securityService.getCurrentUser(request));
-
- result.addObject("model", map);
- return result;
- }
-
- /**
- * Determine if the given request represents a form submission.
- *
- * @param request current HTTP request
- * @return if the request represents a form submission
- */
- private boolean isFormSubmission(HttpServletRequest request) {
- return "POST".equals(request.getMethod());
- }
-
- private String handleParameters(HttpServletRequest request) {
- User user = securityService.getCurrentUser(request);
- for (Share share : shareService.getSharesForUser(user)) {
- int id = share.getId();
-
- String description = getParameter(request, "description", id);
- boolean delete = getParameter(request, "delete", id) != null;
- String expireIn = getParameter(request, "expireIn", id);
-
- if (delete) {
- shareService.deleteShare(id);
- } else {
- if (expireIn != null) {
- share.setExpires(parseExpireIn(expireIn));
- }
- share.setDescription(description);
- shareService.updateShare(share);
- }
- }
-
- return null;
- }
-
- private List<ShareInfo> getShareInfos(HttpServletRequest request) {
- List<ShareInfo> result = new ArrayList<ShareInfo>();
- User user = securityService.getCurrentUser(request);
- for (Share share : shareService.getSharesForUser(user)) {
- List<MediaFile> files = shareService.getSharedFiles(share.getId());
- if (!files.isEmpty()) {
- MediaFile file = files.get(0);
- result.add(new ShareInfo(share, file.isDirectory() ? file : mediaFileService.getParentOf(file)));
- }
- }
- return result;
- }
-
-
- private String getParameter(HttpServletRequest request, String name, int id) {
- return StringUtils.trimToNull(request.getParameter(name + "[" + id + "]"));
- }
-
- private Date parseExpireIn(String expireIn) {
- int days = Integer.parseInt(expireIn);
- if (days == 0) {
- return null;
- }
-
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.DAY_OF_YEAR, days);
- return calendar.getTime();
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setShareService(ShareService shareService) {
- this.shareService = shareService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public static class ShareInfo {
- private final Share share;
- private final MediaFile dir;
-
- public ShareInfo(Share share, MediaFile dir) {
- this.share = share;
- this.dir = dir;
- }
-
- public Share getShare() {
- return share;
- }
-
- public MediaFile getDir() {
- return dir;
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StarredController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StarredController.java
deleted file mode 100644
index 2da8b5ad..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StarredController.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for showing a user's starred items.
- *
- * @author Sindre Mehus
- */
-public class StarredController extends ParameterizableViewController {
-
- private PlayerService playerService;
- private MediaFileDao mediaFileDao;
- private SecurityService securityService;
- private SettingsService settingsService;
- private MediaFileService mediaFileService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- User user = securityService.getCurrentUser(request);
- String username = user.getUsername();
- UserSettings userSettings = settingsService.getUserSettings(username);
-
- List<MediaFile> artists = mediaFileDao.getStarredDirectories(0, Integer.MAX_VALUE, username);
- List<MediaFile> albums = mediaFileDao.getStarredAlbums(0, Integer.MAX_VALUE, username);
- List<MediaFile> songs = mediaFileDao.getStarredFiles(0, Integer.MAX_VALUE, username);
- mediaFileService.populateStarredDate(artists, username);
- mediaFileService.populateStarredDate(albums, username);
- mediaFileService.populateStarredDate(songs, username);
-
- map.put("user", user);
- map.put("partyModeEnabled", userSettings.isPartyModeEnabled());
- map.put("player", playerService.getPlayer(request, response));
- map.put("artists", artists);
- map.put("albums", albums);
- map.put("songs", songs);
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusChartController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusChartController.java
deleted file mode 100644
index 878b8ae8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusChartController.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.service.*;
-import org.jfree.chart.*;
-import org.jfree.chart.axis.*;
-import org.jfree.chart.plot.*;
-import org.jfree.chart.renderer.xy.*;
-import org.jfree.data.*;
-import org.jfree.data.time.*;
-import org.springframework.web.servlet.*;
-
-import javax.servlet.http.*;
-import java.awt.*;
-import java.util.*;
-import java.util.List;
-
-/**
- * Controller for generating a chart showing bitrate vs time.
- *
- * @author Sindre Mehus
- */
-public class StatusChartController extends AbstractChartController {
-
- private StatusService statusService;
-
- public static final int IMAGE_WIDTH = 350;
- public static final int IMAGE_HEIGHT = 150;
-
- public synchronized ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String type = request.getParameter("type");
- int index = Integer.parseInt(request.getParameter("index"));
-
- List<TransferStatus> statuses = Collections.emptyList();
- if ("stream".equals(type)) {
- statuses = statusService.getAllStreamStatuses();
- } else if ("download".equals(type)) {
- statuses = statusService.getAllDownloadStatuses();
- } else if ("upload".equals(type)) {
- statuses = statusService.getAllUploadStatuses();
- }
-
- if (index < 0 || index >= statuses.size()) {
- return null;
- }
- TransferStatus status = statuses.get(index);
-
- TimeSeries series = new TimeSeries("Kbps", Millisecond.class);
- TransferStatus.SampleHistory history = status.getHistory();
- long to = System.currentTimeMillis();
- long from = to - status.getHistoryLengthMillis();
- Range range = new DateRange(from, to);
-
- if (!history.isEmpty()) {
-
- TransferStatus.Sample previous = history.get(0);
-
- for (int i = 1; i < history.size(); i++) {
- TransferStatus.Sample sample = history.get(i);
-
- long elapsedTimeMilis = sample.getTimestamp() - previous.getTimestamp();
- long bytesStreamed = Math.max(0L, sample.getBytesTransfered() - previous.getBytesTransfered());
-
- double kbps = (8.0 * bytesStreamed / 1024.0) / (elapsedTimeMilis / 1000.0);
- series.addOrUpdate(new Millisecond(new Date(sample.getTimestamp())), kbps);
-
- previous = sample;
- }
- }
-
- // Compute moving average.
- series = MovingAverage.createMovingAverage(series, "Kbps", 20000, 5000);
-
- // Find min and max values.
- double min = 100;
- double max = 250;
- for (Object obj : series.getItems()) {
- TimeSeriesDataItem item = (TimeSeriesDataItem) obj;
- double value = item.getValue().doubleValue();
- if (item.getPeriod().getFirstMillisecond() > from) {
- min = Math.min(min, value);
- max = Math.max(max, value);
- }
- }
-
- // Add 10% to max value.
- max *= 1.1D;
-
- // Subtract 10% from min value.
- min *= 0.9D;
-
- TimeSeriesCollection dataset = new TimeSeriesCollection();
- dataset.addSeries(series);
- JFreeChart chart = ChartFactory.createTimeSeriesChart(null, null, null, dataset, false, false, false);
- XYPlot plot = (XYPlot) chart.getPlot();
-
- plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
- Paint background = new GradientPaint(0, 0, Color.lightGray, 0, IMAGE_HEIGHT, Color.white);
- plot.setBackgroundPaint(background);
-
- XYItemRenderer renderer = plot.getRendererForDataset(dataset);
- renderer.setSeriesPaint(0, Color.blue.darker());
- renderer.setSeriesStroke(0, new BasicStroke(2f));
-
- // Set theme-specific colors.
- Color bgColor = getBackground(request);
- Color fgColor = getForeground(request);
-
- chart.setBackgroundPaint(bgColor);
-
- ValueAxis domainAxis = plot.getDomainAxis();
- domainAxis.setRange(range);
- domainAxis.setTickLabelPaint(fgColor);
- domainAxis.setTickMarkPaint(fgColor);
- domainAxis.setAxisLinePaint(fgColor);
-
- ValueAxis rangeAxis = plot.getRangeAxis();
- rangeAxis.setRange(new Range(min, max));
- rangeAxis.setTickLabelPaint(fgColor);
- rangeAxis.setTickMarkPaint(fgColor);
- rangeAxis.setAxisLinePaint(fgColor);
-
- ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart, IMAGE_WIDTH, IMAGE_HEIGHT);
-
- return null;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusController.java
deleted file mode 100644
index 964e7810..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StatusController.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.service.StatusService;
-import net.sourceforge.subsonic.util.FileUtil;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-import org.springframework.web.servlet.support.RequestContextUtils;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Controller for the status page.
- *
- * @author Sindre Mehus
- */
-public class StatusController extends ParameterizableViewController {
-
- private StatusService statusService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- List<TransferStatus> streamStatuses = statusService.getAllStreamStatuses();
- List<TransferStatus> downloadStatuses = statusService.getAllDownloadStatuses();
- List<TransferStatus> uploadStatuses = statusService.getAllUploadStatuses();
-
- Locale locale = RequestContextUtils.getLocale(request);
- List<TransferStatusHolder> transferStatuses = new ArrayList<TransferStatusHolder>();
-
- for (int i = 0; i < streamStatuses.size(); i++) {
- long minutesAgo = streamStatuses.get(i).getMillisSinceLastUpdate() / 1000L / 60L;
- if (minutesAgo < 60L) {
- transferStatuses.add(new TransferStatusHolder(streamStatuses.get(i), true, false, false, i, locale));
- }
- }
- for (int i = 0; i < downloadStatuses.size(); i++) {
- transferStatuses.add(new TransferStatusHolder(downloadStatuses.get(i), false, true, false, i, locale));
- }
- for (int i = 0; i < uploadStatuses.size(); i++) {
- transferStatuses.add(new TransferStatusHolder(uploadStatuses.get(i), false, false, true, i, locale));
- }
-
- map.put("transferStatuses", transferStatuses);
- map.put("chartWidth", StatusChartController.IMAGE_WIDTH);
- map.put("chartHeight", StatusChartController.IMAGE_HEIGHT);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public static class TransferStatusHolder {
- private TransferStatus transferStatus;
- private boolean isStream;
- private boolean isDownload;
- private boolean isUpload;
- private int index;
- private Locale locale;
-
- public TransferStatusHolder(TransferStatus transferStatus, boolean isStream, boolean isDownload, boolean isUpload,
- int index, Locale locale) {
- this.transferStatus = transferStatus;
- this.isStream = isStream;
- this.isDownload = isDownload;
- this.isUpload = isUpload;
- this.index = index;
- this.locale = locale;
- }
-
- public boolean isStream() {
- return isStream;
- }
-
- public boolean isDownload() {
- return isDownload;
- }
-
- public boolean isUpload() {
- return isUpload;
- }
-
- public int getIndex() {
- return index;
- }
-
- public Player getPlayer() {
- return transferStatus.getPlayer();
- }
-
- public String getPlayerType() {
- Player player = transferStatus.getPlayer();
- return player == null ? null : player.getType();
- }
-
- public String getUsername() {
- Player player = transferStatus.getPlayer();
- return player == null ? null : player.getUsername();
- }
-
- public String getPath() {
- return FileUtil.getShortPath(transferStatus.getFile());
- }
-
- public String getBytes() {
- return StringUtil.formatBytes(transferStatus.getBytesTransfered(), locale);
- }
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StreamController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StreamController.java
deleted file mode 100644
index a40f5da4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/StreamController.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.awt.Dimension;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.SearchService;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.math.LongRange;
-import org.springframework.web.bind.ServletRequestBindingException;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.Controller;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.VideoTranscodingSettings;
-import net.sourceforge.subsonic.io.PlayQueueInputStream;
-import net.sourceforge.subsonic.io.RangeOutputStream;
-import net.sourceforge.subsonic.io.ShoutCastOutputStream;
-import net.sourceforge.subsonic.service.AudioScrobblerService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.StatusService;
-import net.sourceforge.subsonic.service.TranscodingService;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.Util;
-
-/**
- * A controller which streams the content of a {@link net.sourceforge.subsonic.domain.PlayQueue} to a remote
- * {@link Player}.
- *
- * @author Sindre Mehus
- */
-public class StreamController implements Controller {
-
- private static final Logger LOG = Logger.getLogger(StreamController.class);
-
- private StatusService statusService;
- private PlayerService playerService;
- private PlaylistService playlistService;
- private SecurityService securityService;
- private SettingsService settingsService;
- private TranscodingService transcodingService;
- private AudioScrobblerService audioScrobblerService;
- private MediaFileService mediaFileService;
- private SearchService searchService;
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- TransferStatus status = null;
- PlayQueueInputStream in = null;
- Player player = playerService.getPlayer(request, response, false, true);
- User user = securityService.getUserByName(player.getUsername());
-
- try {
-
- if (!user.isStreamRole()) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN, "Streaming is forbidden for user " + user.getUsername());
- return null;
- }
-
- // If "playlist" request parameter is set, this is a Podcast request. In that case, create a separate
- // play queue (in order to support multiple parallel Podcast streams).
- Integer playlistId = ServletRequestUtils.getIntParameter(request, "playlist");
- boolean isPodcast = playlistId != null;
- if (isPodcast) {
- PlayQueue playQueue = new PlayQueue();
- playQueue.addFiles(false, playlistService.getFilesInPlaylist(playlistId));
- player.setPlayQueue(playQueue);
- Util.setContentLength(response, playQueue.length());
- LOG.info("Incoming Podcast request for playlist " + playlistId);
- }
-
- String contentType = StringUtil.getMimeType(request.getParameter("suffix"));
- response.setContentType(contentType);
-
- String preferredTargetFormat = request.getParameter("format");
- Integer maxBitRate = ServletRequestUtils.getIntParameter(request, "maxBitRate");
- if (Integer.valueOf(0).equals(maxBitRate)) {
- maxBitRate = null;
- }
-
- VideoTranscodingSettings videoTranscodingSettings = null;
-
- // Is this a request for a single file (typically from the embedded Flash player)?
- // In that case, create a separate playlist (in order to support multiple parallel streams).
- // Also, enable partial download (HTTP byte range).
- MediaFile file = getSingleFile(request);
- boolean isSingleFile = file != null;
- LongRange range = null;
-
- if (isSingleFile) {
- PlayQueue playQueue = new PlayQueue();
- playQueue.addFiles(true, file);
- player.setPlayQueue(playQueue);
-
- if (!file.isVideo()) {
- response.setIntHeader("ETag", file.getId());
- response.setHeader("Accept-Ranges", "bytes");
- }
-
- TranscodingService.Parameters parameters = transcodingService.getParameters(file, player, maxBitRate, preferredTargetFormat, videoTranscodingSettings);
- long fileLength = getFileLength(parameters);
- boolean isConversion = parameters.isDownsample() || parameters.isTranscode();
- boolean estimateContentLength = ServletRequestUtils.getBooleanParameter(request, "estimateContentLength", false);
-
- range = getRange(request, file);
- if (range != null) {
- LOG.info("Got range: " + range);
- response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
- Util.setContentLength(response, fileLength - range.getMinimumLong());
- long firstBytePos = range.getMinimumLong();
- long lastBytePos = fileLength - 1;
- response.setHeader("Content-Range", "bytes " + firstBytePos + "-" + lastBytePos + "/" + fileLength);
- } else if (!isConversion || estimateContentLength) {
- Util.setContentLength(response, fileLength);
- }
-
- String transcodedSuffix = transcodingService.getSuffix(player, file, preferredTargetFormat);
- response.setContentType(StringUtil.getMimeType(transcodedSuffix));
-
- if (file.isVideo()) {
- videoTranscodingSettings = createVideoTranscodingSettings(file, request);
- }
- }
-
- if (request.getMethod().equals("HEAD")) {
- return null;
- }
-
- // Terminate any other streams to this player.
- if (!isPodcast && !isSingleFile) {
- for (TransferStatus streamStatus : statusService.getStreamStatusesForPlayer(player)) {
- if (streamStatus.isActive()) {
- streamStatus.terminate();
- }
- }
- }
-
- status = statusService.createStreamStatus(player);
-
- in = new PlayQueueInputStream(player, status, maxBitRate, preferredTargetFormat, videoTranscodingSettings, transcodingService,
- audioScrobblerService, mediaFileService, searchService);
- OutputStream out = RangeOutputStream.wrap(response.getOutputStream(), range);
-
- // Enabled SHOUTcast, if requested.
- boolean isShoutCastRequested = "1".equals(request.getHeader("icy-metadata"));
- if (isShoutCastRequested && !isSingleFile) {
- response.setHeader("icy-metaint", "" + ShoutCastOutputStream.META_DATA_INTERVAL);
- response.setHeader("icy-notice1", "This stream is served using Subsonic");
- response.setHeader("icy-notice2", "Subsonic - Free media streamer - subsonic.org");
- response.setHeader("icy-name", "Subsonic");
- response.setHeader("icy-genre", "Mixed");
- response.setHeader("icy-url", "http://subsonic.org/");
- out = new ShoutCastOutputStream(out, player.getPlayQueue(), settingsService);
- }
-
- final int BUFFER_SIZE = 2048;
- byte[] buf = new byte[BUFFER_SIZE];
-
- while (true) {
-
- // Check if stream has been terminated.
- if (status.terminated()) {
- return null;
- }
-
- if (player.getPlayQueue().getStatus() == PlayQueue.Status.STOPPED) {
- if (isPodcast || isSingleFile) {
- break;
- } else {
- sendDummy(buf, out);
- }
- } else {
-
- int n = in.read(buf);
- if (n == -1) {
- if (isPodcast || isSingleFile) {
- break;
- } else {
- sendDummy(buf, out);
- }
- } else {
- out.write(buf, 0, n);
- }
- }
- }
-
- } finally {
- if (status != null) {
- securityService.updateUserByteCounts(user, status.getBytesTransfered(), 0L, 0L);
- statusService.removeStreamStatus(status);
- }
- IOUtils.closeQuietly(in);
- }
- return null;
- }
-
- private MediaFile getSingleFile(HttpServletRequest request) throws ServletRequestBindingException {
- String path = request.getParameter("path");
- if (path != null) {
- return mediaFileService.getMediaFile(path);
- }
- Integer id = ServletRequestUtils.getIntParameter(request, "id");
- if (id != null) {
- return mediaFileService.getMediaFile(id);
- }
- return null;
- }
-
- private long getFileLength(TranscodingService.Parameters parameters) {
- MediaFile file = parameters.getMediaFile();
-
- if (!parameters.isDownsample() && !parameters.isTranscode()) {
- return file.getFileSize();
- }
- Integer duration = file.getDurationSeconds();
- Integer maxBitRate = parameters.getMaxBitRate();
-
- if (duration == null) {
- LOG.warn("Unknown duration for " + file + ". Unable to estimate transcoded size.");
- return file.getFileSize();
- }
-
- if (maxBitRate == null) {
- LOG.error("Unknown bit rate for " + file + ". Unable to estimate transcoded size.");
- return file.getFileSize();
- }
-
- return duration * maxBitRate * 1000L / 8L;
- }
-
- private LongRange getRange(HttpServletRequest request, MediaFile file) {
-
- // First, look for "Range" HTTP header.
- LongRange range = StringUtil.parseRange(request.getHeader("Range"));
- if (range != null) {
- return range;
- }
-
- // Second, look for "offsetSeconds" request parameter.
- String offsetSeconds = request.getParameter("offsetSeconds");
- range = parseAndConvertOffsetSeconds(offsetSeconds, file);
- if (range != null) {
- return range;
- }
-
- return null;
- }
-
- private LongRange parseAndConvertOffsetSeconds(String offsetSeconds, MediaFile file) {
- if (offsetSeconds == null) {
- return null;
- }
-
- try {
- Integer duration = file.getDurationSeconds();
- Long fileSize = file.getFileSize();
- if (duration == null || fileSize == null) {
- return null;
- }
- float offset = Float.parseFloat(offsetSeconds);
-
- // Convert from time offset to byte offset.
- long byteOffset = (long) (fileSize * (offset / duration));
- return new LongRange(byteOffset, Long.MAX_VALUE);
-
- } catch (Exception x) {
- LOG.error("Failed to parse and convert time offset: " + offsetSeconds, x);
- return null;
- }
- }
-
- private VideoTranscodingSettings createVideoTranscodingSettings(MediaFile file, HttpServletRequest request) throws ServletRequestBindingException {
- Integer existingWidth = file.getWidth();
- Integer existingHeight = file.getHeight();
- Integer maxBitRate = ServletRequestUtils.getIntParameter(request, "maxBitRate");
- int timeOffset = ServletRequestUtils.getIntParameter(request, "timeOffset", 0);
-
- Dimension dim = getRequestedVideoSize(request.getParameter("size"));
- if (dim == null) {
- dim = getSuitableVideoSize(existingWidth, existingHeight, maxBitRate);
- }
-
- return new VideoTranscodingSettings(dim.width, dim.height, timeOffset);
- }
-
- protected Dimension getRequestedVideoSize(String sizeSpec) {
- if (sizeSpec == null) {
- return null;
- }
-
- Pattern pattern = Pattern.compile("^(\\d+)x(\\d+)$");
- Matcher matcher = pattern.matcher(sizeSpec);
- if (matcher.find()) {
- int w = Integer.parseInt(matcher.group(1));
- int h = Integer.parseInt(matcher.group(2));
- if (w >= 0 && h >= 0 && w <= 2000 && h <= 2000) {
- return new Dimension(w, h);
- }
- }
- return null;
- }
-
- protected Dimension getSuitableVideoSize(Integer existingWidth, Integer existingHeight, Integer maxBitRate) {
- if (maxBitRate == null) {
- return new Dimension(320, 240);
- }
-
- int w, h;
- if (maxBitRate <= 600) {
- w = 320; h = 240;
- } else if (maxBitRate <= 1000) {
- w = 480; h = 360;
- } else {
- w = 640; h = 480;
- }
-
- if (existingWidth == null || existingHeight == null) {
- return new Dimension(w, h);
- }
-
- if (existingWidth < w || existingHeight < h) {
- return new Dimension(even(existingWidth), even(existingHeight));
- }
-
- double aspectRate = existingWidth.doubleValue() / existingHeight.doubleValue();
- w = (int) Math.round(h * aspectRate);
-
- return new Dimension(even(w), even(h));
- }
-
- // Make sure width and height are multiples of two, as some versions of ffmpeg require it.
- private int even(int size) {
- return size + (size % 2);
- }
-
- /**
- * Feed the other end with some dummy data to keep it from reconnecting.
- */
- private void sendDummy(byte[] buf, OutputStream out) throws IOException {
- try {
- Thread.sleep(2000);
- } catch (InterruptedException x) {
- LOG.warn("Interrupted in sleep.", x);
- }
- Arrays.fill(buf, (byte) 0xFF);
- out.write(buf);
- out.flush();
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-
- public void setAudioScrobblerService(AudioScrobblerService audioScrobblerService) {
- this.audioScrobblerService = audioScrobblerService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TopController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TopController.java
deleted file mode 100644
index 800aef0e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TopController.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.service.VersionService;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Controller for the top frame.
- *
- * @author Sindre Mehus
- */
-public class TopController extends ParameterizableViewController {
-
- private SettingsService settingsService;
- private VersionService versionService;
- private SecurityService securityService;
-
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
-
- List<MusicFolder> allMusicFolders = settingsService.getAllMusicFolders();
- User user = securityService.getCurrentUser(request);
-
- map.put("user", user);
- map.put("musicFoldersExist", !allMusicFolders.isEmpty());
- map.put("brand", settingsService.getBrand());
- map.put("licensed", settingsService.isLicenseValid());
-
- UserSettings userSettings = settingsService.getUserSettings(user.getUsername());
- if (userSettings.isFinalVersionNotificationEnabled() && versionService.isNewFinalVersionAvailable()) {
- map.put("newVersionAvailable", true);
- map.put("latestVersion", versionService.getLatestFinalVersion());
-
- } else if (userSettings.isBetaVersionNotificationEnabled() && versionService.isNewBetaVersionAvailable()) {
- map.put("newVersionAvailable", true);
- map.put("latestVersion", versionService.getLatestBetaVersion());
- }
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setVersionService(VersionService versionService) {
- this.versionService = versionService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TranscodingSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TranscodingSettingsController.java
deleted file mode 100644
index 8bd87408..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/TranscodingSettingsController.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.Transcoding;
-import net.sourceforge.subsonic.service.TranscodingService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Controller for the page used to administrate the set of transcoding configurations.
- *
- * @author Sindre Mehus
- */
-public class TranscodingSettingsController extends ParameterizableViewController {
-
- private TranscodingService transcodingService;
- private SettingsService settingsService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
-
- if (isFormSubmission(request)) {
- handleParameters(request, map);
- }
-
- ModelAndView result = super.handleRequestInternal(request, response);
- map.put("transcodings", transcodingService.getAllTranscodings());
- map.put("transcodeDirectory", transcodingService.getTranscodeDirectory());
- map.put("brand", settingsService.getBrand());
-
- result.addObject("model", map);
- return result;
- }
-
- /**
- * Determine if the given request represents a form submission.
- *
- * @param request current HTTP request
- * @return if the request represents a form submission
- */
- private boolean isFormSubmission(HttpServletRequest request) {
- return "POST".equals(request.getMethod());
- }
-
- private void handleParameters(HttpServletRequest request, Map<String, Object> map) {
-
- for (Transcoding transcoding : transcodingService.getAllTranscodings()) {
- Integer id = transcoding.getId();
- String name = getParameter(request, "name", id);
- String sourceFormats = getParameter(request, "sourceFormats", id);
- String targetFormat = getParameter(request, "targetFormat", id);
- String step1 = getParameter(request, "step1", id);
- String step2 = getParameter(request, "step2", id);
- boolean delete = getParameter(request, "delete", id) != null;
-
- if (delete) {
- transcodingService.deleteTranscoding(id);
- } else if (name == null) {
- map.put("error", "transcodingsettings.noname");
- } else if (sourceFormats == null) {
- map.put("error", "transcodingsettings.nosourceformat");
- } else if (targetFormat == null) {
- map.put("error", "transcodingsettings.notargetformat");
- } else if (step1 == null) {
- map.put("error", "transcodingsettings.nostep1");
- } else {
- transcoding.setName(name);
- transcoding.setSourceFormats(sourceFormats);
- transcoding.setTargetFormat(targetFormat);
- transcoding.setStep1(step1);
- transcoding.setStep2(step2);
- transcodingService.updateTranscoding(transcoding);
- }
- }
-
- String name = StringUtils.trimToNull(request.getParameter("name"));
- String sourceFormats = StringUtils.trimToNull(request.getParameter("sourceFormats"));
- String targetFormat = StringUtils.trimToNull(request.getParameter("targetFormat"));
- String step1 = StringUtils.trimToNull(request.getParameter("step1"));
- String step2 = StringUtils.trimToNull(request.getParameter("step2"));
- boolean defaultActive = request.getParameter("defaultActive") != null;
-
- if (name != null || sourceFormats != null || targetFormat != null || step1 != null || step2 != null) {
- Transcoding transcoding = new Transcoding(null, name, sourceFormats, targetFormat, step1, step2, null, defaultActive);
- if (name == null) {
- map.put("error", "transcodingsettings.noname");
- } else if (sourceFormats == null) {
- map.put("error", "transcodingsettings.nosourceformat");
- } else if (targetFormat == null) {
- map.put("error", "transcodingsettings.notargetformat");
- } else if (step1 == null) {
- map.put("error", "transcodingsettings.nostep1");
- } else {
- transcodingService.createTranscoding(transcoding);
- }
- if (map.containsKey("error")) {
- map.put("newTranscoding", transcoding);
- }
- }
- }
-
- private String getParameter(HttpServletRequest request, String name, Integer id) {
- return StringUtils.trimToNull(request.getParameter(name + "[" + id + "]"));
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java
deleted file mode 100644
index de7bf8dd..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UploadController.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.*;
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.upload.*;
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.util.*;
-import org.apache.commons.fileupload.*;
-import org.apache.commons.fileupload.servlet.*;
-import org.apache.commons.io.*;
-import org.apache.tools.zip.*;
-import org.springframework.web.servlet.*;
-import org.springframework.web.servlet.mvc.*;
-
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
-
-/**
- * Controller which receives uploaded files.
- *
- * @author Sindre Mehus
- */
-public class UploadController extends ParameterizableViewController {
-
- private static final Logger LOG = Logger.getLogger(UploadController.class);
-
- private SecurityService securityService;
- private PlayerService playerService;
- private StatusService statusService;
- private SettingsService settingsService;
- public static final String UPLOAD_STATUS = "uploadStatus";
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
- List<File> uploadedFiles = new ArrayList<File>();
- List<File> unzippedFiles = new ArrayList<File>();
- TransferStatus status = null;
-
- try {
-
- status = statusService.createUploadStatus(playerService.getPlayer(request, response, false, false));
- status.setBytesTotal(request.getContentLength());
-
- request.getSession().setAttribute(UPLOAD_STATUS, status);
-
- // Check that we have a file upload request
- if (!ServletFileUpload.isMultipartContent(request)) {
- throw new Exception("Illegal request.");
- }
-
- File dir = null;
- boolean unzip = false;
-
- UploadListener listener = new UploadListenerImpl(status);
-
- FileItemFactory factory = new MonitoredDiskFileItemFactory(listener);
- ServletFileUpload upload = new ServletFileUpload(factory);
-
- List<?> items = upload.parseRequest(request);
-
- // First, look for "dir" and "unzip" parameters.
- for (Object o : items) {
- FileItem item = (FileItem) o;
-
- if (item.isFormField() && "dir".equals(item.getFieldName())) {
- dir = new File(item.getString());
- } else if (item.isFormField() && "unzip".equals(item.getFieldName())) {
- unzip = true;
- }
- }
-
- if (dir == null) {
- throw new Exception("Missing 'dir' parameter.");
- }
-
- // Look for file items.
- for (Object o : items) {
- FileItem item = (FileItem) o;
-
- if (!item.isFormField()) {
- String fileName = item.getName();
- if (fileName.trim().length() > 0) {
-
- File targetFile = new File(dir, new File(fileName).getName());
-
- if (!securityService.isUploadAllowed(targetFile)) {
- throw new Exception("Permission denied: " + StringUtil.toHtml(targetFile.getPath()));
- }
-
- if (!dir.exists()) {
- dir.mkdirs();
- }
-
- item.write(targetFile);
- uploadedFiles.add(targetFile);
- LOG.info("Uploaded " + targetFile);
-
- if (unzip && targetFile.getName().toLowerCase().endsWith(".zip")) {
- unzip(targetFile, unzippedFiles);
- }
- }
- }
- }
-
- } catch (Exception x) {
- LOG.warn("Uploading failed.", x);
- map.put("exception", x);
- } finally {
- if (status != null) {
- statusService.removeUploadStatus(status);
- request.getSession().removeAttribute(UPLOAD_STATUS);
- User user = securityService.getCurrentUser(request);
- securityService.updateUserByteCounts(user, 0L, 0L, status.getBytesTransfered());
- }
- }
-
- map.put("uploadedFiles", uploadedFiles);
- map.put("unzippedFiles", unzippedFiles);
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- private void unzip(File file, List<File> unzippedFiles) throws Exception {
- LOG.info("Unzipping " + file);
-
- ZipFile zipFile = new ZipFile(file);
-
- try {
-
- Enumeration<?> entries = zipFile.getEntries();
-
- while (entries.hasMoreElements()) {
- ZipEntry entry = (ZipEntry) entries.nextElement();
- File entryFile = new File(file.getParentFile(), entry.getName());
-
- if (!entry.isDirectory()) {
-
- if (!securityService.isUploadAllowed(entryFile)) {
- throw new Exception("Permission denied: " + StringUtil.toHtml(entryFile.getPath()));
- }
-
- entryFile.getParentFile().mkdirs();
- InputStream inputStream = null;
- OutputStream outputStream = null;
- try {
- inputStream = zipFile.getInputStream(entry);
- outputStream = new FileOutputStream(entryFile);
-
- byte[] buf = new byte[8192];
- while (true) {
- int n = inputStream.read(buf);
- if (n == -1) {
- break;
- }
- outputStream.write(buf, 0, n);
- }
-
- LOG.info("Unzipped " + entryFile);
- unzippedFiles.add(entryFile);
- } finally {
- IOUtils.closeQuietly(inputStream);
- IOUtils.closeQuietly(outputStream);
- }
- }
- }
-
- zipFile.close();
- file.delete();
-
- } finally {
- zipFile.close();
- }
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- /**
- * Receives callbacks as the file upload progresses.
- */
- private class UploadListenerImpl implements UploadListener {
- private TransferStatus status;
- private long start;
-
- private UploadListenerImpl(TransferStatus status) {
- this.status = status;
- start = System.currentTimeMillis();
- }
-
- public void start(String fileName) {
- status.setFile(new File(fileName));
- }
-
- public void bytesRead(long bytesRead) {
-
- // Throttle bitrate.
-
- long byteCount = status.getBytesTransfered() + bytesRead;
- long bitCount = byteCount * 8L;
-
- float elapsedMillis = Math.max(1, System.currentTimeMillis() - start);
- float elapsedSeconds = elapsedMillis / 1000.0F;
- long maxBitsPerSecond = getBitrateLimit();
-
- status.setBytesTransfered(byteCount);
-
- if (maxBitsPerSecond > 0) {
- float sleepMillis = 1000.0F * (bitCount / maxBitsPerSecond - elapsedSeconds);
- if (sleepMillis > 0) {
- try {
- Thread.sleep((long) sleepMillis);
- } catch (InterruptedException x) {
- LOG.warn("Failed to sleep.", x);
- }
- }
- }
- }
-
- private long getBitrateLimit() {
- return 1024L * settingsService.getUploadBitrateLimit() / Math.max(1, statusService.getAllUploadStatuses().size());
- }
- }
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserChartController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserChartController.java
deleted file mode 100644
index 0428eff8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserChartController.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.awt.Color;
-import java.awt.GradientPaint;
-import java.awt.Paint;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.ChartUtilities;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.AxisLocation;
-import org.jfree.chart.axis.CategoryAxis;
-import org.jfree.chart.axis.CategoryLabelPositions;
-import org.jfree.chart.axis.LogarithmicAxis;
-import org.jfree.chart.plot.CategoryPlot;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.renderer.category.BarRenderer;
-import org.jfree.data.category.CategoryDataset;
-import org.jfree.data.category.DefaultCategoryDataset;
-import org.springframework.web.servlet.ModelAndView;
-
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.SecurityService;
-
-/**
- * Controller for generating a chart showing bitrate vs time.
- *
- * @author Sindre Mehus
- */
-public class UserChartController extends AbstractChartController {
-
- private SecurityService securityService;
-
- public static final int IMAGE_WIDTH = 400;
- public static final int IMAGE_MIN_HEIGHT = 200;
- private static final long BYTES_PER_MB = 1024L * 1024L;
-
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String type = request.getParameter("type");
- CategoryDataset dataset = createDataset(type);
- JFreeChart chart = createChart(dataset, request);
-
- int imageHeight = Math.max(IMAGE_MIN_HEIGHT, 15 * dataset.getColumnCount());
-
- ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart, IMAGE_WIDTH, imageHeight);
- return null;
- }
-
- private CategoryDataset createDataset(String type) {
- DefaultCategoryDataset dataset = new DefaultCategoryDataset();
- List<User> users = securityService.getAllUsers();
- for (User user : users) {
- double value;
- if ("stream".equals(type)) {
- value = user.getBytesStreamed();
- } else if ("download".equals(type)) {
- value = user.getBytesDownloaded();
- } else if ("upload".equals(type)) {
- value = user.getBytesUploaded();
- } else if ("total".equals(type)) {
- value = user.getBytesStreamed() + user.getBytesDownloaded() + user.getBytesUploaded();
- } else {
- throw new RuntimeException("Illegal chart type: " + type);
- }
-
- value /= BYTES_PER_MB;
- dataset.addValue(value, "Series", user.getUsername());
- }
-
- return dataset;
- }
-
- private JFreeChart createChart(CategoryDataset dataset, HttpServletRequest request) {
- JFreeChart chart = ChartFactory.createBarChart(null, null, null, dataset, PlotOrientation.HORIZONTAL, false, false, false);
-
- CategoryPlot plot = chart.getCategoryPlot();
- Paint background = new GradientPaint(0, 0, Color.lightGray, 0, IMAGE_MIN_HEIGHT, Color.white);
- plot.setBackgroundPaint(background);
- plot.setDomainGridlinePaint(Color.white);
- plot.setDomainGridlinesVisible(true);
- plot.setRangeGridlinePaint(Color.white);
- plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
-
- LogarithmicAxis rangeAxis = new LogarithmicAxis(null);
- rangeAxis.setStrictValuesFlag(false);
- rangeAxis.setAllowNegativesFlag(true);
- plot.setRangeAxis(rangeAxis);
-
- // Disable bar outlines.
- BarRenderer renderer = (BarRenderer) plot.getRenderer();
- renderer.setDrawBarOutline(false);
-
- // Set up gradient paint for series.
- GradientPaint gp0 = new GradientPaint(
- 0.0f, 0.0f, Color.blue,
- 0.0f, 0.0f, new Color(0, 0, 64)
- );
- renderer.setSeriesPaint(0, gp0);
-
- // Rotate labels.
- CategoryAxis domainAxis = plot.getDomainAxis();
- domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0));
-
- // Set theme-specific colors.
- Color bgColor = getBackground(request);
- Color fgColor = getForeground(request);
-
- chart.setBackgroundPaint(bgColor);
-
- domainAxis.setTickLabelPaint(fgColor);
- domainAxis.setTickMarkPaint(fgColor);
- domainAxis.setAxisLinePaint(fgColor);
-
- rangeAxis.setTickLabelPaint(fgColor);
- rangeAxis.setTickMarkPaint(fgColor);
- rangeAxis.setAxisLinePaint(fgColor);
-
- return chart;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserSettingsController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserSettingsController.java
deleted file mode 100644
index 58848840..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/UserSettingsController.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.util.List;
-import java.util.Date;
-
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.command.*;
-import org.springframework.web.servlet.mvc.*;
-import org.springframework.web.bind.*;
-import org.apache.commons.lang.StringUtils;
-
-import javax.servlet.http.*;
-
-/**
- * Controller for the page used to administrate users.
- *
- * @author Sindre Mehus
- */
-public class UserSettingsController extends SimpleFormController {
-
- private SecurityService securityService;
- private SettingsService settingsService;
- private TranscodingService transcodingService;
-
- @Override
- protected Object formBackingObject(HttpServletRequest request) throws Exception {
- UserSettingsCommand command = new UserSettingsCommand();
-
- User user = getUser(request);
- if (user != null) {
- command.setUser(user);
- command.setEmail(user.getEmail());
- command.setAdmin(User.USERNAME_ADMIN.equals(user.getUsername()));
- UserSettings userSettings = settingsService.getUserSettings(user.getUsername());
- command.setTranscodeSchemeName(userSettings.getTranscodeScheme().name());
-
- } else {
- command.setNew(true);
- command.setStreamRole(true);
- command.setSettingsRole(true);
- }
-
- command.setUsers(securityService.getAllUsers());
- command.setTranscodingSupported(transcodingService.isDownsamplingSupported(null));
- command.setTranscodeDirectory(transcodingService.getTranscodeDirectory().getPath());
- command.setTranscodeSchemes(TranscodeScheme.values());
- command.setLdapEnabled(settingsService.isLdapEnabled());
-
- return command;
- }
-
- private User getUser(HttpServletRequest request) throws ServletRequestBindingException {
- Integer userIndex = ServletRequestUtils.getIntParameter(request, "userIndex");
- if (userIndex != null) {
- List<User> allUsers = securityService.getAllUsers();
- if (userIndex >= 0 && userIndex < allUsers.size()) {
- return allUsers.get(userIndex);
- }
- }
- return null;
- }
-
- @Override
- protected void doSubmitAction(Object comm) throws Exception {
- UserSettingsCommand command = (UserSettingsCommand) comm;
-
- if (command.isDelete()) {
- deleteUser(command);
- } else if (command.isNew()) {
- createUser(command);
- } else {
- updateUser(command);
- }
- resetCommand(command);
- }
-
- private void deleteUser(UserSettingsCommand command) {
- securityService.deleteUser(command.getUsername());
- }
-
- public void createUser(UserSettingsCommand command) {
- User user = new User(command.getUsername(), command.getPassword(), StringUtils.trimToNull(command.getEmail()));
- user.setLdapAuthenticated(command.isLdapAuthenticated());
- securityService.createUser(user);
- updateUser(command);
- }
-
- private void updateUser(UserSettingsCommand command) {
- User user = securityService.getUserByName(command.getUsername());
- user.setEmail(StringUtils.trimToNull(command.getEmail()));
- user.setLdapAuthenticated(command.isLdapAuthenticated());
- user.setAdminRole(command.isAdminRole());
- user.setDownloadRole(command.isDownloadRole());
- user.setUploadRole(command.isUploadRole());
- user.setCoverArtRole(command.isCoverArtRole());
- user.setCommentRole(command.isCommentRole());
- user.setPodcastRole(command.isPodcastRole());
- user.setStreamRole(command.isStreamRole());
- user.setJukeboxRole(command.isJukeboxRole());
- user.setSettingsRole(command.isSettingsRole());
- user.setShareRole(command.isShareRole());
-
- if (command.isPasswordChange()) {
- user.setPassword(command.getPassword());
- }
-
- securityService.updateUser(user);
-
- UserSettings userSettings = settingsService.getUserSettings(command.getUsername());
- userSettings.setTranscodeScheme(TranscodeScheme.valueOf(command.getTranscodeSchemeName()));
- userSettings.setChanged(new Date());
- settingsService.updateUserSettings(userSettings);
- }
-
- private void resetCommand(UserSettingsCommand command) {
- command.setUser(null);
- command.setUsers(securityService.getAllUsers());
- command.setDelete(false);
- command.setPasswordChange(false);
- command.setNew(true);
- command.setStreamRole(true);
- command.setSettingsRole(true);
- command.setPassword(null);
- command.setConfirmPassword(null);
- command.setEmail(null);
- command.setTranscodeSchemeName(null);
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/VideoPlayerController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/VideoPlayerController.java
deleted file mode 100644
index 1d7686eb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/VideoPlayerController.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.ParameterizableViewController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Controller for the page used to play videos.
- *
- * @author Sindre Mehus
- */
-public class VideoPlayerController extends ParameterizableViewController {
-
- public static final int DEFAULT_BIT_RATE = 1000;
- public static final int[] BIT_RATES = {200, 300, 400, 500, 700, 1000, 1200, 1500, 2000, 3000, 5000};
- private static final long TRIAL_DAYS = 30L;
-
- private MediaFileService mediaFileService;
- private SettingsService settingsService;
- private PlayerService playerService;
-
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
- Map<String, Object> map = new HashMap<String, Object>();
- int id = ServletRequestUtils.getRequiredIntParameter(request, "id");
- MediaFile file = mediaFileService.getMediaFile(id);
-
- int timeOffset = ServletRequestUtils.getIntParameter(request, "timeOffset", 0);
- timeOffset = Math.max(0, timeOffset);
- Integer duration = file.getDurationSeconds();
- if (duration != null) {
- map.put("skipOffsets", createSkipOffsets(duration));
- timeOffset = Math.min(duration, timeOffset);
- duration -= timeOffset;
- }
-
- map.put("video", file);
- map.put("player", playerService.getPlayer(request, response).getId());
- map.put("maxBitRate", ServletRequestUtils.getIntParameter(request, "maxBitRate", DEFAULT_BIT_RATE));
- map.put("popout", ServletRequestUtils.getBooleanParameter(request, "popout", false));
- map.put("duration", duration);
- map.put("timeOffset", timeOffset);
- map.put("bitRates", BIT_RATES);
-
- if (!settingsService.isLicenseValid() && settingsService.getVideoTrialExpires() == null) {
- Date expiryDate = new Date(System.currentTimeMillis() + TRIAL_DAYS * 24L * 3600L * 1000L);
- settingsService.setVideoTrialExpires(expiryDate);
- settingsService.save();
- }
- Date trialExpires = settingsService.getVideoTrialExpires();
- map.put("trialExpires", trialExpires);
- map.put("trialExpired", trialExpires != null && trialExpires.before(new Date()));
- map.put("trial", trialExpires != null && !settingsService.isLicenseValid());
-
- ModelAndView result = super.handleRequestInternal(request, response);
- result.addObject("model", map);
- return result;
- }
-
- public static Map<String, Integer> createSkipOffsets(int durationSeconds) {
- LinkedHashMap<String, Integer> result = new LinkedHashMap<String, Integer>();
- for (int i = 0; i < durationSeconds; i += 60) {
- result.put(StringUtil.formatDuration(i), i);
- }
- return result;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/WapController.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/WapController.java
deleted file mode 100644
index 02509687..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/controller/WapController.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.controller;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.SortedSet;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.bind.ServletRequestUtils;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.MusicIndex;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.RandomSearchCriteria;
-import net.sourceforge.subsonic.domain.SearchCriteria;
-import net.sourceforge.subsonic.domain.SearchResult;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.SearchService;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.MusicIndexService;
-import net.sourceforge.subsonic.service.PlayerService;
-import net.sourceforge.subsonic.service.PlaylistService;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-
-/**
- * Multi-controller used for wap pages.
- *
- * @author Sindre Mehus
- */
-public class WapController extends MultiActionController {
-
- private SettingsService settingsService;
- private PlayerService playerService;
- private PlaylistService playlistService;
- private SecurityService securityService;
- private MusicIndexService musicIndexService;
- private MediaFileService mediaFileService;
- private SearchService searchService;
-
- public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception {
- return wap(request, response);
- }
-
- public ModelAndView wap(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
- List<MusicFolder> folders = settingsService.getAllMusicFolders();
-
- if (folders.isEmpty()) {
- map.put("noMusic", true);
- } else {
-
- SortedMap<MusicIndex, SortedSet<MusicIndex.Artist>> allArtists = musicIndexService.getIndexedArtists(folders);
-
- // If an index is given as parameter, only show music files for this index.
- String index = request.getParameter("index");
- if (index != null) {
- SortedSet<MusicIndex.Artist> artists = allArtists.get(new MusicIndex(index));
- if (artists == null) {
- map.put("noMusic", true);
- } else {
- map.put("artists", artists);
- }
- }
-
- // Otherwise, list all indexes.
- else {
- map.put("indexes", allArtists.keySet());
- }
- }
-
- return new ModelAndView("wap/index", "model", map);
- }
-
- public ModelAndView browse(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String path = request.getParameter("path");
- MediaFile parent = mediaFileService.getMediaFile(path);
-
- // Create array of file(s) to display.
- List<MediaFile> children;
- if (parent.isDirectory()) {
- children = mediaFileService.getChildrenOf(parent, true, true, true);
- } else {
- children = new ArrayList<MediaFile>();
- children.add(parent);
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("parent", parent);
- map.put("children", children);
- map.put("user", securityService.getCurrentUser(request));
-
- return new ModelAndView("wap/browse", "model", map);
- }
-
- public ModelAndView playlist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- // Create array of players to control. If the "player" attribute is set for this session,
- // only the player with this ID is controlled. Otherwise, all players are controlled.
- List<Player> players = playerService.getAllPlayers();
-
- String playerId = (String) request.getSession().getAttribute("player");
- if (playerId != null) {
- Player player = playerService.getPlayerById(playerId);
- if (player != null) {
- players = Arrays.asList(player);
- }
- }
-
- Map<String, Object> map = new HashMap<String, Object>();
-
- for (Player player : players) {
- PlayQueue playQueue = player.getPlayQueue();
- map.put("playlist", playQueue);
-
- if (request.getParameter("play") != null) {
- MediaFile file = mediaFileService.getMediaFile(request.getParameter("play"));
- playQueue.addFiles(false, file);
- } else if (request.getParameter("add") != null) {
- MediaFile file = mediaFileService.getMediaFile(request.getParameter("add"));
- playQueue.addFiles(true, file);
- } else if (request.getParameter("skip") != null) {
- playQueue.setIndex(Integer.parseInt(request.getParameter("skip")));
- } else if (request.getParameter("clear") != null) {
- playQueue.clear();
- } else if (request.getParameter("load") != null) {
- List<MediaFile> songs = playlistService.getFilesInPlaylist(ServletRequestUtils.getIntParameter(request, "id"));
- playQueue.addFiles(false, songs);
- } else if (request.getParameter("random") != null) {
- List<MediaFile> randomFiles = searchService.getRandomSongs(new RandomSearchCriteria(20, null, null, null, null));
- playQueue.addFiles(false, randomFiles);
- }
- }
-
- map.put("players", players);
- return new ModelAndView("wap/playlist", "model", map);
- }
-
- public ModelAndView loadPlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("playlists", playlistService.getReadablePlaylistsForUser(securityService.getCurrentUsername(request)));
- return new ModelAndView("wap/loadPlaylist", "model", map);
- }
-
- public ModelAndView search(HttpServletRequest request, HttpServletResponse response) throws Exception {
- return new ModelAndView("wap/search");
- }
-
- public ModelAndView searchResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String query = request.getParameter("query");
-
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("hits", search(query));
-
- return new ModelAndView("wap/searchResult", "model", map);
- }
-
- public ModelAndView settings(HttpServletRequest request, HttpServletResponse response) throws Exception {
- String playerId = (String) request.getSession().getAttribute("player");
-
- List<Player> allPlayers = playerService.getAllPlayers();
- User user = securityService.getCurrentUser(request);
- List<Player> players = new ArrayList<Player>();
- Map<String, Object> map = new HashMap<String, Object>();
-
- for (Player player : allPlayers) {
- // Only display authorized players.
- if (user.isAdminRole() || user.getUsername().equals(player.getUsername())) {
- players.add(player);
- }
-
- }
- map.put("playerId", playerId);
- map.put("players", players);
- return new ModelAndView("wap/settings", "model", map);
- }
-
- public ModelAndView selectPlayer(HttpServletRequest request, HttpServletResponse response) throws Exception {
- request.getSession().setAttribute("player", request.getParameter("playerId"));
- return settings(request, response);
- }
-
- private List<MediaFile> search(String query) throws IOException {
- SearchCriteria criteria = new SearchCriteria();
- criteria.setQuery(query);
- criteria.setOffset(0);
- criteria.setCount(50);
-
- SearchResult result = searchService.search(criteria, SearchService.IndexType.SONG);
- return result.getMediaFiles();
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public void setPlaylistService(PlaylistService playlistService) {
- this.playlistService = playlistService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMusicIndexService(MusicIndexService musicIndexService) {
- this.musicIndexService = musicIndexService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AbstractDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AbstractDao.java
deleted file mode 100644
index de17f4d4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AbstractDao.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import org.springframework.jdbc.core.*;
-
-import net.sourceforge.subsonic.Logger;
-
-/**
- * Abstract superclass for all DAO's.
- *
- * @author Sindre Mehus
- */
-public class AbstractDao {
- private static final Logger LOG = Logger.getLogger(AbstractDao.class);
-
- private DaoHelper daoHelper;
-
- /**
- * Returns a JDBC template for performing database operations.
- * @return A JDBC template.
- */
- public JdbcTemplate getJdbcTemplate() {
- return daoHelper.getJdbcTemplate();
- }
-
- protected String questionMarks(String columns) {
- int count = columns.split(", ").length;
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < count; i++) {
- builder.append('?');
- if (i < count - 1) {
- builder.append(", ");
- }
- }
- return builder.toString();
- }
-
- protected String prefix(String columns, String prefix) {
- StringBuilder builder = new StringBuilder();
- for (String s : columns.split(", ")) {
- builder.append(prefix).append(".").append(s).append(",");
- }
- if (builder.length() > 0) {
- builder.setLength(builder.length() - 1);
- }
- return builder.toString();
- }
-
- protected int update(String sql, Object... args) {
- long t = System.nanoTime();
- int result = getJdbcTemplate().update(sql, args);
- log(sql, t);
- return result;
- }
-
- private void log(String sql, long startTimeNano) {
-// long micros = (System.nanoTime() - startTimeNano) / 1000L;
-// LOG.debug(micros + " " + sql);
- }
-
- protected <T> List<T> query(String sql, RowMapper rowMapper, Object... args) {
- long t = System.nanoTime();
- List<T> result = getJdbcTemplate().query(sql, args, rowMapper);
- log(sql, t);
- return result;
- }
-
- protected List<String> queryForStrings(String sql, Object... args) {
- long t = System.nanoTime();
- List<String> result = getJdbcTemplate().queryForList(sql, args, String.class);
- log(sql, t);
- return result;
- }
-
- protected Integer queryForInt(String sql, Integer defaultValue, Object... args) {
- long t = System.nanoTime();
- List<Integer> list = getJdbcTemplate().queryForList(sql, args, Integer.class);
- Integer result = list.isEmpty() ? defaultValue : list.get(0) == null ? defaultValue : list.get(0);
- log(sql, t);
- return result;
- }
-
- protected Date queryForDate(String sql, Date defaultValue, Object... args) {
- long t = System.nanoTime();
- List<Date> list = getJdbcTemplate().queryForList(sql, args, Date.class);
- Date result = list.isEmpty() ? defaultValue : list.get(0) == null ? defaultValue : list.get(0);
- log(sql, t);
- return result;
- }
-
- protected Long queryForLong(String sql, Long defaultValue, Object... args) {
- long t = System.nanoTime();
- List<Long> list = getJdbcTemplate().queryForList(sql, args, Long.class);
- Long result = list.isEmpty() ? defaultValue : list.get(0) == null ? defaultValue : list.get(0);
- log(sql, t);
- return result;
- }
-
- protected <T> T queryOne(String sql, RowMapper rowMapper, Object... args) {
- List<T> list = query(sql, rowMapper, args);
- return list.isEmpty() ? null : list.get(0);
- }
-
- public void setDaoHelper(DaoHelper daoHelper) {
- this.daoHelper = daoHelper;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AlbumDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AlbumDao.java
deleted file mode 100644
index 603f6dad..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AlbumDao.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Album;
-import net.sourceforge.subsonic.domain.MediaFile;
-import org.apache.commons.lang.ObjectUtils;
-import org.springframework.jdbc.core.RowMapper;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Provides database services for albums.
- *
- * @author Sindre Mehus
- */
-public class AlbumDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(AlbumDao.class);
- private static final String COLUMNS = "id, path, name, artist, song_count, duration_seconds, cover_art_path, " +
- "play_count, last_played, comment, created, last_scanned, present";
-
- private final RowMapper rowMapper = new AlbumMapper();
-
- /**
- * Returns the album with the given artist and album name.
- *
- * @param artistName The artist name.
- * @param albumName The album name.
- * @return The album or null.
- */
- public Album getAlbum(String artistName, String albumName) {
- return queryOne("select " + COLUMNS + " from album where artist=? and name=?", rowMapper, artistName, albumName);
- }
-
- /**
- * Returns the album that the given file (most likely) is part of.
- *
- * @param file The media file.
- * @return The album or null.
- */
- public Album getAlbumForFile(MediaFile file) {
-
- // First, get all albums with the correct album name (irrespective of artist).
- List<Album> candidates = query("select " + COLUMNS + " from album where name=?", rowMapper, file.getAlbumName());
- if (candidates.isEmpty()) {
- return null;
- }
-
- // Look for album with the correct artist.
- for (Album candidate : candidates) {
- if (ObjectUtils.equals(candidate.getArtist(), file.getArtist())) {
- return candidate;
- }
- }
-
- // Look for album with the same path as the file.
- for (Album candidate : candidates) {
- if (ObjectUtils.equals(candidate.getPath(), file.getParentPath())) {
- return candidate;
- }
- }
-
- // No appropriate album found.
- return null;
- }
-
- public Album getAlbum(int id) {
- return queryOne("select " + COLUMNS + " from album where id=?", rowMapper, id);
- }
-
- public List<Album> getAlbumsForArtist(String artist) {
- return query("select " + COLUMNS + " from album where artist=? and present order by name", rowMapper, artist);
- }
-
- /**
- * Creates or updates an album.
- *
- * @param album The album to create/update.
- */
- public synchronized void createOrUpdateAlbum(Album album) {
- String sql = "update album set " +
- "song_count=?," +
- "duration_seconds=?," +
- "cover_art_path=?," +
- "play_count=?," +
- "last_played=?," +
- "comment=?," +
- "created=?," +
- "last_scanned=?," +
- "present=? " +
- "where artist=? and name=?";
-
- int n = update(sql, album.getSongCount(), album.getDurationSeconds(), album.getCoverArtPath(), album.getPlayCount(), album.getLastPlayed(),
- album.getComment(), album.getCreated(), album.getLastScanned(), album.isPresent(), album.getArtist(), album.getName());
-
- if (n == 0) {
-
- update("insert into album (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null, album.getPath(), album.getName(), album.getArtist(),
- album.getSongCount(), album.getDurationSeconds(), album.getCoverArtPath(), album.getPlayCount(), album.getLastPlayed(),
- album.getComment(), album.getCreated(), album.getLastScanned(), album.isPresent());
- }
-
- int id = queryForInt("select id from album where artist=? and name=?", null, album.getArtist(), album.getName());
- album.setId(id);
- }
-
- /**
- * Returns albums in alphabetical order.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @param byArtist Whether to sort by artist name
- * @return Albums in alphabetical order.
- */
- public List<Album> getAlphabetialAlbums(int offset, int count, boolean byArtist) {
- String orderBy = byArtist ? "artist, name" : "name";
- return query("select " + COLUMNS + " from album where present order by " + orderBy + " limit ? offset ?", rowMapper, count, offset);
- }
-
- /**
- * Returns the most frequently played albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most frequently played albums.
- */
- public List<Album> getMostFrequentlyPlayedAlbums(int offset, int count) {
- return query("select " + COLUMNS + " from album where play_count > 0 and present " +
- "order by play_count desc limit ? offset ?", rowMapper, count, offset);
- }
-
- /**
- * Returns the most recently played albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most recently played albums.
- */
- public List<Album> getMostRecentlyPlayedAlbums(int offset, int count) {
- return query("select " + COLUMNS + " from album where last_played is not null and present " +
- "order by last_played desc limit ? offset ?", rowMapper, count, offset);
- }
-
- /**
- * Returns the most recently added albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most recently added albums.
- */
- public List<Album> getNewestAlbums(int offset, int count) {
- return query("select " + COLUMNS + " from album where present order by created desc limit ? offset ?",
- rowMapper, count, offset);
- }
-
- /**
- * Returns the most recently starred albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @param username Returns albums starred by this user.
- * @return The most recently starred albums for this user.
- */
- public List<Album> getStarredAlbums(int offset, int count, String username) {
- return query("select " + prefix(COLUMNS, "album") + " from album, starred_album where album.id = starred_album.album_id and " +
- "album.present and starred_album.username=? order by starred_album.created desc limit ? offset ?",
- rowMapper, username, count, offset);
- }
-
- public void markNonPresent(Date lastScanned) {
- int minId = queryForInt("select id from album where true limit 1", 0);
- int maxId = queryForInt("select max(id) from album", 0);
-
- final int batchSize = 1000;
- for (int id = minId; id <= maxId; id += batchSize) {
- update("update album set present=false where id between ? and ? and last_scanned != ? and present", id, id + batchSize, lastScanned);
- }
- }
-
- public void expunge() {
- int minId = queryForInt("select id from album where true limit 1", 0);
- int maxId = queryForInt("select max(id) from album", 0);
-
- final int batchSize = 1000;
- for (int id = minId; id <= maxId; id += batchSize) {
- update("delete from album where id between ? and ? and not present", id, id + batchSize);
- }
- }
-
- public void starAlbum(int albumId, String username) {
- unstarAlbum(albumId, username);
- update("insert into starred_album(album_id, username, created) values (?,?,?)", albumId, username, new Date());
- }
-
- public void unstarAlbum(int albumId, String username) {
- update("delete from starred_album where album_id=? and username=?", albumId, username);
- }
-
- public Date getAlbumStarredDate(int albumId, String username) {
- return queryForDate("select created from starred_album where album_id=? and username=?", null, albumId, username);
- }
-
- private static class AlbumMapper implements ParameterizedRowMapper<Album> {
- public Album mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new Album(
- rs.getInt(1),
- rs.getString(2),
- rs.getString(3),
- rs.getString(4),
- rs.getInt(5),
- rs.getInt(6),
- rs.getString(7),
- rs.getInt(8),
- rs.getTimestamp(9),
- rs.getString(10),
- rs.getTimestamp(11),
- rs.getTimestamp(12),
- rs.getBoolean(13));
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ArtistDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ArtistDao.java
deleted file mode 100644
index 41d57c33..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ArtistDao.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Artist;
-import org.springframework.jdbc.core.RowMapper;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Provides database services for artists.
- *
- * @author Sindre Mehus
- */
-public class ArtistDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(ArtistDao.class);
- private static final String COLUMNS = "id, name, cover_art_path, album_count, last_scanned, present";
-
- private final RowMapper rowMapper = new ArtistMapper();
-
- /**
- * Returns the artist with the given name.
- *
- * @param artistName The artist name.
- * @return The artist or null.
- */
- public Artist getArtist(String artistName) {
- return queryOne("select " + COLUMNS + " from artist where name=?", rowMapper, artistName);
- }
-
- /**
- * Returns the artist with the given ID.
- *
- * @param id The artist ID.
- * @return The artist or null.
- */
- public Artist getArtist(int id) {
- return queryOne("select " + COLUMNS + " from artist where id=?", rowMapper, id);
- }
-
- /**
- * Creates or updates an artist.
- *
- * @param artist The artist to create/update.
- */
- public synchronized void createOrUpdateArtist(Artist artist) {
- String sql = "update artist set " +
- "cover_art_path=?," +
- "album_count=?," +
- "last_scanned=?," +
- "present=? " +
- "where name=?";
-
- int n = update(sql, artist.getCoverArtPath(), artist.getAlbumCount(), artist.getLastScanned(), artist.isPresent(), artist.getName());
-
- if (n == 0) {
-
- update("insert into artist (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null,
- artist.getName(), artist.getCoverArtPath(), artist.getAlbumCount(), artist.getLastScanned(), artist.isPresent());
- }
-
- int id = queryForInt("select id from artist where name=?", null, artist.getName());
- artist.setId(id);
- }
-
- /**
- * Returns artists in alphabetical order.
- *
- * @param offset Number of artists to skip.
- * @param count Maximum number of artists to return.
- * @return Artists in alphabetical order.
- */
- public List<Artist> getAlphabetialArtists(int offset, int count) {
- return query("select " + COLUMNS + " from artist where present order by name limit ? offset ?", rowMapper, count, offset);
- }
-
- /**
- * Returns the most recently starred artists.
- *
- * @param offset Number of artists to skip.
- * @param count Maximum number of artists to return.
- * @param username Returns artists starred by this user.
- * @return The most recently starred artists for this user.
- */
- public List<Artist> getStarredArtists(int offset, int count, String username) {
- return query("select " + prefix(COLUMNS, "artist") + " from artist, starred_artist where artist.id = starred_artist.artist_id and " +
- "artist.present and starred_artist.username=? order by starred_artist.created desc limit ? offset ?",
- rowMapper, username, count, offset);
- }
-
- public void markPresent(String artistName, Date lastScanned) {
- update("update artist set present=?, last_scanned=? where name=?", true, lastScanned, artistName);
- }
-
- public void markNonPresent(Date lastScanned) {
- int minId = queryForInt("select id from artist where true limit 1", 0);
- int maxId = queryForInt("select max(id) from artist", 0);
-
- final int batchSize = 1000;
- for (int id = minId; id <= maxId; id += batchSize) {
- update("update artist set present=false where id between ? and ? and last_scanned != ? and present", id, id + batchSize, lastScanned);
- }
- }
-
- public void expunge() {
- int minId = queryForInt("select id from artist where true limit 1", 0);
- int maxId = queryForInt("select max(id) from artist", 0);
-
- final int batchSize = 1000;
- for (int id = minId; id <= maxId; id += batchSize) {
- update("delete from artist where id between ? and ? and not present", id, id + batchSize);
- }
- }
-
- public void starArtist(int artistId, String username) {
- unstarArtist(artistId, username);
- update("insert into starred_artist(artist_id, username, created) values (?,?,?)", artistId, username, new Date());
- }
-
- public void unstarArtist(int artistId, String username) {
- update("delete from starred_artist where artist_id=? and username=?", artistId, username);
- }
-
- public Date getArtistStarredDate(int artistId, String username) {
- return queryForDate("select created from starred_artist where artist_id=? and username=?", null, artistId, username);
- }
-
- private static class ArtistMapper implements ParameterizedRowMapper<Artist> {
- public Artist mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new Artist(
- rs.getInt(1),
- rs.getString(2),
- rs.getString(3),
- rs.getInt(4),
- rs.getTimestamp(5),
- rs.getBoolean(6));
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AvatarDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AvatarDao.java
deleted file mode 100644
index abdc118d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/AvatarDao.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.domain.Avatar;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-/**
- * Provides database services for avatars.
- *
- * @author Sindre Mehus
- */
-public class AvatarDao extends AbstractDao {
-
- private static final String COLUMNS = "id, name, created_date, mime_type, width, height, data";
- private final AvatarRowMapper rowMapper = new AvatarRowMapper();
-
- /**
- * Returns all system avatars.
- *
- * @return All system avatars.
- */
- public List<Avatar> getAllSystemAvatars() {
- String sql = "select " + COLUMNS + " from system_avatar";
- return query(sql, rowMapper);
- }
-
- /**
- * Returns the system avatar with the given ID.
- *
- * @param id The system avatar ID.
- * @return The avatar or <code>null</code> if not found.
- */
- public Avatar getSystemAvatar(int id) {
- String sql = "select " + COLUMNS + " from system_avatar where id=" + id;
- return queryOne(sql, rowMapper);
- }
-
- /**
- * Returns the custom avatar for the given user.
- *
- * @param username The username.
- * @return The avatar or <code>null</code> if not found.
- */
- public Avatar getCustomAvatar(String username) {
- String sql = "select " + COLUMNS + " from custom_avatar where username=?";
- return queryOne(sql, rowMapper, username);
- }
-
- /**
- * Sets the custom avatar for the given user.
- *
- * @param avatar The avatar, or <code>null</code> to remove the avatar.
- * @param username The username.
- */
- public void setCustomAvatar(Avatar avatar, String username) {
- String sql = "delete from custom_avatar where username=?";
- update(sql, username);
-
- if (avatar != null) {
- update("insert into custom_avatar(" + COLUMNS + ", username) values(" + questionMarks(COLUMNS) + ", ?)",
- null, avatar.getName(), avatar.getCreatedDate(), avatar.getMimeType(),
- avatar.getWidth(), avatar.getHeight(), avatar.getData(), username);
- }
- }
-
- private static class AvatarRowMapper implements ParameterizedRowMapper<Avatar> {
- public Avatar mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new Avatar(rs.getInt(1), rs.getString(2), rs.getTimestamp(3), rs.getString(4),
- rs.getInt(5), rs.getInt(6), rs.getBytes(7));
- }
- }
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/DaoHelper.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/DaoHelper.java
deleted file mode 100644
index 802a5b3d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/DaoHelper.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.schema.Schema;
-import net.sourceforge.subsonic.dao.schema.Schema25;
-import net.sourceforge.subsonic.dao.schema.Schema26;
-import net.sourceforge.subsonic.dao.schema.Schema27;
-import net.sourceforge.subsonic.dao.schema.Schema28;
-import net.sourceforge.subsonic.dao.schema.Schema29;
-import net.sourceforge.subsonic.dao.schema.Schema30;
-import net.sourceforge.subsonic.dao.schema.Schema31;
-import net.sourceforge.subsonic.dao.schema.Schema32;
-import net.sourceforge.subsonic.dao.schema.Schema33;
-import net.sourceforge.subsonic.dao.schema.Schema34;
-import net.sourceforge.subsonic.dao.schema.Schema35;
-import net.sourceforge.subsonic.dao.schema.Schema36;
-import net.sourceforge.subsonic.dao.schema.Schema37;
-import net.sourceforge.subsonic.dao.schema.Schema38;
-import net.sourceforge.subsonic.dao.schema.Schema40;
-import net.sourceforge.subsonic.dao.schema.Schema43;
-import net.sourceforge.subsonic.dao.schema.Schema45;
-import net.sourceforge.subsonic.dao.schema.Schema46;
-import net.sourceforge.subsonic.dao.schema.Schema47;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.datasource.DriverManagerDataSource;
-
-import javax.sql.DataSource;
-import java.io.File;
-
-/**
- * DAO helper class which creates the data source, and updates the database schema.
- *
- * @author Sindre Mehus
- */
-public class DaoHelper {
-
- private static final Logger LOG = Logger.getLogger(DaoHelper.class);
-
- private Schema[] schemas = {new Schema25(), new Schema26(), new Schema27(), new Schema28(), new Schema29(),
- new Schema30(), new Schema31(), new Schema32(), new Schema33(), new Schema34(),
- new Schema35(), new Schema36(), new Schema37(), new Schema38(), new Schema40(),
- new Schema43(), new Schema45(), new Schema46(), new Schema47()};
- private DataSource dataSource;
- private static boolean shutdownHookAdded;
-
- public DaoHelper() {
- dataSource = createDataSource();
- checkDatabase();
- addShutdownHook();
- }
-
- private void addShutdownHook() {
- if (shutdownHookAdded) {
- return;
- }
- shutdownHookAdded = true;
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- System.err.println("Shutting down database.");
- getJdbcTemplate().execute("shutdown");
- System.err.println("Done.");
- }
- });
- }
-
- /**
- * Returns a JDBC template for performing database operations.
- *
- * @return A JDBC template.
- */
- public JdbcTemplate getJdbcTemplate() {
- return new JdbcTemplate(dataSource);
- }
-
- private DataSource createDataSource() {
- File subsonicHome = SettingsService.getSubsonicHome();
- DriverManagerDataSource ds = new DriverManagerDataSource();
- ds.setDriverClassName("org.hsqldb.jdbcDriver");
- ds.setUrl("jdbc:hsqldb:file:" + subsonicHome.getPath() + "/db/subsonic");
- ds.setUsername("sa");
- ds.setPassword("");
-
- return ds;
- }
-
- private void checkDatabase() {
- LOG.info("Checking database schema.");
- try {
- for (Schema schema : schemas) {
- schema.execute(getJdbcTemplate());
- }
- LOG.info("Done checking database schema.");
- } catch (Exception x) {
- LOG.error("Failed to initialize database.", x);
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/InternetRadioDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/InternetRadioDao.java
deleted file mode 100644
index c3c20a74..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/InternetRadioDao.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.InternetRadio;
-
-/**
- * Provides database services for internet radio.
- *
- * @author Sindre Mehus
- */
-public class InternetRadioDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(InternetRadioDao.class);
- private static final String COLUMNS = "id, name, stream_url, homepage_url, enabled, changed";
- private final InternetRadioRowMapper rowMapper = new InternetRadioRowMapper();
-
- /**
- * Returns all internet radio stations.
- *
- * @return Possibly empty list of all internet radio stations.
- */
- public List<InternetRadio> getAllInternetRadios() {
- String sql = "select " + COLUMNS + " from internet_radio";
- return query(sql, rowMapper);
- }
-
- /**
- * Creates a new internet radio station.
- *
- * @param radio The internet radio station to create.
- */
- public void createInternetRadio(InternetRadio radio) {
- String sql = "insert into internet_radio (" + COLUMNS + ") values (null, ?, ?, ?, ?, ?)";
- update(sql, radio.getName(), radio.getStreamUrl(), radio.getHomepageUrl(), radio.isEnabled(), radio.getChanged());
- LOG.info("Created internet radio station " + radio.getName());
- }
-
- /**
- * Deletes the internet radio station with the given ID.
- *
- * @param id The internet radio station ID.
- */
- public void deleteInternetRadio(Integer id) {
- String sql = "delete from internet_radio where id=?";
- update(sql, id);
- LOG.info("Deleted internet radio station with ID " + id);
- }
-
- /**
- * Updates the given internet radio station.
- *
- * @param radio The internet radio station to update.
- */
- public void updateInternetRadio(InternetRadio radio) {
- String sql = "update internet_radio set name=?, stream_url=?, homepage_url=?, enabled=?, changed=? where id=?";
- update(sql, radio.getName(), radio.getStreamUrl(), radio.getHomepageUrl(), radio.isEnabled(), radio.getChanged(), radio.getId());
- }
-
- private static class InternetRadioRowMapper implements ParameterizedRowMapper<InternetRadio> {
- public InternetRadio mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new InternetRadio(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getBoolean(5), rs.getTimestamp(6));
- }
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MediaFileDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MediaFileDao.java
deleted file mode 100644
index e75bc7a6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MediaFileDao.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MediaLibraryStatistics;
-import org.springframework.jdbc.core.RowMapper;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Date;
-import java.util.List;
-
-import static net.sourceforge.subsonic.domain.MediaFile.MediaType;
-import static net.sourceforge.subsonic.domain.MediaFile.MediaType.*;
-
-/**
- * Provides database services for media files.
- *
- * @author Sindre Mehus
- */
-public class MediaFileDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(MediaFileDao.class);
- private static final String COLUMNS = "id, path, folder, type, format, title, album, artist, album_artist, disc_number, " +
- "track_number, year, genre, bit_rate, variable_bit_rate, duration_seconds, file_size, width, height, cover_art_path, " +
- "parent_path, play_count, last_played, comment, created, changed, last_scanned, children_last_updated, present, version";
-
- private static final int VERSION = 1;
-
- private final RowMapper rowMapper = new MediaFileMapper();
- private final RowMapper musicFileInfoRowMapper = new MusicFileInfoMapper();
-
- /**
- * Returns the media file for the given path.
- *
- * @param path The path.
- * @return The media file or null.
- */
- public MediaFile getMediaFile(String path) {
- return queryOne("select " + COLUMNS + " from media_file where path=?", rowMapper, path);
- }
-
- /**
- * Returns the media file for the given ID.
- *
- * @param id The ID.
- * @return The media file or null.
- */
- public MediaFile getMediaFile(int id) {
- return queryOne("select " + COLUMNS + " from media_file where id=?", rowMapper, id);
- }
-
- /**
- * Returns the media file that are direct children of the given path.
- *
- * @param path The path.
- * @return The list of children.
- */
- public List<MediaFile> getChildrenOf(String path) {
- return query("select " + COLUMNS + " from media_file where parent_path=? and present", rowMapper, path);
- }
-
- public List<MediaFile> getFilesInPlaylist(int playlistId) {
- return query("select " + prefix(COLUMNS, "media_file") + " from media_file, playlist_file where " +
- "media_file.id = playlist_file.media_file_id and " +
- "playlist_file.playlist_id = ? and " +
- "media_file.present order by playlist_file.id", rowMapper, playlistId);
- }
-
- public List<MediaFile> getSongsForAlbum(String artist, String album) {
- return query("select " + COLUMNS + " from media_file where album_artist=? and album=? and present and type in (?,?,?) order by track_number", rowMapper,
- artist, album, MUSIC.name(), AUDIOBOOK.name(), PODCAST.name());
- }
-
- public List<MediaFile> getVideos(int size, int offset) {
- return query("select " + COLUMNS + " from media_file where type=? and present order by title limit ? offset ?", rowMapper,
- VIDEO.name(), size, offset);
- }
-
- /**
- * Creates or updates a media file.
- *
- * @param file The media file to create/update.
- */
- public synchronized void createOrUpdateMediaFile(MediaFile file) {
- String sql = "update media_file set " +
- "folder=?," +
- "type=?," +
- "format=?," +
- "title=?," +
- "album=?," +
- "artist=?," +
- "album_artist=?," +
- "disc_number=?," +
- "track_number=?," +
- "year=?," +
- "genre=?," +
- "bit_rate=?," +
- "variable_bit_rate=?," +
- "duration_seconds=?," +
- "file_size=?," +
- "width=?," +
- "height=?," +
- "cover_art_path=?," +
- "parent_path=?," +
- "play_count=?," +
- "last_played=?," +
- "comment=?," +
- "changed=?," +
- "last_scanned=?," +
- "children_last_updated=?," +
- "present=?, " +
- "version=? " +
- "where path=?";
-
- int n = update(sql,
- file.getFolder(), file.getMediaType().name(), file.getFormat(), file.getTitle(), file.getAlbumName(), file.getArtist(),
- file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(),
- file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(),
- file.getCoverArtPath(), file.getParentPath(), file.getPlayCount(), file.getLastPlayed(), file.getComment(),
- file.getChanged(), file.getLastScanned(), file.getChildrenLastUpdated(), file.isPresent(), VERSION, file.getPath());
-
- if (n == 0) {
-
- // Copy values from obsolete table music_file_info.
- MediaFile musicFileInfo = getMusicFileInfo(file.getPath());
- if (musicFileInfo != null) {
- file.setComment(musicFileInfo.getComment());
- file.setLastPlayed(musicFileInfo.getLastPlayed());
- file.setPlayCount(musicFileInfo.getPlayCount());
- }
-
- update("insert into media_file (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")", null,
- file.getPath(), file.getFolder(), file.getMediaType().name(), file.getFormat(), file.getTitle(), file.getAlbumName(), file.getArtist(),
- file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(),
- file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(),
- file.getCoverArtPath(), file.getParentPath(), file.getPlayCount(), file.getLastPlayed(), file.getComment(),
- file.getCreated(), file.getChanged(), file.getLastScanned(),
- file.getChildrenLastUpdated(), file.isPresent(), VERSION);
- }
-
- int id = queryForInt("select id from media_file where path=?", null, file.getPath());
- file.setId(id);
- }
-
- private MediaFile getMusicFileInfo(String path) {
- return queryOne("select play_count, last_played, comment from music_file_info where path=?", musicFileInfoRowMapper, path);
- }
-
- @Deprecated
- public List<String> getArtists() {
- return queryForStrings("select distinct artist from media_file where artist is not null and present order by artist");
- }
-
- public void deleteMediaFile(String path) {
- update("update media_file set present=false, children_last_updated=? where path=?", new Date(0L), path);
- }
-
- public List<String> getGenres() {
- return queryForStrings("select distinct genre from media_file where genre is not null and present order by genre");
- }
-
- /**
- * Returns the most frequently played albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most frequently played albums.
- */
- public List<MediaFile> getMostFrequentlyPlayedAlbums(int offset, int count) {
- return query("select " + COLUMNS + " from media_file where type=? and play_count > 0 and present " +
- "order by play_count desc limit ? offset ?", rowMapper, ALBUM.name(), count, offset);
- }
-
- /**
- * Returns the most recently played albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most recently played albums.
- */
- public List<MediaFile> getMostRecentlyPlayedAlbums(int offset, int count) {
- return query("select " + COLUMNS + " from media_file where type=? and last_played is not null and present " +
- "order by last_played desc limit ? offset ?", rowMapper, ALBUM.name(), count, offset);
- }
-
- /**
- * Returns the most recently added albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most recently added albums.
- */
- public List<MediaFile> getNewestAlbums(int offset, int count) {
- return query("select " + COLUMNS + " from media_file where type=? and present order by created desc limit ? offset ?",
- rowMapper, ALBUM.name(), count, offset);
- }
-
- /**
- * Returns albums in alphabetical order.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @param byArtist Whether to sort by artist name
- * @return Albums in alphabetical order.
- */
- public List<MediaFile> getAlphabetialAlbums(int offset, int count, boolean byArtist) {
- String orderBy = byArtist ? "artist, album" : "album";
- return query("select " + COLUMNS + " from media_file where type=? and artist != '' and present order by " + orderBy + " limit ? offset ?",
- rowMapper, ALBUM.name(), count, offset);
- }
-
- /**
- * Returns the most recently starred albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @param username Returns albums starred by this user.
- * @return The most recently starred albums for this user.
- */
- public List<MediaFile> getStarredAlbums(int offset, int count, String username) {
- return query("select " + prefix(COLUMNS, "media_file") + " from media_file, starred_media_file where media_file.id = starred_media_file.media_file_id and " +
- "media_file.present and media_file.type=? and starred_media_file.username=? order by starred_media_file.created desc limit ? offset ?",
- rowMapper, ALBUM.name(), username, count, offset);
- }
-
- /**
- * Returns the most recently starred directories.
- *
- * @param offset Number of directories to skip.
- * @param count Maximum number of directories to return.
- * @param username Returns directories starred by this user.
- * @return The most recently starred directories for this user.
- */
- public List<MediaFile> getStarredDirectories(int offset, int count, String username) {
- return query("select " + prefix(COLUMNS, "media_file") + " from media_file, starred_media_file where media_file.id = starred_media_file.media_file_id and " +
- "media_file.present and media_file.type=? and starred_media_file.username=? order by starred_media_file.created desc limit ? offset ?",
- rowMapper, DIRECTORY.name(), username, count, offset);
- }
-
- /**
- * Returns the most recently starred files.
- *
- * @param offset Number of files to skip.
- * @param count Maximum number of files to return.
- * @param username Returns files starred by this user.
- * @return The most recently starred files for this user.
- */
- public List<MediaFile> getStarredFiles(int offset, int count, String username) {
- return query("select " + prefix(COLUMNS, "media_file") + " from media_file, starred_media_file where media_file.id = starred_media_file.media_file_id and " +
- "media_file.present and media_file.type in (?,?,?,?) and starred_media_file.username=? order by starred_media_file.created desc limit ? offset ?",
- rowMapper, MUSIC.name(), PODCAST.name(), AUDIOBOOK.name(), VIDEO.name(), username, count, offset);
- }
-
- public void starMediaFile(int id, String username) {
- unstarMediaFile(id, username);
- update("insert into starred_media_file(media_file_id, username, created) values (?,?,?)", id, username, new Date());
- }
-
- public void unstarMediaFile(int id, String username) {
- update("delete from starred_media_file where media_file_id=? and username=?", id, username);
- }
-
- public Date getMediaFileStarredDate(int id, String username) {
- return queryForDate("select created from starred_media_file where media_file_id=? and username=?", null, id, username);
- }
-
- /**
- * Returns media library statistics, including the number of artists, albums and songs.
- *
- * @return Media library statistics.
- */
- public MediaLibraryStatistics getStatistics() {
- int artistCount = queryForInt("select count(1) from artist where present", 0);
- int albumCount = queryForInt("select count(1) from album where present", 0);
- int songCount = queryForInt("select count(1) from media_file where type in (?, ?, ?, ?) and present", 0, VIDEO.name(), MUSIC.name(), AUDIOBOOK.name(), PODCAST.name());
- long totalLengthInBytes = queryForLong("select sum(file_size) from media_file where present", 0L);
- long totalDurationInSeconds = queryForLong("select sum(duration_seconds) from media_file where present", 0L);
-
- return new MediaLibraryStatistics(artistCount, albumCount, songCount, totalLengthInBytes, totalDurationInSeconds);
- }
-
- public void markPresent(String path, Date lastScanned) {
- update("update media_file set present=?, last_scanned=? where path=?", true, lastScanned, path);
- }
-
- public void markNonPresent(Date lastScanned) {
- int minId = queryForInt("select id from media_file where true limit 1", 0);
- int maxId = queryForInt("select max(id) from media_file", 0);
-
- final int batchSize = 1000;
- Date childrenLastUpdated = new Date(0L); // Used to force a children rescan if file is later resurrected.
- for (int id = minId; id <= maxId; id += batchSize) {
- update("update media_file set present=false, children_last_updated=? where id between ? and ? and last_scanned != ? and present",
- childrenLastUpdated, id, id + batchSize, lastScanned);
- }
- }
-
- public void expunge() {
- int minId = queryForInt("select id from media_file where true limit 1", 0);
- int maxId = queryForInt("select max(id) from media_file", 0);
-
- final int batchSize = 1000;
- for (int id = minId; id <= maxId; id += batchSize) {
- update("delete from media_file where id between ? and ? and not present", id, id + batchSize);
- }
- update("checkpoint");
- }
-
- private static class MediaFileMapper implements ParameterizedRowMapper<MediaFile> {
- public MediaFile mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new MediaFile(
- rs.getInt(1),
- rs.getString(2),
- rs.getString(3),
- MediaType.valueOf(rs.getString(4)),
- rs.getString(5),
- rs.getString(6),
- rs.getString(7),
- rs.getString(8),
- rs.getString(9),
- rs.getInt(10) == 0 ? null : rs.getInt(10),
- rs.getInt(11) == 0 ? null : rs.getInt(11),
- rs.getInt(12) == 0 ? null : rs.getInt(12),
- rs.getString(13),
- rs.getInt(14) == 0 ? null : rs.getInt(14),
- rs.getBoolean(15),
- rs.getInt(16) == 0 ? null : rs.getInt(16),
- rs.getLong(17) == 0 ? null : rs.getLong(17),
- rs.getInt(18) == 0 ? null : rs.getInt(18),
- rs.getInt(19) == 0 ? null : rs.getInt(19),
- rs.getString(20),
- rs.getString(21),
- rs.getInt(22),
- rs.getTimestamp(23),
- rs.getString(24),
- rs.getTimestamp(25),
- rs.getTimestamp(26),
- rs.getTimestamp(27),
- rs.getTimestamp(28),
- rs.getBoolean(29));
- }
- }
-
- private static class MusicFileInfoMapper implements ParameterizedRowMapper<MediaFile> {
- public MediaFile mapRow(ResultSet rs, int rowNum) throws SQLException {
- MediaFile file = new MediaFile();
- file.setPlayCount(rs.getInt(1));
- file.setLastPlayed(rs.getTimestamp(2));
- file.setComment(rs.getString(3));
- return file;
- }
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MusicFolderDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MusicFolderDao.java
deleted file mode 100644
index a5205d71..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/MusicFolderDao.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.io.File;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MusicFolder;
-
-/**
- * Provides database services for music folders.
- *
- * @author Sindre Mehus
- */
-public class MusicFolderDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(MusicFolderDao.class);
- private static final String COLUMNS = "id, path, name, enabled, changed";
- private final MusicFolderRowMapper rowMapper = new MusicFolderRowMapper();
-
- /**
- * Returns all music folders.
- *
- * @return Possibly empty list of all music folders.
- */
- public List<MusicFolder> getAllMusicFolders() {
- String sql = "select " + COLUMNS + " from music_folder";
- return query(sql, rowMapper);
- }
-
- /**
- * Creates a new music folder.
- *
- * @param musicFolder The music folder to create.
- */
- public void createMusicFolder(MusicFolder musicFolder) {
- String sql = "insert into music_folder (" + COLUMNS + ") values (null, ?, ?, ?, ?)";
- update(sql, musicFolder.getPath(), musicFolder.getName(), musicFolder.isEnabled(), musicFolder.getChanged());
- LOG.info("Created music folder " + musicFolder.getPath());
- }
-
- /**
- * Deletes the music folder with the given ID.
- *
- * @param id The music folder ID.
- */
- public void deleteMusicFolder(Integer id) {
- String sql = "delete from music_folder where id=?";
- update(sql, id);
- LOG.info("Deleted music folder with ID " + id);
- }
-
- /**
- * Updates the given music folder.
- *
- * @param musicFolder The music folder to update.
- */
- public void updateMusicFolder(MusicFolder musicFolder) {
- String sql = "update music_folder set path=?, name=?, enabled=?, changed=? where id=?";
- update(sql, musicFolder.getPath().getPath(), musicFolder.getName(),
- musicFolder.isEnabled(), musicFolder.getChanged(), musicFolder.getId());
- }
-
- private static class MusicFolderRowMapper implements ParameterizedRowMapper<MusicFolder> {
- public MusicFolder mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new MusicFolder(rs.getInt(1), new File(rs.getString(2)), rs.getString(3), rs.getBoolean(4), rs.getTimestamp(5));
- }
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlayerDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlayerDao.java
deleted file mode 100644
index f129fa37..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlayerDao.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.CoverArtScheme;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayerTechnology;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-
-/**
- * Provides player-related database services.
- *
- * @author Sindre Mehus
- */
-public class PlayerDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(PlayerDao.class);
- private static final String COLUMNS = "id, name, type, username, ip_address, auto_control_enabled, " +
- "last_seen, cover_art_scheme, transcode_scheme, dynamic_ip, technology, client_id";
-
- private PlayerRowMapper rowMapper = new PlayerRowMapper();
- private Map<String, PlayQueue> playlists = Collections.synchronizedMap(new HashMap<String, PlayQueue>());
-
- /**
- * Returns all players.
- *
- * @return Possibly empty list of all users.
- */
- public List<Player> getAllPlayers() {
- String sql = "select " + COLUMNS + " from player";
- return query(sql, rowMapper);
- }
-
- /**
- * Returns all players owned by the given username and client ID.
- *
- * @param username The name of the user.
- * @param clientId The third-party client ID (used if this player is managed over the
- * Subsonic REST API). May be <code>null</code>.
- * @return All relevant players.
- */
- public List<Player> getPlayersForUserAndClientId(String username, String clientId) {
- if (clientId != null) {
- String sql = "select " + COLUMNS + " from player where username=? and client_id=?";
- return query(sql, rowMapper, username, clientId);
- } else {
- String sql = "select " + COLUMNS + " from player where username=? and client_id is null";
- return query(sql, rowMapper, username);
- }
- }
-
- /**
- * Returns the player with the given ID.
- *
- * @param id The unique player ID.
- * @return The player with the given ID, or <code>null</code> if no such player exists.
- */
- public Player getPlayerById(String id) {
- String sql = "select " + COLUMNS + " from player where id=?";
- return queryOne(sql, rowMapper, id);
- }
-
- /**
- * Creates a new player.
- *
- * @param player The player to create.
- */
- public synchronized void createPlayer(Player player) {
- int id = getJdbcTemplate().queryForInt("select max(id) from player") + 1;
- player.setId(String.valueOf(id));
- String sql = "insert into player (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")";
- update(sql, player.getId(), player.getName(), player.getType(), player.getUsername(),
- player.getIpAddress(), player.isAutoControlEnabled(),
- player.getLastSeen(), player.getCoverArtScheme().name(),
- player.getTranscodeScheme().name(), player.isDynamicIp(),
- player.getTechnology().name(), player.getClientId());
- addPlaylist(player);
-
- LOG.info("Created player " + id + '.');
- }
-
- /**
- * Deletes the player with the given ID.
- *
- * @param id The player ID.
- */
- public void deletePlayer(String id) {
- String sql = "delete from player where id=?";
- update(sql, id);
- playlists.remove(id);
- }
-
-
- /**
- * Delete players that haven't been used for the given number of days, and which is not given a name
- * or is used by a REST client.
- *
- * @param days Number of days.
- */
- public void deleteOldPlayers(int days) {
- Calendar cal = Calendar.getInstance();
- cal.add(Calendar.DATE, -days);
- String sql = "delete from player where name is null and client_id is null and (last_seen is null or last_seen < ?)";
- int n = update(sql, cal.getTime());
- if (n > 0) {
- LOG.info("Deleted " + n + " player(s) that haven't been used after " + cal.getTime());
- }
- }
-
- /**
- * Updates the given player.
- *
- * @param player The player to update.
- */
- public void updatePlayer(Player player) {
- String sql = "update player set " +
- "name = ?," +
- "type = ?," +
- "username = ?," +
- "ip_address = ?," +
- "auto_control_enabled = ?," +
- "last_seen = ?," +
- "cover_art_scheme = ?," +
- "transcode_scheme = ?, " +
- "dynamic_ip = ?, " +
- "technology = ?, " +
- "client_id = ? " +
- "where id = ?";
- update(sql, player.getName(), player.getType(), player.getUsername(),
- player.getIpAddress(), player.isAutoControlEnabled(),
- player.getLastSeen(), player.getCoverArtScheme().name(),
- player.getTranscodeScheme().name(), player.isDynamicIp(),
- player.getTechnology(), player.getClientId(), player.getId());
- }
-
- private void addPlaylist(Player player) {
- PlayQueue playQueue = playlists.get(player.getId());
- if (playQueue == null) {
- playQueue = new PlayQueue();
- playlists.put(player.getId(), playQueue);
- }
- player.setPlayQueue(playQueue);
- }
-
- private class PlayerRowMapper implements ParameterizedRowMapper<Player> {
- public Player mapRow(ResultSet rs, int rowNum) throws SQLException {
- Player player = new Player();
- int col = 1;
- player.setId(rs.getString(col++));
- player.setName(rs.getString(col++));
- player.setType(rs.getString(col++));
- player.setUsername(rs.getString(col++));
- player.setIpAddress(rs.getString(col++));
- player.setAutoControlEnabled(rs.getBoolean(col++));
- player.setLastSeen(rs.getTimestamp(col++));
- player.setCoverArtScheme(CoverArtScheme.valueOf(rs.getString(col++)));
- player.setTranscodeScheme(TranscodeScheme.valueOf(rs.getString(col++)));
- player.setDynamicIp(rs.getBoolean(col++));
- player.setTechnology(PlayerTechnology.valueOf(rs.getString(col++)));
- player.setClientId(rs.getString(col++));
-
- addPlaylist(player);
- return player;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlaylistDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlaylistDao.java
deleted file mode 100644
index 54cbaded..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PlaylistDao.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Playlist;
-import org.springframework.jdbc.core.RowMapper;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * Provides database services for playlists.
- *
- * @author Sindre Mehus
- */
-public class PlaylistDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(PlaylistDao.class);
- private static final String COLUMNS = "id, username, is_public, name, comment, file_count, duration_seconds, " +
- "created, changed, imported_from";
- private final RowMapper rowMapper = new PlaylistMapper();
-
- public List<Playlist> getReadablePlaylistsForUser(String username) {
-
- List<Playlist> result1 = getWritablePlaylistsForUser(username);
- List<Playlist> result2 = query("select " + COLUMNS + " from playlist where is_public", rowMapper);
- List<Playlist> result3 = query("select " + prefix(COLUMNS, "playlist") + " from playlist, playlist_user where " +
- "playlist.id = playlist_user.playlist_id and " +
- "playlist.username != ? and " +
- "playlist_user.username = ?", rowMapper, username, username);
-
- // Put in sorted map to avoid duplicates.
- SortedMap<Integer, Playlist> map = new TreeMap<Integer, Playlist>();
- for (Playlist playlist : result1) {
- map.put(playlist.getId(), playlist);
- }
- for (Playlist playlist : result2) {
- map.put(playlist.getId(), playlist);
- }
- for (Playlist playlist : result3) {
- map.put(playlist.getId(), playlist);
- }
- return new ArrayList<Playlist>(map.values());
- }
-
- public List<Playlist> getWritablePlaylistsForUser(String username) {
- return query("select " + COLUMNS + " from playlist where username=?", rowMapper, username);
- }
-
- public Playlist getPlaylist(int id) {
- return queryOne("select " + COLUMNS + " from playlist where id=?", rowMapper, id);
- }
-
- public List<Playlist> getAllPlaylists() {
- return query("select " + COLUMNS + " from playlist", rowMapper);
- }
-
- public synchronized void createPlaylist(Playlist playlist) {
- update("insert into playlist(" + COLUMNS + ") values(" + questionMarks(COLUMNS) + ")",
- null, playlist.getUsername(), playlist.isPublic(), playlist.getName(), playlist.getComment(),
- 0, 0, playlist.getCreated(), playlist.getChanged(), playlist.getImportedFrom());
-
- int id = queryForInt("select max(id) from playlist", 0);
- playlist.setId(id);
- }
-
- public void setFilesInPlaylist(int id, List<MediaFile> files) {
- update("delete from playlist_file where playlist_id=?", id);
- int duration = 0;
- for (MediaFile file : files) {
- update("insert into playlist_file (playlist_id, media_file_id) values (?, ?)", id, file.getId());
- if (file.getDurationSeconds() != null) {
- duration += file.getDurationSeconds();
- }
- }
- update("update playlist set file_count=?, duration_seconds=?, changed=? where id=?", files.size(), duration, new Date(), id);
- }
-
- public List<String> getPlaylistUsers(int playlistId) {
- return queryForStrings("select username from playlist_user where playlist_id=?", playlistId);
- }
-
- public void addPlaylistUser(int playlistId, String username) {
- if (!getPlaylistUsers(playlistId).contains(username)) {
- update("insert into playlist_user(playlist_id,username) values (?,?)", playlistId, username);
- }
- }
-
- public void deletePlaylistUser(int playlistId, String username) {
- update("delete from playlist_user where playlist_id=? and username=?", playlistId, username);
- }
-
- public synchronized void deletePlaylist(int id) {
- update("delete from playlist where id=?", id);
- }
-
- public void updatePlaylist(Playlist playlist) {
- update("update playlist set username=?, is_public=?, name=?, comment=?, changed=?, imported_from=? where id=?",
- playlist.getUsername(), playlist.isPublic(), playlist.getName(), playlist.getComment(),
- new Date(), playlist.getImportedFrom(), playlist.getId());
- }
-
- private static class PlaylistMapper implements ParameterizedRowMapper<Playlist> {
- public Playlist mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new Playlist(
- rs.getInt(1),
- rs.getString(2),
- rs.getBoolean(3),
- rs.getString(4),
- rs.getString(5),
- rs.getInt(6),
- rs.getInt(7),
- rs.getTimestamp(8),
- rs.getTimestamp(9),
- rs.getString(10));
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PodcastDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PodcastDao.java
deleted file mode 100644
index 3f274ec6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/PodcastDao.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.springframework.jdbc.core.RowMapper;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.domain.PodcastChannel;
-import net.sourceforge.subsonic.domain.PodcastEpisode;
-import net.sourceforge.subsonic.domain.PodcastStatus;
-
-/**
- * Provides database services for Podcast channels and episodes.
- *
- * @author Sindre Mehus
- */
-public class PodcastDao extends AbstractDao {
-
- private static final String CHANNEL_COLUMNS = "id, url, title, description, status, error_message";
- private static final String EPISODE_COLUMNS = "id, channel_id, url, path, title, description, publish_date, " +
- "duration, bytes_total, bytes_downloaded, status, error_message";
-
- private PodcastChannelRowMapper channelRowMapper = new PodcastChannelRowMapper();
- private PodcastEpisodeRowMapper episodeRowMapper = new PodcastEpisodeRowMapper();
-
- /**
- * Creates a new Podcast channel.
- *
- * @param channel The Podcast channel to create.
- * @return The ID of the newly created channel.
- */
- public synchronized int createChannel(PodcastChannel channel) {
- String sql = "insert into podcast_channel (" + CHANNEL_COLUMNS + ") values (" + questionMarks(CHANNEL_COLUMNS) + ")";
- update(sql, null, channel.getUrl(), channel.getTitle(), channel.getDescription(),
- channel.getStatus().name(), channel.getErrorMessage());
-
- return getJdbcTemplate().queryForInt("select max(id) from podcast_channel");
- }
-
- /**
- * Returns all Podcast channels.
- *
- * @return Possibly empty list of all Podcast channels.
- */
- public List<PodcastChannel> getAllChannels() {
- String sql = "select " + CHANNEL_COLUMNS + " from podcast_channel";
- return query(sql, channelRowMapper);
- }
-
- /**
- * Updates the given Podcast channel.
- *
- * @param channel The Podcast channel to update.
- */
- public void updateChannel(PodcastChannel channel) {
- String sql = "update podcast_channel set url=?, title=?, description=?, status=?, error_message=? where id=?";
- update(sql, channel.getUrl(), channel.getTitle(), channel.getDescription(),
- channel.getStatus().name(), channel.getErrorMessage(), channel.getId());
- }
-
- /**
- * Deletes the Podcast channel with the given ID.
- *
- * @param id The Podcast channel ID.
- */
- public void deleteChannel(int id) {
- String sql = "delete from podcast_channel where id=?";
- update(sql, id);
- }
-
- /**
- * Creates a new Podcast episode.
- *
- * @param episode The Podcast episode to create.
- */
- public void createEpisode(PodcastEpisode episode) {
- String sql = "insert into podcast_episode (" + EPISODE_COLUMNS + ") values (" + questionMarks(EPISODE_COLUMNS) + ")";
- update(sql, null, episode.getChannelId(), episode.getUrl(), episode.getPath(),
- episode.getTitle(), episode.getDescription(), episode.getPublishDate(),
- episode.getDuration(), episode.getBytesTotal(), episode.getBytesDownloaded(),
- episode.getStatus().name(), episode.getErrorMessage());
- }
-
- /**
- * Returns all Podcast episodes for a given channel.
- *
- * @return Possibly empty list of all Podcast episodes for the given channel, sorted in
- * reverse chronological order (newest episode first).
- */
- public List<PodcastEpisode> getEpisodes(int channelId) {
- String sql = "select " + EPISODE_COLUMNS + " from podcast_episode where channel_id=? order by publish_date desc";
- return query(sql, episodeRowMapper, channelId);
- }
-
- /**
- * Returns the Podcast episode with the given ID.
- *
- * @param episodeId The Podcast episode ID.
- * @return The episode or <code>null</code> if not found.
- */
- public PodcastEpisode getEpisode(int episodeId) {
- String sql = "select " + EPISODE_COLUMNS + " from podcast_episode where id=?";
- return queryOne(sql, episodeRowMapper, episodeId);
- }
-
- /**
- * Updates the given Podcast episode.
- *
- * @param episode The Podcast episode to update.
- * @return The number of episodes updated (zero or one).
- */
- public int updateEpisode(PodcastEpisode episode) {
- String sql = "update podcast_episode set url=?, path=?, title=?, description=?, publish_date=?, duration=?, " +
- "bytes_total=?, bytes_downloaded=?, status=?, error_message=? where id=?";
- return update(sql, episode.getUrl(), episode.getPath(), episode.getTitle(),
- episode.getDescription(), episode.getPublishDate(), episode.getDuration(),
- episode.getBytesTotal(), episode.getBytesDownloaded(), episode.getStatus().name(),
- episode.getErrorMessage(), episode.getId());
- }
-
- /**
- * Deletes the Podcast episode with the given ID.
- *
- * @param id The Podcast episode ID.
- */
- public void deleteEpisode(int id) {
- String sql = "delete from podcast_episode where id=?";
- update(sql, id);
- }
-
- private static class PodcastChannelRowMapper implements RowMapper {
- public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new PodcastChannel(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4),
- PodcastStatus.valueOf(rs.getString(5)), rs.getString(6));
- }
- }
-
- private static class PodcastEpisodeRowMapper implements ParameterizedRowMapper<PodcastEpisode> {
- public PodcastEpisode mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new PodcastEpisode(rs.getInt(1), rs.getInt(2), rs.getString(3), rs.getString(4), rs.getString(5),
- rs.getString(6), rs.getTimestamp(7), rs.getString(8), (Long) rs.getObject(9),
- (Long) rs.getObject(10), PodcastStatus.valueOf(rs.getString(11)), rs.getString(12));
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/RatingDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/RatingDao.java
deleted file mode 100644
index 221fe889..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/RatingDao.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import org.springframework.dao.EmptyResultDataAccessException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides database services for ratings.
- *
- * @author Sindre Mehus
- */
-public class RatingDao extends AbstractDao {
-
- /**
- * Returns paths for the highest rated music files.
- *
- * @param offset Number of files to skip.
- * @param count Maximum number of files to return.
- * @return Paths for the highest rated music files.
- */
- public List<String> getHighestRated(int offset, int count) {
- if (count < 1) {
- return new ArrayList<String>();
- }
-
- String sql = "select user_rating.path from user_rating, media_file " +
- "where user_rating.path=media_file.path and media_file.present " +
- "group by path " +
- "order by avg(rating) desc limit " + count + " offset " + offset;
- return queryForStrings(sql);
- }
-
- /**
- * Sets the rating for a media file and a given user.
- *
- * @param username The user name.
- * @param mediaFile The media file.
- * @param rating The rating between 1 and 5, or <code>null</code> to remove the rating.
- */
- public void setRatingForUser(String username, MediaFile mediaFile, Integer rating) {
- if (rating != null && (rating < 1 || rating > 5)) {
- return;
- }
-
- update("delete from user_rating where username=? and path=?", username, mediaFile.getPath());
- if (rating != null) {
- update("insert into user_rating values(?, ?, ?)", username, mediaFile.getPath(), rating);
- }
- }
-
- /**
- * Returns the average rating for the given media file.
- *
- * @param mediaFile The media file.
- * @return The average rating, or <code>null</code> if no ratings are set.
- */
- public Double getAverageRating(MediaFile mediaFile) {
- try {
- return (Double) getJdbcTemplate().queryForObject("select avg(rating) from user_rating where path=?", new Object[]{mediaFile.getPath()}, Double.class);
- } catch (EmptyResultDataAccessException x) {
- return null;
- }
- }
-
- /**
- * Returns the rating for the given user and media file.
- *
- * @param username The user name.
- * @param mediaFile The media file.
- * @return The rating, or <code>null</code> if no rating is set.
- */
- public Integer getRatingForUser(String username, MediaFile mediaFile) {
- try {
- return getJdbcTemplate().queryForInt("select rating from user_rating where username=? and path=?", new Object[]{username, mediaFile.getPath()});
- } catch (EmptyResultDataAccessException x) {
- return null;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ShareDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ShareDao.java
deleted file mode 100644
index 17d4cd73..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/ShareDao.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.domain.Share;
-
-/**
- * Provides database services for shared media.
- *
- * @author Sindre Mehus
- */
-public class ShareDao extends AbstractDao {
-
- private static final String COLUMNS = "id, name, description, username, created, expires, last_visited, visit_count";
-
- private ShareRowMapper shareRowMapper = new ShareRowMapper();
- private ShareFileRowMapper shareFileRowMapper = new ShareFileRowMapper();
-
- /**
- * Creates a new share.
- *
- * @param share The share to create. The ID of the share will be set by this method.
- */
- public synchronized void createShare(Share share) {
- String sql = "insert into share (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")";
- update(sql, null, share.getName(), share.getDescription(), share.getUsername(), share.getCreated(),
- share.getExpires(), share.getLastVisited(), share.getVisitCount());
-
- int id = getJdbcTemplate().queryForInt("select max(id) from share");
- share.setId(id);
- }
-
- /**
- * Returns all shares.
- *
- * @return Possibly empty list of all shares.
- */
- public List<Share> getAllShares() {
- String sql = "select " + COLUMNS + " from share";
- return query(sql, shareRowMapper);
- }
-
- public Share getShareByName(String shareName) {
- String sql = "select " + COLUMNS + " from share where name=?";
- return queryOne(sql, shareRowMapper, shareName);
- }
-
- public Share getShareById(int id) {
- String sql = "select " + COLUMNS + " from share where id=?";
- return queryOne(sql, shareRowMapper, id);
- }
-
- /**
- * Updates the given share.
- *
- * @param share The share to update.
- */
- public void updateShare(Share share) {
- String sql = "update share set name=?, description=?, username=?, created=?, expires=?, last_visited=?, visit_count=? where id=?";
- update(sql, share.getName(), share.getDescription(), share.getUsername(), share.getCreated(), share.getExpires(),
- share.getLastVisited(), share.getVisitCount(), share.getId());
- }
-
- /**
- * Creates shared files.
- *
- * @param shareId The share ID.
- * @param paths Paths of the files to share.
- */
- public void createSharedFiles(int shareId, String... paths) {
- String sql = "insert into share_file (share_id, path) values (?, ?)";
- for (String path : paths) {
- update(sql, shareId, path);
- }
- }
-
- /**
- * Returns files for a share.
- *
- * @param shareId The ID of the share.
- * @return The paths of the shared files.
- */
- public List<String> getSharedFiles(int shareId) {
- return query("select path from share_file where share_id=?", shareFileRowMapper, shareId);
- }
-
- /**
- * Deletes the share with the given ID.
- *
- * @param id The ID of the share to delete.
- */
- public void deleteShare(Integer id) {
- update("delete from share where id=?", id);
- }
-
- private static class ShareRowMapper implements ParameterizedRowMapper<Share> {
- public Share mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new Share(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getTimestamp(5),
- rs.getTimestamp(6), rs.getTimestamp(7), rs.getInt(8));
- }
- }
-
- private static class ShareFileRowMapper implements ParameterizedRowMapper<String> {
- public String mapRow(ResultSet rs, int rowNum) throws SQLException {
- return rs.getString(1);
- }
-
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/TranscodingDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/TranscodingDao.java
deleted file mode 100644
index 22b8ae20..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/TranscodingDao.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Transcoding;
-
-/**
- * Provides database services for transcoding configurations.
- *
- * @author Sindre Mehus
- */
-public class TranscodingDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(TranscodingDao.class);
- private static final String COLUMNS = "id, name, source_formats, target_format, step1, step2, step3, default_active";
- private TranscodingRowMapper rowMapper = new TranscodingRowMapper();
-
- /**
- * Returns all transcodings.
- *
- * @return Possibly empty list of all transcodings.
- */
- public List<Transcoding> getAllTranscodings() {
- String sql = "select " + COLUMNS + " from transcoding2";
- return query(sql, rowMapper);
- }
-
- /**
- * Returns all active transcodings for the given player.
- *
- * @param playerId The player ID.
- * @return All active transcodings for the player.
- */
- public List<Transcoding> getTranscodingsForPlayer(String playerId) {
- String sql = "select " + COLUMNS + " from transcoding2, player_transcoding2 " +
- "where player_transcoding2.player_id = ? " +
- "and player_transcoding2.transcoding_id = transcoding2.id";
- return query(sql, rowMapper, playerId);
- }
-
- /**
- * Sets the list of active transcodings for the given player.
- *
- * @param playerId The player ID.
- * @param transcodingIds ID's of the active transcodings.
- */
- public void setTranscodingsForPlayer(String playerId, int[] transcodingIds) {
- update("delete from player_transcoding2 where player_id = ?", playerId);
- String sql = "insert into player_transcoding2(player_id, transcoding_id) values (?, ?)";
- for (int transcodingId : transcodingIds) {
- update(sql, playerId, transcodingId);
- }
- }
-
- /**
- * Creates a new transcoding.
- *
- * @param transcoding The transcoding to create.
- */
- public synchronized void createTranscoding(Transcoding transcoding) {
- int id = getJdbcTemplate().queryForInt("select max(id) + 1 from transcoding2");
- transcoding.setId(id);
- String sql = "insert into transcoding2 (" + COLUMNS + ") values (" + questionMarks(COLUMNS) + ")";
- update(sql, transcoding.getId(), transcoding.getName(), transcoding.getSourceFormats(),
- transcoding.getTargetFormat(), transcoding.getStep1(),
- transcoding.getStep2(), transcoding.getStep3(), transcoding.isDefaultActive());
- LOG.info("Created transcoding " + transcoding.getName());
- }
-
- /**
- * Deletes the transcoding with the given ID.
- *
- * @param id The transcoding ID.
- */
- public void deleteTranscoding(Integer id) {
- String sql = "delete from transcoding2 where id=?";
- update(sql, id);
- LOG.info("Deleted transcoding with ID " + id);
- }
-
- /**
- * Updates the given transcoding.
- *
- * @param transcoding The transcoding to update.
- */
- public void updateTranscoding(Transcoding transcoding) {
- String sql = "update transcoding2 set name=?, source_formats=?, target_format=?, " +
- "step1=?, step2=?, step3=?, default_active=? where id=?";
- update(sql, transcoding.getName(), transcoding.getSourceFormats(),
- transcoding.getTargetFormat(), transcoding.getStep1(), transcoding.getStep2(),
- transcoding.getStep3(), transcoding.isDefaultActive(), transcoding.getId());
- }
-
- private static class TranscodingRowMapper implements ParameterizedRowMapper<Transcoding> {
- public Transcoding mapRow(ResultSet rs, int rowNum) throws SQLException {
- return new Transcoding(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5),
- rs.getString(6), rs.getString(7), rs.getBoolean(8));
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/UserDao.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/UserDao.java
deleted file mode 100644
index e7807765..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/UserDao.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.AvatarScheme;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Provides user-related database services.
- *
- * @author Sindre Mehus
- */
-public class UserDao extends AbstractDao {
-
- private static final Logger LOG = Logger.getLogger(UserDao.class);
- private static final String USER_COLUMNS = "username, password, email, ldap_authenticated, bytes_streamed, bytes_downloaded, bytes_uploaded";
- private static final String USER_SETTINGS_COLUMNS = "username, locale, theme_id, final_version_notification, beta_version_notification, " +
- "main_caption_cutoff, main_track_number, main_artist, main_album, main_genre, " +
- "main_year, main_bit_rate, main_duration, main_format, main_file_size, " +
- "playlist_caption_cutoff, playlist_track_number, playlist_artist, playlist_album, playlist_genre, " +
- "playlist_year, playlist_bit_rate, playlist_duration, playlist_format, playlist_file_size, " +
- "last_fm_enabled, last_fm_username, last_fm_password, transcode_scheme, show_now_playing, selected_music_folder_id, " +
- "party_mode_enabled, now_playing_allowed, avatar_scheme, system_avatar_id, changed, show_chat";
-
- private static final Integer ROLE_ID_ADMIN = 1;
- private static final Integer ROLE_ID_DOWNLOAD = 2;
- private static final Integer ROLE_ID_UPLOAD = 3;
- private static final Integer ROLE_ID_PLAYLIST = 4;
- private static final Integer ROLE_ID_COVER_ART = 5;
- private static final Integer ROLE_ID_COMMENT = 6;
- private static final Integer ROLE_ID_PODCAST = 7;
- private static final Integer ROLE_ID_STREAM = 8;
- private static final Integer ROLE_ID_SETTINGS = 9;
- private static final Integer ROLE_ID_JUKEBOX = 10;
- private static final Integer ROLE_ID_SHARE = 11;
-
- private UserRowMapper userRowMapper = new UserRowMapper();
- private UserSettingsRowMapper userSettingsRowMapper = new UserSettingsRowMapper();
-
- /**
- * Returns the user with the given username.
- *
- * @param username The username used when logging in.
- * @return The user, or <code>null</code> if not found.
- */
- public User getUserByName(String username) {
- String sql = "select " + USER_COLUMNS + " from user where username=?";
- return queryOne(sql, userRowMapper, username);
- }
-
- /**
- * Returns the user with the given email address.
- *
- * @param email The email address.
- * @return The user, or <code>null</code> if not found.
- */
- public User getUserByEmail(String email) {
- String sql = "select " + USER_COLUMNS + " from user where email=?";
- return queryOne(sql, userRowMapper, email);
- }
-
- /**
- * Returns all users.
- *
- * @return Possibly empty array of all users.
- */
- public List<User> getAllUsers() {
- String sql = "select " + USER_COLUMNS + " from user";
- return query(sql, userRowMapper);
- }
-
- /**
- * Creates a new user.
- *
- * @param user The user to create.
- */
- public void createUser(User user) {
- String sql = "insert into user (" + USER_COLUMNS + ") values (" + questionMarks(USER_COLUMNS) + ')';
- update(sql, user.getUsername(), encrypt(user.getPassword()), user.getEmail(), user.isLdapAuthenticated(),
- user.getBytesStreamed(), user.getBytesDownloaded(), user.getBytesUploaded());
- writeRoles(user);
- }
-
- /**
- * Deletes the user with the given username.
- *
- * @param username The username.
- */
- public void deleteUser(String username) {
- if (User.USERNAME_ADMIN.equals(username)) {
- throw new IllegalArgumentException("Can't delete admin user.");
- }
-
- String sql = "delete from user_role where username=?";
- update(sql, username);
-
- sql = "delete from user where username=?";
- update(sql, username);
- }
-
- /**
- * Updates the given user.
- *
- * @param user The user to update.
- */
- public void updateUser(User user) {
- String sql = "update user set password=?, email=?, ldap_authenticated=?, bytes_streamed=?, bytes_downloaded=?, bytes_uploaded=? " +
- "where username=?";
- getJdbcTemplate().update(sql, new Object[]{encrypt(user.getPassword()), user.getEmail(), user.isLdapAuthenticated(),
- user.getBytesStreamed(), user.getBytesDownloaded(), user.getBytesUploaded(),
- user.getUsername()});
- writeRoles(user);
- }
-
- /**
- * Returns the name of the roles for the given user.
- *
- * @param username The user name.
- * @return Roles the user is granted.
- */
- public String[] getRolesForUser(String username) {
- String sql = "select r.name from role r, user_role ur " +
- "where ur.username=? and ur.role_id=r.id";
- List<?> roles = getJdbcTemplate().queryForList(sql, new Object[]{username}, String.class);
- String[] result = new String[roles.size()];
- for (int i = 0; i < result.length; i++) {
- result[i] = (String) roles.get(i);
- }
- return result;
- }
-
- /**
- * Returns settings for the given user.
- *
- * @param username The username.
- * @return User-specific settings, or <code>null</code> if no such settings exist.
- */
- public UserSettings getUserSettings(String username) {
- String sql = "select " + USER_SETTINGS_COLUMNS + " from user_settings where username=?";
- return queryOne(sql, userSettingsRowMapper, username);
- }
-
- /**
- * Updates settings for the given username, creating it if necessary.
- *
- * @param settings The user-specific settings.
- */
- public void updateUserSettings(UserSettings settings) {
- getJdbcTemplate().update("delete from user_settings where username=?", new Object[]{settings.getUsername()});
-
- String sql = "insert into user_settings (" + USER_SETTINGS_COLUMNS + ") values (" + questionMarks(USER_SETTINGS_COLUMNS) + ')';
- String locale = settings.getLocale() == null ? null : settings.getLocale().toString();
- UserSettings.Visibility main = settings.getMainVisibility();
- UserSettings.Visibility playlist = settings.getPlaylistVisibility();
- getJdbcTemplate().update(sql, new Object[]{settings.getUsername(), locale, settings.getThemeId(),
- settings.isFinalVersionNotificationEnabled(), settings.isBetaVersionNotificationEnabled(),
- main.getCaptionCutoff(), main.isTrackNumberVisible(), main.isArtistVisible(), main.isAlbumVisible(),
- main.isGenreVisible(), main.isYearVisible(), main.isBitRateVisible(), main.isDurationVisible(),
- main.isFormatVisible(), main.isFileSizeVisible(),
- playlist.getCaptionCutoff(), playlist.isTrackNumberVisible(), playlist.isArtistVisible(), playlist.isAlbumVisible(),
- playlist.isGenreVisible(), playlist.isYearVisible(), playlist.isBitRateVisible(), playlist.isDurationVisible(),
- playlist.isFormatVisible(), playlist.isFileSizeVisible(),
- settings.isLastFmEnabled(), settings.getLastFmUsername(), encrypt(settings.getLastFmPassword()),
- settings.getTranscodeScheme().name(), settings.isShowNowPlayingEnabled(),
- settings.getSelectedMusicFolderId(), settings.isPartyModeEnabled(), settings.isNowPlayingAllowed(),
- settings.getAvatarScheme().name(), settings.getSystemAvatarId(), settings.getChanged(), settings.isShowChatEnabled()});
- }
-
- private static String encrypt(String s) {
- if (s == null) {
- return null;
- }
- try {
- return "enc:" + StringUtil.utf8HexEncode(s);
- } catch (Exception e) {
- return s;
- }
- }
-
- private static String decrypt(String s) {
- if (s == null) {
- return null;
- }
- if (!s.startsWith("enc:")) {
- return s;
- }
- try {
- return StringUtil.utf8HexDecode(s.substring(4));
- } catch (Exception e) {
- return s;
- }
- }
-
- private void readRoles(User user) {
- synchronized (user.getUsername().intern()) {
- String sql = "select role_id from user_role where username=?";
- List<?> roles = getJdbcTemplate().queryForList(sql, new Object[]{user.getUsername()}, Integer.class);
- for (Object role : roles) {
- if (ROLE_ID_ADMIN.equals(role)) {
- user.setAdminRole(true);
- } else if (ROLE_ID_DOWNLOAD.equals(role)) {
- user.setDownloadRole(true);
- } else if (ROLE_ID_UPLOAD.equals(role)) {
- user.setUploadRole(true);
- } else if (ROLE_ID_PLAYLIST.equals(role)) {
- user.setPlaylistRole(true);
- } else if (ROLE_ID_COVER_ART.equals(role)) {
- user.setCoverArtRole(true);
- } else if (ROLE_ID_COMMENT.equals(role)) {
- user.setCommentRole(true);
- } else if (ROLE_ID_PODCAST.equals(role)) {
- user.setPodcastRole(true);
- } else if (ROLE_ID_STREAM.equals(role)) {
- user.setStreamRole(true);
- } else if (ROLE_ID_SETTINGS.equals(role)) {
- user.setSettingsRole(true);
- } else if (ROLE_ID_JUKEBOX.equals(role)) {
- user.setJukeboxRole(true);
- } else if (ROLE_ID_SHARE.equals(role)) {
- user.setShareRole(true);
- } else {
- LOG.warn("Unknown role: '" + role + '\'');
- }
- }
- }
- }
-
- private void writeRoles(User user) {
- synchronized (user.getUsername().intern()) {
- String sql = "delete from user_role where username=?";
- getJdbcTemplate().update(sql, new Object[]{user.getUsername()});
- sql = "insert into user_role (username, role_id) values(?, ?)";
- if (user.isAdminRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_ADMIN});
- }
- if (user.isDownloadRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_DOWNLOAD});
- }
- if (user.isUploadRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_UPLOAD});
- }
- if (user.isPlaylistRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_PLAYLIST});
- }
- if (user.isCoverArtRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_COVER_ART});
- }
- if (user.isCommentRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_COMMENT});
- }
- if (user.isPodcastRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_PODCAST});
- }
- if (user.isStreamRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_STREAM});
- }
- if (user.isJukeboxRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_JUKEBOX});
- }
- if (user.isSettingsRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_SETTINGS});
- }
- if (user.isShareRole()) {
- getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_SHARE});
- }
- }
- }
-
- private class UserRowMapper implements ParameterizedRowMapper<User> {
- public User mapRow(ResultSet rs, int rowNum) throws SQLException {
- User user = new User(rs.getString(1), decrypt(rs.getString(2)), rs.getString(3), rs.getBoolean(4),
- rs.getLong(5), rs.getLong(6), rs.getLong(7));
- readRoles(user);
- return user;
- }
- }
-
- private static class UserSettingsRowMapper implements ParameterizedRowMapper<UserSettings> {
- public UserSettings mapRow(ResultSet rs, int rowNum) throws SQLException {
- int col = 1;
- UserSettings settings = new UserSettings(rs.getString(col++));
- settings.setLocale(StringUtil.parseLocale(rs.getString(col++)));
- settings.setThemeId(rs.getString(col++));
- settings.setFinalVersionNotificationEnabled(rs.getBoolean(col++));
- settings.setBetaVersionNotificationEnabled(rs.getBoolean(col++));
-
- settings.getMainVisibility().setCaptionCutoff(rs.getInt(col++));
- settings.getMainVisibility().setTrackNumberVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setArtistVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setAlbumVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setGenreVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setYearVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setBitRateVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setDurationVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setFormatVisible(rs.getBoolean(col++));
- settings.getMainVisibility().setFileSizeVisible(rs.getBoolean(col++));
-
- settings.getPlaylistVisibility().setCaptionCutoff(rs.getInt(col++));
- settings.getPlaylistVisibility().setTrackNumberVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setArtistVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setAlbumVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setGenreVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setYearVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setBitRateVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setDurationVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setFormatVisible(rs.getBoolean(col++));
- settings.getPlaylistVisibility().setFileSizeVisible(rs.getBoolean(col++));
-
- settings.setLastFmEnabled(rs.getBoolean(col++));
- settings.setLastFmUsername(rs.getString(col++));
- settings.setLastFmPassword(decrypt(rs.getString(col++)));
-
- settings.setTranscodeScheme(TranscodeScheme.valueOf(rs.getString(col++)));
- settings.setShowNowPlayingEnabled(rs.getBoolean(col++));
- settings.setSelectedMusicFolderId(rs.getInt(col++));
- settings.setPartyModeEnabled(rs.getBoolean(col++));
- settings.setNowPlayingAllowed(rs.getBoolean(col++));
- settings.setAvatarScheme(AvatarScheme.valueOf(rs.getString(col++)));
- settings.setSystemAvatarId((Integer) rs.getObject(col++));
- settings.setChanged(rs.getTimestamp(col++));
- settings.setShowChatEnabled(rs.getBoolean(col++));
-
- return settings;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema.java
deleted file mode 100644
index 674f85ca..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import org.springframework.jdbc.core.*;
-
-/**
- * Used for creating and evolving the database schema.
- *
- * @author Sindre Mehus
- */
-public abstract class Schema {
-
- /**
- * Executes this schema.
- * @param template The JDBC template to use.
- */
- public abstract void execute(JdbcTemplate template);
-
- /**
- * Returns whether the given table exists.
- * @param template The JDBC template to use.
- * @param table The table in question.
- * @return Whether the table exists.
- */
- protected boolean tableExists(JdbcTemplate template, String table) {
- try {
- template.execute("select 1 from " + table);
- } catch (Exception x) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns whether the given column in the given table exists.
- * @param template The JDBC template to use.
- * @param column The column in question.
- * @param table The table in question.
- * @return Whether the column exists.
- */
- protected boolean columnExists(JdbcTemplate template, String column, String table) {
- try {
- template.execute("select " + column + " from " + table + " where 1 = 0");
- } catch (Exception x) {
- return false;
- }
- return true;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema25.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema25.java
deleted file mode 100644
index 33cc2525..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema25.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import org.springframework.jdbc.core.*;
-import net.sourceforge.subsonic.*;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 2.5.
- *
- * @author Sindre Mehus
- */
-public class Schema25 extends Schema{
- private static final Logger LOG = Logger.getLogger(Schema25.class);
-
- public void execute(JdbcTemplate template) {
- if (!tableExists(template, "version")) {
- LOG.info("Database table 'version' not found. Creating it.");
- template.execute("create table version (version int not null)");
- template.execute("insert into version values (1)");
- LOG.info("Database table 'version' was created successfully.");
- }
-
- if (!tableExists(template, "role")) {
- LOG.info("Database table 'role' not found. Creating it.");
- template.execute("create table role (" +
- "id int not null," +
- "name varchar not null," +
- "primary key (id))");
- template.execute("insert into role values (1, 'admin')");
- template.execute("insert into role values (2, 'download')");
- template.execute("insert into role values (3, 'upload')");
- template.execute("insert into role values (4, 'playlist')");
- template.execute("insert into role values (5, 'coverart')");
- LOG.info("Database table 'role' was created successfully.");
- }
-
- if (!tableExists(template, "user")) {
- LOG.info("Database table 'user' not found. Creating it.");
- template.execute("create table user (" +
- "username varchar not null," +
- "password varchar not null," +
- "primary key (username))");
- template.execute("insert into user values ('admin', 'admin')");
- LOG.info("Database table 'user' was created successfully.");
- }
-
- if (!tableExists(template, "user_role")) {
- LOG.info("Database table 'user_role' not found. Creating it.");
- template.execute("create table user_role (" +
- "username varchar not null," +
- "role_id int not null," +
- "primary key (username, role_id)," +
- "foreign key (username) references user(username)," +
- "foreign key (role_id) references role(id))");
- template.execute("insert into user_role values ('admin', 1)");
- template.execute("insert into user_role values ('admin', 2)");
- template.execute("insert into user_role values ('admin', 3)");
- template.execute("insert into user_role values ('admin', 4)");
- template.execute("insert into user_role values ('admin', 5)");
- LOG.info("Database table 'user_role' was created successfully.");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema26.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema26.java
deleted file mode 100644
index 6d60b29b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema26.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.*;
-import net.sourceforge.subsonic.util.Util;
-import org.springframework.jdbc.core.*;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 2.6.
- *
- * @author Sindre Mehus
- */
-public class Schema26 extends Schema{
- private static final Logger LOG = Logger.getLogger(Schema26.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 2") == 0) {
- LOG.info("Updating database schema to version 2.");
- template.execute("insert into version values (2)");
- }
-
- if (!tableExists(template, "music_folder")) {
- LOG.info("Database table 'music_folder' not found. Creating it.");
- template.execute("create table music_folder (" +
- "id identity," +
- "path varchar not null," +
- "name varchar not null," +
- "enabled boolean not null)");
- template.execute("insert into music_folder values (null, '" + Util.getDefaultMusicFolder() + "', 'Music', true)");
- LOG.info("Database table 'music_folder' was created successfully.");
- }
-
- if (!tableExists(template, "music_file_info")) {
- LOG.info("Database table 'music_file_info' not found. Creating it.");
- template.execute("create cached table music_file_info (" +
- "id identity," +
- "path varchar not null," +
- "rating int," +
- "comment varchar," +
- "play_count int," +
- "last_played datetime)");
- template.execute("create index idx_music_file_info_path on music_file_info(path)");
- LOG.info("Database table 'music_file_info' was created successfully.");
- }
-
- if (!tableExists(template, "internet_radio")) {
- LOG.info("Database table 'internet_radio' not found. Creating it.");
- template.execute("create table internet_radio (" +
- "id identity," +
- "name varchar not null," +
- "stream_url varchar not null," +
- "homepage_url varchar," +
- "enabled boolean not null)");
- LOG.info("Database table 'internet_radio' was created successfully.");
- }
-
- if (!tableExists(template, "player")) {
- LOG.info("Database table 'player' not found. Creating it.");
- template.execute("create table player (" +
- "id int not null," +
- "name varchar," +
- "type varchar," +
- "username varchar," +
- "ip_address varchar," +
- "auto_control_enabled boolean not null," +
- "last_seen datetime," +
- "cover_art_scheme varchar not null," +
- "transcode_scheme varchar not null," +
- "primary key (id))");
- LOG.info("Database table 'player' was created successfully.");
- }
-
- // 'dynamic_ip' was added in 2.6.beta2
- if (!columnExists(template, "dynamic_ip", "player")) {
- LOG.info("Database column 'player.dynamic_ip' not found. Creating it.");
- template.execute("alter table player " +
- "add dynamic_ip boolean default true not null");
- LOG.info("Database column 'player.dynamic_ip' was added successfully.");
- }
-
- if (template.queryForInt("select count(*) from role where id = 6") == 0) {
- LOG.info("Role 'comment' not found in database. Creating it.");
- template.execute("insert into role values (6, 'comment')");
- template.execute("insert into user_role " +
- "select distinct u.username, 6 from user u, user_role ur " +
- "where u.username = ur.username and ur.role_id in (1, 5)");
- LOG.info("Role 'comment' was created successfully.");
- }
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema27.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema27.java
deleted file mode 100644
index 4057622e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema27.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.*;
-import org.springframework.jdbc.core.*;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 2.7.
- *
- * @author Sindre Mehus
- */
-public class Schema27 extends Schema{
- private static final Logger LOG = Logger.getLogger(Schema27.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 3") == 0) {
- LOG.info("Updating database schema to version 3.");
- template.execute("insert into version values (3)");
-
- LOG.info("Converting database column 'music_file_info.path' to varchar_ignorecase.");
- template.execute("drop index idx_music_file_info_path");
- template.execute("alter table music_file_info alter column path varchar_ignorecase not null");
- template.execute("create index idx_music_file_info_path on music_file_info(path)");
- LOG.info("Database column 'music_file_info.path' was converted successfully.");
- }
-
- if (!columnExists(template, "bytes_streamed", "user")) {
- LOG.info("Database columns 'user.bytes_streamed/downloaded/uploaded' not found. Creating them.");
- template.execute("alter table user add bytes_streamed bigint default 0 not null");
- template.execute("alter table user add bytes_downloaded bigint default 0 not null");
- template.execute("alter table user add bytes_uploaded bigint default 0 not null");
- LOG.info("Database columns 'user.bytes_streamed/downloaded/uploaded' were added successfully.");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema28.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema28.java
deleted file mode 100644
index dbee6730..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema28.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.*;
-import org.springframework.jdbc.core.*;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 2.8.
- *
- * @author Sindre Mehus
- */
-public class Schema28 extends Schema {
- private static final Logger LOG = Logger.getLogger(Schema28.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 4") == 0) {
- LOG.info("Updating database schema to version 4.");
- template.execute("insert into version values (4)");
- }
-
- if (!tableExists(template, "user_settings")) {
- LOG.info("Database table 'user_settings' not found. Creating it.");
- template.execute("create table user_settings (" +
- "username varchar not null," +
- "locale varchar," +
- "theme_id varchar," +
- "final_version_notification boolean default true not null," +
- "beta_version_notification boolean default false not null," +
- "main_caption_cutoff int default 35 not null," +
- "main_track_number boolean default true not null," +
- "main_artist boolean default true not null," +
- "main_album boolean default false not null," +
- "main_genre boolean default false not null," +
- "main_year boolean default false not null," +
- "main_bit_rate boolean default false not null," +
- "main_duration boolean default true not null," +
- "main_format boolean default false not null," +
- "main_file_size boolean default false not null," +
- "playlist_caption_cutoff int default 35 not null," +
- "playlist_track_number boolean default false not null," +
- "playlist_artist boolean default true not null," +
- "playlist_album boolean default true not null," +
- "playlist_genre boolean default false not null," +
- "playlist_year boolean default true not null," +
- "playlist_bit_rate boolean default false not null," +
- "playlist_duration boolean default true not null," +
- "playlist_format boolean default true not null," +
- "playlist_file_size boolean default true not null," +
- "primary key (username)," +
- "foreign key (username) references user(username) on delete cascade)");
- LOG.info("Database table 'user_settings' was created successfully.");
- }
-
- if (!tableExists(template, "transcoding")) {
- LOG.info("Database table 'transcoding' not found. Creating it.");
- template.execute("create table transcoding (" +
- "id identity," +
- "name varchar not null," +
- "source_format varchar not null," +
- "target_format varchar not null," +
- "step1 varchar not null," +
- "step2 varchar," +
- "step3 varchar," +
- "enabled boolean not null)");
-
- template.execute("insert into transcoding values(null,'wav > mp3', 'wav', 'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'flac > mp3','flac','mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'ogg > mp3' ,'ogg' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'wma > mp3' ,'wma' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'m4a > mp3' ,'m4a' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,false)");
- template.execute("insert into transcoding values(null,'aac > mp3' ,'aac' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,false)");
- template.execute("insert into transcoding values(null,'ape > mp3' ,'ape' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'mpc > mp3' ,'mpc' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'mv > mp3' ,'mv' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
- template.execute("insert into transcoding values(null,'shn > mp3' ,'shn' ,'mp3','ffmpeg -i %s -v 0 -f wav -','lame -b %b --tt %t --ta %a --tl %l -S --resample 44.1 - -',null,true)");
-
- LOG.info("Database table 'transcoding' was created successfully.");
- }
-
- if (!tableExists(template, "player_transcoding")) {
- LOG.info("Database table 'player_transcoding' not found. Creating it.");
- template.execute("create table player_transcoding (" +
- "player_id int not null," +
- "transcoding_id int not null," +
- "primary key (player_id, transcoding_id)," +
- "foreign key (player_id) references player(id) on delete cascade," +
- "foreign key (transcoding_id) references transcoding(id) on delete cascade)");
- LOG.info("Database table 'player_transcoding' was created successfully.");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema29.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema29.java
deleted file mode 100644
index dd4748d1..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema29.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.*;
-import org.springframework.jdbc.core.*;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 2.9.
- *
- * @author Sindre Mehus
- */
-public class Schema29 extends Schema {
- private static final Logger LOG = Logger.getLogger(Schema29.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 5") == 0) {
- LOG.info("Updating database schema to version 5.");
- template.execute("insert into version values (5)");
- }
-
- if (!tableExists(template, "user_rating")) {
- LOG.info("Database table 'user_rating' not found. Creating it.");
- template.execute("create table user_rating (" +
- "username varchar not null," +
- "path varchar not null," +
- "rating double not null," +
- "primary key (username, path)," +
- "foreign key (username) references user(username) on delete cascade)");
- LOG.info("Database table 'user_rating' was created successfully.");
-
- template.execute("insert into user_rating select 'admin', path, rating from music_file_info " +
- "where rating is not null and rating > 0");
- LOG.info("Migrated data from 'music_file_info' to 'user_rating'.");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema30.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema30.java
deleted file mode 100644
index cdea199b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema30.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.*;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-import org.springframework.jdbc.core.*;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.0.
- *
- * @author Sindre Mehus
- */
-public class Schema30 extends Schema {
- private static final Logger LOG = Logger.getLogger(Schema30.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 6") == 0) {
- LOG.info("Updating database schema to version 6.");
- template.execute("insert into version values (6)");
- }
-
- if (!columnExists(template, "last_fm_enabled", "user_settings")) {
- LOG.info("Database columns 'user_settings.last_fm_*' not found. Creating them.");
- template.execute("alter table user_settings add last_fm_enabled boolean default false not null");
- template.execute("alter table user_settings add last_fm_username varchar null");
- template.execute("alter table user_settings add last_fm_password varchar null");
- LOG.info("Database columns 'user_settings.last_fm_*' were added successfully.");
- }
-
- if (!columnExists(template, "transcode_scheme", "user_settings")) {
- LOG.info("Database column 'user_settings.transcode_scheme' not found. Creating it.");
- template.execute("alter table user_settings add transcode_scheme varchar default '" +
- TranscodeScheme.OFF.name() + "' not null");
- LOG.info("Database column 'user_settings.transcode_scheme' was added successfully.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema31.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema31.java
deleted file mode 100644
index 00fb0c87..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema31.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.1.
- *
- * @author Sindre Mehus
- */
-public class Schema31 extends Schema {
- private static final Logger LOG = Logger.getLogger(Schema31.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 7") == 0) {
- LOG.info("Updating database schema to version 7.");
- template.execute("insert into version values (7)");
- }
-
- if (!columnExists(template, "enabled", "music_file_info")) {
- LOG.info("Database column 'music_file_info.enabled' not found. Creating it.");
- template.execute("alter table music_file_info add enabled boolean default true not null");
- LOG.info("Database column 'music_file_info.enabled' was added successfully.");
- }
-
- if (!columnExists(template, "default_active", "transcoding")) {
- LOG.info("Database column 'transcoding.default_active' not found. Creating it.");
- template.execute("alter table transcoding add default_active boolean default true not null");
- LOG.info("Database column 'transcoding.default_active' was added successfully.");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema32.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema32.java
deleted file mode 100644
index a1439bb0..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema32.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.2.
- *
- * @author Sindre Mehus
- */
-public class Schema32 extends Schema {
- private static final Logger LOG = Logger.getLogger(Schema32.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 8") == 0) {
- LOG.info("Updating database schema to version 8.");
- template.execute("insert into version values (8)");
- }
-
- if (!columnExists(template, "show_now_playing", "user_settings")) {
- LOG.info("Database column 'user_settings.show_now_playing' not found. Creating it.");
- template.execute("alter table user_settings add show_now_playing boolean default true not null");
- LOG.info("Database column 'user_settings.show_now_playing' was added successfully.");
- }
-
- if (!columnExists(template, "selected_music_folder_id", "user_settings")) {
- LOG.info("Database column 'user_settings.selected_music_folder_id' not found. Creating it.");
- template.execute("alter table user_settings add selected_music_folder_id int default -1 not null");
- LOG.info("Database column 'user_settings.selected_music_folder_id' was added successfully.");
- }
-
- if (!tableExists(template, "podcast_channel")) {
- LOG.info("Database table 'podcast_channel' not found. Creating it.");
- template.execute("create table podcast_channel (" +
- "id identity," +
- "url varchar not null," +
- "title varchar," +
- "description varchar," +
- "status varchar not null," +
- "error_message varchar)");
- LOG.info("Database table 'podcast_channel' was created successfully.");
- }
-
- if (!tableExists(template, "podcast_episode")) {
- LOG.info("Database table 'podcast_episode' not found. Creating it.");
- template.execute("create table podcast_episode (" +
- "id identity," +
- "channel_id int not null," +
- "url varchar not null," +
- "path varchar," +
- "title varchar," +
- "description varchar," +
- "publish_date datetime," +
- "duration varchar," +
- "bytes_total bigint," +
- "bytes_downloaded bigint," +
- "status varchar not null," +
- "error_message varchar," +
- "foreign key (channel_id) references podcast_channel(id) on delete cascade)");
- LOG.info("Database table 'podcast_episode' was created successfully.");
- }
-
- if (template.queryForInt("select count(*) from role where id = 7") == 0) {
- LOG.info("Role 'podcast' not found in database. Creating it.");
- template.execute("insert into role values (7, 'podcast')");
- template.execute("insert into user_role " +
- "select distinct u.username, 7 from user u, user_role ur " +
- "where u.username = ur.username and ur.role_id = 1");
- LOG.info("Role 'podcast' was created successfully.");
- }
-
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema33.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema33.java
deleted file mode 100644
index 6f754306..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema33.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.3.
- *
- * @author Sindre Mehus
- */
-public class Schema33 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema33.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 9") == 0) {
- LOG.info("Updating database schema to version 9.");
- template.execute("insert into version values (9)");
- }
-
- if (!columnExists(template, "client_side_playlist", "player")) {
- LOG.info("Database column 'player.client_side_playlist' not found. Creating it.");
- template.execute("alter table player add client_side_playlist boolean default false not null");
- LOG.info("Database column 'player.client_side_playlist' was added successfully.");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema34.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema34.java
deleted file mode 100644
index daaf98ca..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema34.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.4.
- *
- * @author Sindre Mehus
- */
-public class Schema34 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema34.class);
-
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 10") == 0) {
- LOG.info("Updating database schema to version 10.");
- template.execute("insert into version values (10)");
- }
-
- if (!columnExists(template, "ldap_authenticated", "user")) {
- LOG.info("Database column 'user.ldap_authenticated' not found. Creating it.");
- template.execute("alter table user add ldap_authenticated boolean default false not null");
- LOG.info("Database column 'user.ldap_authenticated' was added successfully.");
- }
-
- if (!columnExists(template, "party_mode_enabled", "user_settings")) {
- LOG.info("Database column 'user_settings.party_mode_enabled' not found. Creating it.");
- template.execute("alter table user_settings add party_mode_enabled boolean default false not null");
- LOG.info("Database column 'user_settings.party_mode_enabled' was added successfully.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema35.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema35.java
deleted file mode 100644
index 56b5073d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema35.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.apache.commons.io.IOUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.5.
- *
- * @author Sindre Mehus
- */
-public class Schema35 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema35.class);
-
- private static final String[] AVATARS = {
- "Formal", "Engineer", "Footballer", "Green-Boy",
-
- "Linux-Zealot", "Mac-Zealot", "Windows-Zealot", "Army-Officer", "Beatnik",
- "All-Caps", "Clown", "Commie-Pinko", "Forum-Flirt", "Gamer", "Hopelessly-Addicted",
- "Jekyll-And-Hyde", "Joker", "Lurker", "Moderator", "Newbie", "No-Dissent",
- "Performer", "Push-My-Button", "Ray-Of-Sunshine", "Red-Hot-Chili-Peppers-1",
- "Red-Hot-Chili-Peppers-2", "Red-Hot-Chili-Peppers-3", "Red-Hot-Chili-Peppers-4",
- "Ringmaster", "Rumor-Junkie", "Sozzled-Surfer", "Statistician", "Tech-Support",
- "The-Guru", "The-Referee", "Troll", "Uptight",
-
- "Fire-Guitar", "Drum", "Headphones", "Mic", "Turntable", "Vinyl",
-
- "Cool", "Laugh", "Study"
- };
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 11") == 0) {
- LOG.info("Updating database schema to version 11.");
- template.execute("insert into version values (11)");
- }
-
- if (!columnExists(template, "now_playing_allowed", "user_settings")) {
- LOG.info("Database column 'user_settings.now_playing_allowed' not found. Creating it.");
- template.execute("alter table user_settings add now_playing_allowed boolean default true not null");
- LOG.info("Database column 'user_settings.now_playing_allowed' was added successfully.");
- }
-
- if (!columnExists(template, "web_player_default", "user_settings")) {
- LOG.info("Database column 'user_settings.web_player_default' not found. Creating it.");
- template.execute("alter table user_settings add web_player_default boolean default false not null");
- LOG.info("Database column 'user_settings.web_player_default' was added successfully.");
- }
-
- if (template.queryForInt("select count(*) from role where id = 8") == 0) {
- LOG.info("Role 'stream' not found in database. Creating it.");
- template.execute("insert into role values (8, 'stream')");
- template.execute("insert into user_role select distinct u.username, 8 from user u");
- LOG.info("Role 'stream' was created successfully.");
- }
-
- if (!tableExists(template, "system_avatar")) {
- LOG.info("Database table 'system_avatar' not found. Creating it.");
- template.execute("create table system_avatar (" +
- "id identity," +
- "name varchar," +
- "created_date datetime not null," +
- "mime_type varchar not null," +
- "width int not null," +
- "height int not null," +
- "data binary not null)");
- LOG.info("Database table 'system_avatar' was created successfully.");
- }
-
- for (String avatar : AVATARS) {
- createAvatar(template, avatar);
- }
-
- if (!tableExists(template, "custom_avatar")) {
- LOG.info("Database table 'custom_avatar' not found. Creating it.");
- template.execute("create table custom_avatar (" +
- "id identity," +
- "name varchar," +
- "created_date datetime not null," +
- "mime_type varchar not null," +
- "width int not null," +
- "height int not null," +
- "data binary not null," +
- "username varchar not null," +
- "foreign key (username) references user(username) on delete cascade)");
- LOG.info("Database table 'custom_avatar' was created successfully.");
- }
-
- if (!columnExists(template, "avatar_scheme", "user_settings")) {
- LOG.info("Database column 'user_settings.avatar_scheme' not found. Creating it.");
- template.execute("alter table user_settings add avatar_scheme varchar default 'NONE' not null");
- LOG.info("Database column 'user_settings.avatar_scheme' was added successfully.");
- }
-
- if (!columnExists(template, "system_avatar_id", "user_settings")) {
- LOG.info("Database column 'user_settings.system_avatar_id' not found. Creating it.");
- template.execute("alter table user_settings add system_avatar_id int");
- template.execute("alter table user_settings add foreign key (system_avatar_id) references system_avatar(id)");
- LOG.info("Database column 'user_settings.system_avatar_id' was added successfully.");
- }
-
- if (!columnExists(template, "jukebox", "player")) {
- LOG.info("Database column 'player.jukebox' not found. Creating it.");
- template.execute("alter table player add jukebox boolean default false not null");
- LOG.info("Database column 'player.jukebox' was added successfully.");
- }
- }
-
- private void createAvatar(JdbcTemplate template, String avatar) {
- if (template.queryForInt("select count(*) from system_avatar where name = ?", new Object[]{avatar}) == 0) {
-
- InputStream in = null;
- try {
- in = getClass().getResourceAsStream(avatar + ".png");
- byte[] imageData = IOUtils.toByteArray(in);
- template.update("insert into system_avatar values (null, ?, ?, ?, ?, ?, ?)",
- new Object[]{avatar, new Date(), "image/png", 48, 48, imageData});
- LOG.info("Created avatar '" + avatar + "'.");
- } catch (IOException x) {
- LOG.error("Failed to create avatar '" + avatar + "'.", x);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema36.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema36.java
deleted file mode 100644
index caed6cdb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema36.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implementes the database schema for Subsonic version 3.6.
- *
- * @author Sindre Mehus
- */
-public class Schema36 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema36.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 12") == 0) {
- LOG.info("Updating database schema to version 12.");
- template.execute("insert into version values (12)");
- }
-
- if (!columnExists(template, "technology", "player")) {
- LOG.info("Database column 'player.technology' not found. Creating it.");
- template.execute("alter table player add technology varchar default 'WEB' not null");
- LOG.info("Database column 'player.technology' was added successfully.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema37.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema37.java
deleted file mode 100644
index afb8fb6e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema37.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 3.7.
- *
- * @author Sindre Mehus
- */
-public class Schema37 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema37.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 13") == 0) {
- LOG.info("Updating database schema to version 13.");
- template.execute("insert into version values (13)");
- }
-
- if (template.queryForInt("select count(*) from role where id = 9") == 0) {
- LOG.info("Role 'settings' not found in database. Creating it.");
- template.execute("insert into role values (9, 'settings')");
- template.execute("insert into user_role select distinct u.username, 9 from user u");
- LOG.info("Role 'settings' was created successfully.");
- }
-
- if (template.queryForInt("select count(*) from role where id = 10") == 0) {
- LOG.info("Role 'jukebox' not found in database. Creating it.");
- template.execute("insert into role values (10, 'jukebox')");
- template.execute("insert into user_role " +
- "select distinct u.username, 10 from user u, user_role ur " +
- "where u.username = ur.username and ur.role_id = 1");
- LOG.info("Role 'jukebox' was created successfully.");
- }
-
- if (!columnExists(template, "changed", "music_folder")) {
- LOG.info("Database column 'music_folder.changed' not found. Creating it.");
- template.execute("alter table music_folder add changed datetime default 0 not null");
- LOG.info("Database column 'music_folder.changed' was added successfully.");
- }
-
- if (!columnExists(template, "changed", "internet_radio")) {
- LOG.info("Database column 'internet_radio.changed' not found. Creating it.");
- template.execute("alter table internet_radio add changed datetime default 0 not null");
- LOG.info("Database column 'internet_radio.changed' was added successfully.");
- }
-
- if (!columnExists(template, "changed", "user_settings")) {
- LOG.info("Database column 'user_settings.changed' not found. Creating it.");
- template.execute("alter table user_settings add changed datetime default 0 not null");
- LOG.info("Database column 'user_settings.changed' was added successfully.");
- }
-
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema38.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema38.java
deleted file mode 100644
index fac49511..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema38.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 3.8.
- *
- * @author Sindre Mehus
- */
-public class Schema38 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema38.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 14") == 0) {
- LOG.info("Updating database schema to version 14.");
- template.execute("insert into version values (14)");
- }
-
- if (!columnExists(template, "client_id", "player")) {
- LOG.info("Database column 'player.client_id' not found. Creating it.");
- template.execute("alter table player add client_id varchar");
- LOG.info("Database column 'player.client_id' was added successfully.");
- }
-
- if (!columnExists(template, "show_chat", "user_settings")) {
- LOG.info("Database column 'user_settings.show_chat' not found. Creating it.");
- template.execute("alter table user_settings add show_chat boolean default true not null");
- LOG.info("Database column 'user_settings.show_chat' was added successfully.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema40.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema40.java
deleted file mode 100644
index e01d1ef0..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema40.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 4.0.
- *
- * @author Sindre Mehus
- */
-public class Schema40 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema40.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 15") == 0) {
- LOG.info("Updating database schema to version 15.");
- template.execute("insert into version values (15)");
-
- // Reset stream byte count since they have been wrong in earlier releases.
- template.execute("update user set bytes_streamed = 0");
- LOG.info("Reset stream byte count statistics.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema43.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema43.java
deleted file mode 100644
index cba1572c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema43.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import net.sourceforge.subsonic.Logger;
-
-import java.util.Arrays;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 4.3.
- *
- * @author Sindre Mehus
- */
-public class Schema43 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema43.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- // version 16 was used for 4.3.beta1
- if (template.queryForInt("select count(*) from version where version = 16") == 0) {
- LOG.info("Updating database schema to version 16.");
- template.execute("insert into version values (16)");
- }
-
- if (template.queryForInt("select count(*) from version where version = 17") == 0) {
- LOG.info("Updating database schema to version 17.");
- template.execute("insert into version values (17)");
-
- for (String format : Arrays.asList("avi", "mpg", "mpeg", "mp4", "m4v", "mkv", "mov", "wmv", "ogv")) {
- template.update("delete from transcoding where source_format=? and target_format=?", new Object[] {format, "flv"});
- template.execute("insert into transcoding values(null,'" + format + " > flv' ,'" + format + "' ,'flv','ffmpeg -ss %o -i %s -async 1 -b %bk -s %wx%h -ar 44100 -ac 2 -v 0 -f flv -',null,null,true,true)");
- template.execute("insert into player_transcoding select p.id as player_id, t.id as transaction_id from player p, transcoding t where t.name = '" + format + " > flv'");
- }
- LOG.info("Created video transcoding configuration.");
- }
-
- if (!columnExists(template, "email", "user")) {
- LOG.info("Database column 'user.email' not found. Creating it.");
- template.execute("alter table user add email varchar");
- LOG.info("Database column 'user.email' was added successfully.");
- }
-
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema45.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema45.java
deleted file mode 100644
index d82f2a92..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema45.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 4.5.
- *
- * @author Sindre Mehus
- */
-public class Schema45 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema45.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 18") == 0) {
- LOG.info("Updating database schema to version 18.");
- template.execute("insert into version values (18)");
- }
-
- if (template.queryForInt("select count(*) from role where id = 11") == 0) {
- LOG.info("Role 'share' not found in database. Creating it.");
- template.execute("insert into role values (11, 'share')");
- template.execute("insert into user_role " +
- "select distinct u.username, 11 from user u, user_role ur " +
- "where u.username = ur.username and ur.role_id = 1");
- LOG.info("Role 'share' was created successfully.");
- }
-
- if (!tableExists(template, "share")) {
- LOG.info("Table 'share' not found in database. Creating it.");
- template.execute("create cached table share (" +
- "id identity," +
- "name varchar not null," +
- "description varchar," +
- "username varchar not null," +
- "created datetime not null," +
- "expires datetime," +
- "last_visited datetime," +
- "visit_count int default 0 not null," +
- "unique (name)," +
- "foreign key (username) references user(username) on delete cascade)");
- template.execute("create index idx_share_name on share(name)");
-
- LOG.info("Table 'share' was created successfully.");
- LOG.info("Table 'share_file' not found in database. Creating it.");
- template.execute("create cached table share_file (" +
- "id identity," +
- "share_id int not null," +
- "path varchar not null," +
- "foreign key (share_id) references share(id) on delete cascade)");
- LOG.info("Table 'share_file' was created successfully.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema46.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema46.java
deleted file mode 100644
index c1fcf357..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema46.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import net.sourceforge.subsonic.Logger;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 4.6.
- *
- * @author Sindre Mehus
- */
-public class Schema46 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema46.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 19") == 0) {
- LOG.info("Updating database schema to version 19.");
- template.execute("insert into version values (19)");
- }
-
- if (!tableExists(template, "transcoding2")) {
- LOG.info("Database table 'transcoding2' not found. Creating it.");
- template.execute("create table transcoding2 (" +
- "id identity," +
- "name varchar not null," +
- "source_formats varchar not null," +
- "target_format varchar not null," +
- "step1 varchar not null," +
- "step2 varchar," +
- "step3 varchar)");
-
- template.execute("insert into transcoding2 values(null,'mp3 audio'," +
- "'ogg oga aac m4a flac wav wma aif aiff ape mpc shn', 'mp3', " +
- "'ffmpeg -i %s -ab %bk -v 0 -f mp3 -', null, null)");
-
- template.execute("insert into transcoding2 values(null,'flv/h264 video', " +
- "'avi mpg mpeg mp4 m4v mkv mov wmv ogv divx m2ts', 'flv', " +
- "'ffmpeg -ss %o -i %s -async 1 -b %bk -s %wx%h -ar 44100 -ac 2 -v 0 -f flv -vcodec libx264 -preset superfast -threads 0 -', null, null)");
-
- LOG.info("Database table 'transcoding2' was created successfully.");
- }
-
- if (!tableExists(template, "player_transcoding2")) {
- LOG.info("Database table 'player_transcoding2' not found. Creating it.");
- template.execute("create table player_transcoding2 (" +
- "player_id int not null," +
- "transcoding_id int not null," +
- "primary key (player_id, transcoding_id)," +
- "foreign key (player_id) references player(id) on delete cascade," +
- "foreign key (transcoding_id) references transcoding2(id) on delete cascade)");
-
- template.execute("insert into player_transcoding2(player_id, transcoding_id) " +
- "select distinct p.id, t.id from player p, transcoding2 t");
-
- LOG.info("Database table 'player_transcoding2' was created successfully.");
- }
-
- if (!columnExists(template, "default_active", "transcoding2")) {
- LOG.info("Database column 'transcoding2.default_active' not found. Creating it.");
- template.execute("alter table transcoding2 add default_active boolean default true not null");
- LOG.info("Database column 'transcoding2.default_active' was added successfully.");
- }
- }
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema47.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema47.java
deleted file mode 100644
index 8b290b47..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/dao/schema/Schema47.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.dao.schema;
-
-import net.sourceforge.subsonic.Logger;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-/**
- * Used for creating and evolving the database schema.
- * This class implements the database schema for Subsonic version 4.7.
- *
- * @author Sindre Mehus
- */
-public class Schema47 extends Schema {
-
- private static final Logger LOG = Logger.getLogger(Schema47.class);
-
- @Override
- public void execute(JdbcTemplate template) {
-
- if (template.queryForInt("select count(*) from version where version = 20") == 0) {
- LOG.info("Updating database schema to version 20.");
- template.execute("insert into version values (20)");
- }
-
- if (!tableExists(template, "media_file")) {
- LOG.info("Database table 'media_file' not found. Creating it.");
- template.execute("create cached table media_file (" +
- "id identity," +
- "path varchar not null," +
- "folder varchar," +
- "type varchar not null," +
- "format varchar," +
- "title varchar," +
- "album varchar," +
- "artist varchar," +
- "album_artist varchar," +
- "disc_number int," +
- "track_number int," +
- "year int," +
- "genre varchar," +
- "bit_rate int," +
- "variable_bit_rate boolean not null," +
- "duration_seconds int," +
- "file_size bigint," +
- "width int," +
- "height int," +
- "cover_art_path varchar," +
- "parent_path varchar," +
- "play_count int not null," +
- "last_played datetime," +
- "comment varchar," +
- "created datetime not null," +
- "changed datetime not null," +
- "last_scanned datetime not null," +
- "children_last_updated datetime not null," +
- "present boolean not null," +
- "version int not null," +
- "unique (path))");
-
- template.execute("create index idx_media_file_path on media_file(path)");
- template.execute("create index idx_media_file_parent_path on media_file(parent_path)");
- template.execute("create index idx_media_file_type on media_file(type)");
- template.execute("create index idx_media_file_album on media_file(album)");
- template.execute("create index idx_media_file_artist on media_file(artist)");
- template.execute("create index idx_media_file_album_artist on media_file(album_artist)");
- template.execute("create index idx_media_file_present on media_file(present)");
- template.execute("create index idx_media_file_genre on media_file(genre)");
- template.execute("create index idx_media_file_play_count on media_file(play_count)");
- template.execute("create index idx_media_file_created on media_file(created)");
- template.execute("create index idx_media_file_last_played on media_file(last_played)");
-
- LOG.info("Database table 'media_file' was created successfully.");
- }
-
- if (!tableExists(template, "artist")) {
- LOG.info("Database table 'artist' not found. Creating it.");
- template.execute("create cached table artist (" +
- "id identity," +
- "name varchar not null," +
- "cover_art_path varchar," +
- "album_count int default 0 not null," +
- "last_scanned datetime not null," +
- "present boolean not null," +
- "unique (name))");
-
- template.execute("create index idx_artist_name on artist(name)");
- template.execute("create index idx_artist_present on artist(present)");
-
- LOG.info("Database table 'artist' was created successfully.");
- }
-
- if (!tableExists(template, "album")) {
- LOG.info("Database table 'album' not found. Creating it.");
- template.execute("create cached table album (" +
- "id identity," +
- "path varchar not null," +
- "name varchar not null," +
- "artist varchar not null," +
- "song_count int default 0 not null," +
- "duration_seconds int default 0 not null," +
- "cover_art_path varchar," +
- "play_count int default 0 not null," +
- "last_played datetime," +
- "comment varchar," +
- "created datetime not null," +
- "last_scanned datetime not null," +
- "present boolean not null," +
- "unique (artist, name))");
-
- template.execute("create index idx_album_artist_name on album(artist, name)");
- template.execute("create index idx_album_play_count on album(play_count)");
- template.execute("create index idx_album_last_played on album(last_played)");
- template.execute("create index idx_album_present on album(present)");
-
- LOG.info("Database table 'album' was created successfully.");
- }
-
- if (!tableExists(template, "starred_media_file")) {
- LOG.info("Database table 'starred_media_file' not found. Creating it.");
- template.execute("create table starred_media_file (" +
- "id identity," +
- "media_file_id int not null," +
- "username varchar not null," +
- "created datetime not null," +
- "foreign key (media_file_id) references media_file(id) on delete cascade,"+
- "foreign key (username) references user(username) on delete cascade," +
- "unique (media_file_id, username))");
-
- template.execute("create index idx_starred_media_file_media_file_id on starred_media_file(media_file_id)");
- template.execute("create index idx_starred_media_file_username on starred_media_file(username)");
-
- LOG.info("Database table 'starred_media_file' was created successfully.");
- }
-
- if (!tableExists(template, "starred_album")) {
- LOG.info("Database table 'starred_album' not found. Creating it.");
- template.execute("create table starred_album (" +
- "id identity," +
- "album_id int not null," +
- "username varchar not null," +
- "created datetime not null," +
- "foreign key (album_id) references album(id) on delete cascade," +
- "foreign key (username) references user(username) on delete cascade," +
- "unique (album_id, username))");
-
- template.execute("create index idx_starred_album_album_id on starred_album(album_id)");
- template.execute("create index idx_starred_album_username on starred_album(username)");
-
- LOG.info("Database table 'starred_album' was created successfully.");
- }
-
- if (!tableExists(template, "starred_artist")) {
- LOG.info("Database table 'starred_artist' not found. Creating it.");
- template.execute("create table starred_artist (" +
- "id identity," +
- "artist_id int not null," +
- "username varchar not null," +
- "created datetime not null," +
- "foreign key (artist_id) references artist(id) on delete cascade,"+
- "foreign key (username) references user(username) on delete cascade," +
- "unique (artist_id, username))");
-
- template.execute("create index idx_starred_artist_artist_id on starred_artist(artist_id)");
- template.execute("create index idx_starred_artist_username on starred_artist(username)");
-
- LOG.info("Database table 'starred_artist' was created successfully.");
- }
-
- if (!tableExists(template, "playlist")) {
- LOG.info("Database table 'playlist' not found. Creating it.");
- template.execute("create table playlist (" +
- "id identity," +
- "username varchar not null," +
- "is_public boolean not null," +
- "name varchar not null," +
- "comment varchar," +
- "file_count int default 0 not null," +
- "duration_seconds int default 0 not null," +
- "created datetime not null," +
- "changed datetime not null," +
- "foreign key (username) references user(username) on delete cascade)");
-
- LOG.info("Database table 'playlist' was created successfully.");
- }
-
- if (!columnExists(template, "imported_from", "playlist")) {
- LOG.info("Database column 'playlist.imported_from' not found. Creating it.");
- template.execute("alter table playlist add imported_from varchar");
- LOG.info("Database column 'playlist.imported_from' was added successfully.");
- }
-
- if (!tableExists(template, "playlist_file")) {
- LOG.info("Database table 'playlist_file' not found. Creating it.");
- template.execute("create cached table playlist_file (" +
- "id identity," +
- "playlist_id int not null," +
- "media_file_id int not null," +
- "foreign key (playlist_id) references playlist(id) on delete cascade," +
- "foreign key (media_file_id) references media_file(id) on delete cascade)");
-
- LOG.info("Database table 'playlist_file' was created successfully.");
- }
-
- if (!tableExists(template, "playlist_user")) {
- LOG.info("Database table 'playlist_user' not found. Creating it.");
- template.execute("create table playlist_user (" +
- "id identity," +
- "playlist_id int not null," +
- "username varchar not null," +
- "unique(playlist_id, username)," +
- "foreign key (playlist_id) references playlist(id) on delete cascade," +
- "foreign key (username) references user(username) on delete cascade)");
-
- LOG.info("Database table 'playlist_user' was created successfully.");
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Album.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Album.java
deleted file mode 100644
index 23e8afaf..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Album.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.Date;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class Album {
-
- private int id;
- private String path;
- private String name;
- private String artist;
- private int songCount;
- private int durationSeconds;
- private String coverArtPath;
- private int playCount;
- private Date lastPlayed;
- private String comment;
- private Date created;
- private Date lastScanned;
- private boolean present;
-
- public Album() {
- }
-
- public Album(int id, String path, String name, String artist, int songCount, int durationSeconds, String coverArtPath,
- int playCount, Date lastPlayed, String comment, Date created, Date lastScanned, boolean present) {
- this.id = id;
- this.path = path;
- this.name = name;
- this.artist = artist;
- this.songCount = songCount;
- this.durationSeconds = durationSeconds;
- this.coverArtPath = coverArtPath;
- this.playCount = playCount;
- this.lastPlayed = lastPlayed;
- this.comment = comment;
- this.created = created;
- this.lastScanned = lastScanned;
- this.present = present;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public void setArtist(String artist) {
- this.artist = artist;
- }
-
- public int getSongCount() {
- return songCount;
- }
-
- public void setSongCount(int songCount) {
- this.songCount = songCount;
- }
-
- public int getDurationSeconds() {
- return durationSeconds;
- }
-
- public void setDurationSeconds(int durationSeconds) {
- this.durationSeconds = durationSeconds;
- }
-
- public String getCoverArtPath() {
- return coverArtPath;
- }
-
- public void setCoverArtPath(String coverArtPath) {
- this.coverArtPath = coverArtPath;
- }
-
- public int getPlayCount() {
- return playCount;
- }
-
- public void setPlayCount(int playCount) {
- this.playCount = playCount;
- }
-
- public Date getLastPlayed() {
- return lastPlayed;
- }
-
- public void setLastPlayed(Date lastPlayed) {
- this.lastPlayed = lastPlayed;
- }
-
- public String getComment() {
- return comment;
- }
-
- public void setComment(String comment) {
- this.comment = comment;
- }
-
- public Date getCreated() {
- return created;
- }
-
- public void setCreated(Date created) {
- this.created = created;
- }
-
- public Date getLastScanned() {
- return lastScanned;
- }
-
- public void setLastScanned(Date lastScanned) {
- this.lastScanned = lastScanned;
- }
-
- public boolean isPresent() {
- return present;
- }
-
- public void setPresent(boolean present) {
- this.present = present;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Artist.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Artist.java
deleted file mode 100644
index e6141f78..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Artist.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.Date;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class Artist {
-
- private int id;
- private String name;
- private String coverArtPath;
- private int albumCount;
- private Date lastScanned;
- private boolean present;
-
- public Artist() {
- }
-
- public Artist(int id, String name, String coverArtPath, int albumCount, Date lastScanned, boolean present) {
- this.id = id;
- this.name = name;
- this.coverArtPath = coverArtPath;
- this.albumCount = albumCount;
- this.lastScanned = lastScanned;
- this.present = present;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getCoverArtPath() {
- return coverArtPath;
- }
-
- public void setCoverArtPath(String coverArtPath) {
- this.coverArtPath = coverArtPath;
- }
-
- public int getAlbumCount() {
- return albumCount;
- }
-
- public void setAlbumCount(int albumCount) {
- this.albumCount = albumCount;
- }
-
- public Date getLastScanned() {
- return lastScanned;
- }
-
- public void setLastScanned(Date lastScanned) {
- this.lastScanned = lastScanned;
- }
-
- public boolean isPresent() {
- return present;
- }
-
- public void setPresent(boolean present) {
- this.present = present;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Avatar.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Avatar.java
deleted file mode 100644
index 0089a8a3..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Avatar.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.Date;
-
-/**
- * An icon representing a user.
- *
- * @author Sindre Mehus
- */
-public class Avatar {
-
- private int id;
- private String name;
- private Date createdDate;
- private String mimeType;
- private int width;
- private int height;
- private byte[] data;
-
- public Avatar(int id, String name, Date createdDate, String mimeType, int width, int height, byte[] data) {
- this.id = id;
- this.name = name;
- this.createdDate = createdDate;
- this.mimeType = mimeType;
- this.width = width;
- this.height = height;
- this.data = data;
- }
-
- public int getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-
- public Date getCreatedDate() {
- return createdDate;
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- public int getWidth() {
- return width;
- }
-
- public int getHeight() {
- return height;
- }
-
- public byte[] getData() {
- return data;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/AvatarScheme.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/AvatarScheme.java
deleted file mode 100644
index 024dcb24..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/AvatarScheme.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Enumeration of avatar schemes.
- *
- * @author Sindre Mehus
- */
-public enum AvatarScheme {
-
- /**
- * No avatar should be displayed.
- */
- NONE(-1),
-
- /**
- * One of the system avatars should be displayed.
- */
- SYSTEM(0),
-
- /**
- * The custom avatar should be displayed.
- */
- CUSTOM(-2);
-
- private final int code;
-
- AvatarScheme(int code) {
- this.code = code;
- }
-
- public int getCode() {
- return code;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CacheElement.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CacheElement.java
deleted file mode 100644
index bb52eff7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CacheElement.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class CacheElement {
-
- private final long id;
- private final int type;
- private final String key;
- private final Object value;
- private final long created;
-
- public CacheElement(int type, String key, Object value, long created) {
- this.type = type;
- this.key = key;
- this.value = value;
- this.created = created;
-
- id = createId(type, key);
- }
-
- public static long createId(int type, String key) {
- return ((long) type << 32) | Math.abs(key.hashCode());
- }
-
- public long getId() {
- return id;
- }
-
- public int getType() {
- return type;
- }
-
- public String getKey() {
- return key;
- }
-
- public Object getValue() {
- return value;
- }
-
- public long getCreated() {
- return created;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CoverArtScheme.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CoverArtScheme.java
deleted file mode 100644
index 91293e9f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/CoverArtScheme.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Enumeration of cover art schemes. Each value contains a size, which indicates how big the
- * scaled covert art images should be.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.3 $ $Date: 2005/06/15 18:10:40 $
- */
-public enum CoverArtScheme {
-
- OFF(0),
- SMALL(70),
- MEDIUM(100),
- LARGE(150);
-
- private int size;
-
- CoverArtScheme(int size) {
- this.size = size;
- }
-
- /**
- * Returns the covert art size for this scheme.
- * @return the covert art size for this scheme.
- */
- public int getSize() {
- return size;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/InternetRadio.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/InternetRadio.java
deleted file mode 100644
index ae0c1f67..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/InternetRadio.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.Date;
-
-/**
- * Represents an internet radio station.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.2 $ $Date: 2005/12/25 13:48:46 $
- */
-public class InternetRadio {
-
- private Integer id;
- private String name;
- private String streamUrl;
- private String homepageUrl;
- private boolean isEnabled;
- private Date changed;
-
- /**
- * Creates a new internet radio station.
- *
- * @param id The system-generated ID.
- * @param name The user-defined name.
- * @param streamUrl The stream URL for the station.
- * @param homepageUrl The home page URL for the station.
- * @param isEnabled Whether the station is enabled.
- * @param changed When the corresponding database entry was last changed.
- */
- public InternetRadio(Integer id, String name, String streamUrl, String homepageUrl, boolean isEnabled, Date changed) {
- this.id = id;
- this.name = name;
- this.streamUrl = streamUrl;
- this.homepageUrl = homepageUrl;
- this.isEnabled = isEnabled;
- this.changed = changed;
- }
-
- /**
- * Creates a new internet radio station.
- *
- * @param name The user-defined name.
- * @param streamUrl The URL for the station.
- * @param homepageUrl The home page URL for the station.
- * @param isEnabled Whether the station is enabled.
- * @param changed When the corresponding database entry was last changed.
- */
- public InternetRadio(String name, String streamUrl, String homepageUrl, boolean isEnabled, Date changed) {
- this(null, name, streamUrl, homepageUrl, isEnabled, changed);
- }
-
- /**
- * Returns the system-generated ID.
- *
- * @return The system-generated ID.
- */
- public Integer getId() {
- return id;
- }
-
- /**
- * Returns the user-defined name.
- *
- * @return The user-defined name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the user-defined name.
- *
- * @param name The user-defined name.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the stream URL of the radio station.
- *
- * @return The stream URL of the radio station.
- */
- public String getStreamUrl() {
- return streamUrl;
- }
-
- /**
- * Sets the stream URL of the radio station.
- *
- * @param streamUrl The stream URL of the radio station.
- */
- public void setStreamUrl(String streamUrl) {
- this.streamUrl = streamUrl;
- }
-
- /**
- * Returns the homepage URL of the radio station.
- *
- * @return The homepage URL of the radio station.
- */
- public String getHomepageUrl() {
- return homepageUrl;
- }
-
- /**
- * Sets the home page URL of the radio station.
- *
- * @param homepageUrl The home page URL of the radio station.
- */
- public void setHomepageUrl(String homepageUrl) {
- this.homepageUrl = homepageUrl;
- }
-
- /**
- * Returns whether the radio station is enabled.
- *
- * @return Whether the radio station is enabled.
- */
- public boolean isEnabled() {
- return isEnabled;
- }
-
- /**
- * Sets whether the radio station is enabled.
- *
- * @param enabled Whether the radio station is enabled.
- */
- public void setEnabled(boolean enabled) {
- isEnabled = enabled;
- }
-
- /**
- * Returns when the corresponding database entry was last changed.
- *
- * @return When the corresponding database entry was last changed.
- */
- public Date getChanged() {
- return changed;
- }
-
- /**
- * Sets when the corresponding database entry was last changed.
- *
- * @param changed When the corresponding database entry was last changed.
- */
- public void setChanged(Date changed) {
- this.changed = changed;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFile.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFile.java
deleted file mode 100644
index 4f315028..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFile.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sourceforge.subsonic.util.FileUtil;
-import org.apache.commons.io.FilenameUtils;
-
-import java.io.File;
-import java.util.Date;
-
-/**
- * A media file (audio, video or directory) with an assortment of its meta data.
- *
- * @author Sindre Mehus
- * @version $Id$
- */
-public class MediaFile {
-
- private int id;
- private String path;
- private String folder;
- private MediaType mediaType;
- private String format;
- private String title;
- private String albumName;
- private String artist;
- private String albumArtist;
- private Integer discNumber;
- private Integer trackNumber;
- private Integer year;
- private String genre;
- private Integer bitRate;
- private boolean variableBitRate;
- private Integer durationSeconds;
- private Long fileSize;
- private Integer width;
- private Integer height;
- private String coverArtPath;
- private String parentPath;
- private int playCount;
- private Date lastPlayed;
- private String comment;
- private Date created;
- private Date changed;
- private Date lastScanned;
- private Date starredDate;
- private Date childrenLastUpdated;
- private boolean present;
-
- public MediaFile(int id, String path, String folder, MediaType mediaType, String format, String title,
- String albumName, String artist, String albumArtist, Integer discNumber, Integer trackNumber, Integer year, String genre, Integer bitRate,
- boolean variableBitRate, Integer durationSeconds, Long fileSize, Integer width, Integer height, String coverArtPath,
- String parentPath, int playCount, Date lastPlayed, String comment, Date created, Date changed, Date lastScanned,
- Date childrenLastUpdated, boolean present) {
- this.id = id;
- this.path = path;
- this.folder = folder;
- this.mediaType = mediaType;
- this.format = format;
- this.title = title;
- this.albumName = albumName;
- this.artist = artist;
- this.albumArtist = albumArtist;
- this.discNumber = discNumber;
- this.trackNumber = trackNumber;
- this.year = year;
- this.genre = genre;
- this.bitRate = bitRate;
- this.variableBitRate = variableBitRate;
- this.durationSeconds = durationSeconds;
- this.fileSize = fileSize;
- this.width = width;
- this.height = height;
- this.coverArtPath = coverArtPath;
- this.parentPath = parentPath;
- this.playCount = playCount;
- this.lastPlayed = lastPlayed;
- this.comment = comment;
- this.created = created;
- this.changed = changed;
- this.lastScanned = lastScanned;
- this.childrenLastUpdated = childrenLastUpdated;
- this.present = present;
- }
-
- public MediaFile() {
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getFolder() {
- return folder;
- }
-
- public void setFolder(String folder) {
- this.folder = folder;
- }
-
- public File getFile() {
- // TODO: Optimize
- return new File(path);
- }
-
- public boolean exists() {
- return FileUtil.exists(getFile());
- }
-
- public MediaType getMediaType() {
- return mediaType;
- }
-
- public void setMediaType(MediaType mediaType) {
- this.mediaType = mediaType;
- }
-
- public boolean isVideo() {
- return mediaType == MediaType.VIDEO;
- }
-
- public boolean isAudio() {
- return mediaType == MediaType.MUSIC || mediaType == MediaType.AUDIOBOOK || mediaType == MediaType.PODCAST;
- }
-
- public String getFormat() {
- return format;
- }
-
- public void setFormat(String format) {
- this.format = format;
- }
-
- public boolean isDirectory() {
- return !isFile();
- }
-
- public boolean isFile() {
- return mediaType != MediaType.DIRECTORY && mediaType != MediaType.ALBUM;
- }
-
- public boolean isAlbum() {
- return mediaType == MediaType.ALBUM;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getAlbumName() {
- return albumName;
- }
-
- public void setAlbumName(String album) {
- this.albumName = album;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public void setArtist(String artist) {
- this.artist = artist;
- }
-
- public String getAlbumArtist() {
- return albumArtist;
- }
-
- public void setAlbumArtist(String albumArtist) {
- this.albumArtist = albumArtist;
- }
-
- public String getName() {
- if (isFile()) {
- return title != null ? title : FilenameUtils.getBaseName(path);
- }
-
- return FilenameUtils.getName(path);
- }
-
- public Integer getDiscNumber() {
- return discNumber;
- }
-
- public void setDiscNumber(Integer discNumber) {
- this.discNumber = discNumber;
- }
-
- public Integer getTrackNumber() {
- return trackNumber;
- }
-
- public void setTrackNumber(Integer trackNumber) {
- this.trackNumber = trackNumber;
- }
-
- public Integer getYear() {
- return year;
- }
-
- public void setYear(Integer year) {
- this.year = year;
- }
-
- public String getGenre() {
- return genre;
- }
-
- public void setGenre(String genre) {
- this.genre = genre;
- }
-
- public Integer getBitRate() {
- return bitRate;
- }
-
- public void setBitRate(Integer bitRate) {
- this.bitRate = bitRate;
- }
-
- public boolean isVariableBitRate() {
- return variableBitRate;
- }
-
- public void setVariableBitRate(boolean variableBitRate) {
- this.variableBitRate = variableBitRate;
- }
-
- public Integer getDurationSeconds() {
- return durationSeconds;
- }
-
- public void setDurationSeconds(Integer durationSeconds) {
- this.durationSeconds = durationSeconds;
- }
-
- public String getDurationString() {
- if (durationSeconds == null) {
- return null;
- }
-
- StringBuilder result = new StringBuilder(8);
-
- int seconds = durationSeconds;
-
- int hours = seconds / 3600;
- seconds -= hours * 3600;
-
- int minutes = seconds / 60;
- seconds -= minutes * 60;
-
- if (hours > 0) {
- result.append(hours).append(':');
- if (minutes < 10) {
- result.append('0');
- }
- }
-
- result.append(minutes).append(':');
- if (seconds < 10) {
- result.append('0');
- }
- result.append(seconds);
-
- return result.toString();
- }
-
- public Long getFileSize() {
- return fileSize;
- }
-
- public void setFileSize(Long fileSize) {
- this.fileSize = fileSize;
- }
-
- public Integer getWidth() {
- return width;
- }
-
- public void setWidth(Integer width) {
- this.width = width;
- }
-
- public Integer getHeight() {
- return height;
- }
-
- public void setHeight(Integer height) {
- this.height = height;
- }
-
- public String getCoverArtPath() {
- return coverArtPath;
- }
-
- public void setCoverArtPath(String coverArtPath) {
- this.coverArtPath = coverArtPath;
- }
-
-
- public String getParentPath() {
- return parentPath;
- }
-
- public void setParentPath(String parentPath) {
- this.parentPath = parentPath;
- }
-
- public File getParentFile() {
- return getFile().getParentFile();
- }
-
- public int getPlayCount() {
- return playCount;
- }
-
- public void setPlayCount(int playCount) {
- this.playCount = playCount;
- }
-
- public Date getLastPlayed() {
- return lastPlayed;
- }
-
- public void setLastPlayed(Date lastPlayed) {
- this.lastPlayed = lastPlayed;
- }
-
- public String getComment() {
- return comment;
- }
-
- public void setComment(String comment) {
- this.comment = comment;
- }
-
- public Date getCreated() {
- return created;
- }
-
- public void setCreated(Date created) {
- this.created = created;
- }
-
- public Date getChanged() {
- return changed;
- }
-
- public void setChanged(Date changed) {
- this.changed = changed;
- }
-
- public Date getLastScanned() {
- return lastScanned;
- }
-
- public void setLastScanned(Date lastScanned) {
- this.lastScanned = lastScanned;
- }
-
- public Date getStarredDate() {
- return starredDate;
- }
-
- public void setStarredDate(Date starredDate) {
- this.starredDate = starredDate;
- }
-
- /**
- * Returns when the children was last updated in the database.
- */
- public Date getChildrenLastUpdated() {
- return childrenLastUpdated;
- }
-
- public void setChildrenLastUpdated(Date childrenLastUpdated) {
- this.childrenLastUpdated = childrenLastUpdated;
- }
-
- public boolean isPresent() {
- return present;
- }
-
- public void setPresent(boolean present) {
- this.present = present;
- }
-
- @Override
- public boolean equals(Object o) {
- return o instanceof MediaFile && ((MediaFile) o).path.equals(path);
- }
-
- @Override
- public int hashCode() {
- return path.hashCode();
- }
-
- public File getCoverArtFile() {
- // TODO: Optimize
- return coverArtPath == null ? null : new File(coverArtPath);
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- public static enum MediaType {
- MUSIC,
- PODCAST,
- AUDIOBOOK,
- VIDEO,
- DIRECTORY,
- ALBUM
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFileComparator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFileComparator.java
deleted file mode 100644
index 13b5bbbd..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaFileComparator.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.Comparator;
-
-import static net.sourceforge.subsonic.domain.MediaFile.MediaType.DIRECTORY;
-
-/**
- * Comparator for sorting media files.
- */
-public class MediaFileComparator implements Comparator<MediaFile> {
-
- private final boolean sortAlbumsByYear;
-
- public MediaFileComparator(boolean sortAlbumsByYear) {
- this.sortAlbumsByYear = sortAlbumsByYear;
- }
-
- public int compare(MediaFile a, MediaFile b) {
-
- // Directories before files.
- if (a.isFile() && b.isDirectory()) {
- return 1;
- }
- if (a.isDirectory() && b.isFile()) {
- return -1;
- }
-
- // Non-album directories before album directories.
- if (a.isAlbum() && b.getMediaType() == DIRECTORY) {
- return 1;
- }
- if (a.getMediaType() == DIRECTORY && b.isAlbum()) {
- return -1;
- }
-
- // Sort albums by year
- if (sortAlbumsByYear && a.isAlbum() && b.isAlbum()) {
- int i = nullSafeCompare(a.getYear(), b.getYear(), false);
- if (i != 0) {
- return i;
- }
- }
-
- if (a.isDirectory() && b.isDirectory()) {
- return a.getName().compareToIgnoreCase(b.getName());
- }
-
- // Compare by disc and track numbers, if present.
- Integer trackA = getSortableDiscAndTrackNumber(a);
- Integer trackB = getSortableDiscAndTrackNumber(b);
- int i = nullSafeCompare(trackA, trackB, false);
- if (i != 0) {
- return i;
- }
-
- return a.getName().compareToIgnoreCase(b.getName());
- }
-
- private <T extends Comparable<T>> int nullSafeCompare(T a, T b, boolean nullIsSmaller) {
- if (a == null && b == null) {
- return 0;
- }
- if (a == null) {
- return nullIsSmaller ? -1 : 1;
- }
- if (b == null) {
- return nullIsSmaller ? 1 : -1;
- }
- return a.compareTo(b);
- }
-
- private Integer getSortableDiscAndTrackNumber(MediaFile file) {
- if (file.getTrackNumber() == null) {
- return null;
- }
-
- int discNumber = file.getDiscNumber() == null ? 1 : file.getDiscNumber();
- return discNumber * 1000 + file.getTrackNumber();
- }
-}
-
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaLibraryStatistics.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaLibraryStatistics.java
deleted file mode 100644
index c8b0cdd9..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MediaLibraryStatistics.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Contains media libaray statistics, including the number of artists, albums and songs.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.1 $ $Date: 2005/11/17 18:29:03 $
- */
-public class MediaLibraryStatistics {
-
- private int artistCount;
- private int albumCount;
- private int songCount;
- private long totalLengthInBytes;
- private long totalDurationInSeconds;
-
- public MediaLibraryStatistics(int artistCount, int albumCount, int songCount, long totalLengthInBytes, long totalDurationInSeconds) {
- this.artistCount = artistCount;
- this.albumCount = albumCount;
- this.songCount = songCount;
- this.totalLengthInBytes = totalLengthInBytes;
- this.totalDurationInSeconds = totalDurationInSeconds;
- }
-
- public int getArtistCount() {
- return artistCount;
- }
-
- public int getAlbumCount() {
- return albumCount;
- }
-
- public int getSongCount() {
- return songCount;
- }
-
- public long getTotalLengthInBytes() {
- return totalLengthInBytes;
- }
-
- public long getTotalDurationInSeconds() {
- return totalDurationInSeconds;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicFolder.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicFolder.java
deleted file mode 100644
index 613b0a7f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicFolder.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Date;
-
-/**
- * Represents a top level directory in which music or other media is stored.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.1 $ $Date: 2005/11/27 14:32:05 $
- */
-public class MusicFolder implements Serializable {
-
- private Integer id;
- private File path;
- private String name;
- private boolean isEnabled;
- private Date changed;
-
- /**
- * Creates a new music folder.
- *
- * @param id The system-generated ID.
- * @param path The path of the music folder.
- * @param name The user-defined name.
- * @param enabled Whether the folder is enabled.
- * @param changed When the corresponding database entry was last changed.
- */
- public MusicFolder(Integer id, File path, String name, boolean enabled, Date changed) {
- this.id = id;
- this.path = path;
- this.name = name;
- isEnabled = enabled;
- this.changed = changed;
- }
-
- /**
- * Creates a new music folder.
- *
- * @param path The path of the music folder.
- * @param name The user-defined name.
- * @param enabled Whether the folder is enabled.
- * @param changed When the corresponding database entry was last changed.
- */
- public MusicFolder(File path, String name, boolean enabled, Date changed) {
- this(null, path, name, enabled, changed);
- }
-
- /**
- * Returns the system-generated ID.
- *
- * @return The system-generated ID.
- */
- public Integer getId() {
- return id;
- }
-
- /**
- * Returns the path of the music folder.
- *
- * @return The path of the music folder.
- */
- public File getPath() {
- return path;
- }
-
- /**
- * Sets the path of the music folder.
- *
- * @param path The path of the music folder.
- */
- public void setPath(File path) {
- this.path = path;
- }
-
- /**
- * Returns the user-defined name.
- *
- * @return The user-defined name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the user-defined name.
- *
- * @param name The user-defined name.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns whether the folder is enabled.
- *
- * @return Whether the folder is enabled.
- */
- public boolean isEnabled() {
- return isEnabled;
- }
-
- /**
- * Sets whether the folder is enabled.
- *
- * @param enabled Whether the folder is enabled.
- */
- public void setEnabled(boolean enabled) {
- isEnabled = enabled;
- }
-
- /**
- * Returns when the corresponding database entry was last changed.
- *
- * @return When the corresponding database entry was last changed.
- */
- public Date getChanged() {
- return changed;
- }
-
- /**
- * Sets when the corresponding database entry was last changed.
- *
- * @param changed When the corresponding database entry was last changed.
- */
- public void setChanged(Date changed) {
- this.changed = changed;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicIndex.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicIndex.java
deleted file mode 100644
index 5753fa4d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/MusicIndex.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.io.Serializable;
-
-/**
- * A music index is a mapping from an index string to a list of prefixes. A complete index consists of a list of
- * <code>MusicIndex</code> instances.<p/>
- * <p/>
- * For a normal alphabetical index, such a mapping would typically be <em>"A" -&gt; ["A"]</em>. The index can also be used
- * to group less frequently used letters, such as <em>"X-&Aring;" -&gt; ["X", "Y", "Z", "&AElig;", "&Oslash;", "&Aring;"]</em>, or to make multiple
- * indexes for frequently used letters, such as <em>"SA" -&gt; ["SA"]</em> and <em>"SO" -&gt; ["SO"]</em><p/>
- * <p/>
- * Clicking on an index in the user interface will typically bring up a list of all music files that are categorized
- * under that index.
- *
- * @author Sindre Mehus
- */
-public class MusicIndex implements Serializable {
-
- public static final MusicIndex OTHER = new MusicIndex("#");
-
- private final String index;
- private final List<String> prefixes = new ArrayList<String>();
-
- /**
- * Creates a new index with the given index string.
- *
- * @param index The index string, e.g., "A" or "The".
- */
- public MusicIndex(String index) {
- this.index = index;
- }
-
- /**
- * Adds a prefix to this index. Music files that starts with this prefix will be categorized under this index entry.
- *
- * @param prefix The prefix.
- */
- public void addPrefix(String prefix) {
- prefixes.add(prefix);
- }
-
- /**
- * Returns the index name.
- *
- * @return The index name.
- */
- public String getIndex() {
- return index;
- }
-
- /**
- * Returns the list of prefixes.
- *
- * @return The list of prefixes.
- */
- public List<String> getPrefixes() {
- return prefixes;
- }
-
- /**
- * Returns whether this object is equal to another one.
- *
- * @param o Object to compare to.
- * @return <code>true</code> if, and only if, the other object is a <code>MusicIndex</code> with the same
- * index name as this one.
- */
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof MusicIndex)) {
- return false;
- }
-
- final MusicIndex musicIndex = (MusicIndex) o;
-
- if (index != null ? !index.equals(musicIndex.index) : musicIndex.index != null) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns a hash code for this object.
- *
- * @return A hash code for this object.
- */
- @Override
- public int hashCode() {
- return (index != null ? index.hashCode() : 0);
- }
-
- /**
- * An artist in an index.
- */
- public static class Artist implements Comparable<Artist>, Serializable {
-
- private final String name;
- private final String sortableName;
- private final List<MediaFile> mediaFiles = new ArrayList<MediaFile>();
-
- public Artist(String name, String sortableName) {
- this.name = name;
- this.sortableName = sortableName;
- }
-
- public void addMediaFile(MediaFile mediaFile) {
- mediaFiles.add(mediaFile);
- }
-
- public String getName() {
- return name;
- }
-
- public String getSortableName() {
- return sortableName;
- }
-
- public List<MediaFile> getMediaFiles() {
- return mediaFiles;
- }
-
- public int compareTo(Artist artist) {
- return sortableName.compareToIgnoreCase(artist.sortableName);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- Artist artist = (Artist) o;
- return sortableName.equalsIgnoreCase(artist.sortableName);
- }
-
- @Override
- public int hashCode() {
- return sortableName.hashCode();
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/NATPMPRouter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/NATPMPRouter.java
deleted file mode 100644
index ef3821a1..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/NATPMPRouter.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import com.hoodcomputing.natpmp.MapRequestMessage;
-import com.hoodcomputing.natpmp.NatPmpDevice;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class NATPMPRouter implements Router {
-
- private final NatPmpDevice device;
-
- private NATPMPRouter(NatPmpDevice device) {
- this.device = device;
- }
-
- public static NATPMPRouter findRouter() {
- try {
- return new NATPMPRouter(new NatPmpDevice(false));
- } catch (Exception x) {
- return null;
- }
- }
-
- public void addPortMapping(int externalPort, int internalPort, int leaseDuration) throws Exception {
-
- // Use one week if lease duration is "forever".
- if (leaseDuration == 0) {
- leaseDuration = 7 * 24 * 3600;
- }
-
- MapRequestMessage map = new MapRequestMessage(true, internalPort, externalPort, leaseDuration, null);
- device.enqueueMessage(map);
- device.waitUntilQueueEmpty();
- }
-
- public void deletePortMapping(int externalPort, int internalPort) throws Exception {
- MapRequestMessage map = new MapRequestMessage(true, internalPort, externalPort, 0, null);
- device.enqueueMessage(map);
- device.waitUntilQueueEmpty();
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayQueue.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayQueue.java
deleted file mode 100644
index 97748f72..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayQueue.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sourceforge.subsonic.util.FileUtil;
-import org.apache.commons.lang.StringUtils;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * A playlist is a list of music files that are associated to a remote player.
- *
- * @author Sindre Mehus
- */
-public class PlayQueue {
-
- private List<MediaFile> files = new ArrayList<MediaFile>();
- private boolean repeatEnabled;
- private String name = "(unnamed)";
- private Status status = Status.PLAYING;
- private RandomSearchCriteria randomSearchCriteria;
-
- /**
- * The index of the current song, or -1 is the end of the playlist is reached.
- * Note that both the index and the playlist size can be zero.
- */
- private int index = 0;
-
- /**
- * Used for undo functionality.
- */
- private List<MediaFile> filesBackup = new ArrayList<MediaFile>();
- private int indexBackup = 0;
-
- /**
- * Returns the user-defined name of the playlist.
- *
- * @return The name of the playlist, or <code>null</code> if no name has been assigned.
- */
- public synchronized String getName() {
- return name;
- }
-
- /**
- * Sets the user-defined name of the playlist.
- *
- * @param name The name of the playlist.
- */
- public synchronized void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the current song in the playlist.
- *
- * @return The current song in the playlist, or <code>null</code> if no current song exists.
- */
- public synchronized MediaFile getCurrentFile() {
- if (index == -1 || index == 0 && size() == 0) {
- setStatus(Status.STOPPED);
- return null;
- } else {
- MediaFile file = files.get(index);
-
- // Remove file from playlist if it doesn't exist.
- if (!file.exists()) {
- files.remove(index);
- index = Math.max(0, Math.min(index, size() - 1));
- return getCurrentFile();
- }
-
- return file;
- }
- }
-
- /**
- * Returns all music files in the playlist.
- *
- * @return All music files in the playlist.
- */
- public synchronized List<MediaFile> getFiles() {
- return files;
- }
-
- /**
- * Returns the music file at the given index.
- *
- * @param index The index.
- * @return The music file at the given index.
- * @throws IndexOutOfBoundsException If the index is out of range.
- */
- public synchronized MediaFile getFile(int index) {
- return files.get(index);
- }
-
- /**
- * Skip to the next song in the playlist.
- */
- public synchronized void next() {
- index++;
-
- // Reached the end?
- if (index >= size()) {
- index = isRepeatEnabled() ? 0 : -1;
- }
- }
-
- /**
- * Returns the number of songs in the playlists.
- *
- * @return The number of songs in the playlists.
- */
- public synchronized int size() {
- return files.size();
- }
-
- /**
- * Returns whether the playlist is empty.
- *
- * @return Whether the playlist is empty.
- */
- public synchronized boolean isEmpty() {
- return files.isEmpty();
- }
-
- /**
- * Returns the index of the current song.
- *
- * @return The index of the current song, or -1 if the end of the playlist is reached.
- */
- public synchronized int getIndex() {
- return index;
- }
-
- /**
- * Sets the index of the current song.
- *
- * @param index The index of the current song.
- */
- public synchronized void setIndex(int index) {
- makeBackup();
- this.index = Math.max(0, Math.min(index, size() - 1));
- setStatus(Status.PLAYING);
- }
-
- /**
- * Adds one or more music file to the playlist.
- *
- * @param append Whether existing songs in the playlist should be kept.
- * @param mediaFiles The music files to add.
- * @throws IOException If an I/O error occurs.
- */
- public synchronized void addFiles(boolean append, Iterable<MediaFile> mediaFiles) throws IOException {
- makeBackup();
- if (!append) {
- index = 0;
- files.clear();
- }
- for (MediaFile mediaFile : mediaFiles) {
- files.add(mediaFile);
- }
- setStatus(Status.PLAYING);
- }
-
- /**
- * Convenience method, equivalent to {@link #addFiles(boolean, Iterable)}.
- */
- public synchronized void addFiles(boolean append, MediaFile... mediaFiles) throws IOException {
- addFiles(append, Arrays.asList(mediaFiles));
- }
-
- /**
- * Removes the music file at the given index.
- *
- * @param index The playlist index.
- */
- public synchronized void removeFileAt(int index) {
- makeBackup();
- index = Math.max(0, Math.min(index, size() - 1));
- if (this.index > index) {
- this.index--;
- }
- files.remove(index);
-
- if (index != -1) {
- this.index = Math.max(0, Math.min(this.index, size() - 1));
- }
- }
-
- /**
- * Clears the playlist.
- */
- public synchronized void clear() {
- makeBackup();
- files.clear();
- index = 0;
- }
-
- /**
- * Shuffles the playlist.
- */
- public synchronized void shuffle() {
- makeBackup();
- MediaFile currentFile = getCurrentFile();
- Collections.shuffle(files);
- if (currentFile != null) {
- index = files.indexOf(currentFile);
- }
- }
-
- /**
- * Sorts the playlist according to the given sort order.
- */
- public synchronized void sort(final SortOrder sortOrder) {
- makeBackup();
- MediaFile currentFile = getCurrentFile();
-
- Comparator<MediaFile> comparator = new Comparator<MediaFile>() {
- public int compare(MediaFile a, MediaFile b) {
- switch (sortOrder) {
- case TRACK:
- Integer trackA = a.getTrackNumber();
- Integer trackB = b.getTrackNumber();
- if (trackA == null) {
- trackA = 0;
- }
- if (trackB == null) {
- trackB = 0;
- }
- return trackA.compareTo(trackB);
-
- case ARTIST:
- String artistA = StringUtils.trimToEmpty(a.getArtist());
- String artistB = StringUtils.trimToEmpty(b.getArtist());
- return artistA.compareTo(artistB);
-
- case ALBUM:
- String albumA = StringUtils.trimToEmpty(a.getAlbumName());
- String albumB = StringUtils.trimToEmpty(b.getAlbumName());
- return albumA.compareTo(albumB);
- default:
- return 0;
- }
- }
- };
-
- Collections.sort(files, comparator);
- if (currentFile != null) {
- index = files.indexOf(currentFile);
- }
- }
-
- /**
- * Moves the song at the given index one step up.
- *
- * @param index The playlist index.
- */
- public synchronized void moveUp(int index) {
- makeBackup();
- if (index <= 0 || index >= size()) {
- return;
- }
- Collections.swap(files, index, index - 1);
-
- if (this.index == index) {
- this.index--;
- } else if (this.index == index - 1) {
- this.index++;
- }
- }
-
- /**
- * Moves the song at the given index one step down.
- *
- * @param index The playlist index.
- */
- public synchronized void moveDown(int index) {
- makeBackup();
- if (index < 0 || index >= size() - 1) {
- return;
- }
- Collections.swap(files, index, index + 1);
-
- if (this.index == index) {
- this.index++;
- } else if (this.index == index + 1) {
- this.index--;
- }
- }
-
- /**
- * Returns whether the playlist is repeating.
- *
- * @return Whether the playlist is repeating.
- */
- public synchronized boolean isRepeatEnabled() {
- return repeatEnabled;
- }
-
- /**
- * Sets whether the playlist is repeating.
- *
- * @param repeatEnabled Whether the playlist is repeating.
- */
- public synchronized void setRepeatEnabled(boolean repeatEnabled) {
- this.repeatEnabled = repeatEnabled;
- }
-
- /**
- * Revert the last operation.
- */
- public synchronized void undo() {
- List<MediaFile> filesTmp = new ArrayList<MediaFile>(files);
- int indexTmp = index;
-
- index = indexBackup;
- files = filesBackup;
-
- indexBackup = indexTmp;
- filesBackup = filesTmp;
- }
-
- /**
- * Returns the playlist status.
- *
- * @return The playlist status.
- */
- public synchronized Status getStatus() {
- return status;
- }
-
- /**
- * Sets the playlist status.
- *
- * @param status The playlist status.
- */
- public synchronized void setStatus(Status status) {
- this.status = status;
- if (index == -1) {
- index = Math.max(0, Math.min(index, size() - 1));
- }
- }
-
- /**
- * Returns the criteria used to generate this random playlist.
- *
- * @return The search criteria, or <code>null</code> if this is not a random playlist.
- */
- public synchronized RandomSearchCriteria getRandomSearchCriteria() {
- return randomSearchCriteria;
- }
-
- /**
- * Sets the criteria used to generate this random playlist.
- *
- * @param randomSearchCriteria The search criteria, or <code>null</code> if this is not a random playlist.
- */
- public synchronized void setRandomSearchCriteria(RandomSearchCriteria randomSearchCriteria) {
- this.randomSearchCriteria = randomSearchCriteria;
- }
-
- /**
- * Returns the total length in bytes.
- *
- * @return The total length in bytes.
- */
- public synchronized long length() {
- long length = 0;
- for (MediaFile mediaFile : files) {
- length += mediaFile.getFileSize();
- }
- return length;
- }
-
- private void makeBackup() {
- filesBackup = new ArrayList<MediaFile>(files);
- indexBackup = index;
- }
-
- /**
- * Playlist status.
- */
- public enum Status {
- PLAYING,
- STOPPED
- }
-
- /**
- * Playlist sort order.
- */
- public enum SortOrder {
- TRACK,
- ARTIST,
- ALBUM
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Player.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Player.java
deleted file mode 100644
index e1780936..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Player.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import org.apache.commons.lang.StringUtils;
-
-import java.util.Date;
-
-/**
- * Represens a remote player. A player has a unique ID, a user-defined name, a logged-on user,
- * miscellaneous identifiers, and an associated playlist.
- *
- * @author Sindre Mehus
- */
-public class Player {
-
- private String id;
- private String name;
- private PlayerTechnology technology = PlayerTechnology.WEB;
- private String clientId;
- private String type;
- private String username;
- private String ipAddress;
- private boolean isDynamicIp = true;
- private boolean isAutoControlEnabled = true;
- private Date lastSeen;
- private CoverArtScheme coverArtScheme = CoverArtScheme.MEDIUM;
- private TranscodeScheme transcodeScheme = TranscodeScheme.OFF;
- private PlayQueue playQueue;
-
- /**
- * Returns the player ID.
- *
- * @return The player ID.
- */
- public String getId() {
- return id;
- }
-
- /**
- * Sets the player ID.
- *
- * @param id The player ID.
- */
- public void setId(String id) {
- this.id = id;
- }
-
- /**
- * Returns the user-defined player name.
- *
- * @return The user-defined player name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the user-defined player name.
- *
- * @param name The user-defined player name.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the player "technology", e.g., web, external or jukebox.
- *
- * @return The player technology.
- */
- public PlayerTechnology getTechnology() {
- return technology;
- }
-
- /**
- * Returns the third-party client ID (used if this player is managed over the
- * Subsonic REST API).
- *
- * @return The client ID.
- */
- public String getClientId() {
- return clientId;
- }
-
- /**
- * Sets the third-party client ID (used if this player is managed over the
- * Subsonic REST API).
- *
- * @param clientId The client ID.
- */
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
- /**
- * Sets the player "technology", e.g., web, external or jukebox.
- *
- * @param technology The player technology.
- */
- public void setTechnology(PlayerTechnology technology) {
- this.technology = technology;
- }
-
- public boolean isJukebox() {
- return technology == PlayerTechnology.JUKEBOX;
- }
-
- public boolean isExternal() {
- return technology == PlayerTechnology.EXTERNAL;
- }
-
- public boolean isExternalWithPlaylist() {
- return technology == PlayerTechnology.EXTERNAL_WITH_PLAYLIST;
- }
-
- public boolean isWeb() {
- return technology == PlayerTechnology.WEB;
- }
-
- /**
- * Returns the player type, e.g., WinAmp, iTunes.
- *
- * @return The player type.
- */
- public String getType() {
- return type;
- }
-
- /**
- * Sets the player type, e.g., WinAmp, iTunes.
- *
- * @param type The player type.
- */
- public void setType(String type) {
- this.type = type;
- }
-
- /**
- * Returns the logged-in user.
- *
- * @return The logged-in user.
- */
- public String getUsername() {
- return username;
- }
-
- /**
- * Sets the logged-in username.
- *
- * @param username The logged-in username.
- */
- public void setUsername(String username) {
- this.username = username;
- }
-
- /**
- * Returns whether the player is automatically started.
- *
- * @return Whether the player is automatically started.
- */
- public boolean isAutoControlEnabled() {
- return isAutoControlEnabled;
- }
-
- /**
- * Sets whether the player is automatically started.
- *
- * @param isAutoControlEnabled Whether the player is automatically started.
- */
- public void setAutoControlEnabled(boolean isAutoControlEnabled) {
- this.isAutoControlEnabled = isAutoControlEnabled;
- }
-
- /**
- * Returns the time when the player was last seen.
- *
- * @return The time when the player was last seen.
- */
- public Date getLastSeen() {
- return lastSeen;
- }
-
- /**
- * Sets the time when the player was last seen.
- *
- * @param lastSeen The time when the player was last seen.
- */
- public void setLastSeen(Date lastSeen) {
- this.lastSeen = lastSeen;
- }
-
- /**
- * Returns the cover art scheme.
- *
- * @return The cover art scheme.
- */
- public CoverArtScheme getCoverArtScheme() {
- return coverArtScheme;
- }
-
- /**
- * Sets the cover art scheme.
- *
- * @param coverArtScheme The cover art scheme.
- */
- public void setCoverArtScheme(CoverArtScheme coverArtScheme) {
- this.coverArtScheme = coverArtScheme;
- }
-
- /**
- * Returns the transcode scheme.
- *
- * @return The transcode scheme.
- */
- public TranscodeScheme getTranscodeScheme() {
- return transcodeScheme;
- }
-
- /**
- * Sets the transcode scheme.
- *
- * @param transcodeScheme The transcode scheme.
- */
- public void setTranscodeScheme(TranscodeScheme transcodeScheme) {
- this.transcodeScheme = transcodeScheme;
- }
-
- /**
- * Returns the IP address of the player.
- *
- * @return The IP address of the player.
- */
- public String getIpAddress() {
- return ipAddress;
- }
-
- /**
- * Sets the IP address of the player.
- *
- * @param ipAddress The IP address of the player.
- */
- public void setIpAddress(String ipAddress) {
- this.ipAddress = ipAddress;
- }
-
- /**
- * Returns whether this player has a dynamic IP address.
- *
- * @return Whether this player has a dynamic IP address.
- */
- public boolean isDynamicIp() {
- return isDynamicIp;
- }
-
- /**
- * Sets whether this player has a dynamic IP address.
- *
- * @param dynamicIp Whether this player has a dynamic IP address.
- */
- public void setDynamicIp(boolean dynamicIp) {
- isDynamicIp = dynamicIp;
- }
-
- /**
- * Returns the player's playlist.
- *
- * @return The player's playlist
- */
- public PlayQueue getPlayQueue() {
- return playQueue;
- }
-
- /**
- * Sets the player's playlist.
- *
- * @param playQueue The player's playlist.
- */
- public void setPlayQueue(PlayQueue playQueue) {
- this.playQueue = playQueue;
- }
-
- /**
- * Returns a long description of the player, e.g., <code>Player 3 [admin]</code>
- *
- * @return A long description of the player.
- */
- public String getDescription() {
- StringBuilder builder = new StringBuilder();
- if (name != null) {
- builder.append(name);
- } else {
- builder.append("Player ").append(id);
- }
-
- builder.append(" [").append(username).append(']');
- return builder.toString();
- }
-
- /**
- * Returns a short description of the player, e.g., <code>Player 3</code>
- *
- * @return A short description of the player.
- */
- public String getShortDescription() {
- if (StringUtils.isNotBlank(name)) {
- return name;
- }
- return "Player " + id;
- }
-
- /**
- * Returns a string representation of the player.
- *
- * @return A string representation of the player.
- * @see #getDescription()
- */
- @Override
- public String toString() {
- return getDescription();
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayerTechnology.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayerTechnology.java
deleted file mode 100644
index 5ba3ff71..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PlayerTechnology.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Enumeration of player technologies.
- *
- * @author Sindre Mehus
- */
-public enum PlayerTechnology {
-
- /**
- * Plays music directly in the web browser using the integrated Flash player.
- */
- WEB,
-
- /**
- * Plays music in an external player, such as WinAmp or Windows Media Player.
- */
- EXTERNAL,
-
- /**
- * Same as above, but the playlist is managed by the player, rather than the Subsonic server.
- * In this mode, skipping within songs is possible.
- */
- EXTERNAL_WITH_PLAYLIST,
-
- /**
- * Plays music directly on the audio device of the Subsonic server.
- */
- JUKEBOX
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Playlist.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Playlist.java
deleted file mode 100644
index 80555ec7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Playlist.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sourceforge.subsonic.util.StringUtil;
-
-import java.util.Date;
-
-/**
- * @author Sindre Mehus
- */
-public class Playlist {
-
- private int id;
- private String username;
- private boolean isPublic;
- private String name;
- private String comment;
- private int fileCount;
- private int durationSeconds;
- private Date created;
- private Date changed;
- private String importedFrom;
-
- public Playlist() {
- }
-
- public Playlist(int id, String username, boolean isPublic, String name, String comment, int fileCount,
- int durationSeconds, Date created, Date changed, String importedFrom) {
- this.id = id;
- this.username = username;
- this.isPublic = isPublic;
- this.name = name;
- this.comment = comment;
- this.fileCount = fileCount;
- this.durationSeconds = durationSeconds;
- this.created = created;
- this.changed = changed;
- this.importedFrom = importedFrom;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public boolean isPublic() {
- return isPublic;
- }
-
- public void setPublic(boolean isPublic) {
- this.isPublic = isPublic;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getComment() {
- return comment;
- }
-
- public void setComment(String comment) {
- this.comment = comment;
- }
-
- public int getFileCount() {
- return fileCount;
- }
-
- public void setFileCount(int fileCount) {
- this.fileCount = fileCount;
- }
-
- public int getDurationSeconds() {
- return durationSeconds;
- }
-
- public void setDurationSeconds(int durationSeconds) {
- this.durationSeconds = durationSeconds;
- }
-
- public String getDurationAsString() {
- return StringUtil.formatDuration(durationSeconds);
- }
-
- public Date getCreated() {
- return created;
- }
-
- public void setCreated(Date created) {
- this.created = created;
- }
-
- public Date getChanged() {
- return changed;
- }
-
- public void setChanged(Date changed) {
- this.changed = changed;
- }
-
- public String getImportedFrom() {
- return importedFrom;
- }
-
- public void setImportedFrom(String importedFrom) {
- this.importedFrom = importedFrom;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastChannel.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastChannel.java
deleted file mode 100644
index 1127a5cb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastChannel.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * A Podcast channel. Each channel contain several episodes.
- *
- * @author Sindre Mehus
- * @see PodcastEpisode
- */
-public class PodcastChannel {
-
- private Integer id;
- private String url;
- private String title;
- private String description;
- private PodcastStatus status;
- private String errorMessage;
-
- public PodcastChannel(Integer id, String url, String title, String description,
- PodcastStatus status, String errorMessage) {
- this.id = id;
- this.url = url;
- this.title = StringUtil.removeMarkup(title);
- this.description = StringUtil.removeMarkup(description);
- this.status = status;
- this.errorMessage = errorMessage;
- }
-
- public PodcastChannel(String url) {
- this.url = url;
- status = PodcastStatus.NEW;
- }
-
- public Integer getId() {
- return id;
- }
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public PodcastStatus getStatus() {
- return status;
- }
-
- public void setStatus(PodcastStatus status) {
- this.status = status;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastEpisode.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastEpisode.java
deleted file mode 100644
index b5a835cb..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastEpisode.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.Date;
-
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * A Podcast episode belonging to a channel.
- *
- * @author Sindre Mehus
- * @see PodcastChannel
- */
-public class PodcastEpisode {
-
- private Integer id;
- private Integer mediaFileId;
- private Integer channelId;
- private String url;
- private String path;
- private String title;
- private String description;
- private Date publishDate;
- private String duration;
- private Long bytesTotal;
- private Long bytesDownloaded;
- private PodcastStatus status;
- private String errorMessage;
-
- public PodcastEpisode(Integer id, Integer channelId, String url, String path, String title,
- String description, Date publishDate, String duration, Long length, Long bytesDownloaded,
- PodcastStatus status, String errorMessage) {
- this.id = id;
- this.channelId = channelId;
- this.url = url;
- this.path = path;
- this.title = StringUtil.removeMarkup(title);
- this.description = StringUtil.removeMarkup(description);
- this.publishDate = publishDate;
- this.duration = duration;
- this.bytesTotal = length;
- this.bytesDownloaded = bytesDownloaded;
- this.status = status;
- this.errorMessage = errorMessage;
- }
-
- public Integer getId() {
- return id;
- }
-
- public Integer getChannelId() {
- return channelId;
- }
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public Date getPublishDate() {
- return publishDate;
- }
-
- public void setPublishDate(Date publishDate) {
- this.publishDate = publishDate;
- }
-
- public String getDuration() {
- return duration;
- }
-
- public void setDuration(String duration) {
- this.duration = duration;
- }
-
- public Long getBytesTotal() {
- return bytesTotal;
- }
-
- public void setBytesTotal(Long bytesTotal) {
- this.bytesTotal = bytesTotal;
- }
-
- public Long getBytesDownloaded() {
- return bytesDownloaded;
- }
-
- public Double getCompletionRate() {
- if (bytesTotal == null || bytesTotal == 0) {
- return null;
- }
- if (bytesDownloaded == null) {
- return 0.0;
- }
-
- double d = bytesDownloaded;
- double t = bytesTotal;
- return d / t;
- }
-
- public void setBytesDownloaded(Long bytesDownloaded) {
- this.bytesDownloaded = bytesDownloaded;
- }
-
- public PodcastStatus getStatus() {
- return status;
- }
-
- public void setStatus(PodcastStatus status) {
- this.status = status;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- public Integer getMediaFileId() {
- return mediaFileId;
- }
-
- public void setMediaFileId(Integer mediaFileId) {
- this.mediaFileId = mediaFileId;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastStatus.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastStatus.java
deleted file mode 100644
index 57cad155..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/PodcastStatus.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Enumeration of statuses for {@link PodcastChannel} and
- * {@link PodcastEpisode}.
- *
- * @author Sindre Mehus
- */
-public enum PodcastStatus {
- NEW, DOWNLOADING, COMPLETED, ERROR, DELETED, SKIPPED
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/RandomSearchCriteria.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/RandomSearchCriteria.java
deleted file mode 100644
index d52cec39..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/RandomSearchCriteria.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Defines criteria used when generating random playlists.
- *
- * @author Sindre Mehus
- * @see net.sourceforge.subsonic.service.SearchService#getRandomSongs
- */
-public class RandomSearchCriteria {
- private final int count;
- private final String genre;
- private final Integer fromYear;
- private final Integer toYear;
- private final Integer musicFolderId;
-
- /**
- * Creates a new instance.
- *
- * @param count Maximum number of songs to return.
- * @param genre Only return songs of the given genre. May be <code>null</code>.
- * @param fromYear Only return songs released after (or in) this year. May be <code>null</code>.
- * @param toYear Only return songs released before (or in) this year. May be <code>null</code>.
- * @param musicFolderId Only return songs from this music folder. May be <code>null</code>.
- */
- public RandomSearchCriteria(int count, String genre, Integer fromYear, Integer toYear, Integer musicFolderId) {
- this.count = count;
- this.genre = genre;
- this.fromYear = fromYear;
- this.toYear = toYear;
- this.musicFolderId = musicFolderId;
- }
-
- public int getCount() {
- return count;
- }
-
- public String getGenre() {
- return genre;
- }
-
- public Integer getFromYear() {
- return fromYear;
- }
-
- public Integer getToYear() {
- return toYear;
- }
-
- public Integer getMusicFolderId() {
- return musicFolderId;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Router.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Router.java
deleted file mode 100644
index ede9d19e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Router.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public interface Router {
-
- /**
- * Adds a NAT entry on the UPNP device.
- *
- * @param externalPort The external port to open on the UPNP device an map on the internal client.
- * @param internalPort The internal client port where data should be redirected.
- * @param leaseDuration Seconds the lease duration in seconds, or 0 for an infinite time.
- */
- void addPortMapping(int externalPort, int internalPort, int leaseDuration) throws Exception;
-
- /**
- * Deletes a NAT entry on the UPNP device.
- *
- * @param externalPort The external port of the NAT entry to delete.
- * @param internalPort The internal port of the NAT entry to delete.
- */
- void deletePortMapping(int externalPort, int internalPort) throws Exception;
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SBBIRouter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SBBIRouter.java
deleted file mode 100644
index a639e665..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SBBIRouter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sbbi.upnp.impls.InternetGatewayDevice;
-
-import java.io.IOException;
-import java.net.InetAddress;
-
-/**
- * @author Sindre Mehus
- */
-public class SBBIRouter implements Router {
-
- // The timeout in milliseconds for finding a router device.
- private static final int DISCOVERY_TIMEOUT = 3000;
-
- private final InternetGatewayDevice device;
-
- private SBBIRouter(InternetGatewayDevice device) {
- this.device = device;
- }
-
- public static SBBIRouter findRouter() throws Exception {
- InternetGatewayDevice[] devices;
- try {
- devices = InternetGatewayDevice.getDevices(DISCOVERY_TIMEOUT);
- } catch (IOException e) {
- throw new Exception("Could not find router", e);
- }
-
- if (devices == null || devices.length == 0) {
- return null;
- }
-
- return new SBBIRouter(devices[0]);
- }
-
- public void addPortMapping(int externalPort, int internalPort, int leaseDuration) throws Exception {
- String localIp = InetAddress.getLocalHost().getHostAddress();
- device.addPortMapping("Subsonic", null, internalPort, externalPort, localIp, leaseDuration, "TCP");
- }
-
- public void deletePortMapping(int externalPort, int internal) throws Exception {
- device.deletePortMapping(null, externalPort, "TCP");
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchCriteria.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchCriteria.java
deleted file mode 100644
index f06a6512..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchCriteria.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sourceforge.subsonic.service.MediaScannerService;
-import net.sourceforge.subsonic.service.SearchService;
-
-/**
- * Defines criteria used when searching.
- *
- * @author Sindre Mehus
- * @see SearchService#search
- */
-public class SearchCriteria {
-
- private String query;
- private int offset;
- private int count;
-
- public void setQuery(String query) {
- this.query = query;
- }
-
- public String getQuery() {
- return query;
- }
-
- public int getOffset() {
- return offset;
- }
-
- public void setOffset(int offset) {
- this.offset = offset;
- }
-
- public int getCount() {
- return count;
- }
-
- public void setCount(int count) {
- this.count = count;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchResult.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchResult.java
deleted file mode 100644
index bf4b370a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/SearchResult.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.sourceforge.subsonic.service.MediaScannerService;
-import net.sourceforge.subsonic.service.SearchService;
-
-/**
- * The outcome of a search.
- *
- * @author Sindre Mehus
- * @see SearchService#search
- */
-public class SearchResult {
-
- private final List<MediaFile> mediaFiles = new ArrayList<MediaFile>();
- private final List<Artist> artists = new ArrayList<Artist>();
- private final List<Album> albums = new ArrayList<Album>();
-
- private int offset;
- private int totalHits;
-
- public List<MediaFile> getMediaFiles() {
- return mediaFiles;
- }
-
- public List<Artist> getArtists() {
- return artists;
- }
-
- public List<Album> getAlbums() {
- return albums;
- }
-
- public int getOffset() {
- return offset;
- }
-
- public void setOffset(int offset) {
- this.offset = offset;
- }
-
- public int getTotalHits() {
- return totalHits;
- }
-
- public void setTotalHits(int totalHits) {
- this.totalHits = totalHits;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Share.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Share.java
deleted file mode 100644
index 7494769b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Share.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package net.sourceforge.subsonic.domain;
-
-import java.util.Date;
-
-/**
- * A collection of media files that is shared with someone, and accessible via a direct URL.
- *
- * @author Sindre Mehus
- * @version $Id$
- */
-public class Share {
-
- private int id;
- private String name;
- private String description;
- private String username;
- private Date created;
- private Date expires;
- private Date lastVisited;
- private int visitCount;
-
- public Share() {
- }
-
- public Share(int id, String name, String description, String username, Date created,
- Date expires, Date lastVisited, int visitCount) {
- this.id = id;
- this.name = name;
- this.description = description;
- this.username = username;
- this.created = created;
- this.expires = expires;
- this.lastVisited = lastVisited;
- this.visitCount = visitCount;
- }
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public Date getCreated() {
- return created;
- }
-
- public void setCreated(Date created) {
- this.created = created;
- }
-
- public Date getExpires() {
- return expires;
- }
-
- public void setExpires(Date expires) {
- this.expires = expires;
- }
-
- public Date getLastVisited() {
- return lastVisited;
- }
-
- public void setLastVisited(Date lastVisited) {
- this.lastVisited = lastVisited;
- }
-
- public int getVisitCount() {
- return visitCount;
- }
-
- public void setVisitCount(int visitCount) {
- this.visitCount = visitCount;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Theme.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Theme.java
deleted file mode 100644
index f8bd66bd..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Theme.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Contains the ID and name for a theme.
- *
- * @author Sindre Mehus
- */
-public class Theme {
- private String id;
- private String name;
-
- public Theme(String id, String name) {
- this.id = id;
- this.name = name;
- }
-
- public String getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TranscodeScheme.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TranscodeScheme.java
deleted file mode 100644
index f45b452a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TranscodeScheme.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Enumeration of transcoding schemes. Transcoding is the process of
- * converting an audio stream to a lower bit rate.
- *
- * @author Sindre Mehus
- */
-public enum TranscodeScheme {
-
- OFF(0),
- MAX_32(32),
- MAX_40(40),
- MAX_48(48),
- MAX_56(56),
- MAX_64(64),
- MAX_80(80),
- MAX_96(96),
- MAX_112(112),
- MAX_128(128),
- MAX_160(160),
- MAX_192(192),
- MAX_224(224),
- MAX_256(256),
- MAX_320(320);
-
- private int maxBitRate;
-
- TranscodeScheme(int maxBitRate) {
- this.maxBitRate = maxBitRate;
- }
-
- /**
- * Returns the maximum bit rate for this transcoding scheme.
- *
- * @return The maximum bit rate for this transcoding scheme.
- */
- public int getMaxBitRate() {
- return maxBitRate;
- }
-
- /**
- * Returns the strictest transcode scheme (i.e., the scheme with the lowest max bitrate).
- *
- * @param other The other transcode scheme. May be <code>null</code>, in which case 'this' is returned.
- * @return The strictest scheme.
- */
- public TranscodeScheme strictest(TranscodeScheme other) {
- if (other == null || other == TranscodeScheme.OFF) {
- return this;
- }
-
- if (this == TranscodeScheme.OFF) {
- return other;
- }
-
- return maxBitRate < other.maxBitRate ? this : other;
- }
-
- /**
- * Returns a human-readable string representation of this object.
- *
- * @return A human-readable string representation of this object.
- */
- public String toString() {
- if (this == OFF) {
- return "No limit";
- }
- return "" + getMaxBitRate() + " Kbps";
- }
-
- /**
- * Returns the enum constant which corresponds to the given max bit rate.
- *
- * @param maxBitRate The max bit rate.
- * @return The corresponding enum, or <code>null</code> if not found.
- */
- public static TranscodeScheme valueOf(int maxBitRate) {
- for (TranscodeScheme scheme : values()) {
- if (scheme.getMaxBitRate() == maxBitRate) {
- return scheme;
- }
- }
- return null;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Transcoding.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Transcoding.java
deleted file mode 100644
index 57c8316f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Transcoding.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Contains the configuration for a transcoding, i.e., a specification of how a given media format
- * should be converted to another.
- * <br/>
- * A transcoding may contain up to three steps. Typically you need to convert in several steps, for
- * instance from OGG to WAV to MP3.
- *
- * @author Sindre Mehus
- */
-public class Transcoding {
-
- private Integer id;
- private String name;
- private String sourceFormats;
- private String targetFormat;
- private String step1;
- private String step2;
- private String step3;
- private boolean defaultActive;
-
- /**
- * Creates a new transcoding specification.
- *
- * @param id The system-generated ID.
- * @param name The user-defined name.
- * @param sourceFormats The source formats, e.g., "ogg wav aac".
- * @param targetFormat The target format, e.g., "mp3".
- * @param step1 The command to execute in step 1.
- * @param step2 The command to execute in step 2.
- * @param step3 The command to execute in step 3.
- * @param defaultActive Whether the transcoding should be automatically activated for all players.
- */
- public Transcoding(Integer id, String name, String sourceFormats, String targetFormat, String step1,
- String step2, String step3, boolean defaultActive) {
- this.id = id;
- this.name = name;
- this.sourceFormats = sourceFormats;
- this.targetFormat = targetFormat;
- this.step1 = step1;
- this.step2 = step2;
- this.step3 = step3;
- this.defaultActive = defaultActive;
- }
-
- /**
- * Returns the system-generated ID.
- *
- * @return The system-generated ID.
- */
- public Integer getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- /**
- * Returns the user-defined name.
- *
- * @return The user-defined name.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the user-defined name.
- *
- * @param name The user-defined name.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the source format, e.g., "ogg wav aac".
- *
- * @return The source format, e.g., "ogg wav aac".
- */
- public String getSourceFormats() {
- return sourceFormats;
- }
-
- public String[] getSourceFormatsAsArray() {
- return StringUtil.split(sourceFormats);
- }
-
- /**
- * Sets the source formats, e.g., "ogg wav aac".
- *
- * @param sourceFormats The source formats, e.g., "ogg wav aac".
- */
- public void setSourceFormats(String sourceFormats) {
- this.sourceFormats = sourceFormats;
- }
-
- /**
- * Returns the target format, e.g., mp3.
- *
- * @return The target format, e.g., mp3.
- */
- public String getTargetFormat() {
- return targetFormat;
- }
-
- /**
- * Sets the target format, e.g., mp3.
- *
- * @param targetFormat The target format, e.g., mp3.
- */
- public void setTargetFormat(String targetFormat) {
- this.targetFormat = targetFormat;
- }
-
- /**
- * Returns the command to execute in step 1.
- *
- * @return The command to execute in step 1.
- */
- public String getStep1() {
- return step1;
- }
-
- /**
- * Sets the command to execute in step 1.
- *
- * @param step1 The command to execute in step 1.
- */
- public void setStep1(String step1) {
- this.step1 = step1;
- }
-
- /**
- * Returns the command to execute in step 2.
- *
- * @return The command to execute in step 2.
- */
- public String getStep2() {
- return step2;
- }
-
- /**
- * Sets the command to execute in step 2.
- *
- * @param step2 The command to execute in step 2.
- */
- public void setStep2(String step2) {
- this.step2 = step2;
- }
-
- /**
- * Returns the command to execute in step 3.
- *
- * @return The command to execute in step 3.
- */
- public String getStep3() {
- return step3;
- }
-
- /**
- * Sets the command to execute in step 3.
- *
- * @param step3 The command to execute in step 3.
- */
- public void setStep3(String step3) {
- this.step3 = step3;
- }
-
- /**
- * Returns whether the transcoding should be automatically activated for all players
- */
- public boolean isDefaultActive() {
- return defaultActive;
- }
-
- /**
- * Sets whether the transcoding should be automatically activated for all players
- */
- public void setDefaultActive(boolean defaultActive) {
- this.defaultActive = defaultActive;
- }
-
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- Transcoding that = (Transcoding) o;
- return !(id != null ? !id.equals(that.id) : that.id != null);
- }
-
- public int hashCode() {
- return (id != null ? id.hashCode() : 0);
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TransferStatus.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TransferStatus.java
deleted file mode 100644
index 06930ae3..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/TransferStatus.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.io.File;
-
-import net.sourceforge.subsonic.util.BoundedList;
-
-/**
- * Status for a single transfer (stream, download or upload).
- *
- * @author Sindre Mehus
- */
-public class TransferStatus {
-
- private static final int HISTORY_LENGTH = 200;
- private static final long SAMPLE_INTERVAL_MILLIS = 5000;
-
- private Player player;
- private File file;
- private long bytesTransfered;
- private long bytesSkipped;
- private long bytesTotal;
- private final SampleHistory history = new SampleHistory();
- private boolean terminated;
- private boolean active = true;
-
- /**
- * Return the number of bytes transferred.
- *
- * @return The number of bytes transferred.
- */
- public synchronized long getBytesTransfered() {
- return bytesTransfered;
- }
-
- /**
- * Adds the given byte count to the total number of bytes transferred.
- *
- * @param byteCount The byte count.
- */
- public synchronized void addBytesTransfered(long byteCount) {
- setBytesTransfered(bytesTransfered + byteCount);
- }
-
- /**
- * Sets the number of bytes transferred.
- *
- * @param bytesTransfered The number of bytes transferred.
- */
- public synchronized void setBytesTransfered(long bytesTransfered) {
- this.bytesTransfered = bytesTransfered;
- createSample(bytesTransfered, false);
- }
-
- private void createSample(long bytesTransfered, boolean force) {
- long now = System.currentTimeMillis();
-
- if (history.isEmpty()) {
- history.add(new Sample(bytesTransfered, now));
- } else {
- Sample lastSample = history.getLast();
- if (force || now - lastSample.getTimestamp() > TransferStatus.SAMPLE_INTERVAL_MILLIS) {
- history.add(new Sample(bytesTransfered, now));
- }
- }
- }
-
- /**
- * Returns the number of milliseconds since the transfer status was last updated.
- *
- * @return Number of milliseconds, or <code>0</code> if never updated.
- */
- public synchronized long getMillisSinceLastUpdate() {
- if (history.isEmpty()) {
- return 0L;
- }
- return System.currentTimeMillis() - history.getLast().timestamp;
- }
-
- /**
- * Returns the total number of bytes, or 0 if unknown.
- *
- * @return The total number of bytes, or 0 if unknown.
- */
- public long getBytesTotal() {
- return bytesTotal;
- }
-
- /**
- * Sets the total number of bytes, or 0 if unknown.
- *
- * @param bytesTotal The total number of bytes, or 0 if unknown.
- */
- public void setBytesTotal(long bytesTotal) {
- this.bytesTotal = bytesTotal;
- }
-
- /**
- * Returns the number of bytes that has been skipped (for instance when
- * resuming downloads).
- *
- * @return The number of skipped bytes.
- */
- public synchronized long getBytesSkipped() {
- return bytesSkipped;
- }
-
- /**
- * Sets the number of bytes that has been skipped (for instance when
- * resuming downloads).
- *
- * @param bytesSkipped The number of skipped bytes.
- */
- public synchronized void setBytesSkipped(long bytesSkipped) {
- this.bytesSkipped = bytesSkipped;
- }
-
-
- /**
- * Adds the given byte count to the total number of bytes skipped.
- *
- * @param byteCount The byte count.
- */
- public synchronized void addBytesSkipped(long byteCount) {
- bytesSkipped += byteCount;
- }
-
- /**
- * Returns the file that is currently being transferred.
- *
- * @return The file that is currently being transferred.
- */
- public synchronized File getFile() {
- return file;
- }
-
- /**
- * Sets the file that is currently being transferred.
- *
- * @param file The file that is currently being transferred.
- */
- public synchronized void setFile(File file) {
- this.file = file;
- }
-
- /**
- * Returns the remote player for the stream.
- *
- * @return The remote player for the stream.
- */
- public synchronized Player getPlayer() {
- return player;
- }
-
- /**
- * Sets the remote player for the stream.
- *
- * @param player The remote player for the stream.
- */
- public synchronized void setPlayer(Player player) {
- this.player = player;
- }
-
- /**
- * Returns a history of samples for the stream
- *
- * @return A (copy of) the history list of samples.
- */
- public synchronized SampleHistory getHistory() {
- return new SampleHistory(history);
- }
-
- /**
- * Returns the history length in milliseconds.
- *
- * @return The history length in milliseconds.
- */
- public long getHistoryLengthMillis() {
- return TransferStatus.SAMPLE_INTERVAL_MILLIS * (TransferStatus.HISTORY_LENGTH - 1);
- }
-
- /**
- * Indicate that the stream should be terminated.
- */
- public void terminate() {
- terminated = true;
- }
-
- /**
- * Returns whether this stream has been terminated.
- * Not that the <em>terminated status</em> is cleared by this method.
- *
- * @return Whether this stream has been terminated.
- */
- public boolean terminated() {
- boolean result = terminated;
- terminated = false;
- return result;
- }
-
- /**
- * Returns whether this transfer is active, i.e., if the connection is still established.
- *
- * @return Whether this transfer is active.
- */
- public boolean isActive() {
- return active;
- }
-
- /**
- * Sets whether this transfer is active, i.e., if the connection is still established.
- *
- * @param active Whether this transfer is active.
- */
- public void setActive(boolean active) {
- this.active = active;
-
- if (active) {
- setBytesSkipped(0L);
- setBytesTotal(0L);
- setBytesTransfered(0L);
- } else {
- createSample(getBytesTransfered(), true);
- }
- }
-
- /**
- * A sample containing a timestamp and the number of bytes transferred up to that point in time.
- */
- public static class Sample {
- private long bytesTransfered;
- private long timestamp;
-
- /**
- * Creates a new sample.
- *
- * @param bytesTransfered The total number of bytes transferred.
- * @param timestamp A point in time, in milliseconds.
- */
- public Sample(long bytesTransfered, long timestamp) {
- this.bytesTransfered = bytesTransfered;
- this.timestamp = timestamp;
- }
-
- /**
- * Returns the number of bytes transferred.
- *
- * @return The number of bytes transferred.
- */
- public long getBytesTransfered() {
- return bytesTransfered;
- }
-
- /**
- * Returns the timestamp of the sample.
- *
- * @return The timestamp in milliseconds.
- */
- public long getTimestamp() {
- return timestamp;
- }
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("TransferStatus-").append(hashCode()).append(" [player: ").append(player.getId()).append(", file: ");
- builder.append(file).append(", terminated: ").append(terminated).append(", active: ").append(active).append("]");
- return builder.toString();
- }
-
- /**
- * Contains recent history of samples.
- */
- public static class SampleHistory extends BoundedList<Sample> {
-
- public SampleHistory() {
- super(HISTORY_LENGTH);
- }
-
- public SampleHistory(SampleHistory other) {
- super(HISTORY_LENGTH);
- addAll(other);
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/User.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/User.java
deleted file mode 100644
index 95e51004..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/User.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Represent a user.
- *
- * @author Sindre Mehus
- */
-public class User {
-
- public static final String USERNAME_ADMIN = "admin";
-
- private final String username;
- private String password;
- private String email;
- private boolean ldapAuthenticated;
- private long bytesStreamed;
- private long bytesDownloaded;
- private long bytesUploaded;
-
- private boolean isAdminRole;
- private boolean isSettingsRole;
- private boolean isDownloadRole;
- private boolean isUploadRole;
- private boolean isPlaylistRole;
- private boolean isCoverArtRole;
- private boolean isCommentRole;
- private boolean isPodcastRole;
- private boolean isStreamRole;
- private boolean isJukeboxRole;
- private boolean isShareRole;
-
- public User(String username, String password, String email, boolean ldapAuthenticated,
- long bytesStreamed, long bytesDownloaded, long bytesUploaded) {
- this.username = username;
- this.password = password;
- this.email = email;
- this.ldapAuthenticated = ldapAuthenticated;
- this.bytesStreamed = bytesStreamed;
- this.bytesDownloaded = bytesDownloaded;
- this.bytesUploaded = bytesUploaded;
- }
-
- public User(String username, String password, String email) {
- this(username, password, email, false, 0, 0, 0);
- }
-
- public String getUsername() {
- return username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public boolean isLdapAuthenticated() {
- return ldapAuthenticated;
- }
-
- public void setLdapAuthenticated(boolean ldapAuthenticated) {
- this.ldapAuthenticated = ldapAuthenticated;
- }
-
- public long getBytesStreamed() {
- return bytesStreamed;
- }
-
- public void setBytesStreamed(long bytesStreamed) {
- this.bytesStreamed = bytesStreamed;
- }
-
- public long getBytesDownloaded() {
- return bytesDownloaded;
- }
-
- public void setBytesDownloaded(long bytesDownloaded) {
- this.bytesDownloaded = bytesDownloaded;
- }
-
- public long getBytesUploaded() {
- return bytesUploaded;
- }
-
- public void setBytesUploaded(long bytesUploaded) {
- this.bytesUploaded = bytesUploaded;
- }
-
- public boolean isAdminRole() {
- return isAdminRole;
- }
-
- public void setAdminRole(boolean isAdminRole) {
- this.isAdminRole = isAdminRole;
- }
-
- public boolean isSettingsRole() {
- return isSettingsRole;
- }
-
- public void setSettingsRole(boolean isSettingsRole) {
- this.isSettingsRole = isSettingsRole;
- }
-
- public boolean isCommentRole() {
- return isCommentRole;
- }
-
- public void setCommentRole(boolean isCommentRole) {
- this.isCommentRole = isCommentRole;
- }
-
- public boolean isDownloadRole() {
- return isDownloadRole;
- }
-
- public void setDownloadRole(boolean isDownloadRole) {
- this.isDownloadRole = isDownloadRole;
- }
-
- public boolean isUploadRole() {
- return isUploadRole;
- }
-
- public void setUploadRole(boolean isUploadRole) {
- this.isUploadRole = isUploadRole;
- }
-
- public boolean isPlaylistRole() {
- return isPlaylistRole;
- }
-
- public void setPlaylistRole(boolean isPlaylistRole) {
- this.isPlaylistRole = isPlaylistRole;
- }
-
- public boolean isCoverArtRole() {
- return isCoverArtRole;
- }
-
- public void setCoverArtRole(boolean isCoverArtRole) {
- this.isCoverArtRole = isCoverArtRole;
- }
-
- public boolean isPodcastRole() {
- return isPodcastRole;
- }
-
- public void setPodcastRole(boolean isPodcastRole) {
- this.isPodcastRole = isPodcastRole;
- }
-
- public boolean isStreamRole() {
- return isStreamRole;
- }
-
- public void setStreamRole(boolean streamRole) {
- isStreamRole = streamRole;
- }
-
- public boolean isJukeboxRole() {
- return isJukeboxRole;
- }
-
- public void setJukeboxRole(boolean jukeboxRole) {
- isJukeboxRole = jukeboxRole;
- }
-
- public boolean isShareRole() {
- return isShareRole;
- }
-
- public void setShareRole(boolean shareRole) {
- isShareRole = shareRole;
- }
-
- @Override
- public String toString() {
- StringBuffer result = new StringBuffer(username);
-
- if (isAdminRole) {
- result.append(" [admin]");
- }
- if (isSettingsRole) {
- result.append(" [settings]");
- }
- if (isDownloadRole) {
- result.append(" [download]");
- }
- if (isUploadRole) {
- result.append(" [upload]");
- }
- if (isPlaylistRole) {
- result.append(" [playlist]");
- }
- if (isCoverArtRole) {
- result.append(" [coverart]");
- }
- if (isCommentRole) {
- result.append(" [comment]");
- }
- if (isPodcastRole) {
- result.append(" [podcast]");
- }
- if (isStreamRole) {
- result.append(" [stream]");
- }
- if (isJukeboxRole) {
- result.append(" [jukebox]");
- }
- if (isShareRole) {
- result.append(" [share]");
- }
-
- return result.toString();
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/UserSettings.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/UserSettings.java
deleted file mode 100644
index 856591bc..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/UserSettings.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import java.util.*;
-
-/**
- * Represent user-specific settings.
- *
- * @author Sindre Mehus
- */
-public class UserSettings {
-
- private String username;
- private Locale locale;
- private String themeId;
- private boolean showNowPlayingEnabled;
- private boolean showChatEnabled;
- private boolean finalVersionNotificationEnabled;
- private boolean betaVersionNotificationEnabled;
- private Visibility mainVisibility = new Visibility();
- private Visibility playlistVisibility = new Visibility();
- private boolean lastFmEnabled;
- private String lastFmUsername;
- private String lastFmPassword;
- private TranscodeScheme transcodeScheme = TranscodeScheme.OFF;
- private int selectedMusicFolderId = -1;
- private boolean partyModeEnabled;
- private boolean nowPlayingAllowed;
- private AvatarScheme avatarScheme = AvatarScheme.NONE;
- private Integer systemAvatarId;
- private Date changed = new Date();
-
- public UserSettings(String username) {
- this.username = username;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public Locale getLocale() {
- return locale;
- }
-
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- public String getThemeId() {
- return themeId;
- }
-
- public void setThemeId(String themeId) {
- this.themeId = themeId;
- }
-
- public boolean isShowNowPlayingEnabled() {
- return showNowPlayingEnabled;
- }
-
- public void setShowNowPlayingEnabled(boolean showNowPlayingEnabled) {
- this.showNowPlayingEnabled = showNowPlayingEnabled;
- }
-
- public boolean isShowChatEnabled() {
- return showChatEnabled;
- }
-
- public void setShowChatEnabled(boolean showChatEnabled) {
- this.showChatEnabled = showChatEnabled;
- }
-
- public boolean isFinalVersionNotificationEnabled() {
- return finalVersionNotificationEnabled;
- }
-
- public void setFinalVersionNotificationEnabled(boolean finalVersionNotificationEnabled) {
- this.finalVersionNotificationEnabled = finalVersionNotificationEnabled;
- }
-
- public boolean isBetaVersionNotificationEnabled() {
- return betaVersionNotificationEnabled;
- }
-
- public void setBetaVersionNotificationEnabled(boolean betaVersionNotificationEnabled) {
- this.betaVersionNotificationEnabled = betaVersionNotificationEnabled;
- }
-
- public Visibility getMainVisibility() {
- return mainVisibility;
- }
-
- public void setMainVisibility(Visibility mainVisibility) {
- this.mainVisibility = mainVisibility;
- }
-
- public Visibility getPlaylistVisibility() {
- return playlistVisibility;
- }
-
- public void setPlaylistVisibility(Visibility playlistVisibility) {
- this.playlistVisibility = playlistVisibility;
- }
-
- public boolean isLastFmEnabled() {
- return lastFmEnabled;
- }
-
- public void setLastFmEnabled(boolean lastFmEnabled) {
- this.lastFmEnabled = lastFmEnabled;
- }
-
- public String getLastFmUsername() {
- return lastFmUsername;
- }
-
- public void setLastFmUsername(String lastFmUsername) {
- this.lastFmUsername = lastFmUsername;
- }
-
- public String getLastFmPassword() {
- return lastFmPassword;
- }
-
- public void setLastFmPassword(String lastFmPassword) {
- this.lastFmPassword = lastFmPassword;
- }
-
- public TranscodeScheme getTranscodeScheme() {
- return transcodeScheme;
- }
-
- public void setTranscodeScheme(TranscodeScheme transcodeScheme) {
- this.transcodeScheme = transcodeScheme;
- }
-
- public int getSelectedMusicFolderId() {
- return selectedMusicFolderId;
- }
-
- public void setSelectedMusicFolderId(int selectedMusicFolderId) {
- this.selectedMusicFolderId = selectedMusicFolderId;
- }
-
- public boolean isPartyModeEnabled() {
- return partyModeEnabled;
- }
-
- public void setPartyModeEnabled(boolean partyModeEnabled) {
- this.partyModeEnabled = partyModeEnabled;
- }
-
- public boolean isNowPlayingAllowed() {
- return nowPlayingAllowed;
- }
-
- public void setNowPlayingAllowed(boolean nowPlayingAllowed) {
- this.nowPlayingAllowed = nowPlayingAllowed;
- }
-
- public AvatarScheme getAvatarScheme() {
- return avatarScheme;
- }
-
- public void setAvatarScheme(AvatarScheme avatarScheme) {
- this.avatarScheme = avatarScheme;
- }
-
- public Integer getSystemAvatarId() {
- return systemAvatarId;
- }
-
- public void setSystemAvatarId(Integer systemAvatarId) {
- this.systemAvatarId = systemAvatarId;
- }
-
- /**
- * Returns when the corresponding database entry was last changed.
- *
- * @return When the corresponding database entry was last changed.
- */
- public Date getChanged() {
- return changed;
- }
-
- /**
- * Sets when the corresponding database entry was last changed.
- *
- * @param changed When the corresponding database entry was last changed.
- */
- public void setChanged(Date changed) {
- this.changed = changed;
- }
-
- /**
- * Configuration of what information to display about a song.
- */
- public static class Visibility {
- private int captionCutoff;
- private boolean isTrackNumberVisible;
- private boolean isArtistVisible;
- private boolean isAlbumVisible;
- private boolean isGenreVisible;
- private boolean isYearVisible;
- private boolean isBitRateVisible;
- private boolean isDurationVisible;
- private boolean isFormatVisible;
- private boolean isFileSizeVisible;
-
- public Visibility() {}
-
- public Visibility(int captionCutoff, boolean trackNumberVisible, boolean artistVisible, boolean albumVisible,
- boolean genreVisible, boolean yearVisible, boolean bitRateVisible,
- boolean durationVisible, boolean formatVisible, boolean fileSizeVisible) {
- this.captionCutoff = captionCutoff;
- isTrackNumberVisible = trackNumberVisible;
- isArtistVisible = artistVisible;
- isAlbumVisible = albumVisible;
- isGenreVisible = genreVisible;
- isYearVisible = yearVisible;
- isBitRateVisible = bitRateVisible;
- isDurationVisible = durationVisible;
- isFormatVisible = formatVisible;
- isFileSizeVisible = fileSizeVisible;
- }
-
- public int getCaptionCutoff() {
- return captionCutoff;
- }
-
- public void setCaptionCutoff(int captionCutoff) {
- this.captionCutoff = captionCutoff;
- }
-
- public boolean isTrackNumberVisible() {
- return isTrackNumberVisible;
- }
-
- public void setTrackNumberVisible(boolean trackNumberVisible) {
- isTrackNumberVisible = trackNumberVisible;
- }
-
- public boolean isArtistVisible() {
- return isArtistVisible;
- }
-
- public void setArtistVisible(boolean artistVisible) {
- isArtistVisible = artistVisible;
- }
-
- public boolean isAlbumVisible() {
- return isAlbumVisible;
- }
-
- public void setAlbumVisible(boolean albumVisible) {
- isAlbumVisible = albumVisible;
- }
-
- public boolean isGenreVisible() {
- return isGenreVisible;
- }
-
- public void setGenreVisible(boolean genreVisible) {
- isGenreVisible = genreVisible;
- }
-
- public boolean isYearVisible() {
- return isYearVisible;
- }
-
- public void setYearVisible(boolean yearVisible) {
- isYearVisible = yearVisible;
- }
-
- public boolean isBitRateVisible() {
- return isBitRateVisible;
- }
-
- public void setBitRateVisible(boolean bitRateVisible) {
- isBitRateVisible = bitRateVisible;
- }
-
- public boolean isDurationVisible() {
- return isDurationVisible;
- }
-
- public void setDurationVisible(boolean durationVisible) {
- isDurationVisible = durationVisible;
- }
-
- public boolean isFormatVisible() {
- return isFormatVisible;
- }
-
- public void setFormatVisible(boolean formatVisible) {
- isFormatVisible = formatVisible;
- }
-
- public boolean isFileSizeVisible() {
- return isFileSizeVisible;
- }
-
- public void setFileSizeVisible(boolean fileSizeVisible) {
- isFileSizeVisible = fileSizeVisible;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Version.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Version.java
deleted file mode 100644
index c4d42a99..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/Version.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Represents the version number of Subsonic.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.3 $ $Date: 2006/01/20 21:25:16 $
- */
-public class Version implements Comparable<Version> {
- private int major;
- private int minor;
- private int beta;
- private int bugfix;
-
- /**
- * Creates a new version instance by parsing the given string.
- * @param version A string of the format "1.27", "1.27.2" or "1.27.beta3".
- */
- public Version(String version) {
- String[] s = version.split("\\.");
- major = Integer.valueOf(s[0]);
- minor = Integer.valueOf(s[1]);
-
- if (s.length > 2) {
- if (s[2].contains("beta")) {
- beta = Integer.valueOf(s[2].replace("beta", ""));
- } else {
- bugfix = Integer.valueOf(s[2]);
- }
- }
- }
-
- public int getMajor() {
- return major;
- }
-
- public int getMinor() {
- return minor;
- }
-
- /**
- * Return whether this object is equal to another.
- * @param o Object to compare to.
- * @return Whether this object is equals to another.
- */
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- final Version version = (Version) o;
-
- if (beta != version.beta) return false;
- if (bugfix != version.bugfix) return false;
- if (major != version.major) return false;
- return minor == version.minor;
- }
-
- /**
- * Returns a hash code for this object.
- * @return A hash code for this object.
- */
- public int hashCode() {
- int result;
- result = major;
- result = 29 * result + minor;
- result = 29 * result + beta;
- result = 29 * result + bugfix;
- return result;
- }
-
- /**
- * Returns a string representation of the form "1.27", "1.27.2" or "1.27.beta3".
- * @return A string representation of the form "1.27", "1.27.2" or "1.27.beta3".
- */
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append(major).append('.').append(minor);
- if (beta != 0) {
- buf.append(".beta").append(beta);
- } else if (bugfix != 0) {
- buf.append('.').append(bugfix);
- }
-
- return buf.toString();
- }
-
- /**
- * Compares this object with the specified object for order.
- * @param version The object to compare to.
- * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or
- * greater than the specified object.
- */
- public int compareTo(Version version) {
- if (major < version.major) {
- return -1;
- } else if (major > version.major) {
- return 1;
- }
-
- if (minor < version.minor) {
- return -1;
- } else if (minor > version.minor) {
- return 1;
- }
-
- if (bugfix < version.bugfix) {
- return -1;
- } else if (bugfix > version.bugfix) {
- return 1;
- }
-
- int thisBeta = beta == 0 ? Integer.MAX_VALUE : beta;
- int otherBeta = version.beta == 0 ? Integer.MAX_VALUE : version.beta;
-
- if (thisBeta < otherBeta) {
- return -1;
- } else if (thisBeta > otherBeta) {
- return 1;
- }
-
- return 0;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/VideoTranscodingSettings.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/VideoTranscodingSettings.java
deleted file mode 100644
index 18661ba4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/VideoTranscodingSettings.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-/**
- * Parameters used when transcoding videos.
- *
- * @author Sindre Mehus
- * @version $Id$
- */
-public class VideoTranscodingSettings {
-
- private final int width;
- private final int height;
- private final int timeOffset;
-
- public VideoTranscodingSettings(int width, int height, int timeOffset) {
- this.width = width;
- this.height = height;
- this.timeOffset = timeOffset;
- }
-
- public int getWidth() {
- return width;
- }
-
- public int getHeight() {
- return height;
- }
-
- public int getTimeOffset() {
- return timeOffset;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/WeUPnPRouter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/WeUPnPRouter.java
deleted file mode 100644
index e36701e8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/domain/WeUPnPRouter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.domain;
-
-import org.wetorrent.upnp.GatewayDevice;
-import org.wetorrent.upnp.GatewayDiscover;
-
-import java.net.InetAddress;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class WeUPnPRouter implements Router {
- private final GatewayDevice device;
-
- private WeUPnPRouter(GatewayDevice device) {
- this.device = device;
- }
-
- public static WeUPnPRouter findRouter() throws Exception {
- GatewayDiscover discover = new GatewayDiscover();
- discover.discover();
- GatewayDevice device = discover.getValidGateway();
- if (device == null) {
- return null;
- }
-
- return new WeUPnPRouter(device);
- }
-
- public void addPortMapping(int externalPort, int internalPort, int leaseDuration) throws Exception {
- String localIp = InetAddress.getLocalHost().getHostAddress();
- device.addPortMapping(externalPort, internalPort, localIp, "TCP", "Subsonic");
- }
-
- public void deletePortMapping(int externalPort, int internalPort) throws Exception {
- device.deletePortMapping(externalPort, "TCP");
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/BootstrapVerificationFilter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/BootstrapVerificationFilter.java
deleted file mode 100644
index c93d0603..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/BootstrapVerificationFilter.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.filter;
-
-import net.sourceforge.subsonic.service.SettingsService;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * This filter is executed very early in the filter chain. It verifies that
- * the Subsonic home directory (c:\subsonic or /var/subsonic) exists and
- * is writable. If not, a proper error message is given to the user.
- * <p/>
- * (The Subsonic home directory is usually created automatically, but a common
- * problem on Linux is that the Tomcat user does not have the necessary
- * privileges).
- *
- * @author Sindre Mehus
- */
-public class BootstrapVerificationFilter implements Filter {
-
- private boolean subsonicHomeVerified = false;
-
-
- public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
- throws IOException, ServletException {
-
- // Already verified?
- if (subsonicHomeVerified) {
- chain.doFilter(req, res);
- return;
- }
-
- File home = SettingsService.getSubsonicHome();
- if (!directoryExists(home)) {
- error(res, "<p>The directory <b>" + home + "</b> does not exist. Please create it and make it writable, " +
- "then restart the servlet container.</p>" +
- "<p>(You can override the directory location by specifying -Dsubsonic.home=... when " +
- "starting the servlet container.)</p>");
-
- } else if (!directoryWritable(home)) {
- error(res, "<p>The directory <b>" + home + "</b> is not writable. Please change file permissions, " +
- "then restart the servlet container.</p>" +
- "<p>(You can override the directory location by specifying -Dsubsonic.home=... when " +
- "starting the servlet container.)</p>");
-
- } else {
- subsonicHomeVerified = true;
- chain.doFilter(req, res);
- }
- }
-
- private boolean directoryExists(File dir) {
- return dir.exists() && dir.isDirectory();
- }
-
- private boolean directoryWritable(File dir) {
- try {
- File tempFile = File.createTempFile("test", null, dir);
- tempFile.delete();
- return true;
- } catch (IOException x) {
- return false;
- }
- }
-
- private void error(ServletResponse res, String error) throws IOException {
- ServletOutputStream out = res.getOutputStream();
- out.println("<html>" +
- "<head><title>Subsonic Error</title></head>" +
- "<body>" +
- "<h2>Subsonic Error</h2>" +
- error +
- "</body>" +
- "</html>");
- }
-
- public void init(FilterConfig filterConfig) {
- }
-
- public void destroy() {
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ParameterDecodingFilter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ParameterDecodingFilter.java
deleted file mode 100644
index 52a98ad0..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ParameterDecodingFilter.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.filter;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.util.StringUtil;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-/**
- * Servlet filter which decodes HTTP request parameters. If a parameter name ends with
- * "Utf8Hex" ({@link #PARAM_SUFFIX}) , the corresponding parameter value is assumed to be the
- * hexadecimal representation of the UTF-8 bytes of the value.
- * <p/>
- * Used to support request parameter values of any character encoding.
- *
- * @author Sindre Mehus
- */
-public class ParameterDecodingFilter implements Filter {
-
- public static final String PARAM_SUFFIX = "Utf8Hex";
- private static final Logger LOG = Logger.getLogger(ParameterDecodingFilter.class);
-
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
-
- // Wrap request in decoder.
- ServletRequest decodedRequest = new DecodingServletRequestWrapper((HttpServletRequest) request);
-
- // Pass the request/response on
- chain.doFilter(decodedRequest, response);
- }
-
- public void init(FilterConfig filterConfig) {
- }
-
- public void destroy() {
- }
-
- private static class DecodingServletRequestWrapper extends HttpServletRequestWrapper {
-
- public DecodingServletRequestWrapper(HttpServletRequest servletRequest) {
- super(servletRequest);
- }
-
- @Override
- public String getParameter(String name) {
- String[] values = getParameterValues(name);
- if (values == null || values.length == 0) {
- return null;
- }
- return values[0];
- }
-
- @Override
- public Map getParameterMap() {
- Map map = super.getParameterMap();
- Map<String, String[]> result = new HashMap<String, String[]>();
-
- for (Object o : map.entrySet()) {
- Map.Entry entry = (Map.Entry) o;
- String name = (String) entry.getKey();
- String[] values = (String[]) entry.getValue();
-
- if (name.endsWith(PARAM_SUFFIX)) {
- result.put(name.replace(PARAM_SUFFIX, ""), decode(values));
- } else {
- result.put(name, values);
- }
- }
- return result;
- }
-
- @Override
- public Enumeration getParameterNames() {
- Enumeration e = super.getParameterNames();
- Vector<String> v = new Vector<String>();
- while (e.hasMoreElements()) {
- String name = (String) e.nextElement();
- if (name.endsWith(PARAM_SUFFIX)) {
- name = name.replace(PARAM_SUFFIX, "");
- }
- v.add(name);
- }
-
- return v.elements();
- }
-
- @Override
- public String[] getParameterValues(String name) {
- String[] values = super.getParameterValues(name);
- if (values != null) {
- return values;
- }
-
- values = super.getParameterValues(name + PARAM_SUFFIX);
- if (values != null) {
- return decode(values);
- }
-
- return null;
- }
-
- private String[] decode(String[] values) {
- if (values == null) {
- return null;
- }
-
- String[] result = new String[values.length];
- for (int i = 0; i < values.length; i++) {
- try {
- result[i] = StringUtil.utf8HexDecode(values[i]);
- } catch (Exception x) {
- LOG.error("Failed to decode parameter value '" + values[i] + "'");
- result[i] = values[i];
- }
- }
-
- return result;
- }
-
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/RequestEncodingFilter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/RequestEncodingFilter.java
deleted file mode 100644
index 3b37e8d4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/RequestEncodingFilter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.filter;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-import java.io.*;
-
-/**
- * Configurable filter for setting the character encoding to use for the HTTP request.
- * Typically used to set UTF-8 encoding when reading request parameters with non-Latin
- * content.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.1 $ $Date: 2006/03/01 16:58:08 $
- */
-public class RequestEncodingFilter implements Filter {
-
- private String encoding;
-
- public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
- throws IOException, ServletException {
- HttpServletRequest request = (HttpServletRequest) req;
- request.setCharacterEncoding(encoding);
-
- // Pass the request/response on
- chain.doFilter(req, res);
- }
-
- public void init(FilterConfig filterConfig) {
- encoding = filterConfig.getInitParameter("encoding");
- }
-
- public void destroy() {
- encoding = null;
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ResponseHeaderFilter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ResponseHeaderFilter.java
deleted file mode 100644
index 33f60f83..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/filter/ResponseHeaderFilter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.filter;
-
-import javax.servlet.*;
-import javax.servlet.http.*;
-import java.io.*;
-import java.util.*;
-
-/**
- * Configurable filter for setting HTTP response headers. Can be used, for instance, to
- * set cache control directives for certain resources.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.1 $ $Date: 2005/08/14 13:14:47 $
- */
-public class ResponseHeaderFilter implements Filter {
- private FilterConfig filterConfig;
-
- public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
- throws IOException, ServletException {
- HttpServletResponse response = (HttpServletResponse) res;
-
- // Sets the provided HTTP response parameters
- for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
- String headerName = (String) e.nextElement();
- response.addHeader(headerName, filterConfig.getInitParameter(headerName));
- }
-
- // pass the request/response on
- chain.doFilter(req, response);
- }
-
- public void init(FilterConfig filterConfig) {
- this.filterConfig = filterConfig;
- }
-
- public void destroy() {
- this.filterConfig = null;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/i18n/SubsonicLocaleResolver.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/i18n/SubsonicLocaleResolver.java
deleted file mode 100644
index 231ad6e7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/i18n/SubsonicLocaleResolver.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.i18n;
-
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.domain.*;
-import org.springframework.web.servlet.*;
-
-import javax.servlet.http.*;
-import java.util.*;
-
-/**
- * Locale resolver implementation which returns the locale selected in the settings.
- *
- * @author Sindre Mehus
- */
-public class SubsonicLocaleResolver implements LocaleResolver {
-
- private SecurityService securityService;
- private SettingsService settingsService;
- private Set<Locale> locales;
-
- /**
- * Resolve the current locale via the given request.
- *
- * @param request Request to be used for resolution.
- * @return The current locale.
- */
- public Locale resolveLocale(HttpServletRequest request) {
- Locale locale = (Locale) request.getAttribute("subsonic.locale");
- if (locale != null) {
- return locale;
- }
-
- // Optimization: Cache locale in the request.
- locale = doResolveLocale(request);
- request.setAttribute("subsonic.locale", locale);
-
- return locale;
- }
-
- private Locale doResolveLocale(HttpServletRequest request) {
- Locale locale = null;
-
- // Look for user-specific locale.
- String username = securityService.getCurrentUsername(request);
- if (username != null) {
- UserSettings userSettings = settingsService.getUserSettings(username);
- if (userSettings != null) {
- locale = userSettings.getLocale();
- }
- }
-
- if (locale != null && localeExists(locale)) {
- return locale;
- }
-
- // Return system locale.
- locale = settingsService.getLocale();
- return localeExists(locale) ? locale : Locale.ENGLISH;
- }
-
- /**
- * Returns whether the given locale exists.
- * @param locale The locale.
- * @return Whether the locale exists.
- */
- private synchronized boolean localeExists(Locale locale) {
- // Lazily create set of locales.
- if (locales == null) {
- locales = new HashSet<Locale>(Arrays.asList(settingsService.getAvailableLocales()));
- }
-
- return locales.contains(locale);
- }
-
- public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
- throw new UnsupportedOperationException("Cannot change locale - use a different locale resolution strategy");
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java
deleted file mode 100644
index 1019f73a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/InputStreamReaderThread.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.io;
-
-import net.sourceforge.subsonic.*;
-import org.apache.commons.io.*;
-
-import java.io.*;
-
-/**
- * Utility class which reads everything from an input stream and optionally logs it.
- *
- * @see TranscodeInputStream
- * @author Sindre Mehus
- */
-public class InputStreamReaderThread extends Thread {
-
- private static final Logger LOG = Logger.getLogger(InputStreamReaderThread.class);
-
- private InputStream input;
- private String name;
- private boolean log;
-
- public InputStreamReaderThread(InputStream input, String name, boolean log) {
- super(name + " InputStreamLogger");
- this.input = input;
- this.name = name;
- this.log = log;
- }
-
- public void run() {
- BufferedReader reader = null;
- try {
- reader = new BufferedReader(new InputStreamReader(input));
- for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- if (log) {
- LOG.debug('(' + name + ") " + line);
- }
- }
- } catch (IOException x) {
- // Intentionally ignored.
- } finally {
- IOUtils.closeQuietly(reader);
- IOUtils.closeQuietly(input);
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java
deleted file mode 100644
index 3be7fdd9..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/PlayQueueInputStream.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.io;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.VideoTranscodingSettings;
-import net.sourceforge.subsonic.service.MediaFileService;
-import net.sourceforge.subsonic.service.SearchService;
-import net.sourceforge.subsonic.util.FileUtil;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.service.AudioScrobblerService;
-import net.sourceforge.subsonic.service.TranscodingService;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-/**
- * Implementation of {@link InputStream} which reads from a {@link net.sourceforge.subsonic.domain.PlayQueue}.
- *
- * @author Sindre Mehus
- */
-public class PlayQueueInputStream extends InputStream {
-
- private static final Logger LOG = Logger.getLogger(PlayQueueInputStream.class);
-
- private final Player player;
- private final TransferStatus status;
- private final Integer maxBitRate;
- private final String preferredTargetFormat;
- private final VideoTranscodingSettings videoTranscodingSettings;
- private final TranscodingService transcodingService;
- private final AudioScrobblerService audioScrobblerService;
- private final MediaFileService mediaFileService;
- private MediaFile currentFile;
- private InputStream currentInputStream;
- private SearchService searchService;
-
- public PlayQueueInputStream(Player player, TransferStatus status, Integer maxBitRate, String preferredTargetFormat,
- VideoTranscodingSettings videoTranscodingSettings, TranscodingService transcodingService,
- AudioScrobblerService audioScrobblerService, MediaFileService mediaFileService, SearchService searchService) {
- this.player = player;
- this.status = status;
- this.maxBitRate = maxBitRate;
- this.preferredTargetFormat = preferredTargetFormat;
- this.videoTranscodingSettings = videoTranscodingSettings;
- this.transcodingService = transcodingService;
- this.audioScrobblerService = audioScrobblerService;
- this.mediaFileService = mediaFileService;
- this.searchService = searchService;
- }
-
- @Override
- public int read() throws IOException {
- byte[] b = new byte[1];
- int n = read(b);
- return n == -1 ? -1 : b[0];
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- prepare();
- if (currentInputStream == null || player.getPlayQueue().getStatus() == PlayQueue.Status.STOPPED) {
- return -1;
- }
-
- int n = currentInputStream.read(b, off, len);
-
- // If end of song reached, skip to next song and call read() again.
- if (n == -1) {
- player.getPlayQueue().next();
- close();
- return read(b, off, len);
- } else {
- status.addBytesTransfered(n);
- }
- return n;
- }
-
- private void prepare() throws IOException {
- PlayQueue playQueue = player.getPlayQueue();
-
- // If playlist is in auto-random mode, populate it with new random songs.
- if (playQueue.getIndex() == -1 && playQueue.getRandomSearchCriteria() != null) {
- populateRandomPlaylist(playQueue);
- }
-
- MediaFile result;
- synchronized (playQueue) {
- result = playQueue.getCurrentFile();
- }
- MediaFile file = result;
- if (file == null) {
- close();
- } else if (!file.equals(currentFile)) {
- close();
- LOG.info(player.getUsername() + " listening to \"" + FileUtil.getShortPath(file.getFile()) + "\"");
- mediaFileService.incrementPlayCount(file);
- if (player.getClientId() == null) { // Don't scrobble REST players.
- audioScrobblerService.register(file, player.getUsername(), false);
- }
-
- TranscodingService.Parameters parameters = transcodingService.getParameters(file, player, maxBitRate, preferredTargetFormat, videoTranscodingSettings);
- currentInputStream = transcodingService.getTranscodedInputStream(parameters);
- currentFile = file;
- status.setFile(currentFile.getFile());
- }
- }
-
- private void populateRandomPlaylist(PlayQueue playQueue) throws IOException {
- List<MediaFile> files = searchService.getRandomSongs(playQueue.getRandomSearchCriteria());
- playQueue.addFiles(false, files);
- LOG.info("Recreated random playlist with " + playQueue.size() + " songs.");
- }
-
- @Override
- public void close() throws IOException {
- try {
- if (currentInputStream != null) {
- currentInputStream.close();
- }
- } finally {
- if (player.getClientId() == null) { // Don't scrobble REST players.
- audioScrobblerService.register(currentFile, player.getUsername(), true);
- }
- currentInputStream = null;
- currentFile = null;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java
deleted file mode 100644
index 25bc03d2..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/RangeOutputStream.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.io;
-
-import org.apache.commons.lang.math.Range;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-/**
- * Special output stream for grabbing only part of a passed stream.
- *
- * @author Sindre Mehus (based on code found on http://www.koders.com/
- */
-public class RangeOutputStream extends FilterOutputStream {
-
- /**
- * The starting index.
- */
- private long start;
-
- /**
- * The ending index.
- */
- private long end;
-
- /**
- * The current position.
- */
- protected long pos;
-
- /**
- * Wraps the given output stream in a RangeOutputStream, using the values
- * in the given range, unless the range is <code>null</code> in which case
- * the original OutputStream is returned.
- *
- * @param out The output stream to wrap in a RangeOutputStream.
- * @param range The range, may be <code>null</code>.
- * @return The possibly wrapped output stream.
- */
- public static OutputStream wrap(OutputStream out, Range range) {
- if (range == null) {
- return out;
- }
- return new RangeOutputStream(out, range.getMinimumLong(), range.getMaximumLong());
- }
-
- /**
- * Creates the stream with the passed start and end.
- *
- * @param out The stream to write to.
- * @param start The starting position.
- * @param end The ending position.
- */
- public RangeOutputStream(OutputStream out, long start, long end) {
- super(out);
- this.start = start;
- this.end = end;
- pos = 0;
- }
-
- /**
- * Writes the byte IF it is within the range, otherwise it only
- * increments the position.
- *
- * @param b The byte to write.
- * @throws IOException Thrown if there was a problem writing to the stream.
- */
- @Override
- public void write(int b) throws IOException {
- if ((pos >= start) && (pos <= end)) {
- super.write(b);
- }
- pos++;
- }
-
- /**
- * Writes the bytes IF it is within the range, otherwise it only
- * increments the position.
- *
- * @param b The bytes to write.
- * @param off The offset to start at.
- * @param len The length to write.
- * @throws IOException Thrown if there was a problem writing to the stream.
- */
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- boolean allowWrite = false;
- long newPos = pos + off, newOff = off, newLen = len;
-
- // Check to see if we are in the range
- if (newPos <= end) {
- if (newPos >= start) {
- // We are so check to make sure we don't leave it
- if (newPos + newLen > end) {
- newLen = end - newPos;
- }
-
- // Enable writing
- allowWrite = true;
- }
-
- // We aren't yet in the range, but if see if the proposed write
- // would place us there
- else if (newPos + newLen >= start) {
- // It would so, update the offset
- newOff += start - newPos;
-
- // New offset means, a new position, so update that too
- newPos = newOff + pos;
- newLen = len + (pos - newPos);
-
- // Make sure we don't go past the range
- if (newPos + newLen > end) {
- newLen = end - newPos;
- }
-
- // Enable writting
- allowWrite = true;
- }
- }
-
- // If we have enabled writing, do the write!
- if (allowWrite) {
- out.write(b, (int) newOff, (int) newLen);
- }
-
- // Move the cursor along
- pos += off + len;
- }
-}
-
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java
deleted file mode 100644
index 9a8618c6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/ShoutCastOutputStream.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.io;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.apache.commons.lang.StringUtils;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Implements SHOUTcast support by decorating an existing output stream.
- * <p/>
- * Based on protocol description found on
- * <em>http://www.smackfu.com/stuff/programming/shoutcast.html</em>
- *
- * @author Sindre Mehus
- */
-public class ShoutCastOutputStream extends OutputStream {
-
- private static final Logger LOG = Logger.getLogger(ShoutCastOutputStream.class);
-
- /**
- * Number of bytes between each SHOUTcast metadata block.
- */
- public static final int META_DATA_INTERVAL = 20480;
-
- /**
- * The underlying output stream to decorate.
- */
- private OutputStream out;
-
- /**
- * What to write in the SHOUTcast metadata is fetched from the playlist.
- */
- private PlayQueue playQueue;
-
- /**
- * Keeps track of the number of bytes written (excluding meta-data). Between 0 and {@link #META_DATA_INTERVAL}.
- */
- private int byteCount;
-
- /**
- * The last stream title sent.
- */
- private String previousStreamTitle;
-
- private SettingsService settingsService;
-
- /**
- * Creates a new SHOUTcast-decorated stream for the given output stream.
- *
- * @param out The output stream to decorate.
- * @param playQueue Meta-data is fetched from this playlist.
- */
- public ShoutCastOutputStream(OutputStream out, PlayQueue playQueue, SettingsService settingsService) {
- this.out = out;
- this.playQueue = playQueue;
- this.settingsService = settingsService;
- }
-
- /**
- * Writes the given byte array to the underlying stream, adding SHOUTcast meta-data as necessary.
- */
- public void write(byte[] b, int off, int len) throws IOException {
-
- int bytesWritten = 0;
- while (bytesWritten < len) {
-
- // 'n' is the number of bytes to write before the next potential meta-data block.
- int n = Math.min(len - bytesWritten, ShoutCastOutputStream.META_DATA_INTERVAL - byteCount);
-
- out.write(b, off + bytesWritten, n);
- bytesWritten += n;
- byteCount += n;
-
- // Reached meta-data block?
- if (byteCount % ShoutCastOutputStream.META_DATA_INTERVAL == 0) {
- writeMetaData();
- byteCount = 0;
- }
- }
- }
-
- /**
- * Writes the given byte array to the underlying stream, adding SHOUTcast meta-data as necessary.
- */
- public void write(byte[] b) throws IOException {
- write(b, 0, b.length);
- }
-
- /**
- * Writes the given byte to the underlying stream, adding SHOUTcast meta-data as necessary.
- */
- public void write(int b) throws IOException {
- byte[] buf = new byte[]{(byte) b};
- write(buf);
- }
-
- /**
- * Flushes the underlying stream.
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Closes the underlying stream.
- */
- public void close() throws IOException {
- out.close();
- }
-
- private void writeMetaData() throws IOException {
- String streamTitle = StringUtils.trimToEmpty(settingsService.getWelcomeTitle());
-
- MediaFile result;
- synchronized (playQueue) {
- result = playQueue.getCurrentFile();
- }
- MediaFile mediaFile = result;
- if (mediaFile != null) {
- streamTitle = mediaFile.getArtist() + " - " + mediaFile.getTitle();
- }
-
- byte[] bytes;
-
- if (streamTitle.equals(previousStreamTitle)) {
- bytes = new byte[0];
- } else {
- try {
- previousStreamTitle = streamTitle;
- bytes = createStreamTitle(streamTitle);
- } catch (UnsupportedEncodingException x) {
- LOG.warn("Failed to create SHOUTcast meta-data. Ignoring.", x);
- bytes = new byte[0];
- }
- }
-
- // Length in groups of 16 bytes.
- int length = bytes.length / 16;
- if (bytes.length % 16 > 0) {
- length++;
- }
-
- // Write the length as a single byte.
- out.write(length);
-
- // Write the message.
- out.write(bytes);
-
- // Write padding zero bytes.
- int padding = length * 16 - bytes.length;
- for (int i = 0; i < padding; i++) {
- out.write(0);
- }
- }
-
- private byte[] createStreamTitle(String title) throws UnsupportedEncodingException {
- // Remove any quotes from the title.
- title = title.replaceAll("'", "");
-
- // Convert non-ascii characters to similar ascii characters.
- for (char[] chars : ShoutCastOutputStream.CHAR_MAP) {
- title = title.replace(chars[0], chars[1]);
- }
-
- title = "StreamTitle='" + title + "';";
- return title.getBytes("US-ASCII");
- }
-
- /**
- * Maps from miscellaneous accented characters to similar-looking ASCII characters.
- */
- private static final char[][] CHAR_MAP = {
- {'\u00C0', 'A'}, {'\u00C1', 'A'}, {'\u00C2', 'A'}, {'\u00C3', 'A'}, {'\u00C4', 'A'}, {'\u00C5', 'A'}, {'\u00C6', 'A'},
- {'\u00C8', 'E'}, {'\u00C9', 'E'}, {'\u00CA', 'E'}, {'\u00CB', 'E'}, {'\u00CC', 'I'}, {'\u00CD', 'I'}, {'\u00CE', 'I'},
- {'\u00CF', 'I'}, {'\u00D2', 'O'}, {'\u00D3', 'O'}, {'\u00D4', 'O'}, {'\u00D5', 'O'}, {'\u00D6', 'O'}, {'\u00D9', 'U'},
- {'\u00DA', 'U'}, {'\u00DB', 'U'}, {'\u00DC', 'U'}, {'\u00DF', 'B'}, {'\u00E0', 'a'}, {'\u00E1', 'a'}, {'\u00E2', 'a'},
- {'\u00E3', 'a'}, {'\u00E4', 'a'}, {'\u00E5', 'a'}, {'\u00E6', 'a'}, {'\u00E7', 'c'}, {'\u00E8', 'e'}, {'\u00E9', 'e'},
- {'\u00EA', 'e'}, {'\u00EB', 'e'}, {'\u00EC', 'i'}, {'\u00ED', 'i'}, {'\u00EE', 'i'}, {'\u00EF', 'i'}, {'\u00F1', 'n'},
- {'\u00F2', 'o'}, {'\u00F3', 'o'}, {'\u00F4', 'o'}, {'\u00F5', 'o'}, {'\u00F6', 'o'}, {'\u00F8', 'o'}, {'\u00F9', 'u'},
- {'\u00FA', 'u'}, {'\u00FB', 'u'}, {'\u00FC', 'u'}, {'\u2013', '-'}
- };
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java
deleted file mode 100644
index b7a5e31e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/io/TranscodeInputStream.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.io;
-
-import net.sourceforge.subsonic.*;
-
-import org.apache.commons.io.*;
-
-import java.io.*;
-
-/**
- * Subclass of {@link InputStream} which provides on-the-fly transcoding.
- * Instances of <code>TranscodeInputStream</code> can be chained together, for instance to convert
- * from OGG to WAV to MP3.
- *
- * @author Sindre Mehus
- */
-public class TranscodeInputStream extends InputStream {
-
- private static final Logger LOG = Logger.getLogger(TranscodeInputStream.class);
-
- private InputStream processInputStream;
- private OutputStream processOutputStream;
- private Process process;
- private final File tmpFile;
-
- /**
- * Creates a transcoded input stream by executing an external process. If <code>in</code> is not null,
- * data from it is copied to the command.
- *
- * @param processBuilder Used to create the external process.
- * @param in Data to feed to the process. May be {@code null}.
- * @param tmpFile Temporary file to delete when this stream is closed. May be {@code null}.
- * @throws IOException If an I/O error occurs.
- */
- public TranscodeInputStream(ProcessBuilder processBuilder, final InputStream in, File tmpFile) throws IOException {
- this.tmpFile = tmpFile;
-
- StringBuffer buf = new StringBuffer("Starting transcoder: ");
- for (String s : processBuilder.command()) {
- buf.append('[').append(s).append("] ");
- }
- LOG.debug(buf);
-
- process = processBuilder.start();
- processOutputStream = process.getOutputStream();
- processInputStream = process.getInputStream();
-
- // Must read stderr from the process, otherwise it may block.
- final String name = processBuilder.command().get(0);
- new InputStreamReaderThread(process.getErrorStream(), name, true).start();
-
- // Copy data in a separate thread
- if (in != null) {
- new Thread(name + " TranscodedInputStream copy thread") {
- public void run() {
- try {
- IOUtils.copy(in, processOutputStream);
- } catch (IOException x) {
- // Intentionally ignored. Will happen if the remote player closes the stream.
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(processOutputStream);
- }
- }
- }.start();
- }
- }
-
- /**
- * @see InputStream#read()
- */
- public int read() throws IOException {
- return processInputStream.read();
- }
-
- /**
- * @see InputStream#read(byte[])
- */
- public int read(byte[] b) throws IOException {
- return processInputStream.read(b);
- }
-
- /**
- * @see InputStream#read(byte[], int, int)
- */
- public int read(byte[] b, int off, int len) throws IOException {
- return processInputStream.read(b, off, len);
- }
-
- /**
- * @see InputStream#close()
- */
- public void close() throws IOException {
- IOUtils.closeQuietly(processInputStream);
- IOUtils.closeQuietly(processOutputStream);
-
- if (process != null) {
- process.destroy();
- }
-
- if (tmpFile != null) {
- if (!tmpFile.delete()) {
- LOG.warn("Failed to delete tmp file: " + tmpFile);
- }
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/SubsonicLdapBindAuthenticator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/SubsonicLdapBindAuthenticator.java
deleted file mode 100644
index fee4ff2c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/SubsonicLdapBindAuthenticator.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ldap;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.acegisecurity.BadCredentialsException;
-import org.acegisecurity.ldap.DefaultInitialDirContextFactory;
-import org.acegisecurity.ldap.search.FilterBasedLdapUserSearch;
-import org.acegisecurity.providers.ldap.LdapAuthenticator;
-import org.acegisecurity.providers.ldap.authenticator.BindAuthenticator;
-import org.acegisecurity.userdetails.ldap.LdapUserDetails;
-import org.apache.commons.lang.StringUtils;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * LDAP authenticator which uses a delegate {@link BindAuthenticator}, and which
- * supports dynamically changing LDAP provider URL and search filter.
- *
- * @author Sindre Mehus
- */
-public class SubsonicLdapBindAuthenticator implements LdapAuthenticator {
-
- private static final Logger LOG = Logger.getLogger(SubsonicLdapBindAuthenticator.class);
-
- private SecurityService securityService;
- private SettingsService settingsService;
-
- private long authenticatorTimestamp;
- private BindAuthenticator delegateAuthenticator;
-
- public LdapUserDetails authenticate(String username, String password) {
-
- // LDAP authentication must be enabled on the system.
- if (!settingsService.isLdapEnabled()) {
- throw new BadCredentialsException("LDAP authentication disabled.");
- }
-
- // User must be defined in Subsonic, unless auto-shadowing is enabled.
- User user = securityService.getUserByName(username);
- if (user == null && !settingsService.isLdapAutoShadowing()) {
- throw new BadCredentialsException("User does not exist.");
- }
-
- // LDAP authentication must be enabled for the given user.
- if (user != null && !user.isLdapAuthenticated()) {
- throw new BadCredentialsException("LDAP authentication disabled for user.");
- }
-
- try {
- createDelegate();
- LdapUserDetails details = delegateAuthenticator.authenticate(username, password);
- if (details != null) {
- LOG.info("User '" + username + "' successfully authenticated in LDAP. DN: " + details.getDn());
-
- if (user == null) {
- User newUser = new User(username, "", null, true, 0L, 0L, 0L);
- newUser.setStreamRole(true);
- newUser.setSettingsRole(true);
- securityService.createUser(newUser);
- LOG.info("Created local user '" + username + "' for DN " + details.getDn());
- }
- }
-
- return details;
- } catch (RuntimeException x) {
- LOG.info("Failed to authenticate user '" + username + "' in LDAP.", x);
- throw x;
- }
- }
-
- /**
- * Creates the delegate {@link BindAuthenticator}.
- */
- private synchronized void createDelegate() {
-
- // Only create it if necessary.
- if (delegateAuthenticator == null || authenticatorTimestamp < settingsService.getSettingsChanged()) {
-
- DefaultInitialDirContextFactory contextFactory = new DefaultInitialDirContextFactory(settingsService.getLdapUrl());
-
- String managerDn = settingsService.getLdapManagerDn();
- String managerPassword = settingsService.getLdapManagerPassword();
- if (StringUtils.isNotEmpty(managerDn) && StringUtils.isNotEmpty(managerPassword)) {
- contextFactory.setManagerDn(managerDn);
- contextFactory.setManagerPassword(managerPassword);
- }
-
- Map<String, String> extraEnvVars = new HashMap<String, String>();
- extraEnvVars.put("java.naming.referral", "follow");
- contextFactory.setExtraEnvVars(extraEnvVars);
-
- FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch("", settingsService.getLdapSearchFilter(), contextFactory);
- userSearch.setSearchSubtree(true);
- userSearch.setDerefLinkFlag(true);
-
- delegateAuthenticator = new BindAuthenticator(contextFactory);
- delegateAuthenticator.setUserSearch(userSearch);
-
- authenticatorTimestamp = settingsService.getSettingsChanged();
- }
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java
deleted file mode 100644
index a3b9359e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/ldap/UserDetailsServiceBasedAuthoritiesPopulator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.ldap;
-
-import org.acegisecurity.GrantedAuthority;
-import org.acegisecurity.ldap.LdapDataAccessException;
-import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator;
-import org.acegisecurity.userdetails.UserDetailsService;
-import org.acegisecurity.userdetails.UserDetails;
-import org.acegisecurity.userdetails.ldap.LdapUserDetails;
-
-/**
- * An {@link LdapAuthoritiesPopulator} that retrieves the roles from the
- * database using the {@link UserDetailsService} instead of retrieving the roles
- * from LDAP. An instance of this class can be configured for the
- * {@link org.acegisecurity.providers.ldap.LdapAuthenticationProvider} when
- * authentication should be done using LDAP and authorization using the
- * information stored in the database.
- *
- * @author Thomas M. Hofmann
- */
-public class UserDetailsServiceBasedAuthoritiesPopulator implements LdapAuthoritiesPopulator {
-
- private UserDetailsService userDetailsService;
-
- public GrantedAuthority[] getGrantedAuthorities(LdapUserDetails userDetails) throws LdapDataAccessException {
- UserDetails details = userDetailsService.loadUserByUsername(userDetails.getUsername());
- return details.getAuthorities();
- }
-
- public void setUserDetailsService(UserDetailsService userDetailsService) {
- this.userDetailsService = userDetailsService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/security/RESTRequestParameterProcessingFilter.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/security/RESTRequestParameterProcessingFilter.java
deleted file mode 100644
index add44643..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/security/RESTRequestParameterProcessingFilter.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.security;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.service.SettingsService;
-import net.sourceforge.subsonic.domain.Version;
-import net.sourceforge.subsonic.controller.RESTController;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.XMLBuilder;
-import org.acegisecurity.Authentication;
-import org.acegisecurity.AuthenticationException;
-import org.acegisecurity.context.SecurityContextHolder;
-import org.acegisecurity.providers.ProviderManager;
-import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.web.bind.ServletRequestUtils;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Performs authentication based on credentials being present in the HTTP request parameters. Also checks
- * API versions and license information.
- * <p/>
- * The username should be set in parameter "u", and the password should be set in parameter "p".
- * The REST protocol version should be set in parameter "v".
- *
- * The password can either be in plain text or be UTF-8 hexencoded preceded by "enc:".
- *
- * @author Sindre Mehus
- */
-public class RESTRequestParameterProcessingFilter implements Filter {
-
- private static final Logger LOG = Logger.getLogger(RESTRequestParameterProcessingFilter.class);
- private static final long TRIAL_DAYS = 35L;
-
- private ProviderManager authenticationManager;
- private SettingsService settingsService;
-
- /**
- * {@inheritDoc}
- */
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- if (!(request instanceof HttpServletRequest)) {
- throw new ServletException("Can only process HttpServletRequest");
- }
- if (!(response instanceof HttpServletResponse)) {
- throw new ServletException("Can only process HttpServletResponse");
- }
-
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
-
- String username = StringUtils.trimToNull(httpRequest.getParameter("u"));
- String password = decrypt(StringUtils.trimToNull(httpRequest.getParameter("p")));
- String version = StringUtils.trimToNull(httpRequest.getParameter("v"));
- String client = StringUtils.trimToNull(httpRequest.getParameter("c"));
-
- RESTController.ErrorCode errorCode = null;
-
- // The username and password parameters are not required if the user
- // was previously authenticated, for example using Basic Auth.
- Authentication previousAuth = SecurityContextHolder.getContext().getAuthentication();
- boolean missingCredentials = previousAuth == null && (username == null || password == null);
- if (missingCredentials || version == null || client == null) {
- errorCode = RESTController.ErrorCode.MISSING_PARAMETER;
- }
-
- if (errorCode == null) {
- errorCode = checkAPIVersion(version);
- }
-
- if (errorCode == null) {
- errorCode = authenticate(username, password, previousAuth);
- }
-
- if (errorCode == null) {
- String restMethod = StringUtils.substringAfterLast(httpRequest.getRequestURI(), "/");
- errorCode = checkLicense(client, restMethod);
- }
-
- if (errorCode == null) {
- chain.doFilter(request, response);
- } else {
- SecurityContextHolder.getContext().setAuthentication(null);
- sendErrorXml(httpRequest, httpResponse, errorCode);
- }
- }
-
- private RESTController.ErrorCode checkAPIVersion(String version) {
- Version serverVersion = new Version(StringUtil.getRESTProtocolVersion());
- Version clientVersion = new Version(version);
-
- if (serverVersion.getMajor() > clientVersion.getMajor()) {
- return RESTController.ErrorCode.PROTOCOL_MISMATCH_CLIENT_TOO_OLD;
- } else if (serverVersion.getMajor() < clientVersion.getMajor()) {
- return RESTController.ErrorCode.PROTOCOL_MISMATCH_SERVER_TOO_OLD;
- } else if (serverVersion.getMinor() < clientVersion.getMinor()) {
- return RESTController.ErrorCode.PROTOCOL_MISMATCH_SERVER_TOO_OLD;
- }
- return null;
- }
-
- private RESTController.ErrorCode authenticate(String username, String password, Authentication previousAuth) {
-
- // Previously authenticated and username not overridden?
- if (username == null && previousAuth != null) {
- return null;
- }
-
- // Ensure password is given.
- if (password == null) {
- return RESTController.ErrorCode.MISSING_PARAMETER;
- }
-
- try {
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
- Authentication authResult = authenticationManager.authenticate(authRequest);
- SecurityContextHolder.getContext().setAuthentication(authResult);
-// LOG.info("Authentication succeeded for user " + username);
- } catch (AuthenticationException x) {
- LOG.info("Authentication failed for user " + username);
- return RESTController.ErrorCode.NOT_AUTHENTICATED;
- }
- return null;
- }
-
- private RESTController.ErrorCode checkLicense(String client, String restMethod) {
- if (settingsService.isLicenseValid()) {
- return null;
- }
-
- if (settingsService.getRESTTrialExpires(client) == null) {
- Date expiryDate = new Date(System.currentTimeMillis() + TRIAL_DAYS * 24L * 3600L * 1000L);
- settingsService.setRESTTrialExpires(client, expiryDate);
- settingsService.save();
- LOG.info("REST access for client '" + client + "' will expire " + expiryDate);
- } else if (settingsService.getRESTTrialExpires(client).before(new Date())) {
-
- // Exception: iPhone clients are allowed to call any method except stream.view and download.view.
- List<String> iPhoneClients = Arrays.asList("iSub", "zsubsonic");
- List<String> restrictedMethods = Arrays.asList("stream.view", "download.view");
- if (iPhoneClients.contains(client) && !restrictedMethods.contains(restMethod)) {
- return null;
- }
-
- LOG.info("REST access for client '" + client + "' has expired.");
- return RESTController.ErrorCode.NOT_LICENSED;
- }
-
- return null;
- }
-
- public static String decrypt(String s) {
- if (s == null) {
- return null;
- }
- if (!s.startsWith("enc:")) {
- return s;
- }
- try {
- return StringUtil.utf8HexDecode(s.substring(4));
- } catch (Exception e) {
- return s;
- }
- }
-
- private void sendErrorXml(HttpServletRequest request, HttpServletResponse response, RESTController.ErrorCode errorCode) throws IOException {
- String format = ServletRequestUtils.getStringParameter(request, "f", "xml");
- boolean json = "json".equals(format);
- boolean jsonp = "jsonp".equals(format);
- XMLBuilder builder;
-
- response.setCharacterEncoding(StringUtil.ENCODING_UTF8);
-
- if (json) {
- builder = XMLBuilder.createJSONBuilder();
- response.setContentType("application/json");
- } else if (jsonp) {
- builder = XMLBuilder.createJSONPBuilder(request.getParameter("callback"));
- response.setContentType("text/javascript");
- } else {
- builder = XMLBuilder.createXMLBuilder();
- response.setContentType("text/xml");
- }
-
- builder.preamble(StringUtil.ENCODING_UTF8);
- builder.add("subsonic-response", false,
- new XMLBuilder.Attribute("xmlns", "http://subsonic.org/restapi"),
- new XMLBuilder.Attribute("status", "failed"),
- new XMLBuilder.Attribute("version", StringUtil.getRESTProtocolVersion()));
-
- builder.add("error", true,
- new XMLBuilder.Attribute("code", errorCode.getCode()),
- new XMLBuilder.Attribute("message", errorCode.getMessage()));
- builder.end();
- response.getWriter().print(builder);
- }
-
- /**
- * {@inheritDoc}
- */
- public void init(FilterConfig filterConfig) throws ServletException {
- }
-
- /**
- * {@inheritDoc}
- */
- public void destroy() {
- }
-
- public void setAuthenticationManager(ProviderManager authenticationManager) {
- this.authenticationManager = authenticationManager;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/AdService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/AdService.java
deleted file mode 100644
index 9ae4d765..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/AdService.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-/**
- * Provides services for generating ads.
- *
- * @author Sindre Mehus
- */
-public class AdService {
-
- private final String[] ads = {
-
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=40&l=ur1&category=computers_accesories&banner=1CH7VNNWF908JYQPHX82&f=ifr' width='120' height='60' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=21&l=ur1&category=game_downloads&banner=13PTQH69Q2290VF8SR82&f=ifr' width='125' height='125' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='ad/omakasa.html' width='120' height='240' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=29&l=ur1&category=homeaudiohometheater&banner=0T4YJ6YBNCMJM9GGAK02&f=ifr' width='120' height='600' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=21&l=ur1&category=50mp3albums5each&banner=19QT8FZHDHFZDN87C482&f=ifr' width='125' height='125' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=21&l=ur1&category=computers_accesories&banner=0Q1FJ9TBD13SA09DSMR2&f=ifr' width='125' height='125' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=40&l=ur1&category=mp3&banner=0TBQHNYNA4B47J02NFG2&f=ifr' width='120' height='60' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab' id='Player_3d36fdd7-b2fa-4dfd-b517-c5efe035a14d' WIDTH='120px' HEIGHT='500px'> <PARAM NAME='movie' VALUE='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8010%2F3d36fdd7-b2fa-4dfd-b517-c5efe035a14d&Operation=GetDisplayTemplate'><PARAM NAME='quality' VALUE='high'><PARAM NAME='bgcolor' VALUE='#FFFFFF'><PARAM NAME='allowscriptaccess' VALUE='always'><embed src='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8010%2F3d36fdd7-b2fa-4dfd-b517-c5efe035a14d&Operation=GetDisplayTemplate' id='Player_3d36fdd7-b2fa-4dfd-b517-c5efe035a14d' quality='high' bgcolor='#ffffff' name='Player_3d36fdd7-b2fa-4dfd-b517-c5efe035a14d' allowscriptaccess='always' type='application/x-shockwave-flash' align='middle' height='500px' width='120px'/> </OBJECT> <NOSCRIPT><A HREF='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8010%2F3d36fdd7-b2fa-4dfd-b517-c5efe035a14d&Operation=NoScript'>Amazon.com Widgets</A></NOSCRIPT>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=40&l=ur1&category=kindle&banner=19NTJJCKSX6TY1C567G2&f=ifr' width='120' height='60' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='ad/omakasa.html' width='120' height='240' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=14&l=ur1&category=electronicsrot&f=ifr' width='160' height='600' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab' id='Player_3fde1609-804d-46de-8802-2a16321cf533' WIDTH='160px' HEIGHT='400px'> <PARAM NAME='movie' VALUE='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8009%2F3fde1609-804d-46de-8802-2a16321cf533&Operation=GetDisplayTemplate'><PARAM NAME='quality' VALUE='high'><PARAM NAME='bgcolor' VALUE='#FFFFFF'><PARAM NAME='allowscriptaccess' VALUE='always'><embed src='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8009%2F3fde1609-804d-46de-8802-2a16321cf533&Operation=GetDisplayTemplate' id='Player_3fde1609-804d-46de-8802-2a16321cf533' quality='high' bgcolor='#ffffff' name='Player_3fde1609-804d-46de-8802-2a16321cf533' allowscriptaccess='always' type='application/x-shockwave-flash' align='middle' height='400px' width='160px'/> </OBJECT> <NOSCRIPT><A HREF='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8009%2F3fde1609-804d-46de-8802-2a16321cf533&Operation=NoScript'>Amazon.com Widgets</A></NOSCRIPT>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=40&l=ur1&category=unboxdigital&banner=10NVPFMW8ACPNX4T4E82&f=ifr' width='120' height='60' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<OBJECT classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab' id='Player_2e2141ca-ec13-4dc9-88f2-08be95e47e6d' WIDTH='160px' HEIGHT='300px'> <PARAM NAME='movie' VALUE='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8014%2F2e2141ca-ec13-4dc9-88f2-08be95e47e6d&Operation=GetDisplayTemplate'><PARAM NAME='quality' VALUE='high'><PARAM NAME='bgcolor' VALUE='#FFFFFF'><PARAM NAME='allowscriptaccess' VALUE='always'><embed src='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8014%2F2e2141ca-ec13-4dc9-88f2-08be95e47e6d&Operation=GetDisplayTemplate' id='Player_2e2141ca-ec13-4dc9-88f2-08be95e47e6d' quality='high' bgcolor='#ffffff' name='Player_2e2141ca-ec13-4dc9-88f2-08be95e47e6d' allowscriptaccess='always' type='application/x-shockwave-flash' align='middle' height='300px' width='160px'></embed></OBJECT> <NOSCRIPT><A HREF='http://ws.amazon.com/widgets/q?ServiceVersion=20070822&MarketPlace=US&ID=V20070822%2FUS%2Fsubsonic-20%2F8014%2F2e2141ca-ec13-4dc9-88f2-08be95e47e6d&Operation=NoScript'>Amazon.com Widgets</A></NOSCRIPT>",
- "<iframe src='http://rcm.amazon.com/e/cm?t=subsonic-20&o=1&p=14&l=ur1&category=musicandentertainmentrot&f=ifr' width='160' height='600' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://www.subsonic.org/pages/subsonic-ad.jsp' width='180' height='400' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>",
- "<iframe src='http://www.subsonic.org/pages/zazeen-ad.jsp' width='120' height='600' scrolling='no' border='0' marginwidth='0' style='border:none;' frameborder='0'></iframe>"
- };
- private int adInterval;
- private int pageCount;
- private int adIndex;
-
- /**
- * Returns an ad or <code>null</code> if no ad should be displayed.
- */
- public String getAd() {
- if (pageCount++ % adInterval == 0) {
-
- adIndex = (adIndex + 1) % ads.length;
- return ads[adIndex];
- }
-
- return null;
- }
-
- /**
- * Set by Spring.
- */
- public void setAdInterval(int adInterval) {
- this.adInterval = adInterval;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/AudioScrobblerService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/AudioScrobblerService.java
deleted file mode 100644
index 9ca402b8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/AudioScrobblerService.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.impl.client.BasicResponseHandler;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.params.HttpConnectionParams;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Provides services for "audioscrobbling", which is the process of
- * registering what songs are played at www.last.fm.
- * <p/>
- * See http://www.last.fm/api/submissions
- *
- * @author Sindre Mehus
- */
-public class AudioScrobblerService {
-
- private static final Logger LOG = Logger.getLogger(AudioScrobblerService.class);
- private static final int MAX_PENDING_REGISTRATION = 2000;
- private static final long MIN_REGISTRATION_INTERVAL = 30000L;
-
- private RegistrationThread thread;
- private final Map<String, Long> lastRegistrationTimes = new HashMap<String, Long>();
- private final LinkedBlockingQueue<RegistrationData> queue = new LinkedBlockingQueue<RegistrationData>();
-
- private SettingsService settingsService;
-
- /**
- * Registers the given media file at www.last.fm. This method returns immediately, the actual registration is done
- * by a separate thread.
- *
- * @param mediaFile The media file to register.
- * @param username The user which played the music file.
- * @param submission Whether this is a submission or a now playing notification.
- */
- public synchronized void register(MediaFile mediaFile, String username, boolean submission) {
-
- if (thread == null) {
- thread = new RegistrationThread();
- thread.start();
- }
-
- if (queue.size() >= MAX_PENDING_REGISTRATION) {
- LOG.warn("Last.fm scrobbler queue is full. Ignoring " + mediaFile);
- return;
- }
-
- RegistrationData registrationData = createRegistrationData(mediaFile, username, submission);
- if (registrationData == null) {
- return;
- }
-
- try {
- queue.put(registrationData);
- } catch (InterruptedException x) {
- LOG.warn("Interrupted while queuing Last.fm scrobble.", x);
- }
- }
-
- /**
- * Returns registration details, or <code>null</code> if not eligible for registration.
- */
- private RegistrationData createRegistrationData(MediaFile mediaFile, String username, boolean submission) {
-
- if (mediaFile == null || mediaFile.isVideo()) {
- return null;
- }
-
- UserSettings userSettings = settingsService.getUserSettings(username);
- if (!userSettings.isLastFmEnabled() || userSettings.getLastFmUsername() == null || userSettings.getLastFmPassword() == null) {
- return null;
- }
-
- long now = System.currentTimeMillis();
-
- // Don't register submissions more often than every 30 seconds.
- if (submission) {
- Long lastRegistrationTime = lastRegistrationTimes.get(username);
- if (lastRegistrationTime != null && now - lastRegistrationTime < MIN_REGISTRATION_INTERVAL) {
- return null;
- }
- lastRegistrationTimes.put(username, now);
- }
-
- RegistrationData reg = new RegistrationData();
- reg.username = userSettings.getLastFmUsername();
- reg.password = userSettings.getLastFmPassword();
- reg.artist = mediaFile.getArtist();
- reg.album = mediaFile.getAlbumName();
- reg.title = mediaFile.getTitle();
- reg.duration = mediaFile.getDurationSeconds() == null ? 0 : mediaFile.getDurationSeconds();
- reg.time = new Date(now);
- reg.submission = submission;
-
- return reg;
- }
-
- /**
- * Scrobbles the given song data at last.fm, using the protocol defined at http://www.last.fm/api/submissions.
- *
- * @param registrationData Registration data for the song.
- */
- private void scrobble(RegistrationData registrationData) throws Exception {
- if (registrationData == null) {
- return;
- }
-
- String[] lines = authenticate(registrationData);
- if (lines == null) {
- return;
- }
-
- String sessionId = lines[1];
- String nowPlayingUrl = lines[2];
- String submissionUrl = lines[3];
-
- if (registrationData.submission) {
- lines = registerSubmission(registrationData, sessionId, submissionUrl);
- } else {
- lines = registerNowPlaying(registrationData, sessionId, nowPlayingUrl);
- }
-
- if (lines[0].startsWith("FAILED")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm: " + lines[0]);
- } else if (lines[0].startsWith("BADSESSION")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm. Invalid session.");
- } else if (lines[0].startsWith("OK")) {
- LOG.debug("Successfully registered " + (registrationData.submission ? "submission" : "now playing") +
- " for song '" + registrationData.title + "' for user " + registrationData.username + " at Last.fm.");
- }
- }
-
- /**
- * Returns the following lines if authentication succeeds:
- * <p/>
- * Line 0: Always "OK"
- * Line 1: Session ID, e.g., "17E61E13454CDD8B68E8D7DEEEDF6170"
- * Line 2: URL to use for now playing, e.g., "http://post.audioscrobbler.com:80/np_1.2"
- * Line 3: URL to use for submissions, e.g., "http://post2.audioscrobbler.com:80/protocol_1.2"
- * <p/>
- * If authentication fails, <code>null</code> is returned.
- */
- private String[] authenticate(RegistrationData registrationData) throws Exception {
- String clientId = "sub";
- String clientVersion = "0.1";
- long timestamp = System.currentTimeMillis() / 1000L;
- String authToken = calculateAuthenticationToken(registrationData.password, timestamp);
- String[] lines = executeGetRequest("http://post.audioscrobbler.com/?hs=true&p=1.2.1&c=" + clientId + "&v=" +
- clientVersion + "&u=" + registrationData.username + "&t=" + timestamp + "&a=" + authToken);
-
- if (lines[0].startsWith("BANNED")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm. Client version is banned.");
- return null;
- }
-
- if (lines[0].startsWith("BADAUTH")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm. Wrong username or password.");
- return null;
- }
-
- if (lines[0].startsWith("BADTIME")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm. Bad timestamp, please check local clock.");
- return null;
- }
-
- if (lines[0].startsWith("FAILED")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm: " + lines[0]);
- return null;
- }
-
- if (!lines[0].startsWith("OK")) {
- LOG.warn("Failed to scrobble song '" + registrationData.title + "' at Last.fm. Unknown response: " + lines[0]);
- return null;
- }
-
- return lines;
- }
-
- private String[] registerSubmission(RegistrationData registrationData, String sessionId, String url) throws IOException {
- Map<String, String> params = new HashMap<String, String>();
- params.put("s", sessionId);
- params.put("a[0]", registrationData.artist);
- params.put("t[0]", registrationData.title);
- params.put("i[0]", String.valueOf(registrationData.time.getTime() / 1000L));
- params.put("o[0]", "P");
- params.put("r[0]", "");
- params.put("l[0]", String.valueOf(registrationData.duration));
- params.put("b[0]", registrationData.album);
- params.put("n[0]", "");
- params.put("m[0]", "");
- return executePostRequest(url, params);
- }
-
- private String[] registerNowPlaying(RegistrationData registrationData, String sessionId, String url) throws IOException {
- Map<String, String> params = new HashMap<String, String>();
- params.put("s", sessionId);
- params.put("a", registrationData.artist);
- params.put("t", registrationData.title);
- params.put("b", registrationData.album);
- params.put("l", String.valueOf(registrationData.duration));
- params.put("n", "");
- params.put("m", "");
- return executePostRequest(url, params);
- }
-
- private String calculateAuthenticationToken(String password, long timestamp) {
- return DigestUtils.md5Hex(DigestUtils.md5Hex(password) + timestamp);
- }
-
- private String[] executeGetRequest(String url) throws IOException {
- return executeRequest(new HttpGet(url));
- }
-
- private String[] executePostRequest(String url, Map<String, String> parameters) throws IOException {
- List<NameValuePair> params = new ArrayList<NameValuePair>();
- for (Map.Entry<String, String> entry : parameters.entrySet()) {
- params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
- }
-
- HttpPost request = new HttpPost(url);
- request.setEntity(new UrlEncodedFormEntity(params, StringUtil.ENCODING_UTF8));
-
- return executeRequest(request);
- }
-
- private String[] executeRequest(HttpUriRequest request) throws IOException {
- HttpClient client = new DefaultHttpClient();
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
- HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
-
- try {
- ResponseHandler<String> responseHandler = new BasicResponseHandler();
- String response = client.execute(request, responseHandler);
- return response.split("\\n");
-
- } finally {
- client.getConnectionManager().shutdown();
- }
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- private class RegistrationThread extends Thread {
- private RegistrationThread() {
- super("AudioScrobbler Registration");
- }
-
- @Override
- public void run() {
- while (true) {
- RegistrationData registrationData = null;
- try {
- registrationData = queue.take();
- scrobble(registrationData);
- } catch (IOException x) {
- handleNetworkError(registrationData, x);
- } catch (Exception x) {
- LOG.warn("Error in Last.fm registration.", x);
- }
- }
- }
-
- private void handleNetworkError(RegistrationData registrationData, IOException x) {
- try {
- queue.put(registrationData);
- LOG.info("Last.fm registration for " + registrationData.title +
- " encountered network error. Will try again later. In queue: " + queue.size(), x);
- } catch (InterruptedException e) {
- LOG.error("Failed to reschedule Last.fm registration for " + registrationData.title, e);
- }
- try {
- sleep(15L * 60L * 1000L); // Wait 15 minutes.
- } catch (InterruptedException e) {
- LOG.error("Failed to sleep after Last.fm registration failure for " + registrationData.title, e);
- }
- }
- }
-
- private static class RegistrationData {
- private String username;
- private String password;
- private String artist;
- private String album;
- private String title;
- private int duration;
- private Date time;
- public boolean submission;
- }
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/JukeboxService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/JukeboxService.java
deleted file mode 100644
index 9f2eff22..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/JukeboxService.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.PlayQueue;
-import net.sourceforge.subsonic.domain.Transcoding;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.domain.VideoTranscodingSettings;
-import net.sourceforge.subsonic.service.jukebox.AudioPlayer;
-import net.sourceforge.subsonic.util.FileUtil;
-import org.apache.commons.io.IOUtils;
-
-import java.io.InputStream;
-
-import static net.sourceforge.subsonic.service.jukebox.AudioPlayer.State.EOM;
-
-/**
- * Plays music on the local audio device.
- *
- * @author Sindre Mehus
- */
-public class JukeboxService implements AudioPlayer.Listener {
-
- private static final Logger LOG = Logger.getLogger(JukeboxService.class);
-
- private AudioPlayer audioPlayer;
- private TranscodingService transcodingService;
- private AudioScrobblerService audioScrobblerService;
- private StatusService statusService;
- private SettingsService settingsService;
- private SecurityService securityService;
-
- private Player player;
- private TransferStatus status;
- private MediaFile currentPlayingFile;
- private float gain = 0.5f;
- private int offset;
- private MediaFileService mediaFileService;
-
- /**
- * Updates the jukebox by starting or pausing playback on the local audio device.
- *
- * @param player The player in question.
- * @param offset Start playing after this many seconds into the track.
- */
- public synchronized void updateJukebox(Player player, int offset) throws Exception {
- User user = securityService.getUserByName(player.getUsername());
- if (!user.isJukeboxRole()) {
- LOG.warn(user.getUsername() + " is not authorized for jukebox playback.");
- return;
- }
-
- if (player.getPlayQueue().getStatus() == PlayQueue.Status.PLAYING) {
- this.player = player;
- MediaFile result;
- synchronized (player.getPlayQueue()) {
- result = player.getPlayQueue().getCurrentFile();
- }
- play(result, offset);
- } else {
- if (audioPlayer != null) {
- audioPlayer.pause();
- }
- }
- }
-
- private synchronized void play(MediaFile file, int offset) {
- InputStream in = null;
- try {
-
- // Resume if possible.
- boolean sameFile = file != null && file.equals(currentPlayingFile);
- boolean paused = audioPlayer != null && audioPlayer.getState() == AudioPlayer.State.PAUSED;
- if (sameFile && paused && offset == 0) {
- audioPlayer.play();
- } else {
- this.offset = offset;
- if (audioPlayer != null) {
- audioPlayer.close();
- if (currentPlayingFile != null) {
- onSongEnd(currentPlayingFile);
- }
- }
-
- if (file != null) {
- TranscodingService.Parameters parameters = new TranscodingService.Parameters(file, new VideoTranscodingSettings(0, 0, offset));
- String command = settingsService.getJukeboxCommand();
- parameters.setTranscoding(new Transcoding(null, null, null, null, command, null, null, false));
- in = transcodingService.getTranscodedInputStream(parameters);
- audioPlayer = new AudioPlayer(in, this);
- audioPlayer.setGain(gain);
- audioPlayer.play();
- onSongStart(file);
- }
- }
-
- currentPlayingFile = file;
-
- } catch (Exception x) {
- LOG.error("Error in jukebox: " + x, x);
- IOUtils.closeQuietly(in);
- }
- }
-
- public synchronized void stateChanged(AudioPlayer audioPlayer, AudioPlayer.State state) {
- if (state == EOM) {
- player.getPlayQueue().next();
- MediaFile result;
- synchronized (player.getPlayQueue()) {
- result = player.getPlayQueue().getCurrentFile();
- }
- play(result, 0);
- }
- }
-
- public synchronized float getGain() {
- return gain;
- }
-
- public synchronized int getPosition() {
- return audioPlayer == null ? 0 : offset + audioPlayer.getPosition();
- }
-
- /**
- * Returns the player which currently uses the jukebox.
- *
- * @return The player, may be {@code null}.
- */
- public Player getPlayer() {
- return player;
- }
-
- private void onSongStart(MediaFile file) {
- LOG.info(player.getUsername() + " starting jukebox for \"" + FileUtil.getShortPath(file.getFile()) + "\"");
- status = statusService.createStreamStatus(player);
- status.setFile(file.getFile());
- status.addBytesTransfered(file.getFileSize());
- mediaFileService.incrementPlayCount(file);
- scrobble(file, false);
- }
-
- private void onSongEnd(MediaFile file) {
- LOG.info(player.getUsername() + " stopping jukebox for \"" + FileUtil.getShortPath(file.getFile()) + "\"");
- if (status != null) {
- statusService.removeStreamStatus(status);
- }
- scrobble(file, true);
- }
-
- private void scrobble(MediaFile file, boolean submission) {
- if (player.getClientId() == null) { // Don't scrobble REST players.
- audioScrobblerService.register(file, player.getUsername(), submission);
- }
- }
-
- public synchronized void setGain(float gain) {
- this.gain = gain;
- if (audioPlayer != null) {
- audioPlayer.setGain(gain);
- }
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-
- public void setAudioScrobblerService(AudioScrobblerService audioScrobblerService) {
- this.audioScrobblerService = audioScrobblerService;
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaFileService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaFileService.java
deleted file mode 100644
index bc575714..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaFileService.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sf.ehcache.Ehcache;
-import net.sf.ehcache.Element;
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.AlbumDao;
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.Album;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MediaFileComparator;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.service.metadata.JaudiotaggerParser;
-import net.sourceforge.subsonic.service.metadata.MetaData;
-import net.sourceforge.subsonic.service.metadata.MetaDataParser;
-import net.sourceforge.subsonic.service.metadata.MetaDataParserFactory;
-import net.sourceforge.subsonic.util.FileUtil;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import static net.sourceforge.subsonic.domain.MediaFile.MediaType.*;
-
-/**
- * Provides services for instantiating and caching media files and cover art.
- *
- * @author Sindre Mehus
- */
-public class MediaFileService {
-
- private static final Logger LOG = Logger.getLogger(MediaFileService.class);
-
- private Ehcache mediaFileMemoryCache;
-
- private SecurityService securityService;
- private SettingsService settingsService;
- private MediaFileDao mediaFileDao;
- private AlbumDao albumDao;
- private MetaDataParserFactory metaDataParserFactory;
-
- /**
- * Returns a media file instance for the given file. If possible, a cached value is returned.
- *
- * @param file A file on the local file system.
- * @return A media file instance, or null if not found.
- * @throws SecurityException If access is denied to the given file.
- */
- public MediaFile getMediaFile(File file) {
- return getMediaFile(file, settingsService.isFastCacheEnabled());
- }
-
- /**
- * Returns a media file instance for the given file. If possible, a cached value is returned.
- *
- * @param file A file on the local file system.
- * @return A media file instance, or null if not found.
- * @throws SecurityException If access is denied to the given file.
- */
- public MediaFile getMediaFile(File file, boolean useFastCache) {
-
- // Look in fast memory cache first.
- Element element = mediaFileMemoryCache.get(file);
- MediaFile result = element == null ? null : (MediaFile) element.getObjectValue();
- if (result != null) {
- return result;
- }
-
- if (!securityService.isReadAllowed(file)) {
- throw new SecurityException("Access denied to file " + file);
- }
-
- // Secondly, look in database.
- result = mediaFileDao.getMediaFile(file.getPath());
- if (result != null) {
- result = checkLastModified(result, useFastCache);
- mediaFileMemoryCache.put(new Element(file, result));
- return result;
- }
-
- if (!FileUtil.exists(file)) {
- return null;
- }
- // Not found in database, must read from disk.
- result = createMediaFile(file);
-
- // Put in cache and database.
- mediaFileMemoryCache.put(new Element(file, result));
- mediaFileDao.createOrUpdateMediaFile(result);
-
- return result;
- }
-
- private MediaFile checkLastModified(MediaFile mediaFile, boolean useFastCache) {
- if (useFastCache || mediaFile.getChanged().getTime() >= FileUtil.lastModified(mediaFile.getFile())) {
- return mediaFile;
- }
- mediaFile = createMediaFile(mediaFile.getFile());
- mediaFileDao.createOrUpdateMediaFile(mediaFile);
- return mediaFile;
- }
-
- /**
- * Returns a media file instance for the given path name. If possible, a cached value is returned.
- *
- * @param pathName A path name for a file on the local file system.
- * @return A media file instance.
- * @throws SecurityException If access is denied to the given file.
- */
- public MediaFile getMediaFile(String pathName) {
- return getMediaFile(new File(pathName));
- }
-
- // TODO: Optimize with memory caching.
- public MediaFile getMediaFile(int id) {
- MediaFile mediaFile = mediaFileDao.getMediaFile(id);
- if (mediaFile == null) {
- return null;
- }
-
- if (!securityService.isReadAllowed(mediaFile.getFile())) {
- throw new SecurityException("Access denied to file " + mediaFile);
- }
-
- return checkLastModified(mediaFile, settingsService.isFastCacheEnabled());
- }
-
- public MediaFile getParentOf(MediaFile mediaFile) {
- if (mediaFile.getParentPath() == null) {
- return null;
- }
- return getMediaFile(mediaFile.getParentPath());
- }
-
- public List<MediaFile> getChildrenOf(String parentPath, boolean includeFiles, boolean includeDirectories, boolean sort) {
- return getChildrenOf(new File(parentPath), includeFiles, includeDirectories, sort);
- }
-
- public List<MediaFile> getChildrenOf(File parent, boolean includeFiles, boolean includeDirectories, boolean sort) {
- return getChildrenOf(getMediaFile(parent), includeFiles, includeDirectories, sort);
- }
-
- /**
- * Returns all media files that are children of a given media file.
- *
- * @param includeFiles Whether files should be included in the result.
- * @param includeDirectories Whether directories should be included in the result.
- * @param sort Whether to sort files in the same directory.
- * @return All children media files.
- */
- public List<MediaFile> getChildrenOf(MediaFile parent, boolean includeFiles, boolean includeDirectories, boolean sort) {
- return getChildrenOf(parent, includeFiles, includeDirectories, sort, settingsService.isFastCacheEnabled());
- }
-
- /**
- * Returns all media files that are children of a given media file.
- *
- * @param includeFiles Whether files should be included in the result.
- * @param includeDirectories Whether directories should be included in the result.
- * @param sort Whether to sort files in the same directory.
- * @return All children media files.
- */
- public List<MediaFile> getChildrenOf(MediaFile parent, boolean includeFiles, boolean includeDirectories, boolean sort, boolean useFastCache) {
-
- if (!parent.isDirectory()) {
- return Collections.emptyList();
- }
-
- // Make sure children are stored and up-to-date in the database.
- if (!useFastCache) {
- updateChildren(parent);
- }
-
- List<MediaFile> result = new ArrayList<MediaFile>();
- for (MediaFile child : mediaFileDao.getChildrenOf(parent.getPath())) {
- child = checkLastModified(child, useFastCache);
- if (child.isDirectory() && includeDirectories) {
- result.add(child);
- }
- if (child.isFile() && includeFiles) {
- result.add(child);
- }
- }
-
- if (sort) {
- Comparator<MediaFile> comparator = new MediaFileComparator(settingsService.isSortAlbumsByYear());
- // Note: Intentionally not using Collections.sort() since it can be problematic on Java 7.
- // http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#jdk7
- Set<MediaFile> set = new TreeSet<MediaFile>(comparator);
- set.addAll(result);
- result = new ArrayList<MediaFile>(set);
- }
-
- return result;
- }
-
- /**
- * Returns whether the given file is the root of a media folder.
- *
- * @see MusicFolder
- */
- public boolean isRoot(MediaFile mediaFile) {
- for (MusicFolder musicFolder : settingsService.getAllMusicFolders(false, true)) {
- if (mediaFile.getPath().equals(musicFolder.getPath().getPath())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns all genres in the music collection.
- *
- * @return Sorted list of genres.
- */
- public List<String> getGenres() {
- return mediaFileDao.getGenres();
- }
-
- /**
- * Returns the most frequently played albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most frequently played albums.
- */
- public List<MediaFile> getMostFrequentlyPlayedAlbums(int offset, int count) {
- return mediaFileDao.getMostFrequentlyPlayedAlbums(offset, count);
- }
-
- /**
- * Returns the most recently played albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most recently played albums.
- */
- public List<MediaFile> getMostRecentlyPlayedAlbums(int offset, int count) {
- return mediaFileDao.getMostRecentlyPlayedAlbums(offset, count);
- }
-
- /**
- * Returns the most recently added albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @return The most recently added albums.
- */
- public List<MediaFile> getNewestAlbums(int offset, int count) {
- return mediaFileDao.getNewestAlbums(offset, count);
- }
-
- /**
- * Returns the most recently starred albums.
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @param username Returns albums starred by this user.
- * @return The most recently starred albums for this user.
- */
- public List<MediaFile> getStarredAlbums(int offset, int count, String username) {
- return mediaFileDao.getStarredAlbums(offset, count, username);
- }
-
- /**
- * Returns albums in alphabetial order.
- *
- *
- * @param offset Number of albums to skip.
- * @param count Maximum number of albums to return.
- * @param byArtist Whether to sort by artist name
- * @return Albums in alphabetical order.
- */
- public List<MediaFile> getAlphabetialAlbums(int offset, int count, boolean byArtist) {
- return mediaFileDao.getAlphabetialAlbums(offset, count, byArtist);
- }
-
- public Date getMediaFileStarredDate(int id, String username) {
- return mediaFileDao.getMediaFileStarredDate(id, username);
- }
-
- public void populateStarredDate(List<MediaFile> mediaFiles, String username) {
- for (MediaFile mediaFile : mediaFiles) {
- populateStarredDate(mediaFile, username);
- }
- }
-
- public void populateStarredDate(MediaFile mediaFile, String username) {
- Date starredDate = mediaFileDao.getMediaFileStarredDate(mediaFile.getId(), username);
- mediaFile.setStarredDate(starredDate);
- }
-
- private void updateChildren(MediaFile parent) {
-
- // Check timestamps.
- if (parent.getChildrenLastUpdated().getTime() >= parent.getChanged().getTime()) {
- return;
- }
-
- List<MediaFile> storedChildren = mediaFileDao.getChildrenOf(parent.getPath());
- Map<String, MediaFile> storedChildrenMap = new HashMap<String, MediaFile>();
- for (MediaFile child : storedChildren) {
- storedChildrenMap.put(child.getPath(), child);
- }
-
- List<File> children = filterMediaFiles(FileUtil.listFiles(parent.getFile()));
- for (File child : children) {
- if (storedChildrenMap.remove(child.getPath()) == null) {
- // Add children that are not already stored.
- mediaFileDao.createOrUpdateMediaFile(createMediaFile(child));
- }
- }
-
- // Delete children that no longer exist on disk.
- for (String path : storedChildrenMap.keySet()) {
- mediaFileDao.deleteMediaFile(path);
- }
-
- // Update timestamp in parent.
- parent.setChildrenLastUpdated(parent.getChanged());
- parent.setPresent(true);
- mediaFileDao.createOrUpdateMediaFile(parent);
- }
-
- private List<File> filterMediaFiles(File[] candidates) {
- List<File> result = new ArrayList<File>();
- for (File candidate : candidates) {
- String suffix = FilenameUtils.getExtension(candidate.getName()).toLowerCase();
- if (!isExcluded(candidate) && (FileUtil.isDirectory(candidate) || isAudioFile(suffix) || isVideoFile(suffix))) {
- result.add(candidate);
- }
- }
- return result;
- }
-
- private boolean isAudioFile(String suffix) {
- for (String s : settingsService.getMusicFileTypesAsArray()) {
- if (suffix.equals(s.toLowerCase())) {
- return true;
- }
- }
- return false;
- }
-
- private boolean isVideoFile(String suffix) {
- for (String s : settingsService.getVideoFileTypesAsArray()) {
- if (suffix.equals(s.toLowerCase())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns whether the given file is excluded.
- *
- * @param file The child file in question.
- * @return Whether the child file is excluded.
- */
- private boolean isExcluded(File file) {
-
- // Exclude all hidden files starting with a "." or "@eaDir" (thumbnail dir created on Synology devices).
- String name = file.getName();
- return name.startsWith(".") || name.startsWith("@eaDir") || name.equals("Thumbs.db");
- }
-
- private MediaFile createMediaFile(File file) {
- MediaFile mediaFile = new MediaFile();
- Date lastModified = new Date(FileUtil.lastModified(file));
- mediaFile.setPath(file.getPath());
- mediaFile.setFolder(securityService.getRootFolderForFile(file));
- mediaFile.setParentPath(file.getParent());
- mediaFile.setChanged(lastModified);
- mediaFile.setLastScanned(new Date());
- mediaFile.setPlayCount(0);
- mediaFile.setChildrenLastUpdated(new Date(0));
- mediaFile.setCreated(lastModified);
- mediaFile.setMediaType(DIRECTORY);
- mediaFile.setPresent(true);
-
- if (file.isFile()) {
-
- MetaDataParser parser = metaDataParserFactory.getParser(file);
- if (parser != null) {
- MetaData metaData = parser.getMetaData(file);
- mediaFile.setArtist(metaData.getArtist());
- mediaFile.setAlbumArtist(metaData.getArtist());
- mediaFile.setAlbumName(metaData.getAlbumName());
- mediaFile.setTitle(metaData.getTitle());
- mediaFile.setDiscNumber(metaData.getDiscNumber());
- mediaFile.setTrackNumber(metaData.getTrackNumber());
- mediaFile.setGenre(metaData.getGenre());
- mediaFile.setYear(metaData.getYear());
- mediaFile.setDurationSeconds(metaData.getDurationSeconds());
- mediaFile.setBitRate(metaData.getBitRate());
- mediaFile.setVariableBitRate(metaData.getVariableBitRate());
- mediaFile.setHeight(metaData.getHeight());
- mediaFile.setWidth(metaData.getWidth());
- }
- String format = StringUtils.trimToNull(StringUtils.lowerCase(FilenameUtils.getExtension(mediaFile.getPath())));
- mediaFile.setFormat(format);
- mediaFile.setFileSize(FileUtil.length(file));
- mediaFile.setMediaType(getMediaType(mediaFile));
-
- } else {
-
- // Is this an album?
- if (!isRoot(mediaFile)) {
- File[] children = FileUtil.listFiles(file);
- File firstChild = null;
- for (File child : filterMediaFiles(children)) {
- if (FileUtil.isFile(child)) {
- firstChild = child;
- break;
- }
- }
-
- if (firstChild != null) {
- mediaFile.setMediaType(ALBUM);
-
- // Guess artist/album name and year.
- MetaDataParser parser = metaDataParserFactory.getParser(firstChild);
- if (parser != null) {
- MetaData metaData = parser.getMetaData(firstChild);
- mediaFile.setArtist(metaData.getArtist());
- mediaFile.setAlbumName(metaData.getAlbumName());
- mediaFile.setYear(metaData.getYear());
- }
-
- // Look for cover art.
- try {
- File coverArt = findCoverArt(children);
- if (coverArt != null) {
- mediaFile.setCoverArtPath(coverArt.getPath());
- }
- } catch (IOException x) {
- LOG.error("Failed to find cover art.", x);
- }
-
- } else {
- mediaFile.setArtist(file.getName());
- }
- }
- }
-
- return mediaFile;
- }
-
- private MediaFile.MediaType getMediaType(MediaFile mediaFile) {
- if (isVideoFile(mediaFile.getFormat())) {
- return VIDEO;
- }
- String path = mediaFile.getPath().toLowerCase();
- String genre = StringUtils.trimToEmpty(mediaFile.getGenre()).toLowerCase();
- if (path.contains("podcast") || genre.contains("podcast")) {
- return PODCAST;
- }
- if (path.contains("audiobook") || genre.contains("audiobook") || path.contains("audio book") || genre.contains("audio book")) {
- return AUDIOBOOK;
- }
- return MUSIC;
- }
-
- public void refreshMediaFile(MediaFile mediaFile) {
- mediaFile = createMediaFile(mediaFile.getFile());
- mediaFileDao.createOrUpdateMediaFile(mediaFile);
- mediaFileMemoryCache.remove(mediaFile.getFile());
- }
-
- /**
- * Returns a cover art image for the given media file.
- */
- public File getCoverArt(MediaFile mediaFile) {
- if (mediaFile.getCoverArtFile() != null) {
- return mediaFile.getCoverArtFile();
- }
- MediaFile parent = getParentOf(mediaFile);
- return parent == null ? null : parent.getCoverArtFile();
- }
-
- /**
- * Finds a cover art image for the given directory, by looking for it on the disk.
- */
- private File findCoverArt(File[] candidates) throws IOException {
- for (String mask : settingsService.getCoverArtFileTypesAsArray()) {
- for (File candidate : candidates) {
- if (candidate.isFile() && candidate.getName().toUpperCase().endsWith(mask.toUpperCase()) && !candidate.getName().startsWith(".")) {
- return candidate;
- }
- }
- }
-
- // Look for embedded images in audiofiles. (Only check first audio file encountered).
- JaudiotaggerParser parser = new JaudiotaggerParser();
- for (File candidate : candidates) {
- if (parser.isApplicable(candidate)) {
- if (parser.isImageAvailable(getMediaFile(candidate))) {
- return candidate;
- } else {
- return null;
- }
- }
- }
- return null;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaFileMemoryCache(Ehcache mediaFileMemoryCache) {
- this.mediaFileMemoryCache = mediaFileMemoryCache;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- /**
- * Returns all media files that are children, grand-children etc of a given media file.
- * Directories are not included in the result.
- *
- * @param sort Whether to sort files in the same directory.
- * @return All descendant music files.
- */
- public List<MediaFile> getDescendantsOf(MediaFile ancestor, boolean sort) {
-
- if (ancestor.isFile()) {
- return Arrays.asList(ancestor);
- }
-
- List<MediaFile> result = new ArrayList<MediaFile>();
-
- for (MediaFile child : getChildrenOf(ancestor, true, true, sort)) {
- if (child.isDirectory()) {
- result.addAll(getDescendantsOf(child, sort));
- } else {
- result.add(child);
- }
- }
- return result;
- }
-
- public void setMetaDataParserFactory(MetaDataParserFactory metaDataParserFactory) {
- this.metaDataParserFactory = metaDataParserFactory;
- }
-
- public void updateMediaFile(MediaFile mediaFile) {
- mediaFileDao.createOrUpdateMediaFile(mediaFile);
- }
-
- /**
- * Increments the play count and last played date for the given media file and its
- * directory and album.
- */
- public void incrementPlayCount(MediaFile file) {
- Date now = new Date();
- file.setLastPlayed(now);
- file.setPlayCount(file.getPlayCount() + 1);
- updateMediaFile(file);
-
- MediaFile parent = getParentOf(file);
- if (!isRoot(parent)) {
- parent.setLastPlayed(now);
- parent.setPlayCount(parent.getPlayCount() + 1);
- updateMediaFile(parent);
- }
-
- Album album = albumDao.getAlbum(file.getAlbumArtist(), file.getAlbumName());
- if (album != null) {
- album.setLastPlayed(now);
- album.setPlayCount(album.getPlayCount() + 1);
- albumDao.createOrUpdateAlbum(album);
- }
- }
-
- public void setAlbumDao(AlbumDao albumDao) {
- this.albumDao = albumDao;
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaScannerService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaScannerService.java
deleted file mode 100644
index 84f2d31c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MediaScannerService.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.File;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.AlbumDao;
-import net.sourceforge.subsonic.dao.ArtistDao;
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.Album;
-import net.sourceforge.subsonic.domain.Artist;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MediaLibraryStatistics;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.util.FileUtil;
-import org.apache.commons.lang.ObjectUtils;
-
-/**
- * Provides services for scanning the music library.
- *
- * @author Sindre Mehus
- */
-public class MediaScannerService {
-
- private static final int INDEX_VERSION = 15;
- private static final Logger LOG = Logger.getLogger(MediaScannerService.class);
-
- private MediaLibraryStatistics statistics;
-
- private boolean scanning;
- private Timer timer;
- private SettingsService settingsService;
- private SearchService searchService;
- private MediaFileService mediaFileService;
- private MediaFileDao mediaFileDao;
- private ArtistDao artistDao;
- private AlbumDao albumDao;
- private int scanCount;
-
- public void init() {
- deleteOldIndexFiles();
- statistics = mediaFileDao.getStatistics();
- schedule();
- }
-
- /**
- * Schedule background execution of media library scanning.
- */
- public synchronized void schedule() {
- if (timer != null) {
- timer.cancel();
- }
- timer = new Timer(true);
-
- TimerTask task = new TimerTask() {
- @Override
- public void run() {
- scanLibrary();
- }
- };
-
- long daysBetween = settingsService.getIndexCreationInterval();
- int hour = settingsService.getIndexCreationHour();
-
- if (daysBetween == -1) {
- LOG.info("Automatic media scanning disabled.");
- return;
- }
-
- Date now = new Date();
- Calendar cal = Calendar.getInstance();
- cal.setTime(now);
- cal.set(Calendar.HOUR_OF_DAY, hour);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
-
- if (cal.getTime().before(now)) {
- cal.add(Calendar.DATE, 1);
- }
-
- Date firstTime = cal.getTime();
- long period = daysBetween * 24L * 3600L * 1000L;
- timer.schedule(task, firstTime, period);
-
- LOG.info("Automatic media library scanning scheduled to run every " + daysBetween + " day(s), starting at " + firstTime);
-
- // In addition, create index immediately if it doesn't exist on disk.
- if (settingsService.getLastScanned() == null) {
- LOG.info("Media library never scanned. Doing it now.");
- scanLibrary();
- }
- }
-
- /**
- * Returns whether the media library is currently being scanned.
- */
- public synchronized boolean isScanning() {
- return scanning;
- }
-
- /**
- * Returns the number of files scanned so far.
- */
- public int getScanCount() {
- return scanCount;
- }
-
- /**
- * Scans the media library.
- * The scanning is done asynchronously, i.e., this method returns immediately.
- */
- public synchronized void scanLibrary() {
- if (isScanning()) {
- return;
- }
- scanning = true;
-
- Thread thread = new Thread("MediaLibraryScanner") {
- @Override
- public void run() {
- doScanLibrary();
- }
- };
-
- thread.setPriority(Thread.MIN_PRIORITY);
- thread.start();
- }
-
- private void doScanLibrary() {
- LOG.info("Starting to scan media library.");
-
- try {
- Date lastScanned = new Date();
- Map<String, Integer> albumCount = new HashMap<String, Integer>();
- scanCount = 0;
-
- searchService.startIndexing();
-
- // Recurse through all files on disk.
- for (MusicFolder musicFolder : settingsService.getAllMusicFolders()) {
- MediaFile root = mediaFileService.getMediaFile(musicFolder.getPath(), false);
- scanFile(root, musicFolder, lastScanned, albumCount);
- }
- mediaFileDao.markNonPresent(lastScanned);
- artistDao.markNonPresent(lastScanned);
- albumDao.markNonPresent(lastScanned);
-
- // Update statistics
- statistics = mediaFileDao.getStatistics();
-
- settingsService.setLastScanned(lastScanned);
- settingsService.save(false);
- LOG.info("Scanned media library with " + scanCount + " entries.");
-
- } catch (Throwable x) {
- LOG.error("Failed to scan media library.", x);
- } finally {
- scanning = false;
- searchService.stopIndexing();
- }
- }
-
- private void scanFile(MediaFile file, MusicFolder musicFolder, Date lastScanned, Map<String, Integer> albumCount) {
- scanCount++;
- if (scanCount % 250 == 0) {
- LOG.info("Scanned media library with " + scanCount + " entries.");
- }
-
- searchService.index(file);
-
- // Update the root folder if it has changed.
- if (!musicFolder.getPath().getPath().equals(file.getFolder())) {
- file.setFolder(musicFolder.getPath().getPath());
- mediaFileDao.createOrUpdateMediaFile(file);
- }
-
- if (file.isDirectory()) {
- for (MediaFile child : mediaFileService.getChildrenOf(file, true, false, false, false)) {
- scanFile(child, musicFolder, lastScanned, albumCount);
- }
- for (MediaFile child : mediaFileService.getChildrenOf(file, false, true, false, false)) {
- scanFile(child, musicFolder, lastScanned, albumCount);
- }
- } else {
- updateAlbum(file, lastScanned, albumCount);
- updateArtist(file, lastScanned, albumCount);
- }
-
- mediaFileDao.markPresent(file.getPath(), lastScanned);
- artistDao.markPresent(file.getArtist(), lastScanned);
- }
-
- private void updateAlbum(MediaFile file, Date lastScanned, Map<String, Integer> albumCount) {
- if (file.getAlbumName() == null || file.getArtist() == null || file.getParentPath() == null || !file.isAudio()) {
- return;
- }
-
- Album album = albumDao.getAlbumForFile(file);
- if (album == null) {
- album = new Album();
- album.setPath(file.getParentPath());
- album.setName(file.getAlbumName());
- album.setArtist(file.getArtist());
- album.setCreated(file.getChanged());
- }
- if (album.getCoverArtPath() == null) {
- MediaFile parent = mediaFileService.getParentOf(file);
- if (parent != null) {
- album.setCoverArtPath(parent.getCoverArtPath());
- }
- }
- boolean firstEncounter = !lastScanned.equals(album.getLastScanned());
- if (firstEncounter) {
- album.setDurationSeconds(0);
- album.setSongCount(0);
- Integer n = albumCount.get(file.getArtist());
- albumCount.put(file.getArtist(), n == null ? 1 : n + 1);
- }
- if (file.getDurationSeconds() != null) {
- album.setDurationSeconds(album.getDurationSeconds() + file.getDurationSeconds());
- }
- if (file.isAudio()) {
- album.setSongCount(album.getSongCount() + 1);
- }
-
- album.setLastScanned(lastScanned);
- album.setPresent(true);
- albumDao.createOrUpdateAlbum(album);
- if (firstEncounter) {
- searchService.index(album);
- }
-
- // Update the file's album artist, if necessary.
- if (!ObjectUtils.equals(album.getArtist(), file.getAlbumArtist())) {
- file.setAlbumArtist(album.getArtist());
- mediaFileDao.createOrUpdateMediaFile(file);
- }
- }
-
- private void updateArtist(MediaFile file, Date lastScanned, Map<String, Integer> albumCount) {
- if (file.getArtist() == null || !file.isAudio()) {
- return;
- }
-
- Artist artist = artistDao.getArtist(file.getArtist());
- if (artist == null) {
- artist = new Artist();
- artist.setName(file.getArtist());
- }
- if (artist.getCoverArtPath() == null) {
- MediaFile parent = mediaFileService.getParentOf(file);
- if (parent != null) {
- artist.setCoverArtPath(parent.getCoverArtPath());
- }
- }
- boolean firstEncounter = !lastScanned.equals(artist.getLastScanned());
-
- Integer n = albumCount.get(artist.getName());
- artist.setAlbumCount(n == null ? 0 : n);
-
- artist.setLastScanned(lastScanned);
- artist.setPresent(true);
- artistDao.createOrUpdateArtist(artist);
-
- if (firstEncounter) {
- searchService.index(artist);
- }
- }
-
- /**
- * Returns media library statistics, including the number of artists, albums and songs.
- *
- * @return Media library statistics.
- */
- public MediaLibraryStatistics getStatistics() {
- return statistics;
- }
-
- /**
- * Deletes old versions of the index file.
- */
- private void deleteOldIndexFiles() {
- for (int i = 2; i < INDEX_VERSION; i++) {
- File file = getIndexFile(i);
- try {
- if (FileUtil.exists(file)) {
- if (file.delete()) {
- LOG.info("Deleted old index file: " + file.getPath());
- }
- }
- } catch (Exception x) {
- LOG.warn("Failed to delete old index file: " + file.getPath(), x);
- }
- }
- }
-
- /**
- * Returns the index file for the given index version.
- *
- * @param version The index version.
- * @return The index file for the given index version.
- */
- private File getIndexFile(int version) {
- File home = SettingsService.getSubsonicHome();
- return new File(home, "subsonic" + version + ".index");
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSearchService(SearchService searchService) {
- this.searchService = searchService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- public void setArtistDao(ArtistDao artistDao) {
- this.artistDao = artistDao;
- }
-
- public void setAlbumDao(AlbumDao albumDao) {
- this.albumDao = albumDao;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MusicIndexService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MusicIndexService.java
deleted file mode 100644
index b6ee682e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/MusicIndexService.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.MusicIndex;
-import net.sourceforge.subsonic.domain.MusicIndex.Artist;
-
-/**
- * Provides services for grouping artists by index.
- *
- * @author Sindre Mehus
- */
-public class MusicIndexService {
-
- private SettingsService settingsService;
- private MediaFileService mediaFileService;
- private MediaFileDao mediaFileDao;
-
- /**
- * Returns a map from music indexes to sets of artists that are direct children of the given music folders.
- *
- * @param folders The music folders.
- * @return A map from music indexes to sets of artists that are direct children of this music file.
- * @throws IOException If an I/O error occurs.
- */
- public SortedMap<MusicIndex, SortedSet<Artist>> getIndexedArtists(List<MusicFolder> folders) throws IOException {
-
- String[] ignoredArticles = settingsService.getIgnoredArticlesAsArray();
- String[] shortcuts = settingsService.getShortcutsAsArray();
- final List<MusicIndex> indexes = createIndexesFromExpression(settingsService.getIndexString());
-
- Comparator<MusicIndex> indexComparator = new MusicIndexComparator(indexes);
- SortedSet<Artist> artists = createArtists(folders, ignoredArticles, shortcuts);
- SortedMap<MusicIndex, SortedSet<Artist>> result = new TreeMap<MusicIndex, SortedSet<Artist>>(indexComparator);
-
- for (Artist artist : artists) {
- MusicIndex index = getIndex(artist, indexes);
- SortedSet<Artist> artistSet = result.get(index);
- if (artistSet == null) {
- artistSet = new TreeSet<Artist>();
- result.put(index, artistSet);
- }
- artistSet.add(artist);
- }
-
- return result;
- }
-
- /**
- * Creates a new instance by parsing the given expression. The expression consists of an index name, followed by
- * an optional list of one-character prefixes. For example:<p/>
- * <p/>
- * The expression <em>"A"</em> will create the index <em>"A" -&gt; ["A"]</em><br/>
- * The expression <em>"The"</em> will create the index <em>"The" -&gt; ["The"]</em><br/>
- * The expression <em>"A(A&Aring;&AElig;)"</em> will create the index <em>"A" -&gt; ["A", "&Aring;", "&AElig;"]</em><br/>
- * The expression <em>"X-Z(XYZ)"</em> will create the index <em>"X-Z" -&gt; ["X", "Y", "Z"]</em>
- *
- * @param expr The expression to parse.
- * @return A new instance.
- */
- protected MusicIndex createIndexFromExpression(String expr) {
- int separatorIndex = expr.indexOf('(');
- if (separatorIndex == -1) {
-
- MusicIndex index = new MusicIndex(expr);
- index.addPrefix(expr);
- return index;
- }
-
- MusicIndex index = new MusicIndex(expr.substring(0, separatorIndex));
- String prefixString = expr.substring(separatorIndex + 1, expr.length() - 1);
- for (int i = 0; i < prefixString.length(); i++) {
- index.addPrefix(prefixString.substring(i, i + 1));
- }
- return index;
- }
-
- /**
- * Creates a list of music indexes by parsing the given expression. The expression is a space-separated list of
- * sub-expressions, for which the rules described in {@link #createIndexFromExpression} apply.
- *
- * @param expr The expression to parse.
- * @return A list of music indexes.
- */
- protected List<MusicIndex> createIndexesFromExpression(String expr) {
- List<MusicIndex> result = new ArrayList<MusicIndex>();
-
- StringTokenizer tokenizer = new StringTokenizer(expr, " ");
- while (tokenizer.hasMoreTokens()) {
- MusicIndex index = createIndexFromExpression(tokenizer.nextToken());
- result.add(index);
- }
-
- return result;
- }
-
- private SortedSet<Artist> createArtists(List<MusicFolder> folders, String[] ignoredArticles, String[] shortcuts) throws IOException {
- return settingsService.isOrganizeByFolderStructure() ?
- createArtistsByFolderStructure(folders, ignoredArticles, shortcuts) :
- createArtistsByTagStructure(folders, ignoredArticles, shortcuts);
- }
-
- private SortedSet<Artist> createArtistsByFolderStructure(List<MusicFolder> folders, String[] ignoredArticles, String[] shortcuts) {
- SortedMap<String, Artist> artistMap = new TreeMap<String, Artist>();
- Set<String> shortcutSet = new HashSet<String>(Arrays.asList(shortcuts));
-
- for (MusicFolder folder : folders) {
-
- MediaFile root = mediaFileService.getMediaFile(folder.getPath(), true);
- List<MediaFile> children = mediaFileService.getChildrenOf(root, false, true, true, true);
- for (MediaFile child : children) {
- if (shortcutSet.contains(child.getName())) {
- continue;
- }
-
- String sortableName = createSortableName(child.getName(), ignoredArticles);
- Artist artist = artistMap.get(sortableName);
- if (artist == null) {
- artist = new Artist(child.getName(), sortableName);
- artistMap.put(sortableName, artist);
- }
- artist.addMediaFile(child);
- }
- }
-
- return new TreeSet<Artist>(artistMap.values());
- }
-
- private SortedSet<Artist> createArtistsByTagStructure(List<MusicFolder> folders, String[] ignoredArticles, String[] shortcuts) {
- Set<String> shortcutSet = new HashSet<String>(Arrays.asList(shortcuts));
- SortedSet<Artist> artists = new TreeSet<Artist>();
-
- // TODO: Filter by folder
- for (String artistName : mediaFileDao.getArtists()) {
-
- if (shortcutSet.contains(artistName)) {
- continue;
- }
-
- String sortableName = createSortableName(artistName, ignoredArticles);
- Artist artist = new Artist(artistName, sortableName);
- artists.add(artist);
- }
-
- return artists;
- }
-
- private String createSortableName(String name, String[] ignoredArticles) {
- String uppercaseName = name.toUpperCase();
- for (String article : ignoredArticles) {
- if (uppercaseName.startsWith(article.toUpperCase() + " ")) {
- return name.substring(article.length() + 1) + ", " + article;
- }
- }
- return name;
- }
-
- /**
- * Returns the music index to which the given artist belongs.
- *
- * @param artist The artist in question.
- * @param indexes List of available indexes.
- * @return The music index to which this music file belongs, or {@link MusicIndex#OTHER} if no index applies.
- */
- private MusicIndex getIndex(Artist artist, List<MusicIndex> indexes) {
- String sortableName = artist.getSortableName().toUpperCase();
- for (MusicIndex index : indexes) {
- for (String prefix : index.getPrefixes()) {
- if (sortableName.startsWith(prefix.toUpperCase())) {
- return index;
- }
- }
- }
- return MusicIndex.OTHER;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- private static class MusicIndexComparator implements Comparator<MusicIndex>, Serializable {
-
- private List<MusicIndex> indexes;
-
- public MusicIndexComparator(List<MusicIndex> indexes) {
- this.indexes = indexes;
- }
-
- public int compare(MusicIndex a, MusicIndex b) {
- int indexA = indexes.indexOf(a);
- int indexB = indexes.indexOf(b);
-
- if (indexA == -1) {
- indexA = Integer.MAX_VALUE;
- }
- if (indexB == -1) {
- indexB = Integer.MAX_VALUE;
- }
-
- if (indexA < indexB) {
- return -1;
- }
- if (indexA > indexB) {
- return 1;
- }
- return 0;
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/NetworkService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/NetworkService.java
deleted file mode 100644
index b54026a0..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/NetworkService.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.NameValuePair;
-import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.BasicResponseHandler;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.util.EntityUtils;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.NATPMPRouter;
-import net.sourceforge.subsonic.domain.Router;
-import net.sourceforge.subsonic.domain.SBBIRouter;
-import net.sourceforge.subsonic.domain.WeUPnPRouter;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.Util;
-
-/**
- * Provides network-related services, including port forwarding on UPnP routers and
- * URL redirection from http://xxxx.subsonic.org.
- *
- * @author Sindre Mehus
- */
-public class NetworkService {
-
- private static final Logger LOG = Logger.getLogger(NetworkService.class);
- private static final long PORT_FORWARDING_DELAY = 3600L;
- private static final long URL_REDIRECTION_DELAY = 2 * 3600L;
-
- private static final String URL_REDIRECTION_REGISTER_URL = getBackendUrl() + "/backend/redirect/register.view";
- private static final String URL_REDIRECTION_UNREGISTER_URL = getBackendUrl() + "/backend/redirect/unregister.view";
- private static final String URL_REDIRECTION_TEST_URL = getBackendUrl() + "/backend/redirect/test.view";
-
- private SettingsService settingsService;
- private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
- private final PortForwardingTask portForwardingTask = new PortForwardingTask();
- private final URLRedirectionTask urlRedirectionTask = new URLRedirectionTask();
- private Future<?> portForwardingFuture;
- private Future<?> urlRedirectionFuture;
-
- private final Status portForwardingStatus = new Status();
- private final Status urlRedirectionStatus = new Status();
- private boolean testUrlRedirection;
-
- public void init() {
- initPortForwarding();
- initUrlRedirection(false);
- }
-
- /**
- * Configures UPnP port forwarding.
- */
- public synchronized void initPortForwarding() {
- portForwardingStatus.setText("Idle");
- if (portForwardingFuture != null) {
- portForwardingFuture.cancel(true);
- }
- portForwardingFuture = executor.scheduleWithFixedDelay(portForwardingTask, 0L, PORT_FORWARDING_DELAY, TimeUnit.SECONDS);
- }
-
- /**
- * Configures URL redirection.
- *
- * @param test Whether to test that the redirection works.
- */
- public synchronized void initUrlRedirection(boolean test) {
- urlRedirectionStatus.setText("Idle");
- if (urlRedirectionFuture != null) {
- urlRedirectionFuture.cancel(true);
- }
- testUrlRedirection = test;
- urlRedirectionFuture = executor.scheduleWithFixedDelay(urlRedirectionTask, 0L, URL_REDIRECTION_DELAY, TimeUnit.SECONDS);
- }
-
- public Status getPortForwardingStatus() {
- return portForwardingStatus;
- }
-
- public Status getURLRedirecionStatus() {
- return urlRedirectionStatus;
- }
-
- public static String getBackendUrl() {
- return "true".equals(System.getProperty("subsonic.test")) ? "http://localhost:8181" : "http://subsonic.org";
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- private class PortForwardingTask extends Task {
-
- @Override
- protected void execute() {
-
- boolean enabled = settingsService.isPortForwardingEnabled();
- portForwardingStatus.setText("Looking for router...");
- Router router = findRouter();
- if (router == null) {
- LOG.warn("No UPnP router found.");
- portForwardingStatus.setText("No router found.");
- } else {
-
- portForwardingStatus.setText("Router found.");
-
- int port = settingsService.getPort();
- int httpsPort = settingsService.getHttpsPort();
-
- // Create new NAT entry.
- if (enabled) {
- try {
- router.addPortMapping(port, port, 0);
- String message = "Successfully forwarding port " + port;
-
- if (httpsPort != 0 && httpsPort != port) {
- router.addPortMapping(httpsPort, httpsPort, 0);
- message += " and port " + httpsPort;
- }
- message += ".";
-
- LOG.info(message);
- portForwardingStatus.setText(message);
- } catch (Throwable x) {
- String message = "Failed to create port forwarding.";
- LOG.warn(message, x);
- portForwardingStatus.setText(message + " See log for details.");
- }
- }
-
- // Delete NAT entry.
- else {
- try {
- router.deletePortMapping(port, port);
- LOG.info("Deleted port mapping for port " + port);
- if (httpsPort != 0 && httpsPort != port) {
- router.deletePortMapping(httpsPort, httpsPort);
- LOG.info("Deleted port mapping for port " + httpsPort);
- }
- } catch (Throwable x) {
- LOG.warn("Failed to delete port mapping.", x);
- }
- portForwardingStatus.setText("Port forwarding disabled.");
- }
- }
-
- // Don't do it again if disabled.
- if (!enabled && portForwardingFuture != null) {
- portForwardingFuture.cancel(false);
- }
- }
-
- private Router findRouter() {
- try {
- Router router = SBBIRouter.findRouter();
- if (router != null) {
- return router;
- }
- } catch (Throwable x) {
- LOG.warn("Failed to find UPnP router using SBBI library.", x);
- }
-
- try {
- Router router = WeUPnPRouter.findRouter();
- if (router != null) {
- return router;
- }
- } catch (Throwable x) {
- LOG.warn("Failed to find UPnP router using WeUPnP library.", x);
- }
-
- try {
- Router router = NATPMPRouter.findRouter();
- if (router != null) {
- return router;
- }
- } catch (Throwable x) {
- LOG.warn("Failed to find NAT-PMP router.", x);
- }
-
- return null;
- }
- }
-
- private class URLRedirectionTask extends Task {
-
- @Override
- protected void execute() {
-
- boolean enable = settingsService.isUrlRedirectionEnabled();
- HttpPost request = new HttpPost(enable ? URL_REDIRECTION_REGISTER_URL : URL_REDIRECTION_UNREGISTER_URL);
-
- int port = settingsService.getPort();
- boolean trial = !settingsService.isLicenseValid();
- Date trialExpires = settingsService.getUrlRedirectTrialExpires();
-
- List<NameValuePair> params = new ArrayList<NameValuePair>();
- params.add(new BasicNameValuePair("serverId", settingsService.getServerId()));
- params.add(new BasicNameValuePair("redirectFrom", settingsService.getUrlRedirectFrom()));
- params.add(new BasicNameValuePair("port", String.valueOf(port)));
- params.add(new BasicNameValuePair("localIp", Util.getLocalIpAddress()));
- params.add(new BasicNameValuePair("localPort", String.valueOf(port)));
- params.add(new BasicNameValuePair("contextPath", settingsService.getUrlRedirectContextPath()));
- params.add(new BasicNameValuePair("trial", String.valueOf(trial)));
- if (trial && trialExpires != null) {
- params.add(new BasicNameValuePair("trialExpires", String.valueOf(trialExpires.getTime())));
- } else {
- params.add(new BasicNameValuePair("licenseHolder", settingsService.getLicenseEmail()));
- }
-
- HttpClient client = new DefaultHttpClient();
-
- try {
- urlRedirectionStatus.setText(enable ? "Registering web address..." : "Unregistering web address...");
- request.setEntity(new UrlEncodedFormEntity(params, StringUtil.ENCODING_UTF8));
-
- HttpResponse response = client.execute(request);
- StatusLine status = response.getStatusLine();
-
- switch (status.getStatusCode()) {
- case HttpStatus.SC_BAD_REQUEST:
- urlRedirectionStatus.setText(EntityUtils.toString(response.getEntity()));
- break;
- case HttpStatus.SC_OK:
- urlRedirectionStatus.setText(enable ? "Successfully registered web address." : "Web address disabled.");
- break;
- default:
- throw new IOException(status.getStatusCode() + " " + status.getReasonPhrase());
- }
-
- } catch (Throwable x) {
- LOG.warn(enable ? "Failed to register web address." : "Failed to unregister web address.", x);
- urlRedirectionStatus.setText(enable ? ("Failed to register web address. " + x.getMessage() +
- " (" + x.getClass().getSimpleName() + ")") : "Web address disabled.");
- } finally {
- client.getConnectionManager().shutdown();
- }
-
- // Test redirection, but only once.
- if (testUrlRedirection) {
- testUrlRedirection = false;
- testUrlRedirection();
- }
-
- // Don't do it again if disabled.
- if (!enable && urlRedirectionFuture != null) {
- urlRedirectionFuture.cancel(false);
- }
- }
-
- private void testUrlRedirection() {
-
- HttpGet request = new HttpGet(URL_REDIRECTION_TEST_URL + "?redirectFrom=" + settingsService.getUrlRedirectFrom());
- HttpClient client = new DefaultHttpClient();
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
- HttpConnectionParams.setSoTimeout(client.getParams(), 30000);
-
- try {
- urlRedirectionStatus.setText("Testing web address " + settingsService.getUrlRedirectFrom() + ".subsonic.org. Please wait...");
- String response = client.execute(request, new BasicResponseHandler());
- urlRedirectionStatus.setText(response);
-
- } catch (Throwable x) {
- LOG.warn("Failed to test web address.", x);
- urlRedirectionStatus.setText("Failed to test web address. " + x.getMessage() + " (" + x.getClass().getSimpleName() + ")");
- } finally {
- client.getConnectionManager().shutdown();
- }
- }
- }
-
- private abstract class Task implements Runnable {
- public void run() {
- String name = getClass().getSimpleName();
- try {
- execute();
- } catch (Throwable x) {
- LOG.error("Error executing " + name + ": " + x.getMessage(), x);
- }
- }
-
- protected abstract void execute();
- }
-
- public static class Status {
-
- private String text;
- private Date date;
-
- public void setText(String text) {
- this.text = text;
- date = new Date();
- }
-
- public String getText() {
- return text;
- }
-
- public Date getDate() {
- return date;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlayerService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlayerService.java
deleted file mode 100644
index 0f24b2b8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlayerService.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.dao.PlayerDao;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.Transcoding;
-import net.sourceforge.subsonic.domain.TransferStatus;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.commons.lang.StringUtils;
-
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Provides services for maintaining the set of players.
- *
- * @author Sindre Mehus
- * @see Player
- */
-public class PlayerService {
-
- private static final String COOKIE_NAME = "player";
- private static final int COOKIE_EXPIRY = 365 * 24 * 3600; // One year
-
- private PlayerDao playerDao;
- private StatusService statusService;
- private SecurityService securityService;
- private TranscodingService transcodingService;
-
- public void init() {
- playerDao.deleteOldPlayers(60);
- }
-
- /**
- * Equivalent to <code>getPlayer(request, response, true)</code> .
- */
- public Player getPlayer(HttpServletRequest request, HttpServletResponse response) {
- return getPlayer(request, response, true, false);
- }
-
- /**
- * Returns the player associated with the given HTTP request. If no such player exists, a new
- * one is created.
- *
- * @param request The HTTP request.
- * @param response The HTTP response.
- * @param remoteControlEnabled Whether this method should return a remote-controlled player.
- * @param isStreamRequest Whether the HTTP request is a request for streaming data.
- * @return The player associated with the given HTTP request.
- */
- public synchronized Player getPlayer(HttpServletRequest request, HttpServletResponse response,
- boolean remoteControlEnabled, boolean isStreamRequest) {
-
- // Find by 'player' request parameter.
- Player player = getPlayerById(request.getParameter("player"));
-
- // Find in session context.
- if (player == null && remoteControlEnabled) {
- String playerId = (String) request.getSession().getAttribute("player");
- if (playerId != null) {
- player = getPlayerById(playerId);
- }
- }
-
- // Find by cookie.
- String username = securityService.getCurrentUsername(request);
- if (player == null && remoteControlEnabled) {
- player = getPlayerById(getPlayerIdFromCookie(request, username));
- }
-
- // Make sure we're not hijacking the player of another user.
- if (player != null && player.getUsername() != null && username != null && !player.getUsername().equals(username)) {
- player = null;
- }
-
- // Look for player with same IP address and user name.
- if (player == null) {
- player = getPlayerByIpAddressAndUsername(request.getRemoteAddr(), username);
-
- // Don't use this player if it's used by REST API.
- if (player != null && player.getClientId() != null) {
- player = null;
- }
- }
-
- // If no player was found, create it.
- if (player == null) {
- player = new Player();
- createPlayer(player);
-// LOG.debug("Created player " + player.getId() + " (remoteControlEnabled: " + remoteControlEnabled +
-// ", isStreamRequest: " + isStreamRequest + ", username: " + username +
-// ", ip: " + request.getRemoteAddr() + ").");
- }
-
- // Update player data.
- boolean isUpdate = false;
- if (username != null && player.getUsername() == null) {
- player.setUsername(username);
- isUpdate = true;
- }
- if (player.getIpAddress() == null || isStreamRequest ||
- (!isPlayerConnected(player) && player.isDynamicIp() && !request.getRemoteAddr().equals(player.getIpAddress()))) {
- player.setIpAddress(request.getRemoteAddr());
- isUpdate = true;
- }
- String userAgent = request.getHeader("user-agent");
- if (isStreamRequest) {
- player.setType(userAgent);
- player.setLastSeen(new Date());
- isUpdate = true;
- }
-
- if (isUpdate) {
- updatePlayer(player);
- }
-
- // Set cookie in response.
- if (response != null) {
- String cookieName = COOKIE_NAME + "-" + StringUtil.utf8HexEncode(username);
- Cookie cookie = new Cookie(cookieName, player.getId());
- cookie.setMaxAge(COOKIE_EXPIRY);
- String path = request.getContextPath();
- if (StringUtils.isEmpty(path)) {
- path = "/";
- }
- cookie.setPath(path);
- response.addCookie(cookie);
- }
-
- // Save player in session context.
- if (remoteControlEnabled) {
- request.getSession().setAttribute("player", player.getId());
- }
-
- return player;
- }
-
- /**
- * Updates the given player.
- *
- * @param player The player to update.
- */
- public void updatePlayer(Player player) {
- playerDao.updatePlayer(player);
- }
-
- /**
- * Returns the player with the given ID.
- *
- * @param id The unique player ID.
- * @return The player with the given ID, or <code>null</code> if no such player exists.
- */
- public Player getPlayerById(String id) {
- return playerDao.getPlayerById(id);
- }
-
- /**
- * Returns whether the given player is connected.
- *
- * @param player The player in question.
- * @return Whether the player is connected.
- */
- private boolean isPlayerConnected(Player player) {
- for (TransferStatus status : statusService.getStreamStatusesForPlayer(player)) {
- if (status.isActive()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the player with the given IP address and username. If no username is given, only IP address is
- * used as search criteria.
- *
- * @param ipAddress The IP address.
- * @param username The remote user.
- * @return The player with the given IP address, or <code>null</code> if no such player exists.
- */
- private Player getPlayerByIpAddressAndUsername(final String ipAddress, final String username) {
- if (ipAddress == null) {
- return null;
- }
- for (Player player : getAllPlayers()) {
- boolean ipMatches = ipAddress.equals(player.getIpAddress());
- boolean userMatches = username == null || username.equals(player.getUsername());
- if (ipMatches && userMatches) {
- return player;
- }
- }
- return null;
- }
-
- /**
- * Reads the player ID from the cookie in the HTTP request.
- *
- * @param request The HTTP request.
- * @param username The name of the current user.
- * @return The player ID embedded in the cookie, or <code>null</code> if cookie is not present.
- */
- private String getPlayerIdFromCookie(HttpServletRequest request, String username) {
- Cookie[] cookies = request.getCookies();
- if (cookies == null) {
- return null;
- }
- String cookieName = COOKIE_NAME + "-" + StringUtil.utf8HexEncode(username);
- for (Cookie cookie : cookies) {
- if (cookieName.equals(cookie.getName())) {
- return cookie.getValue();
- }
- }
- return null;
- }
-
- /**
- * Returns all players owned by the given username and client ID.
- *
- * @param username The name of the user.
- * @param clientId The third-party client ID (used if this player is managed over the
- * Subsonic REST API). May be <code>null</code>.
- * @return All relevant players.
- */
- public List<Player> getPlayersForUserAndClientId(String username, String clientId) {
- return playerDao.getPlayersForUserAndClientId(username, clientId);
- }
-
- /**
- * Returns all currently registered players.
- *
- * @return All currently registered players.
- */
- public List<Player> getAllPlayers() {
- return playerDao.getAllPlayers();
- }
-
- /**
- * Removes the player with the given ID.
- *
- * @param id The unique player ID.
- */
- public synchronized void removePlayerById(String id) {
- playerDao.deletePlayer(id);
- }
-
- /**
- * Creates and returns a clone of the given player.
- *
- * @param playerId The ID of the player to clone.
- * @return The cloned player.
- */
- public Player clonePlayer(String playerId) {
- Player player = getPlayerById(playerId);
- if (player.getName() != null) {
- player.setName(player.getName() + " (copy)");
- }
-
- createPlayer(player);
- return player;
- }
-
- /**
- * Creates the given player, and activates all transcodings.
- *
- * @param player The player to create.
- */
- public void createPlayer(Player player) {
- playerDao.createPlayer(player);
-
- List<Transcoding> transcodings = transcodingService.getAllTranscodings();
- List<Transcoding> defaultActiveTranscodings = new ArrayList<Transcoding>();
- for (Transcoding transcoding : transcodings) {
- if (transcoding.isDefaultActive()) {
- defaultActiveTranscodings.add(transcoding);
- }
- }
-
- transcodingService.setTranscodingsForPlayer(player, defaultActiveTranscodings);
- }
-
- public void setStatusService(StatusService statusService) {
- this.statusService = statusService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setPlayerDao(PlayerDao playerDao) {
- this.playerDao = playerDao;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlaylistService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlaylistService.java
deleted file mode 100644
index 6208c3dc..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PlaylistService.java
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.util.Pair;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringEscapeUtils;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.JDOMException;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.MediaFileDao;
-import net.sourceforge.subsonic.dao.PlaylistDao;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Playlist;
-import net.sourceforge.subsonic.util.StringUtil;
-
-/**
- * Provides services for loading and saving playlists to and from persistent storage.
- *
- * @author Sindre Mehus
- * @see net.sourceforge.subsonic.domain.PlayQueue
- */
-public class PlaylistService {
-
- private static final Logger LOG = Logger.getLogger(PlaylistService.class);
- private MediaFileService mediaFileService;
- private MediaFileDao mediaFileDao;
- private PlaylistDao playlistDao;
- private SecurityService securityService;
- private SettingsService settingsService;
-
- public void init() {
- try {
- importPlaylists();
- } catch (Throwable x) {
- LOG.warn("Failed to import playlists: " + x, x);
- }
- }
-
- public List<Playlist> getReadablePlaylistsForUser(String username) {
- return playlistDao.getReadablePlaylistsForUser(username);
- }
-
- public List<Playlist> getWritablePlaylistsForUser(String username) {
-
- // Admin users are allowed to modify all playlists that are visible to them.
- if (securityService.isAdmin(username)) {
- return getReadablePlaylistsForUser(username);
- }
-
- return playlistDao.getWritablePlaylistsForUser(username);
- }
-
- public Playlist getPlaylist(int id) {
- return playlistDao.getPlaylist(id);
- }
-
- public List<String> getPlaylistUsers(int playlistId) {
- return playlistDao.getPlaylistUsers(playlistId);
- }
-
- public List<MediaFile> getFilesInPlaylist(int id) {
- return mediaFileDao.getFilesInPlaylist(id);
- }
-
- public void setFilesInPlaylist(int id, List<MediaFile> files) {
- playlistDao.setFilesInPlaylist(id, files);
- }
-
- public void createPlaylist(Playlist playlist) {
- playlistDao.createPlaylist(playlist);
- }
-
- public void addPlaylistUser(int playlistId, String username) {
- playlistDao.addPlaylistUser(playlistId, username);
- }
-
- public void deletePlaylistUser(int playlistId, String username) {
- playlistDao.deletePlaylistUser(playlistId, username);
- }
-
- public boolean isReadAllowed(Playlist playlist, String username) {
- if (username == null) {
- return false;
- }
- if (username.equals(playlist.getUsername()) || playlist.isPublic()) {
- return true;
- }
- return playlistDao.getPlaylistUsers(playlist.getId()).contains(username);
- }
-
- public boolean isWriteAllowed(Playlist playlist, String username) {
- return username != null && username.equals(playlist.getUsername());
- }
-
- public void deletePlaylist(int id) {
- playlistDao.deletePlaylist(id);
- }
-
- public void updatePlaylist(Playlist playlist) {
- playlistDao.updatePlaylist(playlist);
- }
-
- public Playlist importPlaylist(String username, String playlistName, String fileName, String format, InputStream inputStream) throws Exception {
- PlaylistFormat playlistFormat = PlaylistFormat.getPlaylistFormat(format);
- if (playlistFormat == null) {
- throw new Exception("Unsupported playlist format: " + format);
- }
-
- Pair<List<MediaFile>, List<String>> result = parseFiles(IOUtils.toByteArray(inputStream), playlistFormat);
- if (result.getFirst().isEmpty() && !result.getSecond().isEmpty()) {
- throw new Exception("No songs in the playlist were found.");
- }
-
- for (String error : result.getSecond()) {
- LOG.warn("File in playlist '" + fileName + "' not found: " + error);
- }
-
- Date now = new Date();
- Playlist playlist = new Playlist();
- playlist.setUsername(username);
- playlist.setCreated(now);
- playlist.setChanged(now);
- playlist.setPublic(true);
- playlist.setName(playlistName);
- playlist.setImportedFrom(fileName);
-
- createPlaylist(playlist);
- setFilesInPlaylist(playlist.getId(), result.getFirst());
-
- return playlist;
- }
-
- private Pair<List<MediaFile>, List<String>> parseFiles(byte[] playlist, PlaylistFormat playlistFormat) throws IOException {
- Pair<List<MediaFile>, List<String>> result = null;
-
- // Try with multiple encodings; use the one that finds the most files.
- String[] encodings = {StringUtil.ENCODING_LATIN, StringUtil.ENCODING_UTF8, Charset.defaultCharset().name()};
- for (String encoding : encodings) {
- Pair<List<MediaFile>, List<String>> files = parseFilesWithEncoding(playlist, playlistFormat, encoding);
- if (result == null || result.getFirst().size() < files.getFirst().size()) {
- result = files;
- }
- }
- return result;
- }
-
- private Pair<List<MediaFile>, List<String>> parseFilesWithEncoding(byte[] playlist, PlaylistFormat playlistFormat, String encoding) throws IOException {
- BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(playlist), encoding));
- return playlistFormat.parse(reader, mediaFileService);
- }
-
- public void exportPlaylist(int id, OutputStream out) throws Exception {
- PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, StringUtil.ENCODING_UTF8));
- new M3UFormat().format(getFilesInPlaylist(id), writer);
- }
-
- /**
- * Implementation of M3U playlist format.
- */
- private void importPlaylists() throws Exception {
- String playlistFolderPath = settingsService.getPlaylistFolder();
- if (playlistFolderPath == null) {
- return;
- }
- File playlistFolder = new File(playlistFolderPath);
- if (!playlistFolder.exists()) {
- return;
- }
-
- List<Playlist> allPlaylists = playlistDao.getAllPlaylists();
- for (File file : playlistFolder.listFiles()) {
- try {
- importPlaylistIfNotExisting(file, allPlaylists);
- } catch (Exception x) {
- LOG.warn("Failed to auto-import playlist " + file + ". " + x.getMessage());
- }
- }
- }
-
- private void importPlaylistIfNotExisting(File file, List<Playlist> allPlaylists) throws Exception {
- String format = FilenameUtils.getExtension(file.getPath());
- if (PlaylistFormat.getPlaylistFormat(format) == null) {
- return;
- }
-
- String fileName = file.getName();
- for (Playlist playlist : allPlaylists) {
- if (fileName.equals(playlist.getImportedFrom())) {
- return; // Already imported.
- }
- }
- InputStream in = new FileInputStream(file);
- try {
- importPlaylist(User.USERNAME_ADMIN, FilenameUtils.getBaseName(fileName), fileName, format, in);
- LOG.info("Auto-imported playlist " + file);
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- public void setPlaylistDao(PlaylistDao playlistDao) {
- this.playlistDao = playlistDao;
- }
-
- public void setMediaFileDao(MediaFileDao mediaFileDao) {
- this.mediaFileDao = mediaFileDao;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
- /**
- * Abstract superclass for playlist formats.
- */
-
- private abstract static class PlaylistFormat {
- public abstract Pair<List<MediaFile>, List<String>> parse(BufferedReader reader, MediaFileService mediaFileService) throws IOException;
-
- public abstract void format(List<MediaFile> files, PrintWriter writer) throws IOException;
-
- public static PlaylistFormat getPlaylistFormat(String format) {
- if (format == null) {
- return null;
- }
- if (format.equalsIgnoreCase("m3u") || format.equalsIgnoreCase("m3u8")) {
- return new M3UFormat();
- }
- if (format.equalsIgnoreCase("pls")) {
- return new PLSFormat();
- }
- if (format.equalsIgnoreCase("xspf")) {
- return new XSPFFormat();
- }
- return null;
- }
-
- protected MediaFile getMediaFile(MediaFileService mediaFileService, String path) {
- try {
- MediaFile file = mediaFileService.getMediaFile(path);
- if (file != null && file.exists()) {
- return file;
- }
- } catch (SecurityException x) {
- // Ignored
- }
- return null;
- }
- }
-
- private static class M3UFormat extends PlaylistFormat {
- public Pair<List<MediaFile>, List<String>> parse(BufferedReader reader, MediaFileService mediaFileService) throws IOException {
- List<MediaFile> ok = new ArrayList<MediaFile>();
- List<String> error = new ArrayList<String>();
- String line = reader.readLine();
- while (line != null) {
- if (!line.startsWith("#")) {
- MediaFile file = getMediaFile(mediaFileService, line);
- if (file != null) {
- ok.add(file);
- } else {
- error.add(line);
- }
- }
- line = reader.readLine();
- }
- return new Pair<List<MediaFile>, List<String>>(ok, error);
- }
-
- public void format(List<MediaFile> files, PrintWriter writer) throws IOException {
- writer.println("#EXTM3U");
- for (MediaFile file : files) {
- writer.println(file.getPath());
- }
- if (writer.checkError()) {
- throw new IOException("Error when writing playlist");
- }
- }
- }
-
- /**
- * Implementation of PLS playlist format.
- */
- private static class PLSFormat extends PlaylistFormat {
- public Pair<List<MediaFile>, List<String>> parse(BufferedReader reader, MediaFileService mediaFileService) throws IOException {
- List<MediaFile> ok = new ArrayList<MediaFile>();
- List<String> error = new ArrayList<String>();
-
- Pattern pattern = Pattern.compile("^File\\d+=(.*)$");
- String line = reader.readLine();
- while (line != null) {
-
- Matcher matcher = pattern.matcher(line);
- if (matcher.find()) {
- String path = matcher.group(1);
- MediaFile file = getMediaFile(mediaFileService, path);
- if (file != null) {
- ok.add(file);
- } else {
- error.add(path);
- }
- }
- line = reader.readLine();
- }
- return new Pair<List<MediaFile>, List<String>>(ok, error);
- }
-
- public void format(List<MediaFile> files, PrintWriter writer) throws IOException {
- writer.println("[playlist]");
- int counter = 0;
-
- for (MediaFile file : files) {
- counter++;
- writer.println("File" + counter + '=' + file.getPath());
- }
- writer.println("NumberOfEntries=" + counter);
- writer.println("Version=2");
-
- if (writer.checkError()) {
- throw new IOException("Error when writing playlist.");
- }
- }
- }
-
- /**
- * Implementation of XSPF (http://www.xspf.org/) playlist format.
- */
- private static class XSPFFormat extends PlaylistFormat {
- public Pair<List<MediaFile>, List<String>> parse(BufferedReader reader, MediaFileService mediaFileService) throws IOException {
- List<MediaFile> ok = new ArrayList<MediaFile>();
- List<String> error = new ArrayList<String>();
-
- SAXBuilder builder = new SAXBuilder();
- Document document;
- try {
- document = builder.build(reader);
- } catch (JDOMException x) {
- LOG.warn("Failed to parse XSPF playlist.", x);
- throw new IOException("Failed to parse XSPF playlist.");
- }
-
- Element root = document.getRootElement();
- Namespace ns = root.getNamespace();
- Element trackList = root.getChild("trackList", ns);
- List<?> tracks = trackList.getChildren("track", ns);
-
- for (Object obj : tracks) {
- Element track = (Element) obj;
- String location = track.getChildText("location", ns);
- if (location != null && location.startsWith("file://")) {
- location = location.replaceFirst("file://", "");
- MediaFile file = getMediaFile(mediaFileService, location);
- if (file != null) {
- ok.add(file);
- } else {
- error.add(location);
- }
- }
- }
- return new Pair<List<MediaFile>, List<String>>(ok, error);
- }
-
- public void format(List<MediaFile> files, PrintWriter writer) throws IOException {
- writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- writer.println("<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">");
- writer.println(" <trackList>");
-
- for (MediaFile file : files) {
- writer.println(" <track><location>file://" + StringEscapeUtils.escapeXml(file.getPath()) + "</location></track>");
- }
- writer.println(" </trackList>");
- writer.println("</playlist>");
-
- if (writer.checkError()) {
- throw new IOException("Error when writing playlist.");
- }
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PodcastService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PodcastService.java
deleted file mode 100644
index 09184df6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/PodcastService.java
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.PodcastDao;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.PodcastChannel;
-import net.sourceforge.subsonic.domain.PodcastEpisode;
-import net.sourceforge.subsonic.domain.PodcastStatus;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.Namespace;
-import org.jdom.input.SAXBuilder;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Provides services for Podcast reception.
- *
- * @author Sindre Mehus
- */
-public class PodcastService {
-
- private static final Logger LOG = Logger.getLogger(PodcastService.class);
- private static final DateFormat[] RSS_DATE_FORMATS = {new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US),
- new SimpleDateFormat("dd MMM yyyy HH:mm:ss Z", Locale.US)};
-
- private static final Namespace[] ITUNES_NAMESPACES = {Namespace.getNamespace("http://www.itunes.com/DTDs/Podcast-1.0.dtd"),
- Namespace.getNamespace("http://www.itunes.com/dtds/podcast-1.0.dtd")};
-
- private final ExecutorService refreshExecutor;
- private final ExecutorService downloadExecutor;
- private final ScheduledExecutorService scheduledExecutor;
- private ScheduledFuture<?> scheduledRefresh;
- private PodcastDao podcastDao;
- private SettingsService settingsService;
- private SecurityService securityService;
- private MediaFileService mediaFileService;
-
- public PodcastService() {
- ThreadFactory threadFactory = new ThreadFactory() {
- public Thread newThread(Runnable r) {
- Thread t = Executors.defaultThreadFactory().newThread(r);
- t.setDaemon(true);
- return t;
- }
- };
- refreshExecutor = Executors.newFixedThreadPool(5, threadFactory);
- downloadExecutor = Executors.newFixedThreadPool(3, threadFactory);
- scheduledExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory);
- }
-
- public synchronized void init() {
- // Clean up partial downloads.
- for (PodcastChannel channel : getAllChannels()) {
- for (PodcastEpisode episode : getEpisodes(channel.getId(), false)) {
- if (episode.getStatus() == PodcastStatus.DOWNLOADING) {
- deleteEpisode(episode.getId(), false);
- LOG.info("Deleted Podcast episode '" + episode.getTitle() + "' since download was interrupted.");
- }
- }
- }
-
- schedule();
- }
-
- public synchronized void schedule() {
- Runnable task = new Runnable() {
- public void run() {
- LOG.info("Starting scheduled Podcast refresh.");
- refreshAllChannels(true);
- LOG.info("Completed scheduled Podcast refresh.");
- }
- };
-
- if (scheduledRefresh != null) {
- scheduledRefresh.cancel(true);
- }
-
- int hoursBetween = settingsService.getPodcastUpdateInterval();
-
- if (hoursBetween == -1) {
- LOG.info("Automatic Podcast update disabled.");
- return;
- }
-
- long periodMillis = hoursBetween * 60L * 60L * 1000L;
- long initialDelayMillis = 5L * 60L * 1000L;
-
- scheduledRefresh = scheduledExecutor.scheduleAtFixedRate(task, initialDelayMillis, periodMillis, TimeUnit.MILLISECONDS);
- Date firstTime = new Date(System.currentTimeMillis() + initialDelayMillis);
- LOG.info("Automatic Podcast update scheduled to run every " + hoursBetween + " hour(s), starting at " + firstTime);
- }
-
- /**
- * Creates a new Podcast channel.
- *
- * @param url The URL of the Podcast channel.
- */
- public void createChannel(String url) {
- url = sanitizeUrl(url);
- PodcastChannel channel = new PodcastChannel(url);
- int channelId = podcastDao.createChannel(channel);
-
- refreshChannels(Arrays.asList(getChannel(channelId)), true);
- }
-
- private String sanitizeUrl(String url) {
- return url.replace(" ", "%20");
- }
-
- private PodcastChannel getChannel(int channelId) {
- for (PodcastChannel channel : getAllChannels()) {
- if (channelId == channel.getId()) {
- return channel;
- }
- }
- return null;
- }
-
- /**
- * Returns all Podcast channels.
- *
- * @return Possibly empty list of all Podcast channels.
- */
- public List<PodcastChannel> getAllChannels() {
- return podcastDao.getAllChannels();
- }
-
- /**
- * Returns all Podcast episodes for a given channel.
- *
- * @param channelId The Podcast channel ID.
- * @param includeDeleted Whether to include logically deleted episodes in the result.
- * @return Possibly empty list of all Podcast episodes for the given channel, sorted in
- * reverse chronological order (newest episode first).
- */
- public List<PodcastEpisode> getEpisodes(int channelId, boolean includeDeleted) {
- List<PodcastEpisode> all = podcastDao.getEpisodes(channelId);
- addMediaFileIdToEpisodes(all);
- if (includeDeleted) {
- return all;
- }
-
- List<PodcastEpisode> filtered = new ArrayList<PodcastEpisode>();
- for (PodcastEpisode episode : all) {
- if (episode.getStatus() != PodcastStatus.DELETED) {
- filtered.add(episode);
- }
- }
- return filtered;
- }
-
- public PodcastEpisode getEpisode(int episodeId, boolean includeDeleted) {
- PodcastEpisode episode = podcastDao.getEpisode(episodeId);
- if (episode == null) {
- return null;
- }
- if (episode.getStatus() == PodcastStatus.DELETED && !includeDeleted) {
- return null;
- }
- addMediaFileIdToEpisodes(Arrays.asList(episode));
- return episode;
- }
-
- private void addMediaFileIdToEpisodes(List<PodcastEpisode> episodes) {
- for (PodcastEpisode episode : episodes) {
- if (episode.getPath() != null) {
- MediaFile mediaFile = mediaFileService.getMediaFile(episode.getPath());
- if (mediaFile != null) {
- episode.setMediaFileId(mediaFile.getId());
- }
- }
- }
- }
-
- private PodcastEpisode getEpisode(int channelId, String url) {
- if (url == null) {
- return null;
- }
-
- for (PodcastEpisode episode : getEpisodes(channelId, true)) {
- if (url.equals(episode.getUrl())) {
- return episode;
- }
- }
- return null;
- }
-
- public void refreshAllChannels(boolean downloadEpisodes) {
- refreshChannels(getAllChannels(), downloadEpisodes);
- }
-
- private void refreshChannels(final List<PodcastChannel> channels, final boolean downloadEpisodes) {
- for (final PodcastChannel channel : channels) {
- Runnable task = new Runnable() {
- public void run() {
- doRefreshChannel(channel, downloadEpisodes);
- }
- };
- refreshExecutor.submit(task);
- }
- }
-
- @SuppressWarnings({"unchecked"})
- private void doRefreshChannel(PodcastChannel channel, boolean downloadEpisodes) {
- InputStream in = null;
- HttpClient client = new DefaultHttpClient();
-
- try {
- channel.setStatus(PodcastStatus.DOWNLOADING);
- channel.setErrorMessage(null);
- podcastDao.updateChannel(channel);
-
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 2 * 60 * 1000); // 2 minutes
- HttpConnectionParams.setSoTimeout(client.getParams(), 10 * 60 * 1000); // 10 minutes
- HttpGet method = new HttpGet(channel.getUrl());
-
- HttpResponse response = client.execute(method);
- in = response.getEntity().getContent();
-
- Document document = new SAXBuilder().build(in);
- Element channelElement = document.getRootElement().getChild("channel");
-
- channel.setTitle(channelElement.getChildTextTrim("title"));
- channel.setDescription(channelElement.getChildTextTrim("description"));
- channel.setStatus(PodcastStatus.COMPLETED);
- channel.setErrorMessage(null);
- podcastDao.updateChannel(channel);
-
- refreshEpisodes(channel, channelElement.getChildren("item"));
-
- } catch (Exception x) {
- LOG.warn("Failed to get/parse RSS file for Podcast channel " + channel.getUrl(), x);
- channel.setStatus(PodcastStatus.ERROR);
- channel.setErrorMessage(x.toString());
- podcastDao.updateChannel(channel);
- } finally {
- IOUtils.closeQuietly(in);
- client.getConnectionManager().shutdown();
- }
-
- if (downloadEpisodes) {
- for (final PodcastEpisode episode : getEpisodes(channel.getId(), false)) {
- if (episode.getStatus() == PodcastStatus.NEW && episode.getUrl() != null) {
- downloadEpisode(episode);
- }
- }
- }
- }
-
- public void downloadEpisode(final PodcastEpisode episode) {
- Runnable task = new Runnable() {
- public void run() {
- doDownloadEpisode(episode);
- }
- };
- downloadExecutor.submit(task);
- }
-
- private void refreshEpisodes(PodcastChannel channel, List<Element> episodeElements) {
-
- List<PodcastEpisode> episodes = new ArrayList<PodcastEpisode>();
-
- for (Element episodeElement : episodeElements) {
-
- String title = episodeElement.getChildTextTrim("title");
- String duration = getITunesElement(episodeElement, "duration");
- String description = episodeElement.getChildTextTrim("description");
- if (StringUtils.isBlank(description)) {
- description = getITunesElement(episodeElement, "summary");
- }
-
- Element enclosure = episodeElement.getChild("enclosure");
- if (enclosure == null) {
- LOG.debug("No enclosure found for episode " + title);
- continue;
- }
-
- String url = enclosure.getAttributeValue("url");
- url = sanitizeUrl(url);
- if (url == null) {
- LOG.debug("No enclosure URL found for episode " + title);
- continue;
- }
-
- if (getEpisode(channel.getId(), url) == null) {
- Long length = null;
- try {
- length = new Long(enclosure.getAttributeValue("length"));
- } catch (Exception x) {
- LOG.warn("Failed to parse enclosure length.", x);
- }
-
- Date date = parseDate(episodeElement.getChildTextTrim("pubDate"));
- PodcastEpisode episode = new PodcastEpisode(null, channel.getId(), url, null, title, description, date,
- duration, length, 0L, PodcastStatus.NEW, null);
- episodes.add(episode);
- LOG.info("Created Podcast episode " + title);
- }
- }
-
- // Sort episode in reverse chronological order (newest first)
- Collections.sort(episodes, new Comparator<PodcastEpisode>() {
- public int compare(PodcastEpisode a, PodcastEpisode b) {
- long timeA = a.getPublishDate() == null ? 0L : a.getPublishDate().getTime();
- long timeB = b.getPublishDate() == null ? 0L : b.getPublishDate().getTime();
-
- if (timeA < timeB) {
- return 1;
- }
- if (timeA > timeB) {
- return -1;
- }
- return 0;
- }
- });
-
- // Create episodes in database, skipping the proper number of episodes.
- int downloadCount = settingsService.getPodcastEpisodeDownloadCount();
- if (downloadCount == -1) {
- downloadCount = Integer.MAX_VALUE;
- }
-
- for (int i = 0; i < episodes.size(); i++) {
- PodcastEpisode episode = episodes.get(i);
- if (i >= downloadCount) {
- episode.setStatus(PodcastStatus.SKIPPED);
- }
- podcastDao.createEpisode(episode);
- }
- }
-
- private Date parseDate(String s) {
- for (DateFormat dateFormat : RSS_DATE_FORMATS) {
- try {
- return dateFormat.parse(s);
- } catch (Exception x) {
- // Ignored.
- }
- }
- LOG.warn("Failed to parse publish date: '" + s + "'.");
- return null;
- }
-
- private String getITunesElement(Element element, String childName) {
- for (Namespace ns : ITUNES_NAMESPACES) {
- String value = element.getChildTextTrim(childName, ns);
- if (value != null) {
- return value;
- }
- }
- return null;
- }
-
- private void doDownloadEpisode(PodcastEpisode episode) {
- InputStream in = null;
- OutputStream out = null;
-
- if (getEpisode(episode.getId(), false) == null) {
- LOG.info("Podcast " + episode.getUrl() + " was deleted. Aborting download.");
- return;
- }
-
- LOG.info("Starting to download Podcast from " + episode.getUrl());
-
- HttpClient client = new DefaultHttpClient();
- try {
- PodcastChannel channel = getChannel(episode.getChannelId());
-
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 2 * 60 * 1000); // 2 minutes
- HttpConnectionParams.setSoTimeout(client.getParams(), 10 * 60 * 1000); // 10 minutes
- HttpGet method = new HttpGet(episode.getUrl());
-
- HttpResponse response = client.execute(method);
- in = response.getEntity().getContent();
-
- File file = getFile(channel, episode);
- out = new FileOutputStream(file);
-
- episode.setStatus(PodcastStatus.DOWNLOADING);
- episode.setBytesDownloaded(0L);
- episode.setErrorMessage(null);
- episode.setPath(file.getPath());
- podcastDao.updateEpisode(episode);
-
- byte[] buffer = new byte[4096];
- long bytesDownloaded = 0;
- int n;
- long nextLogCount = 30000L;
-
- while ((n = in.read(buffer)) != -1) {
- out.write(buffer, 0, n);
- bytesDownloaded += n;
-
- if (bytesDownloaded > nextLogCount) {
- episode.setBytesDownloaded(bytesDownloaded);
- nextLogCount += 30000L;
- if (getEpisode(episode.getId(), false) == null) {
- break;
- }
- podcastDao.updateEpisode(episode);
- }
- }
-
- if (getEpisode(episode.getId(), false) == null) {
- LOG.info("Podcast " + episode.getUrl() + " was deleted. Aborting download.");
- IOUtils.closeQuietly(out);
- file.delete();
- } else {
- episode.setBytesDownloaded(bytesDownloaded);
- podcastDao.updateEpisode(episode);
- LOG.info("Downloaded " + bytesDownloaded + " bytes from Podcast " + episode.getUrl());
- IOUtils.closeQuietly(out);
- episode.setStatus(PodcastStatus.COMPLETED);
- podcastDao.updateEpisode(episode);
- deleteObsoleteEpisodes(channel);
- }
-
- } catch (Exception x) {
- LOG.warn("Failed to download Podcast from " + episode.getUrl(), x);
- episode.setStatus(PodcastStatus.ERROR);
- episode.setErrorMessage(x.toString());
- podcastDao.updateEpisode(episode);
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- client.getConnectionManager().shutdown();
- }
- }
-
- private synchronized void deleteObsoleteEpisodes(PodcastChannel channel) {
- int episodeCount = settingsService.getPodcastEpisodeRetentionCount();
- if (episodeCount == -1) {
- return;
- }
-
- List<PodcastEpisode> episodes = getEpisodes(channel.getId(), false);
-
- // Don't do anything if other episodes of the same channel is currently downloading.
- for (PodcastEpisode episode : episodes) {
- if (episode.getStatus() == PodcastStatus.DOWNLOADING) {
- return;
- }
- }
-
- // Reverse array to get chronological order (oldest episodes first).
- Collections.reverse(episodes);
-
- int episodesToDelete = Math.max(0, episodes.size() - episodeCount);
- for (int i = 0; i < episodesToDelete; i++) {
- deleteEpisode(episodes.get(i).getId(), true);
- LOG.info("Deleted old Podcast episode " + episodes.get(i).getUrl());
- }
- }
-
- private synchronized File getFile(PodcastChannel channel, PodcastEpisode episode) {
-
- File podcastDir = new File(settingsService.getPodcastFolder());
- File channelDir = new File(podcastDir, StringUtil.fileSystemSafe(channel.getTitle()));
-
- if (!channelDir.exists()) {
- boolean ok = channelDir.mkdirs();
- if (!ok) {
- throw new RuntimeException("Failed to create directory " + channelDir);
- }
-
- MediaFile mediaFile = mediaFileService.getMediaFile(channelDir);
- mediaFile.setComment(channel.getDescription());
- mediaFileService.updateMediaFile(mediaFile);
- }
-
- String filename = StringUtil.getUrlFile(episode.getUrl());
- if (filename == null) {
- filename = episode.getTitle();
- }
- filename = StringUtil.fileSystemSafe(filename);
- String extension = FilenameUtils.getExtension(filename);
- filename = FilenameUtils.removeExtension(filename);
- if (StringUtils.isBlank(extension)) {
- extension = "mp3";
- }
-
- File file = new File(channelDir, filename + "." + extension);
- for (int i = 0; file.exists(); i++) {
- file = new File(channelDir, filename + i + "." + extension);
- }
-
- if (!securityService.isWriteAllowed(file)) {
- throw new SecurityException("Access denied to file " + file);
- }
- return file;
- }
-
- /**
- * Deletes the Podcast channel with the given ID.
- *
- * @param channelId The Podcast channel ID.
- */
- public void deleteChannel(int channelId) {
- // Delete all associated episodes (in case they have files that need to be deleted).
- List<PodcastEpisode> episodes = getEpisodes(channelId, false);
- for (PodcastEpisode episode : episodes) {
- deleteEpisode(episode.getId(), false);
- }
- podcastDao.deleteChannel(channelId);
- }
-
- /**
- * Deletes the Podcast episode with the given ID.
- *
- * @param episodeId The Podcast episode ID.
- * @param logicalDelete Whether to perform a logical delete by setting the
- * episode status to {@link PodcastStatus#DELETED}.
- */
- public void deleteEpisode(int episodeId, boolean logicalDelete) {
- PodcastEpisode episode = podcastDao.getEpisode(episodeId);
- if (episode == null) {
- return;
- }
-
- // Delete file.
- if (episode.getPath() != null) {
- File file = new File(episode.getPath());
- if (file.exists()) {
- file.delete();
- // TODO: Delete directory if empty?
- }
- }
-
- if (logicalDelete) {
- episode.setStatus(PodcastStatus.DELETED);
- episode.setErrorMessage(null);
- podcastDao.updateEpisode(episode);
- } else {
- podcastDao.deleteEpisode(episodeId);
- }
- }
-
- public void setPodcastDao(PodcastDao podcastDao) {
- this.podcastDao = podcastDao;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/RatingService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/RatingService.java
deleted file mode 100644
index 6208faf2..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/RatingService.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.dao.*;
-import net.sourceforge.subsonic.domain.*;
-import net.sourceforge.subsonic.util.FileUtil;
-
-import java.util.*;
-import java.io.File;
-
-/**
- * Provides services for user ratings.
- *
- * @author Sindre Mehus
- */
-public class RatingService {
-
- private RatingDao ratingDao;
- private SecurityService securityService;
- private MediaFileService mediaFileService;
-
- /**
- * Returns the highest rated music files.
- *
- * @param offset Number of files to skip.
- * @param count Maximum number of files to return.
- * @return The highest rated music files.
- */
- public List<MediaFile> getHighestRated(int offset, int count) {
- List<String> highestRated = ratingDao.getHighestRated(offset, count);
- List<MediaFile> result = new ArrayList<MediaFile>();
- for (String path : highestRated) {
- File file = new File(path);
- if (FileUtil.exists(file) && securityService.isReadAllowed(file)) {
- result.add(mediaFileService.getMediaFile(path));
- }
- }
- return result;
- }
-
- /**
- * Sets the rating for a music file and a given user.
- *
- * @param username The user name.
- * @param mediaFile The music file.
- * @param rating The rating between 1 and 5, or <code>null</code> to remove the rating.
- */
- public void setRatingForUser(String username, MediaFile mediaFile, Integer rating) {
- ratingDao.setRatingForUser(username, mediaFile, rating);
- }
-
- /**
- * Returns the average rating for the given music file.
- *
- * @param mediaFile The music file.
- * @return The average rating, or <code>null</code> if no ratings are set.
- */
- public Double getAverageRating(MediaFile mediaFile) {
- return ratingDao.getAverageRating(mediaFile);
- }
-
- /**
- * Returns the rating for the given user and music file.
- *
- * @param username The user name.
- * @param mediaFile The music file.
- * @return The rating, or <code>null</code> if no rating is set.
- */
- public Integer getRatingForUser(String username, MediaFile mediaFile) {
- return ratingDao.getRatingForUser(username, mediaFile);
- }
-
- public void setRatingDao(RatingDao ratingDao) {
- this.ratingDao = ratingDao;
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SearchService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SearchService.java
deleted file mode 100644
index 2698bbd6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SearchService.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.AlbumDao;
-import net.sourceforge.subsonic.dao.ArtistDao;
-import net.sourceforge.subsonic.domain.Album;
-import net.sourceforge.subsonic.domain.Artist;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.RandomSearchCriteria;
-import net.sourceforge.subsonic.domain.SearchCriteria;
-import net.sourceforge.subsonic.domain.SearchResult;
-import net.sourceforge.subsonic.util.FileUtil;
-import org.apache.lucene.analysis.ASCIIFoldingFilter;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.LowerCaseFilter;
-import org.apache.lucene.analysis.StopFilter;
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-import org.apache.lucene.analysis.standard.StandardFilter;
-import org.apache.lucene.analysis.standard.StandardTokenizer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.NumericField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.queryParser.MultiFieldQueryParser;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.NumericRangeQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Searcher;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-import org.apache.lucene.util.Version;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import static net.sourceforge.subsonic.service.SearchService.IndexType.*;
-import static net.sourceforge.subsonic.service.SearchService.IndexType.SONG;
-
-/**
- * Performs Lucene-based searching and indexing.
- *
- * @author Sindre Mehus
- * @version $Id$
- * @see MediaScannerService
- */
-public class SearchService {
-
- private static final Logger LOG = Logger.getLogger(SearchService.class);
-
- private static final String FIELD_ID = "id";
- private static final String FIELD_TITLE = "title";
- private static final String FIELD_ALBUM = "album";
- private static final String FIELD_ARTIST = "artist";
- private static final String FIELD_GENRE = "genre";
- private static final String FIELD_YEAR = "year";
- private static final String FIELD_MEDIA_TYPE = "mediaType";
- private static final String FIELD_FOLDER = "folder";
-
- private static final Version LUCENE_VERSION = Version.LUCENE_30;
-
- private MediaFileService mediaFileService;
- private SettingsService settingsService;
- private ArtistDao artistDao;
- private AlbumDao albumDao;
-
- private IndexWriter artistWriter;
- private IndexWriter artistId3Writer;
- private IndexWriter albumWriter;
- private IndexWriter albumId3Writer;
- private IndexWriter songWriter;
-
- public SearchService() {
- removeLocks();
- }
-
-
- public void startIndexing() {
- try {
- artistWriter = createIndexWriter(ARTIST);
- artistId3Writer = createIndexWriter(ARTIST_ID3);
- albumWriter = createIndexWriter(ALBUM);
- albumId3Writer = createIndexWriter(ALBUM_ID3);
- songWriter = createIndexWriter(SONG);
- } catch (Exception x) {
- LOG.error("Failed to create search index.", x);
- }
- }
-
- public void index(MediaFile mediaFile) {
- try {
- if (mediaFile.isFile()) {
- songWriter.addDocument(SONG.createDocument(mediaFile));
- } else if (mediaFile.isAlbum()) {
- albumWriter.addDocument(ALBUM.createDocument(mediaFile));
- } else {
- artistWriter.addDocument(ARTIST.createDocument(mediaFile));
- }
- } catch (Exception x) {
- LOG.error("Failed to create search index for " + mediaFile, x);
- }
- }
-
- public void index(Artist artist) {
- try {
- artistId3Writer.addDocument(ARTIST_ID3.createDocument(artist));
- } catch (Exception x) {
- LOG.error("Failed to create search index for " + artist, x);
- }
- }
-
- public void index(Album album) {
- try {
- albumId3Writer.addDocument(ALBUM_ID3.createDocument(album));
- } catch (Exception x) {
- LOG.error("Failed to create search index for " + album, x);
- }
- }
-
- public void stopIndexing() {
- try {
- artistWriter.optimize();
- artistId3Writer.optimize();
- albumWriter.optimize();
- albumId3Writer.optimize();
- songWriter.optimize();
- } catch (Exception x) {
- LOG.error("Failed to create search index.", x);
- } finally {
- FileUtil.closeQuietly(artistId3Writer);
- FileUtil.closeQuietly(artistWriter);
- FileUtil.closeQuietly(albumWriter);
- FileUtil.closeQuietly(albumId3Writer);
- FileUtil.closeQuietly(songWriter);
- }
- }
-
- public SearchResult search(SearchCriteria criteria, IndexType indexType) {
- SearchResult result = new SearchResult();
- int offset = criteria.getOffset();
- int count = criteria.getCount();
- result.setOffset(offset);
-
- IndexReader reader = null;
- try {
- reader = createIndexReader(indexType);
- Searcher searcher = new IndexSearcher(reader);
- Analyzer analyzer = new SubsonicAnalyzer();
-
- MultiFieldQueryParser queryParser = new MultiFieldQueryParser(LUCENE_VERSION, indexType.getFields(), analyzer, indexType.getBoosts());
- Query query = queryParser.parse(criteria.getQuery());
-
- TopDocs topDocs = searcher.search(query, null, offset + count);
- result.setTotalHits(topDocs.totalHits);
-
- int start = Math.min(offset, topDocs.totalHits);
- int end = Math.min(start + count, topDocs.totalHits);
- for (int i = start; i < end; i++) {
- Document doc = searcher.doc(topDocs.scoreDocs[i].doc);
- switch (indexType) {
- case SONG:
- case ARTIST:
- case ALBUM:
- MediaFile mediaFile = mediaFileService.getMediaFile(Integer.valueOf(doc.get(FIELD_ID)));
- addIfNotNull(mediaFile, result.getMediaFiles());
- break;
- case ARTIST_ID3:
- Artist artist = artistDao.getArtist(Integer.valueOf(doc.get(FIELD_ID)));
- addIfNotNull(artist, result.getArtists());
- break;
- case ALBUM_ID3:
- Album album = albumDao.getAlbum(Integer.valueOf(doc.get(FIELD_ID)));
- addIfNotNull(album, result.getAlbums());
- break;
- default:
- break;
- }
- }
-
- } catch (Throwable x) {
- LOG.error("Failed to execute Lucene search.", x);
- } finally {
- FileUtil.closeQuietly(reader);
- }
- return result;
- }
-
- /**
- * Returns a number of random songs.
- *
- * @param criteria Search criteria.
- * @return List of random songs.
- */
- public List<MediaFile> getRandomSongs(RandomSearchCriteria criteria) {
- List<MediaFile> result = new ArrayList<MediaFile>();
-
- String musicFolderPath = null;
- if (criteria.getMusicFolderId() != null) {
- MusicFolder musicFolder = settingsService.getMusicFolderById(criteria.getMusicFolderId());
- musicFolderPath = musicFolder.getPath().getPath();
- }
-
- IndexReader reader = null;
- try {
- reader = createIndexReader(SONG);
- Searcher searcher = new IndexSearcher(reader);
-
- BooleanQuery query = new BooleanQuery();
- query.add(new TermQuery(new Term(FIELD_MEDIA_TYPE, MediaFile.MediaType.MUSIC.name().toLowerCase())), BooleanClause.Occur.MUST);
- if (criteria.getGenre() != null) {
- String genre = normalizeGenre(criteria.getGenre());
- query.add(new TermQuery(new Term(FIELD_GENRE, genre)), BooleanClause.Occur.MUST);
- }
- if (criteria.getFromYear() != null || criteria.getToYear() != null) {
- NumericRangeQuery<Integer> rangeQuery = NumericRangeQuery.newIntRange(FIELD_YEAR, criteria.getFromYear(), criteria.getToYear(), true, true);
- query.add(rangeQuery, BooleanClause.Occur.MUST);
- }
- if (musicFolderPath != null) {
- query.add(new TermQuery(new Term(FIELD_FOLDER, musicFolderPath)), BooleanClause.Occur.MUST);
- }
-
- TopDocs topDocs = searcher.search(query, null, Integer.MAX_VALUE);
- Random random = new Random(System.currentTimeMillis());
-
- for (int i = 0; i < Math.min(criteria.getCount(), topDocs.totalHits); i++) {
- int index = random.nextInt(topDocs.totalHits);
- Document doc = searcher.doc(topDocs.scoreDocs[index].doc);
- int id = Integer.valueOf(doc.get(FIELD_ID));
- try {
- result.add(mediaFileService.getMediaFile(id));
- } catch (Exception x) {
- LOG.warn("Failed to get media file " + id);
- }
- }
-
- } catch (Throwable x) {
- LOG.error("Failed to search or random songs.", x);
- } finally {
- FileUtil.closeQuietly(reader);
- }
- return result;
- }
-
- private static String normalizeGenre(String genre) {
- return genre.toLowerCase().replace(" ", "");
- }
-
- /**
- * Returns a number of random albums.
- *
- * @param count Number of albums to return.
- * @return List of random albums.
- */
- public List<MediaFile> getRandomAlbums(int count) {
- List<MediaFile> result = new ArrayList<MediaFile>();
-
- IndexReader reader = null;
- try {
- reader = createIndexReader(ALBUM);
- Searcher searcher = new IndexSearcher(reader);
-
- Query query = new MatchAllDocsQuery();
- TopDocs topDocs = searcher.search(query, null, Integer.MAX_VALUE);
- Random random = new Random(System.currentTimeMillis());
-
- for (int i = 0; i < Math.min(count, topDocs.totalHits); i++) {
- int index = random.nextInt(topDocs.totalHits);
- Document doc = searcher.doc(topDocs.scoreDocs[index].doc);
- int id = Integer.valueOf(doc.get(FIELD_ID));
- try {
- addIfNotNull(mediaFileService.getMediaFile(id), result);
- } catch (Exception x) {
- LOG.warn("Failed to get media file " + id, x);
- }
- }
-
- } catch (Throwable x) {
- LOG.error("Failed to search for random albums.", x);
- } finally {
- FileUtil.closeQuietly(reader);
- }
- return result;
- }
-
- /**
- * Returns a number of random albums, using ID3 tag.
- *
- * @param count Number of albums to return.
- * @return List of random albums.
- */
- public List<Album> getRandomAlbumsId3(int count) {
- List<Album> result = new ArrayList<Album>();
-
- IndexReader reader = null;
- try {
- reader = createIndexReader(ALBUM_ID3);
- Searcher searcher = new IndexSearcher(reader);
-
- Query query = new MatchAllDocsQuery();
- TopDocs topDocs = searcher.search(query, null, Integer.MAX_VALUE);
- Random random = new Random(System.currentTimeMillis());
-
- for (int i = 0; i < Math.min(count, topDocs.totalHits); i++) {
- int index = random.nextInt(topDocs.totalHits);
- Document doc = searcher.doc(topDocs.scoreDocs[index].doc);
- int id = Integer.valueOf(doc.get(FIELD_ID));
- try {
- addIfNotNull(albumDao.getAlbum(id), result);
- } catch (Exception x) {
- LOG.warn("Failed to get album file " + id, x);
- }
- }
-
- } catch (Throwable x) {
- LOG.error("Failed to search for random albums.", x);
- } finally {
- FileUtil.closeQuietly(reader);
- }
- return result;
- }
-
- private <T> void addIfNotNull(T value, List<T> list) {
- if (value != null) {
- list.add(value);
- }
- }
- private IndexWriter createIndexWriter(IndexType indexType) throws IOException {
- File dir = getIndexDirectory(indexType);
- return new IndexWriter(FSDirectory.open(dir), new SubsonicAnalyzer(), true, new IndexWriter.MaxFieldLength(10));
- }
-
- private IndexReader createIndexReader(IndexType indexType) throws IOException {
- File dir = getIndexDirectory(indexType);
- return IndexReader.open(FSDirectory.open(dir), true);
- }
-
- private File getIndexRootDirectory() {
- return new File(SettingsService.getSubsonicHome(), "lucene2");
- }
-
- private File getIndexDirectory(IndexType indexType) {
- return new File(getIndexRootDirectory(), indexType.toString().toLowerCase());
- }
-
- private void removeLocks() {
- for (IndexType indexType : IndexType.values()) {
- Directory dir = null;
- try {
- dir = FSDirectory.open(getIndexDirectory(indexType));
- if (IndexWriter.isLocked(dir)) {
- IndexWriter.unlock(dir);
- LOG.info("Removed Lucene lock file in " + dir);
- }
- } catch (Exception x) {
- LOG.warn("Failed to remove Lucene lock file in " + dir, x);
- } finally {
- FileUtil.closeQuietly(dir);
- }
- }
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setArtistDao(ArtistDao artistDao) {
- this.artistDao = artistDao;
- }
-
- public void setAlbumDao(AlbumDao albumDao) {
- this.albumDao = albumDao;
- }
-
- public static enum IndexType {
-
- SONG(new String[]{FIELD_TITLE, FIELD_ARTIST}, FIELD_TITLE) {
- @Override
- public Document createDocument(MediaFile mediaFile) {
- Document doc = new Document();
- doc.add(new NumericField(FIELD_ID, Field.Store.YES, false).setIntValue(mediaFile.getId()));
- doc.add(new Field(FIELD_MEDIA_TYPE, mediaFile.getMediaType().name(), Field.Store.NO, Field.Index.ANALYZED_NO_NORMS));
-
- if (mediaFile.getTitle() != null) {
- doc.add(new Field(FIELD_TITLE, mediaFile.getTitle(), Field.Store.YES, Field.Index.ANALYZED));
- }
- if (mediaFile.getArtist() != null) {
- doc.add(new Field(FIELD_ARTIST, mediaFile.getArtist(), Field.Store.YES, Field.Index.ANALYZED));
- }
- if (mediaFile.getGenre() != null) {
- doc.add(new Field(FIELD_GENRE, normalizeGenre(mediaFile.getGenre()), Field.Store.NO, Field.Index.ANALYZED));
- }
- if (mediaFile.getYear() != null) {
- doc.add(new NumericField(FIELD_YEAR, Field.Store.NO, true).setIntValue(mediaFile.getYear()));
- }
- if (mediaFile.getFolder() != null) {
- doc.add(new Field(FIELD_FOLDER, mediaFile.getFolder(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
- }
-
- return doc;
- }
- },
-
- ALBUM(new String[]{FIELD_ALBUM, FIELD_ARTIST}, FIELD_ALBUM) {
- @Override
- public Document createDocument(MediaFile mediaFile) {
- Document doc = new Document();
- doc.add(new NumericField(FIELD_ID, Field.Store.YES, false).setIntValue(mediaFile.getId()));
-
- if (mediaFile.getArtist() != null) {
- doc.add(new Field(FIELD_ARTIST, mediaFile.getArtist(), Field.Store.YES, Field.Index.ANALYZED));
- }
- if (mediaFile.getAlbumName() != null) {
- doc.add(new Field(FIELD_ALBUM, mediaFile.getAlbumName(), Field.Store.YES, Field.Index.ANALYZED));
- }
-
- return doc;
- }
- },
-
- ALBUM_ID3(new String[]{FIELD_ALBUM, FIELD_ARTIST}, FIELD_ALBUM) {
- @Override
- public Document createDocument(Album album) {
- Document doc = new Document();
- doc.add(new NumericField(FIELD_ID, Field.Store.YES, false).setIntValue(album.getId()));
-
- if (album.getArtist() != null) {
- doc.add(new Field(FIELD_ARTIST, album.getArtist(), Field.Store.YES, Field.Index.ANALYZED));
- }
- if (album.getName() != null) {
- doc.add(new Field(FIELD_ALBUM, album.getName(), Field.Store.YES, Field.Index.ANALYZED));
- }
-
- return doc;
- }
- },
-
- ARTIST(new String[]{FIELD_ARTIST}, null) {
- @Override
- public Document createDocument(MediaFile mediaFile) {
- Document doc = new Document();
- doc.add(new NumericField(FIELD_ID, Field.Store.YES, false).setIntValue(mediaFile.getId()));
-
- if (mediaFile.getArtist() != null) {
- doc.add(new Field(FIELD_ARTIST, mediaFile.getArtist(), Field.Store.YES, Field.Index.ANALYZED));
- }
-
- return doc;
- }
- },
-
- ARTIST_ID3(new String[]{FIELD_ARTIST}, null) {
- @Override
- public Document createDocument(Artist artist) {
- Document doc = new Document();
- doc.add(new NumericField(FIELD_ID, Field.Store.YES, false).setIntValue(artist.getId()));
- doc.add(new Field(FIELD_ARTIST, artist.getName(), Field.Store.YES, Field.Index.ANALYZED));
-
- return doc;
- }
- };
-
- private final String[] fields;
- private final Map<String, Float> boosts;
-
- private IndexType(String[] fields, String boostedField) {
- this.fields = fields;
- boosts = new HashMap<String, Float>();
- if (boostedField != null) {
- boosts.put(boostedField, 2.0F);
- }
- }
-
- public String[] getFields() {
- return fields;
- }
-
- protected Document createDocument(MediaFile mediaFile) {
- throw new UnsupportedOperationException();
- }
-
- protected Document createDocument(Artist artist) {
- throw new UnsupportedOperationException();
- }
-
- protected Document createDocument(Album album) {
- throw new UnsupportedOperationException();
- }
-
- public Map<String, Float> getBoosts() {
- return boosts;
- }
- }
-
- private class SubsonicAnalyzer extends StandardAnalyzer {
- private SubsonicAnalyzer() {
- super(LUCENE_VERSION);
- }
-
- @Override
- public TokenStream tokenStream(String fieldName, Reader reader) {
- TokenStream result = super.tokenStream(fieldName, reader);
- return new ASCIIFoldingFilter(result);
- }
-
- @Override
- public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException {
- class SavedStreams {
- StandardTokenizer tokenStream;
- TokenStream filteredTokenStream;
- }
-
- SavedStreams streams = (SavedStreams) getPreviousTokenStream();
- if (streams == null) {
- streams = new SavedStreams();
- setPreviousTokenStream(streams);
- streams.tokenStream = new StandardTokenizer(LUCENE_VERSION, reader);
- streams.filteredTokenStream = new StandardFilter(streams.tokenStream);
- streams.filteredTokenStream = new LowerCaseFilter(streams.filteredTokenStream);
- streams.filteredTokenStream = new StopFilter(true, streams.filteredTokenStream, STOP_WORDS_SET);
- streams.filteredTokenStream = new ASCIIFoldingFilter(streams.filteredTokenStream);
- } else {
- streams.tokenStream.reset(reader);
- }
- streams.tokenStream.setMaxTokenLength(DEFAULT_MAX_TOKEN_LENGTH);
-
- return streams.filteredTokenStream;
- }
- }
-}
-
-
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SecurityService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SecurityService.java
deleted file mode 100644
index d6ca871d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SecurityService.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.File;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.acegisecurity.GrantedAuthority;
-import org.acegisecurity.GrantedAuthorityImpl;
-import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
-import org.acegisecurity.userdetails.UserDetails;
-import org.acegisecurity.userdetails.UserDetailsService;
-import org.acegisecurity.userdetails.UsernameNotFoundException;
-import org.acegisecurity.wrapper.SecurityContextHolderAwareRequestWrapper;
-import org.springframework.dao.DataAccessException;
-
-import net.sf.ehcache.Ehcache;
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.UserDao;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.User;
-import net.sourceforge.subsonic.util.FileUtil;
-
-/**
- * Provides security-related services for authentication and authorization.
- *
- * @author Sindre Mehus
- */
-public class SecurityService implements UserDetailsService {
-
- private static final Logger LOG = Logger.getLogger(SecurityService.class);
-
- private UserDao userDao;
- private SettingsService settingsService;
- private Ehcache userCache;
-
- /**
- * Locates the user based on the username.
- *
- * @param username The username presented to the {@link DaoAuthenticationProvider}
- * @return A fully populated user record (never <code>null</code>)
- * @throws UsernameNotFoundException if the user could not be found or the user has no GrantedAuthority.
- * @throws DataAccessException If user could not be found for a repository-specific reason.
- */
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
- User user = getUserByName(username);
- if (user == null) {
- throw new UsernameNotFoundException("User \"" + username + "\" was not found.");
- }
-
- String[] roles = userDao.getRolesForUser(username);
- GrantedAuthority[] authorities = new GrantedAuthority[roles.length];
- for (int i = 0; i < roles.length; i++) {
- authorities[i] = new GrantedAuthorityImpl("ROLE_" + roles[i].toUpperCase());
- }
-
- // If user is LDAP authenticated, disable user. The proper authentication should in that case
- // be done by SubsonicLdapBindAuthenticator.
- boolean enabled = !user.isLdapAuthenticated();
-
- return new org.acegisecurity.userdetails.User(username, user.getPassword(), enabled, true, true, true, authorities);
- }
-
- /**
- * Returns the currently logged-in user for the given HTTP request.
- *
- * @param request The HTTP request.
- * @return The logged-in user, or <code>null</code>.
- */
- public User getCurrentUser(HttpServletRequest request) {
- String username = getCurrentUsername(request);
- return username == null ? null : userDao.getUserByName(username);
- }
-
- /**
- * Returns the name of the currently logged-in user.
- *
- * @param request The HTTP request.
- * @return The name of the logged-in user, or <code>null</code>.
- */
- public String getCurrentUsername(HttpServletRequest request) {
- return new SecurityContextHolderAwareRequestWrapper(request, null).getRemoteUser();
- }
-
- /**
- * Returns the user with the given username.
- *
- * @param username The username used when logging in.
- * @return The user, or <code>null</code> if not found.
- */
- public User getUserByName(String username) {
- return userDao.getUserByName(username);
- }
-
- /**
- * Returns the user with the given email address.
- *
- * @param email The email address.
- * @return The user, or <code>null</code> if not found.
- */
- public User getUserByEmail(String email) {
- return userDao.getUserByEmail(email);
- }
-
- /**
- * Returns all users.
- *
- * @return Possibly empty array of all users.
- */
- public List<User> getAllUsers() {
- return userDao.getAllUsers();
- }
-
- /**
- * Returns whether the given user has administrative rights.
- */
- public boolean isAdmin(String username) {
- if (User.USERNAME_ADMIN.equals(username)) {
- return true;
- }
- User user = getUserByName(username);
- return user != null && user.isAdminRole();
- }
-
- /**
- * Creates a new user.
- *
- * @param user The user to create.
- */
- public void createUser(User user) {
- userDao.createUser(user);
- LOG.info("Created user " + user.getUsername());
- }
-
- /**
- * Deletes the user with the given username.
- *
- * @param username The username.
- */
- public void deleteUser(String username) {
- userDao.deleteUser(username);
- LOG.info("Deleted user " + username);
- userCache.remove(username);
- }
-
- /**
- * Updates the given user.
- *
- * @param user The user to update.
- */
- public void updateUser(User user) {
- userDao.updateUser(user);
- userCache.remove(user.getUsername());
- }
-
- /**
- * Updates the byte counts for given user.
- *
- * @param user The user to update, may be <code>null</code>.
- * @param bytesStreamedDelta Increment bytes streamed count with this value.
- * @param bytesDownloadedDelta Increment bytes downloaded count with this value.
- * @param bytesUploadedDelta Increment bytes uploaded count with this value.
- */
- public void updateUserByteCounts(User user, long bytesStreamedDelta, long bytesDownloadedDelta, long bytesUploadedDelta) {
- if (user == null) {
- return;
- }
-
- user.setBytesStreamed(user.getBytesStreamed() + bytesStreamedDelta);
- user.setBytesDownloaded(user.getBytesDownloaded() + bytesDownloadedDelta);
- user.setBytesUploaded(user.getBytesUploaded() + bytesUploadedDelta);
-
- userDao.updateUser(user);
- }
-
- /**
- * Returns whether the given file may be read.
- *
- * @return Whether the given file may be read.
- */
- public boolean isReadAllowed(File file) {
- // Allowed to read from both music folder and podcast folder.
- return isInMusicFolder(file) || isInPodcastFolder(file);
- }
-
- /**
- * Returns whether the given file may be written, created or deleted.
- *
- * @return Whether the given file may be written, created or deleted.
- */
- public boolean isWriteAllowed(File file) {
- // Only allowed to write podcasts or cover art.
- boolean isPodcast = isInPodcastFolder(file);
- boolean isCoverArt = isInMusicFolder(file) && file.getName().startsWith("cover.");
-
- return isPodcast || isCoverArt;
- }
-
- /**
- * Returns whether the given file may be uploaded.
- *
- * @return Whether the given file may be uploaded.
- */
- public boolean isUploadAllowed(File file) {
- return isInMusicFolder(file) && !FileUtil.exists(file);
- }
-
- /**
- * Returns whether the given file is located in one of the music folders (or any of their sub-folders).
- *
- * @param file The file in question.
- * @return Whether the given file is located in one of the music folders.
- */
- private boolean isInMusicFolder(File file) {
- return getMusicFolderForFile(file) != null;
- }
-
- private MusicFolder getMusicFolderForFile(File file) {
- List<MusicFolder> folders = settingsService.getAllMusicFolders(false, true);
- String path = file.getPath();
- for (MusicFolder folder : folders) {
- if (isFileInFolder(path, folder.getPath().getPath())) {
- return folder;
- }
- }
- return null;
- }
-
- /**
- * Returns whether the given file is located in the Podcast folder (or any of its sub-folders).
- *
- * @param file The file in question.
- * @return Whether the given file is located in the Podcast folder.
- */
- private boolean isInPodcastFolder(File file) {
- String podcastFolder = settingsService.getPodcastFolder();
- return isFileInFolder(file.getPath(), podcastFolder);
- }
-
- public String getRootFolderForFile(File file) {
- MusicFolder folder = getMusicFolderForFile(file);
- if (folder != null) {
- return folder.getPath().getPath();
- }
-
- if (isInPodcastFolder(file)) {
- return settingsService.getPodcastFolder();
- }
- return null;
- }
-
- /**
- * Returns whether the given file is located in the given folder (or any of its sub-folders).
- * If the given file contains the expression ".." (indicating a reference to the parent directory),
- * this method will return <code>false</code>.
- *
- * @param file The file in question.
- * @param folder The folder in question.
- * @return Whether the given file is located in the given folder.
- */
- protected boolean isFileInFolder(String file, String folder) {
- // Deny access if file contains ".." surrounded by slashes (or end of line).
- if (file.matches(".*(/|\\\\)\\.\\.(/|\\\\|$).*")) {
- return false;
- }
-
- // Convert slashes.
- file = file.replace('\\', '/');
- folder = folder.replace('\\', '/');
-
- return file.toUpperCase().startsWith(folder.toUpperCase());
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setUserDao(UserDao userDao) {
- this.userDao = userDao;
- }
-
- public void setUserCache(Ehcache userCache) {
- this.userCache = userCache;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/ServiceLocator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/ServiceLocator.java
deleted file mode 100644
index 4a7f95b4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/ServiceLocator.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import javax.xml.parsers.SAXParser;
-
-import net.sourceforge.subsonic.service.metadata.MetaDataParserFactory;
-
-/**
- * Locates services for objects that are not part of the Spring context.
- *
- * @author Sindre Mehus
- */
-@Deprecated
-public class ServiceLocator {
-
- private static SettingsService settingsService;
-
- private ServiceLocator() {
- }
-
- public static SettingsService getSettingsService() {
- return settingsService;
- }
-
- public static void setSettingsService(SettingsService settingsService) {
- ServiceLocator.settingsService = settingsService;
- }
-}
-
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SettingsService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SettingsService.java
deleted file mode 100644
index a0b3e8d5..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/SettingsService.java
+++ /dev/null
@@ -1,1225 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.BasicResponseHandler;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.AvatarDao;
-import net.sourceforge.subsonic.dao.InternetRadioDao;
-import net.sourceforge.subsonic.dao.MusicFolderDao;
-import net.sourceforge.subsonic.dao.UserDao;
-import net.sourceforge.subsonic.domain.Avatar;
-import net.sourceforge.subsonic.domain.InternetRadio;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.domain.Theme;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.util.FileUtil;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.Util;
-
-/**
- * Provides persistent storage of application settings and preferences.
- *
- * @author Sindre Mehus
- */
-public class SettingsService {
-
- // Subsonic home directory.
- private static final File SUBSONIC_HOME_WINDOWS = new File("c:/subsonic");
- private static final File SUBSONIC_HOME_OTHER = new File("/var/subsonic");
-
- // Global settings.
- private static final String KEY_INDEX_STRING = "IndexString";
- private static final String KEY_IGNORED_ARTICLES = "IgnoredArticles";
- private static final String KEY_SHORTCUTS = "Shortcuts";
- private static final String KEY_PLAYLIST_FOLDER = "PlaylistFolder";
- private static final String KEY_MUSIC_FILE_TYPES = "MusicFileTypes";
- private static final String KEY_VIDEO_FILE_TYPES = "VideoFileTypes";
- private static final String KEY_COVER_ART_FILE_TYPES = "CoverArtFileTypes";
- private static final String KEY_COVER_ART_LIMIT = "CoverArtLimit";
- private static final String KEY_WELCOME_TITLE = "WelcomeTitle";
- private static final String KEY_WELCOME_SUBTITLE = "WelcomeSubtitle";
- private static final String KEY_WELCOME_MESSAGE = "WelcomeMessage2";
- private static final String KEY_LOGIN_MESSAGE = "LoginMessage";
- private static final String KEY_LOCALE_LANGUAGE = "LocaleLanguage";
- private static final String KEY_LOCALE_COUNTRY = "LocaleCountry";
- private static final String KEY_LOCALE_VARIANT = "LocaleVariant";
- private static final String KEY_THEME_ID = "Theme";
- private static final String KEY_INDEX_CREATION_INTERVAL = "IndexCreationInterval";
- private static final String KEY_INDEX_CREATION_HOUR = "IndexCreationHour";
- private static final String KEY_FAST_CACHE_ENABLED = "FastCacheEnabled";
- private static final String KEY_PODCAST_UPDATE_INTERVAL = "PodcastUpdateInterval";
- private static final String KEY_PODCAST_FOLDER = "PodcastFolder";
- private static final String KEY_PODCAST_EPISODE_RETENTION_COUNT = "PodcastEpisodeRetentionCount";
- private static final String KEY_PODCAST_EPISODE_DOWNLOAD_COUNT = "PodcastEpisodeDownloadCount";
- private static final String KEY_DOWNLOAD_BITRATE_LIMIT = "DownloadBitrateLimit";
- private static final String KEY_UPLOAD_BITRATE_LIMIT = "UploadBitrateLimit";
- private static final String KEY_STREAM_PORT = "StreamPort";
- private static final String KEY_LICENSE_EMAIL = "LicenseEmail";
- private static final String KEY_LICENSE_CODE = "LicenseCode";
- private static final String KEY_LICENSE_DATE = "LicenseDate";
- private static final String KEY_DOWNSAMPLING_COMMAND = "DownsamplingCommand3";
- private static final String KEY_JUKEBOX_COMMAND = "JukeboxCommand";
- private static final String KEY_REWRITE_URL = "RewriteUrl";
- private static final String KEY_LDAP_ENABLED = "LdapEnabled";
- private static final String KEY_LDAP_URL = "LdapUrl";
- private static final String KEY_LDAP_MANAGER_DN = "LdapManagerDn";
- private static final String KEY_LDAP_MANAGER_PASSWORD = "LdapManagerPassword";
- private static final String KEY_LDAP_SEARCH_FILTER = "LdapSearchFilter";
- private static final String KEY_LDAP_AUTO_SHADOWING = "LdapAutoShadowing";
- private static final String KEY_GETTING_STARTED_ENABLED = "GettingStartedEnabled";
- private static final String KEY_PORT_FORWARDING_ENABLED = "PortForwardingEnabled";
- private static final String KEY_PORT = "Port";
- private static final String KEY_HTTPS_PORT = "HttpsPort";
- private static final String KEY_URL_REDIRECTION_ENABLED = "UrlRedirectionEnabled";
- private static final String KEY_URL_REDIRECT_FROM = "UrlRedirectFrom";
- private static final String KEY_URL_REDIRECT_TRIAL_EXPIRES = "UrlRedirectTrialExpires";
- private static final String KEY_URL_REDIRECT_CONTEXT_PATH = "UrlRedirectContextPath";
- private static final String KEY_REST_TRIAL_EXPIRES = "RestTrialExpires-";
- private static final String KEY_VIDEO_TRIAL_EXPIRES = "VideoTrialExpires";
- private static final String KEY_SERVER_ID = "ServerId";
- private static final String KEY_SETTINGS_CHANGED = "SettingsChanged";
- private static final String KEY_LAST_SCANNED = "LastScanned";
- private static final String KEY_ORGANIZE_BY_FOLDER_STRUCTURE = "OrganizeByFolderStructure";
- private static final String KEY_SORT_ALBUMS_BY_YEAR = "SortAlbumsByYear";
-
- // Default values.
- private static final String DEFAULT_INDEX_STRING = "A B C D E F G H I J K L M N O P Q R S T U V W X-Z(XYZ)";
- private static final String DEFAULT_IGNORED_ARTICLES = "The El La Los Las Le Les";
- private static final String DEFAULT_SHORTCUTS = "New Incoming Podcast";
- private static final String DEFAULT_PLAYLIST_FOLDER = Util.getDefaultPlaylistFolder();
- private static final String DEFAULT_MUSIC_FILE_TYPES = "mp3 ogg oga aac m4a flac wav wma aif aiff ape mpc shn";
- private static final String DEFAULT_VIDEO_FILE_TYPES = "flv avi mpg mpeg mp4 m4v mkv mov wmv ogv divx m2ts";
- private static final String DEFAULT_COVER_ART_FILE_TYPES = "cover.jpg folder.jpg jpg jpeg gif png";
- private static final int DEFAULT_COVER_ART_LIMIT = 30;
- private static final String DEFAULT_WELCOME_TITLE = "Welcome to Subsonic!";
- private static final String DEFAULT_WELCOME_SUBTITLE = null;
- private static final String DEFAULT_WELCOME_MESSAGE = "__Welcome to Subsonic!__\n" +
- "\\\\ \\\\\n" +
- "Subsonic is a free, web-based media streamer, providing ubiquitous access to your music. \n" +
- "\\\\ \\\\\n" +
- "Use it to share your music with friends, or to listen to your own music while at work. You can stream to multiple " +
- "players simultaneously, for instance to one player in your kitchen and another in your living room.\n" +
- "\\\\ \\\\\n" +
- "To change or remove this message, log in with administrator rights and go to {link:Settings > General|generalSettings.view}.";
- private static final String DEFAULT_LOGIN_MESSAGE = null;
- private static final String DEFAULT_LOCALE_LANGUAGE = "en";
- private static final String DEFAULT_LOCALE_COUNTRY = "";
- private static final String DEFAULT_LOCALE_VARIANT = "";
- private static final String DEFAULT_THEME_ID = "default";
- private static final int DEFAULT_INDEX_CREATION_INTERVAL = 1;
- private static final int DEFAULT_INDEX_CREATION_HOUR = 3;
- private static final boolean DEFAULT_FAST_CACHE_ENABLED = false;
- private static final int DEFAULT_PODCAST_UPDATE_INTERVAL = 24;
- private static final String DEFAULT_PODCAST_FOLDER = Util.getDefaultPodcastFolder();
- private static final int DEFAULT_PODCAST_EPISODE_RETENTION_COUNT = 10;
- private static final int DEFAULT_PODCAST_EPISODE_DOWNLOAD_COUNT = 1;
- private static final long DEFAULT_DOWNLOAD_BITRATE_LIMIT = 0;
- private static final long DEFAULT_UPLOAD_BITRATE_LIMIT = 0;
- private static final long DEFAULT_STREAM_PORT = 0;
- private static final String DEFAULT_LICENSE_EMAIL = null;
- private static final String DEFAULT_LICENSE_CODE = null;
- private static final String DEFAULT_LICENSE_DATE = null;
- private static final String DEFAULT_DOWNSAMPLING_COMMAND = "ffmpeg -i %s -ab %bk -v 0 -f mp3 -";
- private static final String DEFAULT_JUKEBOX_COMMAND = "ffmpeg -ss %o -i %s -v 0 -f au -";
- private static final boolean DEFAULT_REWRITE_URL = true;
- private static final boolean DEFAULT_LDAP_ENABLED = false;
- private static final String DEFAULT_LDAP_URL = "ldap://host.domain.com:389/cn=Users,dc=domain,dc=com";
- private static final String DEFAULT_LDAP_MANAGER_DN = null;
- private static final String DEFAULT_LDAP_MANAGER_PASSWORD = null;
- private static final String DEFAULT_LDAP_SEARCH_FILTER = "(sAMAccountName={0})";
- private static final boolean DEFAULT_LDAP_AUTO_SHADOWING = false;
- private static final boolean DEFAULT_PORT_FORWARDING_ENABLED = false;
- private static final boolean DEFAULT_GETTING_STARTED_ENABLED = true;
- private static final int DEFAULT_PORT = 80;
- private static final int DEFAULT_HTTPS_PORT = 0;
- private static final boolean DEFAULT_URL_REDIRECTION_ENABLED = false;
- private static final String DEFAULT_URL_REDIRECT_FROM = "yourname";
- private static final String DEFAULT_URL_REDIRECT_TRIAL_EXPIRES = null;
- private static final String DEFAULT_URL_REDIRECT_CONTEXT_PATH = null;
- private static final String DEFAULT_REST_TRIAL_EXPIRES = null;
- private static final String DEFAULT_VIDEO_TRIAL_EXPIRES = null;
- private static final String DEFAULT_SERVER_ID = null;
- private static final long DEFAULT_SETTINGS_CHANGED = 0L;
- private static final boolean DEFAULT_ORGANIZE_BY_FOLDER_STRUCTURE = true;
- private static final boolean DEFAULT_SORT_ALBUMS_BY_YEAR = true;
-
- // Array of obsolete keys. Used to clean property file.
- private static final List<String> OBSOLETE_KEYS = Arrays.asList("PortForwardingPublicPort", "PortForwardingLocalPort",
- "DownsamplingCommand", "DownsamplingCommand2", "AutoCoverBatch", "MusicMask", "VideoMask", "CoverArtMask");
-
- private static final String LOCALES_FILE = "/net/sourceforge/subsonic/i18n/locales.txt";
- private static final String THEMES_FILE = "/net/sourceforge/subsonic/theme/themes.txt";
-
- private static final Logger LOG = Logger.getLogger(SettingsService.class);
-
- private Properties properties = new Properties();
- private List<Theme> themes;
- private List<Locale> locales;
- private InternetRadioDao internetRadioDao;
- private MusicFolderDao musicFolderDao;
- private UserDao userDao;
- private AvatarDao avatarDao;
- private VersionService versionService;
-
- private String[] cachedCoverArtFileTypesArray;
- private String[] cachedMusicFileTypesArray;
- private String[] cachedVideoFileTypesArray;
- private List<MusicFolder> cachedMusicFolders;
-
- private static File subsonicHome;
-
- private boolean licenseValidated = true;
-
- public SettingsService() {
- File propertyFile = getPropertyFile();
-
- if (propertyFile.exists()) {
- FileInputStream in = null;
- try {
- in = new FileInputStream(propertyFile);
- properties.load(in);
- } catch (Exception x) {
- LOG.error("Unable to read from property file.", x);
- } finally {
- IOUtils.closeQuietly(in);
- }
-
- // Remove obsolete properties.
- for (Iterator<Object> iterator = properties.keySet().iterator(); iterator.hasNext();) {
- String key = (String) iterator.next();
- if (OBSOLETE_KEYS.contains(key)) {
- LOG.debug("Removing obsolete property [" + key + ']');
- iterator.remove();
- }
- }
- }
-
- save(false);
- }
-
- /**
- * Register in service locator so that non-Spring objects can access me.
- * This method is invoked automatically by Spring.
- */
- public void init() {
- ServiceLocator.setSettingsService(this);
- validateLicenseAsync();
- }
-
- public void save() {
- save(true);
- }
-
- public void save(boolean updateChangedDate) {
- if (updateChangedDate) {
- setProperty(KEY_SETTINGS_CHANGED, String.valueOf(System.currentTimeMillis()));
- }
-
- OutputStream out = null;
- try {
- out = new FileOutputStream(getPropertyFile());
- properties.store(out, "Subsonic preferences. NOTE: This file is automatically generated.");
- } catch (Exception x) {
- LOG.error("Unable to write to property file.", x);
- } finally {
- IOUtils.closeQuietly(out);
- }
- }
-
- private File getPropertyFile() {
- return new File(getSubsonicHome(), "subsonic.properties");
- }
-
- /**
- * Returns the Subsonic home directory.
- *
- * @return The Subsonic home directory, if it exists.
- * @throws RuntimeException If directory doesn't exist.
- */
- public static synchronized File getSubsonicHome() {
-
- if (subsonicHome != null) {
- return subsonicHome;
- }
-
- File home;
-
- String overrideHome = System.getProperty("subsonic.home");
- if (overrideHome != null) {
- home = new File(overrideHome);
- } else {
- boolean isWindows = System.getProperty("os.name", "Windows").toLowerCase().startsWith("windows");
- home = isWindows ? SUBSONIC_HOME_WINDOWS : SUBSONIC_HOME_OTHER;
- }
-
- // Attempt to create home directory if it doesn't exist.
- if (!home.exists() || !home.isDirectory()) {
- boolean success = home.mkdirs();
- if (success) {
- subsonicHome = home;
- } else {
- String message = "The directory " + home + " does not exist. Please create it and make it writable. " +
- "(You can override the directory location by specifying -Dsubsonic.home=... when " +
- "starting the servlet container.)";
- System.err.println("ERROR: " + message);
- }
- } else {
- subsonicHome = home;
- }
-
- return home;
- }
-
- private boolean getBoolean(String key, boolean defaultValue) {
- return Boolean.valueOf(properties.getProperty(key, String.valueOf(defaultValue)));
- }
-
- private void setBoolean(String key, boolean value) {
- setProperty(key, String.valueOf(value));
- }
-
- public String getIndexString() {
- return properties.getProperty(KEY_INDEX_STRING, DEFAULT_INDEX_STRING);
- }
-
- public void setIndexString(String indexString) {
- setProperty(KEY_INDEX_STRING, indexString);
- }
-
- public String getIgnoredArticles() {
- return properties.getProperty(KEY_IGNORED_ARTICLES, DEFAULT_IGNORED_ARTICLES);
- }
-
- public String[] getIgnoredArticlesAsArray() {
- return getIgnoredArticles().split("\\s+");
- }
-
- public void setIgnoredArticles(String ignoredArticles) {
- setProperty(KEY_IGNORED_ARTICLES, ignoredArticles);
- }
-
- public String getShortcuts() {
- return properties.getProperty(KEY_SHORTCUTS, DEFAULT_SHORTCUTS);
- }
-
- public String[] getShortcutsAsArray() {
- return StringUtil.split(getShortcuts());
- }
-
- public void setShortcuts(String shortcuts) {
- setProperty(KEY_SHORTCUTS, shortcuts);
- }
-
- public String getPlaylistFolder() {
- return properties.getProperty(KEY_PLAYLIST_FOLDER, DEFAULT_PLAYLIST_FOLDER);
- }
-
- public String getMusicFileTypes() {
- return properties.getProperty(KEY_MUSIC_FILE_TYPES, DEFAULT_MUSIC_FILE_TYPES);
- }
-
- public synchronized void setMusicFileTypes(String fileTypes) {
- setProperty(KEY_MUSIC_FILE_TYPES, fileTypes);
- cachedMusicFileTypesArray = null;
- }
-
- public synchronized String[] getMusicFileTypesAsArray() {
- if (cachedMusicFileTypesArray == null) {
- cachedMusicFileTypesArray = toStringArray(getMusicFileTypes());
- }
- return cachedMusicFileTypesArray;
- }
-
- public String getVideoFileTypes() {
- return properties.getProperty(KEY_VIDEO_FILE_TYPES, DEFAULT_VIDEO_FILE_TYPES);
- }
-
- public synchronized void setVideoFileTypes(String fileTypes) {
- setProperty(KEY_VIDEO_FILE_TYPES, fileTypes);
- cachedVideoFileTypesArray = null;
- }
-
- public synchronized String[] getVideoFileTypesAsArray() {
- if (cachedVideoFileTypesArray == null) {
- cachedVideoFileTypesArray = toStringArray(getVideoFileTypes());
- }
- return cachedVideoFileTypesArray;
- }
-
- public String getCoverArtFileTypes() {
- return properties.getProperty(KEY_COVER_ART_FILE_TYPES, DEFAULT_COVER_ART_FILE_TYPES);
- }
-
- public synchronized void setCoverArtFileTypes(String fileTypes) {
- setProperty(KEY_COVER_ART_FILE_TYPES, fileTypes);
- cachedCoverArtFileTypesArray = null;
- }
-
- public synchronized String[] getCoverArtFileTypesAsArray() {
- if (cachedCoverArtFileTypesArray == null) {
- cachedCoverArtFileTypesArray = toStringArray(getCoverArtFileTypes());
- }
- return cachedCoverArtFileTypesArray;
- }
-
- public int getCoverArtLimit() {
- return Integer.parseInt(properties.getProperty(KEY_COVER_ART_LIMIT, "" + DEFAULT_COVER_ART_LIMIT));
- }
-
- public void setCoverArtLimit(int limit) {
- setProperty(KEY_COVER_ART_LIMIT, "" + limit);
- }
-
- public String getWelcomeTitle() {
- return StringUtils.trimToNull(properties.getProperty(KEY_WELCOME_TITLE, DEFAULT_WELCOME_TITLE));
- }
-
- public void setWelcomeTitle(String title) {
- setProperty(KEY_WELCOME_TITLE, title);
- }
-
- public String getWelcomeSubtitle() {
- return StringUtils.trimToNull(properties.getProperty(KEY_WELCOME_SUBTITLE, DEFAULT_WELCOME_SUBTITLE));
- }
-
- public void setWelcomeSubtitle(String subtitle) {
- setProperty(KEY_WELCOME_SUBTITLE, subtitle);
- }
-
- public String getWelcomeMessage() {
- return StringUtils.trimToNull(properties.getProperty(KEY_WELCOME_MESSAGE, DEFAULT_WELCOME_MESSAGE));
- }
-
- public void setWelcomeMessage(String message) {
- setProperty(KEY_WELCOME_MESSAGE, message);
- }
-
- public String getLoginMessage() {
- return StringUtils.trimToNull(properties.getProperty(KEY_LOGIN_MESSAGE, DEFAULT_LOGIN_MESSAGE));
- }
-
- public void setLoginMessage(String message) {
- setProperty(KEY_LOGIN_MESSAGE, message);
- }
-
- /**
- * Returns the number of days between automatic index creation, of -1 if automatic index
- * creation is disabled.
- */
- public int getIndexCreationInterval() {
- return Integer.parseInt(properties.getProperty(KEY_INDEX_CREATION_INTERVAL, "" + DEFAULT_INDEX_CREATION_INTERVAL));
- }
-
- /**
- * Sets the number of days between automatic index creation, of -1 if automatic index
- * creation is disabled.
- */
- public void setIndexCreationInterval(int days) {
- setProperty(KEY_INDEX_CREATION_INTERVAL, String.valueOf(days));
- }
-
- /**
- * Returns the hour of day (0 - 23) when automatic index creation should run.
- */
- public int getIndexCreationHour() {
- return Integer.parseInt(properties.getProperty(KEY_INDEX_CREATION_HOUR, String.valueOf(DEFAULT_INDEX_CREATION_HOUR)));
- }
-
- /**
- * Sets the hour of day (0 - 23) when automatic index creation should run.
- */
- public void setIndexCreationHour(int hour) {
- setProperty(KEY_INDEX_CREATION_HOUR, String.valueOf(hour));
- }
-
- public boolean isFastCacheEnabled() {
- return getBoolean(KEY_FAST_CACHE_ENABLED, DEFAULT_FAST_CACHE_ENABLED);
- }
-
- public void setFastCacheEnabled(boolean enabled) {
- setBoolean(KEY_FAST_CACHE_ENABLED, enabled);
- }
-
- /**
- * Returns the number of hours between Podcast updates, of -1 if automatic updates
- * are disabled.
- */
- public int getPodcastUpdateInterval() {
- return Integer.parseInt(properties.getProperty(KEY_PODCAST_UPDATE_INTERVAL, String.valueOf(DEFAULT_PODCAST_UPDATE_INTERVAL)));
- }
-
- /**
- * Sets the number of hours between Podcast updates, of -1 if automatic updates
- * are disabled.
- */
- public void setPodcastUpdateInterval(int hours) {
- setProperty(KEY_PODCAST_UPDATE_INTERVAL, String.valueOf(hours));
- }
-
- /**
- * Returns the number of Podcast episodes to keep (-1 to keep all).
- */
- public int getPodcastEpisodeRetentionCount() {
- return Integer.parseInt(properties.getProperty(KEY_PODCAST_EPISODE_RETENTION_COUNT, String.valueOf(DEFAULT_PODCAST_EPISODE_RETENTION_COUNT)));
- }
-
- /**
- * Sets the number of Podcast episodes to keep (-1 to keep all).
- */
- public void setPodcastEpisodeRetentionCount(int count) {
- setProperty(KEY_PODCAST_EPISODE_RETENTION_COUNT, String.valueOf(count));
- }
-
- /**
- * Returns the number of Podcast episodes to download (-1 to download all).
- */
- public int getPodcastEpisodeDownloadCount() {
- return Integer.parseInt(properties.getProperty(KEY_PODCAST_EPISODE_DOWNLOAD_COUNT, String.valueOf(DEFAULT_PODCAST_EPISODE_DOWNLOAD_COUNT)));
- }
-
- /**
- * Sets the number of Podcast episodes to download (-1 to download all).
- */
- public void setPodcastEpisodeDownloadCount(int count) {
- setProperty(KEY_PODCAST_EPISODE_DOWNLOAD_COUNT, String.valueOf(count));
- }
-
- /**
- * Returns the Podcast download folder.
- */
- public String getPodcastFolder() {
- return properties.getProperty(KEY_PODCAST_FOLDER, DEFAULT_PODCAST_FOLDER);
- }
-
- /**
- * Sets the Podcast download folder.
- */
- public void setPodcastFolder(String folder) {
- setProperty(KEY_PODCAST_FOLDER, folder);
- }
-
- /**
- * @return The download bitrate limit in Kbit/s. Zero if unlimited.
- */
- public long getDownloadBitrateLimit() {
- return Long.parseLong(properties.getProperty(KEY_DOWNLOAD_BITRATE_LIMIT, "" + DEFAULT_DOWNLOAD_BITRATE_LIMIT));
- }
-
- /**
- * @param limit The download bitrate limit in Kbit/s. Zero if unlimited.
- */
- public void setDownloadBitrateLimit(long limit) {
- setProperty(KEY_DOWNLOAD_BITRATE_LIMIT, "" + limit);
- }
-
- /**
- * @return The upload bitrate limit in Kbit/s. Zero if unlimited.
- */
- public long getUploadBitrateLimit() {
- return Long.parseLong(properties.getProperty(KEY_UPLOAD_BITRATE_LIMIT, "" + DEFAULT_UPLOAD_BITRATE_LIMIT));
- }
-
- /**
- * @param limit The upload bitrate limit in Kbit/s. Zero if unlimited.
- */
- public void setUploadBitrateLimit(long limit) {
- setProperty(KEY_UPLOAD_BITRATE_LIMIT, "" + limit);
- }
-
- /**
- * @return The non-SSL stream port. Zero if disabled.
- */
- public int getStreamPort() {
- return Integer.parseInt(properties.getProperty(KEY_STREAM_PORT, "" + DEFAULT_STREAM_PORT));
- }
-
- /**
- * @param port The non-SSL stream port. Zero if disabled.
- */
- public void setStreamPort(int port) {
- setProperty(KEY_STREAM_PORT, "" + port);
- }
-
- public String getLicenseEmail() {
- return properties.getProperty(KEY_LICENSE_EMAIL, DEFAULT_LICENSE_EMAIL);
- }
-
- public void setLicenseEmail(String email) {
- setProperty(KEY_LICENSE_EMAIL, email);
- }
-
- public String getLicenseCode() {
- return properties.getProperty(KEY_LICENSE_CODE, DEFAULT_LICENSE_CODE);
- }
-
- public void setLicenseCode(String code) {
- setProperty(KEY_LICENSE_CODE, code);
- }
-
- public Date getLicenseDate() {
- String value = properties.getProperty(KEY_LICENSE_DATE, DEFAULT_LICENSE_DATE);
- return value == null ? null : new Date(Long.parseLong(value));
- }
-
- public void setLicenseDate(Date date) {
- String value = (date == null ? null : String.valueOf(date.getTime()));
- setProperty(KEY_LICENSE_DATE, value);
- }
-
- public boolean isLicenseValid() {
- return true;
- }
-
- public boolean isLicenseValid(String email, String license) {
- return true;
- }
-
- public String getDownsamplingCommand() {
- return properties.getProperty(KEY_DOWNSAMPLING_COMMAND, DEFAULT_DOWNSAMPLING_COMMAND);
- }
-
- public void setDownsamplingCommand(String command) {
- setProperty(KEY_DOWNSAMPLING_COMMAND, command);
- }
-
- public String getJukeboxCommand() {
- return properties.getProperty(KEY_JUKEBOX_COMMAND, DEFAULT_JUKEBOX_COMMAND);
- }
-
- public boolean isRewriteUrlEnabled() {
- return getBoolean(KEY_REWRITE_URL, DEFAULT_REWRITE_URL);
- }
-
- public void setRewriteUrlEnabled(boolean rewriteUrl) {
- setBoolean(KEY_REWRITE_URL, rewriteUrl);
- }
-
- public boolean isLdapEnabled() {
- return getBoolean(KEY_LDAP_ENABLED, DEFAULT_LDAP_ENABLED);
- }
-
- public void setLdapEnabled(boolean ldapEnabled) {
- setBoolean(KEY_LDAP_ENABLED, ldapEnabled);
- }
-
- public String getLdapUrl() {
- return properties.getProperty(KEY_LDAP_URL, DEFAULT_LDAP_URL);
- }
-
- public void setLdapUrl(String ldapUrl) {
- properties.setProperty(KEY_LDAP_URL, ldapUrl);
- }
-
- public String getLdapSearchFilter() {
- return properties.getProperty(KEY_LDAP_SEARCH_FILTER, DEFAULT_LDAP_SEARCH_FILTER);
- }
-
- public void setLdapSearchFilter(String ldapSearchFilter) {
- properties.setProperty(KEY_LDAP_SEARCH_FILTER, ldapSearchFilter);
- }
-
- public String getLdapManagerDn() {
- return properties.getProperty(KEY_LDAP_MANAGER_DN, DEFAULT_LDAP_MANAGER_DN);
- }
-
- public void setLdapManagerDn(String ldapManagerDn) {
- properties.setProperty(KEY_LDAP_MANAGER_DN, ldapManagerDn);
- }
-
- public String getLdapManagerPassword() {
- String s = properties.getProperty(KEY_LDAP_MANAGER_PASSWORD, DEFAULT_LDAP_MANAGER_PASSWORD);
- try {
- return StringUtil.utf8HexDecode(s);
- } catch (Exception x) {
- LOG.warn("Failed to decode LDAP manager password.", x);
- return s;
- }
- }
-
- public void setLdapManagerPassword(String ldapManagerPassword) {
- try {
- ldapManagerPassword = StringUtil.utf8HexEncode(ldapManagerPassword);
- } catch (Exception x) {
- LOG.warn("Failed to encode LDAP manager password.", x);
- }
- properties.setProperty(KEY_LDAP_MANAGER_PASSWORD, ldapManagerPassword);
- }
-
- public boolean isLdapAutoShadowing() {
- return getBoolean(KEY_LDAP_AUTO_SHADOWING, DEFAULT_LDAP_AUTO_SHADOWING);
- }
-
- public void setLdapAutoShadowing(boolean ldapAutoShadowing) {
- setBoolean(KEY_LDAP_AUTO_SHADOWING, ldapAutoShadowing);
- }
-
- public boolean isGettingStartedEnabled() {
- return getBoolean(KEY_GETTING_STARTED_ENABLED, DEFAULT_GETTING_STARTED_ENABLED);
- }
-
- public void setGettingStartedEnabled(boolean isGettingStartedEnabled) {
- setBoolean(KEY_GETTING_STARTED_ENABLED, isGettingStartedEnabled);
- }
-
- public boolean isPortForwardingEnabled() {
- return getBoolean(KEY_PORT_FORWARDING_ENABLED, DEFAULT_PORT_FORWARDING_ENABLED);
- }
-
- public void setPortForwardingEnabled(boolean isPortForwardingEnabled) {
- setBoolean(KEY_PORT_FORWARDING_ENABLED, isPortForwardingEnabled);
- }
-
- public int getPort() {
- return Integer.valueOf(properties.getProperty(KEY_PORT, String.valueOf(DEFAULT_PORT)));
- }
-
- public void setPort(int port) {
- setProperty(KEY_PORT, String.valueOf(port));
- }
-
- public int getHttpsPort() {
- return Integer.valueOf(properties.getProperty(KEY_HTTPS_PORT, String.valueOf(DEFAULT_HTTPS_PORT)));
- }
-
- public void setHttpsPort(int httpsPort) {
- setProperty(KEY_HTTPS_PORT, String.valueOf(httpsPort));
- }
-
- public boolean isUrlRedirectionEnabled() {
- return getBoolean(KEY_URL_REDIRECTION_ENABLED, DEFAULT_URL_REDIRECTION_ENABLED);
- }
-
- public void setUrlRedirectionEnabled(boolean isUrlRedirectionEnabled) {
- setBoolean(KEY_URL_REDIRECTION_ENABLED, isUrlRedirectionEnabled);
- }
-
- public String getUrlRedirectFrom() {
- return properties.getProperty(KEY_URL_REDIRECT_FROM, DEFAULT_URL_REDIRECT_FROM);
- }
-
- public void setUrlRedirectFrom(String urlRedirectFrom) {
- properties.setProperty(KEY_URL_REDIRECT_FROM, urlRedirectFrom);
- }
-
- public Date getUrlRedirectTrialExpires() {
- String value = properties.getProperty(KEY_URL_REDIRECT_TRIAL_EXPIRES, DEFAULT_URL_REDIRECT_TRIAL_EXPIRES);
- return value == null ? null : new Date(Long.parseLong(value));
- }
-
- public void setUrlRedirectTrialExpires(Date date) {
- String value = (date == null ? null : String.valueOf(date.getTime()));
- setProperty(KEY_URL_REDIRECT_TRIAL_EXPIRES, value);
- }
-
- public Date getVideoTrialExpires() {
- String value = properties.getProperty(KEY_VIDEO_TRIAL_EXPIRES, DEFAULT_VIDEO_TRIAL_EXPIRES);
- return value == null ? null : new Date(Long.parseLong(value));
- }
-
- public void setVideoTrialExpires(Date date) {
- String value = (date == null ? null : String.valueOf(date.getTime()));
- setProperty(KEY_VIDEO_TRIAL_EXPIRES, value);
- }
-
- public String getUrlRedirectContextPath() {
- return properties.getProperty(KEY_URL_REDIRECT_CONTEXT_PATH, DEFAULT_URL_REDIRECT_CONTEXT_PATH);
- }
-
- public void setUrlRedirectContextPath(String contextPath) {
- properties.setProperty(KEY_URL_REDIRECT_CONTEXT_PATH, contextPath);
- }
-
- public Date getRESTTrialExpires(String client) {
- String value = properties.getProperty(KEY_REST_TRIAL_EXPIRES + client, DEFAULT_REST_TRIAL_EXPIRES);
- return value == null ? null : new Date(Long.parseLong(value));
- }
-
- public void setRESTTrialExpires(String client, Date date) {
- String value = (date == null ? null : String.valueOf(date.getTime()));
- setProperty(KEY_REST_TRIAL_EXPIRES + client, value);
- }
-
- public String getServerId() {
- return properties.getProperty(KEY_SERVER_ID, DEFAULT_SERVER_ID);
- }
-
- public void setServerId(String serverId) {
- properties.setProperty(KEY_SERVER_ID, serverId);
- }
-
- public long getSettingsChanged() {
- return Long.parseLong(properties.getProperty(KEY_SETTINGS_CHANGED, String.valueOf(DEFAULT_SETTINGS_CHANGED)));
- }
-
- public Date getLastScanned() {
- String lastScanned = properties.getProperty(KEY_LAST_SCANNED);
- return lastScanned == null ? null : new Date(Long.parseLong(lastScanned));
- }
-
- public void setLastScanned(Date date) {
- if (date == null) {
- properties.remove(KEY_LAST_SCANNED);
- } else {
- properties.setProperty(KEY_LAST_SCANNED, String.valueOf(date.getTime()));
- }
- }
-
- public boolean isOrganizeByFolderStructure() {
- return getBoolean(KEY_ORGANIZE_BY_FOLDER_STRUCTURE, DEFAULT_ORGANIZE_BY_FOLDER_STRUCTURE);
- }
-
- public void setOrganizeByFolderStructure(boolean b) {
- setBoolean(KEY_ORGANIZE_BY_FOLDER_STRUCTURE, b);
- }
-
- public boolean isSortAlbumsByYear() {
- return getBoolean(KEY_SORT_ALBUMS_BY_YEAR, DEFAULT_SORT_ALBUMS_BY_YEAR);
- }
-
- public void setSortAlbumsByYear(boolean b) {
- setBoolean(KEY_SORT_ALBUMS_BY_YEAR, b);
- }
-
- /**
- * Returns the locale (for language, date format etc).
- *
- * @return The locale.
- */
- public Locale getLocale() {
- String language = properties.getProperty(KEY_LOCALE_LANGUAGE, DEFAULT_LOCALE_LANGUAGE);
- String country = properties.getProperty(KEY_LOCALE_COUNTRY, DEFAULT_LOCALE_COUNTRY);
- String variant = properties.getProperty(KEY_LOCALE_VARIANT, DEFAULT_LOCALE_VARIANT);
-
- return new Locale(language, country, variant);
- }
-
- /**
- * Sets the locale (for language, date format etc.)
- *
- * @param locale The locale.
- */
- public void setLocale(Locale locale) {
- setProperty(KEY_LOCALE_LANGUAGE, locale.getLanguage());
- setProperty(KEY_LOCALE_COUNTRY, locale.getCountry());
- setProperty(KEY_LOCALE_VARIANT, locale.getVariant());
- }
-
- /**
- * Returns the ID of the theme to use.
- *
- * @return The theme ID.
- */
- public String getThemeId() {
- return properties.getProperty(KEY_THEME_ID, DEFAULT_THEME_ID);
- }
-
- /**
- * Sets the ID of the theme to use.
- *
- * @param themeId The theme ID
- */
- public void setThemeId(String themeId) {
- setProperty(KEY_THEME_ID, themeId);
- }
-
- /**
- * Returns a list of available themes.
- *
- * @return A list of available themes.
- */
- public synchronized Theme[] getAvailableThemes() {
- if (themes == null) {
- themes = new ArrayList<Theme>();
- try {
- InputStream in = SettingsService.class.getResourceAsStream(THEMES_FILE);
- String[] lines = StringUtil.readLines(in);
- for (String line : lines) {
- String[] elements = StringUtil.split(line);
- if (elements.length == 2) {
- themes.add(new Theme(elements[0], elements[1]));
- } else {
- LOG.warn("Failed to parse theme from line: [" + line + "].");
- }
- }
- } catch (IOException x) {
- LOG.error("Failed to resolve list of themes.", x);
- themes.add(new Theme("default", "Subsonic default"));
- }
- }
- return themes.toArray(new Theme[themes.size()]);
- }
-
- /**
- * Returns a list of available locales.
- *
- * @return A list of available locales.
- */
- public synchronized Locale[] getAvailableLocales() {
- if (locales == null) {
- locales = new ArrayList<Locale>();
- try {
- InputStream in = SettingsService.class.getResourceAsStream(LOCALES_FILE);
- String[] lines = StringUtil.readLines(in);
-
- for (String line : lines) {
- locales.add(parseLocale(line));
- }
-
- } catch (IOException x) {
- LOG.error("Failed to resolve list of locales.", x);
- locales.add(Locale.ENGLISH);
- }
- }
- return locales.toArray(new Locale[locales.size()]);
- }
-
- private Locale parseLocale(String line) {
- String[] s = line.split("_");
- String language = s[0];
- String country = "";
- String variant = "";
-
- if (s.length > 1) {
- country = s[1];
- }
- if (s.length > 2) {
- variant = s[2];
- }
- return new Locale(language, country, variant);
- }
-
- /**
- * Returns the "brand" name. Normally, this is just "Subsonic".
- *
- * @return The brand name.
- */
- public String getBrand() {
- return "Subsonic";
- }
-
- /**
- * Returns all music folders. Non-existing and disabled folders are not included.
- *
- * @return Possibly empty list of all music folders.
- */
- public List<MusicFolder> getAllMusicFolders() {
- return getAllMusicFolders(false, false);
- }
-
- /**
- * Returns all music folders.
- *
- * @param includeDisabled Whether to include disabled folders.
- * @param includeNonExisting Whether to include non-existing folders.
- * @return Possibly empty list of all music folders.
- */
- public List<MusicFolder> getAllMusicFolders(boolean includeDisabled, boolean includeNonExisting) {
- if (cachedMusicFolders == null) {
- cachedMusicFolders = musicFolderDao.getAllMusicFolders();
- }
-
- List<MusicFolder> result = new ArrayList<MusicFolder>(cachedMusicFolders.size());
- for (MusicFolder folder : cachedMusicFolders) {
- if ((includeDisabled || folder.isEnabled()) && (includeNonExisting || FileUtil.exists(folder.getPath()))) {
- result.add(folder);
- }
- }
- return result;
- }
-
- /**
- * Returns the music folder with the given ID.
- *
- * @param id The ID.
- * @return The music folder with the given ID, or <code>null</code> if not found.
- */
- public MusicFolder getMusicFolderById(Integer id) {
- List<MusicFolder> all = getAllMusicFolders();
- for (MusicFolder folder : all) {
- if (id.equals(folder.getId())) {
- return folder;
- }
- }
- return null;
- }
-
- /**
- * Creates a new music folder.
- *
- * @param musicFolder The music folder to create.
- */
- public void createMusicFolder(MusicFolder musicFolder) {
- musicFolderDao.createMusicFolder(musicFolder);
- cachedMusicFolders = null;
- }
-
- /**
- * Deletes the music folder with the given ID.
- *
- * @param id The ID of the music folder to delete.
- */
- public void deleteMusicFolder(Integer id) {
- musicFolderDao.deleteMusicFolder(id);
- cachedMusicFolders = null;
- }
-
- /**
- * Updates the given music folder.
- *
- * @param musicFolder The music folder to update.
- */
- public void updateMusicFolder(MusicFolder musicFolder) {
- musicFolderDao.updateMusicFolder(musicFolder);
- cachedMusicFolders = null;
- }
-
- /**
- * Returns all internet radio stations. Disabled stations are not returned.
- *
- * @return Possibly empty list of all internet radio stations.
- */
- public List<InternetRadio> getAllInternetRadios() {
- return getAllInternetRadios(false);
- }
-
- /**
- * Returns the internet radio station with the given ID.
- *
- * @param id The ID.
- * @return The internet radio station with the given ID, or <code>null</code> if not found.
- */
- public InternetRadio getInternetRadioById(Integer id) {
- for (InternetRadio radio : getAllInternetRadios()) {
- if (id.equals(radio.getId())) {
- return radio;
- }
- }
- return null;
- }
-
- /**
- * Returns all internet radio stations.
- *
- * @param includeAll Whether disabled stations should be included.
- * @return Possibly empty list of all internet radio stations.
- */
- public List<InternetRadio> getAllInternetRadios(boolean includeAll) {
- List<InternetRadio> all = internetRadioDao.getAllInternetRadios();
- List<InternetRadio> result = new ArrayList<InternetRadio>(all.size());
- for (InternetRadio folder : all) {
- if (includeAll || folder.isEnabled()) {
- result.add(folder);
- }
- }
- return result;
- }
-
- /**
- * Creates a new internet radio station.
- *
- * @param radio The internet radio station to create.
- */
- public void createInternetRadio(InternetRadio radio) {
- internetRadioDao.createInternetRadio(radio);
- }
-
- /**
- * Deletes the internet radio station with the given ID.
- *
- * @param id The internet radio station ID.
- */
- public void deleteInternetRadio(Integer id) {
- internetRadioDao.deleteInternetRadio(id);
- }
-
- /**
- * Updates the given internet radio station.
- *
- * @param radio The internet radio station to update.
- */
- public void updateInternetRadio(InternetRadio radio) {
- internetRadioDao.updateInternetRadio(radio);
- }
-
- /**
- * Returns settings for the given user.
- *
- * @param username The username.
- * @return User-specific settings. Never <code>null</code>.
- */
- public UserSettings getUserSettings(String username) {
- UserSettings settings = userDao.getUserSettings(username);
- return settings == null ? createDefaultUserSettings(username) : settings;
- }
-
- private UserSettings createDefaultUserSettings(String username) {
- UserSettings settings = new UserSettings(username);
- settings.setFinalVersionNotificationEnabled(true);
- settings.setBetaVersionNotificationEnabled(false);
- settings.setShowNowPlayingEnabled(true);
- settings.setShowChatEnabled(true);
- settings.setPartyModeEnabled(false);
- settings.setNowPlayingAllowed(true);
- settings.setLastFmEnabled(false);
- settings.setLastFmUsername(null);
- settings.setLastFmPassword(null);
- settings.setChanged(new Date());
-
- UserSettings.Visibility playlist = settings.getPlaylistVisibility();
- playlist.setCaptionCutoff(35);
- playlist.setArtistVisible(true);
- playlist.setAlbumVisible(true);
- playlist.setYearVisible(true);
- playlist.setDurationVisible(true);
- playlist.setBitRateVisible(true);
- playlist.setFormatVisible(true);
- playlist.setFileSizeVisible(true);
-
- UserSettings.Visibility main = settings.getMainVisibility();
- main.setCaptionCutoff(35);
- main.setTrackNumberVisible(true);
- main.setArtistVisible(true);
- main.setDurationVisible(true);
-
- return settings;
- }
-
- /**
- * Updates settings for the given username.
- *
- * @param settings The user-specific settings.
- */
- public void updateUserSettings(UserSettings settings) {
- userDao.updateUserSettings(settings);
- }
-
- /**
- * Returns all system avatars.
- *
- * @return All system avatars.
- */
- public List<Avatar> getAllSystemAvatars() {
- return avatarDao.getAllSystemAvatars();
- }
-
- /**
- * Returns the system avatar with the given ID.
- *
- * @param id The system avatar ID.
- * @return The avatar or <code>null</code> if not found.
- */
- public Avatar getSystemAvatar(int id) {
- return avatarDao.getSystemAvatar(id);
- }
-
- /**
- * Returns the custom avatar for the given user.
- *
- * @param username The username.
- * @return The avatar or <code>null</code> if not found.
- */
- public Avatar getCustomAvatar(String username) {
- return avatarDao.getCustomAvatar(username);
- }
-
- /**
- * Sets the custom avatar for the given user.
- *
- * @param avatar The avatar, or <code>null</code> to remove the avatar.
- * @param username The username.
- */
- public void setCustomAvatar(Avatar avatar, String username) {
- avatarDao.setCustomAvatar(avatar, username);
- }
-
- private void setProperty(String key, String value) {
- if (value == null) {
- properties.remove(key);
- } else {
- properties.setProperty(key, value);
- }
- }
-
- private String[] toStringArray(String s) {
- List<String> result = new ArrayList<String>();
- StringTokenizer tokenizer = new StringTokenizer(s, " ");
- while (tokenizer.hasMoreTokens()) {
- result.add(tokenizer.nextToken());
- }
-
- return result.toArray(new String[result.size()]);
- }
-
- private void validateLicense() {
- licenseValidated = true;
- }
-
- public void validateLicenseAsync() {
- new Thread() {
- @Override
- public void run() {
- validateLicense();
- }
- }.start();
- }
-
- public void setInternetRadioDao(InternetRadioDao internetRadioDao) {
- this.internetRadioDao = internetRadioDao;
- }
-
- public void setMusicFolderDao(MusicFolderDao musicFolderDao) {
- this.musicFolderDao = musicFolderDao;
- }
-
- public void setUserDao(UserDao userDao) {
- this.userDao = userDao;
- }
-
- public void setAvatarDao(AvatarDao avatarDao) {
- this.avatarDao = avatarDao;
- }
-
- public void setVersionService(VersionService versionService) {
- this.versionService = versionService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/ShareService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/ShareService.java
deleted file mode 100644
index cf5860e6..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/ShareService.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.RandomStringUtils;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.dao.ShareDao;
-import net.sourceforge.subsonic.domain.Share;
-import net.sourceforge.subsonic.domain.User;
-
-/**
- * Provides services for sharing media.
- *
- * @author Sindre Mehus
- * @see Share
- */
-public class ShareService {
-
- private static final Logger LOG = Logger.getLogger(ShareService.class);
-
- private ShareDao shareDao;
- private SecurityService securityService;
- private SettingsService settingsService;
- private MediaFileService mediaFileService;
-
- public List<Share> getAllShares() {
- return shareDao.getAllShares();
- }
-
- public List<Share> getSharesForUser(User user) {
- List<Share> result = new ArrayList<Share>();
- for (Share share : getAllShares()) {
- if (user.isAdminRole() || ObjectUtils.equals(user.getUsername(), share.getUsername())) {
- result.add(share);
- }
- }
- return result;
- }
-
- public Share getShareById(int id) {
- return shareDao.getShareById(id);
- }
-
- public List<MediaFile> getSharedFiles(int id) {
- List<MediaFile> result = new ArrayList<MediaFile>();
- for (String path : shareDao.getSharedFiles(id)) {
- try {
- result.add(mediaFileService.getMediaFile(path));
- } catch (Exception x) {
- // Ignored
- }
- }
- return result;
- }
-
- public Share createShare(HttpServletRequest request, List<MediaFile> files) throws Exception {
-
- Share share = new Share();
- share.setName(RandomStringUtils.random(5, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
- share.setCreated(new Date());
- share.setUsername(securityService.getCurrentUsername(request));
-
- Calendar expires = Calendar.getInstance();
- expires.add(Calendar.YEAR, 1);
- share.setExpires(expires.getTime());
-
- shareDao.createShare(share);
- for (MediaFile file : files) {
- shareDao.createSharedFiles(share.getId(), file.getPath());
- }
- LOG.info("Created share '" + share.getName() + "' with " + files.size() + " file(s).");
-
- return share;
- }
-
- public void updateShare(Share share) {
- shareDao.updateShare(share);
- }
-
- public void deleteShare(int id) {
- shareDao.deleteShare(id);
- }
-
- public String getShareBaseUrl() {
- return "http://" + settingsService.getUrlRedirectFrom() + ".subsonic.org/share/";
- }
-
- public String getShareUrl(Share share) {
- return getShareBaseUrl() + share.getName();
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setShareDao(ShareDao shareDao) {
- this.shareDao = shareDao;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setMediaFileService(MediaFileService mediaFileService) {
- this.mediaFileService = mediaFileService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/StatusService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/StatusService.java
deleted file mode 100644
index a893166a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/StatusService.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.TransferStatus;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Provides services for maintaining the list of stream, download and upload statuses.
- * <p/>
- * Note that for stream statuses, the last inactive status is also stored.
- *
- * @author Sindre Mehus
- * @see TransferStatus
- */
-public class StatusService {
-
- private final List<TransferStatus> streamStatuses = new ArrayList<TransferStatus>();
- private final List<TransferStatus> downloadStatuses = new ArrayList<TransferStatus>();
- private final List<TransferStatus> uploadStatuses = new ArrayList<TransferStatus>();
-
- // Maps from player ID to latest inactive stream status.
- private final Map<String, TransferStatus> inactiveStreamStatuses = new LinkedHashMap<String, TransferStatus>();
-
- public synchronized TransferStatus createStreamStatus(Player player) {
- // Reuse existing status, if possible.
- TransferStatus status = inactiveStreamStatuses.get(player.getId());
- if (status != null) {
- status.setActive(true);
- } else {
- status = createStatus(player, streamStatuses);
- }
- return status;
- }
-
- public synchronized void removeStreamStatus(TransferStatus status) {
- // Move it to the map of inactive statuses.
- status.setActive(false);
- inactiveStreamStatuses.put(status.getPlayer().getId(), status);
- streamStatuses.remove(status);
- }
-
- public synchronized List<TransferStatus> getAllStreamStatuses() {
-
- List<TransferStatus> result = new ArrayList<TransferStatus>(streamStatuses);
-
- // Add inactive status for those players that have no active status.
- Set<String> activePlayers = new HashSet<String>();
- for (TransferStatus status : streamStatuses) {
- activePlayers.add(status.getPlayer().getId());
- }
-
- for (Map.Entry<String, TransferStatus> entry : inactiveStreamStatuses.entrySet()) {
- if (!activePlayers.contains(entry.getKey())) {
- result.add(entry.getValue());
- }
- }
- return result;
- }
-
- public synchronized List<TransferStatus> getStreamStatusesForPlayer(Player player) {
- List<TransferStatus> result = new ArrayList<TransferStatus>();
- for (TransferStatus status : streamStatuses) {
- if (status.getPlayer().getId().equals(player.getId())) {
- result.add(status);
- }
- }
-
- // If no active statuses exists, add the inactive one.
- if (result.isEmpty()) {
- TransferStatus inactiveStatus = inactiveStreamStatuses.get(player.getId());
- if (inactiveStatus != null) {
- result.add(inactiveStatus);
- }
- }
-
- return result;
- }
-
- public synchronized TransferStatus createDownloadStatus(Player player) {
- return createStatus(player, downloadStatuses);
- }
-
- public synchronized void removeDownloadStatus(TransferStatus status) {
- downloadStatuses.remove(status);
- }
-
- public synchronized List<TransferStatus> getAllDownloadStatuses() {
- return new ArrayList<TransferStatus>(downloadStatuses);
- }
-
- public synchronized TransferStatus createUploadStatus(Player player) {
- return createStatus(player, uploadStatuses);
- }
-
- public synchronized void removeUploadStatus(TransferStatus status) {
- uploadStatuses.remove(status);
- }
-
- public synchronized List<TransferStatus> getAllUploadStatuses() {
- return new ArrayList<TransferStatus>(uploadStatuses);
- }
-
- private synchronized TransferStatus createStatus(Player player, List<TransferStatus> statusList) {
- TransferStatus status = new TransferStatus();
- status.setPlayer(player);
- statusList.add(status);
- return status;
- }
-
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java
deleted file mode 100644
index 2c8b9c5e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/TranscodingService.java
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.controller.VideoPlayerController;
-import net.sourceforge.subsonic.dao.TranscodingDao;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.Player;
-import net.sourceforge.subsonic.domain.TranscodeScheme;
-import net.sourceforge.subsonic.domain.Transcoding;
-import net.sourceforge.subsonic.domain.UserSettings;
-import net.sourceforge.subsonic.domain.VideoTranscodingSettings;
-import net.sourceforge.subsonic.io.TranscodeInputStream;
-import net.sourceforge.subsonic.util.StringUtil;
-import net.sourceforge.subsonic.util.Util;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.filefilter.PrefixFileFilter;
-import org.apache.commons.lang.StringUtils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Provides services for transcoding media. Transcoding is the process of
- * converting an audio stream to a different format and/or bit rate. The latter is
- * also called downsampling.
- *
- * @author Sindre Mehus
- * @see TranscodeInputStream
- */
-public class TranscodingService {
-
- private static final Logger LOG = Logger.getLogger(TranscodingService.class);
-
- private TranscodingDao transcodingDao;
- private SettingsService settingsService;
- private PlayerService playerService;
-
- /**
- * Returns all transcodings.
- *
- * @return Possibly empty list of all transcodings.
- */
- public List<Transcoding> getAllTranscodings() {
- return transcodingDao.getAllTranscodings();
- }
-
- /**
- * Returns all active transcodings for the given player. Only enabled transcodings are returned.
- *
- * @param player The player.
- * @return All active transcodings for the player.
- */
- public List<Transcoding> getTranscodingsForPlayer(Player player) {
- return transcodingDao.getTranscodingsForPlayer(player.getId());
- }
-
- /**
- * Sets the list of active transcodings for the given player.
- *
- * @param player The player.
- * @param transcodingIds ID's of the active transcodings.
- */
- public void setTranscodingsForPlayer(Player player, int[] transcodingIds) {
- transcodingDao.setTranscodingsForPlayer(player.getId(), transcodingIds);
- }
-
- /**
- * Sets the list of active transcodings for the given player.
- *
- * @param player The player.
- * @param transcodings The active transcodings.
- */
- public void setTranscodingsForPlayer(Player player, List<Transcoding> transcodings) {
- int[] transcodingIds = new int[transcodings.size()];
- for (int i = 0; i < transcodingIds.length; i++) {
- transcodingIds[i] = transcodings.get(i).getId();
- }
- setTranscodingsForPlayer(player, transcodingIds);
- }
-
-
- /**
- * Creates a new transcoding.
- *
- * @param transcoding The transcoding to create.
- */
- public void createTranscoding(Transcoding transcoding) {
- transcodingDao.createTranscoding(transcoding);
-
- // Activate this transcoding for all players?
- if (transcoding.isDefaultActive()) {
- for (Player player : playerService.getAllPlayers()) {
- List<Transcoding> transcodings = getTranscodingsForPlayer(player);
- transcodings.add(transcoding);
- setTranscodingsForPlayer(player, transcodings);
- }
- }
- }
-
- /**
- * Deletes the transcoding with the given ID.
- *
- * @param id The transcoding ID.
- */
- public void deleteTranscoding(Integer id) {
- transcodingDao.deleteTranscoding(id);
- }
-
- /**
- * Updates the given transcoding.
- *
- * @param transcoding The transcoding to update.
- */
- public void updateTranscoding(Transcoding transcoding) {
- transcodingDao.updateTranscoding(transcoding);
- }
-
- /**
- * Returns whether transcoding is required for the given media file and player combination.
- *
- * @param mediaFile The media file.
- * @param player The player.
- * @return Whether transcoding will be performed if invoking the
- * {@link #getTranscodedInputStream} method with the same arguments.
- */
- public boolean isTranscodingRequired(MediaFile mediaFile, Player player) {
- return getTranscoding(mediaFile, player, null) != null;
- }
-
- /**
- * Returns the suffix for the given player and media file, taking transcodings into account.
- *
- * @param player The player in question.
- * @param file The media file.
- * @param preferredTargetFormat Used to select among multiple applicable transcodings. May be {@code null}.
- * @return The file suffix, e.g., "mp3".
- */
- public String getSuffix(Player player, MediaFile file, String preferredTargetFormat) {
- Transcoding transcoding = getTranscoding(file, player, preferredTargetFormat);
- return transcoding != null ? transcoding.getTargetFormat() : file.getFormat();
- }
-
- /**
- * Creates parameters for a possibly transcoded or downsampled input stream for the given media file and player combination.
- * <p/>
- * A transcoding is applied if it is applicable for the format of the given file, and is activated for the
- * given player.
- * <p/>
- * If no transcoding is applicable, the file may still be downsampled, given that the player is configured
- * with a bit rate limit which is higher than the actual bit rate of the file.
- * <p/>
- * Otherwise, a normal input stream to the original file is returned.
- *
- * @param mediaFile The media file.
- * @param player The player.
- * @param maxBitRate Overrides the per-player and per-user bitrate limit. May be {@code null}.
- * @param preferredTargetFormat Used to select among multiple applicable transcodings. May be {@code null}.
- * @param videoTranscodingSettings Parameters used when transcoding video. May be {@code null}.
- * @return Parameters to be used in the {@link #getTranscodedInputStream} method.
- */
- public Parameters getParameters(MediaFile mediaFile, Player player, Integer maxBitRate, String preferredTargetFormat,
- VideoTranscodingSettings videoTranscodingSettings) {
-
- Parameters parameters = new Parameters(mediaFile, videoTranscodingSettings);
-
- TranscodeScheme transcodeScheme = getTranscodeScheme(player);
- if (maxBitRate == null && transcodeScheme != TranscodeScheme.OFF) {
- maxBitRate = transcodeScheme.getMaxBitRate();
- }
-
- Transcoding transcoding = getTranscoding(mediaFile, player, preferredTargetFormat);
- if (transcoding != null) {
- parameters.setTranscoding(transcoding);
- if (maxBitRate == null) {
- maxBitRate = mediaFile.isVideo() ? VideoPlayerController.DEFAULT_BIT_RATE : 128;
- }
- } else if (maxBitRate != null) {
- boolean supported = isDownsamplingSupported(mediaFile);
- Integer bitRate = mediaFile.getBitRate();
- if (supported && bitRate != null && bitRate > maxBitRate) {
- parameters.setDownsample(true);
- }
- }
-
- parameters.setMaxBitRate(maxBitRate);
- return parameters;
- }
-
- /**
- * Returns a possibly transcoded or downsampled input stream for the given music file and player combination.
- * <p/>
- * A transcoding is applied if it is applicable for the format of the given file, and is activated for the
- * given player.
- * <p/>
- * If no transcoding is applicable, the file may still be downsampled, given that the player is configured
- * with a bit rate limit which is higher than the actual bit rate of the file.
- * <p/>
- * Otherwise, a normal input stream to the original file is returned.
- *
- * @param parameters As returned by {@link #getParameters}.
- * @return A possible transcoded or downsampled input stream.
- * @throws IOException If an I/O error occurs.
- */
- public InputStream getTranscodedInputStream(Parameters parameters) throws IOException {
- try {
-
- if (parameters.getTranscoding() != null) {
- return createTranscodedInputStream(parameters);
- }
-
- if (parameters.downsample) {
- return createDownsampledInputStream(parameters);
- }
-
- } catch (Exception x) {
- LOG.warn("Failed to transcode " + parameters.getMediaFile() + ". Using original.", x);
- }
-
- return new FileInputStream(parameters.getMediaFile().getFile());
- }
-
-
- /**
- * Returns the strictest transcoding scheme defined for the player and the user.
- */
- private TranscodeScheme getTranscodeScheme(Player player) {
- String username = player.getUsername();
- if (username != null) {
- UserSettings userSettings = settingsService.getUserSettings(username);
- return player.getTranscodeScheme().strictest(userSettings.getTranscodeScheme());
- }
-
- return player.getTranscodeScheme();
- }
-
- /**
- * Returns an input stream by applying the given transcoding to the given music file.
- *
- * @param parameters Transcoding parameters.
- * @return The transcoded input stream.
- * @throws IOException If an I/O error occurs.
- */
- private InputStream createTranscodedInputStream(Parameters parameters)
- throws IOException {
-
- Transcoding transcoding = parameters.getTranscoding();
- Integer maxBitRate = parameters.getMaxBitRate();
- VideoTranscodingSettings videoTranscodingSettings = parameters.getVideoTranscodingSettings();
- MediaFile mediaFile = parameters.getMediaFile();
-
- TranscodeInputStream in = createTranscodeInputStream(transcoding.getStep1(), maxBitRate, videoTranscodingSettings, mediaFile, null);
-
- if (transcoding.getStep2() != null) {
- in = createTranscodeInputStream(transcoding.getStep2(), maxBitRate, videoTranscodingSettings, mediaFile, in);
- }
-
- if (transcoding.getStep3() != null) {
- in = createTranscodeInputStream(transcoding.getStep3(), maxBitRate, videoTranscodingSettings, mediaFile, in);
- }
-
- return in;
- }
-
- /**
- * Creates a transcoded input stream by interpreting the given command line string.
- * This includes the following:
- * <ul>
- * <li>Splitting the command line string to an array.</li>
- * <li>Replacing occurrences of "%s" with the path of the given music file.</li>
- * <li>Replacing occurrences of "%t" with the title of the given music file.</li>
- * <li>Replacing occurrences of "%l" with the album name of the given music file.</li>
- * <li>Replacing occurrences of "%a" with the artist name of the given music file.</li>
- * <li>Replacing occurrcences of "%b" with the max bitrate.</li>
- * <li>Replacing occurrcences of "%o" with the video time offset (used for scrubbing).</li>
- * <li>Replacing occurrcences of "%w" with the video image width.</li>
- * <li>Replacing occurrcences of "%h" with the video image height.</li>
- * <li>Prepending the path of the transcoder directory if the transcoder is found there.</li>
- * </ul>
- *
- * @param command The command line string.
- * @param maxBitRate The maximum bitrate to use. May not be {@code null}.
- * @param videoTranscodingSettings Parameters used when transcoding video. May be {@code null}.
- * @param mediaFile The media file.
- * @param in Data to feed to the process. May be {@code null}. @return The newly created input stream.
- */
- private TranscodeInputStream createTranscodeInputStream(String command, Integer maxBitRate,
- VideoTranscodingSettings videoTranscodingSettings, MediaFile mediaFile, InputStream in) throws IOException {
-
- String title = mediaFile.getTitle();
- String album = mediaFile.getAlbumName();
- String artist = mediaFile.getArtist();
-
- if (title == null) {
- title = "Unknown Song";
- }
- if (album == null) {
- title = "Unknown Album";
- }
- if (artist == null) {
- title = "Unknown Artist";
- }
-
- List<String> result = new LinkedList<String>(Arrays.asList(StringUtil.split(command)));
- result.set(0, getTranscodeDirectory().getPath() + File.separatorChar + result.get(0));
-
- File tmpFile = null;
-
- for (int i = 1; i < result.size(); i++) {
- String cmd = result.get(i);
- if (cmd.contains("%b")) {
- cmd = cmd.replace("%b", String.valueOf(maxBitRate));
- }
- if (cmd.contains("%t")) {
- cmd = cmd.replace("%t", title);
- }
- if (cmd.contains("%l")) {
- cmd = cmd.replace("%l", album);
- }
- if (cmd.contains("%a")) {
- cmd = cmd.replace("%a", artist);
- }
- if (cmd.contains("%o") && videoTranscodingSettings != null) {
- cmd = cmd.replace("%o", String.valueOf(videoTranscodingSettings.getTimeOffset()));
- }
- if (cmd.contains("%w") && videoTranscodingSettings != null) {
- cmd = cmd.replace("%w", String.valueOf(videoTranscodingSettings.getWidth()));
- }
- if (cmd.contains("%h") && videoTranscodingSettings != null) {
- cmd = cmd.replace("%h", String.valueOf(videoTranscodingSettings.getHeight()));
- }
- if (cmd.contains("%s")) {
-
- // Work-around for filename character encoding problem on Windows.
- // Create temporary file, and feed this to the transcoder.
- String path = mediaFile.getFile().getAbsolutePath();
- if (Util.isWindows() && !mediaFile.isVideo() && !StringUtils.isAsciiPrintable(path)) {
- tmpFile = File.createTempFile("subsonic", "." + FilenameUtils.getExtension(path));
- tmpFile.deleteOnExit();
- FileUtils.copyFile(new File(path), tmpFile);
- LOG.debug("Created tmp file: " + tmpFile);
- cmd = cmd.replace("%s", tmpFile.getPath());
- } else {
- cmd = cmd.replace("%s", path);
- }
- }
-
- result.set(i, cmd);
- }
- return new TranscodeInputStream(new ProcessBuilder(result), in, tmpFile);
- }
-
- /**
- * Returns an applicable transcoding for the given file and player, or <code>null</code> if no
- * transcoding should be done.
- */
- private Transcoding getTranscoding(MediaFile mediaFile, Player player, String preferredTargetFormat) {
-
- List<Transcoding> applicableTranscodings = new LinkedList<Transcoding>();
- String suffix = mediaFile.getFormat();
-
- for (Transcoding transcoding : getTranscodingsForPlayer(player)) {
- for (String sourceFormat : transcoding.getSourceFormatsAsArray()) {
- if (sourceFormat.equalsIgnoreCase(suffix)) {
- if (isTranscodingInstalled(transcoding)) {
- applicableTranscodings.add(transcoding);
- }
- }
- }
- }
-
- if (applicableTranscodings.isEmpty()) {
- return null;
- }
-
- for (Transcoding transcoding : applicableTranscodings) {
- if (transcoding.getTargetFormat().equalsIgnoreCase(preferredTargetFormat)) {
- return transcoding;
- }
- }
-
- return applicableTranscodings.get(0);
- }
-
- /**
- * Returns a downsampled input stream to the music file.
- *
- * @param parameters Downsample parameters.
- * @throws IOException If an I/O error occurs.
- */
- private InputStream createDownsampledInputStream(Parameters parameters) throws IOException {
- String command = settingsService.getDownsamplingCommand();
- return createTranscodeInputStream(command, parameters.getMaxBitRate(), parameters.getVideoTranscodingSettings(),
- parameters.getMediaFile(), null);
- }
-
- /**
- * Returns whether downsampling is supported (i.e., whether LAME is installed or not.)
- *
- * @param mediaFile If not null, returns whether downsampling is supported for this file.
- * @return Whether downsampling is supported.
- */
- public boolean isDownsamplingSupported(MediaFile mediaFile) {
- if (mediaFile != null) {
- boolean isMp3 = "mp3".equalsIgnoreCase(mediaFile.getFormat());
- if (!isMp3) {
- return false;
- }
- }
-
- String commandLine = settingsService.getDownsamplingCommand();
- return isTranscodingStepInstalled(commandLine);
- }
-
- private boolean isTranscodingInstalled(Transcoding transcoding) {
- return isTranscodingStepInstalled(transcoding.getStep1()) &&
- isTranscodingStepInstalled(transcoding.getStep2()) &&
- isTranscodingStepInstalled(transcoding.getStep3());
- }
-
- private boolean isTranscodingStepInstalled(String step) {
- if (StringUtils.isEmpty(step)) {
- return true;
- }
- String executable = StringUtil.split(step)[0];
- PrefixFileFilter filter = new PrefixFileFilter(executable);
- String[] matches = getTranscodeDirectory().list(filter);
- return matches != null && matches.length > 0;
- }
-
- /**
- * Returns the directory in which all transcoders are installed.
- */
- public File getTranscodeDirectory() {
- File dir = new File(SettingsService.getSubsonicHome(), "transcode");
- if (!dir.exists()) {
- boolean ok = dir.mkdir();
- if (ok) {
- LOG.info("Created directory " + dir);
- } else {
- LOG.warn("Failed to create directory " + dir);
- }
- }
- return dir;
- }
-
- public void setTranscodingDao(TranscodingDao transcodingDao) {
- this.transcodingDao = transcodingDao;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-
- public void setPlayerService(PlayerService playerService) {
- this.playerService = playerService;
- }
-
- public static class Parameters {
- private boolean downsample;
- private final MediaFile mediaFile;
- private final VideoTranscodingSettings videoTranscodingSettings;
- private Integer maxBitRate;
- private Transcoding transcoding;
-
- public Parameters(MediaFile mediaFile, VideoTranscodingSettings videoTranscodingSettings) {
- this.mediaFile = mediaFile;
- this.videoTranscodingSettings = videoTranscodingSettings;
- }
-
- public void setMaxBitRate(Integer maxBitRate) {
- this.maxBitRate = maxBitRate;
- }
-
- public boolean isDownsample() {
- return downsample;
- }
-
- public void setDownsample(boolean downsample) {
- this.downsample = downsample;
- }
-
- public boolean isTranscode() {
- return transcoding != null;
- }
-
- public void setTranscoding(Transcoding transcoding) {
- this.transcoding = transcoding;
- }
-
- public Transcoding getTranscoding() {
- return transcoding;
- }
-
- public MediaFile getMediaFile() {
- return mediaFile;
- }
-
- public Integer getMaxBitRate() {
- return maxBitRate;
- }
-
- public VideoTranscodingSettings getVideoTranscodingSettings() {
- return videoTranscodingSettings;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/VersionService.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/VersionService.java
deleted file mode 100644
index e24e6409..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/VersionService.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.Version;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.BasicResponseHandler;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.HttpConnectionParams;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Provides version-related services, including functionality for determining whether a newer
- * version of Subsonic is available.
- *
- * @author Sindre Mehus
- */
-public class VersionService {
-
- private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
- private static final Logger LOG = Logger.getLogger(VersionService.class);
-
- private Version localVersion;
- private Version latestFinalVersion;
- private Version latestBetaVersion;
- private Date localBuildDate;
- private String localBuildNumber;
-
- /**
- * Time when latest version was fetched (in milliseconds).
- */
- private long lastVersionFetched;
-
- /**
- * Only fetch last version this often (in milliseconds.).
- */
- private static final long LAST_VERSION_FETCH_INTERVAL = 7L * 24L * 3600L * 1000L; // One week
-
- /**
- * URL from which to fetch latest versions.
- */
- private static final String VERSION_URL = "http://subsonic.org/backend/version.view";
-
- /**
- * Returns the version number for the locally installed Subsonic version.
- *
- * @return The version number for the locally installed Subsonic version.
- */
- public synchronized Version getLocalVersion() {
- if (localVersion == null) {
- try {
- localVersion = new Version(readLineFromResource("/version.txt"));
- LOG.info("Resolved local Subsonic version to: " + localVersion);
- } catch (Exception x) {
- LOG.warn("Failed to resolve local Subsonic version.", x);
- }
- }
- return localVersion;
- }
-
- /**
- * Returns the version number for the latest available Subsonic final version.
- *
- * @return The version number for the latest available Subsonic final version, or <code>null</code>
- * if the version number can't be resolved.
- */
- public synchronized Version getLatestFinalVersion() {
- refreshLatestVersion();
- return latestFinalVersion;
- }
-
- /**
- * Returns the version number for the latest available Subsonic beta version.
- *
- * @return The version number for the latest available Subsonic beta version, or <code>null</code>
- * if the version number can't be resolved.
- */
- public synchronized Version getLatestBetaVersion() {
- refreshLatestVersion();
- return latestBetaVersion;
- }
-
- /**
- * Returns the build date for the locally installed Subsonic version.
- *
- * @return The build date for the locally installed Subsonic version, or <code>null</code>
- * if the build date can't be resolved.
- */
- public synchronized Date getLocalBuildDate() {
- if (localBuildDate == null) {
- try {
- String date = readLineFromResource("/build_date.txt");
- localBuildDate = DATE_FORMAT.parse(date);
- } catch (Exception x) {
- LOG.warn("Failed to resolve local Subsonic build date.", x);
- }
- }
- return localBuildDate;
- }
-
- /**
- * Returns the build number for the locally installed Subsonic version.
- *
- * @return The build number for the locally installed Subsonic version, or <code>null</code>
- * if the build number can't be resolved.
- */
- public synchronized String getLocalBuildNumber() {
- if (localBuildNumber == null) {
- try {
- localBuildNumber = readLineFromResource("/build_number.txt");
- } catch (Exception x) {
- LOG.warn("Failed to resolve local Subsonic build number.", x);
- }
- }
- return localBuildNumber;
- }
-
- /**
- * Returns whether a new final version of Subsonic is available.
- *
- * @return Whether a new final version of Subsonic is available.
- */
- public boolean isNewFinalVersionAvailable() {
- Version latest = getLatestFinalVersion();
- Version local = getLocalVersion();
-
- if (latest == null || local == null) {
- return false;
- }
-
- return local.compareTo(latest) < 0;
- }
-
- /**
- * Returns whether a new beta version of Subsonic is available.
- *
- * @return Whether a new beta version of Subsonic is available.
- */
- public boolean isNewBetaVersionAvailable() {
- Version latest = getLatestBetaVersion();
- Version local = getLocalVersion();
-
- if (latest == null || local == null) {
- return false;
- }
-
- return local.compareTo(latest) < 0;
- }
-
- /**
- * Reads the first line from the resource with the given name.
- *
- * @param resourceName The resource name.
- * @return The first line of the resource.
- */
- private String readLineFromResource(String resourceName) {
- InputStream in = VersionService.class.getResourceAsStream(resourceName);
- if (in == null) {
- return null;
- }
- BufferedReader reader = null;
- try {
-
- reader = new BufferedReader(new InputStreamReader(in));
- return reader.readLine();
-
- } catch (IOException x) {
- return null;
- } finally {
- IOUtils.closeQuietly(reader);
- IOUtils.closeQuietly(in);
- }
- }
-
- /**
- * Refreshes the latest final and beta versions.
- */
- private void refreshLatestVersion() {
- long now = System.currentTimeMillis();
- boolean isOutdated = now - lastVersionFetched > LAST_VERSION_FETCH_INTERVAL;
-
- if (isOutdated) {
- try {
- lastVersionFetched = now;
- readLatestVersion();
- } catch (Exception x) {
- LOG.warn("Failed to resolve latest Subsonic version.", x);
- }
- }
- }
-
- /**
- * Resolves the latest available Subsonic version by screen-scraping a web page.
- *
- * @throws IOException If an I/O error occurs.
- */
- private void readLatestVersion() throws IOException {
-
- HttpClient client = new DefaultHttpClient();
- HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
- HttpConnectionParams.setSoTimeout(client.getParams(), 10000);
- HttpGet method = new HttpGet(VERSION_URL + "?v=" + getLocalVersion());
- String content;
- try {
-
- ResponseHandler<String> responseHandler = new BasicResponseHandler();
- content = client.execute(method, responseHandler);
-
- } finally {
- client.getConnectionManager().shutdown();
- }
-
- BufferedReader reader = new BufferedReader(new StringReader(content));
- Pattern finalPattern = Pattern.compile("SUBSONIC_FULL_VERSION_BEGIN(.*)SUBSONIC_FULL_VERSION_END");
- Pattern betaPattern = Pattern.compile("SUBSONIC_BETA_VERSION_BEGIN(.*)SUBSONIC_BETA_VERSION_END");
-
- try {
- String line = reader.readLine();
- while (line != null) {
- Matcher finalMatcher = finalPattern.matcher(line);
- if (finalMatcher.find()) {
- latestFinalVersion = new Version(finalMatcher.group(1));
- LOG.info("Resolved latest Subsonic final version to: " + latestFinalVersion);
- }
- Matcher betaMatcher = betaPattern.matcher(line);
- if (betaMatcher.find()) {
- latestBetaVersion = new Version(betaMatcher.group(1));
- LOG.info("Resolved latest Subsonic beta version to: " + latestBetaVersion);
- }
- line = reader.readLine();
- }
-
- } finally {
- reader.close();
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/AudioPlayer.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/AudioPlayer.java
deleted file mode 100644
index 902387be..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/AudioPlayer.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.jukebox;
-
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.FloatControl;
-import javax.sound.sampled.SourceDataLine;
-
-import org.apache.commons.io.IOUtils;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.service.JukeboxService;
-
-import static net.sourceforge.subsonic.service.jukebox.AudioPlayer.State.*;
-
-/**
- * A simple wrapper for playing sound from an input stream.
- * <p/>
- * Supports pause and resume, but not restarting.
- *
- * @author Sindre Mehus
- * @version $Id$
- */
-public class AudioPlayer {
-
- private static final Logger LOG = Logger.getLogger(JukeboxService.class);
-
- private final InputStream in;
- private final Listener listener;
- private final SourceDataLine line;
- private final AtomicReference<State> state = new AtomicReference<State>(PAUSED);
- private FloatControl gainControl;
-
- public AudioPlayer(InputStream in, Listener listener) throws Exception {
- this.in = new BufferedInputStream(in);
- this.listener = listener;
-
- AudioFormat format = AudioSystem.getAudioFileFormat(this.in).getFormat();
- line = AudioSystem.getSourceDataLine(format);
- line.open(format);
- LOG.debug("Opened line " + line);
-
- if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
- gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
- setGain(0.5f);
- }
- new AudioDataWriter();
- }
-
- /**
- * Starts (or resumes) the player. This only has effect if the current state is
- * {@link State#PAUSED}.
- */
- public synchronized void play() {
- if (state.get() == PAUSED) {
- line.start();
- setState(PLAYING);
- }
- }
-
- /**
- * Pauses the player. This only has effect if the current state is
- * {@link State#PLAYING}.
- */
- public synchronized void pause() {
- if (state.get() == PLAYING) {
- setState(PAUSED);
- line.stop();
- line.flush();
- }
- }
-
- /**
- * Closes the player, releasing all resources. After this the player state is
- * {@link State#CLOSED} (unless the current state is {@link State#EOM}).
- */
- public synchronized void close() {
- if (state.get() != CLOSED && state.get() != EOM) {
- setState(CLOSED);
- }
-
- try {
- line.stop();
- } catch (Throwable x) {
- LOG.warn("Failed to stop player: " + x, x);
- }
- try {
- if (line.isOpen()) {
- line.close();
- LOG.debug("Closed line " + line);
- }
- } catch (Throwable x) {
- LOG.warn("Failed to close player: " + x, x);
- }
- IOUtils.closeQuietly(in);
- }
-
- /**
- * Returns the player state.
- */
- public State getState() {
- return state.get();
- }
-
- /**
- * Sets the gain.
- *
- * @param gain The gain between 0.0 and 1.0.
- */
- public void setGain(float gain) {
- if (gainControl != null) {
-
- double minGainDB = gainControl.getMinimum();
- double maxGainDB = gainControl.getMaximum();
- double ampGainDB = 0.5f * maxGainDB - minGainDB;
- double cste = Math.log(10.0) / 20;
- double valueDB = minGainDB + (1 / cste) * Math.log(1 + (Math.exp(cste * ampGainDB) - 1) * gain);
-
- valueDB = Math.min(valueDB, maxGainDB);
- valueDB = Math.max(valueDB, minGainDB);
-
- gainControl.setValue((float) valueDB);
- }
- }
-
- /**
- * Returns the position in seconds.
- */
- public int getPosition() {
- return (int) (line.getMicrosecondPosition() / 1000000L);
- }
-
- private void setState(State state) {
- if (this.state.getAndSet(state) != state && listener != null) {
- listener.stateChanged(this, state);
- }
- }
-
- private class AudioDataWriter implements Runnable {
-
- public AudioDataWriter() {
- new Thread(this).start();
- }
-
- public void run() {
- try {
- byte[] buffer = new byte[8192];
-
- while (true) {
-
- switch (state.get()) {
- case CLOSED:
- case EOM:
- return;
- case PAUSED:
- Thread.sleep(250);
- break;
- case PLAYING:
- int n = in.read(buffer);
- if (n == -1) {
- setState(EOM);
- return;
- }
- line.write(buffer, 0, n);
- break;
- }
- }
- } catch (Throwable x) {
- LOG.warn("Error when copying audio data: " + x, x);
- } finally {
- close();
- }
- }
- }
-
- public interface Listener {
- void stateChanged(AudioPlayer player, State state);
- }
-
- public static enum State {
- PAUSED,
- PLAYING,
- CLOSED,
- EOM
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/PlayerTest.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/PlayerTest.java
deleted file mode 100644
index 30ed2847..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/jukebox/PlayerTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package net.sourceforge.subsonic.service.jukebox;
-
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.FileInputStream;
-
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JSlider;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class PlayerTest implements AudioPlayer.Listener {
-
- private AudioPlayer player;
-
- public PlayerTest() throws Exception {
- player = new AudioPlayer(new FileInputStream("i:\\tmp\\foo.au"), this);
- createGUI();
- }
-
- private void createGUI() {
- JFrame frame = new JFrame();
-
- JButton startButton = new JButton("Start");
- JButton stopButton = new JButton("Stop");
- JButton resetButton = new JButton("Reset");
- final JSlider gainSlider = new JSlider(0, 1000);
-
- startButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- player.play();
- }
- });
- stopButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- player.pause();
- }
- });
- resetButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- player.close();
- }
- });
- gainSlider.addChangeListener(new ChangeListener() {
- public void stateChanged(ChangeEvent e) {
- float gain = (float) gainSlider.getValue() / 1000.0F;
- player.setGain(gain);
- }
- });
-
- frame.setLayout(new FlowLayout());
- frame.add(startButton);
- frame.add(stopButton);
- frame.add(resetButton);
- frame.add(gainSlider);
-
- frame.pack();
- frame.setVisible(true);
- }
-
- public static void main(String[] args) throws Exception {
- new PlayerTest();
- }
-
- public void stateChanged(AudioPlayer player, AudioPlayer.State state) {
- System.out.println(state);
- }
-}
-
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/DefaultMetaDataParser.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/DefaultMetaDataParser.java
deleted file mode 100644
index 897f39d4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/DefaultMetaDataParser.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.metadata;
-
-import java.io.File;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-
-/**
- * Parses meta data by guessing artist, album and song title based on the path of the file.
- *
- * @author Sindre Mehus
- */
-public class DefaultMetaDataParser extends MetaDataParser {
-
- /**
- * Parses meta data for the given file. No guessing or reformatting is done.
- *
- * @param file The file to parse.
- * @return Meta data for the file.
- */
- public MetaData getRawMetaData(File file) {
- MetaData metaData = new MetaData();
- metaData.setArtist(guessArtist(file));
- metaData.setAlbumName(guessAlbum(file, metaData.getArtist()));
- metaData.setTitle(guessTitle(file));
- return metaData;
- }
-
- /**
- * Updates the given file with the given meta data.
- * This method has no effect.
- *
- * @param file The file to update.
- * @param metaData The new meta data.
- */
- public void setMetaData(MediaFile file, MetaData metaData) {
- }
-
- /**
- * Returns whether this parser supports tag editing (using the {@link #setMetaData} method).
- *
- * @return Always false.
- */
- public boolean isEditingSupported() {
- return false;
- }
-
- /**
- * Returns whether this parser is applicable to the given file.
- *
- * @param file The file in question.
- * @return Whether this parser is applicable to the given file.
- */
- public boolean isApplicable(File file) {
- return file.isFile();
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/FFmpegParser.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/FFmpegParser.java
deleted file mode 100644
index 60ae1750..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/FFmpegParser.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.metadata;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.io.InputStreamReaderThread;
-import net.sourceforge.subsonic.service.ServiceLocator;
-import net.sourceforge.subsonic.service.TranscodingService;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.commons.io.FilenameUtils;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Parses meta data from video files using FFmpeg (http://ffmpeg.org/).
- * <p/>
- * Currently duration, bitrate and dimension are supported.
- *
- * @author Sindre Mehus
- */
-public class FFmpegParser extends MetaDataParser {
-
- private static final Logger LOG = Logger.getLogger(FFmpegParser.class);
- private static final Pattern DURATION_PATTERN = Pattern.compile("Duration: (\\d+):(\\d+):(\\d+).(\\d+)");
- private static final Pattern BITRATE_PATTERN = Pattern.compile("bitrate: (\\d+) kb/s");
- private static final Pattern DIMENSION_PATTERN = Pattern.compile("Video.*?, (\\d+)x(\\d+)");
- private static final Pattern PAR_PATTERN = Pattern.compile("PAR (\\d+):(\\d+)");
-
- private TranscodingService transcodingService;
-
- /**
- * Parses meta data for the given music file. No guessing or reformatting is done.
- *
- *
- * @param file The music file to parse.
- * @return Meta data for the file.
- */
- @Override
- public MetaData getRawMetaData(File file) {
-
- MetaData metaData = new MetaData();
-
- try {
-
- File ffmpeg = new File(transcodingService.getTranscodeDirectory(), "ffmpeg");
-
- String[] command = new String[]{ffmpeg.getAbsolutePath(), "-i", file.getAbsolutePath()};
- Process process = Runtime.getRuntime().exec(command);
- InputStream stdout = process.getInputStream();
- InputStream stderr = process.getErrorStream();
-
- // Consume stdout, we're not interested in that.
- new InputStreamReaderThread(stdout, "ffmpeg", true).start();
-
- // Read everything from stderr. It will contain text similar to:
- // Input #0, avi, from 'foo.avi':
- // Duration: 00:00:33.90, start: 0.000000, bitrate: 2225 kb/s
- // Stream #0.0: Video: mpeg4, yuv420p, 352x240 [PAR 1:1 DAR 22:15], 29.97 fps, 29.97 tbr, 29.97 tbn, 30k tbc
- // Stream #0.1: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s
- String[] lines = StringUtil.readLines(stderr);
-
- Integer width = null;
- Integer height = null;
- Double par = 1.0;
- for (String line : lines) {
-
- Matcher matcher = DURATION_PATTERN.matcher(line);
- if (matcher.find()) {
- int hours = Integer.parseInt(matcher.group(1));
- int minutes = Integer.parseInt(matcher.group(2));
- int seconds = Integer.parseInt(matcher.group(3));
- metaData.setDurationSeconds(hours * 3600 + minutes * 60 + seconds);
- }
-
- matcher = BITRATE_PATTERN.matcher(line);
- if (matcher.find()) {
- metaData.setBitRate(Integer.valueOf(matcher.group(1)));
- }
-
- matcher = DIMENSION_PATTERN.matcher(line);
- if (matcher.find()) {
- width = Integer.valueOf(matcher.group(1));
- height = Integer.valueOf(matcher.group(2));
- }
-
- // PAR = Pixel Aspect Rate
- matcher = PAR_PATTERN.matcher(line);
- if (matcher.find()) {
- int a = Integer.parseInt(matcher.group(1));
- int b = Integer.parseInt(matcher.group(2));
- if (a > 0 && b > 0) {
- par = (double) a / (double) b;
- }
- }
- }
-
- if (width != null && height != null) {
- width = (int) Math.round(width.doubleValue() * par);
- metaData.setWidth(width);
- metaData.setHeight(height);
- }
-
-
- } catch (Throwable x) {
- LOG.warn("Error when parsing metadata in " + file, x);
- }
-
- return metaData;
- }
-
- /**
- * Not supported.
- */
- @Override
- public void setMetaData(MediaFile file, MetaData metaData) {
- throw new RuntimeException("setMetaData() not supported in " + getClass().getSimpleName());
- }
-
- /**
- * Returns whether this parser supports tag editing (using the {@link #setMetaData} method).
- *
- * @return Always false.
- */
- @Override
- public boolean isEditingSupported() {
- return false;
- }
-
- /**
- * Returns whether this parser is applicable to the given file.
- *
- * @param file The file in question.
- * @return Whether this parser is applicable to the given file.
- */
- @Override
- public boolean isApplicable(File file) {
- String format = FilenameUtils.getExtension(file.getName()).toLowerCase();
-
- for (String s : ServiceLocator.getSettingsService().getVideoFileTypesAsArray()) {
- if (format.equals(s)) {
- return true;
- }
- }
- return false;
- }
-
- public void setTranscodingService(TranscodingService transcodingService) {
- this.transcodingService = transcodingService;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/JaudiotaggerParser.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/JaudiotaggerParser.java
deleted file mode 100644
index 8fa7659a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/JaudiotaggerParser.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.metadata;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.domain.MediaFile;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.jaudiotagger.audio.AudioFile;
-import org.jaudiotagger.audio.AudioFileIO;
-import org.jaudiotagger.audio.AudioHeader;
-import org.jaudiotagger.tag.FieldKey;
-import org.jaudiotagger.tag.Tag;
-import org.jaudiotagger.tag.datatype.Artwork;
-import org.jaudiotagger.tag.reference.GenreTypes;
-
-import java.io.File;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.logging.LogManager;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Parses meta data from audio files using the Jaudiotagger library
- * (http://www.jthink.net/jaudiotagger/)
- *
- * @author Sindre Mehus
- */
-public class JaudiotaggerParser extends MetaDataParser {
-
- private static final Logger LOG = Logger.getLogger(JaudiotaggerParser.class);
- private static final Pattern GENRE_PATTERN = Pattern.compile("\\((\\d+)\\).*");
- private static final Pattern TRACK_NUMBER_PATTERN = Pattern.compile("(\\d+)/\\d+");
-
- static {
- try {
- LogManager.getLogManager().reset();
- } catch (Throwable x) {
- LOG.warn("Failed to turn off logging from Jaudiotagger.", x);
- }
- }
-
- /**
- * Parses meta data for the given music file. No guessing or reformatting is done.
- *
- *
- * @param file The music file to parse.
- * @return Meta data for the file.
- */
- @Override
- public MetaData getRawMetaData(File file) {
-
- MetaData metaData = new MetaData();
-
- try {
- AudioFile audioFile = AudioFileIO.read(file);
- Tag tag = audioFile.getTag();
- if (tag != null) {
- metaData.setAlbumName(getTagField(tag, FieldKey.ALBUM));
- metaData.setTitle(getTagField(tag, FieldKey.TITLE));
- metaData.setYear(parseInteger(getTagField(tag, FieldKey.YEAR)));
- metaData.setGenre(mapGenre(getTagField(tag, FieldKey.GENRE)));
- metaData.setDiscNumber(parseInteger(getTagField(tag, FieldKey.DISC_NO)));
- metaData.setTrackNumber(parseTrackNumber(getTagField(tag, FieldKey.TRACK)));
-
- String songArtist = getTagField(tag, FieldKey.ARTIST);
- String albumArtist = getTagField(tag, FieldKey.ALBUM_ARTIST);
- metaData.setArtist(StringUtils.isBlank(albumArtist) ? songArtist : albumArtist);
- }
-
- AudioHeader audioHeader = audioFile.getAudioHeader();
- if (audioHeader != null) {
- metaData.setVariableBitRate(audioHeader.isVariableBitRate());
- metaData.setBitRate((int) audioHeader.getBitRateAsNumber());
- metaData.setDurationSeconds(audioHeader.getTrackLength());
- }
-
-
- } catch (Throwable x) {
- LOG.warn("Error when parsing tags in " + file, x);
- }
-
- return metaData;
- }
-
- private String getTagField(Tag tag, FieldKey fieldKey) {
- try {
- return StringUtils.trimToNull(tag.getFirst(fieldKey));
- } catch (Exception x) {
- // Ignored.
- return null;
- }
- }
-
- /**
- * Returns all tags supported by id3v1.
- */
- public static SortedSet<String> getID3V1Genres() {
- return new TreeSet<String>(GenreTypes.getInstanceOf().getAlphabeticalValueList());
- }
-
- /**
- * Sometimes the genre is returned as "(17)" or "(17)Rock", instead of "Rock". This method
- * maps the genre ID to the corresponding text.
- */
- private String mapGenre(String genre) {
- if (genre == null) {
- return null;
- }
- Matcher matcher = GENRE_PATTERN.matcher(genre);
- if (matcher.matches()) {
- int genreId = Integer.parseInt(matcher.group(1));
- if (genreId >= 0 && genreId < GenreTypes.getInstanceOf().getSize()) {
- return GenreTypes.getInstanceOf().getValueForId(genreId);
- }
- }
- return genre;
- }
-
- /**
- * Parses the track number from the given string. Also supports
- * track numbers on the form "4/12".
- */
- private Integer parseTrackNumber(String trackNumber) {
- if (trackNumber == null) {
- return null;
- }
-
- Integer result = null;
-
- try {
- result = new Integer(trackNumber);
- } catch (NumberFormatException x) {
- Matcher matcher = TRACK_NUMBER_PATTERN.matcher(trackNumber);
- if (matcher.matches()) {
- try {
- result = Integer.valueOf(matcher.group(1));
- } catch (NumberFormatException e) {
- return null;
- }
- }
- }
-
- if (Integer.valueOf(0).equals(result)) {
- return null;
- }
- return result;
- }
-
- private Integer parseInteger(String s) {
- s = StringUtils.trimToNull(s);
- if (s == null) {
- return null;
- }
- try {
- Integer result = Integer.valueOf(s);
- if (Integer.valueOf(0).equals(result)) {
- return null;
- }
- return result;
- } catch (NumberFormatException x) {
- return null;
- }
- }
-
- /**
- * Updates the given file with the given meta data.
- *
- * @param file The music file to update.
- * @param metaData The new meta data.
- */
- @Override
- public void setMetaData(MediaFile file, MetaData metaData) {
-
- try {
- AudioFile audioFile = AudioFileIO.read(file.getFile());
- Tag tag = audioFile.getTagOrCreateAndSetDefault();
-
- tag.setField(FieldKey.ARTIST, StringUtils.trimToEmpty(metaData.getArtist()));
- tag.setField(FieldKey.ALBUM_ARTIST, StringUtils.trimToEmpty(metaData.getArtist()));
- tag.setField(FieldKey.ALBUM, StringUtils.trimToEmpty(metaData.getAlbumName()));
- tag.setField(FieldKey.TITLE, StringUtils.trimToEmpty(metaData.getTitle()));
- tag.setField(FieldKey.GENRE, StringUtils.trimToEmpty(metaData.getGenre()));
-
- Integer track = metaData.getTrackNumber();
- if (track == null) {
- tag.deleteField(FieldKey.TRACK);
- } else {
- tag.setField(FieldKey.TRACK, String.valueOf(track));
- }
-
- Integer year = metaData.getYear();
- if (year == null) {
- tag.deleteField(FieldKey.YEAR);
- } else {
- tag.setField(FieldKey.YEAR, String.valueOf(year));
- }
-
- audioFile.commit();
-
- } catch (Throwable x) {
- LOG.warn("Failed to update tags for file " + file, x);
- throw new RuntimeException("Failed to update tags for file " + file + ". " + x.getMessage(), x);
- }
- }
-
- /**
- * Returns whether this parser supports tag editing (using the {@link #setMetaData} method).
- *
- * @return Always true.
- */
- @Override
- public boolean isEditingSupported() {
- return true;
- }
-
- /**
- * Returns whether this parser is applicable to the given file.
- *
- * @param file The music file in question.
- * @return Whether this parser is applicable to the given file.
- */
- @Override
- public boolean isApplicable(File file) {
- if (!file.isFile()) {
- return false;
- }
-
- String format = FilenameUtils.getExtension(file.getName()).toLowerCase();
-
- return format.equals("mp3") ||
- format.equals("m4a") ||
- format.equals("aac") ||
- format.equals("ogg") ||
- format.equals("flac") ||
- format.equals("wav") ||
- format.equals("mpc") ||
- format.equals("mp+") ||
- format.equals("ape") ||
- format.equals("wma");
- }
-
- /**
- * Returns whether cover art image data is available in the given file.
- *
- * @param file The music file.
- * @return Whether cover art image data is available.
- */
- public boolean isImageAvailable(MediaFile file) {
- try {
- return getArtwork(file) != null;
- } catch (Throwable x) {
- LOG.warn("Failed to find cover art tag in " + file, x);
- return false;
- }
- }
-
- /**
- * Returns the cover art image data embedded in the given file.
- *
- * @param file The music file.
- * @return The embedded cover art image data, or <code>null</code> if not available.
- */
- public byte[] getImageData(MediaFile file) {
- try {
- return getArtwork(file).getBinaryData();
- } catch (Throwable x) {
- LOG.warn("Failed to find cover art tag in " + file, x);
- return null;
- }
- }
-
- private Artwork getArtwork(MediaFile file) throws Exception {
- AudioFile audioFile = AudioFileIO.read(file.getFile());
- Tag tag = audioFile.getTag();
- return tag == null ? null : tag.getFirstArtwork();
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaData.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaData.java
deleted file mode 100644
index d3fa08a0..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaData.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.metadata;
-
-/**
- * Contains meta-data (song title, artist, album etc) for a music file.
- * @author Sindre Mehus
- */
-public class MetaData {
-
- private Integer discNumber;
- private Integer trackNumber;
- private String title;
- private String artist;
- private String albumName;
- private String genre;
- private Integer year;
- private Integer bitRate;
- private boolean variableBitRate;
- private Integer durationSeconds;
- private Integer width;
- private Integer height;
-
- public Integer getDiscNumber() {
- return discNumber;
- }
-
- public void setDiscNumber(Integer discNumber) {
- this.discNumber = discNumber;
- }
-
- public Integer getTrackNumber() {
- return trackNumber;
- }
-
- public void setTrackNumber(Integer trackNumber) {
- this.trackNumber = trackNumber;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getArtist() {
- return artist;
- }
-
- public void setArtist(String artist) {
- this.artist = artist;
- }
-
- public String getAlbumName() {
- return albumName;
- }
-
- public void setAlbumName(String albumName) {
- this.albumName = albumName;
- }
-
- public String getGenre() {
- return genre;
- }
-
- public void setGenre(String genre) {
- this.genre = genre;
- }
-
- public Integer getYear() {
- return year;
- }
-
- public void setYear(Integer year) {
- this.year = year;
- }
-
- public Integer getBitRate() {
- return bitRate;
- }
-
- public void setBitRate(Integer bitRate) {
- this.bitRate = bitRate;
- }
-
- public boolean getVariableBitRate() {
- return variableBitRate;
- }
-
- public void setVariableBitRate(boolean variableBitRate) {
- this.variableBitRate = variableBitRate;
- }
-
- public Integer getDurationSeconds() {
- return durationSeconds;
- }
-
- public void setDurationSeconds(Integer durationSeconds) {
- this.durationSeconds = durationSeconds;
- }
-
- public Integer getWidth() {
- return width;
- }
-
- public void setWidth(Integer width) {
- this.width = width;
- }
-
- public Integer getHeight() {
- return height;
- }
-
- public void setHeight(Integer height) {
- this.height = height;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParser.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParser.java
deleted file mode 100644
index 2ed70acc..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParser.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.metadata;
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.commons.io.FilenameUtils;
-
-import net.sourceforge.subsonic.domain.MediaFile;
-import net.sourceforge.subsonic.domain.MusicFolder;
-import net.sourceforge.subsonic.service.ServiceLocator;
-import net.sourceforge.subsonic.service.SettingsService;
-
-
-/**
- * Parses meta data from media files.
- *
- * @author Sindre Mehus
- */
-public abstract class MetaDataParser {
-
- /**
- * Parses meta data for the given file.
- *
- * @param file The file to parse.
- * @return Meta data for the file, never null.
- */
- public MetaData getMetaData(File file) {
-
- MetaData metaData = getRawMetaData(file);
- String artist = metaData.getArtist();
- String album = metaData.getAlbumName();
- String title = metaData.getTitle();
-
- if (artist == null) {
- artist = guessArtist(file);
- }
- if (album == null) {
- album = guessAlbum(file, artist);
- }
- if (title == null) {
- title = guessTitle(file);
- }
-
- title = removeTrackNumberFromTitle(title, metaData.getTrackNumber());
- metaData.setArtist(artist);
- metaData.setAlbumName(album);
- metaData.setTitle(title);
-
- return metaData;
- }
-
- /**
- * Parses meta data for the given file. No guessing or reformatting is done.
- *
- *
- * @param file The file to parse.
- * @return Meta data for the file.
- */
- public abstract MetaData getRawMetaData(File file);
-
- /**
- * Updates the given file with the given meta data.
- *
- * @param file The file to update.
- * @param metaData The new meta data.
- */
- public abstract void setMetaData(MediaFile file, MetaData metaData);
-
- /**
- * Returns whether this parser is applicable to the given file.
- *
- * @param file The file in question.
- * @return Whether this parser is applicable to the given file.
- */
- public abstract boolean isApplicable(File file);
-
- /**
- * Returns whether this parser supports tag editing (using the {@link #setMetaData} method).
- *
- * @return Whether tag editing is supported.
- */
- public abstract boolean isEditingSupported();
-
- /**
- * Guesses the artist for the given file.
- */
- public String guessArtist(File file) {
- File parent = file.getParentFile();
- if (isRoot(parent)) {
- return null;
- }
- File grandParent = parent.getParentFile();
- return isRoot(grandParent) ? null : grandParent.getName();
- }
-
- /**
- * Guesses the album for the given file.
- */
- public String guessAlbum(File file, String artist) {
- File parent = file.getParentFile();
- String album = isRoot(parent) ? null : parent.getName();
- if (artist != null && album != null) {
- album = album.replace(artist + " - ", "");
- }
- return album;
- }
-
- /**
- * Guesses the title for the given file.
- */
- public String guessTitle(File file) {
- return removeTrackNumberFromTitle(FilenameUtils.getBaseName(file.getPath()), null);
- }
-
- private boolean isRoot(File file) {
- SettingsService settings = ServiceLocator.getSettingsService();
- List<MusicFolder> folders = settings.getAllMusicFolders(false, true);
- for (MusicFolder folder : folders) {
- if (file.equals(folder.getPath())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Removes any prefixed track number from the given title string.
- *
- * @param title The title with or without a prefixed track number, e.g., "02 - Back In Black".
- * @param trackNumber If specified, this is the "true" track number.
- * @return The title with the track number removed, e.g., "Back In Black".
- */
- protected String removeTrackNumberFromTitle(String title, Integer trackNumber) {
- title = title.trim();
-
- // Don't remove numbers if true track number is given, and title does not start with it.
- if (trackNumber != null && !title.matches("0?" + trackNumber + "[\\.\\- ].*")) {
- return title;
- }
-
- String result = title.replaceFirst("^\\d{2}[\\.\\- ]+", "");
- return result.length() == 0 ? title : result;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParserFactory.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParserFactory.java
deleted file mode 100644
index 31b56be4..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/service/metadata/MetaDataParserFactory.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.service.metadata;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Factory for creating meta-data parsers.
- *
- * @author Sindre Mehus
- */
-public class MetaDataParserFactory {
-
- private List<MetaDataParser> parsers;
-
- public void setParsers(List<MetaDataParser> parsers) {
- this.parsers = parsers;
- }
-
- /**
- * Returns a meta-data parser for the given file.
- *
- * @param file The file in question.
- * @return An applicable parser, or <code>null</code> if no parser is found.
- */
- public MetaDataParser getParser(File file) {
- for (MetaDataParser parser : parsers) {
- if (parser.isApplicable(file)) {
- return parser;
- }
- }
- return null;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java
deleted file mode 100644
index c7c09677..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/EscapeJavaScriptTag.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.taglib;
-
-import org.apache.commons.lang.StringEscapeUtils;
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.JspTagException;
-import javax.servlet.jsp.tagext.BodyTagSupport;
-import java.io.IOException;
-
-/**
- * Escapes the characters in a <code>String</code> using JavaScript String rules.
- * <p/>
- * Escapes any values it finds into their JavaScript String form.
- * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)
- * <p/>
- * So a tab becomes the characters <code>'\\'</code> and
- * <code>'t'</code>.
- * <p/>
- * The only difference between Java strings and JavaScript strings
- * is that in JavaScript, a single quote must be escaped.
- * <p/>
- * Example:
- * <pre>
- * input string: He didn't say, "Stop!"
- * output string: He didn\'t say, \"Stop!\"
- * </pre>
- *
- * @author Sindre Mehus
- */
-public class EscapeJavaScriptTag extends BodyTagSupport {
-
- private String string;
-
- public int doStartTag() throws JspException {
- return EVAL_BODY_BUFFERED;
- }
-
- public int doEndTag() throws JspException {
- try {
- pageContext.getOut().print(StringEscapeUtils.escapeJavaScript(string));
- } catch (IOException x) {
- throw new JspTagException(x);
- }
- return EVAL_PAGE;
- }
-
- public void release() {
- string = null;
- super.release();
- }
-
- public String getString() {
- return string;
- }
-
- public void setString(String string) {
- this.string = string;
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java
deleted file mode 100644
index 0279316b..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/FormatBytesTag.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.taglib;
-
-import net.sourceforge.subsonic.util.*;
-import org.springframework.web.servlet.support.*;
-
-import javax.servlet.http.*;
-import javax.servlet.jsp.*;
-import javax.servlet.jsp.tagext.*;
-import java.io.*;
-import java.util.*;
-
-/**
- * Converts a byte-count to a formatted string suitable for display to the user, with respect
- * to the current locale.
- * <p/>
- * For instance:
- * <ul>
- * <li><code>format(918)</code> returns <em>"918 B"</em>.</li>
- * <li><code>format(98765)</code> returns <em>"96 KB"</em>.</li>
- * <li><code>format(1238476)</code> returns <em>"1.2 MB"</em>.</li>
- * </ul>
- * This class assumes that 1 KB is 1024 bytes.
- *
- * @author Sindre Mehus
- */
-public class FormatBytesTag extends BodyTagSupport {
-
- private long bytes;
-
- public int doStartTag() throws JspException {
- return EVAL_BODY_BUFFERED;
- }
-
- public int doEndTag() throws JspException {
- Locale locale = RequestContextUtils.getLocale((HttpServletRequest) pageContext.getRequest());
- String result = StringUtil.formatBytes(bytes, locale);
-
- try {
- pageContext.getOut().print(result);
- } catch (IOException x) {
- throw new JspTagException(x);
- }
- return EVAL_PAGE;
- }
-
- public void release() {
- bytes = 0L;
- super.release();
- }
-
- public long getBytes() {
- return bytes;
- }
-
- public void setBytes(long bytes) {
- this.bytes = bytes;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java
deleted file mode 100644
index 1043902e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/ParamTag.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.taglib;
-
-import javax.servlet.jsp.tagext.*;
-import javax.servlet.jsp.*;
-
-/**
- * A tag representing an URL query parameter.
- *
- * @see ParamTag
- * @author Sindre Mehus
- */
-public class ParamTag extends TagSupport {
-
- private String name;
- private String value;
-
- public int doEndTag() throws JspTagException {
-
- // Add parameter name and value to surrounding 'url' tag.
- UrlTag tag = (UrlTag) findAncestorWithClass(this, UrlTag.class);
- if (tag == null) {
- throw new JspTagException("'sub:param' tag used outside 'sub:url'");
- }
- tag.addParameter(name, value);
- return EVAL_PAGE;
- }
-
- public void release() {
- name = null;
- value = null;
- super.release();
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java
deleted file mode 100644
index 141ba847..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/UrlTag.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.taglib;
-
-import net.sourceforge.subsonic.Logger;
-import net.sourceforge.subsonic.filter.ParameterDecodingFilter;
-import net.sourceforge.subsonic.util.StringUtil;
-import org.apache.taglibs.standard.tag.common.core.UrlSupport;
-import org.apache.commons.lang.CharUtils;
-
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.JspTagException;
-import javax.servlet.jsp.PageContext;
-import javax.servlet.jsp.tagext.BodyTagSupport;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Creates a URL with optional query parameters. Similar to 'c:url', but
- * you may specify which character encoding to use for the URL query
- * parameters. If no encoding is specified, the following steps are performed:
- * <ul>
- * <li>Parameter values are encoded as the hexadecimal representation of the UTF-8 bytes of the original string.</li>
- * <li>Parameter names are prepended with the suffix "Utf8Hex"</li>
- * <li>Note: Nothing is done with the parameter name or value if the value only contains ASCII alphanumeric characters.</li>
- * </ul>
- * <p/>
- * (The problem with c:url is that is uses the same encoding as the http response,
- * but most(?) servlet container assumes that ISO-8859-1 is used.)
- *
- * @author Sindre Mehus
- */
-public class UrlTag extends BodyTagSupport {
-
- private String DEFAULT_ENCODING = "Utf8Hex";
- private static final Logger LOG = Logger.getLogger(UrlTag.class);
-
- private String var;
- private String value;
- private String encoding = DEFAULT_ENCODING;
- private List<Parameter> parameters = new ArrayList<Parameter>();
-
- public int doStartTag() throws JspException {
- parameters.clear();
- return EVAL_BODY_BUFFERED;
- }
-
- public int doEndTag() throws JspException {
-
- // Rewrite and encode the url.
- String result = formatUrl();
-
- // Store or print the output
- if (var != null)
- pageContext.setAttribute(var, result, PageContext.PAGE_SCOPE);
- else {
- try {
- pageContext.getOut().print(result);
- } catch (IOException x) {
- throw new JspTagException(x);
- }
- }
- return EVAL_PAGE;
- }
-
- private String formatUrl() throws JspException {
- String baseUrl = UrlSupport.resolveUrl(value, null, pageContext);
-
- StringBuffer result = new StringBuffer();
- result.append(baseUrl);
- if (!parameters.isEmpty()) {
- result.append('?');
-
- for (int i = 0; i < parameters.size(); i++) {
- Parameter parameter = parameters.get(i);
- try {
- result.append(parameter.getName());
- if (isUtf8Hex() && !isAsciiAlphaNumeric(parameter.getValue())) {
- result.append(ParameterDecodingFilter.PARAM_SUFFIX);
- }
-
- result.append('=');
- if (parameter.getValue() != null) {
- result.append(encode(parameter.getValue()));
- }
- if (i < parameters.size() - 1) {
- result.append("&");
- }
-
- } catch (UnsupportedEncodingException x) {
- throw new JspTagException(x);
- }
- }
- }
- return result.toString();
- }
-
- private String encode(String s) throws UnsupportedEncodingException {
- if (isUtf8Hex()) {
- if (isAsciiAlphaNumeric(s)) {
- return s;
- }
-
- try {
- return StringUtil.utf8HexEncode(s);
- } catch (Exception x) {
- LOG.error("Failed to utf8hex-encode the string '" + s + "'.", x);
- return s;
- }
- }
-
- return URLEncoder.encode(s, encoding);
- }
-
- private boolean isUtf8Hex() {
- return DEFAULT_ENCODING.equals(encoding);
- }
-
- private boolean isAsciiAlphaNumeric(String s) {
- if (s == null) {
- return true;
- }
-
- for (int i = 0; i < s.length(); i++) {
- if (!CharUtils.isAsciiAlphanumeric(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- public void release() {
- var = null;
- value = null;
- encoding = DEFAULT_ENCODING;
- parameters.clear();
- super.release();
- }
-
- public void addParameter(String name, String value) {
- parameters.add(new Parameter(name, value));
- }
-
- public String getVar() {
- return var;
- }
-
- public void setVar(String var) {
- this.var = var;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public String getEncoding() {
- return encoding;
- }
-
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
-
- /**
- * A URL query parameter.
- */
- private static class Parameter {
- private String name;
- private String value;
-
- private Parameter(String name, String value) {
- this.name = name;
- this.value = value;
- }
-
- private String getName() {
- return name;
- }
-
- private String getValue() {
- return value;
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java
deleted file mode 100644
index e099bd1e..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/taglib/WikiTag.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.taglib;
-
-import org.radeox.api.engine.*;
-import org.radeox.api.engine.context.*;
-import org.radeox.engine.*;
-import org.radeox.engine.context.*;
-import org.apache.commons.lang.*;
-
-import javax.servlet.jsp.*;
-import javax.servlet.jsp.tagext.*;
-import java.io.*;
-
-/**
- * Renders a Wiki text with markup to HTML, using the Radeox render engine.
- *
- * @author Sindre Mehus
- */
-public class WikiTag extends BodyTagSupport {
-
- private static final RenderContext RENDER_CONTEXT = new BaseRenderContext();
- private static final RenderEngine RENDER_ENGINE = new BaseRenderEngine();
-
- private String text;
-
- public int doStartTag() throws JspException {
- return EVAL_BODY_BUFFERED;
- }
-
- public int doEndTag() throws JspException {
- String result;
- synchronized (RENDER_ENGINE) {
- result = RENDER_ENGINE.render(StringEscapeUtils.unescapeXml(text), RENDER_CONTEXT);
- }
- try {
- pageContext.getOut().print(result);
- } catch (IOException x) {
- throw new JspTagException(x);
- }
- return EVAL_PAGE;
- }
-
- public void release() {
- text = null;
- super.release();
- }
-
- public String getText() {
- return text;
- }
-
- public void setText(String text) {
- this.text = text;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeResolver.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeResolver.java
deleted file mode 100644
index 874c2e9c..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeResolver.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.theme;
-
-import net.sourceforge.subsonic.service.*;
-import net.sourceforge.subsonic.domain.*;
-import org.springframework.web.servlet.*;
-
-import javax.servlet.http.*;
-import java.util.*;
-
-/**
- * Theme resolver implementation which returns the theme selected in the settings.
- *
- * @author Sindre Mehus
- */
-public class SubsonicThemeResolver implements ThemeResolver {
-
- private SecurityService securityService;
- private SettingsService settingsService;
- private Set<String> themeIds;
-
- /**
- * Resolve the current theme name via the given request.
- *
- * @param request Request to be used for resolution
- * @return The current theme name
- */
- public String resolveThemeName(HttpServletRequest request) {
- String themeId = (String) request.getAttribute("subsonic.theme");
- if (themeId != null) {
- return themeId;
- }
-
- // Optimization: Cache theme in the request.
- themeId = doResolveThemeName(request);
- request.setAttribute("subsonic.theme", themeId);
-
- return themeId;
- }
-
- private String doResolveThemeName(HttpServletRequest request) {
- String themeId = null;
-
- // Look for user-specific theme.
- String username = securityService.getCurrentUsername(request);
- if (username != null) {
- UserSettings userSettings = settingsService.getUserSettings(username);
- if (userSettings != null) {
- themeId = userSettings.getThemeId();
- }
- }
-
- if (themeId != null && themeExists(themeId)) {
- return themeId;
- }
-
- // Return system theme.
- themeId = settingsService.getThemeId();
- return themeExists(themeId) ? themeId : "default";
- }
-
- /**
- * Returns whether the theme with the given ID exists.
- * @param themeId The theme ID.
- * @return Whether the theme with the given ID exists.
- */
- private synchronized boolean themeExists(String themeId) {
- // Lazily create set of theme IDs.
- if (themeIds == null) {
- themeIds = new HashSet<String>();
- Theme[] themes = settingsService.getAvailableThemes();
- for (Theme theme : themes) {
- themeIds.add(theme.getId());
- }
- }
-
- return themeIds.contains(themeId);
- }
-
- /**
- * Set the current theme name to the given one. This method is not supported.
- *
- * @param request Request to be used for theme name modification
- * @param response Response to be used for theme name modification
- * @param themeName The new theme name
- * @throws UnsupportedOperationException If the ThemeResolver implementation
- * does not support dynamic changing of the theme
- */
- public void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName) {
- throw new UnsupportedOperationException("Cannot change theme - use a different theme resolution strategy");
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeSource.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeSource.java
deleted file mode 100644
index 61db6516..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/theme/SubsonicThemeSource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.theme;
-
-import org.springframework.ui.context.support.ResourceBundleThemeSource;
-import org.springframework.context.MessageSource;
-import org.springframework.context.support.ResourceBundleMessageSource;
-
-/**
- * Theme source implementation which uses two resource bundles: the
- * theme specific (e.g., barents.properties), and the default (default.properties).
- *
- * @author Sindre Mehus
- */
-public class SubsonicThemeSource extends ResourceBundleThemeSource {
-
- private String defaultResourceBundle;
-
- @Override
- protected MessageSource createMessageSource(String basename) {
- ResourceBundleMessageSource messageSource = (ResourceBundleMessageSource) super.createMessageSource(basename);
-
- ResourceBundleMessageSource parentMessageSource = new ResourceBundleMessageSource();
- parentMessageSource.setBasename(defaultResourceBundle);
- messageSource.setParentMessageSource(parentMessageSource);
-
- return messageSource;
- }
-
- public void setDefaultResourceBundle(String defaultResourceBundle) {
- this.defaultResourceBundle = defaultResourceBundle;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItem.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItem.java
deleted file mode 100644
index f9b89bb7..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItem.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.upload;
-
-import org.apache.commons.fileupload.disk.DiskFileItem;
-
-import java.io.File;
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * Extension of Commons FileUpload for monitoring the upload progress.
- *
- * @author Pierre-Alexandre Losson -- http://www.telio.be/blog -- plosson@users.sourceforge.net
- */
-public class MonitoredDiskFileItem extends DiskFileItem {
- private MonitoredOutputStream mos;
- private UploadListener listener;
-
- public MonitoredDiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold,
- File repository, UploadListener listener) {
- super(fieldName, contentType, isFormField, fileName, sizeThreshold, repository);
- this.listener = listener;
- if (fileName != null) {
- listener.start(fileName);
- }
- }
-
- public OutputStream getOutputStream() throws IOException {
- if (mos == null) {
- mos = new MonitoredOutputStream(super.getOutputStream(), listener);
- }
- return mos;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItemFactory.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItemFactory.java
deleted file mode 100644
index b5d6125d..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredDiskFileItemFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.upload;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-
-import java.io.File;
-
-/**
- * Extension of Commons FileUpload for monitoring the upload progress.
- *
- * @author Pierre-Alexandre Losson -- http://www.telio.be/blog -- plosson@users.sourceforge.net
- */
-public class MonitoredDiskFileItemFactory extends DiskFileItemFactory {
- private UploadListener listener;
-
- public MonitoredDiskFileItemFactory(UploadListener listener) {
- super();
- this.listener = listener;
- }
-
- public MonitoredDiskFileItemFactory(int sizeThreshold, File repository, UploadListener listener) {
- super(sizeThreshold, repository);
- this.listener = listener;
- }
-
- public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) {
- return new MonitoredDiskFileItem(fieldName, contentType, isFormField, fileName, getSizeThreshold(), getRepository(), listener);
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredOutputStream.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredOutputStream.java
deleted file mode 100644
index c7f0d525..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/MonitoredOutputStream.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.upload;
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * Extension of Commons FileUpload for monitoring the upload progress.
- *
- * @author Pierre-Alexandre Losson -- http://www.telio.be/blog -- plosson@users.sourceforge.net
- */
-public class MonitoredOutputStream extends OutputStream {
- private OutputStream target;
- private UploadListener listener;
-
- public MonitoredOutputStream(OutputStream target, UploadListener listener) {
- this.target = target;
- this.listener = listener;
- }
-
- public void write(byte[] b, int off, int len) throws IOException {
- target.write(b, off, len);
- listener.bytesRead(len);
- }
-
- public void write(byte[] b) throws IOException {
- target.write(b);
- listener.bytesRead(b.length);
- }
-
- public void write(int b) throws IOException {
- target.write(b);
- listener.bytesRead(1);
- }
-
- public void close() throws IOException {
- target.close();
- }
-
- public void flush() throws IOException {
- target.flush();
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/UploadListener.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/UploadListener.java
deleted file mode 100644
index 7eac415a..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/upload/UploadListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.upload;
-
-/**
- * Extension of Commons FileUpload for monitoring the upload progress.
- *
- * @author Pierre-Alexandre Losson -- http://www.telio.be/blog -- plosson@users.sourceforge.net
- */
-public interface UploadListener {
- void start(String fileName);
- void bytesRead(long bytesRead);
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/BoundedList.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/BoundedList.java
deleted file mode 100644
index fb240d5f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/BoundedList.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.util;
-
-import java.util.*;
-
-/**
- * Simple implementation of a bounded list. If the maximum size is reached, adding a new element will
- * remove the first element in the list.
- *
- * @author Sindre Mehus
- * @version $Revision: 1.1 $ $Date: 2005/05/09 20:01:25 $
- */
-public class BoundedList<E> extends LinkedList<E> {
- private int maxSize;
-
- /**
- * Creates a new bounded list with the given maximum size.
- * @param maxSize The maximum number of elements the list may hold.
- */
- public BoundedList(int maxSize) {
- this.maxSize = maxSize;
- }
-
- /**
- * Adds an element to the tail of the list. If the list is full, the first element is removed.
- * @param e The element to add.
- * @return Always <code>true</code>.
- */
- public boolean add(E e) {
- if (isFull()) {
- removeFirst();
- }
- return super.add(e);
- }
-
- /**
- * Adds an element to the head of list. If the list is full, the last element is removed.
- * @param e The element to add.
- */
- public void addFirst(E e) {
- if (isFull()) {
- removeLast();
- }
- super.addFirst(e);
- }
-
- /**
- * Returns whether the list if full.
- * @return Whether the list is full.
- */
- private boolean isFull() {
- return size() == maxSize;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/FileUtil.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/FileUtil.java
deleted file mode 100644
index e91758ef..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/FileUtil.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.util;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.Arrays;
-
-import net.sourceforge.subsonic.Logger;
-
-/**
- * Miscellaneous file utility methods.
- *
- * @author Sindre Mehus
- */
-public final class FileUtil {
-
- private static final Logger LOG = Logger.getLogger(FileUtil.class);
-
- /**
- * Disallow external instantiation.
- */
- private FileUtil() {
- }
-
- public static boolean isFile(final File file) {
- return timed(new FileTask<Boolean>("isFile", file) {
- @Override
- public Boolean execute() {
- return file.isFile();
- }
- });
- }
-
- public static boolean isDirectory(final File file) {
- return timed(new FileTask<Boolean>("isDirectory", file) {
- @Override
- public Boolean execute() {
- return file.isDirectory();
- }
- });
- }
-
- public static boolean exists(final File file) {
- return timed(new FileTask<Boolean>("exists", file) {
- @Override
- public Boolean execute() {
- return file.exists();
- }
- });
- }
-
- public static long lastModified(final File file) {
- return timed(new FileTask<Long>("lastModified", file) {
- @Override
- public Long execute() {
- return file.lastModified();
- }
- });
- }
-
- public static long length(final File file) {
- return timed(new FileTask<Long>("length", file) {
- @Override
- public Long execute() {
- return file.length();
- }
- });
- }
-
- /**
- * Similar to {@link File#listFiles()}, but never returns null.
- * Instead a warning is logged, and an empty array is returned.
- */
- public static File[] listFiles(final File dir) {
- File[] files = timed(new FileTask<File[]>("listFiles", dir) {
- @Override
- public File[] execute() {
- return dir.listFiles();
- }
- });
-
- if (files == null) {
- LOG.warn("Failed to list children for " + dir.getPath());
- return new File[0];
- }
- return files;
- }
-
- /**
- * Similar to {@link File#listFiles(FilenameFilter)}, but never returns null.
- * Instead a warning is logged, and an empty array is returned.
- */
- public static File[] listFiles(final File dir, final FilenameFilter filter, boolean sort) {
- File[] files = timed(new FileTask<File[]>("listFiles2", dir) {
- @Override
- public File[] execute() {
- return dir.listFiles(filter);
- }
- });
- if (files == null) {
- LOG.warn("Failed to list children for " + dir.getPath());
- return new File[0];
- }
- if (sort) {
- Arrays.sort(files);
- }
- return files;
- }
-
- /**
- * Returns a short path for the given file. The path consists of the name
- * of the parent directory and the given file.
- */
- public static String getShortPath(File file) {
- if (file == null) {
- return null;
- }
- File parent = file.getParentFile();
- if (parent == null) {
- return file.getName();
- }
- return parent.getName() + File.separator + file.getName();
- }
-
- /**
- * Closes the "closable", ignoring any excepetions.
- *
- * @param closeable The Closable to close, may be {@code null}.
- */
- public static void closeQuietly(Closeable closeable) {
- if (closeable != null) {
- try {
- closeable.close();
- } catch (IOException e) {
- // Ignored
- }
- }
- }
-
- private static <T> T timed(FileTask<T> task) {
-// long t0 = System.nanoTime();
-// try {
- return task.execute();
-// } finally {
-// long t1 = System.nanoTime();
-// LOG.debug((t1 - t0) / 1000L + " microsec, " + task);
-// }
- }
-
- private abstract static class FileTask<T> {
-
- private final String name;
- private final File file;
-
- public FileTask(String name, File file) {
- this.name = name;
- this.file = file;
- }
-
- public abstract T execute();
-
- @Override
- public String toString() {
- return name + ", " + file;
- }
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/Pair.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/Pair.java
deleted file mode 100644
index 7edecaa2..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/Pair.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.util;
-
-import java.io.Serializable;
-
-/**
- * @author Sindre Mehus
- */
-public class Pair<S, T> implements Serializable {
-
- private S first;
- private T second;
-
- public Pair() {
- }
-
- public Pair(S first, T second) {
- this.first = first;
- this.second = second;
- }
-
- public S getFirst() {
- return first;
- }
-
- public void setFirst(S first) {
- this.first = first;
- }
-
- public T getSecond() {
- return second;
- }
-
- public void setSecond(T second) {
- this.second = second;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/StringUtil.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/StringUtil.java
deleted file mode 100644
index ebad9fbf..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/StringUtil.java
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.util;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.security.MessageDigest;
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.LongRange;
-
-/**
- * Miscellaneous string utility methods.
- *
- * @author Sindre Mehus
- */
-public final class StringUtil {
-
- public static final String ENCODING_LATIN = "ISO-8859-1";
- public static final String ENCODING_UTF8 = "UTF-8";
- private static final DateFormat ISO_8601_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-
- private static final String[][] HTML_SUBSTITUTIONS = {
- {"&", "&amp;"},
- {"<", "&lt;"},
- {">", "&gt;"},
- {"'", "&#39;"},
- {"\"", "&#34;"},
- };
-
- private static final String[][] MIME_TYPES = {
- {"mp3", "audio/mpeg"},
- {"ogg", "audio/ogg"},
- {"oga", "audio/ogg"},
- {"ogx", "application/ogg"},
- {"aac", "audio/mp4"},
- {"m4a", "audio/mp4"},
- {"flac", "audio/flac"},
- {"wav", "audio/x-wav"},
- {"wma", "audio/x-ms-wma"},
- {"ape", "audio/x-monkeys-audio"},
- {"mpc", "audio/x-musepack"},
- {"shn", "audio/x-shn"},
-
- {"flv", "video/x-flv"},
- {"avi", "video/avi"},
- {"mpg", "video/mpeg"},
- {"mpeg", "video/mpeg"},
- {"mp4", "video/mp4"},
- {"m4v", "video/x-m4v"},
- {"mkv", "video/x-matroska"},
- {"mov", "video/quicktime"},
- {"wmv", "video/x-ms-wmv"},
- {"ogv", "video/ogg"},
- {"divx", "video/divx"},
- {"m2ts", "video/MP2T"},
-
- {"gif", "image/gif"},
- {"jpg", "image/jpeg"},
- {"jpeg", "image/jpeg"},
- {"png", "image/png"},
- {"bmp", "image/bmp"},
- };
-
- private static final String[] FILE_SYSTEM_UNSAFE = {"/", "\\", "..", ":", "\"", "?", "*", "|"};
-
- /**
- * Disallow external instantiation.
- */
- private StringUtil() {
- }
-
- /**
- * Returns the specified string converted to a format suitable for
- * HTML. All single-quote, double-quote, greater-than, less-than and
- * ampersand characters are replaces with their corresponding HTML
- * Character Entity code.
- *
- * @param s the string to convert
- * @return the converted string
- */
- public static String toHtml(String s) {
- if (s == null) {
- return null;
- }
- for (String[] substitution : HTML_SUBSTITUTIONS) {
- if (s.contains(substitution[0])) {
- s = s.replaceAll(substitution[0], substitution[1]);
- }
- }
- return s;
- }
-
-
- /**
- * Formats the given date to a ISO-8601 date/time format, and UTC timezone.
- * <p/>
- * The returned date uses the following format: 2007-12-17T14:57:17
- *
- * @param date The date to format
- * @return The corresponding ISO-8601 formatted string.
- */
- public static String toISO8601(Date date) {
- if (date == null) {
- return null;
- }
-
- synchronized (ISO_8601_DATE_FORMAT) {
- return ISO_8601_DATE_FORMAT.format(date);
- }
- }
-
- /**
- * Removes the suffix (the substring after the last dot) of the given string. The dot is
- * also removed.
- *
- * @param s The string in question, e.g., "foo.mp3".
- * @return The string without the suffix, e.g., "foo".
- */
- public static String removeSuffix(String s) {
- int index = s.lastIndexOf('.');
- return index == -1 ? s : s.substring(0, index);
- }
-
- /**
- * Returns the proper MIME type for the given suffix.
- *
- * @param suffix The suffix, e.g., "mp3" or ".mp3".
- * @return The corresponding MIME type, e.g., "audio/mpeg". If no MIME type is found,
- * <code>application/octet-stream</code> is returned.
- */
- public static String getMimeType(String suffix) {
- for (String[] map : MIME_TYPES) {
- if (map[0].equalsIgnoreCase(suffix) || ('.' + map[0]).equalsIgnoreCase(suffix)) {
- return map[1];
- }
- }
- return "application/octet-stream";
- }
-
- /**
- * Converts a byte-count to a formatted string suitable for display to the user.
- * For instance:
- * <ul>
- * <li><code>format(918)</code> returns <em>"918 B"</em>.</li>
- * <li><code>format(98765)</code> returns <em>"96 KB"</em>.</li>
- * <li><code>format(1238476)</code> returns <em>"1.2 MB"</em>.</li>
- * </ul>
- * This method assumes that 1 KB is 1024 bytes.
- *
- * @param byteCount The number of bytes.
- * @param locale The locale used for formatting.
- * @return The formatted string.
- */
- public static synchronized String formatBytes(long byteCount, Locale locale) {
-
- // More than 1 GB?
- if (byteCount >= 1024 * 1024 * 1024) {
- NumberFormat gigaByteFormat = new DecimalFormat("0.00 GB", new DecimalFormatSymbols(locale));
- return gigaByteFormat.format((double) byteCount / (1024 * 1024 * 1024));
- }
-
- // More than 1 MB?
- if (byteCount >= 1024 * 1024) {
- NumberFormat megaByteFormat = new DecimalFormat("0.0 MB", new DecimalFormatSymbols(locale));
- return megaByteFormat.format((double) byteCount / (1024 * 1024));
- }
-
- // More than 1 KB?
- if (byteCount >= 1024) {
- NumberFormat kiloByteFormat = new DecimalFormat("0 KB", new DecimalFormatSymbols(locale));
- return kiloByteFormat.format((double) byteCount / 1024);
- }
-
- return byteCount + " B";
- }
-
- /**
- * Formats a duration with minutes and seconds, e.g., "93:45"
- */
- public static String formatDuration(int seconds) {
- int minutes = seconds / 60;
- int secs = seconds % 60;
-
- StringBuilder builder = new StringBuilder(6);
- builder.append(minutes).append(":");
- if (secs < 10) {
- builder.append("0");
- }
- builder.append(secs);
- return builder.toString();
- }
-
- /**
- * Splits the input string. White space is interpreted as separator token. Double quotes
- * are interpreted as grouping operator. <br/>
- * For instance, the input <code>"u2 rem "greatest hits""</code> will return an array with
- * three elements: <code>{"u2", "rem", "greatest hits"}</code>
- *
- * @param input The input string.
- * @return Array of elements.
- */
- public static String[] split(String input) {
- if (input == null) {
- return new String[0];
- }
-
- Pattern pattern = Pattern.compile("\".*?\"|\\S+");
- Matcher matcher = pattern.matcher(input);
-
- List<String> result = new ArrayList<String>();
- while (matcher.find()) {
- String element = matcher.group();
- if (element.startsWith("\"") && element.endsWith("\"") && element.length() > 1) {
- element = element.substring(1, element.length() - 1);
- }
- result.add(element);
- }
-
- return result.toArray(new String[result.size()]);
- }
-
- /**
- * Reads lines from the given input stream. All lines are trimmed. Empty lines and lines starting
- * with "#" are skipped. The input stream is always closed by this method.
- *
- * @param in The input stream to read from.
- * @return Array of lines.
- * @throws IOException If an I/O error occurs.
- */
- public static String[] readLines(InputStream in) throws IOException {
- BufferedReader reader = null;
-
- try {
- reader = new BufferedReader(new InputStreamReader(in));
- List<String> result = new ArrayList<String>();
- for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- line = line.trim();
- if (!line.startsWith("#") && line.length() > 0) {
- result.add(line);
- }
- }
- return result.toArray(new String[result.size()]);
-
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(reader);
- }
- }
-
- /**
- * Converts the given string of whitespace-separated integers to an <code>int</code> array.
- *
- * @param s String consisting of integers separated by whitespace.
- * @return The corresponding array of ints.
- * @throws NumberFormatException If string contains non-parseable text.
- */
- public static int[] parseInts(String s) {
- if (s == null) {
- return new int[0];
- }
-
- String[] strings = StringUtils.split(s);
- int[] ints = new int[strings.length];
- for (int i = 0; i < strings.length; i++) {
- ints[i] = Integer.parseInt(strings[i]);
- }
- return ints;
- }
-
- /**
- * Change protocol from "https" to "http" for the given URL. The port number is also changed,
- * but not if the given URL is already "http".
- *
- * @param url The original URL.
- * @param port The port number to use, for instance 443.
- * @return The transformed URL.
- * @throws MalformedURLException If the original URL is invalid.
- */
- public static String toHttpUrl(String url, int port) throws MalformedURLException {
- URL u = new URL(url);
- if ("https".equals(u.getProtocol())) {
- return new URL("http", u.getHost(), port, u.getFile()).toString();
- }
- return url;
- }
-
- /**
- * Determines whether a is equal to b, taking null into account.
- *
- * @return Whether a and b are equal, or both null.
- */
- public static boolean isEqual(Object a, Object b) {
- return a == null ? b == null : a.equals(b);
- }
-
- /**
- * Parses a locale from the given string.
- *
- * @param s The locale string. Should be formatted as per the documentation in {@link Locale#toString()}.
- * @return The locale.
- */
- public static Locale parseLocale(String s) {
- if (s == null) {
- return null;
- }
-
- String[] elements = s.split("_");
-
- if (elements.length == 0) {
- return new Locale(s, "", "");
- }
- if (elements.length == 1) {
- return new Locale(elements[0], "", "");
- }
- if (elements.length == 2) {
- return new Locale(elements[0], elements[1], "");
- }
- return new Locale(elements[0], elements[1], elements[2]);
- }
-
- /**
- * URL-encodes the input value using UTF-8.
- */
- public static String urlEncode(String s) {
- try {
- return URLEncoder.encode(s, StringUtil.ENCODING_UTF8);
- } catch (UnsupportedEncodingException x) {
- throw new RuntimeException(x);
- }
- }
-
- /**
- * Encodes the given string by using the hexadecimal representation of its UTF-8 bytes.
- *
- * @param s The string to encode.
- * @return The encoded string.
- */
- public static String utf8HexEncode(String s) {
- if (s == null) {
- return null;
- }
- byte[] utf8;
- try {
- utf8 = s.getBytes(ENCODING_UTF8);
- } catch (UnsupportedEncodingException x) {
- throw new RuntimeException(x);
- }
- return String.valueOf(Hex.encodeHex(utf8));
- }
-
- /**
- * Decodes the given string by using the hexadecimal representation of its UTF-8 bytes.
- *
- * @param s The string to decode.
- * @return The decoded string.
- * @throws Exception If an error occurs.
- */
- public static String utf8HexDecode(String s) throws Exception {
- if (s == null) {
- return null;
- }
- return new String(Hex.decodeHex(s.toCharArray()), ENCODING_UTF8);
- }
-
- /**
- * Calculates the MD5 digest and returns the value as a 32 character hex string.
- *
- * @param s Data to digest.
- * @return MD5 digest as a hex string.
- */
- public static String md5Hex(String s) {
- if (s == null) {
- return null;
- }
-
- try {
- MessageDigest md5 = MessageDigest.getInstance("MD5");
- return new String(Hex.encodeHex(md5.digest(s.getBytes(ENCODING_UTF8))));
- } catch (Exception x) {
- throw new RuntimeException(x.getMessage(), x);
- }
- }
-
- /**
- * Returns the file part of an URL. For instance:
- * <p/>
- * <code>
- * getUrlFile("http://archive.ncsa.uiuc.edu:80/SDG/Software/Mosaic/Demo/url-primer.html")
- * </code>
- * <p/>
- * will return "url-primer.html".
- *
- * @param url The URL in question.
- * @return The file part, or <code>null</code> if no file can be resolved.
- */
- public static String getUrlFile(String url) {
- try {
- String path = new URL(url).getPath();
- if (StringUtils.isBlank(path) || path.endsWith("/")) {
- return null;
- }
-
- File file = new File(path);
- String filename = file.getName();
- if (StringUtils.isBlank(filename)) {
- return null;
- }
- return filename;
-
- } catch (MalformedURLException x) {
- return null;
- }
- }
-
- /**
- * Rewrites the URL by changing the protocol, host and port.
- *
- * @param urlToRewrite The URL to rewrite.
- * @param urlWithProtocolHostAndPort Use protocol, host and port from this URL.
- * @return The rewritten URL, or an unchanged URL if either argument is not a proper URL.
- */
- public static String rewriteUrl(String urlToRewrite, String urlWithProtocolHostAndPort) {
- if (urlToRewrite == null) {
- return null;
- }
-
- try {
- URL urlA = new URL(urlToRewrite);
- URL urlB = new URL(urlWithProtocolHostAndPort);
-
- URL result = new URL(urlB.getProtocol(), urlB.getHost(), urlB.getPort(), urlA.getFile());
- return result.toExternalForm();
- } catch (MalformedURLException x) {
- return urlToRewrite;
- }
- }
-
- /**
- * Makes a given filename safe by replacing special characters like slashes ("/" and "\")
- * with dashes ("-").
- *
- * @param filename The filename in question.
- * @return The filename with special characters replaced by underscores.
- */
- public static String fileSystemSafe(String filename) {
- for (String s : FILE_SYSTEM_UNSAFE) {
- filename = filename.replace(s, "-");
- }
- return filename;
- }
-
- /**
- * Parses the given string as a HTTP header byte range. See chapter 14.36.1 in RFC 2068
- * for details.
- * <p/>
- * Only a subset of the allowed syntaxes are supported. Only ranges which specify first-byte-pos
- * are supported. The last-byte-pos is optional.
- *
- * @param range The range from the HTTP header, for instance "bytes=0-499" or "bytes=500-"
- * @return A range object (using inclusive values). If the last-byte-pos is not given, the end of
- * the returned range is {@link Long#MAX_VALUE}. The method returns <code>null</code> if the syntax
- * of the given range is not supported.
- */
- public static LongRange parseRange(String range) {
- if (range == null) {
- return null;
- }
-
- Pattern pattern = Pattern.compile("bytes=(\\d+)-(\\d*)");
- Matcher matcher = pattern.matcher(range);
-
- if (matcher.matches()) {
- String firstString = matcher.group(1);
- String lastString = StringUtils.trimToNull(matcher.group(2));
-
- long first = Long.parseLong(firstString);
- long last = lastString == null ? Long.MAX_VALUE : Long.parseLong(lastString);
-
- if (first > last) {
- return null;
- }
-
- return new LongRange(first, last);
- }
- return null;
- }
-
- public static String removeMarkup(String s) {
- if (s == null) {
- return null;
- }
- return s.replaceAll("<.*?>", "");
- }
-
- public static String getRESTProtocolVersion() {
- // TODO: Read from xsd.
- return "1.8.0";
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/Util.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/Util.java
deleted file mode 100644
index ec7175a2..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/Util.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.util;
-
-import net.sourceforge.subsonic.Logger;
-
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.Inet4Address;
-import java.util.Enumeration;
-import java.util.Random;
-
-/**
- * Miscellaneous general utility methods.
- *
- * @author Sindre Mehus
- */
-public final class Util {
-
- private static final Logger LOG = Logger.getLogger(Util.class);
- private static final Random RANDOM = new Random(System.currentTimeMillis());
-
- /**
- * Disallow external instantiation.
- */
- private Util() {
- }
-
- public static String getDefaultMusicFolder() {
- String def = isWindows() ? "c:\\music" : "/var/music";
- return System.getProperty("subsonic.defaultMusicFolder", def);
- }
-
- public static String getDefaultPodcastFolder() {
- String def = isWindows() ? "c:\\music\\Podcast" : "/var/music/Podcast";
- return System.getProperty("subsonic.defaultPodcastFolder", def);
- }
-
- public static String getDefaultPlaylistFolder() {
- String def = isWindows() ? "c:\\playlists" : "/var/playlists";
- return System.getProperty("subsonic.defaultPlaylistFolder", def);
- }
-
- public static boolean isWindows() {
- return System.getProperty("os.name", "Windows").toLowerCase().startsWith("windows");
- }
-
- public static boolean isWindowsInstall() {
- return "true".equals(System.getProperty("subsonic.windowsInstall"));
- }
-
- /**
- * Similar to {@link ServletResponse#setContentLength(int)}, but this
- * method supports lengths bigger than 2GB.
- * <p/>
- * See http://blogger.ziesemer.com/2008/03/suns-version-of-640k-2gb.html
- *
- * @param response The HTTP response.
- * @param length The content length.
- */
- public static void setContentLength(HttpServletResponse response, long length) {
- if (length <= Integer.MAX_VALUE) {
- response.setContentLength((int) length);
- } else {
- response.setHeader("Content-Length", String.valueOf(length));
- }
- }
-
- /**
- * Returns the local IP address.
- * @return The local IP, or the loopback address (127.0.0.1) if not found.
- */
- public static String getLocalIpAddress() {
- try {
-
- // Try the simple way first.
- InetAddress address = InetAddress.getLocalHost();
- if (!address.isLoopbackAddress()) {
- return address.getHostAddress();
- }
-
- // Iterate through all network interfaces, looking for a suitable IP.
- Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
- while (interfaces.hasMoreElements()) {
- NetworkInterface iface = interfaces.nextElement();
- Enumeration<InetAddress> addresses = iface.getInetAddresses();
- while (addresses.hasMoreElements()) {
- InetAddress addr = addresses.nextElement();
- if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {
- return addr.getHostAddress();
- }
- }
- }
-
- } catch (Throwable x) {
- LOG.warn("Failed to resolve local IP address.", x);
- }
-
- return "127.0.0.1";
- }
-
- public static int randomInt(int min, int max) {
- if (min >= max) {
- return 0;
- }
- return min + RANDOM.nextInt(max - min);
-
- }
-} \ No newline at end of file
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java
deleted file mode 100644
index a572ac0f..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/util/XMLBuilder.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.util;
-
-import org.apache.commons.lang.StringEscapeUtils;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.XML;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Stack;
-
-
-/**
- * Simplifies building of XML documents.
- * <p/>
- * <b>Example:</b><br/>
- * The following code:
- * <pre>
- * XMLBuilder builder = XMLBuilder.createXMLBuilder();
- * builder.add("foo").add("bar");
- * builder.add("zonk", 42);
- * builder.end().end();
- * System.out.println(builder.toString());
- * </pre>
- * produces the following XML:
- * <pre>
- * &lt;foo&gt;
- * &lt;bar&gt;
- * &lt;zonk&gt;42&lt;/zonk&gt;
- * &lt;/bar&gt;
- * &lt;/foo&gt;
- * </pre>
- * This class is <em>not</em> thread safe.
- * <p/>
- * Also supports JSON and JSONP formats.
- *
- * @author Sindre Mehus
- */
-public class XMLBuilder {
-
- private static final String INDENTATION = " ";
- private static final String NEWLINE = "\n";
-
- private final Writer writer = new StringWriter();
- private final Stack<String> elementStack = new Stack<String>();
- private final boolean json;
- private final String jsonpCallback;
-
- public static XMLBuilder createXMLBuilder() {
- return new XMLBuilder(false, null);
- }
-
- public static XMLBuilder createJSONBuilder() {
- return new XMLBuilder(true, null);
- }
-
- public static XMLBuilder createJSONPBuilder(String callback) {
- return new XMLBuilder(true, callback);
- }
-
- /**
- * Creates a new instance.
- *
- * @param json Whether to produce JSON rather than XML.
- * @param jsonpCallback Name of javascript callback for JSONP.
- */
- private XMLBuilder(boolean json, String jsonpCallback) {
- this.json = json;
- this.jsonpCallback = jsonpCallback;
- }
-
- /**
- * Adds an XML preamble, with the given encoding. The preamble will typically
- * look like this:
- * <p/>
- * <code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;</code>
- *
- * @param encoding The encoding to put in the preamble.
- * @return A reference to this object.
- */
- public XMLBuilder preamble(String encoding) throws IOException {
- writer.write("<?xml version=\"1.0\" encoding=\"");
- writer.write(encoding);
- writer.write("\"?>");
- newline();
- return this;
- }
-
- /**
- * Adds an element with the given name and a single attribute.
- *
- * @param element The element name.
- * @param attributeKey The attributes key.
- * @param attributeValue The attributes value.
- * @param close Whether to close the element.
- * @return A reference to this object.
- */
- public XMLBuilder add(String element, String attributeKey, Object attributeValue, boolean close) throws IOException {
- return add(element, close, new Attribute(attributeKey, attributeValue));
- }
-
- /**
- * Adds an element with the given name and attributes.
- *
- * @param element The element name.
- * @param close Whether to close the element.
- * @param attributes The element attributes.
- * @return A reference to this object.
- */
- public XMLBuilder add(String element, boolean close, Attribute... attributes) throws IOException {
- return add(element, Arrays.asList(attributes), close);
- }
-
- /**
- * Adds an element with the given name and attributes.
- *
- * @param element The element name.
- * @param attributes The element attributes.
- * @param close Whether to close the element.
- * @return A reference to this object.
- */
- public XMLBuilder add(String element, Iterable<Attribute> attributes, boolean close) throws IOException {
- return add(element, attributes, null, close);
- }
-
- /**
- * Adds an element with the given name, attributes and character data.
- *
- * @param element The element name.
- * @param attributes The element attributes.
- * @param text The character data.
- * @param close Whether to close the element.
- * @return A reference to this object.
- */
- public XMLBuilder add(String element, Iterable<Attribute> attributes, String text, boolean close) throws IOException {
- indent();
- elementStack.push(element);
- writer.write('<');
- writer.write(element);
-
- if (attributes == null) {
- attributes = Collections.emptyList();
- }
-
- Iterator<Attribute> iterator = attributes.iterator();
-
- if (iterator.hasNext()) {
- writer.write(' ');
- }
- while (iterator.hasNext()) {
- Attribute attribute = iterator.next();
- attribute.append(writer);
- if (iterator.hasNext()) {
- writer.write(' ');
- }
- }
-
- if (close && text == null) {
- elementStack.pop();
- writer.write("/>");
- } else {
- writer.write('>');
- }
-
- if (text != null) {
- writer.write(text);
-
- if (close) {
- elementStack.pop();
- writer.write("</");
- writer.write(element);
- writer.write('>');
- }
- }
-
- newline();
- return this;
- }
-
- /**
- * Closes the current element.
- *
- * @return A reference to this object.
- * @throws IllegalStateException If there are no unclosed elements.
- */
- public XMLBuilder end() throws IllegalStateException, IOException {
- if (elementStack.isEmpty()) {
- throw new IllegalStateException("There are no unclosed elements.");
- }
-
- String element = elementStack.pop();
- indent();
- writer.write("</");
- writer.write(element);
- writer.write('>');
- newline();
- return this;
- }
-
- /**
- * Closes all unclosed elements.
- *
- * @return A reference to this object.
- */
- public XMLBuilder endAll() throws IOException {
- while (!elementStack.isEmpty()) {
- end();
- }
- return this;
- }
-
- /**
- * Returns the XML document as a string.
- */
- @Override
- public String toString() {
- String xml = writer.toString();
- if (!json) {
- return xml;
- }
- try {
- JSONObject jsonObject = XML.toJSONObject(xml);
-
- if (jsonpCallback != null) {
- return jsonpCallback + "(" + jsonObject.toString(1) + ");";
- }
-
- return jsonObject.toString(1);
- } catch (JSONException x) {
- throw new RuntimeException("Failed to convert from XML to JSON.", x);
- }
- }
-
- private void indent() throws IOException {
- int depth = elementStack.size();
- for (int i = 0; i < depth; i++) {
- writer.write(INDENTATION);
- }
- }
-
- private void newline() throws IOException {
- writer.write(NEWLINE);
- }
-
- /**
- * An XML element attribute.
- */
- public static class Attribute {
-
- private final String key;
- private final Object value;
-
- public Attribute(String key, Object value) {
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return key;
- }
-
- public Object getValue() {
- return value;
- }
-
- private void append(Writer writer) throws IOException {
- if (key != null && value != null) {
- writer.write(key);
- writer.write("=\"");
- writer.write(StringEscapeUtils.escapeXml(value.toString()));
- writer.write("\"");
- }
- }
- }
-
- /**
- * A set of attributes.
- */
- public static class AttributeSet implements Iterable<Attribute> {
-
- private final Map<String, Attribute> attributes = new LinkedHashMap<String, Attribute>();
-
- public void add(Attribute attribute) {
- attributes.put(attribute.getKey(), attribute);
- }
-
- public void add(String key, Object value) {
- if (key != null && value != null) {
- add(new Attribute(key, value));
- }
- }
-
- public void addAll(Iterable<Attribute> attributes) {
- for (Attribute attribute : attributes) {
- add(attribute);
- }
- }
-
- public Iterator<Attribute> iterator() {
- return attributes.values().iterator();
- }
- }
-
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/DonateValidator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/DonateValidator.java
deleted file mode 100644
index 276eacb0..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/DonateValidator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.validator;
-
-import org.springframework.validation.Validator;
-import org.springframework.validation.Errors;
-import net.sourceforge.subsonic.command.PasswordSettingsCommand;
-import net.sourceforge.subsonic.command.DonateCommand;
-import net.sourceforge.subsonic.controller.DonateController;
-import net.sourceforge.subsonic.service.SettingsService;
-
-/**
- * Validator for {@link DonateController}.
- *
- * @author Sindre Mehus
- */
-public class DonateValidator implements Validator {
- private SettingsService settingsService;
-
- public boolean supports(Class clazz) {
- return clazz.equals(DonateCommand.class);
- }
-
- public void validate(Object obj, Errors errors) {
- DonateCommand command = (DonateCommand) obj;
-
- if (!settingsService.isLicenseValid(command.getEmailAddress(), command.getLicense())) {
- errors.rejectValue("license", "donate.invalidlicense");
- }
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/PasswordSettingsValidator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/PasswordSettingsValidator.java
deleted file mode 100644
index 12fb06ce..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/PasswordSettingsValidator.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.validator;
-
-import org.springframework.validation.*;
-import net.sourceforge.subsonic.command.*;
-import net.sourceforge.subsonic.controller.*;
-
-/**
- * Validator for {@link PasswordSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class PasswordSettingsValidator implements Validator {
-
- public boolean supports(Class clazz) {
- return clazz.equals(PasswordSettingsCommand.class);
- }
-
- public void validate(Object obj, Errors errors) {
- PasswordSettingsCommand command = (PasswordSettingsCommand) obj;
-
- if (command.getPassword() == null || command.getPassword().length() == 0) {
- errors.rejectValue("password", "usersettings.nopassword");
- } else if (!command.getPassword().equals(command.getConfirmPassword())) {
- errors.rejectValue("password", "usersettings.wrongpassword");
- }
- }
-}
diff --git a/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/UserSettingsValidator.java b/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/UserSettingsValidator.java
deleted file mode 100644
index 3445b7d8..00000000
--- a/subsonic-main/src/main/java/net/sourceforge/subsonic/validator/UserSettingsValidator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package net.sourceforge.subsonic.validator;
-
-import net.sourceforge.subsonic.command.UserSettingsCommand;
-import net.sourceforge.subsonic.controller.UserSettingsController;
-import net.sourceforge.subsonic.service.SecurityService;
-import net.sourceforge.subsonic.service.SettingsService;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.validation.Errors;
-import org.springframework.validation.Validator;
-
-/**
- * Validator for {@link UserSettingsController}.
- *
- * @author Sindre Mehus
- */
-public class UserSettingsValidator implements Validator {
-
- private SecurityService securityService;
- private SettingsService settingsService;
-
- /**
- * {@inheritDoc}
- */
- public boolean supports(Class clazz) {
- return clazz.equals(UserSettingsCommand.class);
- }
-
- /**
- * {@inheritDoc}
- */
- public void validate(Object obj, Errors errors) {
- UserSettingsCommand command = (UserSettingsCommand) obj;
- String username = command.getUsername();
- String email = StringUtils.trimToNull(command.getEmail());
- String password = StringUtils.trimToNull(command.getPassword());
- String confirmPassword = command.getConfirmPassword();
-
- if (command.isNew()) {
- if (username == null || username.length() == 0) {
- errors.rejectValue("username", "usersettings.nousername");
- } else if (securityService.getUserByName(username) != null) {
- errors.rejectValue("username", "usersettings.useralreadyexists");
- } else if (email == null) {
- errors.rejectValue("email", "usersettings.noemail");
- } else if (command.isLdapAuthenticated() && !settingsService.isLdapEnabled()) {
- errors.rejectValue("password", "usersettings.ldapdisabled");
- } else if (command.isLdapAuthenticated() && password != null) {
- errors.rejectValue("password", "usersettings.passwordnotsupportedforldap");
- }
- }
-
- if ((command.isNew() || command.isPasswordChange()) && !command.isLdapAuthenticated()) {
- if (password == null) {
- errors.rejectValue("password", "usersettings.nopassword");
- } else if (!password.equals(confirmPassword)) {
- errors.rejectValue("password", "usersettings.wrongpassword");
- }
- }
-
- if (command.isPasswordChange() && command.isLdapAuthenticated()) {
- errors.rejectValue("password", "usersettings.passwordnotsupportedforldap");
- }
-
- }
-
- public void setSecurityService(SecurityService securityService) {
- this.securityService = securityService;
- }
-
- public void setSettingsService(SettingsService settingsService) {
- this.settingsService = settingsService;
- }
-} \ No newline at end of file