From 4edca371681593230c869741e59a8d558cc2aed3 Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Sun, 2 Oct 2016 13:08:37 +0300 Subject: [PATCH] Init documentation Closes #34 --- .gitignore | 3 + .travis.yml | 2 +- CHANGELOG.md | 2 + README.md | 15 +- dev-requirements.txt | 17 ++ docs/Makefile | 225 +++++++++++++++ docs/_static/.placeholder | 0 docs/_templates/.placeholder | 0 docs/changelog.md | 1 + docs/conf.py | 353 ++++++++++++++++++++++++ docs/development.rst | 37 +++ docs/index.rst | 30 ++ docs/install.rst | 19 ++ docs/introduction.rst | 21 ++ docs/make.bat | 281 +++++++++++++++++++ docs/protocols.rst | 30 ++ docs/usage.rst | 127 +++++++++ federation/entities/diaspora/mappers.py | 8 +- federation/exceptions.py | 4 + federation/fetchers.py | 7 +- federation/hostmeta/generators.py | 61 ++-- federation/inbound.py | 11 +- federation/outbound.py | 12 +- federation/utils/diaspora.py | 40 +-- federation/utils/network.py | 38 +-- test-requirements.txt | 6 - 26 files changed, 1231 insertions(+), 119 deletions(-) create mode 100644 dev-requirements.txt create mode 100644 docs/Makefile create mode 100644 docs/_static/.placeholder create mode 100644 docs/_templates/.placeholder create mode 120000 docs/changelog.md create mode 100644 docs/conf.py create mode 100644 docs/development.rst create mode 100644 docs/index.rst create mode 100644 docs/install.rst create mode 100644 docs/introduction.rst create mode 100644 docs/make.bat create mode 100644 docs/protocols.rst create mode 100644 docs/usage.rst delete mode 100644 test-requirements.txt diff --git a/.gitignore b/.gitignore index 51200c4..1b8e46b 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,6 @@ nosetests.xml # PyCharm .idea/ + +# Docs +docs/_build diff --git a/.travis.yml b/.travis.yml index c64a444..596e5ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ cache: directories: - $HOME/.cache/pip install: - - pip install -r test-requirements.txt -U + - pip install -r dev-requirements.txt -U - python setup.py develop - pip freeze script: py.test --cov=./ diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b9af5..8ed2d70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# Changelog + ## [unreleased] ### Backwards incompatible changes diff --git a/README.md b/README.md index 95a0709..216ca5c 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,21 @@ Python library to abstract social federation protocols. Currently supports a sub * Python 3.x -## Testing +## Development -Install requirements: +Install requirements first: - pip install -r test-requirements.txt - -Run tests: + pip install -r dev-requirements.txt + +### Running tests py.test +### Building local docs + + cd docs + make html + ## License BSD 3-clause license (https://www.tldrlegal.com/l/bsd3). diff --git a/dev-requirements.txt b/dev-requirements.txt new file mode 100644 index 0000000..49f40a1 --- /dev/null +++ b/dev-requirements.txt @@ -0,0 +1,17 @@ +## Requirements for local development + +# Package deps from setup.py +-e . + +# Tests +pytest +factory_boy +codecov +coverage +pytest-cov +pytest-warnings + +# Docs +sphinx +sphinx-autobuild +recommonmark diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..a894bcd --- /dev/null +++ b/docs/Makefile @@ -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 ' where 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/Social-Federation.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Social-Federation.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/Social-Federation" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Social-Federation" + @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." diff --git a/docs/_static/.placeholder b/docs/_static/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/docs/_templates/.placeholder b/docs/_templates/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/docs/changelog.md b/docs/changelog.md new file mode 120000 index 0000000..04c99a5 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..8f77e8f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,353 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from recommonmark.parser import CommonMarkParser + +from federation import __version__ + +# +# Social-Federation documentation build configuration file, created by +# sphinx-quickstart on Sun Oct 2 12:42:19 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 = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.coverage', + 'sphinx.ext.viewcode', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# Add Markdown support +source_parsers = { + '.md': CommonMarkParser, +} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ['.rst', '.md'] + +# The encoding of source files. +# +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Social-Federation' +copyright = '2016, Jason Robinson' +author = 'Jason Robinson' + +# 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 = __version__ +# The full version, including alpha/beta/rc tags. +release = __version__ + +# 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. +# " v documentation" by default. +# +# html_title = 'Social-Federation v0.8.0' + +# 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 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', 'h', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'r', '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 = 'Social-Federationdoc' + +# -- 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, 'Social-Federation.tex', 'Social-Federation Documentation', + 'Jason Robinson', '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, 'social-federation', 'Social-Federation 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, 'Social-Federation', 'Social-Federation Documentation', + author, 'Social-Federation', '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 + diff --git a/docs/development.rst b/docs/development.rst new file mode 100644 index 0000000..a3c0e2f --- /dev/null +++ b/docs/development.rst @@ -0,0 +1,37 @@ +Development +=========== + +Help is more than welcome to extend this library. Please see the following resources. + +* `Source code repo `_ +* `Issue tracker `_ +* `Kanban board `_ + +Environment setup +----------------- + +Once you have your (Python 3.3+) virtualenv set up, install the development requirements:: + + pip install -r dev-requirements.txt + +Running tests +------------- + +:: + + py.test + +Building local documentation +---------------------------- + +:: + + cd docs + make html + +Contact for help +---------------- + +Easiest via FreeNode IRC, channel #socialfederation (`webchat here `_). + +You can also ask questions or give feedback via issues. diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..32c7711 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,30 @@ +.. Social-Federation documentation master file, created by + sphinx-quickstart on Sun Oct 2 12:42:19 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Social-Federation's documentation! +============================================= + +Python library to abstract social federation protocols. Currently supports a subset of the Diaspora protocol with full support intended, and additional protocols after that. + +Contents: + +.. toctree:: + :maxdepth: 2 + + introduction + install + protocols + usage + development + changelog + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..658f8ec --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,19 @@ +Install +======= + +Dependencies +------------ + +Depending on your operating system, certain dependencies will need to be installed. + +lxml +.... + +lxml itself is installed by pip but the dependencies need to be installed `as per lxml instructions `_. + +Installation +------------ + +Install with pip or include in your requirements file.:: + + pip install Social-Federation diff --git a/docs/introduction.rst b/docs/introduction.rst new file mode 100644 index 0000000..d4e6a67 --- /dev/null +++ b/docs/introduction.rst @@ -0,0 +1,21 @@ +Introduction +============ + +The aim of Social-Federation is to provide and abstract multiple social web protocols like Diaspora in one package. This way applications can be built to (almost) transparently support many protocols without the app builder having to know everything about those protocols. + +Status +------ + +Currently the library supports a part of the Diaspora protocol with remaining parts being constantly added. See the :ref:`diaspora` protocol page for support status. + +The code base is well tested and in use in several projects. A lot of backward incompatible changes will however be made at this stage still, however those will be clearly documented in changelog entries. + +.. _example-projects: + +Projects using Social-Federation +-------------------------------- + +For examples on how to integrate this library into your project, check these examples: + +* `Socialhome `_ - a federated home page builder slash personal social network server with high emphasis on card style content visualization. +* `Social-Relay `_ - a reference server for the public content relay system that uses the Diaspora protocol. diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..e8b8618 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,281 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ 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. 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. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over 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 + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 1>NUL 2>NUL +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Social-Federation.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Social-Federation.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "epub3" ( + %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +if "%1" == "dummy" ( + %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. Dummy builder generates no files. + goto end +) + +:end diff --git a/docs/protocols.rst b/docs/protocols.rst new file mode 100644 index 0000000..5ecc1c2 --- /dev/null +++ b/docs/protocols.rst @@ -0,0 +1,30 @@ +Protocols +========= + +.. _diaspora: + +Diaspora +-------- + +Currently the library supports a part of the protocol with remaining parts being constantly added. + +Note! Diaspora project is currently rewriting parts of the protocol. This library aims to support the `new version `_. When possible, compatibility will be kept with the current and legacy versions but this is not the main objective. + +The feature set supported by this release is approximately the following: + +* WebFinger, hCard and other discovery documents +* NodeInfo 1.0 documents +* Social-Relay documents +* Magic envelopes, signatures and other transport method related necessities +* Entities as follows: + * Comment + * Like + * Photo + * Profile + * Retraction + * StatusMessage + +Implementation unfortunately currently requires knowledge of how Diaspora discovery works a +s the implementer has to implement all the necessary views correctly (even though this library provides document generators). However, the magic envelope, signature and entity building is all abstracted inside the library. + +For example implementations in real life projects check :ref:`example-projects`. diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..f3ecd98 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,127 @@ +Usage +===== + + +Entities +-------- + +Social-Federation has it's own base entity classes. When incoming messages are processed, the protocol specific entity mappers transform the messages into our base entities. In reverse, when creating outgoing payloads, outgoing protocol specific messages are constructed from the base entities. + +Entity types are as follows below. + +.. autoclass:: federation.entities.base.Comment +.. autoclass:: federation.entities.base.Image +.. autoclass:: federation.entities.base.Post +.. autoclass:: federation.entities.base.Profile +.. autoclass:: federation.entities.base.Reaction +.. autoclass:: federation.entities.base.Relationship +.. autoclass:: federation.entities.base.Retraction + +Protocol entities +................. + +Each protocol additionally has it's own variants of the base entities, for example Diaspora entities in ``federation.entities.diaspora.entities``. All the protocol specific entities subclass the base entities so you can safely work with for example ``DiasporaPost`` and use ``isinstance(obj, Post)``. + +When creating incoming objects from messages, protocol specific entity classes are returned. This is to ensure protocol specific extra attributes or methods are passed back to the caller. + +For sending messages out, either base or protocol specific entities can be passed to the outbound senders. Base entities should be preferred unless the caller knows which protocol to send to. + +If you need the correct protocol speficic entity class from the base entity, each protocol will define a ``get_outbound_entity`` function, for example the Diaspora function as follows. + +.. autofunction:: federation.entities.diaspora.mappers.get_outbound_entity + + +Discovery +--------- + +Social-Federation provides many generators to allow providing the discovery documents that are necessary for the Diaspora protocol for example. The have been made as Pythonic as possible so that library users don't have to meddle with the various documents and their internals. Since each web framework will have it's own way of constructing views, one will still have to provide the view code to call the generators. + +The protocols themselves are too complex to document within this library, please consult protocol documentation on what kind of discovery documents are expected to be served by the application. + +Generators +.......... + +Helper methods +++++++++++++++ + +.. autofunction:: federation.hostmeta.generators.generate_host_meta +.. autofunction:: federation.hostmeta.generators.generate_legacy_webfinger +.. autofunction:: federation.hostmeta.generators.generate_hcard +.. autofunction:: federation.hostmeta.generators.get_nodeinfo_well_known_document + +Generator classes ++++++++++++++++++ + +.. autoclass:: federation.hostmeta.generators.DiasporaHostMeta +.. autoclass:: federation.hostmeta.generators.DiasporaWebFinger +.. autoclass:: federation.hostmeta.generators.DiasporaHCard +.. autoclass:: federation.hostmeta.generators.NodeInfo +.. autoclass:: federation.hostmeta.generators.SocialRelayWellKnown + + +Fetchers +-------- + +High level utility functions to fetch remote objects. These should be favoured instead of protocol specific utility functions. + +.. autofunction:: federation.fetchers.retrieve_remote_profile + + +Inbound +------- + +High level utility functions to pass incoming messages to. These should be favoured instead of protocol specific utility functions. + + +.. autofunction:: federation.inbound.handle_receive + + +Outbound +-------- + +High level utility functions to pass outbound entities to. These should be favoured instead of protocol specific utility functions. + +.. autofunction:: federation.outbound.handle_create_payload + + +Protocols +--------- + +The code for opening and creating protocol messages lives under each protocol module in ``federation.protocols``. Currently Diaspora protocol is the only protocol supported. + +Each protocol defines a ``protocol.Protocol`` class under it's own module. This is expected to contain certain methods that are used by the higher level functions that are called on incoming messages and when sending outbound messages. Everything that is needed to transform an entity into a message payload and vice versa should be here. + +Instead of calling methods directly for a specific protocol, higher level generic functions should be normally used. + + +Utils +----- + +Various utils are provided for internal and external usage. + +Diaspora +........ + +.. autofunction:: federation.utils.diaspora.parse_profile_from_hcard +.. autofunction:: federation.utils.diaspora.retrieve_and_parse_profile +.. autofunction:: federation.utils.diaspora.retrieve_diaspora_hcard +.. autofunction:: federation.utils.diaspora.retrieve_diaspora_webfinger +.. autofunction:: federation.utils.diaspora.retrieve_diaspora_host_meta + +Network +....... + +.. autofunction:: federation.utils.network.fetch_document +.. autofunction:: federation.utils.network.send_document + + +Exceptions +---------- + +Various custom exception classes might be returned. + +.. autoexception:: federation.exceptions.EncryptedMessageError +.. autoexception:: federation.exceptions.NoHeaderInMessageError +.. autoexception:: federation.exceptions.NoSenderKeyFoundError +.. autoexception:: federation.exceptions.NoSuitableProtocolFoundError + diff --git a/federation/entities/diaspora/mappers.py b/federation/entities/diaspora/mappers.py index e860c76..50dc1ff 100644 --- a/federation/entities/diaspora/mappers.py +++ b/federation/entities/diaspora/mappers.py @@ -117,11 +117,9 @@ def get_outbound_entity(entity): We might have to look at entity values to decide the correct outbound entity. If we cannot find one, we should raise as conversion cannot be guaranteed to the given protocol. - Args: - entity - any of the base entity types from federation.entities.base - - Returns: - An instance of the correct protocol specific entity. + :arg entity: An entity instance which can be of a base or protocol entity class. + :returns: Protocol specific entity class instance. + :raises ValueError: If conversion cannot be done. """ cls = entity.__class__ if cls in [DiasporaPost, DiasporaRequest, DiasporaComment, DiasporaLike, DiasporaProfile, DiasporaRetraction]: diff --git a/federation/exceptions.py b/federation/exceptions.py index 9b97c26..9c4d468 100644 --- a/federation/exceptions.py +++ b/federation/exceptions.py @@ -1,14 +1,18 @@ class EncryptedMessageError(Exception): + """Encrypted message could not be opened.""" pass class NoHeaderInMessageError(Exception): + """Message payload is missing required header.""" pass class NoSenderKeyFoundError(Exception): + """Sender private key was not available to sign a payload message.""" pass class NoSuitableProtocolFoundError(Exception): + """No suitable protocol found to pass this payload message to.""" pass diff --git a/federation/fetchers.py b/federation/fetchers.py index a873fa2..46b9a5d 100644 --- a/federation/fetchers.py +++ b/federation/fetchers.py @@ -10,11 +10,8 @@ def retrieve_remote_profile(handle): Currently, due to no other protocols supported, always use the Diaspora protocol. - Args: - handle (str) - The profile handle in format username@domain.tld - - Returns: - Profile or None + :arg handle: The profile handle in format username@domain.tld + :returns: ``federation.entities.base.Profile`` or ``None`` """ protocol_name = "diaspora" utils = importlib.import_module("federation.utils.%s" % protocol_name) diff --git a/federation/hostmeta/generators.py b/federation/hostmeta/generators.py index b7a627e..9a837d2 100644 --- a/federation/hostmeta/generators.py +++ b/federation/hostmeta/generators.py @@ -13,12 +13,10 @@ from xrd import XRD, Link, Element def generate_host_meta(template=None, *args, **kwargs): """Generate a host-meta XRD document. - Args: - template (str, optional) - Ready template to fill with args, for example "diaspora". - **kwargs - Template specific key-value pairs to fill in, see classes. + Template specific key-value pairs need to be passed as ``kwargs``, see classes. - Returns: - str - XRD document + :arg template: Ready template to fill with args, for example "diaspora" (optional) + :returns: Rendered XRD document (str) """ if template == "diaspora": hostmeta = DiasporaHostMeta(*args, **kwargs) @@ -30,12 +28,10 @@ def generate_host_meta(template=None, *args, **kwargs): def generate_legacy_webfinger(template=None, *args, **kwargs): """Generate a legacy webfinger XRD document. - Args: - template (str, optional) - Ready template to fill with args, for example "diaspora". - **kwargs - Template specific key-value pairs to fill in, see classes. + Template specific key-value pairs need to be passed as ``kwargs``, see classes. - Returns: - str - XRD document + :arg template: Ready template to fill with args, for example "diaspora" (optional) + :returns: Rendered XRD document (str) """ if template == "diaspora": webfinger = DiasporaWebFinger(*args, **kwargs) @@ -47,12 +43,10 @@ def generate_legacy_webfinger(template=None, *args, **kwargs): def generate_hcard(template=None, **kwargs): """Generate a hCard document. - Args: - template (str, optional) - Ready template to fill with args, for example "diaspora". - **kwargs - Template specific key-value pairs to fill in, see classes. + Template specific key-value pairs need to be passed as ``kwargs``, see classes. - Returns: - str - HTML document + :arg template: Ready template to fill with args, for example "diaspora" (optional) + :returns: HTML document (str) """ if template == "diaspora": hcard = DiasporaHCard(**kwargs) @@ -72,8 +66,9 @@ class BaseHostMeta(object): class DiasporaHostMeta(BaseHostMeta): """Diaspora host-meta. - Requires keyword args: - webfinger_host (str) + Required keyword args: + + * webfinger_host (str) """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -99,11 +94,12 @@ class BaseLegacyWebFinger(BaseHostMeta): class DiasporaWebFinger(BaseLegacyWebFinger): """Diaspora version of legacy WebFinger. - Requires keyword args: - handle (str) - eg user@domain.tld - host (str) - eg https://domain.tld - guid (str) - guid of user - public_key (str) - public key + Required keyword args: + + * handle (str) - eg user@domain.tld + * host (str) - eg https://domain.tld + * guid (str) - guid of user + * public_key (str) - public key """ def __init__(self, handle, host, guid, public_key, *args, **kwargs): super().__init__(handle, *args, **kwargs) @@ -191,16 +187,9 @@ class SocialRelayWellKnown(object): Schema see `schemas/social-relay-well-known.json` - Args: - subscribe (bool) - tags (tuple, optional) - scope (str, optional) - Should be either "all" or "tags", default is "all" if not given - - Returns: - JSON document (str) - - Raises: - ValidationError on `render` if values don't conform to schema + :arg subscribe: bool + :arg tags: tuple, optional + :arg scope: Should be either "all" or "tags", default is "all" if not given """ def __init__(self, subscribe, tags=(), scope="all", *args, **kwargs): self.doc = { @@ -273,11 +262,9 @@ def get_nodeinfo_well_known_document(url, document_path=None): See spec: http://nodeinfo.diaspora.software - Args: - url (str) - The full base url with protocol, ie https://example.com - document_path (str) - Custom NodeInfo document path if supplied - - :rtype: dict + :arg url: The full base url with protocol, ie https://example.com + :arg document_path: Custom NodeInfo document path if supplied (optional) + :returns: dict """ return { "links": [ diff --git a/federation/inbound.py b/federation/inbound.py index 245d99b..c5af67a 100644 --- a/federation/inbound.py +++ b/federation/inbound.py @@ -13,11 +13,12 @@ PROTOCOLS = ( def handle_receive(payload, user=None, sender_key_fetcher=None, skip_author_verification=False): """Takes a payload and passes it to the correct protocol. - Args: - payload (str) - Payload blob - user (optional, obj) - User that will be passed to `protocol.receive` - sender_key_fetcher (optional, func) - Function that accepts sender handle and returns public key - skip_author_verification (optional, bool) - Don't verify sender (test purposes, false default) + :arg payload: Payload blob (str) + :arg user: User that will be passed to `protocol.receive` (required on private encrypted content) + :arg sender_key_fetcher: Function that accepts sender handle and returns public key (optional) + :arg skip_author_verification: Don't verify sender (test purposes, false default) + :returns: Tuple of sender handle, protocol name and list of entity objects + :raises NoSuitableProtocolFound: When no protocol was identified to pass message to """ logger.debug("handle_receive: processing payload: %s", payload) found_protocol = None diff --git a/federation/outbound.py b/federation/outbound.py index 617495b..8184993 100644 --- a/federation/outbound.py +++ b/federation/outbound.py @@ -9,13 +9,13 @@ def handle_create_payload(entity, from_user, to_user=None): Since we don't know the protocol, we need to first query the recipient. However, for a PoC implementation, supporting only Diaspora, we're going to assume that for now. - Args: - entity (obj) - Entity object to send - from_user (obj) - User sending the object - to_user (obj) - Contact entry to send to (required for non-public content) + ``from_user`` must have ``private_key`` and ``handle`` attributes. + ``to_user`` must have ``key`` attribute. - `from_user` must have `private_key` and `handle` attributes. - `to_user` must have `key` attribute. + :arg entity: Entity object to send + :arg from_user: Profile sending the object + :arg to_user: Profile entry to send to (required for non-public content) + :returns: Built payload message (str) """ # Just use Diaspora protocol for now protocol = Protocol() diff --git a/federation/utils/diaspora.py b/federation/utils/diaspora.py index a47e40e..d79b16f 100644 --- a/federation/utils/diaspora.py +++ b/federation/utils/diaspora.py @@ -15,11 +15,8 @@ def retrieve_diaspora_hcard(handle): """ Retrieve a remote Diaspora hCard document. - Args: - handle (str) - Remote handle to retrieve - - Returns: - str (HTML document) + :arg handle: Remote handle to retrieve + :return: str (HTML document) """ webfinger = retrieve_diaspora_webfinger(handle) if not webfinger: @@ -35,11 +32,8 @@ def retrieve_diaspora_webfinger(handle): """ Retrieve a remote Diaspora webfinger document. - Args: - handle (str) - Remote handle to retrieve - - Returns: - XRD + :arg handle: Remote handle to retrieve + :returns: ``XRD`` instance """ hostmeta = retrieve_diaspora_host_meta(handle.split("@")[1]) if not hostmeta: @@ -56,11 +50,8 @@ def retrieve_diaspora_host_meta(host): """ Retrieve a remote Diaspora host-meta document. - Args: - host (str) - Host to retrieve from - - Returns: - XRD + :arg host: Host to retrieve from + :returns: ``XRD`` instance """ document, code, exception = fetch_document(host=host, path="/.well-known/host-meta") if exception: @@ -73,9 +64,9 @@ def _get_element_text_or_none(document, selector): """ Using a CSS selector, get the element and return the text, or None if no element. - Args: - document (HTMLElement) - HTMLElement document - selector (str) - CSS selector + :arg document: ``HTMLElement`` document + :arg selector: CSS selector + :returns: str or None """ element = document.cssselect(selector) if element: @@ -102,9 +93,9 @@ def parse_profile_from_hcard(hcard, handle): """ Parse all the fields we can from a hCard document to get a Profile. - Args: - hcard (str) - HTML hcard document - handle (str) - User handle in username@domain.tld format + :arg hcard: HTML hcard document (str) + :arg handle: User handle in username@domain.tld format + :returns: ``federation.entities.Profile`` instance """ doc = html.fromstring(hcard) profile = Profile( @@ -126,11 +117,8 @@ def retrieve_and_parse_profile(handle): """ Retrieve the remote user and return a Profile object. - Args: - handle (str) - User handle in username@domain.tld format - - Returns: - Profile or None + :arg handle: User handle in username@domain.tld format + :returns: ``federation.entities.Profile`` instance or None """ hcard = retrieve_diaspora_hcard(handle) if not hcard: diff --git a/federation/utils/network.py b/federation/utils/network.py index 4f27e02..c385e8c 100644 --- a/federation/utils/network.py +++ b/federation/utils/network.py @@ -14,21 +14,17 @@ USER_AGENT = "python/social-federation/%s" % __version__ def fetch_document(url=None, host=None, path="/", timeout=10, raise_ssl_errors=True): """Helper method to fetch remote document. - Must be given either the `url` or `host`. - If `url` is given, only that will be tried without falling back to http from https. - If `host` given, `path` will be added to it. Will fall back to http on non-success status code. + Must be given either the ``url`` or ``host``. + If ``url`` is given, only that will be tried without falling back to http from https. + If ``host`` given, `path` will be added to it. Will fall back to http on non-success status code. - Args: - url (str) - Full url to fetch, including protocol - host (str) - Domain part only without path or protocol - path (str) - Path without domain (defaults to "/") - timeout (int) - Seconds to wait for response (defaults to 10) - raise_ssl_errors (bool) - Pass False if you want to try HTTP even for sites with SSL errors (default True) - - Returns: - document (str) - The full document or None - status_code (int) - Status code returned or None - error (obj) - Exception raised, if any + :arg url: Full url to fetch, including protocol + :arg host: Domain part only without path or protocol + :arg path: Path without domain (defaults to "/") + :arg timeout: Seconds to wait for response (defaults to 10) + :arg raise_ssl_errors: Pass False if you want to try HTTP even for sites with SSL errors (default True) + :returns: Tuple of document (str or None), status code (int or None) and error (an exception class instance or None) + :raises ValueError: If neither url nor host are given as parameters """ if not url and not host: raise ValueError("Need url or host.") @@ -79,16 +75,12 @@ def fetch_document(url=None, host=None, path="/", timeout=10, raise_ssl_errors=T def send_document(url, data, timeout=10, *args, **kwargs): """Helper method to send a document via POST. - Args: - url (str) - Full url to send to, including protocol - data (dict) - POST data to send - timeout (int) - Seconds to wait for response (defaults to 10) + Additional ``*args`` and ``**kwargs`` will be passed on to ``requests.post``. - Additional *args and **kwargs will be passed on to `requests.post`. - - Returns: - status_code (int) - Status code returned or None - error (obj) - Exception raised, if any + :arg url: Full url to send to, including protocol + :arg data: POST data to send (dict) + :arg timeout: Seconds to wait for response (defaults to 10) + :returns: Tuple of status code (int or None) and error (exception class instance or None) """ logger.debug("send_document: url=%s, data=%s, timeout=%s", url, data, timeout) headers = {'user-agent': USER_AGENT} diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index 0148ccc..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -pytest -factory_boy -codecov -coverage -pytest-cov -pytest-warnings