feat: query Vervis for information on a person
I discovered that Vervis understands Content Negotiation. That is, once I figure out my peopleId I can navigate to the respective paths and resceive JSON that is equal to the prettyjson'ed HTML views I can see in the web browser. I don't find everything I would like to have. Therefore I'm writing the results to a file for now and read it in the profile so I can talk to our designer how to move on with what we have right now. Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
This commit is contained in:
parent
bafd831696
commit
311e5123e7
6 changed files with 118 additions and 6 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -18,3 +18,4 @@ storybook-static
|
|||
|
||||
# See https://tauri.app/v1/guides/development/development-cycle#2-start-tauri-development-window
|
||||
src-tauri/target
|
||||
account.json
|
||||
|
|
|
@ -96,6 +96,24 @@ You should have received a copy of the GNU Affero General Public License along w
|
|||
}
|
||||
})}
|
||||
</p>
|
||||
<div>
|
||||
<p>The following is DEBUG information and will be removed in the near future.</p>
|
||||
{#if data?.user}
|
||||
<div>
|
||||
<b>Person</b>
|
||||
<pre>{JSON.stringify(data.user.person, null, 2)}</pre>
|
||||
</div>
|
||||
<div>
|
||||
<b>Followings</b>
|
||||
<pre>{JSON.stringify(data.user.followings, null, 2)}</pre>
|
||||
</div>
|
||||
<div>
|
||||
<b>Followings mapped</b>
|
||||
<p>These are the contents of the items in the previous dump.</p>
|
||||
<pre>{JSON.stringify(data.user.followingsMap, null, 2)}</pre>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- History -->
|
||||
|
|
|
@ -32,7 +32,7 @@ export async function getHomepage({ account, passphrase, server }) {
|
|||
|
||||
if (loggedInResponse.status === 200) {
|
||||
const headers = new AxiosHeaders();
|
||||
headers.set({ Cookie: loggedInResponse.headers['set-cookie'].join(';') });
|
||||
headers.set({ Cookie: getCookie(loggedInResponse) });
|
||||
|
||||
const response = await loginFormData.instance.get('/', {
|
||||
headers
|
||||
|
@ -45,6 +45,15 @@ export async function getHomepage({ account, passphrase, server }) {
|
|||
const tickets = [];
|
||||
|
||||
const dom = cheerio.load(response.data);
|
||||
const inbox = getInboxLinkFromResponse(response);
|
||||
const peopleId = getPeopleIdFromInboxLink(inbox);
|
||||
const r = await fetchPersonData(loginFormData, getCookie(response), peopleId);
|
||||
const person = getPersonFromResponse(r);
|
||||
const s = await fetchFollowings(loginFormData, getCookie(r), person);
|
||||
const followings = getFollowingsFromResponse(s);
|
||||
const t = await fetchFollowingsMap(loginFormData, getCookie(s), followings);
|
||||
const followingsMap = getFollowingsMapFromRsponses(t);
|
||||
|
||||
if (dom('h2:contains("Your teams") + p').text().includes("aren't a member")) {
|
||||
console.log('No teams');
|
||||
}
|
||||
|
@ -72,7 +81,10 @@ export async function getHomepage({ account, passphrase, server }) {
|
|||
}
|
||||
|
||||
return {
|
||||
cookies: response.headers['set-cookie'].join(';'),
|
||||
cookies: getCookie(t[t.length - 1]),
|
||||
followings,
|
||||
followingsMap,
|
||||
person,
|
||||
patches,
|
||||
projects,
|
||||
repos,
|
||||
|
@ -85,3 +97,67 @@ export async function getHomepage({ account, passphrase, server }) {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
function getCookie(lastResponse) {
|
||||
return lastResponse.headers['set-cookie'].join(';');
|
||||
}
|
||||
|
||||
function getInboxLinkFromResponse(response) {
|
||||
const dom = cheerio.load(response.data);
|
||||
// Since the PeopleID is not marked up anywhere on the homepage,
|
||||
// I pick the first link I know that it contains it.
|
||||
// If there was a /me endpoint or something that would help
|
||||
return dom('header span + span + span a').attr('href');
|
||||
}
|
||||
|
||||
function getPersonFromResponse(response) {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
function getFollowingsFromResponse(response) {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
function getFollowingsMapFromRsponses(responses) {
|
||||
return responses.map((response) => response.data);
|
||||
}
|
||||
|
||||
function getPeopleIdFromInboxLink(inboxLink) {
|
||||
// The id is part of the pathname as /people/:peopleId/inbox
|
||||
const url = new URL(inboxLink);
|
||||
const parts = url.pathname.split('/');
|
||||
return parts[2];
|
||||
}
|
||||
|
||||
async function fetchPersonData(loginFormData, cookie, peopleId) {
|
||||
const headers = new AxiosHeaders();
|
||||
headers.set({ Cookie: cookie });
|
||||
|
||||
const response = await loginFormData.instance.get(`/people/${peopleId}`, {
|
||||
headers
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function fetchFollowings(loginFormData, cookie, person) {
|
||||
const headers = new AxiosHeaders();
|
||||
headers.set({ Cookie: cookie });
|
||||
const { pathname } = new URL(person.following);
|
||||
|
||||
const response = await loginFormData.instance.get(pathname, { headers });
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
async function fetchFollowingsMap(loginFormData, cookie, followings) {
|
||||
const headers = new AxiosHeaders();
|
||||
headers.set({ Cookie: cookie });
|
||||
|
||||
const mappedFollowings = followings.items.map((following) => {
|
||||
const { pathname } = new URL(following);
|
||||
return loginFormData.instance.get(pathname, { headers });
|
||||
});
|
||||
|
||||
return Promise.all(mappedFollowings);
|
||||
}
|
||||
|
|
|
@ -59,5 +59,3 @@ export async function postRemoteLogin({ username, password, loginFormData }) {
|
|||
data
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
|
||||
import { fail, redirect } from '@sveltejs/kit';
|
||||
|
||||
import { requests } from '$lib/server/ap/index.js';
|
||||
|
@ -31,8 +33,12 @@ export const actions = {
|
|||
}
|
||||
|
||||
try {
|
||||
const response = await requests.post('/login', { account, passphrase, server });
|
||||
console.log('DEBUG', response);
|
||||
const response = await requests.post('/login', {
|
||||
account,
|
||||
passphrase,
|
||||
server
|
||||
});
|
||||
await writeFile('account.json', JSON.stringify(response));
|
||||
} catch (exc) {
|
||||
console.error(exc);
|
||||
return fail(400, { account, incorrect: true });
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { readFile } from 'node:fs/promises';
|
||||
|
||||
import { requests } from '$lib/server/ap/index.js';
|
||||
|
||||
/** @type {import('./$types').PageServerLoad} */
|
||||
export async function load({ params }) {
|
||||
const profile = await requests.get('/profile');
|
||||
const account = await readAccountData();
|
||||
|
||||
return {
|
||||
server: {
|
||||
|
@ -22,9 +24,20 @@ export async function load({ params }) {
|
|||
},
|
||||
user: {
|
||||
...profile,
|
||||
...account,
|
||||
created_at: new Date(profile.created_at),
|
||||
created_with: 'Anvil',
|
||||
instance: 'example.com'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function readAccountData() {
|
||||
try {
|
||||
const account = await readFile('account.json', 'utf8');
|
||||
return JSON.parse(account);
|
||||
} catch (exc) {
|
||||
console.error(exc);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue