How to add comment and spent time in one call to Gitlab API? - api

I have two separate calls
addSpentTime(projectId, issueIid, duration, date) {
const endpoint = this.apiUrl(
`/projects/${projectId}/issues/${issueIid}/notes?body=/spend ${duration} ${date}`
);
return this.ajaxRequest("POST", endpoint);
}
addComment(projectId, issueIid, comment) {
const endpoint = this.apiUrl(
`/projects/${projectId}/issues/${issueIid}/notes?body=${comment}`
);
return this.ajaxRequest("POST", endpoint);
}
The first one is for sending how much time has been spent on an issue and the latter is for adding a comment to the issue.
I'd like to do both of these actions in one call like this
addSpentTimeAndComment(projectId, issueIid, duration, date, comment) {
const endpoint = this.apiUrl(
`/projects/${projectId}/issues/${issueIid}/notes?body=${comment}/spend ${duration} ${date}`
);
return this.ajaxRequest("POST", endpoint);
}
but the suffix /spend ${duration} ${date} makes it into the comment as well. It seems that the API takes literally everything that comes after body= as a part of the comment. I tried to add \n, \\n, spaces, backslashes to signify the end of the comment so that the /spend part gets evaluated as well and I also tried changing the order so that the /spend is before the comment body but nothing seemed to work. The GitLab API docs don't mention any standard way of ending the comment or maybe they do but I can't find it anywhere. Furthermore, I don't even know what it's called - delimiter, escaping symbol...?
Is there a way of signifying the ending of the comment, giving a way of appending other commands?

As part of the comment (project note) call, append the time as a Quick Action using the /spend <time> call.
By posting that to the API with the comment, GitLab will add the time at the same time it adds the comment.

Related

Karate Netty - CallSingle but not so single

What I had till today:
I have get_jwt.feature and I call it as a part of karate-config.js. Since I have used one account test#test.com I needed only one jwt and I can reuse it across scenarios. callSingle worked as a charm in this case.
Today:
Suddenly I have need for jwt's from two accounts which I dont want to generate for each scenario, callSingle falls short of this task as it does exactly what its supposed to be doing. Now I have hacky idea, I can simply make two files, get_jwt.feature and get_jwt_user2.feature, and single call them each.
So my question: Is there a better way of doing this?
You can use "2 levels" of calls. So point the callSingle() to a JS function that calls get_jwt.feature 2 times, maybe with different arguments and then return a JSON. Pseudo-code below. First is get_jwts.js:
function fn(users) {
var jwt1 = karate.call('get_jwt.feature', users.user1);
var jwt2 = karate.call('get_jwt.feature', users.user2);
return { jwt1: jwt1, jwt2: jwt2 };
};
Then in karate-config.js
config.jwts = karate.callSingle('classpath:get_jwts.js', users);
And now you should be able to do this:
* print jwts.jwt1
* print jwts.jwt2
You can also do a feature-->feature call chain. Do let me know if this works !
EDIT: see Babu's answer in the comments, looks like you can pass an array to callSingle() ! so that may be quite convenient :)

Prevent camel-jackson from removing quotation marks

I am working on a camel route for a REST service. My task is to add a POST in which I need to take a token out of the json that is sent. I am doing the following:
.unmarshal().json(JsonLibrary.Jackson, Token.class)
I added the "camel-jackson" dependency to my pom file and it works fine.
Problem: Now all the json coming is has the double quotation marks stripped off. So the following json:
{"name": "John Doe", "job": "farmer"}
Ends up as:
{name:John Doe,job:farmer}
For some of my code I need the double quotes. I have tried to do a bit of configuring my rest route with no luck. Any one have an idea of a fix?
You mention in the comment that you have
restConfiguration()
.component("jetty")
.scheme("https")
.bindingMode(RestBindingMode.auto)
.dataFormatProperty("prettyPrint", "true")
.port(8443);
You don't mention what your route is. However, if you're using bindingMode it will expect a type() on the get()/post() which will be used to unmarshal json into. It sounds like you only want to do this for the new POST you are adding, so why not have the binding on the post() rather than globally on the restConfiguration()?
e.g.
restConfiguration()
.component("jetty")
.scheme("https")
.dataFormatProperty("prettyPrint", "true")
.port(8443);
rest("/words")
.post("/new/post/url")
.bindingMode(RestBindingMode.auto)
.type(YourPojo.class)
...
.get("existing/stuff")
...

How to get the org_id from a webhook?

When a Webhook is triggered, is there a way to get the org_id from which it was fired? (Aside from climbing up the triggered item)
The only solution I found so far is:
PodioItem::get($item_id); to get the space_id
PodioSpace::get($space_id); to get the full
PodioOrganization::get_for_url($attributes = array()); I get the org_id.
See the "Bundling responses using fields parameter" section at the very bottom of https://developers.podio.com/index/api on how you can use the fields query parameter to include more data. There's even an example that goes almost all the way for you (it walks up to the space level, but you can just tack the org onto it):
/item/{item_id}?fields=app.view(full).fields(space.view(full))
For podio-php you can do:
$item = PodioItem::get($item_id, array('fields' => "app.view(full).fields(space.view(full))"));
Use PodioItem::filter instead of PodioItem::get, I'm pretty sure that you'll have the expected results, so try this:
$item = PodioItem::filter($item_id, array('filters' => "app.view(full).fields(space.view(full))"));
Hope it helps!

Resetting a Bacon property on value changed to empty

TL;DR
How can I reset emailProfile/aliasProfile when email/alias is cleared after having a value?
Slightly longer version
I have a form that has inputs for email and alias. Neither is mandatory. But, if you fill in the alias field, it might require the email as well, if the alias is reserved.
So far so good, I have the pipe setup from an empty form, up until checking if an alias is reserved and whether the given email matches up. This works correctly and reliably.
Where my setup falters, is when after filling in a correct e-mail I clear the email. The status of emailProfile remains status quo (last server response).
What I want to achieve, is to clear emailProfile when email has no value (or actually when validEmail is false), but in all other cases return the last server response.
The direct (and only) way to tackle the problem I can think of, would be to drop the filter and return null from the lookup function when validation fails, but there has to be a better way, right?
// Functions that can be assumed to work as they should (they do):
// form.findInput, validAlias,validEmail, compose,
// fetchProfilesByAlias, fetchProfileByEmail
var alias = Bacon.fromEventTarget(form.findInput("alias"), "change").
merge(
Bacon.fromEventTarget(form.findInput("alias"), "keyup")
).
map(".target").
map(".value").
skipDuplicates().
toProperty(form.findInput("alias").value);
var email = Bacon.fromEventTarget(form.findInput("email"), "change").
merge(
Bacon.fromEventTarget(form.findInput("email"), "keyup")
).
map(".target").
map(".value").
skipDuplicates().
toProperty(form.findInput("email").value);
var aliasProfiles = alias.
debounce(600).
filter(validAlias).
flatMapLatest(compose(Bacon.fromPromise.bind(Bacon), fetchProfilesByAlias)).
toProperty(null);
var emailProfile = email.
debounce(600).
filter(validEmail).
flatMapLatest(compose(Bacon.fromPromise.bind(Bacon), fetchProfileByEmail)).
toProperty(null);
This is the most straightforward way I can think of.
var emailProfile = email.
debounce(600).
flatMapLatest(function(email) {
if (validEmail(email)) {
return Bacon.fromPromise(fetchProfileByEmail(email))
} else {
return null
}
}).
toProperty(null)
Pretty much the same that you already discovered, except the if is not in the lookup function :)

Check if an existing value is in a database

I was wondering how I would go about checking to see if a table contains a value in a certain column.
I need to check if the column 'e-mail' contains an e-mail someone is trying to register with, and if something exists, do nothing, however, if nothing exists, insert the data into the database.
All I need to do is check if the e-mail column contains the value the user is registering with.
I'm using the RedBeanPHP ORM, I can do this without using it but I need to use that for program guidelines.
I've tried finding them but if they don't exist it returns an error within the redbean PHP file. Here's the error:Fatal error: Call to a member function find() on a non-object in /home/aeterna/www/user/rb.php on line 2433
Here's the code that I'm using when trying this:
function searchDatabase($email) {
return R::findOne('users', 'email LIKE "' . $email . '"');
}
My approach on the function would be
function searchDatabase($email) {
$data = array('email' => $email);
$user = R::findOne('users', 'email LIKE :email, $data);
if (!empty($user)) {
// do stuff here
} // end if
} // end function
It's a bit more clean and in your function
Seems like you are not connected to a database.
Have you done R::setup() before R::find()?
RedBeanPHP raises this error if it can't find the R::$redbean instance, the facade static functions just route calls to the $redbean object (to hide all object oriented fuzzyness for people who dont like that sort of thing).
However you need to bootstrap the facade using R::setup(). Normally you can start using RB with just two lines:
require('rb.php'); //cant make this any simpler :(
R::setup(); //this could be done in rb.php but people would not like that ;)
//and then go...
R::find( ... );
I recommend to check whether the $redbean object is available or whether for some reason the code flow has skipped the R::setup() boostrap method.
Edited to account for your updated question:
According to the error message, the error is happening inside the function find() in rb.php on line 2433. I'm guessing that rb.php is the RedBean package.
Make sure you've included rb.php in your script and set up your database, according to the instructions in the RedBean Manual.
As a starting point, look at what it's trying to do on line 2433 in rb.php. It appears to be calling a method on an invalid object. Figure out where that object is being created and why it's invalid. Maybe the find function was supplied with bad parameters.
Feel free to update your question by pasting the entirety of the find() function in rb.php and please indicate which line is 2433. If the function is too lengthy, you can paste it on a site like pastebin.com and link to it from here.
Your error sounds like you haven't done R::setup() yet.
My approach to performing the check you want would be something like this:
$count = count(R::find('users', 'email LIKE :email', array(':email' => $email)));
if($count === 0)
{
$user = R::dispense('users');
$user->name = $name;
$user->email = $email;
$user->dob = $dob;
R::store($user);
}
I don't know if it is this basic or not, but with SQL (using PHP for variables), a query could look like
$lookup = 'customerID';
$result = mysql_fetch_array(mysql_query("SELECT columnName IN tableName WHERE id='".$lookup."' LIMIT 1"));
$exists = is_null($result['columnName'])?false:true;
If you're just trying to find a single value in a database, you should always limit your result to 1, that way, if it is found in the first record, your query will stop.
Hope this helps