2016-09-11 23:57:44 +02:00
|
|
|
from typing import Optional, Any, Dict
|
2016-07-29 15:06:41 +02:00
|
|
|
from collections import OrderedDict
|
|
|
|
from django.views.generic import TemplateView
|
2016-08-14 03:32:11 +02:00
|
|
|
from django.conf import settings
|
2016-11-09 01:45:36 +01:00
|
|
|
from django.http import HttpRequest, HttpResponse, HttpResponseNotFound
|
2017-04-03 11:49:13 +02:00
|
|
|
from django.template import loader
|
2017-03-16 14:24:33 +01:00
|
|
|
from django.shortcuts import render
|
2016-07-29 15:06:41 +02:00
|
|
|
|
2016-11-09 01:45:36 +01:00
|
|
|
import os
|
2016-09-13 19:18:22 +02:00
|
|
|
import ujson
|
|
|
|
|
|
|
|
from zerver.lib import bugdown
|
2017-11-20 03:27:04 +01:00
|
|
|
from zerver.lib.integrations import CATEGORIES, INTEGRATIONS, HubotIntegration, \
|
|
|
|
WebhookIntegration
|
2017-10-28 00:07:31 +02:00
|
|
|
from zerver.lib.request import has_request_variables, REQ
|
2017-10-19 07:21:57 +02:00
|
|
|
from zerver.lib.subdomains import get_subdomain
|
2017-10-20 02:56:49 +02:00
|
|
|
from zerver.models import Realm
|
2017-07-12 02:50:27 +02:00
|
|
|
from zerver.templatetags.app_filters import render_markdown_path
|
2016-07-29 15:06:41 +02:00
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def add_api_uri_context(context: Dict[str, Any], request: HttpRequest) -> None:
|
2017-10-02 07:59:20 +02:00
|
|
|
subdomain = get_subdomain(request)
|
2017-10-20 02:56:49 +02:00
|
|
|
if (subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN
|
|
|
|
or not settings.ROOT_DOMAIN_LANDING_PAGE):
|
2017-10-02 07:59:20 +02:00
|
|
|
display_subdomain = subdomain
|
|
|
|
html_settings_links = True
|
|
|
|
else:
|
|
|
|
display_subdomain = 'yourZulipDomain'
|
|
|
|
html_settings_links = False
|
2016-07-19 14:35:08 +02:00
|
|
|
|
2017-10-30 22:13:13 +01:00
|
|
|
display_host = Realm.host_for_subdomain(display_subdomain)
|
|
|
|
api_url_scheme_relative = display_host + "/api"
|
|
|
|
api_url = settings.EXTERNAL_URI_SCHEME + api_url_scheme_relative
|
2016-09-14 07:07:21 +02:00
|
|
|
|
2017-10-30 22:04:15 +01:00
|
|
|
context['api_url'] = api_url
|
2017-10-30 22:13:13 +01:00
|
|
|
context['api_url_scheme_relative'] = api_url_scheme_relative
|
2016-07-19 14:35:08 +02:00
|
|
|
context["html_settings_links"] = html_settings_links
|
2016-09-14 07:07:21 +02:00
|
|
|
|
2016-09-13 19:09:03 +02:00
|
|
|
class ApiURLView(TemplateView):
|
2017-11-27 09:28:57 +01:00
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, str]:
|
2017-10-27 08:28:23 +02:00
|
|
|
context = super().get_context_data(**kwargs)
|
2016-09-14 07:07:21 +02:00
|
|
|
add_api_uri_context(context, self.request)
|
2016-09-13 19:09:03 +02:00
|
|
|
return context
|
|
|
|
|
2016-08-14 09:44:12 +02:00
|
|
|
class APIView(ApiURLView):
|
|
|
|
template_name = 'zerver/api.html'
|
|
|
|
|
|
|
|
|
2017-07-25 02:35:22 +02:00
|
|
|
class MarkdownDirectoryView(ApiURLView):
|
|
|
|
path_template = ""
|
2016-11-09 01:45:36 +01:00
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def get_path(self, article: str) -> str:
|
2016-11-09 01:45:36 +01:00
|
|
|
if article == "":
|
|
|
|
article = "index"
|
2017-10-02 19:51:17 +02:00
|
|
|
elif "/" in article:
|
|
|
|
article = "missing"
|
2016-11-09 01:45:36 +01:00
|
|
|
return self.path_template % (article,)
|
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
2016-11-09 01:45:36 +01:00
|
|
|
article = kwargs["article"]
|
2017-07-25 02:35:22 +02:00
|
|
|
context = super().get_context_data() # type: Dict[str, Any]
|
2016-11-09 01:45:36 +01:00
|
|
|
path = self.get_path(article)
|
2017-04-03 11:49:13 +02:00
|
|
|
try:
|
|
|
|
loader.get_template(path)
|
2016-11-09 01:45:36 +01:00
|
|
|
context["article"] = path
|
2017-04-03 11:49:13 +02:00
|
|
|
except loader.TemplateDoesNotExist:
|
2016-11-09 01:45:36 +01:00
|
|
|
context["article"] = self.get_path("missing")
|
2017-04-03 11:49:13 +02:00
|
|
|
|
2017-02-18 23:58:54 +01:00
|
|
|
# For disabling the "Back to home" on the homepage
|
|
|
|
context["not_index_page"] = not path.endswith("/index.md")
|
2017-11-08 22:08:23 +01:00
|
|
|
if self.template_name == "zerver/help/main.html":
|
|
|
|
context["page_is_help_center"] = True
|
|
|
|
else:
|
|
|
|
context["page_is_api_center"] = True
|
2017-11-08 05:39:42 +01:00
|
|
|
# An "article" might require the api_uri_context to be rendered
|
|
|
|
api_uri_context = {} # type: Dict[str, Any]
|
|
|
|
add_api_uri_context(api_uri_context, self.request)
|
|
|
|
context["api_uri_context"] = api_uri_context
|
2016-11-09 01:45:36 +01:00
|
|
|
return context
|
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def get(self, request: HttpRequest, article: str="") -> HttpResponse:
|
2016-11-09 01:45:36 +01:00
|
|
|
path = self.get_path(article)
|
2017-07-25 02:35:22 +02:00
|
|
|
result = super().get(self, article=article)
|
2017-04-03 11:49:13 +02:00
|
|
|
try:
|
|
|
|
loader.get_template(path)
|
|
|
|
except loader.TemplateDoesNotExist:
|
2016-11-09 01:45:36 +01:00
|
|
|
# Ensure a 404 response code if no such document
|
|
|
|
result.status_code = 404
|
2017-10-02 19:51:17 +02:00
|
|
|
if "/" in article:
|
|
|
|
result.status_code = 404
|
2016-11-09 01:45:36 +01:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def add_integrations_context(context: Dict[str, Any]) -> None:
|
2017-07-05 22:07:46 +02:00
|
|
|
alphabetical_sorted_categories = OrderedDict(sorted(CATEGORIES.items()))
|
2017-02-28 07:18:45 +01:00
|
|
|
alphabetical_sorted_integration = OrderedDict(sorted(INTEGRATIONS.items()))
|
2017-07-05 22:07:46 +02:00
|
|
|
context['categories_dict'] = alphabetical_sorted_categories
|
2017-02-28 07:18:45 +01:00
|
|
|
context['integrations_dict'] = alphabetical_sorted_integration
|
|
|
|
|
2017-07-12 02:50:27 +02:00
|
|
|
if "html_settings_links" in context and context["html_settings_links"]:
|
2017-08-01 03:12:24 +02:00
|
|
|
settings_html = '<a href="../../#settings">Zulip settings page</a>'
|
|
|
|
subscriptions_html = '<a target="_blank" href="../../#streams">streams page</a>'
|
2017-02-28 07:18:45 +01:00
|
|
|
else:
|
|
|
|
settings_html = 'Zulip settings page'
|
2017-03-09 00:20:22 +01:00
|
|
|
subscriptions_html = 'streams page'
|
2017-02-28 07:18:45 +01:00
|
|
|
|
|
|
|
context['settings_html'] = settings_html
|
|
|
|
context['subscriptions_html'] = subscriptions_html
|
|
|
|
|
2017-11-21 03:50:34 +01:00
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def add_context_for_single_integration(context: Dict[str, Any], name: str, request: HttpRequest) -> None:
|
2017-11-21 03:50:34 +01:00
|
|
|
add_api_uri_context(context, request)
|
|
|
|
|
|
|
|
if "html_settings_links" in context and context["html_settings_links"]:
|
|
|
|
settings_html = '<a href="../../#settings">Zulip settings page</a>'
|
|
|
|
subscriptions_html = '<a target="_blank" href="../../#streams">streams page</a>'
|
|
|
|
else:
|
|
|
|
settings_html = 'Zulip settings page'
|
|
|
|
subscriptions_html = 'streams page'
|
|
|
|
|
|
|
|
context['settings_html'] = settings_html
|
|
|
|
context['subscriptions_html'] = subscriptions_html
|
|
|
|
|
2017-02-28 07:18:45 +01:00
|
|
|
|
2016-09-13 19:09:03 +02:00
|
|
|
class IntegrationView(ApiURLView):
|
2017-03-31 07:40:52 +02:00
|
|
|
template_name = 'zerver/integrations/index.html'
|
2016-07-29 15:06:41 +02:00
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
2017-10-27 08:28:23 +02:00
|
|
|
context = super().get_context_data(**kwargs) # type: Dict[str, Any]
|
2017-02-28 07:18:45 +01:00
|
|
|
add_integrations_context(context)
|
2016-07-29 15:06:41 +02:00
|
|
|
return context
|
2016-09-13 19:18:22 +02:00
|
|
|
|
|
|
|
|
2017-07-12 02:50:27 +02:00
|
|
|
@has_request_variables
|
2017-11-27 09:28:57 +01:00
|
|
|
def integration_doc(request: HttpRequest, integration_name: str=REQ(default=None)) -> HttpResponse:
|
2017-07-12 02:50:27 +02:00
|
|
|
try:
|
|
|
|
integration = INTEGRATIONS[integration_name]
|
|
|
|
except KeyError:
|
|
|
|
return HttpResponseNotFound()
|
|
|
|
|
2017-11-22 03:07:51 +01:00
|
|
|
context = {} # type: Dict[str, Any]
|
2017-11-21 03:50:34 +01:00
|
|
|
add_context_for_single_integration(context, integration_name, request)
|
2017-11-20 03:27:04 +01:00
|
|
|
|
|
|
|
context['integration_name'] = integration.name
|
|
|
|
context['integration_display_name'] = integration.display_name
|
|
|
|
if hasattr(integration, 'stream_name'):
|
|
|
|
context['recommended_stream_name'] = integration.stream_name
|
|
|
|
if isinstance(integration, WebhookIntegration):
|
|
|
|
context['integration_url'] = integration.url[3:]
|
|
|
|
if isinstance(integration, HubotIntegration):
|
|
|
|
context['hubot_docs_url'] = integration.hubot_docs_url
|
|
|
|
|
2017-07-12 02:50:27 +02:00
|
|
|
doc_html_str = render_markdown_path(integration.doc, context)
|
|
|
|
|
|
|
|
return HttpResponse(doc_html_str)
|
|
|
|
|
2017-11-27 09:28:57 +01:00
|
|
|
def api_endpoint_docs(request: HttpRequest) -> HttpResponse:
|
2017-05-17 22:10:22 +02:00
|
|
|
context = {} # type: Dict[str, Any]
|
2016-08-14 09:44:12 +02:00
|
|
|
add_api_uri_context(context, request)
|
|
|
|
|
2016-09-13 19:18:22 +02:00
|
|
|
raw_calls = open('templates/zerver/api_content.json', 'r').read()
|
|
|
|
calls = ujson.loads(raw_calls)
|
|
|
|
langs = set()
|
|
|
|
for call in calls:
|
2017-10-27 02:47:30 +02:00
|
|
|
call["endpoint"] = "%s/v1/%s" % (
|
2017-10-30 22:04:15 +01:00
|
|
|
context["api_url"],
|
2017-10-27 02:47:30 +02:00
|
|
|
call["endpoint"])
|
|
|
|
call["example_request"]["curl"] = call["example_request"]["curl"].replace(
|
|
|
|
"https://api.zulip.com",
|
2017-10-30 22:04:15 +01:00
|
|
|
context["api_url"])
|
2016-09-13 19:18:22 +02:00
|
|
|
response = call['example_response']
|
|
|
|
if '\n' not in response:
|
|
|
|
# For 1-line responses, pretty-print them
|
|
|
|
extended_response = response.replace(", ", ",\n ")
|
|
|
|
else:
|
|
|
|
extended_response = response
|
2017-01-22 06:29:11 +01:00
|
|
|
call['rendered_response'] = bugdown.convert("~~~ .py\n" + extended_response + "\n~~~\n")
|
2016-09-13 19:18:22 +02:00
|
|
|
for example_type in ('request', 'response'):
|
|
|
|
for lang in call.get('example_' + example_type, []):
|
|
|
|
langs.add(lang)
|
2017-03-16 14:24:33 +01:00
|
|
|
return render(
|
|
|
|
request,
|
|
|
|
'zerver/api_endpoints.html',
|
|
|
|
context={'content': calls, 'langs': langs},
|
|
|
|
)
|