Lua: make module system - module

I want to create a program which will have several modules in different folders. Main program will determine which module need to load and will load it. Beside it will load some core functions too.
I created prototype of this logic and it works good.
But since I'm new in Lua, I'm not sure what went right way to implement this.
For now I have next structure of files:
aoc (main program):
aoc = {}
aoc_base_path = debug.getinfo(1).source:match("#(.*)/.*$") -- base path to my program
if not aoc_base_path then
aoc_base_path = ''
else
aoc_base_path = aoc_base_path..'/'
end
local aoc_base_arg={...}
dofile(aoc_base_path.."core/core")
local module = assert(loadfile(aoc_base_path.."modules/"..aoc_base_arg[1].."/module"))
local arg = table.copy(aoc_base_arg) -- this is my custom function (I'm not provide you with listing, it just copy one table to another one
table.remove(arg,1)
module(arg,aoc) -- pass to module all arguments except first one
core/core (core functions loader):
dofile (aoc_base_path..'core/move')
core/move:
local function move(direction, refuel, dig, attack)
-- some logic in local function (to not be overwriten in module)
end
function aoc.move()
-- global function (it logic can be changed by module in case it needed)
return move()
end
modules/mine/module (module):
local arg={...} -- I passed 2 arguments in aoc main program
arg = arg[1]
local aoc = arg[2]
aoc.move()
For now
lua> aoc mine
or
lua> path/to/aoc mine
work OK. But can anyone point me if I doing something wrong?
EDIT: changed logic with getting aoc_base_path

You can simplify aoc a bit:
aoc = {}
aoc_base_path = debug.getinfo(1).source:match("#(.*/)") or ''
dofile(aoc_base_path.."core/core")
local module = assert(loadfile(aoc_base_path.."modules/".. ... .."/module"))
module({select(2,...)},aoc)

Just use Lua's library built-in module functionality with require. With proper set-up of package.loaders you can configure this standard system to load modules from wherever you want and in any manner you want. Specific directories, directly from HTTP, delivered by pigeons according to RFC 1149 - it can do it all.

To keep your directory structure more or less the same but make use of the lua package system you could use an approach like this:
In your base path have a file aoc.lua:
local aoc = {}
local module = ...
local dir = module:gsub("%.","%/"):sub(1,-4)
package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path
return aoc
In /core have a file init.lua that requires the core packages that you want to include
require"core.move"
Then your core packages will look something like:
local function move(direction, refuel, dig, attack)
-- some logic in local function (to not be overwriten in module)
end
require"aoc".move = move
In /modules you can then make things a bit simpler by having a lua file for each module so /modules/mine.lua would look like:
local aoc = require"aoc"
aoc.move()
Then at the lua prompt you'd write:
lua> require"path.to.aoc"
lua> require"core" --load up the core modules
lua> require"mine" -- load mine
Edit
If you want to maintain identically the same style, change aoc.lua to be just return {} and add a file aoc as follows:
local dir = debug.getinfo(1).source:match("#(.*)/.*$") -- base path to my program
if not dir then dir = ''
else dir = dir..'/'
end
package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path
require"core"
for _,mod in ipairs{...} do
require(mod)
end
I would suggest that the advantage of this approach is that all of the mangling is in one file, aoc in this case, and the rest of the file structure is using fairly standard lua package conventions.

Related

Vue. How to pass a variable I have on server (process.env.SERVER) to the browser

On the frontend server I have a file I can read with:
if(!!process.env.SERVER) {
require("dotenv").config( { path: '/hw/.env', debug: true } )
console.log(process.env.myvar)
}
But how can I pass the vlue of process.env.myvar to the browser?
Thanks.
If you want to get some variables for all cases you can create an enviroment file with just .env as the name next to package.json in your project.
To get variables from that file you need to declare them first in the .env like this:
VUE_APP_MYVAR = 'myvar'
In your app you can use it like this:
process.env.VUE_APP_MYVAR
If you need some variables depending on the process, respectively for your enviroment, your myvar can't be called with process.env.SERVER. If SERVER is the process, you need a .env.server file next to your package.json.
You can then, again, declare myvar in .env.server like this:
VUE_APP_MYVAR = 'myvar'
To get process.env.VUE_APP_MYVAR this time you have to ensure, that you build or serve your enviroment named server. Else, your app trying to get process.env.VUE_APP_MYVAR with the process you used.
For Example: If you have .env.development and .env.server, both can contain VUE_APP_MYVAR = 'myvar' with different assigned values. Which one is picked depends on the enviroment you build or serve.
For more information, see the docs: Modes and Environment Variables
#Modes

can karate read files from outside the classpath with a relative path instead of absolute path

I'm trying to read a properties file for karate-config.js. It works when i provide the absolute path from my local but when i provide a relative path. it doesn't work. Any way around this? Thanks !
var config = karate.read("file:/repo/tests/utils/al_dev.json"); -- This doesn't work
var config = karate.read("file:~/repo/tests/utils/al_dev.json"); -- This doesn't work
var config = karate.read("file:/Users/user1/IdeaProjects/repo/tests/utils/al_dev.json"); -- This works
I was able to get it working. I had to update the path to reflect the project structure and it worked.
var config = karate.read("file:../../utils/al_dev.json");
Project structure:
project1 ->
tests ->
Utils ->
Services ->
client 1 ->
client 2 ->
I took advantage of answer wrote by Peter Thomas and it worked for me, I could read a json body from a file somewhere else in the project, not needed to be in the same folder as features. This is a sample of code I used:
Scenario: POST with json file reading from anywhere.
Given path "/api/apitesting/v1/transactions"
And def projectPath = karate.properties['user.home']
And def filePath = projectPath + "/IdeaProjects/01 Courses TM/karate/src/test/resources/data/TestBodyAnywhere.json"
And def requestBody = read('file:' + filePath)
And request requestBody
When method post
Then status 201
As you can see, I used user.home instead of user.dir, (which use to be recommended but this points directly to the same folder where you are calling it instead of pointing to outside that folder). User.home points directly to your root user, so it would be something like this C:/Users/MyUser. Then, from there you can start indicating the relative path in a new variable to your file. Finally, remember to use 'File:' keyword inside the read method and concatenate it with your path variable.
Hope it helps. ;)
Best regards!
Sorry, Karate (Java) can't resolve these special OS paths. I guess you know that this is not recommended, best practice is all test resources be kept under the project root. Anyway, here is a workaround:
* def home = java.lang.System.getProperty('user.home')
* def temp = read('file:' + home + '/repo/tests/utils/al_dev.json')

Add compiler flag only if --default-library=shared is used

The meson build system allows to either build shared or static libraries with the option --default-library. However I am not able to know if a shared or static library is being built and I need that to pass at least a define. Is there a way to query the library type?
This was my guess:
libtype = get_option('default-library')
if libtype = 'shared'
build_dll = ['-DBUILDING_DLL', '-fvisibility=hidden']
else
build_dll = ''
endif
But apparently I get:
Meson encountered an error in file meson.build, line 10, column 0:
Tried to access unknown option "default-library".
In case someone else has this issue, the solution is simple:
libtype = get_option('default_library')
(note the underscore instead of the dash)
(Credit for the answer goes to jpakkane (the creator of meson), who answered on IRC)

Copy an image carrierwave

I have ArtworkUploader and i want to create a duplicate of the artwork image in same directory. Help me to solve this.
My Uploader:
class ArtworkUploader < CarrierWave::Uploader::Base
def store_dir
if model
"uploads/#{model.class.to_s.underscore}/#{model.id}/#{mounted_as}"
end
end
def filename
"artwork.png"
end
end
I tried with console but it doesn't work. What am i missing here?
Console:
> u = User.find(5)
> u.artwork.create(name: "testing.png", file: u.artwork.path)
> NoMethodError: undefined method `create!' for /uploads/5/artwork/Artwork:ArtworkUploader
there are 2 way I can think of you can do that
a) VIA Versioning :
create version of your file
version: copy_file do
process :create_a_copy
end
and now just define create_a_copy method inside your uploader which will just return the same file
This way you can have the copy of the file .I didn't understand your custom filename stuff but the way you have define it your for uploader filename method you can do that the same for version as well something like this
version: copy_file do
process :create_a_copy
def filename
"testing.png"
end
end
NOTE:
Not sure of the filename stuff for version file since I done it long back, but I believe the above setting of different filename method would work.
Adavantage :
All File and copy are associated in one uploader
No extra column is required on database (which is required in approach b)
Now the above approach too have some caveats in it
Slightly more complex
Single delete issue, delete to original uploader would delete its copy as well
b) VIA Separate Column :
They other way you can achieve that is defining a separate column called artwork_copy and mount the same uploader with just a slightly change in your uploader like this
def filename
if self.mounted_as == :artwork
"artwork.png"
else
"testing.png"
end
end
And the way you attach the file (give that your file is stored in locally)
u = User.find(5)
u.artwork_copy = File.open(u.artwork) ## Just cross check
u.save
There is an another way you do this via do the above same
u = User.find(5)
u.artwork_copy.store!(File.open(u.artwork))
Now you it pretty obvious what the advantage/disadvantage of the approach b mention above
Hope this make sense

How to set image path for fckeditor?

I am using fckeditor for PHP. I have set an absolute path for image uploading. I can upload images, but I am unable to use images that were uploaded. Can anyone help me find my problem?
Here is the code I have changed in my config.php file:
// Path to user files relative to the document root.
$Config['UserFilesPath'] = '/userfiles/' ;
// Fill the following value it you prefer to specify the absolute path for the
// user files directory. Useful if you are using a virtual directory, symbolic
// link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
// Attention: The above 'UserFilesPath' must point to the same directory.
$Config['UserFilesAbsolutePath'] = '/var/www/host/mysite//userfiles/' ;
I just solved this frustrating problem after a full day of searching on Google.
The solution is here. Look for:
Returning Full URLs
You can configure the File Browser to return full URLs to FCKeditor, like "http://www.example.com/userfiles/", instead of absolute URLs, like "/userfiles/". To do that, you must configure the connector, combining the UserFilesPath and UserFilesAbsolutePath settings:
UserFilesPath: include here the full URL for the user files directory. For example, set it to "http://www.example.com/userfiles/".
UserFilesAbsolutePath: include here the server path to reach the above URL directory. For example, in a Windows environment, you could have something like "C:/inetpub/mysite/userfiles/", while on Linux, something like "/usr/me/public_html/mysite/userfiles/".
Just adjust the above settings to your installation values and the File Browser will start returning full URLs to the editor.
For your localhost :
$Config['UserFilesPath'] = 'http://localhost/mywebsite/userfiles/' ;
$Config['UserFilesAbsolutePath'] = 'C:\\wamp\www\\mywebsite\\userfiles\\' ;
and in order to get your images from there, use :
$path = 'http://localhost/mywebsite/userfiles/image/myimage.jpg';
Now, For your web server:
$Config['UserFilesPath'] = 'http://localhost/mywebsite/userfiles/' ; // if your webserver named localhost as mine
$Config['UserFilesAbsolutePath'] = '/var/www/vhosts/mywebsite.com/httpdocs/' ;
and the images path remains the same as above.
Check the permission of the folder
Full Subject: FCK editor 2.x: File/image/video upload in different folders for different applications using a single FCKeditor, by making $Config['UserFilesPath'] fully dynamic in a secure way
It can be done in many ways. I am explaining a process, which I applied as per my php applications' code structure. The same code structure/framework I followed for different applications, with each application as a sub-folder in my server. So, there is a logical need to use one single FCKeditor and configure it in some way, so that it work properly for all the applications. The content part of FCKeditor is ok. It can easily be reused by different applications or projects from a single FCKeditor component. But the problem arises with file upload, like image, video or any other document. To make it applicable for different project, the files must be uploaded in separe folders for different projects. And for that $Config['UserFilesPath'] must by configured with dynamic folder path, means different folder path for each project, but calling the the same FCKeditor component in the same location. I am explaning some differnt process together in a step-by-step way. Those worked for me fine with FCKeditor version 2.5.1 and VersionBuild 17566 and I hope they will work for others as well. If it does not work for other developrs, then may be they need to make some tweaks in those process as per their project code structure and folder write permission as well as per the FCKeditor version.
1) In fckeditor\editor\filemanager\connectors\phpconfig.php file
a) Go after global $Config ; and $Config['Enabled'] = false ;
i) There, if want a session dependent secure method: only for single site setting: i.e. one FCKeditor for each one project domain or subdomain, not one FCKeditor for multiple project then place this code:
if(!isset($_SESSION)){
session_start();
}
if(isset($_SESSION['SESSION_SERVER_RELATIVEPATH']) && $_SESSION['SESSION_SERVER_RELATIVEPATH']!="") {
$relative_path=$_SESSION['SESSION_SERVER_RELATIVEPATH'];
include_once($_SERVER['DOCUMENT_ROOT'].$relative_path."configurations/configuration.php");
}
N.B.: Here, $_SESSION['SESSION_SERVER_RELATIVEPATH']: relative folder path of the project corresponding to the webroot; should be like "/project/folder/path/" and set this session variable in a common file in your project where the session started. And there should be a configurations/configuration.php as the configuration file in your project. If it's name or path is different you have to place the corresponding path here instead of configurations/configuration.php
ii) If want to use a single FCKeditor component for different projects represented as different sub-folders and with a session dependent secure way (Assuming different session_name for different projects, to differentiate their sessions in a single server). But it will not work if projects represented as sub-domains or different domains, then have to use the session independent way (iii) provided bellow (though it is insecure). Place this code:
if(!isset($_SESSION)){
session_name($_REQUEST['param_project_to_fck']);
session_start();
}
if(isset($_SESSION['SESSION_SERVER_RELATIVEPATH']) && $_SESSION['SESSION_SERVER_RELATIVEPATH']!="") {
$relative_path=$_SESSION['SESSION_SERVER_RELATIVEPATH'];
include_once($_SERVER['DOCUMENT_ROOT'].$relative_path."configurations/configuration.php");
}
Please read N.B. at the end of previous point, i.e. point (i)
iii) If want to use a single FCKeditor component for different projects represented either different sub-folders as well as sub-domains or domains (though it is not fully secure). Place this code:
if(isset($_REQUEST['param_project_to_fck']) && $_REQUEST['param_project_to_fck']!=""){ //base64 encoded relative folder path of the project corresponding to the webroot; should be like "/project/folder/path/" before encoding
$relative_path=base64_decode($_REQUEST['param_project_to_fck']);
include_once($_SERVER['DOCUMENT_ROOT'].$relative_path."configurations/configuration.php");
}
Please read N.B. at the end of point (i)
b)Now after that for any case you selected, please find this code:
// Path to user files relative to the document root.
$Config['UserFilesPath'] = '/userfiles/' ;
and replace the following code:
if(isset($SERVER_RELATIVEPATH) && $SERVER_RELATIVEPATH==$relative_path) { //to make it relatively secure so that hackers can not create any upload folder automatcally in the server, using a direct link and can not upload files there
$Config['Enabled'] = true ;
$file_upload_relative_path=$SERVER_RELATIVEPATH;
}else{
$Config['Enabled'] = false ;
exit();
}
// Path to user files relative to the document root.
//$Config['UserFilesPath'] = '/userfiles/' ;
//$Config['UserFilesPath'] = $file_upload_relative_path.'userfiles/' ;
$Config['UserFilesPath'] = '/userfiles'.$file_upload_relative_path;
Here $SERVER_RELATIVEPATH is the relative path and it must be set in your project's configuration file included previously.
Here you can set the $Config['UserFilesPath'] with any other dynamic folder path using $file_upload_relative_path variable.In my bluehost linux server, as their was a folder user permission conflict between the project root folder (0755 permission) and the userfiles folder under it and subfolders under userfiles (should be 0777 as per FCKeditor coding), so it does not allow uploading files in those folders. So, I created a folder userfiles at the server webroot (beyond the project root folder), and set the permission to 0777 to it, use the code for the $config setting as :
$Config['UserFilesPath'] = '/userfiles'.$file_upload_relative_path;
But, if you have no problem with write permission in the project's subfolders in your case, then you can use the previous line (commented out in the previous code segment):
$Config['UserFilesPath'] = $file_upload_relative_path.'userfiles/' ;
Mind it, you mast comment out the existing $Config['UserFilesPath'] = '/userfiles/' ; in this file by either replacing or simply commenting out if it exist in other place of the file.
2) If you choose 1) (a) (ii) or (iii) method then open
(a) fckeditor\editor\filemanager\browser\default\browser.html file.
Search for this line: var sConnUrl = GetUrlParam( 'Connector' ) ;
Put these commands after that line:
var param_project_to_fck = GetUrlParam( 'param_project_to_fck' ) ;
Now, Search for this line: sUrl += '&CurrentFolder=' + encodeURIComponent( this.CurrentFolder ) ;
Put this command after that line:
sUrl += '&param_project_to_fck=' + param_project_to_fck ;
(b) Now, open ckeditor\editor\filemanager\browser\default\frmupload.html file.
Search for this line (it should be in the SetCurrentFolder() function):
sUrl += '&CurrentFolder=' + encodeURIComponent( folderPath ) ;
Put this command after that line:
sUrl += '&param_project_to_fck='+window.parent.param_project_to_fck;
3) Now where you want to show the FCKeditor in your project, you have to put those lines first in the corresponding php file/page:
include_once(Absolute/Folder/path/for/FCKeditor/."fckeditor/fckeditor.php") ;
$oFCKeditor = new FCKeditor(Field_name_for_editor_content_area) ;
$oFCKeditor->BasePath = http_full_path_for_FCKeditor_location.'fckeditor/' ;
$oFCKeditor->Height = 400;
$oFCKeditor->Width = 600;
$oFCKeditor->Value =Your_desired_content_to_show_in_editor;
$oFCKeditor->Create() ;
a) Now, if you choose 1) (a) (ii) or (iii) method then place the following code segment before that line: $oFCKeditor->Create() ;
$oFCKeditor->Config["LinkBrowserURL"] = ($oFCKeditor->BasePath)."editor/filemanager/browser/default/browser.html?Connector=../../connectors/php/connector.php&param_project_to_fck=".base64_encode($SERVER_RELATIVEPATH);
$oFCKeditor->Config["ImageBrowserURL"] = ($oFCKeditor->BasePath)."editor/filemanager/browser/default/browser.html?Type=Image&Connector=../../connectors/php/connector.php&param_project_to_fck=".base64_encode($SERVER_RELATIVEPATH);
$oFCKeditor->Config["FlashBrowserURL"] = ($oFCKeditor->BasePath)."editor/filemanager/browser/default/browser.html?Type=Flash&Connector=../../connectors/php/connector.php&param_project_to_fck=".base64_encode($SERVER_RELATIVEPATH);
b) if you chose 1) (a) (ii) method, then in the above code code segment, just replace all the texts: base64_encode($SERVER_RELATIVEPATH) with this one: base64_encode(session_name())
And you are done.
UserFilesPath: include here the full URL for the user files directory. For example, set it to "http://www.example.com/userfiles/".