You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

699 lines
26 KiB
JavaScript

const { v4: uuidv4 } = require('uuid')
// #tgfusefs:dirData:fileName:fuseData:attributes
const { Airgram, Auth, prompt, toObject } = require( 'airgram' )
const airgram = require('./airgram')
const G_UID = process.getuid ? process.getuid() : 0
const G_GID = process.getgid ? process.getgid() : 0
const FILEMODE = {
RO: 33024,
400: 33024,
444: 33060,
666: 33206,
777: 33279,
PRWRR: 4516, // Pipe
}
const cachePrefix = new Date().valueOf()
airgram.use(new Auth({
code: () => prompt(`Please enter the secret code:\n`),
phoneNumber: () => prompt(`Please enter your phone number:\n`),
password: () => prompt(`Please enter your pw:\n`)
}))
const cacheManager = require('cache-manager')
const CACHE = memoryCache = cacheManager.caching({store: 'memory', max: 100, ttl: 10/*seconds*/});
const virtualPipes = {}
const virtualUploads = {}
const virtualUploadMap = []
//const virtualUploadMapReverse = {}
const fuse = require('node-fuse-bindings')
const mountPath = '/home/user/telegram'
/**
* mkdir /tgfusefstmp
* mount -t tmpfs -o size=1G,nr_inodes=10k,mode=777 tmpfs /tgfusefstmp
*/
const tempMountPath = '/home/user/temp'
const fs = require('fs')
const path = require('path')
async function main() {
const me = toObject(await airgram.api.getMe())
console.log(`[Me] `, me.id)
const chats = toObject(await airgram.api.getChats({
chatList: { _: 'chatListMain' },
limit: 100,
}))
/*let uploadFileRequest = await toObject(airgram.api.sendMessage({
chatId: 777000,
inputMessageContent: {
_: 'inputMessageDocument',
document: { _: 'inputFileLocal', path: '/root/test' },
caption: {
_: 'formattedText',
text: `#tgfusefs💾${ 'test.fifo' }`
}
},
}))
console.log('uploadFileRequest', uploadFileRequest)*/
/*{
file: {
_: 'inputFileGenerated',
originalPath: '',
conversion: '#tgfuse',
expectedSize: 0,
},
fileType: {
_: 'fileTypeDocument'
},
priority: 15,
}*/
console.log('Done')
//process.exit(0)
}
const EventEmitter = require('events');
class TGFileUploadEmitter extends EventEmitter {}
const tgFileUploadEmitter = new TGFileUploadEmitter()
const asyncRedis = require("async-redis")
const client = asyncRedis.createClient()
airgram.on('updateMessageSendAcknowledged', ({ update }) => {
console.log(update)
})
airgram.on('updateMessageSendFailed', ({ update }) => {
console.log(update)
tgFileUploadEmitter.emit(`failed:${ update.oldMessageId }`, update)
})
airgram.on('updateMessageSendSucceeded', ({ update }) => {
//console.log(update)
tgFileUploadEmitter.emit(`finished:${ update.oldMessageId }`, update)
})
airgram.on('uploadFile', ({ update }) => {
console.log(update)
})
const resolveAndCache = (name, resolver, cacheTime=60) => memoryCache.wrap(name, resolver, { ttl: cacheTime })
const sleep = (ms) => new Promise(res => setTimeout(res, ms))
async function getAllFiles(chatId, query, resourceLocator, offset, totalMessages) {
if (!totalMessages) totalMessages = []
console.log(query)
let messages = await resolveAndCache(`files:${ resourceLocator }:${ offset }`, async () => {
await sleep(500)
console.log(`renewing cache entry for "files:${ resourceLocator }:${ offset }", newttl=${ !!offset ? 5 : 10 }`)
return toObject(await airgram.api.searchChatMessages({
chatId,
filter: { _: 'searchMessagesFilterEmpty' },
limit: !!offset ? 100 : 50,
fromMessageId: offset || 0,
query,
})).messages
}, !!offset ? 5 : 10)
let lastMessageID
for (let message of messages) lastMessageID = message.id
totalMessages = totalMessages.concat(messages)
if (!!lastMessageID) {
return await getAllFiles(chatId, query, resourceLocator, lastMessageID, totalMessages)
}
return totalMessages
}
const folder2FilterType = {
'ALL': 'searchMessagesFilterEmpty',
'animation': 'searchMessagesFilterAnimation',
'audio': 'searchMessagesFilterAnimation',
'document': 'searchMessagesFilterDocument',
'photo': 'searchMessagesFilterPhoto',
'video': 'searchMessagesFilterVideo',
'voicenote': 'searchMessagesFilterVoiceNote',
'photoandvideo': 'searchMessagesFilterPhotoAndVideo'
}
function getStatusHTML() {
return '<pre>html test</pre>\n'
}
function getContentSize(content) {
switch (content._) {
case 'messagePhoto': return getContentFileID(content.photo)
case 'photo': return getContentFileID(content.photo.size[content.photo.size.length - 1])
case 'photoSize': return getContentFileID(content.photo)
case 'messageAudio': return getContentSize(content.audio)
case 'audio': return getContentSize(content.audio)
case 'messageDocument': return getContentSize(content.document)
case 'document': return getContentSize(content.document)
case 'messageVideo': return getContentSize(content.video)
case 'video': return getContentSize(content.video)
case 'file': return content.size
}
}
function getContentFileID(content) {
switch (content._) {
case 'messagePhoto': return getContentFileID(content.photo)
case 'photo': return getContentFileID(content.photo.size[content.photo.size.length - 1])
case 'photoSize': return getContentFileID(content.photo)
case 'messageAudio': return getContentFileID(content.audio)
case 'audio': return getContentFileID(content.audio)
case 'messageDocument': return getContentFileID(content.document)
case 'document': return getContentFileID(content.document)
case 'messageVideo': return getContentFileID(content.video)
case 'video': return getContentFileID(content.video)
case 'file': return content.id // getContentFileID(content.remote)
// case 'remoteFile': return content.id
}
}
const chatDirs = {}
async function getDirDataFromChat(chatId) {
//console.log('getDirDataFromChat', chatId)
let indexes = toObject(await airgram.api.searchChatMessages({
chatId,
// filter: { _: 'sea' },
limit: 1,
fromMessageId: 0,
query: `#tgfuseindex`,
})).messages
if (indexes.length === 1) {
chatDirs[chatId] = JSON.parse(indexes[0].content.text.text.split('\n')[1]) || []
} else {
chatDirs[chatId] = []
}
}
async function saveDirDataToChat(chatId) {
//console.log('saveDirDataToChat', chatId)
let indexes = toObject(await airgram.api.searchChatMessages({
chatId,
// filter: { _: 'sea' },
limit: 1,
fromMessageId: 0,
query: `#tgfuseindex`,
})).messages
//console.log('saveDirDataToChat indexes.length', indexes.length)
chatDirs[chatId] = chatDirs[chatId] || []
if (indexes.length > 0) {
let deleteResponse = await airgram.api.deleteMessages({
chatId,
messageIds: indexes.map(x => x.id),
revoke: true,
})
//console.log('deleting old msg', chatId)
}
let newIndexResponse = toObject(await airgram.api.sendMessage({
chatId,
inputMessageContent: {
_: 'inputMessageText',
text: {
_: 'formattedText', text: `#tgfuseindex\n${ JSON.stringify(chatDirs[chatId]) }`
}
},
}))
//console.log('saveDirDataToChat', newIndexResponse)
}
function getDirData(path, notAFileName=false) {
//if (path.split('/').length === 4) return path.split('/')[3]
// const p = require('path').parse(path.split('/').splice(3))
let p = path.split('/').splice(3).map(x => Buffer.from(x).toString('base64')).join('/')
p = p.length === 0 ? '$' : p
console.log('getDirData', path, p)
return p
}
let fdCounter = 0
const FD_RANGE = { REAL: 10, VIRTUAL: 50 }
function getFDHandle(offset) {
fdCounter = (fdCounter + 1) % 30
console.log('[FD HANDLER] next handle is ', fdCounter+ offset )
return fdCounter + offset
}
fuse.mount(mountPath, {
readdir: async (path, cb) => {
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
console.log(deepness, p, p.dir.substring(1).split('/'))
console.log('readdir(%s)', path)
if (path === '/') { // first folder
let chatList = await resolveAndCache('chatList', async () => {
return toObject(await airgram.api.getChats({
offsetOrder: '9223372036854775807',
offsetChatId: 0,
limit: 500
})).chatIds
})
return cb(0, ['status.html'].concat(chatList))
}
// Chat ID Directorys
if (deepness === 1 && path.split('/').length == 2) {
return cb(0, ['title', 'json', 'root'])
}
// Chat FilterType Files Directorys
if (deepness >= 1 && path.split('/').length >= 3 && path.indexOf('root') > 0) {
// console.log('every folder in the chatfolder, listing the files corresponding to the type')
const chatId = parseInt(p.dir.split('/')[1])
await resolveAndCache(`dirIndex:${ chatId }`, async () => await getDirDataFromChat(parseInt(chatId)))
let dirs = chatDirs[chatId] || []
const dirData = getDirData(path, true)
console.log('[VDIR] dirs=', dirs, '| dirData=', dirData)
dirs = dirs.filter(dirName => {
if (dirData === '$') return dirName.indexOf('/') === -1
console.log(dirName, dirName.split('/').length, dirData, dirData.split('/').length)
return dirName.length > dirData.length &&
dirName.indexOf(dirData) === 0 &&
dirName.split('/').length === dirData.split('/').length + 1
})
.map(x => {
x = x.indexOf('/') === -1 ? x : x.split('/')[x.split('/').length - 1]
return Buffer.from(x, 'base64').toString('utf8')
})
let files = await getAllFiles(parseInt(p.dir.substr(1)), `#tgfusefs:${ dirData }${ dirData === '$' ? ':' : ''}`, `${ p.dir }:${ p.base }`)
//console.log(`files:${ p.dir }:${ p.base }`, files)
// files folder folder
console.log('---')
return cb(0, files.map(message => {
// console.log(message.content.caption.text.split(':'))
return Buffer.from(message.content.caption.text.split(':')[2], 'base64').toString('utf8')
}).concat(dirs))
}
return cb(0, [])
},
mkdir: async (path, mode, cb) => {
console.log('mkdir(%s, %d)', path, mode)
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
try {
const chatId = parseInt(p.dir.split('/')[1])
if (deepness >= 1 && path.split('/').length > 3 && path.indexOf('root') > 0) {
const dirData = getDirData(path, true)
console.log('mkdir', chatId, path, dirData)
chatDirs[chatId] = chatDirs[chatId] || []
if (chatDirs[chatId].indexOf(dirData) < 0) {
chatDirs[chatId].push(dirData)
await saveDirDataToChat(chatId)
await client.set(cachePrefix+'-'+chatId+'-'+dirData, 1)
}
}
return cb(0)
} catch (e) {
console.error(e)
return cb(fuse.ENOENT)
}
},
rmdir: async (path, cb) => {
console.log('rmdir(%s)', path)
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
try {
const chatId = parseInt(p.dir.split('/')[1])
if (deepness >= 1 && path.split('/').length > 3 && path.indexOf('root') > 0) {
const dirData = getDirData(path, true)
console.log('rmdir', chatId, path, dirData)
chatDirs[chatId] = chatDirs[chatId] || []
if (chatDirs[chatId].indexOf(dirData) > -1) {
chatDirs[chatId].splice(chatDirs[chatId].indexOf(dirData), 1)
await saveDirDataToChat(chatId)
await client.set(chatId+'-'+dirData, 0)
}
}
return cb(0)
} catch (e) {
console.error(e)
return cb(fuse.ENOENT)
}
},
getattr: async (path, cb) => {
if (!!virtualPipes[path]) {
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1, mode: FILEMODE[666], // fifo pipe
size: 10,
})
}
if (path === '/status.html') {
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1, mode: FILEMODE[444],
size: getStatusHTML().length,
})
}
try {
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
const chatId = parseInt(p.dir.split('/')[1])
console.log('getattr(%s)', path, deepness, path.split('/').length, 'chatId=' + chatId)
if (!!chatId && chatId > 0) {
await resolveAndCache(`dirIndex:${ chatId }`, async () => await getDirDataFromChat(chatId))
const dirData = getDirData(path, true)
console.log ('VDIR DATA SEARCHED', dirData, chatDirs[chatId] || [])
let existInCache = false
try {
existInCache = await client.get(cachePrefix+'-'+chatId+'-'+dirData) == 1
console.log('existInCache', existInCache)
} catch (e) { }
if (existInCache || (chatDirs[chatId] || []).indexOf(dirData) > -1 ) {
console.log('[VDIR] emulating', path, existInCache, (chatDirs[chatId] || []).indexOf(dirData))
console.log('---')
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1,
size: 0,
mode: 16877, // dir
})
}
}
if (deepness === 1 && p.name === 'title' && p.ext === '') {
let title = await resolveAndCache(`title:${ p.dir }`, async () => toObject(await airgram.api.getChat({
chatId: parseInt(p.dir.substr(1)),
})).title)
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1, mode: FILEMODE[444], // readonly file
size: title.length + 1, // + 1 for nullbyte
})
}
if (deepness === 1 && p.name === 'json' && p.ext === '') {
let json = await resolveAndCache(`json:${ p.dir }`, async () => JSON.stringify(toObject(await airgram.api.getChat({
chatId: parseInt(p.dir.substr(1)),
})), null, '\t'))
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1, mode: FILEMODE[444], // readonly file
size: json.length + 1, // + 1 for nullbyte
})
}
// every folder in the chatfolder, its size = amount of files in there
if (deepness === 1 && path.split('/').length == 3 && p.base === 'root') {
console.log('every folder in the chatfolder, its size = amount of files in there')
/*if (p.base === 'files') return cb(0, { mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID, nlink: 1, mode: 16877, size: 0, })
let fileTypeCount = await resolveAndCache(`count:${ p.dir }:${ p.base }`, async () => toObject(await airgram.api.getChatMessageCount({
chatId: parseInt(p.dir.substr(1)),
filter: { _: 'searchMessagesFilterEmpty' },
returnLocal: false
})).count, 5)
console.log(`count:${ p.dir }:${ p.base }`, fileTypeCount)
*/
// files folder folder
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1, mode: 16877, // dir
size: 0,
})
}
if (deepness === 1) { // first folder
return cb(0, {
mtime: new Date(), atime: new Date(), ctime: new Date(), uid: G_UID, gid: G_GID,
nlink: 1,
size: 0,
mode: 16877, // dir
})
}
// show file stats for specific file in type dir
if (deepness >= 2 && path.split('/').length >= 4 && p.dir.split('/')[2] === 'root') {
const dirData = getDirData(path)
console.log('dirData', dirData)
//let files = await getAllFiles(parseInt(p.dir.substr(1)), folder2FilterType[ p.base ], `${ p.dir }:${ p.base }`)
let getattr = await resolveAndCache(`getattr:${ path }`, async () => {
const query = `#tgfusefs:${ dirData }:${ Buffer.from(p.base).toString('base64') }:`
console.log ('searching for ===' + query)
return toObject(await airgram.api.searchChatMessages({
chatId,
// filter: { _: 'sea' },
limit: 1,
fromMessageId: 0,
query,
})).messages[0]
}, 15)
if (!getattr) { console.log('no file found, ', path); return cb(fuse.ENOENT) }
console.log('---', getattr.id)
return cb(0, {
mtime: new Date(getattr.date*1e3), atime: new Date(getattr.date*1e3), ctime: new Date(getattr.date*1e3), uid: G_UID, gid: G_GID,
nlink: 1, mode: FILEMODE[666], // file
size: getContentSize(getattr.content),
})
}
// else anything
console.log('nothing is matching for readdir')
return cb(fuse.ENOENT)
} catch (e) {
console.error(e)
return cb(fuse.ENOENT)
}
},
open: async (path, flags, cb) => {
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
console.log('open(%s, %d)', path, flags)
if (!!virtualPipes[path]) return cb(0, getFDHandle(FD_RANGE.VIRTUAL)) // virtual file handles are from 50-79
if (deepness === 1 && p.name === 'title' && p.ext === '') return cb(0, 1)
if (deepness === 1 && p.name === 'json' && p.ext === '') return cb(0, 2)
if (path === '/status.html') return cb(0, 4)
cb(0, getFDHandle(FD_RANGE.REAL)) // real file handles are from 10-39
},
read: async (path, fd, buf, len, pos, cb) => {
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
console.log('read(%s, %d, %d, %d)', path, fd, len, pos)
//console.log(p, deepness)
if (fd === 1 && deepness === 1 && p.name === 'title' && p.ext === '') {
let title = await resolveAndCache(`title:${ p.dir }`, async () => toObject(await airgram.api.getChat({
chatId: parseInt(p.dir.substr(1)),
})).title)
let str = title.slice(pos, pos + len)
if (!str) return cb(0)
buf.write(str)
return cb(str.length)
}
if (fd === 2 && deepness === 1 && p.name === 'json' && p.ext === '') {
let json = await resolveAndCache(`json:${ p.dir }`, async () => JSON.stringify(toObject(await airgram.api.getChat({
chatId: parseInt(p.dir.substr(1)),
})), null, '\t'))
let str = json.slice(pos, pos + len)
if (!str) return cb(0)
buf.write(str)
return cb(str.length)
}
if (fd >= FD_RANGE.VIRTUAL && !!virtualPipes[path]) {
}
if (fd === 4) {
let str = getStatusHTML().slice(pos, pos + len)
if (!str) return cb(0)
buf.write(str)
return cb(str.length)
}
if (fd >= FD_RANGE.REAL && deepness >= 2 && path.split('/').length >= 4 && p.dir.split('/')[2] === 'root') {
// show file stats for specific file in type dir
//let files = await getAllFiles(parseInt(p.dir.substr(1)), folder2FilterType[ p.base ], `${ p.dir }:${ p.base }`)
let getattr = await resolveAndCache(`getattr:${ path }`, async () => toObject(await airgram.api.searchChatMessages({
chatId: parseInt(p.dir.substr(1)),
// filter: { _: 'searchMessagesFilterEmpty' },
limit: 1,
fromMessageId: 0,
query: `#tgfusefs:${ getDirData(p.dir) }:${ Buffer.from(p.base).toString('base64') }`,
})).messages[0], 15)
let fileId = getContentFileID(getattr.content)
let downloadRequest = toObject(await airgram.api.downloadFile({
fileId, priority: 30, offset: pos, limit: len, synchronous: true
}))
return fs.open(downloadRequest.local.path, 'r', function(err, fd) {
// /----- where to start writing at in `buffer`
fs.readSync(fd, buf, 0, len, pos)
// \------- where to read from in the file given by `fd`
return cb(buf.length)
})
}
let str = '< Empty >\n'.slice(pos, pos + len)
if (!str) return cb(0)
buf.write(str)
return cb(str.length)
},
release: async (path, fd, cb) => {
console.log('release(%s, %d)', path, fd)
if (!!virtualPipes[path]) {
const virtualPipe = virtualPipes[path]
console.log(virtualPipes[path])
fs.closeSync(virtualPipes[path].fd)
const b64Name = Buffer.from(require('path').parse(virtualPipe.tempTargetFile).base).toString('base64')
let uploadFileRequest = toObject(await airgram.api.sendMessage({
chatId: 777000,
inputMessageContent: {
_: 'inputMessageDocument',
document: { _: 'inputFileLocal', path: virtualPipe.tempTargetFile },
caption: {
_: 'formattedText', text: `#tgfusefs:${ getDirData(virtualPipe.targetPath) }:${ b64Name }:fuseData:attributes`
}
},
}))
console.log('uploadFileRequest', uploadFileRequest.sendingState)
try {
//console.log(clipJSON)
tgCloud = await new Promise((res, rej) => {
tgFileUploadEmitter.removeAllListeners()
tgFileUploadEmitter.once(`finished:${ uploadFileRequest.id }`, res)
tgFileUploadEmitter.once(`failed:${ uploadFileRequest.id }`, rej)
})
// console.log('upload emitter', tgCloud)
} catch (e) {
console.error(e)
return cb(fuse.ENOENT)
}
fs.unlinkSync(virtualPipes[path].tempTargetFile)
// uploadFile
delete virtualPipes[path]
return cb(0)
}
return cb(0)
},
unlink: async (path, cb) => {
try {
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
console.log('unlink(%s)', path)
if (deepness === 2 && path.split('/').length == 4 && p.dir.split('/')[2] === 'root') {
let unlink = await resolveAndCache(`unlink:${ path }`, async () => toObject(await airgram.api.searchChatMessages({
chatId: parseInt(p.dir.substr(1)),
filter: { _: folder2FilterType[ p.dir.split('/')[2] ] },
limit: 1,
fromMessageId: 0,
query: `#tgfusefs💾${ Buffer.from(p.base).toString('base64') }`,
})).messages[0], 15)
let deleteResponse = await airgram.api.deleteMessages({
chatId: parseInt(p.dir.substr(1)),
messageIds: [ unlink.id ],
revoke: true,
})
return cb(0)
}
} catch (e) {
return cb(fuse.ENOENT)
}
return cb(fuse.ENOENT)
},
rename: async (src, dest, cb) => {
console.log('rename(%s, %s)', src, dest)
return cb(fuse.ENOENT)
},
/*
if (deepness === 2 && path.split('/').length == 4 && ['ALL', 'animation', 'audio', 'document', 'photo', 'video', 'voicenote', 'photoandvideo'].indexOf(p.dir.split('/')[2]) > - 1) {
let rename = await resolveAndCache(`rename:${ path }`, async () => toObject(await airgram.api.searchChatMessages({
chatId: parseInt(p.dir.substr(1)),
filter: { _: folder2FilterType[ p.dir.split('/')[2] ] },
limit: 1,
fromMessageId: 0,
query: `#tgfusefs💾${ p.base }`,
})).messages[0], 15)
let deleteREsponse = await airgram.api.deleteMessages({
chatId: parseInt(p.dir.substr(1)),
messageIds: [ rename.id ],
revoke: true,
})
return cb(0)
}
return cb(fuse.ENOENT)
},*/
create: async (path, mode, cb) => {
const p = require('path').parse(path),
deepness = p.dir.substring(1).split('/').length
console.log('create(%s, %d)', path, mode)
if (deepness >= 2 && path.split('/').length >= 4 && p.dir.split('/')[2] === 'root') {
//createdFiles[path] = true
let cUUID = uuidv4()
const tempTargetFile = require('path').join(tempMountPath, path)
const mkdirp = require('mkdirp')
await mkdirp(require('path').parse(tempTargetFile).dir)
console.log('tempTargetFile', tempTargetFile)
if (fs.existsSync(tempTargetFile)) fs.unlinkSync(tempTargetFile)
return fs.open(tempTargetFile, 'wx', (err, fd) => {
if (err) return console.error(err, cb(fuse.ENOENT))
virtualUploads[cUUID] = path
virtualPipes[path] = {
path,
targetPath: path,
mode,
cUUID,
size: 0,
tempTargetFile,
fd
}
let virtFd = virtualUploadMap.push(path)
return cb(0, virtFd)
})
/*
let uploadFileRequest = await toObject(airgram.api.sendMessage({
chatId: 777000,
inputMessageContent: {
_: 'inputMessageDocument',
document: { _: 'inputFileLocal', expectedSize: 0, originalPath },
caption: {
_: 'formattedText',
text: `#tgfusefs💾${ p.base }`
}
},
}))
let virtFd = virtualUploadMap.push(fifoPath)
return cb(0, virtFd)
console.log('uploadFileRequest', uploadFileRequest)
*/
/*
return tgFileUploadEmitter.once('genStartCB'+cUUID, (genId) => {
//virtualUploadMapReverse[genId] = mapIndex
console.log('file gen created', `genid=${ genId } | virtFd=${ virtFd }`)
cb(0, virtFd)
})*/
//tgFileUploadEmitter.once('genStartFail'+cUUID, () => cb(fuse.ENOENT))
// return cb(0, 123)
}
return cb(fuse.ENOENT)
},
write: async (path, fd, buffer, length, position, cb) => {
// console.log('write(%s, %d, buffer, %d, %d)', path, fd, length, position)
// console.log('writing', buffer.slice(0, length))
try {
const bytesWritten = fs.writeSync(virtualPipes[path].fd, buffer, 0, buffer.length, position)
return cb(bytesWritten)
} catch (e) {
console.error(e)
return cb(fuse.ENOENT)
}
},
}, (err) => {
if (err) throw err
console.log('filesystem mounted on ' + mountPath)
})
process.on('SIGINT', function () {
fuse.unmount(mountPath, function (err) {
if (err) {
console.log('filesystem at ' + mountPath + ' not unmounted', err)
} else {
console.log('filesystem at ' + mountPath + ' unmounted')
}
})
})
console.log(new Date())
main()