Creating a Renamer Plugin¶
Introduction¶
Renamer plugins are Python code, discovered by Twisted’s plugin system, that extends Renamer’s functionality without having to modify the core of Renamer.
There are two kinds of pluggable code in Renamer:
- Commands that perform actions unrelated to directly renaming a file. An example of this would be the undo command.
- Renaming commands that determine new filenames from existing files and ultimately result in an input being renamed. An example of this would be the tvrage command.
Since the topic of creating commands that are not directly related to renaming is so broad, this document will primarily focus on creating a command that performs renaming.
Foundations¶
Renamer commands are simply Twisted Options subclasses with a few extra bits
thrown in, so all the usual Options attributes (such as optParameters
) are
available for use and should be how you expose additional options for your
command.
In almost all cases you will want to inherit from the RenamingCommand
base
class, as it ensure your subclass provides all the right interfaces as well as
invoking your command and performing the actual file renaming.
At the heart of a renaming command is processArgument
which accepts one
argument and returns a Python dictionary. That dictionary is then used to
perform template substitution on the name
and prefix
command-line
options (or, if they’re not given, command-specific defaults.) This process of
calling processArgument
is repeated for each argument given, letting your
command process one argument at a time.
Deferreds¶
If your command performs a long-running task, such as fetching data from a web
server, you can return a Deferred from processArgument
that should
ultimately return with a Python dictionary to be used in assembling the
destination filename.
Sample command¶
Below is the complete source code of a command that renames files named as
POSIX timestamps (e.g. 1287758780.4690211.txt
) to a human-readable
representation of the timestamp (e.g. 2010-10-22 16-46-20.txt
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import os
import string
import time
from renamer.plugin import RenamingCommand
from renamer.errors import PluginError
class ReadableTimestamps(RenamingCommand):
# The name of our command, as it will be used from the command-line.
name = 'timestamp'
# A brief description of the command's purpose, displayed in --help output.
description = 'Rename files with POSIX timestamps to human-readble times.'
# Command-line parameters we support.
optParameters = [
('format', 'f', '%Y-%m-%d %H-%M-%S', 'strftime format.')]
# The default name template to use if no name template is specified via the
# command-line or configuration file.
defaultNameTemplate = string.Template('$time')
# IRenamerCommand
def processArgument(self, arg):
# The extension is not needed as it will be determined from the
# original file name.
name, ext = arg.splitext()
try:
# Try convert the filename to a floating point number.
timestamp = float(name)
except (TypeError, ValueError):
# If it is not a floating point number then we raise an exception
# to stop the process.
raise PluginError('%r is not a valid timestamp' % (name,))
else:
# Convert and format the timestamp according to the "format"
# command-line parameter.
t = time.localtime(timestamp)
return {
'time': time.strftime(self['format'], t)}
|
Installing the plugin¶
Now that we’ve constructed our command we need to make it available to Renamer. This process consists of the following simple steps:
Create a directory for your plugins such as
MyRenamerPlugins
wherever you usually put your source code, beneath this create a directory namedrenamer
and beneath that a directory namedplugins
.Your directory tree should look like:
. |-- MyRenamerPlugins | `-- renamer | | `-- plugins
Add your directory (
MyRenamerPlugins
in the previous step) to sys.path (typically by adding it to the PYTHONPATH environment variable.)Put your plugin source code file (with a
.py
extension) in theMyRenamerPlugins/renamer/plugins
directory. It is important to note that this directory must not be a Python package (i.e. it must not contain__init__.py
) and will be skipped (i.e. no plugins will be loaded) if it is one.You can verify that your plugin is visible by running an interactive Python prompt and doing something similar to:
>>> from renamer.plugins.timestamp import ReadableTimestamps >>>
(This obviously assumes that you used the
ReadableTimestamps
example and stored it in a file calledtimestamp.py
.)If your plugin is installed correctly there should be no errors importing the module.
Using the plugin¶
After your plugin has been installed correctly you can use it:
$ touch 1287758780.4690211.txt
$ rn timestamp 1287758780.4690211.txt
$ ls
2010-10-22 16-46-20.txt
It is possible that you may need to regenerate the Twisted plugin cache if you notice nonsensical errors related to your plugin objects, especially if you’re actively developing a plugin and testing it. Refer to the Twisted documentation regarding plugin caching.