Skip to content
15 changes: 8 additions & 7 deletions onadata/apps/api/viewsets/xform_list_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@

from django_filters import rest_framework as django_filter_filters
from rest_framework import permissions, viewsets
from rest_framework.authentication import TokenAuthentication
from rest_framework.authentication import (
TokenAuthentication,
BaseAuthentication,
BasicAuthentication,
)
from rest_framework.decorators import action
from rest_framework.response import Response

Expand Down Expand Up @@ -43,6 +47,7 @@
)
from onadata.libs.utils.common_tags import GROUP_DELIMETER_TAG, REPEAT_INDEX_TAGS
from onadata.libs.utils.export_builder import ExportBuilder
from rest_framework import renderers

BaseViewset = get_baseviewset_class()

Expand All @@ -57,11 +62,7 @@ class XFormListViewSet(ETagsMixin, BaseViewset, viewsets.ReadOnlyModelViewSet):
OpenRosa Form List API - https://docs.getodk.org/openrosa-form-list/
"""

authentication_classes = (
DigestAuthentication,
EnketoTokenAuthentication,
TokenAuthentication,
)
authentication_classes = [BasicAuthentication, TokenAuthentication]
content_negotiation_class = MediaFileContentNegotiation
filterset_class = filters.FormIDFilter
filter_backends = (
Expand All @@ -74,7 +75,7 @@ class XFormListViewSet(ETagsMixin, BaseViewset, viewsets.ReadOnlyModelViewSet):
).only(
"id_string", "title", "version", "uuid", "description", "user__username", "hash"
)
permission_classes = (permissions.AllowAny,)
permission_classes = [permissions.AllowAny]
renderer_classes = (XFormListRenderer,)
serializer_class = XFormListSerializer
template_name = "api/xformsList.xml"
Expand Down
Empty file.
3 changes: 3 additions & 0 deletions onadata/apps/interview/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions onadata/apps/interview/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class InterviewConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "onadata.apps.interview"
Empty file.
3 changes: 3 additions & 0 deletions onadata/apps/interview/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
3 changes: 3 additions & 0 deletions onadata/apps/interview/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
11 changes: 11 additions & 0 deletions onadata/apps/interview/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.urls import path
from . import views


urlpatterns = [
path(
"form/<int:pk>/",
views.FetchOnadataFormView.as_view(),
name="form_id",
),
]
68 changes: 68 additions & 0 deletions onadata/apps/interview/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import requests
from requests.auth import HTTPBasicAuth
from django.http import JsonResponse
from rest_framework.generics import ListAPIView
from onadata.apps.logger.models import XForm
import xmltodict
from django.shortcuts import get_object_or_404
from rest_framework import status
import os
from rest_framework.authentication import TokenAuthentication, BasicAuthentication
from rest_framework.response import Response
from django.shortcuts import render
import json


# Go to http://localhost:8000/api/v1/form/<form_id>/
class FetchOnadataFormView(ListAPIView):
lookup_field = "pk"
authentication_classes = [BasicAuthentication, TokenAuthentication]

def get(self, request, *args, **kwargs):
try:
# Define authentication of admin user credentials
username = "kenlao" # Replace with environmental variables in production, I used this for simplicity
password = "admin123"

# Define the endpoint URL
pk = kwargs.get("pk")
model = get_object_or_404(XForm, id=pk)
if model:
endpoint = f"http://localhost:8000/api/v1/formlist/{pk}"

# Send a GET request to the endpoint with basic authentication
response = requests.get(
endpoint, auth=HTTPBasicAuth(username, password)
)

# Check for HTTP errors
response.raise_for_status()

# Access the XML response as text
xml_data = response.text

# Parse the XML into a Python dictionary using xmltodict
data_dict = xmltodict.parse(xml_data)
h_head = data_dict.get("h:html", {}).get("h:head", {})

# Return the parsed h_head as JSON response
# return JsonResponse(h_head, safe=False)
return render(
request, "display_data.html", {"data": json.dumps(h_head)}
)

except requests.exceptions.HTTPError as http_err:
return Response(
{"error": f"HTTP error occurred: {str(http_err)}"},
status=status.HTTP_400_BAD_REQUEST,
)
except requests.exceptions.RequestException as req_err:
return Response(
{"error": f"Request error: {str(req_err)}"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
except Exception as e:
return Response(
{"error": f"An unexpected error occurred: {str(e)}"},
status=status.HTTP_400_BAD_REQUEST,
)
2 changes: 1 addition & 1 deletion onadata/apps/logger/models/xform_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class XFormVersion(models.Model):
json = models.TextField()

def __str__(self):
return f"{self.xform.title}-{self.version}"
return f"{self.xform.title}-{self.version}-{self.xform.form_id}"

class Meta:
unique_together = ["xform", "version"]
8 changes: 8 additions & 0 deletions onadata/apps/main/static/js/display_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Get the raw JSON data passed from Django
let rawJsonData = document.getElementById('json-data').textContent;

// Parse the JSON string into a JavaScript object
let jsonData = JSON.parse(rawJsonData);

// Display the JSON data in a formatted way
document.getElementById('json-data').textContent = JSON.stringify(jsonData, null, 2);
10 changes: 10 additions & 0 deletions onadata/apps/main/templates/display_data.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- templates/display_data.html -->
{% load i18n %}
{% load static %}

<body>
<h1>Fetched JSON Data</h1>
<pre id="json-data">{{data | safe }}</pre>
<script type="text/javascript" src="{{STATIC_URL}}js/display_data.js"></script>

</body>
3 changes: 2 additions & 1 deletion onadata/apps/main/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# enable the admin:
from django.contrib import admin
from django.contrib.staticfiles import views as staticfiles_views
from django.urls import include, re_path
from django.urls import include, re_path, path
from django.views.generic import RedirectView

from onadata.apps import sms_support
Expand All @@ -39,6 +39,7 @@
admin.autodiscover()

urlpatterns = [
re_path("^api/v1/", include("onadata.apps.interview.urls")),
# change Language
re_path(r"^i18n/", include(i18n)),
re_path("^api/v1/", include(api_v1_router.urls)),
Expand Down
5 changes: 4 additions & 1 deletion onadata/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,14 @@
"oauth2_provider",
"rest_framework",
"rest_framework.authtoken",
"rest_framework_simplejwt",
"taggit",
"onadata.apps.logger",
"onadata.apps.viewer",
"onadata.apps.main",
"onadata.apps.restservice",
"onadata.apps.api",
"onadata.apps.interview",
"guardian",
"onadata.apps.sms_support",
"onadata.libs",
Expand Down Expand Up @@ -292,12 +294,13 @@
"rest_framework.permissions.AllowAny",
],
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.TokenAuthentication",
"rest_framework_simplejwt.authentication.JWTAuthentication",
"onadata.libs.authentication.DigestAuthentication",
"onadata.libs.authentication.TempTokenAuthentication",
"onadata.libs.authentication.EnketoTokenAuthentication",
"oauth2_provider.contrib.rest_framework.OAuth2Authentication",
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_RENDERER_CLASSES": (
"rest_framework.renderers.JSONRenderer",
Expand Down
1 change: 1 addition & 0 deletions onadata/settings/default_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# settings.py)
from onadata.settings.staging_example import * # noqa pylint: disable=W0401,W0614

# DEBUG = True

ALLOWED_HOSTS = ["*"]

Expand Down
2 changes: 1 addition & 1 deletion onadata/settings/travis_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

PASSWORD_HASHERS = ("django.contrib.auth.hashers.MD5PasswordHasher",)

DEBUG = False
DEBUG = True
TEMPLATES[0]["OPTIONS"]["debug"] = DEBUG
MIDDLEWARE = (
"django.middleware.common.CommonMiddleware",
Expand Down
1 change: 1 addition & 0 deletions requirements/docs.pip
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ tomli==2.0.1
# via sphinx
urllib3==2.2.2
# via requests
djangorestframework-simplejwt