Trouble importing LESS files among different domains - less

Warning: The explanation may be a bit long. In case you are in a hurry, just skip directly to the end of the question, where I summarise what I'm looking for based in my problem.
Here is the problem: I have to load a LESS file (from domain A) from another LESS file (from domain B), and build them on real time with LESS.js. Until then, no harm; the instructions in the start of the official website work out of the box.
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js" ></script>
However, there are other LESS files inside B (let's say module1/less, module2/less, and so on), and A should contain the #imports to those files. Also, there are multiple other domains similar to B (C, D, E...). That's where the problem starts. I couldn't find a proper way to do that, considering that I can't update C, D and E (other people need to do it, and for bureaucracy reasons they will only be able to do it after me), only A and B, so A needs to be compatible with the older version of C, D and E (in case they need any change).
When doing an #import inside an imported LESS file, its relative path is according to that same LESS file path, but since that LESS file may be loaded from B, C, D or E, I can't provide an absolute path out of the box.
What I tried (1): I surely need to find a way to provide the domain name from B to A. Firstly, I tried by adding something like that before the less.min.js line in the B domain HTML file:
<script>
less = {plugins: [{
install: function(less, pluginManager, functions) {
functions.add('getRootLessFolder', function() {
var getDomain = function() {
return window.location.protocol + "//" + window.location.host + "/";
}
return getDomain() + "less/";
});
}
}]}
</script>
And then adding that to the start of B's main LESS file:
#root-less-folder: getRootLessFolder();
So I could update the #imports in A to be like that:
#import "#{root-less-folder}module1/less";
That approach worked... until I tried using it with the older version of B, before making the changes mentioned above. In that way, LESS claims that #root-less-folder is undefined, even if I add (optional) to the #import.
What I tried (2): I also tried to use the paths property in server B, like that:
var getDomain = function() {
return window.location.protocol + "//" + window.location.host + "/";
}
var lessFolder = getDomain() + "less/";
less = {paths:[lessFolder]};
Because according to the documentation:
lessc --include-path=PATH1;PATH2 { paths: ['PATH1', 'PATH2'] }
If the file in an #import rule does not exist at that exact location, Less will look for it at the location(s) passed to this option. You might use this for instance to specify a path to a library which you want to be referenced simply and relatively in the Less files.
So I figured I could use it to make less find the LESS files automatically by just using the line below in A:
#import (optional) "module1/less";
So it wouldn't find module1/less in server A, but would find it in server B because of the paths property. Although, it doesn't seem to try to find module1/less in B. Instead, the Chrome Console spills the 404 error from server A, and the contents of module1/less from B are not present in the produced CSS style (no Console error either), like if it don't even tried.
What I need: I need a way to make method 1 or 2 work under those conditions, or even a method 3.
Being able to populate a LESS variable (if it is not populated only) would solve method 1;
Figuring out how LESS's paths is supposed to work may help using method 2;
Although, maybe you have another suggestion to that problem, which could work out as well.

I've managed to solve my problem. In case anyone else is having this trouble, I will describe what I did: apparently, while you can't reference variables that weren't defined, you can reference plugins that were not defined (in those cases, they are identified as strings).
So I added that before the less.min.js line in the B domain HTML file:
<script>
less = {plugins: [{
install: function(less, pluginManager, functions) {
functions.add('getRootLessFolder', function() {
var getDomain = function() {
return window.location.protocol + "//" + window.location.host + "/";
}
return getDomain() + "less/";
});
}
}]}
</script>
And updated the #imports in A to be like that:
#root-less-folder: getRootLessFolder();
#import (optional) "#{root-less-folder}module1/less";
So when getRootLessFolder is defined, the path is based in its returned value, and when it isn't, the path is "getRootLessFolder()module1/less", which will return a 404, but since it's an optional #import, that won't be a problem.
So if server B is updated, the change in server A is going to work. In case server B is not updated, the change is server A won't break it either.

Related

Cab Dafny use an imported ADT in a match command

Hi I am running into time out problems and am trying to decompose my file into different modules on the hope that a verified module will not have to be reverified, in VS code, when working on a module that imports it.
If any one knows if this is a reasonable way to avoid time out problems I would like to hear.
But the more basic problem I found is that once I import an ADT I can make use of in in if statements but not in match statements. See code below for an example. Any ideas on what I am doing wrong?
module inner {
datatype Twee = Node(value : int, left : Twee, right : Twee) | Leaf
function rot(t:Twee) :Twee
{
match t
case Leaf => t
case Node(v,l,r) => Node(v,r,l)
}
}
module outer {
import TL = inner
function workingIf(t:TL.Twee) :TL.Twee
{ if (t == TL.Leaf) then TL.Leaf else t }
function failingMatch(t:TL.Twee) :TL.Twee
{
match t
case TL.Leaf => t // error "darrow expected"
case TL.Node(v,l,r) => TL.Node(v,r,l)
}
}
Sorry for asking the question - the following worked.
function failingMatch(t:TL.Twee) :TL.Twee
{
match t
case Leaf => t
case Node(v,l,r) => TL.Node(v,r,l)
}
Well that worked but the following failed
function rotateLeft(t:TL.Twee) :TL.Twee
{
match t
case Leaf => t
case Node(v,Leaf,r) => TL.Node(v,TL.Leaf,r)
case Node(v,Node(vl,ll,rl),r) => TL.Node(vl,ll,TL.Node(v,rl,r))
}
The answer to the first question was given by James Wilcox and can be found in What are the relationships among imports, includes, and verification in Dafny?
but for convienience I repeat below:
"import has no direct influence on whether the imported module is verified or not. Modules in other files will not be verified unless their file is listed on the command line. Modules in the current file are always verified (whether or not they are imported by anyone)."
The main question I have raised in https://github.com/dafny-lang/dafny/issues/870
Many thanks to everyone - teaching how to use Dafny with out stack overflow would be so much harder.
Somewhat oddly, the constructor names that follow each case keyword are expected to be unqualified. They are looked up in the type of the expression that follows the match. It's quirky that qualified names are not allowed, and this is likely something that will be corrected in the future (I thought there was a Dafny issue on github about this, but I can't find it).

Terraform: How Do I Setup a Resource Based on Configuration

So here is what I want as a module in Pseudo Code:
IF UseCustom, Create AWS Launch Config With One Custom EBS Device and One Generic EBS Device
ELSE Create AWS Launch Config With One Generic EBS Device
I am aware that I can use the 'count' function within a resource to decide whether it is created or not... So I currently have:
resource aws_launch_configuration "basic_launch_config" {
count = var.boolean ? 0 : 1
blah
}
resource aws_launch_configuration "custom_launch_config" {
count = var.boolean ? 1 : 0
blah
blah
}
Which is great, now it creates the right Launch configuration based on my 'boolean' variable... But in order to then create the AutoScalingGroup using that Launch Configuration, I need the Launch Configuration Name. I know what you're thinking, just output it and grab it, you moron! Well of course I'm outputting it:
output "name" {
description = "The Name of the Default Launch Configuration"
value = aws_launch_configuration.basic_launch_config.*.name
}
output "name" {
description = "The Name of the Custom Launch Configuration"
value = aws_launch_configuration.custom_launch_config.*.name
}
But how the heck do I know from the higher area that I'm calling the module that creates the Launch Configuration and Then the Auto Scaling Group which output to use for passing into the ASG???
Is there a different way to grab the value I want that I'm overlooking? I'm new to Terraform and the whole no real conditional thing is really throwing me for a loop.
Terraform: How to conditionally assign an EBS volume to an ECS Cluster
This seemed to be the cleanest way I could find, using a ternary operator:
output "name {
description = "The Name of the Launch Configuration"
value = "${(var.booleanVar) == 0 ? aws_launch_configuration.default_launch_config.*.name : aws_launch_configuration.custom_launch_config.*.name}
}
Let me know if there is a better way!
You can use the same variable you used to decide which resource to enable to select the appropriate result:
output "name" {
value = var.boolean ? aws_launch_configuration.custom_launch_config[0].name : aws_launch_configuration.basic_launch_config[0].name
}
Another option, which is a little more terse but arguably also a little less clear to a future reader, is to exploit the fact that you will always have one list of zero elements and one list with one elements, like this:
output "name" {
value = concat(
aws_launch_configuration.basic_launch_config[*].name,
aws_launch_configuration.custom_launch_config[*].name,
)[0]
}
Concatenating these two lists will always produce a single-item list due to how the count expressions are written, and so we can use [0] to take that single item and return it.

How to give names to MobX flows

How do I give a name to my flows?
I currently see messages in the console (using dev tools) like:
action '<unnamed flow> - runid: 3 - init'
index.js:1 action '<unnamed flow> - runid: 3 - yield 0'
My code (in typescript):
fetchMetricData = flow( function * (this: MetricDataStore) {
const responseJson:IMetrics[] = yield Http.post("/metrics");
this.metrics = responseJson;
});
According to following text found in MobX Api Reference · MobX page:
Tip: it is recommended to give the generator function a name, this is the name that will show up in dev tools and such
Unfortunately, this is the only way to set the name (I use LiveScript and can't set names to function expressions while defining it).
In your case, you can turn your unnamed function expression into a named one. If you ever face another situation where you can't, you could also use Object.defineProperty(myFunction, 'name', {value: 'myExplicitName'}).
You can find the culprit in the code: mobx/flow.ts at master · mobxjs/mobx.

Karate: How to use a Javascript function from a DIFFERENT feature file

I have created a feature file that will contain lots of javascript functions.
From within a DIFFERENT feature file I want to use ONE of those functions (and pass in a value).
How do I do this please?
My feature file is called SystemSolentraCustomKarateMethods.feature
Here is the current content (it currently contains just one function):
Feature: System Solentra Status Test
Background:
* def checkreturneddatetimeiscorrect =
#The following code compares the passed in datetime with the current systemdatetime and
#makes sure they are within 2 seconds of each other
"""
function(datetime) {
var datenow = new Date();
karate.log("***The Date Now = " + datenow.toISOString() + " ***");
var timenow = datenow.getTime();
karate.log("***The Time Now in Milliseconds = " + timenow+ " ***");
karate.log("***The Passedin Date = " + datetime + " ***");
var passedintime = new Date();
passedintime = Date.parse(datetime);
karate.log("***The Passed in Time = " + passedintime+ " ***");
var difference = timenow - passedintime;
karate.log("***The Time Difference = " + difference + " milliseconds ***");
return (difference < 2000)
}
"""
Thanks Peter I have figured out how to do this now.
(1) The feature file that contains the functions MUST have the Feature, Background and Scenario tags - even if your file does NOT contain any scenarios. (*see my example file below)
(2) In the feature file that you are calling FROM add the following code to the Background section:
* call read('yourfilename.feature')
(3) You can now use the functions within the called feature file
Here is the structure of the feature file I am calling:
Feature: Custom Karate Methods
This feature file contains Custom Karate Methods that can be called and used from other Feature Files
Background:
* def *nameofyourfunction* =
#Comment describing the fuction
"""
function() {
*code*
}
"""
****Scenario: This line is required please do not delete - or the functions cannot be called****
I think you've already seen the answer here, and this question is an exact duplicate: https://stackoverflow.com/a/47002604/143475 (edit: ok, maybe not)
Anyway, I'll repeat what I posted there:
there is no problem when you define multiple functions in one feature and call it from multiple other features
you will anyway need a unique name for each function
when you use call for that feature, all the functions will be available, yes, but if you don't use them, that's okay. if you are worrying about performance and memory, IMHO that is premature optimization
if that does not sound good enough, one way to achieve what you want is to define a Java class Foo with a bunch of static methods. then you can do Foo.myMethodOne(), Foo.myMethodTwo() to your hearts content. I would strongly recommend this approach in your case, because you seem to be expecting an explosion of utility methods, and in my experience, that is better managed in Java, just because you can maintain that code better, IDE support, unit-tests, debugging and all
Hope that makes sense !

How do I get phpFlickr to return the original image?

This code works perfectly:
$f = new phpFlickr(FLICKR_API_KEY, FLICKR_API_SECRET);
$f->setToken(FLICKR_AUTH_TOKEN);
// Next line is just WordPress providing the photoset ID.
$mySetID = get_post_meta($post->ID, 'Flickr set ID', true);
$mySet = $f->photosets_getPhotos($mySetID, NULL, NULL);
foreach ($mySet['photoset']['photo'] as $photo) {
echo '<div><img src="'. $f->buildPhotoURL($photo, 'large') .'" alt="" /></div>';
}
...until buildPhotoURL is told to fetch the "original" size, at which point the URL returned is something like "http://farm6.static.flickr.com/5607/5332878962__o." which is obviously not valid.
While everything I've found through searches seems to agree that doing this requires some "originalsecret" and "originalformat" values that are barely mentioned in Flickr's own documentation, and phpFlickr does seem to try and use them, they're clearly not being fetched by default and I've yet to see someone post code for how to actually provide them. I've tried calling $f->photos_getInfo() just before the echo line, passing in various things to no effect and I'm starting to feel like I'm missing something everyone thinks is obvious, even though nobody has ever produced a valid response(that I can find) to repeated questions about it on the phpFlickr forum.
Note:
This is a Pro account.
We are authenticating properly(these are private sets and they work fine for all other sizes).
Access to the original size in Flickr's privacy settings is set to "Anyone."
Ideas?
I know it's a little late and I'm sure you've figured out the problem by now, but I wanted to share a related answer, because I just spent some time wrestling with a similar issue, and as you said, answers on this subject can't be found anywhere.
To get the information needed to display original size images from a set, the following url should work:
http://api.flickr.com/services/rest/?&method=flickr.photosets.getPhotos&api_key=YOURAPIKEYNUMBER&photoset_id=YOURSETIDNUMBER&per_page=100&sort=date-posted-desc&extras=original_format&format=json&jsoncallback=?
Of course all of the variables are customizable to your needs, but that's just one example which shows the first 100 images in a set sorted descending by date with the original image formatting information attached including the important "original" secret code
To display the images the javascript you can use is
'http://farm' + item.farm + '.static.flickr.com/' + item.server + '/' + item.id + '_' + item.originalsecret + '_' + 'o' + '.' + item.originalformat;
The main sticking point is "&extras=original_format" because that gives you both the originalsecret and originalformat which you need to call an original size image from flickr. I was using the SuperSized background plugin when I ran into the original size problem.
The photosets_getPhotos() method doesn't return the full array for $photo. It returns some basic info about $photo but not $photo['originalformat'], which is needed by buildPhotoURL().
You can tell photosets_getPhotos() to return the original format as an optional extra. This gives buildPhotoURL() everything it needs.
Example:
$mySet = $f->photosets_getPhotos($mySetID, 'original_format', NULL);
foreach ($mySet['photoset']['photo'] as $photo) {
echo '<div><img src="'. $f->buildPhotoURL($photo, 'original') .'" alt="" /></div>';
}
Even better, you can have photosets_getPhotos() return the URL for the original photo itself.
Example:
$mySet = $f->photosets_getPhotos($mySetID, 'url_o', NULL);
foreach ($mySet['photoset']['photo'] as $photo) {
echo '<div><img src="'. $photo['url_o'] .'" alt="" /></div>';
}