diff options
author | V3n3RiX <venerix@redcorelinux.org> | 2017-10-09 18:53:29 +0100 |
---|---|---|
committer | V3n3RiX <venerix@redcorelinux.org> | 2017-10-09 18:53:29 +0100 |
commit | 4f2d7949f03e1c198bc888f2d05f421d35c57e21 (patch) | |
tree | ba5f07bf3f9d22d82e54a462313f5d244036c768 /net-misc/mediatomb |
reinit the tree, so we can have metadata
Diffstat (limited to 'net-misc/mediatomb')
18 files changed, 2708 insertions, 0 deletions
diff --git a/net-misc/mediatomb/Manifest b/net-misc/mediatomb/Manifest new file mode 100644 index 000000000000..81ac542726b7 --- /dev/null +++ b/net-misc/mediatomb/Manifest @@ -0,0 +1,22 @@ +AUX mediatomb-0.12.0.confd 805 SHA256 21b1b9d31a6db76c5c1ccfbf00e5cd553eecfeb0e2bb161ccc024eab2243293c SHA512 74d2866c749272fe71e97e73ddf349070c51879967e7fd55716bb2dfc49f89d80d0655ac05e01fdb107fb057a62540116dcebdda87840b16c7bd11962c12065c WHIRLPOOL 3b545b860f61c5a91db2d9ba0ee8a30b572bb073ae7a82456488a2d8bacfa03e89218722d6e072ed7ab32f995bc5465f8da53c5bdaa4a049eb5d7caa8a71c5d8 +AUX mediatomb-0.12.0.config 6180 SHA256 cb43e92639e5e53908567c050c9a2fc0e5c349fd11a149414590c2c6a402b4d2 SHA512 310f408d6925ac7c2a4b5cbb0a8a854ba41c8aaa678b1e1805649e73be86d9e438da2fce7731df0e244b78271da98751e66624af15328633833603f7645be081 WHIRLPOOL abc2ad05aa92fa540ea4c69db24e205fa84babd308ff769eda68a7e4d68c004b96191c63566db71a308a2c309b10999ab9925af8e00cbf9caa90e16d90467871 +AUX mediatomb-0.12.1-flac-metadata.patch 17889 SHA256 ef5823f1987ed9f449f16030723258598ad192f2806a7e0404774ee0bad29e6c SHA512 e72e162576beb5f19518088f797b49ea81df52d32da2709bfd9f8841a3625d91ee0c7365d418d7469cf1162ca7840e3862b45ba3eb959549ec0d84e6428bc759 WHIRLPOOL 5bb571239fdacff5e86517b6757db69291e74a569e2a3671ad87c4dc91b27e2d121aca514776fa4b3bd8ddc767c46a692b29b15a4b0adb9635960b34e8f2d158 +AUX mediatomb-0.12.1-inotify-hard-links.patch 1483 SHA256 7a7475305d0d5376884e31c5220e9cad281a401a5ee6a4cf4243f084e9975832 SHA512 f9062fc0fa86045b325bbc38a9b31142c1d6e6227e2560f6429390917f675e5d9b3e4910b957b9bf3337b88f79cd2f66353fcd5460218a619303342670592206 WHIRLPOOL 4945f0bf2e21054764c8eeeebb398d3a8817b518f2ad1063ebc8464d73fb1a8dfae4d0d6d871726731fbb225c3d4a2d0155896e068dd9e444ac3d884b4b479d9 +AUX mediatomb-0.12.1-libextractor.patch 21074 SHA256 19f71fc190683056bb5f920a012bb06f10ea8c8680702fa1e5f166293aaf14bd SHA512 c71f872b98f8928baf5c53e5dad59efea622429f8b9e8b257afef53f263b7090fc986dc29e68a2d6164f60c1b74080804b4550b99f5613533001246a5336a77f WHIRLPOOL fb6c4331215d1cf13542627f0b961515e0c6aee4e7d10fb8228b06a4db71f75dd0a7276678b74a175c313d081a58e74734d11dd4620e3234da2054e450332be7 +AUX mediatomb-0.12.1-libmp4v2.patch 5893 SHA256 d39c2f9aab051c5447461718fd0ec72cf5982f6c920a4a985a50831f34babe84 SHA512 8e712c13de6e129a9a0b0805fc00c3af92bc3cedb583fa3e068c27d57ed52ad3b4c777bd92a6b073e2fee88376a28ce4d2467e97ab8ae2f9ea3ed7a64a0e45d3 WHIRLPOOL 6d8c1c06db3aed67f920f40176cd389ac84d7294b78ec5ca3f61920977fde8cbe49dac6bffe1050f97aca15af5fa4a743d947e3cba8f6a3ef9b0370bff7dac67 +AUX mediatomb-0.12.1-mozjs187.patch 8019 SHA256 4f502ead6b2620d188b2e8eeb01e353960d0527ffa46edb7dd73793d2e1343e2 SHA512 dc647eb34e508ac3ccdfc578b30e181da5aad60677a912e7a02967226a22e9f61f3123d84422c9ccd27cbba451b928b939cab3550286342bb662a319b097c66b WHIRLPOOL c09ccd53ca0d619e71e7a1fe3fb223896c8176f212b489012bdc6f5e894ac375622168448225b6cf0527ce527e426a26360ea22a520a4c66bc1a804ed0eb616a +AUX mediatomb-0.12.1-system-ar.patch 1008 SHA256 473ebc6ba78fb21c21512c4e61be8e820f097150e28e2098a04a66a863293029 SHA512 7b07d96769b18f22b3d096ff949cd176fd5f1eb2305fc7dd0df7080326ba1c33ac17b18875453c24d585c4334834aac42d80faac511c11d08c9fc3185f4fc94d WHIRLPOOL 1ac74952948bdc8eee574848ee3febd68dba5dc5a6393adfc7e97ba69bf5a132133a7345677d9ad255a4273469e909535310101dc8c66b53ff7bd9b2d31e4397 +AUX mediatomb-0.12.1-system-uuid.patch 954 SHA256 ec6ad3d71a7ea9ed3adb284aaa6bf57f435f05738f4e20d1f49eefa7e8051780 SHA512 68ac4bca71ac5f2e52daffb58d54199ddc87a7cfd02b89e93bc0c1b4496b95f6c82c0d362d36f37d3a9076c3bfb5d018df809fb485ca687923e5e1b78e6bf4bf WHIRLPOOL 88adbe3f19493314609dea727c6b57b272095396358a14921e966cf3cfab86a3754fe5321d855b3980f7c22a38bf7c18d774b58a60f8a82abed945dc047b24f9 +AUX mediatomb-0.12.1-thumb-cache.patch 8347 SHA256 06620757320e7c04d278f4d0e020aed68c0741f21b15cc985356e8cfb5a00808 SHA512 8c919394f414dd029980916b082aeb567bda096b0e965cc95cfebc25bc7834af199eca4a0f46fc1b27131a48db349a227092ea20c5c5e1b64fbe93e2c13f2e44 WHIRLPOOL 39885a5ce5ef4025c72a2f7e0c0cfc7076c73de48edb27a74abaf491fa027cac265b4617bd69ae94de9b3e63a3c95aaeca124e16c19dce10d5996927559c6129 +AUX mediatomb-0.12.1-thumbnail-locking.patch 4992 SHA256 7c760d4f74dceda8298b44a970b738b375237011d688cea56c584269c96128f7 SHA512 ebe283cb5a56412b80d25a712323628bd40cf3cdde94420dd8e382f52280b8c06e0009ff6a6d0c8531e653cb37e58bbedbf6c61bbd7232d05695628718a55976 WHIRLPOOL 1819c41c3ab162478d2975889f980f52e73672d96cb496af89a8ee70699f2ff386ea4b9973ba60add41e08295958a358eb02be94968a2ea862a8a6e7cf35dfa2 +AUX mediatomb-0.12.1-time-t.patch 2999 SHA256 7fe3a1a73663e6a2d1a188a73c17902da6f7ce169fc8ac3c9e22505e5569e1a3 SHA512 db993ea515e334b85e79f70373ac367f4951fa71b0d648ed67b5e6b4e5a596603ae0352a28411edf730f9b6e7ffa83d9c2ba9f0b4dc7c0e291a17a79cfd50d94 WHIRLPOOL 8ac0e84d9fb13ecb36912e2fac5f6e2326fdf1faced97094dd2e9a5c3e4d91e20e312eb42a5ab80ebeb3d8ce3f3889384580f49f2e9f01e257ed253a06518a00 +AUX mediatomb-0.12.1-youtube-dl.patch 4704 SHA256 76342683dea21e8566f599723658d4e90fb97c8d4d6dcc5c988115a308642667 SHA512 658e580499c17fb5a8f78c41095c38a94043c4e472b1996507b97229ab1fadd3c8044f9c3d27c8f210052e1c96b5ad88cf9e70daef9e98d2e740b9376eb7f102 WHIRLPOOL 3c9055ce23dd87651fe41e354ffc78bb0d3215456f8c0d8268fa968e7bf0d923971615820101fcf60b527305a1a8f9d4413ce0a9d5367fd3dc195f4579dfa020 +AUX mediatomb-0.12.1.initd 833 SHA256 6e79329e8d703d1181e49f188f153a591a2611da5a09b03050022352287fce52 SHA512 a7fd0f7dee5ec657ac139fcfa2d81eeb914e7107df73afa70aa31f40f8cd60faa469ab582aabc235f3b3cd77859ba524da0d79a913479a79dadc7c0f41c90c34 WHIRLPOOL 195dd8121c63917081d2be987622abc2e7679482223b5fc4f673e5387d68b30d574798b46c00420a8824ee7fb9b492adf30264241b932cbe437361ac76a4eba2 +DIST mediatomb-0.12.1.tar.gz 1240612 SHA256 31163c34a7b9d1c9735181737cb31306f29f1f2a0335fb4f53ecccf8f62f11cd SHA512 36e7269a532a79c91b4ea7be36f92cbefa913a1f856e422e46fe2b97ee7a569dd20c38b0cbe651a8e7faacde892ea18f3cac66c3c0737480c44f9b9bc3a45438 WHIRLPOOL 6a9e294aa9f8f40850863a86bae4fd6a81d198d7f4cf34d67a6a0cd568c387ef0f0bd5a3524c7bc05cb304f4e86dd0c12dc773bd1034c1924af6919cc740177b +DIST mediatomb-0.12.2_pre20160522.tar.gz 2415058 SHA256 30df1c8c57dcc2e90d5f0f9ed3c4613cc798aeae21e8541c6668be0066d7c4b9 SHA512 b45c81f548013b8fc0de84e02e47c8acbf21c359a6c41a5f13addfdd9d084ee58b23b776da4dce4da1f924a80a02835c622245165da09107c0b89786e5a69804 WHIRLPOOL cbdbccbe5a0e09a1fd8948382f96e696ab752a66a355eeb3a0eb49d0e75641567870e2979b375724d795362ad265786509a5bd53f6d74d27914ceaa714ec4dc8 +DIST mediatomb_0.12.1-5.debian.tar.gz 36001 SHA256 bfbc971eeaeb09791d4cf1b1102a19ca9ce69d67c97608bba7b8ce3b519a8625 SHA512 420cf0d4fc0aa82337f2893ef18f04f9d079d833f2540d6bee504d423e8acee5e5ae528d97f5cd4228d6648777c62d6186532f7a74d3d0cb04f9226a2de1dd95 WHIRLPOOL 3d826181f97873fc9acb67fa5a3171b9e0c60862066cc0dd29e05a4f793828fbcfb438dd1375d56144933d101824a4f498b5dbf1e269e3bb12e4ee53d9b13d59 +EBUILD mediatomb-0.12.1-r8.ebuild 4323 SHA256 6903d90f8ad5c3bd3d3720c1316ba8719921519e082dcbd4f7bab99672a361d4 SHA512 553a9a3acdfdc32d807b3f081e6322d8156f95951e7e0926f18994410548c341a3343acdb54a6e883c3e65229868fb2427221ac0a531d31673022c5d9beb2bd6 WHIRLPOOL 3e0d0339cf1de52dd2b3eb8dc3dcfacfc2db0241b535204110122b43b5deec32a8a33c04ed25d0797da93c1263316c14d5335edea06a00d4363ea41aae254872 +EBUILD mediatomb-0.12.2_pre20160522.ebuild 3247 SHA256 0507f1643f2556f3e4fbb8ba62fbc6be133ad73fae106bf615f8213385b579ed SHA512 bca0467f059b565e4fda74395c186e2d7373fbbf3bad50d485e314c932ddf67e45e3aaf7b9e728a11dbe169df93f386b164a9441b4301a52a67ea3fb0f2d2c63 WHIRLPOOL 9e9c88b5df9fc0bee63ee1a2a6054faaff9c6395857cb6cdd5606b043dc04daf26c7abd8a66b2f8975772045b0508aa4029db57d6ff158237e174cb89f6c903f +MISC ChangeLog 4659 SHA256 f7f1fee2349c7e0e870931682bd2cc61c7cf9213973f1a3e3970d7229f76a9b8 SHA512 25a1b667ae9898b2ba4fee91855660d86056eb96f62977a377bf13b829cbf4db563ecdc5f0b0584c4c3a2c5092b000f9d39a9a7cde126ec8f6ca914611c2a9af WHIRLPOOL 5cf4470914a22c55e2aa73b0d637c058baea88487a455c27c007633928f989971f22e5d3b4ed56474c58fa4892403be9fc3b878b71b6fde2478e0f16df9237b2 +MISC ChangeLog-2015 11779 SHA256 540c4932f91dfc02cc15169cca1d0850b7a34c32334a3cb6eb6feea8dc74a7fd SHA512 3ad48e5ee61f984263320f8b7f42dcb6878953d97ef21e4d789bea4fd63597a6edf37227be94e442db89158ca93bc17c7eb07d78fa5ae44f2d5e2b7c259cbbc7 WHIRLPOOL 9f053d26641438c1c909da2ea8001192eef1a03f0b0f474bab59bc19b01b6ec873e98d5704b850421504c2f00ab19cfdfd74bd51f47ea4d0f572282533eeb944 +MISC metadata.xml 1407 SHA256 b46441247428bfb76509f1cc0dd257ee744f0206c166135b5ace588ffef6c6f0 SHA512 667d62c12d0e8d9726a16fe683ed55998541f40c00fe26a9d4a5aebd5b717274167b7f22517592802b30535d085cde79b76472976ee77560cce4ba5a7ff38541 WHIRLPOOL 139975ac6eb5278618a9539025a15ac9778f97fa8b567d28ff369fa7871425155ec29a99de8cfac0fe81f69e2d599ec22d0741b5f9312266b9f35e08459b7903 diff --git a/net-misc/mediatomb/files/mediatomb-0.12.0.confd b/net-misc/mediatomb/files/mediatomb-0.12.0.confd new file mode 100644 index 000000000000..7f5c00830251 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.0.confd @@ -0,0 +1,28 @@ +# /etc/conf.d/mediatomb: config file for /etc/init.d/mediatomb + +# See the mediatomb(1) manpage for more info. + +# MediaTomb Web UI port. +# NOTE: The minimum value allowed is 49152 +MEDIATOMB_PORT=49152 + +# Run MediaTomb as this user. +# NOTE: For security reasons do not run MediaTomb as root. +MEDIATOMB_USER="mediatomb" + +# Run MediaTomb as this group. +# NOTE: For security reasons do not run MediaTomb as root. +MEDIATOMB_GROUP="mediatomb" + +# Path to MediaTomb config file. +MEDIATOMB_CONFIG="/etc/mediatomb/config.xml" + +# Path to MediaTomb log file. +MEDIATOMB_LOGFILE="/var/log/mediatomb.log" + +# Path to MediaTomb pid file. +MEDIATOMB_PIDFILE="/var/run/mediatomb.pid" + +# Other options you want to pass to MediaTomb. +# Add "--interface ${MEDIATOMB_INTERFACE}" to bind to a named interface. +MEDIATOMB_OPTIONS="" diff --git a/net-misc/mediatomb/files/mediatomb-0.12.0.config b/net-misc/mediatomb/files/mediatomb-0.12.0.config new file mode 100644 index 000000000000..0cd03b15d8e8 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.0.config @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8"?> +<config version="2" xmlns="http://mediatomb.cc/config/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mediatomb.cc/config/2 http://mediatomb.cc/config/2.xsd"> + <server> + <ui enabled="yes" show-tooltips="yes"> + <accounts enabled="no" session-timeout="30"> + <account user="mediatomb" password="mediatomb"/> + </accounts> + </ui> + <name>MediaTomb</name> + <udn></udn> + <home>/var/lib/mediatomb</home> + <webroot>/usr/share/mediatomb/web</webroot> + <storage> + <sqlite3 enabled="yes"> + <database-file>mediatomb.db</database-file> + </sqlite3> + <mysql enabled="no"> + <host>host</host> + <database>database</database> + <username>username</username> + <password>password</password> + </mysql> + </storage> + <protocolInfo extend="yes"/> + <pc-directory upnp-hide="no"/> + <extended-runtime-options> + <ffmpegthumbnailer enabled="no"> + <thumbnail-size>160</thumbnail-size> + <seek-percentage>10</seek-percentage> + <filmstrip-overlay>no</filmstrip-overlay> + <workaround-bugs>no</workaround-bugs> + <image-quality>8</image-quality> + </ffmpegthumbnailer> + <mark-played-items enabled="no" suppress-cds-updates="yes"> + <string mode="prepend">*</string> + <mark> + <content>video</content> + </mark> + </mark-played-items> + <lastfm enabled="no"> + <username>username</username> + <password>password</password> + </lastfm> + </extended-runtime-options> + </server> + <import hidden-files="no"> + <scripting script-charset="UTF-8"> + <common-script>/usr/share/mediatomb/js/common.js</common-script> + <playlist-script>/usr/share/mediatomb/js/playlists.js</playlist-script> + <virtual-layout type="builtin"> + <import-script>/usr/share/mediatomb/js/import.js</import-script> + </virtual-layout> + </scripting> + <mappings> + <extension-mimetype ignore-unknown="no"> + <map from="mp3" to="audio/mpeg"/> + <map from="ogx" to="application/ogg"/> + <map from="ogv" to="video/ogg"/> + <map from="oga" to="audio/ogg"/> + <map from="ogg" to="audio/ogg"/> + <map from="ogm" to="video/ogg"/> + <map from="asf" to="video/x-ms-asf"/> + <map from="asx" to="video/x-ms-asf"/> + <map from="wma" to="audio/x-ms-wma"/> + <map from="wax" to="audio/x-ms-wax"/> + <map from="wmv" to="video/x-ms-wmv"/> + <map from="wvx" to="video/x-ms-wvx"/> + <map from="wm" to="video/x-ms-wm"/> + <map from="wmx" to="video/x-ms-wmx"/> + <map from="m3u" to="audio/x-mpegurl"/> + <map from="pls" to="audio/x-scpls"/> + <map from="flv" to="video/x-flv"/> + <map from="mkv" to="video/x-matroska"/> + <map from="mka" to="audio/x-matroska"/> + <map from="avi" to="video/divx"/> + <map from="m2ts" to="video/avc"/> + <map from="cr2" to="image/raw"/> + <map from="nef" to="image/raw"/> + </extension-mimetype> + <mimetype-upnpclass> + <map from="audio/*" to="object.item.audioItem.musicTrack"/> + <map from="video/*" to="object.item.videoItem"/> + <map from="image/*" to="object.item.imageItem"/> + </mimetype-upnpclass> + <mimetype-contenttype> + <treat mimetype="audio/mpeg" as="mp3"/> + <treat mimetype="application/ogg" as="ogg"/> + <treat mimetype="video/ogg" as="ogg"/> + <treat mimetype="audio/ogg" as="ogg"/> + <treat mimetype="audio/x-flac" as="flac"/> + <treat mimetype="image/jpeg" as="jpg"/> + <treat mimetype="audio/x-mpegurl" as="playlist"/> + <treat mimetype="audio/x-scpls" as="playlist"/> + <treat mimetype="audio/x-wav" as="pcm"/> + <treat mimetype="audio/L16" as="pcm"/> + <treat mimetype="video/x-msvideo" as="avi"/> + <treat mimetype="video/mp4" as="mp4"/> + <treat mimetype="audio/mp4" as="mp4"/> + <treat mimetype="video/divx" as="avi"/> + </mimetype-contenttype> + </mappings> + <online-content> + <YouTube enabled="no" refresh="28800" update-at-start="yes" purge-after="604800" racy-content="exclude" format="mp4" hd="no"> + <favorites user="NationalGeographic"/> + <playlists user="PlayStation"/> + <uploads user="Google"/> + <standardfeed feed="most_viewed" time-range="today"/> + <standardfeed feed="recently_featured" time-range="today"/> + </YouTube> + </online-content> + </import> + <transcoding enabled="no"> + <mimetype-profile-mappings> + <transcode mimetype="audio/ogg" using="audio2pcm"/> + <transcode mimetype="audio/x-flac" using="audio2pcm"/> + <transcode mimetype="video/ogg" using="video2mpeg"/> + <transcode mimetype="video/x-flv" using="video2mpeg"/> + </mimetype-profile-mappings> + <profiles> + <profile name="audio2pcm" enabled="yes" type="external"> + <mimetype>audio/L16</mimetype> + <accept-url>no</accept-url> + <first-resource>yes</first-resource> + <hide-original-resource>yes</hide-original-resource> + <accept-ogg-theora>no</accept-ogg-theora> + <sample-frequency>44100</sample-frequency> + <audio-channels>2</audio-channels> + <agent command="ffmpeg" arguments="-i %in -acodec pcm_s16be -ab 192k -ar 44100 -ac 2 -f s16be -y %out"/> + <buffer size="1048576" chunk-size="131072" fill-size="262144"/> + </profile> + <profile name="video2mpeg" enabled="yes" type="external"> + <mimetype>video/mpeg</mimetype> + <accept-url>no</accept-url> + <first-resource>yes</first-resource> + <hide-original-resource>yes</hide-original-resource> + <accept-ogg-theora>yes</accept-ogg-theora> + <sample-frequency>48000</sample-frequency> + <audio-channels>2</audio-channels> + <agent command="ffmpeg" arguments="-i %in -vcodec mpeg2video -b 4096k -r 25 -acodec mp2 -ab 192k -ar 48000 -ac 2 -async 1 -f dvd -threads 2 -y %out"/> + <buffer size="10485760" chunk-size="262144" fill-size="524288"/> + </profile> + </profiles> + </transcoding> +</config> diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-flac-metadata.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-flac-metadata.patch new file mode 100644 index 000000000000..0228dffd08d8 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-flac-metadata.patch @@ -0,0 +1,446 @@ +diff -urpN a/build/Makefile.am b/build/Makefile.am +--- a/build/Makefile.am 2010-03-22 21:39:46.000000000 +1100 ++++ b/build/Makefile.am 2013-12-16 10:16:32.426878578 +1100 +@@ -18,6 +18,7 @@ libmediatomb_a_CXXFLAGS = \ + $(ICONV_CXXFLAGS) \ + $(LIBMAGIC_CFLAGS) \ + $(ID3LIB_CFLAGS) \ ++ $(FLAC_CFLAGS) \ + $(LIBEXIF_CFLAGS) \ + $(ZLIB_CFLAGS) \ + $(PTHREAD_CFLAGS) \ +@@ -44,6 +45,7 @@ mediatomb_CXXFLAGS = -I$(top_srcdir)/src + $(ICONV_CXXFLAGS) \ + $(LIBMAGIC_CFLAGS) \ + $(ID3LIB_CFLAGS) \ ++ $(FLAC_CFLAGS) \ + $(LIBEXIF_CFLAGS) \ + $(ZLIB_CFLAGS) \ + $(PTHREAD_CFLAGS) \ +@@ -78,6 +80,7 @@ mediatomb_LDADD = \ + $(JS_LIBS) \ + $(LIBMAGIC_LIBS) \ + $(ID3LIB_LIBS) \ ++ $(FLAC_LIBS) \ + $(LIBEXIF_LIBS) \ + $(ZLIB_LIBS) \ + $(RT_LIBS) \ +diff -urpN a/build/libmediatomb_src b/build/libmediatomb_src +--- a/build/libmediatomb_src 2010-03-23 04:09:53.000000000 +1100 ++++ b/build/libmediatomb_src 2013-12-16 10:14:49.730356868 +1100 +@@ -98,6 +98,8 @@ libmediatomb_a_SOURCES = \ + ../src/metadata/libmp4v2_handler.h \ + ../src/metadata/taglib_handler.cc \ + ../src/metadata/taglib_handler.h \ ++../src/metadata/flac_handler.cc \ ++../src/metadata/flac_handler.h \ + ../src/mpegdemux/buffer.c \ + ../src/mpegdemux/buffer.h \ + ../src/mpegdemux/mpegdemux.c \ +diff -urpN a/configure.ac b/configure.ac +--- a/configure.ac 2010-04-08 08:38:51.000000000 +1000 ++++ b/configure.ac 2013-12-16 10:24:16.547793225 +1100 +@@ -1314,6 +1314,35 @@ LDFLAGS="$LDFLAGS_SAVE" + LIBS="$LIBS_SAVE" + CXXFLAGS="$CXXFLAGS_SAVE" + CPPFLAGS="$CPPFLAGS_SAVE" ++ ++######### FLAC ++ ++FLAC_STATUS= ++ ++MT_OPTION([FLAC], [enable], ++ [FLAC metadata extraction with the help of FLAC],[],[]) ++ ++if test "x$FLAC_OPTION_ENABLED" = xyes; then ++ MT_CHECK_PACKAGE([FLAC], ++ [FLAC/metadata], ++ [FLAC], [main]) ++else ++ FLAC_STATUS=disabled ++fi ++ ++if test "x$FLAC_STATUS" != xyes; then ++ if (test "x$FLAC_OPTION_REQUESTED" = xyes) && ++ (test "x$FLAC_OPTION_ENABLED" = xyes); then ++ AC_MSG_ERROR([unable to configure FLAC support]) ++ fi ++else ++ CFLAGS="$CFLAGS $FLAC_CFLAGS" ++ CXXFLAGS="$CXXFLAGS $FLAC_CFLAGS" ++ LDFLAGS="$LDFLAGS $FLAC_LDFLAGS $FLAC_LIBS" ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS ++fi ++ + ######## curl + + CURL_PROG_FOUND=0 +@@ -1914,7 +1943,7 @@ if (test "x$SOPCAST_OPTION_ENABLED" = xy + AC_DEFINE([SOPCAST], [1], [Enable support for the SopCast service]) + fi + +-AC_DEFINE_UNQUOTED([COMPILE_INFO], "\thost:\t\t\t$host\n\tsqlite3:\t\t$SQLITE3_STATUS\n\tmysql:\t\t\t$MYSQL_STATUS\n\tlibjs:\t\t\t$JS_OK\n\tlibmagic:\t\t$LIBMAGIC_STATUS\n\tinotify:\t\t$INOTIFY_STATUS\n\tlibexif:\t\t$LIBEXIF_STATUS\n\tid3lib:\t\t\t$ID3LIB_STATUS\n\ttaglib:\t\t\t$TAGLIB_STATUS\n\tffmpeg\t\t\t$FFMPEG_STATUS\n\tlibmp4v2:\t\t$LIBMP4V2_STATUS\n\texternal transcoding:\t$EXTERNAL_TRANSCODING_OPTION_ENABLED\n\tcurl:\t\t\t$CURL_OK\n\tYouTube:\t\t$YOUTUBE_OPTION_ENABLED\n\tlibextractor\t\t$LIBEXTRACTOR_STATUS\n\tdb-autocreate:\t\t$DB_AUTOCREATE_OPTION_ENABLED\n\tdebug log:\t\t$DEBUG_LOG_OPTION_ENABLED\n\tprotocol info extension:$PROTOCOLINFO_EXTENSION_OPTION_ENABLED\n\tffmpegthumbnailer:\t$FFMPEGTHUMBNAILER_STATUS\n\tlastfmlib:\t\t$LASTFMLIB_STATUS\n\tdata directory:\t\t$PACKAGE_DATADIR", [compile option summary]) ++AC_DEFINE_UNQUOTED([COMPILE_INFO], "\thost:\t\t\t$host\n\tsqlite3:\t\t$SQLITE3_STATUS\n\tmysql:\t\t\t$MYSQL_STATUS\n\tlibjs:\t\t\t$JS_OK\n\tlibmagic:\t\t$LIBMAGIC_STATUS\n\tinotify:\t\t$INOTIFY_STATUS\n\tlibexif:\t\t$LIBEXIF_STATUS\n\tid3lib:\t\t\t$ID3LIB_STATUS\n\ttaglib:\t\t\t$TAGLIB_STATUS\n\tFLAC:\t\t\t$FLAC_STATUS\n\tffmpeg\t\t\t$FFMPEG_STATUS\n\tlibmp4v2:\t\t$LIBMP4V2_STATUS\n\texternal transcoding:\t$EXTERNAL_TRANSCODING_OPTION_ENABLED\n\tcurl:\t\t\t$CURL_OK\n\tYouTube:\t\t$YOUTUBE_OPTION_ENABLED\n\tlibextractor\t\t$LIBEXTRACTOR_STATUS\n\tdb-autocreate:\t\t$DB_AUTOCREATE_OPTION_ENABLED\n\tdebug log:\t\t$DEBUG_LOG_OPTION_ENABLED\n\tprotocol info extension:$PROTOCOLINFO_EXTENSION_OPTION_ENABLED\n\tffmpegthumbnailer:\t$FFMPEGTHUMBNAILER_STATUS\n\tlastfmlib:\t\t$LASTFMLIB_STATUS\n\tdata directory:\t\t$PACKAGE_DATADIR", [compile option summary]) + + ############### + AC_CONFIG_FILES([ +@@ -1946,6 +1975,7 @@ echo "inotify : $INOTIFY_S + echo "libexif : $LIBEXIF_STATUS" + echo "id3lib : $ID3LIB_STATUS" + echo "taglib : $TAGLIB_STATUS" ++echo "FLAC : $FLAC_STATUS" + echo "libmp4v2 : $LIBMP4V2_STATUS" + echo "ffmpeg : $FFMPEG_STATUS" + echo "ffmpegthumbnailer : $FFMPEGTHUMBNAILER_STATUS" +diff -urpN a/src/cds_resource_manager.cc b/src/cds_resource_manager.cc +--- a/src/cds_resource_manager.cc 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/cds_resource_manager.cc 2013-12-16 10:25:15.277987292 +1100 +@@ -372,6 +372,7 @@ void CdsResourceManager::addResources(Re + // only add upnp:AlbumArtURI if we have an AA, skip the resource + if ((i > 0) && ((item->getResource(i)->getHandlerType() == CH_ID3) || + (item->getResource(i)->getHandlerType() == CH_MP4) || ++ (item->getResource(i)->getHandlerType() == CH_FLAC) || + (item->getResource(i)->getHandlerType() == CH_EXTURL))) + { + String rct; +diff -urpN a/src/config_manager.cc b/src/config_manager.cc +--- a/src/config_manager.cc 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/config_manager.cc 2013-12-16 10:26:57.220886235 +1100 +@@ -624,6 +624,10 @@ String ConfigManager::createDefaultConfi + _(CONTENT_TYPE_OGG))); + mtcontent->appendElementChild(treat_as(_("audio/x-flac"), + _(CONTENT_TYPE_FLAC))); ++ mtcontent->appendElementChild(treat_as(_("audio/x-ms-wma"), ++ _(CONTENT_TYPE_WMA))); ++ mtcontent->appendElementChild(treat_as(_("audio/x-wavpack"), ++ _(CONTENT_TYPE_WAVPACK))); + mtcontent->appendElementChild(treat_as(_("image/jpeg"), + _(CONTENT_TYPE_JPG))); + mtcontent->appendElementChild(treat_as(_("audio/x-mpegurl"), +diff -urpN a/src/metadata/flac_handler.cc b/src/metadata/flac_handler.cc +--- a/src/metadata/flac_handler.cc 1970-01-01 10:00:00.000000000 +1000 ++++ b/src/metadata/flac_handler.cc 2013-12-16 10:30:19.955604387 +1100 +@@ -0,0 +1,204 @@ ++/*MT* ++ ++ MediaTomb - http://www.mediatomb.cc/ ++ ++ flac_handler.cc - this file is part of MediaTomb. ++ ++ Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> ++ ++ Copyright (C) 2006-2009 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, ++ Leonhard Wimmer <leo@mediatomb.cc> ++ ++ MediaTomb is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 ++ as published by the Free Software Foundation. ++ ++ MediaTomb is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ version 2 along with MediaTomb; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ # $Id$ ++*/ ++ ++/// \file flac_handler.cc ++/// \brief Implementeation of the FlacHandler class. ++ ++#ifdef HAVE_CONFIG_H ++ #include "autoconfig.h" ++#endif ++ ++#ifdef HAVE_FLAC ++ ++#include <FLAC/all.h> ++ ++#include "flac_handler.h" ++#include "string_converter.h" ++#include "config_manager.h" ++#include "common.h" ++#include "tools.h" ++#include "mem_io_handler.h" ++ ++#include "content_manager.h" ++ ++using namespace zmm; ++ ++FlacHandler::FlacHandler() : MetadataHandler() ++{ ++} ++ ++static void addField(metadata_fields_t field, const FLAC__StreamMetadata* tags, Ref<CdsItem> item) ++{ ++ String value; ++ int i; ++ ++ Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure ++ ++ switch (field) ++ { ++ case M_TITLE: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "TITLE"); ++ break; ++ case M_ARTIST: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "ARTIST"); ++ break; ++ case M_ALBUM: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "ALBUM"); ++ break; ++ case M_DATE: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "DATE"); ++ break; ++ case M_GENRE: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "GENRE"); ++ break; ++ case M_DESCRIPTION: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "DESCRIPTION"); ++ break; ++ case M_TRACKNUMBER: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "TRACKNUMBER"); ++ break; ++ default: ++ return; ++ } ++ ++ if( 0 <= i ) ++ value = strchr((const char *)tags->data.vorbis_comment.comments[i].entry, '=') + 1; ++ else ++ return; ++ ++ value = trim_string(value); ++ ++ if (string_ok(value)) ++ { ++ item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); ++ log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str()); ++ } ++} ++ ++void FlacHandler::fillMetadata(Ref<CdsItem> item) ++{ ++ FLAC__StreamMetadata* tags = NULL; ++ FLAC__StreamMetadata streaminfo; ++ Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure ++ ++ if( !FLAC__metadata_get_tags(item->getLocation().c_str(), &tags) ) ++ return; ++ ++ if( FLAC__METADATA_TYPE_VORBIS_COMMENT == tags->type ) ++ { ++ for (int i = 0; i < M_MAX; i++) ++ addField((metadata_fields_t) i, tags, item); ++ } ++ ++ FLAC__metadata_object_delete(tags); ++ tags = NULL; ++ ++ if( !FLAC__metadata_get_streaminfo(item->getLocation().c_str(), &streaminfo) ) ++ return; ++ ++ if( FLAC__METADATA_TYPE_STREAMINFO == streaminfo.type ) ++ { ++ // note: UPnP requires bytes/second ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE), String::from((unsigned)((streaminfo.data.stream_info.bits_per_sample * streaminfo.data.stream_info.sample_rate) / 8))); ++ // note: UPnP requires HMS ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION), secondsToHMS((unsigned)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate))); ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), String::from(streaminfo.data.stream_info.sample_rate)); ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), String::from(streaminfo.data.stream_info.channels)); ++ } ++ ++ if( !FLAC__metadata_get_picture(item->getLocation().c_str(), ++ &tags, ++ FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER, ++ NULL, ++ NULL, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1 ) ) ++ return; ++ ++ if( FLAC__METADATA_TYPE_PICTURE == tags->type ) ++ { ++ String art_mimetype = tags->data.picture.mime_type; ++ log_debug("Mime type : %s\n", sc->convert(art_mimetype).c_str()); ++ ++ // saw that simply "PNG" was used with some mp3's, so mimetype setting ++ // was probably invalid ++ if (!string_ok(art_mimetype) || (art_mimetype.index('/') == -1)) ++ { ++#ifdef HAVE_MAGIC ++ art_mimetype = ContentManager::getInstance()->getMimeTypeFromBuffer((void *)tags->data.picture.data, tags->data.picture.data_length); ++ if (!string_ok(art_mimetype)) ++#endif ++ art_mimetype = _(MIMETYPE_DEFAULT); ++ ++ log_debug("Mime type via magic: %s\n", sc->convert(art_mimetype).c_str()); ++ } ++ ++ // if we could not determine the mimetype, then there is no ++ // point to add the resource - it's probably garbage ++ if (art_mimetype != _(MIMETYPE_DEFAULT)) ++ { ++ Ref<CdsResource> resource(new CdsResource(CH_FLAC)); ++ resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(art_mimetype)); ++ resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART)); ++ item->addResource(resource); ++ } ++ } ++ ++ FLAC__metadata_object_delete(tags); ++} ++ ++Ref<IOHandler> FlacHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) ++{ ++ FLAC__StreamMetadata* picture = NULL; ++ ++ if( !FLAC__metadata_get_picture(item->getLocation().c_str(), ++ &picture, ++ FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER, ++ NULL, ++ NULL, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1 ) ) ++ throw _Exception(_("FlacHandler: could not exctract cover from: ") + item->getLocation()); ++ ++ if( FLAC__METADATA_TYPE_PICTURE != picture->type ) ++ throw _Exception(_("TagHandler: resource has no album information")); ++ ++ Ref<IOHandler> h(new MemIOHandler((void *)picture->data.picture.data, picture->data.picture.data_length)); ++ *data_size = picture->data.picture.data_length; ++ ++ FLAC__metadata_object_delete(picture); ++ ++ return h; ++} ++ ++#endif // HAVE_FLAC +diff -urpN a/src/metadata/flac_handler.h b/src/metadata/flac_handler.h +--- a/src/metadata/flac_handler.h 1970-01-01 10:00:00.000000000 +1000 ++++ b/src/metadata/flac_handler.h 2013-12-16 10:31:24.061822827 +1100 +@@ -0,0 +1,47 @@ ++/*MT* ++ ++ MediaTomb - http://www.mediatomb.cc/ ++ ++ flac_handler.h - this file is part of MediaTomb. ++ ++ Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> ++ ++ Copyright (C) 2006-2009 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, ++ Leonhard Wimmer <leo@mediatomb.cc> ++ ++ MediaTomb is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 ++ as published by the Free Software Foundation. ++ ++ MediaTomb is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ version 2 along with MediaTomb; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ # $Id$ ++*/ ++ ++/// \file flac_handler.h ++/// \brief Definition of the FlacHandler class. ++ ++#ifndef __METADATA_FLAC_H__ ++#define __METADATA_FLAC_H__ ++ ++#include "metadata_handler.h" ++ ++/// \brief This class is responsible for reading FLAC metadata ++class FlacHandler : public MetadataHandler ++{ ++public: ++ FlacHandler(); ++ virtual void fillMetadata(zmm::Ref<CdsItem> item); ++ virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum, off_t *data_size); ++}; ++ ++#endif // __METADATA_FLAC_H__ +diff -urpN a/src/metadata_handler.cc b/src/metadata_handler.cc +--- a/src/metadata_handler.cc 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/metadata_handler.cc 2013-12-16 10:35:48.783540865 +1100 +@@ -51,6 +51,10 @@ + #endif // HAVE_ID3LIB + #endif // HAVE_TAGLIB + ++#ifdef HAVE_FLAC ++#include "metadata/flac_handler.h" ++#endif ++ + #ifdef HAVE_LIBMP4V2 + #include "metadata/libmp4v2_handler.h" + #endif +@@ -140,7 +144,8 @@ void MetadataHandler::setMetadata(Ref<Cd + if ((content_type == CONTENT_TYPE_MP3) || + ((content_type == CONTENT_TYPE_OGG) && + (!item->getFlag(OBJECT_FLAG_OGG_THEORA))) || +- (content_type == CONTENT_TYPE_FLAC)) ++ (content_type == CONTENT_TYPE_WMA) || ++ (content_type == CONTENT_TYPE_WAVPACK)) + { + handler = Ref<MetadataHandler>(new TagHandler()); + break; +@@ -155,7 +160,13 @@ void MetadataHandler::setMetadata(Ref<Cd + #endif // HAVE_ID3LIB + #endif // HAVE_TAGLIB + +- ++#ifdef HAVE_FLAC ++ if (content_type == CONTENT_TYPE_FLAC) ++ { ++ handler = Ref<MetadataHandler>(new FlacHandler()); ++ break; ++ } ++#endif + + #ifdef HAVE_EXIV2 + /* +@@ -277,6 +288,10 @@ Ref<MetadataHandler> MetadataHandler::cr + case CH_FFTH: + return Ref<MetadataHandler>(new FfmpegHandler()); + #endif ++#ifdef HAVE_FLAC ++ case CH_FLAC: ++ return Ref<MetadataHandler>(new FlacHandler()); ++#endif + default: + throw _Exception(_("unknown content handler ID: ") + handlerType); + } +diff -urpN a/src/metadata_handler.h b/src/metadata_handler.h +--- a/src/metadata_handler.h 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/metadata_handler.h 2013-12-16 10:52:23.234353526 +1100 +@@ -45,10 +45,13 @@ + #define CH_EXTURL 4 + #define CH_MP4 5 + #define CH_FFTH 6 ++#define CH_FLAC 7 + + #define CONTENT_TYPE_MP3 "mp3" + #define CONTENT_TYPE_OGG "ogg" + #define CONTENT_TYPE_FLAC "flac" ++#define CONTENT_TYPE_WMA "wma" ++#define CONTENT_TYPE_WAVPACK "wv" + #define CONTENT_TYPE_JPG "jpg" + #define CONTENT_TYPE_PLAYLIST "playlist" + #define CONTENT_TYPE_MP4 "mp4" diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch new file mode 100644 index 000000000000..af9a887befe0 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch @@ -0,0 +1,34 @@ +make sure new hard links get processed like new files by handling +the IN_CREATE flag properly + +patch by Mike Frysinger + +--- a/src/autoscan_inotify.cc ++++ b/src/autoscan_inotify.cc +@@ -281,7 +284,7 @@ + } + } + +- if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT)) ++ if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT | IN_CREATE)) + { + String fullPath; + if (mask & IN_ISDIR) +@@ -289,7 +292,7 @@ + else + fullPath = path; + +- if (! (mask & IN_MOVED_TO)) ++ if (! (mask & (IN_MOVED_TO | IN_CREATE))) + { + log_debug("deleting %s\n", fullPath.c_str()); + +@@ -312,7 +315,7 @@ + if (objectID != INVALID_OBJECT_ID) + cm->removeObject(objectID); + } +- if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO)) ++ if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE)) + { + log_debug("adding %s\n", path.c_str()); + // path, recursive, async, hidden, low priority, cancellable diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-libextractor.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-libextractor.patch new file mode 100644 index 000000000000..e46aca9c487f --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-libextractor.patch @@ -0,0 +1,675 @@ +http://bugs.gentoo.org/435394 + +port to libextractor-0.6.x + +patch by Mike Frysinger <vapier@gentoo.org> + +--- a/configure.ac ++++ b/configure.ac +@@ -1631,7 +1631,7 @@ MT_CHECK_OPTIONAL_PACKAGE([lastfmlib], [disable], + ######## extractor + + if test "x$LIBEXTRACTOR_OPTION_ENABLED" = xyes; then +- MT_CHECK_PACKAGE([libextractor], [extractor], [extractor], [EXTRACTOR_getKeywords]) ++ MT_CHECK_PACKAGE([libextractor], [extractor], [extractor], [EXTRACTOR_extract]) + fi + + if test "x$LIBEXTRACTOR_STATUS" = xyes; then +--- a/src/metadata/extractor_handler.cc ++++ b/src/metadata/extractor_handler.cc +@@ -55,322 +55,344 @@ ExtractorHandler::ExtractorHandler() : MetadataHandler() + { + } + +-static EXTRACTOR_KeywordType getTagFromString(String tag) ++static EXTRACTOR_MetaType getTagFromString(String tag) + { +- if (tag == "EXTRACTOR_UNKNOWN") +- return EXTRACTOR_UNKNOWN; +- if (tag == "EXTRACTOR_FILENAME") +- return EXTRACTOR_FILENAME; +- if (tag == "EXTRACTOR_MIMETYPE") +- return EXTRACTOR_MIMETYPE; +- if (tag == "EXTRACTOR_TITLE") +- return EXTRACTOR_TITLE; +- if (tag == "EXTRACTOR_AUTHOR") +- return EXTRACTOR_AUTHOR; +- if (tag == "EXTRACTOR_ARTIST") +- return EXTRACTOR_ARTIST; +- if (tag == "EXTRACTOR_DESCRIPTION") +- return EXTRACTOR_DESCRIPTION; +- if (tag == "EXTRACTOR_COMMENT") +- return EXTRACTOR_COMMENT; +- if (tag == "EXTRACTOR_DATE") +- return EXTRACTOR_DATE; +- if (tag == "EXTRACTOR_PUBLISHER") +- return EXTRACTOR_PUBLISHER; +- if (tag == "EXTRACTOR_LANGUAGE") +- return EXTRACTOR_LANGUAGE; +- if (tag == "EXTRACTOR_ALBUM") +- return EXTRACTOR_ALBUM; +- if (tag == "EXTRACTOR_GENRE") +- return EXTRACTOR_GENRE; +- if (tag == "EXTRACTOR_LOCATION") +- return EXTRACTOR_LOCATION; +- if (tag == "EXTRACTOR_VERSIONNUMBER") +- return EXTRACTOR_VERSIONNUMBER; +- if (tag == "EXTRACTOR_ORGANIZATION") +- return EXTRACTOR_ORGANIZATION; +- if (tag == "EXTRACTOR_COPYRIGHT") +- return EXTRACTOR_COPYRIGHT; +- if (tag == "EXTRACTOR_SUBJECT") +- return EXTRACTOR_SUBJECT; +- if (tag == "EXTRACTOR_KEYWORDS") +- return EXTRACTOR_KEYWORDS; +- if (tag == "EXTRACTOR_CONTRIBUTOR") +- return EXTRACTOR_CONTRIBUTOR; +- if (tag == "EXTRACTOR_RESOURCE_TYPE") +- return EXTRACTOR_RESOURCE_TYPE; +- if (tag == "EXTRACTOR_FORMAT") +- return EXTRACTOR_FORMAT; +- if (tag == "EXTRACTOR_RESOURCE_IDENTIFIER") +- return EXTRACTOR_RESOURCE_IDENTIFIER; +- if (tag == "EXTRACTOR_SOURCE") +- return EXTRACTOR_SOURCE; +- if (tag == "EXTRACTOR_RELATION") +- return EXTRACTOR_RELATION; +- if (tag == "EXTRACTOR_COVERAGE") +- return EXTRACTOR_COVERAGE; +- if (tag == "EXTRACTOR_SOFTWARE") +- return EXTRACTOR_SOFTWARE; +- if (tag == "EXTRACTOR_DISCLAIMER") +- return EXTRACTOR_DISCLAIMER; +- if (tag == "EXTRACTOR_WARNING") +- return EXTRACTOR_WARNING; +- if (tag == "EXTRACTOR_TRANSLATED") +- return EXTRACTOR_TRANSLATED; +- if (tag == "EXTRACTOR_CREATION_DATE") +- return EXTRACTOR_CREATION_DATE; +- if (tag == "EXTRACTOR_MODIFICATION_DATE") +- return EXTRACTOR_MODIFICATION_DATE; +- if (tag == "EXTRACTOR_CREATOR") +- return EXTRACTOR_CREATOR; +- if (tag == "EXTRACTOR_PRODUCER") +- return EXTRACTOR_PRODUCER; +- if (tag == "EXTRACTOR_PAGE_COUNT") +- return EXTRACTOR_PAGE_COUNT; +- if (tag == "EXTRACTOR_PAGE_ORIENTATION") +- return EXTRACTOR_PAGE_ORIENTATION; +- if (tag == "EXTRACTOR_PAPER_SIZE") +- return EXTRACTOR_PAPER_SIZE; +- if (tag == "EXTRACTOR_USED_FONTS") +- return EXTRACTOR_USED_FONTS; +- if (tag == "EXTRACTOR_PAGE_ORDER") +- return EXTRACTOR_PAGE_ORDER; +- if (tag == "EXTRACTOR_CREATED_FOR") +- return EXTRACTOR_CREATED_FOR; +- if (tag == "EXTRACTOR_MAGNIFICATION") +- return EXTRACTOR_MAGNIFICATION; +- if (tag == "EXTRACTOR_RELEASE") +- return EXTRACTOR_RELEASE; +- if (tag == "EXTRACTOR_GROUP") +- return EXTRACTOR_GROUP; +- if (tag == "EXTRACTOR_SIZE") +- return EXTRACTOR_SIZE; +- if (tag == "EXTRACTOR_SUMMARY") +- return EXTRACTOR_SUMMARY; +- if (tag == "EXTRACTOR_PACKAGER") +- return EXTRACTOR_PACKAGER; +- if (tag == "EXTRACTOR_VENDOR") +- return EXTRACTOR_VENDOR; +- if (tag == "EXTRACTOR_LICENSE") +- return EXTRACTOR_LICENSE; +- if (tag == "EXTRACTOR_DISTRIBUTION") +- return EXTRACTOR_DISTRIBUTION; +- if (tag == "EXTRACTOR_BUILDHOST") +- return EXTRACTOR_BUILDHOST; +- if (tag == "EXTRACTOR_OS") +- return EXTRACTOR_OS; +- if (tag == "EXTRACTOR_DEPENDENCY") +- return EXTRACTOR_DEPENDENCY; +- if (tag == "EXTRACTOR_HASH_MD4") +- return EXTRACTOR_HASH_MD4; +- if (tag == "EXTRACTOR_HASH_MD5") +- return EXTRACTOR_HASH_MD5; +- if (tag == "EXTRACTOR_HASH_SHA0") +- return EXTRACTOR_HASH_SHA0; +- if (tag == "EXTRACTOR_HASH_SHA1") +- return EXTRACTOR_HASH_SHA1; +- if (tag == "EXTRACTOR_HASH_RMD160") +- return EXTRACTOR_HASH_RMD160; +- if (tag == "EXTRACTOR_RESOLUTION") +- return EXTRACTOR_RESOLUTION; +- if (tag == "EXTRACTOR_CATEGORY") +- return EXTRACTOR_CATEGORY; +- if (tag == "EXTRACTOR_BOOKTITLE") +- return EXTRACTOR_BOOKTITLE; +- if (tag == "EXTRACTOR_PRIORITY") +- return EXTRACTOR_PRIORITY; +- if (tag == "EXTRACTOR_CONFLICTS") +- return EXTRACTOR_CONFLICTS; +- if (tag == "EXTRACTOR_REPLACES") +- return EXTRACTOR_REPLACES; +- if (tag == "EXTRACTOR_PROVIDES") +- return EXTRACTOR_PROVIDES; +- if (tag == "EXTRACTOR_CONDUCTOR") +- return EXTRACTOR_CONDUCTOR; +- if (tag == "EXTRACTOR_INTERPRET") +- return EXTRACTOR_INTERPRET; +- if (tag == "EXTRACTOR_OWNER") +- return EXTRACTOR_OWNER; +- if (tag == "EXTRACTOR_LYRICS") +- return EXTRACTOR_LYRICS; +- if (tag == "EXTRACTOR_MEDIA_TYPE") +- return EXTRACTOR_MEDIA_TYPE; +- if (tag == "EXTRACTOR_CONTACT") +- return EXTRACTOR_CONTACT; +- if (tag == "EXTRACTOR_THUMBNAIL_DATA") +- return EXTRACTOR_THUMBNAIL_DATA; +- +-#ifdef EXTRACTOR_GE_0_5_2 +- if (tag == "EXTRACTOR_PUBLICATION_DATE") +- return EXTRACTOR_PUBLICATION_DATE; +- if (tag == "EXTRACTOR_CAMERA_MAKE") +- return EXTRACTOR_CAMERA_MAKE; +- if (tag == "EXTRACTOR_CAMERA_MODEL") +- return EXTRACTOR_CAMERA_MODEL; +- if (tag == "EXTRACTOR_EXPOSURE") +- return EXTRACTOR_EXPOSURE; +- if (tag == "EXTRACTOR_APERTURE") +- return EXTRACTOR_APERTURE; +- if (tag == "EXTRACTOR_EXPOSURE_BIAS") +- return EXTRACTOR_EXPOSURE_BIAS; +- if (tag == "EXTRACTOR_FLASH") +- return EXTRACTOR_FLASH; +- if (tag == "EXTRACTOR_FLASH_BIAS") +- return EXTRACTOR_FLASH_BIAS; +- if (tag == "EXTRACTOR_FOCAL_LENGTH") +- return EXTRACTOR_FOCAL_LENGTH; +- if (tag == "EXTRACTOR_FOCAL_LENGTH_35MM") +- return EXTRACTOR_FOCAL_LENGTH_35MM; +- if (tag == "EXTRACTOR_ISO_SPEED") +- return EXTRACTOR_ISO_SPEED; +- if (tag == "EXTRACTOR_EXPOSURE_MODE") +- return EXTRACTOR_EXPOSURE_MODE; +- if (tag == "EXTRACTOR_METERING_MODE") +- return EXTRACTOR_METERING_MODE; +- if (tag == "EXTRACTOR_MACRO_MODE") +- return EXTRACTOR_MACRO_MODE; +- if (tag == "EXTRACTOR_IMAGE_QUALITY") +- return EXTRACTOR_IMAGE_QUALITY; +- if (tag == "EXTRACTOR_WHITE_BALANCE") +- return EXTRACTOR_WHITE_BALANCE; +- if (tag == "EXTRACTOR_ORIENTATION") +- return EXTRACTOR_ORIENTATION; +-#endif // EXTRACTOR_GE_0_5_2 ++#define T(x) [EXTRACTOR_METATYPE_##x] = "EXTRACTOR_METATYPE_"#x, ++ /* XXX: should convert to EXTRACTOR_metatype_to_string() somehow */ ++ const char *types[] = ++ { ++ T(RESERVED) ++ T(MIMETYPE) ++ T(FILENAME) ++ T(COMMENT) ++ ++ T(TITLE) ++ T(BOOK_TITLE) ++ T(BOOK_EDITION) ++ T(BOOK_CHAPTER_NUMBER) ++ T(JOURNAL_NAME) ++ T(JOURNAL_VOLUME) ++ T(JOURNAL_NUMBER) ++ T(PAGE_COUNT) ++ T(PAGE_RANGE) ++ T(AUTHOR_NAME) ++ T(AUTHOR_EMAIL) ++ T(AUTHOR_INSTITUTION) ++ T(PUBLISHER) ++ T(PUBLISHER_ADDRESS) ++ T(PUBLISHER_INSTITUTION) ++ T(PUBLISHER_SERIES) ++ T(PUBLICATION_TYPE) ++ T(PUBLICATION_YEAR) ++ T(PUBLICATION_MONTH) ++ T(PUBLICATION_DAY) ++ T(PUBLICATION_DATE) ++ T(BIBTEX_EPRINT) ++ T(BIBTEX_ENTRY_TYPE) ++ T(LANGUAGE) ++ T(CREATION_TIME) ++ T(URL) ++ ++ T(URI) ++ T(ISRC) ++ T(HASH_MD4) ++ T(HASH_MD5) ++ T(HASH_SHA0) ++ T(HASH_SHA1) ++ T(HASH_RMD160) ++ ++ T(GPS_LATITUDE_REF) ++ T(GPS_LATITUDE) ++ T(GPS_LONGITUDE_REF) ++ T(GPS_LONGITUDE) ++ T(LOCATION_CITY) ++ T(LOCATION_SUBLOCATION) ++ T(LOCATION_COUNTRY) ++ T(LOCATION_COUNTRY_CODE) ++ ++ T(UNKNOWN) ++ T(DESCRIPTION) ++ T(COPYRIGHT) ++ T(RIGHTS) ++ T(KEYWORDS) ++ T(ABSTRACT) ++ T(SUMMARY) ++ T(SUBJECT) ++ T(CREATOR) ++ T(FORMAT) ++ T(FORMAT_VERSION) ++ ++ T(CREATED_BY_SOFTWARE) ++ T(UNKNOWN_DATE) ++ T(CREATION_DATE) ++ T(MODIFICATION_DATE) ++ T(LAST_PRINTED) ++ T(LAST_SAVED_BY) ++ T(TOTAL_EDITING_TIME) ++ T(EDITING_CYCLES) ++ T(MODIFIED_BY_SOFTWARE) ++ T(REVISION_HISTORY) ++ ++ T(EMBEDDED_FILE_SIZE) ++ T(FINDER_FILE_TYPE) ++ T(FINDER_FILE_CREATOR) ++ ++ T(PACKAGE_NAME) ++ T(PACKAGE_VERSION) ++ T(SECTION) ++ T(UPLOAD_PRIORITY) ++ T(PACKAGE_DEPENDENCY) ++ T(PACKAGE_CONFLICTS) ++ T(PACKAGE_REPLACES) ++ T(PACKAGE_PROVIDES) ++ T(PACKAGE_RECOMMENDS) ++ T(PACKAGE_SUGGESTS) ++ T(PACKAGE_MAINTAINER) ++ T(PACKAGE_INSTALLED_SIZE) ++ T(PACKAGE_SOURCE) ++ T(PACKAGE_ESSENTIAL) ++ T(TARGET_ARCHITECTURE) ++ T(PACKAGE_PRE_DEPENDENCY) ++ T(LICENSE) ++ T(PACKAGE_DISTRIBUTION) ++ T(BUILDHOST) ++ T(VENDOR) ++ T(TARGET_OS) ++ T(SOFTWARE_VERSION) ++ T(TARGET_PLATFORM) ++ T(RESOURCE_TYPE) ++ T(LIBRARY_SEARCH_PATH) ++ T(LIBRARY_DEPENDENCY) ++ ++ T(CAMERA_MAKE) ++ T(CAMERA_MODEL) ++ T(EXPOSURE) ++ T(APERTURE) ++ T(EXPOSURE_BIAS) ++ T(FLASH) ++ T(FLASH_BIAS) ++ T(FOCAL_LENGTH) ++ T(FOCAL_LENGTH_35MM) ++ T(ISO_SPEED) ++ T(EXPOSURE_MODE) ++ T(METERING_MODE) ++ T(MACRO_MODE) ++ T(IMAGE_QUALITY) ++ T(WHITE_BALANCE) ++ T(ORIENTATION) ++ T(MAGNIFICATION) ++ ++ T(IMAGE_DIMENSIONS) ++ T(PRODUCED_BY_SOFTWARE) ++ T(THUMBNAIL) ++ T(IMAGE_RESOLUTION) ++ T(SOURCE) ++ ++ T(CHARACTER_SET) ++ T(LINE_COUNT) ++ T(PARAGRAPH_COUNT) ++ T(WORD_COUNT) ++ T(CHARACTER_COUNT) ++ T(PAGE_ORIENTATION) ++ T(PAPER_SIZE) ++ T(TEMPLATE) ++ T(COMPANY) ++ T(MANAGER) ++ T(REVISION_NUMBER) ++ ++ T(DURATION) ++ T(ALBUM) ++ T(ARTIST) ++ T(GENRE) ++ T(TRACK_NUMBER) ++ T(DISC_NUMBER) ++ T(PERFORMER) ++ T(CONTACT_INFORMATION) ++ T(SONG_VERSION) ++ T(PICTURE) ++ T(COVER_PICTURE) ++ T(CONTRIBUTOR_PICTURE) ++ T(EVENT_PICTURE) ++ T(LOGO) ++ T(BROADCAST_TELEVISION_SYSTEM) ++ T(SOURCE_DEVICE) ++ T(DISCLAIMER) ++ T(WARNING) ++ T(PAGE_ORDER) ++ T(WRITER) ++ T(PRODUCT_VERSION) ++ T(CONTRIBUTOR_NAME) ++ T(MOVIE_DIRECTOR) ++ T(NETWORK_NAME) ++ T(SHOW_NAME) ++ T(CHAPTER_NAME) ++ T(SONG_COUNT) ++ T(STARTING_SONG) ++ T(PLAY_COUNTER) ++ T(CONDUCTOR) ++ T(INTERPRETATION) ++ T(COMPOSER) ++ T(BEATS_PER_MINUTE) ++ T(ENCODED_BY) ++ T(ORIGINAL_TITLE) ++ T(ORIGINAL_ARTIST) ++ T(ORIGINAL_WRITER) ++ T(ORIGINAL_RELEASE_YEAR) ++ T(ORIGINAL_PERFORMER) ++ T(LYRICS) ++ T(POPULARITY_METER) ++ T(LICENSEE) ++ T(MUSICIAN_CREDITS_LIST) ++ T(MOOD) ++ T(SUBTITLE) ++ ++ T(GNUNET_DISPLAY_TYPE) ++ T(GNUNET_FULL_DATA) ++ T(RATING) ++ T(ORGANIZATION) ++ T(RIPPER) ++ T(PRODUCER) ++ T(GROUP) ++ T(GNUNET_ORIGINAL_FILENAME) ++ }; ++#undef T ++ size_t i; ++ ++ for (i = 0; i < sizeof(types) / sizeof(types[0]); ++i) ++ if (!strcmp(types[i], tag.c_str())) ++ return (EXTRACTOR_MetaType) i; + + log_warning("Ignoring unknown libextractor tag: %s\n", tag.c_str()); +- return EXTRACTOR_UNKNOWN; ++ return EXTRACTOR_METATYPE_UNKNOWN; + } + +-static void addMetaField(metadata_fields_t field, EXTRACTOR_KeywordList *keywords, Ref<CdsItem> item, Ref<StringConverter> sc) ++struct field_state { ++ Ref<CdsItem> item; ++ Ref<StringConverter> sc; ++ Ref<Array<StringBase> > aux; ++}; ++ ++static int addField(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, ++ enum EXTRACTOR_MetaFormat format, const char *data_mime_type, ++ const char *data, size_t data_len) + { +- String value; +- const char *temp = NULL; +- ++ metadata_fields_t field = M_MAX; ++ resource_attributes_t attr = R_MAX; ++ ++ if (!data) ++ return 0; ++ ++ log_debug("metadata %zu [%s] -> %s\n", (size_t)type, EXTRACTOR_metatype_to_string(type), data); ++ + /// \todo check if UTF-8 conversion is needed, may already be in UTF-8 +- +- switch (field) ++ ++ switch (type) + { +- case M_TITLE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_TITLE, keywords); ++ case EXTRACTOR_METATYPE_TITLE: ++ field = M_TITLE; + break; +- case M_ARTIST: +- temp = EXTRACTOR_extractLast(EXTRACTOR_ARTIST, keywords); ++ case EXTRACTOR_METATYPE_ARTIST: ++ field = M_ARTIST; + break; +- case M_ALBUM: +- temp = EXTRACTOR_extractLast(EXTRACTOR_ALBUM, keywords); ++ case EXTRACTOR_METATYPE_ALBUM: ++ field = M_ALBUM; + break; +- case M_DATE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_DATE, keywords); ++ case EXTRACTOR_METATYPE_PUBLICATION_YEAR: ++ field = M_DATE; + break; +- case M_GENRE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_GENRE, keywords); ++ case EXTRACTOR_METATYPE_GENRE: ++ field = M_GENRE; + break; +- case M_DESCRIPTION: +- temp = EXTRACTOR_extractLast(EXTRACTOR_DESCRIPTION, keywords); +- +- if (temp == NULL) +- temp = EXTRACTOR_extractLast(EXTRACTOR_COMMENT, keywords); ++ case EXTRACTOR_METATYPE_DESCRIPTION: ++ field = M_DESCRIPTION; ++ break; ++ case EXTRACTOR_METATYPE_COMMENT: ++ field = M_DESCRIPTION; ++ break; ++ case EXTRACTOR_METATYPE_IMAGE_DIMENSIONS: ++ attr = R_RESOLUTION; + break; +- default: +- return; + } + +- if (temp != NULL) +- value = temp; ++ String value; ++ struct field_state *field_state = (struct field_state *)cls; ++ Ref<CdsItem> item = field_state->item; ++ Ref<StringConverter> sc = field_state->sc; ++ Ref<Array<StringBase> > aux = field_state->aux; ++ ++ if (field == M_MAX && attr == R_MAX && aux == nil) ++ { ++ log_debug("no match\n"); ++ return 0; ++ } + ++ value = data; + value = trim_string(value); +- +- if (string_ok(value)) ++ if (!string_ok(value)) ++ return 0; ++ ++ if (field != M_MAX) + { + item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); +-// log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str()); ++ log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str()); + } +-} + +-static void addResourceField(resource_attributes_t attr, EXTRACTOR_KeywordList *keywords, Ref<CdsItem> item, Ref<StringConverter> sc) +-{ +- String value; +- const char *temp = NULL; +- +- switch (attr) ++ if (attr != R_MAX) + { +- case R_RESOLUTION: +- temp = EXTRACTOR_extractLast(EXTRACTOR_SIZE, keywords); +- break; +-/* case R_SIZE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_SIZE, keywords); +- break; +-*/ +- default: +- return; ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(attr), value); ++ log_debug("Setting attribute on item: %d, %s\n", attr, value.c_str()); + } + +- if (temp != NULL) +- value = temp; +- +- if (string_ok(value)) ++ if (aux != nil) + { +- item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(attr), value); ++ String tmp; ++ for (int j = 0; j < aux->size(); j++) ++ { ++ tmp = aux->get(j); ++ if (string_ok(tmp)) ++ { ++ if (type == getTagFromString(tmp)) ++ { ++ value = sc->convert(value); ++ item->setAuxData(tmp, value); ++ log_debug(("Adding tag: %s with value %s\n", tmp.c_str(), value.c_str())); ++ } ++ } ++ } + } ++ ++ return 0; + } + + + +-Ref<RExp> ReAudioFormat; +-EXTRACTOR_ExtractorList *extractors = NULL; +-bool load_libraries_failed = false; ++static Ref<RExp> ReAudioFormat; ++static EXTRACTOR_PluginList *plugins = NULL; ++static bool load_libraries_failed = false; + + void ExtractorHandler::fillMetadata(Ref<CdsItem> item) + { + if (load_libraries_failed) + return; +- Ref<Array<StringBase> > aux; +- Ref<StringConverter> sc = StringConverter::i2i(); +- +- if (! extractors) ++ if (! plugins) + { +- extractors = EXTRACTOR_loadDefaultLibraries(); +- if (! extractors) ++ plugins = EXTRACTOR_plugin_add_defaults(EXTRACTOR_OPTION_DEFAULT_POLICY); ++ if (! plugins) ++ { + load_libraries_failed = true; ++ return; ++ } + } +- EXTRACTOR_KeywordList *keywords = EXTRACTOR_getKeywords(extractors, item->getLocation().c_str()); +- +- //EXTRACTOR_printKeywords(stdout, keywords); + +- for (int i = 0; i < M_MAX; i++) +- addMetaField((metadata_fields_t)i, keywords, item, sc); +- +- for (int i = 0; i < R_MAX; i++) +- addResourceField((resource_attributes_t)i, keywords, item, sc); ++ log_debug("processing %s\n", item->getLocation().c_str()); + + Ref<ConfigManager> cm = ConfigManager::getInstance(); +- aux = cm->getStringArrayOption(CFG_IMPORT_LIBOPTS_EXTRACTOR_AUXDATA_TAGS_LIST); +- if (aux != nil) +- { +- String value; +- String tmp; +- const char *temp = NULL; +- +- for (int j = 0; j < aux->size(); j++) +- { +- +- tmp = aux->get(j); +- if (string_ok(tmp)) +- { +- temp = EXTRACTOR_extractLast(getTagFromString(tmp), keywords); +- if (temp != NULL) +- { +- value = temp; +- if (string_ok(value)) +- { +- value = sc->convert(value); +- item->setAuxData(tmp, value); +-// log_debug(("Adding tag: %s with value %s\n", tmp.c_str(), value.c_str())); +- } +- } +- } +- } +- } ++ struct field_state field_state = { ++ .item = item, ++ .sc = StringConverter::i2i(), ++ .aux = cm->getStringArrayOption(CFG_IMPORT_LIBOPTS_EXTRACTOR_AUXDATA_TAGS_LIST), ++ }; ++ EXTRACTOR_extract(plugins, item->getLocation().c_str(), NULL, 0, addField, &field_state); + + if (ReAudioFormat == nil) + { +@@ -379,35 +401,9 @@ void ExtractorHandler::fillMetadata(Ref<CdsItem> item) + ReAudioFormat->compile(_("([0-9]+)\\s+kbps,\\s*([0-9]+)\\s+hz,\\s*" + "(([0-9]+)h)?([0-9]+)m([0-9]+)\\s(\\S+)"), "i"); + } +- +- /* +- temp = EXTRACTOR_extractLast(EXTRACTOR_FORMAT, keywords); +- log_debug("EXTRACTOR_FORMAT: %s\n", temp); +- +- if (temp) +- { +- Ref<Matcher> matcher = ReAudioFormat->match((char *)temp); +- if (matcher != nil) +- { +- log_debug(("BR:%s FR:%s H:%s M:%s S:%s TYPE:%s\n", +- matcher->group(1).c_str(), +- matcher->group(2).c_str(), +- matcher->group(4).c_str(), +- matcher->group(5).c_str(), +- matcher->group(6).c_str(), +- matcher->group(7).c_str())); +- } +- else +- { +- log_debug(("format pattern unmatched!")); +- } +- } +- +- */ +- EXTRACTOR_freeKeywords(keywords); + + // commented out for the sake of efficiency +- // EXTRACTOR_removeAll(extractors); ++ // EXTRACTOR_plugin_remove_all(plugins); + } + + Ref<IOHandler> ExtractorHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-libmp4v2.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-libmp4v2.patch new file mode 100644 index 000000000000..6a6b51e1e05a --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-libmp4v2.patch @@ -0,0 +1,187 @@ +diff -urN old/src/metadata/libmp4v2_handler.cc new/src/metadata/libmp4v2_handler.cc +--- old/src/metadata/libmp4v2_handler.cc 2012-04-05 01:46:26.000000000 +0200 ++++ new/src/metadata/libmp4v2_handler.cc 2012-04-05 02:01:24.000000000 +0200 +@@ -65,29 +65,28 @@ + static void addMetaField(metadata_fields_t field, MP4FileHandle mp4, Ref<CdsItem> item) + { + String value; +- char* mp4_retval = NULL; +- u_int16_t track; +- u_int16_t total_tracks; +- + Ref<StringConverter> sc = StringConverter::i2i(); + ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ ++ if (!MP4TagsFetch(new_tags, mp4)) ++ return; ++ + switch (field) + { + case M_TITLE: +- MP4GetMetadataName(mp4, &mp4_retval); ++ value = new_tags->name; + break; + case M_ARTIST: +- MP4GetMetadataArtist(mp4, &mp4_retval); ++ value = new_tags->artist; + break; + case M_ALBUM: +- MP4GetMetadataAlbum(mp4, &mp4_retval); ++ value = new_tags->album; + break; + case M_DATE: +- MP4GetMetadataYear(mp4, &mp4_retval); +- if (mp4_retval) ++ value = new_tags->releaseDate; ++ if (value.length() > 0) + { +- value = mp4_retval; +- free(mp4_retval); + if (string_ok(value)) + value = value + "-01-01"; + else +@@ -95,34 +94,31 @@ + } + break; + case M_GENRE: +- MP4GetMetadataGenre(mp4, &mp4_retval); ++ value = new_tags->genre; + break; + case M_DESCRIPTION: +- MP4GetMetadataComment(mp4, &mp4_retval); ++ value = new_tags->comments; + break; + case M_TRACKNUMBER: +- MP4GetMetadataTrack(mp4, &track, &total_tracks); +- if (track > 0) ++ if (new_tags->track) + { +- value = String::from(track); +- item->setTrackNumber((int)track); ++ value = String::from(new_tags->track->index); ++ item->setTrackNumber((int)new_tags->track->index); + } + else ++ { ++ MP4TagsFree( new_tags ); + return; ++ } + break; + default: ++ MP4TagsFree( new_tags ); + return; + } + +- if ((field != M_DATE) && (field != M_TRACKNUMBER) && +- (mp4_retval)) +- { +- value = mp4_retval; +- free(mp4_retval); +- } +- ++ MP4TagsFree( new_tags ); + value = trim_string(value); +- ++ + if (string_ok(value)) + { + item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); +@@ -190,14 +186,19 @@ + } + + #if defined(HAVE_MAGIC) +- u_int8_t *art_data; +- u_int32_t art_data_len; ++ void *art_data = 0; ++ u_int32_t art_data_len = 0; + String art_mimetype; ++ ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ MP4TagsFetch(new_tags, mp4); ++ if (new_tags->artworkCount) ++ { ++ art_data = new_tags->artwork->data; ++ art_data_len = new_tags->artwork->size; ++ } + #ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT +- if (MP4GetMetadataCoverArtCount(mp4) && +- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len)) +-#else +- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len); ++ if (new_tags->artworkCount && art_data_len > 0) + #endif + { + if (art_data) +@@ -211,11 +212,10 @@ + } + catch (Exception ex) + { +- free(art_data); ++ MP4TagsFree(new_tags); + throw ex; + } + +- free(art_data); + if (art_mimetype != _(MIMETYPE_DEFAULT)) + { + Ref<CdsResource> resource(new CdsResource(CH_MP4)); +@@ -225,6 +225,7 @@ + } + } + } ++ MP4TagsFree(new_tags); + #endif + MP4Close(mp4); + } +@@ -249,26 +250,35 @@ + + if (ctype != ID3_ALBUM_ART) + throw _Exception(_("LibMP4V2Handler: got unknown content type: ") + ctype); ++ ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ if (MP4TagsFetch(new_tags, mp4)) ++ { + #ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT +- if (!MP4GetMetadataCoverArtCount(mp4)) +- throw _Exception(_("LibMP4V2Handler: resource has no album art information")); ++ if (!new_tags->artworkCount) ++ throw _Exception(_("LibMP4V2Handler: resource has no album art information")); + #endif +- u_int8_t *art_data; +- u_int32_t art_data_len; +- if (MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len)) +- { +- if (art_data) ++ void *art_data = 0; ++ u_int32_t art_data_len; ++ ++ const MP4TagArtwork* art = new_tags->artwork; ++ art_data = art->data; ++ art_data_len = art->size; ++ if (art) + { +- *data_size = (off_t)art_data_len; +- Ref<IOHandler> h(new MemIOHandler((void *)art_data, art_data_len)); +- free(art_data); +- return h; ++ if (art_data) ++ { ++ *data_size = (off_t)art_data_len; ++ Ref<IOHandler> h(new MemIOHandler(art_data, art_data_len)); ++ MP4TagsFree(new_tags); ++ return h; ++ } + } ++ MP4TagsFree(new_tags); + } +- + throw _Exception(_("LibMP4V2Handler: could not serve album art " +- "for file") + item->getLocation() + +- " - embedded image not found"); ++ "for file") + item->getLocation() + ++ " - embedded image not found"); + } + + #endif // HAVE_LIBMP4V2 +De binära filerna old/src/metadata/.libmp4v2_handler.cc.swp och new/src/metadata/.libmp4v2_handler.cc.swp skiljer diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-mozjs187.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-mozjs187.patch new file mode 100644 index 000000000000..c4b080a3656b --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-mozjs187.patch @@ -0,0 +1,260 @@ +maybe this is correct, maybe it's not. spidermonkey's documentation blows, so +who is to say! + +https://bugs.gentoo.org/423991 + +--- a/src/scripting/dvd_image_import_script.cc ++++ b/src/scripting/dvd_image_import_script.cc +@@ -232,8 +232,6 @@ DVDImportScript::DVDImportScript(Ref<Runtime> runtime) : Script(runtime) + + String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_DVD_SCRIPT); + load(scriptPath); +- root = JS_NewScriptObject(cx, script); +- JS_AddNamedRoot(cx, &root, "DVDImportScript"); + log_info("Loaded %s\n", scriptPath.c_str()); + + Ref<Dictionary> mappings = +@@ -296,21 +294,4 @@ void DVDImportScript::processDVDObject(Ref<CdsObject> obj) + #endif + } + +-DVDImportScript::~DVDImportScript() +-{ +-#ifdef JS_THREADSAFE +- JS_SetContextThread(cx); +- JS_BeginRequest(cx); +-#endif +- +- if (root) +- JS_RemoveRoot(cx, &root); +- +-#ifdef JS_THREADSAFE +- JS_EndRequest(cx); +- JS_ClearContextThread(cx); +-#endif +- +-} +- + #endif // HAVE_JS +--- a/src/scripting/dvd_image_import_script.h ++++ b/src/scripting/dvd_image_import_script.h +@@ -41,7 +41,6 @@ class DVDImportScript : public Script + { + public: + DVDImportScript(zmm::Ref<Runtime> runtime); +- ~DVDImportScript(); + /// \brief Adds a DVD object to the database + /// + /// \param title DVD title number +--- a/src/scripting/import_script.cc ++++ b/src/scripting/import_script.cc +@@ -53,8 +53,6 @@ ImportScript::ImportScript(Ref<Runtime> runtime) : Script(runtime) + try + { + load(scriptPath); +- root = JS_NewObject(cx, NULL, script, NULL); +- JS_AddNamedObjectRoot(cx, &root, "ImportScript"); + } + catch (Exception ex) + { +@@ -109,21 +107,4 @@ void ImportScript::processCdsObject(Ref<CdsObject> obj, String rootpath) + #endif + } + +-ImportScript::~ImportScript() +-{ +-#ifdef JS_THREADSAFE +- JS_SetContextThread(cx); +- JS_BeginRequest(cx); +-#endif +- +- if (root) +- JS_RemoveObjectRoot(cx, &root); +- +-#ifdef JS_THREADSAFE +- JS_EndRequest(cx); +- JS_ClearContextThread(cx); +-#endif +- +-} +- + #endif // HAVE_JS +--- a/src/scripting/import_script.h ++++ b/src/scripting/import_script.h +@@ -41,11 +41,8 @@ class ImportScript : public Script + { + public: + ImportScript(zmm::Ref<Runtime> runtime); +- ~ImportScript(); + void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath); + virtual script_class_t whoami() { return S_IMPORT; } +-private: +- JSObject *root; + }; + + #endif // __SCRIPTING_IMPORT_SCRIPT_H__ +--- a/src/scripting/playlist_parser_script.cc ++++ b/src/scripting/playlist_parser_script.cc +@@ -93,8 +93,6 @@ PlaylistParserScript::PlaylistParserScript(Ref<Runtime> runtime) : Script(runtim + + String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT); + load(scriptPath); +- root = JS_NewObject(cx, NULL, script, NULL); +- JS_AddNamedObjectRoot(cx, &root, "PlaylistScript"); + } + catch (Exception ex) + { +@@ -236,21 +234,4 @@ void PlaylistParserScript::processPlaylistObject(zmm::Ref<CdsObject> obj, Ref<Ge + + } + +- +-PlaylistParserScript::~PlaylistParserScript() +-{ +-#ifdef JS_THREADSAFE +- JS_SetContextThread(cx); +- JS_BeginRequest(cx); +-#endif +- +- if (root) +- JS_RemoveObjectRoot(cx, &root); +- +-#ifdef JS_THREADSAFE +- JS_EndRequest(cx); +- JS_ClearContextThread(cx); +-#endif +- +-} + #endif // HAVE_JS +--- a/src/scripting/playlist_parser_script.h ++++ b/src/scripting/playlist_parser_script.h +@@ -42,7 +42,6 @@ class PlaylistParserScript : public Script + { + public: + PlaylistParserScript(zmm::Ref<Runtime> runtime); +- ~PlaylistParserScript(); + zmm::String readln(); + void processPlaylistObject(zmm::Ref<CdsObject> obj, zmm::Ref<GenericTask> task); + virtual script_class_t whoami() { return S_PLAYLIST; } +@@ -52,7 +51,6 @@ private: + int currentObjectID; + char *currentLine; + zmm::Ref<GenericTask> currentTask; +- JSObject *root; + }; + + #endif // __SCRIPTING_PLAYLIST_PARSER_SCRIPT_H__ +--- a/src/scripting/script.cc ++++ b/src/scripting/script.cc +@@ -427,15 +427,10 @@ static JSFunctionSpec js_global_functions[] = { + try + { + common_script = _load(common_scr_path); +- common_root = JS_NewObject(cx, NULL, common_script, NULL); +- JS_AddNamedObjectRoot(cx, &common_root, "common-script"); + _execute(common_script); + } + catch (Exception e) + { +- if (common_root) +- JS_RemoveObjectRoot(cx, &common_root); +- + log_js("Unable to load %s: %s\n", common_scr_path.c_str(), + e.getMessage().c_str()); + } +@@ -459,8 +454,6 @@ Script::~Script() + JS_SetContextThread(cx); + JS_BeginRequest(cx); + #endif +- if (common_root) +- JS_RemoveObjectRoot(cx, &common_root); + + /* + * scripts are unrooted and will be cleaned up by GC +@@ -532,12 +532,12 @@ void Script::defineFunctions(JSFunctionSpec *functions) + throw _Exception(_("Scripting: JS_DefineFunctions failed")); + } + +-JSObject *Script::_load(zmm::String scriptPath) ++JSScript *Script::_load(zmm::String scriptPath) + { + if (glob == NULL) + initGlobalObject(); + +- JSObject *scr; ++ JSScript *scr; + + String scriptText = read_text_file(scriptPath); + +@@ -568,7 +568,7 @@ void Script::load(zmm::String scriptPath) + } + + +-void Script::_execute(JSObject *scr) ++void Script::_execute(JSScript *scr) + { + jsval ret_val; + +--- a/src/scripting/script.h ++++ b/src/scripting/script.h +@@ -66,8 +66,8 @@ public: + JSRuntime *rt; + JSContext *cx; + JSObject *glob; +- JSObject *script; +- JSObject *common_script; ++ JSScript *script; ++ JSScript *common_script; + + public: + Script(zmm::Ref<Runtime> runtime); +@@ -112,11 +112,9 @@ protected: + zmm::Ref<CdsObject> processed; + + private: +- JSObject *common_root; +- + void initGlobalObject(); +- JSObject *_load(zmm::String scriptPath); +- void _execute(JSObject *scr); ++ JSScript *_load(zmm::String scriptPath); ++ void _execute(JSScript *scr); + zmm::Ref<StringConverter> _p2i; + zmm::Ref<StringConverter> _j2i; + zmm::Ref<StringConverter> _f2i; +--- a/configure.ac ++++ b/configure.ac +@@ -1036,13 +1036,13 @@ + ], + [ + unset ac_cv_lib_smjs_JS_NewObject +- AC_CHECK_LIB(mozjs185, JS_NewObject, ++ AC_CHECK_LIB(mozjs187, JS_NewObject, + [ +- MOZLIB=mozjs185 +- JS_LIBS="-lmozjs185" ++ MOZLIB=mozjs187 ++ JS_LIBS="-lmozjs187" + ], + [ +- unset ac_cv_lib_mozjs185_JS_NewObject ++ unset ac_cv_lib_mozjs187_JS_NewObject + AC_CHECK_LIB(mozjs, JS_NewObject, + [ + MOZLIB=mozjs +@@ -1064,11 +1064,11 @@ + MOZLIB=smjs + ], + [ +- unset ac_cv_lib_mozjs185_JS_NewObject +- AC_CHECK_LIB(mozjs185, JS_NewObject, ++ unset ac_cv_lib_mozjs187_JS_NewObject ++ AC_CHECK_LIB(mozjs187, JS_NewObject, + [ +- JS_LIBS="-L$SEARCH_DIR_LIBS -lmozjs185" +- MOZLIB=mozjs185 ++ JS_LIBS="-L$SEARCH_DIR_LIBS -lmozjs187" ++ MOZLIB=mozjs187 + ], + [ + LDFLAGS="-L$SEARCH_DIR_LIBS $LDFLAGS_SAVE -lmozjs" diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-system-ar.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-system-ar.patch new file mode 100644 index 000000000000..349bf7d8da74 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-system-ar.patch @@ -0,0 +1,35 @@ +--- configure.ac 2010-04-08 00:38:51.000000000 +0200 ++++ configure.ac 2013-05-30 12:27:55.620514386 +0200 +@@ -318,6 +318,10 @@ + AC_PROG_CC + AC_PROG_RANLIB + AC_PROG_GCC_TRADITIONAL ++AN_MAKEVAR([AR], [AC_PROG_AR]) ++AN_PROGRAM([ar], [AC_PROG_AR]) ++AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)]) ++AC_PROG_AR + AC_HEADER_DIRENT + AC_HEADER_STDC + AC_HEADER_SYS_WAIT +--- build/Makefile.in 2010-04-08 00:40:15.000000000 +0200 ++++ build/Makefile.in 2013-05-30 12:25:55.310337928 +0200 +@@ -50,7 +50,7 @@ + CONFIG_CLEAN_FILES = + CONFIG_CLEAN_VPATH_FILES = + LIBRARIES = $(noinst_LIBRARIES) +-AR = ar ++AR = @AR@ + ARFLAGS = cru + libmediatomb_a_AR = $(AR) $(ARFLAGS) + libmediatomb_a_LIBADD = +--- tombupnp/build/Makefile.in 2010-04-08 00:40:16.000000000 +0200 ++++ tombupnp/build/Makefile.in 2013-05-30 12:26:18.420371823 +0200 +@@ -48,7 +48,7 @@ + CONFIG_CLEAN_FILES = + CONFIG_CLEAN_VPATH_FILES = + LIBRARIES = $(noinst_LIBRARIES) +-AR = ar ++AR = @AR@ + ARFLAGS = cru + libtombupnp_a_AR = $(AR) $(ARFLAGS) + libtombupnp_a_LIBADD = diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-system-uuid.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-system-uuid.patch new file mode 100644 index 000000000000..053f18cea879 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-system-uuid.patch @@ -0,0 +1,36 @@ +use libuuid from the system rather than local bundled code + +http://bugs.gentoo.org/270830 + +--- a/build/Makefile.am ++++ b/build/Makefile.am +@@ -58,6 +58,7 @@ mediatomb_CXXFLAGS = -I$(top_srcdir)/src \ + mediatomb_LDADD = \ + libmediatomb.a \ + $(top_srcdir)/tombupnp/build/libtombupnp.a \ ++ -luuid \ + $(LIBEXIF_LDFLAGS) \ + $(ZLIB_LDFLAGS) \ + $(EXPAT_LDFLAGS) \ +--- a/build/libmediatomb_src ++++ b/build/libmediatomb_src +@@ -231,19 +231,6 @@ libmediatomb_a_SOURCES = \ + ../src/url.h \ + ../src/url_request_handler.cc \ + ../src/url_request_handler.h \ +-../src/uuid/clear.c \ +-../src/uuid/compare.c \ +-../src/uuid/copy.c \ +-../src/uuid/gen_uuid.c \ +-../src/uuid/isnull.c \ +-../src/uuid/pack.c \ +-../src/uuid/parse.c \ +-../src/uuid/unpack.c \ +-../src/uuid/unparse.c \ +-../src/uuid/uuid.h \ +-../src/uuid/uuidP.h \ +-../src/uuid/uuid_time.c \ +-../src/uuid/uuid_types.h \ + ../src/web/action.cc \ + ../src/web/add.cc \ + ../src/web/add_object.cc \ diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch new file mode 100644 index 000000000000..7de291a552b9 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch @@ -0,0 +1,237 @@ +https://sourceforge.net/tracker/?func=detail&aid=3291468&group_id=129766&atid=715782 + +[PATCH] Add the cache feature of ffmpegthumbnailer. + +I want the cache feature of ffmpegthumbnailer because my machine +is not powerful :-( +So I created this patch for the cache feature. + +This patch adds a new option "cache-dir" in config.xml. +If not specifying any string, the cache feature is disable. +And specifying some directory, the cache feature is enable +and the cache files will be created under the directory. + +Signed-off-by: Ken'ichi Ohmichi <ken1ohmichi@gmail.com> +--- +diff --git a/src/common.h b/src/common.h +index d1998b3..358f4d1 100644 +--- a/src/common.h ++++ b/src/common.h +@@ -367,6 +367,8 @@ + #define DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY YES + #define DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS NO + #define DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY 8 ++ #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED YES ++ #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR "" + #endif + + #if defined(HAVE_LASTFMLIB) +diff --git a/src/config_manager.cc b/src/config_manager.cc +index 8c975f8..2902090 100644 +--- a/src/config_manager.cc ++++ b/src/config_manager.cc +@@ -1873,6 +1873,24 @@ void ConfigManager::validate(String serverhome) + + NEW_INT_OPTION(temp_int); + SET_INT_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY); ++ ++ temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/" ++ "cache-dir", DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR); ++ ++ NEW_OPTION(temp); ++ SET_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR); ++ ++ temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/" ++ "cache-dir/attribute::enabled", ++ DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED); ++ ++ if (!validateYesNo(temp)) ++ throw _Exception(_("Error in config file: " ++ "invalid \"enabled\" attribute value in " ++ "ffmpegthumbnailer <cache-dir> tag")); ++ ++ NEW_BOOL_OPTION(temp == YES ? true : false); ++ SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED); + } + #endif + +diff --git a/src/config_manager.h b/src/config_manager.h +index 52b9842..a447a60 100644 +--- a/src/config_manager.h ++++ b/src/config_manager.h +@@ -110,6 +110,8 @@ typedef enum + CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY, + CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_WORKAROUND_BUGS, + CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY, ++ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED, ++ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR, + #endif + CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_ENABLED, + CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND, +diff --git a/src/metadata/ffmpeg_handler.cc b/src/metadata/ffmpeg_handler.cc +index a637d9c..8e7ef23 100644 +--- a/src/metadata/ffmpeg_handler.cc ++++ b/src/metadata/ffmpeg_handler.cc +@@ -50,6 +50,9 @@ + // INT64_C is not defined in ffmpeg/avformat.h but is needed + // macro defines included via autoconfig.h + #include <stdint.h> ++#include <sys/stat.h> ++#include <errno.h> ++#include <string.h> + + //#ifdef FFMPEG_NEEDS_EXTERN_C + extern "C" +@@ -279,6 +282,122 @@ void FfmpegHandler::fillMetadata(Ref<CdsItem> item) + av_close_input_file(pFormatCtx); + } + ++#ifdef HAVE_FFMPEGTHUMBNAILER ++ ++static int _mkdir(const char *path) ++{ ++ int ret = mkdir(path, 0777); ++ ++ if (ret == 0) { ++ // Make sure we are +x in case of restrictive umask that strips +x. ++ struct stat st; ++ if (stat(path, &st)) { ++ log_warning("could not stat(%s): %s\n", path, strerror(errno)); ++ return -1; ++ } ++ mode_t xbits = S_IXUSR | S_IXGRP | S_IXOTH; ++ if (!(st.st_mode & xbits)) { ++ if (chmod(path, st.st_mode | xbits)) { ++ log_warning("could not chmod(%s, +x): %s\n", path, strerror(errno)); ++ return -1; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static bool makeThumbnailCacheDir(String& path) ++{ ++ char *path_temp = strdup(path.c_str()); ++ char *last_slash = strrchr(path_temp, '/'); ++ char *slash = last_slash; ++ bool ret = false; ++ ++ if (!last_slash) ++ return ret; ++ ++ // Assume most dirs exist, so scan backwards first. ++ // Avoid stat/access checks due to TOCTOU races. ++ errno = 0; ++ for (slash = last_slash; slash > path_temp; --slash) { ++ if (*slash != '/') ++ continue; ++ *slash = '\0'; ++ if (_mkdir(path_temp) == 0) { ++ // Now we can forward scan. ++ while (slash < last_slash) { ++ *slash = DIR_SEPARATOR; ++ if (_mkdir(path_temp) < 0) ++ // Allow EEXIST in case of someone else doing `mkdir`. ++ if (errno != EEXIST) ++ goto done; ++ slash += strlen(slash); ++ } ++ if (slash == last_slash) ++ ret = true; ++ break; ++ } else if (errno == EEXIST) { ++ ret = true; ++ break; ++ } else if (errno != ENOENT) { ++ break; ++ } ++ } ++ ++ done: ++ free(path_temp); ++ return ret; ++} ++ ++static String getThumbnailCacheFilePath(String& movie_filename, bool create) ++{ ++ Ref<ConfigManager> cfg = ConfigManager::getInstance(); ++ String cache_dir = cfg->getOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR); ++ ++ if (cache_dir.length() == 0) { ++ String home_dir = cfg->getOption(CFG_SERVER_HOME); ++ cache_dir = home_dir + "/cache-dir"; ++ } ++ ++ cache_dir = cache_dir + movie_filename + "-thumb.jpg"; ++ if (create && !makeThumbnailCacheDir(cache_dir)) ++ cache_dir = ""; ++ return cache_dir; ++} ++ ++static bool readThumbnailCacheFile(String movie_filename, uint8_t **ptr_img, size_t *size_img) ++{ ++ String path = getThumbnailCacheFilePath(movie_filename, false); ++ FILE *fp = fopen(path.c_str(), "rb"); ++ if (!fp) ++ return false; ++ ++ size_t bytesRead; ++ uint8_t buffer[1024]; ++ *ptr_img = NULL; ++ *size_img = 0; ++ while ((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0) { ++ *ptr_img = (uint8_t *)realloc(*ptr_img, *size_img + bytesRead); ++ memcpy(*ptr_img + *size_img, buffer, bytesRead); ++ *size_img += bytesRead; ++ } ++ fclose(fp); ++ return true; ++} ++ ++static void writeThumbnailCacheFile(String movie_filename, uint8_t *ptr_img, int size_img) ++{ ++ String path = getThumbnailCacheFilePath(movie_filename, true); ++ FILE *fp = fopen(path.c_str(), "wb"); ++ if (!fp) ++ return; ++ fwrite(ptr_img, sizeof(uint8_t), size_img, fp); ++ fclose(fp); ++} ++ ++#endif ++ + Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) + { + *data_size = -1; +@@ -288,6 +407,18 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + if (!cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_ENABLED)) + return nil; + ++ if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) { ++ uint8_t *ptr_image; ++ size_t size_image; ++ if (readThumbnailCacheFile(item->getLocation(), ++ &ptr_image, &size_image)) { ++ *data_size = (off_t)size_image; ++ Ref<IOHandler> h(new MemIOHandler(ptr_image, size_image)); ++ free(ptr_image); ++ log_debug("Returning cached thumbnail for file: %s\n", item->getLocation().c_str()); ++ return h; ++ } ++ } + #ifdef FFMPEGTHUMBNAILER_OLD_API + video_thumbnailer *th = create_thumbnailer(); + image_data *img = create_image_data(); +@@ -318,6 +449,10 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + #endif // old api + throw _Exception(_("Could not generate thumbnail for ") + + item->getLocation()); ++ if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) { ++ writeThumbnailCacheFile(item->getLocation(), ++ img->image_data_ptr, img->image_data_size); ++ } + + *data_size = (off_t)img->image_data_size; + Ref<IOHandler> h(new MemIOHandler((void *)img->image_data_ptr, diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-thumbnail-locking.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-thumbnail-locking.patch new file mode 100644 index 000000000000..70658c495d25 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-thumbnail-locking.patch @@ -0,0 +1,71 @@ +if you try to generate a bunch of thumbnails at once, it can crash: + +Program received signal SIGABRT, Aborted. +[Switching to Thread 0x7fdb7a6cb700 (LWP 17295)] +0x00007fdb8031c899 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 +56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. +(gdb) bt +#0 0x00007fdb8031c899 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 +#1 0x00007fdb8031de27 in __GI_abort () at abort.c:89 +#2 0x00007fdb7f6b9222 in ff_unlock_avcodec () at /var/tmp/portage/media-video/ffmpeg-1.2.6/work/ffmpeg-1.2.6/libavcodec/utils.c:2767 +#3 0x00007fdb7f6b9662 in avcodec_open2 (avctx=0x7fdb64032080, codec=<optimized out>, options=0x0) at /var/tmp/portage/media-video/ffmpeg-1.2.6/work/ffmpeg-1.2.6/libavcodec/utils.c:1132 +#4 0x00007fdb81be57bb in ffmpegthumbnailer::MovieDecoder::initializeVideo (this=this@entry=0x7fdb7a6ca000) at libffmpegthumbnailer/moviedecoder.cpp:176 +#5 0x00007fdb81be599c in ffmpegthumbnailer::MovieDecoder::initialize (this=0x7fdb7a6ca000, filename=...) at libffmpegthumbnailer/moviedecoder.cpp:86 +#6 0x00007fdb81be92cc in ffmpegthumbnailer::VideoThumbnailer::generateThumbnail (this=this@entry=0x7fdb6402af90, videoFile=..., imageWriter=..., pAvContext=pAvContext@entry=0x0) at libffmpegthumbnailer/videothumbnailer.cpp:118 +#7 0x00007fdb81be97b4 in ffmpegthumbnailer::VideoThumbnailer::generateThumbnail (this=this@entry=0x7fdb6402af90, videoFile=..., type=<optimized out>, type@entry=Jpeg, buffer=..., pAvContext=pAvContext@entry=0x0) at libffmpegthumbnailer/videothumbnailer.cpp:191 +#8 0x00007fdb81bea23e in video_thumbnailer_generate_thumbnail_to_buffer (thumbnailer=<optimized out>, movie_filename=0x7fdb7003abc0 "........mp4", generated_image_data=0x7fdb64022680) at libffmpegthumbnailer/videothumbnailerc.cpp:113 +#9 0x00000000004ebfed in FfmpegHandler::serveContent (this=this@entry=0x7fdb64020ff0, item=..., resNum=resNum@entry=0x1, data_size=data_size@entry=0x7fdb7a6caaf0) at ../src/metadata/ffmpeg_handler.cc:475 +#10 0x00000000004e48d7 in FileRequestHandler::open (this=<optimized out>, filename=<optimized out>, info=0x7fdb7a6caaf0, mode=<optimized out>) at ../src/file_request_handler.cc:575 +#11 0x00000000004bba74 in web_open (filename=0x7fdb640175f0 "/content/media/object_id/16634/res_id/1/rh/6/ext/file.jpg", info=0x7fdb7a6caaf0, mode=UPNP_READ) at ../src/web_callbacks.cc:198 +#12 0x000000000052674b in process_request (Fp=<synthetic pointer>, RespInstr=0x7fdb7a6cab70, alias=0x7fdb7a6cab20, filename=0x7fdb7a6caad0, headers=0x7fdb7a6caab0, rtype=<synthetic pointer>, req=0x7fdb7a6cacd0) at ../upnp/src/genlib/net/http/webserver.c:1343 +#13 web_server_callback (parser=0x7fdb7a6cacd0, req=0x7fdb7a6cacd0, info=0x7fdb7a6cacc0) at ../upnp/src/genlib/net/http/webserver.c:1803 +#14 0x000000000051f29a in dispatch_request (hparser=0x7fdb7a6cacd0, info=0x7fdb7a6cacc0) at ../upnp/src/genlib/miniserver/miniserver.c:236 +#15 handle_request (args=0x7fdb6c000c40) at ../upnp/src/genlib/miniserver/miniserver.c:339 +#16 0x000000000052cc66 in WorkerThread (arg=0x7a80e0 <gRecvThreadPool>) at ../threadutil/src/ThreadPool.c:594 +#17 0x00007fdb80697333 in start_thread (arg=0x7fdb7a6cb700) at pthread_create.c:309 +#18 0x00007fdb803d226d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 +(gdb) + +--- a/src/metadata/ffmpeg_handler.cc ++++ b/src/metadata/ffmpeg_handler.cc +@@ -311,6 +311,10 @@ void FfmpegHandler::fillMetadata(Ref<CdsItem> item) + + #ifdef HAVE_FFMPEGTHUMBNAILER + ++// The ffmpegthumbnailer code (ffmpeg?) is not threading safe. ++// Add a lock around the usage to avoid crashing randomly. ++static pthread_mutex_t thumb_lock; ++ + static int _mkdir(const char *path) + { + int ret = mkdir(path, 0777); +@@ -446,6 +450,9 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + return h; + } + } ++ ++ pthread_mutex_lock(&thumb_lock); ++ + #ifdef FFMPEGTHUMBNAILER_OLD_API + video_thumbnailer *th = create_thumbnailer(); + image_data *img = create_image_data(); +@@ -474,8 +481,11 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + if (video_thumbnailer_generate_thumbnail_to_buffer(th, + item->getLocation().c_str(), img) != 0) + #endif // old api ++ { ++ pthread_mutex_unlock(&thumb_lock); + throw _Exception(_("Could not generate thumbnail for ") + + item->getLocation()); ++ } + if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) { + writeThumbnailCacheFile(item->getLocation(), + img->image_data_ptr, img->image_data_size); +@@ -491,6 +501,7 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + video_thumbnailer_destroy_image_data(img); + video_thumbnailer_destroy(th); + #endif// old api ++ pthread_mutex_unlock(&thumb_lock); + return h; + #else + return nil; diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-time-t.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-time-t.patch new file mode 100644 index 000000000000..9961b5fede1f --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-time-t.patch @@ -0,0 +1,56 @@ +From 73d12ad230a4ef4694f8d58b249ec6c2804ee324 Mon Sep 17 00:00:00 2001 +From: Mike Frysinger <vapier@gentoo.org> +Date: Tue, 5 Apr 2016 22:56:27 -0400 +Subject: [PATCH] fix storage quoting with long long values + +On 32-bit systems w/64-bit time_t's (like the x32 ABI) we fail to build: +../src/storage/sql_storage.cc: In member function 'virtual void SQLStorage::autoscanUpdateLM(zmm::Ref<AutoscanDirectory>)': +../src/storage/sql_storage.cc:2139:81: error: call of overloaded 'quote(time_t)' is ambiguous + << " SET " << TQ("last_modified") << '=' << quote(adir->getPreviousLMT()) + +Handle long long types explicitly to fix that. +--- + src/storage/mysql/mysql_storage.h | 1 + + src/storage/sql_storage.h | 1 + + src/storage/sqlite3/sqlite3_storage.h | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/src/storage/mysql/mysql_storage.h b/src/storage/mysql/mysql_storage.h +index c377d76..eaec12c 100644 +--- a/src/storage/mysql/mysql_storage.h ++++ b/src/storage/mysql/mysql_storage.h +@@ -55,6 +55,7 @@ private: + virtual inline zmm::String quote(unsigned long val) { return zmm::String::from(val); } + virtual inline zmm::String quote(bool val) { return zmm::String(val ? '1' : '0'); } + virtual inline zmm::String quote(char val) { return quote(zmm::String(val)); } ++ virtual inline zmm::String quote(long long val) { return zmm::String::from(val); } + virtual zmm::Ref<SQLResult> select(const char *query, int length); + virtual int exec(const char *query, int length, bool getLastInsertId = false); + virtual void storeInternalSetting(zmm::String key, zmm::String value); +diff --git a/src/storage/sql_storage.h b/src/storage/sql_storage.h +index 833693a..bd1afc3 100644 +--- a/src/storage/sql_storage.h ++++ b/src/storage/sql_storage.h +@@ -81,6 +81,7 @@ public: + virtual zmm::String quote(unsigned long val) = 0; + virtual zmm::String quote(bool val) = 0; + virtual zmm::String quote(char val) = 0; ++ virtual zmm::String quote(long long val) = 0; + virtual zmm::Ref<SQLResult> select(const char *query, int length) = 0; + virtual int exec(const char *query, int length, bool getLastInsertId = false) = 0; + +diff --git a/src/storage/sqlite3/sqlite3_storage.h b/src/storage/sqlite3/sqlite3_storage.h +index d825bd4..be6294d 100644 +--- a/src/storage/sqlite3/sqlite3_storage.h ++++ b/src/storage/sqlite3/sqlite3_storage.h +@@ -160,6 +160,7 @@ private: + virtual inline zmm::String quote(unsigned long val) { return zmm::String::from(val); } + virtual inline zmm::String quote(bool val) { return zmm::String(val ? '1' : '0'); } + virtual inline zmm::String quote(char val) { return quote(zmm::String(val)); } ++ virtual inline zmm::String quote(long long val) { return zmm::String::from(val); } + virtual zmm::Ref<SQLResult> select(const char *query, int length); + virtual int exec(const char *query, int length, bool getLastInsertId = false); + virtual void storeInternalSetting(zmm::String key, zmm::String value); +-- +2.7.4 + diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-youtube-dl.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-youtube-dl.patch new file mode 100644 index 000000000000..6001d2fc5661 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-youtube-dl.patch @@ -0,0 +1,141 @@ +--- mediatomb-0.12.1.orig/src/youtube_video_url.cc 2013-12-17 22:46:24.272442249 +0000 ++++ mediatomb-0.12.1/src/youtube_video_url.cc 2013-12-17 22:57:25.968039083 +0000 +@@ -117,89 +117,68 @@ String YouTubeVideoURL::getVideoURL(Stri + + watch = _(YOUTUBE_URL_WATCH) + video_id; + +- Ref<URL> url(new URL(YOUTUBE_PAGESIZE)); ++ /* ++ * NOTE ON PATCH: ++ * ++ * The original code does not seem to work anymore. ++ * ++ * I have commented-out all the original code, and instead ++ * replaced it with a call/exec to youtube-dl (this is a separate/stand-alone python script). ++ * ++ * Available at http://rg3.github.io/youtube-dl/ ++ * ++ * ++ * The current code works on a/my samsung TV. I have not tested it further on other devices. ++ * (I needed a quick fix, because I wanted to watch some video's. :) ) ++ * ++ * I thought I would share the results. ++ * ++ * Suggestions / feedback -> bas-patch@tcfaa.nl ++ * ++ * Regards, Bas Nedermeijer ++ */ ++ ++ int pipefd[2]; ++ pipe(pipefd); ++ ++ if (fork() == 0) ++ { ++ // close reading end in the child ++ close(pipefd[0]); ++ ++ // send stdout to the pipe ++ dup2(pipefd[1], 1); ++ // send stderr to the pipe ++ dup2(pipefd[1], 2); + +- Ref<StringBuffer> buffer = url->download(watch, &retcode, curl_handle, +- false, verbose, true); +- if (retcode != 200) +- { +- throw _Exception(_("Failed to get URL for video with id ") +- + watch + _("HTTP response code: ") + +- String::from(retcode)); +- } ++ // this descriptor is no longer needed ++ close(pipefd[1]); + +- log_debug("------> GOT BUFFER %s\n", buffer->toString().c_str()); +- +- Ref<Matcher> matcher = reVideoURLParams->matcher(buffer->toString()); +- String params; +- if (matcher->next()) +- { +-// params = trim_string(matcher->group(1)); +- params = trim_string( matcher->group( 0 ) ); +- /* +- int brace = params.index( '{' ); +- if ( brace > 0 ) +- params = params.substring( brace ); +- brace = params.index( '}' ); +- if ( brace > 0 ) +- params = params.substring( 0, brace + 1 ); +- */ +- Ref<Matcher> m2 = param_t->matcher(params); +- if (m2->next()) +- { +- String hmm = m2->group(1); +- if (string_ok(hmm)) +- params = hmm; +- else +- { +- throw _Exception(_("Could not retrieve \"t\" parameter.")); +- } +- } ++ // This code assumes youtube-dl is available for usage. ++ execl("/usr/bin/youtube-dl", "/usr/bin/youtube-dl","-g",watch.c_str(),NULL); + } + else + { +- throw _Exception(_("Failed to get URL for video with id (step 1)") + video_id); +- } ++ // parent ++ char buffery[8192]; ++ memset(&buffery[0], 0, sizeof(buffery)); + +- params = _(YOUTUBE_URL_GET) + YOUTUBE_URL_PARAM_VIDEO_ID + '=' + +- video_id + '&' + YOUTUBE_URL_PARAM_T + '=' + params; ++ close(pipefd[1]); // close the write end of the pipe in the parent + +- if (mp4) +- { +- String format = _("&fmt=18"); +- +- if (hd) ++ // Hopefully the read is never called twice, otherwise the buffer will become corrupt. ++ while (read(pipefd[0], buffery, sizeof(buffery)) != 0) + { +- matcher = HD->matcher(buffer->toString()); +- if (matcher->next()) +- { +- if (trim_string(matcher->group(1)) == "true") +- format = _("&fmt=22"); +- } + } +- +- params = params + format; +- } + +- buffer = url->download(params, &retcode, curl_handle, true, verbose, true); ++ log_debug("------> GOT BUFFER %s\n", buffery); ++ String result = _(buffery); + +- matcher = redirectLocation->matcher(buffer->toString()); +- if (matcher->next()) +- { +- if (string_ok(trim_string(matcher->group(1)))) +- return trim_string(matcher->group(1)); +- else +- throw _Exception(_("Failed to get URL for video with id (step 2)")+ +- video_id); +- } ++ result = trim_string(result); + +- if (retcode != 303) +- { +- throw _Exception(_("Unexpected reply from YouTube: ") + +- String::from(retcode)); +- } ++ log_debug("------> GOT BUFFER (after trimming) %s\n", result.c_str()); + +- throw _Exception(_("Could not retrieve YouTube video URL")); ++ return result; ++ } + } + + #endif//YOUTUBE diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1.initd b/net-misc/mediatomb/files/mediatomb-0.12.1.initd new file mode 100644 index 000000000000..6c7989d89d66 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1.initd @@ -0,0 +1,28 @@ +#!/sbin/openrc-run +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +depend() { + need net + # In order to properly support this (need vs use), we would have to + # parse ${MEDIATOMB_CONFIG} and see if mysql is enabled and if it is + # pointing to the local system. #368409 + use mysql +} + +start() { + ebegin "Starting MediaTomb" + start-stop-daemon --start --quiet --exec /usr/bin/mediatomb \ + --pidfile ${MEDIATOMB_PIDFILE} -- --daemon \ + --pidfile ${MEDIATOMB_PIDFILE} --user ${MEDIATOMB_USER} \ + --group ${MEDIATOMB_GROUP} --logfile ${MEDIATOMB_LOGFILE} \ + --config ${MEDIATOMB_CONFIG} --port ${MEDIATOMB_PORT} \ + ${MEDIATOMB_OPTIONS} + eend $? +} + +stop () { + ebegin "Stopping MediaTomb" + start-stop-daemon --stop --retry 10 --quiet --pidfile ${MEDIATOMB_PIDFILE} + eend $? +} diff --git a/net-misc/mediatomb/mediatomb-0.12.1-r8.ebuild b/net-misc/mediatomb/mediatomb-0.12.1-r8.ebuild new file mode 100644 index 000000000000..dbd677893117 --- /dev/null +++ b/net-misc/mediatomb/mediatomb-0.12.1-r8.ebuild @@ -0,0 +1,158 @@ +# Copyright 1999-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=5 +inherit autotools eutils linux-info user + +DEB_VER="5" +DESCRIPTION="MediaTomb is an open source UPnP MediaServer" +HOMEPAGE="http://www.mediatomb.cc/" + +SRC_URI="mirror://sourceforge/mediatomb/${P}.tar.gz + mirror://debian/pool/main/${PN:0:1}/${PN}/${PN}_${PV}-${DEB_VER}.debian.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="amd64 ~arm ~ppc x86" + +IUSE="curl debug +exif +ffmpeg flac id3tag +inotify +javascript lastfm + libextractor +magic +mp4 mysql +sqlite +taglib thumbnail +zlib" +REQUIRED_USE=" + || ( mysql sqlite ) + taglib? ( !id3tag ) + id3tag? ( !taglib ) + thumbnail? ( ffmpeg !libextractor ) + ffmpeg? ( !libextractor ) + libextractor? ( !ffmpeg !thumbnail ) +" + +DEPEND="mysql? ( virtual/mysql ) + dev-libs/expat + id3tag? ( media-libs/id3lib ) + javascript? ( >=dev-lang/spidermonkey-1.8.5:0 ) + taglib? ( media-libs/taglib ) + sqlite? ( >=dev-db/sqlite-3 ) + lastfm? ( >=media-libs/lastfmlib-0.4 ) + exif? ( media-libs/libexif ) + libextractor? ( media-libs/libextractor ) + mp4? ( >=media-libs/libmp4v2-1.9.1_p479:0 ) + ffmpeg? ( virtual/ffmpeg ) + flac? ( media-libs/flac ) + thumbnail? ( media-video/ffmpegthumbnailer[jpeg] ) + curl? ( net-misc/curl net-misc/youtube-dl ) + magic? ( sys-apps/file ) + sys-apps/util-linux + zlib? ( sys-libs/zlib ) + virtual/libiconv +" +RDEPEND="${DEPEND}" + +CONFIG_CHECK="~INOTIFY_USER" + +pkg_setup() { + enewgroup mediatomb + enewuser mediatomb -1 -1 /dev/null mediatomb +} + +src_prepare() { + # Apply Debians patchset + local p dd="${WORKDIR}"/debian/patches + sed -i -r '/^[-+]{3} /s:[.][.]/::' "${dd}"/* || die + # We use our version as it seems to be more complete. + sed -i '/^0010_fix_libmp4v2_build.patch/d' "${dd}"/series || die + for p in $(<"${dd}"/series) ; do + epatch "${dd}"/${p} + done + + # libmp4v2 API breakage #410235 + epatch "${FILESDIR}"/${P}-libmp4v2.patch + + # Use system libuuid #270830 + epatch "${FILESDIR}"/${P}-system-uuid.patch + + # Support spidermonkey-187 #423991 #482392 + if has_version "~dev-lang/spidermonkey-1.8.7" ; then + epatch "${FILESDIR}"/${P}-mozjs187.patch + fi + + # Support libextractor-0.6.0 #435394 + epatch "${FILESDIR}"/${P}-libextractor.patch + + # Fix inotify and hard links + epatch "${FILESDIR}"/${P}-inotify-hard-links.patch + + # Add support for caching thumbnails + epatch "${FILESDIR}"/${P}-thumb-cache.patch + epatch "${FILESDIR}"/${P}-thumbnail-locking.patch + + # Respect AR #464710 + epatch "${FILESDIR}"/${P}-system-ar.patch + + # Add flac metadata support #494398 + epatch "${FILESDIR}"/${P}-flac-metadata.patch + + # Work around broken youtube support by using youtube-dl #467110 + epatch "${FILESDIR}"/${P}-youtube-dl.patch + + epatch "${FILESDIR}"/${P}-time-t.patch + + epatch_user + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable curl) \ + $(use_enable curl youtube) \ + $(use_enable debug tombdebug) \ + $(use_enable exif libexif) \ + $(use_enable ffmpeg) \ + $(use_enable flac FLAC) \ + $(use_enable id3tag id3lib) \ + $(use_enable inotify) \ + $(use_enable javascript libjs) \ + $(use_enable lastfm lastfmlib) \ + $(use_enable libextractor) \ + $(use_enable magic libmagic) \ + $(use_enable mp4 libmp4v2) \ + $(use_enable mysql) \ + $(use_enable sqlite sqlite3) \ + $(use_enable taglib) \ + $(use_enable thumbnail ffmpegthumbnailer) \ + $(use_enable zlib) \ + --enable-external-transcoding \ + --enable-protocolinfo-extension +} + +src_install() { + default + + newinitd "${FILESDIR}"/${PN}-0.12.1.initd ${PN} + use mysql || sed -i -e "/use mysql/d" "${ED}"/etc/init.d/${PN} + newconfd "${FILESDIR}"/${PN}-0.12.0.confd ${PN} + + insinto /etc/mediatomb + newins "${FILESDIR}/${PN}-0.12.0.config" config.xml + fperms 0600 /etc/mediatomb/config.xml + fowners mediatomb:mediatomb /etc/mediatomb/config.xml + + keepdir /var/lib/mediatomb + fowners mediatomb:mediatomb /var/lib/mediatomb +} + +pkg_postinst() { + if use mysql ; then + elog "MediaTomb has been built with MySQL support and needs" + elog "to be configured before being started." + elog "For more information, please consult the MediaTomb" + elog "documentation: http://mediatomb.cc/pages/documentation" + elog + fi + + elog "To configure MediaTomb edit:" + elog "/etc/mediatomb/config.xml" + elog + elog "The MediaTomb web interface can be reached at (after the service is started):" + elog "http://localhost:49152/" +} diff --git a/net-misc/mediatomb/mediatomb-0.12.2_pre20160522.ebuild b/net-misc/mediatomb/mediatomb-0.12.2_pre20160522.ebuild new file mode 100644 index 000000000000..3640a7bd24bc --- /dev/null +++ b/net-misc/mediatomb/mediatomb-0.12.2_pre20160522.ebuild @@ -0,0 +1,122 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=5 +inherit autotools eutils linux-info systemd user vcs-snapshot + +DESCRIPTION="MediaTomb is an open source UPnP MediaServer" +HOMEPAGE="http://www.mediatomb.cc/" +SRC_URI="https://github.com/v00d00/${PN}/archive/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~arm ~x86" + +IUSE="curl debug +exif +ffmpeg flac id3tag +inotify +javascript lastfm + libav +magic +mp4 mysql +sqlite +taglib thumbnail +zlib" +REQUIRED_USE=" + || ( mysql sqlite ) + taglib? ( !id3tag ) + id3tag? ( !taglib ) + thumbnail? ( ffmpeg ) +" + +DEPEND="mysql? ( virtual/mysql ) + dev-libs/expat + id3tag? ( media-libs/id3lib ) + javascript? ( >=dev-lang/spidermonkey-1.8.5:0 ) + taglib? ( media-libs/taglib ) + sqlite? ( >=dev-db/sqlite-3 ) + lastfm? ( >=media-libs/lastfmlib-0.4 ) + exif? ( media-libs/libexif ) + mp4? ( >=media-libs/libmp4v2-1.9.1_p479:0 ) + ffmpeg? ( + libav? ( >=media-video/libav-10:0= ) + !libav? ( >=media-video/ffmpeg-2.2:0= ) + ) + flac? ( media-libs/flac ) + thumbnail? ( media-video/ffmpegthumbnailer[jpeg] ) + curl? ( net-misc/curl net-misc/youtube-dl ) + magic? ( sys-apps/file ) + sys-apps/util-linux + zlib? ( sys-libs/zlib ) + virtual/libiconv +" +RDEPEND="${DEPEND}" + +CONFIG_CHECK="~INOTIFY_USER" + +pkg_setup() { + use inotify && linux-info_pkg_setup + + enewgroup mediatomb + enewuser mediatomb -1 -1 /dev/null mediatomb +} + +src_prepare() { + # Support spidermonkey-187 #423991 #482392 + if has_version "~dev-lang/spidermonkey-1.8.7" ; then + epatch "${FILESDIR}"/${PN}-0.12.1-mozjs187.patch + fi + + epatch_user + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable curl) \ + $(use_enable curl youtube) \ + $(use_enable debug tombdebug) \ + $(use_enable exif libexif) \ + $(use_enable ffmpeg) \ + $(use_enable flac) \ + $(use_enable id3tag id3lib) \ + $(use_enable inotify) \ + $(use_enable javascript libjs) \ + $(use_enable lastfm lastfm) \ + $(use_enable magic libmagic) \ + $(use_enable mp4 libmp4v2) \ + $(use_enable mysql) \ + $(use_enable sqlite sqlite3) \ + $(use_enable taglib) \ + $(use_enable thumbnail ffmpegthumbnailer) \ + --enable-external-transcoding \ + --enable-protocolinfo-extension +} + +src_install() { + default + + systemd_dounit "${S}"/scripts/systemd/"${PN}".service + use mysql && systemd_dounit "${S}"/scripts/systemd/"${PN}"-mysql.service + + newinitd "${FILESDIR}"/${PN}-0.12.1.initd ${PN} + use mysql || sed -i -e "/use mysql/d" "${ED}"/etc/init.d/${PN} + newconfd "${FILESDIR}"/${PN}-0.12.0.confd ${PN} + + insinto /etc/mediatomb + newins "${FILESDIR}/${PN}-0.12.0.config" config.xml + fperms 0600 /etc/mediatomb/config.xml + fowners mediatomb:mediatomb /etc/mediatomb/config.xml + + keepdir /var/lib/mediatomb + fowners mediatomb:mediatomb /var/lib/mediatomb +} + +pkg_postinst() { + if use mysql ; then + elog "MediaTomb has been built with MySQL support and needs" + elog "to be configured before being started." + elog "For more information, please consult the MediaTomb" + elog "documentation: http://mediatomb.cc/pages/documentation" + elog + fi + + elog "To configure MediaTomb edit:" + elog "/etc/mediatomb/config.xml" + elog + elog "The MediaTomb web interface can be reached at (after the service is started):" + elog "http://localhost:49152/" +} diff --git a/net-misc/mediatomb/metadata.xml b/net-misc/mediatomb/metadata.xml new file mode 100644 index 000000000000..f49135825709 --- /dev/null +++ b/net-misc/mediatomb/metadata.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> +<pkgmetadata> + <maintainer type="person"> + <email>thev00d00@gentoo.org</email> + <name>Ian Whyman</name> + </maintainer> + <maintainer type="project"> + <email>media-video@gentoo.org</email> + <name>Gentoo Video project</name> + </maintainer> + <use> + <flag name="curl">Support YouTube and external media sources (e.g. internet radio)</flag> + <flag name="flac">Enable FLAC metadata/artwork support</flag> + <flag name="id3tag">Use <pkg>media-libs/libid3tag</pkg> for reading files' metadata rather than taglib</flag> + <flag name="inotify">Enable inotify filesystem monitoring support</flag> + <flag name="lastfm">Enable last.fm support</flag> + <flag name="libextractor">Use libextractor to gather files' metadata</flag> + <flag name="magic">Use libmagic to determine file types</flag> + <flag name="mysql">Use <pkg>dev-db/mysql</pkg> as backend rather than SQLite3</flag> + <flag name="taglib">Use <pkg>media-libs/taglib</pkg> for reading files' metadata rather than id3lib</flag> + <flag name="thumbnail">Enables video thumbnails generation through <pkg>media-video/ffmpegthumbnailer</pkg></flag> + </use> + <upstream> + <remote-id type="github">v00d00/mediatomb</remote-id> + <remote-id type="sourceforge">mediatomb</remote-id> + </upstream> +</pkgmetadata> |