I am having some trouble trying to connect/link two Azure logic apps together.
Here is my scenario and how I am trying to use the Logic apps.
I have created a 1st Logic app : that allows a user to upload a .mp4 media file into a folder on OneDrive, and the logic app checks to see if there is new file on that OneDrive folder. If there is new file, it will trigger the logic app and Index the video onto https://www.videoindexer.ai/.
2nd - Logic App : After the video is indexed to https://www.videoindexer.ai/ , I want the user to pick language(s) from the custom web page that I have created, for caption translation(here is the custom web page). Once the user choose the language(s) they click on "submit" and this will send the data(languages) to my 2nd logic app URL end-point, and trigger my second logic app and get the captions based on the user's selection of languages. Finally, it will then output those caption files on to a OneDrive folder.
Here is how I have created both the Logic apps:
1st Logic APP:
2nd Logic APP:
HTML:
<form id="language-form">
<h3>Please select the languages(s) for translating captions: </h3>
<ul>
<li><label><input type="checkbox" name="language" value="en-US"> English</label></li>
<li><label><input type="checkbox" name="language" value="es-ES"> Spanish</label></li>
<li><label><input type="checkbox" name="language" value="ko-KR"> Korean</label></li>
<li><label><input type="checkbox" name="language" value="th-TH"> Thai</label></li>
<li><label><input type="checkbox" name="language" value="ja-JP"> Japanese</label></li>
</ul>
<button type="submit">Submit</button>
</form>
JavaScript:
function fetchForLanguages(languages) {
console.info('starting fetch for', languages)
return fetch("https://prod-00.westus2.logic.azure.com:443/workflows/xxxxxxxxxxxxxxxxx", { // this is my azure provided endpoint
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
languages: languages
})
}).then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`);
}
return response.json()
})
}
function handleSubmit(event) {
event.preventDefault()
const data = new FormData(event.currentTarget)
const languages = data.getAll('language')
console.info('languages selected:', languages)
fetchForLanguages(languages)
.then((result) => console.log('got result:', result))
}
let form = document.getElementById('language-form')
form.addEventListener('submit', handleSubmit)
Here is workflow quite similar to yours with explanation:
[https://azure.microsoft.com/en-us/blog/logic-apps-flow-connectors-will-make-automating-video-indexer-simpler-than-ever/][1]
Here is python function to check for the file is ready before you send an email:
import requests
loc = '' # location
acc_id = '' # account id
vi_subscription_key = '' # primary key
def get_access_token(loc, acc_id):
headers = {'Ocp-Apim-Subscription-Key': vi_subscription_key}
params = {'allowEdit': 'true'}
access_token_req = requests.get(
f'https://api.videoindexer.ai/auth/{loc}/Accounts/{acc_id}/AccessToken',
params=params,
headers=headers)
access_token = access_token_req.text[1:-1]
return access_token
def is_video_proccessed(loc, acc_id, access_token, video_id, video_language='English'):
params = {'accessToken': access_token,
'language': video_language }
get_video_info_req = requests.get(
f'https://api.videoindexer.ai/{loc}/Accounts/{acc_id}/Videos/{video_id}/Index',
params=params)
response = get_video_info_req.json()
if (response['state'] != "Uploaded") and (response['state'] != 'Processing'):
print(f'Video {video_id} finished processing')
return True
Hope this help.
Related
I'm trying to get an activation link from an email to successfully pass it's UID and token to a vue page where it'll get authenticated.
I have my folder structure set up currently like .../registration/activate/_uid/_token.vue, but that causes the registration link to bring up a 404 page.
I've tried setting up to /_uid/_token/_token.vue with the extra token to see what'll happen, and it lets token.vue render, but I don't think the params are being passed. I'm also getting a "Duplicate param keys in route with path: "/registration/activate/:uid?/:token?/:token?" error in console.
<template>
<v-container>
<v-card v-if="status === 'pending'" class="pa-8 text-center">
<p class="title">Please wait</p>
<p class="body-1">Checking registration status...</p>
</v-card>
<v-card v-if="status === 'success'" class="pa-8 text-center">
<p class="title primary--text">Activation successful</p>
<p class="body-1">You may now log in.</p>
<v-btn color="primary" text #click="navigateToLogin">Log In</v-btn>
</v-card>
<v-card v-if="status === 'error'" class="pa-8 text-center">
<p class="title error--text">Invalid activation token</p>
<p class="body-1">This token is invalid. Please try again.</p>
</v-card>
</v-container>
</template>
<script>
export default {
auth: false,
data: () => ({
status: 'pending'
}),
mounted() {
this.$axios
.post('/auth/users/activation/', this.$route.params)
.then((response) => {
this.status = 'success'
})
.catch(() => {
this.status = 'error'
})
},
methods: {
navigateToLogin() {
this.$router.push('/login')
}
}
}
</script>
Here's an example of a registration link.
http://localhost:3000/activate/MTg/5j2-d0af1770a53f1db2a851
Another part of issue that I can't quite solve, is since I'm using python for my backend should I use a python template to submit the UID and token or figure out a way to send the email where the root is localhost:3000 (my frontend) vs :8000 (my backend).
Currently my settings.py looks like this for the registration link:
'ACTIVATION_URL': 'registration/activate/{uid}/{token}',
the root is localhost:8000 for the whole API. So if I can't figure out how to manually set it to 3000 for just this link, I guess I'll need to use a template right? Any suggestions are welcome!
the problem is your path declaration. In Vue you should declare a param in path like this:
path: "/registration/activate/:uid/:token"
after this if you enter http://localhost:3000/activate/MTg/5j2-d0af1770a53f1db2a851 your this.$route.params should look like this:
{"uid":"MTg","token":"5j2-d0af1770a53f1db2a851"}
and you axios request is fine.
and because yout are sending a JSON to server if your using django you can use this code to get the body of a request:
def avtivate(request):
if request.is_ajax():
if request.method == 'POST':
print 'Raw Data: "%s"' % request.body
return HttpResponse("OK")
Backstory
I'm building an online marketplace for used cars where owners can list their cars for sale and buyers can find affordable used cars more easily.
I'm using Sails.js v1.0 as my app's Node.js framework.
Challenge
I want users to be able to add images to each car they've listed, Craigslist-style.
Current Implementation
Here's what I have thus far...
In images.ejs view file I have an ajax-form element:
<ajax-form class="" action="images" :syncing.sync="syncing" :cloud-error.sync="cloudError" #submitted="submittedForm()" :handle-parsing="handleParsingForm" enctype="multipart/form-data">
<div class="form-outer flex justify-center items-center h-100 bt bw2">
<div class="form-inner bg-yellow pa3 w-100">
<div class="mb3 w-100">
<label class="db tl mv2 f4" for="upload">Upload</label>
<input class="pv3" id="upload" type="file" :class="[formErrors.upload ? 'is-invalid' : '']" v-on:change>
<div class="bg-light-red light-gray pa2 br2 mt1" v-if="formErrors.upload">Please select at least one image.</div>
</div>
<p class="bg-light-red light-gray pa2 br2 mt1" v-if="cloudError"><small>An error occured while processing your request. Please check your information and try again, or contact support if the error persists.</small></p>
<div class="">
<ajax-button :syncing="syncing" class="bg-green pa2 ba b--dark-gray br2 bw1 b circular-bold">Add images.</ajax-button>
</div>
</div>
</div>
</ajax-form>
This form submits to the controller at POST: cars/images.js:
module.exports = {
friendlyName: 'Images',
description: 'Allow users to upload images of car.',
inputs: {
},
exits: {
},
fn: async function (req, res) {
req.file('upload').upload({
// don't allow the total upload size to exceed ~10MB
maxBytes: 10000000
},function whenDone(err, uploadedFiles) {
if (err) {
return res.serverError(err);
}
// If no files were uploaded, respond with an error.
if (uploadedFiles.length === 0){
return res.badRequest('No file was uploaded');
}
// Get the base URL for our deployed application from our custom config
// (e.g. this might be "http://foobar.example.com:1339" or "https://example.com")
var baseUrl = sails.config.custom.baseUrl;
// Save the "fd" and the url where the upload for a user can be accessed
User.update(req.session.userId, {
// Generate a unique URL where the upload can be downloaded.
uploadUrl: require('util').format('%s/user/upload/%s', baseUrl, req.session.userId),
// Grab the first file and use it's `fd` (file descriptor)
uploadFd: uploadedFiles[0].fd
})
.exec(function (err){
if (err) return res.serverError(err);
return res.ok();
});
});
}
};
This controller/sails action is using the standard req/res objects within the Sails.js actions2 format.
All of the Sails documentation on file uploads points to the Sails body-parser implementation called Skipper, but I feel the documentation is lacking on the new actions2 syntax.
Can anyone point me to a concrete example of implementing this file upload feature, especially for uploading multiple image files?
When I add an item to my database it just shows the id was added but the name attribute I chose for the item was not added: Meaning - The 'name' attribute I add to the 'player' is not persisted when I save it. Can someone please tell me why? I think it's an issue with string conversion but I am not sure.
*I am able to update the item's name using POSTMAN's PUT option.
Using the x-www-form-urlencoded option, I can update my item's name with a plain string.
So do I need to simply do some sort of string conversion or is something else wrong with my code? And please let me know if you need me to provide more code. Thanks!
Here's my code:
browser control - network:
Yes - (and I only add a name attribute)
When I add the name attribute it is not saved - yet an item is still created. That is the problem.
browser console - network tab:
Remote Address:127.0.0.1:3000
Request URL:http://localhost:3000/api/players
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,he;q=0.6
Connection:keep-alive
Content-Length:18
Content-Type:application/json;charset=UTF-8
Cookie:connect.sid=s%3AX2FaOplCDPU3qDaM7vVQPb5vFo_ievn1.zFM%2FKNj2QN5eDspCFOJEE2fYwXiTyUnN90sR8oTfnpI
Host:localhost:3000
Origin:http://localhost:3000
Referer:http://localhost:3000/add
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Request Payloadview source
{showName:Jay}
showName: "Jay"
Response Headersview source
Connection:keep-alive
Content-Length:29
Content-Type:application/json
Date:Sun, 06 Jul 2014 06:13:25 GMT
X-Powered-By:Express
Here's code of the route: server side. maybe there's an error here:
.post(function(req, res) {
var player = new Player(); // create a new instance of the Player model
player.name = req.body.name; // set the player name (comes from the request)
player.sport = req.body.sport;
player.league = req.body.league;
player.team = req.body.team;
player.age = req.body.age;
player.description = req.body.description;
// save the player and check for errors
player.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Player created!' });
});
})
.get(function(req, res) {
Player.find(function(err, players) {
if (err)
res.send(err);
res.json(players);
});
});
controller: add.js
angular.module('MyApp')
.controller('AddCtrl', ['$scope', '$alert', 'Player', function($scope, $alert, Player) {
$scope.addShow = function() {
Player.save({ showName: $scope.showName },
function() {
$scope.showName = '';
$scope.addForm.$setPristine();
$alert({
content: 'Player has been added.',
placement: 'top-right',
type: 'success',
duration: 3
});
},
function(response) {
$scope.showName = '';
$scope.addForm.$setPristine();
$alert({
content: response.data.message,
placement: 'top-right',
type: 'danger',
duration: 3
});
});
};
}]);
template: add.html
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">Add Sports Player</div>
<div class="panel-body">
<form class="form" method="post" ng-submit="addShow()" name="addForm">
<div class="form-group" ng-class="{ 'has-success' : addForm.showName.$valid && addForm.showName.$dirty, 'has-error' : addForm.showName.$invalid && addForm.showName.$dirty }">
<input class="form-control" type="text" name="showName" ng-model="showName" placeholder="Enter TV show name" required autofocus>
<div class="help-block text-danger" ng-if="addForm.showName.$dirty" ng-messages="addForm.showName.$error">
<div ng-message="required">Sports Player's name is required.</div>
</div>
</div>
<button class="btn btn-primary" type="submit" ng-disabled="addForm.$invalid">Add</button>
</form>
</div>
</div>
service: player.js
angular.module('MyApp')
.factory('Player', ['$resource', function($resource) {
return $resource('/api/players/:_id');
}]);
From what I can tell, you are making a POST HTTP request to /api/players:
Request URL:http://localhost:3000/api/players
Request Method:POST
However, you're only sending showName:
Request Payloadview source
{showName:Jay}
showName: "Jay"
But on the server side, you are not looking for showName, and instead looking name, sport, league, etc:
var player = new Player(); // create a new instance of the Player model
player.name = req.body.name; // set the player name (comes from the request)
player.sport = req.body.sport;
player.league = req.body.league;
player.team = req.body.team;
player.age = req.body.age;
player.description = req.body.description;
If you want to store name, then you'll need to send over name instead of showName. If you want to store showName, then you'll need to pull it from the request body (req.body.showName). So either send over all those attributes from the client side to the server side, or change the server side to accept only showName for a Player.
Hopefully that makes sense? There's just a disconnect from what you're sending on the client side to what you're looking for on the server side. It's also a bit confusing that it looks like on the client side you're dealing with a TV show, and on the server side its some player for a sport team?
I am creating an application to get some experience in jQuery Mobile and backbone. I have made a "restful" API with node.js that handles the data I need. It works fine with all my static pages I made in index.html. But when I need to create a page with data from a certain id I am a bit lost.
For example when I want to display all items(/items) I have a data-role=page with id items that list all items, but when I need to go to a detailed page for each item (/items/1) i want to create that details page whenever a user wants details on an item, in other words when a user visit the url spots#3 for example.
Is this possible?
my router: the model gives me all data i want
Spoter.Router = Backbone.Router.extend({
routes: {
"": "",
"spot#:id": "spotDetails"
},
//Details on a certain spot with id
spotDetails: function(id) {
var spotDetailsContentDiv = Spoter.spotDetailsContent;
spotDetailsContentDiv.empty();
var spot = new Spoter.spotModel({id: id});
spot.fetch({
successCallback: function(data) {
var spotDetailsView = new Spoter.spotDetailsView({
model: data
});
spotDetailsContentDiv.html(spotDetailsView.render().el);
}
});
}
});
View:
Spoter.spotDetailsView = Backbone.View.extend({
render:function () {
this.$el.html(this.template(this.model));
return this;
}
});
Template with underscore
<ul data-role="listview" data-theme="c" data-inset="true">
<li>
<a href="#">
<h1><%= this.model.name %></h1>
<p><%= this.model.description %></p>
</a>
</li>
</ul>
None of the answers I have found anywhere have worked. I am trying to extend the example in "Developing Backbone.js Applications" to upload files. Although the form has enctype="multipart/form-data," request.files is always undefined.
The form HTML is:
<form id="addBook" action="..." enctype="multipart/form-data">
<div>
<label for="coverImage">CoverImage: </label><input id="coverImage" name="coverImage" type="file" />
<label for="title">Title: </label><input id="title" type="text" />
<label for="author">Author: </label><input id="author" type="text" />
<label for="releaseDate">Release date: </label><input id="releaseDate" type="text" />
<label for="keywords">Keywords: </label><input id="keywords" type="text" />
<button id="add">Add</button>
</div>
</form>
The backbone that saves the new record is
addBook: function( e ) {
e.preventDefault();
var formData = {};
var reader = new FileReader();
$( '#addBook div' ).children( 'input' ).each( function( i, el ) {
if( $( el ).val() != '' )
{
if( el.id === 'keywords' ) {
formData[ el.id ] = [];
_.each( $( el ).val().split( ' ' ), function( keyword ) {
formData[ el.id ].push({ 'keyword': keyword });
});
} else if( el.id === 'releaseDate' ) {
formData[ el.id ] = $( '#releaseDate' ).datepicker( 'getDate' ).getTime();
} else {
formData[ el.id ] = $( el ).val();
}
}
});
console.log(formData);
this.collection.create( formData );
}
The Node being called.
//Insert a new book
app.post( '/api/books', function( request, response ) {
console.log(request.body);
console.log(request.files);
});
The value of coverimage send to node is correct, I just never get anything in request.files. I have a cool drag and drop I would like to use instead, but until I get this working I am stuck.
I tried the JQuery-file-upload, that got me nowhere.
If I had hair, I would be pulling it out right now.
I wouldn't be submitting the file as part of the model.save/collection.create(model).
What I've used is Plupload for a file upload manager, submitting a file to an upload handler. This upload handler either returns the path to the uploaded file, or fileId if a reference is stored in a database table.
From there I populate a property in my backbone model, then persist the model. You can have your model listenTo plupload, for an upload completed event or similar.
I'm also following the sample of the book "Developing Backbone.js Applications", I extended the functionality to upload images to a folder in the server and save the path in my model to show the correct images. It is working fine. I tried to use Plupload and other jquery plugins but I didn't like them. My sample is using ajax to upload images to the server and then using them. I read many posts referencing the use of iframes to have ajax functionality. The best approach for this I found is using the jquery.form.js to avoid postbacks and load the images in a nice way.
The running sample working fine with nodeJS:
https://github.com/albertomontellano/bookLibrarySampleNodeJS
I based my solution in the post of Mark Dawson:
http://markdawson.tumblr.com/post/18359176420/asynchronous-file-uploading-using-express-and-node-js
However, I had to correct a method of this post to make it work correctly:
app.post('/api/photos', function(req, res) {
var responseServerPath = 'images/' + req.files.userPhoto.name;
var serverPath = 'site/images/' + req.files.userPhoto.name;
console.log(req.files.userPhoto.path);
require('fs').rename(
req.files.userPhoto.path,
serverPath,
function(error) {
if(error) {
console.log(error);
res.send({
error: 'Ah crap! Something bad happened'
});
return;
}
res.send({
path: responseServerPath
});
}
);
});
I hope it helps.
Turned out I had to end up hiring someone to do it, because I can't find any examples online of anybody uploading a file through backbone, even without updating any database interaction. Everybody has the same basic advice about what tools to use to upload the files, but I can't for the life of me find ONE example of someone implementing it.
I am planning on making the code available to everybody, so they can see how it works.