Dokumentacija etherpad APIja, popravki, preurejen obrazec za urejanje

pull/26/head
Jurij Podgoršek 2023-12-16 01:53:05 +01:00
parent 1ae74fdcd4
commit 4423b69f3f
16 changed files with 109 additions and 59 deletions

View File

@ -1,15 +0,0 @@
# -*- restclient -*-
##########################
# YUFU API dokumentacija #
##########################
# Poganjamo z restclient major mode-om v emacsu
# Ustvari nov pad
POST https://yufu-manifest.ddev.site/etherpad-api/createPad?padID=d2d479bf-b3cb-455a-b7db-5d53c31d1fa2
Content-Type: application/x-www-form-urlencoded
text=While post-communist, post-socialist and post-Yugoslav discourses merely reinforce the appearance of an unchanging and unstable present with a more or less accurate expression of the situation, Yugofuturism follows the example of other ethnofuturist movements such as Afrofuturism, Sinofuturism, Baltic Ethnofuturism and Hungarofuturism, which tactically empower peripheral identities and subversively affirm individual cultural curiosities.
# Brisi vsebino pada
GET https://yufu-manifest.ddev.site/etherpad-api/deletePad?padID=d2d479bf-b3cb-455a-b7db-5d53c31d1fa2

View File

@ -0,0 +1 @@
../web/modules/custom/etherpad_api/doc/api.rest

View File

@ -0,0 +1 @@
../web/modules/custom/yufu_concept/tests/local-emacs-test.rest

View File

@ -2,4 +2,4 @@ BASE_URL="https://yufu-manifest.ddev.site"
JSONAPI_PATH="/jsonapi"
FILE_PATH="/sites/default/files"
ETHERPAD_URL="https://pisi.kompot.si"
ETHERPAD_API_URL="https://yufu-manifest.ddev.site/etherpad-api"
ETHERPAD_PREFIX="yufu-"

2
nuxt/.gitignore vendored
View File

@ -4,5 +4,5 @@ node_modules
.nitro
.cache
.output
.env
.env.local
dist

View File

@ -1,6 +1,6 @@
<script setup="setup">
const { etherpadApiUrl, etherpadPrefix } = useRuntimeConfig().public
const { etherpadApiUrl } = useEtherpadApi()
const prikazi = ref(false)
const revisionId = ref(null)
@ -9,8 +9,8 @@ const dodajPojem = async () => {
revisionId.value = crypto.randomUUID()
// Ustvari nov, prazen pad
const padId = etherpadPrefix + revisionId.value
const resp = await $fetch(`${etherpadApiUrl}/createPad?padID=${padId}&text=`)
const padId = revisionId.value
const resp = await $fetch(`${etherpadApiUrl}/createPad?padID=${padId}`)
prikazi.value = true
}

View File

@ -2,7 +2,7 @@
import { stripHtml } from 'string-strip-html'
const { etherpadApiUrl, etherpadPrefix } = useRuntimeConfig().public
const { etherFetch } = useEtherpadApi()
const store = usePojmiStore()
@ -20,36 +20,29 @@ const urejanje = ref(false)
const urediPojem = async () => {
// Ustvari pad s tekstom pojma, ce se ne obstaja
const tekstPojma = stripHtml(pojem.value.tekst).result
const resp = await $fetch(`${etherpadApiUrl}/createPad?padID=${etherpadPrefix + revisionId.value}`, {
method: 'post',
body: {
text: tekstPojma
}
const resp = await etherFetch('/createPad', {
padID: revisionId.value,
text: tekstPojma
})
urejanje.value = true
}
const brisiPojem = async () => {
const resp = await $fetch(`${etherpadApiUrl}/deletePad?padID=${etherpadPrefix + revisionId.value}`)
alert('pad izbrisan')
}
</script>
<template>
<section class="pojem">
<h2>{{ pojem.naslov }}</h2>
<div class="tekst" v-html="pojem.tekst" />
<div class="gumb" @click="urediPojem">Uredi</div>
<div class="gumb" @click="brisiPojem">Briši (pad)</div>
<div v-if="urejanje" class="pojem">
<PojemForm :revisionId="revisionId" />
<PojemForm v-if="urejanje" :revisionId="revisionId" :pojem="pojem" />
<div v-else>
<div class="gumb" @click="urediPojem">Uredi</div>
<h2>{{ pojem.naslov }}</h2>
<div class="tekst" v-html="pojem.tekst" />
</div>
</section>
</template>
<style scoped>
.gumb {
float: right;
margin-right: 1rem;
}
</style>

View File

@ -1,28 +1,30 @@
<script setup="setup">
const { etherpadUrl, etherpadPrefix } = useRuntimeConfig().public
const { etherFetch } = useEtherpadApi()
const store = usePojmiStore()
const props = defineProps({
naslov: String,
revisionId: String
revisionId: String,
pojem: Object,
urejanje: Object
})
//const pojem = computed(() => store.pojmi[props.naslov])
let naslov = ref(props.pojem.naslov)
let email = ref('')
//await store.naloziPojme()
// const UREJAM = !!pojem.value
const UREJAM = false
let naslov = ''
let tekst = ''
let email = ''
const oddajPredlog = data => {
console.log('oddajam predlog!', naslov, tekst, email)
store.ustvariPojem(data)
const oddajPredlog = async data => {
// @TODO vsebina pada v tekst, testirat
const resp = await etherFetch('/getText', { padID: props.revisionId })
store.ustvariPojem({
title: naslov.value,
email: email.value,
text: resp.data.text,
uuid: props.revisionId
})
alert("sprememba predlagana!")
// @TODO vrni urejanje v navaden prikaz, ko je končano!
urejanje.set(false)
}
const etherNalozen = ev => {
@ -33,7 +35,6 @@ const etherNalozen = ev => {
<template>
<section class="pojem">
<div v-if="UREJAM">UREJAM</div>
<form class="pojem" @submit.prevent="oddajPredlog">
<label for="naslov">Naslov</label>
<input name="naslov" type="text" v-model="naslov">

View File

@ -0,0 +1,21 @@
export const useEtherpadApi = () => {
const { baseUrl } = useRuntimeConfig().public
const etherpadApiUrl = `${baseUrl}/etherpad-api`
const etherFetch = (path, params) => {
// Convert to form key-value pairs
const formBody = Object.keys(params)
.map(key => `${key}=${encodeURIComponent(params[key])}`)
.join('&')
// Call API
return $fetch(etherpadApiUrl + path, {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
body: formBody
})
}
return { etherpadApiUrl, etherFetch }
}

View File

@ -36,7 +36,6 @@ export default defineNuxtConfig({
baseUrl: process.env.BASE_URL,
jsonapiPath: process.env.JSONAPI_PATH,
etherpadUrl: process.env.ETHERPAD_URL,
etherpadApiUrl: process.env.ETHERPAD_API_URL,
etherpadPrefix: process.env.ETHERPAD_PREFIX
}
}

View File

@ -19,7 +19,10 @@ export const usePojmiStore = defineStore('pojmi', {
const { baseUrl, headers, deserialize } = useApi()
const req = await $fetch(`${baseUrl}/api/pojem/dodaj`, {
headers,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify(data)
})

View File

@ -0,0 +1,20 @@
# Etherpad API
This module can be used to proxy requests to an etherpad API.
After installing the module, you must set the etherpad instance API URL and the API key.
Etherpad API documentation can be found here: https://etherpad.org/doc/v1.8.4/#index_http_api
The etherpad API proxy URL is /etherpad-api (@TODO make configurable). When calling it, you can omit the version part (e.g. /1) and the API key (which is set in the configuration). The pad ID prefix is hardcoded for the moment (so that requests are limited to specific pads, not the whole instance).
Some example API calls can found in [api.rest](doc/api.rest).
You can do either GET or POST requests to the proxy, passing parameters via query or post parameters. POST parameters must be passed as key-value pairs (application/x-www-form-urlencoded). The proxy always makes POST requests to etherpad, for the sake of simplicity. The API key is always added, the padID is always prefixed.
## TODO
- configurable PAD ID prefix
- configurable proxy API path
- API call whitelist
- security audit
- use pad groups instead of prefixed pads? (https://etherpad.org/doc/v1.8.4/#index_groups)

View File

@ -0,0 +1,26 @@
# -*- restclient -*-
##############################
# Etherpad API documentation #
##############################
# You can run these requests using the emacs restclient major mode
# Create new pad (with content)
POST https://yufu-manifest.ddev.site/etherpad-api/createPad?padID=d2d479bf-b3cb-455a-b7db-5d53c31d1fa2
Content-Type: application/x-www-form-urlencoded
text=While post-communist, post-socialist and post-Yugoslav discourses merely reinforce the appearance of an unchanging and unstable present with a more or less accurate expression of the situation, Yugofuturism follows the example of other ethnofuturist movements such as Afrofuturism, Sinofuturism, Baltic Ethnofuturism and Hungarofuturism, which tactically empower peripheral identities and subversively affirm individual cultural curiosities.
# Crate new pad (with content, JSON)
POST https://yufu-manifest.ddev.site/etherpad-api/createPad?padID=d2d479bf-b3cb-455a-b7db-5d53c31d1fa2
Content-Type: application/json
{
"text": "While post-communist, post-socialist and post-Yugoslav discourses merely reinforce the appearance of an unchanging and unstable present with a more or less accurate expression of the situation, Yugofuturism follows the example of other ethnofuturist movements such as Afrofuturism, Sinofuturism, Baltic Ethnofuturism and Hungarofuturism, which tactically empower peripheral identities and subversively affirm individual cultural curiosities."
}
# Fetch pad content
GET https://yufu-manifest.ddev.site/etherpad-api/getText?padID=d2d479bf-b3cb-455a-b7db-5d53c31d1fa2
# Delete pad content
GET https://yufu-manifest.ddev.site/etherpad-api/deletePad?padID=d2d479bf-b3cb-455a-b7db-5d53c31d1fa2

View File

@ -52,7 +52,7 @@ class Client {
/**
* Method description.
*/
public function request($method, $url, $opts = []) {
public function request($url, $opts = []) {
$uri = "{$this->baseUrl}/" . self::API_VERSION . '/' . explode('?', $url)[0];
if (!isset($opts['form_params'])) {
$opts['form_params'] = [];

View File

@ -41,7 +41,7 @@ class EtherpadApiController extends ControllerBase {
$opts = ['form_params' => $data];
try {
return $this->client->request($request->getMethod(), $uri, $opts);
return $this->client->request($uri, $opts);
} catch (ClientException $exception) {
return new Response($exception->getMessage(), $exception->getCode());
}

View File

@ -1,4 +1,4 @@
# _*_ restclient _*_
# -*- restclient -*-
# Makes post http request to a resource from yufu_concept module.
# Make sure uuid is uniq or it will create new revision.