Merge a5a0dcc023 into 94a0b415ef
				
					
				
			This commit is contained in:
		
						commit
						db23c96a69
					
				| @ -174,3 +174,4 @@ features or generally made searx better: | |||||||
| - @micsthepick | - @micsthepick | ||||||
| - Daniel Kukula `<https://github.com/dkuku>` | - Daniel Kukula `<https://github.com/dkuku>` | ||||||
| - Patrick Evans `https://github.com/holysoles` | - Patrick Evans `https://github.com/holysoles` | ||||||
|  | - shreven `<https://shreven.org>`_ B8B56F6FC0EADCA5B6177BC5F599020F48EE6F97 | ||||||
|  | |||||||
| @ -11,6 +11,10 @@ | |||||||
|      docs_url: https://docs.searxng.org |      docs_url: https://docs.searxng.org | ||||||
|      public_instances: https://searx.space |      public_instances: https://searx.space | ||||||
|      wiki_url: https://github.com/searxng/searxng/wiki |      wiki_url: https://github.com/searxng/searxng/wiki | ||||||
|  |      custom_files: | ||||||
|  |        logo: /path/to/file.png | ||||||
|  |        favicon_png: /path/to/file.png | ||||||
|  |        favicon_svg: /path/to/file.svg | ||||||
| 
 | 
 | ||||||
| ``issue_url`` : | ``issue_url`` : | ||||||
|   If you host your own issue tracker change this URL. |   If you host your own issue tracker change this URL. | ||||||
| @ -23,3 +27,12 @@ | |||||||
| 
 | 
 | ||||||
| ``wiki_url`` : | ``wiki_url`` : | ||||||
|   Link to your wiki (or ``false``) |   Link to your wiki (or ``false``) | ||||||
|  | 
 | ||||||
|  | ``custom_files.logo`` : | ||||||
|  |   Filepath to a custom logo. Be sure it has the right file extension, as that's used to determine the mimetype. | ||||||
|  | 
 | ||||||
|  | ``custom_files.favicon_png`` : | ||||||
|  |   Filepath to a custom PNG favicon. | ||||||
|  | 
 | ||||||
|  | ``custom_files.favicon_svg`` : | ||||||
|  |   Filepath to a custom SVG favicon. When using, be sure to also set ``custom_files.favicon_png``, as some browsers still don't support SVG favicons. | ||||||
|  | |||||||
| @ -29,6 +29,12 @@ brand: | |||||||
|   #   links: |   #   links: | ||||||
|   #     Uptime: https://uptime.searxng.org/history/darmarit-org |   #     Uptime: https://uptime.searxng.org/history/darmarit-org | ||||||
|   #     About: "https://searxng.org" |   #     About: "https://searxng.org" | ||||||
|  |   # custom_files: | ||||||
|  |   #   # If using custom logo, be sure to set the right file extension as it's used to determine the mimetype. | ||||||
|  |   #   logo: /path/to/file.png | ||||||
|  |   #   # For custom favicons, you must include a PNG version, as some browsers still don't support SVG favicons. | ||||||
|  |   #   favicon_png: /path/to/file.png | ||||||
|  |   #   favicon_svg: /path/to/file.svg | ||||||
| 
 | 
 | ||||||
| search: | search: | ||||||
|   # Filter results. 0: None, 1: Moderate, 2: Strict |   # Filter results. 0: None, 1: Moderate, 2: Strict | ||||||
|  | |||||||
| @ -152,6 +152,7 @@ SCHEMA = { | |||||||
|         'public_instances': SettingsValue((False, str), 'https://searx.space'), |         'public_instances': SettingsValue((False, str), 'https://searx.space'), | ||||||
|         'wiki_url': SettingsValue(str, 'https://github.com/searxng/searxng/wiki'), |         'wiki_url': SettingsValue(str, 'https://github.com/searxng/searxng/wiki'), | ||||||
|         'custom': SettingsValue(dict, {'links': {}}), |         'custom': SettingsValue(dict, {'links': {}}), | ||||||
|  |         'custom_files': SettingsValue(dict, {}), | ||||||
|     }, |     }, | ||||||
|     'search': { |     'search': { | ||||||
|         'safe_search': SettingsValue((0, 1, 2), 0), |         'safe_search': SettingsValue((0, 1, 2), 0), | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								searx/static/themes/simple/css/searxng-rtl.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								searx/static/themes/simple/css/searxng-rtl.min.css
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								searx/static/themes/simple/css/searxng.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								searx/static/themes/simple/css/searxng.min.css
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -151,7 +151,6 @@ module.exports = function (grunt) { | |||||||
|           svgo: ['--config', 'svg4web.svgo.js'] |           svgo: ['--config', 'svg4web.svgo.js'] | ||||||
|         }, |         }, | ||||||
|         files: { |         files: { | ||||||
|           '<%= _templates %>/simple/searxng-wordmark.min.svg': '<%= _brand %>/searxng-wordmark.svg', |  | ||||||
|           'img/searxng.svg': '<%= _brand %>/searxng.svg', |           'img/searxng.svg': '<%= _brand %>/searxng.svg', | ||||||
|           'img/img_load_error.svg': '<%= _brand %>/img_load_error.svg' |           'img/img_load_error.svg': '<%= _brand %>/img_load_error.svg' | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -6,7 +6,11 @@ | |||||||
|   text-align: center; |   text-align: center; | ||||||
| 
 | 
 | ||||||
|   .title { |   .title { | ||||||
|     background: url('../img/searxng.png') no-repeat; |     &.custom_logo { | ||||||
|  |       background-image: url('../../../../custom/logo'); | ||||||
|  |     } | ||||||
|  |     background-image: url('../img/searxng.png'); | ||||||
|  |     background-repeat: no-repeat; | ||||||
|     min-height: 4rem; |     min-height: 4rem; | ||||||
|     margin: 4rem auto; |     margin: 4rem auto; | ||||||
|     background-position: center; |     background-position: center; | ||||||
|  | |||||||
| @ -27,9 +27,11 @@ | |||||||
|   {% block head %} |   {% block head %} | ||||||
|   <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"> |   <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"> | ||||||
|   {% endblock %} |   {% endblock %} | ||||||
|   <link rel="icon" href="{{ url_for('static', filename='img/favicon.png') }}" sizes="any"> |   <link rel="icon" href="{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.png') }}" sizes="any"> | ||||||
|   <link rel="icon" href="{{ url_for('static', filename='img/favicon.svg') }}" type="image/svg+xml"> |   <link rel="apple-touch-icon" href="{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.png') }}"> | ||||||
|   <link rel="apple-touch-icon" href="{{ url_for('static', filename='img/favicon.png') }}"> |   {% if not get_setting('brand.custom_files.favicon_png', false) or get_setting('brand.custom_files.favicon_svg', false) %} | ||||||
|  |   <link rel="icon" href="{{ url_for('custom', custom_file='favicon_svg', filename='img/favicon.svg') }}" type="image/svg+xml"> | ||||||
|  |   {% endif %} | ||||||
| </head> | </head> | ||||||
| <body class="{{ endpoint }}_endpoint" > | <body class="{{ endpoint }}_endpoint" > | ||||||
|   <main id="main_{{  self._TemplateReference__context.name|replace("simple/", "")|replace(".html", "") }}" class="{{body_class}}"> |   <main id="main_{{  self._TemplateReference__context.name|replace("simple/", "")|replace(".html", "") }}" class="{{body_class}}"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| {% from 'simple/icons.html' import icon_big %} | {% from 'simple/icons.html' import icon_big %} | ||||||
| {% block content %} | {% block content %} | ||||||
| <div class="index"> | <div class="index"> | ||||||
|     <div class="title"><h1>SearXNG</h1></div> |     <div class="title{% if get_setting('brand.custom_files.logo', false) %} custom_logo{% endif %}"><h1>SearXNG</h1></div> | ||||||
|     {% include 'simple/simple_search.html' %} |     {% include 'simple/simple_search.html' %} | ||||||
| </div> | </div> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
|   <LongName>SearXNG metasearch</LongName> |   <LongName>SearXNG metasearch</LongName> | ||||||
|   <Description>SearXNG is a metasearch engine that respects your privacy.</Description> |   <Description>SearXNG is a metasearch engine that respects your privacy.</Description> | ||||||
|   <InputEncoding>UTF-8</InputEncoding> |   <InputEncoding>UTF-8</InputEncoding> | ||||||
|   <Image type="image/png">{{ url_for('static', filename='img/favicon.png', _external=True) }}</Image> |   <Image type="image/png">{{ url_for('custom', custom_file='favicon_png', filename='img/favicon.png', _external=True) }}</Image> | ||||||
|   {% if opensearch_method == 'GET' %} |   {% if opensearch_method == 'GET' %} | ||||||
|   <Url rel="results" type="text/html" method="{{ opensearch_method }}" template="{{ url_for('search', _external=True) }}?q={searchTerms}"/> |   <Url rel="results" type="text/html" method="{{ opensearch_method }}" template="{{ url_for('search', _external=True) }}?q={searchTerms}"/> | ||||||
|   {% else %} |   {% else %} | ||||||
|  | |||||||
| @ -2,6 +2,6 @@ | |||||||
| {%- extends "simple/base.html" -%} | {%- extends "simple/base.html" -%} | ||||||
| {%- block header -%} | {%- block header -%} | ||||||
|   <a href="{{ url_for('index') }}">{{- '' -}} |   <a href="{{ url_for('index') }}">{{- '' -}} | ||||||
|     <img class="logo" src="{{ url_for('static', filename='img/searxng.png') }}" alt="SearXNG">{{- '' -}} |     <img class="logo" src="{{ url_for('custom', custom_file='logo', filename='img/searxng.png') }}" alt="SearXNG">{{- '' -}} | ||||||
|   </a>{{- '' -}} |   </a>{{- '' -}} | ||||||
| {%- endblock -%} | {%- endblock -%} | ||||||
|  | |||||||
| @ -2,7 +2,12 @@ | |||||||
|   <div id="search_header"> |   <div id="search_header"> | ||||||
|     <a id="search_logo" href="{{ url_for('index') }}" tabindex="0" title="{{ _('Display the front page') }}"> |     <a id="search_logo" href="{{ url_for('index') }}" tabindex="0" title="{{ _('Display the front page') }}"> | ||||||
|       <span hidden>SearXNG</span> |       <span hidden>SearXNG</span> | ||||||
|       {% include 'simple/searxng-wordmark.min.svg' without context %} |       <img width="23px" height="23px" src=" | ||||||
|  |       {%- if not get_setting('brand.custom_files.favicon_svg', false) -%} | ||||||
|  |       {{ url_for('custom', custom_file='favicon_png', filename='img/favicon.svg') }} | ||||||
|  |       {%- else -%} {{ url_for('custom', custom_file='favicon_svg', filename='img/favicon.svg') }} | ||||||
|  |       {%- endif -%} | ||||||
|  |       "></img> | ||||||
|     </a> |     </a> | ||||||
|     <div id="search_view"> |     <div id="search_view"> | ||||||
|       <div class="search_box"> |       <div class="search_box"> | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 746 B | 
| @ -37,6 +37,7 @@ from flask import ( | |||||||
|     make_response, |     make_response, | ||||||
|     redirect, |     redirect, | ||||||
|     send_from_directory, |     send_from_directory, | ||||||
|  |     send_file, | ||||||
| ) | ) | ||||||
| from flask.wrappers import Response | from flask.wrappers import Response | ||||||
| from flask.json import jsonify | from flask.json import jsonify | ||||||
| @ -74,6 +75,7 @@ from searx import webutils | |||||||
| from searx.webutils import ( | from searx.webutils import ( | ||||||
|     highlight_content, |     highlight_content, | ||||||
|     get_static_files, |     get_static_files, | ||||||
|  |     get_custom_files, | ||||||
|     get_result_templates, |     get_result_templates, | ||||||
|     get_themes, |     get_themes, | ||||||
|     exception_classname_to_text, |     exception_classname_to_text, | ||||||
| @ -132,6 +134,7 @@ if not searx_debug and settings['server']['secret_key'] == 'ultrasecretkey': | |||||||
| # about static | # about static | ||||||
| logger.debug('static directory is %s', settings['ui']['static_path']) | logger.debug('static directory is %s', settings['ui']['static_path']) | ||||||
| static_files = get_static_files(settings['ui']['static_path']) | static_files = get_static_files(settings['ui']['static_path']) | ||||||
|  | custom_files = get_custom_files() | ||||||
| 
 | 
 | ||||||
| # about templates | # about templates | ||||||
| logger.debug('templates directory is %s', settings['ui']['templates_path']) | logger.debug('templates directory is %s', settings['ui']['templates_path']) | ||||||
| @ -256,6 +259,15 @@ def get_result_template(theme_name: str, template_name: str): | |||||||
| 
 | 
 | ||||||
| def custom_url_for(endpoint: str, **values): | def custom_url_for(endpoint: str, **values): | ||||||
|     suffix = "" |     suffix = "" | ||||||
|  |     if endpoint == 'custom' and values.get('custom_file'): | ||||||
|  |         if values['custom_file'] in custom_files: | ||||||
|  |             values.pop('filename') | ||||||
|  |             if get_setting('ui.static_use_hash'): | ||||||
|  |                 suffix = "?" + custom_files[values['custom_file']]['hash'] | ||||||
|  |         else: | ||||||
|  |             # if there's no custom file defined in settings.yml, then use the default file | ||||||
|  |             values.pop('custom_file') | ||||||
|  |             endpoint = 'static' | ||||||
|     if endpoint == 'static' and values.get('filename'): |     if endpoint == 'static' and values.get('filename'): | ||||||
|         file_hash = static_files.get(values['filename']) |         file_hash = static_files.get(values['filename']) | ||||||
|         if not file_hash: |         if not file_hash: | ||||||
| @ -1275,8 +1287,25 @@ def opensearch(): | |||||||
|     return resp |     return resp | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @app.route('/custom/<path:custom_file>') | ||||||
|  | def custom(custom_file): | ||||||
|  |     if custom_file in custom_files: | ||||||
|  |         filepath = custom_files[custom_file]['path'] | ||||||
|  |         if os.path.isfile(filepath): | ||||||
|  |             if 'mimetype' in custom_files[custom_file]: | ||||||
|  |                 return send_file(filepath, mimetype=custom_files[custom_file]['mimetype']) | ||||||
|  |             return send_file(filepath) | ||||||
|  |         logger.warning('%s does not exist or is not a file', filepath) | ||||||
|  |     return flask.abort(404) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| @app.route('/favicon.ico') | @app.route('/favicon.ico') | ||||||
| def favicon(): | def favicon(): | ||||||
|  |     if 'favicon_png' in custom_files: | ||||||
|  |         filepath = custom_files['favicon_png']['path'] | ||||||
|  |         if os.path.isfile(filepath): | ||||||
|  |             return send_file(filepath, mimetype='image/png') | ||||||
|  |         logger.warning('%s does not exist or is not a file', filepath) | ||||||
|     theme = request.preferences.get_value("theme") |     theme = request.preferences.get_value("theme") | ||||||
|     return send_from_directory( |     return send_from_directory( | ||||||
|         os.path.join(app.root_path, settings['ui']['static_path'], 'themes', theme, 'img'),  # pyright: ignore |         os.path.join(app.root_path, settings['ui']['static_path'], 'themes', theme, 'img'),  # pyright: ignore | ||||||
|  | |||||||
| @ -204,6 +204,28 @@ def get_static_files(static_path: str) -> Dict[str, str]: | |||||||
|     return static_files |     return static_files | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def get_custom_files() -> Dict[str, dict]: | ||||||
|  |     custom_files: Dict[str, dict] = {} | ||||||
|  | 
 | ||||||
|  |     for option in settings['brand']['custom_files']: | ||||||
|  |         filepath = settings['brand']['custom_files'][option] | ||||||
|  |         if os.path.isfile(filepath): | ||||||
|  |             custom_files.setdefault(option, {}) | ||||||
|  |             custom_files[option]['path'] = filepath | ||||||
|  |             custom_files[option]['hash'] = get_hash_for_file(pathlib.Path(filepath)) | ||||||
|  |             if option == 'favicon_png': | ||||||
|  |                 custom_files[option]['mimetype'] = 'image/png' | ||||||
|  |             if option == 'favicon_svg': | ||||||
|  |                 custom_files[option]['mimetype'] = 'image/svg+xml' | ||||||
|  |         else: | ||||||
|  |             logger.warning('%s does not exist or is not a file', filepath) | ||||||
|  | 
 | ||||||
|  |     if 'favicon_svg' in custom_files and 'favicon_png' not in custom_files: | ||||||
|  |         logger.warning('Some browsers only support PNG favicons, but you have only set an SVG favicon') | ||||||
|  | 
 | ||||||
|  |     return custom_files | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def get_result_templates(templates_path): | def get_result_templates(templates_path): | ||||||
|     result_templates = set() |     result_templates = set() | ||||||
|     templates_path_length = len(templates_path) + 1 |     templates_path_length = len(templates_path) + 1 | ||||||
|  | |||||||
| @ -8,7 +8,6 @@ STATIC_BUILT_PATHS=( | |||||||
|     'searx/static/themes/simple/js' |     'searx/static/themes/simple/js' | ||||||
|     'searx/static/themes/simple/src/generated/pygments.less' |     'searx/static/themes/simple/src/generated/pygments.less' | ||||||
|     'searx/static/themes/simple/img' |     'searx/static/themes/simple/img' | ||||||
|     'searx/templates/simple/searxng-wordmark.min.svg' |  | ||||||
|     'searx/templates/simple/icons.html' |     'searx/templates/simple/icons.html' | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user