From 9d9c8877daba0ea49649935bcbeefbf291cb70cb Mon Sep 17 00:00:00 2001 From: Pablo Hoffman Date: Sun, 5 Jun 2011 22:02:56 -0300 Subject: [PATCH] added 'scrapy edit' command --- docs/topics/commands.rst | 20 +++++++++++++++++ docs/topics/settings.rst | 9 ++++++++ extras/scrapy_bash_completion | 2 +- scrapy/commands/edit.py | 35 +++++++++++++++++++++++++++++ scrapy/settings/default_settings.py | 9 ++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 scrapy/commands/edit.py diff --git a/docs/topics/commands.rst b/docs/topics/commands.rst index 6b30a4e59..984894505 100644 --- a/docs/topics/commands.rst +++ b/docs/topics/commands.rst @@ -151,6 +151,7 @@ Project-only commands: * :command:`crawl` * :command:`list` +* :command:`edit` * :command:`parse` * :command:`genspider` * :command:`server` @@ -269,6 +270,25 @@ Usage example:: spider1 spider2 +.. command:: edit + +edit +---- + +* Syntax: ``scrapy edit `` +* Requires project: *yes* + +Edit the given spider using the editor defined in the :setting:`EDITOR` +setting. + +This command is provided only as a convenient shortcut for the most common +case, the developer is of course free to choose any tool or IDE to write and +debug his spiders. + +Usage example:: + + $ scrapy edit spider1 + .. command:: fetch fetch diff --git a/docs/topics/settings.rst b/docs/topics/settings.rst index ce41831d8..515fe503c 100644 --- a/docs/topics/settings.rst +++ b/docs/topics/settings.rst @@ -451,6 +451,15 @@ The class used to detect and filter duplicate requests. The default (``RequestFingerprintDupeFilter``) filters based on request fingerprint (using ``scrapy.utils.request.request_fingerprint``) and grouping per domain. +.. setting:: EDITOR + +EDITOR +------ + +The editor to use for editing spiders with the :command:`edit` command. It +defaults to the ``EDITOR`` environment variable, if set. Otherwise, it defaults +to ``vi`` (on Unix systems) or the IDLE editor (on Windows). + .. setting:: ENCODING_ALIASES ENCODING_ALIASES diff --git a/extras/scrapy_bash_completion b/extras/scrapy_bash_completion index b0654ee6a..17e162510 100644 --- a/extras/scrapy_bash_completion +++ b/extras/scrapy_bash_completion @@ -5,7 +5,7 @@ _scrapy_completion() { cmd=${COMP_WORDS[1]} cur=${COMP_WORDS[2]} case "$cmd" in - crawl) + crawl|edit) spiders=$(scrapy list 2>/dev/null) || spiders="" COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W "$spiders" -- "$cur")) ;; diff --git a/scrapy/commands/edit.py b/scrapy/commands/edit.py new file mode 100644 index 000000000..90f5e6d4c --- /dev/null +++ b/scrapy/commands/edit.py @@ -0,0 +1,35 @@ +import sys, os + +from scrapy.command import ScrapyCommand +from scrapy.exceptions import UsageError + +class Command(ScrapyCommand): + + requires_project = True + default_settings = {'LOG_ENABLED': False} + + def syntax(self): + return "" + + def short_desc(self): + return "Edit spider" + + def long_desc(self): + return "Edit a spider using the editor defined in EDITOR setting" + + def _err(self, msg): + sys.stderr.write(msg + os.linesep) + self.exitcode = 1 + + def run(self, args, opts): + if len(args) != 1: + raise UsageError() + editor = self.crawler.settings['EDITOR'] + try: + spider = self.crawler.spiders.create(args[0]) + except KeyError: + return self._err("Spider not found: %s" % args[0]) + + sfile = sys.modules[spider.__module__].__file__ + sfile = sfile.replace('.pyc', '.py') + self.exitcode = os.system('%s "%s"' % (editor, sfile)) diff --git a/scrapy/settings/default_settings.py b/scrapy/settings/default_settings.py index ab7b89a6a..65ae30cc1 100644 --- a/scrapy/settings/default_settings.py +++ b/scrapy/settings/default_settings.py @@ -13,6 +13,7 @@ Scrapy developers, if you add a setting here remember to: """ +import sys, os from os.path import join, abspath, dirname BOT_NAME = 'scrapybot' @@ -82,6 +83,14 @@ DOWNLOADER_STATS = True DUPEFILTER_CLASS = 'scrapy.contrib.dupefilter.RequestFingerprintDupeFilter' +try: + EDITOR = os.environ['EDITOR'] +except KeyError: + if sys.platform == 'win32': + EDITOR = '%s -m idlelib.idle' + else: + EDITOR = 'vi' + ENCODING_ALIASES = {} ENCODING_ALIASES_BASE = {