initial commit
1 parent 2f9b8a0 commit a28430fcf14568bf7b99dd29a2a3a618b2174f33
0xRoM authored on 21 Mar
Showing 14 changed files
View
110
README.md
TriliumScripts
===============
 
My collection of scripts for use with trilium
Collection of scripts for use with trilium
 
## syntax highlighting
 
**highlight_moodlog.js** & **highlight_todo.js** - Both of these will apply appropriate syntaxy highlighting to the specific note.
 
### installation
 
1) add the code as the notes contents.
 
2) set "note type" to "JS frontend"
 
3) add an "owned attribute" of "#widget"
 
### use
 
on the note you want highlighting set the "owned attributes" to "#todotxt #hideHighlightWidget" or "#moodlog #hideHighlightWidget" depending on which syntax type you want to highlight
 
## bidirectional sync
 
**trilium_sync.php** - script to keep a folder of local text files and a trilium note in sync.
 
### installation
 
Edit the config values at the top of the script to match your trilium setup. Run it manually to test it is working as expected. If it is create a cron job.
 
### example use
 
```
$> php trilium_sync.php
[i] checking connections
[i] version: x.xx.x
[i] gathering info
 
- Folders -
Folder/Path Folder Name Parent noteId Mod Trl Mod Dsk Status
Synced/ Synced root j0DRZhIzV97W 1742502936 1742507367 Exists
Synced/BothPlaces/ BothPlaces j0DRZhIzV97W AQb3Dg0yZHSu 1742507075 1742507200 Exists
Synced/[del] tobe del/ [del] tobe del j0DRZhIzV97W j0xUs1FdZL1Y 1742507321 Missing_Disk
Synced/AddToTrilium/ AddToTrilium 1742507383 Missing_Trilium
Synced/tobe deleted/ tobe deleted 1742507200 Missing_Trilium
- Files -
Folder/Path Filename Parent noteId Mod Trl Mod Dsk Hash Status
Synced/BothPlaces/ UpdateDiskFile AQb3Dg0yZHSu IwUZLwWdbiWG 1742507314 1742507199 Diff Update_Disk
Synced/BothPlaces/ UpdateTriliumFile AQb3Dg0yZHSu 7pMPgsb9AVRf 1742507130 1742507345 Diff Update_Trilium
Synced/[del] tobe del/ gone_also.txt j0xUs1FdZL1Y 4wOoHDy07csr 1742507178 N/A Missing_Disk
Synced/AddToTrilium/ fromDiskToTrilium.txt 1742507394 N/A Missing_Trilium
Synced/tobe deleted/ gone_also.txt 1742507200 N/A Missing_Trilium
 
[-] deleting disk folder: /mnt/hgfs/PentestOS/Misc/trilium_sync/Synced/tobe deleted/
[+] creating trilium folder: Synced/AddToTrilium/
[+] creating trilium note: /mnt/hgfs/PentestOS/Misc/trilium_sync/Synced/AddToTrilium/fromDiskToTrilium.txt
[+] updating file on disk: /mnt/hgfs/PentestOS/Misc/trilium_sync/Synced/BothPlaces/UpdateDiskFile
[+] updating file on trilium: /mnt/hgfs/PentestOS/Misc/trilium_sync/Synced/BothPlaces/UpdateTriliumFile
```
View
166
highlight_moodlog.js 0 → 100644
const TPL = `<div style="padding: 10px; border-top: 1px solid var(--main-border-color); contain: none;">
<strong>Moodlog Highlighting Applied</strong>
</div>`;
 
class MoodlogHighlighterWidget extends api.NoteContextAwareWidget {
static get parentWidget() {
//console.log("MDLG: Getting parent widget: center-pane");
return 'center-pane';
}
 
get position() {
//console.log("MDLG: Setting position: 100");
return 100;
}
 
isEnabled() {
const enabled = super.isEnabled()
&& this.note.type === 'text'
&& this.note.hasLabel('moodlog');
//console.log(`MDLG: isEnabled: ${enabled}`);
return enabled;
}
 
doRender() {
//console.log("MDLG: Rendering widget...");
this.$widget = $(TPL);
//console.log("MDLG: Widget rendered:", this.$widget);
return this.$widget;
}
 
async refreshWithNote(note) {
//console.log("MDLG: Refreshing with note:", note);
const { content } = await note.getNoteComplement();
//console.log("MDLG: Note content fetched:", content);
 
// Check if content is fetched properly
if (!content) {
//console.log("MDLG: No content fetched. Exiting refresh.");
return;
}
 
const highlightedContent = this.applyHighlighting(content);
//console.log("MDLG: Highlighted content:", highlightedContent);
 
if (highlightedContent !== content) {
//console.log("MDLG: Updating note content with highlighted version");
 
// Use the setNoteContent function to update the note content
try {
await setNoteContent(note.noteId, highlightedContent);
//console.log("MDLG: Content updated with highlighted version");
} catch (error) {
//console.error("MDLG: Error updating content:", error);
}
} else {
//console.log("MDLG: No changes to content, skipping update.");
}
}
 
 
applyHighlighting(content) {
//console.log("MDLG: Applying highlighting to content...");
 
// Replace <br> with \n, then remove all other HTML tags
const plainTextContent = content.replace(/<br\s*\/?>/gi, '\n').replace(/<[^>]*>/g, ' ');
//console.log("MDLG: Stripped content:", plainTextContent);
 
// Combined regex for date & time
const dateTimePattern = /([1-2]\d{3}[-/.](0?[1-9]|1[0-2])[-/.](0[1-9]|[12]\d|3[01]))\s+(\d{1,2}:\d{2})/g;
const projectPattern = /\[\S+?\]/g;
const contextPattern = /(\s|^)(@\S+)/g;
const hashtagPattern = /(\s|^)(#\S+)/g;
const positivePattern = /(\s|^)(\+\S+)/g;
const negativePattern = /(\s|^)(-\S+)/g;
 
// Escape HTML characters to prevent issues with replacements
function escapeHtml(str) {
return str.replace(/[&<>"']/g, function (char) {
return {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
}[char];
});
}
 
// Helper function to map the number to a colour based on the gradient
function getProjectColour(number) {
const minColor = { r: 107, g: 109, b: 229 }; // #6b6de5
const maxColor = { r: 70, g: 226, b: 96 }; // #46e260
 
const ratio = number / 9; // since we are working with 0-9
 
// Interpolate the RGB values between minColor and maxColor
const r = Math.round(minColor.r + ratio * (maxColor.r - minColor.r));
const g = Math.round(minColor.g + ratio * (maxColor.g - minColor.g));
const b = Math.round(minColor.b + ratio * (maxColor.b - minColor.b));
 
return `rgb(${r}, ${g}, ${b})`;
}
// Process each line of the plain text content
let highlightedLines = plainTextContent.split("\n").map(line => {
//console.log("MDLG: Processing line:", line);
 
// Apply combined date & time highlight
line = line.replace(dateTimePattern, `<span style="color: rgb(188, 55, 237);">$1</span> <span style="color: rgb(188, 55, 237);">$4</span>`);
 
// Apply other highlights
line = line.replace(projectPattern, (match) => {
// Extract the number inside square brackets
const number = parseInt(match.match(/\d+/)[0], 10);
const colour = getProjectColour(number);
return `<span style="color: ${colour}; font-weight: bold;">${escapeHtml(match)}</span>`;
});
// Apply other highlights
//line = line.replace(projectPattern, `<span style="color: rgb(224, 218, 36); font-weight: bold;">$&</span>`);
line = line.replace(contextPattern, (_, space, tag) => `${space}<span style="color: rgb(255 165 10);">${escapeHtml(tag)}</span>`);
line = line.replace(hashtagPattern, (_, space, tag) => `${space}<span style="color: rgb(41, 229, 242);">${escapeHtml(tag)}</span>`);
line = line.replace(positivePattern, (_, space, tag) => `${space}<span style="color: rgb(44, 227, 34);">${escapeHtml(tag)}</span>`);
line = line.replace(negativePattern, (_, space, tag) => `${space}<span style="color: rgb(230, 59, 44);">${escapeHtml(tag)}</span>`);
 
return line.trim();
});
 
// Join lines with proper <br> handling
let finalContent = highlightedLines.join("<br>");
 
//console.log("MDLG: Highlighted content:", finalContent);
return finalContent;
}
 
 
 
 
async entitiesReloadedEvent({ loadResults }) {
//console.log("MDLG: Entities reloaded event triggered");
if (loadResults.isNoteContentReloaded(this.noteId)) {
//console.log("MDLG: Note content reloaded, refreshing widget...");
//this.refresh();
} else {
//console.log("MDLG: No content reload detected.");
}
}
 
}
 
console.log("MDLG: Starting Moodlog Highlighter Widget");
module.exports = MoodlogHighlighterWidget;
 
function setNoteContent(noteId, content) {
/*const noteElement = document.querySelector(`note-detail-readonly-text-content`);
 
if (noteElement) {
noteElement.innerHTML = content; // Update the displayed content
console.log(`MDLG: Updated note ${noteId} in the DOM.`);
} else {
console.warn(`MDLG: Note element with data-note-id='${noteId}' not found.`);
}*/
return api.runOnBackend((id, data) => api.getNote(id).setContent(data), [noteId, content]);
}
View
158
highlight_todotxt.js 0 → 100644
const TPL = `<div style="padding: 10px; border-top: 1px solid var(--main-border-color); contain: none;">
<strong>Todo Highlighting Applied</strong>
</div>`;
 
class MoodlogHighlighterWidget extends api.NoteContextAwareWidget {
static get parentWidget() {
//console.log("MDLG: Getting parent widget: center-pane");
return 'center-pane';
}
 
get position() {
//console.log("MDLG: Setting position: 100");
return 100;
}
 
isEnabled() {
const enabled = super.isEnabled()
&& this.note.type === 'text'
&& this.note.hasLabel('todotxt');
//console.log(`MDLG: isEnabled: ${enabled}`);
return enabled;
}
 
doRender() {
//console.log("MDLG: Rendering widget...");
this.$widget = $(TPL);
//console.log("MDLG: Widget rendered:", this.$widget);
return this.$widget;
}
 
async refreshWithNote(note) {
//console.log("MDLG: Refreshing with note:", note);
const { content } = await note.getNoteComplement();
//console.log("MDLG: Note content fetched:", content);
 
// Check if content is fetched properly
if (!content) {
//console.log("MDLG: No content fetched. Exiting refresh.");
return;
}
 
const highlightedContent = this.applyHighlighting(content);
//console.log("MDLG: Highlighted content:", highlightedContent);
 
if (highlightedContent !== content) {
//console.log("MDLG: Updating note content with highlighted version");
 
// Use the setNoteContent function to update the note content
try {
await setNoteContent(note.noteId, highlightedContent);
//console.log("MDLG: Content updated with highlighted version");
} catch (error) {
//console.error("MDLG: Error updating content:", error);
}
} else {
//console.log("MDLG: No changes to content, skipping update.");
}
}
 
 
applyHighlighting(content) {
// Replace <br> with \n, then remove all other HTML tags
const plainTextContent = content.replace(/<br\s*\/?\>/gi, '\n').replace(/<[^>]*>/g, ' ');
 
// Regular expressions for Todo.txt syntax
const datePattern = /\b(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/([1-2]\d{3})\b/g;
const completedTaskPattern = /^\s*x\s+.*/g;
const priorityPattern = /^(\s*\([A-E]\))\s+/;
const projectPattern = /(?:\s|^)(\+\S+)/g;
const contextPattern = /(?:\s|^)(@\S+)/g;
const waitPattern = /\bWAIT\b/gi;
const customAttributePattern = /(\s+[^\s:]+:[^\s:]+)+\s*$/g;
function escapeHtml(str) {
return str.replace(/[&<>"']/g, char => ({
'&': '&amp;', '<': '&lt;', '>': '&gt;',
'"': '&quot;', "'": '&#039;'
})[char]);
}
 
let highlightedLines = plainTextContent.split("\n").map(line => {
// If line starts with 'x', make the whole line grey
if (/^\s*x\s+/.test(line)) {
return `<span style="color: grey;">${line}</span>`;
}
// Highlight priority with different colours based on level
line = line.replace(priorityPattern, (match, priority) => {
const level = priority.match(/[A-E]/)?.[0];
const colors = {
'A': 'rgb(255, 0, 0)', // Red
'B': 'rgb(255, 102, 0)', // Orange
'C': 'rgb(255, 204, 0)', // Yellow
'D': 'rgb(0, 153, 255)', // Blue
'E': 'rgb(102, 204, 102)' // Green
};
const color = colors[level] || 'black';
return `<span style="color: ${color}; font-weight: bold;">${escapeHtml(priority)}</span> `;
});
// Highlight date
line = line.replace(datePattern, (match) => {
return `<span style="color: rgb(188, 55, 237);">${escapeHtml(match)}</span>`;
});
 
// Highlight project tags
line = line.replace(projectPattern, (_, tag) => `<span style="color: rgb(224, 218, 36);"> ${escapeHtml(tag)}</span>`);
// Highlight context tags
line = line.replace(contextPattern, (_, tag) => `<span style="color: rgb(255, 165, 10);"> ${escapeHtml(tag)}</span>`);
// Highlight WAIT command
line = line.replace(waitPattern, `<span style="color: rgb(255, 69, 0);">WAIT</span>`);
// Highlight custom attributes
line = line.replace(customAttributePattern, `<span style="color: rgb(100, 149, 237);">$1</span>`);
// Remove leading space (if any) from the beginning of the line, without affecting spaces before + or @
line = line.replace(/^\s+/, '');
return line.trim();
});
 
return highlightedLines.join("<br>");
}
 
 
 
 
 
async entitiesReloadedEvent({ loadResults }) {
//console.log("MDLG: Entities reloaded event triggered");
if (loadResults.isNoteContentReloaded(this.noteId)) {
//console.log("MDLG: Note content reloaded, refreshing widget...");
//this.refresh();
} else {
//console.log("MDLG: No content reload detected.");
}
}
 
}
 
console.log("TodoHighlight: Starting todotxt Highlighter Widget");
module.exports = MoodlogHighlighterWidget;
 
function setNoteContent(noteId, content) {
/*const noteElement = document.querySelector(`note-detail-readonly-text-content`);
 
if (noteElement) {
noteElement.innerHTML = content; // Update the displayed content
console.log(`MDLG: Updated note ${noteId} in the DOM.`);
} else {
console.warn(`MDLG: Note element with data-note-id='${noteId}' not found.`);
}*/
return api.runOnBackend((id, data) => api.getNote(id).setContent(data), [noteId, content]);
}
View
41
htb2trilium/INSTALL.md 0 → 100644
## scripts require:
 
```
> pip3 install trilium-py
```
 
## config.json
- get trilium token in trilium options->ETAPI and "create new token"
- create a new note with a title "Machines"
- click on this note -> "note info". Note ID is there. This ID goes in "trilium_machines_htb_folder" in the config file
- set the folder's owned attributes to:
 
```
#label:user=promoted,single,text #label:root=promoted,single,text #label:respect=promoted,single,text #user=0 #root=0 #respect=0
```
 
- create a note named "HTBMachineTemplate"
- set it's "owned attributes" to:
 
```
#template #label:User=promoted,single,text #label:Root=promoted,single,text #label:Tags=promoted,single,text
```
 
- get this page's ID and put in "trilium_machines_template_id"
- create "challenges" page, this page's ID goes in: trilium_challenges_folder
- create "Sherlocks" page, this page's ID goes in: trilium_sherlocks_folder
- create 2 pages "HTBChallengesTemplate" and "HTBSherlocksTemplate", both of these should have the owned attributes:
 
```
#template #label:Difficulty=promoted,single,text #label:Solved=promoted,single,text #label:Released=promoted,single,text
```
 
- The ID's of "HTBChallengesTemplate" and "HTBSherlocksTemplate" go in the matching config values.
 
- to get "in progress" todo colour - add to trilium demo/scripting/taskmanager/implementation/CSS:
 
```
span.fancytree-node.inprogress .fancytree-title {
color: orange !important;
}
```
View
16
htb2trilium/README.md 0 → 100644
htb2trilium
===============
 
Pull hackthebox info and stats into personal trilium note taking software
 
single machine view:
 
![machine view](images/machine_view.png)
 
overview of machines:
 
![machines overview](images/machines_overview.png)
 
navigation:
 
![navigation](images/navigation.png)
View
htb2trilium/config.json 0 → 100644
View
htb2trilium/htb2trilium_challenges.py 0 → 100644
View
htb2trilium/htb2trilium_machines.py 0 → 100644
View
htb2trilium/htb2trilium_sherlocks.py 0 → 100644
View
htb2trilium/htb_client.py 0 → 100644
View
htb2trilium/images/machine_view.png 0 → 100755
View
htb2trilium/images/machines_overview.png 0 → 100755
View
htb2trilium/images/navigation.png 0 → 100755
View
trilium_sync.php 0 → 100644
Buy Me A Coffee