Repository navigation
Update index.html based on whether meta-tag is set or not #953
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
09a4753
c4dc018
17717aa
627b1fe
beeeab7
34e403d
988ee0f
abbdbab
7090ee0
3b25fda
7a8230e
3989aa8
16688d4
24a9a58
bfdb2ce
bf9a59e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| const fs = require('fs-extra') | ||
| const { cyan, bold } = require('colorette') | ||
| const { URL } = require('url') | ||
| const LDP = require('../../lib/ldp') | ||
| const AccountManager = require('../../lib/models/account-manager') | ||
| const SolidHost = require('../../lib/models/solid-host') | ||
|
|
||
| module.exports.getAccountManager = getAccountManager | ||
| module.exports.loadAccounts = loadAccounts | ||
| module.exports.loadConfig = loadConfig | ||
| module.exports.loadUsernames = loadUsernames | ||
|
|
||
| /** | ||
| * Returns an instance of AccountManager | ||
| * | ||
| * @param {Object} config | ||
| * @param {Object} [options] | ||
| * @returns {AccountManager} | ||
| */ | ||
| function getAccountManager (config, options = {}) { | ||
| const ldp = options.ldp || new LDP(config) | ||
| const host = options.host || SolidHost.from({ port: config.port, serverUri: config.serverUri }) | ||
| return AccountManager.from({ | ||
| host, | ||
| store: ldp, | ||
| multiuser: config.multiuser | ||
| }) | ||
| } | ||
|
|
||
| function loadConfig (program, options) { | ||
| let argv = { | ||
| ...options, | ||
| version: program.version() | ||
| } | ||
| let configFile = argv['configFile'] || './config.json' | ||
|
|
||
| try { | ||
| const file = fs.readFileSync(configFile) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm. Given that I imagine accessing files from another user on the same pod. So some sanitation would need to happen...
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The user that provides this input is the server admin, so they can do way worse 😉 |
||
|
|
||
| // Use flags with priority over config file | ||
| const config = JSON.parse(file) | ||
| argv = { ...config, ...argv } | ||
| } catch (err) { | ||
| // No file exists, not a problem | ||
| console.log(cyan(bold('TIP')), 'create a config.json: `$ solid init`') | ||
| } | ||
|
|
||
| return argv | ||
| } | ||
|
|
||
| /** | ||
| * | ||
| * @param root | ||
| * @param [serverUri] If not set, hostname must be set | ||
| * @param [hostname] If not set, serverUri must be set | ||
| * @returns {*} | ||
| */ | ||
| function loadAccounts ({ root, serverUri, hostname }) { | ||
| const files = fs.readdirSync(root) | ||
| hostname = hostname || new URL(serverUri).hostname | ||
| const isUserDirectory = new RegExp(`.${hostname}$`) | ||
| return files | ||
| .filter(file => isUserDirectory.test(file)) | ||
| } | ||
|
|
||
| function loadUsernames ({ root, serverUri }) { | ||
| const hostname = new URL(serverUri).hostname | ||
| return loadAccounts({ root, hostname }) | ||
| .map(userDirectory => userDirectory.substr(0, userDirectory.length - hostname.length - 1)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the right hand side comes up again and again, maybe it's time for aa helper function to make it more speaking.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this coming up again and again? |
||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| const fs = require('fs') | ||
| const path = require('path') | ||
| const cheerio = require('cheerio') | ||
| const LDP = require('../../lib/ldp') | ||
| const { URL } = require('url') | ||
| const debug = require('../../lib/debug') | ||
| const { readFile } = require('../../lib/common/fs-utils') | ||
|
|
||
| const { compileTemplate, writeTemplate } = require('../../lib/common/template-utils') | ||
| const { loadConfig, loadAccounts } = require('./cli-utils') | ||
| const { getName, getWebId } = require('../../lib/common/user-utils') | ||
| const { initConfigDir, initTemplateDirs } = require('../../lib/server-config') | ||
|
|
||
| module.exports = function (program) { | ||
| program | ||
| .command('updateindex') | ||
| .description('Update index.html in root of all PODs that haven\'t been marked otherwise') | ||
| .action(async (options) => { | ||
| const config = loadConfig(program, options) | ||
| const configPath = initConfigDir(config) | ||
| const templates = initTemplateDirs(configPath) | ||
| const indexTemplatePath = path.join(templates.account, 'index.html') | ||
| const indexTemplate = await compileTemplate(indexTemplatePath) | ||
| const ldp = new LDP(config) | ||
| const accounts = loadAccounts(config) | ||
| const usersProcessed = accounts.map(async account => { | ||
| const accountDirectory = path.join(config.root, account) | ||
| const indexFilePath = path.join(accountDirectory, '/index.html') | ||
| if (!isUpdateAllowed(indexFilePath)) { | ||
| return | ||
| } | ||
| const accountUrl = getAccountUrl(account, config) | ||
| try { | ||
| const webId = await getWebId(accountDirectory, accountUrl, ldp.suffixMeta, (filePath) => readFile(filePath)) | ||
| const name = await getName(webId, ldp.fetchGraph) | ||
| writeTemplate(indexFilePath, indexTemplate, { name, webId }) | ||
| } catch (err) { | ||
| debug.errors(`Failed to create new index for ${account}: ${JSON.stringify(err, null, 2)}`) | ||
| } | ||
| }) | ||
| await Promise.all(usersProcessed) | ||
| debug.accounts(`Processed ${usersProcessed.length} users`) | ||
| }) | ||
| } | ||
|
|
||
| function getAccountUrl (name, config) { | ||
| const serverUrl = new URL(config.serverUri) | ||
| return `${serverUrl.protocol}//${name}.${serverUrl.host}/` | ||
| } | ||
|
|
||
| function isUpdateAllowed (indexFilePath) { | ||
| const indexSource = fs.readFileSync(indexFilePath, 'utf-8') | ||
| const $ = cheerio.load(indexSource) | ||
| const allowAutomaticUpdateValue = $('meta[name="solid-allow-automatic-updates"]').prop('content') | ||
| return !allowAutomaticUpdateValue || allowAutomaticUpdateValue === 'true' | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,28 @@ | ||
| const $rdf = require('rdflib') | ||
|
|
||
| const SOLID = $rdf.Namespace('http://www.w3.org/ns/solid/terms#') | ||
| const VCARD = $rdf.Namespace('http://www.w3.org/2006/vcard/ns#') | ||
|
|
||
| module.exports.getName = getName | ||
| module.exports.getWebId = getWebId | ||
| module.exports.isValidUsername = isValidUsername | ||
|
|
||
| async function getName (webId, fetchGraph) { | ||
| const graph = await fetchGraph(webId) | ||
| const nameNode = graph.any($rdf.sym(webId), VCARD('fn')) | ||
| return nameNode.value | ||
| } | ||
|
|
||
| async function getWebId (accountDirectory, accountUrl, suffixMeta, fetchData) { | ||
| const metaFilePath = `${accountDirectory}/${suffixMeta}` | ||
| const metaFileUri = `${accountUrl}${suffixMeta}` | ||
| const metaData = await fetchData(metaFilePath) | ||
| const metaGraph = $rdf.graph() | ||
| $rdf.parse(metaData, metaGraph, metaFileUri, 'text/turtle') | ||
| const webIdNode = metaGraph.any(undefined, SOLID('account'), $rdf.sym(accountUrl)) | ||
| return webIdNode.value | ||
| } | ||
|
|
||
| function isValidUsername (username) { | ||
| return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(username) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be rephrased as: