diff --git a/.vitepress/config.mts b/.vitepress/config.mts index db58958..9581f63 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -3,6 +3,7 @@ import process from 'node:process'; import { URL, fileURLToPath } from 'node:url'; import { defineConfig } from 'vitepress'; import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'; +import { markdownFitMedia } from './plugins/markdown-fit-media'; const __dirname = path.dirname(fileURLToPath(new URL(import.meta.url))); @@ -123,6 +124,13 @@ export default defineConfig({ markdown: { config(md) { md.use(tabsMarkdownPlugin); + md.use(markdownFitMedia, { + imgDir: './public', + lazyLoad: true, + decoding: 'auto', + aspectRatio: true, + imgSizeHint: true, + }); }, }, vite: { diff --git a/.vitepress/plugins/markdown-fit-media.ts b/.vitepress/plugins/markdown-fit-media.ts new file mode 100644 index 0000000..d9e0441 --- /dev/null +++ b/.vitepress/plugins/markdown-fit-media.ts @@ -0,0 +1,192 @@ +// Modified from https://github.com/ulfschneider/markdown-it-fitmedia +import * as cheerio from 'cheerio'; +import sizeOf from 'image-size'; +import type MarkdownIt from 'markdown-it'; + +interface FitMediaOptions { + imgDir?: string; + imgLazyLoad?: boolean; + imgDecoding?: string; + imgSizeHint?: boolean; + lazyLoad?: boolean; + decoding?: string; + sizeHint?: boolean; + fitElements?: string[]; +} + +interface Dimensions { + width: number; + height: number; +} + +interface Token { + content: string; + attrIndex: (key: string) => number; + attrs: [string, string][]; + attrPush: (attr: [string, string]) => void; +} + +function getDimensions(src: string, fitMediaOptions: FitMediaOptions): Dimensions { + if (fitMediaOptions.imgDir) { + return sizeOf(`${fitMediaOptions.imgDir}${src}`); + } + return sizeOf(src); +} + +function styleAspectRatio(style: string | undefined, width: number, height: number): string { + if (style && !/aspect-ratio/i.test(style)) { + if (!/;\s*$/.test(style)) { + style += '; '; + } + style += `aspect-ratio:${width}/${height};`; + } + else { + style = `aspect-ratio:${width}/${height};`; + } + return style; +} + +function fitHtmlElements(md: MarkdownIt, fitMediaOptions: FitMediaOptions): void { + const blockRenderer = md.renderer.rules.html_block; + const elementRenderer = (tokens: Token[], idx: number): string | undefined => { + try { + const token = tokens[idx]; + const $ = cheerio.load(token.content); + const elements = $(fitMediaOptions.fitElements?.toString() || ''); + + if (elements.length > 0) { + elements.each(function () { + const width = parseInt($(this).attr('width') || '0'); + const height = parseInt($(this).attr('height') || '0'); + if (width > 0 && height > 0) { + let style = $(this).attr('style'); + style = styleAspectRatio(style, width, height); + style += ' width:100%; max-width:100%; height:auto;'; + $(this).attr('style', style); + } + }); + return $('body').html() || undefined; + } + } + catch (error) { + console.error(`Failure when fitting media element ${error}`); + } + }; + + md.renderer.rules.html_block = (tokens: Token[], idx: number, options: any, env: any, self: any): string => { + const html = elementRenderer(tokens, idx); + return html || blockRenderer(tokens, idx, options, env, self); + }; +} + +function fitHtmlImgs(md: MarkdownIt, fitMediaOptions: FitMediaOptions): void { + const inlineRenderer = md.renderer.rules.html_inline; + const blockRenderer = md.renderer.rules.html_block; + const imgRenderer = (tokens: Token[], idx: number): string | undefined => { + try { + const token = tokens[idx]; + const $ = cheerio.load(token.content); + const imgs = $('img'); + if (imgs.length > 0) { + imgs.each(function () { + if (fitMediaOptions.imgLazyLoad) { + $(this).attr('loading', 'lazy'); + } + if (fitMediaOptions.imgDecoding && fitMediaOptions.imgDecoding !== 'auto') { + $(this).attr('decoding', fitMediaOptions.imgDecoding); + } + const src = $(this).attr('src'); + if (src) { + const dimensions = getDimensions(src, fitMediaOptions); + const height = dimensions.height; + const width = dimensions.width; + if (height > 0 && width > 0) { + let style = $(this).attr('style'); + style = styleAspectRatio(style, width, height); + $(this).attr('style', style); + $(this).attr('width', width.toString()); + $(this).attr('height', height.toString()); + } + } + }); + return $('body').html() || undefined; + } + } + catch (error) { + console.error(`Failure when adjusting img ${error}`); + } + }; + + md.renderer.rules.html_inline = (tokens: Token[], idx: number, options: any, env: any, self: any): string => { + const html = imgRenderer(tokens, idx); + return html || inlineRenderer(tokens, idx, options, env, self); + }; + + md.renderer.rules.html_block = (tokens: Token[], idx: number, options: any, env: any, self: any): string => { + const html = imgRenderer(tokens, idx); + return html || blockRenderer(tokens, idx, options, env, self); + }; +} + +function fitMarkdownImgs(md: MarkdownIt, fitMediaOptions: FitMediaOptions): void { + const attr = (token: Token, key: string, value?: string): string | null => { + const idx = token.attrIndex(key); + if (value === undefined) { + return idx >= 0 ? token.attrs[idx][1] : null; + } + else { + if (idx < 0) { + token.attrPush([key, value]); + } + else { + token.attrs[idx][1] = value; + } + return value; + } + }; + + const defaultRender = md.renderer.rules.image; + md.renderer.rules.image = (tokens: Token[], idx: number, options: any, env: any, self: any): string => { + try { + const img = tokens[idx]; + + if (fitMediaOptions.imgLazyLoad) { + attr(img, 'loading', 'lazy'); + } + if (fitMediaOptions.imgDecoding && fitMediaOptions.imgDecoding !== 'auto') { + attr(img, 'decoding', fitMediaOptions.imgDecoding); + } + + const src = attr(img, 'src'); + if (src) { + const dimensions = getDimensions(src, fitMediaOptions); + const height = dimensions.height; + const width = dimensions.width; + if (height > 0 && width > 0) { + let style = attr(img, 'style'); + style = styleAspectRatio(style || '', width, height); + attr(img, 'style', style); + attr(img, 'width', width.toString()); + attr(img, 'height', height.toString()); + } + } + } + catch (error) { + console.error(`Failure when adjusting img ${error}`); + } + + return defaultRender(tokens, idx, options, env, self); + }; +} + +function fitImgs(md: MarkdownIt, fitMediaOptions: FitMediaOptions): void { + fitHtmlImgs(md, fitMediaOptions); + fitMarkdownImgs(md, fitMediaOptions); +} + +function markdownFitMedia(md: MarkdownIt, options: FitMediaOptions): void { + fitImgs(md, options); + fitHtmlElements(md, options); +} + +export { markdownFitMedia }; diff --git a/contribution-guides/contribute-as-developer.md b/contribution-guides/contribute-as-developer.md index 17fe568..5138e5e 100644 --- a/contribution-guides/contribute-as-developer.md +++ b/contribution-guides/contribute-as-developer.md @@ -130,8 +130,13 @@ Hopefully, this situation with CryptoCompare is temporary and they will remove t ## Working with the develop branch The big changes to the code all happen in the `develop` branch. Those might include changes to the schema both in the user database and the global database. Errors related to partially migrated databases might manifest as errors in the UI when executing queries or failures to start the app or sign in. For working on develop instead of the normal `data` rotki directory, we use another in the root path called `develop_data`. + To avoid losing information, we recommend copying your account from `data` to `develop_data` each time you pull new changes in develop, especially if you know that any DB schema changes happened. +:::warning +If your production data in `data` has syncing with Rotki Premium enabled, please ensure that you disable this after copying to `develop_data`, otherwise there is a strong risk of syncing non-production data back to your production environment, and this could cause problems. +::: + ## Adding new Centralized Exchanges (CEXes) All centralized exchanges modules live in a separate python file under [here](https://github.com/rotki/rotki/tree/develop/rotkehlchen/exchanges). diff --git a/package.json b/package.json index fd9af2a..e7c3e7a 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,12 @@ "@types/node": "20.17.9", "@vue/compiler-sfc": "3.5.13", "@vue/runtime-dom": "3.5.13", + "cheerio": "1.0.0", "eslint": "9.16.0", "husky": "9.1.7", + "image-size": "1.1.1", "lint-staged": "15.2.10", + "markdown-it": "14.1.0", "papaparse": "5.4.1", "url": "0.11.4", "vitepress": "1.5.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16b3a53..8bc9ad3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,15 +27,24 @@ importers: '@vue/runtime-dom': specifier: 3.5.13 version: 3.5.13 + cheerio: + specifier: 1.0.0 + version: 1.0.0 eslint: specifier: 9.16.0 version: 9.16.0(jiti@1.21.6) husky: specifier: 9.1.7 version: 9.1.7 + image-size: + specifier: 1.1.1 + version: 1.1.1 lint-staged: specifier: 15.2.10 version: 15.2.10 + markdown-it: + specifier: 14.1.0 + version: 14.1.0 papaparse: specifier: 5.4.1 version: 5.4.1 @@ -944,6 +953,13 @@ packages: character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0: + resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} + engines: {node: '>=18.17'} + ci-info@4.0.0: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} @@ -1000,6 +1016,13 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -1065,6 +1088,9 @@ packages: emoji-regex@10.3.0: resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + encoding-sniffer@0.2.0: + resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + enhanced-resolve@5.17.1: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} @@ -1468,10 +1494,19 @@ packages: engines: {node: '>=18'} hasBin: true + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + image-size@1.1.1: + resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==} + engines: {node: '>=16.x'} + hasBin: true + import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -1484,6 +1519,9 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -1576,6 +1614,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + lint-staged@15.2.10: resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} engines: {node: '>=18.12.0'} @@ -1616,6 +1657,10 @@ packages: mark.js@8.11.1: resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + markdown-table@3.0.3: resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} @@ -1655,6 +1700,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -1862,6 +1910,15 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1940,6 +1997,10 @@ packages: property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -1954,6 +2015,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -2003,6 +2067,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + search-insights@2.15.0: resolution: {integrity: sha512-ch2sPCUDD4sbPQdknVl9ALSi9H7VyoeVbsxznYz6QV55jJ8CI3EtwpO1i84keN4+hF5IeHWIeGvc08530JkVXQ==} @@ -2177,12 +2244,19 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici@6.21.0: + resolution: {integrity: sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==} + engines: {node: '>=18.17'} + unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} @@ -2297,6 +2371,14 @@ packages: typescript: optional: true + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3251,6 +3333,29 @@ snapshots: character-entities@2.0.2: {} + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + encoding-sniffer: 0.2.0 + htmlparser2: 9.1.0 + parse5: 7.2.1 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 6.21.0 + whatwg-mimetype: 4.0.0 + ci-info@4.0.0: {} clean-regexp@1.0.0: @@ -3302,6 +3407,16 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + cssesc@3.0.0: {} csstype@3.1.3: {} @@ -3358,6 +3473,11 @@ snapshots: emoji-regex@10.3.0: {} + encoding-sniffer@0.2.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 @@ -3850,8 +3970,16 @@ snapshots: husky@9.1.7: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + ignore@5.3.2: {} + image-size@1.1.1: + dependencies: + queue: 6.0.2 + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -3861,6 +3989,8 @@ snapshots: indent-string@4.0.0: {} + inherits@2.0.4: {} + is-arrayish@0.2.1: {} is-builtin-module@3.2.1: @@ -3932,6 +4062,10 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + lint-staged@15.2.10: dependencies: chalk: 5.3.0 @@ -3989,6 +4123,15 @@ snapshots: mark.js@8.11.1: {} + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + markdown-table@3.0.3: {} mdast-util-find-and-replace@3.0.1: @@ -4104,6 +4247,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + mdurl@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -4412,6 +4557,19 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.2.1 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.2.1 + + parse5@7.2.1: + dependencies: + entities: 4.5.0 + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -4471,6 +4629,8 @@ snapshots: property-information@6.5.0: {} + punycode.js@2.3.1: {} + punycode@1.4.1: {} punycode@2.3.1: {} @@ -4481,6 +4641,10 @@ snapshots: queue-microtask@1.2.3: {} + queue@6.0.2: + dependencies: + inherits: 2.0.4 + read-pkg-up@7.0.1: dependencies: find-up: 4.1.0 @@ -4549,6 +4713,8 @@ snapshots: dependencies: queue-microtask: 1.2.3 + safer-buffer@2.1.2: {} + search-insights@2.15.0: {} semver@5.7.2: {} @@ -4702,10 +4868,14 @@ snapshots: typescript@5.5.4: {} + uc.micro@2.1.0: {} + ufo@1.5.4: {} undici-types@6.19.8: {} + undici@6.21.0: {} + unist-util-is@6.0.0: dependencies: '@types/unist': 3.0.2 @@ -4852,6 +5022,12 @@ snapshots: optionalDependencies: typescript: 5.5.4 + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + which@2.0.2: dependencies: isexe: 2.0.0 diff --git a/requirement-and-installation/build-from-source.md b/requirement-and-installation/build-from-source.md index 3e9547f..10caa90 100644 --- a/requirement-and-installation/build-from-source.md +++ b/requirement-and-installation/build-from-source.md @@ -1,5 +1,12 @@ # Build from Source +:::warning +Please note that you should not switch between running unreleased code +from git branches and official releases of Rotki on the same [data +set](../usage-guides/data-directory.md), as unreleased code does not +provide guarantees around forward-compatibility of data schemas etc. +::: + ## Prerequisites Before starting, ensure you have the following installed: diff --git a/usage-guides/data-directory.md b/usage-guides/data-directory.md index 71aef01..b55f92e 100644 --- a/usage-guides/data-directory.md +++ b/usage-guides/data-directory.md @@ -9,3 +9,9 @@ rotki saves user data by default in a different directory per OS. For each OS, d Before v1.6.0, rotki was saving data in `$USER/.rotkehlchen`. From v1.6.0, that directory got migrated to the OS equivalent standard directory, and it should be safe for users to delete the old directory as long as the new directory contains the migrated DB. A very good idea for the rotki data directory would be to make frequent backups of it as it contains all of the data of all of your rotki accounts and cache data for historical price queries. + +## Data directory for unreleased development code + +If you are running rotki from unreleased code from git branches, +please note that [the data directory is in a slightly different +location](../contribution-guides/contribute-as-developer.html#working-with-the-develop-branch). diff --git a/usage-guides/index.md b/usage-guides/index.md index da9ef54..c4f6558 100644 --- a/usage-guides/index.md +++ b/usage-guides/index.md @@ -94,6 +94,10 @@ To back up your data on the rotki Server: If you use multiple accounts/devices, the one with the most recent login will upload the latest data to the rotki Server. Using the same account from another device may prompt you to replace your local database with the remote one. +:::warning +Do not run rotki on multiple accounts/devices at the same time, as this opens up the risk of several issues relating to data consistency. +::: + ![Replace local database with remote backup](/images/rotki_premium_replace_local_db_with_remote.png) ### Manually Move Global Database