Skip to content

Commit

Permalink
Static Website & deployment (facebookresearch#1544)
Browse files Browse the repository at this point in the history
* Static website builder.
  • Loading branch information
stephenroller authored Mar 25, 2019
1 parent 1182d35 commit 679d7d4
Show file tree
Hide file tree
Showing 20 changed files with 2,211 additions and 8 deletions.
27 changes: 27 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ commands:
. ~/venv/bin/activate
pip3 install --upgrade --progress-bar off pip
pip3 install --progress-bar off flake8 gitpython
python setup.py develop
installdeps:
description: "Installs all dependencies"
Expand Down Expand Up @@ -144,13 +145,39 @@ jobs:
name: All nightly CPU tests
command: python setup.py test -s tests.suites.nightly_cpu -q

deploy_website:
executor: standard_cpu
working_directory: ~/ParlAI
steps:
- checkout
- setup
- installdeps
- installtorchcpu
- run:
working_directory: ~/ParlAI/website
name: Build the website
command: make
- run:
working_directory: ~/ParlAI/
name: Upload the website
command: |
sudo apt-get install s3cmd
s3cmd --access_key="${S3_ACCESS_KEY}" --secret_key="${S3_SECRET_KEY}" sync -f --delete-removed website/build/ "s3://parl.ai/"
s3cmd --access_key="${S3_ACCESS_KEY}" --secret_key="${S3_SECRET_KEY}" setacl --acl-public --recursive "s3://parl.ai/"
s3cmd --access_key="${S3_ACCESS_KEY}" --secret_key="${S3_SECRET_KEY}" modify --add-header="Content-type:text/css" 's3://parl.ai/static/css/*' 's3://parl.ai/docs/_static/*.css' 's3://parl.ai/docs/_static/css/*.css'
workflows:
version: 2
commit:
jobs:
- lint
- datatests
- unittests
- deploy_website:
filters:
branches:
only: master
nightly:
triggers:
- schedule:
Expand Down
3 changes: 1 addition & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h2>News</h2>
## News

2019-03-15: The [Wizard of Wikipedia project page](http://parl.ai/projects/wizard_of_wikipedia/) is updated with pretrained models and specialized model code.

Expand All @@ -24,7 +24,6 @@

2018-04-13: [NIPS ConvAI2 competition!](http://convai.io/) Train Dialogue Agents to chat about personal interests and get to know their dialogue partner -- using the PersonaChat dataset as a training source, with data and baseline code in ParlAI. Competition starts now! Ends September 1st.


2018-03-13: Added [ParlAI-Messenger](http://parl.ai/static/docs/messenger.html), a new method for connecting human agents to a world in ParlAI using Facebook Messenger. Host your bots on Facebook Messenger to expose them to a broad audience!

2018-03-07: Added [IBM's sequence to sequence](https://github.com/IBM/pytorch-seq2seq) model to parlai/agents. To use it, just set --model ibm_seq2seq.
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Its goal is to provide researchers:
- many popular datasets available all in one place -- from open-domain chitchat to visual question answering.
- a wide set of reference models -- from retrieval baselines to Transformers.
- seamless integration of [Amazon Mechanical Turk](https://www.mturk.com/mturk/welcome) for data collection and human evaluation
- integration with [Facebook Messenger](http://www.parl.ai/static/docs/tutorial_messenger.html) to connect agents with humans in a chat interface
- integration with [Facebook Messenger](http://www.parl.ai/docs/tutorial_messenger.html) to connect agents with humans in a chat interface

Many [tasks](https://github.com/facebookresearch/ParlAI/blob/master/parlai/tasks/task_list.py) are supported, including popular datasets such as [SQuAD](https://rajpurkar.github.io/SQuAD-explorer/), [bAbI tasks](https://arxiv.org/abs/1502.05698), [MS MARCO](http://www.msmarco.org/), [MCTest](https://www.microsoft.com/en-us/research/publication/mctest-challenge-dataset-open-domain-machine-comprehension-text/), [WikiQA](https://www.microsoft.com/en-us/download/details.aspx?id=52419), [WebQuestions](http://www.aclweb.org/anthology/D13-1160), [SimpleQuestions](https://arxiv.org/abs/1506.02075), [WikiMovies](https://arxiv.org/abs/1606.03126), [QACNN & QADailyMail](https://arxiv.org/abs/1506.03340), [CBT](https://arxiv.org/abs/1511.02301), [BookTest](https://arxiv.org/abs/1610.00956), [bAbI Dialogue tasks](https://arxiv.org/abs/1605.07683), [Ubuntu Dialogue](https://arxiv.org/abs/1506.08909), [OpenSubtitles](http://opus.lingfil.uu.se/OpenSubtitles.php), [Cornell Movie](https://www.cs.cornell.edu/~cristian/Cornell_Movie-Dialogs_Corpus.html), [VQA-COCO2014](http://visualqa.org/), [VisDial](https://arxiv.org/abs/1611.08669) and [CLEVR](http://cs.stanford.edu/people/jcjohns/clevr/). See [here](https://github.com/facebookresearch/ParlAI/blob/master/parlai/tasks/task_list.py) for the current complete task list.

Expand Down Expand Up @@ -150,7 +150,7 @@ All agents (including teachers) speak to each other with a single format -- the
This is used to pass text, labels, rewards, and more between agents.
It’s the same object type when talking (acting) or listening (observing), but a different view (i.e. with different values in the fields).

The observation/action dict fields are as follows (or see [the documentation](http://parl.ai/static/docs/observations.html)):
The observation/action dict fields are as follows (or see [the documentation](http://parl.ai/docs/observations.html)):

<p align=center><img width="33%" src="docs/source/\_static/img/act-obs-dict.png" /></p>

Expand Down Expand Up @@ -279,7 +279,7 @@ Each task folder contains:
- **agents.py** file which contains default or special teacher classes used by core.create_task to instantiate these classes from command-line arguments (if desired).
- **worlds.py** file can optionally be added for tasks that need to define new/complex environments.

To add your own task, see the [tutorial](http://www.parl.ai/static/docs/tutorial_task.html).
To add your own task, see the [tutorial](http://www.parl.ai/docs/tutorial_task.html).


### MTurk
Expand Down Expand Up @@ -316,11 +316,11 @@ To add your own MTurk task:
- implement __run.py__, with code for setting up and running the world where `MTurkAgent` lives in.
- (Optional) implement __worlds.py__, with a world class that extends from `World`.

Please see [the MTurk tutorial](http://parl.ai/static/docs/tutorial_mturk.html) to learn more about the MTurk examples and how to create and run your own task.
Please see [the MTurk tutorial](http://parl.ai/docs/tutorial_mturk.html) to learn more about the MTurk examples and how to create and run your own task.

### Messenger

Please see [the Facebook Messenger tutorial](http://parl.ai/static/docs/tutorial_messenger.html) to learn more about how to use ParlAI with Facebook Messenger.
Please see [the Facebook Messenger tutorial](http://parl.ai/docs/tutorial_messenger.html) to learn more about how to use ParlAI with Facebook Messenger.


## Support
Expand Down
2 changes: 1 addition & 1 deletion docs/source/_static/css/parlai_theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ h1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend, p.capti
font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
}

nav p.caption {
.wy-menu.wy-menu-vertical p.caption {
color: #fcfcfc;
}

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ joblib
nltk
numpy
pexpect
py-gfm
pyzmq
regex
requests
Expand Down
11 changes: 11 additions & 0 deletions website/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
all: clean
python generate.py
cd ../docs; make html
pwd
cp -a ../docs/build/html build/docs
cp -a static build/
python postprocess_docs.py

clean:
rm -rf build/*

5 changes: 5 additions & 0 deletions website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This is the code to build the parlai website.

- `generate.py`: does the actual rendering
- `static`: assets in this folder will be copied verbatim to parl.ai/static/
- `templates`: contains html templates for a variety of pages
129 changes: 129 additions & 0 deletions website/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env python

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

"""
Builds the ParlAI website.
"""

import os
import git
import markdown
from mdx_gfm import PartialGithubFlavoredMarkdownExtension

GIT_ROOT_LEVEL = git.Git().rev_parse('--show-toplevel')
WEBSITE_ROOT = os.path.join(GIT_ROOT_LEVEL, 'website')
TEMPLATES = os.path.join(WEBSITE_ROOT, 'templates')
OUT_DIR = os.path.join(WEBSITE_ROOT, 'build')


def ghmarkdown(source):
return markdown.markdown(
source,
extensions=[PartialGithubFlavoredMarkdownExtension()]
)


def _read_file(filename):
with open(filename) as f:
return f.read()


def _mkdirp(directory):
"""Equivalent to mkdir -p"""
if not os.path.exists(directory):
os.makedirs(directory)


def _write_file(partial_filename, content):
filename = os.path.join(OUT_DIR, partial_filename)

_mkdirp(os.path.dirname(filename))

print("writing {} bytes to {}".format(len(content), filename))
with open(filename, 'w') as f:
f.write(content)


def wrap_base(content, title):
template = _read_file(os.path.join(TEMPLATES, 'base.html'))
template = template.replace('{{{CONTENT}}}', content)
template = template.replace('{{{TITLE}}}', title)
return template


def make_errorpage():
content = _read_file(os.path.join(TEMPLATES, 'error.html'))
html = wrap_base(content, "Error")
_write_file('error.html', html)


def make_aboutpage():
template = _read_file(os.path.join(TEMPLATES, 'about.html'))
readme = _read_file(os.path.join(GIT_ROOT_LEVEL, 'README.md'))
readme_html = ghmarkdown(readme)
readme_html = readme_html.replace("docs/source/\\", "/docs/")
content = template.replace('{{{CONTENT}}}', readme_html)
html = wrap_base(content, "About | ParlAI")
_write_file('about/index.html', html)


def make_homepage():
template = _read_file(os.path.join(TEMPLATES, 'home.html'))
news = _read_file(os.path.join(GIT_ROOT_LEVEL, 'NEWS.md'))
news = news.replace('## News', '')
news_html = ghmarkdown(news)
content = template.replace('{{{CONTENT}}}', news_html)
html = wrap_base(content, "ParlAI")
_write_file('index.html', html)


def make_projects_landing():
template = _read_file(os.path.join(TEMPLATES, 'project.html'))
landing = _read_file(os.path.join(GIT_ROOT_LEVEL, 'projects/README.md'))
landing = landing.replace(
'This directory also contains subfolders for some of the projects which are '
'housed in the ParlAI repo, others are maintained via external websites. '
'Please also refer',
'See the [ParlAI projects](https://github.com/facebookresearch/ParlAI/'
'tree/master/projects) page on GitHub for more information. Refer'
)
landing_html = template.replace('{{{CONTENT}}}', ghmarkdown(landing))
html = wrap_base(landing_html, "Projects | ParlAI")
_write_file('projects/index.html', html)


def make_projects_individual():
template = _read_file(os.path.join(TEMPLATES, 'project.html'))
projects_dir = os.path.join(GIT_ROOT_LEVEL, 'projects')
possible_projects = os.listdir(projects_dir)
projects = [
pp for pp in possible_projects
if os.path.exists(os.path.join(projects_dir, pp, 'README.md'))
]
for p in projects:
content = _read_file(os.path.join(projects_dir, p, 'README.md'))
content_html = template.replace('{{{CONTENT}}}', ghmarkdown(content))
content_html = content_html.replace(
'src="',
'src="https://raw.githubusercontent.com/facebookresearch/'
'ParlAI/master/projects/{}'
.format(p + '/' if p else '')
)
title = p.title().replace("_", " ")
html = wrap_base(content_html, title)
_write_file(os.path.join('projects', p, 'index.html'), html)


def main():
make_errorpage()
make_homepage()
make_aboutpage()
make_projects_landing()
make_projects_individual()


if __name__ == '__main__':
main()
32 changes: 32 additions & 0 deletions website/postprocess_docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import os

NEEDLE1 = '<a href="#" class="icon icon-home"> ParlAI'
NEEDLE2 = '<a href="index.html" class="icon icon-home"> ParlAI'
REPLACEMENT = """
<a href="/" style="float: left">
<img style="padding: 0px; background-color: #fff; width: 53px; height: 53px; margin-left: 70px;" src="/static/img/icon.png">
</a>
<a href="/" style="color: #000; float: left; margin-top: 12px; font-size: 20px; font-weight: 600">
ParlAI
</a>
""" # noqa: E501


if __name__ == '__main__':
for root, dirs, files in os.walk("build/docs/"):
for file in files:
if file.endswith(".html"):
file_path = os.path.join(root, file)
print("Postprocessing ", file_path)
with open(file_path, 'r') as fin:
content = fin.read()
content = content.replace(NEEDLE1, REPLACEMENT)
content = content.replace(NEEDLE2, REPLACEMENT)
with open(file_path, 'w') as fout:
fout.write(content)
Loading

0 comments on commit 679d7d4

Please sign in to comment.