We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
NIkola does not see plugins listed under DISABLED_PLUGINS
First noticed while running `nikola build`:
`ERROR: _switch to py3:please!. Task dependency 'sitemap' does not exist.`

> polyzen> there's no longer a way to disable the sitemap? i don't see it under `nikola plugin --list-installed` nor `nikola list` unless it's part of render_site
> +ralsina> sitemap at /home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/task/sitemap/
> +ralsina> I suspect disabled plugins are not listed anymore, try that in some other folder
> polyzen> ah yes


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nikola/plugins/command/plugin.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # Copyright © 2012-2015 Roberto Alsina and others.
4 
5 # Permission is hereby granted, free of charge, to any
6 # person obtaining a copy of this software and associated
7 # documentation files (the "Software"), to deal in the
8 # Software without restriction, including without limitation
9 # the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the
11 # Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice
15 # shall be included in all copies or substantial portions of
16 # the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
22 # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 
27 """Manage plugins."""
28 
29 from __future__ import print_function
30 import io
31 import os
32 import shutil
33 import subprocess
34 import time
35 import requests
36 
37 import pygments
38 from pygments.lexers import PythonLexer
39 from pygments.formatters import TerminalFormatter
40 
41 from nikola.plugin_categories import Command
42 from nikola import utils
43 
44 LOGGER = utils.get_logger('plugin', utils.STDERR_HANDLER)
45 
46 
47 class CommandPlugin(Command):
48     """Manage plugins."""
49 
50     json = None
51     name = "plugin"
52     doc_usage = "[[-u][--user] --install name] | [[-u] [-l |--upgrade|--list-installed] | [--uninstall name]]"
53     doc_purpose = "manage plugins"
54     output_dir = None
55     needs_config = False
56     cmd_options = [
57         {
58             'name': 'install',
59             'short': 'i',
60             'long': 'install',
61             'type': str,
62             'default': '',
63             'help': 'Install a plugin.',
64         },
65         {
66             'name': 'uninstall',
67             'long': 'uninstall',
68             'short': 'r',
69             'type': str,
70             'default': '',
71             'help': 'Uninstall a plugin.'
72         },
73         {
74             'name': 'list',
75             'short': 'l',
76             'long': 'list',
77             'type': bool,
78             'default': False,
79             'help': 'Show list of available plugins.'
80         },
81         {
82             'name': 'url',
83             'short': 'u',
84             'long': 'url',
85             'type': str,
86             'help': "URL for the plugin repository (default: "
87                     "https://plugins.getnikola.com/v7/plugins.json)",
88             'default': 'https://plugins.getnikola.com/v7/plugins.json'
89         },
90         {
91             'name': 'user',
92             'long': 'user',
93             'type': bool,
94             'help': "Install user-wide, available for all sites.",
95             'default': False
96         },
97         {
98             'name': 'upgrade',
99             'long': 'upgrade',
100             'type': bool,
101             'help': "Upgrade all installed plugins.",
102             'default': False
103         },
104         {
105             'name': 'list_installed',
106             'long': 'list-installed',
107             'type': bool,
108             'help': "List the installed plugins with their location.",
109             'default': False
110         },
111     ]
112 
113     def _execute(self, options, args):
114         """Install plugin into current site."""
115         url = options['url']
116         user_mode = options['user']
117 
118         # See the "mode" we need to operate in
119         install = options.get('install')
120         uninstall = options.get('uninstall')
121         upgrade = options.get('upgrade')
122         list_available = options.get('list')
123         list_installed = options.get('list_installed')
124         show_install_notes = options.get('show_install_notes', True)
125         command_count = [bool(x) for x in (
126             install,
127             uninstall,
128             upgrade,
129             list_available,
130             list_installed)].count(True)
131         if command_count > 1 or command_count == 0:
132             print(self.help())
133             return 2
134 
135         if options.get('output_dir') is not None:
136             self.output_dir = options.get('output_dir')
137         else:
138             if not self.site.configured and not user_mode and install:
139                 LOGGER.notice('No site found, assuming --user')
140                 user_mode = True
141 
142             if user_mode:
143                 self.output_dir = os.path.expanduser('~/.nikola/plugins')
144             else:
145                 self.output_dir = 'plugins'
146 
147         if list_available:
148             return self.list_available(url)
149         elif list_installed:
150             return self.list_installed()
151         elif upgrade:
152             return self.do_upgrade(url)
153         elif uninstall:
154             return self.do_uninstall(uninstall)
155         elif install:
156             return self.do_install(url, install, show_install_notes)
157 
158     def list_available(self, url):
159         """List all available plugins."""
160         data = self.get_json(url)
161         print("Available Plugins:")
162         print("------------------")
163         for plugin in sorted(data.keys()):
164             print(plugin)
165         return 0
166 
167     def list_installed(self):
168         """List installed plugins."""
169         plugins = []
170         for plugin in self.site.plugin_manager.getAllPlugins():
171             p = plugin.path
172             if os.path.isdir(p):
173                 p = p + os.sep
174             else:
175                 p = p + '.py'
176             plugins.append([plugin.name, p])
177 
178         plugins.sort()
179         for name, path in plugins:
180             print('{0} at {1}'.format(name, path))
181         return 0
182 
183     def do_upgrade(self, url):
184         """Upgrade all installed plugins."""
185         LOGGER.warning('This is not very smart, it just reinstalls some plugins and hopes for the best')
186         data = self.get_json(url)
187         plugins = []
188         for plugin in self.site.plugin_manager.getAllPlugins():
189             p = plugin.path
190             if os.path.isdir(p):
191                 p = p + os.sep
192             else:
193                 p = p + '.py'
194             if plugin.name in data:
195                 plugins.append([plugin.name, p])
196         print('Will upgrade {0} plugins: {1}'.format(len(plugins), ', '.join(n for n, _ in plugins)))
197         for name, path in plugins:
198             print('Upgrading {0}'.format(name))
199             p = path
200             while True:
201                 tail, head = os.path.split(path)
202                 if head == 'plugins':
203                     self.output_dir = path
204                     break
205                 elif tail == '':
206                     LOGGER.error("Can't find the plugins folder for path: {0}".format(p))
207                     return 1
208                 else:
209                     path = tail
210             self.do_install(url, name)
211         return 0
212 
213     def do_install(self, url, name, show_install_notes=True):
214         """Download and install a plugin."""
215         data = self.get_json(url)
216         if name in data:
217             utils.makedirs(self.output_dir)
218             url = data[name]
219             LOGGER.info("Downloading '{0}'".format(url))
220             try:
221                 zip_data = requests.get(url).content
222             except requests.exceptions.SSLError:
223                 LOGGER.warning("SSL error, using http instead of https (press ^C to abort)")
224                 time.sleep(1)
225                 url = url.replace('https', 'http', 1)
226                 zip_data = requests.get(url).content
227 
228             zip_file = io.BytesIO()
229             zip_file.write(zip_data)
230             LOGGER.info('Extracting: {0} into {1}/'.format(name, self.output_dir))
231             utils.extract_all(zip_file, self.output_dir)
232             dest_path = os.path.join(self.output_dir, name)
233         else:
234             try:
235                 plugin_path = utils.get_plugin_path(name)
236             except:
237                 LOGGER.error("Can't find plugin " + name)
238                 return 1
239 
240             utils.makedirs(self.output_dir)
241             dest_path = os.path.join(self.output_dir, name)
242             if os.path.exists(dest_path):
243                 LOGGER.error("{0} is already installed".format(name))
244                 return 1
245 
246             LOGGER.info('Copying {0} into plugins'.format(plugin_path))
247             shutil.copytree(plugin_path, dest_path)
248 
249         reqpath = os.path.join(dest_path, 'requirements.txt')
250         if os.path.exists(reqpath):
251             LOGGER.notice('This plugin has Python dependencies.')
252             LOGGER.info('Installing dependencies with pip...')
253             try:
254                 subprocess.check_call(('pip', 'install', '-r', reqpath))
255             except subprocess.CalledProcessError:
256                 LOGGER.error('Could not install the dependencies.')
257                 print('Contents of the requirements.txt file:\n')
258                 with io.open(reqpath, 'r', encoding='utf-8') as fh:
259                     print(utils.indent(fh.read(), 4 * ' '))
260                 print('You have to install those yourself or through a '
261                       'package manager.')
262             else:
263                 LOGGER.info('Dependency installation succeeded.')
264         reqnpypath = os.path.join(dest_path, 'requirements-nonpy.txt')
265         if os.path.exists(reqnpypath):
266             LOGGER.notice('This plugin has third-party '
267                           'dependencies you need to install '
268                           'manually.')
269             print('Contents of the requirements-nonpy.txt file:\n')
270             with io.open(reqnpypath, 'r', encoding='utf-8') as fh:
271                 for l in fh.readlines():
272                     i, j = l.split('::')
273                     print(utils.indent(i.strip(), 4 * ' '))
274                     print(utils.indent(j.strip(), 8 * ' '))
275                     print()
276 
277             print('You have to install those yourself or through a package '
278                   'manager.')
279         confpypath = os.path.join(dest_path, 'conf.py.sample')
280         if os.path.exists(confpypath) and show_install_notes:
281             LOGGER.notice('This plugin has a sample config file.  Integrate it with yours in order to make this plugin work!')
282             print('Contents of the conf.py.sample file:\n')
283             with io.open(confpypath, 'r', encoding='utf-8') as fh:
284                 if self.site.colorful:
285                     print(utils.indent(pygments.highlight(
286                         fh.read(), PythonLexer(), TerminalFormatter()),
287                         4 * ' '))
288                 else:
289                     print(utils.indent(fh.read(), 4 * ' '))
290         return 0
291 
292     def do_uninstall(self, name):
293         """Uninstall a plugin."""
294         for plugin in self.site.plugin_manager.getAllPlugins():  # FIXME: this is repeated thrice
295             p = plugin.path
296             if os.path.isdir(p):
297                 p = p + os.sep
298             else:
299                 p = os.path.dirname(p)
300             if name == plugin.name:  # Uninstall this one
301                 LOGGER.warning('About to uninstall plugin: {0}'.format(name))
302                 LOGGER.warning('This will delete {0}'.format(p))
303                 sure = utils.ask_yesno('Are you sure?')
304                 if sure:
305                     LOGGER.warning('Removing {0}'.format(p))
306                     shutil.rmtree(p)
307                     return 0
308                 return 1
309         LOGGER.error('Unknown plugin: {0}'.format(name))
310         return 1
311 
312     def get_json(self, url):
313         """Download the JSON file with all plugins."""
314         if self.json is None:
315             try:
316                 self.json = requests.get(url).json()
317             except requests.exceptions.SSLError:
318                 LOGGER.warning("SSL error, using http instead of https (press ^C to abort)")
319                 time.sleep(1)
320                 url = url.replace('https', 'http', 1)
321                 self.json = requests.get(url).json()
322         return self.json
323
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nikola/plugins/command/plugin.py b/nikola/plugins/command/plugin.py
--- a/nikola/plugins/command/plugin.py
+++ b/nikola/plugins/command/plugin.py
@@ -176,8 +176,11 @@
             plugins.append([plugin.name, p])
 
         plugins.sort()
+        print('Installed Plugins')
+        print('-----------------')
         for name, path in plugins:
             print('{0} at {1}'.format(name, path))
+        print('\n\nAlso, you have disabled these plugins: {}'.format(self.site.config['DISABLED_PLUGINS']))
         return 0
 
     def do_upgrade(self, url):

{"golden_diff": "diff --git a/nikola/plugins/command/plugin.py b/nikola/plugins/command/plugin.py\n--- a/nikola/plugins/command/plugin.py\n+++ b/nikola/plugins/command/plugin.py\n@@ -176,8 +176,11 @@\n             plugins.append([plugin.name, p])\n \n         plugins.sort()\n+        print('Installed Plugins')\n+        print('-----------------')\n         for name, path in plugins:\n             print('{0} at {1}'.format(name, path))\n+        print('\\n\\nAlso, you have disabled these plugins: {}'.format(self.site.config['DISABLED_PLUGINS']))\n         return 0\n \n     def do_upgrade(self, url):\n", "issue": "NIkola does not see plugins listed under DISABLED_PLUGINS\nFirst noticed while running `nikola build`:\n`ERROR: _switch to py3:please!. Task dependency 'sitemap' does not exist.`\n\n> polyzen> there's no longer a way to disable the sitemap? i don't see it under `nikola plugin --list-installed` nor `nikola list` unless it's part of render_site\n> +ralsina> sitemap at /home/ralsina/Desktop/proyectos/nikola/master/nikola/plugins/task/sitemap/\n> +ralsina> I suspect disabled plugins are not listed anymore, try that in some other folder\n> polyzen> ah yes\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2015 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"Manage plugins.\"\"\"\n\nfrom __future__ import print_function\nimport io\nimport os\nimport shutil\nimport subprocess\nimport time\nimport requests\n\nimport pygments\nfrom pygments.lexers import PythonLexer\nfrom pygments.formatters import TerminalFormatter\n\nfrom nikola.plugin_categories import Command\nfrom nikola import utils\n\nLOGGER = utils.get_logger('plugin', utils.STDERR_HANDLER)\n\n\nclass CommandPlugin(Command):\n    \"\"\"Manage plugins.\"\"\"\n\n    json = None\n    name = \"plugin\"\n    doc_usage = \"[[-u][--user] --install name] | [[-u] [-l |--upgrade|--list-installed] | [--uninstall name]]\"\n    doc_purpose = \"manage plugins\"\n    output_dir = None\n    needs_config = False\n    cmd_options = [\n        {\n            'name': 'install',\n            'short': 'i',\n            'long': 'install',\n            'type': str,\n            'default': '',\n            'help': 'Install a plugin.',\n        },\n        {\n            'name': 'uninstall',\n            'long': 'uninstall',\n            'short': 'r',\n            'type': str,\n            'default': '',\n            'help': 'Uninstall a plugin.'\n        },\n        {\n            'name': 'list',\n            'short': 'l',\n            'long': 'list',\n            'type': bool,\n            'default': False,\n            'help': 'Show list of available plugins.'\n        },\n        {\n            'name': 'url',\n            'short': 'u',\n            'long': 'url',\n            'type': str,\n            'help': \"URL for the plugin repository (default: \"\n                    \"https://plugins.getnikola.com/v7/plugins.json)\",\n            'default': 'https://plugins.getnikola.com/v7/plugins.json'\n        },\n        {\n            'name': 'user',\n            'long': 'user',\n            'type': bool,\n            'help': \"Install user-wide, available for all sites.\",\n            'default': False\n        },\n        {\n            'name': 'upgrade',\n            'long': 'upgrade',\n            'type': bool,\n            'help': \"Upgrade all installed plugins.\",\n            'default': False\n        },\n        {\n            'name': 'list_installed',\n            'long': 'list-installed',\n            'type': bool,\n            'help': \"List the installed plugins with their location.\",\n            'default': False\n        },\n    ]\n\n    def _execute(self, options, args):\n        \"\"\"Install plugin into current site.\"\"\"\n        url = options['url']\n        user_mode = options['user']\n\n        # See the \"mode\" we need to operate in\n        install = options.get('install')\n        uninstall = options.get('uninstall')\n        upgrade = options.get('upgrade')\n        list_available = options.get('list')\n        list_installed = options.get('list_installed')\n        show_install_notes = options.get('show_install_notes', True)\n        command_count = [bool(x) for x in (\n            install,\n            uninstall,\n            upgrade,\n            list_available,\n            list_installed)].count(True)\n        if command_count > 1 or command_count == 0:\n            print(self.help())\n            return 2\n\n        if options.get('output_dir') is not None:\n            self.output_dir = options.get('output_dir')\n        else:\n            if not self.site.configured and not user_mode and install:\n                LOGGER.notice('No site found, assuming --user')\n                user_mode = True\n\n            if user_mode:\n                self.output_dir = os.path.expanduser('~/.nikola/plugins')\n            else:\n                self.output_dir = 'plugins'\n\n        if list_available:\n            return self.list_available(url)\n        elif list_installed:\n            return self.list_installed()\n        elif upgrade:\n            return self.do_upgrade(url)\n        elif uninstall:\n            return self.do_uninstall(uninstall)\n        elif install:\n            return self.do_install(url, install, show_install_notes)\n\n    def list_available(self, url):\n        \"\"\"List all available plugins.\"\"\"\n        data = self.get_json(url)\n        print(\"Available Plugins:\")\n        print(\"------------------\")\n        for plugin in sorted(data.keys()):\n            print(plugin)\n        return 0\n\n    def list_installed(self):\n        \"\"\"List installed plugins.\"\"\"\n        plugins = []\n        for plugin in self.site.plugin_manager.getAllPlugins():\n            p = plugin.path\n            if os.path.isdir(p):\n                p = p + os.sep\n            else:\n                p = p + '.py'\n            plugins.append([plugin.name, p])\n\n        plugins.sort()\n        for name, path in plugins:\n            print('{0} at {1}'.format(name, path))\n        return 0\n\n    def do_upgrade(self, url):\n        \"\"\"Upgrade all installed plugins.\"\"\"\n        LOGGER.warning('This is not very smart, it just reinstalls some plugins and hopes for the best')\n        data = self.get_json(url)\n        plugins = []\n        for plugin in self.site.plugin_manager.getAllPlugins():\n            p = plugin.path\n            if os.path.isdir(p):\n                p = p + os.sep\n            else:\n                p = p + '.py'\n            if plugin.name in data:\n                plugins.append([plugin.name, p])\n        print('Will upgrade {0} plugins: {1}'.format(len(plugins), ', '.join(n for n, _ in plugins)))\n        for name, path in plugins:\n            print('Upgrading {0}'.format(name))\n            p = path\n            while True:\n                tail, head = os.path.split(path)\n                if head == 'plugins':\n                    self.output_dir = path\n                    break\n                elif tail == '':\n                    LOGGER.error(\"Can't find the plugins folder for path: {0}\".format(p))\n                    return 1\n                else:\n                    path = tail\n            self.do_install(url, name)\n        return 0\n\n    def do_install(self, url, name, show_install_notes=True):\n        \"\"\"Download and install a plugin.\"\"\"\n        data = self.get_json(url)\n        if name in data:\n            utils.makedirs(self.output_dir)\n            url = data[name]\n            LOGGER.info(\"Downloading '{0}'\".format(url))\n            try:\n                zip_data = requests.get(url).content\n            except requests.exceptions.SSLError:\n                LOGGER.warning(\"SSL error, using http instead of https (press ^C to abort)\")\n                time.sleep(1)\n                url = url.replace('https', 'http', 1)\n                zip_data = requests.get(url).content\n\n            zip_file = io.BytesIO()\n            zip_file.write(zip_data)\n            LOGGER.info('Extracting: {0} into {1}/'.format(name, self.output_dir))\n            utils.extract_all(zip_file, self.output_dir)\n            dest_path = os.path.join(self.output_dir, name)\n        else:\n            try:\n                plugin_path = utils.get_plugin_path(name)\n            except:\n                LOGGER.error(\"Can't find plugin \" + name)\n                return 1\n\n            utils.makedirs(self.output_dir)\n            dest_path = os.path.join(self.output_dir, name)\n            if os.path.exists(dest_path):\n                LOGGER.error(\"{0} is already installed\".format(name))\n                return 1\n\n            LOGGER.info('Copying {0} into plugins'.format(plugin_path))\n            shutil.copytree(plugin_path, dest_path)\n\n        reqpath = os.path.join(dest_path, 'requirements.txt')\n        if os.path.exists(reqpath):\n            LOGGER.notice('This plugin has Python dependencies.')\n            LOGGER.info('Installing dependencies with pip...')\n            try:\n                subprocess.check_call(('pip', 'install', '-r', reqpath))\n            except subprocess.CalledProcessError:\n                LOGGER.error('Could not install the dependencies.')\n                print('Contents of the requirements.txt file:\\n')\n                with io.open(reqpath, 'r', encoding='utf-8') as fh:\n                    print(utils.indent(fh.read(), 4 * ' '))\n                print('You have to install those yourself or through a '\n                      'package manager.')\n            else:\n                LOGGER.info('Dependency installation succeeded.')\n        reqnpypath = os.path.join(dest_path, 'requirements-nonpy.txt')\n        if os.path.exists(reqnpypath):\n            LOGGER.notice('This plugin has third-party '\n                          'dependencies you need to install '\n                          'manually.')\n            print('Contents of the requirements-nonpy.txt file:\\n')\n            with io.open(reqnpypath, 'r', encoding='utf-8') as fh:\n                for l in fh.readlines():\n                    i, j = l.split('::')\n                    print(utils.indent(i.strip(), 4 * ' '))\n                    print(utils.indent(j.strip(), 8 * ' '))\n                    print()\n\n            print('You have to install those yourself or through a package '\n                  'manager.')\n        confpypath = os.path.join(dest_path, 'conf.py.sample')\n        if os.path.exists(confpypath) and show_install_notes:\n            LOGGER.notice('This plugin has a sample config file.  Integrate it with yours in order to make this plugin work!')\n            print('Contents of the conf.py.sample file:\\n')\n            with io.open(confpypath, 'r', encoding='utf-8') as fh:\n                if self.site.colorful:\n                    print(utils.indent(pygments.highlight(\n                        fh.read(), PythonLexer(), TerminalFormatter()),\n                        4 * ' '))\n                else:\n                    print(utils.indent(fh.read(), 4 * ' '))\n        return 0\n\n    def do_uninstall(self, name):\n        \"\"\"Uninstall a plugin.\"\"\"\n        for plugin in self.site.plugin_manager.getAllPlugins():  # FIXME: this is repeated thrice\n            p = plugin.path\n            if os.path.isdir(p):\n                p = p + os.sep\n            else:\n                p = os.path.dirname(p)\n            if name == plugin.name:  # Uninstall this one\n                LOGGER.warning('About to uninstall plugin: {0}'.format(name))\n                LOGGER.warning('This will delete {0}'.format(p))\n                sure = utils.ask_yesno('Are you sure?')\n                if sure:\n                    LOGGER.warning('Removing {0}'.format(p))\n                    shutil.rmtree(p)\n                    return 0\n                return 1\n        LOGGER.error('Unknown plugin: {0}'.format(name))\n        return 1\n\n    def get_json(self, url):\n        \"\"\"Download the JSON file with all plugins.\"\"\"\n        if self.json is None:\n            try:\n                self.json = requests.get(url).json()\n            except requests.exceptions.SSLError:\n                LOGGER.warning(\"SSL error, using http instead of https (press ^C to abort)\")\n                time.sleep(1)\n                url = url.replace('https', 'http', 1)\n                self.json = requests.get(url).json()\n        return self.json\n", "path": "nikola/plugins/command/plugin.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2015 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"Manage plugins.\"\"\"\n\nfrom __future__ import print_function\nimport io\nimport os\nimport shutil\nimport subprocess\nimport time\nimport requests\n\nimport pygments\nfrom pygments.lexers import PythonLexer\nfrom pygments.formatters import TerminalFormatter\n\nfrom nikola.plugin_categories import Command\nfrom nikola import utils\n\nLOGGER = utils.get_logger('plugin', utils.STDERR_HANDLER)\n\n\nclass CommandPlugin(Command):\n    \"\"\"Manage plugins.\"\"\"\n\n    json = None\n    name = \"plugin\"\n    doc_usage = \"[[-u][--user] --install name] | [[-u] [-l |--upgrade|--list-installed] | [--uninstall name]]\"\n    doc_purpose = \"manage plugins\"\n    output_dir = None\n    needs_config = False\n    cmd_options = [\n        {\n            'name': 'install',\n            'short': 'i',\n            'long': 'install',\n            'type': str,\n            'default': '',\n            'help': 'Install a plugin.',\n        },\n        {\n            'name': 'uninstall',\n            'long': 'uninstall',\n            'short': 'r',\n            'type': str,\n            'default': '',\n            'help': 'Uninstall a plugin.'\n        },\n        {\n            'name': 'list',\n            'short': 'l',\n            'long': 'list',\n            'type': bool,\n            'default': False,\n            'help': 'Show list of available plugins.'\n        },\n        {\n            'name': 'url',\n            'short': 'u',\n            'long': 'url',\n            'type': str,\n            'help': \"URL for the plugin repository (default: \"\n                    \"https://plugins.getnikola.com/v7/plugins.json)\",\n            'default': 'https://plugins.getnikola.com/v7/plugins.json'\n        },\n        {\n            'name': 'user',\n            'long': 'user',\n            'type': bool,\n            'help': \"Install user-wide, available for all sites.\",\n            'default': False\n        },\n        {\n            'name': 'upgrade',\n            'long': 'upgrade',\n            'type': bool,\n            'help': \"Upgrade all installed plugins.\",\n            'default': False\n        },\n        {\n            'name': 'list_installed',\n            'long': 'list-installed',\n            'type': bool,\n            'help': \"List the installed plugins with their location.\",\n            'default': False\n        },\n    ]\n\n    def _execute(self, options, args):\n        \"\"\"Install plugin into current site.\"\"\"\n        url = options['url']\n        user_mode = options['user']\n\n        # See the \"mode\" we need to operate in\n        install = options.get('install')\n        uninstall = options.get('uninstall')\n        upgrade = options.get('upgrade')\n        list_available = options.get('list')\n        list_installed = options.get('list_installed')\n        show_install_notes = options.get('show_install_notes', True)\n        command_count = [bool(x) for x in (\n            install,\n            uninstall,\n            upgrade,\n            list_available,\n            list_installed)].count(True)\n        if command_count > 1 or command_count == 0:\n            print(self.help())\n            return 2\n\n        if options.get('output_dir') is not None:\n            self.output_dir = options.get('output_dir')\n        else:\n            if not self.site.configured and not user_mode and install:\n                LOGGER.notice('No site found, assuming --user')\n                user_mode = True\n\n            if user_mode:\n                self.output_dir = os.path.expanduser('~/.nikola/plugins')\n            else:\n                self.output_dir = 'plugins'\n\n        if list_available:\n            return self.list_available(url)\n        elif list_installed:\n            return self.list_installed()\n        elif upgrade:\n            return self.do_upgrade(url)\n        elif uninstall:\n            return self.do_uninstall(uninstall)\n        elif install:\n            return self.do_install(url, install, show_install_notes)\n\n    def list_available(self, url):\n        \"\"\"List all available plugins.\"\"\"\n        data = self.get_json(url)\n        print(\"Available Plugins:\")\n        print(\"------------------\")\n        for plugin in sorted(data.keys()):\n            print(plugin)\n        return 0\n\n    def list_installed(self):\n        \"\"\"List installed plugins.\"\"\"\n        plugins = []\n        for plugin in self.site.plugin_manager.getAllPlugins():\n            p = plugin.path\n            if os.path.isdir(p):\n                p = p + os.sep\n            else:\n                p = p + '.py'\n            plugins.append([plugin.name, p])\n\n        plugins.sort()\n        print('Installed Plugins')\n        print('-----------------')\n        for name, path in plugins:\n            print('{0} at {1}'.format(name, path))\n        print('\\n\\nAlso, you have disabled these plugins: {}'.format(self.site.config['DISABLED_PLUGINS']))\n        return 0\n\n    def do_upgrade(self, url):\n        \"\"\"Upgrade all installed plugins.\"\"\"\n        LOGGER.warning('This is not very smart, it just reinstalls some plugins and hopes for the best')\n        data = self.get_json(url)\n        plugins = []\n        for plugin in self.site.plugin_manager.getAllPlugins():\n            p = plugin.path\n            if os.path.isdir(p):\n                p = p + os.sep\n            else:\n                p = p + '.py'\n            if plugin.name in data:\n                plugins.append([plugin.name, p])\n        print('Will upgrade {0} plugins: {1}'.format(len(plugins), ', '.join(n for n, _ in plugins)))\n        for name, path in plugins:\n            print('Upgrading {0}'.format(name))\n            p = path\n            while True:\n                tail, head = os.path.split(path)\n                if head == 'plugins':\n                    self.output_dir = path\n                    break\n                elif tail == '':\n                    LOGGER.error(\"Can't find the plugins folder for path: {0}\".format(p))\n                    return 1\n                else:\n                    path = tail\n            self.do_install(url, name)\n        return 0\n\n    def do_install(self, url, name, show_install_notes=True):\n        \"\"\"Download and install a plugin.\"\"\"\n        data = self.get_json(url)\n        if name in data:\n            utils.makedirs(self.output_dir)\n            url = data[name]\n            LOGGER.info(\"Downloading '{0}'\".format(url))\n            try:\n                zip_data = requests.get(url).content\n            except requests.exceptions.SSLError:\n                LOGGER.warning(\"SSL error, using http instead of https (press ^C to abort)\")\n                time.sleep(1)\n                url = url.replace('https', 'http', 1)\n                zip_data = requests.get(url).content\n\n            zip_file = io.BytesIO()\n            zip_file.write(zip_data)\n            LOGGER.info('Extracting: {0} into {1}/'.format(name, self.output_dir))\n            utils.extract_all(zip_file, self.output_dir)\n            dest_path = os.path.join(self.output_dir, name)\n        else:\n            try:\n                plugin_path = utils.get_plugin_path(name)\n            except:\n                LOGGER.error(\"Can't find plugin \" + name)\n                return 1\n\n            utils.makedirs(self.output_dir)\n            dest_path = os.path.join(self.output_dir, name)\n            if os.path.exists(dest_path):\n                LOGGER.error(\"{0} is already installed\".format(name))\n                return 1\n\n            LOGGER.info('Copying {0} into plugins'.format(plugin_path))\n            shutil.copytree(plugin_path, dest_path)\n\n        reqpath = os.path.join(dest_path, 'requirements.txt')\n        if os.path.exists(reqpath):\n            LOGGER.notice('This plugin has Python dependencies.')\n            LOGGER.info('Installing dependencies with pip...')\n            try:\n                subprocess.check_call(('pip', 'install', '-r', reqpath))\n            except subprocess.CalledProcessError:\n                LOGGER.error('Could not install the dependencies.')\n                print('Contents of the requirements.txt file:\\n')\n                with io.open(reqpath, 'r', encoding='utf-8') as fh:\n                    print(utils.indent(fh.read(), 4 * ' '))\n                print('You have to install those yourself or through a '\n                      'package manager.')\n            else:\n                LOGGER.info('Dependency installation succeeded.')\n        reqnpypath = os.path.join(dest_path, 'requirements-nonpy.txt')\n        if os.path.exists(reqnpypath):\n            LOGGER.notice('This plugin has third-party '\n                          'dependencies you need to install '\n                          'manually.')\n            print('Contents of the requirements-nonpy.txt file:\\n')\n            with io.open(reqnpypath, 'r', encoding='utf-8') as fh:\n                for l in fh.readlines():\n                    i, j = l.split('::')\n                    print(utils.indent(i.strip(), 4 * ' '))\n                    print(utils.indent(j.strip(), 8 * ' '))\n                    print()\n\n            print('You have to install those yourself or through a package '\n                  'manager.')\n        confpypath = os.path.join(dest_path, 'conf.py.sample')\n        if os.path.exists(confpypath) and show_install_notes:\n            LOGGER.notice('This plugin has a sample config file.  Integrate it with yours in order to make this plugin work!')\n            print('Contents of the conf.py.sample file:\\n')\n            with io.open(confpypath, 'r', encoding='utf-8') as fh:\n                if self.site.colorful:\n                    print(utils.indent(pygments.highlight(\n                        fh.read(), PythonLexer(), TerminalFormatter()),\n                        4 * ' '))\n                else:\n                    print(utils.indent(fh.read(), 4 * ' '))\n        return 0\n\n    def do_uninstall(self, name):\n        \"\"\"Uninstall a plugin.\"\"\"\n        for plugin in self.site.plugin_manager.getAllPlugins():  # FIXME: this is repeated thrice\n            p = plugin.path\n            if os.path.isdir(p):\n                p = p + os.sep\n            else:\n                p = os.path.dirname(p)\n            if name == plugin.name:  # Uninstall this one\n                LOGGER.warning('About to uninstall plugin: {0}'.format(name))\n                LOGGER.warning('This will delete {0}'.format(p))\n                sure = utils.ask_yesno('Are you sure?')\n                if sure:\n                    LOGGER.warning('Removing {0}'.format(p))\n                    shutil.rmtree(p)\n                    return 0\n                return 1\n        LOGGER.error('Unknown plugin: {0}'.format(name))\n        return 1\n\n    def get_json(self, url):\n        \"\"\"Download the JSON file with all plugins.\"\"\"\n        if self.json is None:\n            try:\n                self.json = requests.get(url).json()\n            except requests.exceptions.SSLError:\n                LOGGER.warning(\"SSL error, using http instead of https (press ^C to abort)\")\n                time.sleep(1)\n                url = url.replace('https', 'http', 1)\n                self.json = requests.get(url).json()\n        return self.json\n", "path": "nikola/plugins/command/plugin.py"}]}