Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a drawpile session from outside the desktop app #1364

Open
seanwestfall opened this issue Sep 2, 2024 · 11 comments
Open

Create a drawpile session from outside the desktop app #1364

seanwestfall opened this issue Sep 2, 2024 · 11 comments
Labels
feature New features or improvements to existing ones needs design An idea that needs a design for it, like a UI mockup or similar needs discussion For ideas not fully fleshed out yet and need more work before putting into motion

Comments

@seanwestfall
Copy link

Hello,
I would like to request some help in finding a way to modify the source of drawpile, to allow me to create a session from outside a loaded drawpile desktop app. I can see from the listserver that you can insert a session from here, https://github.com/drawpile/listserver/blob/97603b31130be4fdfef441fbc9443baaecd4b98a/db/db_sqlite.go#L435, but there does not appear to be a way to create a session from the listserver, the listserver insert session only inserts an already created session from a loaded drawpile app.

Upon sleuthing through the source code of drawpile, it would appear you would need to create a session from inside an active loaded version of drawpile web first. I can see that there is a function within drawpile for creating a session here:

std::tuple<Session*, QString> SessionServer::createSession(const QString &id, const QString &idAlias, const protocol::ProtocolVersion &protocolVersion, const QString &founder)

and that drawpile has a web API here:

void Webadmin::setSessions(MultiServer *server)

Would it be possible to call this API to create a session, if I specified the listserver / host, the username of the admin, the title, and password if there is one, that would call the create session function

Thanks if there is any guidance out there, hint, tips, or any help would be very appreciated.

@askmeaboutlo0m askmeaboutlo0m added the support User needs assistance in using program label Sep 2, 2024
@askmeaboutlo0m
Copy link
Member

The server portion of Drawpile does not deal with the drawing protocol, so it providing a function to create a session doesn't make much sense architecturally. I mean, you could create a session in theory, but it would have a canvas with size zero and no layers, which is not spectacularly useful.

But the way you're supposed to solve this is using session templates. You provide files with metadata like the session title and whatnot, plus a recording of the initial state taken from a client. You can tell the server a directory to scan for those templates and it will act like those templated sessions always exist and will automatically reify them when someone join them. The session will then keep running according to the idle timeout and persistence rules of the server afterwards. Once it is terminated by any means, it returns to its slumbering state and will be revived from the template once someone joins it.

Does that solve your use case? Otherwise providing an explanation of that would be helpful to actually give you proper pointers, this looks like an XY problem to me.

The listserver is for listing sessions, similar to listservers in a video game. It doesn't have anything to do with creating sessions.

@seanwestfall
Copy link
Author

seanwestfall commented Sep 2, 2024

I'm trying to understand session templates by following the docs, it says you can create a template from the export options from file, but looking from web.drawpile.net I can not see this option.

Screen Shot 2024-09-02 at 1 52 35 PM

Does there need to an option included when building/compiling drawpile desktop server?

@askmeaboutlo0m
Copy link
Member

askmeaboutlo0m commented Sep 3, 2024 via email

@seanwestfall
Copy link
Author

it seems like an understandable want, but I want the ability to create a drawpile app session from the list server admin. Like a button, connected to a loaded and running version of drawpile desktop app that will start up a session and give you a link that can be shared with others that will take you to session.

Something like this:
create a session button

If you understand drawpile, then you would know that there isn't a way to create a session from the admin listserver. It needs to be created from within drawpile desktop first, and then it'll be listed in the list server, but there is no way to create a session from the list server alone. So that's why I am looking for a way to create a session from the webadmin api, either with session templates or some other way by modifying the source code.

@askmeaboutlo0m
Copy link
Member

You are describing implementation. What drives you to want to have this button in the first place?

By your description, the solution is to use the client to host a session. That'll create the session and give you a link that you can send to others to join the session. But presumably there's some reason why you want to do it via some other means instead.

@MorrowShore MorrowShore added feature New features or improvements to existing ones and removed support User needs assistance in using program labels Sep 7, 2024
@MorrowShore
Copy link
Member

Could be coincidence, but I (Raven) also looked in the same spot for an option to create a new session the first time I used Drawpile.
An additional way to create session won't be bad to have, especially since this one already requires being logged into the admin panel (and therefore unlikely to have bad implications).
It could be said that having a way to create sessions along the ability to manage them seems only natural.
But the problem arises when we ask what parameters would it start the session with. This probably calls for a suite of options in the admin panel for creating sessions and their parameters, which is not ideal to have in an admin panel.
Would leave this open in case it reoccurs or is referenced in future feature requests.

@askmeaboutlo0m
Copy link
Member

askmeaboutlo0m commented Sep 7, 2024 via email

@MorrowShore MorrowShore added needs design An idea that needs a design for it, like a UI mockup or similar needs technical concept An idea that needs its technical side thought out, likely requires someone familiar with the code labels Sep 7, 2024
@seanwestfall
Copy link
Author

Let me explain my current approach to this:

I found out that there is a web server for the chat system in https://github.com/drawpile/Drawpile/blob/main/src/thinsrv/webadmin/webadmin.cpp#L51
I'm not sure exactly where this HTTP server leads to, so I've been trying to match on a chat command to see where it ends up, and this could be in either https://github.com/drawpile/Drawpile/blob/main/src/libserver/client.cpp#L276 or https://github.com/drawpile/Drawpile/blob/main/src/libserver/session.cpp#L1655 or https://github.com/drawpile/Drawpile/blob/main/src/libserver/sessionserver.cpp#L310. If tried matching on a text command from either of these entry points, but so far I haven't found something that works. I am sending a matchable command like this:
Screen Shot 2024-09-09 at 1 06 54 PM from the listserver.

After I figure out how to send a text based command to the webserver, I plan to link it to the session creation function in https://github.com/drawpile/Drawpile/blob/main/src/desktop/mainwindow.cpp#L2259 Using https://doc.qt.io/qt-6/signalsandslots.html,

I am creating a copy of MainWindow::hostSession() as a signal:

// ./src/desktop/mainwindow.h line 126
signals:
	void hostSessionEnabled(bool enabled);
	void smallScreenModeChanged(bool smallScreenMode);
	void windowReplacementFailed(MainWindow *win);
	void viewShifted(qreal deltaX, qreal deltaY);

	void hostSessionViaRemote(
                const QString &title, const QString &password, const QString &alias,
                bool nsfm, const QString &announcementUrl,
                const QString &remoteAddress);

and once I can match on a text command I plan to invoke it with

#include "desktop/mainwindow.h"
...
emit hostSessionViaRemote("title","password","alias",false,"announcmenturl","0.0.0.0");

I know as you guys have pointed out, that setting the parameters is not going to be so simple, but this is the basic approach I am taking to doing this.

@askmeaboutlo0m
Copy link
Member

Please answer the question I posed about the use case. You are very likely walking in the wrong direction here, I don't want to help string you along on this path straight into a brick wall.

@seanwestfall
Copy link
Author

seanwestfall commented Sep 16, 2024

So, let me update you on my progress, as I did implement what I described above, and it did work in concept, though, I am receiving some other errors after the mainwindow::hostSession() function is called.

What approached worked was I added a string matching condition in the chatwidget component:

void ChatWidget::systemMessage(const QString &message, bool alert)
{
	const bool wasAtEnd = d->isAtEnd();
	const QString safetext = htmlutils::linkify(htmlutils::emojify(message.toHtmlEscaped()));

	if(alert) {

		if(message == "create_new_session") {
			const auto safetext2 = QStringLiteral("the create_new_session function was called!");
			d->publicChat().appendMessageCompact(
				0, QString(), safetext2, false, true);
			emit expandRequested();

			/*
			const QString &title, const QString &password, const QString &alias, bool nsfm, const QString &announcementUrl, const QString &remoteAddress
			*/

			emit emitHostSessionViaRemote();

		} else {
			d->publicChat().appendMessageCompact(
				0, QString(), safetext, false, true);
			emit expandRequested();
		}
	} else {
		d->publicChat().appendNotification(safetext);
	}

	notification::Event event =
		alert ? notification::Event::PrivateChat : notification::Event::Chat;
	notifySanitize(event, message);

	if(wasAtEnd || alert) {
		d->scrollChatToEnd(0);
	}
}

Which I connected with a signal and slot, that traces back to the mainwindow, where the host session function is held:

within Chatwidget is a connector function

void ChatWidget::connectMainWindow(MainWindow *mainWindow)
{
	connect(this, &ChatWidget::emitHostSessionViaRemote, mainWindow, &MainWindow::hostSessionViaRemote);
}

which is called by chatbox

void ChatBox::connectMainWindow(MainWindow *mainWindow)
{
	m_chatWidget->connectMainWindow(mainWindow);
}

which is called in the mainwindow, within it's constructor:

...
	m_chatbox->connectMainWindow(this);
...

then there is a copy of hostSession set as a public slot:

void MainWindow::hostSessionViaRemote()
{
	m_doc->client()->sendMessage(net::makeChatMessage(1, 0, 0, QStringLiteral("the hostSessionViaRemote function has been called")));
	showErrorMessage(tr("the hostSessionViaRemote function has been called"));

	const QString &title = QStringLiteral("testtitle");
	const QString &password = nullptr;
	const QString &alias = QStringLiteral("alias");
	bool nsfm = false;
	const QString &announcementUrl = QStringLiteral("welcome");
	const QString &remoteAddress = QStringLiteral("...");

	if(!m_doc->canvas()) {
		showErrorMessage(tr("No canvas to host! Create one or open a file."));
		return;
	}
	...
}

The slot defined in mainwindow.h

public slots:
	// Triggerable actions
	...
	void hostSessionViaRemote();

triggering all of this with a system message of create_new_session does lead to some errors coming from the hostSession function, but the way to call it worked.

@MorrowShore
Copy link
Member

Hello again.
**We're awaiting the reasoning or rationale as to why you would want this feature. **

Redundancy is good, but it's not viable alone.

Thank you for the technical concept.
Implementing it is more than possible, just hasslesome.

@MorrowShore MorrowShore added needs discussion For ideas not fully fleshed out yet and need more work before putting into motion and removed needs technical concept An idea that needs its technical side thought out, likely requires someone familiar with the code labels Oct 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New features or improvements to existing ones needs design An idea that needs a design for it, like a UI mockup or similar needs discussion For ideas not fully fleshed out yet and need more work before putting into motion
Projects
None yet
Development

No branches or pull requests

3 participants