{"action":"created","comment":{"url":"https://api.github.com/repos/owtf/owtf/pulls/comments/56272653","id":56272653,"diff_hunk":"@@ -11,174 +11,198 @@\n import ConfigParser\n \n \n-class Installer(object):\n-    \"\"\"\n-    This class takes care of installation of various restricted stuff across various linux distros\n+def create_directory(directory):\n+    \"\"\"Create parent directories as necessary.\n+\n+    :param directory: (~str) Path of directory to be made.\n+\n+    :return: True - if directory is created, and False - if not.\n     \"\"\"\n-    def __init__(self, RootDir):\n-        self.RootDir = RootDir\n-        self.pid = os.getpid()\n-        self.scripts_path = os.path.join(RootDir, \"scripts\") # custom scripts\n-        self.owtf_pip = os.path.join(RootDir, \"install\", \"owtf.pip\") # OWTF python libraries\n-        self.restricted_cfg = os.path.join(RootDir, \"install\", \"distro-independent.cfg\") # Restricted tools and dictionaries which are distro independent\n-        self.distros_cfg = os.path.join(RootDir, \"install\", \"linux-distributions.cfg\") # Various distros and install scripts\n-        self.parser = argparse.ArgumentParser()\n-        self.parser.add_argument('--no-user-input', help='run script with default options for user input', action=\"store_true\")\n-        self.parser.add_argument('--core-only', help='install only owtf dependencies, skip optional tools', action=\"store_true\")\n-\n-    def create_directory(self, directory):\n-        # Create parent directories as necessary\n-        try:\n-            os.makedirs(directory)\n+    try:\n+        os.makedirs(directory)\n+        return True\n+    except OSError:\n+        # Checks if the folder is empty\n+        if not os.listdir(directory):\n             return True\n-        except OSError:\n-            # Checks if the folder is empty\n-            if not os.listdir(directory):\n-                return True\n-            return False\n-\n-    def run_command(self, command):\n-        Colorizer.normal(\"[*] Running following command\")\n-        Colorizer.info(\"%s\" % command)\n-        if not wget_wrapper(command):\n-            return\n-        os.system(command)\n-\n-    @staticmethod\n-    def version(root_dir):\n-        \"\"\"Prints the local git repo's last commit hash\"\"\"\n-        # check if the root dir is a git repository\n-        if os.path.exists(os.path.join(root_dir, '.git')):\n-            command = 'git log -n 1 --pretty=format:\"%H\"'\n-            commit_hash = os.popen(command).read()\n-            return commit_hash\n-        else:\n-            return \"*Not a git repository.*\"\n-\n-    @staticmethod\n-    def check_sudo():\n-        \"\"\"Checks if the user has sudo access\"\"\"\n-        sudo = os.system(\"sudo -v\")\n-        if sudo == 0:\n-            return\n-        else:\n-            Colorizer.warning(\"[!] Your user does not have sudo privileges. Some OWTF components require sudo permissions to install\")\n-            # exit cleanly\n-            sys.exit()\n-\n-    def install_in_directory(self, directory, command):\n-        if self.create_directory(directory):\n-            Colorizer.info(\"[*] Switching to %s\" % directory)\n-            os.chdir(directory)\n-            self.run_command(command)\n-        else:\n-            Colorizer.warning(\"[!] Directory %s already exists, so skipping installation for this\" % directory)\n-\n-    def install_using_pip(self, requirements_file):\n-        # Instead of using file directly with pip which can crash because of single library\n-        self.run_command(\"sudo -E pip2 install --upgrade -r %s\" % requirements_file)\n-\n-    def install_restricted_from_cfg(self, config_file):\n-        cp = ConfigParser.ConfigParser({\"RootDir\":self.RootDir, \"Pid\":self.pid})\n-        cp.read(config_file)\n-        for section in cp.sections():\n-            Colorizer.info(\"[*] Installing %s\" % section)\n-            self.install_in_directory(os.path.expanduser(cp.get(section, \"directory\")), cp.get(section, \"command\"))\n-\n-    def install(self, cmd_arguments):\n-\n-        args = self.parser.parse_args(cmd_arguments)\n-\n-        # User asked to select distro (in case it cannot be automatically detected) and distro related stuff is installed\n-        cp = ConfigParser.ConfigParser({\"RootDir\":self.RootDir, \"Pid\":self.pid})\n-        cp.read(self.distros_cfg)\n-\n-        #Try get the distro automatically\n-        distro, version, arch = platform.linux_distribution()\n-        distro_num = 0\n-        if \"kali\" in distro.lower():\n-            distro_num = 1\n-        elif \"samurai\" in distro.lower():\n-            distro_num = 2\n-        elif \"debian\" in distro.lower():\n-            distro_num = 3\n-\n-        # Loop until proper input is received\n-        while True:\n-            if distro_num != 0:\n-                Colorizer.info(\"[*] %s has been automatically detected... \" % distro)\n-                Colorizer.normal(\"Continuing in auto-mode\")\n-                break\n+        return False\n \n-            if args.no_user_input:\n-                distro_num = 0\n-                break\n-\n-            print(\"\")\n-            for i, item in enumerate(cp.sections()):\n-                Colorizer.warning(\"(%d) %s\" % (i + 1, item))\n-            Colorizer.warning(\"(0) My distro is not listed :( %s\" % distro)\n-\n-            distro_num = raw_input(\"Select a number based on your distribution : \")\n-            try: # Cheking if valid input is received\n-                distro_num = int(distro_num)\n-                break\n-            except ValueError:\n-                print('')\n-                Colorizer.warning(\"Invalid Number specified\")\n-                continue\n-\n-        # First all distro independent stuff is installed\n-        self.install_restricted_from_cfg(self.restricted_cfg)\n \n+def run_command(command):\n+    \"\"\"Execute the provided shell command.\n+\n+    :param command: (~str) Linux shell command.\n+\n+    :return: True - if command executed, and False if not.\n+    \"\"\"\n+    Colorizer.normal(\"[*] Running following command\")\n+    Colorizer.info(\"%s\" % command)\n+    # If command is `wget`, then before execution, `wget_wrapper` checks whether there is enough disk space available\n+    if not wget_wrapper(command):\n+        return False\n+    return os.system(command)\n+\n+\n+def zest_version():\n+    \"\"\"Prints the local git repo's last commit hash.\"\"\"\n+    # Check if the root dir is a git repository\n+    if os.path.exists(os.path.join(root_dir, '.git')):\n+        command = 'git log -n 1 --pretty=format:\"%H\"'\n+        commit_hash = os.popen(command).read()\n+        return commit_hash\n+    else:\n+        return \"*Not a git repository.*\"\n+\n+\n+def check_sudo():\n+    \"\"\"Checks if the user has sudo access.\"\"\"\n+    sudo = os.system(\"sudo -v\")\n+    if not sudo:\n+        return\n+    else:\n+        Colorizer.warning(\"[!] Your user does not have sudo privileges. Some OWTF components require sudo permissions to install\")\n+        sys.exit()\n+\n+\n+def install_in_directory(directory, command):\n+    \"\"\"Execute a certain command while staying inside one directory.\n+\n+    :param directory: (~str) Path of directory in which installation command has to be executed.\n+    :param command: (~str) Linux shell command (most likely `wget` here)\n+\n+    :return: True - if installation successful or directory already exists, and False if not.\n+    \"\"\"\n+    if create_directory(directory):\n+        Colorizer.info(\"[*] Switching to %s\" % directory)\n+        os.chdir(directory)\n+        return run_command(command)\n+    else:\n+        Colorizer.warning(\"[!] Directory %s already exists, so skipping installation for this\" % directory)\n+        return True\n+\n+\n+def install_using_pip(requirements_file):\n+    \"\"\"Install pip libraries as mentioned in a requirements file.\n+\n+    :param requirements_file: (~str) Path to requirements file - in which libraries are listed.\n+\n+    :return: True - if installation successful, and False if not.\n+    \"\"\"\n+    # Instead of using file directly with pip which can crash because of single library\n+    return run_command(\"sudo -E pip2 install --upgrade -r %s\" % requirements_file)\n+\n+\n+def install_restricted_from_cfg(config_file):\n+    \"\"\"Install restricted tools and dependencies which are distro independent.\n+\n+    :param config_file: (~str) Path to configuration file having information about restricted content.\n+    \"\"\"\n+    cp = ConfigParser.ConfigParser({\"RootDir\": root_dir, \"Pid\": pid})\n+    cp.read(config_file)\n+    for section in cp.sections():\n+        Colorizer.info(\"[*] Installing %s\" % section)\n+        install_in_directory(os.path.expanduser(cp.get(section, \"directory\")), cp.get(section, \"command\"))\n+\n+\n+def install(cmd_arguments):\n+    \"\"\"Perform installation of OWTF Framework. Wraps around all helper methods made in this module.\n+\n+    :param cmd_arguments:\n+    \"\"\"\n+","path":"install/install.py","position":218,"original_position":218,"commit_id":"4305d4f810e1f46ea2a7bc7644169bd9fb4be459","original_commit_id":"4305d4f810e1f46ea2a7bc7644169bd9fb4be459","user":{"login":"karandesai-96","id":10494087,"avatar_url":"https://avatars.githubusercontent.com/u/10494087?v=3","gravatar_id":"","url":"https://api.github.com/users/karandesai-96","html_url":"https://github.com/karandesai-96","followers_url":"https://api.github.com/users/karandesai-96/followers","following_url":"https://api.github.com/users/karandesai-96/following{/other_user}","gists_url":"https://api.github.com/users/karandesai-96/gists{/gist_id}","starred_url":"https://api.github.com/users/karandesai-96/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karandesai-96/subscriptions","organizations_url":"https://api.github.com/users/karandesai-96/orgs","repos_url":"https://api.github.com/users/karandesai-96/repos","events_url":"https://api.github.com/users/karandesai-96/events{/privacy}","received_events_url":"https://api.github.com/users/karandesai-96/received_events","type":"User","site_admin":false},"body":"- [x] Done.\r\n","created_at":"2016-03-16T02:06:20Z","updated_at":"2016-03-16T02:06:20Z","html_url":"https://github.com/owtf/owtf/pull/588#discussion_r56272653","pull_request_url":"https://api.github.com/repos/owtf/owtf/pulls/588","_links":{"self":{"href":"https://api.github.com/repos/owtf/owtf/pulls/comments/56272653"},"html":{"href":"https://github.com/owtf/owtf/pull/588#discussion_r56272653"},"pull_request":{"href":"https://api.github.com/repos/owtf/owtf/pulls/588"}}},"pull_request":{"url":"https://api.github.com/repos/owtf/owtf/pulls/588","id":62179819,"html_url":"https://github.com/owtf/owtf/pull/588","diff_url":"https://github.com/owtf/owtf/pull/588.diff","patch_url":"https://github.com/owtf/owtf/pull/588.patch","issue_url":"https://api.github.com/repos/owtf/owtf/issues/588","number":588,"state":"open","locked":false,"title":"Cleanup install script to reduce memory overhead.","user":{"login":"karandesai-96","id":10494087,"avatar_url":"https://avatars.githubusercontent.com/u/10494087?v=3","gravatar_id":"","url":"https://api.github.com/users/karandesai-96","html_url":"https://github.com/karandesai-96","followers_url":"https://api.github.com/users/karandesai-96/followers","following_url":"https://api.github.com/users/karandesai-96/following{/other_user}","gists_url":"https://api.github.com/users/karandesai-96/gists{/gist_id}","starred_url":"https://api.github.com/users/karandesai-96/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karandesai-96/subscriptions","organizations_url":"https://api.github.com/users/karandesai-96/orgs","repos_url":"https://api.github.com/users/karandesai-96/repos","events_url":"https://api.github.com/users/karandesai-96/events{/privacy}","received_events_url":"https://api.github.com/users/karandesai-96/received_events","type":"User","site_admin":false},"body":"- Installer class had only one instance, and no other usages.\r\n- So to avoid wastage of memory by even making that instance, all the methods were converted to `classmethods` and now called directly in main. This improves performance.\r\n- Apart from that there were minor PEP8 fixes for an overall cleanup of the script. Tested well, works fine.","created_at":"2016-03-09T04:54:27Z","updated_at":"2016-03-16T02:06:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4fab89db1ab9563e288019c45f9a10acc82c93d5","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/owtf/owtf/pulls/588/commits","review_comments_url":"https://api.github.com/repos/owtf/owtf/pulls/588/comments","review_comment_url":"https://api.github.com/repos/owtf/owtf/pulls/comments{/number}","comments_url":"https://api.github.com/repos/owtf/owtf/issues/588/comments","statuses_url":"https://api.github.com/repos/owtf/owtf/statuses/4305d4f810e1f46ea2a7bc7644169bd9fb4be459","head":{"label":"karandesai-96:install-cleanup","ref":"install-cleanup","sha":"4305d4f810e1f46ea2a7bc7644169bd9fb4be459","user":{"login":"karandesai-96","id":10494087,"avatar_url":"https://avatars.githubusercontent.com/u/10494087?v=3","gravatar_id":"","url":"https://api.github.com/users/karandesai-96","html_url":"https://github.com/karandesai-96","followers_url":"https://api.github.com/users/karandesai-96/followers","following_url":"https://api.github.com/users/karandesai-96/following{/other_user}","gists_url":"https://api.github.com/users/karandesai-96/gists{/gist_id}","starred_url":"https://api.github.com/users/karandesai-96/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karandesai-96/subscriptions","organizations_url":"https://api.github.com/users/karandesai-96/orgs","repos_url":"https://api.github.com/users/karandesai-96/repos","events_url":"https://api.github.com/users/karandesai-96/events{/privacy}","received_events_url":"https://api.github.com/users/karandesai-96/received_events","type":"User","site_admin":false},"repo":{"id":52928380,"name":"owtf","full_name":"karandesai-96/owtf","owner":{"login":"karandesai-96","id":10494087,"avatar_url":"https://avatars.githubusercontent.com/u/10494087?v=3","gravatar_id":"","url":"https://api.github.com/users/karandesai-96","html_url":"https://github.com/karandesai-96","followers_url":"https://api.github.com/users/karandesai-96/followers","following_url":"https://api.github.com/users/karandesai-96/following{/other_user}","gists_url":"https://api.github.com/users/karandesai-96/gists{/gist_id}","starred_url":"https://api.github.com/users/karandesai-96/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/karandesai-96/subscriptions","organizations_url":"https://api.github.com/users/karandesai-96/orgs","repos_url":"https://api.github.com/users/karandesai-96/repos","events_url":"https://api.github.com/users/karandesai-96/events{/privacy}","received_events_url":"https://api.github.com/users/karandesai-96/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/karandesai-96/owtf","description":"OWASP OWTF, the Offensive (Web) Testing Framework, is an OWASP+PTES-focused try to unite great tools and make pen testing more efficient, written mostly in Python @owtfp http://owtf.org","fork":true,"url":"https://api.github.com/repos/karandesai-96/owtf","forks_url":"https://api.github.com/repos/karandesai-96/owtf/forks","keys_url":"https://api.github.com/repos/karandesai-96/owtf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/karandesai-96/owtf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/karandesai-96/owtf/teams","hooks_url":"https://api.github.com/repos/karandesai-96/owtf/hooks","issue_events_url":"https://api.github.com/repos/karandesai-96/owtf/issues/events{/number}","events_url":"https://api.github.com/repos/karandesai-96/owtf/events","assignees_url":"https://api.github.com/repos/karandesai-96/owtf/assignees{/user}","branches_url":"https://api.github.com/repos/karandesai-96/owtf/branches{/branch}","tags_url":"https://api.github.com/repos/karandesai-96/owtf/tags","blobs_url":"https://api.github.com/repos/karandesai-96/owtf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/karandesai-96/owtf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/karandesai-96/owtf/git/refs{/sha}","trees_url":"https://api.github.com/repos/karandesai-96/owtf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/karandesai-96/owtf/statuses/{sha}","languages_url":"https://api.github.com/repos/karandesai-96/owtf/languages","stargazers_url":"https://api.github.com/repos/karandesai-96/owtf/stargazers","contributors_url":"https://api.github.com/repos/karandesai-96/owtf/contributors","subscribers_url":"https://api.github.com/repos/karandesai-96/owtf/subscribers","subscription_url":"https://api.github.com/repos/karandesai-96/owtf/subscription","commits_url":"https://api.github.com/repos/karandesai-96/owtf/commits{/sha}","git_commits_url":"https://api.github.com/repos/karandesai-96/owtf/git/commits{/sha}","comments_url":"https://api.github.com/repos/karandesai-96/owtf/comments{/number}","issue_comment_url":"https://api.github.com/repos/karandesai-96/owtf/issues/comments{/number}","contents_url":"https://api.github.com/repos/karandesai-96/owtf/contents/{+path}","compare_url":"https://api.github.com/repos/karandesai-96/owtf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/karandesai-96/owtf/merges","archive_url":"https://api.github.com/repos/karandesai-96/owtf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/karandesai-96/owtf/downloads","issues_url":"https://api.github.com/repos/karandesai-96/owtf/issues{/number}","pulls_url":"https://api.github.com/repos/karandesai-96/owtf/pulls{/number}","milestones_url":"https://api.github.com/repos/karandesai-96/owtf/milestones{/number}","notifications_url":"https://api.github.com/repos/karandesai-96/owtf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/karandesai-96/owtf/labels{/name}","releases_url":"https://api.github.com/repos/karandesai-96/owtf/releases{/id}","deployments_url":"https://api.github.com/repos/karandesai-96/owtf/deployments","created_at":"2016-03-02T02:53:24Z","updated_at":"2016-03-02T02:53:26Z","pushed_at":"2016-03-15T07:27:43Z","git_url":"git://github.com/karandesai-96/owtf.git","ssh_url":"git@github.com:karandesai-96/owtf.git","clone_url":"https://github.com/karandesai-96/owtf.git","svn_url":"https://github.com/karandesai-96/owtf","homepage":"https://www.owasp.org/index.php/OWASP_OWTF","size":17188,"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":"owtf:develop","ref":"develop","sha":"7fc42674204edcfbac09f94cfd877f56a8032171","user":{"login":"owtf","id":1230211,"avatar_url":"https://avatars.githubusercontent.com/u/1230211?v=3","gravatar_id":"","url":"https://api.github.com/users/owtf","html_url":"https://github.com/owtf","followers_url":"https://api.github.com/users/owtf/followers","following_url":"https://api.github.com/users/owtf/following{/other_user}","gists_url":"https://api.github.com/users/owtf/gists{/gist_id}","starred_url":"https://api.github.com/users/owtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/owtf/subscriptions","organizations_url":"https://api.github.com/users/owtf/orgs","repos_url":"https://api.github.com/users/owtf/repos","events_url":"https://api.github.com/users/owtf/events{/privacy}","received_events_url":"https://api.github.com/users/owtf/received_events","type":"Organization","site_admin":false},"repo":{"id":3215654,"name":"owtf","full_name":"owtf/owtf","owner":{"login":"owtf","id":1230211,"avatar_url":"https://avatars.githubusercontent.com/u/1230211?v=3","gravatar_id":"","url":"https://api.github.com/users/owtf","html_url":"https://github.com/owtf","followers_url":"https://api.github.com/users/owtf/followers","following_url":"https://api.github.com/users/owtf/following{/other_user}","gists_url":"https://api.github.com/users/owtf/gists{/gist_id}","starred_url":"https://api.github.com/users/owtf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/owtf/subscriptions","organizations_url":"https://api.github.com/users/owtf/orgs","repos_url":"https://api.github.com/users/owtf/repos","events_url":"https://api.github.com/users/owtf/events{/privacy}","received_events_url":"https://api.github.com/users/owtf/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/owtf/owtf","description":"OWASP OWTF, the Offensive (Web) Testing Framework, is an OWASP+PTES-focused try to unite great tools and make pen testing more efficient, written mostly in Python @owtfp http://owtf.org","fork":false,"url":"https://api.github.com/repos/owtf/owtf","forks_url":"https://api.github.com/repos/owtf/owtf/forks","keys_url":"https://api.github.com/repos/owtf/owtf/keys{/key_id}","collaborators_url":"https://api.github.com/repos/owtf/owtf/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/owtf/owtf/teams","hooks_url":"https://api.github.com/repos/owtf/owtf/hooks","issue_events_url":"https://api.github.com/repos/owtf/owtf/issues/events{/number}","events_url":"https://api.github.com/repos/owtf/owtf/events","assignees_url":"https://api.github.com/repos/owtf/owtf/assignees{/user}","branches_url":"https://api.github.com/repos/owtf/owtf/branches{/branch}","tags_url":"https://api.github.com/repos/owtf/owtf/tags","blobs_url":"https://api.github.com/repos/owtf/owtf/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/owtf/owtf/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/owtf/owtf/git/refs{/sha}","trees_url":"https://api.github.com/repos/owtf/owtf/git/trees{/sha}","statuses_url":"https://api.github.com/repos/owtf/owtf/statuses/{sha}","languages_url":"https://api.github.com/repos/owtf/owtf/languages","stargazers_url":"https://api.github.com/repos/owtf/owtf/stargazers","contributors_url":"https://api.github.com/repos/owtf/owtf/contributors","subscribers_url":"https://api.github.com/repos/owtf/owtf/subscribers","subscription_url":"https://api.github.com/repos/owtf/owtf/subscription","commits_url":"https://api.github.com/repos/owtf/owtf/commits{/sha}","git_commits_url":"https://api.github.com/repos/owtf/owtf/git/commits{/sha}","comments_url":"https://api.github.com/repos/owtf/owtf/comments{/number}","issue_comment_url":"https://api.github.com/repos/owtf/owtf/issues/comments{/number}","contents_url":"https://api.github.com/repos/owtf/owtf/contents/{+path}","compare_url":"https://api.github.com/repos/owtf/owtf/compare/{base}...{head}","merges_url":"https://api.github.com/repos/owtf/owtf/merges","archive_url":"https://api.github.com/repos/owtf/owtf/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/owtf/owtf/downloads","issues_url":"https://api.github.com/repos/owtf/owtf/issues{/number}","pulls_url":"https://api.github.com/repos/owtf/owtf/pulls{/number}","milestones_url":"https://api.github.com/repos/owtf/owtf/milestones{/number}","notifications_url":"https://api.github.com/repos/owtf/owtf/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/owtf/owtf/labels{/name}","releases_url":"https://api.github.com/repos/owtf/owtf/releases{/id}","deployments_url":"https://api.github.com/repos/owtf/owtf/deployments","created_at":"2012-01-19T06:42:44Z","updated_at":"2016-03-13T11:06:11Z","pushed_at":"2016-03-15T10:59:37Z","git_url":"git://github.com/owtf/owtf.git","ssh_url":"git@github.com:owtf/owtf.git","clone_url":"https://github.com/owtf/owtf.git","svn_url":"https://github.com/owtf/owtf","homepage":"https://www.owasp.org/index.php/OWASP_OWTF","size":131578,"stargazers_count":241,"watchers_count":241,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":102,"mirror_url":null,"open_issues_count":58,"forks":102,"open_issues":58,"watchers":241,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/owtf/owtf/pulls/588"},"html":{"href":"https://github.com/owtf/owtf/pull/588"},"issue":{"href":"https://api.github.com/repos/owtf/owtf/issues/588"},"comments":{"href":"https://api.github.com/repos/owtf/owtf/issues/588/comments"},"review_comments":{"href":"https://api.github.com/repos/owtf/owtf/pulls/588/comments"},"review_comment":{"href":"https://api.github.com/repos/owtf/owtf/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/owtf/owtf/pulls/588/commits"},"statuses":{"href":"https://api.github.com/repos/owtf/owtf/statuses/4305d4f810e1f46ea2a7bc7644169bd9fb4be459"}}}}