Redo the Review Bot extension configuration.

Review Request #8487 — Created Oct. 24, 2016 and submitted

Information

ReviewBot
master
4334144...

Reviewers

Most of the Review Bot "configuration" now exists in integration configs (which
specify which tools should run under which conditions), but there are two
pieces of global configuration for the extension that still need to happen.
Specifically, Review Bot needs a user account (to use for posting reviews and
other API requests), and the URL of the AMQP broker.

We had an existing settings form that was capable of doing that, but it was
kind of terrible. It used a <select> widget pre-populated with all the users
on the system, which isn't scalable, plus it required people to manually create
a user account through the database UI first. It also had no feedback about
whether the broker URL was correct.

This change replaces that with a new form which is submitted asynchronously.
The user selector uses selectize with similar styling to the new multi-user
select field that we added recently, and includes a "create" option for making
a new Review Bot user. Once the settings are configured, it will attempt to
refresh the tools list on each worker, to show some feedback. Right now the
feedback includes the connection state and the list of workers (but not what
tools are available). If everything is configured correctly (the user and
broker are set, the broker is available, and there are running workers), this
will then link to the integration list to set up individual tool
configurations.

  • Loaded the form with various states of configuration. Saw that the form
    fields were always properly populated.
  • Created a reviewbot user through the form and saw that the User was created
    and properly set in the extension settings.
  • Updated the user through the form and saw that the extension settings were
    changed.
  • Filled out the broker URL field and saw that the extension settings were
    changed.
  • Verified that the broker status was updated on initial page load and any
    time the configuration settings changed.
  • Tested broker status (and worker status) feedback for the different cases of
    "unable to connect", "connected without workers", and "connected with
    workers".

Description From Last Updated

The usage of the pencil instead of a text field in these forms makes it feel a bit alien, compared …

chipx86chipx86

I don't think we need to cast here, do we? Worth leaving this as logging.exception maybe?

chipx86chipx86

Same as above.

chipx86chipx86

Alphabetical order.

chipx86chipx86

Docstring?

chipx86chipx86

Properties are documented as attributes, and aren't really intended to have things like "Returns". Unfortunately, there's no equivalent for specifying …

chipx86chipx86

"Model Attributes"

chipx86chipx86

Did dedent get added somewhere?

chipx86chipx86

No need for type="text/javascript" these days.

chipx86chipx86

No trailing comma.

chipx86chipx86

No trailing comma.

chipx86chipx86

This should just use ReviewBotExtension.instance.

chipx86chipx86

This can be: user = get_object_or_none(User, pk=exetnsion.settings['user']) get_object_or_none is provided by Djblets.

chipx86chipx86

ReviewBotExtension.instance

chipx86chipx86

Maybe just combine these?

chipx86chipx86

ReviewBotExtension.instance

chipx86chipx86

ReviewBotExtension.instance

chipx86chipx86

get_object_or_none

chipx86chipx86

get_object_or_none

chipx86chipx86

ReviewBotExtension.instance

chipx86chipx86

ReviewBotExtension.instance

chipx86chipx86

ReviewBotExtension.instance

chipx86chipx86

This should actually be: avatar_services.for_user(user) That way it will return the configured avatar service for that user. If there isn't …

brenniebrennie

avatar_url ?

brenniebrennie

Properties should go before methods.

chipx86chipx86

Same here.

chipx86chipx86

We might want to show an alert or some inline error, instead of failing silently.

chipx86chipx86

We might want to show an alert or some inline error, instead of failing silently.

chipx86chipx86

Since the entire function is inside this, how about just returning if !this._rendered.

chipx86chipx86

We should have an alert or inline feedback here, too.

chipx86chipx86

I don't know that we want to treat this as public API. We could just return a standard 403 for …

chipx86chipx86

This can be done in dispatch, so it applies to all HTTP requests on the view.

chipx86chipx86

This can also go in dispatch. In fact, we should just make a mixin for this, for use in all …

chipx86chipx86
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
  2. 
      
chipx86
  1. 
      
  2. Show all issues

    The usage of the pencil instead of a text field in these forms makes it feel a bit alien, compared to other administration forms. This is the only admin form so far that's instant-apply. I see the need, since we want to be able to show the status, but I wonder if we can do this in a slightly different way.

    My thought is that instead of using the inline editor here, we can use a standard text field, helping keep this consistent (visually) with other forms. Then, instead of having a Save button in the bottom-right of the form, we just put it next to the text field. While it's in a different location, it's at least the same type of UI as found in other forms, from a user's perpsective. It allows this to stay instant apply while also remaining visually consistent with other forms.

    Another option (maybe even better) is to keep the Save button where it's at and have that trigger saving of both the user and the broker URL. The Status information can then appear below the form in its own Workers box. Might even be able to do more with that at some point, showing more than just the name (logs, connection errors, installed tools, etc.).

    1. Let me ponder for a bit...

  3. bot/reviewbot/tasks.py (Diff revision 1)
     
     
    Show all issues

    I don't think we need to cast here, do we?

    Worth leaving this as logging.exception maybe?

  4. bot/reviewbot/tasks.py (Diff revision 1)
     
     
    Show all issues

    Same as above.

  5. extension/reviewbotext/admin_urls.py (Diff revision 1)
     
     
     
    Show all issues

    Alphabetical order.

  6. extension/reviewbotext/extension.py (Diff revision 1)
     
     
     
    Show all issues

    Docstring?

  7. extension/reviewbotext/extension.py (Diff revision 1)
     
     
     
     
     
     
     
     
     
    Show all issues

    Properties are documented as attributes, and aren't really intended to have things like "Returns". Unfortunately, there's no equivalent for specifying the type for attributes in Sphinx/autodocs/napolean. (The "Attributes" section fakes it by basically doing <i>type info</i> in the output).

  8. Show all issues

    "Model Attributes"

  9. Show all issues

    Did dedent get added somewhere?

    1. It's in a pending change in my Review Board tree.

  10. Show all issues

    No need for type="text/javascript" these days.

  11. Show all issues

    No trailing comma.

  12. Show all issues

    No trailing comma.

  13. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
    Show all issues

    This should just use ReviewBotExtension.instance.

  14. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    This can be:

    user = get_object_or_none(User, pk=exetnsion.settings['user'])
    

    get_object_or_none is provided by Djblets.

  15. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
    Show all issues

    ReviewBotExtension.instance

  16. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
    Show all issues

    Maybe just combine these?

  17. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
    Show all issues

    ReviewBotExtension.instance

  18. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
    Show all issues

    ReviewBotExtension.instance

  19. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    get_object_or_none

  20. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
     
    Show all issues

    get_object_or_none

    1. get_object_or_none doesn't do what this code does.

  21. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
    Show all issues

    ReviewBotExtension.instance

  22. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
    Show all issues

    ReviewBotExtension.instance

  23. extension/reviewbotext/views.py (Diff revision 1)
     
     
     
     
    Show all issues

    ReviewBotExtension.instance

  24. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
  2. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
  2. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
  2. 
      
brennie
  1. 
      
  2. extension/reviewbotext/views.py (Diff revision 4)
     
     
     
     
    Show all issues

    avatar_url ?

  3. 
      
brennie
  1. 
      
  2. extension/reviewbotext/views.py (Diff revision 4)
     
     
    Show all issues

    This should actually be:

    avatar_services.for_user(user)
    

    That way it will return the configured avatar service for that user. If there isn't one, it will return the default service or None.

  3. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
  2. 
      
chipx86
  1. This overall looks great. I just have some small nits, and some areas where we could improve error handling.

  2. extension/reviewbotext/extension.py (Diff revision 5)
     
     
     
    Show all issues

    Properties should go before methods.

  3. extension/reviewbotext/extension.py (Diff revision 5)
     
     
     
    Show all issues

    Same here.

  4. Show all issues

    We might want to show an alert or some inline error, instead of failing silently.

  5. Show all issues

    We might want to show an alert or some inline error, instead of failing silently.

  6. Show all issues

    Since the entire function is inside this, how about just returning if !this._rendered.

  7. Show all issues

    We should have an alert or inline feedback here, too.

  8. extension/reviewbotext/views.py (Diff revision 5)
     
     
    Show all issues

    I don't know that we want to treat this as public API. We could just return a standard 403 for now, maybe work toward having Review Board be smart when encountering a 403 without a payload so we can standardize things there without the import.

  9. extension/reviewbotext/views.py (Diff revision 5)
     
     
     
    Show all issues

    This can be done in dispatch, so it applies to all HTTP requests on the view.

    1. The overall number of lines of code is a lot longer to introduce a new method to save repeating it twice.

  10. extension/reviewbotext/views.py (Diff revision 5)
     
     
     
    Show all issues

    This can also go in dispatch.

    In fact, we should just make a mixin for this, for use in all the views that need it.

    1. I'm not going to get too fancy with the mixins because Django 1.9 has a bunch of official mixin API for testing permissions/identity. I'll add a TODO comment to switch to those.

  11. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        bot/reviewbot/tasks.py
        extension/reviewbotext/extension.py
        extension/reviewbotext/admin_urls.py
        extension/reviewbotext/forms.py
        extension/reviewbotext/views.py
        extension/reviewbotext/resources.py
    
    Ignored Files:
        extension/reviewbotext/static/js/extensionConfig.es6.js
        extension/reviewbotext/templates/reviewbot/configure.html
        extension/reviewbotext/static/js/.jshintrc
        extension/reviewbotext/static/css/extension-config.less
    
    
  2. 
      
chipx86
  1. Ship It!
  2. 
      
david
Review request changed
Status:
Completed
Change Summary:
Pushed to master (1228452)