Kotlin Jsoup web scrapping - kotlin

I'm practicing with Kotlin/Jsoup but I don't know what's wrong
Code to get:
<div class="player-container">
<script>
var tabsArray = new Object();
tabsArray['1'] = "<iframe width='100%' height='100%' src='/redirect.php?player=9&code=LmdHOcKJ4LMy3D5VQ8Nk1QxqZ4wPR2ni6nL8OMtdRHY&' frameborder='0' noresize scrolling='no' allowfullscreen></iframe>";
</script>
<div class="iframe-container" id="video_player">
</div>
My code:
app.get(data).document.select("is-9-desktop").forEach {
val urlDecoded = it.select("iframe").attr("src:containsOwn(redirect.php?player=9&)")
val url2 = (urlDecoded).replace("code=", "https://www.fembed.com/v/")
val url = (url2).substring(0,url2.indexOf("&thumbnail="));
if (url.startsWith("https://www.fembed.com")) {
val extractor = FEmbed()
extractor.getUrl(url).forEach { link ->
callback.invoke(link)
}

Related

Can you pretty print IHtmlContent?

If I have a IHtmlContent can I pretty print it?
Example:
var html = new HtmlString("<article><h2>Hello!</h2></article>");
I want it pretty printed with line breaks and indention into:
<article>
<h2>Hello!</h2>
</article>
I do not want:
<article><h2>Hello!</h2></article>
You could try to JavaScript to add the line breaks and indention into, then, use <pre> tag to render the html content. Please check the following sample:
Index.cshtml:
#{
var html ="<article><h2>Hello!</h2></article>";
}
<div id="printdiv">
#Html.Raw(html)
</div>
<div id="output">
</div>
<input type='button' id='btn' value='Print' onclick='printDiv();'>
#section Scripts{
<script>
function printDiv() {
var divToPrint = document.getElementById('printdiv');
//display the pretty html content in the web page.
document.getElementById("output").innerHTML = "<pre>" + process(divToPrint.innerHTML).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</pre>";
//create a new window to print the div content.
var newWin = window.open('', 'Print-Window');
newWin.document.open();
newWin.document.write('<html><body onload="window.print()"><pre>' + process(divToPrint.innerHTML).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + '</pre></body></html>');
newWin.document.close();
setTimeout(function () { newWin.close(); }, 10);
}
function process(str) {
var div = document.createElement('div');
div.innerHTML = str.trim();
return format(div, 0).innerHTML;
}
function format(node, level) {
var indentBefore = new Array(level++ + 1).join(' '),
indentAfter = new Array(level - 1).join(' '),
textNode;
for (var i = 0; i < node.children.length; i++) {
textNode = document.createTextNode('\n' + indentBefore);
node.insertBefore(textNode, node.children[i]);
format(node.children[i], level);
if (node.lastElementChild == node.children[i]) {
textNode = document.createTextNode('\n' + indentAfter);
node.appendChild(textNode);
}
}
return node;
}
</script>
}
The result like this:
You can parse it XML with XDocument.Parse then use XmlWriter with its settings set to Indent to true. Worked for me on my HTML too.
var html = new HtmlString("<article><h2>Hello!</h2></article>");
using var writer = new StringWriter();
html.WriteTo(writer, HtmlEncoder.Default);
var htmlString = writer.ToString();
var settings = new XmlWriterSettings
{
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8,
Indent = true,
};
var sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb, settings))
{
XDocument.Parse(htmlString).Save(writer);
}
Console.WriteLine(sb.ToString());

ngIf on div containing dynamically generated compoent

I have a dynamically generated component which generates on run time. following is the .ts file
`#ViewChild(TermsheetDirective) termHost: TermsheetDirective;
#Input() term;
#Input() title = '';
#Input() Qnumber = '';
#Output() result = new EventEmitter<any>();
section_title = '';
number = '';
component = [];
show = false;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
}
ngOnInit() {
this.number = this.Qnumber;
this.section_title = this.title;
}
ngAfterViewInit() {
}
ngAfterContentInit() {
}
loadcomponents() {
console.log(this.termHost);
for (let j = 0; j < this.term.components.length; j++) {
let termItem = this.term.components[j];
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(termItem.component);
let viewContainerRef = this.termHost.viewContainerRef;
let componentRef = viewContainerRef.createComponent(componentFactory);
(<TermComponent>componentRef.instance).data = termItem.data;
this.component[j] = componentRef;
}
}
getdata() {
let output = [];
for (let i = 0; i < this.component.length; i++) {
let temp = {
slug : this.section_title,
type : this.component[i].type,
value : this.component[i]._component.getdata()
};
output[i] = temp;
}
this.result.emit(output);
return output;
}
showcomp() {
console.log("In if");
this.show = true;
this.loadcomponents();
}
hidecomp() {
this.show = false;
}`
and following is my html
`<div class="main">
<div class="div_for_ques">
<div class="question">
<div class="number">
{{number}}
</div>
<div class="textbox">
{{section_title}}
</div>
<div class="arrow" *ngIf="!show">
<a (click)="showcomp()" class="glyphicon"></a>
</div>
<div class="arrow" *ngIf="show">
<a (click)="hidecomp()" class="glyphicon"></a>
</div>
</div>
<div class="sec_two" *ngIf="show">
<ng-template term-host></ng-template>
</div>
</div>
</div>`
I want the div that contains the dynamically generated component to appear only when a certain button is clicked. but i am having following response.
But when I try to show this div without ngIf it is working fine. But with ngIf termHost is undefined! Can someone please explain what is happening here!
Well, you are trying to reference to viewContainerRef before change detection cycle has completed, that is why you get that error.
There is more than one solution to this, you can use a setter for the ViewChild, that will be called once after the *ngIf becomes true
e.g
#ViewChild('') set content(x:x) {
this.x = x;
}
OR you can inject the change detector manually
constructor(private changeDetector : ChangeDetectorRef) {}
You can then call it after you click your button
this.changeDetector.detectChanges();
OR You can also use a QueryList to achieve the same effect because you can subscribe to changes
Please apply these techniques to your logic to solve your problem

File upload using dropzon.js

I'm trying to upload files using dropzone.js
View:
#using (Html.BeginForm("SaveMethod", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data", #class = "dropzone", id = "js-upload-form" }))
........................
<div class="form-inline">
<div class="form-group">
<input type="file" name="MainFile" id="js-upload-files"/>
</div>
<div class="upload-drop-zone" id="drop-zone">
Just drag and drop files here
</div>
<div class="dropzone-previews"></div>
</div>
JS:
var formData = null;
formData = new FormData($form[0]);
dropZone.ondrop = function (e) {
e.preventDefault();
this.className = 'upload-drop-zone';
startUpload(e.dataTransfer.files)
}
dropZone.ondragover = function () {
this.className = 'upload-drop-zone drop';
return false;
}
dropZone.ondragleave = function () {
this.className = 'upload-drop-zone';
return false;
}
var startUpload = function (files) {
for (var i = 0; i < files.length; i++) {
formData.append(files[i].name, files[i]);
}
}
Controller:
[HttpPost]
public JsonResult SaveMethod(TaskManage objTaskManage, HttpPostedFileBase files)
{
}
Now, after submit, i want to have files that was dropped on drop area along with the files attached in upload control. Here, what happens is files giving me null and when i use Request.Files["MainFile"] i get only the files dropped on dropzone area, it doesn't show me the file i have upload to control.
I'm not able to find out the issue. Any help is really appreciated.
File upload in ASP.NET MVC using Dropzone JS and HTML5
You can download the latest version from the official site here http://www.dropzonejs.com/ and also we can install using the nuget package manage console by the following command Package Manager Console
PM> Install-Package dropzone
Now create a bundle for your script file in BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/dropzonescripts").Include(
"~/Scripts/dropzone/dropzone.js"));
Similarly add the dropzone stylesheet in the BundleConfig.cs
bundles.Add(new StyleBundle("~/Content/dropzonescss").Include(
"~/Scripts/dropzone/css/basic.css",
"~/Scripts/dropzone/css/dropzone.css"));
Now add the bundle reference in your _Layout page
View Page:
<div class="jumbotron">
<form action="~/Home/SaveUploadedFile" method="post" enctype="multipart/form-data" class="dropzone" id="dropzoneForm" style="width: 50px; background: none; border: none;">
<div class="fallback">
<input name="file" type="file" multiple />
<input type="submit" value="Upload" />
</div>
</form>
</div>
Controller:
public ActionResult SaveUploadedFile()
{
bool isSavedSuccessfully = true;
string fName = "";
try{
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//Save file content goes here
fName = file.FileName;
if (file != null && file.ContentLength > 0)
{
var originalDirectory = new DirectoryInfo(string.Format("{0}Images\\WallImages", Server.MapPath(#"\")));
string pathString = System.IO.Path.Combine(originalDirectory.ToString(), "imagepath");
var fileName1 = Path.GetFileName(file.FileName);
bool isExists = System.IO.Directory.Exists(pathString);
if (!isExists)
System.IO.Directory.CreateDirectory(pathString);
var path = string.Format("{0}\\{1}", pathString, file.FileName);
file.SaveAs(path);
}
}
}
catch(Exception ex)
{
isSavedSuccessfully = false;
}
if (isSavedSuccessfully)
{
return Json(new { Message = fName });
}
else
{
return Json(new { Message = "Error in saving file" });
}
}
Now add the following script to your view page at the and in script tag.
//File Upload response from the server
Dropzone.options.dropzoneForm = {
init: function () {
this.on("complete", function (data) {
//var res = eval('(' + data.xhr.responseText + ')');
var res = JSON.parse(data.xhr.responseText);
});
}
};
Here you can see the response from server.

Banking API queried by Javascript

I am finalising a college project and I am stuck.
I have created an API in netbeans and it is working fine.
Returing e.g.
<?xml version="1.0" encoding="UTF-8"?>
<accountholder>
<accountnumber>45672</accountnumber>
<address>234 THE BANK, DUBLIN 1</address>
<balance>763.32</balance>
<email>JOHANN#SMITH.COM</email>
<firstname>JOHANN</firstname>
<id>1</id>
<lastname>SMITH</lastname>
<pinnumber>1234</pinnumber>
</accountholder>
Now I am trying to create a javascript to return data when searching by Id.
<script language="javascript" type="text/javascript">
var request = null;
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("MsXML2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = null;
}
}
}
if (request == null)
alert("Error creating request object!");
}
function getMessage()
{
createRequest();
var accountholderid = document.getElementById("Id").value;
id=eval(accountholderid);
var url = "http://localhost:8080/BankProjectApi/webresources/bankprojectapi.accountholder/"+id;
request.onreadystatechange = handleResponse;
request.open("GET", url, true);
request.send(null);
}
function handleResponse() {
if (request.readyState==4 && request.status==200)
{
var xmlDocument=request.responseXML;
var firstname = xmlDocument.getElementsByTagName("firstname");
var lastname = xmlDocument.getElementsByTagName("lastname");
var accountnumber = xmlDocument.getElementsByTagName("accountnumber");
for(var i=0; i<firstname.length; i++) {
var firstname = firstname[i].childNodes[0].nodeValue;
var lastname = lastname[i].childNodes[0].nodeValue;
var accountnumber= accountnumber[i].childNodes[0].nodeValue;
document.getElementById('lastname').value=firstname;
document.getElementById('firstname').value=lastname;
document.getElementById('accountnumber').value=accountnumber;
}
}
}
</script>
In the body I have an input textfield with a button with an on click:
<td>Enter Account holder ID : </td>
<td><input type="text" id="playerid" size="10"/>
<input type="button" value="Get Details" onclick="getMessage()"/>
</tr>
<tr>
<td>Account holder Last Name : </td>
<td> <input type="text" id="lastname" size="10"/> </td>
</tr>
<tr>
<td>Account holder First Name : </td>
<td> <input type="text" id="firstname" size="10"/> </td>
</tr>
<tr>
<td>Account number : </td>
<td> <input type="text" id="accountnumber" size="10"/> </td>
</tr>
What am I missing as it is not returning anything :(
I believe your id value for the 'accountholderid' was looking for 'Id' instead of 'playerid'.
May I ask why you are calling 'eval' on the value? Do you need parseInt?
(function () {
var request = null;
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject('MsXML2.XMLHTTP');
} catch (othermicrosoft) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
} catch (failed) {
request = null;
}
}
}
if (request === null) {
alert('Error creating request object!');
}
}
function getMessage() {
createRequest();
var accountholderid = document.getElementById('playerid').value,
id = eval(accountholderid),
url = 'http://localhost:8080/BankProjectApi/webresources/bankprojectapi.accountholder/' + id;
request.onreadystatechange = handleResponse;
request.open("GET", url, true);
request.send(null);
}
function handleResponse() {
if (request.readyState === 4 && request.status === 200) {
var xmlDocument = request.responseXML,
firstname = xmlDocument.getElementsByTagName('firstname'),
lastname = xmlDocument.getElementsByTagName('lastname'),
accountnumber = xmlDocument.getElementsByTagName('accountnumber');
for(var i = 0, max = firstname.length; i < max; i += 1) {
var firstname = firstname[i].childNodes[0].nodeValue,
lastname = lastname[i].childNodes[0].nodeValue,
accountnumber = accountnumber[i].childNodes[0].nodeValue;
document.getElementById('lastname').value = firstname;
document.getElementById('firstname').value = lastname;
document.getElementById('accountnumber').value = accountnumber;
}
}
}
}());
Also, I did a quick refactoring of your code to aid in my assessing the issue, adhere to more community conventions as well as avoid common JS pitfalls. (ex. closure, missing var declarations, ===, curlys everywhere, single variable pattern, and some others).

Rally App SDK: Is there a way to have variable columns for table?

Using the Rally App SDK, is there a way to create a table with a variable number of columns? For example, for a selected release, the columns are the iterations within that release date range, and the rows are each project.
I have all of the data I want to display, but not sure how to create the table.
Here's an example app that dynamically builds a table config with Iteration Names as columns and then adds some dummy data to it. Not too exciting, but it illustrates the idea.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- Copyright (c) 2002-2011 Rally Software Development Corp. All rights reserved. -->
<html>
<head>
<title>Iterations as Table Columns</title>
<meta name="Name" content="App: Iterations as Table Columns"/>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.29/sdk.js"></script>
<script type="text/javascript">
function iterationsAsTableColumns(rallyDataSource)
{
var wait = null;
var table = null;
var tableHolder = null;
// private method the builds the table of Iteration columns and your info
function showResults(results)
{
if (wait) {
wait.hide();
wait = null;
}
if (table) {
table.destroy();
}
var myIterations = results.iterations;
if (myIterations.length === 0) {
tableHolder.innerHTML = "No iterations were found";
return;
}
var columnKeys = new Array();
var columnHeaders = new Array();
var columnWidths = new Array();
var columnWidthValue = '80px';
var keyName;
// Dynamically build column config arrays for table config
for (i=0; i<myIterations.length;i++){
keyName = "Column"+i;
columnKeys.push(keyName);
columnHeaders.push("'" + myIterations[i].Name + "'");
columnWidths.push("'" + columnWidthValue + "'");
}
var config = { 'columnKeys' : columnKeys,
'columnHeaders' : columnHeaders,
'columnWidths' : columnWidths
};
table = new rally.sdk.ui.Table(config);
var cellValue;
var propertyAttributeStatement;
var rowData = new Array();
for (i=0;i<10;i++){
// create Object for row data
rowItem = new Object();
for (j=0; j<columnKeys.length;j++){
cellValue = "Cell[" + i + "][" + j + "] = Your Data Here";
propertyAttributeStatement = "rowItem." + columnKeys[j] + " = '"+cellValue+"';";
eval(propertyAttributeStatement);
}
rowData.push(rowItem);
}
table.addRows(rowData);
table.display(tableHolder);
}
//private method to query for iterations that get listed as columns
function runMainQuery(sender, eventArgs) {
var queryCriteria = '(Project.Name = "Avalanche Hazard Mapping"")';
var queryConfig =
{
key : "iterations",
type : "Iteration",
fetch : "FormattedID,Name,Project,StartDate,EndDate,CreationDate",
order : "CreationDate desc",
};
tableHolder.innerHTML = "";
wait = new rally.sdk.ui.basic.Wait({});
wait.display(tableHolder);
rallyDataSource.findAll(queryConfig, showResults);
}
//private method to start building controls on page
function initPage() {
buttonSpan = document.getElementById('buttonSpan');
tableHolder = document.getElementById('table');
var buttonConfig = {
text: "Show Table",
value: "myValue"
};
var showTableButton = new rally.sdk.ui.basic.Button(buttonConfig);
showTableButton.display(buttonSpan, runMainQuery);
}
// only public method
this.display = function() {
rally.sdk.ui.AppHeader.showPageTools(true);
initPage();
};
}
</script>
<script type="text/javascript">
rally.addOnLoad(function() {
var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
var iterationsAsTableColumnsExample = new iterationsAsTableColumns(rallyDataSource);
iterationsAsTableColumnsExample.display();
});
</script>
</head>
<body>
<div>
<span id="buttonSpan"></span>
</div>
<div style="height: 15px;"> </div>
<div id="table"></div>
</body>
</html>