{"action":"created","comment":{"url":"https://api.github.com/repos/Flexget/Flexget/pulls/comments/90753820","pull_request_review_id":11274156,"id":90753820,"diff_hunk":"@@ -1,124 +1,561 @@\n from __future__ import unicode_literals, division, absolute_import\n from builtins import *  # noqa pylint: disable=unused-import, redefined-builtin\n-from past.utils import old_div\n-from future.moves.urllib.parse import urlencode, quote\n+from time import mktime\n \n+from xml.dom import minidom\n+from past.builtins import basestring\n+from datetime import datetime\n+from dateutil.parser import parse as dateutil_parse\n+from dateutil.tz import tz\n+from future.moves.urllib.parse import quote_plus\n+\n+import re\n import logging\n+import feedparser\n \n from flexget import plugin\n from flexget.entry import Entry\n from flexget.event import event\n-import feedparser\n+from flexget.config_schema import one_or_more\n+from flexget.utils.tools import parse_timedelta\n+from flexget.utils.template import render_from_entry, RenderError\n+from flexget.utils.search import normalize_unicode\n+from flexget.plugins.parsers.parser_common import normalize_name, remove_dirt\n \n-__author__ = 'deksan'\n+__author__ = 'andy (org. by deksan)'\n \n log = logging.getLogger('newznab')\n \n+CATEGORIES = {\n+    # Games Consoles\n+    'game': 1000,\n+    'game/nds': 1010,\n+    'game/psp': 1020,\n+    'game/wii': 1030,\n+    'game/xbox': 1040,\n+    'game/xbox360': 1050,\n+    'game/wiiware': 1060,\n+    'game/xbox360dlc': 1070,\n+    'game/ps3': 1080,\n+    'game/xbox-one': 1090,  # unofficial\n+    'game/ps4': 1100,  # unofficial\n+    # Movie\n+    'movie': 2000,\n+    'movie/foreign': 2010,\n+    'movie/other': 2020,\n+    'movie/sd': 2030,\n+    'movie/hd': 2040,\n+    'movie/uhd': 2045,  # unofficial\n+    'movie/bluray': 2050,\n+    'movie/3d': 2060,\n+    'movie/dvd': 2070,\n+    'movie/web-dl': 2080,  # unofficial\n+    # Music\n+    'music': 3000,\n+    'music/mp3': 3010,\n+    'music/video': 3020,\n+    'music/audiobook': 3030,\n+    'music/lossless': 3040,\n+    'music/foreign': 3060,  # unofficial\n+    # PC (Games + Software)\n+    'pc': 4000,\n+    'pc/0day': 4010,\n+    'pc/iso': 4020,\n+    'pc/mac': 4030,\n+    'pc/mobile-other': 4040,\n+    'pc/games': 4050,\n+    'pc/mobile-ios': 4060,\n+    'pc/mobile-android': 4070,\n+    # TV\n+    'tv': 5000,\n+    'tv/web-dl': 5010,  # unofficial\n+    'tv/foreign': 5020,\n+    'tv/sd': 5030,\n+    'tv/hd': 5040,\n+    'tv/uhd': 5045,  # unofficial\n+    'tv/other': 5050,\n+    'tv/sport': 5060,\n+    'tv/anime': 5070,\n+    'tv/documentary': 5080,  # unofficial\n+    # XXX\n+    'xxx': 6000,\n+    'xxx/dvd': 6010,\n+    'xxx/wmv': 6020,\n+    'xxx/xvid': 6030,\n+    'xxx/x264': 6040,\n+    'xxx/uhd': 6045,  # unofficial\n+    'xxx/pack': 6050,\n+    'xxx/imageset': 6060,\n+    'xxx/packs': 6070,  # unofficial\n+    'xxx/sd': 6080,  # unofficial\n+    'xxx/web-dl': 6090,  # unofficial\n+    # Misc\n+    'misc': 7000,\n+    'misc/misc': 7010,\n+    'misc/ebook': 7020,\n+    'misc/comics': 7030,\n+    # Unknown\n+    'not-determined': 7900\n+}\n+\n+NEWSNAB_NS_PREFIX = 'newznab_'\n+\n \n class Newznab(object):\n     \"\"\"\n     Newznab search plugin\n-    Provide a url or your website + apikey and a category\n+    Provide the 'api_server_url' + 'api_key and a 'search_type' and optionally newznab categories\n+    'search_type' is any of: 'generic', 'movie', 'tv' can be combined with category\n+    NOTE: If needed will do a metadata lookup for the search_types tv/movie\n+    TIP: Use nzbhydra to perform searches on multiple indexers with one config https://github.com/theotherp/nzbhydra\n+\n+    NOTE: will populate those newznab fields if available:\n+    'newznab_age'       - age in days of this release\n+    'newznab_pubdate'   - date the indexer added the nzb to its database (aka age)\n+    'newznab_guid'      - unique guid of this release\n+    'newznab_grabs'     - number of grabs\n+    'newznab_size'      - size in bytes of the release\n+    'newznab_files'     - number of files this release (archive) has\n+    'newznab_usenetdate'- date the release was posted on usenet\n+    'newznab_password'  - if the release uses a password\n+\n+    Config example:\n+    # simple: uses the (series_name or title) to search in the 'tv' category\n+    newznab:\n+        api_server_url: https://api.nzbindexer.com\n+        api_key: my_apikey\n+        search_type: generic\n+        category: tv\n+\n+    # meta id based: uses the (tvdb/ragetv id) to search only in the tv/hd,uhd categories, for results that are up-to 3 days old\n+    newznab:\n+        api_server_url: https://api.nzbindexer.com\n+        api_key: my_apikey\n+        search_type: tv\n+        category:\n+            - tv/hd\n+            - tv/uhd\n+        maxage: 3 days\n \n-    Config example::\n+    # meta id based: uses the (imdb id) to search only in the movie/uhd category, for results that are up-to 1 week old\n+    newznab:\n+        api_server_url: https://api.nzbindexer.com\n+        api_key: my_apikey\n+        search_type: movie\n+        category: movie/uhd\n+        maxage: 1 week\n \n-        newznab:\n-          url: \"http://website/api?apikey=xxxxxxxxxxxxxxxxxxxxxxxxxx&t=movie&extended=1\"\n-          website: https://website\n-          apikey: xxxxxxxxxxxxxxxxxxxxxxxxxx\n-          category: movie\n+    # custom search string: builds the search string and searches in the tv/hd and a custom 5999 category\n+    newznab:\n+        api_server_url: https://api.nzbindexer.com\n+        api_key: my_apikey\n+        search_type:\n+            custom_query: \"{{trakt_series_name}} {{series_id}}\"\n+        category:\n+            - tv/hd\n+            - 5999\n \n-    Category is any of: movie, tvsearch, music, book\n+    # forces quotes around the search query, some ill behaving indexers wont correctly handle multiterm queries like: 'title s01e01'\n+    # If you notice you get results of titles that are not in the search query or wrong season/episodes, try this.\n+    # NOTE: will most likely break well behaving indexers, so use in a separate task/entry or use nzbhydra\n+    newznab:\n+        api_server_url: https://api.nzbindexer.com\n+        search_type: generic\n+        category: tv\n+        force_quotes: yes\n     \"\"\"\n \n     schema = {\n         'type': 'object',\n         'properties': {\n-            'category': {'type': 'string', 'enum': ['movie', 'tvsearch', 'tv', 'music', 'book']},\n-            'url': {'type': 'string', 'format': 'url'},\n-            'website': {'type': 'string', 'format': 'url'},\n-            'apikey': {'type': 'string'}\n+            'api_server_url': {'type': 'string', 'format': 'url'},\n+            'api_key': {'type': 'string'},\n+            'search_type': {\n+                'oneOf': [\n+                    {'type': 'string', 'enum': ['generic', 'tv', 'movie']},\n+                    {\n+                        'type': 'object',\n+                        'properties': {\n+                            'custom_query': {'type': 'string'},\n+                        },\n+                        'required': ['custom_query']\n+                    },\n+                ],\n+            },\n+            'category': one_or_more({\n+                'oneOf': [\n+                    {'type': 'integer'},\n+                    {'type': 'string', 'enum': list(CATEGORIES)},\n+                ]}, unique_items=True),\n+            'maxage': {'type': 'string', 'format': 'interval'},\n+            'force_quotes': {'type': 'boolean', 'default': False},\n         },\n-        'required': ['category'],\n+        'required': ['api_server_url', 'search_type'],\n         'additionalProperties': False\n     }\n \n-    def build_config(self, config):\n+    def update_metadata(self, task, entry, config):\n+        # lets guess the generic type\n+        do_show_lookup = False\n+        do_movie_lookup = False\n+        if not isinstance(config['search_type'], basestring) and config['search_type'].get('custom_query'):\n+            if entry.get('series_name') or entry.get('tvdb_id'):\n+                do_show_lookup = True\n+            else:\n+                do_movie_lookup = True\n+\n+        # update entry metadata based on task config\n+        if config['search_type'] == 'tv' or do_show_lookup:\n+            if task.config.get('trakt_lookup'):\n+                plugin.get_plugin_by_name('trakt_lookup').instance.lazy_series_lookup(entry)\n+                log.verbose('Doing trakt_lookup for < %s >' % entry.get('series_name', entry['title']))\n+            if task.config.get('tvmaze_lookup'):\n+                plugin.get_plugin_by_name('tvmaze_lookup').instance.lazy_series_lookup(entry)\n+                log.verbose('Doing tvmaze_lookup for < %s >' % entry.get('series_name', entry['title']))\n+            if task.config.get('thetvdb_lookup') or not entry.get('tvdb_id'):  # default fallback\n+                plugin.get_plugin_by_name('thetvdb_lookup').instance.lazy_series_lookup(entry, 'en')\n+                log.verbose('Doing thetvdb_lookup for < %s >' % entry.get('series_name', entry['title']))\n+        elif config['search_type'] == 'movie' or do_movie_lookup:\n+            if task.config.get('trakt_lookup'):\n+                plugin.get_plugin_by_name('trakt_lookup').instance.lazy_movie_lookup(entry)\n+                log.verbose('Doing trakt_lookup for < %s >' % entry.get('title'))\n+            if task.config.get('tmdb_lookup'):\n+                plugin.get_plugin_by_name('tmdb_lookup').instance.lookup(entry)\n+                log.verbose('Doing tmdb_lookup for < %s >' % entry.get('title'))\n+            if task.config.get('imdb_lookup') or not entry.get('imdb_id'):  # default fallback\n+                plugin.get_plugin_by_name('imdb_lookup').instance.lookup(entry)\n+                log.verbose('Doing imdb_lookup for < %s >' % entry.get('title'))\n+\n+    def get_metaid_url_parameter(self, task, entry, config):\n+        # only use for tv/movie search type\n+        if config['search_type'] != 'tv' and config['search_type'] != 'movie':\n+            return ''\n+\n+        self.update_metadata(task, entry, config)\n+\n+        url_param = ''\n+        # use first valid meta id\n+        if config['search_type'] == 'tv':\n+            if entry.get('tvdb_id'):\n+                url_param = '&tvdbid=%s' % entry.get('tvdb_id')\n+            elif entry.get('tvrage_id'):\n+                url_param = '&rid=%s' % entry.get('tvrage_id')\n+            # lets not use those for now, rarely supported!\n+            # elif entry.get('tvmaze_series_id'):\n+            #    url_param = '&tvmazeid=%s' % entry.get('tvmaze_series_id')\n+            # elif entry.get('trakt_id'):\n+            #    url_param = '&traktid=%s' % entry.get('trakt_id')\n+            if not url_param:\n+                log.error('Could not get valid meta id for series < %s >' % (entry.get('series_name', entry['title'])))\n+        elif config['search_type'] == 'movie':\n+            if entry.get('imdb_id'):\n+                url_param = '&imdbid=%s' % str(entry['imdb_id']).replace('tt', '')\n+                # tmdb is not supported for move lookups by indexers!\n+            if not url_param:\n+                log.error('Could not get imdb_id for movie < %s >' % (entry.get('movie_name', entry['title'])))\n+\n+        return url_param\n+\n+    def build_base_url(self, config):\n         log.debug(type(config))\n \n-        if config['category'] == 'tv':\n-            config['category'] = 'tvsearch'\n+        api_url = config['api_server_url'] + '/api?' + '&extended=1'\n+\n+        if config.get('api_key'):\n+            api_url += '&apikey=%s' % config['api_key']\n \n-        if 'url' not in config:\n-            if 'apikey' in config and 'website' in config:\n-                params = {\n-                    't': config['category'],\n-                    'apikey': config['apikey'],\n-                    'extended': 1\n-                }\n-                config['url'] = config['website'] + '/api?' + urlencode(params)\n+        if config['search_type'] == 'tv':\n+            api_url += '&t=tvsearch'\n+        elif config['search_type'] == 'movie':\n+            api_url += '&t=movie'\n+        else:\n+            api_url += '&t=search'\n \n-        return config\n+        if 'category' in config:\n+            categories = config.get('category')\n+            if not isinstance(categories, list):\n+                categories = [categories]\n+            # Convert named categories to its respective categories id number\n+            categories = [c if isinstance(c, int) else CATEGORIES[c] for c in categories]\n+            if len(categories) > 0:\n+                categories_string = ','.join(str(c) for c in categories)\n+                api_url += '&cat=%s' % categories_string\n \n-    def fill_entries_for_url(self, url, task):\n-        entries = []\n-        log.verbose('Fetching %s' % url)\n+        if config.get('maxage'):\n+            api_url += '&maxage=%s' % parse_timedelta(config['maxage']).days\n+\n+        return api_url\n+\n+    def convert_to_naive_utc(self, value):\n+        parsed_date = None\n+        try:\n+            parsed_date = dateutil_parse(value, fuzzy=True)\n+            try:\n+                parsed_date = parsed_date.astimezone(tz.tzutc()).replace(tzinfo=None)\n+            except ValueError:\n+                parsed_date = parsed_date.replace(tzinfo=None)\n+        except ValueError:\n+            log.warning('Invalid time format < %s > in Entry < %s >' % value)\n+        except Exception as ex:\n+            log.trace('Unexpected time field < %s > error: <%s>' % (value, ex))\n+\n+        return parsed_date\n \n+    def convert_to_number(self, valuestring):\n+        number = None\n         try:\n-            r = task.requests.get(url)\n-        except task.requests.RequestException as e:\n-            log.error(\"Failed fetching '%s': %s\" % (url, e))\n+            number = int(valuestring)\n+        except ValueError:\n+            try:\n+                number = float(valuestring)\n+            except ValueError:\n+                log.trace('Invalid number field < %s >' % valuestring)\n+        except Exception as ex:\n+            log.trace('Invalid number field < %s > error: <%s>' % (valuestring, ex))\n \n-        rss = feedparser.parse(r.content)\n-        log.debug(\"Raw RSS: %s\" % rss)\n+        return number\n \n-        if not len(rss.entries):\n-            log.info('No results returned')\n+    def string_to_bool(self, value):\n+        return value.lower() in ('yes', 'true', 't', '1', 'y')\n \n-        for rss_entry in rss.entries:\n+    def dump_entry(self, entry):\n+        log.verbose('#####################################################################################')","path":"flexget/plugins/sites/newznab.py","position":362,"original_position":362,"commit_id":"11cba71a5fe74e55a8f7cf09fdfa3632a823c368","original_commit_id":"11cba71a5fe74e55a8f7cf09fdfa3632a823c368","user":{"login":"Andy2244","id":5340247,"avatar_url":"https://avatars.githubusercontent.com/u/5340247?v=3","gravatar_id":"","url":"https://api.github.com/users/Andy2244","html_url":"https://github.com/Andy2244","followers_url":"https://api.github.com/users/Andy2244/followers","following_url":"https://api.github.com/users/Andy2244/following{/other_user}","gists_url":"https://api.github.com/users/Andy2244/gists{/gist_id}","starred_url":"https://api.github.com/users/Andy2244/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Andy2244/subscriptions","organizations_url":"https://api.github.com/users/Andy2244/orgs","repos_url":"https://api.github.com/users/Andy2244/repos","events_url":"https://api.github.com/users/Andy2244/events{/privacy}","received_events_url":"https://api.github.com/users/Andy2244/received_events","type":"User","site_admin":false},"body":"Yes only for myself, so i can easily spot the start/end of entrys and check if they have all the new fields with good values.","created_at":"2016-12-03T09:07:17Z","updated_at":"2016-12-03T09:07:17Z","html_url":"https://github.com/Flexget/Flexget/pull/1530#discussion_r90753820","pull_request_url":"https://api.github.com/repos/Flexget/Flexget/pulls/1530","_links":{"self":{"href":"https://api.github.com/repos/Flexget/Flexget/pulls/comments/90753820"},"html":{"href":"https://github.com/Flexget/Flexget/pull/1530#discussion_r90753820"},"pull_request":{"href":"https://api.github.com/repos/Flexget/Flexget/pulls/1530"}}},"pull_request":{"url":"https://api.github.com/repos/Flexget/Flexget/pulls/1530","id":96354767,"html_url":"https://github.com/Flexget/Flexget/pull/1530","diff_url":"https://github.com/Flexget/Flexget/pull/1530.diff","patch_url":"https://github.com/Flexget/Flexget/pull/1530.patch","issue_url":"https://api.github.com/repos/Flexget/Flexget/issues/1530","number":1530,"state":"open","locked":false,"title":"rewrite of newznab plugin:","user":{"login":"Andy2244","id":5340247,"avatar_url":"https://avatars.githubusercontent.com/u/5340247?v=3","gravatar_id":"","url":"https://api.github.com/users/Andy2244","html_url":"https://github.com/Andy2244","followers_url":"https://api.github.com/users/Andy2244/followers","following_url":"https://api.github.com/users/Andy2244/following{/other_user}","gists_url":"https://api.github.com/users/Andy2244/gists{/gist_id}","starred_url":"https://api.github.com/users/Andy2244/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Andy2244/subscriptions","organizations_url":"https://api.github.com/users/Andy2244/orgs","repos_url":"https://api.github.com/users/Andy2244/repos","events_url":"https://api.github.com/users/Andy2244/events{/privacy}","received_events_url":"https://api.github.com/users/Andy2244/received_events","type":"User","site_admin":false},"body":"### Motivation for changes:\r\nBetter metadata lookup support and adding all of the usefully features the newznap api offers. Parsing/storing of advanced attributes that can be directly used by the Age/If and Sort_by plugins.\r\n\r\n### Detailed changes:\r\nAdded:\r\n- official and unofficial newznab categories via `category`\r\n- `search_type` generic/custom_query\r\n- ability to build custom search query strings from existing fields via` custom_query`\r\n- `maxage` and `force_quotes`\r\n- automatic metadata lookup, based on task config\r\n- tvdb support\r\n\r\nChanged:\r\n- config `search_type` `all` renamed to `generic`\r\n- `website `renamed to `api_server_url`\r\n- `apikey `renamed to `api_key`\r\n\r\nEntry changes:\r\n- added the following 'newznab' namespace fields if found:\r\n    `newznab_age`                     - age in days of this release\r\n    `newznab_pubdate`               - date the indexer added the nzb to its database (aka age)\r\n    `newznab_guid`                     - unique guid of this release\r\n    `newznab_grabs`                   - number of grabs\r\n    `newznab_size`                      - size in bytes of the release\r\n    `newznab_files`                      - number of files this release (archive) has\r\n    `newznab_usenetdate`          - date the release was posted on usenet\r\n    `newznab_password`             - if the release uses a password\r\n\r\n\r\n### Config usage if relevant (new plugin or updated schema):\r\n```\r\n    Config example:\r\n    # simple: uses the 'title' to search in the 'tv' category\r\n    newznab:\r\n        api_server_url: https://api.nzbindexer.com\r\n        api_key: my_apikey\r\n        search_type: generic\r\n        category: tv\r\n\r\n    # meta id based: uses the (tvdb/ragetv id) to search only in the tv/hd,uhd categories, for results that are up-to 3 days old\r\n    newznab:\r\n        api_server_url: https://api.nzbindexer.com\r\n        api_key: my_apikey\r\n        search_type: tv\r\n        category:\r\n            - tv/hd\r\n            - tv/uhd\r\n        maxage: 3 days\r\n\r\n    # meta id based: uses the (imdb id) to search only in the movie/uhd category, for results that are up-to 1 week old\r\n    newznab:\r\n        api_server_url: https://api.nzbindexer.com\r\n        api_key: my_apikey\r\n        search_type: movie\r\n        category: movie/uhd\r\n        maxage: 1 week\r\n\r\n    # custom search string: builds the search string and searches in the tv/hd and a custom 5999 category\r\n    newznab:\r\n        api_server_url: https://api.nzbindexer.com\r\n        api_key: my_apikey\r\n        search_type:\r\n            custom_query: \"{{trakt_series_name}} {{series_id}}\"\r\n        category:\r\n            - tv/hd\r\n            - 5999\r\n\r\n    # forces quotes around the search query, some ill behaving indexers wont correctly handle multiterm queries like: 'title s01e01'\r\n    # If you notice you get results of titles that are not in the search query or wrong season/episodes, try this.\r\n    # NOTE: will most likely break well behaving indexers, so use in a separate task/entry or use nzbhydra\r\n    newznab:\r\n        api_server_url: https://api.nzbindexer.com\r\n        search_type: generic\r\n        category: tv\r\n        force_quotes: yes\r\n```\r\nExamples for the new attribute fields:\r\n```\r\n# only get latest (if maxage is not supported by indexer)\r\n    age:\r\n      field: newznab_pubdate\r\n      action: reject\r\n      age: 3 weeks\r\n# sort by grabs\r\n    sort_by: \r\n        #field: newznab_age\r\n        field: newznab_grabs\r\n        reverse: yes\r\n# sanity check of tv shows\r\n    if:\r\n        - newznab_usenetdate < trakt_ep_first_aired: reject\r\n```","created_at":"2016-12-02T21:21:12Z","updated_at":"2016-12-03T09:07:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c5ae0f54ca8c17a38f7b53d9b06410e3550f7b1c","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Flexget/Flexget/pulls/1530/commits","review_comments_url":"https://api.github.com/repos/Flexget/Flexget/pulls/1530/comments","review_comment_url":"https://api.github.com/repos/Flexget/Flexget/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Flexget/Flexget/issues/1530/comments","statuses_url":"https://api.github.com/repos/Flexget/Flexget/statuses/11cba71a5fe74e55a8f7cf09fdfa3632a823c368","head":{"label":"Andy2244:develop","ref":"develop","sha":"11cba71a5fe74e55a8f7cf09fdfa3632a823c368","user":{"login":"Andy2244","id":5340247,"avatar_url":"https://avatars.githubusercontent.com/u/5340247?v=3","gravatar_id":"","url":"https://api.github.com/users/Andy2244","html_url":"https://github.com/Andy2244","followers_url":"https://api.github.com/users/Andy2244/followers","following_url":"https://api.github.com/users/Andy2244/following{/other_user}","gists_url":"https://api.github.com/users/Andy2244/gists{/gist_id}","starred_url":"https://api.github.com/users/Andy2244/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Andy2244/subscriptions","organizations_url":"https://api.github.com/users/Andy2244/orgs","repos_url":"https://api.github.com/users/Andy2244/repos","events_url":"https://api.github.com/users/Andy2244/events{/privacy}","received_events_url":"https://api.github.com/users/Andy2244/received_events","type":"User","site_admin":false},"repo":{"id":75426381,"name":"Flexget","full_name":"Andy2244/Flexget","owner":{"login":"Andy2244","id":5340247,"avatar_url":"https://avatars.githubusercontent.com/u/5340247?v=3","gravatar_id":"","url":"https://api.github.com/users/Andy2244","html_url":"https://github.com/Andy2244","followers_url":"https://api.github.com/users/Andy2244/followers","following_url":"https://api.github.com/users/Andy2244/following{/other_user}","gists_url":"https://api.github.com/users/Andy2244/gists{/gist_id}","starred_url":"https://api.github.com/users/Andy2244/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Andy2244/subscriptions","organizations_url":"https://api.github.com/users/Andy2244/orgs","repos_url":"https://api.github.com/users/Andy2244/repos","events_url":"https://api.github.com/users/Andy2244/events{/privacy}","received_events_url":"https://api.github.com/users/Andy2244/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Andy2244/Flexget","description":"The official FlexGet repository","fork":true,"url":"https://api.github.com/repos/Andy2244/Flexget","forks_url":"https://api.github.com/repos/Andy2244/Flexget/forks","keys_url":"https://api.github.com/repos/Andy2244/Flexget/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Andy2244/Flexget/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Andy2244/Flexget/teams","hooks_url":"https://api.github.com/repos/Andy2244/Flexget/hooks","issue_events_url":"https://api.github.com/repos/Andy2244/Flexget/issues/events{/number}","events_url":"https://api.github.com/repos/Andy2244/Flexget/events","assignees_url":"https://api.github.com/repos/Andy2244/Flexget/assignees{/user}","branches_url":"https://api.github.com/repos/Andy2244/Flexget/branches{/branch}","tags_url":"https://api.github.com/repos/Andy2244/Flexget/tags","blobs_url":"https://api.github.com/repos/Andy2244/Flexget/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Andy2244/Flexget/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Andy2244/Flexget/git/refs{/sha}","trees_url":"https://api.github.com/repos/Andy2244/Flexget/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Andy2244/Flexget/statuses/{sha}","languages_url":"https://api.github.com/repos/Andy2244/Flexget/languages","stargazers_url":"https://api.github.com/repos/Andy2244/Flexget/stargazers","contributors_url":"https://api.github.com/repos/Andy2244/Flexget/contributors","subscribers_url":"https://api.github.com/repos/Andy2244/Flexget/subscribers","subscription_url":"https://api.github.com/repos/Andy2244/Flexget/subscription","commits_url":"https://api.github.com/repos/Andy2244/Flexget/commits{/sha}","git_commits_url":"https://api.github.com/repos/Andy2244/Flexget/git/commits{/sha}","comments_url":"https://api.github.com/repos/Andy2244/Flexget/comments{/number}","issue_comment_url":"https://api.github.com/repos/Andy2244/Flexget/issues/comments{/number}","contents_url":"https://api.github.com/repos/Andy2244/Flexget/contents/{+path}","compare_url":"https://api.github.com/repos/Andy2244/Flexget/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Andy2244/Flexget/merges","archive_url":"https://api.github.com/repos/Andy2244/Flexget/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Andy2244/Flexget/downloads","issues_url":"https://api.github.com/repos/Andy2244/Flexget/issues{/number}","pulls_url":"https://api.github.com/repos/Andy2244/Flexget/pulls{/number}","milestones_url":"https://api.github.com/repos/Andy2244/Flexget/milestones{/number}","notifications_url":"https://api.github.com/repos/Andy2244/Flexget/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Andy2244/Flexget/labels{/name}","releases_url":"https://api.github.com/repos/Andy2244/Flexget/releases{/id}","deployments_url":"https://api.github.com/repos/Andy2244/Flexget/deployments","created_at":"2016-12-02T19:56:11Z","updated_at":"2016-12-02T19:56:23Z","pushed_at":"2016-12-02T20:56:49Z","git_url":"git://github.com/Andy2244/Flexget.git","ssh_url":"git@github.com:Andy2244/Flexget.git","clone_url":"https://github.com/Andy2244/Flexget.git","svn_url":"https://github.com/Andy2244/Flexget","homepage":"http://www.flexget.com","size":48143,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"Flexget:develop","ref":"develop","sha":"5352b5a1c2929a873e335c6478a6b54f353996c0","user":{"login":"Flexget","id":682553,"avatar_url":"https://avatars.githubusercontent.com/u/682553?v=3","gravatar_id":"","url":"https://api.github.com/users/Flexget","html_url":"https://github.com/Flexget","followers_url":"https://api.github.com/users/Flexget/followers","following_url":"https://api.github.com/users/Flexget/following{/other_user}","gists_url":"https://api.github.com/users/Flexget/gists{/gist_id}","starred_url":"https://api.github.com/users/Flexget/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Flexget/subscriptions","organizations_url":"https://api.github.com/users/Flexget/orgs","repos_url":"https://api.github.com/users/Flexget/repos","events_url":"https://api.github.com/users/Flexget/events{/privacy}","received_events_url":"https://api.github.com/users/Flexget/received_events","type":"Organization","site_admin":false},"repo":{"id":1512901,"name":"Flexget","full_name":"Flexget/Flexget","owner":{"login":"Flexget","id":682553,"avatar_url":"https://avatars.githubusercontent.com/u/682553?v=3","gravatar_id":"","url":"https://api.github.com/users/Flexget","html_url":"https://github.com/Flexget","followers_url":"https://api.github.com/users/Flexget/followers","following_url":"https://api.github.com/users/Flexget/following{/other_user}","gists_url":"https://api.github.com/users/Flexget/gists{/gist_id}","starred_url":"https://api.github.com/users/Flexget/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Flexget/subscriptions","organizations_url":"https://api.github.com/users/Flexget/orgs","repos_url":"https://api.github.com/users/Flexget/repos","events_url":"https://api.github.com/users/Flexget/events{/privacy}","received_events_url":"https://api.github.com/users/Flexget/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Flexget/Flexget","description":"The official FlexGet repository","fork":false,"url":"https://api.github.com/repos/Flexget/Flexget","forks_url":"https://api.github.com/repos/Flexget/Flexget/forks","keys_url":"https://api.github.com/repos/Flexget/Flexget/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Flexget/Flexget/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Flexget/Flexget/teams","hooks_url":"https://api.github.com/repos/Flexget/Flexget/hooks","issue_events_url":"https://api.github.com/repos/Flexget/Flexget/issues/events{/number}","events_url":"https://api.github.com/repos/Flexget/Flexget/events","assignees_url":"https://api.github.com/repos/Flexget/Flexget/assignees{/user}","branches_url":"https://api.github.com/repos/Flexget/Flexget/branches{/branch}","tags_url":"https://api.github.com/repos/Flexget/Flexget/tags","blobs_url":"https://api.github.com/repos/Flexget/Flexget/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Flexget/Flexget/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Flexget/Flexget/git/refs{/sha}","trees_url":"https://api.github.com/repos/Flexget/Flexget/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Flexget/Flexget/statuses/{sha}","languages_url":"https://api.github.com/repos/Flexget/Flexget/languages","stargazers_url":"https://api.github.com/repos/Flexget/Flexget/stargazers","contributors_url":"https://api.github.com/repos/Flexget/Flexget/contributors","subscribers_url":"https://api.github.com/repos/Flexget/Flexget/subscribers","subscription_url":"https://api.github.com/repos/Flexget/Flexget/subscription","commits_url":"https://api.github.com/repos/Flexget/Flexget/commits{/sha}","git_commits_url":"https://api.github.com/repos/Flexget/Flexget/git/commits{/sha}","comments_url":"https://api.github.com/repos/Flexget/Flexget/comments{/number}","issue_comment_url":"https://api.github.com/repos/Flexget/Flexget/issues/comments{/number}","contents_url":"https://api.github.com/repos/Flexget/Flexget/contents/{+path}","compare_url":"https://api.github.com/repos/Flexget/Flexget/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Flexget/Flexget/merges","archive_url":"https://api.github.com/repos/Flexget/Flexget/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Flexget/Flexget/downloads","issues_url":"https://api.github.com/repos/Flexget/Flexget/issues{/number}","pulls_url":"https://api.github.com/repos/Flexget/Flexget/pulls{/number}","milestones_url":"https://api.github.com/repos/Flexget/Flexget/milestones{/number}","notifications_url":"https://api.github.com/repos/Flexget/Flexget/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Flexget/Flexget/labels{/name}","releases_url":"https://api.github.com/repos/Flexget/Flexget/releases{/id}","deployments_url":"https://api.github.com/repos/Flexget/Flexget/deployments","created_at":"2011-03-22T19:33:44Z","updated_at":"2016-11-27T02:36:22Z","pushed_at":"2016-12-02T21:21:12Z","git_url":"git://github.com/Flexget/Flexget.git","ssh_url":"git@github.com:Flexget/Flexget.git","clone_url":"https://github.com/Flexget/Flexget.git","svn_url":"https://github.com/Flexget/Flexget","homepage":"http://www.flexget.com","size":56046,"stargazers_count":585,"watchers_count":585,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":327,"mirror_url":null,"open_issues_count":86,"forks":327,"open_issues":86,"watchers":585,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/Flexget/Flexget/pulls/1530"},"html":{"href":"https://github.com/Flexget/Flexget/pull/1530"},"issue":{"href":"https://api.github.com/repos/Flexget/Flexget/issues/1530"},"comments":{"href":"https://api.github.com/repos/Flexget/Flexget/issues/1530/comments"},"review_comments":{"href":"https://api.github.com/repos/Flexget/Flexget/pulls/1530/comments"},"review_comment":{"href":"https://api.github.com/repos/Flexget/Flexget/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Flexget/Flexget/pulls/1530/commits"},"statuses":{"href":"https://api.github.com/repos/Flexget/Flexget/statuses/11cba71a5fe74e55a8f7cf09fdfa3632a823c368"}}}}
{"actor":{"display_login":"Andy2244"}}