mirror of
				https://github.com/gsi-upm/senpy
				synced 2025-11-04 01:08:16 +00:00 
			
		
		
		
	Update docs + notebooks
This commit is contained in:
		@@ -21,16 +21,16 @@ before_script:
 | 
				
			|||||||
  except:
 | 
					  except:
 | 
				
			||||||
    - tags # Avoid unnecessary double testing
 | 
					    - tags # Avoid unnecessary double testing
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
test-3.5:
 | 
					test-3.6:
 | 
				
			||||||
  <<: *test_definition
 | 
					  <<: *test_definition
 | 
				
			||||||
  variables:
 | 
					  variables:
 | 
				
			||||||
    PYTHON_VERSION: "3.5"
 | 
					    PYTHON_VERSION: "3.6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test-2.7:
 | 
					test-3.7:
 | 
				
			||||||
  <<: *test_definition
 | 
					  <<: *test_definition
 | 
				
			||||||
  allow_failure: true
 | 
					  allow_failure: true
 | 
				
			||||||
  variables:
 | 
					  variables:
 | 
				
			||||||
    PYTHON_VERSION: "2.7"
 | 
					    PYTHON_VERSION: "3.7"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
push:
 | 
					push:
 | 
				
			||||||
  stage: push
 | 
					  stage: push
 | 
				
			||||||
@@ -101,4 +101,3 @@ cleanup_py:
 | 
				
			|||||||
   when: always   # this is important; run even if preceding stages failed.
 | 
					   when: always   # this is important; run even if preceding stages failed.
 | 
				
			||||||
   script:
 | 
					   script:
 | 
				
			||||||
    - rm -vf ~/.pypirc  # we don't want to leave these around, but GitLab may clean up anyway.
 | 
					    - rm -vf ~/.pypirc  # we don't want to leave these around, but GitLab may clean up anyway.
 | 
				
			||||||
    - docker logout
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,10 @@ services:
 | 
				
			|||||||
language: python
 | 
					language: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
env:
 | 
					env:
 | 
				
			||||||
  - PYV=2.7
 | 
					  - PYV=3.3
 | 
				
			||||||
 | 
					  - PYV=3.4
 | 
				
			||||||
  - PYV=3.5
 | 
					  - PYV=3.5
 | 
				
			||||||
 | 
					  - PYV=3.6
 | 
				
			||||||
 | 
					  - PYV=3.7
 | 
				
			||||||
# run nosetests - Tests
 | 
					# run nosetests - Tests
 | 
				
			||||||
script: make test-$PYV
 | 
					script: make test-$PYV
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1513
									
								
								docs/Quickstart-10minutes.ipynb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1513
									
								
								docs/Quickstart-10minutes.ipynb
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										152
									
								
								docs/Quickstart-1minute.ipynb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								docs/Quickstart-1minute.ipynb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					 "cells": [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					   "cell_type": "markdown",
 | 
				
			||||||
 | 
					   "metadata": {},
 | 
				
			||||||
 | 
					   "source": [
 | 
				
			||||||
 | 
					    "# Senpy in 1 minute\n",
 | 
				
			||||||
 | 
					    "\n",
 | 
				
			||||||
 | 
					    "This mini-tutorial is the first in the series of senpy tutorials. It only shows how to annotate with a service.\n",
 | 
				
			||||||
 | 
					    "In this first tutorial, we will use the [demo server](http://senpy.gsi.upm.es), which runs some open source plugins for sentiment and emotion analysis."
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					   "cell_type": "markdown",
 | 
				
			||||||
 | 
					   "metadata": {},
 | 
				
			||||||
 | 
					   "source": [
 | 
				
			||||||
 | 
					    "Annotating with senpy is as simple as issuing an HTTP request to the API using your favourite tool.\n",
 | 
				
			||||||
 | 
					    "This is just an example using curl:"
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					   "cell_type": "code",
 | 
				
			||||||
 | 
					   "execution_count": 16,
 | 
				
			||||||
 | 
					   "metadata": {},
 | 
				
			||||||
 | 
					   "outputs": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					     "name": "stdout",
 | 
				
			||||||
 | 
					     "output_type": "stream",
 | 
				
			||||||
 | 
					     "text": [
 | 
				
			||||||
 | 
					      "{\r\n",
 | 
				
			||||||
 | 
					      "  \"@context\": \"http://senpy.gsi.upm.es/api/contexts/YXBpL3NlbnRpbWVudDE0MD8j\",\r\n",
 | 
				
			||||||
 | 
					      "  \"@type\": \"Results\",\r\n",
 | 
				
			||||||
 | 
					      "  \"entries\": [\r\n",
 | 
				
			||||||
 | 
					      "    {\r\n",
 | 
				
			||||||
 | 
					      "      \"@id\": \"prefix:\",\r\n",
 | 
				
			||||||
 | 
					      "      \"@type\": \"Entry\",\r\n",
 | 
				
			||||||
 | 
					      "      \"marl:hasOpinion\": [\r\n",
 | 
				
			||||||
 | 
					      "        {\r\n",
 | 
				
			||||||
 | 
					      "          \"@type\": \"Sentiment\",\r\n",
 | 
				
			||||||
 | 
					      "          \"marl:hasPolarity\": \"marl:Positive\",\r\n",
 | 
				
			||||||
 | 
					      "          \"prov:wasGeneratedBy\": \"prefix:Analysis_1554389334.6431913\"\r\n",
 | 
				
			||||||
 | 
					      "        }\r\n",
 | 
				
			||||||
 | 
					      "      ],\r\n",
 | 
				
			||||||
 | 
					      "      \"nif:isString\": \"Senpy is awesome\",\r\n",
 | 
				
			||||||
 | 
					      "      \"onyx:hasEmotionSet\": []\r\n",
 | 
				
			||||||
 | 
					      "    }\r\n",
 | 
				
			||||||
 | 
					      "  ]\r\n",
 | 
				
			||||||
 | 
					      "}"
 | 
				
			||||||
 | 
					     ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					   ],
 | 
				
			||||||
 | 
					   "source": [
 | 
				
			||||||
 | 
					    "!curl \"http://senpy.gsi.upm.es/api/sentiment140\" --data-urlencode \"input=Senpy is awesome\""
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					   "cell_type": "markdown",
 | 
				
			||||||
 | 
					   "metadata": {},
 | 
				
			||||||
 | 
					   "source": [
 | 
				
			||||||
 | 
					    "Congratulations, you've used your first senpy service!"
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					   "cell_type": "markdown",
 | 
				
			||||||
 | 
					   "metadata": {},
 | 
				
			||||||
 | 
					   "source": [
 | 
				
			||||||
 | 
					    "Here is the equivalent using the `requests` library:"
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					   "cell_type": "code",
 | 
				
			||||||
 | 
					   "execution_count": 17,
 | 
				
			||||||
 | 
					   "metadata": {
 | 
				
			||||||
 | 
					    "scrolled": true
 | 
				
			||||||
 | 
					   },
 | 
				
			||||||
 | 
					   "outputs": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					     "name": "stdout",
 | 
				
			||||||
 | 
					     "output_type": "stream",
 | 
				
			||||||
 | 
					     "text": [
 | 
				
			||||||
 | 
					      "{\n",
 | 
				
			||||||
 | 
					      "  \"@context\": \"http://senpy.gsi.upm.es/api/contexts/YXBpL3NlbnRpbWVudDE0MD9pbnB1dD1TZW5weStpcythd2Vzb21lIw%3D%3D\",\n",
 | 
				
			||||||
 | 
					      "  \"@type\": \"Results\",\n",
 | 
				
			||||||
 | 
					      "  \"entries\": [\n",
 | 
				
			||||||
 | 
					      "    {\n",
 | 
				
			||||||
 | 
					      "      \"@id\": \"prefix:\",\n",
 | 
				
			||||||
 | 
					      "      \"@type\": \"Entry\",\n",
 | 
				
			||||||
 | 
					      "      \"marl:hasOpinion\": [\n",
 | 
				
			||||||
 | 
					      "        {\n",
 | 
				
			||||||
 | 
					      "          \"@type\": \"Sentiment\",\n",
 | 
				
			||||||
 | 
					      "          \"marl:hasPolarity\": \"marl:Positive\",\n",
 | 
				
			||||||
 | 
					      "          \"prov:wasGeneratedBy\": \"prefix:Analysis_1554389335.9803226\"\n",
 | 
				
			||||||
 | 
					      "        }\n",
 | 
				
			||||||
 | 
					      "      ],\n",
 | 
				
			||||||
 | 
					      "      \"nif:isString\": \"Senpy is awesome\",\n",
 | 
				
			||||||
 | 
					      "      \"onyx:hasEmotionSet\": []\n",
 | 
				
			||||||
 | 
					      "    }\n",
 | 
				
			||||||
 | 
					      "  ]\n",
 | 
				
			||||||
 | 
					      "}\n"
 | 
				
			||||||
 | 
					     ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					   ],
 | 
				
			||||||
 | 
					   "source": [
 | 
				
			||||||
 | 
					    "import requests\n",
 | 
				
			||||||
 | 
					    "res = requests.get('http://senpy.gsi.upm.es/api/sentiment140',\n",
 | 
				
			||||||
 | 
					    "                   params={\"input\": \"Senpy is awesome\",})\n",
 | 
				
			||||||
 | 
					    "print(res.text)"
 | 
				
			||||||
 | 
					   ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					 ],
 | 
				
			||||||
 | 
					 "metadata": {
 | 
				
			||||||
 | 
					  "anaconda-cloud": {},
 | 
				
			||||||
 | 
					  "kernelspec": {
 | 
				
			||||||
 | 
					   "display_name": "Python 3",
 | 
				
			||||||
 | 
					   "language": "python",
 | 
				
			||||||
 | 
					   "name": "python3"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "language_info": {
 | 
				
			||||||
 | 
					   "codemirror_mode": {
 | 
				
			||||||
 | 
					    "name": "ipython",
 | 
				
			||||||
 | 
					    "version": 3
 | 
				
			||||||
 | 
					   },
 | 
				
			||||||
 | 
					   "file_extension": ".py",
 | 
				
			||||||
 | 
					   "mimetype": "text/x-python",
 | 
				
			||||||
 | 
					   "name": "python",
 | 
				
			||||||
 | 
					   "nbconvert_exporter": "python",
 | 
				
			||||||
 | 
					   "pygments_lexer": "ipython3",
 | 
				
			||||||
 | 
					   "version": "3.7.3"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "toc": {
 | 
				
			||||||
 | 
					   "colors": {
 | 
				
			||||||
 | 
					    "hover_highlight": "#DAA520",
 | 
				
			||||||
 | 
					    "running_highlight": "#FF0000",
 | 
				
			||||||
 | 
					    "selected_highlight": "#FFD700"
 | 
				
			||||||
 | 
					   },
 | 
				
			||||||
 | 
					   "moveMenuLeft": true,
 | 
				
			||||||
 | 
					   "nav_menu": {
 | 
				
			||||||
 | 
					    "height": "68px",
 | 
				
			||||||
 | 
					    "width": "252px"
 | 
				
			||||||
 | 
					   },
 | 
				
			||||||
 | 
					   "navigate_menu": true,
 | 
				
			||||||
 | 
					   "number_sections": true,
 | 
				
			||||||
 | 
					   "sideBar": true,
 | 
				
			||||||
 | 
					   "threshold": 4,
 | 
				
			||||||
 | 
					   "toc_cell": false,
 | 
				
			||||||
 | 
					   "toc_section_display": "block",
 | 
				
			||||||
 | 
					   "toc_window_display": false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					 },
 | 
				
			||||||
 | 
					 "nbformat": 4,
 | 
				
			||||||
 | 
					 "nbformat_minor": 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										4832
									
								
								docs/Quickstart-30minutes.ipynb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4832
									
								
								docs/Quickstart-30minutes.ipynb
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2599
									
								
								docs/Quickstart.rst
									
									
									
									
									
								
							
							
						
						
									
										2599
									
								
								docs/Quickstart.rst
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -7,3 +7,4 @@ Advanced usage
 | 
				
			|||||||
    server-cli
 | 
					    server-cli
 | 
				
			||||||
    conversion
 | 
					    conversion
 | 
				
			||||||
    commandline
 | 
					    commandline
 | 
				
			||||||
 | 
					    development
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								docs/conf.py
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								docs/conf.py
									
									
									
									
									
								
							@@ -38,6 +38,8 @@ extensions = [
 | 
				
			|||||||
    'sphinxcontrib.httpdomain',
 | 
					    'sphinxcontrib.httpdomain',
 | 
				
			||||||
    'sphinx.ext.coverage',
 | 
					    'sphinx.ext.coverage',
 | 
				
			||||||
    'sphinx.ext.autosectionlabel',
 | 
					    'sphinx.ext.autosectionlabel',
 | 
				
			||||||
 | 
					    'nbsphinx',
 | 
				
			||||||
 | 
					    'sphinx.ext.mathjax',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Add any paths that contain templates here, relative to this directory.
 | 
					# Add any paths that contain templates here, relative to this directory.
 | 
				
			||||||
@@ -54,7 +56,7 @@ master_doc = 'index'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# General information about the project.
 | 
					# General information about the project.
 | 
				
			||||||
project = u'Senpy'
 | 
					project = u'Senpy'
 | 
				
			||||||
copyright = u'2016, J. Fernando Sánchez'
 | 
					copyright = u'2019, J. Fernando Sánchez'
 | 
				
			||||||
description = u'A framework for sentiment and emotion analysis services'
 | 
					description = u'A framework for sentiment and emotion analysis services'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The version info for the project you're documenting, acts as replacement for
 | 
					# The version info for the project you're documenting, acts as replacement for
 | 
				
			||||||
@@ -79,7 +81,7 @@ language = None
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# List of patterns, relative to source directory, that match files and
 | 
					# List of patterns, relative to source directory, that match files and
 | 
				
			||||||
# directories to ignore when looking for source files.
 | 
					# directories to ignore when looking for source files.
 | 
				
			||||||
exclude_patterns = ['_build']
 | 
					exclude_patterns = ['_build', '**.ipynb_checkpoints']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The reST default role (used for this markup: `text`) to use for all
 | 
					# The reST default role (used for this markup: `text`) to use for all
 | 
				
			||||||
# documents.
 | 
					# documents.
 | 
				
			||||||
@@ -286,3 +288,13 @@ texinfo_documents = [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
 | 
					# If true, do not generate a @detailmenu in the "Top" node's menu.
 | 
				
			||||||
#texinfo_no_detailmenu = False
 | 
					#texinfo_no_detailmenu = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					nbsphinx_prolog = """
 | 
				
			||||||
 | 
					.. note:: This page has been auto-generated from a Jupyter notebook using nbsphinx_.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The original source is available at: https://github.com/gsi-upm/senpy/tree/master/docs//{{ env.doc2path(env.docname, base=None) }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. _nbsphinx: https://nbsphinx.readthedocs.io/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,11 +4,10 @@ Demo
 | 
				
			|||||||
There is a demo available on http://senpy.gsi.upm.es/, where you can test a live instance of Senpy, with several open source plugins.
 | 
					There is a demo available on http://senpy.gsi.upm.es/, where you can test a live instance of Senpy, with several open source plugins.
 | 
				
			||||||
You can use the playground (a web interface) or make HTTP requests to the service API.
 | 
					You can use the playground (a web interface) or make HTTP requests to the service API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. image:: senpy-playground.png
 | 
					.. image:: playground-0.20.png
 | 
				
			||||||
  :height: 400px
 | 
					  :target: http://senpy.gsi.upm.es
 | 
				
			||||||
  :width: 800px
 | 
					  :width: 800px
 | 
				
			||||||
  :scale: 100 %
 | 
					 | 
				
			||||||
  :align: center
 | 
					  :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The source code and description of the plugins used in the demo are available here: https://lab.gsi.upm.es/senpy/senpy-plugins-community/.
 | 
					The source code and description of the plugins used in the demo are available here: https://github.com/gsi-upm/senpy-plugins-community/.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,10 +25,9 @@ To get familiar with the concepts behind Senpy, and what it can offer for servic
 | 
				
			|||||||
   :maxdepth: 2
 | 
					   :maxdepth: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   senpy
 | 
					   senpy
 | 
				
			||||||
   Quickstart
 | 
					   demo
 | 
				
			||||||
 | 
					   Quickstart.ipynb
 | 
				
			||||||
   installation
 | 
					   installation
 | 
				
			||||||
   development
 | 
					 | 
				
			||||||
   apischema
 | 
					   apischema
 | 
				
			||||||
   advanced
 | 
					   advanced
 | 
				
			||||||
   demo
 | 
					 | 
				
			||||||
   publications
 | 
					   publications
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								docs/playground-0.20.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/playground-0.20.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 68 KiB  | 
@@ -22,7 +22,7 @@ Hence, two parts are necessary: 1) the code that will process the entry, and 2)
 | 
				
			|||||||
In practice, this is what a plugin looks like, tests included:
 | 
					In practice, this is what a plugin looks like, tests included:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. literalinclude:: ../senpy/plugins/example/rand_plugin.py
 | 
					.. literalinclude:: ../example-plugins/rand_plugin.py
 | 
				
			||||||
   :emphasize-lines: 5-11
 | 
					   :emphasize-lines: 5-11
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,8 +76,9 @@ Most plugins will need access to files (dictionaries, lexicons, etc.).
 | 
				
			|||||||
These files are usually heavy or under a license that does not allow redistribution.
 | 
					These files are usually heavy or under a license that does not allow redistribution.
 | 
				
			||||||
For this reason, senpy has a `data_folder` that is separated from the source files.
 | 
					For this reason, senpy has a `data_folder` that is separated from the source files.
 | 
				
			||||||
The location of this folder is controlled programmatically or by setting the `SENPY_DATA` environment variable.
 | 
					The location of this folder is controlled programmatically or by setting the `SENPY_DATA` environment variable.
 | 
				
			||||||
 | 
					You can use the `self.path(filepath)` function to get the path of a given `filepath` within the data folder.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Plugins have a convenience function `self.open` which will automatically prepend the data folder to relative paths:
 | 
					Plugins have a convenience function `self.open` which will automatically look for the file if it exists, or open a new one if it doesn't:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code:: python
 | 
					.. code:: python
 | 
				
			||||||
@@ -132,7 +133,7 @@ And you can run it with:
 | 
				
			|||||||
   docker run -p 5000:5000 gsiupm/exampleplugin
 | 
					   docker run -p 5000:5000 gsiupm/exampleplugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If the plugin uses non-source files (:ref:`loading data and files`), the recommended way is to use `SENPY_DATA` folder.
 | 
					If the plugin uses non-source files (:ref:`How should I load external data and files`), the recommended way is to use `SENPY_DATA` folder.
 | 
				
			||||||
Data can then be mounted in the container or added to the image.
 | 
					Data can then be mounted in the container or added to the image.
 | 
				
			||||||
The former is recommended for open source plugins with licensed resources, whereas the latter is the most convenient and can be used for private images.
 | 
					The former is recommended for open source plugins with licensed resources, whereas the latter is the most convenient and can be used for private images.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,3 @@
 | 
				
			|||||||
sphinxcontrib-httpdomain>=1.4
 | 
					sphinxcontrib-httpdomain>=1.4
 | 
				
			||||||
 | 
					ipykernel
 | 
				
			||||||
nbsphinx
 | 
					nbsphinx
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user