This commit is contained in:
privet.fun 2023-06-04 14:05:48 -07:00
parent 076310e100
commit c675a9537c
21 changed files with 306 additions and 118 deletions

View file

@ -1,4 +1,4 @@
# AI Labs v 1.0.3 RC
# AI Labs v 1.0.4 RC
##### [Changelog](#changelog_link)
Incorporate AI into your phpBB board and get ready for an exciting experience.
@ -41,7 +41,7 @@ Go to `ACP` > `Customise` > `Manage extensions` and enable the `AI Labs` extensi
Finally go to `ACP` > `Extensions` > `AI Labs` > `Settings` and add desired AI configurations:
![Attachment settings](../privet/ailabs/docs/ailabs_settings.png)
## ChatGPT basic setup
## ChatGPT setup
* You will need OpenAI account, sign up at https://platform.openai.com/.
To obtain API key go to https://platform.openai.com/account/api-keys, click on `Create new secret key`, copy and save in a safe place generated API key.
@ -105,12 +105,29 @@ Refer to https://platform.openai.com/docs/api-reference/images/create to learn m
* Refer to https://api.stability.ai/docs#tag/v1generation/operation/textToImage to learn more about configuration JSON parameters.
## Troubleshooting
AI Labs extension maintains internal logs, you should have admin or moderator rights to see log icon:
![Attachment settings](../privet/ailabs/docs/debugging_post_icon.png)
You can see entire AI communication history in the log:
![Attachment settings](../privet/ailabs/docs/debugging_log.png)
If Log entry is empty it ususally means that `/ailabs/*` routes blocked by one of phpBB extensions (eg <a href="https://www.phpbb.com/customise/db/extension/login_required">Login Required</a>) and you will need to add `/ailabs/*` to extension whitelist.
You can examine Log `response` (JSON) to see details for AI response.
Please feel free to post your quesions or concerns at https://github.com/privet-fun/phpbb_ailabs/issues.
## Support and suggestions
This extension is currently being actively developed. For communication, please use https://github.com/privet-fun/phpbb_ailabs/issues.
## <a name="changelog_link"></a>Changelog
* 1.0.4 June 4, 2023
- Troubleshooting section added
- Added cofiguration for reply in topics
- Fixed links generation for cases where cookies disabled
- AI Labs internal controlles (`/ailabs/*`) will attempt to establish session to deal with phpBB extensions like <a href="https://www.phpbb.com/customise/db/extension/login_required">Login Required</a>
- Better descriptions added to help with setup
- Minor bugfixes
* 1.0.3 June 1, 2023
- bumped php requirements to >= 7.4
- Comma removed, reported by [Vlad__](https://www.phpbbguru.net/community/viewtopic.php?p=561224#p561224)

View file

@ -6,15 +6,23 @@
<a id="maincontent"></a>
<h1>{{ lang('ACP_AILABS_TITLE') }}</h1>
<div style="display: flex; align-items: baseline;">
<h1 style="white-space: nowrap;">{{ lang('ACP_AILABS_TITLE') }}</h1>
<div style="width: 100%;"></div><span style="white-space: nowrap;">v. {{ U_AILABS_VERSION }}</span>
</div>
<p>
{{ lang('LBL_AILABS_SETTINGS_DESC') }}
<span>{{ lang('LBL_AILABS_SETTINGS_DESC') }}</span>
{% if U_AILABS_VEIW %}
<a href="{{ U_ADD }}" class="button2" style="float: {{ S_CONTENT_FLOW_END }};">{{ lang('ACP_AILABS_ADD') }}</a>
<br>
<br>
{% if U_IP_CHECK %}
<span>{{ U_IP_CHECK }}</span>
{% endif %}
{% endif %}
{% if U_AILABS_ADD_EDIT %}
@ -120,13 +128,15 @@
function doReset() {
setTimeout(function () {
resetValue('ailabs_forums_post', {{ ailabs_forums_post }});
resetValue('ailabs_forums_mention', {{ ailabs_forums_mention }});
resetValue('ailabs_forums_reply', {{ ailabs_forums_reply }});
resetValue('ailabs_forums_mention', {{ ailabs_forums_mention }});
}, 500);
}
window.addEventListener("DOMContentLoaded", function () {
$(".chosen-select").chosen();
setupSelect('ailabs_forums_post', {{ ailabs_forums_post }});
setupSelect('ailabs_forums_reply', {{ ailabs_forums_reply }});
setupSelect('ailabs_forums_mention', {{ ailabs_forums_mention }});
});
@ -151,7 +161,7 @@
</dd>
</dl>
<dl>
<dt><label for="ailabs_username">{L_ENTER_USERNAME}{L_COLON}</label></dt>
<dt><label for="ailabs_username">{{ lang('LBL_AILABS_USERNAME') ~ lang('COLON') }}</label></dt>
<dd><input required class="text medium" type="text" id="ailabs_username" name="ailabs_username"
value="{{ ailabs_username }}" /></dd>
<dd>[ <a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a> ]
@ -195,10 +205,10 @@
</fieldset>
<fieldset>
<legend>{{ lang('LBL_AILABS_REPLY_POST_FORUMS') }}</legend>
<span>{{ lang('LBL_AILABS_REPLY_POST_FORUMS_EXPLAIN') }}</span>
<select id="ailabs_forums_post_select" class="chosen-select" multiple data-placeholder="{{ lang('LBL_AILABS_SELECT_FORUMS') }}"
style="width: 100%;">
<legend>{{ lang('LBL_AILABS_POST_FORUMS') }}</legend>
<span>{{ lang('LBL_AILABS_POST_FORUMS_EXPLAIN') }}</span>
<select id="ailabs_forums_post_select" class="chosen-select" multiple
data-placeholder="{{ lang('LBL_AILABS_SELECT_FORUMS') }}" style="width: 100%;">
{% for key,value in AILABS_FORUMS_LIST %}
<option value="{{ key }}">{{ value }}</option>
{% endfor %}
@ -206,10 +216,21 @@
</fieldset>
<fieldset>
<legend>{{ lang('LBL_AILABS_REPLY_QUOTE_FORUMS') }}</legend>
<span>{{ lang('LBL_AILABS_REPLY_QUOTE_FORUMS_EXPLAIN') }}</span>
<select id="ailabs_forums_mention_select" class="chosen-select" multiple data-placeholder="{{ lang('LBL_AILABS_SELECT_FORUMS') }}"
style="width: 100%;">
<legend>{{ lang('LBL_AILABS_REPLY_FORUMS') }}</legend>
<span>{{ lang('LBL_AILABS_REPLY_FORUMS_EXPLAIN') }}</span>
<select id="ailabs_forums_reply_select" class="chosen-select" multiple
data-placeholder="{{ lang('LBL_AILABS_SELECT_FORUMS') }}" style="width: 100%;">
{% for key,value in AILABS_FORUMS_LIST %}
<option value="{{ key }}">{{ value }}</option>
{% endfor %}
</select>
</fieldset>
<fieldset>
<legend>{{ lang('LBL_AILABS_QUOTE_FORUMS') }}</legend>
<span>{{ lang('LBL_AILABS_QUOTE_FORUMS_EXPLAIN') }}</span>
<select id="ailabs_forums_mention_select" class="chosen-select" multiple
data-placeholder="{{ lang('LBL_AILABS_SELECT_FORUMS') }}" style="width: 100%;">
{% for key,value in AILABS_FORUMS_LIST %}
<option value="{{ key }}">{{ value }}</option>
{% endfor %}
@ -220,6 +241,7 @@
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
<p class="submit-buttons">
<input type="hidden" id="ailabs_forums_post" name="ailabs_forums_post">
<input type="hidden" id="ailabs_forums_reply" name="ailabs_forums_reply">
<input type="hidden" id="ailabs_forums_mention" name="ailabs_forums_mention">
<input type="reset" class="button2" value="{{ lang('RESET') }}" onclick="doReset()">
@ -235,11 +257,17 @@
<table class="tableUsers zebra-table">
<thead>
<tr>
<th colspan="2" style="background: transparent; border: none;"></th>
<th colspan="3">{{ lang('LBL_AILABS_REPLY_TO') }}</th>
<th colspan="3" style="background: transparent; border: none;"></th>
</tr>
<tr>
<th>{{ lang('LBL_AILABS_USERNAME') }}</th>
<th>{{ lang('LBL_AILABS_CONTROLLER') }}</th>
<th>{{ lang('LBL_AILABS_REPLY_POST_FORUMS') }}</th>
<th>{{ lang('LBL_AILABS_REPLY_QUOTE_FORUMS') }}</th>
<th>{{ lang('LBL_AILABS_POST_FORUMS') }}</th>
<th>{{ lang('LBL_AILABS_REPLY_FORUMS') }}</th>
<th>{{ lang('LBL_AILABS_QUOTE_FORUMS') }}</th>
<th class="centered-text">{{ lang('LBL_AILABS_ENABLED') }}</th>
<th></th>
</tr>
@ -247,9 +275,10 @@
<tbody>
{% for user in U_AILABS_USERS %}
<tr>
<td><a href="/memberlist.php?mode=viewprofile&u={{ user.user_id }}">{{ user.username }}</a></td>
<td><a href="{{ user.username_url }}">{{ user.username }}</a></td>
<td>{{ user.controller }}</td>
<td>{{ user.forums_post_names }}</td>
<td>{{ user.forums_reply_names }}</td>
<td>{{ user.forums_mention_names }}</td>
<td class="centered-text"><input type="checkbox" onclick="return false" {{ user.enabled ? 'checked' : '' }}>
</td>

View file

@ -3,8 +3,8 @@
"type": "phpbb-extension",
"description": "AI Labs",
"homepage": "https://privet.fun",
"version": "1.0.3",
"time": "2023-06-01",
"version": "1.0.4",
"time": "2023-06-04",
"keywords": [
"phpbb",
"extension",

View file

@ -15,6 +15,7 @@ services:
- '@template'
- '@user'
- '%core.root_path%'
- '%core.php_ext%'
- '%privet.ailabs.tables.users%'
privet.ailabs.listener:

View file

@ -23,6 +23,7 @@ class acp_controller //implements acp_interface
protected $template;
protected $user;
protected $root_path;
protected $php_ext;
protected $ailabs_users_table;
protected $id;
@ -51,6 +52,7 @@ class acp_controller //implements acp_interface
\phpbb\template\template $template,
\phpbb\user $user,
$root_path,
$php_ext,
$ailabs_users_table
) {
$this->config = $config;
@ -63,6 +65,7 @@ class acp_controller //implements acp_interface
$this->template = $template;
$this->user = $user;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
$this->ailabs_users_table = $ailabs_users_table;
}
@ -93,6 +96,7 @@ class acp_controller //implements acp_interface
'config' => $this->request->variable('ailabs_config', '', true),
'template' => $this->request->variable('ailabs_template', '', true),
'forums_post' => $this->request->variable('ailabs_forums_post', ''),
'forums_reply' => $this->request->variable('ailabs_forums_reply', ''),
'forums_mention' => $this->request->variable('ailabs_forums_mention', ''),
'enabled' => $this->request->variable('ailabs_enabled', true),
];
@ -111,8 +115,8 @@ class acp_controller //implements acp_interface
trigger_error($this->language->lang('AILABS_USER_ALREADY_CONFIGURED', $username) . adm_back_link($this->u_action), E_USER_WARNING);
}
if (empty($data['forums_post']) && empty($data['forums_mention'])) {
trigger_error($this->language->lang('AILABS_SPECIFY_POST_OR_MENTION') . adm_back_link($this->u_action), E_USER_WARNING);
if (empty($data['forums_post']) && empty($data['forums_reply']) && empty($data['forums_mention'])) {
trigger_error($this->language->lang('AILABS_SPECIFY_FORUM') . adm_back_link($this->u_action), E_USER_WARNING);
}
if (!isset($error)) {
@ -122,6 +126,7 @@ class acp_controller //implements acp_interface
'config' => (string) html_entity_decode($data['config']),
'template' => (string) html_entity_decode($data['template']),
'forums_post' => (string) html_entity_decode($data['forums_post']),
'forums_reply' => (string) html_entity_decode($data['forums_reply']),
'forums_mention' => (string) html_entity_decode($data['forums_mention']),
'enabled' => (bool) $data['enabled']
];
@ -159,6 +164,7 @@ class acp_controller //implements acp_interface
'ailabs_config' => (string) $row['config'],
'ailabs_template' => (string) $row['template'],
'ailabs_forums_post' => (string) $row['forums_post'],
'ailabs_forums_reply' => (string) $row['forums_reply'],
'ailabs_forums_mention' => (string) $row['forums_mention'],
'ailabs_enabled' => (bool) $row['enabled']
];
@ -177,8 +183,6 @@ class acp_controller //implements acp_interface
]);
}
global $phpbb_root_path, $phpEx;
$this->template->assign_vars(
array_merge(
$edit,
@ -187,8 +191,9 @@ class acp_controller //implements acp_interface
'U_AILABS_ADD_EDIT' => true,
'U_ACTION' => $this->action == 'add' ? $this->u_action . '&amp;action=add' : $this->u_action . '&amp;action=edit&amp;user_id=' . $this->user_id,
'U_BACK' => $this->u_action,
'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=ailabs_configuration&amp;field=ailabs_username&amp;select_single=true'),
'U_FIND_USERNAME' => generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=searchuser&amp;form=ailabs_configuration&amp;field=ailabs_username&amp;select_single=true', true, $this->user->session_id),
'AILABS_FORUMS_LIST' => $this->build_forums_list(),
'U_AILABS_VERSION' => $this->config['privet_ailabs_version'],
]
)
);
@ -229,7 +234,9 @@ class acp_controller //implements acp_interface
$controller = explode("/", $row['controller']);
$row['controller'] = end($controller);
$row['username_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $row['user_id'], true, $this->user->session_id);
$row['forums_post_names'] = $this->get_forums_names($row['forums_post'], $forums);
$row['forums_reply_names'] = $this->get_forums_names($row['forums_reply'], $forums);
$row['forums_mention_names'] = $this->get_forums_names($row['forums_mention'], $forums);
$row['U_EDIT'] = $this->u_action . '&amp;action=edit&amp;user_id=' . $row['user_id'] . '&amp;hash=' . generate_link_hash('acp_ailabs');
$row['U_DELETE'] = $this->u_action . '&amp;action=delete&amp;user_id=' . $row['user_id'] . '&amp;username=' . $row['username'] . '&amp;hash=' . generate_link_hash('acp_ailabs');
@ -243,12 +250,23 @@ class acp_controller //implements acp_interface
'U_AILABS_USERS' => $ailabs_users,
'U_ADD' => $this->u_action . '&amp;action=add',
'U_ACTION' => $this->u_action,
'U_AILABS_VEIW' => true
'U_AILABS_VEIW' => true,
'U_AILABS_VERSION' => $this->config['privet_ailabs_version'],
'U_IP_CHECK' => $this->warn_ip_check()
];
return $this->template->assign_vars($template_vars);
}
protected function warn_ip_check()
{
if ($this->config['ip_check'] != 0) {
$url = generate_board_url() . '/' . append_sid("adm/index.$this->php_ext", ['i' => 'acp_board', 'mode' => 'security'], true, $this->user->session_id);
return $this->language->lang('LBL_AILABS_IP_VALIDATION', $url);
}
return null;
}
protected function find_user_id($username)
{
$user_id = null;
@ -306,19 +324,18 @@ class acp_controller //implements acp_interface
return $return;
}
protected function get_forums_names($str, $forums) {
protected function get_forums_names($str, $forums)
{
$result = [];
if(!empty($str)) {
if (!empty($str)) {
$arr = json_decode($str);
if(!empty($arr) && is_array($arr)) {
foreach($arr as $id)
{
$name = empty($forums[$id]) ? $id : $forums[$id];
array_push($result, $name);
if (!empty($arr) && is_array($arr)) {
foreach ($arr as $id) {
$name = empty($forums[$id]) ? $id : $forums[$id];
array_push($result, $name);
}
}
}
return join(', ', $result);
}
}

View file

@ -92,72 +92,71 @@ class chatgpt extends AIController
$post_first_discarded = null;
$mode = $this->job['post_mode'];
if ($mode == 'reply' || $mode == 'quote') {
$history = ['post_text' => $this->job['post_text']];
$history = ['post_text' => $this->job['post_text']];
$pattern = '/<QUOTE\sauthor="' . $this->job['ailabs_username'] . '"\spost_id="(.*)"\stime="(.*)"\suser_id="' . $this->job['ailabs_user_id'] . '">/';
$pattern = '/<QUOTE\sauthor="' . $this->job['ailabs_username'] . '"\spost_id="(.*)"\stime="(.*)"\suser_id="' . $this->job['ailabs_user_id'] . '">/';
$this->log['history.pattern'] = $pattern;
$this->log_flush();
$this->log['history.pattern'] = $pattern;
$this->log_flush();
$history_tokens = 0;
$round = -1;
do {
$round++;
$matches = null;
preg_match_all(
$pattern,
$history['post_text'],
$matches
);
// Attempt to unwind history using quoted posts
$history_tokens = 0;
$round = -1;
do {
$round++;
$matches = null;
preg_match_all(
$pattern,
$history['post_text'],
$matches
);
$history = null;
$history = null;
if ($matches != null && !empty($matches) && !empty($matches[1][0])) {
$postid = (int) $matches[1][0];
if ($matches != null && !empty($matches) && !empty($matches[1][0])) {
$postid = (int) $matches[1][0];
$sql = 'SELECT j.job_id, j.post_id, j.response_post_id, j.request, j.response, p.post_text, j.request_tokens, j.response_tokens ' .
'FROM ' . $this->jobs_table . ' j ' .
'JOIN ' . POSTS_TABLE . ' p ON p.post_id = j.post_id ' .
'WHERE ' . $this->db->sql_build_array('SELECT', ['response_post_id' => $postid]);
$result = $this->db->sql_query($sql);
$history = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
$sql = 'SELECT j.job_id, j.post_id, j.response_post_id, j.request, j.response, p.post_text, j.request_tokens, j.response_tokens ' .
'FROM ' . $this->jobs_table . ' j ' .
'JOIN ' . POSTS_TABLE . ' p ON p.post_id = j.post_id ' .
'WHERE ' . $this->db->sql_build_array('SELECT', ['response_post_id' => $postid]);
$result = $this->db->sql_query($sql);
$history = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (!empty($history)) {
$count_tokens = $history['request_tokens'] + $history['response_tokens'];
if (!empty($history)) {
$count_tokens = $history['request_tokens'] + $history['response_tokens'];
$discard = $this->max_tokens < ($this->message_tokens + $history_tokens + $count_tokens);
$discard = $this->max_tokens < ($this->message_tokens + $history_tokens + $count_tokens);
$posts[] = [
'postid' => $postid,
'request_tokens' => $history['request_tokens'],
'response_tokens' => $history['response_tokens'],
'runnig_total_tokens' => $history_tokens + $count_tokens,
'discard' => $discard
];
$posts[] = [
'postid' => $postid,
'request_tokens' => $history['request_tokens'],
'response_tokens' => $history['response_tokens'],
'runnig_total_tokens' => $history_tokens + $count_tokens,
'discard' => $discard
];
if ($discard) {
$post_first_discarded = $postid;
break;
}
$post_first_taken = $postid;
$history_tokens += $count_tokens;
array_unshift(
$messages,
['role' => 'user', 'content' => trim($history['request'])],
['role' => 'assistant', 'content' => trim($history['response'])]
);
if ($discard) {
$post_first_discarded = $postid;
break;
}
}
} while (!empty($history));
if (!empty($posts)) {
$this->log['history.posts'] = $posts;
$this->log_flush();
$post_first_taken = $postid;
$history_tokens += $count_tokens;
array_unshift(
$messages,
['role' => 'user', 'content' => trim($history['request'])],
['role' => 'assistant', 'content' => trim($history['response'])]
);
}
}
} while (!empty($history));
if (!empty($posts)) {
$this->log['history.posts'] = $posts;
$this->log_flush();
}
if (!empty($this->cfg->prefix)) {
@ -237,14 +236,16 @@ class chatgpt extends AIController
$this->log['finish'] = date('Y-m-d H:i:s');
if (!empty($posts)) {
$viewtopic = "{$this->root_path}viewtopic.{$this->php_ext}";
$discarded = '';
if ($post_first_discarded != null) {
$discarded = $this->language->lang('AILABS_POSTS_DISCARDED', $post_first_discarded);
$discarded = $this->language->lang('AILABS_POSTS_DISCARDED', $viewtopic, $post_first_discarded);
}
$total_posts_count = count($posts) * 2 + 2;
$total_tokens_used_count = $request_tokens + $response_tokens;
$info = $this->language->lang(
'AILABS_DISCARDED_INFO',
$viewtopic,
$post_first_taken,
$total_posts_count,
$discarded,

View file

@ -33,10 +33,10 @@ class log extends AIController
if (!empty($data)) {
foreach ($data as &$row) {
$row['poster_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $row['poster_id'], true, '');
$row['ailabs_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $row['ailabs_user_id'], true, '');
$row['poster_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $row['poster_id'], true, $this->user->session_id);
$row['ailabs_user_url'] = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $row['ailabs_user_id'], true, $this->user->session_id);
if (!empty($row['response_post_id'])) {
$row['response_url'] = generate_board_url() . '/' . append_sid('viewtopic.php?p=' . $row['response_post_id'] . '#p' . $row['response_post_id'], true, '');
$row['response_url'] = generate_board_url() . '/' . append_sid("viewtopic.$this->php_ext", 'p=' . $row['response_post_id'] . '#p' . $row['response_post_id'], true, $this->user->session_id);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View file

@ -115,8 +115,12 @@ class listener implements EventSubscriberInterface
if ($mode == 'post' && $user['post'] == 1) {
array_push($ailabs_users, $user);
} else {
if ($user['mention'] == 1 && in_array($user['user_id'], $ailabs_users_notified))
if ($mode == 'reply' && $user['reply'] == 1) {
array_push($ailabs_users, $user);
} else {
if ($user['mention'] == 1 && in_array($user['user_id'], $ailabs_users_notified))
array_push($ailabs_users, $user);
}
}
}
@ -154,6 +158,39 @@ class listener implements EventSubscriberInterface
$request = utf8_encode_ucr($request);
}
global $config;
$cookie_name = $config['cookie_name'];
$headers = [];
$copy_headers = ['X-Forwarded-For', 'User-Agent'];
foreach ($copy_headers as $header_name) {
if (!empty($this->request->header($header_name))) {
array_push($headers, "$header_name: " . $this->request->header($header_name));
}
}
$cookies = [];
if ($this->request->is_set($cookie_name . '_sid', \phpbb\request\request_interface::COOKIE) || $this->request->is_set($cookie_name . '_u', \phpbb\request\request_interface::COOKIE)) {
array_push($cookies, $cookie_name . '_u=' . $this->request->variable($cookie_name . '_u', 0, false, \phpbb\request\request_interface::COOKIE));
array_push($cookies, $cookie_name . '_k=' . $this->request->variable($cookie_name . '_k', '', false, \phpbb\request\request_interface::COOKIE));
array_push($cookies, $cookie_name . '_sid=' . $this->request->variable($cookie_name . '_sid', '', false, \phpbb\request\request_interface::COOKIE));
array_push($headers, "Cookie: " . implode('; ', $cookies));
}
$context = null;
if (!empty($headers)) {
$context = stream_context_create(
array(
'http' => array(
'method' => "HEAD",
'header' => implode("\r\n", $headers)
)
)
);
}
// https://area51.phpbb.com/docs/dev/master/db/dbal.html
foreach ($ailabs_users as $user) {
$data = [
@ -174,8 +211,11 @@ class listener implements EventSubscriberInterface
$this->update_post($data);
$url = generate_board_url() . $user['controller'] . '?job_id=' . $data['job_id'];
get_headers($url);
$url = append_sid(generate_board_url() . $user['controller'], ['job_id' => $data['job_id']], true, $this->user->session_id);
// Provide same cookies, session id and browser name so phpBB can authenticate user.
// Verify that Server Configuration > Security Settings > Session IP validation set to none
get_headers($url, false, $context);
unset($data);
}
}
@ -211,6 +251,7 @@ class listener implements EventSubscriberInterface
$return = array();
$sql = 'SELECT c.user_id, ' .
'c.forums_post LIKE \'%"' . $id . '"%\' as post, ' .
'c.forums_reply LIKE \'%"' . $id . '"%\' as reply, ' .
'c.forums_mention LIKE \'%"' . $id . '"%\' as mention, ' .
'c.controller, ' .
'u.username ' .
@ -223,6 +264,7 @@ class listener implements EventSubscriberInterface
'user_id' => $row['user_id'],
'username' => $row['username'],
'post' => $row['post'],
'reply' => $row['reply'],
'mention' => $row['mention'],
'controller' => $row['controller']
));
@ -312,9 +354,9 @@ class listener implements EventSubscriberInterface
$ailabs = array();
foreach ($jobs as $key => $value) {
$value->user_url = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $value->ailabs_user_id, true, '');
$value->user_url = generate_board_url() . '/' . append_sid("memberlist.$this->php_ext", 'mode=viewprofile&amp;u=' . $value->ailabs_user_id, true, $this->user->session_id);
if (!empty($value->response_post_id)) {
$value->response_url = generate_board_url() . '/' . append_sid('viewtopic.php?p=' . $value->response_post_id . '#p' . $value->response_post_id, true, '');
$value->response_url = generate_board_url() . '/' . append_sid("viewtopic.$this->php_ext", "p=$value->response_post_id#p$value->response_post_id", true, $this->user->session_id);
}
$value->status = $this->get_status(empty($value->status) ? null : $value->status);
array_push($ailabs, $value);

View file

@ -240,8 +240,14 @@ class AIController
{
// Prep posting
$poll = $uid = $bitfield = $options = '';
$allow_bbcode = $allow_urls = $allow_smilies = true;
generate_text_for_storage($response, $uid, $bitfield, $options, $allow_bbcode, $allow_urls, $allow_smilies);
generate_text_for_storage($response, $uid, $bitfield, $options, true, true, true);
// For some reason uid is not calculated by generate_text_for_storage
if (empty($uid)) {
$message_parser = new \parse_message($response);
$message_parser->parse(true, true, true);
$uid = $message_parser->bbcode_uid;
}
$data = array(
'poster_id' => $job['ailabs_user_id'],

View file

@ -19,8 +19,8 @@ if (empty($lang) || !is_array($lang)) {
$lang = array_merge($lang, [
'AILABS_ERROR_CHECK_LOGS' => '[color=#FF0000]Error. Pelase check logs.[/color]',
'AILABS_POSTS_DISCARDED' => ', posts starting from [url=/viewtopic.php?p=%1$d#p%1$d]this post[/url] were discarded',
'AILABS_DISCARDED_INFO' => '[size=75][url=/viewtopic.php?p=%1$d#p%1$d]Beginning[/url] of a conversation containing %2$d posts%3$s (%4$d tokens of %5$d were used)[/size]',
'AILABS_POSTS_DISCARDED' => ', posts starting from [url=%1$s?p=%2$d#p%2$d]this post[/url] were discarded',
'AILABS_DISCARDED_INFO' => '[size=75][url=%1$s?p=%2$d#p%2$d]Beginning[/url] of a conversation containing %3$d posts%4$s (%5$d tokens of %6$d were used)[/size]',
'AILABS_THINKING' => 'thinking',
'AILABS_REPLYING' => 'replying…',
'AILABS_REPLIED' => 'replied ↓',

View file

@ -29,7 +29,7 @@ $lang = array_merge($lang, [
'AILABS_USER_EMPTY' => 'Please select user',
'AILABS_USER_NOT_FOUND' => 'Unable to locate user %1$s',
'AILABS_USER_ALREADY_CONFIGURED' => 'User %1$s already configured, only one configuration per user supported',
'AILABS_SPECIFY_POST_OR_MENTION' => 'Both Reply on a post and Reply when quoted can\'t be empty, please specify at least one',
'AILABS_SPECIFY_FORUM' => 'Please select at least one forum',
'LOG_ACP_AILABS_ADDED' => 'AI Labs configuration added',
'LOG_ACP_AILABS_EDITED' => 'AI Labs configuration updated',
@ -39,20 +39,31 @@ $lang = array_merge($lang, [
'ACP_AILABS_UPDATED' => 'Configuration successfully updated',
'ACP_AILABS_DELETED_CONFIRM' => 'Are you sure that you wish to delete the configuration associated with user %1$s?',
'LBL_AILABS_SETTINGS_DESC' => 'Please visit 👉 <a href="https://github.com/privet-fun/phpbb_ailabs">https://github.com/privet-fun/phpbb_ailabs</a> for detailed configuration instructions and examples',
'LBL_AILABS_USERNAME' => 'User Name',
'LBL_AILABS_SETTINGS_DESC' => 'Please visit 👉 <a href="https://github.com/privet-fun/phpbb_ailabs">https://github.com/privet-fun/phpbb_ailabs</a> for detailed configuration instructions, troubleshooting and examples.',
'LBL_AILABS_USERNAME' => 'AI bot',
'LBL_AILABS_CONTROLLER' => 'AI',
'LBL_AILABS_CONFIG' => 'Configuration JSON',
'LBL_AILABS_TEMPLATE' => 'Template',
'LBL_AILABS_REPLY_POST_FORUMS' => 'Reply on a post',
'LBL_AILABS_REPLY_QUOTE_FORUMS' => 'Reply when quoted',
'LBL_AILABS_REPLY_TO' => 'Forums where AI bot reply to',
'LBL_AILABS_POST_FORUMS' => 'New topic',
'LBL_AILABS_REPLY_FORUMS' => 'Reply in a topic',
'LBL_AILABS_QUOTE_FORUMS' => 'Quote or <a href="https://www.phpbb.com/customise/db/extension/simple_mentions/" rel="nofollow">mention</a>',
'LBL_AILABS_ENABLED' => 'Enabled',
'LBL_AILABS_SELECT_FORUMS' => 'Select forums...',
'LBL_AILABS_CONFIG_EXPLAIN' => 'Must be valid JSON, please refer to documnetation for details',
'LBL_AILABS_TEMPLATE_EXPLAIN' => 'Valid variables: {post_id}, {request}, {info}, {response}, {images}, {attachments}, {poster_id}, {poster_name}, {ailabs_username}',
'LBL_AILABS_REPLY_POST_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to new posts',
'LBL_AILABS_REPLY_QUOTE_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to quoted posts',
'LBL_AILABS_POST_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to new topic',
'LBL_AILABS_REPLY_FORUMS_EXPLAIN' => 'Specify forums where AI will reply to reply in the topic',
'LBL_AILABS_QUOTE_FORUMS_EXPLAIN' => 'Specify forums where AI will reply when quoted or <a href="https://www.phpbb.com/customise/db/extension/simple_mentions/" rel="nofollow">mentioned</a>',
'LBL_AILABS_IP_VALIDATION' => '⚠️ Warning: Your ACP > General > Server Configuration > Security Settings > ' .
'<a href="%1$s">Session IP validation setting NOT set to None</a>, ' .
'this may prevent AI Labs to reply if you are using phpBB extensions which force user to be logged in ' .
'(eg <a href="https://www.phpbb.com/customise/db/extension/login_required">Login Required</a>). ' .
'Set Session IP validation to None or add "/ailabs/*" to extension whitelist. ' .
'Please refer to <a href="https://github.com/privet-fun/phpbb_ailabs#troubleshooting">troubleshooting section</a> for more details.',
'LBL_AILABS_CONFIG_DEFAULT' => 'Load default configuration',
'LBL_AILABS_TEMPLATE_DEFAULT' => 'Load default template',
]);

View file

@ -19,8 +19,8 @@ if (empty($lang) || !is_array($lang)) {
$lang = array_merge($lang, [
'AILABS_ERROR_CHECK_LOGS' => '[color=#FF0000]Ошибка. Лог содержит детальную информацию.[/color]',
'AILABS_POSTS_DISCARDED' => ', сообщения начиная с [url=/viewtopic.php?p=%1$d#p%1$d]этого[/url] не включены',
'AILABS_DISCARDED_INFO' => '[size=75][url=/viewtopic.php?p=%1$d#p%1$d]Начало[/url] беседы из %2$d сообщений%3$s (%4$d токенов из %5$d использовано)[/size]',
'AILABS_POSTS_DISCARDED' => ', сообщения начиная с [url=%1$s?p=%2$d#p%2$d]этого[/url] не включены',
'AILABS_DISCARDED_INFO' => '[size=75][url=%1$s?p=%2$d#p%2$d]Начало[/url] беседы из %3$d сообщений%4$s (%5$d токенов из %6$d использовано)[/size]',
'AILABS_THINKING' => 'думает',
'AILABS_REPLYING' => 'отвечает…',
'AILABS_REPLIED' => 'ответил ↓',

View file

@ -29,7 +29,7 @@ $lang = array_merge($lang, [
'AILABS_USER_EMPTY' => 'Пожалуйста, выберите пользователя',
'AILABS_USER_NOT_FOUND' => 'Не удалось найти пользователя %1$s',
'AILABS_USER_ALREADY_CONFIGURED' => 'Пользователь %1$s уже настроен, поддерживается только одна конфигурация на пользователя',
'AILABS_SPECIFY_POST_OR_MENTION' => 'Нельзя оставлять пустыми и "Ответ на сообщение" и "Ответ при цитировании", пожалуйста, укажите хотя бы одно значение',
'AILABS_SPECIFY_FORUM' => 'Укажите хотя бы один форум',
'LOG_ACP_AILABS_ADDED' => 'Конфигурация AI Labs добавлена',
'LOG_ACP_AILABS_EDITED' => 'Конфигурация AI Labs изменена',
@ -39,20 +39,33 @@ $lang = array_merge($lang, [
'ACP_AILABS_UPDATED' => 'Конфигурация успешно обновлена',
'ACP_AILABS_DELETED_CONFIRM' => 'Вы уверены, что хотите удалить конфигурацию, связанную с пользователем %1$s?',
'LBL_AILABS_SETTINGS_DESC' => 'Пожалуйста, посетите 👉 <a href="https://github.com/privet-fun/phpbb_ailabs">https://github.com/privet-fun/phpbb_ailabs</a> для получения подробных инструкций по настройке и примеров',
'LBL_AILABS_USERNAME' => 'Имя пользователя',
'LBL_AILABS_SETTINGS_DESC' => 'Пожалуйста, посетите 👉 <a href="https://github.com/privet-fun/phpbb_ailabs">https://github.com/privet-fun/phpbb_ailabs</a> для получения подробных инструкций по настройке и примеров.',
'LBL_AILABS_USERNAME' => 'AI бот',
'LBL_AILABS_CONTROLLER' => 'AI',
'LBL_AILABS_CONFIG' => 'Конфигурация в формате JSON',
'LBL_AILABS_TEMPLATE' => 'Шаблон',
'LBL_AILABS_REPLY_POST_FORUMS' => 'Ответ на сообщение',
'LBL_AILABS_REPLY_QUOTE_FORUMS' => 'Ответ при цитировании',
'LBL_AILABS_REPLY_TO' => 'Форумы где AI бот отвечает на',
'LBL_AILABS_POST_FORUMS' => 'Новую тему',
'LBL_AILABS_REPLY_FORUMS' => 'Ответ в теме',
'LBL_AILABS_QUOTE_FORUMS' => 'Цитирование или <a href="https://www.phpbb.com/customise/db/extension/simple_mentions/" rel="nofollow">упоминание</a>',
'LBL_AILABS_ENABLED' => 'Включено',
'LBL_AILABS_SELECT_FORUMS' => 'Выберите форумы...',
'LBL_AILABS_CONFIG_EXPLAIN' => 'Пожалуйста, обратитесь к документации для получения подробных инструкций по настройке и примеров',
'LBL_AILABS_TEMPLATE_EXPLAIN' => 'Допустимые переменные: {post_id}, {request}, {info}, {response}, {images}, {attachments}, {poster_id}, {poster_name}, {ailabs_username}',
'LBL_AILABS_REPLY_POST_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на новые сообщения',
'LBL_AILABS_REPLY_QUOTE_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на цитируемые сообщения',
'LBL_AILABS_POST_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на новые темы',
'LBL_AILABS_REPLY_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на ответы',
'LBL_AILABS_QUOTE_FORUMS_EXPLAIN' => 'Укажите форумы, на которых AI будет отвечать на цитируемые сообщения или <a href="https://www.phpbb.com/customise/db/extension/simple_mentions/" rel="nofollow">упоминания</a>',
'LBL_AILABS_IP_VALIDATION' => '⚠️ Предупреждение: Администрировать > Общие > Конфигурация сервера > Безопасность > ' .
'<a href="%1$s">Проверка IP-адреса сессии НЕ установлена в значение «Нет»</a>. ' .
'Это может препятствовать работе AI Labs в случае если вы используете расширения phpBB, ' .
'требующие авторизацию пользователя ' .
'(например <a href="https://www.phpbb.com/customise/db/extension/login_required">Login Required</a>). ' .
'Установите проверку IP-адреса сессии в значение "Нет" или добавьте "/ailabs/*" в белый список расширений. ' .
'Пожалуйста, обратитесь к <a href="https://github.com/privet-fun/phpbb_ailabs#troubleshooting">разделу по ' .
'устранению неполадок</a> для получения дополнительной информации.',
'LBL_AILABS_CONFIG_DEFAULT' => 'Загрузить конфигурацию по умолчанию',
'LBL_AILABS_TEMPLATE_DEFAULT' => 'Загрузить шаблон по умолчанию',
]);

View file

@ -0,0 +1,51 @@
<?php
/**
*
* AI Labs extension
*
* @copyright (c) 2023, privet.fun, https://privet.fun
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/
namespace privet\ailabs\migrations\v1x;
class release_1_0_4_schema extends \phpbb\db\migration\migration
{
static public function depends_on()
{
return array('\privet\ailabs\migrations\v1x\release_1_0_0_schema');
}
public function effectively_installed()
{
return isset($this->config['privet_ailabs_version']) && version_compare($this->config['privet_ailabs_version'], '1.0.4', '>=');
}
public function update_data()
{
return array(
array('config.add', array('privet_ailabs_version', '1.0.4')),
);
}
public function revert_data()
{
return array(
array('config.remove', array('privet_ailabs_version')),
);
}
public function update_schema()
{
return [
'add_columns' => [
$this->table_prefix . 'ailabs_users' => [
'forums_reply' => ['VCHAR', ''], // eg ["forum_id1","forum_id2"]
],
],
];
}
}