How do I programmatically add a tag to a file uploaded to a community on IBM SmartCloud? - ibm-sbt

I am uploading the file using the IBM Social Business Toolkit and now want to add tag(s) to it. Either as part of the upload or immediately afterwards. In the javadocs I can see that the FileService has a method to add a comment to a file. I can't see an equivalent for Tags though.

There is a Java method to update a tag on a community file - but it is broken in the most recent version of Smartcloud. It has actually been fixed in the most recent GitHub version of the code but it is not available for download as of April 2015.
The bug is reported here https://github.com/OpenNTF/SocialSDK/issues/1624. The method SHOULD be updateCommunityFileMetadata and with that we could add TAGs as Metadata. That would be simple to add to the end of the "addFile" Java method.
The sample code to TAG a file can be found here in the playgroup - it is updating the Meta Data via JavaScript API
https://greenhouse.lotus.com/sbt/sbtplayground.nsf/JavaScriptSnippets.xsp#snippet=Social_Files_API_UpdateCommunityFileMetadata
to TAG a file use the following
function tagFile(yourFileId, yourDocUnid){
require([ "sbt/connections/FileService", "sbt/dom", "sbt/json" ], function(FileService, dom, json) {
var fileService = new FileService();
var fileId = yourFileId
var docId = yourDocUnid
var tagArray = [];
tagArray.push(docId)
fileService.updateCommunityFileMetadata({
id: fileId,
tags: tagArray
}, communityId).then(function(file) {
dom.setText("json", json.jsonBeanStringify(file));
}, function(error) {
dom.setText("json", json.jsonBeanStringify(error));
});
});
}

Related

Send multiple files to Slack via API

According to Slack's documentation is only possible to send one file per time via API. The method is this: https://api.slack.com/methods/files.upload.
Using Slack's desktop and web applications we can send multiple files at once, which is useful because the files are grouped, helping in the visualization when we have more than one image with the same context. See the example below:
Do you guys know if it's possible, via API, to send multiple files at once or somehow achieve the same results as the image above?
Thanks in advance!
I've faced with the same problem. But I've tried to compose one message with several pdf files.
How I solved this task
Upload files without setting channel parameter(this prevents publishing) and collect permalinks from response. Please, check file object ref. https://api.slack.com/types/file. Via "files.upload" method you can upload only one file. So, you will need to invoke this method as many times as you have files to upload.
Compose message using Slack markdown <{permalink1_from_first_step}| ><{permalink2_from_first_step}| > - Slack parse links and automatically reformat message
Here is an implementation of the procedure recommended in the other answer in python
def postMessageWithFiles(message,fileList,channel):
import slack_sdk
SLACK_TOKEN = "slackTokenHere"
client = slack_sdk.WebClient(token=SLACK_TOKEN)
for file in fileList:
upload=client.files_upload(file=file,filename=file)
message=message+"<"+upload['file']['permalink']+"| >"
outP = client.chat_postMessage(
channel=channel,
text=message
)
postMessageWithFiles(
message="Here is my message",
fileList=["1.jpg", "1-Copy1.jpg"],
channel="myFavoriteChannel",
)
A Node.JS (es6) example using Slack's Bolt framework
import pkg from '#slack/bolt';
const { App } = pkg;
import axios from 'axios'
// In Bolt, you can get channel ID in the callback from the `body` argument
const channelID = 'C000000'
// Sample Data - URLs of images to post in a gallery view
const imageURLs = ['https://source.unsplash.com/random', 'https://source.unsplash.com/random']
const uploadFile = async (fileURL) {
const image = await axios.get(fileURL, { responseType: 'arraybuffer' });
return await app.client.files.upload({
file: image.data
// Do not use "channels" here for image gallery view to work
})
}
const permalinks = await Promise.all(imageURLs.map(async (imageURL) => {
return (await uploadImage(imageURL)).file.permalink
}))
const images = permalinks.map((permalink) => `<${permalink}| >`).join('')
const message = `Check out the images below: ${images}`
// Post message with images in a "gallery" view
// In Bolt, this is the same as doing `await say({`
// If you use say(, you don't need a channel param.
await app.client.chat.postMessage({
text: message,
channel: channelID,
// Do not use blocks here for image gallery view to work
})
The above example includes some added functionality - download images from a list of image URLs and then upload those images to Slack. Note that this is untested, I trimmed down the fully functioning code I'm using.
Slack's image.upload API docs will mention that the file format needs to be in multipart/form-data. Don't worry about that part, Bolt (via Slack's Node API), will handle that conversion automatically (and may not even work if you feed it FormData). It accepts file data as arraybuffer (used here), stream, and possibly other formats too.
If you're uploading local files, look at passing an fs readstream to the Slack upload function.
For Python you can use:
permalink_list = []
file_list=['file1.csv', 'file2.csv', 'file3.csv']
for file in file_list:
response = client.files_upload(file=file)
permalink = response['file']['permalink']
permalink_list.append(permalink)
text = ""
for permalink in permalink_list:
text_single_link = "<{}| >".format(permalink)
text = text + text_single_link
response = client.chat_postMessage(channel=channelid, text=text)
Here you can play around with the link logic - Slack Block Kit Builder
Python solution using new recommended client.files_upload_v2 (tested on slack-sdk-3.19.5 on 2022-12-21):
import slack_sdk
def slack_msg_with_files(message, file_uploads_data, channel):
client = slack_sdk.WebClient(token='your_slack_bot_token_here')
upload = client.files_upload_v2(
file_uploads=file_uploads_data,
channel=channel,
initial_comment=message,
)
print("Result of Slack send:\n%s" % upload)
file_uploads = [
{
"file": path_to_file1,
"title": "My File 1",
},
{
"file": path_to_file2,
"title": "My File 2",
},
]
slack_msg_with_files(
message='Text to add to a slack message along with the files',
file_uploads_data=file_uploads,
channel=SLACK_CHANNEL_ID # can be found in Channel settings in Slack. For some reason the channel names don't work with `files_upload_v2` on slack-sdk-3.19.5
)
(some additional error handling would not hurt)
Simply use Slack Blocks: Block Kit Builder. Great feature for the message customizations.

MvcRazorToPdf How to download file using ajax call? MVC

I tried to use MvcRazorToPdf, i can able to generate mail merge letters. My aim is after downloading file i want to return json message from controller. how to do?
Controller: [how to convert the below lines to generate pdf and download without return]
return new PdfActionResult(pdfres, (writer, document) =>
{
document.SetPageSize(new Rectangle(PageSize.A4));
document.NewPage();
})
{
FileDownloadName = "ElanWasHere.pdf"
};
I appreciate your help. thanks

Auto-updates to Electron

I'm looking to deploy an auto-update feature to an Electron installation that I have, however I am finding it difficult to find any resources on the web.
I've built a self contained application using Adobe Air before and it seemed to be a lot easier writing update code that effectively checked a url and automatically downloaded and installed the update across Windows and MAC OSX.
I am currently using the electron-boilerplate for ease of build.
I have a few questions:
How do I debug the auto update feature? Do I setup a local connection and test through that using a local Node server or can I use any web server?
In terms of signing the application I am only looking to run apps on MAC OSX and particularly Windows. Do I have to sign the applications in order to run auto-updates? (I managed to do this with Adobe Air using a local certificate.
Are there any good resources that detail how to implement the auto-update feature? As I'm having difficulty finding some good documentation on how to do this.
I am also new to Electron but I think there is no simple auto-update from electron-boilerplate (which I also use). Electron's auto-updater uses Squirrel.Windows installer which you also need to implement into your solution in order to use it.
I am currently trying to use this:
https://www.npmjs.com/package/electron-installer-squirrel-windows
And more info can be found here:
https://github.com/atom/electron/blob/master/docs/api/auto-updater.md
https://github.com/squirrel/squirrel.windows
EDIT: I just opened the project to try it for a while and it looks it works. Its pretty straightforward. These are pieces from my gulpfile.
In current configuration, I use electron-packager to create a package.
var packager = require('electron-packager')
var createPackage = function () {
var deferred = Q.defer();
packager({
//OPTIONS
}, function done(err, appPath) {
if (err) {
gulpUtil.log(err);
}
deferred.resolve();
});
return deferred.promise;
};
Then I create an installer with electron-installer-squirrel-windows.
var squirrelBuilder = require('electron-installer-squirrel-windows');
var createInstaller = function () {
var deferred = Q.defer();
squirrelBuilder({
// OPTIONS
}, function (err) {
if (err)
gulpUtil.log(err);
deferred.resolve();
});
return deferred.promise;
}
Also you need to add some code for the Squirrel to your electron background/main code. I used a template electron-squirrel-startup.
if(require('electron-squirrel-startup')) return;
The whole thing is described on the electron-installer-squirrel-windows npm documentation mentioned above. Looks like the bit of documentation is enough to make it start.
Now I am working on with electron branding through Squirrel and with creating appropriate gulp scripts for automation.
You could also use standard Electron's autoUpdater module on OS X and my simple port of it for Windows: https://www.npmjs.com/package/electron-windows-updater
I followed this tutorial and got it working with my electron app although it needs to be signed to work so you would need:
certificateFile: './path/to/cert.pfx'
In the task config.
and:
"build": {
"win": {
"certificateFile": "./path/to/cert.pfx",
"certificatePassword": "password"
}
},
In the package.json
Are there any good resources that detail how to implement the auto-update feature? As I'm having difficulty finding some good documentation on how to do this.
You don't have to implement it by yourself. You can use the provided autoUpdater by Electron and just set a feedUrl. You need a server that provides the update information compliant to the Squirrel protocol.
There are a couple of self-hosted ones (https://electronjs.org/docs/tutorial/updates#deploying-an-update-server) or a hosted service like https://www.update.rocks
Question 1:
I use Postman to validate that my auto-update server URLs return the response I am expecting. When I know that the URLs provide the expected results, I know I can use those URLs within the Electron's Auto Updater of my Application.
Example of testing Mac endpoint with Postman:
Request:
https://my-server.com/api/macupdates/checkforupdate.php?appversion=1.0.5&cpuarchitecture=x64
JSON Response when there is an update available:
{
"url": "https:/my-server.com/updates/darwin/x64/my-electron=app-x64-1.1.0.zip",
"name": "1.1.0",
"pub_date": "2021-07-03T15:17:12+00:00"
}
Question 2:
Yes, your Electron App must be code signed to use the auto-update feature on Mac. On Windows I'm not sure because my Windows Electron app is code signed and I did not try without it. Though it is recommended that you sign your app even if the auto-update could work without it (not only for security reasons but mainly because otherwise your users will get scary danger warnings from Windows when they install your app for the first time and they might just delete it right away).
Question 3:
For good documentation, you should start with the official Electron Auto Updater documentation, as of 2021-07-07 it is really good.
The hard part, is figuring out how to make things work for Mac. For Windows it's a matter of minutes and you are done. In fact...
For Windows auto-update, it is easy to setup - you just have to put the RELEASES and nupkg files on a server and then use that URL as the FeedURL within your Electron App's autoUpdater. So if your app's update files are located at https://my-server.com/updates/win32/x64/ - you would point the Electron Auto Updater to that URL, that's it.
For Mac auto-update, you need to manually specify the absolute URL of the latest Electron App .zip file to the Electron autoUpdater. So, in order to make the Mac autoUpdater work, you will need to have a way to get a JSON response in a very specific format. Sadly, you can't just put your Electron App's files on your server and expect it to work with Mac just like that. Instead, the autoUpdater needs a URL that will return the aforementioned JSON response. So to do that, you need to pass Electron's Auto Updater feedURL the URL that will be able to return this expected kind of JSON response.
The way you achieve this can be anything but I use PHP just because that's the server I already paid for.
So in summary, with Mac, even if your files are located at https://my-server.com/updates/darwin/x64/ - you will not provide that URL to Electron's Auto Updater FeedURL. Instead will provide another URL which returns the expected JSON response.
Here's an example of my main.js file for the Electron main process of my App:
// main.js (Electron main process)
function registerAutoUpdater() {
const appVersion = app.getVersion();
const os = require('os');
const cpuArchitecture = os.arch();
const domain = 'https://my-server.com';
const windowsURL = `${domain}/updates/win32/x64`;
const macURL = `${domain}/api/macupdates/checkforupdate.php?appversion=${appVersion}&cpuarchitecture=${cpuArchitecture}`;
//init the autoUpdater with proper update feed URL
const autoUpdateURL = `${isMac ? macURL : windowsURL}`;
autoUpdater.setFeedURL({url: autoUpdateURL});
log.info('Registered autoUpdateURL = ' + (isMac ? 'macURL' : 'windowsURL'));
//initial checkForUpdates
autoUpdater.checkForUpdates();
//Automatic 2-hours interval loop checkForUpdates
setInterval(() => {
autoUpdater.checkForUpdates();
}, 7200000);
}
And here's an example of the checkforupdate.php file that returns the expected JSON response back to the Electron Auto Updater:
<?php
//FD Electron App Mac auto update API endpoint.
// The way Squirrel.Mac works is by checking a given API endpoint to see if there is a new version.
// If there is no new version, the endpoint should return HTTP 204. If there is a new version,
// however, it will expect a HTTP 200 JSON-formatted response, containing a url to a .zip file:
// https://github.com/Squirrel/Squirrel.Mac#server-support
$clientAppVersion = $_GET["appversion"] ?? null;
if (!isValidVersionString($clientAppVersion)) {
http_response_code(204);
exit();
}
$clientCpuArchitecture = $_GET["cpuarchitecture"] ?? null;
$latestVersionInfo = getLatestVersionInfo($clientAppVersion, $clientCpuArchitecture);
if (!isset($latestVersionInfo["versionNumber"])) {
http_response_code(204);
exit();
}
// Real logic starts here when basics did not fail
$isUpdateVailable = isUpdateAvailable($clientAppVersion, $latestVersionInfo["versionNumber"]);
if ($isUpdateVailable) {
http_response_code(200);
header('Content-Type: application/json;charset=utf-8');
$jsonResponse = array(
"url" => $latestVersionInfo["directZipFileURL"],
"name" => $latestVersionInfo["versionNumber"],
"pub_date" => date('c', $latestVersionInfo["createdAtUnixTimeStamp"]),
);
echo json_encode($jsonResponse);
} else {
//no update: must respond with a status code of 204 No Content.
http_response_code(204);
}
exit();
// End of execution.
// Everything bellow here are function declarations.
function getLatestVersionInfo($clientAppVersion, $clientCpuArchitecture): array {
// override path if client requests an arm64 build
if ($clientCpuArchitecture === 'arm64') {
$directory = "../../updates/darwin/arm64/";
$baseUrl = "https://my-server.com/updates/darwin/arm64/";
} else if (!$clientCpuArchitecture || $clientCpuArchitecture === 'x64') {
$directory = "../../updates/darwin/";
$baseUrl = "https://my-server.com/updates/darwin/";
}
// default name with version 0.0.0 avoids failing
$latestVersionFileName = "Finance D - Tenue de livres-darwin-x64-0.0.0.zip";
$arrayOfFiles = scandir($directory);
foreach ($arrayOfFiles as $file) {
if (is_file($directory . $file)) {
$serverFileVersion = getVersionNumberFromFileName($file);
if (isVersionNumberGreater($serverFileVersion, $clientAppVersion)) {
$latestVersionFileName = $file;
}
}
}
return array(
"versionNumber" => getVersionNumberFromFileName($latestVersionFileName),
"directZipFileURL" => $baseUrl . rawurlencode($latestVersionFileName),
"createdAtUnixTimeStamp" => filemtime(realpath($directory . $latestVersionFileName))
);
}
function isUpdateAvailable($clientVersion, $serverVersion): bool {
return
isValidVersionString($clientVersion) &&
isValidVersionString($serverVersion) &&
isVersionNumberGreater($serverVersion, $clientVersion);
}
function getVersionNumberFromFileName($fileName) {
// extract the version number with regEx replacement
return preg_replace("/Finance D - Tenue de livres-darwin-(x64|arm64)-|\.zip/", "", $fileName);
}
function removeAllNonDigits($semanticVersionString) {
// use regex replacement to keep only numeric values in the semantic version string
return preg_replace("/\D+/", "", $semanticVersionString);
}
function isVersionNumberGreater($serverFileVersion, $clientFileVersion): bool {
// receives two semantic versions (1.0.4) and compares their numeric value (104)
// true when server version is greater than client version (105 > 104)
return removeAllNonDigits($serverFileVersion) > removeAllNonDigits($clientFileVersion);
}
function isValidVersionString($versionString) {
// true when matches semantic version numbering: 0.0.0
return preg_match("/\d\.\d\.\d/", $versionString);
}

BreezeJs With Web API OData Returns "404" error when try to read Meta Data information

Getting 404 page not found error when try to access OData Meta data information from breeze, but i can get the information if i put url directly on Browser(without breeze).
My Server Side OData Entity Configuration is noted below.
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.Namespace = "BisService.Entities";
odataBuilder.EntitySet<CompanyDto>("Company").EntityType.HasKey(x => x.Id);
config.MapODataServiceRoute("BisService", "BizService", odataBuilder.GetEdmModel());
I am using following config on Breeze.'
var serverAddress = "/BisService/";
breeze.config.initializeAdapterInstance('dataService', 'webApiOData', true);
var manager = new breeze.EntityManager(serverAddress);
var query = breeze.EntityQuery.from("Company");
manager.executeQuery(query, function(data) {
console.log(data)
});
I ran into issues similar to this while attempting to implement breezejs with odata.
After reading the OData on the Server article on breezejs.com, we decided that Web Api would suit us just fine.
If you need to continue down the odata path, see the Open Data article.
I ran into what may have been the same issue today. In my case, I traced it down to the addition of the following header in the request:
MaxDataServiceVersion: 3.0
This is added by datajs and my work around was to comment out the following line in datajs-1.1.2.js:
if (!assigned(request.headers.MaxDataServiceVersion)) {
//request.headers.MaxDataServiceVersion = handler.maxDataServiceVersion || "1.0";
}
which is line 2334 in the version I have.

Getting original file meta-data from FineUploader

I am aware that performing a stat on an uploaded file will only give creation/modified/access dates at the time the file was uploaded.
So a very quick question, is there any way for FineUploader to access the original file meta-data for these fields and send it along with the upload request?
From what I understand, this is probably not possible, but it never hurts to ask!
This feature is not natively supported by Fine Uploader. You could open up an issue if you think it would be a useful feature.
That being said, you can do it using Fine Uploader's callbacks and the FileAPI. The best you could do in any browser right now is get the lastModifiedDate using the FileAPI and add that to the parameters for each file in your onSubmitted callback,
var getLastModifiedDate = function(file) {
/* Cross-broswer File API shim to get Last Modified Date of a file */
}
var fineuploader = new qq.FineUploader/* ... */
/* snippet */
callbacks: {
onSubmitted: function(id, name) {
var file = fineuploader.getFile(id),
lastModified = getLastModifiedDate(file);
fineuploader.setParams({ lastModified: lastModified }, id);
});
}
/* snippet */
I found this question and answer which has an example and a shim to retrieve the lastModifiedDate.

Resources