How to add Multiple public folders in remix.run - remix

I am currently trying to build a electron app using Remix. Thanks to this great setup here https://github.com/itsMapleLeaf/remix-electron.
My requirements is as follows.
When the user uploads an asset, I store it inside a folder xyz in the app path. For mac is /Users/xyz/Application Support/app-folder/assets. I need to show these assets as image tags in electron view. But it fails to locate these files as the public folder is set to /build/. I tried using the file:/// protocol with absolute path but that didn't work as well.
The above repo has a config to set the public folder and that works, but then app stops working as it expects to find JS assets in /build/ folder. And I am not able to dynamically set the "publicPath" value in remix.config.js.
The solution I am looking for, is to have two public folders. 1. default /build/ folder and another one from app location. So remix can serve assets from both paths.
Any help is highly appreciated.
Thank you.

You'll need to update the remix-electron source.
In main.ts, you'll see where it gets all the asset files. You can include your other folders here. Note this is done at initialization, so any dynamically added files won't be included later. You'll need to export a function that lets you add to the asset files.
let [assetFiles] = await Promise.all([
collectAssetFiles(publicFolder),
collectAssetFiles(otherPublicFolder), // add additional folders
app.whenReady(),
])
https://github.com/itsMapleLeaf/remix-electron/blob/20352cc20f976bed03ffd20354c2d011e5ebed64/src/main.ts#L55-L58
Another option is to update the serveAsset function. This is called on every request with the path. You can then check your list of public folders for the asset. This will pickup any new files added.
export async function serveAsset(
request: Electron.ProtocolRequest,
files: AssetFile[],
): Promise<Electron.ProtocolResponse | undefined> {
const url = new URL(request.url)
// TODO: try different folders for list of files to check
const file = files.find((file) => file.path === url.pathname)
if (!file) return
return {
data: await file.content(),
mimeType: mime.getType(file.path) ?? undefined,
}
}
https://github.com/itsMapleLeaf/remix-electron/blob/20352cc20f976bed03ffd20354c2d011e5ebed64/src/asset-files.ts#L24-L37

Related

VSCode extension - access timeline tab

Is there a way for a VSCode extension to access the timeline tab? I searched the docs but I couldn't find anything?
To be more specific, I'd like to watch for changes in certain files and get the diff of that change. I managed to register a listener on file changes, but I also want the actual change. This is what I have so far:
const vscode = require("vscode");
function activate(context) {
const workspacePath = vscode.workspace.workspaceFolders[0];
const watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(workspacePath, "**/package.json")
);
watcher.onDidChange((e) => {
console.log(e); # this only prints the file path, not the content.
}
}
module.exports = {activate};
There is no Timeline API available yet. There is however, a proposed API being discussed for a while (https://github.com/microsoft/vscode/issues/84297), but the last comment is one year old.
But, if you need to detect file changes (not necessarily the file being edited by the user, but any file in the workspace) and compare its content, you need not only the FileSystemWatcher but also some lib that provides you text differencing algorithm, like jsdiff.
Hope this helps

How to avoid performing a firebase function on folders on cloud storage events

I'm trying to organize assets(images) into folders with a unique id for each asset, the reason being that each asset will have multiple formats (thumbnails, and formats optimized for web and different viewports).
So for every asset that I upload to the folder assets-temp/ is then moved and renamed by the functions into assets/{unique-id}/original{extension}.
example: assets-temp/my-awesome-image.jpg should become assets/489023840984/original.jpg.
note: I also keep track of the files with their original name in the DB and in the original's file metadata.
The issue: The function runs and performs what I want, but it also adds a folder named assets/{uuid}/original/ with nothing in it...
The function:
exports.process_new_assets = functions.storage.object().onFinalize(async (object) => {
// Run this function only for files uploaded to the "assets-temp/" folder.
if (!object.name.startsWith('assets-temp/')) return null;
const file = bucket.file(object.name);
const fileExt = path.extname(object.name);
const destination = bucket.file(`assets/${id}/original${fileExt}`);
const metadata = {
id,
name: object.name.split('/').pop()
};
// Move the file to the new location.
return file.move(destination, {metadata});
});
I am guessing that this might happen if the operation of uploading the original image triggers two separate events: one that creates the directory assets-temp and one that creates the file assets-temp/my-awesome-image.jpg.
If I guessed right, the first operation will trigger your function with a directory object (named "assets-temp/"). This matches your first if, so the code will proceed and do
destination = bucket.file('assets/${id}/original') // fileExt being empty
and then call file.move - this will create assets/id/original/ directory.
Simply improve your 'if' to exclude a file named "assets-temp/".
According to the documentation there is no such thing as folders in cloud storage, however, it is possible to emulate them, like you can do by using the console GUI. When creating folders what really happens is that an empty object is created(zero bytes of space) but its name ends with a forward slash, also folder names can end with _$folder$ but it is my understanding that that is how things worked in older versions so for newer buckets the forward slash is enough.

Where is my Electron App located

I have an electron app, that also operates on files in the same directory. These are not files the user selects, or files bundled inside the electron application, but I do need to reference them
for example:
/Users/test/Documents/myapp.app
/Users/test/Documents/example.zip
I need to know where that application is located, e.g.:
/Users/test/Documents
But instead when test.app is ran I get:
/Users/test/Documents/myapp.app/Contents/Resources/app/
Resulting in errors when it tries to access /Users/test/Documents/myapp.app/Contents/Resources/app/test.zip, or if I use a relative path, /test.zip.
How would I reliably access example.zip in this scenario? Note that I cannot bundle it with my app, it's being placed there by somebody else, so moving it is not an option, and it's a file I'm expecting to be there.
A friend and I looked up how Atom does it and arrived at this solution:
function getAppRoot() {
if ( process.platform === 'win32' ) {
return path.join( app.getAppPath(), '/../../../' );
} else {
return path.join( app.getAppPath(), '/../../../../' );
}
}
I think either app.getPath('exe') or process.execPath is what you are looking for. They both give you the path of the currently used executable.
Edit: Look at the docs for app.getPath() to get the paths of all the different folder (e.g. home, appdata, documents, etc.)
Where are you running the Electron App? If it is running under 'Documents' (I am assuming Windows), you can pass in the documents to app.getPath like so: app.getPath('documents').
If you are calling this from the render process, you might have to import remote and do the following if you are in a render process remote.app.getPath('documents');.
This electron doc will be better at explaining the path options you can pass in.
You can use the fs.readdir function to list all the files that are in a particular directory (could be your app's or anywhere). You can make a directory from the code to put all the new files so it would be easier for you to list them out properly to process.
const testFolder = './tests/';
const fs = require('fs');
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
console.log(file);
});
});
How do you get a list of the names of all files present in a directory in Node.js?

How to get local file system path in azure websites

I have a file hosted on the disk along with my website that I want to read .Not sure how do I access the file when I use System.Environment.CurrentDirectory it point to a D drive location .Can someone please tell me how can I get to my file stored at the root of where my site is hosted.
Thanks
There is an environment variable called HOME in your website's environment that will get you part way there.
You can access it using razor syntax or in code (C#). For example, suppose you have a file called data.txt that is at the root of your site with the default document and the rest of your files. You could get it's full path like this.
#{ var dataFileName = Environment.GetEnvironmentVariable("HOME").ToString() + "\\site\\wwwroot\\data.txt"; }
You can find this out on your own using the Site Control Management/"Kudu". For example, if your website is contoso.azurewebsites.net, then simply navigate to contoso.scm.azurewebsites.net. In here you can learn all about the file system and environment variables available to your website.
For testability, I use below code.
string path = "";
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HOME")))
path = Environment.GetEnvironmentVariable("HOME") + "\\site\\wwwroot\\bin";
else
path = ".";
path += "\\Resources\\myfile.json";
In above example, I added myfile.json file to Resources folder in a project with Content and Copy if newer property setting.
This works for me in both localhost and azure:
Path.Combine(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath, "file_at_root.txt");
System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath is the full local path to your site's root.
I'm currently using AppDomain.CurrentDomain.BaseDirectory (.NET Core project). It returns "D:\home\site\wwwroot\" in Azure and the application root in local so the only difference is adding "bin\\" when it is Azure. I am searching the entire directory tree, just in case, but it can be trimmed.
It's something like:
private static string GetDriverPath(ILogger logger, string fileName)
{
var path = AppDomain.CurrentDomain.BaseDirectory;
if (File.Exists(Path.Combine(path, fileName)))
{
return path;
}
string[] paths= Directory.GetFiles(path, fileName, SearchOption.AllDirectories);
if (paths.Any())
{
return Path.GetDirectoryName(paths.First());
}
throw new FileNotFoundException($"{fileName} was not found in {path}.", fileName);
}
I'm new answering questions and this is an old one but I hope it helps someone.
You can do it using the below code.
string fullFilePath = Environment.GetEnvironmentVariable("HOME") != null
? Environment.GetEnvironmentVariable("HOME") + #"\site\wwwroot\test.txt" //It will give the file directory path post azure deployment
: Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())) + #"\test.txt";//It will give the file directory path in dev environment.

How can I count the files inside a folder of project solution?

I want to develop a windows phone based application in which I need to put the number of files in a folder (this folder is already a part of the project) to a list so that at run time I can access those files. If anybody can give me idea of how to do that then it will be great help.
In normal WPF applications we can write code like
DirectoryInfo di = new DirectoryInfo("D:\\Tempo");
FileInfo[] fi = di.GetFiles("*", SearchOption.AllDirectories);
MessageBox.Show(fi.Length.ToString());
But Windows phone inside solution how do I do that?
I can get a single file access by this code
if (Application.GetResourceStream(new Uri("/WindowsPhone;component/Folder/file09.jpg", UriKind.Relative)) != null)
{
MessageBox.Show("Hi");
}
But inside that folder there are many files and I want to put them into list so at run time I can access those images. But the user won't be knowing about that so it should be a C# code, not a XAML code. Any help would be great.
It's pretty easy.
Make sure you add the specific folder to the Solution. Along with any files you want in that folder.
Make sure each file's Properties are set like so:
Build Action: Content
Copy to Output Directory: Do not copy
Make sure the application had loaded before calling
Lets say I had a folder called "Testfiles" and I want to read from it then:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
ReadAllFilesFromFolder("Testfiles");
}
// TODO: recursion to get subfolders and files (maybe?)
public async void ReadAllFilesFromFolder(string folder_name)
{
var package = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assetsFolder = await package.GetFolderAsync(folder_name);
foreach (var file in await assetsFolder.GetFilesAsync())
{
// TODO: whatever you want to do with file
// string filename = file.Name;
}
}

Resources