Compare commits

..

3 Commits

Author SHA1 Message Date
14a19c38b2 build: add cache to ./configure with -C flag
All checks were successful
CI / Check spelling (pull_request) Successful in 17s
CI / Check coding style (pull_request) Successful in 32s
CI / Linux (debian) (pull_request) Successful in 9m59s
CI / Linux (arch) (pull_request) Successful in 12m14s
CI / Linux (ubuntu) (pull_request) Successful in 12m44s
Add the -C flag to ./configure to enable caching, reducing redundant
resource fetching during builds when packages and the machine remain
unchanged. Caching may cause issues only if applied across different machines
or if packages are modified, neither of which is the case during the build.
2025-09-02 15:31:41 +02:00
7a833963ad build: use local libstrophe version and limit depth
`--depth 1` flag ensures that only latest version is loaded (since there is no need to sync full git)
Using local libstrophe version increases speed of fetching
2025-09-02 15:21:18 +02:00
8ed922f827 build: Add multithreading to make
All checks were successful
CI / Check spelling (pull_request) Successful in 18s
CI / Check coding style (pull_request) Successful in 31s
CI / Linux (debian) (pull_request) Successful in 11m2s
CI / Linux (arch) (pull_request) Successful in 13m12s
CI / Linux (ubuntu) (pull_request) Successful in 16m3s
nproc is a standard util that prints amount of available processes.
-j is a flag that specifies how many cores can be utilized by `make` (default is 1)
-j$(nproc) allows to use all the available machine cores, potentially significantly speeding up completion of CI actions
2025-09-02 14:45:48 +02:00
72 changed files with 1981 additions and 2986 deletions

View File

@@ -1,44 +0,0 @@
---
name: Bug report
about: Create a report
title: ''
labels: bug
assignees: ''
---
<!--- Provide a general summary of the issue in the Title above -->
<!--- More than 50 issues open? Please don't file any new feature requests -->
<!--- Help us reduce the work first :-) -->
## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
## Steps to Reproduce (for bugs)
<!--- Describe, in detail, what needs to happen to reproduce this bug -->
<!--- Give us a screenshot (if it's helpful for this particular bug) -->
1.
2.
3.
4.
## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
## Environment
* Give us the version and build information output generated by `profanity -v`
* If you could not yet build profanity, mention the revision you try to build from
* Operating System/Distribution
* glib version
* libstrophe version
* Some bugs might be due to specific implementation in the server. `/serversoftware example.domain` can be helpful

View File

@@ -1,44 +0,0 @@
name: CI API Docs
on:
push:
branches: [master]
paths:
- 'apidocs/**'
pull_request:
branches: [master]
paths:
- 'apidocs/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
test-c-api-docs:
runs-on: ubuntu-latest
name: Test C API Documentation Generation
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends make doxygen
- name: Test C API docs generation
run: |
cd apidocs/c/
doxygen c-prof.conf
test-python-api-docs:
runs-on: ubuntu-latest
name: Test Python API Documentation Generation
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends make python3-sphinx
- name: Test Python API docs generation
run: |
cd apidocs/python/
sphinx-apidoc -f -o . src && make -j$(nproc) xml SPHINXOPTS="-W --keep-going -n"

View File

@@ -1,18 +1,10 @@
name: CI Code
name: CI
on:
push:
branches: [master]
paths-ignore:
- 'docs/**'
- 'apidocs/**'
- 'README.md'
pull_request:
branches: [master]
paths-ignore:
- 'docs/**'
- 'apidocs/**'
- 'README.md'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -91,7 +83,7 @@ jobs:
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install dependencies
- name: install dependencies
run: |
sudo apt update
sudo apt install -y --no-install-recommends codespell

View File

@@ -124,7 +124,6 @@ unittest_sources = \
src/event/server_events.c src/event/server_events.h \
src/event/client_events.c src/event/client_events.h \
src/ui/tray.h src/ui/tray.c \
tests/prof_cmocka.h \
tests/unittests/xmpp/stub_vcard.c \
tests/unittests/xmpp/stub_avatar.c \
tests/unittests/xmpp/stub_ox.c \
@@ -171,7 +170,6 @@ unittest_sources = \
tests/unittests/unittests.c
functionaltest_sources = \
tests/prof_cmocka.h \
tests/functionaltests/proftest.c tests/functionaltests/proftest.h \
tests/functionaltests/test_connect.c tests/functionaltests/test_connect.h \
tests/functionaltests/test_ping.c tests/functionaltests/test_ping.h \
@@ -286,7 +284,6 @@ endif
TESTS = tests/unittests/unittests
check_PROGRAMS = tests/unittests/unittests
tests_unittests_unittests_CPPFLAGS = -Itests/
tests_unittests_unittests_SOURCES = $(unittest_sources)
tests_unittests_unittests_LDADD = -lcmocka
@@ -350,13 +347,9 @@ endif
.PHONY: my-prof.supp
my-prof.supp:
@sed '/^# AUTO-GENERATED START/q' prof.supp > $@
@printf "\n\n# glib\n" >> $@
@cat /usr/share/glib-2.0/valgrind/glib.supp >> $@
@printf "\n\n# Python\n" >> $@
@wget -O- https://raw.githubusercontent.com/python/cpython/refs/tags/v`python3 --version | cut -d' ' -f2`/Misc/valgrind-python.supp >> $@
@printf "\n\n# gtk\n" >> $@
@test -z "@GTK_VERSION@" || wget -O- https://raw.githubusercontent.com/GNOME/gtk/refs/tags/@GTK_VERSION@/gtk.supp >> $@
@printf "\n\n# more gtk\n" >> $@
@test -z "@GTK_VERSION@" || cat /usr/share/gtk-3.0/valgrind/gtk.supp >> $@
check-unit: tests/unittests/unittests

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,247 +1,220 @@
/** @file profhooks.h
* @brief C Plugin Hooks for CProof.
*
* This header defines optional callback hooks that CProof plugins can implement to
* handle events such as startup, shutdown, message processing, and presence updates in
* CProof, a console-based XMPP client. These hooks are called by CProof when the
* corresponding events occur, allowing plugins to customize behavior. All hooks are
* optional; plugins can define only the hooks they need, and CProof will automatically
* invoke them when appropriate.
*
* To use these hooks, define the functions in your plugin with the signatures provided
* in this header. For example, to handle the startup event:
*
* @code
* #include "profhooks.h"
* void prof_on_start(void) {
* // Handle CProof startup
* }
* @endcode
*
* For additional plugin functionality, such as displaying messages or registering
* commands, see the CProof API functions in profapi.h.
*
* @see profapi.h
*/
/** @mainpage CProof Plugins API and Hooks
* List of all API functions available to plugins: @ref profapi.h
* List of all hooks which plugins may implement: @ref profhooks.h
*/
/** @file
C Hooks.
*/
/**
* Called when a plugin is loaded, either when CProof is started, or when the /plugins load or /plugins install commands are called
* @param version The version of CProof
* @param status The package status of CProof, "development" or "release"
* @param account_name Account name of the currently logged in account, or NULL if not logged in
* @param fulljid The user's full Jabber ID (barejid and resource) if logged in, NULL otherwise
*/
Called when a plugin is loaded, either when profanity is started, or when the /plugins load or /plugins install commands are called
@param version the version of Profanity
@param status the package status of Profanity, "development" or "release"
@param account_name account name of the currently logged in account, or NULL if not logged in
@param fulljid the users full Jabber ID (barejid and resource) if logged in, NULL otherwise
*/
void prof_init(const char * const version, const char * const status, const char *const account_name, const char *const fulljid);
/**
* Called when CProof is started
*/
Called when Profanity is started
*/
void prof_on_start(void);
/**
* Called when the user quits CProof
*/
Called when the user quits Profanity
*/
void prof_on_shutdown(void);
/**
* Called when a plugin is unloaded with the /plugins unload command
*/
Called when a plugin is unloaded with the /plugins unload command
*/
void prof_on_unload(void);
/**
* Called when the user connects with an account
* @param account_name Account name of the account used for logging in
* @param fulljid The full Jabber ID (barejid and resource) of the account
*/
Called when the user connects with an account
@param account_name account name of the account used for logging in
@param fulljid the full Jabber ID (barejid and resource) of the account
*/
void prof_on_connect(const char * const account_name, const char * const fulljid);
/**
* Called when the user disconnects an account
* @param account_name Account name of the account being disconnected
* @param fulljid The full Jabber ID (barejid and resource) of the account
*/
Called when the user disconnects an account
@param account_name account name of the account being disconnected
@param fulljid the full Jabber ID (barejid and resource) of the account
*/
void prof_on_disconnect(const char * const account_name, const char * const fulljid);
/**
* Called before a chat message is displayed
* @param barejid Jabber ID of the message sender
* @param resource Resource of the message sender
* @param message The received message
* @return The new message to display, or NULL to preserve the original message
*/
Called before a chat message is displayed
@param barejid Jabber ID of the message sender
@param resource resource of the message sender
@param message the received message
@return the new message to display, or NULL to preserve the original message
*/
char* prof_pre_chat_message_display(const char * const barejid, const char *const resource, const char *message);
/**
* Called after a chat message is displayed
* @param barejid Jabber ID of the message sender
* @param resource Resource of the message sender
* @param message The received message
*/
Called after a chat message is displayed
@param barejid Jabber ID of the message sender
@param resource resource of the message sender
@param message the received message
*/
void prof_post_chat_message_display(const char * const barejid, const char *const resource, const char *message);
/**
* Called before a chat message is sent
* @param barejid Jabber ID of the message recipient
* @param message The message to be sent
* @return The modified or original message to send, or NULL to cancel sending of the message
*/
Called before a chat message is sent
@param barejid Jabber ID of the message recipient
@param message the message to be sent
@return the modified or original message to send, or NULL to cancel sending of the message
*/
char* prof_pre_chat_message_send(const char * const barejid, const char *message);
/**
* Called after a chat message has been sent
* @param barejid Jabber ID of the message recipient
* @param message The sent message
*/
Called after a chat message has been sent
@param barejid Jabber ID of the message recipient
@param message the sent message
*/
void prof_post_chat_message_send(const char * const barejid, const char *message);
/**
* Called before a chat room message is displayed
* @param barejid Jabber ID of the room
* @param nick Nickname of message sender
* @param message The received message
* @return The new message to display, or NULL to preserve the original message
*/
Called before a chat room message is displayed
@param barejid Jabber ID of the room
@param nick nickname of message sender
@param message the received message
@return the new message to display, or NULL to preserve the original message
*/
char* prof_pre_room_message_display(const char * const barejid, const char * const nick, const char *message);
/**
* Called after a chat room message is displayed
* @param barejid Jabber ID of the room
* @param nick Nickname of the message sender
* @param message The received message
*/
Called after a chat room message is displayed
@param barejid Jabber ID of the room
@param nick nickname of the message sender
@param message the received message
*/
void prof_post_room_message_display(const char * const barejid, const char * const nick, const char *message);
/**
* Called before a chat room message is sent
* @param barejid Jabber ID of the room
* @param message The message to be sent
* @return The modified or original message to send, or NULL to cancel sending of the message
*/
Called before a chat room message is sent
@param barejid Jabber ID of the room
@param message the message to be sent
@return the modified or original message to send, or NULL to cancel sending of the message
*/
char* prof_pre_room_message_send(const char * const barejid, const char *message);
/**
* Called after a chat room message has been sent
* @param barejid Jabber ID of the room
* @param message The sent message
*/
Called after a chat room message has been sent
@param barejid Jabber ID of the room
@param message the sent message
*/
void prof_post_room_message_send(const char * const barejid, const char *message);
/**
* Called when the server sends a chat room history message
* @param barejid Jabber ID of the room
* @param nick Nickname of the message sender
* @param message The message to be sent
* @param timestamp Time the message was originally sent to the room, in ISO8601 format
*/
Called when the server sends a chat room history message
@param barejid Jabber ID of the room
@param nick nickname of the message sender
@param message the message to be sent
@param timestamp time the message was originally sent to the room, in ISO8601 format
*/
void prof_on_room_history_message(const char * const barejid, const char *const nick, const char *const message, const char *const timestamp);
/**
* Called before a private chat room message is displayed
* @param barejid Jabber ID of the room
* @param nick Nickname of message sender
* @param message The received message
* @return The new message to display, or NULL to preserve the original message
*/
Called before a private chat room message is displayed
@param barejid Jabber ID of the room
@param nick nickname of message sender
@param message the received message
@return the new message to display, or NULL to preserve the original message
*/
char* prof_pre_priv_message_display(const char * const barejid, const char * const nick, const char *message);
/**
* Called after a private chat room message is displayed
* @param barejid Jabber ID of the room
* @param nick Nickname of the message sender
* @param message The received message
*/
Called after a private chat room message is displayed
@param barejid Jabber ID of the room
@param nick nickname of the message sender
@param message the received message
*/
void prof_post_priv_message_display(const char * const barejid, const char * const nick, const char *message);
/**
* Called before a private chat room message is sent
* @param barejid Jabber ID of the room
* @param nick Nickname of message recipient
* @param message The message to be sent
* @return The modified or original message to send, or NULL to cancel sending of the message
*/
Called before a private chat room message is sent
@param barejid Jabber ID of the room
@param nick nickname of message recipient
@param message the message to be sent
@return the modified or original message to send, or NULL to cancel sending of the message
*/
char* prof_pre_priv_message_send(const char * const barejid, const char * const nick, const char *message);
/**
* Called after a private chat room message has been sent
* @param barejid Jabber ID of the room
* @param nick Nickname of the message recipient
* @param message The sent message
*/
Called after a private chat room message has been sent
@param barejid Jabber ID of the room
@param nick nickname of the message recipient
@param message the sent message
*/
void prof_post_priv_message_send(const char * const barejid, const char * const nick, const char *message);
/**
* Called before an XMPP message stanza is sent
* @param stanza The stanza to send
* @return The new stanza to send, or NULL to preserve the original stanza
*/
Called before an XMPP message stanza is sent
@param stanza The stanza to send
@return The new stanza to send, or NULL to preserve the original stanza
*/
char* prof_on_message_stanza_send(const char *const stanza);
/**
* Called when an XMPP message stanza is received
* @param stanza The stanza received
* @return 1 if CProof should continue to process the message stanza, 0 otherwise
*/
Called when an XMPP message stanza is received
@param stanza The stanza received
@return 1 if Profanity should continue to process the message stanza, 0 otherwise
*/
int prof_on_message_stanza_receive(const char *const stanza);
/**
* Called before an XMPP presence stanza is sent
* @param stanza The stanza to send
* @return The new stanza to send, or NULL to preserve the original stanza
*/
Called before an XMPP presence stanza is sent
@param stanza The stanza to send
@return The new stanza to send, or NULL to preserve the original stanza
*/
char* prof_on_presence_stanza_send(const char *const stanza);
/**
* Called when an XMPP presence stanza is received
* @param stanza The stanza received
* @return 1 if CProof should continue to process the presence stanza, 0 otherwise
*/
Called when an XMPP presence stanza is received
@param stanza The stanza received
@return 1 if Profanity should continue to process the presence stanza, 0 otherwise
*/
int prof_on_presence_stanza_receive(const char *const stanza);
/**
* Called before an XMPP iq stanza is sent
* @param stanza The stanza to send
* @return The new stanza to send, or NULL to preserve the original stanza
*/
Called before an XMPP iq stanza is sent
@param stanza The stanza to send
@return The new stanza to send, or NULL to preserve the original stanza
*/
char* prof_on_iq_stanza_send(const char *const stanza);
/**
* Called when an XMPP iq stanza is received
* @param stanza The stanza received
* @return 1 if CProof should continue to process the iq stanza, 0 otherwise
*/
Called when an XMPP iq stanza is received
@param stanza The stanza received
@return 1 if Profanity should continue to process the iq stanza, 0 otherwise
*/
int prof_on_iq_stanza_receive(const char *const stanza);
/**
* Called when a contact goes offline
* @param barejid Jabber ID of the contact
* @param resource The resource being disconnected
* @param status The status message received with the offline presence, or NULL
*/
Called when a contact goes offline
@param barejid Jabber ID of the contact
@param resource the resource being disconnected
@param status the status message received with the offline presence, or NULL
*/
void prof_on_contact_offline(const char *const barejid, const char *const resource, const char *const status);
/**
* Called when a presence notification is received from a contact
* @param barejid Jabber ID of the contact
* @param resource The resource being disconnected
* @param presence Presence of the contact, one of "chat", "online", "away", "xa" or "dnd"
* @param status The status message received with the presence, or NULL
* @param priority The priority associated with the resource
*/
Called when a presence notification is received from a contact
@param barejid Jabber ID of the contact
@param resource the resource being disconnected
@param presence presence of the contact, one of "chat", "online", "away", "xa" or "dnd"
@param status the status message received with the presence, or NULL
@param priority the priority associated with the resource
*/
void prof_on_contact_presence(const char *const barejid, const char *const resource, const char *const presence, const char *const status, const int priority);
/**
* Called when a chat window is focused
* @param barejid Jabber ID of the chat window recipient
*/
Called when a chat window is focused
@param barejid Jabber ID of the chat window recipient
*/
void prof_on_chat_win_focus(const char *const barejid);
/**
* Called when a chat room window is focused
* @param barejid Jabber ID of the room
*/
void prof_on_room_win_focus(const char *const barejid);
Called when a chat room window is focused
@param barejid Jabber ID of the room
*/
void prof_on_room_win_focus(const char *const barejid);

View File

@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
# CProof Python Plugins API documentation build configuration file.
# Profanity Python Plugins API documentation build configuration file, created by
# sphinx-quickstart on Thu Mar 17 23:01:31 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
@@ -46,25 +47,25 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'CProof Python Plugins API'
copyright = u'2025, CProof, based on Profanity by boothj5 et al.'
author = u'CProof Developers'
project = u'Profanity Python Plugins API'
copyright = u'2016 - 2018, boothj5'
author = u'boothj5'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'0.15.0'
version = u'0.5.0'
# The full version, including alpha/beta/rc tags.
release = u'0.15.0'
release = u'0.5.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
@@ -74,7 +75,7 @@ language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build', 'modules.rst']
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
@@ -121,7 +122,7 @@ html_theme = 'default'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
html_title = "CProof Python Plugins"
html_title = "Profanity Python Plugins"
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
@@ -138,7 +139,7 @@ html_title = "CProof Python Plugins"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# html_static_path = ['_static']
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
@@ -201,7 +202,7 @@ html_show_copyright = False
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'CProofPythonPluginsAPIdoc'
htmlhelp_basename = 'ProfanityPythonPluginsAPIdoc'
# -- Options for LaTeX output ---------------------------------------------
@@ -223,8 +224,8 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'CProofPythonPluginsAPI.tex', u'CProof Python Plugins API Documentation',
u'CProof Developers', 'manual'),
(master_doc, 'ProfanityPythonPluginsAPI.tex', u'Profanity Python Plugins API Documentation',
u'boothj5', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -253,7 +254,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'cproofpythonpluginsapi', u'CProof Python Plugins API Documentation',
(master_doc, 'profanitypythonpluginsapi', u'Profanity Python Plugins API Documentation',
[author], 1)
]

View File

@@ -1,8 +1,8 @@
CProof Python Plugins API
===========================
Profanity Python Plugins API
============================
The ``prof`` module describes functions that plugins may call to interact with CProof.
The ``plugin`` module describes functions that plugins may define to be notified of various events in CProof.
The ``prof`` module describes functions that plugins may call to interact with Profanity.
The ``plugin`` module describes functions that plugins may define to be notified of various events in Profanity.
Contents:
@@ -11,5 +11,4 @@ Contents:
prof
plugin
:ref:`genindex`
* :ref:`genindex`

View File

@@ -1,495 +1,360 @@
"""
The plugin module defines optional callback functions that CProof plugins can
implement to handle events such as startup, shutdown, message processing, and
presence updates.
This page describes functions that plugins may implement to be called from Profanity on certain events. All functions are optional.
All functions are optional and are called by CProof when the corresponding event
occurs. You need to define them in your module and they will automatically be used
for callback events.
Examples:
::
def prof_on_start():
prof.cons_show("Profanity has started...")
To utilize full functionality, such as the ``prof.cons_show`` function, see ``prof``
documentation and use::
def prof_pre_room_message_display(room, nick, message):
prof.cons_show("Manipulating chat room message before display...")
new_message = message + " (added by plugin)"
return new_message
import prof
def prof_on_contact_presence(barejid, resource, presence, status, priority):
notify_message = barejid + " is " + presence
prof.notify(notify_message, 5, "Presence")
"""
# Initialization and Lifecycle
# ---------------------------
def prof_init(version, status, account_name, fulljid):
"""Called when a plugin is loaded, either when profanity is started, or when the ``/plugins load`` or ``/plugins install`` commands are called
def prof_init(version: str, status: str, account_name: str | None, fulljid: str | None) -> None:
"""Initializes the plugin when loaded by CProof.
Called when CProof starts or when the plugin is loaded via the ``/plugins load``
or ``/plugins install`` commands.
:param version: The version of CProof (e.g., ``"1.0.0"``).
:param status: The package status of CProof (``"development"`` or ``"release"``).
:param account_name: The account name of the logged-in user, or None if not logged in.
:param fulljid: The full Jabber ID (barejid/resource) of the logged-in user, or None if not logged in.
:return: None
Example::
def prof_init(version: str, status: str, account_name: str | None, fulljid: str | None) -> None:
prof.cons_show(f"MyPlugin for CProof {version} ({status}) has been loaded, account: {account_name}")
:param version: the version of Profanity
:param status: the package status of Profanity, ``"development"`` or ``"release"``
:param account_name: account name of the currently logged in account, or ``None`` if not logged in
:param fulljid: the users full Jabber ID (barejid and resource) if logged in, ``None`` otherwise
:type version: str or unicode
:type status: str or unicode
:type account_name: str, unicode or None
:type fulljid: str, unicode or None
"""
pass
def prof_on_start() -> None:
"""Called when CProof starts.
Use this to perform setup tasks that should occur at application startup.
:return: None
Example::
def prof_on_start() -> None:
prof.cons_show("CProof has started...")
def prof_on_start():
"""Called when Profanity is started
"""
pass
def prof_on_shutdown() -> None:
"""Called when CProof is shutting down.
Use this to perform cleanup tasks before the application exits.
:return: None
Example::
def prof_on_shutdown() -> None:
prof.cons_show("CProof is shutting down...")
def prof_on_shutdown():
"""Called when the user quits Profanity
"""
pass
def prof_on_unload() -> None:
"""Called when the plugin is unloaded via the ``/plugins unload`` command.
Use this to clean up plugin-specific resources.
:return: None
Example::
def prof_on_unload() -> None:
prof.cons_show("Plugin unloaded")
def prof_on_unload():
"""Called when a plugin is unloaded with the ``/plugins unload`` command
"""
pass
def prof_on_connect(account_name: str, fulljid: str) -> None:
"""Called when a user connects to CProof with an account.
:param account_name: The account name used for login.
:param fulljid: The full Jabber ID (barejid/resource) of the connected account.
:return: None
def prof_on_connect(account_name, fulljid):
"""Called when the user connects with an account
Example::
def prof_on_connect(account_name: str, fulljid: str) -> None:
prof.cons_show(f"Connected as {account_name} ({fulljid})")
:param account_name: account name of the account used for logging in
:param fulljid: the full Jabber ID (barejid and resource) of the account
:type account_name: str or unicode
:type fulljid: str or unicode
"""
pass
def prof_on_disconnect(account_name: str, fulljid: str) -> None:
"""Called when a user disconnects an account from CProof.
:param account_name: The account name being disconnected.
:param fulljid: The full Jabber ID (barejid/resource) of the disconnected account.
:return: None
def prof_on_disconnect(account_name, fulljid):
"""Called when the user disconnects an account
Example::
def prof_on_disconnect(account_name: str, fulljid: str) -> None:
prof.cons_show(f"Disconnected {account_name} ({fulljid})")
:param account_name: account name of the account being disconnected
:param fulljid: the full Jabber ID (barejid and resource) of the account
:type account_name: str or unicode
:type fulljid: str or unicode
"""
pass
# Chat Message Handlers
# ---------------------
def prof_pre_chat_message_display(barejid: str, resource: str, message: str) -> str | None:
"""Called before a chat message is displayed in a chat window.
def prof_pre_chat_message_display(barejid, resource, message):
"""Called before a chat message is displayed
Allows the plugin to modify or cancel the message display.
:param barejid: The Jabber ID of the message sender (e.g., ``bob@example.com``).
:param resource: The sender's resource (e.g., ``laptop``).
:param message: The received message.
:return: The modified message to display, or None to preserve the original.
Example::
def prof_pre_chat_message_display(barejid: str, resource: str, message: str) -> str | None:
new_message = f"{message} (from {barejid})"
return new_message
:param barejid: Jabber ID of the message sender
:param resource: resource of the message sender
:param message: the received message
:type barejid: str or unicode
:type resource: str or unicode
:type message: str or unicode
:return: the new message to display, or ``None`` to preserve the original message
:rtype: str or unicode
"""
pass
def prof_post_chat_message_display(barejid: str, resource: str, message: str) -> None:
"""Called after a chat message is displayed in a chat window.
Use this to perform actions after the message is shown.
def prof_post_chat_message_display(barejid, resource, message):
"""Called after a chat message is displayed
:param barejid: The Jabber ID of the message sender (e.g., ``bob@example.com``).
:param resource: The sender's resource (e.g., ``laptop``).
:param message: The displayed message.
:return: None
Example::
def prof_post_chat_message_display(barejid: str, resource: str, message: str) -> None:
prof.cons_show(f"Displayed message from {barejid}/{resource}: {message}")
:param barejid: Jabber ID of the message sender
:param resource: resource of the message sender
:param message: the received message
:type barejid: str or unicode
:type resource: str or unicode
:type message: str or unicode
"""
pass
def prof_pre_chat_message_send(barejid: str, message: str) -> str | None:
"""Called before a chat message is sent from CProof.
Allows the plugin to modify or cancel the message.
def prof_pre_chat_message_send(barejid, message):
"""Called before a chat message is sent
:param barejid: The Jabber ID of the recipient (e.g., ``bob@example.com``).
:param message: The message to be sent.
:return: The modified message to send, or None to cancel sending.
Example::
def prof_pre_chat_message_send(barejid: str, message: str) -> str | None:
return f"{message} (sent by plugin)"
:param barejid: Jabber ID of the message recipient
:param message: the message to be sent
:type barejid: str or unicode
:type message: str or unicode
:return: the modified or original message to send, or ``None`` to cancel sending of the message
:rtype: str or unicode
"""
pass
def prof_post_chat_message_send(barejid: str, message: str) -> None:
"""Called after a chat message is sent from CProof.
Use this to log or react to sent messages.
def prof_post_chat_message_send(barejid, message):
"""Called after a chat message has been sent
:param barejid: The Jabber ID of the recipient (e.g., ``bob@example.com``).
:param message: The sent message.
:return: None
Example::
def prof_post_chat_message_send(barejid: str, message: str) -> None:
prof.cons_show(f"Sent to {barejid}: {message}")
:param barejid: Jabber ID of the message recipient
:param message: the sent message
:type barejid: str or unicode
:type message: str or unicode
"""
pass
# Room Message Handlers
# ---------------------
def prof_pre_room_message_display(barejid: str, nick: str, message: str) -> str | None:
"""Called before a chat room message is displayed.
def prof_pre_room_message_display(barejid, nick, message):
"""Called before a chat room message is displayed
Allows the plugin to modify or cancel the message display.
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message sender.
:param message: The received message.
:return: The modified message to display, or None to preserve the original.
Example::
def prof_pre_room_message_display(barejid: str, nick: str, message: str) -> str | None:
return f"{message} (from {nick})"
:param barejid: Jabber ID of the room
:param nick: nickname of message sender
:param message: the received message
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
:return: the new message to display, or ``None`` to preserve the original message
:rtype: str or unicode
"""
pass
def prof_post_room_message_display(barejid: str, nick: str, message: str) -> None:
"""Called after a chat room message is displayed.
Use this to perform actions after the message is shown.
def prof_post_room_message_display(barejid, nick, message):
"""Called after a chat room message is displayed
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message sender.
:param message: The displayed message.
:return: None
Example::
def prof_post_room_message_display(barejid: str, nick: str, message: str) -> None:
prof.cons_show(f"Displayed in {barejid} from {nick}: {message}")
:param barejid: Jabber ID of the room
:param nick: nickname of the message sender
:param message: the received message
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
"""
pass
def prof_pre_room_message_send(barejid: str, message: str) -> str | None:
"""Called before a chat room message is sent.
Allows the plugin to modify or cancel the message.
def prof_pre_room_message_send(barejid, message):
"""Called before a chat room message is sent
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param message: The message to be sent.
:return: The modified message to send, or None to cancel sending.
Example::
def prof_pre_room_message_send(barejid: str, message: str) -> str | None:
return f"{message} (sent by plugin)"
:param barejid: Jabber ID of the room
:param message: the message to be sent
:type barejid: str or unicode
:type message: str or unicode
:return: the modified or original message to send, or ``None`` to cancel sending of the message
:rtype: str or unicode
"""
pass
def prof_post_room_message_send(barejid: str, message: str) -> None:
"""Called after a chat room message is sent.
Use this to log or react to sent messages.
def prof_post_room_message_send(barejid, message):
"""Called after a chat room message has been sent
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param message: The sent message.
:return: None
Example::
def prof_post_room_message_send(barejid: str, message: str) -> None:
prof.cons_show(f"Sent to {barejid}: {message}")
:param barejid: Jabber ID of the room
:param message: the sent message
:type barejid: str or unicode
:type message: str or unicode
"""
pass
def prof_on_room_history_message(barejid: str, nick: str, message: str, timestamp: str) -> None:
"""Called when a chat room history message is received from the server.
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message sender.
:param message: The received message.
:param timestamp: The message's original send time in ISO 8601 format (e.g., ``2025-09-10T19:45:00Z``).
:return: None
def prof_on_room_history_message(barejid, nick, message, timestamp):
"""Called when the server sends a chat room history message
Example::
def prof_on_room_history_message(barejid: str, nick: str, message: str, timestamp: str) -> None:
prof.cons_show(f"History in {barejid} from {nick} at {timestamp}: {message}")
:param barejid: Jabber ID of the room
:param nick: nickname of the message sender
:param message: the message to be sent
:param timestamp: time the message was originally sent to the room, in ISO8601 format
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
:type timestamp: str or unicode
"""
pass
# Private Message Handlers
# ------------------------
def prof_pre_priv_message_display(barejid: str, nick: str, message: str) -> str | None:
"""Called before a private chat room message is displayed.
def prof_pre_priv_message_display(barejid, nick, message):
"""Called before a private chat room message is displayed
Allows the plugin to modify or cancel the message display.
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message sender.
:param message: The received message.
:return: The modified message to display, or None to preserve the original.
Example::
def prof_pre_priv_message_display(barejid: str, nick: str, message: str) -> str | None:
return f"{message} (private from {nick})"
:param barejid: Jabber ID of the room
:param nick: nickname of message sender
:param message: the received message
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
:return: the new message to display, or ``None`` to preserve the original message
:rtype: str or unicode
"""
pass
def prof_post_priv_message_display(barejid: str, nick: str, message: str) -> None:
"""Called after a private chat room message is displayed.
Use this to perform actions after the message is shown.
def prof_post_priv_message_display(barejid, nick, message):
"""Called after a private chat room message is displayed
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message sender.
:param message: The displayed message.
:return: None
Example::
def prof_post_priv_message_display(barejid: str, nick: str, message: str) -> None:
prof.cons_show(f"Displayed private in {barejid} from {nick}: {message}")
:param barejid: Jabber ID of the room
:param nick: nickname of the message sender
:param message: the received message
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
"""
pass
def prof_pre_priv_message_send(barejid: str, nick: str, message: str) -> str | None:
"""Called before a private chat room message is sent.
Allows the plugin to modify or cancel the message.
def prof_pre_priv_message_send(barejid, nick, message):
"""Called before a private chat room message is sent
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message recipient.
:param message: The message to be sent.
:return: The modified message to send, or None to cancel sending.
Example::
def prof_pre_priv_message_send(barejid: str, nick: str, message: str) -> str | None:
return f"{message} (private to {nick})"
:param barejid: Jabber ID of the room
:param nick: nickname of message recipient
:param message: the message to be sent
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
:return: the modified or original message to send, or ``None`` to cancel sending of the message
:rtype: str or unicode
"""
pass
def prof_post_priv_message_send(barejid: str, nick: str, message: str) -> None:
"""Called after a private chat room message is sent.
Use this to log or react to sent messages.
def prof_post_priv_message_send(barejid, nick, message):
"""Called after a private chat room message has been sent
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:param nick: The nickname of the message recipient.
:param message: The sent message.
:return: None
Example::
def prof_post_priv_message_send(barejid: str, nick: str, message: str) -> None:
prof.cons_show(f"Sent private to {nick} in {barejid}: {message}")
:param barejid: Jabber ID of the room
:param nick: nickname of the message recipient
:param message: the sent message
:type barejid: str or unicode
:type nick: str or unicode
:type message: str or unicode
"""
pass
# Stanza Handlers
# ---------------
def prof_on_message_stanza_send(stanza: str) -> str | None:
"""Called before an XMPP message stanza is sent.
def prof_on_message_stanza_send(stanza):
"""Called before an XMPP message stanza is sent
Allows the plugin to modify or cancel the stanza.
:param stanza: The XMPP message stanza to send.
:return: The modified stanza to send, or None to preserve the original.
Example::
def prof_on_message_stanza_send(stanza: str) -> str | None:
prof.cons_show(f"Sending message stanza: {stanza}")
return stanza
:param stanza: The stanza to send
:type stanza: str or unicode
:return: The new stanza to send, or ``None`` to preserve the original stanza
:rtype: str or unicode
"""
pass
def prof_on_message_stanza_receive(stanza: str) -> bool:
"""Called when an XMPP message stanza is received.
Allows the plugin to control whether CProof processes the stanza.
def prof_on_message_stanza_receive(stanza):
"""Called when an XMPP message stanza is received
:param stanza: The received XMPP message stanza.
:return: True to allow CProof to process the stanza, False to block processing.
Example::
def prof_on_message_stanza_receive(stanza: str) -> bool:
prof.cons_show(f"Received message stanza: {stanza}")
return True
:param stanza: The stanza received
:type stanza: str or unicode
:return: ``True`` if Profanity should continue to process the message stanza, ``False`` otherwise
:rtype: boolean
"""
pass
def prof_on_presence_stanza_send(stanza: str) -> str | None:
"""Called before an XMPP presence stanza is sent.
Allows the plugin to modify or cancel the stanza.
def prof_on_presence_stanza_send(stanza):
"""Called before an XMPP presence stanza is sent
:param stanza: The XMPP presence stanza to send.
:return: The modified stanza to send, or None to preserve the original.
Example::
def prof_on_presence_stanza_send(stanza: str) -> str | None:
prof.cons_show(f"Sending presence stanza: {stanza}")
return stanza
:param stanza: The stanza to send
:type stanza: str or unicode
:return: The new stanza to send, or ``None`` to preserve the original stanza
:rtype: str or unicode
"""
pass
def prof_on_presence_stanza_receive(stanza: str) -> bool:
"""Called when an XMPP presence stanza is received.
Allows the plugin to control whether CProof processes the stanza.
def prof_on_presence_stanza_receive(stanza):
"""Called when an XMPP presence stanza is received
:param stanza: The received XMPP presence stanza.
:return: True to allow CProof to process the stanza, False to block processing.
Example::
def prof_on_presence_stanza_receive(stanza: str) -> bool:
prof.cons_show(f"Received presence stanza: {stanza}")
return True
:param stanza: The stanza received
:type stanza: str or unicode
:return: ``True`` if Profanity should continue to process the presence stanza, ``False`` otherwise
:rtype: boolean
"""
pass
def prof_on_iq_stanza_send(stanza: str) -> str | None:
"""Called before an XMPP IQ stanza is sent.
Allows the plugin to modify or cancel the stanza.
def prof_on_iq_stanza_send(stanza):
"""Called before an XMPP iq stanza is sent
:param stanza: The XMPP IQ stanza to send.
:return: The modified stanza to send, or None to preserve the original.
Example::
def prof_on_iq_stanza_send(stanza: str) -> str | None:
prof.cons_show(f"Sending IQ stanza: {stanza}")
return stanza
:param stanza: The stanza to send
:type stanza: str or unicode
:return: The new stanza to send, or ``None`` to preserve the original stanza
:rtype: str or unicode
"""
pass
def prof_on_iq_stanza_receive(stanza: str) -> bool:
"""Called when an XMPP IQ stanza is received.
Allows the plugin to control whether CProof processes the stanza.
def prof_on_iq_stanza_receive(stanza):
"""Called when an XMPP iq stanza is received
:param stanza: The received XMPP IQ stanza.
:return: True to allow CProof to process the stanza, False to block processing.
Example::
def prof_on_iq_stanza_receive(stanza: str) -> bool:
prof.cons_show(f"Received IQ stanza: {stanza}")
return True
:param stanza: The stanza received
:type stanza: str or unicode
:return: ``True`` if Profanity should continue to process the iq stanza, ``False`` otherwise
:rtype: boolean
"""
pass
# Contact Presence Handlers
# -------------------------
def prof_on_contact_offline(barejid: str, resource: str, status: str | None) -> None:
"""Called when a contact goes offline.
def prof_on_contact_offline(barejid, resource, status):
"""Called when a contact goes offline
:param barejid: The Jabber ID of the contact (e.g., ``bob@example.com``).
:param resource: The resource being disconnected (e.g., ``laptop``).
:param status: The status message received with the offline presence, or None.
:return: None
Example::
def prof_on_contact_offline(barejid: str, resource: str, status: str | None) -> None:
prof.cons_show(f"{barejid}/{resource} went offline: {status or 'No status'}")
:param barejid: Jabber ID of the contact
:param resource: the resource being disconnected
:param status: the status message received with the offline presence, or ``None``
:type barejid: str or unicode
:type resource: str or unicode
:type status: str or unicode
"""
pass
def prof_on_contact_presence(barejid: str, resource: str, presence: str, status: str | None, priority: int) -> None:
"""Called when a presence notification is received from a contact.
:param barejid: The Jabber ID of the contact (e.g., ``bob@example.com``).
:param resource: The resource of the contact (e.g., ``laptop``).
:param presence: The contact's presence (``"chat"``, ``"online"``, ``"away"``, ``"xa"``, or ``"dnd"``).
:param status: The status message received with the presence, or None.
:param priority: The priority associated with the resource.
:return: None
def prof_on_contact_presence(barejid, resource, presence, status, priority):
"""Called when a presence notification is received from a contact
Example::
def prof_on_contact_presence(barejid: str, resource: str, presence: str, status: str | None, priority: int) -> None:
prof.notify(f"{barejid} is {presence}", 5000, "Presence")
:param barejid: Jabber ID of the contact
:param resource: the resource being disconnected
:param presence: presence of the contact, one of ``"chat"``, ``"online"``, ``"away"``, ``"xa"`` or ``"dnd"``
:param status: the status message received with the presence, or ``None``
:param priority: the priority associated with the resource
:type barejid: str or unicode
:type resource: str or unicode
:type presence: str or unicode
:type status: str or unicode
:type priority: int
"""
pass
# Window Focus Handlers
# ---------------------
def prof_on_chat_win_focus(barejid: str) -> None:
"""Called when a chat window is focused.
def prof_on_chat_win_focus(barejid):
"""Called when a chat window is focused
:param barejid: The Jabber ID of the chat window recipient (e.g., ``bob@example.com``).
:return: None
Example::
def prof_on_chat_win_focus(barejid: str) -> None:
prof.cons_show(f"Focused chat window for {barejid}")
:param barejid: Jabber ID of the chat window recipient
:type barejid: str or unicode
"""
pass
def prof_on_room_win_focus(barejid: str) -> None:
"""Called when a chat room window is focused.
:param barejid: The Jabber ID of the room (e.g., ``chat@conference.example.com``).
:return: None
def prof_on_room_win_focus(barejid):
"""Called when a chat room window is focused
Example::
def prof_on_room_win_focus(barejid: str) -> None:
prof.cons_show(f"Focused room window for {barejid}")
:param barejid: Jabber ID of the room
:type barejid: str or unicode
"""
pass
pass

File diff suppressed because it is too large Load Diff

View File

@@ -1675,7 +1675,7 @@ char*
cmd_ac_complete_filepath(const char* const input, char* const startstr, gboolean previous)
{
unsigned int output_off = 0;
char* tmp = NULL;
char* tmp;
// strip command
char* inpcp = (char*)input + strlen(startstr);
@@ -1687,36 +1687,38 @@ cmd_ac_complete_filepath(const char* const input, char* const startstr, gboolean
// strip quotes
if (*inpcp == '"') {
tmp = strrchr(inpcp + 1, '"');
tmp = strchr(inpcp + 1, '"');
if (tmp) {
*tmp = '\0';
}
tmp = strdup(inpcp + 1);
free(inpcp);
inpcp = tmp;
tmp = NULL;
}
// expand ~ to $HOME
if (inpcp[0] == '~' && inpcp[1] == '/') {
char* home = getenv("HOME");
if (!home) {
tmp = g_strdup_printf("%s/%sfoo", getenv("HOME"), inpcp + 2);
if (!tmp) {
free(inpcp);
return NULL;
}
tmp = g_strdup_printf("%s/%sfoo", home, inpcp + 2);
output_off = strlen(home) + 1;
output_off = strlen(getenv("HOME")) + 1;
} else {
tmp = g_strdup_printf("%sfoo", inpcp);
if (!tmp) {
free(inpcp);
return NULL;
}
}
free(inpcp);
if (!tmp) {
return NULL;
}
inpcp = tmp;
char* foofile = strdup(basename(tmp));
char* directory = strdup(dirname(tmp));
g_free(tmp);
char* inpcp2 = strdup(inpcp);
char* foofile = strdup(basename(inpcp2));
char* directory = strdup(dirname(inpcp));
free(inpcp);
free(inpcp2);
GArray* files = g_array_new(TRUE, FALSE, sizeof(char*));
g_array_set_clear_func(files, (GDestroyNotify)_filepath_item_free);
@@ -1735,26 +1737,40 @@ cmd_ac_complete_filepath(const char* const input, char* const startstr, gboolean
continue;
}
char* acstring = NULL;
char* acstring;
if (output_off) {
tmp = g_strdup_printf("%s/%s", directory, dir->d_name);
if (tmp) {
acstring = g_strdup_printf("~/%s", tmp + output_off);
g_free(tmp);
if (!tmp) {
free(directory);
free(foofile);
return NULL;
}
acstring = g_strdup_printf("~/%s", tmp + output_off);
if (!acstring) {
free(directory);
free(foofile);
return NULL;
}
free(tmp);
} else if (strcmp(directory, "/") == 0) {
acstring = g_strdup_printf("/%s", dir->d_name);
if (!acstring) {
free(directory);
free(foofile);
return NULL;
}
} else {
acstring = g_strdup_printf("%s/%s", directory, dir->d_name);
}
if (!acstring) {
g_array_free(files, TRUE);
free(foofile);
free(directory);
return NULL;
if (!acstring) {
free(directory);
free(foofile);
return NULL;
}
}
g_array_append_val(files, acstring);
char* acstring_cpy = strdup(acstring);
g_array_append_val(files, acstring_cpy);
free(acstring);
}
closedir(d);
}

View File

@@ -433,7 +433,7 @@ static const struct cmd_t command_defs[] = {
{ "<contact>", "The contact you wish to view information about." },
{ "<nick>", "When in a chat room, the occupant you wish to view information about." })
CMD_EXAMPLES(
"/info thor@asgard.server.org",
"/info thor@aasgard.server.org",
"/info heimdall")
},

View File

@@ -8577,20 +8577,19 @@ cmd_omemo_trust_mode(ProfWin* window, const char* const command, gchar** args)
{
#ifdef HAVE_OMEMO
auto_gchar gchar* trust_mode = prefs_get_string(PREF_OMEMO_TRUST_MODE);
if (!args[1]) {
cons_show("Current trust mode is %s", trust_mode);
cons_show("Current trust mode is %s", prefs_get_string(PREF_OMEMO_TRUST_MODE));
return TRUE;
}
if (g_strcmp0(args[1], "manual") == 0) {
cons_show("Current trust mode is %s - setting to %s", trust_mode, args[1]);
cons_show("Current trust mode is %s - setting to %s", prefs_get_string(PREF_OMEMO_TRUST_MODE), args[1]);
cons_show("You need to trust all OMEMO fingerprints manually");
} else if (g_strcmp0(args[1], "firstusage") == 0) {
cons_show("Current trust mode is %s - setting to %s", trust_mode, args[1]);
cons_show("Current trust mode is %s - setting to %s", prefs_get_string(PREF_OMEMO_TRUST_MODE), args[1]);
cons_show("The first seen OMEMO fingerprints will be trusted automatically - new keys must be trusted manually");
} else if (g_strcmp0(args[1], "blind") == 0) {
cons_show("Current trust mode is %s - setting to %s", trust_mode, args[1]);
cons_show("Current trust mode is %s - setting to %s", prefs_get_string(PREF_OMEMO_TRUST_MODE), args[1]);
cons_show("ALL OMEMO fingerprints will be trusted automatically");
} else {
cons_bad_cmd_usage(command);

View File

@@ -45,7 +45,6 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <curl/curl.h>
#include <curl/easy.h>
@@ -200,10 +199,6 @@ load_custom_keyfile(prof_keyfile_t* keyfile, gchar* filename)
if (g_file_test(keyfile->filename, G_FILE_TEST_EXISTS)) {
g_chmod(keyfile->filename, S_IRUSR | S_IWUSR);
} else {
int fno = g_creat(keyfile->filename, S_IRUSR | S_IWUSR);
if (fno != -1)
g_close(fno, NULL);
}
return _load_keyfile(keyfile);

View File

@@ -86,16 +86,10 @@ python_get_version_number(void)
return version_number;
}
static void
_unref_module(PyObject* module)
{
Py_XDECREF(module);
}
void
python_env_init(void)
{
loaded_modules = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_unref_module);
loaded_modules = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)Py_XDECREF);
python_init_prof();

View File

@@ -1,36 +1,40 @@
/*
* buffer.c
*
* Message buffer implementation for CProof.
*
* This module provides an in-memory buffer for managing active chat entries in the
* console-based XMPP client. Separate from persistent SQLite storage, it holds
* messages and metadata solely for UI rendering, ensuring responsive scrolling and
* display without exceeding ncurses pad limits (10k lines). By tracking rendered
* line counts per entry, it proactively trims content to prevent overflow, enabling
* seamless integration with ncurses for position-aware rendering.
*
* Key features and operations:
* - Append/prepend entries (messages) with automatic line-based cleanup.
* - Track cumulative lines for overflow prevention and efficient buffer sizing.
* - Remove entries by ID or index; mark delivery receipts as received.
* - Retrieve entries by index or ID for rendering and history queries.
* - Store metadata including timestamps, senders, themes, and ncurses y-positions.
*
* CProof. Fork of Profanity (since 2025).
* vim: expandtab:ts=4:sts=4:sw=4
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2025 CProof Developers
*
* Licensed under the GNU General Public License, version 3,
* with the OpenSSL exception. See LICENSE for details.
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
*
* vim: expandtab:ts=4:sts=4:sw=4
*/
#include "config.h"
#include "ui/window_list.h"
#include <stdlib.h>
#include <string.h>
@@ -50,8 +54,15 @@
#include "ui/window.h"
#include "ui/buffer.h"
#define MAX_BUFFER_SIZE 200
#define STRDUP_OR_NULL(str) ((str) ? strdup(str) : NULL)
struct prof_buff_t
{
GSList* entries;
int lines;
};
static void _free_entry(ProfBuffEntry* entry);
static ProfBuffEntry* _create_entry(const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos);
static void _buffer_add(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos, gboolean append);
@@ -97,24 +108,23 @@ _buffer_add(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* t
buffer->lines += e->_lines;
// With 10% margin to ensure overflow prevention
while (buffer->lines >= PAD_SIZE - (PAD_SIZE / 10) && g_slist_length(buffer->entries) > 1) {
while (g_slist_length(buffer->entries) >= MAX_BUFFER_SIZE) {
// Delete message from the opposite size to free buffer
GSList* buffer_entry_to_delete = append ? buffer->entries : g_slist_last(buffer->entries);
ProfBuffEntry* entry_to_delete = (ProfBuffEntry*)buffer_entry_to_delete->data;
// log_debug("(Messages left in buffer: %d) DELETING: %s", g_slist_length(buffer->entries), entry_to_delete->id);
buffer->lines -= entry_to_delete->_lines;
_free_entry(entry_to_delete);
buffer->entries = g_slist_delete_link(buffer->entries, buffer_entry_to_delete);
}
if (from_jid && y_end_pos == y_start_pos) {
// win_redraw will redraw with entries above removed,
// it will also recalculate actual size of the message that caused overflow
int old_lines = buffer->lines;
win_redraw(wins_get_current());
log_debug("Ncurses Overflow! From: %s, position: %d, ID: %s, append: %s, used message buffer size: %d, rendered lines: (old: %d/ actual: %d/ max: %d)",
from_jid, y_start_pos, id, append ? "TRUE" : "FALSE", g_slist_length(buffer->entries), old_lines, buffer->lines, PAD_SIZE);
log_warning("Ncurses Overflow! From: %s, position: %d, ID: %s, append: %s, used message buffer size: %d, message buffer size: %d, rendered lines buffer size: %d",
from_jid, y_start_pos, id, append ? "TRUE" : "FALSE", g_slist_length(buffer->entries), MAX_BUFFER_SIZE, PAD_SIZE);
// At this point we have a message that caused overflow of the render buffer.
// Ideally, we want to clean other messages to rerender everything properly. To do so,
// first we need to determine the size of the message that we are trying to display,
// then we need to print the message.
// However, _buffer_add is too late in the code to do this, therefore it has to be done in the win_print_old_history.
}
buffer->entries = append ? g_slist_append(buffer->entries, e) : g_slist_prepend(buffer->entries, e);

View File

@@ -68,12 +68,6 @@ typedef struct prof_buff_entry_t
char* id;
} ProfBuffEntry;
struct prof_buff_t
{
GSList* entries;
int lines;
};
typedef struct prof_buff_t* ProfBuff;
ProfBuff buffer_create();

View File

@@ -170,29 +170,6 @@ create_input_window(void)
_inp_win_update_virtual();
}
static gboolean
_inp_slashguard_check(void)
{
if (get_password)
return false;
/* ignore empty and quoted messages */
if (inp_line == NULL || inp_line[0] == '\0' || inp_line[0] == '>')
return false;
if (!prefs_get_boolean(PREF_SLASH_GUARD))
return false;
size_t n = 1;
while (inp_line[n] != '\0' && n < 4) {
if (inp_line[n] == '/') {
cons_show("Your text contains a slash in the first 4 characters");
free(inp_line);
inp_line = NULL;
return true;
}
n++;
}
return false;
}
char*
inp_readline(void)
{
@@ -226,7 +203,17 @@ inp_readline(void)
chat_state_idle();
}
if (inp_line && !_inp_slashguard_check()) {
if (inp_line) {
if (!get_password && prefs_get_boolean(PREF_SLASH_GUARD)) {
// ignore quoted messages
if (strlen(inp_line) > 1 && inp_line[0] != '>') {
char* res = (char*)memchr(inp_line + 1, '/', 3);
if (res) {
cons_show("Your text contains a slash in the first 4 characters");
return NULL;
}
}
}
char* ret = inp_line;
inp_line = NULL;
return ret;

View File

@@ -2003,10 +2003,6 @@ win_redraw(ProfWin* window)
_win_print_internal(window, e->show_char, e->pad_indent, e->time, e->flags, e->theme_item, e->display_from, e->message, e->receipt);
}
e->y_end_pos = getcury(window->layout->win);
// Recalculate lines (might be incorrect in case of NCurses overflow)
window->layout->buffer->lines -= e->_lines;
e->_lines = e->y_end_pos - e->y_start_pos;
window->layout->buffer->lines += e->_lines;
}
}

View File

@@ -1,7 +1,10 @@
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "prof_cmocka.h"
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <sys/stat.h>
#include "config.h"

View File

@@ -2,8 +2,11 @@
#include <sys/wait.h>
#include <glib.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include "prof_cmocka.h"
#include <cmocka.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,5 +0,0 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <setjmp.h>
#include <cmocka.h>

View File

@@ -21,7 +21,8 @@
*/
#include <glib.h>
#include "prof_cmocka.h"
#include <setjmp.h>
#include <cmocka.h>
#include <xmpp/xmpp.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "common.h"
#include "config/account.h"

View File

@@ -21,7 +21,8 @@
*/
#include <glib.h>
#include "prof_cmocka.h"
#include <setjmp.h>
#include <cmocka.h>
#include "database.h"

View File

@@ -1,5 +1,8 @@
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include "prof_cmocka.h"
#include <cmocka.h>
#include <glib.h>
#include <stdio.h>
#include <unistd.h>

View File

@@ -21,7 +21,8 @@
*/
#include <glib.h>
#include "prof_cmocka.h"
#include <setjmp.h>
#include <cmocka.h>
#include "log.h"

View File

@@ -2,7 +2,10 @@
#include <libotr/message.h>
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "config/account.h"

View File

@@ -1,5 +1,8 @@
#include <glib.h>
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/contact.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,5 +1,8 @@
#include <stdarg.h>
#include <string.h>
#include "prof_cmocka.h"
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/chat_session.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,6 +1,9 @@
#include "xmpp/resource.h"
#include "common.h"
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
void

View File

@@ -1,6 +1,9 @@
#include <glib.h>
#include <stdarg.h>
#include <string.h>
#include "prof_cmocka.h"
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/contact.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <glib.h>
#include "event/client_events.h"
#include "command/cmd_funcs.h"

View File

@@ -1,5 +1,8 @@
#include <stdarg.h>
#include <string.h>
#include "prof_cmocka.h"
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/form.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/jid.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/muc.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "tools/parser.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "plugins/disco.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -1,6 +1,9 @@
#include <glib.h>
#include <stdarg.h>
#include <string.h>
#include "prof_cmocka.h"
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include "xmpp/contact.h"

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>

View File

@@ -3,7 +3,8 @@
#include <glib.h>
#include <wchar.h>
#include "prof_cmocka.h"
#include <setjmp.h>
#include <cmocka.h>
#include "ui/window.h"
#include "ui/ui.h"

View File

@@ -1,7 +1,10 @@
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "prof_cmocka.h"
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <locale.h>

View File

@@ -1,4 +1,7 @@
#include "prof_cmocka.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include "xmpp/xmpp.h"