Node.js - get last subdirectory in directory by alphabetical search - node.js

Using Node.js, I am looking for a neat way of finding the most recent subdirectory in a directory where the subdirectory happens to be the last one if they are sorted alphabetically/numerically.
All the subdirectories are named by timestamp, like so:
- parent dir
--- 494985839399
--- 232111234483
--- 334433885832
--- 112221994948
... etc
Now I assume when you read a directory and iterate over its contents it's not guaranteed to be sorted by recency or alphabetically?
So, I am looking for a good way to find that subdir besides brute force O(n) search. Unfortunately I will obviously not know the name of the dir, thus making a search or sort necessary.
What's the best way to do this with Node? It can be synchronous or async because this is not for a server.

You can use readdir to get the directories in an array and then sort the array. Like this:
var fs = require('fs');
var result = fs.readdirSync('parentDir').sort().reverse();
var subdir = result[0];
This is not optimised at all (for example, you can make readdir async and make a custom sort function that sorts descending).
In one line:
var result = require('fs').readdirSync('parentDir').sort().reverse()[0];
(I did not test the code)

Related

Get a top level from Path object of pathlib

I use pathlib to match all files recursively to filter the files based on their content. Then I would like to find what is the top level of the folder of this file. Assume the following. I have a file in the folder:
a/b/c/file.log
I do the search from the level a:
for f in path_data.glob("**/*"):
if something inside file f:
# I would like to get in what folder this file is, i.e. 'b'
I now that I can get all parents levels using:
f.parents would give me b/c
f.parent would give me c
f.name would give me file.log
But how could I get b?
Just to precise: the number of levels where the file is stored is not known.
UPD: I know I could do it with split, but I would like to know if there is a proper API to do that. I couldn't find it.
The question was asked a while ago, but didn't quite get the attention. Nevertheless, I still would publish the answer:
f.parts[0]

path.join does not work?

I want to read from a path and I wrote two different codes.The first code does not work but the second code works perfectly. I do not understand the differences. can someone explain to me what is going on? thanks.
the file is stored in /modules/config/
First Code:
var tmpModulePath = path.join('./modules/',"config/");
var moduleConfigInfo = require(tmpModulePath + "_test.js");
Second code:
var tmpModulePath = path.join('./modules/',"config/");
var moduleConfigInfo = require("./" + tmpModulePath + "_test.js");
from the first code, I do get this error: Can not find module ..._tset.csv
If you console.log the generated path you get this results:
First code block:
"modules/config/_test.js"
Second code block:
"./modules/config/_test.js"
In the second case, you have a relative path starting from your current directory (./). require will look for a modules folder starting from your current directory.
In the first case, the path is absolute, meaning that require will look for a modules folder starting from the root path of your filesystem.
I hope you understand the difference now.
What you really want to use in this case is path.resolve:
var tmpModulePath1 = path.resolve('./', 'modules/',"config/", 'test.js');
Check the answer to this question to understand the difference between .join and .resolve.

How do I append array items to a string over a loop in puppet

lets say I have an array with directory names
dirs = ['opt', 'apps', 'apache']
I want to iterate and generate a list of following paths
/opt
/opt/apps
/opt/apps/apache
through which I can create file resource.
Is there a reason you want to iterate through those files like that?
Because the simplest way to turn those into file resources would be this:
$dirs = ['/opt', '/opt/apps', '/opt/apps/apache']
file { $dirs:
ensure => directory,
}
If you just want to make sure that all the preceeding directories are created, there is also the dirtree module, which will do this all for you:
https://forge.puppet.com/pltraining/dirtree
$apache_dir = dirtree('/opt/apps/apache')
# Will return: ['/opt', '/opt/apps', '/opt/apps/apache']
You can then use that variable to create the directories.
As Matt mentions, you can also use maps, or an iterator to create the resources.
Basic example here:
$dirs = ['/opt', '/opt/apps', '/opt/apps/apache']
$dirs.each |String $path| {
file {$path:
ensure => directory,
}
}
Documented here: https://docs.puppet.com/puppet/latest/lang_iteration.html
There are a few different ways to do what you want to do in the code, it depends on how much management you want to do of those resources after creation.

How to read the files concurrently from different folders but in a specific order within each folder?

I want to use apache camel file component.
I have a requirement where there are multiple files in different folders.
I want to read files under those directories in an order (based on timestamp).
Note: All these directories will be the subdirectories of the root.
Eg: root-
/dir1 - file1, file2, file3
/dir2 - file4, file5, file6
What I need here is,
1 thread should read all files in dir1 based on timestamp and other thread should read from dir2.
What I am doing now is,
from("file:/root/?recursive=true&sortBy=file:modified").threads(10).to("another component");
But this is not working the way I wanted, instead it is assigning different threads to different files and so the order of processing is not achieved.
Please let me know how to achieve my requirement.
You need to use a dynamic router to route to different consumers based on the directory the file is in. eg suppose you want three processors running in parallel:
from("file:/root?sortBy=file:modified)
.to("myDynamicRouter")
from("seda:myQueue0")
.to("myProcessor")
from("seda:myQueue1")
.to("myProcessor")
from("seda:myQueue2")
.to("myProcessor")
MyDynamicRouter is a router which will return the name of a SEDA queue based on the directory of the file (see http://camel.apache.org/dynamic-router.html)
eg
public void process(File file) {
String queueName = "seda:MyQueue" + (file.getParent().hashCode() % 3);
return queueName;
}
So all the files will be read from the different directories in date order. When they get put on the various seda queues they will remain in date order. As all files from the same directory are put on the same queue, they will be processed in date order.
One thing to watch is that files from different directories may be interleaved together in the same processor. Without a lot of work and some blocking going that, is just something you'll have to allow for when coding your processor.

How to get full path from relative path

I'm trying to access a page from another domain, I can get all other html from php, but the files like images and audio files have relatives paths making them to be looked inside the local server whereas they're on the other server.
I've allowed cross-domain access though PHP from the other page.
header('Access-Control-Allow-Origin: *');
Then I use AJAX load to load that pages' content.
$('#local_div').load('page_to_load_on_side_B #div_on_that_page');
Now, the path looks like this:
../../user/6/535e55ed00978.jpg
But I want it to be full like.
http//:www.siteB.com/user/6/535e55ed00978.jpg
Correction: I have full access to both sites so I need to get the absolute paths from the site where these files are originating.
For this problem would use one of the following:
Server Side Approach
I would create a parameter in server B named for example abspath. When this param is set to 1 the script would start an output buffer ob_start() then before submiting would get ob contents with ob_get_clean() and finally using regular expressions make a replace of all urls for http//:www.siteB.com/. So, the script on server A would look like follows:
<?php
$abspath=(isset($_REQUEST["abspath"])?$_REQUEST["abspath"]:0);
if($abspath==1) ob_start();
// Do page processing (your actual code here)
if($abspath==1)
{
$html=ob_get_clean();
$html=preg_replace("\.\.\/\.\.\/", "http://siteb.com/");
echo $html;
}
?>
So in client side (site A) your ajax call would be:
$('#local_div').load('page_to_load_on_side_B?abspath=1#div_on_that_page');
So when abspath param is set to 1 site B script would replace relative path (note I guessed all paths as ../..) to absolute path. This approach can be improved a lot.
Client Side Approach
This replace would be done in JavaScript locally avoiding changing Server B scripts, . The replacements in Javascript would be the same. If all relative paths starts with ../.. the regex is very simple, so in site A replace $('#local_div').load('page_to_load_on_side_B #div_on_that_page'); for the following (note that I asume all relatives urls starts with ../..):
$.get('page_to_load_on_side_B #div_on_that_page', function(data) {
data=data.replace(/\.\.\/\.\.\//, 'http://siteb.com/');
$('#local_div').html(data);
});
That will do the replacement before setting html to DIV so images will be loaded from absolute URL.
Ensure full CORS access to site B.
The second approach is clean than the first so I guess would use Javascript to do the replacements, both are the same only changes where the replace is done.
There is a PHP function that can make absolute path from relative one.
realpath()
If you mean URL path, simply replace all occurences of "../" and add domain in front.
Try this one:
function getRelativePath($from, $to)
{
// some compatibility fixes for Windows paths
$from = is_dir($from) ? rtrim($from, '\/') . '/' : $from;
$to = is_dir($to) ? rtrim($to, '\/') . '/' : $to;
$from = str_replace('\\', '/', $from);
$to = str_replace('\\', '/', $to);
$from = explode('/', $from);
$to = explode('/', $to);
$relPath = $to;
foreach($from as $depth => $dir) {
// find first non-matching dir
if($dir === $to[$depth]) {
// ignore this directory
array_shift($relPath);
} else {
// get number of remaining dirs to $from
$remaining = count($from) - $depth;
if($remaining > 1) {
// add traversals up to first matching dir
$padLength = (count($relPath) + $remaining - 1) * -1;
$relPath = array_pad($relPath, $padLength, '..');
break;
} else {
$relPath[0] = './' . $relPath[0];
}
}
}
return implode('/', $relPath);
}
Also you can find below solution:
In general, there are 2 solutions to this problem:
1) Use $_SERVER["DOCUMENT_ROOT"] – We can use this variable to make all our includes relative to the server root directory, instead of the current working directory(script’s directory). Then we would use something like this for all our includes:
include($_SERVER["DOCUMENT_ROOT"] . "/dir/script_name.php");
2) Use dirname(FILE) – The FILE constant contains the full path and filename of the script that it is used in. The function dirname() removes the file name from the path, giving us the absolute path of the directory the file is in regardless of which script included it. Using this gives us the option of using relative paths just as we would with any other language, like C/C++. We would prefix all our relative path like this:
include(dirname(__FILE__) . "/dir/script_name.php");
You may also use basename() together with dirname() to find the included scripts name and not just the name of the currently executing script, like this:
script_name = basename(__FILE__);
I personally prefer the second method over the first one, as it gives me more freedom and a better way to create a modular web application.
Note: Remember that there is a difference between using a backslash “\” and a forward (normal) slash “/” under Unix based systems. If you are testing your application on a windows machine and you use these interchangeably, it will work fine. But once you try to move your script to a Unix server it will cause some problems. Backslashes (“\”) are also used in PHP as in Unix, to indicate that the character that follows is a special character. Therefore, be careful not to use these in your path names.

Resources