feat: Deprecate In App Help (#6801)
* [feat] Removed help from toolbar.js * [feat] Removed help from global search * [feat] redirected search in help to docs website [] Url needs to be configurable from hooks * [Feat] Removed search functions for help * [fix] Help links not redirecting * [feat] Modified "Help" menu on desk toolbar * [feat] Removed docs search from desk toolbar * Removed Search from toolbar.js * Removed /search_docs from website * Removed help from migrate * Deprecated help from command utils * Removed help.py * Removed help setup from travis.yml * [fix] Fixed formatting issues * [fix] Deleted commented code from toolbar.js * [fix] Minor link fix * [Fix] Fixed a small typo * Removed docs_app dependency from pathces * [fix] Removed commented code * [fix] Typo in function name * fix: remove commented code * [fix] Changed 'Deprecated' message to 'Removed' Removed will be the correct term instead of deprecated
This commit is contained in:
parent
e4224ea5d8
commit
dad1c04aae
13 changed files with 15 additions and 546 deletions
|
|
@ -35,8 +35,6 @@ before_script:
|
|||
- cd ~/frappe-bench
|
||||
- bench use test_site
|
||||
- bench reinstall --yes
|
||||
- bench setup-help
|
||||
- bench setup-global-help --mariadb_root_password travis
|
||||
- bench scheduler disable
|
||||
- sed -i 's/9000/9001/g' sites/common_site_config.json
|
||||
- bench start &
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
### User Permissions
|
||||
- User Permission is now a DocType, a new UX for the existing Role and User Permission managers to make it easy to enter permissions. For more details please check <a href="https://erpnext.org/docs/user/manual/en/setting-up/users-and-permissions/user-permissions">User Permissions</a>
|
||||
- User Permission is now a DocType, a new UX for the existing Role and User Permission managers to make it easy to enter permissions. For more details please check <a href="https://erpnext.com/docs/user/manual/en/setting-up/users-and-permissions/user-permissions">User Permissions</a>
|
||||
|
|
@ -571,54 +571,27 @@ def get_version():
|
|||
@click.command('setup-global-help')
|
||||
@click.option('--mariadb_root_password')
|
||||
def setup_global_help(mariadb_root_password=None):
|
||||
'''setup help table in a separate database that will be
|
||||
'''Removed: setup help table in a separate database that will be
|
||||
shared by the whole bench and set `global_help_setup` as 1 in
|
||||
common_site_config.json'''
|
||||
|
||||
from frappe.installer import update_site_config
|
||||
|
||||
frappe.local.flags = frappe._dict()
|
||||
frappe.local.flags.in_setup_help = True
|
||||
frappe.local.flags.in_install = True
|
||||
frappe.local.lang = 'en'
|
||||
frappe.local.conf = frappe.get_site_config(sites_path='.')
|
||||
|
||||
update_site_config('global_help_setup', 1,
|
||||
site_config_path=os.path.join('.', 'common_site_config.json'))
|
||||
|
||||
if mariadb_root_password:
|
||||
frappe.local.conf.root_password = mariadb_root_password
|
||||
|
||||
from frappe.utils.help import sync
|
||||
sync()
|
||||
print_in_app_help_deprecation()
|
||||
|
||||
@click.command('get-docs-app')
|
||||
@click.argument('app')
|
||||
def get_docs_app(app):
|
||||
'''Get the docs app for given app'''
|
||||
from frappe.utils.help import setup_apps_for_docs
|
||||
setup_apps_for_docs(app)
|
||||
'''Removed: Get the docs app for given app'''
|
||||
print_in_app_help_deprecation()
|
||||
|
||||
@click.command('get-all-docs-apps')
|
||||
def get_all_docs_apps():
|
||||
'''Get docs apps for all apps'''
|
||||
from frappe.utils.help import setup_apps_for_docs
|
||||
for app in frappe.get_installed_apps():
|
||||
setup_apps_for_docs(app)
|
||||
'''Removed: Get docs apps for all apps'''
|
||||
print_in_app_help_deprecation()
|
||||
|
||||
@click.command('setup-help')
|
||||
@pass_context
|
||||
def setup_help(context):
|
||||
'''Setup help table in the current site (called after migrate)'''
|
||||
from frappe.utils.help import sync
|
||||
|
||||
for site in context.sites:
|
||||
try:
|
||||
frappe.init(site)
|
||||
frappe.connect()
|
||||
sync()
|
||||
finally:
|
||||
frappe.destroy()
|
||||
'''Removed: Setup help table in the current site (called after migrate)'''
|
||||
print_in_app_help_deprecation()
|
||||
|
||||
@click.command('rebuild-global-search')
|
||||
@pass_context
|
||||
|
|
@ -681,6 +654,10 @@ def auto_deploy(context, app, migrate=False, restart=False, remote='upstream'):
|
|||
else:
|
||||
print('No Updates')
|
||||
|
||||
def print_in_app_help_deprecation():
|
||||
print("In app help has been removed.\nYou can access the documentation on erpnext.com/docs or frappe.io/docs")
|
||||
return
|
||||
|
||||
commands = [
|
||||
build,
|
||||
clear_cache,
|
||||
|
|
@ -709,8 +686,6 @@ commands = [
|
|||
watch,
|
||||
_bulk_rename,
|
||||
add_to_email_queue,
|
||||
setup_global_help,
|
||||
setup_help,
|
||||
rebuild_global_search,
|
||||
auto_deploy
|
||||
]
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ from frappe.website import render, router
|
|||
from frappe.desk.doctype.desktop_icon.desktop_icon import sync_desktop_icons
|
||||
from frappe.core.doctype.language.language import sync_languages
|
||||
from frappe.modules.utils import sync_customizations
|
||||
import frappe.utils.help
|
||||
|
||||
def migrate(verbose=True, rebuild_website=False):
|
||||
'''Migrate all apps to the latest version, will:
|
||||
|
|
@ -60,10 +59,6 @@ def migrate(verbose=True, rebuild_website=False):
|
|||
|
||||
frappe.db.commit()
|
||||
|
||||
if not frappe.conf.get('global_help_setup'):
|
||||
# sync help if not set as global
|
||||
frappe.utils.help.sync()
|
||||
|
||||
clear_notifications()
|
||||
|
||||
frappe.publish_realtime("version-update")
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@ frappe.patches.v11_0.rename_workflow_action_to_workflow_action_master #13-06-201
|
|||
frappe.patches.v11_0.rename_email_alert_to_notification #13-06-2018
|
||||
frappe.patches.v11_0.delete_duplicate_user_permissions
|
||||
frappe.patches.v11_0.set_dropbox_file_backup
|
||||
frappe.patches.v11_0.get_docs_apps_if_not_present
|
||||
frappe.patches.v10_0.set_default_locking_time
|
||||
frappe.patches.v11_0.rename_google_maps_doctype
|
||||
frappe.patches.v10_0.modify_smallest_currency_fraction
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils.help import setup_apps_for_docs
|
||||
|
||||
def execute():
|
||||
for app in frappe.get_installed_apps():
|
||||
setup_apps_for_docs(app)
|
||||
|
|
@ -47,16 +47,8 @@
|
|||
style="padding: 50% 7px; font-size: 17px; background-color: #fafbfc; font-weight: 100;">?</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<div class="input-group" style="border-bottom: 1px solid #d1d8dd;">
|
||||
<input id="input-help" type="text" placeholder="{{ __("What do you need help with?") }}" autofocus>
|
||||
<span class="input-group-btn"><button class="btn btn-default">{{ __("Go") }}</button></span>
|
||||
</div>
|
||||
<li id="help-links"></li>
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a data-link-type="documentation"
|
||||
data-path="/documentation/index" target="_blank" rel="noopener noreferrer">{{ __("Documentation") }}</a>
|
||||
</li>
|
||||
<li class="divider documentation-links"></li>
|
||||
<li><a href="#" onclick="return frappe.ui.toolbar.show_about();">
|
||||
{%= __("About") %}</a></li>
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ frappe.search.SearchDialog = Class.extend({
|
|||
});
|
||||
|
||||
// Help results
|
||||
this.$modal_body.on('click', 'a[data-path]', frappe.help.show_results);
|
||||
// this.$modal_body.on('click', 'a[data-path]', frappe.help.show_results);
|
||||
this.bind_keyboard_events();
|
||||
},
|
||||
|
||||
|
|
@ -366,35 +366,12 @@ frappe.search.SearchDialog = Class.extend({
|
|||
frappe.search.utils.get_global_results(keywords, start, limit)
|
||||
.then(function(global_results) {
|
||||
results = results.concat(global_results);
|
||||
return frappe.search.utils.get_help_results(keywords);
|
||||
}).then(function(help_results) {
|
||||
results = results.concat(help_results);
|
||||
callback(results, keywords);
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
help: {
|
||||
input_placeholder: __("Search Help"),
|
||||
empty_state_text: __("Search the docs"),
|
||||
no_results_status: (keyword) => __("<p>No results found for '" + keyword +
|
||||
"' in Help</p><p>Would you like to search <a class='switch-to-global-search text-muted' "+
|
||||
"style='text-decoration: underline;'>globally</a>" +
|
||||
" or the <a href='https://discuss.erpnext.com' class='forum-link text-muted' " +
|
||||
"style='text-decoration: underline;'>forums</a> instead?</p>"),
|
||||
|
||||
get_results: function(keywords, callback) {
|
||||
var results = [];
|
||||
frappe.search.utils.get_help_results(keywords)
|
||||
.then(function(help_results) {
|
||||
results = results.concat(help_results);
|
||||
callback(results, keywords);
|
||||
}, function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
|
@ -407,46 +407,6 @@ frappe.search.utils = {
|
|||
});
|
||||
},
|
||||
|
||||
get_help_results: function(keywords) {
|
||||
function get_results_set(data) {
|
||||
var result;
|
||||
var set = {
|
||||
title: "Help",
|
||||
fetch_type: "Help",
|
||||
results: []
|
||||
}
|
||||
data.forEach(function(d) {
|
||||
// more properties
|
||||
result = {
|
||||
label: d[0],
|
||||
value: d[0],
|
||||
description: d[1],
|
||||
data_path: d[2],
|
||||
onclick: function() {
|
||||
|
||||
}
|
||||
}
|
||||
set.results.push(result);
|
||||
});
|
||||
return [set];
|
||||
}
|
||||
return new Promise(function(resolve, reject) {
|
||||
frappe.call({
|
||||
method: "frappe.utils.help.get_help",
|
||||
args: {
|
||||
text: keywords
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
resolve(get_results_set(r.message));
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
get_nav_results: function(keywords) {
|
||||
function sort_uniques(array) {
|
||||
var routes = [], out = [];
|
||||
|
|
|
|||
|
|
@ -110,17 +110,10 @@ frappe.ui.toolbar.Toolbar = Class.extend({
|
|||
$("#input-help").on("keydown", function (e) {
|
||||
if(e.which == 13) {
|
||||
var keywords = $(this).val();
|
||||
show_help_results(keywords);
|
||||
$(this).val("");
|
||||
}
|
||||
});
|
||||
|
||||
$("#input-help + span").on("click", function () {
|
||||
var keywords = $("#input-help").val();
|
||||
show_help_results(keywords);
|
||||
$(this).val("");
|
||||
});
|
||||
|
||||
$(document).on("page-change", function () {
|
||||
var $help_links = $(".dropdown-help #help-links");
|
||||
$help_links.html("");
|
||||
|
|
@ -146,18 +139,10 @@ frappe.ui.toolbar.Toolbar = Class.extend({
|
|||
for (var i = 0; i < links.length; i++) {
|
||||
var link = links[i];
|
||||
var url = link.url;
|
||||
var app_name = url.split('//', 2)[1].split('/', 2)[1];
|
||||
var data_path = url.slice(url.indexOf('/user'));
|
||||
if(data_path.lastIndexOf('.')){
|
||||
data_path = data_path.slice(0, data_path.lastIndexOf('.'));
|
||||
}
|
||||
data_path = data_path.replace('user', app_name);
|
||||
|
||||
$("<a>", {
|
||||
href: link.url,
|
||||
text: link.label,
|
||||
target: "_blank",
|
||||
"data-path": data_path
|
||||
target: "_blank"
|
||||
}).appendTo($help_links);
|
||||
}
|
||||
|
||||
|
|
@ -169,11 +154,6 @@ frappe.ui.toolbar.Toolbar = Class.extend({
|
|||
|
||||
$(document).on("click", ".help-modal a", show_results);
|
||||
|
||||
var me = this;
|
||||
function show_help_results(keywords) {
|
||||
me.search.init_search(keywords, "help");
|
||||
}
|
||||
|
||||
function show_results(e) {
|
||||
//edit links
|
||||
var href = e.target.href;
|
||||
|
|
@ -183,20 +163,6 @@ frappe.ui.toolbar.Toolbar = Class.extend({
|
|||
var path = $(e.target).attr("data-path");
|
||||
if(path) {
|
||||
e.preventDefault();
|
||||
frappe.call({
|
||||
method: "frappe.utils.help.get_help_content",
|
||||
args: {
|
||||
path: path
|
||||
},
|
||||
callback: function (r) {
|
||||
if(r.message && r.message.title) {
|
||||
$result_modal.find('.modal-title').html("<span>"
|
||||
+ r.message.title + "</span>");
|
||||
$result_modal.find('.modal-body').html(r.message.content);
|
||||
$result_modal.modal('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,346 +0,0 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals, print_function
|
||||
|
||||
import frappe
|
||||
import hashlib
|
||||
|
||||
from frappe.model.db_schema import DbManager
|
||||
from frappe.installer import get_root_connection
|
||||
from frappe.database import Database
|
||||
import os, subprocess
|
||||
from bs4 import BeautifulSoup
|
||||
import jinja2.exceptions
|
||||
|
||||
import io
|
||||
|
||||
def sync():
|
||||
# make table
|
||||
print('Syncing help database...')
|
||||
help_db = HelpDatabase()
|
||||
help_db.make_database()
|
||||
help_db.connect()
|
||||
help_db.make_table()
|
||||
help_db.sync_pages()
|
||||
help_db.build_index()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_help(text):
|
||||
return HelpDatabase().search(text)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_installed_app_help(text):
|
||||
return HelpDatabase().app_docs_search(text)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_help_content(path):
|
||||
return HelpDatabase().get_content(path)
|
||||
|
||||
def get_improve_page_html(app_name, target):
|
||||
docs_config = frappe.get_module(app_name + ".config.docs")
|
||||
source_link = docs_config.source_link
|
||||
branch = getattr(docs_config, "branch", "master")
|
||||
html = '''<div class="page-container">
|
||||
<div class="page-content">
|
||||
<div class="edit-container text-center">
|
||||
<i class="fa fa-smile text-muted"></i>
|
||||
<a class="edit text-muted" href="{source_link}/blob/{branch}/{target}">
|
||||
Improve this page
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>'''.format(source_link=source_link, app_name=app_name, target=target, branch=branch)
|
||||
return html
|
||||
|
||||
|
||||
class HelpDatabase(object):
|
||||
def __init__(self):
|
||||
self.global_help_setup = frappe.conf.get('global_help_setup')
|
||||
if self.global_help_setup:
|
||||
bench_name = os.path.basename(os.path.abspath(frappe.get_app_path('frappe')).split('/apps/')[0])
|
||||
self.help_db_name = hashlib.sha224(bench_name.encode('utf-8')).hexdigest()[:15]
|
||||
|
||||
def make_database(self):
|
||||
'''make database for global help setup'''
|
||||
if not self.global_help_setup:
|
||||
return
|
||||
|
||||
dbman = DbManager(get_root_connection())
|
||||
dbman.drop_database(self.help_db_name)
|
||||
|
||||
# make database
|
||||
if not self.help_db_name in dbman.get_database_list():
|
||||
try:
|
||||
dbman.create_user(self.help_db_name, self.help_db_name)
|
||||
except Exception as e:
|
||||
# user already exists
|
||||
if e.args[0] != 1396: raise
|
||||
dbman.create_database(self.help_db_name)
|
||||
dbman.grant_all_privileges(self.help_db_name, self.help_db_name)
|
||||
dbman.flush_privileges()
|
||||
|
||||
def connect(self):
|
||||
if self.global_help_setup:
|
||||
self.db = Database(user=self.help_db_name, password=self.help_db_name)
|
||||
else:
|
||||
self.db = frappe.db
|
||||
|
||||
def make_table(self):
|
||||
if not 'help' in self.db.get_tables():
|
||||
self.db.sql('''create table help(
|
||||
path varchar(255),
|
||||
content text,
|
||||
title text,
|
||||
intro text,
|
||||
full_path text,
|
||||
fulltext(title),
|
||||
fulltext(content),
|
||||
index (path))
|
||||
COLLATE=utf8mb4_unicode_ci
|
||||
ENGINE=MyISAM
|
||||
CHARACTER SET=utf8mb4''')
|
||||
|
||||
def search(self, words):
|
||||
self.connect()
|
||||
return self.db.sql('''
|
||||
select title, intro, path from help where title like %s union
|
||||
select title, intro, path from help where match(content) against (%s) limit 10''', ('%'+words+'%', words))
|
||||
|
||||
def app_docs_search(self, words):
|
||||
self.connect()
|
||||
frappe_path = '%' + 'apps/frappe' + '%'
|
||||
return self.db.sql('''
|
||||
select
|
||||
title, intro, full_path
|
||||
from
|
||||
help
|
||||
where
|
||||
title like %s
|
||||
and
|
||||
full_path not like %s
|
||||
|
||||
union
|
||||
|
||||
select
|
||||
title, intro, full_path
|
||||
from
|
||||
help
|
||||
where
|
||||
match(content) against (%s)
|
||||
and
|
||||
full_path not like %s
|
||||
limit
|
||||
10
|
||||
|
||||
''', ('%'+words+'%', frappe_path, words, frappe_path))
|
||||
|
||||
def get_content(self, path):
|
||||
self.connect()
|
||||
query = '''select title, content from help
|
||||
where path like "{path}%" order by path desc limit 1'''
|
||||
result = None
|
||||
|
||||
if not path.endswith('index'):
|
||||
result = self.db.sql(query.format(path=os.path.join(path, 'index')))
|
||||
|
||||
if not result:
|
||||
result = self.db.sql(query.format(path=path))
|
||||
|
||||
return {'title':result[0][0], 'content':result[0][1]} if result else {}
|
||||
|
||||
def sync_pages(self):
|
||||
self.db.sql('truncate help')
|
||||
doc_contents = '<ol>'
|
||||
apps = os.listdir('../apps') if self.global_help_setup else frappe.get_installed_apps()
|
||||
|
||||
for app in apps:
|
||||
# Expect handling of cloning docs apps in bench
|
||||
docs_app = frappe.get_hooks('docs_app', app, app)[0]
|
||||
|
||||
web_folder = 'www/' if docs_app != app else ''
|
||||
|
||||
docs_folder = '../apps/{docs_app}/{docs_app}/{web_folder}docs/user'.format(
|
||||
docs_app=docs_app, web_folder=web_folder)
|
||||
self.out_base_path = '../apps/{docs_app}/{docs_app}/{web_folder}docs'.format(
|
||||
docs_app=docs_app, web_folder=web_folder)
|
||||
if os.path.exists(docs_folder):
|
||||
app_name = getattr(frappe.get_module(app), '__title__', None) or app.title()
|
||||
doc_contents += '<li><a data-path="/{app}/index">{app_name}</a></li>'.format(
|
||||
app=app, app_name=app_name)
|
||||
|
||||
for basepath, folders, files in os.walk(docs_folder):
|
||||
files = self.reorder_files(files)
|
||||
for fname in files:
|
||||
if fname.rsplit('.', 1)[-1] in ('md', 'html'):
|
||||
fpath = os.path.join(basepath, fname)
|
||||
with io.open(fpath, 'r', encoding = 'utf-8') as f:
|
||||
try:
|
||||
content = frappe.render_template(f.read(),
|
||||
{'docs_base_url': '/assets/{app}_docs'.format(app=app)}, safe_render=False)
|
||||
|
||||
relpath = self.get_out_path(fpath)
|
||||
relpath = relpath.replace("user", app)
|
||||
content = frappe.utils.md_to_html(content)
|
||||
title = self.make_title(basepath, fname, content)
|
||||
intro = self.make_intro(content)
|
||||
content = self.make_content(content, fpath, relpath, app, docs_app)
|
||||
self.db.sql('''insert into help(path, content, title, intro, full_path)
|
||||
values (%s, %s, %s, %s, %s)''', (relpath, content, title, intro, fpath))
|
||||
except jinja2.exceptions.TemplateSyntaxError:
|
||||
print("Invalid Jinja Template for {0}. Skipping".format(fpath))
|
||||
|
||||
doc_contents += "</ol>"
|
||||
self.db.sql('''insert into help(path, content, title, intro, full_path) values (%s, %s, %s, %s, %s)''',
|
||||
('/documentation/index', doc_contents, 'Documentation', '', ''))
|
||||
|
||||
|
||||
def make_title(self, basepath, filename, html):
|
||||
if '<h1>' in html:
|
||||
title = html.split("<h1>", 1)[1].split("</h1>", 1)[0]
|
||||
elif 'index' in filename:
|
||||
title = basepath.rsplit('/', 1)[-1].title().replace("-", " ")
|
||||
else:
|
||||
title = filename.rsplit('.', 1)[0].title().replace("-", " ")
|
||||
return title
|
||||
|
||||
def make_intro(self, html):
|
||||
intro = ""
|
||||
if '<p>' in html:
|
||||
intro = html.split('<p>', 1)[1].split('</p>', 1)[0]
|
||||
if 'Duration' in html:
|
||||
intro = "Help Video: " + intro
|
||||
return intro
|
||||
|
||||
def make_content(self, html, path, relpath, app_name, doc_app):
|
||||
if '<h1>' in html:
|
||||
html = html.split('</h1>', 1)[1]
|
||||
|
||||
if '{next}' in html:
|
||||
html = html.replace('{next}', '')
|
||||
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
self.fix_links(soup, app_name)
|
||||
self.fix_images(soup, doc_app)
|
||||
|
||||
parent = self.get_parent(relpath)
|
||||
if parent:
|
||||
parent_tag = soup.new_tag('a')
|
||||
parent_tag.string = parent['title']
|
||||
parent_tag['class'] = 'parent-link'
|
||||
parent_tag['data-path'] = parent['path']
|
||||
soup.find().insert_before(parent_tag)
|
||||
|
||||
return soup.prettify()
|
||||
|
||||
def fix_links(self, soup, app_name):
|
||||
for link in soup.find_all('a'):
|
||||
if link.has_attr('href'):
|
||||
url = link['href']
|
||||
if '/user' in url:
|
||||
data_path = url[url.index('/user'):]
|
||||
if '.' in data_path:
|
||||
data_path = data_path[: data_path.rindex('.')]
|
||||
if data_path:
|
||||
link['data-path'] = data_path.replace("user", app_name)
|
||||
|
||||
def fix_images(self, soup, app_name):
|
||||
for img in soup.find_all('img'):
|
||||
if img.has_attr('src'):
|
||||
url = img['src']
|
||||
if '/docs/' in url:
|
||||
img['src'] = url.replace('/docs/', '/assets/{0}_docs/'.format(app_name))
|
||||
|
||||
def build_index(self):
|
||||
for data in self.db.sql('select path, full_path, content from help'):
|
||||
self.make_index(data[0], data[1], data[2])
|
||||
|
||||
def make_index(self, original_path, full_path, content):
|
||||
'''Make index from index.txt'''
|
||||
if '{index}' in content:
|
||||
path = os.path.dirname(full_path)
|
||||
files = []
|
||||
|
||||
# get files from index.txt
|
||||
index_path = os.path.join(path, "index.txt")
|
||||
if os.path.exists(index_path):
|
||||
with open(index_path, 'r') as f:
|
||||
files = f.read().splitlines()
|
||||
|
||||
# files not in index.txt
|
||||
for f in os.listdir(path):
|
||||
if not os.path.isdir(os.path.join(path, f)) and len(f.rsplit('.', 1)) == 2:
|
||||
name, extn = f.rsplit('.', 1)
|
||||
if name not in files \
|
||||
and name != 'index' and extn in ('md', 'html'):
|
||||
files.append(name)
|
||||
|
||||
links_html = "<ol class='index-links'>"
|
||||
for line in files:
|
||||
fpath = os.path.join(os.path.dirname(original_path), line)
|
||||
|
||||
title = self.db.sql('select title from help where path like %s',
|
||||
os.path.join(fpath, 'index') + '%')
|
||||
if not title:
|
||||
title = self.db.sql('select title from help where path like %s',
|
||||
fpath + '%')
|
||||
|
||||
if title:
|
||||
title = title[0][0]
|
||||
links_html += "<li><a data-path='{fpath}'> {title} </a></li>".format(
|
||||
fpath=fpath, title=title)
|
||||
# else:
|
||||
# bad entries in .txt files
|
||||
# print fpath
|
||||
|
||||
links_html += "</ol>"
|
||||
html = content.replace('{index}', links_html)
|
||||
|
||||
self.db.sql('update help set content=%s where path=%s', (html, original_path))
|
||||
|
||||
def get_out_path(self, path):
|
||||
return '/' + os.path.relpath(path, self.out_base_path)
|
||||
|
||||
def get_parent(self, child_path):
|
||||
if 'index' in child_path:
|
||||
child_path = child_path[: child_path.rindex('index')]
|
||||
if child_path[-1] == '/':
|
||||
child_path = child_path[:-1]
|
||||
child_path = child_path[: child_path.rindex('/')]
|
||||
|
||||
out = None
|
||||
if child_path:
|
||||
parent_path = child_path + "/index"
|
||||
out = self.get_content(parent_path)
|
||||
#if parent is documentation root
|
||||
else:
|
||||
parent_path = "/documentation/index"
|
||||
out = {}
|
||||
out['title'] = "Documentation"
|
||||
|
||||
if not out:
|
||||
return None
|
||||
|
||||
out['path'] = parent_path
|
||||
return out
|
||||
|
||||
def reorder_files(self, files):
|
||||
pos = 0
|
||||
if 'index.md' in files:
|
||||
pos = files.index('index.md')
|
||||
elif 'index.html' in files:
|
||||
pos = files.index('index.html')
|
||||
if pos:
|
||||
files[0], files[pos] = files[pos], files[0]
|
||||
return files
|
||||
|
||||
def setup_apps_for_docs(app):
|
||||
docs_app = frappe.get_hooks('docs_app', app, app)[0]
|
||||
|
||||
if docs_app and not os.path.exists(frappe.get_app_path(app)):
|
||||
print("Getting {docs_app} required by {app}".format(docs_app=docs_app, app=app))
|
||||
subprocess.check_output(['bench', 'get-app', docs_app], cwd = '..')
|
||||
else:
|
||||
if docs_app:
|
||||
print("{docs_app} required by {app} already present".format(docs_app=docs_app, app=app))
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{% extends "templates/web.html" %}
|
||||
|
||||
{% block page_content %}
|
||||
|
||||
{% include "templates/includes/search_template.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from jinja2 import utils
|
||||
from html2text import html2text
|
||||
from frappe.utils import sanitize_html
|
||||
from frappe.utils.help import get_installed_app_help
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
if frappe.form_dict.q:
|
||||
query = str(utils.escape(sanitize_html(frappe.form_dict.q)))
|
||||
context.title = _('Documentation Results for "{0}"').format(query)
|
||||
context.route = '/search_docs'
|
||||
d = frappe._dict()
|
||||
d.results = get_docs_results(query)
|
||||
context.update(d)
|
||||
else:
|
||||
context.title = _('Docs Search')
|
||||
|
||||
@frappe.whitelist(allow_guest = True)
|
||||
def get_docs_results(text):
|
||||
out = []
|
||||
results = get_installed_app_help(text)
|
||||
for d in results:
|
||||
full_path = d[2]
|
||||
out.append(frappe._dict({
|
||||
'title': d[0],
|
||||
'preview': html2text(d[1]),
|
||||
'route': full_path[full_path.index('docs/'):]
|
||||
}))
|
||||
|
||||
return out
|
||||
Loading…
Add table
Reference in a new issue