| Server IP : 85.112.90.236 / Your IP : 192.168.1.26 Web Server : Apache System : Linux 85-112-90-236.cprapid.com 6.12.0-211.7.3.el10_2.x86_64 #1 SMP PREEMPT_DYNAMIC Tue May 19 12:46:58 EDT 2026 x86_64 User : ftechme ( 1002) PHP Version : 8.2.32 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /proc/self/root/bin/ |
Upload File : |
#!/usr/bin/python3
#
# yelp-build-url-handler
# Copyright (C) 2023, 2024 Red Hat Inc.
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os
import sys
import subprocess
import urllib.parse
import gi
import errno
import dbus
from dbus import Interface, SessionBus
gi.require_version('Gio', '2.0')
from gi.repository import Gio, GLib
class YelpBuildUrlHandler:
def main(self):
if len(sys.argv) != 2:
print('Usage: yelp-build-url-handler <URL>', file=sys.stderr)
return 1
url = sys.argv[1]
return self.handle_url(url)
def determine_paths_from_url(self, url):
parsed_url = urllib.parse.urlparse(url)
if parsed_url.scheme != 'help':
print(f'Invalid URI scheme: {parsed_url.scheme}', file=sys.stderr)
return None
path = parsed_url.path.lstrip('/')
languages = GLib.get_language_names() + ['C']
for language in languages:
base_path = os.path.join('/usr/share/help', language)
cache_path = os.path.join(GLib.get_user_cache_dir(), 'yelp-build', language)
full_source_path = os.path.join(base_path, path)
if os.path.isdir(full_source_path):
source_dir = full_source_path
output_dir = os.path.join(cache_path, path)
output_file = os.path.join(output_dir, 'index.html')
return {
'source_dir': source_dir,
'output_dir': output_dir,
'output_file': output_file,
'full_source_path': full_source_path
}
else:
full_source_file = full_source_path + '.page'
if os.path.isfile(full_source_file):
source_dir = os.path.dirname(full_source_file)
output_file = os.path.join(cache_path, path + '.html')
output_dir = os.path.dirname(output_file)
return {
'source_dir': source_dir,
'output_dir': output_dir,
'output_file': output_file,
'full_source_path': full_source_file
}
print(f'Help content not found for path: {path}', file=sys.stderr)
return None
def handle_url(self, url):
paths = self.determine_paths_from_url(url)
if paths is None:
return 1
source_dir = paths['source_dir']
output_dir = paths['output_dir']
output_file = paths['output_file']
full_source_path = paths['full_source_path']
cache_stale = True
try:
output_status = os.stat(output_dir)
source_status = os.stat(source_dir)
if output_status.st_mtime < source_status.st_mtime:
cache_stale = False
except OSError as e:
pass
if cache_stale:
cache_stale = not self.generate_html(source_dir, output_dir)
if cache_stale:
print(f'Failed to generate HTML for path {full_source_path}', file=sys.stderr)
return 1
sandboxed_dir = self.grant_access_to_browser(output_dir)
if sandboxed_dir is None:
print(f'Failed to grant browser access to generated HTML for path {full_source_path}', file=sys.stderr)
return 1
basename = os.path.basename(output_file)
sandboxed_file = os.path.join(sandboxed_dir, basename)
redirect_file = self.write_redirect_file(sandboxed_dir, sandboxed_file)
if redirect_file is None:
return 1
if not self.show_generated_html(redirect_file):
print('Failed to start browser', file=sys.stderr)
return 1
def generate_html(self, source_dir, output_dir):
os.makedirs(output_dir, exist_ok=True)
argv = ['yelp-build', 'html', '.', '-o', output_dir]
try:
subprocess.run(argv, cwd=source_dir, check=True)
return True
except subprocess.CalledProcessError as e:
print(f'Could not run "{" ".join(argv)}": {e}', file=sys.stderr)
return False
def grant_access_to_browser(self, output_dir):
default_browser = Gio.AppInfo.get_default_for_type('text/html', False)
if default_browser is None:
print('Default web browser not found!', file=sys.stderr)
return None
app_id = default_browser.get_id()
if app_id is None:
print('Default web browser has no app ID!', file=sys.stderr)
return None
app_id = app_id.removesuffix('.desktop')
try:
dir_fd = os.open(output_dir, os.O_PATH)
except OSError as e:
print(f'Failed to open directory {output_dir}: {e}', file=sys.stderr)
return None
bus = SessionBus()
try:
portal_documents_object = bus.get_object('org.freedesktop.portal.Documents', '/org/freedesktop/portal/documents')
portal_documents = Interface(portal_documents_object, dbus_interface='org.freedesktop.portal.Documents')
except dbus.DBusException as e:
print(f'Failed to connect to Documents portal: {e}', file=sys.stderr)
os.close(dir_fd)
return None
flags = (
1 << 0 # ReuseExisting
| 1 << 1 # Persistent
| 1 << 3 # ExportDirectory
)
permissions = ['read']
try:
doc_with_signature, *_ = portal_documents.AddFull([dbus.types.UnixFd(dir_fd)], flags, app_id, permissions)
if not doc_with_signature:
print('No document IDs returned from portal', file=sys.stderr)
os.close(dir_fd)
return None
doc_id, *_ = doc_with_signature
sandboxed_dir = os.path.join(GLib.get_user_runtime_dir(), 'doc', doc_id, os.path.basename(output_dir))
os.close(dir_fd)
except dbus.DBusException as e:
print(f'Failed to call AddFull method: {e}', file=sys.stderr)
os.close(dir_fd)
return None
return sandboxed_dir
def show_generated_html(self, output):
try:
uri = GLib.filename_to_uri(output)
Gio.AppInfo.launch_default_for_uri(uri, None)
except Exception as e:
print(f'Failed to launch default application: {e}', file=sys.stderr)
return False
return True
def write_redirect_file(self, sandboxed_dir, sandboxed_file):
html = f'<meta http-equiv="refresh" content="0; url=file://{sandboxed_file}">'
redirect_file = os.path.join(sandboxed_dir, 'yelp-build-redirect.html')
try:
with open(redirect_file, 'w') as f:
f.write(html)
except Exception as e:
print(f'Error writing redirect file {redirect_file}: {e}', file=sys.stderr)
return None
return redirect_file
if __name__ == '__main__':
try:
sys.exit(YelpBuildUrlHandler().main())
except KeyboardInterrupt:
sys.exit(1)