#260 Update the documentation
Merged 7 years ago by sayanchowdhury. Opened 7 years ago by jcline.
jcline/fedora-hubs docs  into  develop

file modified
+14 -395
@@ -1,405 +1,24 @@ 

+ Fedora Hubs

+ ===========

  Fedora Hubs will provide a communication and collaboration center for Fedora

  contributors of all types. The idea is that contributors will be able to visit

  Hubs to check on their involvements across Fedora, discover new places that they

  can contribute, and more.

  

  Hubs is currently under development, and you can see the progress on the

- Development instance here: http://209.132.184.98

+ Development instance here: https://hubs-dev.fedorainfracloud.org/

  

- Mailing List

- ============

- We have a mailing list here:

- https://lists.fedoraproject.org/archives/list/hubs-devel@lists.fedoraproject.org

+ Get Involved

+ ------------

  

- Road Map

- ========

+ Visit our `mailing list <https://lists.fedoraproject.org/archives/list/hubs-devel@lists.fedoraproject.org>`_

+ and join us in the ``#fedora-hubs`` IRC channel on irc.freenode.net. Meetings are held

+ weekly in ``#fedora-hubs`` at 14:00UTC and the minutes for every meeting are

+ `archived <https://meetbot.fedoraproject.org/sresults/?group_id=fedora-hubs&type=team>`_.

+ In the meetings we review our statuses from the preceding week and do ticket triage, too.

  

- We are currently working towards a roadmap of the following features with a mid-October target milestone for them:

+ For a more detailed overview of what Fedora Hubs is, see the

+ `documentation <https://docs.pagure.io/fedora-hubs/overview.html>`_.

  

- 1) **Zanata support** - Zanata is releasing a new version in November, but we've been in contact with Alex from that team and he said he will provide us with sample data to start developing against while they work on creating the webhooks we need to get that data. So we could do a release in October that has the support (and wait for the November Zanata release to turn it on.) Specifics of what widgets Zanata support would entail for the October release is TBD.

- 

- 2) **IRC Integration** - We'd like to have some IRC features available in the October release via the Waartaa project.

- 

- 3) **Badge support** -  Sayan already has a PR ready for tahrir (I believe) to add paths to badges; once that gets merged he can start working on the widget for hubs.

- 

- 4) **Hyperkitty support** - Hyperkitty needs some new API methods to provide full post content and metadata about replies / etc. Right now the migration off of Persona is top priority as Mozilla is shutting down Persona in September, but after that Aurelien can work on this. It shouldn't be super complicated. Once completed, Hyperkitty new thread posts will appear in the feed widget and if new replies are received to the thread, it'll bounce the thread to the top of the feed widget again.

- 

- 5) **Plusplus widget** - Aurelien and szkrepto have backend done; needs to be added to the webui.

- 

- Want to get involved? Looking for something to work on?

- =======================================================

- * Unfamiliar with what hubs is all about? Read through these blog posts / videos with lots of information about our vision for the project:

- http://blog.linuxgrrl.com/category/fedora/fedora-hubs/

- 

- * Building the development environment locally on your computer is a good beginning step to getting involved. If you have questions / run into issues, feel free to ask on

- #fedora-hubs in irc.freenode.net. Devyani put together a great blog post on how to get it working and what to expect here: https://devyani7kota.wordpress.com/2016/08/29/fedora-hubs-getting-started/

- 

- * We meet weekly in #fedora-hubs at 1400 UTC (10 AM EDT) on irc.freenode.net. We review our statuses from the preceding week and do ticket triage too. Please join us and get acquainted!

- 

- * **UX Designers** - take a look at our issues tagged 'needsmockup' that have no assignee listed and have a chat with mizmo (Máirín Duffy) for issue assignment / orientation.

- 

- * **Developers** - take a look at our issues with 'normal' or 'low' priority. We're tagging issues with think are particularly good for newbies to take on with the "easy" tag.

- 

- Hacking

- =======

- Install fedora dependencies::

- 

-     $ sudo dnf install gcc gcc-c++ sqlite-devel libffi-devel openssl-devel redhat-rpm-config

- 

- Hubs should work on either python2 **or** python3.  These instructions will

- show the way for python2 only, though.

- 

- Setup a python virtualenv::

- 

-     $ sudo dnf install python-virtualenvwrapper postgresql postgresql-devel

-     $ mkvirtualenv hubs

- 

- If the mkvirtualenv command returns "command not found..." you may need to

- refresh your bash profile::

- 

-     $ source ~/.bashrc

- 

- Note that, you only have to type ``mkvirtualenv`` the *very

- first time* you set up hubs.  When you try go to work on hubs

- a second time (and every time after that..) you only have to

- type ``workon hubs``, which will re-activate the virtual

- environment that you *made* last time.  (The ``mk`` in

- ``mkvirtualenv`` stands for "make".)

- 

- Now we need to pull the project and change our working directory::

- 

-     $ git clone https://pagure.io/fedora-hubs.git

-     $ cd ./fedora-hubs

- 

- OK -- with that done, now install the dependencies from PyPI::

- 

-     $ pip install -r requirements.txt

- 

- If anything complains about having an old version, you can update it with the following, after replacing [packagename] with the package in question::

- 

- 	$ pip install --upgrade [packagename]

- 

- Configure the project to authenticate against iddev.fedorainfracloud.org::

- 

-     oidc-register --debug https://iddev.fedorainfracloud.org/ http://localhost:5000

- 

- If the previous command complains about an error verifying the certificate, you will want to replace httplib2's ca cert file. Afterward, re-run the above command::

- 

-     cp /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

-         ~/.virtualenvs/hubs/lib/python2.7/site-packages/httplib2/cacerts.txt

- 

- Create a local configuration file::

- 

-     echo "OIDC_ID_TOKEN_COOKIE_SECURE = False" > config

- 

- With that, try running the app by creating the database::

- 

-     $ python populate.py  # To create the db

- 

- If this fails with a complaint about no module named sanitizer, or something about HTMLsanitizer, you will need to install bleach::

- 

- 	$ pip install bleach

- 

- Finish running the app by starting the devel server with your local config file. There will be warnings, but you can safely ignore them::

- 

-     $ python runserver.py -c config  # To run the dev server with our local conf

- 

- And then navigate to http://localhost:5000/

- 

- If you want to test it with 8 worker threads, try ``gunicorn``::

- 

-     $ pip install gunicorn

-     $ gunicorn -w 8 -t 60 --log-config logging.ini --reload hubs.app:app -b :5000

- 

- Note that then the application is available at http://localhost:8000/

- 

- When hacking on widgets, it is useful to have this one-liner handy.  It removes

- the db alltogether, re-populates it, and restarts the app::

- 

-     $ rm /var/tmp/hubs.db; rm /var/tmp/fedora-hubs-cache.db; PYTHONPATH=. python populate.py; gunicorn -w 8 -t 240 --log-config logging.ini hubs.app:app -b :5000

- 

- Run the tests!

- --------------

- 

- We have a test suite.  You should run it *before* you start working on some

- code, to make sure that nothing is broken before you start.  And you should run

- it after you finish your change, before you push, to verify that your change

- didn't inadvertently break something else.

- 

- You can run it with::

- 

-     $ pip install -r test-requirements.txt

-     $ ./runtest.sh

- 

- 

- 

- If the unit tests are all failing and returning errors like this::

- 

-     ImportError: cannot import name dummy

- 

- 

- It most likely is a result of html5lib breaking api stability. Please downgrade to the version below::

- 

-     pip install html5lib==0.9999999

- 

- 

- See the options available with::

- 

-     $ ./runtest.sh --help

- 

- You can run the JavaScript tests from ``hubs/static/client`` with::

-     $ npm test

- 

- Some credentials...

- -------------------

- 

- You need to add a new file to the ``fedmsg.d/`` directory.

- Call it ``fedmsg.d/credentials.py``.  It's needed to query FAS

- for information about other users. When we deploy this thing to

- production, we'll use a system account for this but for now, just

- use your personal account. You don't want to accidentally share this

- with anyone else. so be sure to keep it private.  It should have

- contents like this::

- 

-     config = {

-         # Put your FAS credentials here...

-         # but leave them commented out.  Note that, if you leave your fas

-         # credentials out, some widgets won't be as accurate as they could be..

-         # but it also makes the app faster than it would otherwise be (which is

-         # nice for development).

-         #'fas_credentials': {

-         #    'username': 'YOUR_FAS_USERNAME',

-         #    'password': 'YOUR_FAS_PASSWORD',

-         #},

- 

-         # Go and generate a token for this here:

-         # https://github.com/settings/tokens

-         'github.oauth_token': 'YOUR_GITHUB_TOKEN',

-     }

- 

- Make sure to leave the '' around you username and password - don't delete them! Some widgets will work without the above info being present..

- but it is needed for a subset of them.

- 

- JavaScript assets

- --------------

- 

- Some widgets and pages run on React so to install those dependencies::

- 

-     $ cd hubs/static/client && npm install

- 

- For the Feed and My Stream, change the ``SSE_URL`` location in the ``config`` you created

- to point to the streaming server then build JavaScript assets. Add ``--w`` for live reloading::

- 

-     $ cd hubs/static/client && node_modules/.bin/webpack

- 

- 

- My Stream - the Extra Mile

- ------------------------------------------

- 

- One portion of Hubs - the My Stream page - requires more legwork to stand up.

- If you just want to see how hubs works and you want to hack on other

- peripheral stuff around it, you don't need to bother with these steps.

- 

- The stream requires a direct DB connection to the datanommer

- database; it can't proxy through datagrepper because it needs more

- flexibility.  To get this working, you're going to set up:

- 

- - a postgres db

- - the datanommer daemon

- 

- Start with some required packages::

- 

-     $ sudo dnf install postgresql-server python-datanommer-consumer datanommer-commands fedmsg-hub npm

- 

- And there are some support libraries you'll also need::

- 

-     $ sudo dnf install python-psycopg2 python-fedmsg-meta-fedora-infrastructure

- 

- Now, with packages installed, you need to tell postgres to create its initial filesystem layout::

- 

-     $ sudo postgresql-setup initdb

- 

- And then, we need to tweak its config to let us connect easily for development::

- 

-     $ sudo vim /var/lib/pgsql/data/pg_hba.conf

- 

- Change **two lines** from ``ident`` to ``trust``.  These two::

- 

-     # IPv4 local connections:

-     host    all             all             127.0.0.1/32            trust

-     # IPv6 local connections:

-     host    all             all             ::1/128                 trust

- 

- Start that beast up::

- 

-     $ sudo systemctl start postgresql

- 

- Now, with the db daemon configured and running, let's configure datanommer.  Edit this file::

- 

-     $ sudo vim /etc/fedmsg.d/datanommer.py

- 

- And do two things:  1) set enabled to ``True`` and 2) give it a real sqlalchemy url, like this::

- 

-     config = {

-         'datanommer.enabled': True,

-         'datanommer.sqlalchemy.url': 'postgres://postgres:whatever@localhost/datanommer',

-     }

- 

- Tell postgres that it should create space for a 'datanommer' database with this command::

- 

-     $ sudo -u postgres psql -c "CREATE DATABASE datanommer;"

- 

- And finally, tell datanommer to create all of its tables in that new db we just created::

- 

-     $ datanommer-create-db

- 

- Tell the fedmsg-hub daemon to restart itself.  It should pick up datanommer as a plugin and start handing messages to it::

- 

-     $ sudo systemctl restart fedmsg-hub

- 

- And then, wait a few seconds for a message to get nommed, and then you can

- check that it's working by running ``sudo datanommer-stats``.  It should print

- out some kind of summary about what kinds of messages are in the db now -- it

- will just grow and grow over time::

- 

-     $ datanommer-stats

-     [2015-07-01 14:33:21][    fedmsg    INFO] buildsys has 70 entries

-     [2015-07-01 14:33:21][    fedmsg    INFO] faf has 7 entries

-     [2015-07-01 14:33:21][    fedmsg    INFO] copr has 6 entries

-     [2015-07-01 14:33:21][    fedmsg    INFO] askbot has 2 entries

- 

- **Lastly**, (fingers crossed) start up the fedora-hubs webapp and load your

- profile page. Change back to the project root and run::

- 

-   $ python runserver.py -c config

- 

- Once there are some messages that get into your local database

- that *should* show up on your page. they should appear there.  (At very least,

- you shouldn't get an error message about that page being unable to be

- displayed).

- 

- Stubbing out a new Widget

- =========================

- 

- You write a new widget in the ``hubs/widgets/`` directory and must declare it

- in the registry dict in ``hubs/widgets/__init__.py``.

- 

- In order to be valid, a widget must have:

- 

- - A ``data(session, widgets, **kwargs)`` function that returns a

-   jsonifiable dict of data.  This will get cached -- more on that later.

- - A ``template`` object that is a jinja2 template for that widget.

- - Optionally, a ``chrome`` decorator.

- - A ``should_invalidate(message, session, widget)`` function that will be used to

-   *potentially* invalidate the widget's cache. That function will get called by

-   a backend daemon listening for fedmsg messages so when you update your group

-   memberships in FAS, a fedmsg message hits the fedora-hubs backend and returns

-   True if the lookup value should be nuked/refreshed in memcached (or some

-   other store).

- 

- If you want to try making a new widget:

- 

- - Copy an existing one in ``hubs/widgets/``

- - Add it to the registry in ``hubs/widgets/__init__.py``

- - If you want it to show up on a **user** page, add it to ``hubs/defaults.py``

-   in the ``add_user_widgets`` function.

- - If you want it to show up on **group** pages, add it to ``populate.py``.

- 

- Destroy your database, rebuild it, and re-run the app.  Your widget should show up.

- 

- A proposal, client-side templates

- =================================

- 

- - The template per-widget is currently held and rendered *server-side* with

-   jinja2.  This is how all our apps do it, more or less.

- 

-   We might want to consider using handlebars.js for our templates instead and

-   rendering all of the widgets asynchronously on the client.  It could be cool,

-   but is new-ground for our team.

- 

-   Furthermore, we should likely use something like angular **or** backbone.js

-   to manage the data synchronization with those client-side templates.

- 

- Some discussion on how to do pushed updates to web clients:

- 

- - We could re-use the existing websocket service we have at

-   ``wss://hub.fedoraproject.org:9939`` but it has some problems:

- - It is very inflexible.  You can subscribe to fedmsg *topics* and then you

-   receive the firehose of those topics. For a widget, we already have to write

-   a 'cache invalidation' function that listens for messages and then somehow

-   knows to invalidate the cache *for a widget* based on some of those messages.

-   If we re-used the firehose on the client, we would have to write that

-   function *twice* for *each widget*, once in python to invalidate the server's

-   memcached cache when a fedmsg message comes in and once in javascript to tell

-   the client to reload and redraw a oprtion of itself when a fedmsg comes in

-   over the websocket firehose.

- - Instead, let's give fedora-hubs its own *widget-specific* `EventSource

-   <https://developer.mozilla.org/en-US/docs/Web/API/EventSource>`_ server that

-   we tie in to the server-side cache-invalidation backend code.  I.e., when a

-   message comes into the backend, it runs all the cache invalidation checkers

-   to see which widgets' caches should be refreshed, and once they are refreshed

-   we can emit events over EventSource to tell only *those* widgets on any

-   connected clients to redraw themselves.

- 

- As an aside, it became clear to me when making the diagram in the next section

- that, if we use handlebars.js and get rid of the server-side template

- rendering, then 1) the data returned by AJAX requests at page load and 2) the

- data pushed by the EventSource server can be *the exact same data*.  It will

- simplify and streamline the responsibilities of the pieces if the backend is

- worried *only* about these per-widget JSON responses.

- 

- A picture is worth...

- ---------------------

- 

- Here are some more details on how the whole thing should work together.

- 

- .. figure:: https://raw.githubusercontent.com/ralphbean/fedora-hubs-prototype/develop/docs/diagram.png

-    :scale: 50 %

-    :alt: A diagram of component interactions

- 

-    A diagram of component interactions

- 

- Let's talk through how data will flow through the system by asking *what

- happens when a user requsts their main hubs page*:

- 

- - The user requests the page and the wsgi app responds with some barebones HTML

-   and enough javascript to get off the ground.

- - The user's browser runs javascript that *subscribes* it to the EventSource server.

- - The user's browser runs that javascript, which requests data for each of the

-   widgets defined on the page.

- - The wsgi app receives those requests and checks to see if the data for any of

-   them is *cached in memcached*.  If it is, then it is returned.  If not, then

-   the wsgi app executes the ``data(...)`` function of that widget to get the

-   response ready.  It is stuffed in memcached for later access and returned.

- - The client renders widgets as the data for each of its requests comes back.

- 

- Later, what happens when a *trac ticket* is filed that should show up in some widget on their page?

- 

- - The ticket is updated on fedorahosted.org and a fedmsg message is fired.

- - That is received by the hubs backend, which looks up *all* the cached

-   responses that should be invalidated by that event (there is a widget on

-   mizmo's page, threebean's page, and on the design hub that should all get

-   fresh data because of this change).

- - All of those widgets get their cached data nuked.

- - All of those widgets get their cached data rebuilt by calling ``data(...)`` on them.

- - An EventSource event is fired off for any listening clients that *new data is

-   available for widgets X, Y, and Z*.  The data is included in the EventSource

-   payload so the clients can immediately redraw without bothering to re-query

-   the wsgi app.

- 

- What happens when the user is viewing the *design team* hub and

- simultaneously, an admin *changes the configuration of a widget on that page*?

- 

- - Changing the configuration results in a HTTP POST to the wsgi app.

- - The configuration is changed accordingly in the postgres database.

- - A fedmsg message is fired off indicating that *the configuration for widget X

-   has changed*.

- - The wsgi app responds 200 OK to the admin.

- - Meanwhile, that fedmsg message is received by the backend which:

- - ...looks up the cache key for *widget X with the old configuration* and nukes

-   it the cached data.

- - ...looks up the cache key for *widget X with the new configuration* and

-   builds the cached data by calling ``data(...)`` on the widget.

- - An EventSource event is fired off which gets recieved by everyone looking at

-   the *design team hub*.  The widget on their pages gets redrawn with data from

-   the EventSource event.

+ To set up a development environment and start contributing, check out

+ the `development guide <https://docs.pagure.io/fedora-hubs/dev-guide.html>`_.

file removed
-44
@@ -1,44 +0,0 @@ 

- Developer Setup

- ===============

- 

- This guide should get you up and running with a development environment.

- The simpliest way to stand up a development environment is to use

- `Vagrant <https://www.vagrantup.com/docs/>`_, but it is also easy to set

- up a development environment without Vagrant.

- 

- Vagrant

- ^^^^^^^

- 

- A ``Vagrantfile`` called ``Vagrantfile.example`` is provided in the root of the

- `Fedora Hub repository <https://pagure.io/fedora-hubs/>`_. To use it, simply

- copy ``Vagrantfile.example`` to ``Vagrantfile`` and modify it as you see fit.

- All settings are documented inline.

- 

- If you do not have Vagrant set up, follow these steps:

- 

- #. Install Ansible, Vagrant, and several helpful Vagrant plugins::

- 

-    $ sudo dnf install ansible vagrant-libvirt vagrant-sshfs vagrant-hostmanager

- 

- #. Create and configure the virtual machine::

- 

-    $ vagrant up --provider=libvirt

-    $ vagrant reload  # Reboot the machine to use the latest kernel, etc.

- 

- #. You can now use ssh to connect to the machine::

- 

-    $ vagrant ssh

- 

- #. If you ever want to re-run the provisioning scripts, you can::

- 

-    $ vagrant provision

- 

- #. If you decide you want a fresh development environment, simply destroy your

-    virtual machine and recreate it::

- 

-    $ vagrant destroy && vagrant up

- 

- You should now be able to point the browser in your host at http://localhost:5000/

- and use Fedora Hubs after you start the development server in the virtual machine.

- 

- Happy hacking!

file added
+225
@@ -0,0 +1,225 @@ 

+ # Makefile for Sphinx documentation

+ #

+ 

+ # You can set these variables from the command line.

+ SPHINXOPTS    =

+ SPHINXBUILD   = sphinx-build

+ PAPER         =

+ BUILDDIR      = _build

+ 

+ # Internal variables.

+ PAPEROPT_a4     = -D latex_paper_size=a4

+ PAPEROPT_letter = -D latex_paper_size=letter

+ ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

+ # the i18n builder cannot share the environment and doctrees with the others

+ I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

+ 

+ .PHONY: help

+ help:

+ 	@echo "Please use \`make <target>' where <target> is one of"

+ 	@echo "  html       to make standalone HTML files"

+ 	@echo "  dirhtml    to make HTML files named index.html in directories"

+ 	@echo "  singlehtml to make a single large HTML file"

+ 	@echo "  pickle     to make pickle files"

+ 	@echo "  json       to make JSON files"

+ 	@echo "  htmlhelp   to make HTML files and a HTML help project"

+ 	@echo "  qthelp     to make HTML files and a qthelp project"

+ 	@echo "  applehelp  to make an Apple Help Book"

+ 	@echo "  devhelp    to make HTML files and a Devhelp project"

+ 	@echo "  epub       to make an epub"

+ 	@echo "  epub3      to make an epub3"

+ 	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"

+ 	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"

+ 	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"

+ 	@echo "  text       to make text files"

+ 	@echo "  man        to make manual pages"

+ 	@echo "  texinfo    to make Texinfo files"

+ 	@echo "  info       to make Texinfo files and run them through makeinfo"

+ 	@echo "  gettext    to make PO message catalogs"

+ 	@echo "  changes    to make an overview of all changed/added/deprecated items"

+ 	@echo "  xml        to make Docutils-native XML files"

+ 	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"

+ 	@echo "  linkcheck  to check all external links for integrity"

+ 	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"

+ 	@echo "  coverage   to run coverage check of the documentation (if enabled)"

+ 	@echo "  dummy      to check syntax errors of document sources"

+ 

+ .PHONY: clean

+ clean:

+ 	rm -rf $(BUILDDIR)/*

+ 

+ .PHONY: html

+ html:

+ 	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html

+ 	@echo

+ 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

+ 

+ .PHONY: dirhtml

+ dirhtml:

+ 	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml

+ 	@echo

+ 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

+ 

+ .PHONY: singlehtml

+ singlehtml:

+ 	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml

+ 	@echo

+ 	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

+ 

+ .PHONY: pickle

+ pickle:

+ 	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle

+ 	@echo

+ 	@echo "Build finished; now you can process the pickle files."

+ 

+ .PHONY: json

+ json:

+ 	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json

+ 	@echo

+ 	@echo "Build finished; now you can process the JSON files."

+ 

+ .PHONY: htmlhelp

+ htmlhelp:

+ 	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp

+ 	@echo

+ 	@echo "Build finished; now you can run HTML Help Workshop with the" \

+ 	      ".hhp project file in $(BUILDDIR)/htmlhelp."

+ 

+ .PHONY: qthelp

+ qthelp:

+ 	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp

+ 	@echo

+ 	@echo "Build finished; now you can run "qcollectiongenerator" with the" \

+ 	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"

+ 	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/fedora-hubs.qhcp"

+ 	@echo "To view the help file:"

+ 	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/fedora-hubs.qhc"

+ 

+ .PHONY: applehelp

+ applehelp:

+ 	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp

+ 	@echo

+ 	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."

+ 	@echo "N.B. You won't be able to view it unless you put it in" \

+ 	      "~/Library/Documentation/Help or install it in your application" \

+ 	      "bundle."

+ 

+ .PHONY: devhelp

+ devhelp:

+ 	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp

+ 	@echo

+ 	@echo "Build finished."

+ 	@echo "To view the help file:"

+ 	@echo "# mkdir -p $$HOME/.local/share/devhelp/fedora-hubs"

+ 	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/fedora-hubs"

+ 	@echo "# devhelp"

+ 

+ .PHONY: epub

+ epub:

+ 	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub

+ 	@echo

+ 	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

+ 

+ .PHONY: epub3

+ epub3:

+ 	$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3

+ 	@echo

+ 	@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."

+ 

+ .PHONY: latex

+ latex:

+ 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex

+ 	@echo

+ 	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."

+ 	@echo "Run \`make' in that directory to run these through (pdf)latex" \

+ 	      "(use \`make latexpdf' here to do that automatically)."

+ 

+ .PHONY: latexpdf

+ latexpdf:

+ 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex

+ 	@echo "Running LaTeX files through pdflatex..."

+ 	$(MAKE) -C $(BUILDDIR)/latex all-pdf

+ 	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

+ 

+ .PHONY: latexpdfja

+ latexpdfja:

+ 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex

+ 	@echo "Running LaTeX files through platex and dvipdfmx..."

+ 	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja

+ 	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

+ 

+ .PHONY: text

+ text:

+ 	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text

+ 	@echo

+ 	@echo "Build finished. The text files are in $(BUILDDIR)/text."

+ 

+ .PHONY: man

+ man:

+ 	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man

+ 	@echo

+ 	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

+ 

+ .PHONY: texinfo

+ texinfo:

+ 	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo

+ 	@echo

+ 	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."

+ 	@echo "Run \`make' in that directory to run these through makeinfo" \

+ 	      "(use \`make info' here to do that automatically)."

+ 

+ .PHONY: info

+ info:

+ 	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo

+ 	@echo "Running Texinfo files through makeinfo..."

+ 	make -C $(BUILDDIR)/texinfo info

+ 	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."

+ 

+ .PHONY: gettext

+ gettext:

+ 	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale

+ 	@echo

+ 	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."

+ 

+ .PHONY: changes

+ changes:

+ 	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes

+ 	@echo

+ 	@echo "The overview file is in $(BUILDDIR)/changes."

+ 

+ .PHONY: linkcheck

+ linkcheck:

+ 	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck

+ 	@echo

+ 	@echo "Link check complete; look for any errors in the above output " \

+ 	      "or in $(BUILDDIR)/linkcheck/output.txt."

+ 

+ .PHONY: doctest

+ doctest:

+ 	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest

+ 	@echo "Testing of doctests in the sources finished, look at the " \

+ 	      "results in $(BUILDDIR)/doctest/output.txt."

+ 

+ .PHONY: coverage

+ coverage:

+ 	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage

+ 	@echo "Testing of coverage in the sources finished, look at the " \

+ 	      "results in $(BUILDDIR)/coverage/python.txt."

+ 

+ .PHONY: xml

+ xml:

+ 	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml

+ 	@echo

+ 	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."

+ 

+ .PHONY: pseudoxml

+ pseudoxml:

+ 	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml

+ 	@echo

+ 	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

+ 

+ .PHONY: dummy

+ dummy:

+ 	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy

+ 	@echo

+ 	@echo "Build finished. Dummy builder generates no files."

file added
+423
@@ -0,0 +1,423 @@ 

+ # -*- coding: utf-8 -*-

+ #

+ # fedora-hubs documentation build configuration file, created by

+ # sphinx-quickstart on Wed Sep 21 16:41:24 2016.

+ #

+ # This file is execfile()d with the current directory set to its

+ # containing dir.

+ #

+ # Note that not all possible configuration values are present in this

+ # autogenerated file.

+ #

+ # All configuration values have a default; values that are commented out

+ # serve to show the default.

+ 

+ # If extensions (or modules to document with autodoc) are in another directory,

+ # add these directories to sys.path here. If the directory is relative to the

+ # documentation root, use os.path.abspath to make it absolute, like shown here.

+ #

+ # import os

+ # import sys

+ # sys.path.insert(0, os.path.abspath('.'))

+ 

+ # -- General configuration ------------------------------------------------

+ 

+ # If your documentation needs a minimal Sphinx version, state it here.

+ #

+ # needs_sphinx = '1.0'

+ 

+ # Add any Sphinx extension module names here, as strings. They can be

+ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom

+ # ones.

+ extensions = []

+ 

+ # Add any paths that contain templates here, relative to this directory.

+ templates_path = ['_templates']

+ 

+ # The suffix(es) of source filenames.

+ # You can specify multiple suffix as a list of string:

+ #

+ # source_suffix = ['.rst', '.md']

+ source_suffix = '.rst'

+ 

+ # The encoding of source files.

+ #

+ # source_encoding = 'utf-8-sig'

+ 

+ # The master toctree document.

+ master_doc = 'index'

+ 

+ # General information about the project.

+ project = u'fedora-hubs'

+ copyright = u'2016, Red Hat, Inc. and others.'

+ author = u'Red Hat, Inc. and others.'

+ 

+ # The version info for the project you're documenting, acts as replacement for

+ # |version| and |release|, also used in various other places throughout the

+ # built documents.

+ #

+ # The short X.Y version.

+ version = u'0.0.1'

+ # The full version, including alpha/beta/rc tags.

+ release = u'0.0.1'

+ 

+ # The language for content autogenerated by Sphinx. Refer to documentation

+ # for a list of supported languages.

+ #

+ # This is also used if you do content translation via gettext catalogs.

+ # Usually you set "language" from the command line for these cases.

+ language = None

+ 

+ # There are two options for replacing |today|: either, you set today to some

+ # non-false value, then it is used:

+ #

+ # today = ''

+ #

+ # Else, today_fmt is used as the format for a strftime call.

+ #

+ # today_fmt = '%B %d, %Y'

+ 

+ # List of patterns, relative to source directory, that match files and

+ # directories to ignore when looking for source files.

+ # This patterns also effect to html_static_path and html_extra_path

+ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

+ 

+ # The reST default role (used for this markup: `text`) to use for all

+ # documents.

+ #

+ # default_role = None

+ 

+ # If true, '()' will be appended to :func: etc. cross-reference text.

+ #

+ # add_function_parentheses = True

+ 

+ # If true, the current module name will be prepended to all description

+ # unit titles (such as .. function::).

+ #

+ # add_module_names = True

+ 

+ # If true, sectionauthor and moduleauthor directives will be shown in the

+ # output. They are ignored by default.

+ #

+ # show_authors = False

+ 

+ # The name of the Pygments (syntax highlighting) style to use.

+ pygments_style = 'sphinx'

+ 

+ # A list of ignored prefixes for module index sorting.

+ # modindex_common_prefix = []

+ 

+ # If true, keep warnings as "system message" paragraphs in the built documents.

+ # keep_warnings = False

+ 

+ # If true, `todo` and `todoList` produce output, else they produce nothing.

+ todo_include_todos = False

+ 

+ 

+ # -- Options for HTML output ----------------------------------------------

+ 

+ # The theme to use for HTML and HTML Help pages.  See the documentation for

+ # a list of builtin themes.

+ #

+ html_theme = 'alabaster'

+ 

+ # Theme options are theme-specific and customize the look and feel of a theme

+ # further.  For a list of options available for each theme, see the

+ # documentation.

+ #

+ # html_theme_options = {}

+ 

+ # Add any paths that contain custom themes here, relative to this directory.

+ # html_theme_path = []

+ 

+ # The name for this set of Sphinx documents.

+ # "<project> v<release> documentation" by default.

+ #

+ # html_title = u'fedora-hubs v0.0.1'

+ 

+ # A shorter title for the navigation bar.  Default is the same as html_title.

+ #

+ # html_short_title = None

+ 

+ # The name of an image file (relative to this directory) to place at the top

+ # of the sidebar.

+ #

+ # html_logo = None

+ 

+ # The name of an image file (relative to this directory) to use as a favicon of

+ # the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32

+ # pixels large.

+ #

+ # html_favicon = None

+ 

+ # Add any paths that contain custom static files (such as style sheets) here,

+ # relative to this directory. They are copied after the builtin static files,

+ # so a file named "default.css" will overwrite the builtin "default.css".

+ html_static_path = ['_static']

+ 

+ # Add any extra paths that contain custom files (such as robots.txt or

+ # .htaccess) here, relative to this directory. These files are copied

+ # directly to the root of the documentation.

+ #

+ # html_extra_path = []

+ 

+ # If not None, a 'Last updated on:' timestamp is inserted at every page

+ # bottom, using the given strftime format.

+ # The empty string is equivalent to '%b %d, %Y'.

+ #

+ # html_last_updated_fmt = None

+ 

+ # If true, SmartyPants will be used to convert quotes and dashes to

+ # typographically correct entities.

+ #

+ # html_use_smartypants = True

+ 

+ # Custom sidebar templates, maps document names to template names.

+ #

+ # html_sidebars = {}

+ 

+ # Additional templates that should be rendered to pages, maps page names to

+ # template names.

+ #

+ # html_additional_pages = {}

+ 

+ # If false, no module index is generated.

+ #

+ # html_domain_indices = True

+ 

+ # If false, no index is generated.

+ #

+ # html_use_index = True

+ 

+ # If true, the index is split into individual pages for each letter.

+ #

+ # html_split_index = False

+ 

+ # If true, links to the reST sources are added to the pages.

+ #

+ # html_show_sourcelink = True

+ 

+ # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.

+ #

+ # html_show_sphinx = True

+ 

+ # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.

+ #

+ # html_show_copyright = True

+ 

+ # If true, an OpenSearch description file will be output, and all pages will

+ # contain a <link> tag referring to it.  The value of this option must be the

+ # base URL from which the finished HTML is served.

+ #

+ # html_use_opensearch = ''

+ 

+ # This is the file name suffix for HTML files (e.g. ".xhtml").

+ # html_file_suffix = None

+ 

+ # Language to be used for generating the HTML full-text search index.

+ # Sphinx supports the following languages:

+ #   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'

+ #   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'

+ #

+ # html_search_language = 'en'

+ 

+ # A dictionary with options for the search language support, empty by default.

+ # 'ja' uses this config value.

+ # 'zh' user can custom change `jieba` dictionary path.

+ #

+ # html_search_options = {'type': 'default'}

+ 

+ # The name of a javascript file (relative to the configuration directory) that

+ # implements a search results scorer. If empty, the default will be used.

+ #

+ # html_search_scorer = 'scorer.js'

+ 

+ # Output file base name for HTML help builder.

+ htmlhelp_basename = 'fedora-hubsdoc'

+ 

+ # -- Options for LaTeX output ---------------------------------------------

+ 

+ latex_elements = {

+      # The paper size ('letterpaper' or 'a4paper').

+      #

+      # 'papersize': 'letterpaper',

+ 

+      # The font size ('10pt', '11pt' or '12pt').

+      #

+      # 'pointsize': '10pt',

+ 

+      # Additional stuff for the LaTeX preamble.

+      #

+      # 'preamble': '',

+ 

+      # Latex figure (float) alignment

+      #

+      # 'figure_align': 'htbp',

+ }

+ 

+ # Grouping the document tree into LaTeX files. List of tuples

+ # (source start file, target name, title,

+ #  author, documentclass [howto, manual, or own class]).

+ latex_documents = [

+     (master_doc, 'fedora-hubs.tex', u'fedora-hubs Documentation',

+      u'AUTHORS', 'manual'),

+ ]

+ 

+ # The name of an image file (relative to this directory) to place at the top of

+ # the title page.

+ #

+ # latex_logo = None

+ 

+ # For "manual" documents, if this is true, then toplevel headings are parts,

+ # not chapters.

+ #

+ # latex_use_parts = False

+ 

+ # If true, show page references after internal links.

+ #

+ # latex_show_pagerefs = False

+ 

+ # If true, show URL addresses after external links.

+ #

+ # latex_show_urls = False

+ 

+ # Documents to append as an appendix to all manuals.

+ #

+ # latex_appendices = []

+ 

+ # It false, will not define \strong, \code, 	itleref, \crossref ... but only

+ # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added

+ # packages.

+ #

+ # latex_keep_old_macro_names = True

+ 

+ # If false, no module index is generated.

+ #

+ # latex_domain_indices = True

+ 

+ 

+ # -- Options for manual page output ---------------------------------------

+ 

+ # One entry per manual page. List of tuples

+ # (source start file, name, description, authors, manual section).

+ man_pages = [

+     (master_doc, 'fedora-hubs', u'fedora-hubs Documentation',

+      [author], 1)

+ ]

+ 

+ # If true, show URL addresses after external links.

+ #

+ # man_show_urls = False

+ 

+ 

+ # -- Options for Texinfo output -------------------------------------------

+ 

+ # Grouping the document tree into Texinfo files. List of tuples

+ # (source start file, target name, title, author,

+ #  dir menu entry, description, category)

+ texinfo_documents = [

+     (master_doc, 'fedora-hubs', u'fedora-hubs Documentation',

+      author, 'fedora-hubs', 'One line description of project.',

+      'Miscellaneous'),

+ ]

+ 

+ # Documents to append as an appendix to all manuals.

+ #

+ # texinfo_appendices = []

+ 

+ # If false, no module index is generated.

+ #

+ # texinfo_domain_indices = True

+ 

+ # How to display URL addresses: 'footnote', 'no', or 'inline'.

+ #

+ # texinfo_show_urls = 'footnote'

+ 

+ # If true, do not generate a @detailmenu in the "Top" node's menu.

+ #

+ # texinfo_no_detailmenu = False

+ 

+ 

+ # -- Options for Epub output ----------------------------------------------

+ 

+ # Bibliographic Dublin Core info.

+ epub_title = project

+ epub_author = author

+ epub_publisher = author

+ epub_copyright = copyright

+ 

+ # The basename for the epub file. It defaults to the project name.

+ # epub_basename = project

+ 

+ # The HTML theme for the epub output. Since the default themes are not

+ # optimized for small screen space, using the same theme for HTML and epub

+ # output is usually not wise. This defaults to 'epub', a theme designed to save

+ # visual space.

+ #

+ # epub_theme = 'epub'

+ 

+ # The language of the text. It defaults to the language option

+ # or 'en' if the language is not set.

+ #

+ # epub_language = ''

+ 

+ # The scheme of the identifier. Typical schemes are ISBN or URL.

+ # epub_scheme = ''

+ 

+ # The unique identifier of the text. This can be a ISBN number

+ # or the project homepage.

+ #

+ # epub_identifier = ''

+ 

+ # A unique identification for the text.

+ #

+ # epub_uid = ''

+ 

+ # A tuple containing the cover image and cover page html template filenames.

+ #

+ # epub_cover = ()

+ 

+ # A sequence of (type, uri, title) tuples for the guide element of content.opf.

+ #

+ # epub_guide = ()

+ 

+ # HTML files that should be inserted before the pages created by sphinx.

+ # The format is a list of tuples containing the path and title.

+ #

+ # epub_pre_files = []

+ 

+ # HTML files that should be inserted after the pages created by sphinx.

+ # The format is a list of tuples containing the path and title.

+ #

+ # epub_post_files = []

+ 

+ # A list of files that should not be packed into the epub file.

+ epub_exclude_files = ['search.html']

+ 

+ # The depth of the table of contents in toc.ncx.

+ #

+ # epub_tocdepth = 3

+ 

+ # Allow duplicate toc entries.

+ #

+ # epub_tocdup = True

+ 

+ # Choose between 'default' and 'includehidden'.

+ #

+ # epub_tocscope = 'default'

+ 

+ # Fix unsupported image types using the Pillow.

+ #

+ # epub_fix_images = False

+ 

+ # Scale large images.

+ #

+ # epub_max_image_width = 0

+ 

+ # How to display URL addresses: 'footnote', 'no', or 'inline'.

+ #

+ # epub_show_urls = 'inline'

+ 

+ # If false, no index is generated.

+ #

+ # epub_use_index = True

file added
+479
@@ -0,0 +1,479 @@ 

+ 

+ .. _development-guide:

+ 

+ Development Guide

+ =================

+ 

+ Fedora Hubs is a web application written in Python. It uses the

+ `Flask <http://flask.pocoo.org/>`_ web framework and `SQLAlchemy

+ <http://www.sqlalchemy.org/>`_ to interact with the database.

+ 

+ It also uses the `React <https://facebook.github.io/react/>`_ JavaScript

+ framework and `fedora-bootstrap <https://pagure.io/fedora-bootstrap/>`_.

+ 

+ 

+ Getting Started on a Task

+ -------------------------

+ 

+ UX Designers

+ ^^^^^^^^^^^^

+ 

+ Start by taking a look at our list of `unassigned issues tagged 'needsmockup'

+ <https://pagure.io/fedora-hubs/issues?status=Open&assignee=0&tags=needsmockup>`_.

+ Have a chat with mizmo (Máirín Duffy) for issue assignment / orientation.

+ 

+ 

+ Developers

+ ^^^^^^^^^^

+ Take a look at our `issues <https://pagure.io/fedora-hubs/issues/>`_ with

+ 'normal' or 'low' priority. We're tagging issues that we think are particularly

+ good for newbies to take on with the "easy" tag.

+ 

+ 

+ Development Environment

+ -----------------------

+ 

+ There are several options available when setting up a development environment.

+ The simpliest way to stand up a development environment is to use

+ `Vagrant <https://www.vagrantup.com/docs/>`_, but it is also easy to set

+ up a development environment without Vagrant. This documentation assumes you

+ are using the latest stable version of Fedora.

+ 

+ 

+ Vagrant

+ ^^^^^^^

+ 

+ A ``Vagrantfile`` called ``Vagrantfile.example`` is provided in the root of the

+ `Fedora Hub repository <https://pagure.io/fedora-hubs/>`_. To use it, simply

+ copy ``Vagrantfile.example`` to ``Vagrantfile`` and modify it as you see fit.

+ All settings are documented inline.

+ 

+ If you do not have Vagrant set up, follow these steps:

+ 

+ #. Install Ansible, Vagrant, and several helpful Vagrant plugins::

+ 

+    $ sudo dnf install ansible vagrant-libvirt vagrant-sshfs

+ 

+ #. In the root of the git repository, copy ``Vagrantfile.example`` to ``Vagrantfile``::

+ 

+    $ cp Vagrantfile.example Vagrantfile

+ 

+ #. Create and configure the virtual machine::

+ 

+    $ vagrant up --provider=libvirt

+    $ vagrant reload  # Reboot the machine to use the latest kernel, etc.

+ 

+ #. You can now use ssh to connect to the machine::

+ 

+    $ vagrant ssh

+ 

+ #. You'll be greeted by a message of the day with instructions on how to start the

+    development server.

+ 

+ #. If you ever want to re-run the provisioning scripts, you can::

+ 

+    $ vagrant provision

+ 

+ #. If you decide you want a fresh development environment, simply destroy your

+    virtual machine and recreate it::

+ 

+    $ vagrant destroy && vagrant up

+ 

+ Once you start the development server in the guest, you should be able to access

+ Fedora Hubs by navigating to http://localhost:5000/ on the browser in your host.

+ 

+ Happy hacking!

+ 

+ 

+ Ansible

+ ^^^^^^^

+ 

+ If you would prefer not to use Vagrant, you can also just use Ansible directly.

+ 

+ .. warning::

+     The Ansible role used to set up a development environment assumes it can do

+     things like overwrite the user's .bashrc. You should not run this on a host

+     you don't feel comfortable re-provisioning.

+ 

+ First, you need to install the packages required to run Ansible::

+ 

+     $ sudo dnf install ansible python2-dnf libselinux-python

+ 

+ Next, we need to create an Ansible `inventory

+ <http://docs.ansible.com/ansible/intro_inventory.html>`_. If you want to run

+ Ansible on the local host, you can easily create one with::

+ 

+     $ echo -e "localhost ansible_connection=local" >> /tmp/ansible_inventory

+ 

+ Finally, run Ansible using the inventory::

+ 

+     $ ansible-playbook --inventory-file=/tmp/ansible_inventory ansible/vagrant-playbook.yml

+ 

+ Once it finishes, you should have a fully functional development environment!

+ 

+ 

+ Manual

+ ^^^^^^

+ 

+ Install fedora dependencies::

+ 

+     $ sudo dnf install gcc gcc-c++ sqlite-devel libffi-devel openssl-devel redhat-rpm-config

+ 

+ Hubs should work on either python2 **or** python3.  These instructions will

+ show the way for python2 only, though.

+ 

+ Setup a python virtualenv::

+ 

+     $ sudo dnf install python-virtualenvwrapper postgresql postgresql-devel

+     $ mkvirtualenv hubs

+ 

+ If the mkvirtualenv command returns "command not found..." you may need to

+ refresh your bash profile::

+ 

+     $ source ~/.bashrc

+ 

+ Note that, you only have to type ``mkvirtualenv`` the *very

+ first time* you set up hubs.  When you try go to work on hubs

+ a second time (and every time after that..) you only have to

+ type ``workon hubs``, which will re-activate the virtual

+ environment that you *made* last time.  (The ``mk`` in

+ ``mkvirtualenv`` stands for "make".)

+ 

+ Now we need to pull the project and change our working directory::

+ 

+     $ git clone https://pagure.io/fedora-hubs.git

+     $ cd ./fedora-hubs

+ 

+ OK -- with that done, now install the dependencies from PyPI::

+ 

+     $ pip install -r requirements.txt

+ 

+ If anything complains about having an old version, you can update it with the following, after replacing [packagename] with the package in question::

+ 

+ 	$ pip install --upgrade [packagename]

+ 

+ Configure the project to authenticate against iddev.fedorainfracloud.org::

+ 

+     oidc-register --debug https://iddev.fedorainfracloud.org/ http://localhost:5000

+ 

+ If the previous command complains about an error verifying the certificate, you will want to replace httplib2's ca cert file. Afterward, re-run the above command::

+ 

+     cp /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem

+         ~/.virtualenvs/hubs/lib/python2.7/site-packages/httplib2/cacerts.txt

+ 

+ Create a local configuration file::

+ 

+     echo "OIDC_ID_TOKEN_COOKIE_SECURE = False" > config

+ 

+ With that, try running the app by creating the database::

+ 

+     $ python populate.py  # To create the db

+ 

+ If this fails with a complaint about no module named sanitizer, or something about HTMLsanitizer, you will need to install bleach::

+ 

+ 	$ pip install bleach

+ 

+ Finish running the app by starting the devel server with your local config file. There will be warnings, but you can safely ignore them::

+ 

+     $ python runserver.py -c config  # To run the dev server with our local conf

+ 

+ And then navigate to http://localhost:5000/

+ 

+ If you want to test it with 8 worker threads, try ``gunicorn``::

+ 

+     $ pip install gunicorn

+     $ gunicorn -w 8 -t 60 --log-config logging.ini --reload hubs.app:app -b :5000

+ 

+ Note that then the application is available at http://localhost:8000/

+ 

+ When hacking on widgets, it is useful to have this one-liner handy.  It removes

+ the db alltogether, re-populates it, and restarts the app::

+ 

+     $ rm /var/tmp/hubs.db; rm /var/tmp/fedora-hubs-cache.db; PYTHONPATH=. python populate.py; gunicorn -w 8 -t 240 --log-config logging.ini hubs.app:app -b :5000

+ 

+ 

+ Run the tests!

+ --------------

+ 

+ We have a test suite.  You should run it *before* you start working on some

+ code, to make sure that nothing is broken before you start.  And you should run

+ it after you finish your change, before you push, to verify that your change

+ didn't inadvertently break something else.

+ 

+ You can run it with::

+ 

+     $ pip install -r test-requirements.txt

+     $ ./runtest.sh

+ 

+ 

+ 

+ If the unit tests are all failing and returning errors like this::

+ 

+     ImportError: cannot import name dummy

+ 

+ 

+ It most likely is a result of html5lib breaking api stability. Please downgrade to the version below::

+ 

+     pip install html5lib==0.9999999

+ 

+ 

+ See the options available with::

+ 

+     $ ./runtest.sh --help

+ 

+ You can run the JavaScript tests from ``hubs/static/client`` with::

+     $ npm test

+ 

+ Some credentials...

+ -------------------

+ 

+ You need to add a new file to the ``fedmsg.d/`` directory.

+ Call it ``fedmsg.d/credentials.py``.  It's needed to query FAS

+ for information about other users. When we deploy this thing to

+ production, we'll use a system account for this but for now, just

+ use your personal account. You don't want to accidentally share this

+ with anyone else. so be sure to keep it private.  It should have

+ contents like this::

+ 

+     config = {

+         # Put your FAS credentials here...

+         # but leave them commented out.  Note that, if you leave your fas

+         # credentials out, some widgets won't be as accurate as they could be..

+         # but it also makes the app faster than it would otherwise be (which is

+         # nice for development).

+         #'fas_credentials': {

+         #    'username': 'YOUR_FAS_USERNAME',

+         #    'password': 'YOUR_FAS_PASSWORD',

+         #},

+ 

+         # Go and generate a token for this here:

+         # https://github.com/settings/tokens

+         'github.oauth_token': 'YOUR_GITHUB_TOKEN',

+     }

+ 

+ Make sure to leave the '' around you username and password - don't delete them! Some widgets will work without the above info being present..

+ but it is needed for a subset of them.

+ 

+ JavaScript assets

+ -----------------

+ 

+ Some widgets and pages run on React so to install those dependencies::

+ 

+     $ cd hubs/static/client && npm install

+ 

+ For the Feed and My Stream, change the ``SSE_URL`` location in the ``config`` you created

+ to point to the streaming server then build JavaScript assets. Add ``--w`` for live reloading::

+ 

+     $ cd hubs/static/client && node_modules/.bin/webpack

+ 

+ 

+ My Stream - the Extra Mile

+ --------------------------

+ 

+ One portion of Hubs - the My Stream page - requires more legwork to stand up.

+ If you just want to see how hubs works and you want to hack on other

+ peripheral stuff around it, you don't need to bother with these steps.

+ 

+ The stream requires a direct DB connection to the datanommer

+ database; it can't proxy through datagrepper because it needs more

+ flexibility.  To get this working, you're going to set up:

+ 

+ - a postgres db

+ - the datanommer daemon

+ 

+ Start with some required packages::

+ 

+     $ sudo dnf install postgresql-server python-datanommer-consumer datanommer-commands fedmsg-hub npm

+ 

+ And there are some support libraries you'll also need::

+ 

+     $ sudo dnf install python-psycopg2 python-fedmsg-meta-fedora-infrastructure

+ 

+ Now, with packages installed, you need to tell postgres to create its initial filesystem layout::

+ 

+     $ sudo postgresql-setup initdb

+ 

+ And then, we need to tweak its config to let us connect easily for development::

+ 

+     $ sudo vim /var/lib/pgsql/data/pg_hba.conf

+ 

+ Change **two lines** from ``ident`` to ``trust``.  These two::

+ 

+     # IPv4 local connections:

+     host    all             all             127.0.0.1/32            trust

+     # IPv6 local connections:

+     host    all             all             ::1/128                 trust

+ 

+ Start that beast up::

+ 

+     $ sudo systemctl start postgresql

+ 

+ Now, with the db daemon configured and running, let's configure datanommer.  Edit this file::

+ 

+     $ sudo vim /etc/fedmsg.d/datanommer.py

+ 

+ And do two things:  1) set enabled to ``True`` and 2) give it a real sqlalchemy url, like this::

+ 

+     config = {

+         'datanommer.enabled': True,

+         'datanommer.sqlalchemy.url': 'postgres://postgres:whatever@localhost/datanommer',

+     }

+ 

+ Tell postgres that it should create space for a 'datanommer' database with this command::

+ 

+     $ sudo -u postgres psql -c "CREATE DATABASE datanommer;"

+ 

+ And finally, tell datanommer to create all of its tables in that new db we just created::

+ 

+     $ datanommer-create-db

+ 

+ Tell the fedmsg-hub daemon to restart itself.  It should pick up datanommer as a plugin and start handing messages to it::

+ 

+     $ sudo systemctl restart fedmsg-hub

+ 

+ And then, wait a few seconds for a message to get nommed, and then you can

+ check that it's working by running ``sudo datanommer-stats``.  It should print

+ out some kind of summary about what kinds of messages are in the db now -- it

+ will just grow and grow over time::

+ 

+     $ datanommer-stats

+     [2015-07-01 14:33:21][    fedmsg    INFO] buildsys has 70 entries

+     [2015-07-01 14:33:21][    fedmsg    INFO] faf has 7 entries

+     [2015-07-01 14:33:21][    fedmsg    INFO] copr has 6 entries

+     [2015-07-01 14:33:21][    fedmsg    INFO] askbot has 2 entries

+ 

+ **Lastly**, (fingers crossed) start up the fedora-hubs webapp and load your

+ profile page. Change back to the project root and run::

+ 

+   $ python runserver.py -c config

+ 

+ Once there are some messages that get into your local database

+ that *should* show up on your page. they should appear there.  (At very least,

+ you shouldn't get an error message about that page being unable to be

+ displayed).

+ 

+ Stubbing out a new Widget

+ =========================

+ 

+ You write a new widget in the ``hubs/widgets/`` directory and must declare it

+ in the registry dict in ``hubs/widgets/__init__.py``.

+ 

+ In order to be valid, a widget must have:

+ 

+ - A ``data(session, widgets, **kwargs)`` function that returns a

+   jsonifiable dict of data.  This will get cached -- more on that later.

+ - A ``template`` object that is a jinja2 template for that widget.

+ - Optionally, a ``chrome`` decorator.

+ - A ``should_invalidate(message, session, widget)`` function that will be used to

+   *potentially* invalidate the widget's cache. That function will get called by

+   a backend daemon listening for fedmsg messages so when you update your group

+   memberships in FAS, a fedmsg message hits the fedora-hubs backend and returns

+   True if the lookup value should be nuked/refreshed in memcached (or some

+   other store).

+ 

+ If you want to try making a new widget:

+ 

+ - Copy an existing one in ``hubs/widgets/``

+ - Add it to the registry in ``hubs/widgets/__init__.py``

+ - If you want it to show up on a **user** page, add it to ``hubs/defaults.py``

+   in the ``add_user_widgets`` function.

+ - If you want it to show up on **group** pages, add it to ``populate.py``.

+ 

+ Destroy your database, rebuild it, and re-run the app.  Your widget should show up.

+ 

+ A proposal, client-side templates

+ =================================

+ 

+ - The template per-widget is currently held and rendered *server-side* with

+   jinja2.  This is how all our apps do it, more or less.

+ 

+   We might want to consider using handlebars.js for our templates instead and

+   rendering all of the widgets asynchronously on the client.  It could be cool,

+   but is new-ground for our team.

+ 

+   Furthermore, we should likely use something like angular **or** backbone.js

+   to manage the data synchronization with those client-side templates.

+ 

+ Some discussion on how to do pushed updates to web clients:

+ 

+ - We could re-use the existing websocket service we have at

+   ``wss://hub.fedoraproject.org:9939`` but it has some problems:

+ - It is very inflexible.  You can subscribe to fedmsg *topics* and then you

+   receive the firehose of those topics. For a widget, we already have to write

+   a 'cache invalidation' function that listens for messages and then somehow

+   knows to invalidate the cache *for a widget* based on some of those messages.

+   If we re-used the firehose on the client, we would have to write that

+   function *twice* for *each widget*, once in python to invalidate the server's

+   memcached cache when a fedmsg message comes in and once in javascript to tell

+   the client to reload and redraw a oprtion of itself when a fedmsg comes in

+   over the websocket firehose.

+ - Instead, let's give fedora-hubs its own *widget-specific* `EventSource

+   <https://developer.mozilla.org/en-US/docs/Web/API/EventSource>`_ server that

+   we tie in to the server-side cache-invalidation backend code.  I.e., when a

+   message comes into the backend, it runs all the cache invalidation checkers

+   to see which widgets' caches should be refreshed, and once they are refreshed

+   we can emit events over EventSource to tell only *those* widgets on any

+   connected clients to redraw themselves.

+ 

+ As an aside, it became clear to me when making the diagram in the next section

+ that, if we use handlebars.js and get rid of the server-side template

+ rendering, then 1) the data returned by AJAX requests at page load and 2) the

+ data pushed by the EventSource server can be *the exact same data*.  It will

+ simplify and streamline the responsibilities of the pieces if the backend is

+ worried *only* about these per-widget JSON responses.

+ 

+ A picture is worth...

+ ---------------------

+ 

+ Here are some more details on how the whole thing should work together.

+ 

+ .. figure:: diagram.png

+    :scale: 50 %

+    :alt: A diagram of component interactions

+ 

+    A diagram of component interactions

+ 

+ Let's talk through how data will flow through the system by asking *what

+ happens when a user requsts their main hubs page*:

+ 

+ - The user requests the page and the wsgi app responds with some barebones HTML

+   and enough javascript to get off the ground.

+ - The user's browser runs javascript that *subscribes* it to the EventSource server.

+ - The user's browser runs that javascript, which requests data for each of the

+   widgets defined on the page.

+ - The wsgi app receives those requests and checks to see if the data for any of

+   them is *cached in memcached*.  If it is, then it is returned.  If not, then

+   the wsgi app executes the ``data(...)`` function of that widget to get the

+   response ready.  It is stuffed in memcached for later access and returned.

+ - The client renders widgets as the data for each of its requests comes back.

+ 

+ Later, what happens when a *trac ticket* is filed that should show up in some widget on their page?

+ 

+ - The ticket is updated on fedorahosted.org and a fedmsg message is fired.

+ - That is received by the hubs backend, which looks up *all* the cached

+   responses that should be invalidated by that event (there is a widget on

+   mizmo's page, threebean's page, and on the design hub that should all get

+   fresh data because of this change).

+ - All of those widgets get their cached data nuked.

+ - All of those widgets get their cached data rebuilt by calling ``data(...)`` on them.

+ - An EventSource event is fired off for any listening clients that *new data is

+   available for widgets X, Y, and Z*.  The data is included in the EventSource

+   payload so the clients can immediately redraw without bothering to re-query

+   the wsgi app.

+ 

+ What happens when the user is viewing the *design team* hub and

+ simultaneously, an admin *changes the configuration of a widget on that page*?

+ 

+ - Changing the configuration results in a HTTP POST to the wsgi app.

+ - The configuration is changed accordingly in the postgres database.

+ - A fedmsg message is fired off indicating that *the configuration for widget X

+   has changed*.

+ - The wsgi app responds 200 OK to the admin.

+ - Meanwhile, that fedmsg message is received by the backend which:

+ - ...looks up the cache key for *widget X with the old configuration* and nukes

+   it the cached data.

+ - ...looks up the cache key for *widget X with the new configuration* and

+   builds the cached data by calling ``data(...)`` on the widget.

+ - An EventSource event is fired off which gets recieved by everyone looking at

+   the *design team hub*.  The widget on their pages gets redrawn with data from

+   the EventSource event.

file added
+24
@@ -0,0 +1,24 @@ 

+ .. fedora-hubs documentation master file, created by

+    sphinx-quickstart on Wed Sep 21 16:41:24 2016.

+    You can adapt this file completely to your liking, but it should at least

+    contain the root `toctree` directive.

+ 

+ Welcome to Fedora Hubs' documentation!

+ ======================================

+ 

+ Contents:

+ 

+ .. toctree::

+    :maxdepth: 2

+ 

+    overview

+    dev-guide

+ 

+ 

+ Indices and tables

+ ==================

+ 

+ * :ref:`genindex`

+ * :ref:`modindex`

+ * :ref:`search`

+ 

file added
+37
@@ -0,0 +1,37 @@ 

+ Fedora Hubs Overview

+ ====================

+ 

+ Fedora Hubs is a web application that will provide a communication and collaboration

+ center for Fedora contributors of all types. It aims to integrate with all the various

+ tools teams use and provide a consistent experience for contributors across projects

+ and teams.

+ 

+ Without Fedora Hubs the Fedora web presence is very static. All of the action is on

+ mailing lists and IRC which can be intimidating to new contributors. The vision is

+ to have a modern, web-based Fedora activity center which feels like the positive,

+ connected energy of Flock or FUDCon, available to all of us at any time.

+ 

+ Integration

+ ^^^^^^^^^^^

+ 

+ Fedora Hubs integrates with, or plans to integrate with, the following tools and projects:

+ 

+ * IRC integration via the `Waartaa project <https://github.com/waartaa/waartaa>`_.

+ 

+ * `Fedora Badges <https://badges.fedoraproject.org/>`_ integration.

+ 

+ * `Mailing list <https://lists.fedoraproject.org/archives/>`_ integration via

+   `HyperKitty <https://gitlab.com/mailman/hyperkitty>`_.

+ 

+ * `Fedora Planet <http://fedoraplanet.org/>`_ and `Fedora Magazine <https://fedoramagazine.org/>`_

+   integration.

+ 

+ * `Zanata <https://fedora.zanata.org/>`_ integration.

+ 

+ * Plusplus widget to award cookies, just like IRC.

+ 

+ If you would like to know more, `these blog posts / videos

+ <http://blog.linuxgrrl.com/category/fedora/fedora-hubs/>`_ are packed with lots of

+ information about our vision for the project, or check out the

+ `issue tracker <https://pagure.io/fedora-hubs/issues/>`_ to see what features are

+ planned.

This commit adds a Sphinx project with the existing README (split into a
few different files) and some additional or updated documentation.

Signed-off-by: Jeremy Cline jeremy@jcline.org

It's worth noting that I did copy my development docs from the vagrantfile branch, but I wanted to see it all together. I'll resolve the difference when one branch or the other gets merged.

Can we change AUTHORS to Red Hat, Inc. and others.

Do we need to add the hubsup instruction here.

rebased

7 years ago

rebased

7 years ago

I updated the AUTHORS and added a bit more detail to the Vagrant setup.

There are a few links in the README to what I expect the docs hosting location on Pagure to be (https://docs.pagure.io/fedora-hubs/overview.html for example), but I assume a switch needs to get flipped in the repository configuration before the docs are built and hosted there.

rebased

7 years ago

Pull-Request has been merged by sayanchowdhury

7 years ago