def initialize(): """Begins initialization of Review Board. This sets up the logging, generates cache serial numbers, and then fires an initializing signal that other parts of the codebase can connect to. This must be called for such features as e-mail notification to work. """ import logging import os from django.conf import settings from djblets.util.misc import generate_cache_serials from djblets import log from reviewboard import signals from reviewboard.extensions.base import get_extension_manager # This overrides a default django templatetag (url), and we want to make # sure it will always get loaded in every python instance. import reviewboard.site.templatetags # Set up logging. log.init_logging() if settings.DEBUG: logging.debug("Log file for Review Board v%s (PID %s)" % (get_version_string(), os.getpid())) # Generate cache serials generate_cache_serials() # Load all extensions get_extension_manager().load() signals.initializing.send(sender=None)
def initialize(): """Begins initialization of Review Board. This sets up the logging, generates cache serial numbers, and then fires an initializing signal that other parts of the codebase can connect to. This must be called for such features as e-mail notification to work. """ import logging import os import settings_local # Set RBSITE_PYTHON_PATH to the path we need for any RB-bundled # scripts we may call. os.environ['RBSITE_PYTHONPATH'] = \ os.path.dirname(settings_local.__file__) from django.conf import settings from django.db import DatabaseError from djblets import log from djblets.cache.serials import generate_ajax_serial from reviewboard import signals from reviewboard.admin.siteconfig import load_site_config from reviewboard.extensions.base import get_extension_manager # This overrides a default django templatetag (url), and we want to make # sure it will always get loaded in every python instance. import reviewboard.site.templatetags is_running_test = getattr(settings, 'RUNNING_TEST', False) if not is_running_test: # Set up logging. log.init_logging() load_site_config() if not is_running_test: if settings.DEBUG: logging.debug("Log file for Review Board v%s (PID %s)" % (get_version_string(), os.getpid())) # Generate the AJAX serial, used for AJAX request caching. generate_ajax_serial() # Load all extensions try: get_extension_manager().load() except DatabaseError: # This database is from a time before extensions, so don't attempt # to load any extensions yet. pass signals.initializing.send(sender=None)
def initialize(): """Begins initialization of Review Board. This sets up the logging, generates cache serial numbers, and then fires an initializing signal that other parts of the codebase can connect to. This must be called for such features as e-mail notification to work. """ import logging import os import sys import settings_local # Set PYTHONPATH to match the directory of settings, for subprocesses. os.environ['PYTHONPATH'] = '%s:%s' % \ (os.path.dirname(settings_local.__file__), os.environ.get('PYTHONPATH', '')) from django.conf import settings from django.db import DatabaseError from djblets.util.misc import generate_ajax_serial from djblets import log from reviewboard import signals from reviewboard.extensions.base import get_extension_manager # This overrides a default django templatetag (url), and we want to make # sure it will always get loaded in every python instance. import reviewboard.site.templatetags # Set up logging. log.init_logging() if settings.DEBUG: logging.debug("Log file for Review Board v%s (PID %s)" % (get_version_string(), os.getpid())) # Generate the AJAX serial, used for AJAX request caching. generate_ajax_serial() # Load all extensions try: get_extension_manager().load() except DatabaseError: # This database is from a time before extensions, so don't attempt to # load any extensions yet. pass signals.initializing.send(sender=None)
def include_enabled_extensions(settings): """ This adds enabled extensions to the INSTALLED_APPS cache so that operations like syncdb and evolve will take extensions into consideration. """ # Some of our checks require access to django.conf.settings, so # tell Django about our settings. # # This must go before the imports. setup_environ(settings) from django.db.models.loading import load_app from django.db import DatabaseError from reviewboard.extensions.base import get_extension_manager try: manager = get_extension_manager() manager.load() except DatabaseError: # This database is from a time before extensions, so don't attempt to # load any extensions yet. return for extension in manager.get_enabled_extensions(): load_app(extension.info.app_name)
def create(self, request, *args, **kwargs): ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') testing = ext.get_settings('autoland_testing', False) if not testing and not request.user.has_perm( 'mozreview.add_autolandeventlogentry'): return PERMISSION_DENIED try: fields = json.loads(request.body) for field_name in self.fields: assert (type( fields[field_name]) == self.fields[field_name]['type']) except (ValueError, IndexError, KeyError, AssertionError) as e: return INVALID_FORM_DATA, { 'error': '%s' % e, } try: autoland_request = AutolandRequest.objects.get( pk=fields['request_id']) except AutolandRequest.DoesNotExist: return DOES_NOT_EXIST rr = ReviewRequest.objects.get(pk=autoland_request.review_request_id) if fields['landed']: autoland_request.repository_revision = fields['result'] autoland_request.save() # If we've landed to the "inbound" repository, we'll close the # review request automatically. landing_repo = rr.repository.extra_data.get( 'landing_repository_url') if autoland_request.repository_url == landing_repo: rr.close(ReviewRequest.SUBMITTED) AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.SERVED, details=fields['result']) elif not fields.get('error_msg') and fields.get('result'): AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.REQUESTED, details=fields['result']) else: AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.PROBLEM, error_msg=fields['error_msg']) lock_id = get_autoland_lock_id(rr.id, autoland_request.repository_url, autoland_request.push_revision) release_lock(lock_id) return 200, {}
def handle(self, *args, **options): """Handle the command. Args: *args (tuple): The name of the check to resolve. **options (dict, unused): Options parsed on the command line. For this command, no options are available. Raises: django.core.management.CommandError: There was an error with arguments or enabling the extension. """ extension_ids = options['extension_ids'] if not extension_ids: raise CommandError( _('You must specify an extension ID to disable.')) extension_mgr = get_extension_manager() for extension_id in extension_ids: try: extension_mgr.disable_extension(extension_id) except Exception as e: raise CommandError( _('Unexpected error disabling extension %s: %s') % (extension_id, e))
def create(self, request, review_request_id, *args, **kwargs): try: review_request = review_request_resource.get_object( request, *args, review_request_id=review_request_id, **kwargs) except ObjectDoesNotExist: return DOES_NOT_EXIST em = get_extension_manager() ext = em.get_enabled_extension('buildbotstatus.extension.Buildbotstatus') url = ext.settings['buildbot_url'] if not url: raise Exception('No Buildbot URL configured') commit_id = review_request.commit_id statuses = find_builds(url, commit_id) for status in statuses: status['url'] = 'http://%s/builders/%s/builds/%s' % \ (url, status['builderName'], status['number']) status['cssClass'] = 'buildbot-failure' status['result'] = ' '.join(status['text']) warnings = int(status.get('warnings-count', 0)) if warnings > 0: status['cssClass'] = 'buildbot-warning' status['result'] = '%s warnings' % warnings elif 'success' in status['result']: status['cssClass'] = 'buildbot-success' return 201, { self.item_result_key: json.dumps(statuses), }
def report(request, template_name='reviews/dashboard.html'): report_name = request.GET.get('name', None) if not report_name: raise Http404 # Check if its a configured report in admin pages from reviewboard.extensions.base import get_extension_manager from rbcustomreports.extension import CustomReportsExtension extension_manager = get_extension_manager() extension = extension_manager.get_enabled_extension( CustomReportsExtension.id) if report_name not in extension.settings['selected_reports']: raise Http404 report_title = reports[report_name]['title'] if not report_title: raise Http404 extra_context = {} rb_object = request.GET.get('object', None) if rb_object: extra_context['rb_object'] = rb_object grid = reports[report_name]['data_class'](request, title=report_title, extra_context=extra_context) return grid.render_to_response(template_name, extra_context={ 'sidebar_hooks': DashboardHook.hooks, })
def configure_extension(request, ext_class, form_class, template_name='extensions/configure_extension.html'): return djblets_ext_views.configure_extension(request, ext_class, form_class, get_extension_manager(), template_name)
def broadcast_message(context): from rbbroadcastmessage.extension import BroadcastMessageExtension extension_manager = get_extension_manager() extension = extension_manager.get_enabled_extension( BroadcastMessageExtension.id) if extension.settings.has_key('broadcast_message'): return extension.settings['broadcast_message'] else: return ""
def refresh_tools_view(self, request, template_name="refresh.html"): extension_manager = get_extension_manager() extension = extension_manager.get_enabled_extension( ReviewBotExtension.id) Tool.objects.all().update(in_last_update=False) extension.send_refresh_tools() return render_to_response( template_name, RequestContext(request, {}, current_app=self.admin_site.name))
def get_extension_manager(self): """Return the extension manager used for these extensions. Subclasses don't need to override this unless they're doing something highly specialized. Returns: djblets.extensions.manager.ExtensionManager: The extension manager used for the unit tests. """ return get_extension_manager()
def refresh_tools_view(self, request, template_name="refresh.html"): extension_manager = get_extension_manager() extension = extension_manager.get_enabled_extension( ReviewBotExtension.id) ReviewBotTool.objects.all().update(in_last_update=False) extension.send_refresh_tools() return render_to_response( template_name, RequestContext(request, {}, current_app=self.admin_site.name))
def create(self, request, *args, **kwargs): ext = get_extension_manager().get_enabled_extension("mozreview.extension.MozReviewExtension") testing = ext.get_settings("autoland_testing", False) if not testing and not request.user.has_perm("mozreview.add_autolandeventlogentry"): return PERMISSION_DENIED try: fields = json.loads(request.body) for field_name in self.fields: assert type(fields[field_name]) == self.fields[field_name]["type"] except (ValueError, IndexError, KeyError, AssertionError) as e: return INVALID_FORM_DATA, {"error": "%s" % e} try: autoland_request = AutolandRequest.objects.get(pk=fields["request_id"]) except AutolandRequest.DoesNotExist: return DOES_NOT_EXIST rr = ReviewRequest.objects.get(pk=autoland_request.review_request_id) if fields["landed"]: autoland_request.repository_revision = fields["result"] autoland_request.save() # If we've landed to the "inbound" repository, we'll close the # review request automatically. landing_repo = rr.repository.extra_data.get("landing_repository_url") if autoland_request.repository_url == landing_repo: rr.close(ReviewRequest.SUBMITTED) AutolandEventLogEntry.objects.create( autoland_request_id=fields["request_id"], status=AutolandEventLogEntry.SERVED, details=fields["result"] ) elif not fields.get("error_msg") and fields.get("result"): AutolandEventLogEntry.objects.create( autoland_request_id=fields["request_id"], status=AutolandEventLogEntry.REQUESTED, details=fields["result"], ) else: AutolandEventLogEntry.objects.create( autoland_request_id=fields["request_id"], status=AutolandEventLogEntry.PROBLEM, error_msg=fields["error_msg"], ) lock_id = get_autoland_lock_id(rr.id, autoland_request.repository_url, autoland_request.push_revision) release_lock(lock_id) return 200, {}
def create(self, request, *args, **kwargs): ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') testing = ext.settings.get('autoland_testing', False) if not testing and not request.user.has_perm( 'mozreview.add_autolandeventlogentry'): return PERMISSION_DENIED try: fields = json.loads(request.body) landed = fields['landed'] # result and error_msg are mutually exclusive filtered_field = 'error_msg' if landed else 'result' mandatory_fields = [f for f in self.fields if f != filtered_field] for field_name in mandatory_fields: assert type(fields[field_name]) == self.fields[field_name]['type'] except (ValueError, IndexError, AssertionError) as e: return INVALID_FORM_DATA, { 'error': e, } try: AutolandRequest.objects.get(pk=fields['request_id']) except AutolandRequest.DoesNotExist: return DOES_NOT_EXIST if landed: autoland_request = AutolandRequest.objects.filter(pk=fields['request_id']) autoland_request.update(repository_revision=fields['result']) assert len(autoland_request) == 1 # If we've landed to the "inbound" repository, we'll close the # review request automatically. rr = ReviewRequest.objects.get(pk=autoland_request[0].review_request_id) landing_repo = rr.repository.extra_data.get('landing_repository_url') if autoland_request[0].repository_url == landing_repo: rr.close(ReviewRequest.SUBMITTED) AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.SERVED, details=fields['result']) else: AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.PROBLEM, error_msg=fields['error_msg'] ) return 200, {}
def create(self, request, *args, **kwargs): ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') testing = ext.settings.get('autoland_testing', False) if not testing and not request.user.has_perm( 'mozreview.add_autolandeventlogentry'): return PERMISSION_DENIED try: fields = json.loads(request.body) landed = fields['landed'] for field_name in fields: assert type(fields[field_name]) == self.fields[field_name]['type'] except (ValueError, IndexError, AssertionError) as e: return INVALID_FORM_DATA, { 'error': e, } try: ImportPullRequestRequest.objects.get(pk=fields['request_id']) except ImportPullRequestRequest.DoesNotExist: return DOES_NOT_EXIST if landed: # Autoland gives us a review request url, we need to extract the id try: review_request_id = int(fields['result'].split('/')[-1]) except ValueError as e: return INVALID_FORM_DATA, {'error': e} ImportPullRequestRequest.objects.filter( pk=fields['request_id']).update( review_request_id=review_request_id, bugid=fields['bugid']) AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.SERVED, details=fields['result']) else: # We need to store the bugid even if the import failed so we can # use that same bug for later imports of this pullrequest. ImportPullRequestRequest.objects.filter( pk=fields['request_id']).update(bugid=fields['bugid']) AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.PROBLEM, error_msg=fields['error_msg'] ) return 200, {}
def handle(self, *args, **options): if len(args) != 1: raise CommandError( _('You must specify an extension ID to disable.')) extension_id = args[0] extension_mgr = get_extension_manager() try: extension_mgr.disable_extension(extension_id) except Exception as e: raise CommandError( _('Unexpected error disabling extension: %s') % e)
def handle(self, *args, **options): if len(args) != 1: raise CommandError( _('You must specify an extension ID to disable.')) extension_id = args[0] extension_mgr = get_extension_manager() try: extension_mgr.disable_extension(extension_id) except Exception as e: raise CommandError(_('Unexpected error disabling extension: %s') % e)
def import_pullrequest(request, user, repo, pullrequest): ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') enabled = ext.get_settings('autoland_import_pullrequest_ui_enabled', False) if not enabled: return HttpResponseForbidden('Importing pullrequests is disabled') trigger_url = import_pullrequest_trigger_resource.get_uri(request) template = get_template('mozreview/import-pullrequest.html') return HttpResponse(template.render(Context({ 'request': request, 'user': user, 'repo': repo, 'pullrequest': pullrequest, 'trigger_url': trigger_url, })))
def handle(self, *args, **options): if len(args) != 1: raise CommandError( _('You must specify an extension ID to enable.')) extension_id = args[0] extension_mgr = get_extension_manager() try: extension_mgr.enable_extension(extension_id) except InvalidExtensionError: raise CommandError(_('%s is not a valid extension ID.') % extension_id) except EnablingExtensionError as e: raise CommandError(_('Error enabling extension: %s\n\n%s') % (e.message, e.load_error)) except Exception as e: raise CommandError(_('Unexpected error enabling extension: %s') % e)
def include_enabled_extensions(settings): """ This adds enabled extensions to the INSTALLED_APPS cache so that operations like syncdb and evolve will take extensions into consideration. """ from django.db.models.loading import load_app from django.db import DatabaseError from reviewboard.extensions.base import get_extension_manager try: manager = get_extension_manager() except DatabaseError: # This database is from a time before extensions, so don't attempt to # load any extensions yet. return for extension in manager.get_enabled_extensions(): load_app(extension.info.app_name)
def handle(self, *args, **options): if len(args) != 1: raise CommandError( _('You must specify an extension ID to enable.')) extension_id = args[0] extension_mgr = get_extension_manager() try: extension_mgr.enable_extension(extension_id) except InvalidExtensionError: raise CommandError( _('%s is not a valid extension ID.') % extension_id) except EnablingExtensionError as e: raise CommandError( _('Error enabling extension: %s\n\n%s') % (e.message, e.load_error)) except Exception as e: raise CommandError( _('Unexpected error enabling extension: %s') % e)
def handle(self, *args, **options): """Handle the command. Args: *args (tuple): The name of the check to resolve. **options (dict, unused): Options parsed on the command line. For this command, no options are available. Raises: django.core.management.CommandError: There was an error with arguments or disabling the extension. """ extension_ids = options['extension_ids'] if not extension_ids: raise CommandError( _('You must specify an extension ID to enable.')) extension_mgr = get_extension_manager() for extension_id in extension_ids: try: extension_mgr.enable_extension(extension_id) except InvalidExtensionError: raise CommandError( _('%s is not a valid extension ID.') % extension_id) except EnablingExtensionError as e: raise CommandError( _('Error enabling extension: %(message)s\n\n%(error)s') % { 'message': e.message, 'error': e.load_error, }) except Exception as e: raise CommandError( _('Unexpected error enabling extension %s: %s') % (extension_id, e))
def get_ldap_connection(): """Return an ldap connection. `None` will be returned if a connection cannot be made for any reason. """ ext = get_extension_manager().get_enabled_extension("mozreview.extension.MozReviewExtension") url = ext.settings.get("ldap_url") user = ext.settings.get("ldap_user") password = ext.settings.get("ldap_password") if any([not url, not user, not password]): logging.error("MozReview ldap support configured incorrectly.") return None try: c = ldap.initialize(url) c.simple_bind_s(user, password) except ldap.LDAPError as e: logging.error("Failed to connect to ldap: %s" % e) return None return c
def create(self, request, *args, **kwargs): ext = get_extension_manager().get_enabled_extension("mozreview.extension.MozReviewExtension") testing = ext.settings.get("autoland_testing", False) if not testing and not request.user.has_perm("mozreview.add_autolandeventlogentry"): return PERMISSION_DENIED try: fields = json.loads(request.body) landed = fields["landed"] # result and error_msg are mutually exclusive filtered_field = "error_msg" if landed else "result" mandatory_fields = [f for f in self.fields if f != filtered_field] for field_name in mandatory_fields: assert type(fields[field_name]) == self.fields[field_name]["type"] except (ValueError, IndexError, AssertionError) as e: return INVALID_FORM_DATA, {"error": e} try: AutolandRequest.objects.get(pk=fields["request_id"]) except AutolandRequest.DoesNotExist: return DOES_NOT_EXIST if landed: AutolandRequest.objects.filter(pk=fields["request_id"]).update(repository_revision=fields["result"]) AutolandEventLogEntry.objects.create( autoland_request_id=fields["request_id"], status=AutolandEventLogEntry.SERVED, details=fields["result"] ) else: AutolandEventLogEntry.objects.create( autoland_request_id=fields["request_id"], status=AutolandEventLogEntry.PROBLEM, error_msg=fields["error_msg"], ) return 200, {}
def get_ldap_connection(): """Return an ldap connection. `None` will be returned if a connection cannot be made for any reason. """ ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') url = ext.get_settings('ldap_url') user = ext.get_settings('ldap_user') password = ext.get_settings('ldap_password') if any([not url, not user, not password]): logger.error("MozReview ldap support configured incorrectly.") return None try: c = ldap.initialize(url) c.simple_bind_s(user, password) except ldap.LDAPError as e: logger.error('Failed to connect to ldap: %s' % e) return None return c
def update(self, *args, **kwargs): pass def has_modify_permissions(self, request, extension, *args, **kwargs): """Return whether the user has access to modify this extension. Args: request (django.http.HttpRequest): The request. extension (reviewboard.extensions.base.Extension): The extension being modified. *args (tuple, unused): Additional positional arguments. **kwargs (dict, unused): Additional keyword arguments. Returns: bool: True, always. Individual permissions checks will be done via the :py:func:`djblets.webapi.decorators.webapi_permission_required` decorator. """ return True extension_resource = ExtensionResource(get_extension_manager())
from djblets.webapi.decorators import (webapi_login_required, webapi_response_errors, webapi_request_fields) from djblets.webapi.errors import (DOES_NOT_EXIST, INVALID_FORM_DATA, NOT_LOGGED_IN, PERMISSION_DENIED) from reviewboard.extensions.base import get_extension_manager from reviewboard.webapi.decorators import webapi_check_local_site from reviewboard.webapi.resources import WebAPIResource from reviewbotext.models import Profile, Tool EXTENSION_MANAGER = get_extension_manager() class ToolResource(WebAPIResource): """Resource for workers to update the installed tools list. This API endpoint isn't actually RESTful, and just provides a place for workers to "dump" their entire list of installed tools as a single POST. A GET request will not actually return a list of tools. """ name = 'tool' allowed_methods = ('GET', 'POST',) model_object_key = 'id' uri_object_key = 'tool_id' @webapi_check_local_site
"""Review Board's extension resource.""" from djblets.extensions.resources import (ExtensionResource as DjbletsExtensionResource) from djblets.util.decorators import augment_method_from from reviewboard.extensions.base import get_extension_manager from reviewboard.webapi.base import RBResourceMixin from reviewboard.webapi.decorators import (webapi_check_local_site, webapi_check_login_required) class ExtensionResource(RBResourceMixin, DjbletsExtensionResource): """Review Board's extension resource. This resource special-cases the one in Djblets to provide API token and OAuth token access. """ @webapi_check_login_required @webapi_check_local_site @augment_method_from(DjbletsExtensionResource) def get(self, *args, **kwargs): pass extension_resource = ExtensionResource(get_extension_manager())
def __init__(self): super(Resources, self).__init__() self.extension = ExtensionResource(get_extension_manager())
from django.conf import settings from django.conf.urls.defaults import patterns, include, url from django.contrib import admin from reviewboard import initialize from reviewboard.extensions.base import get_extension_manager from reviewboard.webapi.resources import root_resource extension_manager = get_extension_manager() handler404 = 'django.views.defaults.page_not_found' handler500 = 'django.views.defaults.server_error' # Load in all the models for the admin UI. if not admin.site._registry: admin.autodiscover() # URLs global to all modes urlpatterns = patterns('', (r'^admin/extensions/', include('djblets.extensions.urls'), {'extension_manager': extension_manager}), (r'^admin/', include('reviewboard.admin.urls')), ) # Add static media if running in DEBUG mode if settings.DEBUG or getattr(settings, 'RUNNING_TEST', False): urlpatterns += patterns('django.views.static',
def initialize(): """Begin initialization of Review Board. This sets up the logging, generates cache serial numbers, loads extensions, and sets up other aspects of Review Board. Once it has finished, it will fire the :py:data:`reviewboard.signals.initializing` signal. This must be called at some point before most features will work, but it will be called automatically in a standard install. If you are writing an extension or management command, you do not need to call this yourself. """ import logging import os import settings_local # Set RBSITE_PYTHON_PATH to the path we need for any RB-bundled # scripts we may call. os.environ[b'RBSITE_PYTHONPATH'] = \ os.path.dirname(settings_local.__file__) from Crypto import Random from django.conf import settings from django.db import DatabaseError from djblets import log from djblets.cache.serials import generate_ajax_serial from reviewboard import signals from reviewboard.admin.siteconfig import load_site_config from reviewboard.extensions.base import get_extension_manager # This overrides a default django templatetag (url), and we want to make # sure it will always get loaded in every python instance. import reviewboard.site.templatetags is_running_test = getattr(settings, 'RUNNING_TEST', False) if not is_running_test: # Force PyCrypto to re-initialize the random number generator. Random.atfork() # Set up logging. log.init_logging() load_site_config() if not is_running_test: if settings.DEBUG: logging.debug("Log file for Review Board v%s (PID %s)" % (get_version_string(), os.getpid())) # Generate the AJAX serial, used for AJAX request caching. generate_ajax_serial() # Store the AJAX serial as a template serial, so we have a reference # to the real serial last modified timestamp of our templates. This # is useful since the extension manager will be modifying AJAX_SERIAL # to prevent stale caches for templates using hooks. Not all templates # use hooks, and may want to base cache keys off TEMPLATE_SERIAL # instead. # # We only want to do this once, so we don't end up replacing it # later with a modified AJAX_SERIAL later. if not getattr(settings, 'TEMPLATE_SERIAL', None): settings.TEMPLATE_SERIAL = settings.AJAX_SERIAL try: # Django >= 1.7 from django import setup setup() except ImportError: # Django < 1.7 pass if not is_running_test: # Load all extensions try: get_extension_manager().load() except DatabaseError: # This database is from a time before extensions, so don't attempt # to load any extensions yet. pass signals.initializing.send(sender=None)
def initialize(load_extensions=True, setup_logging=True, setup_templates=True): """Begin initialization of Review Board. This sets up the logging, generates cache serial numbers, loads extensions, and sets up other aspects of Review Board. Once it has finished, it will fire the :py:data:`reviewboard.signals.initializing` signal. This must be called at some point before most features will work, but it will be called automatically in a standard install. If you are writing an extension or management command, you do not need to call this yourself. Args: load_extensions (bool, optional): Whether extensions should be automatically loaded upon initialization. If set, extensions will only load if the site has been upgraded to the latest version of Review Board. setup_logging (bool, optional): Whether to set up logging based on the configured settings. This can be disabled if the caller has their own logging configuration. setup_templates (bool, optional): Whether to set up state for template rendering. This can be disabled if the caller has no need for template rendering of any kind. This does not prevent template rendering from happening, but may change the output of some templates. Keep in mind that many pieces of functionality, such as avatars and some management commands, may be impacted by this setting. """ import importlib import logging import os os.environ.setdefault(str('DJANGO_SETTINGS_MODULE'), str('reviewboard.settings')) import settings_local # Set RBSITE_PYTHON_PATH to the path we need for any RB-bundled # scripts we may call. os.environ[str('RBSITE_PYTHONPATH')] = \ os.path.dirname(settings_local.__file__) from django import setup from django.apps import apps if not apps.ready: setup() from django.conf import settings from django.db import DatabaseError from djblets import log from djblets.cache.serials import generate_ajax_serial from djblets.siteconfig.models import SiteConfiguration from reviewboard import signals from reviewboard.admin.siteconfig import load_site_config from reviewboard.extensions.base import get_extension_manager is_running_test = getattr(settings, 'RUNNING_TEST', False) if setup_logging and not is_running_test: # Set up logging. log.init_logging() load_site_config() if (setup_templates or load_extensions) and not is_running_test: if settings.DEBUG: logging.debug("Log file for Review Board v%s (PID %s)" % (get_version_string(), os.getpid())) # Generate the AJAX serial, used for AJAX request caching. generate_ajax_serial() # Store the AJAX serial as a template serial, so we have a reference # to the real serial last modified timestamp of our templates. This # is useful since the extension manager will be modifying AJAX_SERIAL # to prevent stale caches for templates using hooks. Not all templates # use hooks, and may want to base cache keys off TEMPLATE_SERIAL # instead. # # We only want to do this once, so we don't end up replacing it # later with a modified AJAX_SERIAL later. if not getattr(settings, 'TEMPLATE_SERIAL', None): settings.TEMPLATE_SERIAL = settings.AJAX_SERIAL siteconfig = SiteConfiguration.objects.get_current() if load_extensions and not is_running_test: installed_version = get_version_string() if siteconfig.version == installed_version: # Load all extensions try: get_extension_manager().load() except DatabaseError: # This database is from a time before extensions, so don't # attempt to load any extensions yet. pass else: logging.warning( 'Extensions will not be loaded. The site must ' 'be upgraded from Review Board %s to %s.', siteconfig.version, installed_version) signals.initializing.send(sender=None)
def create(self, request, *args, **kwargs): ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') testing = ext.get_settings('autoland_testing', False) if not testing and not request.user.has_perm( 'mozreview.add_autolandeventlogentry'): return PERMISSION_DENIED try: fields = json.loads(request.body) for field_name in self.fields: assert (type( fields[field_name]) == self.fields[field_name]['type']) except (ValueError, IndexError, KeyError, AssertionError) as e: return INVALID_FORM_DATA, { 'error': '%s' % e, } try: autoland_request = AutolandRequest.objects.get( pk=fields['request_id']) except AutolandRequest.DoesNotExist: return DOES_NOT_EXIST rr = ReviewRequest.objects.get(pk=autoland_request.review_request_id) bz_comment = None if fields['landed']: autoland_request.repository_revision = fields['result'] autoland_request.save() # If we've landed to the "inbound" repository, we'll close the # review request automatically. landing_repo = rr.repository.extra_data.get( 'landing_repository_url') if autoland_request.repository_url == landing_repo: rr.close(ReviewRequest.SUBMITTED) AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.SERVED, details=fields['result']) elif not fields.get('error_msg') and fields.get('result'): AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.REQUESTED, details=fields['result']) else: AutolandEventLogEntry.objects.create( autoland_request_id=fields['request_id'], status=AutolandEventLogEntry.PROBLEM, error_msg=fields['error_msg']) # The error message contains context explaining that Autoland # failed, so no leading text is necessary. bz_comment = fields['error_msg'] lock_id = get_autoland_lock_id(rr.id, autoland_request.repository_url, autoland_request.push_revision) release_lock(lock_id) if bz_comment: bugzilla = Bugzilla(get_bugzilla_api_key(request.user)) bug_id = int(rr.get_bug_list()[0]) # Catch and log Bugzilla errors rather than bubbling them up, # since we don't want the Autoland server to continously # retry the update. try: bugzilla.post_comment(bug_id, bz_comment) except BugzillaError as e: logger.error('Failed to post comment to Bugzilla: %s' % e) return 200, {}
def create(self, request, review_request_id, try_syntax, *args, **kwargs): try: rr = ReviewRequest.objects.get(pk=review_request_id) except ReviewRequest.DoesNotExist: return DOES_NOT_EXIST if not try_syntax.startswith('try: '): return INVALID_FORM_DATA, { 'fields': { 'try_syntax': ['The provided try syntax was invalid'] } } commit_data = fetch_commit_data(rr) if not is_pushed(rr, commit_data) or not is_parent(rr, commit_data): logger.error('Failed triggering Autoland because the review ' 'request is not pushed, or not the parent review ' 'request.') return NOT_PUSHED_PARENT_REVIEW_REQUEST enabled = rr.repository.extra_data.get('autolanding_to_try_enabled') if not enabled: return AUTOLAND_CONFIGURATION_ERROR.with_message( 'Autolanding to try not enabled.') target_repository = rr.repository.extra_data.get('try_repository_url') if not target_repository: return AUTOLAND_CONFIGURATION_ERROR.with_message( 'Autoland has not been configured with a proper try URL.') last_revision = json.loads( commit_data.extra_data.get(COMMITS_KEY))[-1][0] ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') logger.info('Submitting a request to Autoland for review request ' 'ID %s for revision %s destination try' % (review_request_id, last_revision)) autoland_url = ext.get_settings('autoland_url') if not autoland_url: return AUTOLAND_CONFIGURATION_ERROR autoland_user = ext.get_settings('autoland_user') autoland_password = ext.get_settings('autoland_password') if not autoland_user or not autoland_password: return AUTOLAND_CONFIGURATION_ERROR pingback_url = autoland_request_update_resource.get_uri(request) lock_id = get_autoland_lock_id(rr.id, target_repository, last_revision) if not acquire_lock(lock_id): return AUTOLAND_REQUEST_IN_PROGRESS try: # We use a hard-coded destination here. If we ever open this up # to make the destination a parameter to this resource, we need to # verify that the destination is in fact an "scm_level_1" # repository to ensure that people don't try to land to inbound # using this resource. response = requests.post( autoland_url + '/autoland', data=json.dumps({ 'ldap_username': request.mozreview_profile.ldap_username, 'tree': rr.repository.name, 'pingback_url': pingback_url, 'rev': last_revision, 'destination': TRY_AUTOLAND_DESTINATION, 'trysyntax': try_syntax, }), headers={ 'content-type': 'application/json', }, timeout=AUTOLAND_REQUEST_TIMEOUT, auth=(autoland_user, autoland_password)) except requests.exceptions.RequestException: logger.error('We hit a RequestException when submitting a ' 'request to Autoland') release_lock(lock_id) return AUTOLAND_ERROR except requests.exceptions.Timeout: logger.error('We timed out when submitting a request to ' 'Autoland') release_lock(lock_id) return AUTOLAND_TIMEOUT if response.status_code != 200: release_lock(lock_id) return AUTOLAND_ERROR, { 'status_code': response.status_code, 'message': response.json().get('error'), } # We succeeded in scheduling the job. try: autoland_request_id = int(response.json().get('request_id', 0)) finally: if autoland_request_id is None: release_lock(lock_id) return AUTOLAND_ERROR, { 'status_code': response.status_code, 'request_id': None, } AutolandRequest.objects.create(autoland_id=autoland_request_id, push_revision=last_revision, repository_url=target_repository, review_request_id=rr.id, user_id=request.user.id, extra_data=json.dumps( {'try_syntax': try_syntax})) AutolandEventLogEntry.objects.create( status=AutolandEventLogEntry.REQUESTED, autoland_request_id=autoland_request_id) self.save_autolandrequest_id('p2rb.autoland_try', rr, autoland_request_id) return 200, {}
def create(self, request, review_request_id, commit_descriptions, *args, **kwargs): try: rr = ReviewRequest.objects.get(pk=review_request_id) except ReviewRequest.DoesNotExist: return DOES_NOT_EXIST commit_data = fetch_commit_data(rr) if not is_pushed(rr, commit_data) or not is_parent(rr, commit_data): logger.error('Failed triggering Autoland because the review ' 'request is not pushed, or not the parent review ' 'request.') return NOT_PUSHED_PARENT_REVIEW_REQUEST enabled = rr.repository.extra_data.get('autolanding_enabled') if not enabled: return AUTOLAND_CONFIGURATION_ERROR.with_message( 'Autolanding not enabled.') target_repository = rr.repository.extra_data.get( 'landing_repository_url') push_bookmark = rr.repository.extra_data.get('landing_bookmark') if not target_repository: return AUTOLAND_CONFIGURATION_ERROR.with_message( 'Autoland has not been configured with a proper landing URL.') last_revision = json.loads( commit_data.extra_data.get(COMMITS_KEY))[-1][0] ext = get_extension_manager().get_enabled_extension( 'mozreview.extension.MozReviewExtension') logger.info('Submitting a request to Autoland for review request ' 'ID %s for revision %s destination %s' % (review_request_id, last_revision, target_repository)) autoland_url = ext.get_settings('autoland_url') if not autoland_url: return AUTOLAND_CONFIGURATION_ERROR autoland_user = ext.get_settings('autoland_user') autoland_password = ext.get_settings('autoland_password') if not autoland_user or not autoland_password: return AUTOLAND_CONFIGURATION_ERROR pingback_url = autoland_request_update_resource.get_uri(request) lock_id = get_autoland_lock_id(rr.id, target_repository, last_revision) if not acquire_lock(lock_id): return AUTOLAND_REQUEST_IN_PROGRESS try: response = requests.post( autoland_url + '/autoland', data=json.dumps({ 'ldap_username': request.mozreview_profile.ldap_username, 'tree': rr.repository.name, 'pingback_url': pingback_url, 'rev': last_revision, 'destination': target_repository, 'push_bookmark': push_bookmark, 'commit_descriptions': json.loads(commit_descriptions), }), headers={ 'content-type': 'application/json', }, timeout=AUTOLAND_REQUEST_TIMEOUT, auth=(autoland_user, autoland_password)) except requests.exceptions.RequestException: logger.error('We hit a RequestException when submitting a ' 'request to Autoland') release_lock(lock_id) return AUTOLAND_ERROR except requests.exceptions.Timeout: logger.error('We timed out when submitting a request to ' 'Autoland') release_lock(lock_id) return AUTOLAND_TIMEOUT if response.status_code != 200: release_lock(lock_id) try: error_message = response.json().get('error') except ValueError: error_message = response.text return AUTOLAND_ERROR, { 'status_code': response.status_code, 'message': error_message, } # We succeeded in scheduling the job. try: autoland_request_id = int(response.json().get('request_id', 0)) finally: if autoland_request_id is None: release_lock(lock_id) return AUTOLAND_ERROR, { 'status_code': response.status_code, 'request_id': None, } AutolandRequest.objects.create( autoland_id=autoland_request_id, push_revision=last_revision, repository_url=target_repository, review_request_id=rr.id, user_id=request.user.id, ) AutolandEventLogEntry.objects.create( status=AutolandEventLogEntry.REQUESTED, autoland_request_id=autoland_request_id) self.save_autolandrequest_id('p2rb.autoland', rr, autoland_request_id) return 200, {}
def get_overrides(): extension = get_extension_manager().get_enabled_extension( 'pygments_override.extension.PygmentsOverride') return extension.get_overrides_map()
def __init__(self): self.extension = ExtensionResource(get_extension_manager()) self._loaded = False
def create(self, request, review_request_id, commit_descriptions, *args, **kwargs): try: rr = ReviewRequest.objects.get(pk=review_request_id) except ReviewRequest.DoesNotExist: return DOES_NOT_EXIST commit_data = fetch_commit_data(rr) if not is_pushed(rr, commit_data) or not is_parent(rr, commit_data): logger.error( "Failed triggering Autoland because the review " "request is not pushed, or not the parent review " "request." ) return NOT_PUSHED_PARENT_REVIEW_REQUEST target_repository = rr.repository.extra_data.get("landing_repository_url") push_bookmark = rr.repository.extra_data.get("landing_bookmark") if not target_repository: return AUTOLAND_CONFIGURATION_ERROR.with_message( "Autoland has not been configured with a proper landing URL." ) last_revision = json.loads(commit_data.extra_data.get(COMMITS_KEY))[-1][0] ext = get_extension_manager().get_enabled_extension("mozreview.extension.MozReviewExtension") logger.info( "Submitting a request to Autoland for review request " "ID %s for revision %s destination %s" % (review_request_id, last_revision, target_repository) ) autoland_url = ext.get_settings("autoland_url") if not autoland_url: return AUTOLAND_CONFIGURATION_ERROR autoland_user = ext.get_settings("autoland_user") autoland_password = ext.get_settings("autoland_password") if not autoland_user or not autoland_password: return AUTOLAND_CONFIGURATION_ERROR pingback_url = autoland_request_update_resource.get_uri(request) lock_id = get_autoland_lock_id(rr.id, target_repository, last_revision) if not acquire_lock(lock_id): return AUTOLAND_REQUEST_IN_PROGRESS try: response = requests.post( autoland_url + "/autoland", data=json.dumps( { "ldap_username": request.mozreview_profile.ldap_username, "tree": rr.repository.name, "pingback_url": pingback_url, "rev": last_revision, "destination": target_repository, "push_bookmark": push_bookmark, "commit_descriptions": json.loads(commit_descriptions), } ), headers={"content-type": "application/json"}, timeout=AUTOLAND_REQUEST_TIMEOUT, auth=(autoland_user, autoland_password), ) except requests.exceptions.RequestException: logger.error("We hit a RequestException when submitting a " "request to Autoland") release_lock(lock_id) return AUTOLAND_ERROR except requests.exceptions.Timeout: logger.error("We timed out when submitting a request to " "Autoland") release_lock(lock_id) return AUTOLAND_TIMEOUT if response.status_code != 200: release_lock(lock_id) return AUTOLAND_ERROR, {"status_code": response.status_code, "message": response.json().get("error")} # We succeeded in scheduling the job. try: autoland_request_id = int(response.json().get("request_id", 0)) finally: if autoland_request_id is None: release_lock(lock_id) return AUTOLAND_ERROR, {"status_code": response.status_code, "request_id": None} autoland_request = AutolandRequest.objects.create( autoland_id=autoland_request_id, push_revision=last_revision, repository_url=target_repository, review_request_id=rr.id, user_id=request.user.id, ) AutolandEventLogEntry.objects.create( status=AutolandEventLogEntry.REQUESTED, autoland_request_id=autoland_request_id ) self.save_autolandrequest_id("p2rb.autoland", rr, autoland_request_id) return 200, {}
def test_review_request_box_template_hooks(self): """Testing ReviewRequestDetailView template hooks for the review request box """ class ContentTemplateHook(TemplateHook): def initialize(self, name, content): super(ContentTemplateHook, self).initialize(name) self.content = content def render_to_string(self, request, context): return self.content class TestExtension(Extension): registration = RegisteredExtension.objects.create( class_name='test-extension', name='test-extension', enabled=True, installed=True) extension = TestExtension(get_extension_manager()) review_request = self.create_review_request(publish=True) hooks = [] for name in ('before-review-request-summary', 'review-request-summary-pre', 'review-request-summary-post', 'after-review-request-summary-post', 'before-review-request-fields', 'after-review-request-fields', 'before-review-request-extra-panes', 'review-request-extra-panes-pre', 'review-request-extra-panes-post', 'after-review-request-extra-panes'): hooks.append(ContentTemplateHook(extension, name, '[%s here]' % name)) # Turn off some parts of the page, to simplify the resulting HTML # and shorten render/parse times. self.spy_on(get_review_request_fieldsets, call_fake=lambda *args, **kwargs: []) response = self.client.get( local_site_reverse('review-request-detail', args=[review_request.display_id])) self.assertEqual(response.status_code, 200) parsed_html = six.text_type( parse_html(response.content.decode('utf-8'))) self.assertIn( '<div class="review-request-body">\n' '[before-review-request-summary here]', parsed_html) self.assertIn( '<div class="review-request-section review-request-summary">\n' '[review-request-summary-pre here]', parsed_html) self.assertIn( '</time>\n</p>[review-request-summary-post here]\n</div>', parsed_html) self.assertIn( '[before-review-request-fields here]' '<table class="review-request-section"' ' id="review-request-details">', parsed_html) self.assertIn( '</div>' '[after-review-request-fields here] ' '[before-review-request-extra-panes here]' '<div id="review-request-extra">\n' '[review-request-extra-panes-pre here]', parsed_html) self.assertIn( '</div>[review-request-extra-panes-post here]\n' '</div>[after-review-request-extra-panes here]\n' '</div>', parsed_html)
def create(self, request, review_request_id, try_syntax, *args, **kwargs): try: rr = ReviewRequest.objects.get(pk=review_request_id) except ReviewRequest.DoesNotExist: return DOES_NOT_EXIST if not try_syntax.startswith("try: "): return INVALID_FORM_DATA, {"fields": {"try_syntax": ["The provided try syntax was invalid"]}} commit_data = fetch_commit_data(rr) if not is_pushed(rr, commit_data) or not is_parent(rr, commit_data): logger.error( "Failed triggering Autoland because the review " "request is not pushed, or not the parent review " "request." ) return NOT_PUSHED_PARENT_REVIEW_REQUEST target_repository = rr.repository.extra_data.get("try_repository_url") if not target_repository: return AUTOLAND_CONFIGURATION_ERROR.with_message("Autoland has not been configured with a proper try URL.") last_revision = json.loads(commit_data.extra_data.get(COMMITS_KEY))[-1][0] ext = get_extension_manager().get_enabled_extension("mozreview.extension.MozReviewExtension") logger.info( "Submitting a request to Autoland for review request " "ID %s for revision %s destination try" % (review_request_id, last_revision) ) autoland_url = ext.get_settings("autoland_url") if not autoland_url: return AUTOLAND_CONFIGURATION_ERROR autoland_user = ext.get_settings("autoland_user") autoland_password = ext.get_settings("autoland_password") if not autoland_user or not autoland_password: return AUTOLAND_CONFIGURATION_ERROR pingback_url = autoland_request_update_resource.get_uri(request) lock_id = get_autoland_lock_id(rr.id, target_repository, last_revision) if not acquire_lock(lock_id): return AUTOLAND_REQUEST_IN_PROGRESS try: # We use a hard-coded destination here. If we ever open this up # to make the destination a parameter to this resource, we need to # verify that the destination is in fact an "scm_level_1" # repository to ensure that people don't try to land to inbound # using this resource. response = requests.post( autoland_url + "/autoland", data=json.dumps( { "ldap_username": request.mozreview_profile.ldap_username, "tree": rr.repository.name, "pingback_url": pingback_url, "rev": last_revision, "destination": TRY_AUTOLAND_DESTINATION, "trysyntax": try_syntax, } ), headers={"content-type": "application/json"}, timeout=AUTOLAND_REQUEST_TIMEOUT, auth=(autoland_user, autoland_password), ) except requests.exceptions.RequestException: logger.error("We hit a RequestException when submitting a " "request to Autoland") release_lock(lock_id) return AUTOLAND_ERROR except requests.exceptions.Timeout: logger.error("We timed out when submitting a request to " "Autoland") release_lock(lock_id) return AUTOLAND_TIMEOUT if response.status_code != 200: release_lock(lock_id) return AUTOLAND_ERROR, {"status_code": response.status_code, "message": response.json().get("error")} # We succeeded in scheduling the job. try: autoland_request_id = int(response.json().get("request_id", 0)) finally: if autoland_request_id is None: release_lock(lock_id) return AUTOLAND_ERROR, {"status_code": response.status_code, "request_id": None} autoland_request = AutolandRequest.objects.create( autoland_id=autoland_request_id, push_revision=last_revision, repository_url=target_repository, review_request_id=rr.id, user_id=request.user.id, extra_data=json.dumps({"try_syntax": try_syntax}), ) AutolandEventLogEntry.objects.create( status=AutolandEventLogEntry.REQUESTED, autoland_request_id=autoland_request_id ) self.save_autolandrequest_id("p2rb.autoland_try", rr, autoland_request_id) return 200, {}
from __future__ import unicode_literals from django.conf import settings from django.conf.urls import patterns, include, url from django.conf.urls.static import static from django.contrib import admin from django.views.generic import TemplateView from reviewboard.datagrids.urls import urlpatterns as datagrid_urlpatterns from reviewboard.extensions.base import get_extension_manager from reviewboard.hostingsvcs.urls import urlpatterns as hostingsvcs_urlpatterns from reviewboard.search.urls import urlpatterns as search_urlpatterns from reviewboard.webapi.resources import resources extension_manager = get_extension_manager() handler404 = 'django.views.defaults.page_not_found' handler500 = 'django.views.defaults.server_error' # Useful collections of URL names that may be interesting to callers. # This is especially useful for any apply_to lists in hooks. diffviewer_url_names = [ 'view-diff', 'view-interdiff', 'view-diff-revision', ] reviewable_url_names = diffviewer_url_names + [ 'file-attachment', 'screenshot', ]
from djblets.db.query import LocalDataQuerySet from djblets.util.decorators import augment_method_from from djblets.webapi.decorators import (webapi_login_required, webapi_request_fields, webapi_response_errors) from djblets.webapi.errors import (DOES_NOT_EXIST, INVALID_FORM_DATA, NOT_LOGGED_IN, PERMISSION_DENIED) from reviewboard.diffviewer.models import FileDiff from reviewboard.extensions.base import get_extension_manager from reviewboard.reviews.models import BaseComment, Review from reviewboard.webapi.decorators import webapi_check_local_site from reviewboard.webapi.resources import resources, WebAPIResource from reviewbotext.models import ManualPermission, Profile, Tool, ToolExecution EXTENSION_MANAGER = get_extension_manager() class ToolResource(WebAPIResource): """Resource for workers to update the installed tools list. This API endpoint isn't actually RESTful, and just provides a place for workers to "dump" their entire list of installed tools as a single POST. A GET request will not actually return a list of tools. """ name = 'tool' allowed_methods = ( 'GET', 'POST', ) model_object_key = 'id'
def create(self, request, github_user, github_repo, pullrequest, *args, **kwargs): ext = get_extension_manager().get_enabled_extension("mozreview.extension.MozReviewExtension") testing = ext.get_settings("autoland_testing", False) autoland_url = ext.get_settings("autoland_url") if not autoland_url: return AUTOLAND_CONFIGURATION_ERROR autoland_user = ext.get_settings("autoland_user") autoland_password = ext.get_settings("autoland_password") if not autoland_user or not autoland_password: return AUTOLAND_CONFIGURATION_ERROR # if we've seen an import for this pullrequest before, see if we have # an existing bugid we can reuse. Otherwise, Autoland will attempt to # extract one from the pullrequest title and if that fails, file a new # bug. bugid = None prs = ImportPullRequestRequest.objects.filter( github_user=github_user, github_repo=github_repo, github_pullrequest=pullrequest ) prs = prs.order_by("-pk")[0:1] if prs: bugid = prs[0].bugid pingback_url = import_pullrequest_update_resource.get_uri(request) logger.info( "Submitting a request to Autoland for pull request" "%s/%s/%s for bug %s with pingback_url %s" % (github_user, github_repo, pullrequest, bugid, pingback_url) ) destination = IMPORT_PULLREQUEST_DESTINATION if testing: # This is just slightly better than hard coding the repo name destination = Repository.objects.all()[0].name try: response = requests.post( autoland_url + "/pullrequest/mozreview", data=json.dumps( { "user": github_user, "repo": github_repo, "pullrequest": pullrequest, "destination": destination, "bzuserid": request.session["Bugzilla_login"], "bzcookie": request.session["Bugzilla_logincookie"], "bugid": bugid, "pingback_url": pingback_url, } ), headers={"content-type": "application/json"}, timeout=AUTOLAND_REQUEST_TIMEOUT, auth=(autoland_user, autoland_password), ) except requests.exceptions.RequestException: logger.error("We hit a RequestException when submitting a " "request to Autoland") return AUTOLAND_ERROR except requests.exceptions.Timeout: logger.error("We timed out when submitting a request to " "Autoland") return AUTOLAND_TIMEOUT if response.status_code != 200: return AUTOLAND_ERROR, {"status_code": response.status_code, "message": response.json().get("error")} # We succeeded in scheduling the job. try: request_id = int(response.json()["request_id"]) except KeyError, ValueError: return AUTOLAND_ERROR, {"status_code": response.status_code, "request_id": autoland_request_id}
def configure_extension(request, ext_class, form_class): return djblets_ext_views.configure_extension(request, ext_class, form_class, get_extension_manager())