예제 #1
0
def js_product_info():
    """Return JSON-serialized information on the product.

    This will include the product name, version (human-readable and raw
    version information), release status, and the URL to the manual, in a
    form that can be directly embedded into a template's JavaScript section.

    Since the data won't change between calls without performing an upgrade
    and restart, result is cached in the process. Repeated calls will return
    the cached information.

    Returns:
        django.utils.safestring.SafeText:
        The JSON-serialized product information.
    """
    global _product_info_str

    # We're caching the results, since this isn't going to ever change
    # between requests while the process is still running.
    if _product_info_str is None:
        _product_info_str = json_dumps({
            'isRelease': is_release(),
            'manualURL': get_manual_url(),
            'name': settings.PRODUCT_NAME,
            'version': get_version_string(),
            'versionInfo': VERSION[:-1],
        })

    return _product_info_str
예제 #2
0
def version(request):
    return {
        'version': get_version_string(),
        'package_version': get_package_version(),
        'is_release': is_release(),
        'version_raw': VERSION,
        'RB_MANUAL_URL': get_manual_url(),
    }
예제 #3
0
def version(request):
    """Return a dictionary with version information."""
    return {
        'version': get_version_string(),
        'package_version': get_package_version(),
        'is_release': is_release(),
        'version_raw': VERSION,
        'RB_MANUAL_URL': get_manual_url(),
    }
예제 #4
0
def fail_if_missing_dependencies():
    """Exit the process with an error if dependency messages were shown.

    If :py:func:`dependency_error` or :py:func:`dependency_warning` were
    called, this will print some help information with a link to the manual
    and then exit the process.
    """
    if _dependency_warning_count > 0 or _dependency_error_count > 0:
        from reviewboard import get_manual_url

        _dependency_message('Please see %s for help setting up Review Board.' %
                            get_manual_url())

        if _dependency_error_count > 0:
            sys.exit(1)
예제 #5
0
def fail_if_missing_dependencies():
    """Exit the process with an error if dependency messages were shown.

    If :py:func:`dependency_error` or :py:func:`dependency_warning` were
    called, this will print some help information with a link to the manual
    and then exit the process.
    """
    if _dependency_warning_count > 0 or _dependency_error_count > 0:
        from reviewboard import get_manual_url

        _dependency_message('Please see %s for help setting up Review Board.'
                            % get_manual_url())

        if _dependency_error_count > 0:
            sys.exit(1)
예제 #6
0
def version(request):
    """Return a dictionary with version information.

    Args:
        request (django.http.HttpRequest):
            The current HTTP request.

    Returns:
        dict:
        State to add to the context.
    """
    return {
        'version': get_version_string(),
        'package_version': get_package_version(),
        'is_release': is_release(),
        'version_raw': VERSION,
        'RB_MANUAL_URL': get_manual_url(),
    }
예제 #7
0
    def get_extra_context(self, request):
        """Return extra context for the template.

        Args:
            request (django.http.HttpRequest):
                The HTTP request from the client.

        Returns:
            dict:
            Extra context to pass to the template.
        """
        extra_context = cache_memoize(
            'admin-widget-repos-data',
            lambda: self._get_repositories_data(request))
        extra_context['add_repo_docs_url'] = \
            '%sadmin/configuration/repositories/' % get_manual_url()

        return extra_context
예제 #8
0
rbext_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(rbext_dir, 'conf', 'rbext'))

import pkg_resources
from django.utils.encoding import force_str

from reviewboard import get_manual_url
from reviewboard.cmdline.utils.argparsing import (HelpFormatter,
                                                  RBProgVersionAction)
from reviewboard.cmdline.utils.console import init_console

# NOTE: We want to include Django-based modules as late as possible, in order
#       to allow extension-provided settings to apply.

MANUAL_URL = get_manual_url()
EXTENSION_MANUAL_URL = '%sextending/' % MANUAL_URL

console = None


class BaseCommand(object):
    """Base class for a command."""

    #: The name of a command.
    #:
    #: This is what the user will type on the command line after ``rbext``.
    name = None

    #: The summary of the command.
    #:
예제 #9
0
    def _create_extension_py(self, name, package_name, class_name, summary,
                             configurable, has_static_media):
        """Create the content for an extension.py file.

        Args:
            name (unicode):
                The name of the extension.

            package_name (unicode):
                The name of the package.

            class_name (unicode):
                The name of the extension class.

            summary (unicode):
                A summary of the extension.

            configurable (bool):
                Whether the package is set to be configurable.

            has_static_media (bool):
                Whether the package is set to have static media files.

        Returns:
            unicode:
            The resulting content for the file.
        """
        extension_docs_url = '%sextending/extensions/' % get_manual_url()

        static_media_content = """
                # You can create a list of CSS bundles to compile and ship
                # with your extension. These can include both *.css and
                # *.less (http://lesscss.org/) files. See
                # %(static_docs_url)s
                css_bundles = {
                    'my-bundle-name': {
                        'source_filenames': [
                            'css/style.less',
                        ],
                        'apply_to': ['my-view-url-name'],
                    },
                }

                # JavaScript bundles are also supported. These support
                # standard *.js files and *.es6.js files (which allow for
                # writing and transpiling ES6 JavaScript).
                js_bundles = {
                    'my-bundle-name': {
                        'source_filenames': [
                            'js/script.es6.js',
                            'js/another-script.js',
                        ],
                    },
                }
        """ % {
            'static_docs_url': '%sstatic-files/' % extension_docs_url,
        }

        configuration_content = """
                # Default values for any configuration settings for your
                # extension.
                default_settings = {
                    'my_field_1': 'my default value',
                    'my_field_2': False,
                }

                # Set is_configurable and define an admin_urls.py to add
                # a standard configuration page for your extension.
                # See %(configure_docs_url)s
                is_configurable = True
        """ % {
            'configure_docs_url': '%sconfiguration/' % extension_docs_url,
        }

        return '''
            """%(name)s for Review Board."""

            from __future__ import unicode_literals

            from django.utils.translation import ugettext_lazy as _
            from reviewboard.extensions.base import Extension
            from reviewboard.extensions.hooks import TemplateHook


            class %(class_name)s(Extension):
                """Internal description for your extension here."""

                metadata = {
                    'Name': _(%(metadata_name)s),
                    'Summary': _(%(metadata_summary)s),
                }
            %(extra_class_content)s
                def initialize(self):
                    """Initialize the extension."""
                    # Set up any hooks your extension needs here. See
                    # %(hooks_docs_url)s
                    TemplateHook(self,
                                 'before-login-form',
                                 '%(package_name)s/before-login-form.html')
        ''' % {
            'class_name':
            class_name,
            'extra_class_content':
            ''.join(extra_content for extra_content, should_add in (
                (configuration_content, configurable),
                (static_media_content, has_static_media)) if should_add),
            'hooks_docs_url':
            '%s#python-extension-hooks' % extension_docs_url,
            'metadata_name':
            self._sanitize_string_for_python(name),
            'metadata_summary':
            self._sanitize_string_for_python(summary or 'REPLACE ME'),
            'name':
            name,
            'package_name':
            package_name,
        }
예제 #10
0
    def main(self, options):
        """Main function for creating an extension.

        Args:
            options (argparse.Namesapce):
                Options set from the arguments.

        Returns:
            int:
            The comamnd's exit code.
        """
        self._process_options(options)

        name = options.name
        package_name = options.package_name
        summary = options.summary
        description = options.description
        class_name = options.class_name
        configurable = options.enable_configuration
        enable_static_media = options.enable_static_media

        # Create the directory hierarchy.
        root_dir = package_name

        if os.path.exists(root_dir):
            self.error(
                ugettext('There\'s already a directory named "%s". You must '
                         'remove it before you can create a new extension '
                         'there.') % root_dir)

        ext_dir = os.path.join(root_dir, package_name)
        static_dir = os.path.join(ext_dir, 'static')
        templates_dir = os.path.join(ext_dir, 'templates')

        for path in (root_dir, ext_dir):
            os.mkdir(path, 0o755)

        if enable_static_media:
            os.mkdir(static_dir, 0o755)

            for path in ('css', 'js', 'images'):
                os.mkdir(os.path.join(static_dir, path))

        # Create the packaging files.
        self._write_file(
            os.path.join(root_dir, 'README.rst'),
            self._create_readme(name=name,
                                summary=summary,
                                description=description))

        self._write_file(
            os.path.join(root_dir, 'MANIFEST.in'),
            self._create_manifest(static_dir=static_dir,
                                  templates_dir=templates_dir))

        self._write_file(os.path.join(root_dir, 'setup.py'),
                         self._create_setup_py(
                             package_name=package_name,
                             version=options.package_version,
                             summary=summary,
                             author=options.author_name,
                             author_email=options.author_email,
                             class_name=class_name),
                         mode=0o755)

        # Create the extension source files.
        self._write_file(os.path.join(ext_dir, '__init__.py'), '')

        self._write_file(
            os.path.join(ext_dir, 'extension.py'),
            self._create_extension_py(name=name,
                                      package_name=package_name,
                                      class_name=class_name,
                                      summary=summary,
                                      configurable=configurable,
                                      has_static_media=enable_static_media))

        if configurable:
            form_class_name = '%sForm' % class_name

            self._write_file(
                os.path.join(ext_dir, 'admin_urls.py'),
                self._create_admin_urls_py(package_name=package_name,
                                           class_name=class_name,
                                           form_class_name=form_class_name))

            self._write_file(
                os.path.join(ext_dir, 'forms.py'),
                self._create_forms_py(form_class_name=form_class_name))

        # We're done!
        print('Generated a new extension in %s' % os.path.abspath(root_dir))
        print()
        print('For information on writing your extension, see')
        print('%sextending/' % get_manual_url())

        return 0
예제 #11
0
    def _create_extension_py(self, name, package_name, class_name, summary,
                             configurable, has_static_media):
        """Create the content for an extension.py file.

        Args:
            name (unicode):
                The name of the extension.

            package_name (unicode):
                The name of the package.

            class_name (unicode):
                The name of the extension class.

            summary (unicode):
                A summary of the extension.

            configurable (bool):
                Whether the package is set to be configurable.

            has_static_media (bool):
                Whether the package is set to have static media files.

        Returns:
            unicode:
            The resulting content for the file.
        """
        extension_docs_url = '%sextending/extensions/' % get_manual_url()

        static_media_content = """
                # You can create a list of CSS bundles to compile and ship
                # with your extension. These can include both *.css and
                # *.less (http://lesscss.org/) files. See
                # %(static_docs_url)s
                css_bundles = {
                    'my-bundle-name': {
                        'source_filenames': [
                            'css/style.less',
                        ],
                        'apply_to': ['my-view-url-name'],
                    },
                }

                # JavaScript bundles are also supported. These support
                # standard *.js files and *.es6.js files (which allow for
                # writing and transpiling ES6 JavaScript).
                js_bundles = {
                    'my-bundle-name': {
                        'source_filenames': [
                            'js/script.es6.js',
                            'js/another-script.js',
                        ],
                    },
                }
        """ % {
            'static_docs_url': '%sstatic-files/' % extension_docs_url,
        }

        configuration_content = """
                # Default values for any configuration settings for your
                # extension.
                default_settings = {
                    'my_field_1': 'my default value',
                    'my_field_2': False,
                }

                # Set is_configurable and define an admin_urls.py to add
                # a standard configuration page for your extension.
                # See %(configure_docs_url)s
                is_configurable = True
        """ % {
            'configure_docs_url': '%sconfiguration/' % extension_docs_url,
        }

        return '''
            """%(name)s for Review Board."""

            from __future__ import unicode_literals

            from django.utils.translation import ugettext_lazy as _
            from reviewboard.extensions.base import Extension
            from reviewboard.extensions.hooks import TemplateHook


            class %(class_name)s(Extension):
                """Internal description for your extension here."""

                metadata = {
                    'Name': _(%(metadata_name)s),
                    'Summary': _(%(metadata_summary)s),
                }
            %(extra_class_content)s
                def initialize(self):
                    """Initialize the extension."""
                    # Set up any hooks your extension needs here. See
                    # %(hooks_docs_url)s
                    TemplateHook(self,
                                 'before-login-form',
                                 '%(package_name)s/before-login-form.html')
        ''' % {
            'class_name': class_name,
            'extra_class_content': ''.join(
                extra_content
                for extra_content, should_add in (
                    (configuration_content, configurable),
                    (static_media_content, has_static_media))
                if should_add
            ),
            'hooks_docs_url': '%s#python-extension-hooks' % extension_docs_url,
            'metadata_name': self._sanitize_string_for_python(name),
            'metadata_summary': self._sanitize_string_for_python(
                summary or 'REPLACE ME'),
            'name': name,
            'package_name': package_name,
        }
예제 #12
0
    def main(self, options):
        """Main function for creating an extension.

        Args:
            options (argparse.Namesapce):
                Options set from the arguments.

        Returns:
            int:
            The comamnd's exit code.
        """
        self._process_options(options)

        name = options.name
        package_name = options.package_name
        summary = options.summary
        description = options.description
        class_name = options.class_name
        configurable = options.enable_configuration
        enable_static_media = options.enable_static_media

        # Create the directory hierarchy.
        root_dir = package_name

        if os.path.exists(root_dir):
            self.error(
                ugettext('There\'s already a directory named "%s". You must '
                         'remove it before you can create a new extension '
                         'there.')
                % root_dir)

        ext_dir = os.path.join(root_dir, package_name)
        static_dir = os.path.join(ext_dir, 'static')
        templates_dir = os.path.join(ext_dir, 'templates')

        for path in (root_dir, ext_dir):
            os.mkdir(path, 0o755)

        if enable_static_media:
            os.mkdir(static_dir, 0o755)

            for path in ('css', 'js', 'images'):
                os.mkdir(os.path.join(static_dir, path))

        # Create the packaging files.
        self._write_file(
            os.path.join(root_dir, 'README.rst'),
            self._create_readme(name=name,
                                summary=summary,
                                description=description))

        self._write_file(
            os.path.join(root_dir, 'MANIFEST.in'),
            self._create_manifest(static_dir=static_dir,
                                  templates_dir=templates_dir))

        self._write_file(
            os.path.join(root_dir, 'setup.py'),
            self._create_setup_py(package_name=package_name,
                                  version=options.package_version,
                                  summary=summary,
                                  author=options.author_name,
                                  author_email=options.author_email,
                                  class_name=class_name),
            mode=0o755)

        # Create the extension source files.
        self._write_file(os.path.join(ext_dir, '__init__.py'), '')

        self._write_file(
            os.path.join(ext_dir, 'extension.py'),
            self._create_extension_py(
                name=name,
                package_name=package_name,
                class_name=class_name,
                summary=summary,
                configurable=configurable,
                has_static_media=enable_static_media))

        if configurable:
            form_class_name = '%sForm' % class_name

            self._write_file(
                os.path.join(ext_dir, 'admin_urls.py'),
                self._create_admin_urls_py(
                    package_name=package_name,
                    class_name=class_name,
                    form_class_name=form_class_name))

            self._write_file(
                os.path.join(ext_dir, 'forms.py'),
                self._create_forms_py(form_class_name=form_class_name))

        # We're done!
        print('Generated a new extension in %s' % os.path.abspath(root_dir))
        print()
        print('For information on writing your extension, see')
        print('%sextending/' % get_manual_url())

        return 0