Compare commits

...

893 Commits

Author SHA1 Message Date
Joshua M. Boniface
1bf3a26a61 Bump version for 10.3.3 2019-05-17 23:12:21 -04:00
Joshua M. Boniface
c5760b3a40 Merge pull request #1380 from bugfixin/dlna-photo-thumb-fix
Improve Photo rendering in DLNA
2019-05-17 22:55:43 -04:00
Joshua M. Boniface
4de8bf3295 Merge pull request #1338 from cvium/fix_extras
Enforce a specific folder structure for Extras to avoid misidentification
2019-05-17 09:00:22 -04:00
bugfixin
87c8f19f19 Move DLNA thumbnail element to after larger image elements 2019-05-16 18:00:38 +00:00
Claus Vium
0ef52c739e Review changes
Untested
2019-05-16 07:27:38 +02:00
Joshua M. Boniface
0a9a6b949c Merge pull request #1372 from DrPandemic/fix-pin
Fix broken pin in 10.3.z
2019-05-14 21:54:28 -04:00
DrPandemic
c22068d6b1 Fix pin bug introduced in 10.3.z.
The issue is that the new easyPassword format prepends the hash
function. This PR extract the hash from "$SHA1$_hash_".
2019-05-11 19:53:34 -04:00
Joshua M. Boniface
bbc1a86b57 Merge pull request #1306 from oddstr13/pr-sudoless-build-1
Move artifact chown inside docker to avoid sudo
2019-05-10 09:25:41 -04:00
Bond-009
cd83d80f2b Merge pull request #1294 from DrPandemic/fix-download-non-ascii
Fix non-ascii filename downloads
2019-05-09 17:30:19 +02:00
Jean-Samuel Aubry-Guzzi
12721eb7dd Fix non-ascii filename downloads
Follow https://tools.ietf.org/html/rfc5987#section-3.2.2 to encode
non-ascii filenames in HTTP Content-Disposition header.
2019-05-07 19:43:04 -04:00
Claus Vium
b8a09339cd Enforce extras folder structure according to Emby's wiki 2019-05-02 08:14:00 +02:00
Odd Stråbø
3634d367c1 Move artifact chown inside docker to avoid sudo 2019-05-01 20:32:15 +02:00
Claus Vium
c1daea0ec7 Change owner and parent id of extras to the main media item 2019-05-01 07:47:22 +02:00
Joshua Boniface
e8196fed7c Bump version for 10.3.2 2019-04-30 20:18:54 -04:00
Joshua M. Boniface
477702fbb9 Merge pull request #1324 from joshuaboniface/arm64
Add arm64 packaging for Debuntu
2019-04-30 20:07:41 -04:00
Joshua M. Boniface
2216a271bb Merge pull request #1335 from Bond-009/ffmpeglimit
Limit amount of ffmpeg processes extracting images at once
2019-04-30 20:06:24 -04:00
Bond-009
91cd7d2f6b Limit amount of ffmpeg processes extracting images at once 2019-04-30 23:35:39 +02:00
Anthony Lavado
4e681d25d9 Merge pull request #1334 from Bond-009/musicbrainzfix
Iterate over IEnumerable before disposing
2019-04-30 16:56:54 -04:00
Bond-009
06cc2891de Merge pull request #1310 from bugfixin/progressivestreamingservice-unreachable
Remove unreachable code from BaseProgressiveStreamingService
2019-04-30 22:20:54 +02:00
Bond-009
682432f55a Iterate over IEnumerable before disposing 2019-04-30 22:18:40 +02:00
Anthony Lavado
7c4cb5ec58 Merge pull request #1333 from bugfixin/easypinfix
Fix incorrect hasPassword flag when easy pin set
2019-04-30 15:36:25 -04:00
bugfixin
1df73fdeba Fix incorrect hasPassword flag when easy pin set 2019-04-30 19:16:53 +00:00
Bond-009
21ba8a0593 Merge pull request #1332 from cvium/fix_tvdb_ep_provider
Make the TvdbEpisodeProvider class Public
2019-04-30 20:59:18 +02:00
Claus Vium
08ed52eb72 Make the TvdbEpisodeProvider class Public 2019-04-30 20:08:59 +02:00
Anthony Lavado
99700e1b95 Merge pull request #1327 from joshuaboniface/disco
Support libssl1.1 for Ubuntu Disco
2019-04-30 02:38:21 -04:00
Joshua M. Boniface
4e0be95368 Merge pull request #1305 from bugfixin/passwordless-form-encoded
Fix passwordless authentication with non-json content-types
2019-04-29 23:07:04 -04:00
Joshua Boniface
c8a59c8343 Support libssl1.1 for Ubuntu Disco 2019-04-29 23:03:57 -04:00
Joshua Boniface
2b2a2ed708 Add arm64 packaging for Debuntu 2019-04-29 00:56:17 -04:00
bugfixin
a827a2fbcc Remove unreachable code and const trySupportSeek within BaseProgressiveStreamingService 2019-04-25 19:14:33 +00:00
Anthony Lavado
f97f6b8061 Merge pull request #1296 from Bond-009/fix1234
Fix #1234
2019-04-25 01:37:02 -04:00
bugfixin
844ea9d77e Don't coalesce empty strings to null in StringMapTypeDeserializer 2019-04-25 04:36:28 +00:00
Bond_009
71479286e9 Fix #1234 2019-04-24 19:56:57 +02:00
Claus Vium
28c2ac528d Re-add content length, semi revert of changes in #1010 (#1287)
* Re-add content length, semi revert of changes in #1010
2019-04-24 14:06:54 +02:00
Joshua Boniface
696a36b4a5 Update submodule for 10.3.1 2019-04-20 15:59:50 -04:00
Joshua Boniface
5fb4922c6f Bump version to 10.3.1 2019-04-20 14:24:40 -04:00
Joshua M. Boniface
3738f95871 Merge pull request #1258 from Bond-009/fixpluginload
Handle exception when loading unsupported assembly
2019-04-20 12:35:57 -04:00
Joshua M. Boniface
6797bdec04 Merge pull request #1264 from jellyfin/fix-empty-pw-migration
Fix comparison for empty password migration
2019-04-20 12:20:22 -04:00
Claus Vium
764c6d5461 Fix comparison for empty password migration 2019-04-20 17:50:34 +02:00
Bond-009
6973182ade Fix more possible exceptions 2019-04-20 17:47:11 +02:00
Bond-009
f62af07381 Handle exception when loading unsupported assembly
Fixes #1256
2019-04-20 17:47:11 +02:00
Joshua Boniface
46c37c0ae8 Bump version to 10.3.0 (release) 2019-04-19 14:25:29 -04:00
Joshua Boniface
4ad71766fc Merge branch 'translations' into release-10.3.z 2019-04-19 14:19:22 -04:00
Weblate
9d60cc8c66 Rename Chinese (Traditional) file 2019-04-19 13:59:04 -04:00
Libor Filípek
4a6243096a Translated using Weblate (Czech)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/cs/
2019-04-19 13:38:32 -04:00
Heldenkrieger01
10cbdc8e8e Translated using Weblate (Swiss German)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/gsw/
2019-04-19 12:09:39 -04:00
SaddFox
4886fc467c Translated using Weblate (Slovenian)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/sl/
2019-04-19 12:09:38 -04:00
WWWesten
8e2827cc39 Translated using Weblate (Kazakh)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/kk/
2019-04-19 12:09:37 -04:00
Βασίλης Μουρατίδης
395d2e4917 Translated using Weblate (Greek)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/el/
2019-04-19 12:09:37 -04:00
Dan Johansen
d31f5229da Translated using Weblate (Danish)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/da/
2019-04-19 12:09:37 -04:00
Libor Filípek
d6622818dc Translated using Weblate (Czech)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/cs/
2019-04-19 12:09:37 -04:00
tinganhsu
ba684d6d3a Translated using Weblate (Chinese (Traditional))
Currently translated at 96.8% (91 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hant/
2019-04-19 12:09:36 -04:00
tinganhsu
90c04a4640 Added translation using Weblate (Chinese (Traditional)) 2019-04-19 00:32:52 -04:00
Joshua M. Boniface
06a1e1f166 Merge pull request #1244 from joshuaboniface/hotfix-authapi
Hotfix authapi
2019-04-18 17:58:54 -04:00
Joshua Boniface
31ad366aa9 Implemented suggested conditional 2019-04-18 10:24:08 -04:00
Joshua Boniface
10f33b0273 Update conditional to be correct 2019-04-18 09:31:30 -04:00
Joshua Boniface
eaa1ac8013 Apparently strings can't be !'d 2019-04-17 22:49:17 -04:00
Joshua Boniface
ca3bb308b3 Add the proper Class too 2019-04-17 22:46:26 -04:00
Joshua Boniface
e790f024c2 Return MethodNotAllowedException if Pw is not set
Don't accept pre-hashed (not-plaintext) passwords as the auth
provider no longer supports this due to sha1+salting the passwords
in the database.
2019-04-17 22:33:00 -04:00
Joshua Boniface
250e0c75df Add MethodNotAllowedException with code 405 2019-04-17 22:31:06 -04:00
Joshua M. Boniface
cde7375049 Merge pull request #1242 from Bond-009/metadata
Fix metadata path save
2019-04-17 09:26:04 -04:00
Bond_009
c7fedfbca3 Fix metadata path save 2019-04-17 15:09:31 +02:00
Bond-009
f520831025 Merge pull request #1239 from anthonylavado/fix-ident
Clean up UDP responders, and move ProductName to Public endpoint
2019-04-16 11:56:38 +02:00
Anthony Lavado
2f0719a883 Move the definition of ProductName to the correct class
Missed moving this from one class to the other.
2019-04-16 01:38:00 -04:00
Anthony Lavado
34ab99caf1 Move the ProductName to the public endpoint
Moves the ProductName field over from the private system/info point to
the public one, for easier identification
2019-04-16 01:16:02 -04:00
Anthony Lavado
b2f94c0e40 Remove the old message responders
Leaves only an answer to "Who is Jellyfin", removing older ones for
EmbyServer and MediaBrowser_v2.
2019-04-15 00:21:14 -04:00
Joshua Boniface
65bff1181a Bump version to 10.3.0-rc2 and update submodule 2019-04-10 00:51:21 -04:00
Joshua Boniface
efb14f0b58 Bump dockerfile web versions too 2019-04-10 00:49:33 -04:00
Joshua M. Boniface
75a4f04cce Merge pull request #1209 from joshuaboniface/hotfix-authprovider-create
Override username with AuthenticationProvider
2019-04-10 00:18:08 -04:00
Joshua M. Boniface
007fe34363 Merge pull request #1221 from LogicalPhallacy/ffmpegdetection
Make Jellyfin search its base dir for ffmpeg
2019-04-09 23:57:20 -04:00
Phallacy
a7e31ef31f applied changes to just also search jellyfin base dir 2019-04-09 00:27:41 -07:00
Joshua M. Boniface
eae0c28e6d Merge pull request #1178 from jellyfin/LogicalPhallacy-patch-1
Updates windows installer default lib location
2019-04-08 18:44:43 -04:00
Joshua M. Boniface
21950382b9 Merge pull request #1188 from joshuaboniface/hotfix-pluginload
Fix problems with plugin installation
2019-04-08 11:24:53 -04:00
Joshua Boniface
1af9c047fb Override username with AuthenticationProvider
Pass back the Username directive returned by an AuthenticationProvider
to the calling code, so we may override the user-provided Username
value if the authentication provider passes this back. Useful for
instance in an LDAP scenario where what the user types may not
necessarily be the "username" that is mapped in the system, e.g.
the user providing 'mail' while 'uid' is the "username" value.
Could also then be extensible to other authentication providers
as well, should they wish to do a similar thing.
2019-04-07 19:51:45 -04:00
Joshua M. Boniface
2d19bfa7fb Merge pull request #1199 from jftuga/use_tls12_for_nssm
Use TLS 1.2 to download NSSM
2019-04-07 02:48:59 -04:00
John Taylor
f5f7de64de Use TLS 1.2 to download NSSM 2019-04-06 13:40:19 -04:00
Joshua Boniface
754e76a61b Add TODO to remove string target 2019-04-04 02:34:23 -04:00
Joshua Boniface
09505e0988 Apply review feedback
Remove a few superfluous/testing log statements, and print the
deletion debug messages when it occurs rather than earlier. Use
a nicer name for the isDirectory variable.
2019-04-04 01:54:31 -04:00
Anthony Lavado
67e206fa0f Merge pull request #1195 from nvllsvm/optimize
Optimize images with image_optim
2019-04-04 01:16:49 -04:00
Andrew Rabert
608fd873de Optimize images with image_optim 2019-04-03 22:58:52 -04:00
Joshua Boniface
05a4161fd3 Correct the installation and removal of plugins
Upgrading plugins was broken for various reasons. There are four
fixes and a minor one:

1. Use a directory name based only on the `Name` of the plugin, not
   the source filename, which contains the version. Avoids strange
   duplication of the plugin.
2. Use the new directory name for the deletes if it's present, so
   that installation and removal happen at that directory level
   and we don't leave empty folders laying around. Ensures we
   properly remove additional resources in plugins too, not just
   the main `.dll` file.
3. Ignore the incoming `target` when installing, and always set
   it ourself to the proper directory, which would matter when
   reinstalling.
4. Deletes an existing target directory before installing if it
   exists. Note that not calling any of the plugin removal code
   is intentional; I suspect that would delete configurations
   unexpectedly when upgrading which would be annoying. This way,
   it just replaces the files and then reloads.
5. (Minor) Added some actual debug messages around the plugin
   download section so failures can be more accurately seen.
2019-04-03 20:05:14 -04:00
Vasily
05040351dc Merge pull request #1190 from jellyfin/updates
Update Dockerfiles
2019-04-03 18:05:59 +03:00
Andrew Rabert
d75324afc9 Update Dockerfiles
* Use new dotnet image paths
* Update jellyfin-web to 10.3.0-rc1
2019-04-03 01:21:28 -04:00
Joshua Boniface
38fcd31917 Search all subdirectories for Plugins
This was added in #801 which broke the previous plugin install
behaviour. Previously plugins could be loaded from subdirectories
but this search was only for the highest level. Change it to search
all subdirectories instead to restore the previous behaviour.

Also modifies the same option from #934, though I'm not 100% sure
if this is needed here.
2019-04-02 18:29:14 -04:00
LogicalPhallacy
816d8a0216 Update install-jellyfin.ps1 2019-03-31 10:34:49 -07:00
LogicalPhallacy
e37ccd6ec0 Updates windows installer default lib location
You can use the emby import to move an existing library this way.
2019-03-31 10:32:56 -07:00
Joshua Boniface
f27477da26 Bump version to 10.3.0 and update submodule 2019-03-30 15:47:34 -04:00
Andrew Rabert
c032a015a4 Merge pull request #1172 from joshuaboniface/build-improvements
Minor improvements to release build setup
2019-03-30 15:45:11 -04:00
Anthony Lavado
11e81b035a Merge pull request #1171 from joshuaboniface/ubuntu-armhf
Add Ubuntu armhf build
2019-03-30 13:23:10 -04:00
Joshua Boniface
891a03c038 Remove superfluous variable declaration 2019-03-30 12:58:39 -04:00
Joshua Boniface
31aa6c486c Get the version string from build.yaml
For the purposes of packaging, this makes more sense, since we can
include additional appends to this version (e.g. `-rcX`) when we
can't in the SharedVersion file. The previous commit to the
bump_version script sets this as well.
2019-03-30 12:42:33 -04:00
Joshua Boniface
1d9133a5e8 Simplify bump_version and remove changelogs
Make this a lot simpler, use a reference to the release page
in the package changelogs instead of a full list.
2019-03-30 12:42:16 -04:00
Joshua Boniface
3375ca5a8c Split lists echoes into separate lines 2019-03-30 12:19:49 -04:00
Joshua Boniface
1596e93cc1 Fix up the Ubuntu repository definitions 2019-03-30 11:58:56 -04:00
Joshua Boniface
1a540f1cf7 Add Ubuntu armhf (Raspberry Pi) build
A pretty-much direct copy of the Debian armhf build infrastructure.
2019-03-30 11:50:46 -04:00
Joshua M. Boniface
05f5cd1bde Merge pull request #1170 from joshuaboniface/fix-build-typo
Correct bad quote characters
2019-03-29 19:17:32 -04:00
Joshua Boniface
f0fbd0232c Correct bad quote characters 2019-03-29 19:13:01 -04:00
Joshua M. Boniface
72dd609109 Merge pull request #1149 from LogicalPhallacy/ImprovedPasswordReset
Adds per user password reset
2019-03-29 18:26:30 -04:00
LogicalPhallacy
13e94a8b1b Remove dashes from pins 2019-03-29 12:48:07 -07:00
Vasily
d9e7883fb5 Merge pull request #1169 from joshuaboniface/ffmpeg-location
Use new libexecdir location for jellyfin-ffmpeg
2019-03-29 18:16:36 +03:00
Phallacy
2d396cb589 adds readonly to properties 2019-03-29 07:10:49 -07:00
Phallacy
b56031b9f3 fix byte string 2019-03-28 20:49:11 -07:00
Joshua M. Boniface
fd86b141e2 Merge pull request #1166 from Bond-009/#1162
Fix exception on startup
2019-03-28 22:45:34 -04:00
Joshua Boniface
427a3e9b08 Use new libexecdir location for jellyfin-ffmpeg
From commit d6bb1f3c in jellyfin-ffmpeg, which moves the installed
binaries from /usr/share to /usr/lib on the next release.
2019-03-28 18:21:25 -04:00
Bond_009
3001f21f8d Hacky fix for a hacky issue 2019-03-28 19:11:05 +01:00
Phallacy
48b50a22a4 switched to a hexa string with crypto random backing 2019-03-28 08:15:53 -07:00
Phallacy
5e8496bc59 minor fixes and usings 2019-03-27 22:46:25 -07:00
Joshua M. Boniface
2dbc1153e8 Merge pull request #934 from Bond-009/plugin
WIP - Don't require a restart for 75% of plugins
2019-03-27 21:35:09 -04:00
Bond-009
b07c146fd9 Update Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-03-27 16:17:18 -07:00
Joshua M. Boniface
cc2edc4d66 Merge pull request #1151 from Phlogi/patch-1
Use public ports and advertise DNS if available for WAN address
2019-03-27 13:54:14 -04:00
Anthony Lavado
524357bfa8 Merge pull request #1157 from Bond-009/smallfix
Simplify/remove/clean code
2019-03-27 09:53:45 -04:00
Bond-009
7343e07fe5 Fix build error 2019-03-26 19:31:06 +01:00
Phallacy
6be8624373 async improvements and post reset cleanups 2019-03-25 22:17:23 -07:00
LogicalPhallacy
740c95d557 Apply minor suggestions from code review
Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-03-25 21:40:10 -07:00
Joshua M. Boniface
31607fbb37 Merge pull request #1153 from Bond-009/dlna
Check if disposed first
2019-03-25 20:08:11 -04:00
Phlogi
122cba2aa7 Correct use of local variable wanAddress. 2019-03-25 22:26:05 +01:00
Bond-009
b44a70ff36 Simplify/remove/clean code
* Remove useless runtime check (we only support one)
* Remove unused args
* Remove a global constant

And ofc fix some warnings ;)
2019-03-25 22:25:32 +01:00
Phlogi
1b03f078b9 No need to assign empty string. 2019-03-25 21:43:50 +01:00
Phlogi
4c8f8cf64c Removed trailing spaces, renamed get wan IP function. 2019-03-25 21:34:55 +01:00
Bond-009
d623f616fa Improved dispose method 2019-03-25 17:32:27 +01:00
Bond-009
fc8de8aead Check if disposed first 2019-03-25 17:27:24 +01:00
Claus Vium
6480cfcc87 Formatting update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-25 10:19:08 +01:00
Claus Vium
e36d424b5f Formatting update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-25 10:18:47 +01:00
Claus Vium
f7e7d72688 Formatting update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-25 10:18:18 +01:00
Claus Vium
3474568ce2 Update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-25 10:18:04 +01:00
Claus Vium
89f2dfd78a Update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-25 10:17:53 +01:00
Claus Vium
2c4c56d6d6 Formatting update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-25 10:17:40 +01:00
Phlogi
087d4153ae Fix check for available WAN address. 2019-03-24 21:47:18 +01:00
Phallacy
86772bd7bd removes needless dictionary 2019-03-24 12:17:32 -07:00
Claus Vium
4e2841f0d7 Update Emby.Server.Implementations/Library/UserManager.cs
Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-03-24 11:41:03 -07:00
Phallacy
26fe4040bf fixes some usings 2019-03-24 11:40:00 -07:00
Phlogi
fb7f29de18 Format the WAN API Url correctly with https and Port. 2019-03-24 18:33:21 +01:00
Phlogi
d18252542d Also add the WAN switch to the public system info. 2019-03-24 17:11:21 +01:00
Phlogi
030fcaac15 Proper access to configuration objects 2019-03-24 17:02:03 +01:00
Phlogi
7ebb043249 Removed comment, renamed methods consistently. 2019-03-24 16:50:39 +01:00
Claus Vium
598b1c9966 Update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-24 16:47:59 +01:00
Claus Vium
cf36aaef2b Update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-24 16:47:48 +01:00
Claus Vium
f30af9cd5f Update Emby.Server.Implementations/ApplicationHost.cs
Co-Authored-By: Phlogi <Phlogi@users.noreply.github.com>
2019-03-24 16:47:42 +01:00
Bond-009
5024c52c60 Merge pull request #1140 from oddstr13/pr-doxygen-1
Add Doxygen config
2019-03-24 13:26:56 +01:00
Bond-009
e971b62dab Merge pull request #1137 from thornbill/fix-expires-header
Fix default value for Expires header
2019-03-24 13:25:41 +01:00
Phlogi
4ffec8ad26 Fix build, missing changes. 2019-03-24 12:19:10 +01:00
Phlogi
69cc5814d8 Change WAN IP behaviour: Use ServerConfiguration.WanDdns if set in configuration. 2019-03-24 12:11:46 +01:00
Phlogi
414a318a0d WAN Address should use public ports instead of local ports.
https://github.com/jellyfin/jellyfin/issues/601#issuecomment-475941080
2019-03-24 11:59:40 +01:00
Phallacy
758e35baba greaterthen/lessthen reversal fix 2019-03-24 00:30:16 -07:00
Phallacy
09921a00aa made password resets an interface and per user 2019-03-22 00:01:23 -07:00
Odd Stråbø
16a3bb2df4 Implemented some requested changes to the Doxyfile 2019-03-21 18:21:07 +01:00
Odd Stråbø
2c684c0231 Customize Doxygen config. 2019-03-21 13:42:29 +01:00
Odd Stråbø
949a1cce21 Generate doxygen template config doxygen -g 2019-03-21 13:16:33 +01:00
Vasily
0e787f4e9f Merge pull request #1139 from Liggy/debian-init
Update init scripts for compatibility with Devuan
2019-03-20 23:27:24 +03:00
Torsten
bd31091648 Update init scripts for compatibility with Devuan
Include start, stop, restart and status option for /etc/init.d/jellyfin
Use start-stop-daemon to make the script refer to systemctl mechanism
on systems that have systemd installed
2019-03-20 20:16:24 +01:00
Bill Thornton
4cd8903abc Fix default value for Expires header 2019-03-19 23:13:02 -04:00
Joshua M. Boniface
7b01de8db1 Merge pull request #1136 from jellyfin/add-access-to-template
Require access type to be included in bug report
2019-03-19 10:52:49 -04:00
Vasily
f73d8a44df Improve the wording per @joshuaboniface suggestion 2019-03-19 17:37:56 +03:00
Vasily
752d65d020 Require access type to be included in bug report
Inspired by https://github.com/jellyfin/jellyfin/issues/1085#issuecomment-473833591

It seems that the issue with "setup wizard" described there is only prominent when reverse-proxied, not when accessed directly. So this type of information should be gathered in the bug report as well.
2019-03-19 17:13:27 +03:00
LogicalPhallacy
c2667f99f4 Merge pull request #4 from jellyfin/master
updating local master
2019-03-18 22:58:37 -07:00
Joshua M. Boniface
c7e7aa0a61 Merge pull request #1117 from Bond-009/ffmpeg
Check before flushing ffmpeg log
2019-03-18 23:59:12 -04:00
Joshua M. Boniface
fc79659549 Merge pull request #1127 from LogicalPhallacy/lockoutfix
Add configurable user lockout
2019-03-18 21:13:51 -04:00
Vasily
e81a6adb95 Merge pull request #1090 from redSpoutnik/subtitle-display-title
Set DisplayTitle for subtitles
2019-03-17 09:36:35 +03:00
Phallacy
80aedcd7e2 really fixed line endings 2019-03-16 21:36:45 -07:00
Phallacy
fc28c9237c fixed line endings 2019-03-16 21:34:26 -07:00
Phallacy
b04200ca68 adding regex fix 2019-03-16 21:21:14 -07:00
Joshua M. Boniface
67fbbcfd12 Merge pull request #1121 from LogicalPhallacy/master
Update username regex to string literal with escaped -
2019-03-17 00:12:15 -04:00
Joshua M. Boniface
e3dbed1c1a Update Emby.Server.Implementations/Library/UserManager.cs
Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-03-16 10:16:23 -07:00
redSpoutnik
480a6607e2 Merge branch 'master' into subtitle-display-title 2019-03-16 17:54:57 +01:00
redSpoutnik
4a30fee40d Remove some dead code 2019-03-16 17:28:45 +01:00
Phallacy
7f0fa74467 updated regex to string literal with escaped - 2019-03-16 00:38:31 -07:00
Vasily
3d1d27230d Merge pull request #1120 from LogicalPhallacy/master
quick fix for auth bug
2019-03-16 10:32:51 +03:00
LogicalPhallacy
9df1506794 Merge pull request #2 from LogicalPhallacy/master
update lockoutfix to latest for testing
2019-03-16 00:26:12 -07:00
LogicalPhallacy
2d0844b5db Merge pull request #1 from jellyfin/master
merging myself to latest
2019-03-16 00:25:16 -07:00
Phallacy
1ee016c997 configurable user lockout 2019-03-16 00:18:52 -07:00
Phallacy
221389089c quick fix for auth bug 2019-03-15 21:25:19 -07:00
Joshua M. Boniface
59031ee3b8 Merge pull request #1119 from ploughpuff/503retry
MusicBrainz 503 Retry Strategy
2019-03-15 16:47:03 -04:00
PloughPuff
d2e408539e MusicBrainz 503 Retry Strategy
Upon receiving back a 503 Service Unavailable from MusicBrainz (indicating throttling), retry the same request a number of times before giving up.
2019-03-15 19:33:26 +00:00
Bond_009
a8140cc74b Merge branch 'master' of github.com:jellyfin/jellyfin into ffmpeg 2019-03-15 18:08:51 +01:00
Bond_009
d5f080fefb Check before flushing ffmpeg log
The stream could have been diposed while writing.
2019-03-15 17:58:34 +01:00
Joshua M. Boniface
35ff8ec713 Merge pull request #1116 from Bond-009/sub
Fix exception caused by #1096
2019-03-15 12:48:15 -04:00
Bond_009
764c901cd7 Fix exception caused by #1096
```cs
MediaBrowser.Common.Extensions.ResourceNotFoundException: Configuration
with key subtitles not found.
   at
   Emby.Server.Implementations.AppBase.BaseConfigurationManager.<>c__DisplayClass42_0.<GetConfiguration>b__0(String
   k) in
   /home/pi/dev/jellyfin/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs:line
   247
      at
      System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey
      key, Func`2 valueFactory)
         at
	 Emby.Server.Implementations.AppBase.BaseConfigurationManager.GetConfiguration(String
	 key) in
	 /home/pi/dev/jellyfin/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs:line
	 238
	    at
	    MediaBrowser.Providers.MediaInfo.FFProbeVideoInfo.AddExternalSubtitles(Video
	    video, List`1 currentStreams, MetadataRefreshOptions
	    options, CancellationToken cancellationToken) in
	    /home/pi/dev/jellyfin/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs:line
	    486
	       at
	       MediaBrowser.Providers.MediaInfo.FFProbeVideoInfo.Fetch(Video
	       video, CancellationToken cancellationToken, MediaInfo
	       mediaInfo, BlurayDiscInfo blurayInfo,
	       MetadataRefreshOptions options) in
	       /home/pi/dev/jellyfin/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs:line
	       204
	          at
		  MediaBrowser.Providers.MediaInfo.FFProbeVideoInfo.ProbeVideo[T](T
		  item, MetadataRefreshOptions options,
		  CancellationToken cancellationToken) in
		  /home/pi/dev/jellyfin/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs:line
		  119
		     at
		     MediaBrowser.Providers.Manager.MetadataService`2.RunCustomProvider(ICustomMetadataProvider`1
		     provider, TItemType item, String logName,
		     MetadataRefreshOptions options, RefreshResult
		     refreshResult, CancellationToken cancellationToken)
		     in
		     /home/pi/dev/jellyfin/MediaBrowser.Providers/Manager/MetadataService.cs:line
		     806

```
2019-03-15 17:34:15 +01:00
Andrew Rabert
f85d45d17f Merge pull request #1115 from SuperSandro2000/patch-2
Clean apt lists in arm Dockerfiles
2019-03-15 10:53:10 -04:00
Andrew Rabert
022bd1b8b4 Merge pull request #1114 from SuperSandro2000/patch-1
Only remove /var/lib/apt/lists/* in Dockerfile
2019-03-15 10:53:00 -04:00
Sandro Jäckel
31305af7ff Clean apt lists in arm Dockerfiles 2019-03-15 14:39:23 +01:00
Sandro Jäckel
dd929d796f Only remove /var/lib/apt/lists/* 2019-03-15 14:30:15 +01:00
Vasily
11fde02035 Merge pull request #1105 from ploughpuff/ratelimit
Only delay making MusicBrainz request if necessary
2019-03-15 16:01:55 +03:00
Joshua M. Boniface
3d85014edc Merge pull request #1110 from EraYaN/productname-and-ua
Adjusted the Product Name so the User Agent is correct/better.
2019-03-15 00:25:38 -04:00
PloughPuff
d125fbc43d Added contact email to user agent
MusicBrainz request a contact email address is supplied in comment section of user agent field.
2019-03-14 21:34:09 +00:00
redSpoutnik
427688a0a0 Change subtitles DisplayTitle behavior 2019-03-14 22:31:51 +01:00
Erwin de Haan
21cc38fcf4 Adjusted AssemblyCopyright attribute values. 2019-03-14 22:17:56 +01:00
Erwin de Haan
ee7bf86e0f Adjusted the Product Name so the User Agent is correct/better. 2019-03-14 22:11:47 +01:00
PloughPuff
f8bb7a7ff4 Increased interval to 1050ms and moved to class scope
Review comments from JustAMan.
2019-03-14 19:01:17 +00:00
PloughPuff
6d3e6d800f Only delay making request if necessary
When requesting data from MusicBrainz, only delay the request if previous request was less than rate limit ago, instead of always delaying for one second at start.
2019-03-14 19:01:17 +00:00
Vasily
208585d3f6 Merge pull request #1106 from Bond-009/warn2
More warning fixes
2019-03-14 19:54:44 +03:00
Vasily
bf00dedc7f Merge pull request #1103 from Bond-009/stream
Improvements around streams
2019-03-14 19:53:50 +03:00
Bond-009
bf43dc00bb More warning fixes 2019-03-13 22:32:52 +01:00
Bond-009
e64aaebbac Improvements around streams
* Use ArrayPool instead of allocating new buffers each time
* Remove NetworkStream copy
* Remove some dead code
2019-03-13 21:11:01 +01:00
Erwin de Haan
1d443d2ff5 Do not use the nuget packages for comparison, but the last master build (#1091)
* Do not use the nuget packages for comparison, but the last master build.
* Only allow passing builds.
2019-03-13 21:09:08 +01:00
Bond-009
6507a9b2ee Merge pull request #1104 from EraYaN/disable-abi-check-on-drone
Disable the Drone CI ABI check
2019-03-13 20:46:59 +01:00
Erwin de Haan
4cc4d57a78 Disable the Drone CI ABI check 2019-03-13 20:37:08 +01:00
Vasily
605bf0e8c3 Merge pull request #1100 from ploughpuff/rmprobeswitch
Finalise removal of --ffprobe switch
2019-03-13 01:42:07 +03:00
Vasily
89e2af6b57 Merge pull request #1096 from dkanada/opensubs
Remove open subtitles from the server
2019-03-13 01:22:55 +03:00
PloughPuff
b864e9da2a Finalise removal of --ffprobe switch
Removed --ffprobe from src files and server/docker scripts.
2019-03-12 22:09:18 +00:00
Vasily
f10382a696 Merge pull request #1098 from jellyfin/Bond-009-patch-2
Fix build by removing non existent namespace
2019-03-13 00:02:24 +03:00
Vasily
297f25cfc2 Merge pull request #1059 from Bond-009/os
Remove EnvironmentInfo
2019-03-13 00:01:00 +03:00
Bond-009
afdef163ea Fix build by removing non existent namespace
Looks like a wrong auto merge. (We really should fix CI)
2019-03-12 20:49:29 +01:00
Joshua M. Boniface
6751560228 Merge pull request #1092 from joshuaboniface/configurable-webdir
Add configurable webdir option
2019-03-12 12:51:11 -04:00
Joshua M. Boniface
2012eb5e11 Merge pull request #785 from Bond-009/xml
Remove useless abstraction around XmlReaderSettings
2019-03-12 11:49:39 -04:00
Bond-009
58068e249a Merge pull request #1094 from cvium/imageprocessor_exception
Skip processing of images that don't exist
2019-03-12 16:40:20 +01:00
Bond-009
3ddbda9aca Merge branch 'master' into xml 2019-03-12 16:37:18 +01:00
Vasily
1fef8bf266 Merge pull request #1060 from Bond-009/assinfo
Remove redundant class AssemblyInfo
2019-03-12 16:34:21 +03:00
Joshua Boniface
3c4043199a Implement review feedback 2019-03-12 09:18:45 -04:00
Vasily
0220309ea7 Merge pull request #1095 from Bond-009/fix1077
Add AppConfig to the DI service collection
2019-03-12 12:56:39 +03:00
Vasily
497b4f834f Merge pull request #1021 from Bond-009/failonwarn
Fail on warnings for Jellyfin.Server
2019-03-12 11:31:22 +03:00
dkanada
715ddbb3b0 remove open subtitles from the server 2019-03-11 18:10:31 -07:00
Bond-009
0ff038f0a2 Fix nullref 2019-03-11 23:13:01 +01:00
Claus Vium
7322485a6d Skip processing of images that don't exist 2019-03-11 20:44:12 +01:00
Vasily
f77af5f6e4 Merge pull request #1093 from joshuaboniface/saner-paths
Use better path configuration for packages
2019-03-11 15:32:36 +03:00
Vasily
2324c408ba Merge pull request #1089 from jellyfin/translations
Update translations
2019-03-11 15:30:50 +03:00
Joshua Boniface
037cf9e1ee Move CreateDirectory for dataDir to try block 2019-03-10 18:30:10 -04:00
Joshua Boniface
5268553e7f Have datadir envvar match the others 2019-03-10 18:24:11 -04:00
Joshua Boniface
5f7524aca2 Remove unneccessary string 2019-03-10 17:21:10 -04:00
Joshua Boniface
86f5221f96 Use environment variables instead of opts for RPM 2019-03-10 17:11:16 -04:00
Joshua Boniface
ecf85a73ec Use environment variables instead of opts for Deb 2019-03-10 17:09:51 -04:00
Joshua Boniface
132ce3ece1 Add further resources to complete WebPath 2019-03-10 17:04:18 -04:00
Joshua Boniface
25deca9579 Make use of WebPath 2019-03-10 16:20:46 -04:00
Joshua Boniface
93d15cd969 Add configuration flag for Web directory 2019-03-10 16:17:48 -04:00
Anthony Lavado
4b91c9bf66 Merge pull request #1075 from dkanada/thumbnail
Remove mirror images from library thumbnail
2019-03-10 10:52:50 -04:00
WWWesten
16adaa64c9 Translated using Weblate (Kazakh)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/kk/
2019-03-10 03:06:01 -04:00
Matsuri
93fe7957fb Translated using Weblate (Chinese (Simplified))
Currently translated at 97.8% (92 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hans/
2019-03-10 03:06:00 -04:00
Joshua M. Boniface
fb96763f65 Merge pull request #1077 from Bond-009/musicbrainz
Make MusicBrainz base url configurable
2019-03-09 23:19:32 -05:00
Anthony Lavado
63342f89d4 Merge pull request #1081 from cvium/certificate_not_null
Disable HTTPS in Kestrel if Certificate is null
2019-03-09 02:11:02 -05:00
dkanada
47095e6cf8 move a variable out of for loop 2019-03-09 11:17:02 +09:00
Claus Vium
f2062ba19b Disable HTTPS in Kestrel if Certificate is null 2019-03-08 22:25:45 +01:00
Bond-009
58061a7295 Make MusicBrainz base url configurable 2019-03-08 17:15:52 +01:00
Anthony Lavado
c6c398179a Merge pull request #1072 from anthonylavado/remove-header
Remove New File Header
2019-03-08 10:23:13 -05:00
dkanada
e498e47109 remove mirror images from library thumbnail 2019-03-08 18:39:41 +09:00
Anthony Lavado
40089e2fd9 Merge pull request #1071 from jellyfin/Bond-009-patch-1
Fix error from #1069
2019-03-08 02:36:54 -05:00
Anthony Lavado
045a0419f6 remove new file header text, and remove it from solution
This removes the new file header text file from the repository, and also removes the include that was in the project solution.
2019-03-08 02:33:08 -05:00
Bond-009
80fb3dc2cb Fix error 2019-03-08 06:36:00 +01:00
Vasily
fcee64df09 Merge pull request #1069 from Bond-009/fix
Quick nullref fix
2019-03-08 00:58:52 +03:00
Bond-009
757e0194b9 Merge pull request #1067 from cvium/add_urlprefixes
Add urlprefixes during init
2019-03-07 22:54:02 +01:00
Bond-009
4625592a83 Quick nullref fix 2019-03-07 22:52:41 +01:00
Claus Vium
e3b844b5aa Add urlprefixes during init 2019-03-07 22:49:41 +01:00
Bond-009
decaffed86 Remove EnvironmentInfo
This moved the last bit of usefulness of EnvironmentInfo into a static
class.
2019-03-07 22:41:41 +01:00
Bond-009
669c48cc8b Merge pull request #1065 from cvium/closed_response
Don't set status code if response is closed
2019-03-07 22:32:01 +01:00
Vasily
d1fe24ac92 Merge pull request #1064 from Bond-009/fix2
Remove file added in #996
2019-03-08 00:29:33 +03:00
Claus Vium
3fa43a1e08 Don't set status code if response is closed 2019-03-07 22:26:23 +01:00
Vasily
028a98d2c1 Merge pull request #1058 from Bond-009/clean
Cleanup/simplification
2019-03-08 00:23:00 +03:00
Vasily
0f70a81db3 Merge pull request #1063 from EraYaN/azure-pipelines-upstream-change-fix
Update to renamed DownloadGitHubRelease task (Microsoft/azure-pipelines-tasks#9481)
2019-03-08 00:21:32 +03:00
Bond-009
d014a1dc1d Remove file added in #996 2019-03-07 22:16:27 +01:00
Vasily
e04a152ed0 Merge pull request #996 from Bond-009/libscan
Reduce the amount of exceptions thrown
2019-03-08 00:11:53 +03:00
Erwin de Haan
8a680ae324 Update to renamed DownloadGitHubRelease task (Microsoft/azure-pipelines-tasks#9481) 2019-03-07 22:00:28 +01:00
Vasily
75996476a7 Merge pull request #1061 from Bond-009/dead
Remove dead code
2019-03-07 23:57:51 +03:00
Bond-009
620d7b560d Fail on warnings for Jellyfin.Server 2019-03-07 21:52:16 +01:00
Bond-009
ab9859ecef Address comment 2019-03-07 21:42:56 +01:00
Bond_009
37ea50a572 Reduce the amount of exceptions thrown 2019-03-07 21:42:56 +01:00
Joshua M. Boniface
5cb3f04389 Merge pull request #1062 from Bond-009/warnfix
Fix the 2 new warnings
2019-03-07 15:34:51 -05:00
Bond-009
cedf50eeec Fix the 2 new warnings 2019-03-07 21:29:17 +01:00
Bond-009
c5fce647de Cleanup/simplification
* Removed useless copies/allocations
* Reduced unneeded complexity
2019-03-07 21:13:13 +01:00
Bond-009
10a0d6bdba Merge pull request #1010 from cvium/kestrel_poc
Remove System.Net and port to Kestrel
2019-03-07 21:08:57 +01:00
Claus Vium
0abe57e930 Merge remote-tracking branch 'remotes/upstream/master' into kestrel_poc 2019-03-07 20:16:51 +01:00
Bond-009
65c0b486aa Remove dead code
What it says on the tin
2019-03-07 19:27:43 +01:00
Bond-009
ae0ecc1b10 Merge pull request #870 from LogicalPhallacy/betterauth
Better default authentication
2019-03-07 19:11:36 +01:00
Claus Vium
dfff68b2f4 Make SkipLogExtensions static 2019-03-07 19:05:53 +01:00
Bond-009
e4c5d51860 Update MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
Co-Authored-By: cvium <cvium@users.noreply.github.com>
2019-03-07 19:04:50 +01:00
Claus Vium
8c609bc9ce Reduce aspnet imports 2019-03-07 19:04:09 +01:00
Bond-009
f486f5966f Update Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-03-07 09:56:03 -08:00
Bond-009
e91dd14b31 Remove redundent class AssemblyInfo 2019-03-07 18:10:55 +01:00
Joshua M. Boniface
8a53b60912 Merge pull request #947 from EraYaN/azure-pipelines
Add Azure Pipelines YAML
2019-03-07 09:57:14 -05:00
Vasily
a4b52b7264 Merge pull request #844 from ploughpuff/ffmpeg
Reworked FFmpeg path discovery and always display to user
2019-03-07 17:23:06 +03:00
Vasily
5ae0ef0527 Merge pull request #1028 from Bond-009/ratings
Simplify rating loading
2019-03-07 17:22:26 +03:00
Phallacy
dfb1d704ed made hashset static and readonly 2019-03-07 03:32:05 -08:00
Bond_009
ffd6dac03a Remove useless comments 2019-03-07 12:24:44 +01:00
Phallacy
8f4895e8a5 more fixes for perf and style 2019-03-07 03:11:41 -08:00
Bond_009
a9302b8b53 Remove useless abstraction around XmlReaderSettings
This removes the amount of stuff that needs to be passed around
Also removes some unneeded `ManagedFileSystem` usage
2019-03-07 12:04:14 +01:00
Bond-009
c31b0b311b Apply suggestions from code review
more minor fixes before I do larger fixes

Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-03-07 02:41:44 -08:00
Claus Vium
bba049c987 Make FileSystem readonly 2019-03-06 19:29:25 +01:00
Claus Vium
21c2acc520 Remove public Host property 2019-03-06 19:27:05 +01:00
Claus Vium
394d23a73a Review comments 2019-03-06 19:14:03 +01:00
Joshua M. Boniface
276428878e Merge pull request #1051 from joshuaboniface/build-improvements
Build improvements for wrapping infrastructure
2019-03-06 13:12:51 -05:00
Bond-009
04db0369d4 Update LocalizationManager.cs 2019-03-06 17:31:52 +01:00
Joshua Boniface
4ef7eda593 Copy install script from new location 2019-03-06 09:22:38 -05:00
Vasily
2242c8d793 Merge pull request #915 from cvium/remove_encryptionmanager
Remove IEncryptionManager
2019-03-06 15:56:15 +03:00
Phallacy
bef665be36 Minor fixes to address style issues 2019-03-05 23:45:05 -08:00
Joshua Boniface
bf9f342c13 Add build.yaml for parent build infrastructure 2019-03-05 23:53:07 -05:00
Joshua Boniface
a994edda04 Allow complete ignoring of submodule
Used by the parent build infrastructure
2019-03-05 23:52:58 -05:00
Joshua Boniface
9f6bca3658 Put output into bin instead of jellyfin-build 2019-03-05 23:22:07 -05:00
PloughPuff
2617a49b78 Renamed Init() to SetFFmpegPath() 2019-03-05 21:29:15 +00:00
PloughPuff
656bffbbb2 Remove --ffprobe logic 2019-03-05 21:29:15 +00:00
PloughPuff
8104e739d5 Address review comments from Bond 2019-03-05 21:29:15 +00:00
PloughPuff
632968dc81 Added self to contributors 2019-03-05 21:29:15 +00:00
PloughPuff
ed69e690b8 Review comments
Address review comments from JustAMan, Bond-009 and cvium.
2019-03-05 21:29:15 +00:00
PloughPuff
20775116f7 Reworked FFmpeg path discovery and always display to user
1) Reworked FFmpeg and FFprobe path discovery (CLI switch, Custom xml, system $PATH, UI update trigger).  Removed FFMpeg folder from Emby.Server.Implementations.  All path discovery now in MediaEncoder.

2) Always display FFmpeg path to user in Transcode page.

3) Allow user to remove a Custome FFmpeg path and return to using system $PATH (or --ffmpeg if available).

4) Remove unused code associated with 'prebuilt' FFmpeg.

5) Much improved logging during path discovery.
2019-03-05 21:24:54 +00:00
Claus Vium
446f9bf81f Remove more Content-Length references 2019-03-05 20:48:04 +01:00
Claus Vium
913e80fd55 Add ProcessWebSocketRequest to IHttpListener 2019-03-05 20:35:07 +01:00
Claus Vium
9a4a01fb0e Fix DI in FileWriter.TransmitFile 2019-03-05 19:32:22 +01:00
Claus Vium
df92df7bd6 Remove BOM 2019-03-05 19:22:41 +01:00
Claus Vium
78742b8e4c Switch to HeaderNames instead of hardcoded strings (and other header related fixes) 2019-03-05 19:20:28 +01:00
Erwin de Haan
942c400c19 Update README with Azure Pipelines status badge 2019-03-05 17:12:56 +01:00
Joshua M. Boniface
5587dd8bfb Merge pull request #900 from ploughpuff/validator
Implement proper FFmpeg version checking
2019-03-05 11:07:49 -05:00
Bond-009
8d1fc3f984 Merge pull request #1043 from thornbill/update-colors
Update image overlays to use Jellyfin blue
2019-03-05 12:06:48 +01:00
Claus Vium
318e0d4a24 Add GetValueOrDefault dictionary extension 2019-03-05 10:27:25 +01:00
Claus Vium
bc00617df7 Remove unused Brotli compressor 2019-03-05 10:26:43 +01:00
Phallacy
2c26517172 minor style fixes 2019-03-04 23:58:25 -08:00
Claus Vium
51648a2a21 Remove unused _listener 2019-03-05 08:05:42 +01:00
Claus Vium
12df381495 Grab content root from config and fix kestrel port bindings 2019-03-05 07:55:29 +01:00
Claus Vium
17ca23d73b Don't dispose the connection 2019-03-05 07:41:41 +01:00
Bill Thornton
41df94115f Update image overlays to use Jellyfin blue 2019-03-04 22:36:23 -05:00
Claus Vium
0250204f14 Expand todo 2019-03-04 22:26:57 +01:00
Bond-009
0419deeec4 Update LocalizationManager.cs 2019-03-04 20:18:35 +01:00
Claus Vium
9020f68ce1 Use QueryHelpers.AddQueryString 2019-03-04 20:08:54 +01:00
Claus Vium
557c4d065d Review comments 2019-03-04 19:55:59 +01:00
Claus Vium
6cc1bd544a Fix a logging statement 2019-03-04 19:31:26 +01:00
Joshua M. Boniface
aba22b92bc Merge pull request #735 from Bond-009/loop
Readability changes
2019-03-04 00:27:48 -05:00
Claus Vium
040871459b Remove some unused references 2019-03-03 14:35:54 +01:00
Claus Vium
6263b73d9c Await host startup 2019-03-03 14:30:41 +01:00
Claus Vium
1cc433eabc Start the webhost before RunStartupTasks and fix ContentEncoding 2019-03-03 13:54:14 +01:00
Daniel Widrick
5982cdad90 Implement SxxExx EpisodeNum Processing (#1009)
**Changes**
Implement and use SxxExx Episode numbering system from guide data if available.

**Issues**
Fixes #1008
2019-03-03 12:46:03 +01:00
Claus Vium
d450169964 Use EnableHttps instead of CertificateInfo 2019-03-03 08:46:17 +01:00
Claus Vium
e823c11b46 Add certificate to https and minor cleanup 2019-03-03 08:29:23 +01:00
Bond-009
c328417d29 Merge pull request #1030 from jellyfin/release-10.2.z
Backmerge for 10.2.2
2019-03-02 18:12:24 +01:00
Bond-009
c4192f9f8b Merge pull request #1032 from Lynxy/master
Correct the list of series types
2019-03-02 18:11:53 +01:00
Lynxy
5368112d90 Correct the list of series types 2019-03-01 22:28:25 -05:00
Bond-009
ed07ed44ae Simplify rating loading 2019-03-01 19:30:48 +01:00
Bond-009
9993dafe54 Don't mix LINQ and roreach loops for readability 2019-03-01 17:12:22 +01:00
Claus Vium
6bdb5debd2 Add some websocket manager boilerplate 2019-03-01 14:08:51 +01:00
Andrew Rabert
65403747df Merge pull request #1025 from jellyfin/justadep
Treat jellyfin-web as just another dependency for Docker builds
2019-03-01 07:52:29 -05:00
Bond-009
594b271383 Merge pull request #1024 from jellyfin/release-10.2.z
Backmerge for 10.2.2
2019-03-01 07:49:07 +01:00
Andrew Rabert
27f9981142 Treat jellyfin-web as just another dependency for Docker builds 2019-03-01 00:17:46 -05:00
Deniz
3d3d879b99 Translated using Weblate (Turkish)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/tr/
2019-02-28 23:13:39 -05:00
ElFantasma
53ed6e5e6e Translated using Weblate (Spanish (Argentina))
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_AR/
2019-02-28 23:13:38 -05:00
SaddFox
d0e4e0f600 Translated using Weblate (Slovenian)
Currently translated at 87.2% (82 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/sl/
2019-02-28 23:13:36 -05:00
v1tin
311caf3fc3 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pt_BR/
2019-02-28 23:13:35 -05:00
EffeF
7c13021def Translated using Weblate (Italian)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/it/
2019-02-28 23:13:35 -05:00
TheBird956
c8788d83fb Translated using Weblate (French (Canada))
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/fr_CA/
2019-02-28 23:13:35 -05:00
TheBird956
331260cf80 Translated using Weblate (French)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/fr/
2019-02-28 23:13:34 -05:00
Joshua Boniface
58e5931a32 Bump version to 10.2.2 2019-02-28 22:03:08 -05:00
Bond-009
02041fa6f4 Merge pull request #1020 from Lynxy/master
Do not allow new users to delete content by default
2019-02-28 21:17:11 +01:00
Anthony Lavado
fcd299965d Merge pull request #992 from joshuaboniface/armhf-debian
Add Debian armhf (Rasberry Pi) build plus crossbuild
2019-02-28 12:55:59 -05:00
Vasily
79d5a53aea Merge pull request #1018 from fasheng/fix-dlna-rmvb
Fix rmvb video can not play under DLNA
2019-02-28 19:41:53 +03:00
Vasily
f1086a72bf Improve logic when determining return value
Co-Authored-By: ploughpuff <33969763+ploughpuff@users.noreply.github.com>
2019-02-28 15:58:41 +00:00
Xu Fasheng
95d001a053 Update CONTRIBUTORS.md 2019-02-28 22:15:59 +08:00
Vasily
b7fd68d366 Merge pull request #1017 from nvllsvm/dockerffmpeg
Set ffmpeg+ffprobe paths in Docker container
2019-02-28 16:43:35 +03:00
The Lynxy
c84729a4f4 Do not allow new users to delete content by default 2019-02-28 07:50:32 -05:00
Xu Fasheng
4951ec9814 Fix rmvb video can not play under DLNA
Or will report "Could not find handler for /videos/xxx/stream.rm" error
in server side.

Test OK with Kodi and gupnp-tools.
2019-02-28 18:00:25 +08:00
Phallacy
edba82db37 fixed logic flip in auth empty check and fixed crypto algo choice 2019-02-27 23:05:12 -08:00
Andrew Rabert
1d1e6dede9 Set ffmpeg+ffprobe paths in Docker container
Will always ensure containers use correct path.

Yes - the arm images have a different path than the amd64 one. This is
caused by the amd64 image using ffmpeg from jellyfin/ffmpeg while the
others use ffmpeg from their distro's repos.
2019-02-27 21:04:37 -05:00
Andrew Rabert
f384822aa5 Merge pull request #991 from joshuaboniface/ffmpeg-compat
Fix the ffmpeg compatibility
2019-02-27 20:45:43 -05:00
Claus Vium
1ac282b12e Call SharpWebSocket's Closed event handler before disposing 2019-02-27 23:39:20 +01:00
Claus Vium
588a13377c Remove a file that shouldn't have been added 2019-02-27 23:24:43 +01:00
Claus Vium
fb1de5a921 Remove more cruft and add the beginnings of a socket middleware 2019-02-27 23:22:55 +01:00
Claus Vium
71ed840944 Simplify websocket listeners 2019-02-27 22:09:22 +01:00
Claus Vium
dab8e15052 Check websocket state before closing 2019-02-27 21:48:28 +01:00
Claus Vium
e47d121985 Fix websockets 2019-02-27 21:40:47 +01:00
Claus Vium
c0b95dbc79 Fix query log for real 2019-02-27 20:11:40 +01:00
Claus Vium
647adc51c8 Fix query log 2019-02-27 19:55:25 +01:00
PloughPuff
7668ecf9c9 Use Version Class to ease comparisons 2019-02-27 18:20:48 +00:00
Vasily
3769453541 Merge pull request #978 from fasheng/fix-dlna-multiple-interfaces
Fix DLNA for multiple interfaces on linux
2019-02-27 19:23:31 +03:00
Vasily
8c2af50170 Merge pull request #1011 from Bond-009/order
Don't try to order the response the same as the request
2019-02-27 17:29:12 +03:00
Claus Vium
1e97e4d462 Remove IHttpResponse 2019-02-27 14:29:44 +01:00
Claus Vium
27e7e792b3 Replace some usage of QueryParamCollection 2019-02-27 14:23:39 +01:00
Xu Fasheng
7429c07c05 Remove redundant parenthesis 2019-02-27 20:16:54 +08:00
Claus Vium
91afaaf8fe Cleanup in QueryParamCollection 2019-02-27 12:45:06 +01:00
Claus Vium
333bd2107a Remove HttpUtility 2019-02-27 12:40:18 +01:00
Claus Vium
25d3d0b731 Remove some unused stuff 2019-02-27 08:02:32 +01:00
Claus Vium
77addb2283 Remove SocketHttpListener 2019-02-27 07:32:36 +01:00
Joshua M. Boniface
9651a78b0c Merge pull request #977 from Lynxy/genpts
Always set ffmpeg flag +genpts when video stream is being copied
2019-02-27 00:52:51 -05:00
Joshua M. Boniface
9eba31185a Merge pull request #959 from Bond-009/string
Reduce string allocations at startup
2019-02-27 00:37:31 -05:00
Joshua M. Boniface
aea7edf0fa Merge pull request #891 from Bond-009/postsan
Reduce the amount of db calls during the post scan event
2019-02-27 00:31:48 -05:00
Joshua M. Boniface
42d4834f63 Merge pull request #849 from Bond-009/span
Less string allocations
2019-02-27 00:30:31 -05:00
Joshua M. Boniface
ba78f6a0ff Merge pull request #999 from cvium/dont_write_disposed_log
Check that ffmpeg log target isn't disposed before writing to it
2019-02-27 00:27:25 -05:00
Erwin de Haan
feb5b62ad4 Enabled clean and updated the Github Connection Name 2019-02-27 00:53:16 +01:00
Erwin de Haan
5ccba7cf8a Move .azure to .ci 2019-02-27 00:20:04 +01:00
Claus Vium
848cfc32cc More cleanup 2019-02-26 22:57:59 +01:00
Claus Vium
5510e8ebee Remove unused Cookies 2019-02-26 22:53:59 +01:00
Claus Vium
9c02e99e35 Undo some of the span abuse 2019-02-26 22:40:25 +01:00
Claus Vium
148db8b81a Remove unused SharpSocket stuff 2019-02-26 22:11:21 +01:00
Claus Vium
e342b7bc71 Extend the IHttpServer interface to avoid the typecasting 2019-02-26 22:11:21 +01:00
Claus Vium
f1c93ae618 Remove SetContentLength and company 2019-02-26 22:11:21 +01:00
Claus Vium
4e229ad86b Fix PathInfo 2019-02-26 22:11:21 +01:00
Claus Vium
e88f079da6 Remove websocket options and configure kestrel listen ports 2019-02-26 22:11:21 +01:00
Claus Vium
4e8de67aca Remove SocketSharp from Jellyfin.Server and some other cleanup 2019-02-26 22:11:21 +01:00
Claus Vium
a85488cd20 Fix websockets array index out of bounds and some cleanup 2019-02-26 22:11:21 +01:00
Claus Vium
5a7cca9d1b Fix websockets and RawUrl 2019-02-26 22:11:21 +01:00
Claus Vium
d6c6f3c10c Still broken 2019-02-26 22:11:21 +01:00
Claus Vium
38f52a139e Add response compression middleware 2019-02-26 22:11:21 +01:00
Claus Vium
194da8416b Use middlewares instead of Routing 2019-02-26 22:11:21 +01:00
Claus Vium
f3e7bc0573 Replace some todos with http extensions and prepare some socket work 2019-02-26 22:11:21 +01:00
Claus Vium
c3fa299acc Remove hardcoded path and fix url bug in Windows 2019-02-26 22:11:21 +01:00
Claus Vium
852460b991 kestrel init 2019-02-26 22:11:21 +01:00
Claus Vium
33b67a357f Remove unused deps 2019-02-26 22:11:21 +01:00
Claus Vium
4db31acff9 Begin removing System.Net sources 2019-02-26 22:11:21 +01:00
Joshua M. Boniface
968e282c90 Merge pull request #1007 from Bond-009/time
Log time in a standardized way
2019-02-26 16:05:59 -05:00
Bond-009
1731bf7372 Remove ordering items 2019-02-26 20:47:23 +01:00
Bond-009
0804bed66d Log time in a standardized way 2019-02-26 19:40:23 +01:00
Bond-009
a0606b5730 Don't change submodule 2019-02-26 17:11:27 +01:00
Bond-009
9ba6227db4 Less string allocations 2019-02-26 17:11:04 +01:00
Vasily
9bab93262e Merge pull request #1003 from Bond-009/stopwatch
Use stopwatch for more accurate measurements and reduce log spam
2019-02-26 01:27:42 +03:00
Bond_009
0f9006c81f Use stopwatch for more accurate measurements and reduce log spam
DateTime.Now is suitible for small timespans
Replaced the needlessly complex and verbose logging for the httpserver
2019-02-25 18:26:17 +01:00
Vasily
b3438559cc Merge pull request #1000 from cvium/fix_object_disposed
Don't close the socket response multiple times
2019-02-25 16:52:31 +03:00
Vasily
8e5cccb22c Merge pull request #998 from cvium/enableraisingevents_default_true
Set EnableRaisingEvents to true for processes that require it
2019-02-25 16:42:27 +03:00
Vasily
500c0b9cba Merge pull request #979 from Wuerfelbecher/release-disable-debug
Build Package releases without debug turned on
2019-02-25 16:35:06 +03:00
Joshua Boniface
5054a77dcf Fix the ffmpeg compatibility
Doing this the other way was just complex. No longer try to override
the system ffmpeg, just put ours somewhere else and depend on that
package.
2019-02-25 00:41:34 -05:00
Joshua Boniface
dac2c98d8a Disable documentation and debug in build 2019-02-24 23:20:04 -05:00
Claus Vium
4df3333b71 Remove the unused status code 2019-02-24 22:31:46 +01:00
Claus Vium
5262e50fee Try another fix 2019-02-24 22:28:46 +01:00
Claus Vium
547d0ecf58 Move the check further down 2019-02-24 22:04:30 +01:00
Claus Vium
6e07eab247 Don't close the socket response multiple times 2019-02-24 21:45:03 +01:00
Claus Vium
96b3d37caf Check that ffmpeg log target isn't disposed before writing to it 2019-02-24 21:25:24 +01:00
Claus Vium
aafed63c3f Set EnableRaisingEvents to true for processes that require it 2019-02-24 16:33:05 +01:00
Claus Vium
2e9a3d45c2 Fix slow local image validation (#990)
* Check for local image directory existence to avoid tons of exceptions
2019-02-24 10:16:53 -05:00
Bond-009
e281c79d6f Merge pull request #968 from brianjmurrell/release-10.2.z-copr-autobuild
Release 10.2.z copr autobuild
2019-02-24 10:10:19 -05:00
Thomas Büttner
38ec68c488 use common.build.sh for docker image builds
Signed-off-by: Thomas Büttner <thomas@vergesslicher.tech>
2019-02-24 11:17:39 +01:00
Thomas Büttner
da61998ad6 Build releases without debug
Signed-off-by: Thomas Büttner <thomas@vergesslicher.tech>
2019-02-24 11:00:15 +01:00
Joshua M. Boniface
f28dd79fb1 Merge pull request #964 from jellyfin/fedora-runtime
Install the dotnet runtime package in Fedora build
2019-02-23 21:31:38 -05:00
Joshua Boniface
c2e57aba27 Add Debian armhf (Rasberry Pi) build plus crossbuild 2019-02-23 20:07:05 -05:00
Bond-009
4a3e42e779 Merge pull request #986 from JustAMan/submodule-update
Backmerge submodule updating strategy
2019-02-23 10:13:02 -05:00
The Lynxy
67f399dccf Leave +genpts untouched in GetProgressiveVideoArguments() 2019-02-23 10:01:41 -05:00
Lynxy
eb95b025d4 Add to contributors 2019-02-22 23:28:19 -05:00
Anthony Lavado
de45cfdd8c Merge pull request #984 from WWWesten/patch-1
Update kz.csv
2019-02-22 22:05:36 -05:00
Xu Fasheng
47966793c0 Remove useless if..else in SsdpDevicePublisher 2019-02-23 10:15:38 +08:00
Xu Fasheng
0c49079c16 Update comments for DLNA IPv6 2019-02-23 09:56:55 +08:00
Vasily
d82d6b6aef Merge pull request #981 from cvium/close_response_stream
Close the response stream after fetching temp files
2019-02-23 02:01:20 +03:00
Vasily
7ae526da8b Merging #975 to master 2019-02-23 01:52:51 +03:00
WWWesten
e79d44d9f1 Update kz.csv
The new ratings system
2019-02-23 01:51:35 +05:00
Claus Vium
fb7de2f966 Remove duplicate code and use using to properly dispose the response stream 2019-02-22 20:24:42 +01:00
Bond-009
db54fe4c70 Merge pull request #975 from cvium/release-10.2.z
Update submodule
2019-02-22 12:57:20 -05:00
Xu Fasheng
1eb26bdf08 Ignore IPv6 DLNA devices
DLNA is not ready for IPv6 now, uncomment the code will be fine.
2019-02-22 20:18:34 +08:00
Xu Fasheng
cbd0e71c07 Send DLNA devices message to only the matched interface
This will be the right way for multiple interfaces, or the client will
receive all devices message with different IP addresses and could not
detect which one could access.

And provide one option DlnaOptions.SendOnlyMatchedHost to fallback to old
behaviour if this commit missed something.
2019-02-22 20:18:34 +08:00
Xu Fasheng
2db1826ed8 Enable DLNA multi socket binding for linux
If not, DLNA on multiple interfaces not works for linux, for
example ZerotierOne VPN.
2019-02-22 20:13:17 +08:00
Xu Fasheng
cf4e64f430 Add option to toggle if ignore virtual interfaces
Some VPN like ZerotierOne owns IP address but no gateway, and there is no
good idea in NetworkManager.GetIPsDefault() to filter such virtual interfaces,
so just provide one option to let user decide it.
2019-02-22 20:13:17 +08:00
Lynxy
9b39404b9a Always set ffmpeg flag +genpts when video stream is being copied 2019-02-21 19:50:57 -05:00
Claus Vium
00fe66a38c Update submodule 2019-02-21 20:59:10 +01:00
Vasily
406af5f086 Merge pull request #967 from brianjmurrell/dotnet-runtime
dotnet-runtime is needed on Fedora now
2019-02-21 15:25:51 +03:00
Vasily
e7e7d96f51 Merge pull request #776 from cvium/update_tvdb
Update tvdb provider to v2 api
2019-02-21 15:09:54 +03:00
Vasily
785fa76ac6 Merge pull request #955 from ploughpuff/avoid
Avoid exceptions due to folder and file not found
2019-02-21 15:05:31 +03:00
Vasily
6c967c5982 Merge pull request #952 from Liggy/populate-extras
Populate video extras again
2019-02-21 15:02:36 +03:00
Brian J. Murrell
f03e279382 COPR auto building
This adds enhancements so that Fedora/EL packages can be automatically
built in COPR when a webhook is received.  A typical webhook could be
for tagging events for example or even a "Release" webhook to only
build releases.
2019-02-21 02:12:16 -05:00
Brian J. Murrell
1bc2b12ee3 dotnet-runtime is needed in Fedora RPM build also 2019-02-21 02:11:46 -05:00
Joshua Boniface
469a17b3ca Install the dotnet runtime too
This is needed since /usr/bin/dotnet doesn't exist in the SDK package
for whatever reason as of Feb 18 2019.
2019-02-20 20:36:49 -05:00
Bond-009
affb8c8673 Merge pull request #962 from scheidleon/fix-windows-build
Fix Path
2019-02-20 15:38:43 -05:00
scheidleon
74aa38acd7 Fix Path 2019-02-20 21:04:52 +01:00
Joshua M. Boniface
d4ded281aa Merge pull request #961 from jellyfin/release-10.2.z
Release 10.2.1
2019-02-20 14:24:22 -05:00
Claus Vium
c597f0de35 Make Tvdb strings const 2019-02-20 19:55:06 +01:00
Bond-009
3965f90236 Update MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs
Co-Authored-By: cvium <cvium@users.noreply.github.com>
2019-02-20 19:36:33 +01:00
Claus Vium
8af4417f8f Add ConfigureAwait to awaited calls 2019-02-20 19:35:47 +01:00
Joshua Boniface
83948420a4 Bump version to 10.2.1 2019-02-20 13:29:14 -05:00
Andrew Rabert
8c53407a9d Merge pull request #960 from nvllsvm/dock
Use jellyfin/ffmpeg image
2019-02-20 13:15:23 -05:00
Claus Vium
4a5c526ccc Fix logging args and add ilogger with categoryname 2019-02-20 19:08:47 +01:00
Andrew Rabert
69a81c0bc2 Use jellyfin/ffmpeg image 2019-02-20 12:11:50 -05:00
Bond_009
320707d44c Reduce string allocations at startup 2019-02-20 16:49:03 +01:00
Torsten
2690ac299b Only refresh metadata if extras changed 2019-02-20 16:39:49 +01:00
Torsten
268b099ca8 Merge branch 'populate-extras' of github.com:Liggy/jellyfin into populate-extras 2019-02-20 16:38:30 +01:00
Liggy
33171a58b5 Merge branch 'master' into populate-extras 2019-02-20 16:37:57 +01:00
PloughPuff
73c1cdb32a Avoid exceptions due to folder and file not found
1) Use function to return path to temp transcode path which has benefit of creating temp folder if not exists, thereby avoiding the exception when GetFilePaths is used.
2) Check json files exists before attempting to read from it.  Avoids having to mask FileNotFound exceptions when debugging.
2019-02-20 13:30:06 +00:00
Liggy
13bfe5093e Merge branch 'master' into populate-extras 2019-02-20 14:24:23 +01:00
Bond-009
99bed9a9c3 Merge pull request #939 from joshuaboniface/cleanup-builds
Clean up and rename obsolete deployment platforms
2019-02-20 07:28:20 -05:00
Vasily
8ef41020d9 Merge pull request #847 from Bond-009/async
Make websockets code async
2019-02-20 15:03:42 +03:00
Bond-009
fca226bdfd Add comment 2019-02-20 12:53:35 +01:00
Vasily
bca7a26ffd Merge branch 'master' into update_tvdb 2019-02-20 14:46:07 +03:00
Vasily
60df855b26 Merge pull request #930 from fruhnow/AuthorizationCheck
checking user-permission in GetQueryResult
2019-02-20 14:42:35 +03:00
Vasily
44ed037e73 Merge pull request #950 from cvium/replace_priority_queue
Replace OptimizedPriorityQueue source with NuGet reference
2019-02-20 14:39:52 +03:00
Vasily
50ce7572b4 Merge pull request #851 from Bond-009/appdata
Simplify code to get data dir
2019-02-20 14:31:01 +03:00
Vasily
74695428fe Merge pull request #914 from Bond-009/httppostedfile
Separate HttpPostedFile into it's own file
2019-02-20 13:33:42 +03:00
Claus Vium
139807719c Add missing base64 conversion 2019-02-20 11:09:10 +01:00
Claus Vium
1e2050f106 Rename functions to match functionality 2019-02-20 11:09:10 +01:00
Claus Vium
a23f04623e Remove IEncryptionManager 2019-02-20 11:09:06 +01:00
Claus Vium
1f30a50f4a Address review comments 2019-02-20 11:03:04 +01:00
Phallacy
098de6b050 made newlines into linux newlines 2019-02-20 01:17:30 -08:00
Phallacy
a0d31a49a0 merging with master to clear merge conflict 2019-02-20 00:46:13 -08:00
Phallacy
6bbb968b57 minor changes and return to netstandard 2019-02-20 00:00:26 -08:00
Joshua M. Boniface
6c6e9ca9f2 Merge pull request #889 from Bond-009/xmlex
Fix uncaught xml error
2019-02-19 21:31:16 -05:00
Joshua M. Boniface
89d4ce309d Merge pull request #848 from Bond-009/perf
Minor changes to reduce allocations
2019-02-19 21:24:51 -05:00
Joshua M. Boniface
b43317c5e1 Merge pull request #830 from Bond-009/update
Removed remaining self-update code
2019-02-19 21:21:36 -05:00
Torsten
5917e91447 Merge https://github.com/jellyfin/jellyfin into populate-extras 2019-02-19 23:21:40 +01:00
Torsten
9753a76905 Populate video extras again 2019-02-19 22:41:25 +01:00
Bond-009
d978ae1996 Merge pull request #948 from cvium/revert_movie_matching
Revert movie matching
2019-02-19 16:31:01 -05:00
Claus Vium
6016a27736 Check for whitespace 2019-02-19 22:30:21 +01:00
Vasily
24b76dbed8 Merge pull request #936 from EraYaN/fix-drone-abi-tests
Fixed the assemblynames for compatibility check in drone.
2019-02-20 00:22:09 +03:00
Claus Vium
dab25a0eeb Remove OptimizedPriorityQueue source and grab it from nuget 2019-02-19 21:17:30 +01:00
Claus Vium
566646ad8b Remove limit comment 2019-02-19 19:44:22 +01:00
Claus Vium
6c1ca6f737 Remove arbitrary limit and minor style fixes 2019-02-19 19:33:41 +01:00
Claus Vium
aa0c20afd5 Revert "Change multi version logic for movies"
This reverts commit a4055779f6.
2019-02-19 17:39:47 +01:00
Claus Vium
46acff4113 Revert "Remove unnecessary ToList"
This reverts commit 42abb5a993.
2019-02-19 17:39:30 +01:00
Claus Vium
de5c0bab70 Revert "Add Year to the new VideoInfo"
This reverts commit 05ad2e9b3f.
2019-02-19 17:39:10 +01:00
Claus Vium
5181427234 Revert "Merge pull request #924 from cvium/fix_movie_matching"
This reverts commit f274d024ce, reversing
changes made to 4b4399fba6.
2019-02-19 17:34:43 +01:00
Claus Vium
c79324154f Revert "Merge pull request #933 from cvium/fix_movie_matching_again"
This reverts commit 77d4fec6eb, reversing
changes made to f274d024ce.
2019-02-19 17:10:11 +01:00
Felix Ruhnow
53beebc774 switching logging to serilog convention according to pr comments 2019-02-19 12:17:28 +01:00
Felix Ruhnow
ba003e06ef adressing pr comments 2019-02-19 12:09:39 +01:00
Felix Ruhnow
1d631540ac adressing pr comments 2019-02-19 12:06:50 +01:00
Joshua Boniface
3ed9d32f68 Rename Windows scripts folder 2019-02-18 22:07:53 -05:00
Joshua Boniface
3ecfd1fdd1 Rename framework to portable 2019-02-18 22:07:12 -05:00
Joshua Boniface
24574d4964 Rename MacOS build 2019-02-18 22:06:44 -05:00
Joshua Boniface
512ab8c6aa Remove unneeded Linux builds 2019-02-18 22:06:06 -05:00
Erwin de Haan
029bafdf9c Changed build name template and limited number of parallel jobs. 2019-02-19 03:16:17 +01:00
Erwin de Haan
0849c4a447 Switched to dotnet based execution again because of permissions. 2019-02-19 03:12:53 +01:00
Erwin de Haan
5238ba5d8f Fix tool extraction search pattern. 2019-02-19 03:07:44 +01:00
Erwin de Haan
6b1a64652f Fix path for naming, and add extra CopyFIle Task. 2019-02-19 02:59:56 +01:00
Erwin de Haan
9961c8c459 No full publish of artifacts. 2019-02-19 02:55:10 +01:00
Erwin de Haan
18418b6892 Fixed secondary Artifact paths and Debug config. 2019-02-19 02:50:25 +01:00
Erwin de Haan
d4bc7b5a5a Fix NuGet task name. 2019-02-19 02:42:42 +01:00
Erwin de Haan
e2d0f67077 Fix the conditions. 2019-02-19 02:32:36 +01:00
Erwin de Haan
5ef63e738d Added final stage and removed triggers. 2019-02-19 02:28:16 +01:00
Erwin de Haan
7bbcb455c0 Added compat checking to YAML 2019-02-19 02:17:57 +01:00
Erwin de Haan
2ad54cd09d Fixed the assemblynames from drone since, the namespaces do not line up (yet). 2019-02-19 01:18:49 +01:00
Erwin de Haan
7c9803e135 Update azure-pipelines.yml for Azure Pipelines 2019-02-18 23:47:31 +01:00
Erwin de Haan
480999e8e6 Update azure-pipelines.yml for Azure Pipelines 2019-02-18 23:42:24 +01:00
Erwin de Haan
ef17ec700b Update azure-pipelines.yml 2019-02-18 23:24:39 +01:00
Erwin de Haan
4b34b0cfea Merge branch 'azure-pipelines' of https://github.com/EraYaN/jellyfin into azure-pipelines 2019-02-18 23:03:14 +01:00
Erwin de Haan
60fc53306d Fixed vmImage 2019-02-18 22:53:32 +01:00
Bond-009
77d4fec6eb Merge pull request #933 from cvium/fix_movie_matching_again
Semi-revert to prefer old movie grouping behaviour
2019-02-18 16:48:05 -05:00
Bond-009
c6188e26af Got to start somewhere 2019-02-18 22:47:02 +01:00
Erwin de Haan
18717d103a Update azure-pipelines.yml for Azure Pipelines 2019-02-18 22:36:24 +01:00
Erwin de Haan
6834b64922 Add first Azure Pipeline (Build) 2019-02-18 22:26:40 +01:00
Claus Vium
29ff80d69c Minor style fixes 2019-02-18 22:02:16 +01:00
Claus Vium
4a700778e3 Semi-revert to prefer old movie grouping behaviour 2019-02-18 21:56:08 +01:00
Phallacy
56e3063342 little fixes for JustAMan 2019-02-18 10:56:01 -08:00
Joshua M. Boniface
781cca0c82 Merge pull request #902 from brianjmurrell/copr-autobuild
COPR auto building
2019-02-18 13:53:59 -05:00
Andrew Rabert
eab35890dc Merge pull request #862 from EraYaN/abi-check-drone
Add dotnet-compat ABI testing and Debug configuration building to drone-CI
2019-02-18 13:11:06 -05:00
Felix Ruhnow
967d5deeb7 checking user-permission in GetQueryResult to prevent accessing the library without permission but having a link. (+added myself as contributor. forgot last time bout that) 2019-02-18 18:29:58 +01:00
Bond-009
51ba28bd65 Remove useless check 2019-02-18 17:37:10 +01:00
Bond_009
a94aeb5c87 Simplify code to get data dir 2019-02-18 17:35:09 +01:00
Vasily
13f2783a8e Merge pull request #887 from wtayl0r/replace-primitives-with-iconfiguration
Replace primitive injection with IConfiguration
2019-02-18 19:30:11 +03:00
Bond_009
7554f63551 Remove more self-update code 2019-02-18 16:57:08 +01:00
Bond_009
25253cf961 Fix style issues in changed files 2019-02-18 16:57:08 +01:00
Bond_009
77a5617774 Removed remaining self-update code 2019-02-18 16:57:08 +01:00
Vasily
f274d024ce Merge pull request #924 from cvium/fix_movie_matching
Use the movie name instead of folder name
2019-02-18 15:10:36 +03:00
Vasily
395072239d Merge pull request #913 from Bond-009/log
Reduce log spam
2019-02-18 14:50:53 +03:00
Vasily
e2f6ecaef6 Merge pull request #829 from Bond-009/fields
Removed some unused fields
2019-02-18 14:47:02 +03:00
Phallacy
48e7274d37 added justaman notes, fixed new bug from emty has removals 2019-02-18 01:26:01 -08:00
LogicalPhallacy
9f3aa2cead Apply suggestions from code review
Adding minor stylistic suggestions from Bond-009

Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-02-18 00:31:03 -08:00
bobberb
bb50363812 Translated using Weblate (Hebrew)
Currently translated at 97.8% (92 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/he/
2019-02-17 15:59:36 -05:00
Joshua M. Boniface
9a38e4dc8a Merge pull request #925 from Bond-009/newmaser
Merge 10.2.0 release branch back into master
2019-02-17 13:05:12 -05:00
William Taylor
c607c95e64 Removed async from non-async method 2019-02-17 14:33:20 +00:00
William Taylor
18ae107ce4 Removed unnecessary configuration options and reduced primitive dependencies 2019-02-17 14:09:52 +00:00
William Taylor
3f80b16ffa Removed Reference and replaced with package reference 2019-02-17 14:09:52 +00:00
William Taylor
72aa364aa5 Removed extra using 2019-02-17 14:08:52 +00:00
William Taylor
0d5fbcb031 Removed primitives from services in Program.cs
This will make it easier to move dependency registration
to a system without having to new up all the services first.
Moved the primitives to an IConfiguration which is much easier to inject.
2019-02-17 14:08:52 +00:00
Bond-009
a35ea49c99 Merge remote-tracking branch 'upstream/release-10.2.z' into newmaser 2019-02-17 10:38:44 +01:00
Claus Vium
c45b6aa53e Use the movie name instead of folder name 2019-02-17 07:39:36 +01:00
Andrew Rabert
4b4399fba6 Merge pull request #920 from nvllsvm/dockolate_icetainer
Fix cachedir missing from Docker container
2019-02-16 15:54:16 -05:00
Andrew Rabert
c06598635f Fix cachedir missing from Docker container
Adds the /cache volume and set it to writeable by all. This allows for
those using jellyfin to continue using it without modifying their
config. However, retaining cache will require one to mount the /cache
volume.

Also make the /config and /media dirs 777 by default. No permissions on
mounted volumes will be changed.
2019-02-16 15:25:44 -05:00
Joshua Boniface
a15098dc00 Bump release version for last-minute PRs 2019-02-16 12:13:38 -05:00
Bond-009
4811e76860 Merge branch 'master' into perf 2019-02-16 17:05:44 +01:00
Bond-009
64a4f259a2 Merge branch 'master' into async 2019-02-16 17:05:05 +01:00
Bond-009
bdfd042d70 Merge branch 'master' into fields 2019-02-16 17:03:15 +01:00
Bond-009
a993420676 Reduce log spam 2019-02-16 16:42:24 +01:00
Bond-009
fb6a901374 Separate HttpPostedFile 2019-02-16 11:46:58 +01:00
Bond-009
86a4d15a32 Merge pull request #899 from AThomsen/bugfix/dlna_name_race_condition
DLNA: Fix race condition leading to missing device names
2019-02-16 11:07:30 +01:00
Bond-009
25c2267a89 Merge pull request #907 from cvium/fix_assembly_visibility
Fix assembly visibility
2019-02-16 10:38:10 +01:00
Andrew Rabert
b86f049e66 Merge pull request #910 from nvllsvm/make_it_so
Enhance Dockerfiles
2019-02-16 01:53:10 -05:00
Andrew Rabert
12fea24590 Merge pull request #911 from nvllsvm/hooked_on_phonics
Checkout submodules in Docker Hub hook
2019-02-16 01:53:01 -05:00
Andrew Rabert
26e2ffdd31 Checkout submodules in Docker Hub hook 2019-02-16 01:45:48 -05:00
Andrew Rabert
d9ab654abe Enhance Dockerfiles
* Prevent failure when obj exists from host compile
* Enhance readability of disposed stages
* Formatting
2019-02-16 01:37:55 -05:00
Andrew Rabert
c44f96b727 Merge pull request #909 from n8225/dockerBuilds
Fix docker arm builds
2019-02-16 01:34:37 -05:00
n8225
c5ac36c886 Fix docker arm builds 2019-02-15 23:34:16 -06:00
Joshua Boniface
ff9a0c7e55 Update submodule to 10.2.0 release 2019-02-15 21:04:20 -05:00
Joshua Boniface
056e19f350 Remove superfluous changelog entries 2019-02-15 21:04:12 -05:00
Joshua Boniface
f8ba55e202 Update version to 10.2.0 release 2019-02-15 20:52:54 -05:00
Joshua M. Boniface
4ea76f9cdc Merge pull request #883 from jellyfin/translations
Import Translations
2019-02-15 20:47:37 -05:00
Joshua M. Boniface
88f56cd0c4 Merge pull request #892 from joshuaboniface/depend-ffmpeg-version
Add jellyfin-ffmpeg and versioning to package deps
2019-02-15 20:40:29 -05:00
PloughPuff
69ea15f73a Use string interpolation
Two further review comments from JustAMan.
2019-02-16 00:47:38 +00:00
Vasily
b7ae044e65 Merge pull request #885 from Bond-009/warn
More warning fixes
2019-02-16 03:22:12 +03:00
PloughPuff
d8d237f6f2 Review comments
Addressed review comments from JustAMan.  Removed code to determine experimental version.  Store major and minor as two ints.  Allow control of a min and max recommended version.
2019-02-15 23:51:22 +00:00
Bond-009
18e1d03a89 Comments 2019-02-16 00:44:10 +01:00
Vasily
3947f2315d Update Jellyfin.Server/Jellyfin.Server.csproj
Co-Authored-By: Bond-009 <bond.009@outlook.com>
2019-02-16 00:43:56 +01:00
Bond-009
cb9e50b2ea Reorder elements 2019-02-16 00:43:56 +01:00
Bond-009
e620bb9512 Remove more doc warnings 2019-02-16 00:43:56 +01:00
Bond-009
8b04fe7633 More fixes 2019-02-16 00:43:56 +01:00
Bond-009
2cb747651b Correctly dispose WebSocketSharpListener 2019-02-16 00:43:56 +01:00
Bond-009
46897aab4f More warnings 2019-02-16 00:43:56 +01:00
Bond-009
892787cb1a Disable SA1130 2019-02-16 00:43:56 +01:00
Bond-009
be77e14db9 Warnings for docs 2019-02-16 00:43:56 +01:00
Bond-009
34af7501fa Fix up CoreAppHost.cs 2019-02-16 00:43:56 +01:00
Bond-009
183ef34422 Do not declare visible instance fields 2019-02-16 00:43:56 +01:00
Bond-009
637936cb9f Closing braces should be followed by an empty line 2019-02-16 00:43:56 +01:00
Bond-009
fc59b0ab77 Disable SA1512 2019-02-16 00:43:56 +01:00
Bond-009
d8b312674d No multiple empty lines 2019-02-16 00:43:56 +01:00
Bond-009
ebae7229c1 Single line comments should start with a space 2019-02-16 00:43:56 +01:00
Bond-009
3df8cda110 ConfigureAwait 2019-02-16 00:43:56 +01:00
Bond-009
43cf11aa35 Change discards 2019-02-16 00:42:56 +01:00
Bond-009
6d74184cfb Merge pull request #901 from cvium/dispose_webresponse_on_errors
Properly dispose HttpWebResponse when the request failed to avoid 'too many open files'
2019-02-16 00:15:59 +01:00
Claus Vium
21f0a7e020 Make all class implementing dynamically loaded interfaces public 2019-02-15 23:05:14 +01:00
Claus Vium
cb6d2cbd2d Remove SizeLimit 2019-02-15 22:02:17 +01:00
Claus Vium
ce51025e7c Use DI for TvDbClientManager 2019-02-15 20:11:27 +01:00
Claus Vium
5a054e5150 Remove useless doc 2019-02-15 19:33:10 +01:00
Claus Vium
98f003f71a Review comments 2019-02-15 19:33:10 +01:00
Claus Vium
b9efcace79 Extract imagetype-to-keytype statements into a utility function and move tvdb specific utils to separate class 2019-02-15 19:33:10 +01:00
Claus Vium
1aaa8de1f9 Use Task.WhenAll properly 2019-02-15 19:33:10 +01:00
Claus Vium
5e2e190f3e Add key delimiter to avoid potential clashes 2019-02-15 19:33:10 +01:00
Claus Vium
828434058f Use language supplied as argument instead of reading from TvDbClient 2019-02-15 19:33:10 +01:00
Claus Vium
dfbf5fc9fa Add generic key generation function 2019-02-15 19:33:10 +01:00
Claus Vium
8029cd3ebb Add better language support 2019-02-15 19:33:10 +01:00
Vasily
e970d7a6aa Update MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
Co-Authored-By: cvium <cvium@users.noreply.github.com>
2019-02-15 19:33:10 +01:00
Claus Vium
350e795640 Fix namespace in tvdbclientmanager 2019-02-15 19:33:10 +01:00
Claus Vium
f5bda652c4 Add support for searching for episodes by premiere date and fixed timezones 2019-02-15 19:33:10 +01:00
Claus Vium
e8189cd0f6 Fix namespaces 2019-02-15 19:33:10 +01:00
Claus Vium
18231fedef Add braces to if's and other minor style changes 2019-02-15 19:33:10 +01:00
Claus Vium
935c7231eb Review comments 2019-02-15 19:33:10 +01:00
Vasily
da2c7db0df Apply suggestions from code review
Co-Authored-By: cvium <cvium@users.noreply.github.com>
2019-02-15 19:33:10 +01:00
Claus Vium
83d98ac92d Fix episode provider 2019-02-15 19:33:10 +01:00
Claus Vium
b997b12d27 Add names to tuple items and reduce list iterations 2019-02-15 19:33:10 +01:00
Claus Vium
6887e790c8 Minor fixes in MissingEpisodeProvider 2019-02-15 19:33:10 +01:00
Claus Vium
373a1f72bf Fix actor image provider 2019-02-15 19:33:10 +01:00
Claus Vium
0d43b06042 Fix MissingEpisodeProvider (almost) 2019-02-15 19:33:10 +01:00
Claus Vium
ced9868357 Fix a copy paste mistake and add series end date 2019-02-15 19:33:10 +01:00
Claus Vium
23c867f946 Remove TvdbPrescanTask as it looks like it was used for pre-fetching data, which is no longer relevant 2019-02-15 19:33:10 +01:00
Claus Vium
42c233c74e Add much needed exception handling and logging 2019-02-15 19:33:10 +01:00
Claus Vium
1f8e74f3a8 Add caching for all tvdb requests 2019-02-15 19:33:10 +01:00
Claus Vium
d6835f8dd6 Use the locking properly, this is not Python... 2019-02-15 19:33:10 +01:00
Claus Vium
86940e96d5 More MemoryCache PoC 2019-02-15 19:33:10 +01:00
Claus Vium
75d90c8e4c Add caching PoC 2019-02-15 19:33:10 +01:00
Claus Vium
ecbc0538f6 Add some error handling, grab imdb id and other minor fixes 2019-02-15 19:33:10 +01:00
Claus Vium
2a26760911 Episode provider is somewhat broken 2019-02-15 19:33:10 +01:00
Claus Vium
19b6808602 Remove some junk from series provider 2019-02-15 19:33:10 +01:00
Claus Vium
c2202be0f8 Some of it works??? 2019-02-15 19:33:10 +01:00
Claus Vium
9729ae52a3 initial commit 2019-02-15 19:33:10 +01:00
Vasily
7cc69f30c4 Merge pull request #801 from Bond-009/di
Move to Microsoft.Extensions.DependencyInjection
2019-02-15 21:21:58 +03:00
Brian J. Murrell
e33706ab25 Code review updates
Also fix a bug in the tarball creation that existed even prior
to moving it into create_tarball.sh
2019-02-15 10:22:52 -05:00
Brian J. Murrell
4018b7e2d5 COPR auto building
This adds enhancements so that Fedora/EL packages can be automatically
built in COPR when a webhook is received.  A typical webhook could be
for tagging events for example or even a "Release" webhook to only
build releases.
2019-02-15 08:21:55 -05:00
Vasily
8425d76198 Merge pull request #875 from Bond-009/error
Treat warnings as errors for release builds
2019-02-15 13:58:49 +03:00
Vasily
9bf009c4f8 Merge pull request #898 from EraYaN/namingrules-editorconfig
Switch to Roslyn naming rules in EditorConfig
2019-02-15 13:40:10 +03:00
Claus Vium
2845e7e101 Properly dispose HttpWebResponse when the request failed to avoid 'too many open files' 2019-02-15 08:56:08 +01:00
WWWesten
c78298789d Translated using Weblate (Kazakh)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/kk/
2019-02-14 18:45:24 -05:00
PloughPuff
a6bde0943e Implement proper FFmpeg version checking
Three routes to determine FFmpeg version:
1) Grab the 'ffmpeg version x.y' from from the -version output.  This should work for all pre-built binaries.
2) Compare the library versions against known contents of FFmpeg versions.  This is fallback aimed at custom builds.
3) Compare libavcodec version to determine if newer than latest known release.  This suggests user is running within latest/HEAD/master build.
2019-02-14 22:08:48 +00:00
Anders Thomsen
7bb8985f11 Fix race condition in adding dlna devices to session when the device is discovered repeatedly 2019-02-14 21:53:04 +01:00
Erwin de Haan
db1ebe2559 Static fields prefix 's_' -> '_' 2019-02-14 20:14:29 +01:00
Erwin de Haan
dbebc4774f Switched to Roslyn naming rules 2019-02-14 20:06:20 +01:00
Bond-009
0fbc4545d1 Address comments 2019-02-14 17:02:46 +01:00
Joshua Boniface
8414285b58 Only modify Debian package spec for jellyfin-ffmpeg 2019-02-14 09:15:37 -05:00
Vasily
5d4bef5478 Update jellyfin-web submodule to master as of 14.02.2019 2019-02-14 09:14:04 -05:00
Vasily
cac3a3e945 Merge pull request #863 from fruhnow/tvg-chno
Adding support for "tvg-chno"-Tag in M3U Channel Lists
2019-02-14 12:46:31 +03:00
Joshua Boniface
7ec42b89a0 Correct changelogs for updated 10.2.0~rc2 2019-02-13 17:45:17 -05:00
Bond-009
bca569da42 Reduce the amount of db calls during the post scan event 2019-02-13 22:10:37 +01:00
Bond-009
a82303ccd1 Fix uncaught xml error 2019-02-13 21:41:24 +01:00
Claus Vium
c720504e39 Drop ETag and use Last-Modified header (#890)
Drop ETag and use Last-Modified since performance is much better
2019-02-13 21:08:59 +01:00
ploughpuff
a2dd2ddd55 Rewrite rules for determining app paths and use XDG_CONFIG_HOME for configDir (#781)
Re-write rules for determining dataDir, configDir and logDir.  Generally, arguments from command line take precedence, then JELLYFIN env vars, before using XDG names.

Co-Authored-By: ploughpuff <33969763+ploughpuff@users.noreply.github.com>
2019-02-13 16:35:14 +01:00
Bond-009
5835c4b21d Remove comment 2019-02-13 12:58:46 +01:00
Claus Vium
d8e6808d77 Update Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
fix to styling

Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-02-13 00:44:07 -08:00
Claus Vium
9e58e31de0 Update Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
fix to styling

Co-Authored-By: LogicalPhallacy <44458166+LogicalPhallacy@users.noreply.github.com>
2019-02-13 00:43:48 -08:00
Phallacy
77602aff88 Minor fixes re:PR870, added null checks from PR876 2019-02-13 00:33:00 -08:00
Phallacy
1ffd443d5a fixed nul user check to be first per justaman 2019-02-12 22:30:26 -08:00
Phallacy
1dc5a624a7 fixed gitignore fail 2019-02-12 22:24:05 -08:00
Joshua Boniface
af8f86b3de Bump version to 10.2.0~rc2 2019-02-13 01:03:48 -05:00
Polydeukes
bfc3954995 Translated using Weblate (Spanish)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es/
2019-02-13 00:45:21 -05:00
WWWesten
4ed90d4658 Translated using Weblate (Kazakh)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/kk/
2019-02-13 00:45:21 -05:00
ZsiGiT
3a6a5baa8e Translated using Weblate (Hungarian)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/hu/
2019-02-13 00:45:21 -05:00
Leo Verto
18f0d996c0 Translated using Weblate (German)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/
2019-02-13 00:45:21 -05:00
Claus Vium
da2554bd53 Translated using Weblate (Danish)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/da/
2019-02-13 00:45:21 -05:00
WWWesten
f2811323c2 Translated using Weblate (Kazakh)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/kk/
2019-02-13 00:45:21 -05:00
Erwin de Haan
3f878d63a5 Added Debug build and seperate the check-abi pipeline. 2019-02-12 22:44:01 +01:00
Bond-009
a5882ae162 Treat warnings as errors for release builds 2019-02-12 22:15:11 +01:00
Bond-009
c74028d08d Address comments 2019-02-12 21:59:56 +01:00
Bond-009
3f13851be5 Address comments 2019-02-12 21:06:47 +01:00
Bond_009
ea446fd4a3 Revert back to netcoreapp2.1 2019-02-12 21:06:47 +01:00
Bond_009
585b5201f1 Last bits 2019-02-12 21:06:47 +01:00
Bond_009
8d98885cda Less string allocations 2019-02-12 21:06:47 +01:00
Bond_009
da9418c1b2 Useless copy 2019-02-12 21:06:47 +01:00
Bond_009
9dba930a85 Warn faster for slow requests 2019-02-12 21:06:47 +01:00
Bond_009
7722cb3ffa Some Lists -> IEnumerable 2019-02-12 21:06:47 +01:00
Bond_009
3e6819c718 Don't clone lists 2019-02-12 21:06:47 +01:00
Bond_009
41fb1e5106 Tuple -> ValueTuple 2019-02-12 21:06:47 +01:00
Bond_009
64d5ec12e2 Use HashSets for increased perf 2019-02-12 21:06:47 +01:00
Bond_009
d409623086 Don't create multiple instances of the same type 2019-02-12 20:52:23 +01:00
Bond_009
9af28607c9 Simplify plugin loading 2019-02-12 20:52:23 +01:00
Bond_009
81a8ebde22 Move to Microsoft.Extensions.DependencyInjection
This PR replaces SimpleInjector with
Microsoft.Extensions.DependencyInjection.
2019-02-12 20:52:23 +01:00
Vasily
221a95c93c Translated using Weblate (Russian)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ru/
2019-02-12 20:37:16 +01:00
WWWesten
982ac32471 Translated using Weblate (Russian)
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ru/
2019-02-12 20:37:16 +01:00
Joshua Boniface
d48275a785 Translated using Weblate (English (United Kingdom))
Currently translated at 97.8% (92 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/en_GB/
2019-02-12 20:37:16 +01:00
Stef Havermans
a4e98a0390 Translated using Weblate (Dutch)
Currently translated at 97.8% (92 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nl/
2019-02-12 20:37:16 +01:00
Stef Havermans
0fbdb79df7 Translated using Weblate (Dutch)
Currently translated at 88.2% (83 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nl/
2019-02-12 20:37:16 +01:00
Erwin de Haan
87dc60d4aa Translated using Weblate (Dutch)
Currently translated at 88.2% (83 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nl/
2019-02-12 20:37:16 +01:00
Sarah Zainalabidin
d6b56dde62 Translated using Weblate (Malay)
Currently translated at 98.9% (93 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ms/
2019-02-12 20:37:16 +01:00
Kowalski Prime
0302144b22 Translated using Weblate (Italian)
Currently translated at 98.9% (93 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/it/
2019-02-12 20:37:16 +01:00
ZsiGiT
269b94254b Translated using Weblate (Hungarian)
Currently translated at 98.9% (93 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/hu/
2019-02-12 20:37:16 +01:00
Hadrien Miche
2f377e0a0f Translated using Weblate (French)
Currently translated at 98.9% (93 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/fr/
2019-02-12 20:37:16 +01:00
Erwin de Haan
3b96c78515 Translated using Weblate (English (United States))
Currently translated at 100.0% (94 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/en_US/
2019-02-12 20:37:16 +01:00
bakkegaard
e150174ece Translated using Weblate (Danish)
Currently translated at 98.9% (93 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/da/
2019-02-12 20:37:16 +01:00
Erwin de Haan
33e069e461 Translated using Weblate (Dutch)
Currently translated at 96.8% (91 of 94 strings)

Translation: Jellyfin/Jellyfin
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nl/
2019-02-12 20:37:16 +01:00
Erwin de Haan
8055b70ab1 Fixed full pipeline, runs correctly now with drone exec 2019-02-12 16:21:46 +01:00
Vasily
593b7327cf Merge pull request #868 from WillWill56/fix_bss
Fix audio streaming via BaseProgressiveStreamingService
2019-02-12 17:52:54 +03:00
Joshua M. Boniface
9d795adc3e Merge pull request #872 from WillWill56/fix_sbnullref
Fix potential NullReferenceException
2019-02-12 09:12:18 -05:00
Joshua M. Boniface
0ff38b6012 Merge pull request #869 from cvium/only_zips
Remove DLL support and require all packages/plugins to be zip archives
2019-02-12 09:02:27 -05:00
William Lees
fe43e279c8 Add to contributors 2019-02-12 23:50:53 +11:00
William Lees
d18823ced1 Fix potential NullReferenceException 2019-02-12 23:28:02 +11:00
Phallacy
05bbf71b6d sha256 with salt auth and sha1 interop 2019-02-12 02:16:03 -08:00
LogicalPhallacy
8bf88f4cb2 Merge pull request #9 from jellyfin/master
Yanking in latest changes
2019-02-11 22:48:50 -08:00
William Lees
db4a72df10 Reduce scope of changes 2019-02-12 09:23:51 +11:00
Claus Vium
406fb045c2 Change logging to match the action 2019-02-11 18:54:10 +01:00
Claus Vium
32992b6143 Add extra linebreak 2019-02-11 18:53:35 +01:00
Claus Vium
da169dddb5 Remove DLL support and require all packages/plugins to be zip archives 2019-02-11 18:52:09 +01:00
William Lees
250f03d2d9 add httpClient to more constructors 2019-02-12 00:42:33 +11:00
William Lees
d8cb34dbbc add httpClient to appropriate constructors 2019-02-12 00:24:00 +11:00
Felix Ruhnow
edf5ee0cc4 combining some of the if's and adressing #820 2019-02-11 10:11:07 +01:00
Anthony Lavado
8fd9f5b6a4 Merge pull request #864 from joshuaboniface/zipped-plugins
Add support for ZIP plugin archives
2019-02-11 00:22:32 -05:00
Joshua Boniface
2f4a00d322 Add support for ZIP plugin archives
Most code from @cvium. Also removes the lazy and ill-conceived GUID-
based checksumming, which just died with ZIP archives.
2019-02-10 17:29:55 -05:00
Felix Ruhnow
86089ec03a Adding support for "tvg-chno"-Tag in M3U Channel Lists 2019-02-10 22:23:47 +01:00
Joshua Boniface
9849c183ac Fix syntax error of additional brace 2019-02-10 21:42:37 +01:00
Erwin de Haan
29d6783471 Switched to debian for the compat runners. 2019-02-10 21:10:03 +01:00
Erwin de Haan
236e21efcb Fixed extension of compat checker and added err_ignore flag. 2019-02-10 21:04:39 +01:00
Erwin de Haan
30ec203eff Added first test for dotnet-compat ABI testing to drone. 2019-02-10 20:57:31 +01:00
Joshua Boniface
bcb32ec6ad Bump version to 10.2.0~rc1 2019-02-10 02:08:12 -05:00
Joshua M. Boniface
eb4b705167 Merge pull request #852 from Bond-009/nuget
Use SQLitePCL.pretty.netstandard on NuGet
2019-02-09 21:51:14 -05:00
Joshua M. Boniface
d6c669a7c8 Merge pull request #824 from joshuaboniface/improved-docker-pkgbuild
Improved Docker pkgbuild
2019-02-09 20:58:56 -05:00
Joshua M. Boniface
1b84446831 Merge pull request #853 from joshuaboniface/fix-cache-reset
Fix poor handling of cache directories
2019-02-09 19:37:56 -05:00
Joshua Boniface
fb256b7aa0 Fix control file for Microsoft Docker setup 2019-02-09 19:32:06 -05:00
Joshua Boniface
382b8bb509 Use Path.Combine 2019-02-09 19:14:34 -05:00
Joshua Boniface
00234a5ece Remove superfluous comments 2019-02-09 19:12:55 -05:00
Joshua Boniface
57cefb432a Combine various RUNs in Fedora/CentOS 2019-02-09 19:06:27 -05:00
Joshua Boniface
7be4a8500c Use Microsoft dotnet Docker images 2019-02-09 19:02:27 -05:00
Joshua Boniface
74d2698c5f Fix poor handling of cache directories 2019-02-09 18:37:35 -05:00
Anthony Lavado
4727f69fc9 Merge pull request #807 from joshuaboniface/fix-restart
Fix restart script in OS packages
2019-02-09 15:43:00 -05:00
Anthony Lavado
1e6c41e333 Merge pull request #804 from joshuaboniface/fix-env
Handle new option parser properly
2019-02-09 15:39:52 -05:00
Bond_009
bee8f58265 Upgrade package versions 2019-02-09 21:32:59 +01:00
Bond_009
a71040ba1b Chnage to own NuGet package 2019-02-09 21:28:36 +01:00
Bond_009
a6a4cd5667 Removed some unused fields 2019-02-09 15:57:42 +01:00
Bond_009
3a5bbcf2a8 Style fixes 2019-02-09 15:45:36 +01:00
Bond_009
449074e73f Make more things async 2019-02-09 15:39:17 +01:00
Bond_009
2fc97212a7 Make some methods async 2019-02-09 13:41:09 +01:00
Erwin de Haan
f1ef0b0b4c Fix namespacing so it lines up properly with file names and paths (#715)
* Fix stupid namespacing so it lines up properly with file names and paths.
2019-02-09 10:10:33 +01:00
Joshua M. Boniface
387b4dea25 Merge pull request #840 from Bond-009/requestcleanup
Fix more warnings
2019-02-08 22:02:17 -05:00
Joshua Boniface
3014866f65 Add similar Ubuntu build package 2019-02-08 21:08:34 -05:00
Joshua Boniface
37985c2e26 Update image name 2019-02-08 20:44:41 -05:00
Joshua Boniface
139e3c19ee Replace symlinks with copies and update image name 2019-02-08 20:43:18 -05:00
Joshua Boniface
da860e6e54 Remove superfluous VERSION variables 2019-02-08 20:40:19 -05:00
Claus Vium
ce03662fa7 Add error logging when translation is missing from core 2019-02-08 22:10:55 +01:00
Claus Vium
49923e50db Remove missing languages from localization options 2019-02-08 22:10:55 +01:00
Claus Vium
c3c52b6682 Default to en-US for missing core translations 2019-02-08 22:10:55 +01:00
Vasily
80281e599d Merge pull request #842 from nvllsvm/vaapi
Use VAAPI-enabled ffmpeg
2019-02-08 20:26:30 +03:00
Vasily
3a88a3c795 Merge pull request #822 from Bond-009/imagedimensions
Complete rename ImageSize -> ImageDimensions
2019-02-08 20:02:25 +03:00
Vasily
d6e98f9a50 Merge pull request #819 from Bond-009/cleanup
Some small changes in Device.cs and DidlBuilder.cs
2019-02-08 19:59:55 +03:00
Vasily
2bcbffee0c Merge pull request #841 from joshuaboniface/donation-badge
Fix OC badge to all and add forum badge
2019-02-08 11:32:48 +03:00
Andrew Rabert
22ffc5aee4 Use VAAPI-enabled ffmpeg 2019-02-08 00:19:31 -05:00
Andrew Rabert
ee3a4531a0 Merge pull request #831 from Bond-009/hashset
Move some arrays to generics
2019-02-08 00:08:35 -05:00
Joshua Boniface
aff740c596 Fix OC badge to all and add forum badge 2019-02-07 18:14:43 -05:00
Bond-009
38d9eeffbe Fix more warnings 2019-02-08 00:07:57 +01:00
Anthony Lavado
d6d9fce898 Merge pull request #838 from Bond-009/requestcleanup
Quick style fix
2019-02-07 17:56:21 -05:00
Bond-009
f60ad53393 Quick style fix 2019-02-07 23:36:44 +01:00
Joshua M. Boniface
e8461d3317 Merge pull request #834 from joshuaboniface/donation-badge
Add donation badge and reorganize badges
2019-02-07 08:31:21 -05:00
Joshua Boniface
9dd512df80 Add donation badge and reorganize badges 2019-02-06 20:09:55 -05:00
Joshua M. Boniface
5b0bd88892 Merge pull request #833 from cvium/fix_localization
Add await to GetCountries in LocalizationService
2019-02-06 17:04:11 -05:00
Bond_009
70c85925af Move some arrays to generics 2019-02-06 22:58:12 +01:00
Claus Vium
e449182641 Move import 2019-02-06 22:54:57 +01:00
Claus Vium
fcfe02ee73 Add await to GetCountries in LocalizationService 2019-02-06 22:40:49 +01:00
Joshua Boniface
b8b650540d Allow Fedora/CentOS mounting by default 2019-02-06 09:33:14 -05:00
Joshua Boniface
e1d523ee45 Improve description of keep_artifacts flag 2019-02-05 21:37:56 -05:00
Joshua Boniface
ceb8b9f740 Add explanation to usage output 2019-02-05 21:34:09 -05:00
Joshua Boniface
8413c56392 Update CentOS package build 2019-02-05 19:19:55 -05:00
Joshua Boniface
88038d9644 Update Fedora package build 2019-02-05 19:04:08 -05:00
Joshua Boniface
c846da4f9e Update Debian package build 2019-02-05 18:40:50 -05:00
Joshua Boniface
546f4cd46f Add prerequisite keep_artifacts var 2019-02-05 18:40:31 -05:00
Bond-009
e216702bcf Complete rename ImageSize -> ImageDimensions 2019-02-05 19:53:50 +01:00
Bond-009
be89a5e719 Don't rename method 2019-02-05 18:16:10 +01:00
Bond_009
84d56976ba Some small changes in Device.cs and DidlBuilder.cs
Device.cs:
* Improve dispose function
* Style fixes
* Remove unused field

DidlBuilder.cs:
* Remove unused field
* Replace giant if chain with a switch statement
2019-02-05 17:37:38 +01:00
Claus Vium
0ef2b46106 Remove custom Threading 2019-02-05 16:47:50 +01:00
Anthony Lavado
52294881b1 Merge pull request #812 from joshuaboniface/readme-links
Fix up the explicit docs links in the README
2019-02-04 20:29:52 -05:00
Joshua Boniface
5e8a2db029 Fix up the explicit docs links in the README 2019-02-04 18:29:44 -05:00
Vasily
262eefd8db Merge pull request #805 from joshuaboniface/translate
Add weblate translation status to README
2019-02-05 00:52:37 +03:00
Joshua Boniface
73e8758d84 Add weblate translation status to README 2019-02-04 16:31:47 -05:00
Vasily
181de97ce5 Merge pull request #810 from Bond-009/localization
Fix loading of rating files
2019-02-05 00:19:32 +03:00
Bond_009
ae5514afd6 Fix loading of rating files 2019-02-04 18:46:36 +01:00
Vasily
83af2db679 Merge pull request #798 from Bond-009/apientrypoint
Cleanup around the api endpoints
2019-02-04 14:10:08 +03:00
Vasily
0b3e6548db Merge pull request #797 from Bond-009/warnings
Fix all warnings
2019-02-04 14:08:21 +03:00
Joshua Boniface
72beadc74d Fix restart script for Fedora/CentOS 2019-02-04 00:27:00 -05:00
Joshua Boniface
f0e74c2c6b Fix restart script for Debian 2019-02-04 00:26:23 -05:00
Joshua Boniface
d351fa0c1e Make Fedora package.sh script use bash 2019-02-03 22:59:55 -05:00
Joshua M. Boniface
20033f2275 Merge branch 'master' into fix-env 2019-02-03 22:34:40 -05:00
Joshua M. Boniface
c4c0894b29 Merge pull request #800 from Wuerfelbecher/update-rpm
Add CentOS and update rpm spec for the cachedir option
2019-02-03 22:33:47 -05:00
Joshua M. Boniface
c4f51e16a5 Merge pull request #736 from Bond-009/startasync
Start startup tasks async
2019-02-03 22:23:54 -05:00
Joshua M. Boniface
56dcc45dc0 Merge pull request #732 from Bond-009/locale
Reworked LocalizationManager to load data async
2019-02-03 22:08:20 -05:00
Joshua Boniface
be89d53a9e Handle new option parser properly 2019-02-03 20:57:07 -05:00
Vasily
3ac7531385 Merge pull request #802 from jellyfin/fix-build
Fix build error
2019-02-04 00:09:52 +03:00
Bond-009
cb1ff69585 Fix build error 2019-02-03 21:57:49 +01:00
Vasily
a50fb922c5 Merge pull request #774 from dkanada/plugin
reimplement support for plugin repository
2019-02-03 16:42:29 +03:00
Thomas Büttner
593c6c071c keep trailing 0 in version
Signed-off-by: Thomas Büttner <thomas@vergesslicher.tech>
2019-02-03 13:17:31 +01:00
Thomas Büttner
d573f2d671 use cachedir option
Signed-off-by: Thomas Büttner <thomas@vergesslicher.tech>
2019-02-03 13:17:22 +01:00
Thomas Büttner
1ce5939362 optimize rpm dependencies
Signed-off-by: Thomas Büttner <thomas@vergesslicher.tech>
2019-02-03 13:17:11 +01:00
Thomas Büttner
4d335d8f13 Add CentOS
Signed-off-by: Thomas Büttner <thomas@vergesslicher.tech>
2019-02-03 13:15:38 +01:00
dkanada
c118f111b6 add suggestions from code review 2019-02-03 19:40:55 +09:00
dkanada
52e91243e5 merge progress calculation into a single line 2019-02-03 19:40:55 +09:00
dkanada
9faa68b26f update subtitle task to match the other scheduled tasks 2019-02-03 19:40:55 +09:00
dkanada
aadf7676d1 remove useless comments 2019-02-03 19:40:55 +09:00
dkanada
08ca1337a9 unhide several scheduled tasks and add missing properties 2019-02-03 19:40:55 +09:00
dkanada
07072d9f7b move all scheduled tasks and triggers into folders 2019-02-03 19:40:55 +09:00
dkanada
7e3c45c917 fix build errors and update plugin manifest location 2019-02-03 19:40:55 +09:00
dkanada
548270772c add PluginUpdateTask back into source 2019-02-03 19:37:18 +09:00
Bond-009
cb7bffc233 Remove unused string split 2019-02-03 10:44:07 +01:00
Bond-009
da2caa2902 await async functions 2019-02-03 10:44:07 +01:00
Bond-009
ab0e851db9 Cleanup streaming services 2019-02-03 10:44:07 +01:00
Joshua M. Boniface
32f393d57f Merge pull request #764 from Bond-009/encoding
Remove dead code, made some functions properly async
2019-02-02 19:04:10 -05:00
Bond-009
78e4e2ed92 Fix all warnings 2019-02-02 21:45:29 +01:00
Andrew Rabert
42d5a48491 Merge pull request #788 from Bond-009/warnings
Fix more warnings
2019-02-02 14:21:03 -05:00
Andrew Rabert
20dac6d6b8 Merge pull request #794 from Bond-009/lesslinq
Remove MoreLINQ
2019-02-02 14:19:54 -05:00
Bond_009
1cdcace061 Remove dead code 2019-02-02 15:58:39 +01:00
Bond_009
95ee3c72e3 Properly dispose Tasks 2019-02-02 15:56:54 +01:00
Bond_009
66eabcdd39 Minor changes to encoding code
* Don't wait in intervals of 100ms for the file to exist
2019-02-02 15:56:54 +01:00
Sparky
1d94607a30 Fix docker args
After the change to runtime args in #749 docker broke.

This fixes it.
2019-02-02 15:17:59 +01:00
Bond_009
1385d89df6 Remove MoreLINQ 2019-02-02 12:27:06 +01:00
Bond_009
8b073e2ba5 Remove unused field 2019-02-02 12:19:02 +01:00
Joshua M. Boniface
34da7de47d Merge pull request #783 from joshuaboniface/use-cache-flag
Update builds to use #749 and #756
2019-02-01 20:33:22 -05:00
Joshua M. Boniface
021a1887fb Merge pull request #756 from Bond-009/cachedir
Make cache dir configurable
2019-02-01 20:33:00 -05:00
Joshua Boniface
6772ac5603 Fix double-dashes in Fedora environment file 2019-02-01 20:03:04 -05:00
Joshua Boniface
b630e9de82 Allow adm group to view Jellyfin resources
This is pretty arbitrary and personal, but I detest services that
lock out global access (which is good), but don't simultaneously
make it easy for administrators to enter the directories. The adm
group should only have actual system administrators as members,
so this lets them view the secure directories.
2019-02-01 19:16:47 -05:00
Joshua Boniface
7774977cdd Implement review feedback 2019-02-01 19:12:12 -05:00
Bond_009
5ac6d0ae59 Fix more warnings 2019-02-01 21:56:50 +01:00
Bond-009
fa3a8108e5 Update StartupOptions.cs 2019-02-01 19:52:39 +01:00
Bond_009
660f6174b3 Rebase on master 2019-02-01 18:17:43 +01:00
Bond_009
8af1e93cd4 Make cache dir configurable 2019-02-01 18:13:18 +01:00
Bond_009
cabb824f2a Fix build error 2019-02-01 18:11:46 +01:00
Vasily
b4c5ff89fd Merge pull request #782 from hawken93/wat
Remove commented file MediaBrowser.LocalMetadata.Savers.PersonXmlSaver
2019-02-01 14:30:15 +03:00
hawken
78324ff797 Remove commented file MediaBrowser.LocalMetadata.Savers.PersonXmlSaver 2019-02-01 06:51:53 +00:00
minegociomovil
885a000da7 Update iso6392.txt
Add new es-MX option for the latin metadata search in  www.themoviedb.org

Content add: spa||es-mx|Spanish; Latin|espagnol; Latin
2019-02-01 07:38:09 +01:00
Joshua Boniface
aad34e62ca Move jellyfin-sudoers to conf dir 2019-01-31 22:28:12 -05:00
Joshua Boniface
45d8ace9bb Use good ideas from Fedora systemd in Debian 2019-01-31 22:26:31 -05:00
Joshua Boniface
5e4697802f Replace programdata with datadir everywhere 2019-01-31 22:03:55 -05:00
Joshua Boniface
f6227e99cc Add cachedir to deployment scripts; fix bad logdir 2019-01-31 21:57:25 -05:00
Joshua Boniface
ae24d644db Use double-dash args in install-jellyfn.ps1 2019-01-31 21:52:26 -05:00
Joshua Boniface
b982d7c239 Update to long opts and add cache dirs 2019-01-31 21:50:50 -05:00
Joshua M. Boniface
c713824bf9 Merge pull request #734 from Bond-009/culture
Fix more analyzer warnings
2019-01-31 21:11:13 -05:00
Joshua M. Boniface
ea851317e7 Merge pull request #733 from Bond-009/startuptasks
Remove unused function
2019-01-31 20:59:38 -05:00
Claus Vium
8985fb8d58 Remove support for games as a media type 2019-01-31 19:04:47 +01:00
PloughPuff
b5e8cce4cf Improved help text and output errors to stderr
Addressed review comments from JustAMan.
2019-01-31 18:56:34 +01:00
PloughPuff
211ae30188 Revert back to NoAutoRunWebApp
Addressed further review comments.  Removed unnecessary .ParsedStartupOptions namespace.  Removed DataDir, ConfigDir and LogDir from Interface file as not necessary.
2019-01-31 18:56:34 +01:00
PloughPuff
e18b89ca27 Move Options to Jellyfin.Server and create interface file
Changes following review comments.
2019-01-31 18:56:34 +01:00
PloughPuff
ebd2a30087 Accept single-hyphen usage and rename -programdatadir to -datadir
For backwards compatibility, modify the args[] strings to replace single-hyphens with double-hyphens before parsing.

Also rename -programdatadir to -datadir.
2019-01-31 18:56:34 +01:00
PloughPuff
fd361421b1 Use CommandLineParser package for handling CLI args 2019-01-31 18:56:34 +01:00
Claus Vium
f7a46c7a56 Remove more Connect related stuff 2019-01-31 18:47:50 +01:00
Bond-009
2a1f6361a5 Merge branch 'master' into locale 2019-01-31 18:44:36 +01:00
Phallacy
4519ce26e2 Upgrade crypto provider, retarget better framework 2019-01-31 00:24:53 -08:00
Phallacy
49d9649b8e added submodule dir to gitignore 2019-01-30 23:35:17 -08:00
Bond-009
1ea219bf3f Merge branch 'master' into culture 2019-01-30 16:57:15 +01:00
Bond-009
d0f2b3a747 Merge branch 'master' into startuptasks 2019-01-30 16:55:07 +01:00
Vasily
ffcf6bdd3a Merge pull request #713 from EraYaN/fix-emtpy-statement
Fix empty statement in DidlBuilder.cs
2019-01-30 17:17:38 +03:00
Joshua M. Boniface
795f2c8774 Merge pull request #769 from EraYaN/fix-removed-filesystem-wrapper-conditions
Fix conditions where the ! was swallowed in #726
2019-01-29 19:21:30 -05:00
Erwin de Haan
f8aff0c51d Fix conditions where the ! was swallowed in #726 2019-01-30 01:02:17 +01:00
Vasily
055e43eda7 Update Emby.Server.Implementations/Localization/LocalizationManager.cs
Co-Authored-By: Bond-009 <bond.009@outlook.com>
2019-01-29 18:01:55 +01:00
Vasily
c8cb908004 Merge pull request #716 from Bond-009/warnings
Remove more compile time warnings
2019-01-29 19:32:08 +03:00
Vasily
8ab08dd041 Merge pull request #728 from nvllsvm/ffmpeg_docker
Use ffmpeg from jrottenberg/ffmpeg
2019-01-29 17:25:52 +03:00
Vasily
8487319374 Merge pull request #726 from EraYaN/remove-wrappers-for-system-io
Clean up IFileSystem wrappers around stdlib.
2019-01-29 16:50:01 +03:00
Vasily
91e99effc9 Apply suggestions from code review for flipped conditions.
Co-Authored-By: EraYaN <EraYaN@users.noreply.github.com>
2019-01-29 14:45:07 +01:00
Vasily
0e2e731103 Merge pull request #758 from RazeLighter777/master
Add password field to initial setup
2019-01-29 16:11:44 +03:00
Vasily
6822975fd3 Merge pull request #757 from cvium/fix_aspect_ratio_for_real
Fix default aspect ratio
2019-01-29 16:10:51 +03:00
Justin Suess
12e4c1c7ae Added RazeLighter777 to the contributors file 2019-01-28 20:11:46 -06:00
Justin Suess
6786dfcabd Made password field non-mandatory upon setup 2019-01-28 17:37:20 -06:00
Justin Suess
f06b9a14f3 Added password as an API field to the Startup/User Service 2019-01-28 17:25:37 -06:00
Erwin de Haan
838541b825 Removed loose whitespace and one .ToArray() call. 2019-01-28 22:21:14 +01:00
Erwin de Haan
1d1d7e8a37 Fixed inlining local-variable artifact. 2019-01-28 22:10:52 +01:00
Erwin de Haan
d3afa53191 Final refactored IFileSystem and ManagedFileSystem 2019-01-28 22:10:52 +01:00
Erwin de Haan
450f246f95 Unwrapped GetFileNameWithoutExtension 2019-01-28 22:10:51 +01:00
Erwin de Haan
b9a111432a Unwrapped all /(Write|Read)All(Text|Bytes)/ functions. 2019-01-28 22:10:50 +01:00
Erwin de Haan
581a7fe078 Unwrapped MoveDirectory, DirectoryExists, FileExists & removed MoveFile 2019-01-28 22:10:00 +01:00
Erwin de Haan
a430568082 Unwrapped OpenRead and CopyFile 2019-01-28 22:09:58 +01:00
Erwin de Haan
d7c6d16250 Unwrapped CreateDirectory and DeleteDirectory 2019-01-28 22:09:56 +01:00
Erwin de Haan
3a831994f6 Unwrapped GetDirectoryName and DirectorySeperatorChar 2019-01-28 22:06:34 +01:00
Claus Vium
dc68d61491 Fix default aspect ratio 2019-01-28 21:55:44 +01:00
Claus Vium
a05d803d4c Fix crash when trying to deserialize a non-existing scheduled task 2019-01-27 21:09:40 +01:00
Andrew Rabert
b4893b9ac9 Merge pull request #740 from Bond-009/deadcode
Remove code for pre-installed plugins & properly check if file exists
2019-01-27 14:04:39 -05:00
Andrew Rabert
b0608d26b4 Merge pull request #739 from cvium/change_multi_version_movie
Change multi version logic for movies
2019-01-27 12:19:58 -05:00
Andrew Rabert
67b1f9f716 Merge pull request #737 from EraYaN/skia-assembyinfo
Add AssemblyInfo for Jellyfin.Drawing.Skia
2019-01-27 11:52:31 -05:00
Erwin de Haan
39195aae09 Make guidance in issue templates comments, this will declutter issues when people do not remove it. 2019-01-27 17:24:02 +01:00
Erwin de Haan
cc598a86f1 Make guidance in PR template comments, this way we don't get so people just leaving it there. 2019-01-27 17:24:02 +01:00
Bond_009
ffe79c8982 Check if file exists instead of catching exceptions 2019-01-27 17:00:17 +01:00
Claus Vium
05ad2e9b3f Add Year to the new VideoInfo 2019-01-27 16:50:17 +01:00
Claus Vium
42abb5a993 Remove unnecessary ToList 2019-01-27 16:37:12 +01:00
Claus Vium
a4055779f6 Change multi version logic for movies 2019-01-27 16:27:18 +01:00
Bond_009
1a3543e5a5 Remove code for pre-installed plugins 2019-01-27 16:16:37 +01:00
Erwin de Haan
42e0b32c7d Added AssemblyInfo for Jellyfin.Drawing.Skia 2019-01-27 16:08:51 +01:00
Bond_009
85a58fd655 Start startup tasks async 2019-01-27 15:40:37 +01:00
Bond_009
a709cbdc64 Fix more analyzer warnings 2019-01-27 12:12:44 +01:00
Bond_009
08b63a7c11 Remove unused function
RunStartupTasks never executes because "startuptasks.txt" is never
created
2019-01-27 10:55:52 +01:00
Bond_009
51edd5d067 Reworked LocalizationManager to load data async 2019-01-27 10:36:05 +01:00
Luca Beltrame
ee89236fe8 [VA-API] Fix filter order (#714)
ffmpeg is very picky about the filters to be used when using VA-API,
because most of them are incompatible. This is particularly evident when
burning-in subtitles.
2019-01-27 09:44:56 +01:00
Erwin de Haan
fee42e883c Removed unnecessary unsafe keywords. 2019-01-27 09:26:10 +01:00
Andrew Rabert
cc3422b96b Use ffmpeg from jrottenberg/ffmpeg
Eventually would like to move to his 4.0-vaapi image
2019-01-26 21:16:43 -05:00
Andrew Rabert
50279be686 Merge pull request #727 from cvium/change_default_aspect
Change default aspect ratio to 2/3 from 0
2019-01-26 16:23:55 -05:00
Claus Vium
0e617933f6 Change default aspect ratio to 2/3 from 0 2019-01-26 22:19:14 +01:00
Andrew Rabert
f74bfcb343 Merge pull request #724 from Bond-009/skia
Move Skia back into it's own project
2019-01-26 16:03:16 -05:00
Claus Vium
64b6cfa3dc Add Size to TypedBaseItem 2019-01-26 21:59:06 +01:00
Bond_009
bb056f4b59 Cleanup 2019-01-26 21:10:19 +01:00
Bond_009
ce11869a1a Move Skia back into it's own project 2019-01-26 20:43:13 +01:00
Andrew Rabert
e3b19c22a7 Merge pull request #706 from sparky8251/docker-fix
Make another docker layer reusable
2019-01-26 14:23:41 -05:00
Andrew Rabert
05fd76c0fa Merge pull request #723 from Bond-009/dbperf
Minor improvements to db code
2019-01-26 14:21:31 -05:00
Andrew Rabert
7165868509 Merge pull request #709 from Bond-009/null
Fix always null expressions
2019-01-26 14:14:23 -05:00
Andrew Rabert
4190410c7e Merge pull request #710 from Bond-009/spelling
Fix a spelling mistake
2019-01-26 14:13:47 -05:00
Andrew Rabert
b673054c8d Merge pull request #711 from Bond-009/sysevent
Remove remnants of system events
2019-01-26 14:13:25 -05:00
Andrew Rabert
e051ca6ff6 Merge pull request #721 from Bond-009/imagedimensions
Change image dimentions from double to int
2019-01-26 14:12:40 -05:00
Bond_009
d8d6c6f254 Address comments 2019-01-26 19:46:30 +01:00
Bond_009
2ffab720fb Fix ctor 2019-01-26 18:36:38 +01:00
Bond_009
07f163a4c3 Minor improvements to db code 2019-01-26 18:21:41 +01:00
Bond_009
883575893b Change image dimentions from double to int
Rename ImageSize -> ImageDimensions
2019-01-26 13:16:47 +01:00
Erwin de Haan
d1a0497f55 Revert "Merge pull request #452 from Bond-009/activitydb"
This reverts commit 48ad18d12b, reversing
changes made to fe197415ca.
2019-01-25 23:32:06 +01:00
Bond_009
ded9dee22c Remove more compile time warnings 2019-01-25 23:05:01 +01:00
Erwin de Haan
e8f6a61131 Fix empty statement in DidlBuilder.cs 2019-01-25 22:51:34 +01:00
Bond_009
fd7f420af2 Remove remnants of system events 2019-01-25 22:41:43 +01:00
Bond_009
eaa6cb0ddc Fix a spelling mistake 2019-01-25 22:27:33 +01:00
Bond_009
8af256f9c2 Fix always null expressions 2019-01-25 21:52:10 +01:00
Sparky
9f83ee7b3e Make another docker layer reusable
By moving the apt-get layer before the copies, the apt-get layer can be reused with each build, reducing upload/download needed during updates.

Just a small optimization.
2019-01-25 13:27:12 -05:00
834 changed files with 15513 additions and 36500 deletions

192
.ci/azure-pipelines.yml Normal file
View File

@@ -0,0 +1,192 @@
name: $(Date:yyyyMMdd)$(Rev:.r)
variables:
- name: TestProjects
value: 'Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj'
- name: RestoreBuildProjects
value: 'Jellyfin.Server/Jellyfin.Server.csproj'
pr:
autoCancel: true
trigger:
batch: true
jobs:
- job: main_build
displayName: Main Build
pool:
vmImage: ubuntu-16.04
strategy:
matrix:
release:
BuildConfiguration: Release
debug:
BuildConfiguration: Debug
maxParallel: 2
steps:
- checkout: self
clean: true
submodules: true
persistCredentials: false
- task: DotNetCoreCLI@2
displayName: Restore
inputs:
command: restore
projects: '$(RestoreBuildProjects)'
- task: DotNetCoreCLI@2
displayName: Build
inputs:
projects: '$(RestoreBuildProjects)'
arguments: '--configuration $(BuildConfiguration)'
- task: DotNetCoreCLI@2
displayName: Test
inputs:
command: test
projects: '$(RestoreBuildProjects)'
arguments: '--configuration $(BuildConfiguration)'
enabled: false
- task: DotNetCoreCLI@2
displayName: Publish
inputs:
command: publish
publishWebProjects: false
projects: '$(RestoreBuildProjects)'
arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'
zipAfterPublish: false
# - task: PublishBuildArtifacts@1
# displayName: 'Publish Artifact'
# inputs:
# PathtoPublish: '$(build.artifactstagingdirectory)'
# artifactName: 'jellyfin-build-$(BuildConfiguration)'
# zipAfterPublish: true
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact Naming'
condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)/Jellyfin.Server/Emby.Naming.dll'
artifactName: 'Jellyfin.Naming'
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact Controller'
condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Controller.dll'
artifactName: 'Jellyfin.Controller'
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact Model'
condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Model.dll'
artifactName: 'Jellyfin.Model'
- task: PublishBuildArtifacts@1
displayName: 'Publish Artifact Common'
condition: and(eq(variables['BuildConfiguration'], 'Release'), succeeded())
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)/Jellyfin.Server/MediaBrowser.Common.dll'
artifactName: 'Jellyfin.Common'
- job: dotnet_compat
displayName: Compatibility Check
pool:
vmImage: ubuntu-16.04
dependsOn: main_build
condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber']) # Only execute if the pullrequest numer is defined. (So not for normal CI builds)
strategy:
matrix:
Naming:
NugetPackageName: Jellyfin.Naming
AssemblyFileName: Emby.Naming.dll
Controller:
NugetPackageName: Jellyfin.Controller
AssemblyFileName: MediaBrowser.Controller.dll
Model:
NugetPackageName: Jellyfin.Model
AssemblyFileName: MediaBrowser.Model.dll
Common:
NugetPackageName: Jellyfin.Common
AssemblyFileName: MediaBrowser.Common.dll
maxParallel: 2
steps:
- checkout: none
- task: DownloadBuildArtifacts@0
displayName: Download the Reference Assembly Build Artifact
inputs:
buildType: 'specific' # Options: current, specific
project: $(System.TeamProjectId) # Required when buildType == Specific
pipeline: $(System.DefinitionId) # Required when buildType == Specific, not sure if this will take a name too
#specificBuildWithTriggering: false # Optional
buildVersionToDownload: 'latestFromBranch' # Required when buildType == Specific# Options: latest, latestFromBranch, specific
allowPartiallySucceededBuilds: false # Optional
branchName: '$(System.PullRequest.TargetBranch)' # Required when buildType == Specific && BuildVersionToDownload == LatestFromBranch
#buildId: # Required when buildType == Specific && BuildVersionToDownload == Specific
#tags: # Optional
downloadType: 'single' # Options: single, specific
artifactName: '$(NugetPackageName)'# Required when downloadType == Single
#itemPattern: '**' # Optional
downloadPath: '$(System.ArtifactsDirectory)/current-artifacts'
#parallelizationLimit: '8' # Optional
- task: CopyFiles@2
displayName: Copy Nuget Assembly to current-release folder
inputs:
sourceFolder: $(System.ArtifactsDirectory)/current-artifacts # Optional
contents: '**/*.dll'
targetFolder: $(System.ArtifactsDirectory)/current-release
cleanTargetFolder: true # Optional
overWrite: true # Optional
flattenFolders: true # Optional
- task: DownloadBuildArtifacts@0
displayName: Download the New Assembly Build Artifact
inputs:
buildType: 'current' # Options: current, specific
allowPartiallySucceededBuilds: false # Optional
downloadType: 'single' # Options: single, specific
artifactName: '$(NugetPackageName)' # Required when downloadType == Single
downloadPath: '$(System.ArtifactsDirectory)/new-artifacts'
- task: CopyFiles@2
displayName: Copy Artifact Assembly to new-release folder
inputs:
sourceFolder: $(System.ArtifactsDirectory)/new-artifacts # Optional
contents: '**/*.dll'
targetFolder: $(System.ArtifactsDirectory)/new-release
cleanTargetFolder: true # Optional
overWrite: true # Optional
flattenFolders: true # Optional
- task: DownloadGitHubRelease@0
displayName: Download ABI compatibility check tool from GitHub
inputs:
connection: Jellyfin GitHub
userRepository: EraYaN/dotnet-compatibility
defaultVersionType: 'latest' # Options: latest, specificVersion, specificTag
#version: # Required when defaultVersionType != Latest
itemPattern: '**-ci.zip' # Optional
downloadPath: '$(System.ArtifactsDirectory)'
- task: ExtractFiles@1
displayName: Extract ABI compatibility check tool
inputs:
archiveFilePatterns: '$(System.ArtifactsDirectory)/*-ci.zip'
destinationFolder: $(System.ArtifactsDirectory)/tools
cleanDestinationFolder: true
- task: CmdLine@2
displayName: Execute ABI compatibility check tool
inputs:
script: 'dotnet tools/CompatibilityCheckerCoreCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName)'
workingDirectory: $(System.ArtifactsDirectory) # Optional
#failOnStderr: false # Optional

8
.copr/Makefile Normal file
View File

@@ -0,0 +1,8 @@
srpm:
dnf -y install git
git submodule update --init --recursive
cd deployment/fedora-package-x64; \
./create_tarball.sh; \
rpmbuild -bs pkg-src/jellyfin.spec \
--define "_sourcedir $$PWD/pkg-src/" \
--define "_srcrpmdir $(outdir)"

View File

@@ -8,3 +8,4 @@ README.md
deployment/*/dist
deployment/*/pkg-dist
deployment/collect-dist/
ci/

View File

@@ -1,12 +1,30 @@
---
kind: pipeline
name: build
name: build-debug
steps:
- name: submodules
image: docker:git
commands:
- git submodule update --init --recursive
- name: build
image: microsoft/dotnet:2-sdk
commands:
- dotnet publish --configuration release --output /release Jellyfin.Server
- dotnet publish "Jellyfin.Server" --configuration Debug --output "../ci/ci-debug"
---
kind: pipeline
name: build-release
steps:
- name: submodules
image: docker:git
commands:
- git submodule update --init --recursive
- name: build
image: microsoft/dotnet:2-sdk
commands:
- dotnet publish "Jellyfin.Server" --configuration Release --output "../ci/ci-release"

View File

@@ -15,6 +15,10 @@ insert_final_newline = true
end_of_line = lf
max_line_length = null
# YAML indentation
[*.{yml,yaml}]
indent_size = 2
# XML indentation
[*.{csproj,xml}]
indent_size = 2
@@ -55,15 +59,77 @@ dotnet_style_prefer_conditional_expression_over_return = true:silent
###############################
# Naming Conventions #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Use PascalCase for constant fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
dotnet_naming_symbols.constant_fields.required_modifiers = const
# Style Definitions (From Roslyn)
# Non-private static fields are PascalCase
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected internal, private protected
dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
# Constants are PascalCase
dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants
dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style
dotnet_naming_symbols.constants.applicable_kinds = field, local
dotnet_naming_symbols.constants.required_modifiers = const
dotnet_naming_style.constant_style.capitalization = pascal_case
# Static fields are camelCase and start with s_
dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields
dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_style.static_field_style.capitalization = camel_case
dotnet_naming_style.static_field_style.required_prefix = _
# Instance fields are camelCase and start with _
dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields
dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style
dotnet_naming_symbols.instance_fields.applicable_kinds = field
dotnet_naming_style.instance_field_style.capitalization = camel_case
dotnet_naming_style.instance_field_style.required_prefix = _
# Locals and parameters are camelCase
dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion
dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters
dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style
dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local
dotnet_naming_style.camel_case_style.capitalization = camel_case
# Local functions are PascalCase
dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions
dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
dotnet_naming_style.local_function_style.capitalization = pascal_case
# By default, name items with PascalCase
dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members
dotnet_naming_rule.members_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.all_members.applicable_kinds = *
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
###############################
# C# Coding Conventions #
###############################

View File

@@ -8,28 +8,29 @@ assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
<!-- A clear and concise description of what the bug is. -->
**To Reproduce**
Steps to reproduce the behavior:
<!-- Steps to reproduce the behavior: -->
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
<!-- A clear and concise description of what you expected to happen. -->
**Logs**
Please paste any log errors.
<!-- Please paste any log errors. -->
**Screenshots**
If applicable, add screenshots to help explain your problem.
<!-- If applicable, add screenshots to help explain your problem. -->
**System (please complete the following information):**
- OS: [e.g. Docker, Debian, Windows]
- Browser: [e.g. Firefox, Chrome, Safari]
- Jellyfin Version: [e.g. 10.0.1]
- Reverse proxy: [e.g. no, nginx, apache, etc.]
**Additional context**
Add any other context about the problem here.
<!-- Add any other context about the problem here. -->

View File

@@ -8,13 +8,13 @@ assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
Add any other context or screenshots about the feature request here.
<!-- Add any other context or screenshots about the feature request here. -->

View File

@@ -8,7 +8,7 @@ assignees: ''
---
**Describe the feature you'd like**
A clear and concise description of what you want to happen.
<!-- A clear and concise description of what you want to happen. -->
**Additional context**
Add any other context or screenshots about the feature request here.
<!-- Add any other context or screenshots about the feature request here. -->

View File

@@ -1,9 +1,11 @@
<!--
Ensure your title is short, descriptive, and in the imperative mood (Fix X, Change Y, instead of Fixed X, Changed Y).
For a good inspiration of what to write in commit messages and PRs please review https://chris.beams.io/posts/git-commit/ and our https://jellyfin.readthedocs.io/en/latest/developer-docs/contributing/ page.
-->
**Changes**
Describe your changes here in 1-5 sentences.
<!-- Describe your changes here in 1-5 sentences. -->
**Issues**
Tag any issues that this PR solves here.
Fixes #
<!-- Tag any issues that this PR solves here.
ex. Fixes # -->

5
.gitignore vendored
View File

@@ -264,3 +264,8 @@ deployment/**/pkg-dist-tmp/
deployment/collect-dist/
jellyfin_version.ini
ci/
# Doxygen
doc/

1
.gitmodules vendored
View File

@@ -1,3 +1,4 @@
[submodule "MediaBrowser.WebDashboard/jellyfin-web"]
path = MediaBrowser.WebDashboard/jellyfin-web
url = https://github.com/jellyfin/jellyfin-web.git
branch = .

View File

@@ -92,7 +92,7 @@ namespace BDInfo
}
DirectoryRoot =
_fileSystem.GetDirectoryInfo(_fileSystem.GetDirectoryName(DirectoryBDMV.FullName));
_fileSystem.GetDirectoryInfo(Path.GetDirectoryName(DirectoryBDMV.FullName));
DirectoryBDJO =
GetDirectory("BDJO", DirectoryBDMV, 0);
DirectoryCLIPINF =
@@ -150,7 +150,7 @@ namespace BDInfo
Is3D = true;
}
if (_fileSystem.FileExists(Path.Combine(DirectoryRoot.FullName, "FilmIndex.xml")))
if (File.Exists(Path.Combine(DirectoryRoot.FullName, "FilmIndex.xml")))
{
IsDBOX = true;
}
@@ -165,7 +165,7 @@ namespace BDInfo
foreach (var file in files)
{
PlaylistFiles.Add(
file.Name.ToUpper(), new TSPlaylistFile(this, file, _fileSystem));
file.Name.ToUpper(), new TSPlaylistFile(this, file));
}
}
@@ -185,7 +185,7 @@ namespace BDInfo
foreach (var file in files)
{
StreamClipFiles.Add(
file.Name.ToUpper(), new TSStreamClipFile(file, _fileSystem));
file.Name.ToUpper(), new TSStreamClipFile(file));
}
}
@@ -345,7 +345,7 @@ namespace BDInfo
{
return dir;
}
var parentFolder = _fileSystem.GetDirectoryName(dir.FullName);
var parentFolder = Path.GetDirectoryName(dir.FullName);
if (string.IsNullOrEmpty(parentFolder))
{
dir = null;

View File

@@ -9,8 +9,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2016 CinemaSquid. Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2016 CinemaSquid. Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -1,4 +1,4 @@
//============================================================================
//============================================================================
// BDInfo - Blu-ray Video and Audio Analysis Tool
// Copyright © 2010 Cinema Squid
//
@@ -28,7 +28,6 @@ namespace BDInfo
{
public class TSPlaylistFile
{
private readonly IFileSystem _fileSystem;
private FileSystemMetadata FileInfo = null;
public string FileType = null;
public bool IsInitialized = false;
@@ -64,21 +63,19 @@ namespace BDInfo
new List<TSGraphicsStream>();
public TSPlaylistFile(BDROM bdrom,
FileSystemMetadata fileInfo, IFileSystem fileSystem)
FileSystemMetadata fileInfo)
{
BDROM = bdrom;
FileInfo = fileInfo;
_fileSystem = fileSystem;
Name = fileInfo.Name.ToUpper();
}
public TSPlaylistFile(BDROM bdrom,
string name,
List<TSStreamClip> clips, IFileSystem fileSystem)
List<TSStreamClip> clips)
{
BDROM = bdrom;
Name = name;
_fileSystem = fileSystem;
IsCustom = true;
foreach (var clip in clips)
{
@@ -231,7 +228,7 @@ namespace BDInfo
Streams.Clear();
StreamClips.Clear();
fileStream = _fileSystem.OpenRead(FileInfo.FullName);
fileStream = File.OpenRead(FileInfo.FullName);
fileReader = new BinaryReader(fileStream);
byte[] data = new byte[fileStream.Length];

View File

@@ -1,4 +1,4 @@
//============================================================================
//============================================================================
// BDInfo - Blu-ray Video and Audio Analysis Tool
// Copyright © 2010 Cinema Squid
//
@@ -28,7 +28,6 @@ namespace BDInfo
{
public class TSStreamClipFile
{
private readonly IFileSystem _fileSystem;
public FileSystemMetadata FileInfo = null;
public string FileType = null;
public bool IsValid = false;
@@ -37,10 +36,9 @@ namespace BDInfo
public Dictionary<ushort, TSStream> Streams =
new Dictionary<ushort, TSStream>();
public TSStreamClipFile(FileSystemMetadata fileInfo, IFileSystem fileSystem)
public TSStreamClipFile(FileSystemMetadata fileInfo)
{
FileInfo = fileInfo;
_fileSystem = fileSystem;
Name = fileInfo.Name.ToUpper();
}
@@ -57,7 +55,7 @@ namespace BDInfo
#endif
Streams.Clear();
fileStream = _fileSystem.OpenRead(FileInfo.FullName);
fileStream = File.OpenRead(FileInfo.FullName);
fileReader = new BinaryReader(fileStream);
byte[] data = new byte[fileStream.Length];

View File

@@ -15,7 +15,15 @@
- [cvium](https://github.com/cvium)
- [wtayl0r](https://github.com/wtayl0r)
- [TtheCreator](https://github.com/Tthecreator)
- [dkanada](https://github.com/dkanada)
- [LogicalPhallacy](https://github.com/LogicalPhallacy/)
- [RazeLighter777](https://github.com/RazeLighter777)
- [WillWill56](https://github.com/WillWill56)
- [Liggy](https://github.com/Liggy)
- [fruhnow](https://github.com/fruhnow)
- [Lynxy](https://github.com/Lynxy)
- [fasheng](https://github.com/fasheng)
- [ploughpuff](https://github.com/ploughpuff)
# Emby Contributors

View File

@@ -1,37 +1,34 @@
ARG DOTNET_VERSION=2
ARG DOTNET_VERSION=2.2
# Download ffmpeg first to allow quicker rebuild of other layers
FROM alpine as ffmpeg
ARG FFMPEG_URL=https://www.johnvansickle.com/ffmpeg/old-releases/ffmpeg-4.0.3-64bit-static.tar.xz
RUN wget ${FFMPEG_URL} -O - | tar Jxf - \
&& mkdir ffmpeg-bin \
&& mv ffmpeg*/ffmpeg ffmpeg-bin \
&& mv ffmpeg*/ffprobe ffmpeg-bin
FROM microsoft/dotnet:${DOTNET_VERSION}-sdk as builder
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \
&& dotnet clean \
&& dotnet publish \
--configuration release \
--output /jellyfin \
Jellyfin.Server
FROM microsoft/dotnet:${DOTNET_VERSION}-runtime
COPY --from=builder /jellyfin /jellyfin
COPY --from=ffmpeg /ffmpeg-bin/* /usr/bin/
EXPOSE 8096
VOLUME /config /media
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-x64 /jellyfin"
FROM jellyfin/ffmpeg as ffmpeg
FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}
# libfontconfig1 is required for Skia
RUN apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
libfontconfig1 \
&& apt-get clean autoclean \
&& apt-get autoremove \
&& rm -rf /var/lib/{apt,dpkg,cache,log}
ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
COPY --from=ffmpeg / /
COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.3
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
EXPOSE 8096
VOLUME /cache /config /media
ENTRYPOINT dotnet /jellyfin/jellyfin.dll \
--datadir /config \
--cachedir /cache \
--ffmpeg /usr/local/bin/ffmpeg

View File

@@ -1,24 +1,43 @@
# Requires binfm_misc registration
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
ARG DOTNET_VERSION=3.0
FROM microsoft/dotnet:${DOTNET_VERSION}-sdk-stretch-arm32v7 as builder
FROM multiarch/qemu-user-static:x86_64-arm as qemu
FROM alpine as qemu_extract
COPY --from=qemu /usr/bin qemu-arm-static.tar.gz
RUN tar -xzvf qemu-arm-static.tar.gz
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
#TODO Remove or update the sed line when we update dotnet version.
RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \
&& find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \
&& dotnet clean -maxcpucount:1 \
&& dotnet publish \
-maxcpucount:1 \
--configuration release \
--output /jellyfin \
Jellyfin.Server
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# TODO Remove or update the sed line when we update dotnet version.
RUN find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \;
# Discard objs - may cause failures if exists
RUN find . -type d -name obj | xargs -r rm -r
# Build
RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-arm /jellyfin"
FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm32v7
COPY --from=builder /jellyfin /jellyfin
EXPOSE 8096
FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}-stretch-slim-arm32v7
COPY --from=qemu_extract qemu-arm-static /usr/bin
RUN apt-get update \
&& apt-get install -y ffmpeg
VOLUME /config /media
ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.3
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
EXPOSE 8096
VOLUME /cache /config /media
ENTRYPOINT dotnet /jellyfin/jellyfin.dll \
--datadir /config \
--cachedir /cache \
--ffmpeg /usr/bin/ffmpeg

View File

@@ -1,33 +1,44 @@
# Requires binfm_misc registration for aarch64
# Requires binfm_misc registration
# https://github.com/multiarch/qemu-user-static#binfmt_misc-register
ARG DOTNET_VERSION=3.0
FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu
FROM alpine as qemu_extract
COPY --from=qemu /usr/bin qemu_user_static.tgz
RUN tar -xzvf qemu_user_static.tgz
COPY --from=qemu /usr/bin qemu-aarch64-static.tar.gz
RUN tar -xzvf qemu-aarch64-static.tar.gz
FROM microsoft/dotnet:${DOTNET_VERSION}-sdk-stretch-arm64v8 as builder
COPY --from=qemu_extract qemu-* /usr/bin
FROM mcr.microsoft.com/dotnet/core/sdk:${DOTNET_VERSION} as builder
WORKDIR /repo
COPY . .
#TODO Remove or update the sed line when we update dotnet version.
RUN export DOTNET_CLI_TELEMETRY_OPTOUT=1 \
&& find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \; \
&& dotnet clean \
&& dotnet publish \
--configuration release \
--output /jellyfin \
Jellyfin.Server
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
# TODO Remove or update the sed line when we update dotnet version.
RUN find . -type f -exec sed -i 's/netcoreapp2.1/netcoreapp3.0/g' {} \;
# Discard objs - may cause failures if exists
RUN find . -type d -name obj | xargs -r rm -r
# Build
RUN bash -c "source deployment/common.build.sh && \
build_jellyfin Jellyfin.Server Release linux-arm64 /jellyfin"
FROM microsoft/dotnet:${DOTNET_VERSION}-runtime-stretch-slim-arm64v8
COPY --from=qemu_extract qemu-* /usr/bin
COPY --from=builder /jellyfin /jellyfin
EXPOSE 8096
FROM mcr.microsoft.com/dotnet/core/runtime:${DOTNET_VERSION}-stretch-slim-arm64v8
COPY --from=qemu_extract qemu-aarch64-static /usr/bin
RUN apt-get update \
&& apt-get install -y ffmpeg
VOLUME /config /media
ENTRYPOINT dotnet /jellyfin/jellyfin.dll -programdata /config
&& apt-get install --no-install-recommends --no-install-suggests -y ffmpeg \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /cache /config /media \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
ARG JELLYFIN_WEB_VERSION=10.3.3
RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
&& mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
EXPOSE 8096
VOLUME /cache /config /media
ENTRYPOINT dotnet /jellyfin/jellyfin.dll \
--datadir /config \
--cachedir /cache \
--ffmpeg /usr/bin/ffmpeg

2565
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +0,0 @@
namespace DvdLib.Ifo
{
public enum AudioCodec
{
AC3 = 0,
MPEG1 = 2,
MPEG2ext = 3,
LPCM = 4,
DTS = 6,
}
public enum ApplicationMode
{
Unspecified = 0,
Karaoke = 1,
Surround = 2,
}
public class AudioAttributes
{
public readonly AudioCodec Codec;
public readonly bool MultichannelExtensionPresent;
public readonly ApplicationMode Mode;
public readonly byte QuantDRC;
public readonly byte SampleRate;
public readonly byte Channels;
public readonly ushort LanguageCode;
public readonly byte LanguageExtension;
public readonly byte CodeExtension;
}
public class MultiChannelExtension
{
}
}

View File

@@ -26,17 +26,17 @@ namespace DvdLib.Ifo
if (vmgPath == null)
{
var allIfos = allFiles.Where(i => string.Equals(i.Extension, ".ifo", StringComparison.OrdinalIgnoreCase));
foreach (var ifo in allIfos)
foreach (var ifo in allFiles)
{
var num = ifo.Name.Split('_').ElementAtOrDefault(1);
var numbersRead = new List<ushort>();
if (!string.Equals(ifo.Extension, ".ifo", StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (!string.IsNullOrEmpty(num) && ushort.TryParse(num, out var ifoNumber) && !numbersRead.Contains(ifoNumber))
var nums = ifo.Name.Split(new [] { '_' }, StringSplitOptions.RemoveEmptyEntries);
if (nums.Length >= 2 && ushort.TryParse(nums[1], out var ifoNumber))
{
ReadVTS(ifoNumber, ifo.FullName);
numbersRead.Add(ifoNumber);
}
}
}
@@ -76,7 +76,7 @@ namespace DvdLib.Ifo
}
}
private void ReadVTS(ushort vtsNum, List<FileSystemMetadata> allFiles)
private void ReadVTS(ushort vtsNum, IEnumerable<FileSystemMetadata> allFiles)
{
var filename = string.Format("VTS_{0:00}_0.IFO", vtsNum);

View File

@@ -1,17 +0,0 @@
using System.Collections.Generic;
namespace DvdLib.Ifo
{
public class ProgramChainCommandTable
{
public readonly ushort LastByteAddress;
public readonly List<VirtualMachineCommand> PreCommands;
public readonly List<VirtualMachineCommand> PostCommands;
public readonly List<VirtualMachineCommand> CellCommands;
}
public class VirtualMachineCommand
{
public readonly byte[] Command;
}
}

View File

@@ -25,13 +25,10 @@ namespace DvdLib.Ifo
public byte[] SubpictureStreamControl { get; private set; } // 32*4 entries
private ushort _nextProgramNumber;
public readonly ProgramChain Next;
private ushort _prevProgramNumber;
public readonly ProgramChain Previous;
private ushort _goupProgramNumber;
public readonly ProgramChain Goup; // ?? maybe Group
public ProgramPlaybackMode PlaybackMode { get; private set; }
public uint ProgramCount { get; private set; }
@@ -40,7 +37,6 @@ namespace DvdLib.Ifo
public byte[] Palette { get; private set; } // 16*4 entries
private ushort _commandTableOffset;
public readonly ProgramChainCommandTable CommandTable;
private ushort _programMapOffset;
private ushort _cellPlaybackOffset;

View File

@@ -1,46 +0,0 @@
namespace DvdLib.Ifo
{
public enum VideoCodec
{
MPEG1 = 0,
MPEG2 = 1,
}
public enum VideoFormat
{
NTSC = 0,
PAL = 1,
}
public enum AspectRatio
{
ar4to3 = 0,
ar16to9 = 3
}
public enum FilmMode
{
None = -1,
Camera = 0,
Film = 1,
}
public class VideoAttributes
{
public readonly VideoCodec Codec;
public readonly VideoFormat Format;
public readonly AspectRatio Aspect;
public readonly bool AutomaticPanScan;
public readonly bool AutomaticLetterBox;
public readonly bool Line21CCField1;
public readonly bool Line21CCField2;
public readonly int Width;
public readonly int Height;
public readonly bool Letterboxed;
public readonly FilmMode FilmMode;
public VideoAttributes()
{
}
}
}

View File

@@ -9,8 +9,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -136,7 +136,7 @@ namespace Emby.Dlna.Api
{
var url = Request.AbsoluteUri;
var serverAddress = url.Substring(0, url.IndexOf("/dlna/", StringComparison.OrdinalIgnoreCase));
var xml = _dlnaManager.GetServerDescriptionXml(Request.Headers.ToDictionary(), request.UuId, serverAddress);
var xml = _dlnaManager.GetServerDescriptionXml(Request.Headers, request.UuId, serverAddress);
var cacheLength = TimeSpan.FromDays(1);
var cacheKey = Request.RawUrl.GetMD5();
@@ -147,21 +147,21 @@ namespace Emby.Dlna.Api
public object Get(GetContentDirectory request)
{
var xml = ContentDirectory.GetServiceXml(Request.Headers.ToDictionary());
var xml = ContentDirectory.GetServiceXml();
return _resultFactory.GetResult(Request, xml, XMLContentType);
}
public object Get(GetMediaReceiverRegistrar request)
{
var xml = MediaReceiverRegistrar.GetServiceXml(Request.Headers.ToDictionary());
var xml = MediaReceiverRegistrar.GetServiceXml();
return _resultFactory.GetResult(Request, xml, XMLContentType);
}
public object Get(GetConnnectionManager request)
{
var xml = ConnectionManager.GetServiceXml(Request.Headers.ToDictionary());
var xml = ConnectionManager.GetServiceXml();
return _resultFactory.GetResult(Request, xml, XMLContentType);
}
@@ -193,7 +193,7 @@ namespace Emby.Dlna.Api
return service.ProcessControlRequest(new ControlRequest
{
Headers = Request.Headers.ToDictionary(),
Headers = Request.Headers,
InputXml = requestStream,
TargetServerUuId = id,
RequestedUrl = Request.AbsoluteUri
@@ -236,7 +236,9 @@ namespace Emby.Dlna.Api
public object Get(GetIcon request)
{
var contentType = "image/" + Path.GetExtension(request.Filename).TrimStart('.').ToLower();
var contentType = "image/" + Path.GetExtension(request.Filename)
.TrimStart('.')
.ToLowerInvariant();
var cacheLength = TimeSpan.FromDays(365);
var cacheKey = Request.RawUrl.GetMD5();

View File

@@ -7,6 +7,7 @@ namespace Emby.Dlna.Configuration
public bool EnableServer { get; set; }
public bool EnableDebugLog { get; set; }
public bool BlastAliveMessages { get; set; }
public bool SendOnlyMatchedHost { get; set; }
public int ClientDiscoveryIntervalSeconds { get; set; }
public int BlastAliveMessageIntervalSeconds { get; set; }
public string DefaultUserId { get; set; }
@@ -16,6 +17,7 @@ namespace Emby.Dlna.Configuration
EnablePlayTo = true;
EnableServer = true;
BlastAliveMessages = true;
SendOnlyMatchedHost = true;
ClientDiscoveryIntervalSeconds = 60;
BlastAliveMessageIntervalSeconds = 1800;
}

View File

@@ -1,9 +1,7 @@
using System.Collections.Generic;
using Emby.Dlna.Service;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.ConnectionManager
@@ -13,18 +11,16 @@ namespace Emby.Dlna.ConnectionManager
private readonly IDlnaManager _dlna;
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
public ConnectionManager(IDlnaManager dlna, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
public ConnectionManager(IDlnaManager dlna, IServerConfigurationManager config, ILogger logger, IHttpClient httpClient)
: base(logger, httpClient)
{
_dlna = dlna;
_config = config;
_logger = logger;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
public string GetServiceXml(IDictionary<string, string> headers)
public string GetServiceXml()
{
return new ConnectionManagerXmlBuilder().GetXml();
}
@@ -34,7 +30,7 @@ namespace Emby.Dlna.ConnectionManager
var profile = _dlna.GetProfile(request.Headers) ??
_dlna.GetDefaultProfile();
return new ControlHandler(_config, _logger, XmlReaderSettingsFactory, profile).ProcessControlRequest(request);
return new ControlHandler(_config, _logger, profile).ProcessControlRequest(request);
}
}
}

View File

@@ -4,7 +4,6 @@ using Emby.Dlna.Service;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.ConnectionManager
@@ -32,7 +31,8 @@ namespace Emby.Dlna.ConnectionManager
};
}
public ControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory, DeviceProfile profile) : base(config, logger, xmlReaderSettingsFactory)
public ControlHandler(IServerConfigurationManager config, ILogger logger, DeviceProfile profile)
: base(config, logger)
{
_profile = profile;
}

View File

@@ -11,7 +11,6 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.ContentDirectory
@@ -28,7 +27,6 @@ namespace Emby.Dlna.ContentDirectory
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IUserViewManager _userViewManager;
private readonly IMediaEncoder _mediaEncoder;
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
private readonly ITVSeriesManager _tvSeriesManager;
public ContentDirectory(IDlnaManager dlna,
@@ -38,7 +36,12 @@ namespace Emby.Dlna.ContentDirectory
IServerConfigurationManager config,
IUserManager userManager,
ILogger logger,
IHttpClient httpClient, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory, ITVSeriesManager tvSeriesManager)
IHttpClient httpClient,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
IUserViewManager userViewManager,
IMediaEncoder mediaEncoder,
ITVSeriesManager tvSeriesManager)
: base(logger, httpClient)
{
_dlna = dlna;
@@ -51,7 +54,6 @@ namespace Emby.Dlna.ContentDirectory
_mediaSourceManager = mediaSourceManager;
_userViewManager = userViewManager;
_mediaEncoder = mediaEncoder;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
_tvSeriesManager = tvSeriesManager;
}
@@ -65,7 +67,7 @@ namespace Emby.Dlna.ContentDirectory
}
}
public string GetServiceXml(IDictionary<string, string> headers)
public string GetServiceXml()
{
return new ContentDirectoryXmlBuilder().GetXml();
}
@@ -76,7 +78,6 @@ namespace Emby.Dlna.ContentDirectory
_dlna.GetDefaultProfile();
var serverAddress = request.RequestedUrl.Substring(0, request.RequestedUrl.IndexOf("/dlna", StringComparison.OrdinalIgnoreCase));
string accessToken = null;
var user = GetUser(profile);
@@ -85,7 +86,7 @@ namespace Emby.Dlna.ContentDirectory
_libraryManager,
profile,
serverAddress,
accessToken,
null,
_imageProcessor,
_userDataManager,
user,
@@ -95,7 +96,6 @@ namespace Emby.Dlna.ContentDirectory
_mediaSourceManager,
_userViewManager,
_mediaEncoder,
XmlReaderSettingsFactory,
_tvSeriesManager)
.ProcessControlRequest(request);
}

View File

@@ -25,7 +25,6 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.ContentDirectory
@@ -51,8 +50,22 @@ namespace Emby.Dlna.ContentDirectory
private readonly DeviceProfile _profile;
public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, string accessToken, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IUserViewManager userViewManager, IMediaEncoder mediaEncoder, IXmlReaderSettingsFactory xmlReaderSettingsFactory, ITVSeriesManager tvSeriesManager)
: base(config, logger, xmlReaderSettingsFactory)
public ControlHandler(
ILogger logger,
ILibraryManager libraryManager,
DeviceProfile profile,
string serverAddress,
string accessToken,
IImageProcessor imageProcessor,
IUserDataManager userDataManager,
User user, int systemUpdateId,
IServerConfigurationManager config,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
IUserViewManager userViewManager,
IMediaEncoder mediaEncoder,
ITVSeriesManager tvSeriesManager)
: base(config, logger)
{
_libraryManager = libraryManager;
_userDataManager = userDataManager;
@@ -63,7 +76,7 @@ namespace Emby.Dlna.ContentDirectory
_profile = profile;
_config = config;
_didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, _logger, libraryManager, mediaEncoder);
_didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, accessToken, userDataManager, localization, mediaSourceManager, _logger, mediaEncoder);
}
protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, IDictionary<string, string> methodParams)
@@ -260,7 +273,7 @@ namespace Emby.Dlna.ContentDirectory
if (item.IsDisplayedAsFolder || serverItem.StubType.HasValue)
{
var childrenResult = (GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount));
var childrenResult = GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount);
_didlBuilder.WriteFolderElement(writer, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id);
}
@@ -273,7 +286,7 @@ namespace Emby.Dlna.ContentDirectory
}
else
{
var childrenResult = (GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount));
var childrenResult = GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requestedCount);
totalCount = childrenResult.TotalRecordCount;
provided = childrenResult.Items.Length;
@@ -454,7 +467,7 @@ namespace Emby.Dlna.ContentDirectory
User = user,
Recursive = true,
IsMissing = false,
ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
ExcludeItemTypes = new[] { typeof(Book).Name },
IsFolder = isFolder,
MediaTypes = mediaTypes.ToArray(),
DtoOptions = GetDtoOptions()
@@ -483,27 +496,26 @@ namespace Emby.Dlna.ContentDirectory
return GetGenreItems(item, Guid.Empty, user, sort, startIndex, limit);
}
if (!stubType.HasValue || stubType.Value != StubType.Folder)
if ((!stubType.HasValue || stubType.Value != StubType.Folder)
&& item is IHasCollectionType collectionFolder)
{
var collectionFolder = item as IHasCollectionType;
if (collectionFolder != null && string.Equals(CollectionType.Music, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
if (string.Equals(CollectionType.Music, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
{
return GetMusicFolders(item, user, stubType, sort, startIndex, limit);
}
if (collectionFolder != null && string.Equals(CollectionType.Movies, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
else if (string.Equals(CollectionType.Movies, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
{
return GetMovieFolders(item, user, stubType, sort, startIndex, limit);
}
if (collectionFolder != null && string.Equals(CollectionType.TvShows, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
else if (string.Equals(CollectionType.TvShows, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
{
return GetTvFolders(item, user, stubType, sort, startIndex, limit);
}
if (collectionFolder != null && string.Equals(CollectionType.Folders, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
else if (string.Equals(CollectionType.Folders, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
{
return GetFolders(item, user, stubType, sort, startIndex, limit);
}
if (collectionFolder != null && string.Equals(CollectionType.LiveTv, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
else if (string.Equals(CollectionType.LiveTv, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase))
{
return GetLiveTvChannels(item, user, stubType, sort, startIndex, limit);
}
@@ -524,7 +536,7 @@ namespace Emby.Dlna.ContentDirectory
Limit = limit,
StartIndex = startIndex,
IsVirtualItem = false,
ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
ExcludeItemTypes = new[] { typeof(Book).Name },
IsPlaceHolder = false,
DtoOptions = GetDtoOptions()
};

View File

@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Http;
namespace Emby.Dlna
{
public class ControlRequest
{
public IDictionary<string, string> Headers { get; set; }
public IHeaderDictionary Headers { get; set; }
public Stream InputXml { get; set; }
@@ -15,7 +15,7 @@ namespace Emby.Dlna
public ControlRequest()
{
Headers = new Dictionary<string, string>();
Headers = new HeaderDictionary();
}
}
}

View File

@@ -43,22 +43,30 @@ namespace Emby.Dlna.Didl
private readonly ILocalizationManager _localization;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
private readonly IMediaEncoder _mediaEncoder;
public DidlBuilder(DeviceProfile profile, User user, IImageProcessor imageProcessor, string serverAddress, string accessToken, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, ILogger logger, ILibraryManager libraryManager, IMediaEncoder mediaEncoder)
public DidlBuilder(
DeviceProfile profile,
User user,
IImageProcessor imageProcessor,
string serverAddress,
string accessToken,
IUserDataManager userDataManager,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
ILogger logger,
IMediaEncoder mediaEncoder)
{
_profile = profile;
_user = user;
_imageProcessor = imageProcessor;
_serverAddress = serverAddress;
_accessToken = accessToken;
_userDataManager = userDataManager;
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_logger = logger;
_libraryManager = libraryManager;
_mediaEncoder = mediaEncoder;
_accessToken = accessToken;
_user = user;
}
public static string NormalizeDlnaMediaUrl(string url)
@@ -117,7 +125,8 @@ namespace Emby.Dlna.Didl
}
}
public void WriteItemElement(DlnaOptions options,
public void WriteItemElement(
DlnaOptions options,
XmlWriter writer,
BaseItem item,
User user,
@@ -232,12 +241,15 @@ namespace Emby.Dlna.Didl
AddVideoResource(writer, video, deviceId, filter, contentFeature, streamInfo);
}
var subtitleProfiles = streamInfo.GetSubtitleProfiles(_mediaEncoder, false, _serverAddress, _accessToken)
.Where(subtitle => subtitle.DeliveryMethod == SubtitleDeliveryMethod.External)
.ToList();
var subtitleProfiles = streamInfo.GetSubtitleProfiles(_mediaEncoder, false, _serverAddress, _accessToken);
foreach (var subtitle in subtitleProfiles)
{
if (subtitle.DeliveryMethod != SubtitleDeliveryMethod.External)
{
continue;
}
var subtitleAdded = AddSubtitleElement(writer, subtitle);
if (subtitleAdded && _profile.EnableSingleSubtitleLimit)
@@ -250,7 +262,8 @@ namespace Emby.Dlna.Didl
private bool AddSubtitleElement(XmlWriter writer, SubtitleStreamInfo info)
{
var subtitleProfile = _profile.SubtitleProfiles
.FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase) && i.Method == SubtitleDeliveryMethod.External);
.FirstOrDefault(i => string.Equals(info.Format, i.Format, StringComparison.OrdinalIgnoreCase)
&& i.Method == SubtitleDeliveryMethod.External);
if (subtitleProfile == null)
{
@@ -265,7 +278,7 @@ namespace Emby.Dlna.Didl
// <sec:CaptionInfo sec:type="srt">http://192.168.1.3:9999/video.srt</sec:CaptionInfo>
writer.WriteStartElement("sec", "CaptionInfoEx", null);
writer.WriteAttributeString("sec", "type", null, info.Format.ToLower());
writer.WriteAttributeString("sec", "type", null, info.Format.ToLowerInvariant());
writer.WriteString(info.Url);
writer.WriteFullEndElement();
@@ -282,7 +295,7 @@ namespace Emby.Dlna.Didl
else
{
writer.WriteStartElement(string.Empty, "res", NS_DIDL);
var protocolInfo = string.Format("http-get:*:text/{0}:*", info.Format.ToLower());
var protocolInfo = string.Format("http-get:*:text/{0}:*", info.Format.ToLowerInvariant());
writer.WriteAttributeString("protocolInfo", protocolInfo);
writer.WriteString(info.Url);
@@ -387,91 +400,39 @@ namespace Emby.Dlna.Didl
private string GetDisplayName(BaseItem item, StubType? itemStubType, BaseItem context)
{
if (itemStubType.HasValue && itemStubType.Value == StubType.Latest)
if (itemStubType.HasValue)
{
return _localization.GetLocalizedString("Latest");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Playlists)
{
return _localization.GetLocalizedString("Playlists");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.AlbumArtists)
{
return _localization.GetLocalizedString("HeaderAlbumArtists");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Albums)
{
return _localization.GetLocalizedString("Albums");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Artists)
{
return _localization.GetLocalizedString("Artists");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Songs)
{
return _localization.GetLocalizedString("Songs");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Genres)
{
return _localization.GetLocalizedString("Genres");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteAlbums)
{
return _localization.GetLocalizedString("HeaderFavoriteAlbums");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteArtists)
{
return _localization.GetLocalizedString("HeaderFavoriteArtists");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteSongs)
{
return _localization.GetLocalizedString("HeaderFavoriteSongs");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.ContinueWatching)
{
return _localization.GetLocalizedString("HeaderContinueWatching");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Movies)
{
return _localization.GetLocalizedString("Movies");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Collections)
{
return _localization.GetLocalizedString("Collections");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Favorites)
{
return _localization.GetLocalizedString("Favorites");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.NextUp)
{
return _localization.GetLocalizedString("HeaderNextUp");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteSeries)
{
return _localization.GetLocalizedString("HeaderFavoriteShows");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.FavoriteEpisodes)
{
return _localization.GetLocalizedString("HeaderFavoriteEpisodes");
}
if (itemStubType.HasValue && itemStubType.Value == StubType.Series)
{
return _localization.GetLocalizedString("Shows");
switch (itemStubType.Value)
{
case StubType.Latest: return _localization.GetLocalizedString("Latest");
case StubType.Playlists: return _localization.GetLocalizedString("Playlists");
case StubType.AlbumArtists: return _localization.GetLocalizedString("HeaderAlbumArtists");
case StubType.Albums: return _localization.GetLocalizedString("Albums");
case StubType.Artists: return _localization.GetLocalizedString("Artists");
case StubType.Songs: return _localization.GetLocalizedString("Songs");
case StubType.Genres: return _localization.GetLocalizedString("Genres");
case StubType.FavoriteAlbums: return _localization.GetLocalizedString("HeaderFavoriteAlbums");
case StubType.FavoriteArtists: return _localization.GetLocalizedString("HeaderFavoriteArtists");
case StubType.FavoriteSongs: return _localization.GetLocalizedString("HeaderFavoriteSongs");
case StubType.ContinueWatching: return _localization.GetLocalizedString("HeaderContinueWatching");
case StubType.Movies: return _localization.GetLocalizedString("Movies");
case StubType.Collections: return _localization.GetLocalizedString("Collections");
case StubType.Favorites: return _localization.GetLocalizedString("Favorites");
case StubType.NextUp: return _localization.GetLocalizedString("HeaderNextUp");
case StubType.FavoriteSeries: return _localization.GetLocalizedString("HeaderFavoriteShows");
case StubType.FavoriteEpisodes: return _localization.GetLocalizedString("HeaderFavoriteEpisodes");
case StubType.Series: return _localization.GetLocalizedString("Shows");
default: break;
}
}
var episode = item as Episode;
var season = context as Season;
if (episode != null && season != null)
if (item is Episode episode && context is Season season)
{
// This is a special embedded within a season
if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0)
if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0
&& season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
{
if (season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
{
return string.Format(_localization.GetLocalizedString("ValueSpecialEpisodeName"), item.Name);
}
return string.Format(_localization.GetLocalizedString("ValueSpecialEpisodeName"), item.Name);
}
if (item.IndexNumber.HasValue)
@@ -585,10 +546,8 @@ namespace Emby.Dlna.Didl
public static bool IsIdRoot(string id)
{
if (string.IsNullOrWhiteSpace(id) ||
string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
if (string.IsNullOrWhiteSpace(id)
|| string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
// Samsung sometimes uses 1 as root
|| string.Equals(id, "1", StringComparison.OrdinalIgnoreCase))
{
@@ -808,7 +767,7 @@ namespace Emby.Dlna.Didl
{
writer.WriteString(_profile.RequiresPlainFolders ? "object.container.storageFolder" : "object.container.genre.musicGenre");
}
else if (item is Genre || item is GameGenre)
else if (item is Genre)
{
writer.WriteString(_profile.RequiresPlainFolders ? "object.container.storageFolder" : "object.container.genre");
}
@@ -844,7 +803,7 @@ namespace Emby.Dlna.Didl
// var type = types.FirstOrDefault(i => string.Equals(i, actor.Type, StringComparison.OrdinalIgnoreCase) || string.Equals(i, actor.Role, StringComparison.OrdinalIgnoreCase))
// ?? PersonType.Actor;
// AddValue(writer, "upnp", type.ToLower(), actor.Name, NS_UPNP);
// AddValue(writer, "upnp", type.ToLowerInvariant(), actor.Name, NS_UPNP);
// index++;
@@ -859,10 +818,9 @@ namespace Emby.Dlna.Didl
{
AddCommonFields(item, itemStubType, context, writer, filter);
var hasArtists = item as IHasArtist;
var hasAlbumArtists = item as IHasAlbumArtist;
if (hasArtists != null)
if (item is IHasArtist hasArtists)
{
foreach (var artist in hasArtists.Artists)
{
@@ -932,7 +890,7 @@ namespace Emby.Dlna.Didl
private void AddCover(BaseItem item, BaseItem context, StubType? stubType, XmlWriter writer)
{
ImageDownloadInfo imageInfo = GetImageInfo(item);;
ImageDownloadInfo imageInfo = GetImageInfo(item);
if (imageInfo == null)
{
@@ -962,8 +920,6 @@ namespace Emby.Dlna.Didl
}
}
AddImageResElement(item, writer, 160, 160, "jpg", "JPEG_TN");
if (!_profile.EnableSingleAlbumArtLimit || string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase))
{
AddImageResElement(item, writer, 4096, 4096, "jpg", "JPEG_LRG");
@@ -972,6 +928,9 @@ namespace Emby.Dlna.Didl
AddImageResElement(item, writer, 4096, 4096, "png", "PNG_LRG");
AddImageResElement(item, writer, 160, 160, "png", "PNG_TN");
}
AddImageResElement(item, writer, 160, 160, "jpg", "JPEG_TN");
}
private void AddEmbeddedImageAsCover(string name, XmlWriter writer)
@@ -1088,8 +1047,8 @@ namespace Emby.Dlna.Didl
//{
// var size = _imageProcessor.GetImageSize(imageInfo);
// width = Convert.ToInt32(size.Width);
// height = Convert.ToInt32(size.Height);
// width = size.Width;
// height = size.Height;
//}
//catch
//{
@@ -1112,7 +1071,7 @@ namespace Emby.Dlna.Didl
};
}
class ImageDownloadInfo
private class ImageDownloadInfo
{
internal Guid ItemId;
internal string ImageTag;
@@ -1128,7 +1087,7 @@ namespace Emby.Dlna.Didl
internal ItemImageInfo ItemImageInfo;
}
class ImageUrlInfo
private class ImageUrlInfo
{
internal string Url;
@@ -1147,7 +1106,7 @@ namespace Emby.Dlna.Didl
if (stubType.HasValue)
{
id = stubType.Value.ToString().ToLower() + "_" + id;
id = stubType.Value.ToString().ToLowerInvariant() + "_" + id;
}
return id;
@@ -1162,8 +1121,7 @@ namespace Emby.Dlna.Didl
info.ImageTag,
format,
maxWidth.ToString(CultureInfo.InvariantCulture),
maxHeight.ToString(CultureInfo.InvariantCulture)
);
maxHeight.ToString(CultureInfo.InvariantCulture));
var width = info.Width;
var height = info.Height;
@@ -1172,15 +1130,11 @@ namespace Emby.Dlna.Didl
if (width.HasValue && height.HasValue)
{
var newSize = DrawingUtils.Resize(new ImageSize
{
Height = height.Value,
Width = width.Value
var newSize = DrawingUtils.Resize(
new ImageDimensions(width.Value, height.Value), 0, 0, maxWidth, maxHeight);
}, 0, 0, maxWidth, maxHeight);
width = Convert.ToInt32(newSize.Width);
height = Convert.ToInt32(newSize.Height);
width = newSize.Width;
height = newSize.Height;
var normalizedFormat = format
.Replace("jpeg", "jpg", StringComparison.OrdinalIgnoreCase);

View File

@@ -2,8 +2,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Emby.Dlna.Profiles;
using Emby.Dlna.Server;
using MediaBrowser.Common.Configuration;
@@ -14,9 +16,10 @@ using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Reflection;
using MediaBrowser.Model.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
namespace Emby.Dlna
{
@@ -28,7 +31,7 @@ namespace Emby.Dlna
private readonly ILogger _logger;
private readonly IJsonSerializer _jsonSerializer;
private readonly IServerApplicationHost _appHost;
private readonly IAssemblyInfo _assemblyInfo;
private static readonly Assembly _assembly = typeof(DlnaManager).Assembly;
private readonly Dictionary<string, Tuple<InternalProfileInfo, DeviceProfile>> _profiles = new Dictionary<string, Tuple<InternalProfileInfo, DeviceProfile>>(StringComparer.Ordinal);
@@ -37,7 +40,8 @@ namespace Emby.Dlna
IFileSystem fileSystem,
IApplicationPaths appPaths,
ILoggerFactory loggerFactory,
IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IAssemblyInfo assemblyInfo)
IJsonSerializer jsonSerializer,
IServerApplicationHost appHost)
{
_xmlSerializer = xmlSerializer;
_fileSystem = fileSystem;
@@ -45,14 +49,13 @@ namespace Emby.Dlna
_logger = loggerFactory.CreateLogger("Dlna");
_jsonSerializer = jsonSerializer;
_appHost = appHost;
_assemblyInfo = assemblyInfo;
}
public void InitProfiles()
public async Task InitProfilesAsync()
{
try
{
ExtractSystemProfiles();
await ExtractSystemProfilesAsync();
LoadProfiles();
}
catch (Exception ex)
@@ -202,16 +205,13 @@ namespace Emby.Dlna
}
}
public DeviceProfile GetProfile(IDictionary<string, string> headers)
public DeviceProfile GetProfile(IHeaderDictionary headers)
{
if (headers == null)
{
throw new ArgumentNullException(nameof(headers));
}
// Convert to case insensitive
headers = new Dictionary<string, string>(headers, StringComparer.OrdinalIgnoreCase);
var profile = GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification));
if (profile != null)
@@ -227,12 +227,12 @@ namespace Emby.Dlna
return profile;
}
private bool IsMatch(IDictionary<string, string> headers, DeviceIdentification profileInfo)
private bool IsMatch(IHeaderDictionary headers, DeviceIdentification profileInfo)
{
return profileInfo.Headers.Any(i => IsMatch(headers, i));
}
private bool IsMatch(IDictionary<string, string> headers, HttpHeaderInfo header)
private bool IsMatch(IHeaderDictionary headers, HttpHeaderInfo header)
{
// Handle invalid user setup
if (string.IsNullOrEmpty(header.Name))
@@ -240,14 +240,14 @@ namespace Emby.Dlna
return false;
}
if (headers.TryGetValue(header.Name, out string value))
if (headers.TryGetValue(header.Name, out StringValues value))
{
switch (header.Match)
{
case HeaderMatchType.Equals:
return string.Equals(value, header.Value, StringComparison.OrdinalIgnoreCase);
case HeaderMatchType.Substring:
var isMatch = value.IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
var isMatch = value.ToString().IndexOf(header.Value, StringComparison.OrdinalIgnoreCase) != -1;
//_logger.LogDebug("IsMatch-Substring value: {0} testValue: {1} isMatch: {2}", value, header.Value, isMatch);
return isMatch;
case HeaderMatchType.Regex:
@@ -300,7 +300,7 @@ namespace Emby.Dlna
profile = ReserializeProfile(tempProfile);
profile.Id = path.ToLower().GetMD5().ToString("N");
profile.Id = path.ToLowerInvariant().GetMD5().ToString("N");
_profiles[path] = new Tuple<InternalProfileInfo, DeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
@@ -352,45 +352,48 @@ namespace Emby.Dlna
Info = new DeviceProfileInfo
{
Id = file.FullName.ToLower().GetMD5().ToString("N"),
Id = file.FullName.ToLowerInvariant().GetMD5().ToString("N"),
Name = _fileSystem.GetFileNameWithoutExtension(file),
Type = type
}
};
}
private void ExtractSystemProfiles()
private async Task ExtractSystemProfilesAsync()
{
var namespaceName = GetType().Namespace + ".Profiles.Xml.";
var systemProfilesPath = SystemProfilesPath;
foreach (var name in _assemblyInfo.GetManifestResourceNames(GetType())
.Where(i => i.StartsWith(namespaceName))
.ToList())
foreach (var name in _assembly.GetManifestResourceNames())
{
if (!name.StartsWith(namespaceName))
{
continue;
}
var filename = Path.GetFileName(name).Substring(namespaceName.Length);
var path = Path.Combine(systemProfilesPath, filename);
using (var stream = _assemblyInfo.GetManifestResourceStream(GetType(), name))
using (var stream = _assembly.GetManifestResourceStream(name))
{
var fileInfo = _fileSystem.GetFileInfo(path);
if (!fileInfo.Exists || fileInfo.Length != stream.Length)
{
_fileSystem.CreateDirectory(systemProfilesPath);
Directory.CreateDirectory(systemProfilesPath);
using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
stream.CopyTo(fileStream);
await stream.CopyToAsync(fileStream);
}
}
}
}
// Not necessary, but just to make it easy to find
_fileSystem.CreateDirectory(UserProfilesPath);
Directory.CreateDirectory(UserProfilesPath);
}
public void DeleteProfile(string id)
@@ -490,7 +493,7 @@ namespace Emby.Dlna
internal string Path { get; set; }
}
public string GetServerDescriptionXml(IDictionary<string, string> headers, string serverUuId, string serverAddress)
public string GetServerDescriptionXml(IHeaderDictionary headers, string serverUuId, string serverAddress)
{
var profile = GetProfile(headers) ??
GetDefaultProfile();
@@ -506,12 +509,12 @@ namespace Emby.Dlna
? ImageFormat.Png
: ImageFormat.Jpg;
var resource = GetType().Namespace + ".Images." + filename.ToLower();
var resource = GetType().Namespace + ".Images." + filename.ToLowerInvariant();
return new ImageStream
{
Format = format,
Stream = _assemblyInfo.GetManifestResourceStream(GetType(), resource)
Stream = _assembly.GetManifestResourceStream(resource)
};
}
}

View File

@@ -58,4 +58,9 @@
<EmbeddedResource Include="Profiles\Xml\Xbox One.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
</ItemGroup>
</Project>

View File

@@ -1,5 +1,3 @@
using System.Collections.Generic;
namespace Emby.Dlna
{
public interface IUpnpService
@@ -7,9 +5,8 @@ namespace Emby.Dlna
/// <summary>
/// Gets the content directory XML.
/// </summary>
/// <param name="headers">The headers.</param>
/// <returns>System.String.</returns>
string GetServiceXml(IDictionary<string, string> headers);
string GetServiceXml();
/// <summary>
/// Processes the control request.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Emby.Dlna.PlayTo;
@@ -20,11 +19,10 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Threading;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
using Rssdp;
using Rssdp.Infrastructure;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace Emby.Dlna.Main
{
@@ -50,9 +48,7 @@ namespace Emby.Dlna.Main
private SsdpDevicePublisher _Publisher;
private readonly ITimerFactory _timerFactory;
private readonly ISocketFactory _socketFactory;
private readonly IEnvironmentInfo _environmentInfo;
private readonly INetworkManager _networkManager;
private ISsdpCommunicationsServer _communicationsServer;
@@ -78,11 +74,8 @@ namespace Emby.Dlna.Main
IDeviceDiscovery deviceDiscovery,
IMediaEncoder mediaEncoder,
ISocketFactory socketFactory,
ITimerFactory timerFactory,
IEnvironmentInfo environmentInfo,
INetworkManager networkManager,
IUserViewManager userViewManager,
IXmlReaderSettingsFactory xmlReaderSettingsFactory,
ITVSeriesManager tvSeriesManager)
{
_config = config;
@@ -99,12 +92,11 @@ namespace Emby.Dlna.Main
_deviceDiscovery = deviceDiscovery;
_mediaEncoder = mediaEncoder;
_socketFactory = socketFactory;
_timerFactory = timerFactory;
_environmentInfo = environmentInfo;
_networkManager = networkManager;
_logger = loggerFactory.CreateLogger("Dlna");
ContentDirectory = new ContentDirectory.ContentDirectory(dlnaManager,
ContentDirectory = new ContentDirectory.ContentDirectory(
dlnaManager,
userDataManager,
imageProcessor,
libraryManager,
@@ -116,18 +108,17 @@ namespace Emby.Dlna.Main
mediaSourceManager,
userViewManager,
mediaEncoder,
xmlReaderSettingsFactory,
tvSeriesManager);
ConnectionManager = new ConnectionManager.ConnectionManager(dlnaManager, config, _logger, httpClient, xmlReaderSettingsFactory);
ConnectionManager = new ConnectionManager.ConnectionManager(dlnaManager, config, _logger, httpClient);
MediaReceiverRegistrar = new MediaReceiverRegistrar.MediaReceiverRegistrar(_logger, httpClient, config, xmlReaderSettingsFactory);
MediaReceiverRegistrar = new MediaReceiverRegistrar.MediaReceiverRegistrar(_logger, httpClient, config);
Current = this;
}
public void Run()
public async Task RunAsync()
{
((DlnaManager)_dlnaManager).InitProfiles();
await ((DlnaManager)_dlnaManager).InitProfilesAsync().ConfigureAwait(false);
ReloadComponents();
@@ -173,9 +164,10 @@ namespace Emby.Dlna.Main
{
if (_communicationsServer == null)
{
var enableMultiSocketBinding = _environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows;
var enableMultiSocketBinding = OperatingSystem.Id == OperatingSystemId.Windows ||
OperatingSystem.Id == OperatingSystemId.Linux;
_communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding)
_communicationsServer = new SsdpCommunicationsServer(_config, _socketFactory, _networkManager, _logger, enableMultiSocketBinding)
{
IsShared = true
};
@@ -233,7 +225,7 @@ namespace Emby.Dlna.Main
try
{
_Publisher = new SsdpDevicePublisher(_communicationsServer, _timerFactory, _environmentInfo.OperatingSystemName, _environmentInfo.OperatingSystemVersion);
_Publisher = new SsdpDevicePublisher(_communicationsServer, _networkManager, OperatingSystem.Name, Environment.OSVersion.VersionString, _config.GetDlnaConfiguration().SendOnlyMatchedHost);
_Publisher.LogFunction = LogMessage;
_Publisher.SupportPnpRootDevice = false;
@@ -249,21 +241,21 @@ namespace Emby.Dlna.Main
private async Task RegisterServerEndpoints()
{
var addresses = (await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false)).ToList();
var addresses = await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false);
var udn = CreateUuid(_appHost.SystemId);
foreach (var address in addresses)
{
// TODO: Remove this condition on platforms that support it
//if (address.AddressFamily == IpAddressFamily.InterNetworkV6)
//{
// continue;
//}
if (address.AddressFamily == IpAddressFamily.InterNetworkV6)
{
// Not support IPv6 right now
continue;
}
var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
_logger.LogInformation("Registering publisher for {0} on {1}", fullService, address.ToString());
_logger.LogInformation("Registering publisher for {0} on {1}", fullService, address);
var descriptorUri = "/dlna/" + udn + "/description.xml";
var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri);
@@ -272,6 +264,8 @@ namespace Emby.Dlna.Main
{
CacheLifetime = TimeSpan.FromSeconds(1800), //How long SSDP clients can cache this info.
Location = uri, // Must point to the URL that serves your devices UPnP description document.
Address = address,
SubnetMask = _networkManager.GetLocalIpSubnetMask(address),
FriendlyName = "Jellyfin",
Manufacturer = "Jellyfin",
ModelName = "Jellyfin Server",
@@ -353,8 +347,7 @@ namespace Emby.Dlna.Main
_userDataManager,
_localization,
_mediaSourceManager,
_mediaEncoder,
_timerFactory);
_mediaEncoder);
_manager.Start();
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using Emby.Dlna.Service;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.MediaReceiverRegistrar
@@ -36,7 +35,8 @@ namespace Emby.Dlna.MediaReceiverRegistrar
};
}
public ControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) : base(config, logger, xmlReaderSettingsFactory)
public ControlHandler(IServerConfigurationManager config, ILogger logger)
: base(config, logger)
{
}
}

View File

@@ -1,8 +1,6 @@
using System.Collections.Generic;
using Emby.Dlna.Service;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.MediaReceiverRegistrar
@@ -10,16 +8,14 @@ namespace Emby.Dlna.MediaReceiverRegistrar
public class MediaReceiverRegistrar : BaseService, IMediaReceiverRegistrar
{
private readonly IServerConfigurationManager _config;
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
public MediaReceiverRegistrar(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
public MediaReceiverRegistrar(ILogger logger, IHttpClient httpClient, IServerConfigurationManager config)
: base(logger, httpClient)
{
_config = config;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
public string GetServiceXml(IDictionary<string, string> headers)
public string GetServiceXml()
{
return new MediaReceiverRegistrarXmlBuilder().GetXml();
}
@@ -28,7 +24,7 @@ namespace Emby.Dlna.MediaReceiverRegistrar
{
return new ControlHandler(
_config,
Logger, XmlReaderSettingsFactory)
Logger)
.ProcessControlRequest(request);
}
}

View File

@@ -1,9 +0,0 @@
using System;
namespace Emby.Dlna.PlayTo
{
public class CurrentIdEventArgs : EventArgs
{
public string Id { get; set; }
}
}

View File

@@ -4,13 +4,13 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Emby.Dlna.Common;
using Emby.Dlna.Server;
using Emby.Dlna.Ssdp;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.PlayTo
@@ -19,7 +19,7 @@ namespace Emby.Dlna.PlayTo
{
#region Fields & Properties
private ITimer _timer;
private Timer _timer;
public DeviceInfo Properties { get; set; }
@@ -40,12 +40,7 @@ namespace Emby.Dlna.PlayTo
public TimeSpan? Duration { get; set; }
private TimeSpan _position = TimeSpan.FromSeconds(0);
public TimeSpan Position
{
get => _position;
set => _position = value;
}
public TimeSpan Position { get; set; } = TimeSpan.FromSeconds(0);
public TRANSPORTSTATE TransportState { get; private set; }
@@ -61,24 +56,20 @@ namespace Emby.Dlna.PlayTo
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
public DateTime DateLastActivity { get; private set; }
public Action OnDeviceUnavailable { get; set; }
private readonly ITimerFactory _timerFactory;
public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config, ITimerFactory timerFactory)
public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config)
{
Properties = deviceProperties;
_httpClient = httpClient;
_logger = logger;
_config = config;
_timerFactory = timerFactory;
}
public void Start()
{
_logger.LogDebug("Dlna Device.Start");
_timer = _timerFactory.Create(TimerCallback, null, 1000, Timeout.Infinite);
_timer = new Timer(TimerCallback, null, 1000, Timeout.Infinite);
}
private DateTime _lastVolumeRefresh;
@@ -119,7 +110,9 @@ namespace Emby.Dlna.PlayTo
lock (_timerLock)
{
if (_disposed)
{
return;
}
_volumeRefreshActive = true;
@@ -136,7 +129,9 @@ namespace Emby.Dlna.PlayTo
lock (_timerLock)
{
if (_disposed)
{
return;
}
_volumeRefreshActive = false;
@@ -144,11 +139,6 @@ namespace Emby.Dlna.PlayTo
}
}
public void OnPlaybackStartedExternally()
{
RestartTimer(true);
}
#region Commanding
public Task VolumeDown(CancellationToken cancellationToken)
@@ -333,7 +323,9 @@ namespace Emby.Dlna.PlayTo
private string CreateDidlMeta(string value)
{
if (string.IsNullOrEmpty(value))
{
return string.Empty;
}
return DescriptionXmlBuilder.Escape(value);
}
@@ -342,10 +334,11 @@ namespace Emby.Dlna.PlayTo
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Play");
if (command == null)
{
return Task.CompletedTask;
}
var service = GetAvTransportService();
if (service == null)
{
throw new InvalidOperationException("Unable to find service");
@@ -369,7 +362,9 @@ namespace Emby.Dlna.PlayTo
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Stop");
if (command == null)
{
return;
}
var service = GetAvTransportService();
@@ -385,7 +380,9 @@ namespace Emby.Dlna.PlayTo
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "Pause");
if (command == null)
{
return;
}
var service = GetAvTransportService();
@@ -405,7 +402,9 @@ namespace Emby.Dlna.PlayTo
private async void TimerCallback(object sender)
{
if (_disposed)
{
return;
}
try
{
@@ -425,8 +424,6 @@ namespace Emby.Dlna.PlayTo
return;
}
DateLastActivity = DateTime.UtcNow;
if (transportState.HasValue)
{
// If we're not playing anything no need to get additional data
@@ -505,7 +502,9 @@ namespace Emby.Dlna.PlayTo
var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetVolume");
if (command == null)
{
return;
}
var service = GetServiceRenderingControl();
@@ -518,13 +517,17 @@ namespace Emby.Dlna.PlayTo
.ConfigureAwait(false);
if (result == null || result.Document == null)
{
return;
}
var volume = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetVolumeResponse").Select(i => i.Element("CurrentVolume")).FirstOrDefault(i => i != null);
var volumeValue = volume == null ? null : volume.Value;
var volumeValue = volume?.Value;
if (string.IsNullOrWhiteSpace(volumeValue))
{
return;
}
Volume = int.Parse(volumeValue, UsCulture);
@@ -545,7 +548,9 @@ namespace Emby.Dlna.PlayTo
var command = rendererCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMute");
if (command == null)
{
return;
}
var service = GetServiceRenderingControl();
@@ -560,39 +565,44 @@ namespace Emby.Dlna.PlayTo
if (result == null || result.Document == null)
return;
var valueNode = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetMuteResponse").Select(i => i.Element("CurrentMute")).FirstOrDefault(i => i != null);
var value = valueNode == null ? null : valueNode.Value;
var valueNode = result.Document.Descendants(uPnpNamespaces.RenderingControl + "GetMuteResponse")
.Select(i => i.Element("CurrentMute"))
.FirstOrDefault(i => i != null);
IsMuted = string.Equals(value, "1", StringComparison.OrdinalIgnoreCase);
IsMuted = string.Equals(valueNode?.Value, "1", StringComparison.OrdinalIgnoreCase);
}
private async Task<TRANSPORTSTATE?> GetTransportInfo(TransportCommands avCommands, CancellationToken cancellationToken)
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetTransportInfo");
if (command == null)
{
return null;
}
var service = GetAvTransportService();
if (service == null)
{
return null;
}
var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, avCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false);
if (result == null || result.Document == null)
{
return null;
}
var transportState =
result.Document.Descendants(uPnpNamespaces.AvTransport + "GetTransportInfoResponse").Select(i => i.Element("CurrentTransportState")).FirstOrDefault(i => i != null);
var transportStateValue = transportState == null ? null : transportState.Value;
if (transportStateValue != null)
if (transportStateValue != null
&& Enum.TryParse(transportStateValue, true, out TRANSPORTSTATE state))
{
if (Enum.TryParse(transportStateValue, true, out TRANSPORTSTATE state))
{
return state;
}
return state;
}
return null;
@@ -602,10 +612,11 @@ namespace Emby.Dlna.PlayTo
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetMediaInfo");
if (command == null)
{
return null;
}
var service = GetAvTransportService();
if (service == null)
{
throw new InvalidOperationException("Unable to find service");
@@ -617,7 +628,9 @@ namespace Emby.Dlna.PlayTo
.ConfigureAwait(false);
if (result == null || result.Document == null)
{
return null;
}
var track = result.Document.Descendants("CurrentURIMetaData").FirstOrDefault();
@@ -657,11 +670,13 @@ namespace Emby.Dlna.PlayTo
return null;
}
private async Task<Tuple<bool, uBaseObject>> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken)
private async Task<(bool, uBaseObject)> GetPositionInfo(TransportCommands avCommands, CancellationToken cancellationToken)
{
var command = avCommands.ServiceActions.FirstOrDefault(c => c.Name == "GetPositionInfo");
if (command == null)
return new Tuple<bool, uBaseObject>(false, null);
{
return (false, null);
}
var service = GetAvTransportService();
@@ -676,7 +691,9 @@ namespace Emby.Dlna.PlayTo
.ConfigureAwait(false);
if (result == null || result.Document == null)
return new Tuple<bool, uBaseObject>(false, null);
{
return (false, null);
}
var trackUriElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackURI")).FirstOrDefault(i => i != null);
var trackUri = trackUriElem == null ? null : trackUriElem.Value;
@@ -684,8 +701,8 @@ namespace Emby.Dlna.PlayTo
var durationElem = result.Document.Descendants(uPnpNamespaces.AvTransport + "GetPositionInfoResponse").Select(i => i.Element("TrackDuration")).FirstOrDefault(i => i != null);
var duration = durationElem == null ? null : durationElem.Value;
if (!string.IsNullOrWhiteSpace(duration) &&
!string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
if (!string.IsNullOrWhiteSpace(duration)
&& !string.Equals(duration, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
{
Duration = TimeSpan.Parse(duration, UsCulture);
}
@@ -707,43 +724,75 @@ namespace Emby.Dlna.PlayTo
if (track == null)
{
//If track is null, some vendors do this, use GetMediaInfo instead
return new Tuple<bool, uBaseObject>(true, null);
return (true, null);
}
var trackString = (string)track;
if (string.IsNullOrWhiteSpace(trackString) || string.Equals(trackString, "NOT_IMPLEMENTED", StringComparison.OrdinalIgnoreCase))
{
return new Tuple<bool, uBaseObject>(true, null);
return (true, null);
}
XElement uPnpResponse;
XElement uPnpResponse = null;
// Handle different variations sent back by devices
try
{
uPnpResponse = XElement.Parse(trackString);
uPnpResponse = ParseResponse(trackString);
}
catch (Exception)
catch (Exception ex)
{
// first try to add a root node with a dlna namesapce
try
{
uPnpResponse = XElement.Parse("<data xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">" + trackString + "</data>");
uPnpResponse = uPnpResponse.Descendants().First();
}
catch (Exception ex)
{
_logger.LogError(ex, "Unable to parse xml {0}", trackString);
return new Tuple<bool, uBaseObject>(true, null);
}
_logger.LogError(ex, "Uncaught exception while parsing xml");
}
if (uPnpResponse == null)
{
_logger.LogError("Failed to parse xml: \n {Xml}", trackString);
return (true, null);
}
var e = uPnpResponse.Element(uPnpNamespaces.items);
var uTrack = CreateUBaseObject(e, trackUri);
return new Tuple<bool, uBaseObject>(true, uTrack);
return (true, uTrack);
}
private XElement ParseResponse(string xml)
{
// Handle different variations sent back by devices
try
{
return XElement.Parse(xml);
}
catch (XmlException)
{
}
// first try to add a root node with a dlna namesapce
try
{
return XElement.Parse("<data xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\">" + xml + "</data>")
.Descendants()
.First();
}
catch (XmlException)
{
}
// some devices send back invalid xml
try
{
return XElement.Parse(xml.Replace("&", "&amp;"));
}
catch (XmlException)
{
}
return null;
}
private static uBaseObject CreateUBaseObject(XElement container, string trackUri)
@@ -801,11 +850,9 @@ namespace Emby.Dlna.PlayTo
private async Task<TransportCommands> GetAVProtocolAsync(CancellationToken cancellationToken)
{
var avCommands = AvCommands;
if (avCommands != null)
if (AvCommands != null)
{
return avCommands;
return AvCommands;
}
if (_disposed)
@@ -825,18 +872,15 @@ namespace Emby.Dlna.PlayTo
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
avCommands = TransportCommands.Create(document);
AvCommands = avCommands;
return avCommands;
AvCommands = TransportCommands.Create(document);
return AvCommands;
}
private async Task<TransportCommands> GetRenderingProtocolAsync(CancellationToken cancellationToken)
{
var rendererCommands = RendererCommands;
if (rendererCommands != null)
if (RendererCommands != null)
{
return rendererCommands;
return RendererCommands;
}
if (_disposed)
@@ -845,7 +889,6 @@ namespace Emby.Dlna.PlayTo
}
var avService = GetServiceRenderingControl();
if (avService == null)
{
throw new ArgumentException("Device AvService is null");
@@ -857,9 +900,8 @@ namespace Emby.Dlna.PlayTo
_logger.LogDebug("Dlna Device.GetRenderingProtocolAsync");
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
rendererCommands = TransportCommands.Create(document);
RendererCommands = rendererCommands;
return rendererCommands;
RendererCommands = TransportCommands.Create(document);
return RendererCommands;
}
private string NormalizeUrl(string baseUrl, string url)
@@ -871,85 +913,103 @@ namespace Emby.Dlna.PlayTo
}
if (!url.Contains("/"))
{
url = "/dmr/" + url;
}
if (!url.StartsWith("/"))
{
url = "/" + url;
}
return baseUrl + url;
}
private TransportCommands AvCommands
{
get;
set;
}
private TransportCommands AvCommands { get; set; }
private TransportCommands RendererCommands
{
get;
set;
}
private TransportCommands RendererCommands { get; set; }
public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory, CancellationToken cancellationToken)
public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, CancellationToken cancellationToken)
{
var ssdpHttpClient = new SsdpHttpClient(httpClient, config);
var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false);
var deviceProperties = new DeviceInfo();
var friendlyNames = new List<string>();
var name = document.Descendants(uPnpNamespaces.ud.GetName("friendlyName")).FirstOrDefault();
if (name != null && !string.IsNullOrWhiteSpace(name.Value))
{
friendlyNames.Add(name.Value);
}
var room = document.Descendants(uPnpNamespaces.ud.GetName("roomName")).FirstOrDefault();
if (room != null && !string.IsNullOrWhiteSpace(room.Value))
{
friendlyNames.Add(room.Value);
}
deviceProperties.Name = string.Join(" ", friendlyNames.ToArray());
var deviceProperties = new DeviceInfo()
{
Name = string.Join(" ", friendlyNames),
BaseUrl = string.Format("http://{0}:{1}", url.Host, url.Port)
};
var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault();
if (model != null)
{
deviceProperties.ModelName = model.Value;
}
var modelNumber = document.Descendants(uPnpNamespaces.ud.GetName("modelNumber")).FirstOrDefault();
if (modelNumber != null)
{
deviceProperties.ModelNumber = modelNumber.Value;
}
var uuid = document.Descendants(uPnpNamespaces.ud.GetName("UDN")).FirstOrDefault();
if (uuid != null)
{
deviceProperties.UUID = uuid.Value;
}
var manufacturer = document.Descendants(uPnpNamespaces.ud.GetName("manufacturer")).FirstOrDefault();
if (manufacturer != null)
{
deviceProperties.Manufacturer = manufacturer.Value;
}
var manufacturerUrl = document.Descendants(uPnpNamespaces.ud.GetName("manufacturerURL")).FirstOrDefault();
if (manufacturerUrl != null)
{
deviceProperties.ManufacturerUrl = manufacturerUrl.Value;
}
var presentationUrl = document.Descendants(uPnpNamespaces.ud.GetName("presentationURL")).FirstOrDefault();
if (presentationUrl != null)
{
deviceProperties.PresentationUrl = presentationUrl.Value;
}
var modelUrl = document.Descendants(uPnpNamespaces.ud.GetName("modelURL")).FirstOrDefault();
if (modelUrl != null)
{
deviceProperties.ModelUrl = modelUrl.Value;
}
var serialNumber = document.Descendants(uPnpNamespaces.ud.GetName("serialNumber")).FirstOrDefault();
if (serialNumber != null)
{
deviceProperties.SerialNumber = serialNumber.Value;
}
var modelDescription = document.Descendants(uPnpNamespaces.ud.GetName("modelDescription")).FirstOrDefault();
if (modelDescription != null)
{
deviceProperties.ModelDescription = modelDescription.Value;
deviceProperties.BaseUrl = string.Format("http://{0}:{1}", url.Host, url.Port);
}
var icon = document.Descendants(uPnpNamespaces.ud.GetName("icon")).FirstOrDefault();
if (icon != null)
{
deviceProperties.Icon = CreateIcon(icon);
@@ -958,12 +1018,15 @@ namespace Emby.Dlna.PlayTo
foreach (var services in document.Descendants(uPnpNamespaces.ud.GetName("serviceList")))
{
if (services == null)
{
continue;
}
var servicesList = services.Descendants(uPnpNamespaces.ud.GetName("service"));
if (servicesList == null)
{
continue;
}
foreach (var element in servicesList)
{
@@ -976,9 +1039,7 @@ namespace Emby.Dlna.PlayTo
}
}
var device = new Device(deviceProperties, httpClient, logger, config, timerFactory);
return device;
return new Device(deviceProperties, httpClient, logger, config);
}
#endregion
@@ -1065,75 +1126,73 @@ namespace Emby.Dlna.PlayTo
private void OnPlaybackStart(uBaseObject mediaInfo)
{
if (PlaybackStart != null)
{
PlaybackStart.Invoke(this, new PlaybackStartEventArgs
{
MediaInfo = mediaInfo
});
}
}
private void OnPlaybackProgress(uBaseObject mediaInfo)
{
var mediaUrl = mediaInfo.Url;
if (string.IsNullOrWhiteSpace(mediaUrl))
if (string.IsNullOrWhiteSpace(mediaInfo.Url))
{
return;
}
if (PlaybackProgress != null)
PlaybackStart?.Invoke(this, new PlaybackStartEventArgs
{
PlaybackProgress.Invoke(this, new PlaybackProgressEventArgs
{
MediaInfo = mediaInfo
});
MediaInfo = mediaInfo
});
}
private void OnPlaybackProgress(uBaseObject mediaInfo)
{
if (string.IsNullOrWhiteSpace(mediaInfo.Url))
{
return;
}
PlaybackProgress?.Invoke(this, new PlaybackProgressEventArgs
{
MediaInfo = mediaInfo
});
}
private void OnPlaybackStop(uBaseObject mediaInfo)
{
if (PlaybackStopped != null)
PlaybackStopped?.Invoke(this, new PlaybackStoppedEventArgs
{
PlaybackStopped.Invoke(this, new PlaybackStoppedEventArgs
{
MediaInfo = mediaInfo
});
}
MediaInfo = mediaInfo
});
}
private void OnMediaChanged(uBaseObject old, uBaseObject newMedia)
{
if (MediaChanged != null)
MediaChanged?.Invoke(this, new MediaChangedEventArgs
{
MediaChanged.Invoke(this, new MediaChangedEventArgs
{
OldMediaInfo = old,
NewMediaInfo = newMedia
});
}
OldMediaInfo = old,
NewMediaInfo = newMedia
});
}
#region IDisposable
bool _disposed;
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
DisposeTimer();
}
Dispose(true);
GC.SuppressFinalize(this);
}
private void DisposeTimer()
protected virtual void Dispose(bool disposing)
{
if (_timer != null)
if (_disposed)
{
_timer.Dispose();
_timer = null;
return;
}
if (disposing)
{
_timer?.Dispose();
}
_timer = null;
Properties = null;
_disposed = true;
}
#endregion

View File

@@ -6,6 +6,7 @@ using System.Threading;
using System.Threading.Tasks;
using Emby.Dlna.Didl;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
@@ -17,8 +18,8 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Session;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.PlayTo
@@ -42,30 +43,43 @@ namespace Emby.Dlna.PlayTo
private readonly IDeviceDiscovery _deviceDiscovery;
private readonly string _serverAddress;
private readonly string _accessToken;
private readonly DateTime _creationTime;
public bool IsSessionActive => !_disposed && _device != null;
public bool SupportsMediaControl => IsSessionActive;
public PlayToController(SessionInfo session, ISessionManager sessionManager, ILibraryManager libraryManager, ILogger logger, IDlnaManager dlnaManager, IUserManager userManager, IImageProcessor imageProcessor, string serverAddress, string accessToken, IDeviceDiscovery deviceDiscovery, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IConfigurationManager config, IMediaEncoder mediaEncoder)
public PlayToController(
SessionInfo session,
ISessionManager sessionManager,
ILibraryManager libraryManager,
ILogger logger,
IDlnaManager dlnaManager,
IUserManager userManager,
IImageProcessor imageProcessor,
string serverAddress,
string accessToken,
IDeviceDiscovery deviceDiscovery,
IUserDataManager userDataManager,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
IConfigurationManager config,
IMediaEncoder mediaEncoder)
{
_session = session;
_sessionManager = sessionManager;
_libraryManager = libraryManager;
_logger = logger;
_dlnaManager = dlnaManager;
_userManager = userManager;
_imageProcessor = imageProcessor;
_serverAddress = serverAddress;
_accessToken = accessToken;
_deviceDiscovery = deviceDiscovery;
_userDataManager = userDataManager;
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_config = config;
_mediaEncoder = mediaEncoder;
_accessToken = accessToken;
_logger = logger;
_creationTime = DateTime.UtcNow;
}
public void Init(Device device)
@@ -88,9 +102,10 @@ namespace Emby.Dlna.PlayTo
{
_sessionManager.ReportSessionEnded(_session.Id);
}
catch
catch (Exception ex)
{
// Could throw if the session is already gone
_logger.LogError(ex, "Error reporting the end of session {Id}", _session.Id);
}
}
@@ -98,20 +113,14 @@ namespace Emby.Dlna.PlayTo
{
var info = e.Argument;
info.Headers.TryGetValue("NTS", out string nts);
if (!info.Headers.TryGetValue("USN", out string usn)) usn = string.Empty;
if (!info.Headers.TryGetValue("NT", out string nt)) nt = string.Empty;
if (usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
!_disposed)
if (!_disposed
&& info.Headers.TryGetValue("USN", out string usn)
&& usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1
&& (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1
|| (info.Headers.TryGetValue("NT", out string nt)
&& nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)))
{
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1 ||
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) != -1)
{
OnDeviceUnavailable();
}
OnDeviceUnavailable();
}
}
@@ -374,9 +383,7 @@ namespace Emby.Dlna.PlayTo
return _device.IsPaused ? _device.SetPlay(CancellationToken.None) : _device.SetPause(CancellationToken.None);
case PlaystateCommand.Seek:
{
return Seek(command.SeekPositionTicks ?? 0);
}
return Seek(command.SeekPositionTicks ?? 0);
case PlaystateCommand.NextTrack:
return SetPlaylistIndex(_currentPlaylistIndex + 1);
@@ -442,8 +449,7 @@ namespace Emby.Dlna.PlayTo
var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();
var hasMediaSources = item as IHasMediaSources;
var mediaSources = hasMediaSources != null
var mediaSources = item is IHasMediaSources
? (_mediaSourceManager.GetStaticMediaSources(item, true, user))
: new List<MediaSourceInfo>();
@@ -452,7 +458,7 @@ namespace Emby.Dlna.PlayTo
playlistItem.StreamUrl = DidlBuilder.NormalizeDlnaMediaUrl(playlistItem.StreamInfo.ToUrl(_serverAddress, _accessToken));
var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _libraryManager, _mediaEncoder)
var itemXml = new DidlBuilder(profile, user, _imageProcessor, _serverAddress, _accessToken, _userDataManager, _localization, _mediaSourceManager, _logger, _mediaEncoder)
.GetItemDidl(_config.GetDlnaConfiguration(), item, user, null, _session.DeviceId, new Filter(), playlistItem.StreamInfo);
playlistItem.Didl = itemXml;
@@ -601,22 +607,34 @@ namespace Emby.Dlna.PlayTo
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
_device.PlaybackStart -= _device_PlaybackStart;
_device.PlaybackProgress -= _device_PlaybackProgress;
_device.PlaybackStopped -= _device_PlaybackStopped;
_device.MediaChanged -= _device_MediaChanged;
//_deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft;
_device.OnDeviceUnavailable = null;
_device.Dispose();
}
Dispose(true);
GC.SuppressFinalize(this);
}
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
_device.Dispose();
}
_device.PlaybackStart -= _device_PlaybackStart;
_device.PlaybackProgress -= _device_PlaybackProgress;
_device.PlaybackStopped -= _device_PlaybackStopped;
_device.MediaChanged -= _device_MediaChanged;
_deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft;
_device.OnDeviceUnavailable = null;
_device = null;
_disposed = true;
}
private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
private Task SendGeneralCommand(GeneralCommand command, CancellationToken cancellationToken)
{
@@ -837,13 +855,13 @@ namespace Emby.Dlna.PlayTo
if (index == -1) return request;
var query = url.Substring(index + 1);
QueryParamCollection values = MyHttpUtility.ParseQueryString(query);
Dictionary<string, string> values = QueryHelpers.ParseQuery(query).ToDictionary(kv => kv.Key, kv => kv.Value.ToString());
request.DeviceProfileId = values.Get("DeviceProfileId");
request.DeviceId = values.Get("DeviceId");
request.MediaSourceId = values.Get("MediaSourceId");
request.LiveStreamId = values.Get("LiveStreamId");
request.IsDirectStream = string.Equals("true", values.Get("Static"), StringComparison.OrdinalIgnoreCase);
request.DeviceProfileId = values.GetValueOrDefault("DeviceProfileId");
request.DeviceId = values.GetValueOrDefault("DeviceId");
request.MediaSourceId = values.GetValueOrDefault("MediaSourceId");
request.LiveStreamId = values.GetValueOrDefault("LiveStreamId");
request.IsDirectStream = string.Equals("true", values.GetValueOrDefault("Static"), StringComparison.OrdinalIgnoreCase);
request.AudioStreamIndex = GetIntValue(values, "AudioStreamIndex");
request.SubtitleStreamIndex = GetIntValue(values, "SubtitleStreamIndex");
@@ -857,9 +875,9 @@ namespace Emby.Dlna.PlayTo
}
}
private static int? GetIntValue(QueryParamCollection values, string name)
private static int? GetIntValue(IReadOnlyDictionary<string, string> values, string name)
{
var value = values.Get(name);
var value = values.GetValueOrDefault(name);
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
{
@@ -869,9 +887,9 @@ namespace Emby.Dlna.PlayTo
return null;
}
private static long GetLongValue(QueryParamCollection values, string name)
private static long GetLongValue(IReadOnlyDictionary<string, string> values, string name)
{
var value = values.Get(name);
var value = values.GetValueOrDefault(name);
if (long.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
{

View File

@@ -16,7 +16,6 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.PlayTo
@@ -39,13 +38,12 @@ namespace Emby.Dlna.PlayTo
private readonly IDeviceDiscovery _deviceDiscovery;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IMediaEncoder _mediaEncoder;
private readonly ITimerFactory _timerFactory;
private bool _disposed;
private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1);
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory)
public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder)
{
_logger = logger;
_sessionManager = sessionManager;
@@ -61,7 +59,6 @@ namespace Emby.Dlna.PlayTo
_localization = localization;
_mediaSourceManager = mediaSourceManager;
_mediaEncoder = mediaEncoder;
_timerFactory = timerFactory;
}
public void Start()
@@ -92,11 +89,6 @@ namespace Emby.Dlna.PlayTo
return;
}
if (_sessionManager.Sessions.Any(i => usn.IndexOf(i.DeviceId, StringComparison.OrdinalIgnoreCase) != -1))
{
return;
}
var cancellationToken = _disposeCancellationTokenSource.Token;
await _sessionLock.WaitAsync(cancellationToken).ConfigureAwait(false);
@@ -108,6 +100,11 @@ namespace Emby.Dlna.PlayTo
return;
}
if (_sessionManager.Sessions.Any(i => usn.IndexOf(i.DeviceId, StringComparison.OrdinalIgnoreCase) != -1))
{
return;
}
await AddDevice(info, location, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
@@ -162,17 +159,15 @@ namespace Emby.Dlna.PlayTo
uuid = location.GetMD5().ToString("N");
}
string deviceName = null;
var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersion, uuid, deviceName, uri.OriginalString, null);
var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersion, uuid, null, uri.OriginalString, null);
var controller = sessionInfo.SessionControllers.OfType<PlayToController>().FirstOrDefault();
if (controller == null)
{
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false);
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, cancellationToken).ConfigureAwait(false);
deviceName = device.Properties.Name;
string deviceName = device.Properties.Name;
_sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName);
@@ -186,8 +181,6 @@ namespace Emby.Dlna.PlayTo
serverAddress = _appHost.GetLocalApiUrl(info.LocalIpAddress);
}
string accessToken = null;
controller = new PlayToController(sessionInfo,
_sessionManager,
_libraryManager,
@@ -196,7 +189,7 @@ namespace Emby.Dlna.PlayTo
_userManager,
_imageProcessor,
serverAddress,
accessToken,
null,
_deviceDiscovery,
_userDataManager,
_localization,

View File

@@ -9,8 +9,6 @@ namespace Emby.Dlna.PlayTo
{
public class PlaylistItemFactory
{
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
public PlaylistItem Create(Photo item, DeviceProfile profile)
{
var playlistItem = new PlaylistItem

View File

@@ -107,12 +107,18 @@ namespace Emby.Dlna.PlayTo
foreach (var arg in action.ArgumentList)
{
if (arg.Direction == "out")
{
continue;
}
if (arg.Name == "InstanceID")
{
stateString += BuildArgumentXml(arg, "0");
}
else
{
stateString += BuildArgumentXml(arg, null);
}
}
return string.Format(CommandBase, action.Name, xmlNamespace, stateString);
@@ -125,11 +131,18 @@ namespace Emby.Dlna.PlayTo
foreach (var arg in action.ArgumentList)
{
if (arg.Direction == "out")
{
continue;
}
if (arg.Name == "InstanceID")
{
stateString += BuildArgumentXml(arg, "0");
}
else
{
stateString += BuildArgumentXml(arg, value.ToString(), commandParameter);
}
}
return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);
@@ -142,11 +155,17 @@ namespace Emby.Dlna.PlayTo
foreach (var arg in action.ArgumentList)
{
if (arg.Name == "InstanceID")
{
stateString += BuildArgumentXml(arg, "0");
}
else if (dictionary.ContainsKey(arg.Name))
{
stateString += BuildArgumentXml(arg, dictionary[arg.Name]);
}
else
{
stateString += BuildArgumentXml(arg, value.ToString());
}
}
return string.Format(CommandBase, action.Name, xmlNamesapce, stateString);

View File

@@ -1,9 +0,0 @@
using System;
namespace Emby.Dlna.PlayTo
{
public class TransportStateEventArgs : EventArgs
{
public TRANSPORTSTATE State { get; set; }
}
}

View File

@@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Emby.Dlna.PlayTo
{
public class uParser
{
public static IList<uBaseObject> ParseBrowseXml(XDocument doc)
{
if (doc == null)
{
throw new ArgumentException("doc");
}
var list = new List<uBaseObject>();
var document = doc.Document;
if (document == null)
return list;
var item = (from result in document.Descendants("Result") select result).FirstOrDefault();
if (item == null)
return list;
var uPnpResponse = XElement.Parse((string)item);
var uObjects = from container in uPnpResponse.Elements(uPnpNamespaces.containers)
select new uParserObject { Element = container };
var uObjects2 = from container in uPnpResponse.Elements(uPnpNamespaces.items)
select new uParserObject { Element = container };
list.AddRange(uObjects.Concat(uObjects2).Select(CreateObjectFromXML).Where(uObject => uObject != null));
return list;
}
public static uBaseObject CreateObjectFromXML(uParserObject uItem)
{
return UpnpContainer.Create(uItem.Element);
}
}
}

View File

@@ -1,9 +0,0 @@
using System.Xml.Linq;
namespace Emby.Dlna.PlayTo
{
public class uParserObject
{
public XElement Element { get; set; }
}
}

View File

@@ -8,8 +8,8 @@ using System.Resources;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -107,19 +107,19 @@ namespace Emby.Dlna.Server
'&'
};
private static readonly string[] s_escapeStringPairs = new string[]
{
"<",
"&lt;",
">",
"&gt;",
"\"",
"&quot;",
"'",
"&apos;",
"&",
"&amp;"
};
private static readonly string[] s_escapeStringPairs = new[]
{
"<",
"&lt;",
">",
"&gt;",
"\"",
"&quot;",
"'",
"&apos;",
"&",
"&amp;"
};
private static string GetEscapeSequence(char c)
{
@@ -133,7 +133,7 @@ namespace Emby.Dlna.Server
return result;
}
}
return c.ToString();
return c.ToString(CultureInfo.InvariantCulture);
}
/// <summary>Replaces invalid XML characters in a string with their valid XML equivalent.</summary>
@@ -145,6 +145,7 @@ namespace Emby.Dlna.Server
{
return null;
}
StringBuilder stringBuilder = null;
int length = str.Length;
int num = 0;
@@ -230,9 +231,9 @@ namespace Emby.Dlna.Server
var serverName = new string(characters);
var name = (_profile.FriendlyName ?? string.Empty).Replace("${HostName}", serverName, StringComparison.OrdinalIgnoreCase);
var name = _profile.FriendlyName?.Replace("${HostName}", serverName, StringComparison.OrdinalIgnoreCase);
return name;
return name ?? string.Empty;
}
private void AppendIconList(StringBuilder builder)
@@ -295,65 +296,62 @@ namespace Emby.Dlna.Server
}
private IEnumerable<DeviceIcon> GetIcons()
{
var list = new List<DeviceIcon>();
list.Add(new DeviceIcon
=> new[]
{
MimeType = "image/png",
Depth = "24",
Width = 240,
Height = 240,
Url = "icons/logo240.png"
});
new DeviceIcon
{
MimeType = "image/png",
Depth = "24",
Width = 240,
Height = 240,
Url = "icons/logo240.png"
},
list.Add(new DeviceIcon
{
MimeType = "image/jpeg",
Depth = "24",
Width = 240,
Height = 240,
Url = "icons/logo240.jpg"
});
new DeviceIcon
{
MimeType = "image/jpeg",
Depth = "24",
Width = 240,
Height = 240,
Url = "icons/logo240.jpg"
},
list.Add(new DeviceIcon
{
MimeType = "image/png",
Depth = "24",
Width = 120,
Height = 120,
Url = "icons/logo120.png"
});
new DeviceIcon
{
MimeType = "image/png",
Depth = "24",
Width = 120,
Height = 120,
Url = "icons/logo120.png"
},
list.Add(new DeviceIcon
{
MimeType = "image/jpeg",
Depth = "24",
Width = 120,
Height = 120,
Url = "icons/logo120.jpg"
});
new DeviceIcon
{
MimeType = "image/jpeg",
Depth = "24",
Width = 120,
Height = 120,
Url = "icons/logo120.jpg"
},
list.Add(new DeviceIcon
{
MimeType = "image/png",
Depth = "24",
Width = 48,
Height = 48,
Url = "icons/logo48.png"
});
new DeviceIcon
{
MimeType = "image/png",
Depth = "24",
Width = 48,
Height = 48,
Url = "icons/logo48.png"
},
list.Add(new DeviceIcon
{
MimeType = "image/jpeg",
Depth = "24",
Width = 48,
Height = 48,
Url = "icons/logo48.jpg"
});
return list;
}
new DeviceIcon
{
MimeType = "image/jpeg",
Depth = "24",
Width = 48,
Height = 48,
Url = "icons/logo48.jpg"
}
};
private IEnumerable<DeviceService> GetServices()
{

View File

@@ -7,7 +7,6 @@ using System.Xml;
using Emby.Dlna.Didl;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Extensions;
using MediaBrowser.Model.Xml;
using Microsoft.Extensions.Logging;
namespace Emby.Dlna.Service
@@ -18,13 +17,11 @@ namespace Emby.Dlna.Service
protected readonly IServerConfigurationManager Config;
protected readonly ILogger _logger;
protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
protected BaseControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
protected BaseControlHandler(IServerConfigurationManager config, ILogger logger)
{
Config = config;
_logger = logger;
XmlReaderSettingsFactory = xmlReaderSettingsFactory;
}
public ControlResponse ProcessControlRequest(ControlRequest request)
@@ -61,11 +58,13 @@ namespace Emby.Dlna.Service
using (var streamReader = new StreamReader(request.InputXml))
{
var readerSettings = XmlReaderSettingsFactory.Create(false);
readerSettings.CheckCharacters = false;
readerSettings.IgnoreProcessingInstructions = true;
readerSettings.IgnoreComments = true;
var readerSettings = new XmlReaderSettings()
{
ValidationType = ValidationType.None,
CheckCharacters = false,
IgnoreProcessingInstructions = true,
IgnoreComments = true
};
using (var reader = XmlReader.Create(streamReader, readerSettings))
{

View File

@@ -5,7 +5,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
using Rssdp;
using Rssdp.Infrastructure;
@@ -48,20 +47,17 @@ namespace Emby.Dlna.Ssdp
private SsdpDeviceLocator _deviceLocator;
private readonly ITimerFactory _timerFactory;
private readonly ISocketFactory _socketFactory;
private ISsdpCommunicationsServer _commsServer;
public DeviceDiscovery(
ILoggerFactory loggerFactory,
IServerConfigurationManager config,
ISocketFactory socketFactory,
ITimerFactory timerFactory)
ISocketFactory socketFactory)
{
_logger = loggerFactory.CreateLogger(nameof(DeviceDiscovery));
_config = config;
_socketFactory = socketFactory;
_timerFactory = timerFactory;
}
// Call this method from somewhere in your code to start the search.
@@ -78,7 +74,7 @@ namespace Emby.Dlna.Ssdp
{
if (_listenerCount > 0 && _deviceLocator == null)
{
_deviceLocator = new SsdpDeviceLocator(_commsServer, _timerFactory);
_deviceLocator = new SsdpDeviceLocator(_commsServer);
// (Optional) Set the filter so we only see notifications for devices we care about
// (can be any search target value i.e device type, uuid value etc - any value that appears in the

View File

@@ -5,12 +5,6 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="1.68.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="1.68.0" />
<PackageReference Include="Jellyfin.SkiaSharp.NativeAssets.LinuxArm" Version="1.68.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />

View File

@@ -18,7 +18,6 @@ using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using Microsoft.Extensions.Logging;
using SkiaSharp;
namespace Emby.Drawing
{
@@ -66,7 +65,7 @@ namespace Emby.Drawing
_appPaths = appPaths;
ImageEnhancers = Array.Empty<IImageEnhancer>();
ImageHelper.ImageProcessor = this;
}
@@ -84,8 +83,8 @@ namespace Emby.Drawing
}
}
public string[] SupportedInputFormats =>
new string[]
public IReadOnlyCollection<string> SupportedInputFormats =>
new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"tiff",
"tif",
@@ -138,14 +137,14 @@ namespace Emby.Drawing
}
}
public ImageFormat[] GetSupportedImageOutputFormats()
{
return _imageEncoder.SupportedOutputFormats;
}
public IReadOnlyCollection<ImageFormat> GetSupportedImageOutputFormats()
=> _imageEncoder.SupportedOutputFormats;
private static readonly HashSet<string> TransparentImageTypes
= new HashSet<string>(StringComparer.OrdinalIgnoreCase) { ".png", ".webp", ".gif" };
private static readonly string[] TransparentImageTypes = new string[] { ".png", ".webp", ".gif" };
public bool SupportsTransparency(string path)
=> TransparentImageTypes.Contains(Path.GetExtension(path).ToLower());
=> TransparentImageTypes.Contains(Path.GetExtension(path));
public async Task<(string path, string mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options)
{
@@ -168,10 +167,10 @@ namespace Emby.Drawing
string originalImagePath = originalImage.Path;
DateTime dateModified = originalImage.DateModified;
ImageSize? originalImageSize = null;
ImageDimensions? originalImageSize = null;
if (originalImage.Width > 0 && originalImage.Height > 0)
{
originalImageSize = new ImageSize(originalImage.Width, originalImage.Height);
originalImageSize = new ImageDimensions(originalImage.Width, originalImage.Height);
}
if (!_imageEncoder.SupportsImageEncoding)
@@ -181,6 +180,12 @@ namespace Emby.Drawing
var supportedImageInfo = await GetSupportedImage(originalImagePath, dateModified).ConfigureAwait(false);
originalImagePath = supportedImageInfo.path;
if (!File.Exists(originalImagePath))
{
return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
dateModified = supportedImageInfo.dateModified;
bool requiresTransparency = TransparentImageTypes.Contains(Path.GetExtension(originalImagePath));
@@ -231,7 +236,7 @@ namespace Emby.Drawing
return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
ImageSize newSize = ImageHelper.GetNewImageSize(options, null);
ImageDimensions newSize = ImageHelper.GetNewImageSize(options, null);
int quality = options.Quality;
ImageFormat outputFormat = GetOutputFormat(options.SupportedOutputFormats, requiresTransparency);
@@ -245,7 +250,7 @@ namespace Emby.Drawing
try
{
if (!_fileSystem.FileExists(cacheFilePath))
if (!File.Exists(cacheFilePath))
{
if (options.CropWhiteSpace && !SupportsTransparency(originalImagePath))
{
@@ -262,21 +267,10 @@ namespace Emby.Drawing
return (cacheFilePath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(cacheFilePath));
}
catch (ArgumentOutOfRangeException ex)
{
// Decoder failed to decode it
#if DEBUG
_logger.LogError(ex, "Error encoding image");
#endif
// Just spit out the original file if all the options are default
return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
catch (Exception ex)
{
// If it fails for whatever reason, return the original image
_logger.LogError(ex, "Error encoding image");
// Just spit out the original file if all the options are default
return (originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
finally
@@ -334,7 +328,7 @@ namespace Emby.Drawing
/// <summary>
/// Gets the cache file path based on a set of parameters
/// </summary>
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, int? blur, string backgroundColor, string foregroundLayer)
private string GetCacheFilePath(string originalPath, ImageDimensions outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, int? blur, string backgroundColor, string foregroundLayer)
{
var filename = originalPath
+ "width=" + outputSize.Width
@@ -375,29 +369,28 @@ namespace Emby.Drawing
filename += "v=" + Version;
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLowerInvariant());
}
public ImageSize GetImageSize(BaseItem item, ItemImageInfo info)
=> GetImageSize(item, info, true);
public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info)
=> GetImageDimensions(item, info, true);
public ImageSize GetImageSize(BaseItem item, ItemImageInfo info, bool updateItem)
public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem)
{
int width = info.Width;
int height = info.Height;
if (height > 0 && width > 0)
{
return new ImageSize(width, height);
return new ImageDimensions(width, height);
}
string path = info.Path;
_logger.LogInformation("Getting image size for item {ItemType} {Path}", item.GetType().Name, path);
var size = GetImageSize(path);
info.Height = Convert.ToInt32(size.Height);
info.Width = Convert.ToInt32(size.Width);
ImageDimensions size = GetImageDimensions(path);
info.Width = size.Width;
info.Height = size.Height;
if (updateItem)
{
@@ -410,20 +403,8 @@ namespace Emby.Drawing
/// <summary>
/// Gets the size of the image.
/// </summary>
public ImageSize GetImageSize(string path)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException(nameof(path));
}
using (var s = new SKFileStream(path))
using (var codec = SKCodec.Create(s))
{
var info = codec.Info;
return new ImageSize(info.Width, info.Height);
}
}
public ImageDimensions GetImageDimensions(string path)
=> _imageEncoder.GetImageSize(path);
/// <summary>
/// Gets the image cache tag.
@@ -495,7 +476,7 @@ namespace Emby.Drawing
return (originalImagePath, dateModified);
}
if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat, StringComparer.OrdinalIgnoreCase))
if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat))
{
try
{
@@ -640,12 +621,12 @@ namespace Emby.Drawing
try
{
// Check again in case of contention
if (_fileSystem.FileExists(enhancedImagePath))
if (File.Exists(enhancedImagePath))
{
return (enhancedImagePath, treatmentRequiresTransparency);
}
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(enhancedImagePath));
Directory.CreateDirectory(Path.GetDirectoryName(enhancedImagePath));
await ExecuteImageEnhancers(supportedEnhancers, originalImagePath, enhancedImagePath, item, imageType, imageIndex).ConfigureAwait(false);

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.Drawing;
@@ -6,15 +7,11 @@ namespace Emby.Drawing
{
public class NullImageEncoder : IImageEncoder
{
public string[] SupportedInputFormats =>
new[]
{
"png",
"jpeg",
"jpg"
};
public IReadOnlyCollection<string> SupportedInputFormats
=> new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "png", "jpeg", "jpg" };
public ImageFormat[] SupportedOutputFormats => new[] { ImageFormat.Jpg, ImageFormat.Png };
public IReadOnlyCollection<ImageFormat> SupportedOutputFormats
=> new HashSet<ImageFormat>() { ImageFormat.Jpg, ImageFormat.Png };
public void CropWhiteSpace(string inputPath, string outputPath)
{
@@ -37,7 +34,7 @@ namespace Emby.Drawing
public bool SupportsImageEncoding => false;
public ImageSize GetImageSize(string path)
public ImageDimensions GetImageSize(string path)
{
throw new NotImplementedException();
}

View File

@@ -8,8 +8,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -7,6 +7,7 @@ using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Logging;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace IsoMounter
{
@@ -17,9 +18,7 @@ namespace IsoMounter
#region Private Fields
private readonly IEnvironmentInfo EnvironmentInfo;
private readonly bool ExecutablesAvailable;
private readonly IFileSystem FileSystem;
private readonly ILogger _logger;
private readonly string MountCommand;
private readonly string MountPointRoot;
@@ -31,15 +30,12 @@ namespace IsoMounter
#region Constructor(s)
public LinuxIsoManager(ILogger logger, IFileSystem fileSystem, IEnvironmentInfo environment, IProcessFactory processFactory)
public LinuxIsoManager(ILogger logger, IProcessFactory processFactory)
{
EnvironmentInfo = environment;
FileSystem = fileSystem;
_logger = logger;
ProcessFactory = processFactory;
MountPointRoot = FileSystem.DirectorySeparatorChar + "tmp" + FileSystem.DirectorySeparatorChar + "Emby";
MountPointRoot = Path.DirectorySeparatorChar + "tmp" + Path.DirectorySeparatorChar + "Emby";
_logger.LogDebug(
"[{0}] System PATH is currently set to [{1}].",
@@ -111,7 +107,7 @@ namespace IsoMounter
public bool CanMount(string path)
{
if (EnvironmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Linux)
if (OperatingSystem.Id != OperatingSystemId.Linux)
{
return false;
}
@@ -120,8 +116,8 @@ namespace IsoMounter
Name,
path,
Path.GetExtension(path),
EnvironmentInfo.OperatingSystem,
ExecutablesAvailable.ToString()
OperatingSystem.Name,
ExecutablesAvailable
);
if (ExecutablesAvailable)
@@ -183,7 +179,7 @@ namespace IsoMounter
_logger.LogInformation(
"[{0}] Disposing [{1}].",
Name,
disposing.ToString()
disposing
);
if (disposing)
@@ -214,9 +210,9 @@ namespace IsoMounter
{
string path = test.Trim();
if (!string.IsNullOrEmpty(path) && FileSystem.FileExists(path = Path.Combine(path, name)))
if (!string.IsNullOrEmpty(path) && File.Exists(path = Path.Combine(path, name)))
{
return FileSystem.GetFullPath(path);
return Path.GetFullPath(path);
}
}
@@ -229,9 +225,8 @@ namespace IsoMounter
var uid = getuid();
_logger.LogDebug(
"[{0}] Our current UID is [{1}], GetUserId() returned [{2}].",
"[{0}] GetUserId() returned [{2}].",
Name,
uid.ToString(),
uid
);
@@ -327,7 +322,7 @@ namespace IsoMounter
try
{
FileSystem.CreateDirectory(mountPoint);
Directory.CreateDirectory(mountPoint);
}
catch (UnauthorizedAccessException)
{
@@ -377,7 +372,7 @@ namespace IsoMounter
try
{
FileSystem.DeleteDirectory(mountPoint, false);
Directory.Delete(mountPoint, false);
}
catch (Exception ex)
{
@@ -455,7 +450,7 @@ namespace IsoMounter
try
{
FileSystem.DeleteDirectory(mount.MountedPath, false);
Directory.Delete(mount.MountedPath, false);
}
catch (Exception ex)
{

View File

@@ -9,8 +9,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -36,7 +36,7 @@ namespace Emby.Naming.AudioBook
return null;
}
var extension = Path.GetExtension(path) ?? string.Empty;
var extension = Path.GetExtension(path);
// Check supported extensions
if (!_options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{

View File

@@ -9,8 +9,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Emby.Naming.Common;
namespace Emby.Naming.TV
@@ -22,7 +21,9 @@ namespace Emby.Naming.TV
// There were no failed tests without this block, but to be safe, we can keep it until
// the regex which require file extensions are modified so that they don't need them.
if (IsDirectory)
{
path += ".mp4";
}
EpisodePathParserResult result = null;
@@ -35,6 +36,7 @@ namespace Emby.Naming.TV
continue;
}
}
if (isNamed.HasValue)
{
if (expression.IsNamed != isNamed.Value)
@@ -42,6 +44,7 @@ namespace Emby.Naming.TV
continue;
}
}
if (isOptimistic.HasValue)
{
if (expression.IsOptimistic != isOptimistic.Value)
@@ -191,13 +194,20 @@ namespace Emby.Naming.TV
private void FillAdditional(string path, EpisodePathParserResult info, IEnumerable<EpisodeExpression> expressions)
{
var results = expressions
.Where(i => i.IsNamed)
.Select(i => Parse(path, i))
.Where(i => i.Success);
foreach (var result in results)
foreach (var i in expressions)
{
if (!i.IsNamed)
{
continue;
}
var result = Parse(path, i);
if (!result.Success)
{
continue;
}
if (string.IsNullOrEmpty(info.SeriesName))
{
info.SeriesName = result.SeriesName;
@@ -208,12 +218,10 @@ namespace Emby.Naming.TV
info.EndingEpsiodeNumber = result.EndingEpsiodeNumber;
}
if (!string.IsNullOrEmpty(info.SeriesName))
if (!string.IsNullOrEmpty(info.SeriesName)
&& (!info.EpisodeNumber.HasValue || info.EndingEpsiodeNumber.HasValue))
{
if (!info.EpisodeNumber.HasValue || info.EndingEpsiodeNumber.HasValue)
{
break;
}
break;
}
}
}

View File

@@ -183,8 +183,7 @@ namespace Emby.Naming.Video
{
if (videos.All(i => i.Files.Count == 1 && IsEligibleForMultiVersion(folderName, i.Files[0].Path)))
{
// Enforce the multi-version limit
if (videos.Count <= 8 && HaveSameYear(videos))
if (HaveSameYear(videos))
{
var ordered = videos.OrderBy(i => i.Name).ToList();
@@ -200,23 +199,6 @@ namespace Emby.Naming.Video
}
return videos;
//foreach (var video in videos.OrderBy(i => i.Name))
//{
// var match = list
// .FirstOrDefault(i => string.Equals(i.Name, video.Name, StringComparison.OrdinalIgnoreCase));
// if (match != null && video.Files.Count == 1 && match.Files.Count == 1)
// {
// match.AlternateVersions.Add(video.Files[0]);
// match.Extras.AddRange(video.Extras);
// }
// else
// {
// list.Add(video);
// }
//}
//return list;
}
private bool HaveSameYear(List<VideoInfo> videos)
@@ -226,17 +208,14 @@ namespace Emby.Naming.Video
private bool IsEligibleForMultiVersion(string folderName, string testFilename)
{
testFilename = Path.GetFileNameWithoutExtension(testFilename);
if (string.Equals(folderName, testFilename, StringComparison.OrdinalIgnoreCase))
{
return true;
}
testFilename = Path.GetFileNameWithoutExtension(testFilename) ?? string.Empty;
if (testFilename.StartsWith(folderName, StringComparison.OrdinalIgnoreCase))
{
testFilename = testFilename.Substring(folderName.Length).Trim();
return testFilename.StartsWith("-", StringComparison.OrdinalIgnoreCase) || Regex.Replace(testFilename, @"\[([^]]*)\]", "").Trim() == string.Empty;
return string.IsNullOrEmpty(testFilename) ||
testFilename.StartsWith("-") ||
string.IsNullOrWhiteSpace(Regex.Replace(testFilename, @"\[([^]]*)\]", string.Empty)) ;
}
return false;

View File

@@ -11,111 +11,81 @@ namespace Emby.Notifications
public class CoreNotificationTypes : INotificationTypeFactory
{
private readonly ILocalizationManager _localization;
private readonly IServerApplicationHost _appHost;
public CoreNotificationTypes(ILocalizationManager localization, IServerApplicationHost appHost)
public CoreNotificationTypes(ILocalizationManager localization)
{
_localization = localization;
_appHost = appHost;
}
public IEnumerable<NotificationTypeInfo> GetNotificationTypes()
{
var knownTypes = new List<NotificationTypeInfo>
var knownTypes = new NotificationTypeInfo[]
{
new NotificationTypeInfo
{
Type = NotificationType.ApplicationUpdateInstalled.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.InstallationFailed.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.PluginInstalled.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.PluginError.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.PluginUninstalled.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.PluginUpdateInstalled.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.ServerRestartRequired.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.TaskFailed.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.NewLibraryContent.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.AudioPlayback.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.GamePlayback.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.VideoPlayback.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.AudioPlaybackStopped.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.GamePlaybackStopped.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.VideoPlaybackStopped.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.CameraImageUploaded.ToString()
},
new NotificationTypeInfo
{
Type = NotificationType.UserLockedOut.ToString()
}
};
if (!_appHost.CanSelfUpdate)
{
knownTypes.Add(new NotificationTypeInfo
},
new NotificationTypeInfo
{
Type = NotificationType.ApplicationUpdateAvailable.ToString()
});
}
}
};
foreach (var type in knownTypes)
{

View File

@@ -5,22 +5,17 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Notifications;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Notifications;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Notifications
@@ -30,53 +25,50 @@ namespace Emby.Notifications
/// </summary>
public class Notifications : IServerEntryPoint
{
private readonly IInstallationManager _installationManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
private readonly ITaskManager _taskManager;
private readonly INotificationManager _notificationManager;
private readonly ILibraryManager _libraryManager;
private readonly ISessionManager _sessionManager;
private readonly IServerApplicationHost _appHost;
private readonly ITimerFactory _timerFactory;
private ITimer LibraryUpdateTimer { get; set; }
private Timer LibraryUpdateTimer { get; set; }
private readonly object _libraryChangedSyncLock = new object();
private readonly IConfigurationManager _config;
private readonly IDeviceManager _deviceManager;
private readonly ILocalizationManager _localization;
private readonly IActivityManager _activityManager;
private string[] _coreNotificationTypes;
public Notifications(IInstallationManager installationManager, IActivityManager activityManager, ILocalizationManager localization, IUserManager userManager, ILogger logger, ITaskManager taskManager, INotificationManager notificationManager, ILibraryManager libraryManager, ISessionManager sessionManager, IServerApplicationHost appHost, IConfigurationManager config, IDeviceManager deviceManager, ITimerFactory timerFactory)
public Notifications(
IActivityManager activityManager,
ILocalizationManager localization,
ILogger logger,
INotificationManager notificationManager,
ILibraryManager libraryManager,
IServerApplicationHost appHost,
IConfigurationManager config)
{
_installationManager = installationManager;
_userManager = userManager;
_logger = logger;
_taskManager = taskManager;
_notificationManager = notificationManager;
_libraryManager = libraryManager;
_sessionManager = sessionManager;
_appHost = appHost;
_config = config;
_deviceManager = deviceManager;
_timerFactory = timerFactory;
_localization = localization;
_activityManager = activityManager;
_coreNotificationTypes = new CoreNotificationTypes(localization, appHost).GetNotificationTypes().Select(i => i.Type).ToArray();
_coreNotificationTypes = new CoreNotificationTypes(localization).GetNotificationTypes().Select(i => i.Type).ToArray();
}
public void Run()
public Task RunAsync()
{
_libraryManager.ItemAdded += _libraryManager_ItemAdded;
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
_appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged;
_activityManager.EntryCreated += _activityManager_EntryCreated;
return Task.CompletedTask;
}
private async void _appHost_HasPendingRestartChanged(object sender, EventArgs e)
@@ -125,10 +117,9 @@ namespace Emby.Notifications
return _config.GetConfiguration<NotificationOptions>("notifications");
}
async void _appHost_HasUpdateAvailableChanged(object sender, EventArgs e)
private async void _appHost_HasUpdateAvailableChanged(object sender, EventArgs e)
{
// This notification is for users who can't auto-update (aka running as service)
if (!_appHost.HasUpdateAvailable || _appHost.CanSelfUpdate)
if (!_appHost.HasUpdateAvailable)
{
return;
}
@@ -146,7 +137,7 @@ namespace Emby.Notifications
}
private readonly List<BaseItem> _itemsAdded = new List<BaseItem>();
void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e)
private void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e)
{
if (!FilterItem(e.Item))
{
@@ -157,7 +148,7 @@ namespace Emby.Notifications
{
if (LibraryUpdateTimer == null)
{
LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, 5000,
LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, 5000,
Timeout.Infinite);
}
else

View File

@@ -9,8 +9,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -9,7 +9,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using Microsoft.Extensions.Logging;
using TagLib;
using TagLib.IFD;
@@ -21,13 +20,11 @@ namespace Emby.Photos
public class PhotoProvider : ICustomMetadataProvider<Photo>, IForcedProvider, IHasItemChangeMonitor
{
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private IImageProcessor _imageProcessor;
public PhotoProvider(ILogger logger, IFileSystem fileSystem, IImageProcessor imageProcessor)
public PhotoProvider(ILogger logger, IImageProcessor imageProcessor)
{
_logger = logger;
_fileSystem = fileSystem;
_imageProcessor = imageProcessor;
}
@@ -181,12 +178,12 @@ namespace Emby.Photos
try
{
var size = _imageProcessor.GetImageSize(item, img, false);
var size = _imageProcessor.GetImageDimensions(item, img, false);
if (size.Width > 0 && size.Height > 0)
{
item.Width = Convert.ToInt32(size.Width);
item.Height = Convert.ToInt32(size.Height);
item.Width = size.Width;
item.Height = size.Height;
}
}
catch (ArgumentException)

View File

@@ -9,8 +9,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin: The Free Software Media System")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License Version 2")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -30,13 +30,10 @@ namespace Emby.Server.Implementations.Activity
public class ActivityLogEntryPoint : IServerEntryPoint
{
private readonly IInstallationManager _installationManager;
//private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
private readonly ITaskManager _taskManager;
private readonly IActivityManager _activityManager;
private readonly ILocalizationManager _localization;
private readonly ILibraryManager _libraryManager;
private readonly ISubtitleManager _subManager;
private readonly IUserManager _userManager;
@@ -59,52 +56,50 @@ namespace Emby.Server.Implementations.Activity
_deviceManager = deviceManager;
}
public void Run()
public Task RunAsync()
{
_taskManager.TaskCompleted += _taskManager_TaskCompleted;
_taskManager.TaskCompleted += OnTaskCompleted;
_installationManager.PluginInstalled += _installationManager_PluginInstalled;
_installationManager.PluginUninstalled += _installationManager_PluginUninstalled;
_installationManager.PluginUpdated += _installationManager_PluginUpdated;
_installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed;
_installationManager.PluginInstalled += OnPluginInstalled;
_installationManager.PluginUninstalled += OnPluginUninstalled;
_installationManager.PluginUpdated += OnPluginUpdated;
_installationManager.PackageInstallationFailed += OnPackageInstallationFailed;
_sessionManager.SessionStarted += _sessionManager_SessionStarted;
_sessionManager.AuthenticationFailed += _sessionManager_AuthenticationFailed;
_sessionManager.AuthenticationSucceeded += _sessionManager_AuthenticationSucceeded;
_sessionManager.SessionEnded += _sessionManager_SessionEnded;
_sessionManager.SessionStarted += OnSessionStarted;
_sessionManager.AuthenticationFailed += OnAuthenticationFailed;
_sessionManager.AuthenticationSucceeded += OnAuthenticationSucceeded;
_sessionManager.SessionEnded += OnSessionEnded;
_sessionManager.PlaybackStart += _sessionManager_PlaybackStart;
_sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped;
_sessionManager.PlaybackStart += OnPlaybackStart;
_sessionManager.PlaybackStopped += OnPlaybackStopped;
//_subManager.SubtitlesDownloaded += _subManager_SubtitlesDownloaded;
_subManager.SubtitleDownloadFailure += _subManager_SubtitleDownloadFailure;
_subManager.SubtitleDownloadFailure += OnSubtitleDownloadFailure;
_userManager.UserCreated += _userManager_UserCreated;
_userManager.UserPasswordChanged += _userManager_UserPasswordChanged;
_userManager.UserDeleted += _userManager_UserDeleted;
_userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated;
_userManager.UserLockedOut += _userManager_UserLockedOut;
_userManager.UserCreated += OnUserCreated;
_userManager.UserPasswordChanged += OnUserPasswordChanged;
_userManager.UserDeleted += OnUserDeleted;
_userManager.UserPolicyUpdated += OnUserPolicyUpdated;
_userManager.UserLockedOut += OnUserLockedOut;
//_config.ConfigurationUpdated += _config_ConfigurationUpdated;
//_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated;
_deviceManager.CameraImageUploaded += OnCameraImageUploaded;
_deviceManager.CameraImageUploaded += _deviceManager_CameraImageUploaded;
_appHost.ApplicationUpdated += OnApplicationUpdated;
_appHost.ApplicationUpdated += _appHost_ApplicationUpdated;
return Task.CompletedTask;
}
async void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)
private void OnCameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("CameraImageUploadedFrom"), e.Argument.Device.Name),
Type = NotificationType.CameraImageUploaded.ToString()
});
}
async void _userManager_UserLockedOut(object sender, GenericEventArgs<User> e)
private void OnUserLockedOut(object sender, GenericEventArgs<User> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name),
Type = NotificationType.UserLockedOut.ToString(),
@@ -112,9 +107,9 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _subManager_SubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
private void OnSubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, Notifications.Notifications.GetItemName(e.Item)),
Type = "SubtitleDownloadFailure",
@@ -123,7 +118,7 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e)
private void OnPlaybackStopped(object sender, PlaybackStopEventArgs e)
{
var item = e.MediaInfo;
@@ -144,9 +139,9 @@ namespace Emby.Server.Implementations.Activity
return;
}
var user = e.Users.First();
var user = e.Users[0];
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
Type = GetPlaybackStoppedNotificationType(item.MediaType),
@@ -154,7 +149,7 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
private void OnPlaybackStart(object sender, PlaybackProgressEventArgs e)
{
var item = e.MediaInfo;
@@ -177,7 +172,7 @@ namespace Emby.Server.Implementations.Activity
var user = e.Users.First();
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
Type = GetPlaybackNotificationType(item.MediaType),
@@ -208,10 +203,6 @@ namespace Emby.Server.Implementations.Activity
{
return NotificationType.AudioPlayback.ToString();
}
if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase))
{
return NotificationType.GamePlayback.ToString();
}
if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
{
return NotificationType.VideoPlayback.ToString();
@@ -226,10 +217,6 @@ namespace Emby.Server.Implementations.Activity
{
return NotificationType.AudioPlaybackStopped.ToString();
}
if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase))
{
return NotificationType.GamePlaybackStopped.ToString();
}
if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
{
return NotificationType.VideoPlaybackStopped.ToString();
@@ -238,7 +225,7 @@ namespace Emby.Server.Implementations.Activity
return null;
}
async void _sessionManager_SessionEnded(object sender, SessionEventArgs e)
private void OnSessionEnded(object sender, SessionEventArgs e)
{
string name;
var session = e.SessionInfo;
@@ -255,7 +242,7 @@ namespace Emby.Server.Implementations.Activity
name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName);
}
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = name,
Type = "SessionEnded",
@@ -264,11 +251,11 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _sessionManager_AuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationResult> e)
private void OnAuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationResult> e)
{
var user = e.Argument.User;
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), user.Name),
Type = "AuthenticationSucceeded",
@@ -277,9 +264,9 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _sessionManager_AuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e)
private void OnAuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
Type = "AuthenticationFailed",
@@ -288,9 +275,9 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _appHost_ApplicationUpdated(object sender, GenericEventArgs<PackageVersionInfo> e)
private void OnApplicationUpdated(object sender, GenericEventArgs<PackageVersionInfo> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("MessageApplicationUpdatedTo"), e.Argument.versionStr),
Type = NotificationType.ApplicationUpdateInstalled.ToString(),
@@ -298,27 +285,9 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
private void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
{
await CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("MessageNamedServerConfigurationUpdatedWithValue"), e.Key),
Type = "NamedConfigurationUpdated"
});
}
async void _config_ConfigurationUpdated(object sender, EventArgs e)
{
await CreateLogEntry(new ActivityLogEntry
{
Name = _localization.GetLocalizedString("MessageServerConfigurationUpdated"),
Type = "ServerConfigurationUpdated"
});
}
async void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserPolicyUpdatedWithName"), e.Argument.Name),
Type = "UserPolicyUpdated",
@@ -326,18 +295,18 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _userManager_UserDeleted(object sender, GenericEventArgs<User> e)
private void OnUserDeleted(object sender, GenericEventArgs<User> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name),
Type = "UserDeleted"
});
}
async void _userManager_UserPasswordChanged(object sender, GenericEventArgs<User> e)
private void OnUserPasswordChanged(object sender, GenericEventArgs<User> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name),
Type = "UserPasswordChanged",
@@ -345,9 +314,9 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _userManager_UserCreated(object sender, GenericEventArgs<User> e)
private void OnUserCreated(object sender, GenericEventArgs<User> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name),
Type = "UserCreated",
@@ -355,18 +324,7 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _subManager_SubtitlesDownloaded(object sender, SubtitleDownloadEventArgs e)
{
await CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("SubtitlesDownloadedForItem"), Notifications.Notifications.GetItemName(e.Item)),
Type = "SubtitlesDownloaded",
ItemId = e.Item.Id.ToString("N"),
ShortOverview = string.Format(_localization.GetLocalizedString("ProviderValue"), e.Provider)
});
}
async void _sessionManager_SessionStarted(object sender, SessionEventArgs e)
private void OnSessionStarted(object sender, SessionEventArgs e)
{
string name;
var session = e.SessionInfo;
@@ -383,7 +341,7 @@ namespace Emby.Server.Implementations.Activity
name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName);
}
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = name,
Type = "SessionStarted",
@@ -392,9 +350,9 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _installationManager_PluginUpdated(object sender, GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> e)
private void OnPluginUpdated(object sender, GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name),
Type = NotificationType.PluginUpdateInstalled.ToString(),
@@ -403,18 +361,18 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _installationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
private void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name),
Type = NotificationType.PluginUninstalled.ToString()
});
}
async void _installationManager_PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e)
private void OnPluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e)
{
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name),
Type = NotificationType.PluginInstalled.ToString(),
@@ -422,11 +380,11 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e)
private void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
{
var installationInfo = e.InstallationInfo;
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("NameInstallFailed"), installationInfo.Name),
Type = NotificationType.InstallationFailed.ToString(),
@@ -435,7 +393,7 @@ namespace Emby.Server.Implementations.Activity
});
}
async void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e)
private void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
{
var result = e.Result;
var task = e.Task;
@@ -462,7 +420,7 @@ namespace Emby.Server.Implementations.Activity
vals.Add(e.Result.LongErrorMessage);
}
await CreateLogEntry(new ActivityLogEntry
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
Type = NotificationType.TaskFailed.ToString(),
@@ -473,50 +431,37 @@ namespace Emby.Server.Implementations.Activity
}
}
private async Task CreateLogEntry(ActivityLogEntry entry)
{
try
{
await _activityManager.CreateAsync(entry);
}
catch
{
// Logged at lower levels
}
}
private void CreateLogEntry(ActivityLogEntry entry)
=> _activityManager.Create(entry);
public void Dispose()
{
_taskManager.TaskCompleted -= _taskManager_TaskCompleted;
_taskManager.TaskCompleted -= OnTaskCompleted;
_installationManager.PluginInstalled -= _installationManager_PluginInstalled;
_installationManager.PluginUninstalled -= _installationManager_PluginUninstalled;
_installationManager.PluginUpdated -= _installationManager_PluginUpdated;
_installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed;
_installationManager.PluginInstalled -= OnPluginInstalled;
_installationManager.PluginUninstalled -= OnPluginUninstalled;
_installationManager.PluginUpdated -= OnPluginUpdated;
_installationManager.PackageInstallationFailed -= OnPackageInstallationFailed;
_sessionManager.SessionStarted -= _sessionManager_SessionStarted;
_sessionManager.AuthenticationFailed -= _sessionManager_AuthenticationFailed;
_sessionManager.AuthenticationSucceeded -= _sessionManager_AuthenticationSucceeded;
_sessionManager.SessionEnded -= _sessionManager_SessionEnded;
_sessionManager.SessionStarted -= OnSessionStarted;
_sessionManager.AuthenticationFailed -= OnAuthenticationFailed;
_sessionManager.AuthenticationSucceeded -= OnAuthenticationSucceeded;
_sessionManager.SessionEnded -= OnSessionEnded;
_sessionManager.PlaybackStart -= _sessionManager_PlaybackStart;
_sessionManager.PlaybackStopped -= _sessionManager_PlaybackStopped;
_sessionManager.PlaybackStart -= OnPlaybackStart;
_sessionManager.PlaybackStopped -= OnPlaybackStopped;
_subManager.SubtitlesDownloaded -= _subManager_SubtitlesDownloaded;
_subManager.SubtitleDownloadFailure -= _subManager_SubtitleDownloadFailure;
_subManager.SubtitleDownloadFailure -= OnSubtitleDownloadFailure;
_userManager.UserCreated -= _userManager_UserCreated;
_userManager.UserPasswordChanged -= _userManager_UserPasswordChanged;
_userManager.UserDeleted -= _userManager_UserDeleted;
_userManager.UserPolicyUpdated -= _userManager_UserPolicyUpdated;
_userManager.UserLockedOut -= _userManager_UserLockedOut;
_userManager.UserCreated -= OnUserCreated;
_userManager.UserPasswordChanged -= OnUserPasswordChanged;
_userManager.UserDeleted -= OnUserDeleted;
_userManager.UserPolicyUpdated -= OnUserPolicyUpdated;
_userManager.UserLockedOut -= OnUserLockedOut;
_config.ConfigurationUpdated -= _config_ConfigurationUpdated;
_config.NamedConfigurationUpdated -= _config_NamedConfigurationUpdated;
_deviceManager.CameraImageUploaded -= OnCameraImageUploaded;
_deviceManager.CameraImageUploaded -= _deviceManager_CameraImageUploaded;
_appHost.ApplicationUpdated -= _appHost_ApplicationUpdated;
_appHost.ApplicationUpdated -= OnApplicationUpdated;
}
/// <summary>
@@ -538,6 +483,7 @@ namespace Emby.Server.Implementations.Activity
values.Add(CreateValueString(years, "year"));
days = days % DaysInYear;
}
// Number of months
if (days >= DaysInMonth)
{
@@ -545,25 +491,39 @@ namespace Emby.Server.Implementations.Activity
values.Add(CreateValueString(months, "month"));
days = days % DaysInMonth;
}
// Number of days
if (days >= 1)
{
values.Add(CreateValueString(days, "day"));
}
// Number of hours
if (span.Hours >= 1)
{
values.Add(CreateValueString(span.Hours, "hour"));
}
// Number of minutes
if (span.Minutes >= 1)
{
values.Add(CreateValueString(span.Minutes, "minute"));
}
// Number of seconds (include when 0 if no other components included)
if (span.Seconds >= 1 || values.Count == 0)
{
values.Add(CreateValueString(span.Seconds, "second"));
}
// Combine values into string
var builder = new StringBuilder();
for (int i = 0; i < values.Count; i++)
{
if (builder.Length > 0)
{
builder.Append(i == values.Count - 1 ? " and " : ", ");
}
builder.Append(values[i]);
}
// Return result

View File

@@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Activity
@@ -27,39 +26,26 @@ namespace Emby.Server.Implementations.Activity
_userManager = userManager;
}
public async Task CreateAsync(ActivityLogEntry entry)
public void Create(ActivityLogEntry entry)
{
entry.Date = DateTime.UtcNow;
await _repo.CreateAsync(entry);
_repo.Create(entry);
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
}
public IEnumerable<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{
var result = _repo.GetActivityLogEntries();
var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit);
if (minDate.HasValue)
foreach (var item in result.Items)
{
result = result.Where(x => x.Date >= minDate.Value);
}
if (hasUserId.HasValue)
{
result = result.Where(x => x.UserId != null && x.UserId != Guid.Empty);
}
if (startIndex.HasValue)
{
result = result.Where(x => x.Id >= startIndex.Value);
}
if (limit.HasValue)
{
result = result.Take(limit.Value);
}
if (item.UserId == Guid.Empty)
{
continue;
}
// Add images for each user
foreach (var item in result)
{
var user = _userManager.GetUserById(item.UserId);
if (user != null)
@@ -69,7 +55,12 @@ namespace Emby.Server.Implementations.Activity
}
}
return result.AsEnumerable();
return result;
}
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
{
return GetActivityLogEntries(minDate, null, startIndex, limit);
}
}
}

View File

@@ -1,37 +1,310 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Emby.Server.Implementations.Data;
using MediaBrowser.Controller;
using MediaBrowser.Model.Activity;
using Microsoft.EntityFrameworkCore;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Activity
{
public class ActivityRepository : DbContext, IActivityRepository
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
{
protected string _dataDirPath;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
protected IFileSystem FileSystem { get; private set; }
public DbSet<ActivityLogEntry> ActivityLogs { get; set; }
public ActivityRepository(string dataDirPath)
public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem)
: base(loggerFactory.CreateLogger(nameof(ActivityRepository)))
{
_dataDirPath = dataDirPath;
DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db");
FileSystem = fileSystem;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
public void Initialize()
{
// Ensure the dir exists
Directory.CreateDirectory(_dataDirPath);
try
{
InitializeInternal();
}
catch (Exception ex)
{
Logger.LogError(ex, "Error loading database file. Will reset and retry.");
optionsBuilder.UseSqlite($"Filename={Path.Combine(_dataDirPath, "activitylog.sqlite.db")}");
FileSystem.DeleteFile(DbFilePath);
InitializeInternal();
}
}
public async Task CreateAsync(ActivityLogEntry entry)
private void InitializeInternal()
{
await ActivityLogs.AddAsync(entry);
await SaveChangesAsync();
using (var connection = CreateConnection())
{
RunDefaultInitialization(connection);
connection.RunQueries(new[]
{
"create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)",
"drop index if exists idx_ActivityLogEntries"
});
TryMigrate(connection);
}
}
public IQueryable<ActivityLogEntry> GetActivityLogEntries()
=> ActivityLogs;
private void TryMigrate(ManagedConnection connection)
{
try
{
if (TableExists(connection, "ActivityLogEntries"))
{
connection.RunQueries(new[]
{
"INSERT INTO ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) SELECT Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity FROM ActivityLogEntries",
"drop table if exists ActivityLogEntries"
});
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error migrating activity log database");
}
}
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
public void Create(ActivityLogEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
using (WriteLock.Write())
using (var connection = CreateConnection())
{
connection.RunInTransaction(db =>
{
using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"))
{
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N"));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}
}, TransactionMode);
}
}
public void Update(ActivityLogEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
using (WriteLock.Write())
using (var connection = CreateConnection())
{
connection.RunInTransaction(db =>
{
using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"))
{
statement.TryBind("@Id", entry.Id);
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N"));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}
}, TransactionMode);
}
}
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{
using (WriteLock.Read())
using (var connection = CreateConnection(true))
{
var commandText = BaseActivitySelectText;
var whereClauses = new List<string>();
if (minDate.HasValue)
{
whereClauses.Add("DateCreated>=@DateCreated");
}
if (hasUserId.HasValue)
{
if (hasUserId.Value)
{
whereClauses.Add("UserId not null");
}
else
{
whereClauses.Add("UserId is null");
}
}
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
if (startIndex.HasValue && startIndex.Value > 0)
{
var pagingWhereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLog {0} ORDER BY DateCreated DESC LIMIT {1})",
pagingWhereText,
startIndex.Value.ToString(_usCulture)));
}
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
commandText += " ORDER BY DateCreated DESC";
if (limit.HasValue)
{
commandText += " LIMIT " + limit.Value.ToString(_usCulture);
}
var statementTexts = new List<string>();
statementTexts.Add(commandText);
statementTexts.Add("select count (Id) from ActivityLog" + whereTextWithoutPaging);
return connection.RunInTransaction(db =>
{
var list = new List<ActivityLogEntry>();
var result = new QueryResult<ActivityLogEntry>();
var statements = PrepareAllSafe(db, statementTexts).ToList();
using (var statement = statements[0])
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
foreach (var row in statement.ExecuteQuery())
{
list.Add(GetEntry(row));
}
}
using (var statement = statements[1])
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
result.Items = list.ToArray();
return result;
}, ReadTransactionMode);
}
}
private static ActivityLogEntry GetEntry(IReadOnlyList<IResultSetValue> reader)
{
var index = 0;
var info = new ActivityLogEntry
{
Id = reader[index].ToInt64()
};
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Name = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Overview = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.ShortOverview = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Type = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.ItemId = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.UserId = new Guid(reader[index].ToString());
}
index++;
info.Date = reader[index].ReadDateTime();
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Severity = (LogLevel)Enum.Parse(typeof(LogLevel), reader[index].ToString(), true);
}
return info;
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.IO;
using MediaBrowser.Common.Configuration;
@@ -14,48 +15,52 @@ namespace Emby.Server.Implementations.AppBase
/// </summary>
protected BaseApplicationPaths(
string programDataPath,
string appFolderPath,
string logDirectoryPath = null,
string configurationDirectoryPath = null)
string logDirectoryPath,
string configurationDirectoryPath,
string cacheDirectoryPath,
string webDirectoryPath)
{
ProgramDataPath = programDataPath;
ProgramSystemPath = appFolderPath;
LogDirectoryPath = logDirectoryPath;
ConfigurationDirectoryPath = configurationDirectoryPath;
CachePath = cacheDirectoryPath;
WebPath = webDirectoryPath;
DataPath = Path.Combine(ProgramDataPath, "data");
}
/// <summary>
/// Gets the path to the program data folder
/// </summary>
/// <value>The program data path.</value>
public string ProgramDataPath { get; private set; }
/// <summary>
/// Gets the path to the web UI resources folder
/// </summary>
/// <value>The web UI resources path.</value>
public string WebPath { get; set; }
/// <summary>
/// Gets the path to the system folder
/// </summary>
public string ProgramSystemPath { get; private set; }
public string ProgramSystemPath { get; } = AppContext.BaseDirectory;
/// <summary>
/// The _data directory
/// </summary>
private string _dataDirectory;
/// <summary>
/// Gets the folder path to the data directory
/// </summary>
/// <value>The data directory.</value>
private string _dataPath;
public string DataPath
{
get
{
if (_dataDirectory == null)
{
_dataDirectory = Path.Combine(ProgramDataPath, "data");
Directory.CreateDirectory(_dataDirectory);
}
return _dataDirectory;
}
get => _dataPath;
private set => _dataPath = Directory.CreateDirectory(value).FullName;
}
private const string _virtualDataPath = "%AppDataPath%";
public string VirtualDataPath => _virtualDataPath;
/// <summary>
/// Gets the magic strings used for virtual path manipulation.
/// </summary>
public string VirtualDataPath { get; } = "%AppDataPath%";
/// <summary>
/// Gets the image cache path.
@@ -75,61 +80,17 @@ namespace Emby.Server.Implementations.AppBase
/// <value>The plugin configurations path.</value>
public string PluginConfigurationsPath => Path.Combine(PluginsPath, "configurations");
/// <summary>
/// Gets the path to where temporary update files will be stored
/// </summary>
/// <value>The plugin configurations path.</value>
public string TempUpdatePath => Path.Combine(ProgramDataPath, "updates");
/// <summary>
/// The _log directory
/// </summary>
private string _logDirectoryPath;
/// <summary>
/// Gets the path to the log directory
/// </summary>
/// <value>The log directory path.</value>
public string LogDirectoryPath
{
get
{
if (string.IsNullOrEmpty(_logDirectoryPath))
{
_logDirectoryPath = Path.Combine(ProgramDataPath, "logs");
Directory.CreateDirectory(_logDirectoryPath);
}
return _logDirectoryPath;
}
set => _logDirectoryPath = value;
}
/// <summary>
/// The _config directory
/// </summary>
private string _configurationDirectoryPath;
public string LogDirectoryPath { get; private set; }
/// <summary>
/// Gets the path to the application configuration root directory
/// </summary>
/// <value>The configuration directory path.</value>
public string ConfigurationDirectoryPath
{
get
{
if (string.IsNullOrEmpty(_configurationDirectoryPath))
{
_configurationDirectoryPath = Path.Combine(ProgramDataPath, "config");
Directory.CreateDirectory(_configurationDirectoryPath);
}
return _configurationDirectoryPath;
}
set => _configurationDirectoryPath = value;
}
public string ConfigurationDirectoryPath { get; private set; }
/// <summary>
/// Gets the path to the system configuration file
@@ -137,29 +98,11 @@ namespace Emby.Server.Implementations.AppBase
/// <value>The system configuration file path.</value>
public string SystemConfigurationFilePath => Path.Combine(ConfigurationDirectoryPath, "system.xml");
/// <summary>
/// The _cache directory
/// </summary>
private string _cachePath;
/// <summary>
/// Gets the folder path to the cache directory
/// </summary>
/// <value>The cache directory.</value>
public string CachePath
{
get
{
if (string.IsNullOrEmpty(_cachePath))
{
_cachePath = Path.Combine(ProgramDataPath, "cache");
Directory.CreateDirectory(_cachePath);
}
return _cachePath;
}
set => _cachePath = value;
}
public string CachePath { get; set; }
/// <summary>
/// Gets the folder path to the temp directory within the cache folder

View File

@@ -79,7 +79,7 @@ namespace Emby.Server.Implementations.AppBase
get
{
// Lazy load
LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer, FileSystem));
LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationLoaded, ref _configurationSyncLock, () => (BaseApplicationConfiguration)ConfigurationHelper.GetXmlConfiguration(ConfigurationType, CommonApplicationPaths.SystemConfigurationFilePath, XmlSerializer));
return _configuration;
}
protected set
@@ -127,7 +127,7 @@ namespace Emby.Server.Implementations.AppBase
Logger.LogInformation("Saving system configuration");
var path = CommonApplicationPaths.SystemConfigurationFilePath;
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
lock (_configurationSyncLock)
{
@@ -171,16 +171,29 @@ namespace Emby.Server.Implementations.AppBase
private void UpdateCachePath()
{
string cachePath;
// If the configuration file has no entry (i.e. not set in UI)
if (string.IsNullOrWhiteSpace(CommonConfiguration.CachePath))
{
cachePath = null;
// If the current live configuration has no entry (i.e. not set on CLI/envvars, during startup)
if (string.IsNullOrWhiteSpace(((BaseApplicationPaths)CommonApplicationPaths).CachePath))
{
// Set cachePath to a default value under ProgramDataPath
cachePath = Path.Combine(((BaseApplicationPaths)CommonApplicationPaths).ProgramDataPath, "cache");
}
else
{
// Set cachePath to the existing live value; will require restart if UI value is removed (but not replaced)
// TODO: Figure out how to re-grab this from the CLI/envvars while running
cachePath = ((BaseApplicationPaths)CommonApplicationPaths).CachePath;
}
}
else
{
cachePath = Path.Combine(CommonConfiguration.CachePath, "cache");
// Set cachePath to the new UI-set value
cachePath = CommonConfiguration.CachePath;
}
Logger.LogInformation("Setting cache path to " + cachePath);
((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
}
@@ -197,7 +210,7 @@ namespace Emby.Server.Implementations.AppBase
&& !string.Equals(CommonConfiguration.CachePath ?? string.Empty, newPath))
{
// Validate
if (!FileSystem.DirectoryExists(newPath))
if (!Directory.Exists(newPath))
{
throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
}
@@ -209,8 +222,7 @@ namespace Emby.Server.Implementations.AppBase
protected void EnsureWriteAccess(string path)
{
var file = Path.Combine(path, Guid.NewGuid().ToString());
FileSystem.WriteAllText(file, string.Empty);
File.WriteAllText(file, string.Empty);
FileSystem.DeleteFile(file);
}
@@ -218,7 +230,7 @@ namespace Emby.Server.Implementations.AppBase
private string GetConfigurationFile(string key)
{
return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLower() + ".xml");
return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml");
}
public object GetConfiguration(string key)
@@ -246,14 +258,15 @@ namespace Emby.Server.Implementations.AppBase
private object LoadConfiguration(string path, Type configurationType)
{
if (!File.Exists(path))
{
return Activator.CreateInstance(configurationType);
}
try
{
return XmlSerializer.DeserializeFromFile(configurationType, path);
}
catch (FileNotFoundException)
{
return Activator.CreateInstance(configurationType);
}
catch (IOException)
{
return Activator.CreateInstance(configurationType);
@@ -293,7 +306,7 @@ namespace Emby.Server.Implementations.AppBase
_configurations.AddOrUpdate(key, configuration, (k, v) => configuration);
var path = GetConfigurationFile(key);
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
lock (_configurationSyncLock)
{

View File

@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Linq;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
namespace Emby.Server.Implementations.AppBase
@@ -18,9 +17,8 @@ namespace Emby.Server.Implementations.AppBase
/// <param name="type">The type.</param>
/// <param name="path">The path.</param>
/// <param name="xmlSerializer">The XML serializer.</param>
/// <param name="fileSystem">The file system</param>
/// <returns>System.Object.</returns>
public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
public static object GetXmlConfiguration(Type type, string path, IXmlSerializer xmlSerializer)
{
object configuration;
@@ -29,7 +27,7 @@ namespace Emby.Server.Implementations.AppBase
// Use try/catch to avoid the extra file system lookup using File.Exists
try
{
buffer = fileSystem.ReadAllBytes(path);
buffer = File.ReadAllBytes(path);
configuration = xmlSerializer.DeserializeFromBytes(type, buffer);
}
@@ -48,10 +46,10 @@ namespace Emby.Server.Implementations.AppBase
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !buffer.SequenceEqual(newBytes))
{
fileSystem.CreateDirectory(fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
// Save it after load in case we got new items
fileSystem.WriteAllBytes(path, newBytes);
File.WriteAllBytes(path, newBytes);
}
return configuration;

File diff suppressed because it is too large Load Diff

View File

@@ -14,11 +14,9 @@ namespace Emby.Server.Implementations.Archiving
/// </summary>
public class ZipClient : IZipClient
{
private readonly IFileSystem _fileSystem;
public ZipClient(IFileSystem fileSystem)
public ZipClient()
{
_fileSystem = fileSystem;
}
/// <summary>
@@ -29,7 +27,7 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = _fileSystem.OpenRead(sourceFile))
using (var fileStream = File.OpenRead(sourceFile))
{
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
}
@@ -115,7 +113,7 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = _fileSystem.OpenRead(sourceFile))
using (var fileStream = File.OpenRead(sourceFile))
{
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
}
@@ -155,7 +153,7 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = _fileSystem.OpenRead(sourceFile))
using (var fileStream = File.OpenRead(sourceFile))
{
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
}

View File

@@ -243,8 +243,7 @@ namespace Emby.Server.Implementations.Channels
{
foreach (var item in returnItems)
{
var task = RefreshLatestChannelItems(GetChannelProvider(item), CancellationToken.None);
Task.WaitAll(task);
RefreshLatestChannelItems(GetChannelProvider(item), CancellationToken.None).GetAwaiter().GetResult();
}
}
@@ -303,9 +302,7 @@ namespace Emby.Server.Implementations.Channels
}
numComplete++;
double percent = numComplete;
percent /= allChannelsList.Count;
double percent = (double)numComplete / allChannelsList.Count;
progress.Report(100 * percent);
}
@@ -355,7 +352,7 @@ namespace Emby.Server.Implementations.Channels
return;
}
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
_jsonSerializer.SerializeToFile(mediaSources, path);
}
@@ -658,9 +655,7 @@ namespace Emby.Server.Implementations.Channels
foreach (var item in result.Items)
{
var folder = item as Folder;
if (folder != null)
if (item is Folder folder)
{
await GetChannelItemsInternal(new InternalItemsQuery
{
@@ -834,7 +829,7 @@ namespace Emby.Server.Implementations.Channels
{
try
{
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
_jsonSerializer.SerializeToFile(result, path);
}

View File

@@ -35,64 +35,52 @@ namespace Emby.Server.Implementations.Channels
public static string GetUserDistinctValue(User user)
{
var channels = user.Policy.EnabledChannels
.OrderBy(i => i)
.ToList();
.OrderBy(i => i);
return string.Join("|", channels.ToArray());
return string.Join("|", channels);
}
private void CleanDatabase(CancellationToken cancellationToken)
{
var installedChannelIds = ((ChannelManager)_channelManager).GetInstalledChannelIds();
var databaseIds = _libraryManager.GetItemIds(new InternalItemsQuery
var uninstalledChannels = _libraryManager.GetItemList(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Channel).Name }
IncludeItemTypes = new[] { typeof(Channel).Name },
ExcludeItemIds = installedChannelIds.ToArray()
});
var invalidIds = databaseIds
.Except(installedChannelIds)
.ToList();
foreach (var id in invalidIds)
foreach (var channel in uninstalledChannels)
{
cancellationToken.ThrowIfCancellationRequested();
CleanChannel(id, cancellationToken);
CleanChannel((Channel)channel, cancellationToken);
}
}
private void CleanChannel(Guid id, CancellationToken cancellationToken)
private void CleanChannel(Channel channel, CancellationToken cancellationToken)
{
_logger.LogInformation("Cleaning channel {0} from database", id);
_logger.LogInformation("Cleaning channel {0} from database", channel.Id);
// Delete all channel items
var allIds = _libraryManager.GetItemIds(new InternalItemsQuery
var items = _libraryManager.GetItemList(new InternalItemsQuery
{
ChannelIds = new[] { id }
ChannelIds = new[] { channel.Id }
});
foreach (var deleteId in allIds)
foreach (var item in items)
{
cancellationToken.ThrowIfCancellationRequested();
DeleteItem(deleteId);
_libraryManager.DeleteItem(item, new DeleteOptions
{
DeleteFileLocation = false
}, false);
}
// Finally, delete the channel itself
DeleteItem(id);
}
private void DeleteItem(Guid id)
{
var item = _libraryManager.GetItemById(id);
if (item == null)
{
return;
}
_libraryManager.DeleteItem(item, new DeleteOptions
_libraryManager.DeleteItem(channel, new DeleteOptions
{
DeleteFileLocation = false

View File

@@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Channels
{
class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
{
private readonly IChannelManager _channelManager;
private readonly IUserManager _userManager;

View File

@@ -10,14 +10,18 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Collections
{
public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet>
{
public CollectionImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor)
public CollectionImageProvider(
IFileSystem fileSystem,
IProviderManager providerManager,
IApplicationPaths applicationPaths,
IImageProcessor imageProcessor)
: base(fileSystem, providerManager, applicationPaths, imageProcessor)
{
}
@@ -32,7 +36,7 @@ namespace Emby.Server.Implementations.Collections
return base.Supports(item);
}
protected override List<BaseItem> GetItemsWithImages(BaseItem item)
protected override IReadOnlyList<BaseItem> GetItemsWithImages(BaseItem item)
{
var playlist = (BoxSet)item;
@@ -70,12 +74,13 @@ namespace Emby.Server.Implementations.Collections
return null;
})
.Where(i => i != null)
.DistinctBy(i => i.Id)
.GroupBy(x => x.Id)
.Select(x => x.First())
.OrderBy(i => Guid.NewGuid())
.ToList();
}
protected override string CreateImage(BaseItem item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)
{
return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary);
}

View File

@@ -76,7 +76,7 @@ namespace Emby.Server.Implementations.Collections
return null;
}
_fileSystem.CreateDirectory(path);
Directory.CreateDirectory(path);
var libraryOptions = new LibraryOptions
{
@@ -133,7 +133,7 @@ namespace Emby.Server.Implementations.Collections
try
{
_fileSystem.CreateDirectory(path);
Directory.CreateDirectory(path);
var collection = new BoxSet
{
@@ -342,24 +342,22 @@ namespace Emby.Server.Implementations.Collections
{
private readonly CollectionManager _collectionManager;
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
private ILogger _logger;
public CollectionManagerEntryPoint(ICollectionManager collectionManager, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger)
public CollectionManagerEntryPoint(ICollectionManager collectionManager, IServerConfigurationManager config, ILogger logger)
{
_collectionManager = (CollectionManager)collectionManager;
_config = config;
_fileSystem = fileSystem;
_logger = logger;
}
public async void Run()
public async Task RunAsync()
{
if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted)
{
var path = _collectionManager.GetCollectionsFolderPath();
if (_fileSystem.DirectoryExists(path))
if (Directory.Exists(path))
{
try
{

View File

@@ -74,23 +74,14 @@ namespace Emby.Server.Implementations.Configuration
/// </summary>
private void UpdateMetadataPath()
{
string metadataPath;
if (string.IsNullOrWhiteSpace(Configuration.MetadataPath))
{
metadataPath = GetInternalMetadataPath();
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
}
else
{
metadataPath = Path.Combine(Configuration.MetadataPath, "metadata");
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Configuration.MetadataPath;
}
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = metadataPath;
}
private string GetInternalMetadataPath()
{
return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata");
}
/// <summary>
@@ -148,7 +139,7 @@ namespace Emby.Server.Implementations.Configuration
&& !string.Equals(Configuration.CertificatePath ?? string.Empty, newPath))
{
// Validate
if (!FileSystem.FileExists(newPath))
if (!File.Exists(newPath))
{
throw new FileNotFoundException(string.Format("Certificate file '{0}' does not exist.", newPath));
}
@@ -168,7 +159,7 @@ namespace Emby.Server.Implementations.Configuration
&& !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
{
// Validate
if (!FileSystem.DirectoryExists(newPath))
if (!Directory.Exists(newPath))
{
throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Emby.Server.Implementations
{
public static class ConfigurationOptions
{
public static readonly Dictionary<string, string> Configuration = new Dictionary<string, string>
{
{"HttpListenerHost:DefaultRedirectPath", "web/index.html"},
{"MusicBrainz:BaseUrl", "https://www.musicbrainz.org"}
};
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;
@@ -8,6 +10,39 @@ namespace Emby.Server.Implementations.Cryptography
{
public class CryptographyProvider : ICryptoProvider
{
private static readonly HashSet<string> _supportedHashMethods = new HashSet<string>()
{
"MD5",
"System.Security.Cryptography.MD5",
"SHA",
"SHA1",
"System.Security.Cryptography.SHA1",
"SHA256",
"SHA-256",
"System.Security.Cryptography.SHA256",
"SHA384",
"SHA-384",
"System.Security.Cryptography.SHA384",
"SHA512",
"SHA-512",
"System.Security.Cryptography.SHA512"
};
public string DefaultHashMethod => "PBKDF2";
private RandomNumberGenerator _randomNumberGenerator;
private const int _defaultIterations = 1000;
public CryptographyProvider()
{
//FIXME: When we get DotNet Standard 2.1 we need to revisit how we do the crypto
//Currently supported hash methods from https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptoconfig?view=netcore-2.1
//there might be a better way to autogenerate this list as dotnet updates, but I couldn't find one
//Please note the default method of PBKDF2 is not included, it cannot be used to generate hashes cleanly as it is actually a pbkdf with sha1
_randomNumberGenerator = RandomNumberGenerator.Create();
}
public Guid GetMD5(string str)
{
return new Guid(ComputeMD5(Encoding.Unicode.GetBytes(str)));
@@ -36,5 +71,98 @@ namespace Emby.Server.Implementations.Cryptography
return provider.ComputeHash(bytes);
}
}
public IEnumerable<string> GetSupportedHashMethods()
{
return _supportedHashMethods;
}
private byte[] PBKDF2(string method, byte[] bytes, byte[] salt, int iterations)
{
//downgrading for now as we need this library to be dotnetstandard compliant
//with this downgrade we'll add a check to make sure we're on the downgrade method at the moment
if (method == DefaultHashMethod)
{
using (var r = new Rfc2898DeriveBytes(bytes, salt, iterations))
{
return r.GetBytes(32);
}
}
throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
}
public byte[] ComputeHash(string hashMethod, byte[] bytes)
{
return ComputeHash(hashMethod, bytes, Array.Empty<byte>());
}
public byte[] ComputeHashWithDefaultMethod(byte[] bytes)
{
return ComputeHash(DefaultHashMethod, bytes);
}
public byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt)
{
if (hashMethod == DefaultHashMethod)
{
return PBKDF2(hashMethod, bytes, salt, _defaultIterations);
}
else if (_supportedHashMethods.Contains(hashMethod))
{
using (var h = HashAlgorithm.Create(hashMethod))
{
if (salt.Length == 0)
{
return h.ComputeHash(bytes);
}
else
{
byte[] salted = new byte[bytes.Length + salt.Length];
Array.Copy(bytes, salted, bytes.Length);
Array.Copy(salt, 0, salted, bytes.Length, salt.Length);
return h.ComputeHash(salted);
}
}
}
else
{
throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
}
}
public byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt)
{
return PBKDF2(DefaultHashMethod, bytes, salt, _defaultIterations);
}
public byte[] ComputeHash(PasswordHash hash)
{
int iterations = _defaultIterations;
if (!hash.Parameters.ContainsKey("iterations"))
{
hash.Parameters.Add("iterations", _defaultIterations.ToString(CultureInfo.InvariantCulture));
}
else
{
try
{
iterations = int.Parse(hash.Parameters["iterations"]);
}
catch (Exception e)
{
throw new InvalidDataException($"Couldn't successfully parse iterations value from string: {hash.Parameters["iterations"]}", e);
}
}
return PBKDF2(hash.Id, hash.HashBytes, hash.SaltBytes, iterations);
}
public byte[] GenerateSalt()
{
byte[] salt = new byte[64];
_randomNumberGenerator.GetBytes(salt);
return salt;
}
}
}

View File

@@ -224,7 +224,7 @@ namespace Emby.Server.Implementations.Data
});
}
db.ExecuteAll(string.Join(";", queries.ToArray()));
db.ExecuteAll(string.Join(";", queries));
Logger.LogInformation("PRAGMA synchronous=" + db.Query("PRAGMA synchronous").SelectScalarString().First());
}
@@ -232,23 +232,6 @@ namespace Emby.Server.Implementations.Data
protected virtual int? CacheSize => null;
internal static void CheckOk(int rc)
{
string msg = "";
if (raw.SQLITE_OK != rc)
{
throw CreateException((ErrorCode)rc, msg);
}
}
internal static Exception CreateException(ErrorCode rc, string msg)
{
var exp = new Exception(msg);
return exp;
}
private bool _disposed;
protected void CheckDisposed()
{
@@ -375,13 +358,6 @@ namespace Emby.Server.Implementations.Data
}
}
public class DummyToken : IDisposable
{
public void Dispose()
{
}
}
public static IDisposable Read(this ReaderWriterLockSlim obj)
{
//if (BaseSqliteRepository.ThreadSafeMode > 0)
@@ -390,6 +366,7 @@ namespace Emby.Server.Implementations.Data
//}
return new WriteLockToken(obj);
}
public static IDisposable Write(this ReaderWriterLockSlim obj)
{
//if (BaseSqliteRepository.ThreadSafeMode > 0)

View File

@@ -1,11 +1,8 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.IO;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Data
@@ -13,18 +10,12 @@ namespace Emby.Server.Implementations.Data
public class CleanDatabaseScheduledTask : ILibraryPostScanTask
{
private readonly ILibraryManager _libraryManager;
private readonly IItemRepository _itemRepo;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IApplicationPaths _appPaths;
public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IFileSystem fileSystem, IApplicationPaths appPaths)
public CleanDatabaseScheduledTask(ILibraryManager libraryManager, ILogger logger)
{
_libraryManager = libraryManager;
_itemRepo = itemRepo;
_logger = logger;
_fileSystem = fileSystem;
_appPaths = appPaths;
}
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)

View File

@@ -90,9 +90,10 @@ namespace Emby.Server.Implementations.Data
{
throw new ArgumentNullException(nameof(displayPreferences));
}
if (string.IsNullOrEmpty(displayPreferences.Id))
{
throw new ArgumentNullException(nameof(displayPreferences.Id));
throw new ArgumentException("Display preferences has an invalid Id", nameof(displayPreferences));
}
cancellationToken.ThrowIfCancellationRequested();

File diff suppressed because it is too large Load Diff

View File

@@ -119,9 +119,9 @@ namespace Emby.Server.Implementations.Data
{
list.Add(row[0].ReadGuidFromBlob());
}
catch
catch (Exception ex)
{
Logger.LogError(ex, "Error while getting user");
}
}
}

View File

@@ -55,6 +55,8 @@ namespace Emby.Server.Implementations.Data
{
TryMigrateToLocalUsersTable(connection);
}
RemoveEmptyPasswordHashes();
}
}
@@ -73,6 +75,38 @@ namespace Emby.Server.Implementations.Data
}
}
private void RemoveEmptyPasswordHashes()
{
foreach (var user in RetrieveAllUsers())
{
// If the user password is the sha1 hash of the empty string, remove it
if (!string.Equals(user.Password, "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal)
&& !string.Equals(user.Password, "$SHA1$DA39A3EE5E6B4B0D3255BFEF95601890AFD80709", StringComparison.Ordinal))
{
continue;
}
user.Password = null;
var serialized = _jsonSerializer.SerializeToBytes(user);
using (WriteLock.Write())
using (var connection = CreateConnection())
{
connection.RunInTransaction(db =>
{
using (var statement = db.PrepareStatement("update LocalUsersv2 set data=@data where Id=@InternalId"))
{
statement.TryBind("@InternalId", user.InternalId);
statement.TryBind("@data", serialized);
statement.MoveNext();
}
}, TransactionMode);
}
}
}
/// <summary>
/// Save a user in the repo
/// </summary>

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using MediaBrowser.Model.Reflection;
namespace Emby.Server.Implementations.Data
{
@@ -10,16 +9,13 @@ namespace Emby.Server.Implementations.Data
/// </summary>
public class TypeMapper
{
private readonly IAssemblyInfo _assemblyInfo;
/// <summary>
/// This holds all the types in the running assemblies so that we can de-serialize properly when we don't have strong types
/// </summary>
private readonly ConcurrentDictionary<string, Type> _typeMap = new ConcurrentDictionary<string, Type>();
public TypeMapper(IAssemblyInfo assemblyInfo)
public TypeMapper()
{
_assemblyInfo = assemblyInfo;
}
/// <summary>
@@ -45,8 +41,7 @@ namespace Emby.Server.Implementations.Data
/// <returns>Type.</returns>
private Type LookupType(string typeName)
{
return _assemblyInfo
.GetCurrentAssemblies()
return AppDomain.CurrentDomain.GetAssemblies()
.Select(a => a.GetType(typeName))
.FirstOrDefault(t => t != null);
}

View File

@@ -11,7 +11,6 @@ namespace Emby.Server.Implementations.Devices
{
private readonly IApplicationPaths _appPaths;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly object _syncLock = new object();
@@ -53,11 +52,11 @@ namespace Emby.Server.Implementations.Devices
{
var path = CachePath;
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
lock (_syncLock)
{
_fileSystem.WriteAllText(path, id, Encoding.UTF8);
File.WriteAllText(path, id, Encoding.UTF8);
}
}
catch (Exception ex)
@@ -86,19 +85,10 @@ namespace Emby.Server.Implementations.Devices
private string _id;
public DeviceId(
IApplicationPaths appPaths,
ILoggerFactory loggerFactory,
IFileSystem fileSystem)
public DeviceId(IApplicationPaths appPaths, ILoggerFactory loggerFactory)
{
if (fileSystem == null)
{
throw new ArgumentNullException(nameof(fileSystem));
}
_appPaths = appPaths;
_logger = loggerFactory.CreateLogger("SystemId");
_fileSystem = fileSystem;
}
public string Value => _id ?? (_id = GetDeviceId());

View File

@@ -34,8 +34,6 @@ namespace Emby.Server.Implementations.Devices
private readonly IFileSystem _fileSystem;
private readonly ILibraryMonitor _libraryMonitor;
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
private readonly INetworkManager _network;
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localizationManager;
@@ -55,17 +53,13 @@ namespace Emby.Server.Implementations.Devices
IUserManager userManager,
IFileSystem fileSystem,
ILibraryMonitor libraryMonitor,
IServerConfigurationManager config,
ILoggerFactory loggerFactory,
INetworkManager network)
IServerConfigurationManager config)
{
_json = json;
_userManager = userManager;
_fileSystem = fileSystem;
_libraryMonitor = libraryMonitor;
_config = config;
_logger = loggerFactory.CreateLogger(nameof(DeviceManager));
_network = network;
_libraryManager = libraryManager;
_localizationManager = localizationManager;
_authRepo = authRepo;
@@ -76,7 +70,7 @@ namespace Emby.Server.Implementations.Devices
public void SaveCapabilities(string deviceId, ClientCapabilities capabilities)
{
var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json");
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
lock (_capabilitiesSyncLock)
{
@@ -239,7 +233,7 @@ namespace Emby.Server.Implementations.Devices
path = Path.Combine(path, file.Name);
path = Path.ChangeExtension(path, MimeTypes.ToExtension(file.MimeType) ?? "jpg");
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
await EnsureLibraryFolder(uploadPathInfo.Item2, uploadPathInfo.Item3).ConfigureAwait(false);
@@ -275,7 +269,7 @@ namespace Emby.Server.Implementations.Devices
private void AddCameraUpload(string deviceId, LocalFileInfo file)
{
var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json");
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path));
lock (_cameraUploadSyncLock)
{
@@ -317,7 +311,7 @@ namespace Emby.Server.Implementations.Devices
return Task.CompletedTask;
}
_fileSystem.CreateDirectory(path);
Directory.CreateDirectory(path);
var libraryOptions = new LibraryOptions
{
@@ -414,24 +408,22 @@ namespace Emby.Server.Implementations.Devices
{
private readonly DeviceManager _deviceManager;
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
private ILogger _logger;
public DeviceManagerEntryPoint(IDeviceManager deviceManager, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger)
public DeviceManagerEntryPoint(IDeviceManager deviceManager, IServerConfigurationManager config, ILogger logger)
{
_deviceManager = (DeviceManager)deviceManager;
_config = config;
_fileSystem = fileSystem;
_logger = logger;
}
public async void Run()
public async Task RunAsync()
{
if (!_config.Configuration.CameraUploadUpgraded && _config.Configuration.IsStartupWizardCompleted)
{
var path = _deviceManager.GetUploadsPath();
if (_fileSystem.DirectoryExists(path))
if (Directory.Exists(path))
{
try
{

View File

@@ -9,14 +9,14 @@ namespace Emby.Server.Implementations.Diagnostics
{
public class CommonProcess : IProcess
{
public event EventHandler Exited;
private readonly ProcessOptions _options;
private readonly Process _process;
private bool _disposed = false;
private bool _hasExited;
public CommonProcess(ProcessOptions options)
{
_options = options;
StartInfo = options;
var startInfo = new ProcessStartInfo
{
@@ -27,10 +27,10 @@ namespace Emby.Server.Implementations.Diagnostics
CreateNoWindow = options.CreateNoWindow,
RedirectStandardError = options.RedirectStandardError,
RedirectStandardInput = options.RedirectStandardInput,
RedirectStandardOutput = options.RedirectStandardOutput
RedirectStandardOutput = options.RedirectStandardOutput,
ErrorDialog = options.ErrorDialog
};
startInfo.ErrorDialog = options.ErrorDialog;
if (options.IsHidden)
{
@@ -45,11 +45,22 @@ namespace Emby.Server.Implementations.Diagnostics
if (options.EnableRaisingEvents)
{
_process.EnableRaisingEvents = true;
_process.Exited += _process_Exited;
_process.Exited += OnProcessExited;
}
}
private bool _hasExited;
public event EventHandler Exited;
public ProcessOptions StartInfo { get; }
public StreamWriter StandardInput => _process.StandardInput;
public StreamReader StandardError => _process.StandardError;
public StreamReader StandardOutput => _process.StandardOutput;
public int ExitCode => _process.ExitCode;
private bool HasExited
{
get
@@ -72,25 +83,6 @@ namespace Emby.Server.Implementations.Diagnostics
}
}
private void _process_Exited(object sender, EventArgs e)
{
_hasExited = true;
if (Exited != null)
{
Exited(this, e);
}
}
public ProcessOptions StartInfo => _options;
public StreamWriter StandardInput => _process.StandardInput;
public StreamReader StandardError => _process.StandardError;
public StreamReader StandardOutput => _process.StandardOutput;
public int ExitCode => _process.ExitCode;
public void Start()
{
_process.Start();
@@ -105,10 +97,10 @@ namespace Emby.Server.Implementations.Diagnostics
{
return _process.WaitForExit(timeMs);
}
public Task<bool> WaitForExitAsync(int timeMs)
{
//Note: For this function to work correctly, the option EnableRisingEvents needs to be set to true.
// Note: For this function to work correctly, the option EnableRisingEvents needs to be set to true.
if (HasExited)
{
@@ -130,7 +122,29 @@ namespace Emby.Server.Implementations.Diagnostics
public void Dispose()
{
_process.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
_process?.Dispose();
}
_disposed = true;
}
private void OnProcessExited(object sender, EventArgs e)
{
_hasExited = true;
Exited?.Invoke(this, e);
}
}
}

View File

@@ -5,8 +5,6 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -21,8 +19,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
@@ -36,13 +32,9 @@ namespace Emby.Server.Implementations.Dto
private readonly IItemRepository _itemRepo;
private readonly IImageProcessor _imageProcessor;
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
private readonly IProviderManager _providerManager;
private readonly Func<IChannelManager> _channelManagerFactory;
private readonly IApplicationHost _appHost;
private readonly Func<IDeviceManager> _deviceManager;
private readonly Func<IMediaSourceManager> _mediaSourceManager;
private readonly Func<ILiveTvManager> _livetvManager;
@@ -52,12 +44,8 @@ namespace Emby.Server.Implementations.Dto
IUserDataManager userDataRepository,
IItemRepository itemRepo,
IImageProcessor imageProcessor,
IServerConfigurationManager config,
IFileSystem fileSystem,
IProviderManager providerManager,
Func<IChannelManager> channelManagerFactory,
IApplicationHost appHost,
Func<IDeviceManager> deviceManager,
Func<IMediaSourceManager> mediaSourceManager,
Func<ILiveTvManager> livetvManager)
{
@@ -66,12 +54,8 @@ namespace Emby.Server.Implementations.Dto
_userDataRepository = userDataRepository;
_itemRepo = itemRepo;
_imageProcessor = imageProcessor;
_config = config;
_fileSystem = fileSystem;
_providerManager = providerManager;
_channelManagerFactory = channelManagerFactory;
_appHost = appHost;
_deviceManager = deviceManager;
_mediaSourceManager = mediaSourceManager;
_livetvManager = livetvManager;
}
@@ -95,15 +79,8 @@ namespace Emby.Server.Implementations.Dto
return GetBaseItemDto(item, options, user, owner);
}
public BaseItemDto[] GetBaseItemDtos(List<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
{
return GetBaseItemDtos(items, items.Count, options, user, owner);
}
public BaseItemDto[] GetBaseItemDtos(BaseItem[] items, DtoOptions options, User user = null, BaseItem owner = null)
{
return GetBaseItemDtos(items, items.Length, options, user, owner);
}
public BaseItemDto[] GetBaseItemDtos(IReadOnlyList<BaseItem> items, DtoOptions options, User user = null, BaseItem owner = null)
=> GetBaseItemDtos(items, items.Count, options, user, owner);
public BaseItemDto[] GetBaseItemDtos(IEnumerable<BaseItem> items, int itemCount, DtoOptions options, User user = null, BaseItem owner = null)
{
@@ -374,10 +351,6 @@ namespace Emby.Server.Implementations.Dto
dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo);
dto.SongCount = taggedItems.Count(i => i is Audio);
}
else if (item is GameGenre)
{
dto.GameCount = taggedItems.Count(i => i is Game);
}
else
{
// This populates them all and covers Genre, Person, Studio, Year
@@ -385,7 +358,6 @@ namespace Emby.Server.Implementations.Dto
dto.ArtistCount = taggedItems.Count(i => i is MusicArtist);
dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum);
dto.EpisodeCount = taggedItems.Count(i => i is Episode);
dto.GameCount = taggedItems.Count(i => i is Game);
dto.MovieCount = taggedItems.Count(i => i is Movie);
dto.TrailerCount = taggedItems.Count(i => i is Trailer);
dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo);
@@ -532,17 +504,6 @@ namespace Emby.Server.Implementations.Dto
dto.Album = item.Album;
}
private static void SetGameProperties(BaseItemDto dto, Game item)
{
dto.GameSystem = item.GameSystem;
dto.MultiPartGameFiles = item.MultiPartGameFiles;
}
private static void SetGameSystemProperties(BaseItemDto dto, GameSystem item)
{
dto.GameSystem = item.GameSystemName;
}
private string[] GetImageTags(BaseItem item, List<ItemImageInfo> images)
{
return images
@@ -636,7 +597,8 @@ namespace Emby.Server.Implementations.Dto
}
}).Where(i => i != null)
.DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
.GroupBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
.Select(x => x.First())
.ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
for (var i = 0; i < people.Count; i++)
@@ -698,11 +660,6 @@ namespace Emby.Server.Implementations.Dto
return _libraryManager.GetMusicGenreId(name);
}
if (owner is Game || owner is GameSystem)
{
return _libraryManager.GetGameGenreId(name);
}
return _libraryManager.GetGenreId(name);
}
@@ -1206,20 +1163,6 @@ namespace Emby.Server.Implementations.Dto
}
}
var game = item as Game;
if (game != null)
{
SetGameProperties(dto, game);
}
var gameSystem = item as GameSystem;
if (gameSystem != null)
{
SetGameSystemProperties(dto, gameSystem);
}
var musicVideo = item as MusicVideo;
if (musicVideo != null)
{
@@ -1428,7 +1371,7 @@ namespace Emby.Server.Implementations.Dto
var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary);
ImageSize size;
ImageDimensions size;
var defaultAspectRatio = item.GetDefaultPrimaryImageAspectRatio();
@@ -1439,9 +1382,9 @@ namespace Emby.Server.Implementations.Dto
return defaultAspectRatio;
}
double dummyWidth = 200;
double dummyHeight = dummyWidth / defaultAspectRatio;
size = new ImageSize(dummyWidth, dummyHeight);
int dummyWidth = 200;
int dummyHeight = Convert.ToInt32(dummyWidth / defaultAspectRatio);
size = new ImageDimensions(dummyWidth, dummyHeight);
}
else
{
@@ -1452,7 +1395,7 @@ namespace Emby.Server.Implementations.Dto
try
{
size = _imageProcessor.GetImageSize(item, imageInfo);
size = _imageProcessor.GetImageDimensions(item, imageInfo);
if (size.Width <= 0 || size.Height <= 0)
{
@@ -1481,7 +1424,7 @@ namespace Emby.Server.Implementations.Dto
var width = size.Width;
var height = size.Height;
if (width.Equals(0) || height.Equals(0))
if (width <= 0 || height <= 0)
{
return null;
}

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
@@ -9,12 +9,10 @@
<ProjectReference Include="..\MediaBrowser.Providers\MediaBrowser.Providers.csproj" />
<ProjectReference Include="..\MediaBrowser.WebDashboard\MediaBrowser.WebDashboard.csproj" />
<ProjectReference Include="..\MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj" />
<ProjectReference Include="..\SocketHttpListener\SocketHttpListener.csproj" />
<ProjectReference Include="..\Emby.Dlna\Emby.Dlna.csproj" />
<ProjectReference Include="..\Mono.Nat\Mono.Nat.csproj" />
<ProjectReference Include="..\MediaBrowser.Api\MediaBrowser.Api.csproj" />
<ProjectReference Include="..\MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj" />
<ProjectReference Include="..\OpenSubtitlesHandler\OpenSubtitlesHandler.csproj" />
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
<ProjectReference Include="..\Emby.Drawing\Emby.Drawing.csproj" />
<ProjectReference Include="..\Emby.XmlTv\Emby.XmlTv\Emby.XmlTv.csproj" />
@@ -22,12 +20,20 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
<PackageReference Include="ServiceStack.Text.Core" Version="5.4.0" />
<PackageReference Include="sharpcompress" Version="0.22.0" />
<PackageReference Include="SimpleInjector" Version="4.4.2" />
<PackageReference Include="SQLitePCL.pretty.core" Version="1.1.8" />
<PackageReference Include="SQLitePCLRaw.core" Version="1.1.11" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="1.0.0" />
<PackageReference Include="UTF.Unknown" Version="1.0.0-beta1" />
</ItemGroup>
@@ -40,11 +46,26 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<!-- Code analysers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.6.3" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\iso6392.txt" />
<EmbeddedResource Include="Localization\countries.json" />
<EmbeddedResource Include="Localization\Core\*.json" />
<EmbeddedResource Include="Localization\Ratings\*.txt" />
<EmbeddedResource Include="Localization\Ratings\*.csv" />
</ItemGroup>
</Project>

View File

@@ -9,7 +9,6 @@ using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.EntryPoints
@@ -22,11 +21,10 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly ISessionManager _sessionManager;
private readonly IServerConfigurationManager _config;
private readonly ILiveTvManager _liveTvManager;
private readonly ITimerFactory _timerFactory;
private ITimer _timer;
private Timer _timer;
public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager, ITimerFactory timerFactory)
public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager)
{
_appHost = appHost;
_logger = logger;
@@ -34,15 +32,16 @@ namespace Emby.Server.Implementations.EntryPoints
_sessionManager = sessionManager;
_config = config;
_liveTvManager = liveTvManager;
_timerFactory = timerFactory;
}
public void Run()
public Task RunAsync()
{
if (_appHost.CanSelfRestart)
{
_appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged;
}
return Task.CompletedTask;
}
void _appHost_HasPendingRestartChanged(object sender, EventArgs e)
@@ -51,7 +50,7 @@ namespace Emby.Server.Implementations.EntryPoints
if (_appHost.HasPendingRestart)
{
_timer = _timerFactory.Create(TimerCallback, null, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));
_timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));
}
}

Some files were not shown because too many files have changed in this diff Show More