{"action":"created","comment":{"url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/comments/92717380","pull_request_review_id":13238775,"id":92717380,"diff_hunk":"@@ -145,4 +161,335 @@ public static void parseImageByImaging(File file, DLNAMediaInfo media) throws Im\n \t\t\tmedia.setCodecV(FormatConfiguration.TIFF);\n \t\t}\n \t}\n+\n+\t/**\n+\t * This attempts to get the underlying byte array directly from the\n+\t * {@link InputStream} if it is backed by a byte array, otherwise the\n+\t * {@link InputStream} is copied into a new byte array with\n+\t * {@link IOUtils#toByteArray(InputStream)}.\n+\t * <p><b>\n+\t * This method consumes and closes {@code inputStream}.\n+\t * </b>\n+\t * @param inputStream the <code>InputStream</code> to read.\n+     * @return The resulting byte array.\n+     * @throws IOException if an I/O error occurs\n+\t */\n+\tpublic static byte[] toByteArray(InputStream inputStream) throws IOException {\n+\t\tif (inputStream == null) {\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\t// Avoid copying the data if it's already a byte array\n+\t\tif (inputStream instanceof ByteArrayInputStream) {\n+\t\t\tField f;\n+\t\t\ttry {\n+\t\t\t\tf = ByteArrayInputStream.class.getDeclaredField(\"buf\");\n+\t\t\t\tf.setAccessible(true);\n+\t\t\t\treturn (byte[]) f.get(inputStream);\n+\t\t\t} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {\n+\t\t\t\t// Reflection failed, use IOUtils instead\n+\t\t\t\tLOGGER.debug(\"Unexpected reflection failure in toByteArray(): {}\", e.getMessage());\n+\t\t\t\tLOGGER.trace(\"\", e);\n+\t\t\t}\n+\t\t}\n+\t\ttry {\n+\t\t\treturn IOUtils.toByteArray(inputStream);\n+\t\t} finally {\n+\t\t\tinputStream.close();\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Converts image to a different {@link ImageFormat}. Format support is\n+\t * limited to that of {@link ImageIO}.\n+\t * <p><b>\n+\t * This method consumes and closes {@code inputStream}.\n+\t * </b>\n+\t *\n+\t * @param imageInputStream the source image in a supported format.\n+\t * @param outputFormat the {@link ImageFormat} to generate. If this is\n+\t *                     {@link ImageFormat#SOURCE} or {@code null} this has\n+\t *                     no effect.\n+\t * @return The converted image, {@code null} if the source is {@code null}\n+\t *         or the source image if the operation fails.\n+\t */\n+\tpublic static InputStream convertImage(InputStream imageInputStream, ImageFormat outputFormat) {\n+\t\tif (imageInputStream == null) {\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\tbyte[] imageByteArray = null;\n+\t\ttry {\n+\t\t\timageByteArray = toByteArray(imageInputStream);\n+\t\t} catch (IOException e) {\n+\t\t\tLOGGER.warn(\"Converting image failed: {}\", e.getMessage());\n+\t\t\tLOGGER.trace(\"\", e);\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\tbyte[] result = scaleImage(imageByteArray, 0, 0, null, outputFormat, false);\n+\t\treturn result == null ? null : new ByteArrayInputStream(result);\n+\t}\n+\n+\t/**\n+\t * Converts image to a different {@link ImageFormat}. Format support is\n+\t * limited to that of {@link ImageIO}.\n+\t *\n+\t * @param imageByteArray the source image in a supported format.\n+\t * @param outputFormat the {@link ImageFormat} to generate. If this is\n+\t *                     {@link ImageFormat#SOURCE} or {@code null} this has\n+\t *                     no effect.\n+\t * @return The converted image, {@code null} if the source is {@code null}\n+\t *         or the source image if the operation fails.\n+\t */\n+\tpublic static byte[] convertImage(byte[] imageByteArray, ImageFormat outputFormat) {\n+\t\tif (outputFormat == null || outputFormat.equals(ImageFormat.SOURCE)) {\n+\t\t\treturn imageByteArray;\n+\t\t}\n+\t\treturn scaleImage(imageByteArray, 0, 0, null, outputFormat, false);\n+\t}\n+\n+\t/**\n+\t * Convert and scales an image for use as a thumbnail for a specific\n+\t * {@code RendererConfiguration} .Preserves aspect ratio. Format support is\n+\t * limited to that of {@link ImageIO}.\n+\t * <p><b>\n+\t * This method consumes and closes {@code inputStream}.\n+\t * </b>\n+\t *\n+\t * @param imageInputStream the source image in a supported format.\n+\t * @param imageProfile the DLNA media profile to adhere to for the output.\n+\t * @param renderer the {@link RendererConfiguration} to get output settings\n+\t *                 from.\n+\t * @return The scaled and/or converted thumbnail, {@code null} if the\n+\t *         source is {@code null} or the source image if the operation fails.\n+\t *\n+\t * XXX Ideally all internal thumb handling should be done using byte arrays\n+\t *     instead of streams, and this overload could be removed.\n+\t */\n+\tpublic static InputStream scaleThumb(InputStream imageInputStream, ImageProfile imageProfile, RendererConfiguration renderer) {\n+\t\tif (imageInputStream == null) {\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\tbyte[] imageByteArray = null;\n+\t\ttry {\n+\t\t\timageByteArray = toByteArray(imageInputStream);\n+\t\t} catch (IOException e) {\n+\t\t\tLOGGER.warn(\"Renderer scaling failed: {}\", e.getMessage());\n+\t\t\tLOGGER.trace(\"\", e);\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\tbyte[] result = scaleThumb(imageByteArray, imageProfile, renderer);\n+\t\treturn result == null ? null : new ByteArrayInputStream(result);\n+\t}\n+\n+\t/**\n+\t *\n+\t * @param fileName the \"file name\" part of the HTTP request.\n+\t * @return The \"decoded\" {@link ImageProfile} or {@link ImageProfile#JPEG_TN}\n+\t *         if the parsing fails.\n+\t */\n+\tpublic static ImageProfile parseThumbRequest(String fileName) {\n+\t\tMatcher matcher = Pattern.compile(\"^thumbnail0000(\\\\w+_\\\\w+)_\").matcher(fileName);\n+\t\tif (matcher.find()) {\n+\t\t\ttry {\n+\t\t\t\treturn ImageProfile.valueOf(matcher.group(1).toUpperCase(Locale.ROOT));\n+\t\t\t} catch (IllegalArgumentException e) {\n+\t\t\t\treturn ImageProfile.JPEG_TN;\n+\t\t\t}\n+\t\t}\n+\t\treturn ImageProfile.JPEG_TN;\n+\t}\n+\n+\t/**\n+\t * Convert and scales an image for use as a thumbnail for a specific\n+\t * {@code RendererConfiguration} .Preserves aspect ratio. Format support is\n+\t * limited to that of {@link ImageIO}.\n+\t *\n+\t * @param imageByteArray the source image in a supported format.\n+\t * @param imageProfile the DLNA media profile to adhere to for the output.\n+\t * @param renderer the {@link RendererConfiguration} to get output settings\n+\t *                 from.\n+\t * @return The scaled and/or converted thumbnail, {@code null} if the\n+\t *         source is {@code null} or the source image if the operation fails.\n+\t */\n+\tpublic static byte[] scaleThumb(byte[] imageByteArray, ImageProfile imageProfile, RendererConfiguration renderer) {\n+\t\tswitch (imageProfile) {\n+\t\t\tcase JPEG_LRG:\n+\t\t\t\treturn scaleImage(imageByteArray, 4096, 4096, ScaleType.MAX, ImageFormat.JPEG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t\tcase JPEG_MED:\n+\t\t\t\treturn scaleImage(imageByteArray, 1024, 768, ScaleType.MAX, ImageFormat.JPEG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t\tcase JPEG_SM:\n+\t\t\t\treturn scaleImage(imageByteArray, 640, 480, ScaleType.MAX, ImageFormat.JPEG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t\tcase JPEG_TN:\n+\t\t\t\treturn scaleImage(imageByteArray, 160, 160, ScaleType.MAX, ImageFormat.JPEG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t\tcase PNG_LRG:\n+\t\t\t\treturn scaleImage(imageByteArray, 4096, 4096, ScaleType.MAX, ImageFormat.PNG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t\tcase PNG_TN:\n+\t\t\t\treturn scaleImage(imageByteArray, 160, 160, ScaleType.MAX, ImageFormat.PNG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t\tdefault:\n+\t\t\t\treturn scaleImage(imageByteArray, 160, 160, ScaleType.MAX, ImageFormat.JPEG, renderer != null ? renderer.isThumbnailPadding() : false);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Scales an image to the given dimensions. Scaling can be with or without\n+\t * padding. Preserves aspect ratio. Format support is limited to\n+\t * that of {@link ImageIO}.\n+\t *\n+\t * @param imageByteArray the source image in a supported format.\n+\t * @param fitTo the {@link Rectangle} to fit the image to.\n+\t * @param padToSize Whether padding should be used if source aspect doesn't\n+\t *                  match target aspect.\n+\t * @return The scaled, {@code null} if the source is {@code null} or the\n+\t *         source image if the operation fails.\n+\t */\n+\tpublic static byte[] scaleImage(byte[] imageByteArray, Rectangle fitTo, boolean padToSize) {\n+\t\tif (fitTo.isEmpty()) {\n+\t\t\treturn imageByteArray;\n+\t\t}\n+\t\treturn scaleImage(imageByteArray, fitTo.width, fitTo.height, ScaleType.EXACT, ImageFormat.SOURCE, padToSize);\n+\t}\n+\n+\t/**\n+\t * Scales an image to the given dimensions. Scaling can be with or without\n+\t * padding. Preserves aspect ratio. Format support is limited to\n+\t * that of {@link ImageIO}.\n+\t *\n+\t * @param imageByteArray the source image in a supported format.\n+\t * @param width the new width.\n+\t * @param height the new height.\n+\t * @param padToSize Whether padding should be used if source aspect doesn't\n+\t *                  match target aspect.\n+\t * @return The scaled, {@code null} if the source is {@code null} or the\n+\t *         source image if the operation fails.\n+\t */\n+\n+\tpublic static byte[] scaleImage(byte[] imageByteArray, int width, int height, boolean padToSize) {\n+\t\tif (width == 0 || height == 0) {\n+\t\t\treturn imageByteArray;\n+\t\t}\n+\t\treturn scaleImage(imageByteArray, width, height, ScaleType.EXACT, ImageFormat.SOURCE, padToSize);\n+\t}\n+\n+\t/**\n+\t * Converts and scales an image in one operation. Scaling can be with or\n+\t * without padding. Preserves aspect ratio. Format support is limited to\n+\t * that of {@link ImageIO}.\n+\t *\n+\t * @param imageByteArray the source image in a supported format.\n+\t * @param width the new width or 0 to disable scaling.\n+\t * @param height the new height or 0 to disable scaling.\n+\t * @param scaleType the {@link ScaleType} to use when scaling.\n+\t * @param outputFormat the {@link ImageFormat} to generate or\n+\t *                     {@link ImageFormat#SOURCE} to preserve source format.\n+\t * @param padToSize Whether padding should be used if source aspect doesn't\n+\t *                  match target aspect.\n+\t * @return The scaled and/or converted image, {@code null} if the source is\n+\t *         {@code null} or the source image if the operation fails.\n+\t */\n+\tpublic static byte[] scaleImage(byte[] imageByteArray, int width, int height, ScaleType scaleType, ImageFormat outputFormat, boolean padToSize) {\n+\t\tif (imageByteArray == null) {\n+\t\t\treturn null;\n+\t\t}\n+\t\tif (outputFormat == null) {\n+\t\t\toutputFormat = ImageFormat.SOURCE;\n+\t\t}\n+\n+\t\ttry {\n+\t\t\tImageFormat inputFormat = null;\n+\t\t\tBufferedImage bufferedImage;\n+\t\t\tImageReaderResult imageResult = CustomImageReader.read(new ByteArrayInputStream(imageByteArray));\n+\t\t\tbufferedImage = imageResult.bufferedImage;\n+\t\t\tinputFormat = imageResult.imageFormat;\n+\n+\t\t\tif (bufferedImage == null || inputFormat == null) { // ImageIO doesn't support the image format\n+\t\t\t\tLOGGER.warn(\"Failed to resize image because the source format is unknown\");\n+\t\t\t\treturn imageByteArray;\n+\t\t\t}\n+\n+\t\t\tif (outputFormat.equals(ImageFormat.SOURCE)) {\n+\t\t\t\toutputFormat = inputFormat;\n+\t\t\t}\n+\n+\t\t\tByteArrayOutputStream out = new ByteArrayOutputStream();\n+\t\t\tif (width == 0 ||\n+\t\t\t\theight == 0 ||\n+\t\t\t\t(\n+\t\t\t\t\tScaleType.MAX.equals(scaleType) &&\n+\t\t\t\t\tbufferedImage.getWidth() <= width &&\n+\t\t\t\t\tbufferedImage.getHeight() <= height\n+\t\t\t\t)\n+\t\t\t) {\n+\t\t\t\t//No resize, just convert\n+\t\t\t\tif (inputFormat.equals(outputFormat)) {\n+\t\t\t\t\t// Nothing to do, just return source\n+\t\t\t\t\treturn imageByteArray;\n+\t\t\t\t}\n+\t\t\t\tImageIO.write(bufferedImage, outputFormat.toString(),out);","path":"src/main/java/net/pms/util/ImagesUtil.java","position":323,"original_position":323,"commit_id":"be464c25dad65b6252fb75c586b45b9d2ed4edba","original_commit_id":"be464c25dad65b6252fb75c586b45b9d2ed4edba","user":{"login":"valib","id":1472678,"avatar_url":"https://avatars.githubusercontent.com/u/1472678?v=3","gravatar_id":"","url":"https://api.github.com/users/valib","html_url":"https://github.com/valib","followers_url":"https://api.github.com/users/valib/followers","following_url":"https://api.github.com/users/valib/following{/other_user}","gists_url":"https://api.github.com/users/valib/gists{/gist_id}","starred_url":"https://api.github.com/users/valib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/valib/subscriptions","organizations_url":"https://api.github.com/users/valib/orgs","repos_url":"https://api.github.com/users/valib/repos","events_url":"https://api.github.com/users/valib/events{/privacy}","received_events_url":"https://api.github.com/users/valib/received_events","type":"User","site_admin":false},"body":"@Nadahar what about to use Thumbnailator\r\n\t\t\t\r\n\t\t\t\tThumbnails.of(bufferedImage)\r\n\t\t\t\t\t.size(bufferedImage.getWidth(), bufferedImage.getHeight())\r\n\t\t\t\t\t.outputFormat(outputFormat.toString())\r\n\t\t\t\t\t.outputQuality(1.0f)\r\n\t\t\t\t\t.toOutputStream(out);\r\n\r\n to fix the error \"Invalid argument to native writeImage\" instead of using ImageIO.write","created_at":"2016-12-15T22:47:31Z","updated_at":"2016-12-15T22:47:31Z","html_url":"https://github.com/UniversalMediaServer/UniversalMediaServer/pull/1061#discussion_r92717380","pull_request_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061","_links":{"self":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/comments/92717380"},"html":{"href":"https://github.com/UniversalMediaServer/UniversalMediaServer/pull/1061#discussion_r92717380"},"pull_request":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061"}}},"pull_request":{"url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061","id":90464520,"html_url":"https://github.com/UniversalMediaServer/UniversalMediaServer/pull/1061","diff_url":"https://github.com/UniversalMediaServer/UniversalMediaServer/pull/1061.diff","patch_url":"https://github.com/UniversalMediaServer/UniversalMediaServer/pull/1061.patch","issue_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/1061","number":1061,"state":"open","locked":false,"title":"Show generic icons for media whose don't provide thumbnails","user":{"login":"valib","id":1472678,"avatar_url":"https://avatars.githubusercontent.com/u/1472678?v=3","gravatar_id":"","url":"https://api.github.com/users/valib","html_url":"https://github.com/valib","followers_url":"https://api.github.com/users/valib/followers","following_url":"https://api.github.com/users/valib/following{/other_user}","gists_url":"https://api.github.com/users/valib/gists{/gist_id}","starred_url":"https://api.github.com/users/valib/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/valib/subscriptions","organizations_url":"https://api.github.com/users/valib/orgs","repos_url":"https://api.github.com/users/valib/repos","events_url":"https://api.github.com/users/valib/events{/privacy}","received_events_url":"https://api.github.com/users/valib/received_events","type":"User","site_admin":false},"body":"Show generic icons (thumbnails) for media whose don't provide  thumbnails or  thumbnails are not generated for them like  audio files wihout CoverArt. It can be simply updated by addding images with convention \"media format\".png and \"media format\".jpg to the resources/images folder. Images I provided in this commit are only for testing because I think  that they could be changed to something better.\n","created_at":"2016-10-22T01:03:39Z","updated_at":"2016-12-15T22:47:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8615a1f4f7ba6af9bff4dec32ae28331dca640c0","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061/commits","review_comments_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061/comments","review_comment_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/comments{/number}","comments_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/1061/comments","statuses_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/statuses/be464c25dad65b6252fb75c586b45b9d2ed4edba","head":{"label":"UniversalMediaServer:show_generic_icons","ref":"show_generic_icons","sha":"be464c25dad65b6252fb75c586b45b9d2ed4edba","user":{"login":"UniversalMediaServer","id":1840565,"avatar_url":"https://avatars.githubusercontent.com/u/1840565?v=3","gravatar_id":"","url":"https://api.github.com/users/UniversalMediaServer","html_url":"https://github.com/UniversalMediaServer","followers_url":"https://api.github.com/users/UniversalMediaServer/followers","following_url":"https://api.github.com/users/UniversalMediaServer/following{/other_user}","gists_url":"https://api.github.com/users/UniversalMediaServer/gists{/gist_id}","starred_url":"https://api.github.com/users/UniversalMediaServer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UniversalMediaServer/subscriptions","organizations_url":"https://api.github.com/users/UniversalMediaServer/orgs","repos_url":"https://api.github.com/users/UniversalMediaServer/repos","events_url":"https://api.github.com/users/UniversalMediaServer/events{/privacy}","received_events_url":"https://api.github.com/users/UniversalMediaServer/received_events","type":"Organization","site_admin":false},"repo":{"id":4591214,"name":"UniversalMediaServer","full_name":"UniversalMediaServer/UniversalMediaServer","owner":{"login":"UniversalMediaServer","id":1840565,"avatar_url":"https://avatars.githubusercontent.com/u/1840565?v=3","gravatar_id":"","url":"https://api.github.com/users/UniversalMediaServer","html_url":"https://github.com/UniversalMediaServer","followers_url":"https://api.github.com/users/UniversalMediaServer/followers","following_url":"https://api.github.com/users/UniversalMediaServer/following{/other_user}","gists_url":"https://api.github.com/users/UniversalMediaServer/gists{/gist_id}","starred_url":"https://api.github.com/users/UniversalMediaServer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UniversalMediaServer/subscriptions","organizations_url":"https://api.github.com/users/UniversalMediaServer/orgs","repos_url":"https://api.github.com/users/UniversalMediaServer/repos","events_url":"https://api.github.com/users/UniversalMediaServer/events{/privacy}","received_events_url":"https://api.github.com/users/UniversalMediaServer/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/UniversalMediaServer/UniversalMediaServer","description":"A DLNA-compliant UPnP Media Server.","fork":false,"url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer","forks_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/forks","keys_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/teams","hooks_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/hooks","issue_events_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/events{/number}","events_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/events","assignees_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/assignees{/user}","branches_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/branches{/branch}","tags_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/tags","blobs_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/refs{/sha}","trees_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/statuses/{sha}","languages_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/languages","stargazers_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/stargazers","contributors_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/contributors","subscribers_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/subscribers","subscription_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/subscription","commits_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/commits{/sha}","git_commits_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/commits{/sha}","comments_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/comments{/number}","issue_comment_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/comments{/number}","contents_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/contents/{+path}","compare_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/merges","archive_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/downloads","issues_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues{/number}","pulls_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls{/number}","milestones_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/milestones{/number}","notifications_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/labels{/name}","releases_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/releases{/id}","deployments_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/deployments","created_at":"2012-06-07T22:23:22Z","updated_at":"2016-12-14T12:14:52Z","pushed_at":"2016-12-14T15:29:53Z","git_url":"git://github.com/UniversalMediaServer/UniversalMediaServer.git","ssh_url":"git@github.com:UniversalMediaServer/UniversalMediaServer.git","clone_url":"https://github.com/UniversalMediaServer/UniversalMediaServer.git","svn_url":"https://github.com/UniversalMediaServer/UniversalMediaServer","homepage":null,"size":36627,"stargazers_count":453,"watchers_count":453,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":175,"mirror_url":null,"open_issues_count":274,"forks":175,"open_issues":274,"watchers":453,"default_branch":"master"}},"base":{"label":"UniversalMediaServer:master","ref":"master","sha":"78727617308731681bafbe20ab11f03b4a58d1f0","user":{"login":"UniversalMediaServer","id":1840565,"avatar_url":"https://avatars.githubusercontent.com/u/1840565?v=3","gravatar_id":"","url":"https://api.github.com/users/UniversalMediaServer","html_url":"https://github.com/UniversalMediaServer","followers_url":"https://api.github.com/users/UniversalMediaServer/followers","following_url":"https://api.github.com/users/UniversalMediaServer/following{/other_user}","gists_url":"https://api.github.com/users/UniversalMediaServer/gists{/gist_id}","starred_url":"https://api.github.com/users/UniversalMediaServer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UniversalMediaServer/subscriptions","organizations_url":"https://api.github.com/users/UniversalMediaServer/orgs","repos_url":"https://api.github.com/users/UniversalMediaServer/repos","events_url":"https://api.github.com/users/UniversalMediaServer/events{/privacy}","received_events_url":"https://api.github.com/users/UniversalMediaServer/received_events","type":"Organization","site_admin":false},"repo":{"id":4591214,"name":"UniversalMediaServer","full_name":"UniversalMediaServer/UniversalMediaServer","owner":{"login":"UniversalMediaServer","id":1840565,"avatar_url":"https://avatars.githubusercontent.com/u/1840565?v=3","gravatar_id":"","url":"https://api.github.com/users/UniversalMediaServer","html_url":"https://github.com/UniversalMediaServer","followers_url":"https://api.github.com/users/UniversalMediaServer/followers","following_url":"https://api.github.com/users/UniversalMediaServer/following{/other_user}","gists_url":"https://api.github.com/users/UniversalMediaServer/gists{/gist_id}","starred_url":"https://api.github.com/users/UniversalMediaServer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UniversalMediaServer/subscriptions","organizations_url":"https://api.github.com/users/UniversalMediaServer/orgs","repos_url":"https://api.github.com/users/UniversalMediaServer/repos","events_url":"https://api.github.com/users/UniversalMediaServer/events{/privacy}","received_events_url":"https://api.github.com/users/UniversalMediaServer/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/UniversalMediaServer/UniversalMediaServer","description":"A DLNA-compliant UPnP Media Server.","fork":false,"url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer","forks_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/forks","keys_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/teams","hooks_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/hooks","issue_events_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/events{/number}","events_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/events","assignees_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/assignees{/user}","branches_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/branches{/branch}","tags_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/tags","blobs_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/refs{/sha}","trees_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/statuses/{sha}","languages_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/languages","stargazers_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/stargazers","contributors_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/contributors","subscribers_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/subscribers","subscription_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/subscription","commits_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/commits{/sha}","git_commits_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/git/commits{/sha}","comments_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/comments{/number}","issue_comment_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/comments{/number}","contents_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/contents/{+path}","compare_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/merges","archive_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/downloads","issues_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues{/number}","pulls_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls{/number}","milestones_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/milestones{/number}","notifications_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/labels{/name}","releases_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/releases{/id}","deployments_url":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/deployments","created_at":"2012-06-07T22:23:22Z","updated_at":"2016-12-14T12:14:52Z","pushed_at":"2016-12-14T15:29:53Z","git_url":"git://github.com/UniversalMediaServer/UniversalMediaServer.git","ssh_url":"git@github.com:UniversalMediaServer/UniversalMediaServer.git","clone_url":"https://github.com/UniversalMediaServer/UniversalMediaServer.git","svn_url":"https://github.com/UniversalMediaServer/UniversalMediaServer","homepage":null,"size":36627,"stargazers_count":453,"watchers_count":453,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":175,"mirror_url":null,"open_issues_count":274,"forks":175,"open_issues":274,"watchers":453,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061"},"html":{"href":"https://github.com/UniversalMediaServer/UniversalMediaServer/pull/1061"},"issue":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/1061"},"comments":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/issues/1061/comments"},"review_comments":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061/comments"},"review_comment":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/pulls/1061/commits"},"statuses":{"href":"https://api.github.com/repos/UniversalMediaServer/UniversalMediaServer/statuses/be464c25dad65b6252fb75c586b45b9d2ed4edba"}}}}
{"actor":{"display_login":"valib"}}