Commit 78ee15d4 authored by Eugene Shen's avatar Eugene Shen

Store contact information in ERP5 Persons

Store a jio_configuration string in ERP5 Persons to share contact info,
remove the entire concept of folders and replace it with rooms instead,
use emails to find contacts, replace ERP5 Python Scripts with pure jIO,
move query helpers to gadget_global and force names to be alphanumeric.
parent b9917283
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
<form class="login-form"> <form class="login-form">
<label>Name:</label> <label>Name:</label>
<input type="text" name="name" required="required" /> <input type="text" name="name" required="required" />
<label>Folder:</label>
<input type="text" name="folder" required="required" />
<h3>Remote Storage</h3> <h3>Remote Storage</h3>
<label> <label>
...@@ -44,7 +42,7 @@ ...@@ -44,7 +42,7 @@
<h3>Storage Configuration</h3> <h3>Storage Configuration</h3>
<a class="dropbox-link">Dropbox OAuth</a> <a class="dropbox-link">Dropbox OAuth</a>
<label>Dropbox folder:</label> <label>Dropbox folder:</label>
<input type="text" name="remote_dropbox_url" placeholder="/Apps/OfficeJS Chat/.jio_documents" /> <input type="text" name="remote_dropbox_folder" placeholder="/Apps/OfficeJS Chat/.jio_documents/" />
<label>ERP5 URL:</label> <label>ERP5 URL:</label>
<input type="text" name="remote_erp5_url" placeholder="https://softinst75770.host.vifib.net/erp5/web_site_module/" /> <input type="text" name="remote_erp5_url" placeholder="https://softinst75770.host.vifib.net/erp5/web_site_module/" />
<label>WebDAV URL:</label> <label>WebDAV URL:</label>
...@@ -58,11 +56,9 @@ ...@@ -58,11 +56,9 @@
<label>Default storage:</label> <label>Default storage:</label>
<input type="text" name="auth" placeholder="dropbox" /> <input type="text" name="auth" placeholder="dropbox" />
<label>Dropbox folder:</label> <label>Dropbox folder:</label>
<input type="text" name="auth_dropbox_url" placeholder="/Apps/OfficeJS Chat" /> <input type="text" name="auth_dropbox_folder" placeholder="/Apps/OfficeJS Chat/" />
<label>ERP5 URL:</label> <label>ERP5 URL:</label>
<input type="text" name="auth_erp5_url" placeholder="https://softinst75770.host.vifib.net/erp5/webrtc_rooms_module/" /> <input type="text" name="auth_erp5_url" placeholder="https://softinst75770.host.vifib.net/erp5/webrtc_rooms_module/" />
<label>ERP5 Hateoas:</label>
<input type="text" name="auth_hateoas_url", placeholder="https://softinst75770.host.vifib.net/erp5/web_site_module/hateoas" />
<br /> <br />
<input type="submit" name="login" value="Login!" /> <input type="submit" name="login" value="Login!" />
</form> </form>
......
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
/* URL Options: /* URL Options:
* name: your chat username, e.g. eyqs * name: your chat username, e.g. eyqs
* folder: the root folder for your organization, e.g. nexedi;
* you can only chat with people with access to the same auth folder
* remote: the type of remote storage to use, * remote: the type of remote storage to use,
* either dav, dropbox, erp5, or local * either dav, dropbox, erp5, or local
* remote_dropbox_url: the remote Dropbox folder to synchronize with, * remote_dropbox_folder: the remote Dropbox folder to synchronize with,
* e.g. /Apps/OfficeJS Chat/.jio_documents * e.g. /Apps/OfficeJS Chat/.jio_documents/
* remote_erp5_url: the remote ERP5 instance to synchronize with, * remote_erp5_url: the remote ERP5 instance to synchronize with,
* e.g. https://softinst75770.host.vifib.net/erp5/web_site_module/ * e.g. https://softinst75770.host.vifib.net/erp5/web_site_module/
* remote_dav_url: the remote WebDAV server to synchronize with, * remote_dav_url: the remote WebDAV server to synchronize with,
...@@ -16,52 +14,20 @@ ...@@ -16,52 +14,20 @@
* remote_dav_pass: your WebDAV password, e.g. correct horse battery staple * remote_dav_pass: your WebDAV password, e.g. correct horse battery staple
* auth: the default type of authentication to use for WebRTC rooms, * auth: the default type of authentication to use for WebRTC rooms,
* either dropbox or erp5 * either dropbox or erp5
* auth_dropbox_url: the shared Dropbox folder to act as your auth folder, * auth_dropbox_folder: the shared Dropbox folder for WebRTC negotiations,
* e.g. /Apps/OfficeJS Chat * e.g. /Apps/OfficeJS Chat/
* auth_erp5_url: the shared ERP5 instance to act as your auth folder, * auth_erp5_url: the shared ERP5 instance to store WebRTC negotiations,
* e.g. https://softinst75770.host.vifib.net/erp5/webrtc_rooms_module/ * e.g. https://softinst75770.host.vifib.net/erp5/web_site_module/
*/ */
function cleanId(input_id) {
const reserved = ["_", "&", "=", ",", ";", "\\"];
for (let i = 0, i_len = reserved.length; i < i_len; i++) {
input_id = input_id.replace(reserved[i], "-");
}
return input_id;
}
function getQueryValue(query_list, query_string) {
for (let i = 0, i_len = query_list.length; i < i_len; i++) {
const query = query_list[i];
if (query_string.indexOf(query + "=") !== -1) {
const start = query_string.indexOf(query + "=") + query.length + 1;
let end = query_string.indexOf("&", start);
if (end === -1) {
end = query_string.length;
}
return query_string.slice(start, end);
}
}
return null;
}
function setQueryValue(query_list, query_string, element) {
value = getQueryValue(query_list, query_string);
if (value) {
element.value = value;
}
}
rJS(window) rJS(window)
.ready(function (gadget) { .ready(function (gadget) {
gadget.state_parameter_dict = { gadget.state_parameter_dict = {
element: null, element: null,
name: null, name: null,
folder: null,
auth: null, auth: null,
dropbox_url: null, dropbox_folder: null,
erp5_url: null, erp5_url: null,
hateoas_url: null,
// Dropbox OAuth only allows 500 characters in the state query // Dropbox OAuth only allows 500 characters in the state query
max_state_length: 500, max_state_length: 500,
}; };
...@@ -104,6 +70,38 @@ ...@@ -104,6 +70,38 @@
}) })
.push(null, logError); .push(null, logError);
}) })
.allowPublicAcquisition('getContactByEmail', function (param_list) {
const gadget = this;
const email = param_list[0];
let storage_gadget;
return new RSVP.Queue()
.push(function () {
return gadget.getDeclaredGadget("storage_gadget");
})
.push(function (jio_gadget) {
storage_gadget = jio_gadget;
return storage_gadget.allDocs({
limit: [0, 1000000],
query: 'portal_type: "Person"',
sort_on: [["last_modified", "descending"]],
select_list: ["default_email_coordinate_text", "jio_configuration"],
});
})
.push(function (person_list) {
if (person_list.data.rows.length) {
for (let i = 0, i_len = person_list.data.rows.length;
i < i_len; i++) {
if (person_list.data.rows[i].value
.default_email_coordinate_text === email) {
return person_list.data.rows[i].id;
}
}
}
return person_list.data.rows.length.toString();
})
.push(null, logError);
})
.allowPublicAcquisition('chooseRoom', function (param_list) { .allowPublicAcquisition('chooseRoom', function (param_list) {
const gadget = this; const gadget = this;
...@@ -122,12 +120,10 @@ ...@@ -122,12 +120,10 @@
.push(function (chat_gadget) { .push(function (chat_gadget) {
const fields = webrtc_gadget.state_parameter_dict.element const fields = webrtc_gadget.state_parameter_dict.element
.querySelector(".contact-form").elements; .querySelector(".contact-form").elements;
fields.dropbox_url.value = param_dict.dropbox_url fields.dropbox_folder.value = param_dict.dropbox_folder
|| gadget.state_parameter_dict.dropbox_url; || gadget.state_parameter_dict.dropbox_folder;
fields.erp5_url.value = param_dict.erp5_url fields.erp5_url.value = param_dict.erp5_url
|| gadget.state_parameter_dict.erp5_url; || gadget.state_parameter_dict.erp5_url;
fields.hateoas_url.value = param_dict.hateoas_url
|| gadget.state_parameter_dict.hateoas_url;
webrtc_gadget.state_parameter_dict.element.querySelector(".auth-form") webrtc_gadget.state_parameter_dict.element.querySelector(".auth-form")
.auth.value = param_dict.auth || gadget.state_parameter_dict.auth; .auth.value = param_dict.auth || gadget.state_parameter_dict.auth;
chat_gadget.state_parameter_dict.element chat_gadget.state_parameter_dict.element
...@@ -136,7 +132,6 @@ ...@@ -136,7 +132,6 @@
chat_gadget.state_parameter_dict.element chat_gadget.state_parameter_dict.element
.querySelector(".chat-right-panel-chat")); .querySelector(".chat-right-panel-chat"));
webrtc_gadget.state_parameter_dict.login_dict = { webrtc_gadget.state_parameter_dict.login_dict = {
folder: gadget.state_parameter_dict.folder,
room: param_dict.room, room: param_dict.room,
name: gadget.state_parameter_dict.name, name: gadget.state_parameter_dict.name,
role: param_dict.role, role: param_dict.role,
...@@ -192,10 +187,10 @@ ...@@ -192,10 +187,10 @@
}) })
.declareMethod('render', function () { .declareMethod('render', function () {
let url = decodeURIComponent(document.URL);
const gadget = this; const gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
let url = decodeURIComponent(document.URL);
const state_output = getQueryValue(["state"], url); const state_output = getQueryValue(["state"], url);
if (state_output) { if (state_output) {
url += window.atob(state_output); url += window.atob(state_output);
...@@ -204,12 +199,11 @@ ...@@ -204,12 +199,11 @@
.querySelector(".login-form").elements; .querySelector(".login-form").elements;
let state_input = ""; let state_input = "";
// A list of login-form fields and short keys in order of priority // A list of login-form fields and short keys in order of priority
const query_list = [["name", "m"], ["folder", "f"], ["remote", "r"], const query_list = [["name", "m"], ["remote", "r"],
["remote_dropbox_url", "rd"], ["remote_erp5_url", "re"], ["remote_dropbox_folder", "rd"], ["remote_erp5_url", "re"],
["remote_dav_url", "rv"], ["remote_dav_user", "rvu"], ["remote_dav_url", "rv"], ["remote_dav_user", "rvu"],
["remote_dav_pass", "rvp"], ["auth", "a"], ["remote_dav_pass", "rvp"], ["auth", "a"],
["auth_dropbox_url", "ad"], ["auth_erp5_url", "ae"], ["auth_dropbox_folder", "ad"], ["auth_erp5_url", "ae"]]
["auth_hateoas_url", "ah"]]
for (let i = 0, i_len = query_list.length; i < i_len; i++) { for (let i = 0, i_len = query_list.length; i < i_len; i++) {
const query = query_list[i]; const query = query_list[i];
setQueryValue(query, url, fields[query[0]]); setQueryValue(query, url, fields[query[0]]);
...@@ -246,27 +240,28 @@ ...@@ -246,27 +240,28 @@
const fields = gadget.state_parameter_dict.element const fields = gadget.state_parameter_dict.element
.querySelector(".login-form").elements; .querySelector(".login-form").elements;
gadget.state_parameter_dict.auth = fields.auth.value; gadget.state_parameter_dict.auth = fields.auth.value;
gadget.state_parameter_dict.dropbox_url = gadget.state_parameter_dict.dropbox_folder =
fields.auth_dropbox_url.value; fields.auth_dropbox_folder.value;
gadget.state_parameter_dict.erp5_url = fields.auth_erp5_url.value; gadget.state_parameter_dict.erp5_url = fields.auth_erp5_url.value;
gadget.state_parameter_dict.hateoas_url = gadget.state_parameter_dict.name =
fields.auth_hateoas_url.value; fields.name.value.replace(/[^0-9a-z]/gi, '');
gadget.state_parameter_dict.name = cleanId(fields.name.value);
gadget.state_parameter_dict.folder = cleanId(fields.folder.value);
chat_gadget.state_parameter_dict.name = chat_gadget.state_parameter_dict.name =
gadget.state_parameter_dict.name; gadget.state_parameter_dict.name;
chat_gadget.state_parameter_dict.folder =
gadget.state_parameter_dict.folder;
// XXX apply drivetojiomapping in custom dropbox_url directory
return gadget.createJio({ return gadget.createJio({
remote: fields.remote.value, remote: fields.remote.value,
dropbox_url: fields.remote_dropbox_url.value, dropbox_folder: fields.remote_dropbox_folder.value,
erp5_url: fields.remote_erp5_url.value, erp5_url: fields.remote_erp5_url.value,
dav_url: fields.remote_dav_url.value, dav_url: fields.remote_dav_url.value,
dav_user: fields.remote_dav_user.value, dav_user: fields.remote_dav_user.value,
dav_pass: fields.remote_dav_pass.value, dav_pass: fields.remote_dav_pass.value,
}); });
}) })
.push(function () {
return gadget.getDeclaredGadget("storage_gadget");
})
.push(function (storage_gadget) {
return storage_gadget.repair();
})
.push(function () { .push(function () {
return chat_gadget.render(); return chat_gadget.render();
}) })
...@@ -346,8 +341,8 @@ ...@@ -346,8 +341,8 @@
use_remote_post: remote_post, use_remote_post: remote_post,
conflict_handling: 2, conflict_handling: 2,
query: { query: {
query: 'portal_type: "Text Post"',
limit: [0, 1000000000], limit: [0, 1000000000],
query: 'portal_type: "Person" OR portal_type: "Text Post"',
}, },
local_sub_storage: { local_sub_storage: {
type: "query", type: "query",
......
...@@ -54,8 +54,8 @@ ...@@ -54,8 +54,8 @@
} }
function isSameMessage(lhs, rhs) { function isSameMessage(lhs, rhs) {
return lhs !== undefined && rhs !== undefined && lhs.name === rhs.name return lhs !== undefined && rhs !== undefined
&& lhs.content === rhs.content && lhs.folder === rhs.folder && lhs.name === rhs.name && lhs.content === rhs.content
&& lhs.room === rhs.room && getTime(lhs) === getTime(rhs); && lhs.room === rhs.room && getTime(lhs) === getTime(rhs);
} }
...@@ -144,15 +144,13 @@ ...@@ -144,15 +144,13 @@
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
gadget.state_parameter_dict = { gadget.state_parameter_dict = {
folder: null,
room: null, room: null,
name: null, name: null,
element: null, element: null,
initialized: false, initialized: false,
// A set of names of rooms joined within this folder; // A set of names of current rooms; as a guest, only notify that
// as a guest, only notify that you have joined once // you have joined once you have received the host's remote archive,
// you have received the host's remote archive, so that // so that your notification doesn't override all previous messages
// your notification doesn't override all previous messages
// room_set["room"] = false if joined, true if also notified // room_set["room"] = false if joined, true if also notified
room_set: {}, room_set: {},
// A dictionary of messages based on the current room, e.g. // A dictionary of messages based on the current room, e.g.
...@@ -183,12 +181,12 @@ ...@@ -183,12 +181,12 @@
const gadget = this; const gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
gadget.state_parameter_dict.room = gadget.state_parameter_dict.name;
gadget.state_parameter_dict.element gadget.state_parameter_dict.element
.querySelector(".send-form input").onfocus = function () { .querySelector(".send-form input").onfocus = function () {
return logQueue( return logQueue(
gadget.notifyStatus(gadget.state_parameter_dict.room, false)); gadget.notifyStatus(gadget.state_parameter_dict.room, false));
}; };
gadget.state_parameter_dict.room = gadget.state_parameter_dict.name;
}) })
.push(null, logError); .push(null, logError);
}) })
...@@ -199,32 +197,31 @@ ...@@ -199,32 +197,31 @@
const gadget = this; const gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return gadget.wrapJioAccess('allDocs'); return gadget.wrapJioAccess('allDocs', {
}) limit: [0, 1000000],
.push(function (document_list) { query: 'portal_type: "Text Post"',
const list = document_list.data.rows; sort_on: [["last_modified", "descending"]],
const promise_list = []; select_list: ["content"],
for (let i = 0, i_len = list.length; i < i_len; i++) { });
promise_list.push(gadget.wrapJioAccess('get', list[i].id));
}
return RSVP.all(promise_list);
}) })
.push(function (message_list) { .push(function (message_list) {
const message_queue = new FastPriorityQueue(messageTimeCompare(true)); const message_queue = new FastPriorityQueue(messageTimeCompare(true));
for (let i = 0, i_len = message_list.length; i < i_len; i++) { if (message_list.data.rows.length) {
try { for (let i = 0, i_len = message_list.data.rows.length;
const message = JSON.parse(message_list[i].content); i < i_len; i++) {
if (message && typeof message === "object") { try {
message_queue.add(message); const message = JSON.parse(list[i]);
} if (message && typeof message === "object") {
} catch (error) {} message_queue.add(message);
}
} catch (error) {}
}
} }
const promise_list = []; const promise_list = [];
const message_dict = gadget.state_parameter_dict.last_message_dict; const message_dict = gadget.state_parameter_dict.last_message_dict;
while (!message_queue.isEmpty()) { while (!message_queue.isEmpty()) {
const message = message_queue.poll(); const message = message_queue.poll();
if (message.folder === gadget.state_parameter_dict.folder if (message.room in gadget.state_parameter_dict.room_set) {
&& (message.room in gadget.state_parameter_dict.room_set)) {
promise_list.push(gadget.storeList(message)); promise_list.push(gadget.storeList(message));
promise_list.push(gadget.appendMessage(message)); promise_list.push(gadget.appendMessage(message));
} }
...@@ -346,7 +343,6 @@ ...@@ -346,7 +343,6 @@
return { return {
type: param_dict.type || "message", type: param_dict.type || "message",
name: param_dict.name || gadget.state_parameter_dict.name, name: param_dict.name || gadget.state_parameter_dict.name,
folder: param_dict.folder || gadget.state_parameter_dict.folder,
room: param_dict.room || gadget.state_parameter_dict.room, room: param_dict.room || gadget.state_parameter_dict.room,
time: param_dict.time || new Date(), time: param_dict.time || new Date(),
content: param_dict.content || "", content: param_dict.content || "",
...@@ -421,20 +417,16 @@ ...@@ -421,20 +417,16 @@
// Store message in the archive // Store message in the archive
.declareMethod('storeArchive', function (message) { .declareMethod('storeArchive', function (message) {
const gadget = this; const gadget = this;
return new RSVP.Queue() const id = message.room + "_" + message.name + "_"
.push(function () { + getTime(message).toString();
const id = message.folder + "_" + message.room + "_" return logQueue(gadget.wrapJioAccess('put', id, {
+ message.name + "_" + getTime(message).toString(); portal_type: "Text Post",
return gadget.wrapJioAccess('put', id, { parent_relative_url: "post_text_module",
portal_type: "Text Post", reference: id,
parent_relative_url: "post_text_module", author: message.name,
reference: id, date_ms: getTime(message),
author: message.name, content: JSON.stringify(message),
date_ms: getTime(message), }));
content: JSON.stringify(message),
});
})
.push(null, logError);
}) })
// Add message to the list // Add message to the list
...@@ -514,7 +506,7 @@ ...@@ -514,7 +506,7 @@
class_name = "notify"; class_name = "notify";
} else { } else {
favicon_url = gadget.state_parameter_dict.default_icon; favicon_url = gadget.state_parameter_dict.default_icon;
class_name = ""; class_name = "current";
} }
const link = document.querySelector("link[rel*='icon']") const link = document.querySelector("link[rel*='icon']")
|| document.createElement("link"); || document.createElement("link");
...@@ -524,16 +516,12 @@ ...@@ -524,16 +516,12 @@
document.head.appendChild(link); document.head.appendChild(link);
const contact = gadget.state_parameter_dict.element const contact = gadget.state_parameter_dict.element
.querySelector("#chat-contact-" + room); .querySelector("#chat-contact-" + room);
if (contact.className === "current") { contact.className = class_name;
contact.className = class_name || "current";
} else {
contact.className = class_name;
}
}) })
.push(null, logError); .push(null, logError);
}) })
// Join a different room in the same folder // Join a different room
.declareMethod('changeRoom', function (room) { .declareMethod('changeRoom', function (room) {
const gadget = this; const gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
...@@ -570,7 +558,6 @@ ...@@ -570,7 +558,6 @@
.declareMethod('createContact', function (param_dict) { .declareMethod('createContact', function (param_dict) {
const gadget = this; const gadget = this;
return new RSVP.Queue() return new RSVP.Queue()
// XXX: load params here too
.push(function () { .push(function () {
return gadget.appendContact(param_dict.room); return gadget.appendContact(param_dict.room);
}) })
...@@ -736,9 +723,7 @@ ...@@ -736,9 +723,7 @@
return gadget.createContact({room: contact, role: "guest"}); return gadget.createContact({room: contact, role: "guest"});
case "make-form": case "make-form":
const room = resetInputValue(event.target.elements.content); const room = resetInputValue(event.target.elements.content);
return gadget.createContact({room: room, role: "host"}); return gadget.chooseRoom({room: room, role: "host"});
case "auth-form":
return gadget.connectContact();
case "send-form": case "send-form":
const content = resetInputValue(event.target.elements.content); const content = resetInputValue(event.target.elements.content);
if (content.indexOf("/") === 0) { if (content.indexOf("/") === 0) {
......
...@@ -15,20 +15,20 @@ ...@@ -15,20 +15,20 @@
<p class="status"></p> <p class="status"></p>
<form class="contact-form"> <form class="contact-form">
<label>Name:</label> <label>E-mail Address:</label>
<input type="text" name="name" /> <input type="text" name="email" />
<label>Folder:</label>
<input type="text" name="folder" />
<label>Dropbox folder:</label> <label>Dropbox folder:</label>
<input type="text" name="dropbox_url" placeholder="/Apps/OfficeJS Chat" /> <input type="text" name="dropbox_folder" placeholder="/Apps/OfficeJS Chat/" />
<label>ERP5 URL:</label> <label>ERP5 URL:</label>
<input type="text" name="erp5_url" placeholder="https://softinst75770.host.vifib.net/erp5/webrtc_rooms_module/" /> <input type="text" name="erp5_url" placeholder="https://softinst75770.host.vifib.net/erp5/web_site_module/" />
<label>Hateoas URL:</label>
<input type="text" name="hateoas_url" placeholder="https://softinst75770.host.vifib.net/erp5/web_site_module/hateoas" />
<br /> <br />
<input type="submit" value="Update information!" /> <input type="submit" value="Update information!" />
</form> </form>
<form class="download-form">
<input type="submit" value="Download information from remote storage!" />
</form>
<form class="auth-form"> <form class="auth-form">
<label> <label>
<input type="radio" name="auth" value="erp5" required="required" /> <input type="radio" name="auth" value="erp5" required="required" />
......
...@@ -149,6 +149,28 @@ ...@@ -149,6 +149,28 @@
return value; return value;
}; };
window.getQueryValue = function (query_list, query_string) {
for (let i = 0, i_len = query_list.length; i < i_len; i++) {
const query = query_list[i];
if (query_string.indexOf(query + "=") !== -1) {
const start = query_string.indexOf(query + "=") + query.length + 1;
let end = query_string.indexOf("&", start);
if (end === -1) {
end = query_string.length;
}
return query_string.slice(start, end);
}
}
return null;
}
window.setQueryValue = function (query_list, query_string, element) {
const value = getQueryValue(query_list, query_string);
if (value) {
element.value = value;
}
}
window.pollUntilNotNull = function ( window.pollUntilNotNull = function (
gadget, delay_ms, timeout_ms, gadget, delay_ms, timeout_ms,
nullableFunction, callbackFunction) { nullableFunction, callbackFunction) {
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_Transient_Objects_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Access_arbitrary_user_session_data_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_events_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_folders_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_member_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_topics_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
</tuple>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>erp5_webrtc_room</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
import json
module = context.getPortalObject().getDefaultModule(portal_type="Webrtc Room")
webrtc_folder = module[folder]
negotiation_list = json.loads(webrtc_folder.negotiation_list)
negotiation_list.pop(name, None)
webrtc_folder.edit(
negotiation_list = json.dumps(negotiation_list)
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>folder, name</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoom_deleteContent</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
import json
module = context.getPortalObject().getDefaultModule(portal_type="Webrtc Room")
webrtc_folder = module[folder]
negotiation_list = json.loads(webrtc_folder.negotiation_list)
return negotiation_list.get(name, "")
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>folder, name</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoom_getContent</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
import json
module = context.getPortalObject().getDefaultModule(portal_type="Webrtc Room")
webrtc_folder = module[folder]
negotiation_list = json.loads(webrtc_folder.negotiation_list)
for name in negotiation_list:
if name.startswith("offer_" + room):
return name[6:]
return ""
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>folder, room</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoom_getOffer</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
import json
module = context.getPortalObject().getDefaultModule(portal_type="Webrtc Room")
webrtc_folder = module[folder]
negotiation_list = json.loads(webrtc_folder.negotiation_list)
negotiation_list[name] = content
webrtc_folder.edit(
negotiation_list = json.dumps(negotiation_list)
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>folder, name, content</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoom_putContent</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
import json
module = context.getPortalObject().getDefaultModule(portal_type="Webrtc Room")
webrtc_folder = module[folder]
webrtc_folder.edit(
negotiation_list = json.dumps({})
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>folder</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoom_resetContent</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_title</string>
<string>my_negotiation_list</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoom_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>WebrtcRoom_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Webrtc Room</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>WebrtcRoomsModule_addWebrtcRoom</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>use this dialog to create new rooms</string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>your_title</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoomsModule_viewAddWebrtcRoom</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>WebrtcRoomsModule_viewAddWebrtcRoom</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>New Rooms</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_doSelect</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebrtcRoomsModule_viewWebrtcRoomList</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>WebrtcRoomsModule_viewWebrtcRoomList</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_list</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Webrtc Rooms</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>selection_name</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>negotiation_list</string>
<string>WebRTC Negotiation List</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>Webrtc Room</string>
<string>Webrtc Room</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>webrtc_rooms_module_selection</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>WebRTC Rooms</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
erp5_webrtc_room
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment