Index: setup.cfg
===================================================================
--- setup.cfg	(revision 14244)
+++ setup.cfg	(working copy)
@@ -1,3 +1,27 @@
 [egg_info]
 tag_build = dev
 tag_svn_revision = true
+
+[extract_messages]
+add_comments = TRANSLATOR:
+output_file = tracvote/locale/messages.pot
+keywords = _ ngettext:1,2 N_ tag_ cleandoc_ Option:4 BoolOption:4 IntOption:4 ChoiceOption:4 ListOption:6 ExtensionOption:5 ConfigSection:2
+width = 72
+
+[init_catalog]
+input_file = tracvote/locale/messages.pot
+output_dir = tracvote/locale
+domain = tracvote
+
+[compile_catalog]
+directory = tracvote/locale
+domain = tracvote
+
+[update_catalog]
+input_file = tracvote/locale/messages.pot
+output_dir = tracvote/locale
+domain = tracvote
+
+[check_catalog]
+input_dir = tracvote/locale
+domain = tracvote
Index: setup.py
===================================================================
--- setup.py	(revision 14244)
+++ setup.py	(working copy)
@@ -9,12 +9,27 @@
 
 from setuptools import find_packages, setup
 
+extra = {}
+try:
+    from trac.util.dist import get_l10n_cmdclass
+    cmdclass = get_l10n_cmdclass()
+    if cmdclass:
+        extra['cmdclass'] = cmdclass
+        extractors = [
+            ('**.py', 'trac.dist:extract_python', None)
+        ]
+        extra['message_extractors'] = {
+            'tracvote': extractors,
+        }
+except ImportError:
+    pass
+
 setup(
     name='TracVote',
     version='0.2',
     packages=find_packages(exclude=['*.tests']),
     package_data={
-        'tracvote': ['htdocs/*.*', 'htdocs/js/*.js', 'htdocs/css/*.css']
+        'tracvote': ['htdocs/*.*', 'htdocs/js/*.js', 'htdocs/css/*.css', 'locale/*/LC_MESSAGES/*.mo']
     },
     author='Alec Thomas',
     maintainer = 'Ryan J Ollos',
@@ -28,4 +43,5 @@
     url='http://trac-hacks.org/wiki/VotePlugin',
     description='A plugin for voting on Trac resources.',
     entry_points = {'trac.plugins': ['tracvote = tracvote']},
+    **extra
 )
Index: tracvote/__init__.py
===================================================================
--- tracvote/__init__.py	(revision 14244)
+++ tracvote/__init__.py	(working copy)
@@ -31,11 +31,13 @@
 from trac.util.compat import partial
 from trac.util.datefmt import format_datetime, to_datetime, utc
 from trac.util.text import to_unicode
+from trac.util.translation  import domain_functions
 from trac.web.api import IRequestFilter, IRequestHandler, Href
 from trac.web.chrome import Chrome, ITemplateProvider, add_ctxtnav
 from trac.web.chrome import add_notice, add_script, add_stylesheet
 from trac.wiki.api import IWikiChangeListener, IWikiMacroProvider, parse_args
 
+_, add_domain = domain_functions('tracvote', ('_', 'add_domain'))
 
 # Provide `resource_exists`, that has been backported to Trac 0.11.8 only.
 try:
@@ -147,6 +149,11 @@
 class VoteSystem(Component):
     """Allow up- and down-voting on Trac resources."""
 
+    def __init__(self):
+        """Set up translation domain"""
+        locale_dir = resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
+
     implements(IEnvironmentSetupParticipant,
                IPermissionRequestor,
                IRequestFilter,
@@ -189,7 +196,8 @@
                 (('vote_version', str(schema_version)),)))
 
     voteable_paths = ListOption('vote', 'paths', '/ticket*,/wiki*',
-        doc='List of URL paths to allow voting on. Globs are supported.')
+        doc=_('List of URL paths to allow voting on. Globs are supported.'),
+        doc_domain='tracvote')
 
     ### Public methods
 
@@ -409,10 +417,10 @@
         msg = ''
         if req.args.get('token') != req.form_token:
             if self.env.secure_cookies and req.scheme == 'http':
-                msg = ("Secure cookies are enabled, you must use https for "
+                msg = _("Secure cookies are enabled, you must use https for "
                        "your requests.")
             else:
-                msg = ("Do you have cookies enabled?")
+                msg = _("Do you have cookies enabled?")
             raise TracError(msg)
         else:
             if old_vote == vote:
@@ -491,11 +499,11 @@
 
     def get_macro_description(self, name):
         if name == 'LastVoted':
-            return "Show most recently voted resources."
+            return _("Show most recently voted resources.")
         elif name == 'TopVoted':
-            return "Show listing of voted resources ordered by total score."
+            return _("Show listing of voted resources ordered by total score.")
         elif name == 'VoteList':
-            return "Show listing of most recent votes for a resource."
+            return _("Show listing of most recent votes for a resource.")
 
     def expand_macro(self, formatter, name, content):
         env = formatter.env
@@ -519,9 +527,9 @@
             for i in self.get_votes(req, top=top):
                 resource = Resource(i[0], i[1])
                 # Anotate who and when.
-                voted = ('by %s at %s'
-                         % (format_author(i[3]),
-                            format_datetime(to_datetime(i[4]))))
+                voted = (_('by %(author)s at %(time)s',
+                            author=format_author(i[3]),
+                            time=format_datetime(to_datetime(i[4]))))
                 lst(tag.li(tag.a(
                     get_resource_description(env, resource, compact and
                                              'compact' or 'default'),
@@ -568,8 +576,8 @@
             return True
         elif self.get_schema_version(db) > self.schema_version:
             raise TracError(
-                "A newer version of VotePlugin has been installed before, "
-                "but downgrading is unsupported.")
+                _("A newer version of VotePlugin has been installed before, "
+                "but downgrading is unsupported."))
         return False
 
     def upgrade_environment(self, db):
@@ -602,9 +610,9 @@
                                           locals(), [name])
                     script = getattr(upgrades, name)
                 except AttributeError:
-                    raise TracError("No upgrade module for version "
+                    raise TracError(_("No upgrade module for version "
                                     "%(num)i (%(version)s.py)",
-                                    num=i, version=name)
+                                    num=i, version=name))
                 script.do_upgrade(self.env, i, cursor)
         else:
             # Obsolete call handled gracefully.
@@ -647,24 +655,24 @@
         resource = resource_from_path(self.env, path)
         vote = resource and self.get_vote(req, resource) or 0
         up = tag.img(src=req.href.chrome('vote/' + self.image_map[vote][0]),
-                     alt='Up-vote')
+                     alt=_('Up-vote'))
         down = tag.img(src=req.href.chrome('vote/' + self.image_map[vote][1]),
-                       alt='Down-vote')
+                       alt=_('Down-vote'))
         if not 'action' in req.args and 'VOTE_MODIFY' in req.perm and \
                 get_reporter_id(req) != 'anonymous':
             down = tag.a(down, id='downvote',
                          href=req.href.vote('down', path,
                                             token=req.form_token),
-                         title='Down-vote')
+                         title=_('Down-vote'))
             up = tag.a(up, id='upvote',
                        href=req.href.vote('up', path, token=req.form_token),
-                       title='Up-vote')
+                       title=_('Up-vote'))
             add_script(req, 'vote/js/tracvote.js')
             shown = req.session.get('shown_vote_message')
             if not shown:
-                add_notice(req, 'You can vote for resources on this Trac '
+                add_notice(req, _('You can vote for resources on this Trac '
                            'install by clicking the up-vote/down-vote arrows '
-                           'in the context navigation bar.')
+                           'in the context navigation bar.'))
                 req.session['shown_vote_message'] = '1'
         body, title = self.format_votes(resource)
         votes = tag.span(body, id='votes')
@@ -683,7 +691,7 @@
             count_detail = ' (%s)' % ', '.join(count_detail)
         else:
             count_detail = ''
-        return ('%+i' % total, 'Vote count%s' % count_detail)
+        return ('%+i' % total, _('Vote count%s') % count_detail)
 
     def _get_tables(self, dburi, cursor):
         """Code from TracMigratePlugin by Jun Omae (see tracmigrate.admin)."""
@@ -703,7 +711,7 @@
         elif dburi.startswith('mysql:'):
             sql = "SHOW TABLES"
         else:
-            raise TracError('Unsupported database type "%s"'
+            raise TracError(_('Unsupported database type "%s"')
                             % dburi.split(':')[0])
         cursor.execute(sql)
         return sorted([row[0] for row in cursor])
Index: tracvote/locale/de/LC_MESSAGES/tracvote.po
===================================================================
--- tracvote/locale/de/LC_MESSAGES/tracvote.po	(revision 0)
+++ tracvote/locale/de/LC_MESSAGES/tracvote.po	(working copy)
@@ -0,0 +1,85 @@
+# German translations for PROJECT.
+# Copyright (C) 2014 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2014-11-09 15:35+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: de <LL@li.org>\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
+#: tracvote/__init__.py:420
+msgid "Secure cookies are enabled, you must use https for your requests."
+msgstr "Sichere Cookies angeschaltet. Sie müssen HTTPS für Ihre Anfrage verwenden."
+
+#: tracvote/__init__.py:423
+msgid "Do you have cookies enabled?"
+msgstr "Haben Sie Cookies aktiviert?"
+
+#: tracvote/__init__.py:502
+msgid "Show most recently voted resources."
+msgstr "Seiten mit aktuellesten Abstimmungen anzeigen."
+
+#: tracvote/__init__.py:504
+msgid "Show listing of voted resources ordered by total score."
+msgstr ""
+"Eine nach Gesamtpunktzahl geordnete Liste aller Seiten mit Abstimmungen "
+"anzeigen."
+
+#: tracvote/__init__.py:506
+msgid "Show listing of most recent votes for a resource."
+msgstr "Liste mit aktuellsten Abstimmungen für eine Seite anzeigen."
+
+#: tracvote/__init__.py:532
+#, python-format
+msgid "by %(author)s at %(time)s"
+msgstr "von %(author)s um %(time)s"
+
+#: tracvote/__init__.py:579
+msgid ""
+"A newer version of VotePlugin has been installed before, but downgrading "
+"is unsupported."
+msgstr ""
+"Eine neuere Version des VotePlugin wwar vorher installiert, aber ein "
+"Downgrade wird nicht unterstützt."
+
+#: tracvote/__init__.py:613
+#, python-format
+msgid "No upgrade module for version %(num)i (%(version)s.py)"
+msgstr "Kein Aktualisierungsmodul für Version %(num)i (%(version)s.py)"
+
+#: tracvote/__init__.py:658 tracvote/__init__.py:669
+msgid "Up-vote"
+msgstr "Dafür stimmen"
+
+#: tracvote/__init__.py:660 tracvote/__init__.py:666
+msgid "Down-vote"
+msgstr "Dagegen stimmen"
+
+#: tracvote/__init__.py:673
+msgid ""
+"You can vote for resources on this Trac install by clicking the up-vote"
+"/down-vote arrows in the context navigation bar."
+msgstr ""
+"Sie können über Seiten in dieser Trac-Installation durch Klicken auf die "
+"Dafür/Dagegen-Pfeile in der Kontextnavigationszeile abstimmen."
+
+#: tracvote/__init__.py:694
+#, python-format
+msgid "Vote count%s"
+msgstr "Stimmenzahl%s"
+
+#: tracvote/__init__.py:714
+#, python-format
+msgid "Unsupported database type \"%s\""
+msgstr "Nicht unterstützter Datenbanktyp \"%s\""
+
Index: tracvote/locale/messages.pot
===================================================================
--- tracvote/locale/messages.pot	(revision 0)
+++ tracvote/locale/messages.pot	(working copy)
@@ -0,0 +1,80 @@
+# Translations template for TracVote.
+# Copyright (C) 2014 ORGANIZATION
+# This file is distributed under the same license as the TracVote
+# project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: TracVote 0.2\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2014-11-09 15:35+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
+#: tracvote/__init__.py:420
+msgid "Secure cookies are enabled, you must use https for your requests."
+msgstr ""
+
+#: tracvote/__init__.py:423
+msgid "Do you have cookies enabled?"
+msgstr ""
+
+#: tracvote/__init__.py:502
+msgid "Show most recently voted resources."
+msgstr ""
+
+#: tracvote/__init__.py:504
+msgid "Show listing of voted resources ordered by total score."
+msgstr ""
+
+#: tracvote/__init__.py:506
+msgid "Show listing of most recent votes for a resource."
+msgstr ""
+
+#: tracvote/__init__.py:532
+#, python-format
+msgid "by %(author)s at %(time)s"
+msgstr ""
+
+#: tracvote/__init__.py:579
+msgid ""
+"A newer version of VotePlugin has been installed before, but "
+"downgrading is unsupported."
+msgstr ""
+
+#: tracvote/__init__.py:613
+#, python-format
+msgid "No upgrade module for version %(num)i (%(version)s.py)"
+msgstr ""
+
+#: tracvote/__init__.py:658 tracvote/__init__.py:669
+msgid "Up-vote"
+msgstr ""
+
+#: tracvote/__init__.py:660 tracvote/__init__.py:666
+msgid "Down-vote"
+msgstr ""
+
+#: tracvote/__init__.py:673
+msgid ""
+"You can vote for resources on this Trac install by clicking the up-"
+"vote/down-vote arrows in the context navigation bar."
+msgstr ""
+
+#: tracvote/__init__.py:694
+#, python-format
+msgid "Vote count%s"
+msgstr ""
+
+#: tracvote/__init__.py:714
+#, python-format
+msgid "Unsupported database type \"%s\""
+msgstr ""
+
Index: .
===================================================================
--- .	(revision 14244)
+++ .	(working copy)

Property changes on: .
___________________________________________________________________
Modified: svn:ignore
## -1,3 +1,5 ##
 .project
 .pydevproject
 *.egg-info
+dist
+build
