How to use Moment.js in ServiceNow? - momentjs

Our team is trying to use Moment.js in our instance, but can't seem to get it to work. Here are a couple questions we have about it:
We noticed that there is a dependency out of the box called moment-timezone-with-data-2010-2020-v0.5, is this the same as moment.js? If so, does this mean we don't need to bring in moment.js as a new dependency?
We tried using the above ootb dependency AND tried to bring in moment.js to use in a widget, and we keep getting a console error saying that moment is undefined. Can someone provide some instructions on how to correctly get either one of these dependencies to work?
If we wanted to use moment.js on a platform business rule, what do we have to do to make that happen? Are you able to access a dependency via business rule?
Thanks!

Here's how I was able to do it:
Create a Script Include with the following attributes:
script name is "moment" (it needs to have this exact name)
scope is either global or the same scope as your project (I used global)
set as client callable
Paste the code from MomentJS 2.22.1 into the script body.
To verify that you can access your Script Include, open a Background Script and run the following test code:
var calendar = moment().add(1, 'days').calendar();
gs.log("calendar test: " + calendar);
var dayCount = moment().diff('1809-02-12', 'days');
gs.log('Abraham Lincoln was born ' + dayCount + " days ago!");
To answer your question on moment-timezone-with-data-2010-2020-v0.5: no's it's not the same; here's a link to Moment Timezone which is a different library by the same organization.
As of the time of this post, 2.22.1 is the newest version that runs in ServiceNow. There are newer versions of MomentJS, but they're too new for the SN interpreter.
You can also create a UI Script with version 2.22.1.

Load the code for Moment.js into a script include and then you can call that like any other script include.
If you are going to use the timezone functions you would need to rewrite the calls to moment from the timezone javascript to use the above script include.

moment.js
On April 1st, 2022, the most recent version of moment.js to work on SNOW San Diego is 2.22.1:
https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js
Any version > 2.22.1 will give you the following error:
Could not save record because of a compile error: JavaScript parse error at line (1) column (37954) problem = missing name after . operator (<refname>; line 1)
moment-timezone.js
On April 1st, 2022, the most recent version of moment-timezone.js to work in SNOW San Diego is 0.5.28:
https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.28/moment-timezone.min.js
Any version > 0.5.28 will give you the following error:
Could not save record because of a compile error: JavaScript parse error at line (1) column (236) problem = missing name after . operator (<refname>; line 1)

sadly you can not use momentjs on the server side in ServiceNow. Here are the installation instruction for momentjs for Rhino (the javascript interpreter SNOW uses): https://gist.github.com/UnquietCode/5614860
As you can see you would need to write new Java classes which SNOW will not allow you to do.
On the Client on the other hand you can use it, just copy paste the "Browser" implementation and include it as a global ui script: https://momentjs.com/docs/#/use-it/browser/

Related

rpmUtils.miscutils in python3.6

I am refactoring code from python2(RHEL 7.6) to python3(RHEL 8.2) and I have problem with missing library in python3.6.
Problem:
from rpmUtils.miscutils import splitFilename ModuleNotFoundError: No module named 'rpmUtils'
I've tried to install python3-dnf and python3-rpm packages to RHEL8, but still not working. Is there any solution how to use this library in python3.6 and RHEL8 or should I write some custom function by myself?
Thank you for your answer.
This library was indeed removed, but you have several other options you can use.
Please note that these other functions expect to receive a string in the NEVRA (name, epoch, version, release, architecture) format as an input, not a filename. Thus you must remove the '.rpm' extension of the filename, in order to get a NVRA string (epoch normally is not included in the filename of the RPM package).
So basically you have 2 options:
to use dnf as suggested in i.e. https://bugzilla.redhat.com/show_bug.cgi?id=1364504
to use hawkey i.e. :
import hawkey
rpm_base_filename = os.path.basename(rpm_file)
nevra = hawkey.split_nevra(rpm_base_filename[:-len(".rpm")])
name = nevra.name
version = nevra.version
release = str(nevra.release)
epoch = str(nevra.epoch)
arch = nevra.arch
For example here is a patch for such modification that I made for one of the tools we use as part of the oVirt release process:
https://github.com/oVirt/releng-tools/commit/823405e6b261f7ff27ddbba0e8fa2b86dd2a8698

Qt error is printed on the console; how to see where it originates from?

I'm getting this on the console in a QML app:
QFont::setPointSizeF: Point size <= 0 (0.000000), must be greater than 0
The app is not crashing so I can't use the debugger to get a backtrace for the exception. How do I see where the error originates from?
If you know the function the warning occurs in (in this case, QFont::setPointSizeF()), you can put a breakpoint there. Following the stack trace will lead you to the code that calls that function.
If the warning doesn't include the name of the function and you have the source code available, use git grep with part of the warning to get an idea of where it comes from. This approach can be a bit of trial and error, as the code may span more than one line, etc, and so you might have to try different parts of the string.
If the warning doesn't include the name of the function, you don't have the source code available and/or you don't like the previous approach, use the QT_MESSAGE_PATTERN environment variable:
QT_MESSAGE_PATTERN="%{function}: %{message}"
For the full list of variables at your disposal, see the qSetMessagePattern() docs:
%{appname} - QCoreApplication::applicationName()
%{category} - Logging category
%{file} - Path to source file
%{function} - Function
%{line} - Line in source file
%{message} - The actual message
%{pid} - QCoreApplication::applicationPid()
%{threadid} - The system-wide ID of current thread (if it can be obtained)
%{qthreadptr} - A pointer to the current QThread (result of QThread::currentThread())
%{type} - "debug", "warning", "critical" or "fatal"
%{time process} - time of the message, in seconds since the process started (the token "process" is literal)
%{time boot} - the time of the message, in seconds since the system boot if that can be determined (the token "boot" is literal). If the time since boot could not be obtained, the output is indeterminate (see QElapsedTimer::msecsSinceReference()).
%{time [format]} - system time when the message occurred, formatted by passing the format to QDateTime::toString(). If the format is not specified, the format of Qt::ISODate is used.
%{backtrace [depth=N] [separator="..."]} - A backtrace with the number of frames specified by the optional depth parameter (defaults to 5), and separated by the optional separator parameter (defaults to "|"). This expansion is available only on some platforms (currently only platfoms using glibc). Names are only known for exported functions. If you want to see the name of every function in your application, use QMAKE_LFLAGS += -rdynamic. When reading backtraces, take into account that frames might be missing due to inlining or tail call optimization.
On an unrelated note, the %{time [format]} placeholder is quite useful to quickly "profile" code by qDebug()ing before and after it.
I think you can use qInstallMessageHandler (Qt5) or qInstallMsgHandler (Qt4) to specify a callback which will intercept all qDebug() / qInfo() / etc. messages (example code is in the link). Then you can just add a breakpoint in this callback function and get a nice callstack.
Aside from the obvious, searching your code for calls to setPointSize[F], you can try the following depending on your environment (which you didn't disclose):
If you have the debugging symbols of the Qt libs installed and are using a decent debugger, you can set a conditional breakpoint on the first line in QFont::setPointSizeF() with the condition set to pointSize <= 0. Even if conditional breakpoints don't work you should still be able to set one and step through every call until you've found the culprit.
On Linux there's the tool ltrace which displays all calls of a binary into shared libs, and I suppose there's something similar in the M$ VS toolbox. You can grep the output for calls to setPointSize directly, but of course this won't work for calls within the lib itself (which I guess could be the case when it handles the QML internally).

Turbo Pascal BGI Error: Graphics not initialized (use InitGraph)

I'm making a Turbo Pascal 7.0 program for my class, it has to be on Graphic Mode.
A message pops up
BGI Error: Graphics not initialized (use InitGraph).
I'm already using InitGraph and graph.tpu and I specified the route as "C:\TP7\BGI".
My S.O is Windows 7 and I'm using DosBox 0.74, I already tried to paste all the files from the folder BGI into BIN.
What should I do?
Since dos doesn't have system graphic drivers, the BGI functions as such for BP7.
So in short, use a BGI suitable for your videocard. The ones supplied with BP7 are very old, there are newer, VESA ones that you could try.
Afaik 3rd party BGI needs to be registered explicitly in code though.
At first I have had this "missing Graph.tpu"- ... and later the "Use Initgraph"-issue too.
After hours trying (and reading some not politeful comments in the internet) I finally got Turbo Pascal 7 succesfully running (in Windows 10, x64). In summary I want to share "some secrets":
install the "TP(WDB)-7.3.5-Setup.msi" (comes from clever people in Vietnam)
make sure, that there's the CORRECT PATH to the "BGI"-directory in your program-code. For example:
driver := Detect;
InitGraph (driver, modus, 'c:\TPWDB\BGI');
(By the way: This is ALL, what's there to do with "Initgraph".)
make sure, that in TP7 under "Options" --> "Directories" are the CORRECT PATHS both to "C:\TPWDB\UNITS" and Your actual working dir e.g. "C:\TPWDB\myPrograms"
THAT's IT.
Annotations: The "Graph.TPU" (usually) is already in "UNITS" (together with "Graph3.tpu" by the way).
Hazzling around old driver's isn't needed even... :)
Just the correct paths... :)
Hope, that can help ...

Does sbt have something like gradle's processResources task with ReplaceTokens support?

We are moving into Scala/SBT from a Java/Gradle stack. Our gradle builds were leveraging a task called processResources and some Ant filter thing named ReplaceTokens to dynamically replace tokens in a checked-in .properties file without actually changing the .properties file (just changing the output). The gradle task looks like:
processResources {
def whoami = System.getProperty( 'user.name' );
def hostname = InetAddress.getLocalHost().getHostName()
def buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss z')
filter ReplaceTokens, tokens: [
"buildsig.version" : project.version,
"buildsig.classifier" : project.classifier,
"buildsig.timestamp" : buildTimestamp,
"buildsig.user" : whoami,
"buildsig.system" : hostname,
"buildsig.tag" : buildTag
]
}
This task locates all the template files in the src/main/resources directory, performs the requisite substitutions and outputs the results at build/resources/main. In other words it transforms src/main/resources/buildsig.properties from...
buildsig.version=#buildsig.version#
buildsig.classifier=#buildsig.classifier#
buildsig.timestamp=#buildsig.timestamp#
buildsig.user=#buildsig.user#
buildsig.system=#buildsig.system#
buildsig.tag=#buildsig.tag#
...to build/resources/main/buildsig.properties...
buildsig.version=1.6.5
buildsig.classifier=RELEASE
buildsig.timestamp=2013-05-06 09:46:52 PDT
buildsig.user=jenkins
buildsig.system=bobk-mbp.local
buildsig.tag=dev
Which, ultimately, finds its way into the WAR file at WEB-INF/classes/buildsig.properties. This works like a champ to record build specific information in a Properties file which gets loaded from the classpath at runtime.
What do I do in SBT to get something like this done? I'm new to Scala / SBT so please forgive me if this seems a stupid question. At the end of the day what I need is a means of pulling some information from the environment on which I build and placing that information into a properties file that is classpath loadable at runtime. Any insights you can give to help me get this done are greatly appreciated.
The sbt-buildinfo is a good option. The README shows an example of how to define custom mappings and mappings that should run on each compile. In addition to the straightforward addition of normal settings like version shown there, you want a section like this:
buildInfoKeys ++= Seq[BuildInfoKey](
"hostname" -> java.net.InetAddress.getLocalHost().getHostName(),
"whoami" -> System.getProperty("user.name"),
BuildInfoKey.action("buildTimestamp") {
java.text.DateFormat.getDateTimeInstance.format(new java.util.Date())
}
)
Would the following be what you're looking for:
sbt-editsource: An SBT plugin for editing files
sbt-editsource is a text substitution plugin for SBT 0.11.x and
greater. In a way, it’s a poor man’s sed(1), for SBT. It provides the
ability to apply line-by-line substitutions to a source text file,
producing an edited output file. It supports two kinds of edits:
Variable substitution, where ${var} is replaced by a value. sed-like
regular expression substitution.
This is from Community Plugins.

GNAT Programming Suite - source file not found

Ada is still new to me, so I am trying to find my way around the GPS IDE. I asked another question earlier, but I think this problem has precedence over that one, and may be at the root of my trouble.
When I compile, I am getting a long list of *warning: source file ... not found"
In my .gpr file, I have listed all of the spec and body source files and use the following naming scheme:
package Naming is
for Casing use "mixedcase";
for Dot_Replacement use ".";
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
end Naming;
What is odd it the error messages all look either like this:
warning: source file "xxx_b.adb" not found
or this
warning: source file "xxx.adb" not found
Note that neither of these (xxxb.adb or xxx.adb) conform to the file specs, which should end with .ada.
Can someone explain what is going on here?
I'm 99% sure that the problem is one of the ones I mentioned in answer to your other question: GNAT does not normally support more than one compilation unit in a file. I got exactly the behaviour you describe with GPS and these files:
james_s.ada:
with Jane;
package James is
end James;
jim_s.ada:
package Jim is
end Jim;
package Jane is
end Jane;
The error message on compiling james_s.ada says it can't find Jane_s.ada, but when I ask GPS to go to the declaration of Jane it takes me to the "correct" line in jim_s.ada.
You could use gnatchop to split jim_s.ada, but it doesn't understand project files or naming conventions; you probably want to keep the existing names for the code that works, so you'd rename gnatchop's output as required.
However! to my great surprise, it turns out that GNAT does support having more than one compilation unit in a file, provided package Naming in the project file tells it about each unit in the file:
package Naming is
for Casing use "mixedcase";
for Dot_Replacement use ".";
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
for Spec ("Jim") use "jim_s.ada" at 1;
for Spec ("Jane") use "jim_s.ada" at 2;
end Naming;
It's up to you whether to do this or to bite the bullet and use gnatchop, either on the multi-unit files or on the whole source tree.
First off, this isn't an Ada problem, its a Gnat problem. Other Ada compilers have no problem with the file names you are using.
However, Gnat is rather unique in that it expects there to be only one program unit (package body, package spec, stand-alone routine, etc) per source file. This is because it is also rather unique in that it expects to be able to find the source code for any program unit just by knowing that unit's Ada intentifier. Most other Ada compilers maintain some kind of library file that maps file names to program units, and you have to register all your files into it. (Whereas your typcial C compiler just leaves the problem of finding files for all your code up to the user entirely).
Generally the easiest thing to do with Gnat, the way that will cause you the least trouble, is to just use its default file naming convention (and of course don't put multiple program units in a single file.
If you already have some existing Ada code (perhaps developed for another compiler), the easiest way to import it into Gnat is typically to run the gnatchop tool on it all. So that's what I'd suggest you try.
From GPRbuild User's Guide:
Strings are used for values of attributes or as indexes for these attributes. They are in general case sensitive, except when noted otherwise [...]
Based on this, I believe you have to use "Ada" instead of "ada" as index for Spec_Suffix and Body_Suffix. I currently do not have access to the tools for testing this, so I suggest to just try it out.

Resources