Attributes are removed in HTML code - wysihtml5

I use wysihtml5.
When you insert an image
<img alt src="src" media_img_id="123" data-title="title" data-author="author" />
The result is
<img alt src="src" />
Rules for img
"img": {
"remove": 0,
"check_attributes": {
"width": "numbers",
"alt": "alt",
"src": "url", // if you compiled master manually then change this from 'url' to 'src'
"height": "numbers",
"media_img_id": "numbers"
},
"add_class": {
"align": "align_img"
}
},
How to make the attributes generally not removed?

I have the same task today to extend abilities of this editor.
You should add your attributes in special object:
I'm using additionaly bootstrap3-wysihtml5 - https://github.com/schnawel007/bootstrap3-wysihtml5 . The object that should be added with new attributes for element:
var defaultOptions = $.fn.wysihtml5.defaultOptions = {
/../
"img": {
"check_attributes":
{
"width": "numbers",
"alt": "alt",
"data-encid": "alt", <<-here is my custom attribute
"src": "url",
"height": "numbers"
}
},
/../
}
and in wysihtml5.js you should add condition in which your src attribute is differs from classical source (that this plugin expected) "http://example.png".
line 4922:
if (checkAttributes) {
for (attributeName in checkAttributes) {
method = attributeCheckMethods[checkAttributes[attributeName]];
if (!method) {
continue;
}
newAttributeValue = method(_getAttribute(oldNode, attributeName));
if (typeof(newAttributeValue) === "string") {
attributes[attributeName] = newAttributeValue;
}
}
}
replace with:
if (checkAttributes) {
for (attributeName in checkAttributes) {
method = attributeCheckMethods[checkAttributes[attributeName]];
if (!method) {
continue;
}
newAttributeValue = (attributeName == "src" && checkAttributes["data-encid"])
? oldNode.src
: method(_getAttribute(oldNode, attributeName));
if (typeof(newAttributeValue) === "string") {
attributes[attributeName] = newAttributeValue;
}
}
}
Here I just copy the src attribute value without checking through wysihtml5.js core.
Hope this helps!

Related

Search Key in Nested json in Dart/Flutter

I want to search the key "AylaHeartBeatFrequency" inside nested json. how to search and get its value ? in flutter/dart
{
"sAWSIoT": {
"CloudStatus": 1,
"PairingFlag": 0,
},
"sDebug": {
"LocalDebugMsg_d": "Model ID",
"AylaHeartBeatFrequency": 0
},
"Product": {
"Mode": 1,
"Model": "abc"
},
"data": {
"DeviceType": 300,
"Endpoint": 0,
"UniID": "0000000000000000"
}
}
You can do:
var map = /*put your json here. You can use json.decode() on the json if it's not yet formatted*/, value;
for(var item in map.values) {
if(item.containsKey('AylaHeartBeatFrequency') value = item['AylaHeartBeatFrequency']) ;
}

get github issues by their ids through graphql endpoints

I am trying to get the list of issues by their ids from Github using graphql, but looks like I am missing something or its not possible.
query ($ids:['517','510']!) {
repository(owner:"owner", name:"repo") {
issues(last:20, states:CLOSED) {
edges {
node {
title
url
body
author{
login
}
labels(first:5) {
edges {
node {
name
}
}
}
}
}
}
}
}
The above query is giving me response as below,
{
"errors": [
{
"message": "Parse error on \"'\" (error) at [1, 14]",
"locations": [
{
"line": 1,
"column": 14
}
]
}
]
}
Kindly help me identify if its possible or that I am doing something wrong here.
You can use aliases in order to build a single request requesting multiple issue object :
{
repository(name: "material-ui", owner: "mui-org") {
issue1: issue(number: 2) {
title
createdAt
}
issue2: issue(number: 3) {
title
createdAt
}
issue3: issue(number: 10) {
title
createdAt
}
}
}
Try it in the explorer
which gives :
{
"data": {
"repository": {
"issue1": {
"title": "Support for ref's on Input component",
"createdAt": "2014-10-15T15:49:13Z"
},
"issue2": {
"title": "Unable to pass onChange event to Input component",
"createdAt": "2014-10-15T16:23:28Z"
},
"issue3": {
"title": "Is it possible for me to make this work if I'm using React version 0.12.0?",
"createdAt": "2014-10-30T14:11:59Z"
}
}
}
}
This request can also be simplified using fragments to prevent repetition:
{
repository(name: "material-ui", owner: "mui-org") {
issue1: issue(number: 2) {
...IssueFragment
}
issue2: issue(number: 3) {
...IssueFragment
}
issue3: issue(number: 10) {
...IssueFragment
}
}
}
fragment IssueFragment on Issue {
title
createdAt
}
The request can be built programmatically, such as in this example python script :
import requests
token = "YOUR_TOKEN"
issueIds = [2,3,10]
repoName = "material-ui"
repoOwner = "mui-org"
query = """
query($name: String!, $owner: String!) {
repository(name: $name, owner: $owner) {
%s
}
}
fragment IssueFragment on Issue {
title
createdAt
}
"""
issueFragments = "".join([
"""
issue%d: issue(number: %d) {
...IssueFragment
}""" % (t,t) for t in issueIds
])
r = requests.post("https://api.github.com/graphql",
headers = {
"Authorization": f"Bearer {token}"
},
json = {
"query": query % issueFragments,
"variables": {
"name": repoName,
"owner": repoOwner
}
}
)
print(r.json()["data"]["repository"])
I don't think you can fetch for issues and pass in an array of integers for their ids.
But you can search for a single issue by id like so (this works for me)
query ($n: Int!) {
repository(owner:"owner", name:"repo-name") {
issue (number: $n) {
state
title
author {
url
}
}
}
}
where $n is {"n": <your_number>} defined.
If you have an array of ids, then you can just make multiple queries to GitHub.
Sadly, with this approach, you cannot specify what the state of the issue to be. But I think the logic is that once you know the issue Id, you shouldn't care what state it is, since you have that exact id.

MongoDB GridFSBucket upload stream doesn't return length of base64 image stream

I'm refactoring my team code to remove Deprecation Warnings from MongoDB.
I removed gridfs-stream library and I'm using GridFSBucket instead
But there is a problem: upload stream using GridFSBucket doesn't return the length of base64 image, instead it returns 0. This breaks one of the tests in our code.
This is the code using GridFSBucket:
function getGrid() {
return new mongoose.mongo.GridFSBucket(conn.db);
}
module.exports.store = function(id, contentType, metadata, stream, options, callback) {
... // unrelated things
var strMongoId = mongoId.toHexString(); // http://stackoverflow.com/a/27176168
var opts = {
contentType: contentType,
metadata: metadata
};
options = options || {};
if (options.filename) {
opts.filename = options.filename;
}
if (options.chunk_size) {
var size = parseInt(options.chunk_size, 10);
if (!isNaN(size) && size > 0 && size < 255) {
opts.chunkSizeBytes = chunk_size * size;
}
}
var gfs = getGrid();
var writeStream = gfs.openUploadStreamWithId(strMongoId, opts.filename, opts);
writeStream.on('finish', function(file) {
console.log(file) // <== Notice the log for this line below
return callback(null, file);
});
writeStream.on('error', function(err) {
return callback(err);
});
stream.pipe(writeStream);
};
The result for console.log(file) is:
{
"_id": "5ea7a3ffbc7dd36e7df4561e",
"length": 0, // <== Notice length is 0 here
"chunkSize": 10240,
"uploadDate": "2020-04-28T03:33:19.734Z",
"filename": "default_profile.png",
"md5": "d41d8cd98f00b204e9800998ecf8427e",
"contentType": "image/png",
"metadata": {
"name": "default_profile.png",
"creator": {
"objectType": "user",
"id": "5ea7a3febc7dd36e7df4560a"
}
}
}
This is the old code using gridfs-stream:
var Grid = require('gridfs-stream');
...
function getGrid() {
return new Grid(mongoose.connection.db, mongoose.mongo);
}
module.exports.store = function(id, contentType, metadata, stream, options, callback) {
... // unrelated things
var strMongoId = mongoId.toHexString(); // http://stackoverflow.com/a/27176168
var opts = {
_id: strMongoId,
mode: 'w',
content_type: contentType
};
options = options || {};
if (options.filename) {
opts.filename = options.filename;
}
if (options.chunk_size) {
var size = parseInt(options.chunk_size, 10);
if (!isNaN(size) && size > 0 && size < 255) {
opts.chunk_size = chunk_size * size;
}
}
opts.metadata = metadata;
var gfs = getGrid();
var writeStream = gfs.createWriteStream(opts);
writeStream.on('close', function(file) {
console.log(file) // <== Notice the log for this line below
return callback(null, file);
});
writeStream.on('error', function(err) {
return callback(err);
});
stream.pipe(writeStream);
};
And here is the result of console.log(file):
{
"_id": "5ea7a43a5d6eea73e0a3c8b1",
"filename": "default_profile.png",
"contentType": "image/png",
"length": 634, // <== We have the length here
"chunkSize": 10240,
"uploadDate": "2020-04-28T03:34:18.069Z",
"metadata": {
"name": "default_profile.png",
"creator": {
"objectType": "user",
"id": "5ea7a4395d6eea73e0a3c89d"
}
},
"md5": "c37659eb6a9e741656a8d0348765c668"
}
So how can I get the length using GridFSBucket?
Thank you!
UPDATE:
This is the log of variable stream in both cases:
{
"contentType": "image/png",
"fileName": "default_profile.png",
"transferEncoding": "base64",
"contentDisposition": "attachment",
"generatedFileName": "default_profile.png",
"contentId": "216d9aab57544410901f8ba7981e63aa#mailparser",
"stream": {
"_events": {},
"_eventsCount": 0,
"writable": true,
"checksum": {
"_handle": {},
"writable": true,
"readable": true
},
"length": 0,
"current": ""
}
}

Getting series and values from CSV data in Zingchart

While creating mixed chart in Zingchart we can pass the type attribute values with values array. But I'm not sure when reading data from CSV how this can be achieved.
I want to create mixed chart as on fiddle link below but data is to be read from a csv file.
var myConfig =
{
"type":"mixed",
"series":[
{
"values":[51,53,47,60,48,52,75,52,55,47,60,48],
"type":"bar",
"hover-state":{
"visible":0
}
},
{
"values":[69,68,54,48,70,74,98,70,72,68,49,69],
"type":"line"
}
]
}
zingchart.render({
id : 'myChart',
data : myConfig,
height: 500,
width: 725
});
<script src="https://cdn.zingchart.com/zingchart.min.js"></script>
<div id="myChart"></div>
I put together a demo for you using the sample data you provided in one of your related questions. If you go to this demo page and upload the CSV you originally provided, you should get this chart:
ZingChart includes a CSV parser for basic charts, but a more complex case like this requires a bit of preprocessing to get your data where it needs to be. I used PapaParse for this demo, but there are other parsing libraries available.
Here's the JavaScript. I'm using a simple file input in the HTML to get the CSV.
var csvData;
var limit = [],
normal = [],
excess = [],
dates = [];
var myConfig = {
theme: "none",
"type": "mixed",
"scale-x": {
"items-overlap":true,
"max-items":9999,
values: dates,
guide: {
visible: 0
},
item:{
angle:45
}
},
"series": [{
"type": "bar",
"values": normal,
"stacked": true,
"background-color": "#4372C1",
"hover-state": {
"visible": 0
}
}, {
"type": "bar",
"values": excess,
"stacked": true,
"background-color": "#EB7D33",
"hover-state": {
"visible": 0
}
}, {
"type": "line",
"values": limit
}]
};
/* Get the file and parse with PapaParse */
function parseFile(e) {
var file = e.target.files[0];
Papa.parse(file, {
delimiter: ",",
complete: function(results) {
results.data.shift(); //the first array is header values, we don't need these
csvData = results.data;
prepChart(csvData);
}
});
}
/* Process the results from the PapaParse(d) CSV and populate
** the arrays for each chart series and scale-x values
*/
function prepChart(data) {
var excessVal;
//PapaParse data is in a 2d array
for (var i = 0; i < data.length; i++) {
//save reference to your excess value
//cast all numeric values to int (they're originally strings)
var excessVal = parseInt(data[i][4]);
//date, limit value, and normal value can all be pushed to their arrays
dates.push(data[i][0]);
limit.push(parseInt(data[i][1]));
normal.push(parseInt(data[i][3]));
/* we must push a null value into the excess
** series if there is no excess for this node
*/
if (excessVal == 0) {
excess.push(null);
} else {
excess.push(excessVal);
}
}
//render your chart
zingchart.render({
id: 'myChart',
data: myConfig,
height: 500,
width: 725
});
}
$(document).ready(function() {
$('#csv-file').change(parseFile);
});

How to get all versions of an object in Google cloud storage bucket?

In a web page hosted in Google cloud storage, I will like to show revision history, which require listing all versions of the object.
Sending GET request to the bucket with ?versions parameter return list versions all objects. Is there any way to list all versions of a single object, as in gsutil ls -la, in javascript?
There is not. The closest you can do is to use versions=true and prefix=YOUR_OBJECT_NAME.
GCS will respond with a listing of objects beginning with all of the versions of your object and continuing on to any other objects that begin with YOUR_OBJECT_NAME. You'll have to check those items to see when the listing runs out of versions of your object and moves on to other objects.
If it so happens that only one object begins with YOUR_OBJECT_NAME (for example, your object is "foo.txt" and there are no files named, say, "foo.txt.backup", you will get exactly the files you want. You probably don't want to rely on this as a general practice, though.
Brondon's answer work with XML, but not with gapi client.
/**
* Get versions meta data of the object.
* #return {goog.async.Deferred} return history of the object.
*/
mbi.data.Object.prototype.history = function() {
var df = new goog.async.Deferred();
var use_gapi = true;
var name = this.getName();
if (use_gapi) {
// GAPI does not return result for versions request.
var params = {
'bucket': this.getBucketName(),
'versions': true,
'prefix': name
};
// console.log(params);
var req = gapi.client.rpcRequest('storage.buckets.get',
mbi.app.base.GAPI_STORAGE_VERSION, params);
req.execute(function(json, row) {
if (json) {
df.callback(json);
} else {
df.errback();
throw new Error(row);
}
});
} else {
var xm = mbi.data.Object.getXhr();
var uri = new goog.Uri(this.getUrl());
uri.setParameterValue('versions', 'true');
uri.setParameterValue('max-keys', '25');
uri.setParameterValue('prefix', name);
var url = uri.setPath('').setFragment('').toString();
xm.send(url, url, 'GET', null, {}, 1, function(e) {
var xhr = /** #type {goog.net.XhrIo} */ (e.target);
if (xhr.isSuccess()) {
var xml = xhr.getResponseXml();
// console.log(xml);
var json = mbi.utils.xml.xml2json(xml);
var items = json['ListBucketResult']['Version'];
var versions = goog.isArray(items) ? items : items ? [items] : [];
versions = versions.filter(function(x) {
return x['Key'] == name;
});
df.callback(versions);
} else {
df.errback(xhr.getStatus() + ' ' + xhr.getResponseText());
}
});
}
return df;
};
GAPI return as follow without version meta:
[
{
"id": "gapiRpc",
"result": {
"kind": "storage#bucket",
"id": "mbiwiki-test",
"name": "mbiwiki-test",
"timeCreated": "2013-08-20T01:18:46.957Z",
"metageneration": "9",
"owner": {
"entity": "group-00b4903a97262a358b97b95b39df60893ece79605b60280ad389c889abf70645",
"entityId": "00b4903a97262a358b97b95b39df60893ece79605b60280ad389c889abf70645"
},
"location": "US",
"website": {
"mainPageSuffix": "index.html",
"notFoundPage": "error404.html"
},
"versioning": {
"enabled": true
},
"cors": [
{
"origin": [
"http://static.mechanobio.info",
"http://mbinfo-backend.appspot.com",
"https://mbinfo-backend.appspot.com",
"http://localhost",
"chrome-extension://pbcpfkkhmlbicomenogobbagaaenlnpd",
"chrome-extension://mhigmmbegkpdlhjaphlffclbgkgelnbe",
"chrome-extension://jhmklemcneaienackijjhdikoicmoepp"
],
"method": [
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"PATCH"
],
"responseHeader": [
"content-type",
"Authorization",
"Cache-Control",
"x-goog-meta-reviewer"
]
}
],
"storageClass": "STANDARD",
"etag": "CAk="
}
}
]