mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-09 21:29:11 +00:00
Reduce Desktop App UX Save, Sync Confusion (#538)
- Show next sync time to make users aware of data sync is automated - Keep a single Save button to reduce confusion. It does what Save All previously did. Intent to manual sync should Save All - Default to using app.khoj.dev as default Khoj URL to ease Cloud sync setup - Add detailed chat intro message, mention download desktop app for docs sync - Only show search in web app nav pane if user has documents indexed - Hide download desktop app message in web app if synced files exist - Mark generated profile pic with subscription circle in web app
This commit is contained in:
@@ -24,7 +24,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|||||||
SECRET_KEY = os.getenv("KHOJ_DJANGO_SECRET_KEY")
|
SECRET_KEY = os.getenv("KHOJ_DJANGO_SECRET_KEY")
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = os.getenv("DJANGO_DEBUG", "False") == "True"
|
DEBUG = os.getenv("KHOJ_DEBUG", "False") == "True"
|
||||||
|
|
||||||
ALLOWED_HOSTS = [".khoj.dev", "localhost", "127.0.0.1", "[::1]", "beta.khoj.dev"]
|
ALLOWED_HOSTS = [".khoj.dev", "localhost", "127.0.0.1", "[::1]", "beta.khoj.dev"]
|
||||||
|
|
||||||
|
|||||||
@@ -134,10 +134,11 @@ async def set_user_subscription(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_user_subscription_state(user_subscription: Subscription) -> str:
|
def get_user_subscription_state(email: str) -> str:
|
||||||
"""Get subscription state of user
|
"""Get subscription state of user
|
||||||
Valid state transitions: trial -> subscribed <-> unsubscribed OR expired
|
Valid state transitions: trial -> subscribed <-> unsubscribed OR expired
|
||||||
"""
|
"""
|
||||||
|
user_subscription = Subscription.objects.filter(user__email=email).first()
|
||||||
if not user_subscription:
|
if not user_subscription:
|
||||||
return "trial"
|
return "trial"
|
||||||
elif user_subscription.type == Subscription.Type.TRIAL:
|
elif user_subscription.type == Subscription.Type.TRIAL:
|
||||||
@@ -370,8 +371,8 @@ class EntryAdapters:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def user_has_entries(user: KhojUser):
|
def user_has_entries(user: KhojUser):
|
||||||
return await Entry.objects.filter(user=user).aexists()
|
return Entry.objects.filter(user=user).exists()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def adelete_entry_by_file(user: KhojUser, file_path: str):
|
async def adelete_entry_by_file(user: KhojUser, file_path: str):
|
||||||
@@ -450,5 +451,5 @@ class EntryAdapters:
|
|||||||
return Entry.objects.filter(user=user).values_list("file_type", flat=True).distinct()
|
return Entry.objects.filter(user=user).values_list("file_type", flat=True).distinct()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_unique_file_source(user: KhojUser):
|
def get_unique_file_sources(user: KhojUser):
|
||||||
return Entry.objects.filter(user=user).values_list("file_source", flat=True).distinct()
|
return Entry.objects.filter(user=user).values_list("file_source", flat=True).distinct().all()
|
||||||
|
|||||||
@@ -91,10 +91,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="section-action-row">
|
<div class="section-action-row">
|
||||||
<div class="card-description-row">
|
<div class="card-description-row">
|
||||||
<button id="sync-data" class="sync-data">💾 Save</button>
|
<button id="sync-force" class="sync-data">💾 Save</button>
|
||||||
</div>
|
|
||||||
<div class="card-description-row">
|
|
||||||
<button id="sync-force" class="sync-data">💾 Save All</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-description-row">
|
<div class="card-description-row">
|
||||||
<button id="delete-all" class="sync-data">🗑️ Delete All</button>
|
<button id="delete-all" class="sync-data">🗑️ Delete All</button>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const {dialog} = require('electron');
|
|||||||
const cron = require('cron').CronJob;
|
const cron = require('cron').CronJob;
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
const KHOJ_URL = 'http://127.0.0.1:42110'
|
const KHOJ_URL = 'https://app.khoj.dev';
|
||||||
|
|
||||||
const Store = require('electron-store');
|
const Store = require('electron-store');
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ const schema = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const syncing = false;
|
let syncing = false;
|
||||||
var state = {}
|
var state = {}
|
||||||
const store = new Store({ schema });
|
const store = new Store({ schema });
|
||||||
|
|
||||||
|
|||||||
@@ -155,11 +155,14 @@ window.updateStateAPI.onUpdateState((event, state) => {
|
|||||||
loadingBar.style.display = 'none';
|
loadingBar.style.display = 'none';
|
||||||
let syncStatusElement = document.getElementById("sync-status");
|
let syncStatusElement = document.getElementById("sync-status");
|
||||||
const currentTime = new Date();
|
const currentTime = new Date();
|
||||||
|
nextSyncTime = new Date();
|
||||||
|
nextSyncTime.setMinutes(Math.ceil((nextSyncTime.getMinutes() + 1) / 10) * 10);
|
||||||
if (state.completed == false) {
|
if (state.completed == false) {
|
||||||
syncStatusElement.innerHTML = `Sync was unsuccessful at ${currentTime.toLocaleTimeString()}. Contact team@khoj.dev to report this issue.`;
|
syncStatusElement.innerHTML = `Sync was unsuccessful at ${currentTime.toLocaleTimeString()}. Contact team@khoj.dev to report this issue.`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syncStatusElement.innerHTML = `Last synced at ${currentTime.toLocaleTimeString()}`;
|
const options = { hour: '2-digit', minute: '2-digit' };
|
||||||
|
syncStatusElement.innerHTML = `⏱️ Synced at ${currentTime.toLocaleTimeString(undefined, options)}. Next sync at ${nextSyncTime.toLocaleTimeString(undefined, options)}.`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const urlInput = document.getElementById('khoj-host-url');
|
const urlInput = document.getElementById('khoj-host-url');
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<!--Add Header Logo and Nav Pane-->
|
<!--Add Header Logo and Nav Pane-->
|
||||||
{% import 'utils.html' as utils %}
|
{% import 'utils.html' as utils %}
|
||||||
{{ utils.heading_pane(user_photo, username) }}
|
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
||||||
|
|
||||||
<div class="filler"></div>
|
<div class="filler"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,9 +26,6 @@
|
|||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("settings-nav").classList.add("khoj-nav-selected");
|
document.getElementById("settings-nav").classList.add("khoj-nav-selected");
|
||||||
{% if is_active %}
|
|
||||||
document.getElementById("profile-picture").classList.add("subscribed");
|
|
||||||
{% endif %}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html, body {
|
||||||
|
|||||||
@@ -10,6 +10,16 @@
|
|||||||
</head>
|
</head>
|
||||||
<script type="text/javascript" src="/static/assets/utils.js"></script>
|
<script type="text/javascript" src="/static/assets/utils.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
let welcome_message = `
|
||||||
|
Hi, I am Khoj, your open, personal AI 👋🏽. I can help:
|
||||||
|
• 🧠 Answer general knowledge questions
|
||||||
|
• 💡 Be a sounding board for your ideas
|
||||||
|
• 📜 Chat with your notes & documents
|
||||||
|
|
||||||
|
Download the <a class='inline-chat-link' href='https://khoj.dev/downloads'>🖥️ Desktop app</a> to chat with your computer docs.
|
||||||
|
|
||||||
|
To get started, just start typing below. You can also type / to see a list of commands.
|
||||||
|
`.trim()
|
||||||
let chatOptions = [];
|
let chatOptions = [];
|
||||||
function copyProgrammaticOutput(event) {
|
function copyProgrammaticOutput(event) {
|
||||||
// Remove the first 4 characters which are the "Copy" button
|
// Remove the first 4 characters which are the "Copy" button
|
||||||
@@ -322,7 +332,7 @@
|
|||||||
document.getElementById("chat-input").setAttribute("placeholder", "Configure Khoj to enable chat");
|
document.getElementById("chat-input").setAttribute("placeholder", "Configure Khoj to enable chat");
|
||||||
} else {
|
} else {
|
||||||
// Set welcome message on load
|
// Set welcome message on load
|
||||||
renderMessage("Hey 👋🏾, what's up?", "khoj");
|
renderMessage(welcome_message, "khoj");
|
||||||
}
|
}
|
||||||
return data.response;
|
return data.response;
|
||||||
})
|
})
|
||||||
@@ -363,7 +373,7 @@
|
|||||||
|
|
||||||
<!--Add Header Logo and Nav Pane-->
|
<!--Add Header Logo and Nav Pane-->
|
||||||
{% import 'utils.html' as utils %}
|
{% import 'utils.html' as utils %}
|
||||||
{{ utils.heading_pane(user_photo, username) }}
|
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
||||||
|
|
||||||
<!-- Chat Body -->
|
<!-- Chat Body -->
|
||||||
<div id="chat-body"></div>
|
<div id="chat-body"></div>
|
||||||
@@ -376,9 +386,6 @@
|
|||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("chat-nav").classList.add("khoj-nav-selected");
|
document.getElementById("chat-nav").classList.add("khoj-nav-selected");
|
||||||
{% if is_active %}
|
|
||||||
document.getElementById("profile-picture").classList.add("subscribed");
|
|
||||||
{% endif %}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html, body {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<span class="card-title-text">Files</span>
|
<span class="card-title-text">Files</span>
|
||||||
<div class="instructions">
|
<div class="instructions">
|
||||||
<p class="card-description">Manage files from your computer</p>
|
<p class="card-description">Manage files from your computer</p>
|
||||||
<p id="desktop-client" class="card-description">Download the <a href="https://download.khoj.dev">Khoj Desktop app</a> to sync files from your computer</p>
|
<p id="get-desktop-client" class="card-description">Download the <a href="https://download.khoj.dev">Khoj Desktop app</a> to sync documents from your computer</p>
|
||||||
</div>
|
</div>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="section-manage-files">
|
<div class="section-manage-files">
|
||||||
@@ -56,8 +56,9 @@
|
|||||||
|
|
||||||
if (data.length == 0) {
|
if (data.length == 0) {
|
||||||
document.getElementById("delete-all-files").style.display = "none";
|
document.getElementById("delete-all-files").style.display = "none";
|
||||||
indexedFiles.innerHTML = "<div class='card-description'>Use the <a href='https://download.khoj.dev'>Khoj Desktop client</a> to index files.</div>";
|
indexedFiles.innerHTML = "<div class='card-description'>No documents synced with Khoj</div>";
|
||||||
} else {
|
} else {
|
||||||
|
document.getElementById("get-desktop-client").style.display = "none";
|
||||||
document.getElementById("delete-all-files").style.display = "block";
|
document.getElementById("delete-all-files").style.display = "block";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -272,7 +272,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<!--Add Header Logo and Nav Pane-->
|
<!--Add Header Logo and Nav Pane-->
|
||||||
{% import 'utils.html' as utils %}
|
{% import 'utils.html' as utils %}
|
||||||
{{ utils.heading_pane(user_photo, username) }}
|
{{ utils.heading_pane(user_photo, username, is_active, has_documents) }}
|
||||||
|
|
||||||
<!--Add Text Box To Enter Query, Trigger Incremental Search OnChange -->
|
<!--Add Text Box To Enter Query, Trigger Incremental Search OnChange -->
|
||||||
<input type="text" id="query" class="option" onkeyup=incrementalSearch(event) autofocus="autofocus" placeholder="Search your knowledge base using natural language">
|
<input type="text" id="query" class="option" onkeyup=incrementalSearch(event) autofocus="autofocus" placeholder="Search your knowledge base using natural language">
|
||||||
@@ -287,9 +287,6 @@
|
|||||||
</body>
|
</body>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("search-nav").classList.add("khoj-nav-selected");
|
document.getElementById("search-nav").classList.add("khoj-nav-selected");
|
||||||
{% if is_active %}
|
|
||||||
document.getElementById("profile-picture").classList.add("subscribed");
|
|
||||||
{% endif %}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
{% macro heading_pane(user_photo, username) -%}
|
{% macro heading_pane(user_photo, username, is_active, has_documents) -%}
|
||||||
<div class="khoj-header">
|
<div class="khoj-header">
|
||||||
<a class="khoj-logo" href="/" target="_blank">
|
<a class="khoj-logo" href="/" target="_blank">
|
||||||
<img class="khoj-logo" src="/static/assets/icons/khoj-logo-sideways-500.png" alt="Khoj"></img>
|
<img class="khoj-logo" src="/static/assets/icons/khoj-logo-sideways-500.png" alt="Khoj"></img>
|
||||||
</a>
|
</a>
|
||||||
<nav class="khoj-nav">
|
<nav class="khoj-nav">
|
||||||
<a id="chat-nav" class="khoj-nav" href="/chat">💬 Chat</a>
|
<a id="chat-nav" class="khoj-nav" href="/chat">💬 Chat</a>
|
||||||
|
{% if has_documents %}
|
||||||
<a id="search-nav" class="khoj-nav" href="/search">🔎 Search</a>
|
<a id="search-nav" class="khoj-nav" href="/search">🔎 Search</a>
|
||||||
|
{% endif %}
|
||||||
<!-- Dropdown Menu -->
|
<!-- Dropdown Menu -->
|
||||||
<div id="khoj-nav-menu-container" class="khoj-nav dropdown">
|
<div id="khoj-nav-menu-container" class="khoj-nav dropdown">
|
||||||
{% if user_photo and user_photo != "None" %}
|
{% if user_photo and user_photo != "None" %}
|
||||||
@@ -15,7 +17,11 @@
|
|||||||
<img id="profile-picture" class="circle" src="{{ user_photo }}" alt="{{ username[0].upper() }}" onclick="toggleMenu()" referrerpolicy="no-referrer">
|
<img id="profile-picture" class="circle" src="{{ user_photo }}" alt="{{ username[0].upper() }}" onclick="toggleMenu()" referrerpolicy="no-referrer">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="circle user-initial" alt="{{ username[0].upper() }}" onclick="toggleMenu()">{{ username[0].upper() }}</div>
|
{% if is_active %}
|
||||||
|
<div id="profile-picture" class="circle user-initial subscribed" alt="{{ username[0].upper() }}" onclick="toggleMenu()">{{ username[0].upper() }}</div>
|
||||||
|
{% else %}
|
||||||
|
<div id="profile-picture" class="circle user-initial" alt="{{ username[0].upper() }}" onclick="toggleMenu()">{{ username[0].upper() }}</div>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="khoj-nav-menu" class="khoj-nav-dropdown-content">
|
<div id="khoj-nav-menu" class="khoj-nav-dropdown-content">
|
||||||
<div class="khoj-nav-username"> {{ username }} </div>
|
<div class="khoj-nav-username"> {{ username }} </div>
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def migrate_server_pg(args):
|
def migrate_server_pg(args):
|
||||||
schema_version = "0.14.0"
|
schema_version = "0.15.0"
|
||||||
raw_config = load_config_from_file(args.config_file)
|
raw_config = load_config_from_file(args.config_file)
|
||||||
previous_version = raw_config.get("version")
|
previous_version = raw_config.get("version")
|
||||||
|
|
||||||
|
|||||||
@@ -326,9 +326,7 @@ def get_config_types(
|
|||||||
request: Request,
|
request: Request,
|
||||||
):
|
):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
|
|
||||||
enabled_file_types = EntryAdapters.get_unique_file_types(user)
|
enabled_file_types = EntryAdapters.get_unique_file_types(user)
|
||||||
|
|
||||||
configured_content_types = list(enabled_file_types)
|
configured_content_types = list(enabled_file_types)
|
||||||
|
|
||||||
if state.config and state.config.content_type:
|
if state.config and state.config.content_type:
|
||||||
@@ -665,7 +663,7 @@ async def extract_references_and_questions(
|
|||||||
if conversation_type == ConversationCommand.General:
|
if conversation_type == ConversationCommand.General:
|
||||||
return compiled_references, inferred_queries, q
|
return compiled_references, inferred_queries, q
|
||||||
|
|
||||||
if not await EntryAdapters.user_has_entries(user=user):
|
if not sync_to_async(EntryAdapters.user_has_entries)(user=user):
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"No content index loaded, so cannot extract references from knowledge base. Please configure your data sources and update the index to chat with your notes."
|
"No content index loaded, so cannot extract references from knowledge base. Please configure your data sources and update the index to chat with your notes."
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ templates = Jinja2Templates(directory=constants.web_directory)
|
|||||||
def index(request: Request):
|
def index(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"chat.html",
|
"chat.html",
|
||||||
@@ -44,6 +46,8 @@ def index(request: Request):
|
|||||||
"request": request,
|
"request": request,
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,6 +57,8 @@ def index(request: Request):
|
|||||||
def index_post(request: Request):
|
def index_post(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"chat.html",
|
"chat.html",
|
||||||
@@ -60,6 +66,8 @@ def index_post(request: Request):
|
|||||||
"request": request,
|
"request": request,
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -69,8 +77,8 @@ def index_post(request: Request):
|
|||||||
def search_page(request: Request):
|
def search_page(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
user_subscription = adapters.get_user_subscription(user.email)
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
user_subscription_state = get_user_subscription_state(user_subscription)
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"search.html",
|
"search.html",
|
||||||
@@ -79,6 +87,7 @@ def search_page(request: Request):
|
|||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,8 +97,8 @@ def search_page(request: Request):
|
|||||||
def chat_page(request: Request):
|
def chat_page(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
user_subscription = adapters.get_user_subscription(user.email)
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
user_subscription_state = get_user_subscription_state(user_subscription)
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"chat.html",
|
"chat.html",
|
||||||
@@ -98,6 +107,7 @@ def chat_page(request: Request):
|
|||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -124,28 +134,29 @@ def login_page(request: Request):
|
|||||||
def config_page(request: Request):
|
def config_page(request: Request):
|
||||||
user: KhojUser = request.user.object
|
user: KhojUser = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
|
|
||||||
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
user_subscription = adapters.get_user_subscription(user.email)
|
user_subscription = adapters.get_user_subscription(user.email)
|
||||||
user_subscription_state = get_user_subscription_state(user_subscription)
|
|
||||||
subscription_renewal_date = (
|
subscription_renewal_date = (
|
||||||
user_subscription.renewal_date.strftime("%d %b %Y")
|
user_subscription.renewal_date.strftime("%d %b %Y")
|
||||||
if user_subscription and user_subscription.renewal_date
|
if user_subscription and user_subscription.renewal_date
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
enabled_content_source = set(EntryAdapters.get_unique_file_source(user).all())
|
|
||||||
|
|
||||||
|
enabled_content_source = set(EntryAdapters.get_unique_file_sources(user))
|
||||||
successfully_configured = {
|
successfully_configured = {
|
||||||
"computer": ("computer" in enabled_content_source),
|
"computer": ("computer" in enabled_content_source),
|
||||||
"github": ("github" in enabled_content_source),
|
"github": ("github" in enabled_content_source),
|
||||||
"notion": ("notion" in enabled_content_source),
|
"notion": ("notion" in enabled_content_source),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selected_conversation_config = ConversationAdapters.get_conversation_config(user)
|
||||||
conversation_options = ConversationAdapters.get_conversation_processor_options().all()
|
conversation_options = ConversationAdapters.get_conversation_processor_options().all()
|
||||||
all_conversation_options = list()
|
all_conversation_options = list()
|
||||||
for conversation_option in conversation_options:
|
for conversation_option in conversation_options:
|
||||||
all_conversation_options.append({"chat_model": conversation_option.chat_model, "id": conversation_option.id})
|
all_conversation_options.append({"chat_model": conversation_option.chat_model, "id": conversation_option.id})
|
||||||
|
|
||||||
selected_conversation_config = ConversationAdapters.get_conversation_config(user)
|
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"config.html",
|
"config.html",
|
||||||
context={
|
context={
|
||||||
@@ -161,6 +172,7 @@ def config_page(request: Request):
|
|||||||
"subscription_renewal_date": subscription_renewal_date,
|
"subscription_renewal_date": subscription_renewal_date,
|
||||||
"khoj_cloud_subscription_url": os.getenv("KHOJ_CLOUD_SUBSCRIPTION_URL"),
|
"khoj_cloud_subscription_url": os.getenv("KHOJ_CLOUD_SUBSCRIPTION_URL"),
|
||||||
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -170,6 +182,8 @@ def config_page(request: Request):
|
|||||||
def github_config_page(request: Request):
|
def github_config_page(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
current_github_config = get_user_github_config(user)
|
current_github_config = get_user_github_config(user)
|
||||||
|
|
||||||
if current_github_config:
|
if current_github_config:
|
||||||
@@ -198,6 +212,8 @@ def github_config_page(request: Request):
|
|||||||
"current_config": current_config,
|
"current_config": current_config,
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -207,6 +223,8 @@ def github_config_page(request: Request):
|
|||||||
def notion_config_page(request: Request):
|
def notion_config_page(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
|
user_subscription_state = adapters.get_user_subscription(user.email)
|
||||||
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
current_notion_config = get_user_notion_config(user)
|
current_notion_config = get_user_notion_config(user)
|
||||||
|
|
||||||
current_config = NotionContentConfig(
|
current_config = NotionContentConfig(
|
||||||
@@ -222,6 +240,8 @@ def notion_config_page(request: Request):
|
|||||||
"current_config": current_config,
|
"current_config": current_config,
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -231,6 +251,8 @@ def notion_config_page(request: Request):
|
|||||||
def computer_config_page(request: Request):
|
def computer_config_page(request: Request):
|
||||||
user = request.user.object
|
user = request.user.object
|
||||||
user_picture = request.session.get("user", {}).get("picture")
|
user_picture = request.session.get("user", {}).get("picture")
|
||||||
|
user_subscription_state = get_user_subscription_state(user.email)
|
||||||
|
has_documents = EntryAdapters.user_has_entries(user=user)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"content_source_computer_input.html",
|
"content_source_computer_input.html",
|
||||||
@@ -238,5 +260,7 @@ def computer_config_page(request: Request):
|
|||||||
"request": request,
|
"request": request,
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"user_photo": user_picture,
|
"user_photo": user_picture,
|
||||||
|
"is_active": user_subscription_state == "subscribed" or user_subscription_state == "unsubscribed",
|
||||||
|
"has_documents": has_documents,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ def cli(args=None):
|
|||||||
else:
|
else:
|
||||||
args = run_migrations(args)
|
args = run_migrations(args)
|
||||||
args.config = parse_config_from_file(args.config_file)
|
args.config = parse_config_from_file(args.config_file)
|
||||||
if os.environ.get("DEBUG"):
|
if os.environ.get("KHOJ_DEBUG"):
|
||||||
args.config.app.should_log_telemetry = False
|
args.config.app.should_log_telemetry = False
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|||||||
Reference in New Issue
Block a user