I am working on Casper JS web scraping, for now I have scraped the title from a site. I am making ajax request to the php file where I am collecting the data through post, but the data is not being sent through it while the response status is 200 and OK I don't know what is causing the problem.
The rest of the data is inserted successfully into the table, but not the title.
var casper = require('casper').create();
casper.start("https://www.google.com/");
casper.then(function(){
var data = this.evaluate(function(){
var title = document.getElementsByTagName('title')[0].textContent;
return title;
})
console.log(data);
casper.thenOpen("http://localhost/fiverr/Crawl%20The%20Jobs/modal_scripts.php",{method:"POST",data:data+"&crawled_jobs=true"}).then(function(res){
console.log(res.status);
})
})
casper.run();
The PHP script, I am collecting data in :
if (isset($_POST["crawled_jobs"])) {
$title = $_POST["data"];
$jobs_list_insert = "INSERT INTO jobs VALUES(null,'$title','nady','ahmad','kahn','yess','yesss')";
$con->query($jobs_list_insert);
}
Found a solution :
var i = 0;
console.log("Data Length : " + d.length);
function sendData(i) {
console.log("Posting Data...");
casper.thenOpen("http://localhost/fiverr/Crawl%20The%20Jobs/modal_scripts.php", {
method: "POST",
data: "title=" + d[i].title + "&loc=" + d[i].loc + "&day=" + d[i].day + "&salary=" + d[i].salary + "&link=" + d[i].link + "&logo=" + d[i].compLogo + "&crawled_jobs=true",
async: false
}).then(function(res) {
console.log(res.status);
sendData(i + 1);
})
}
sendData(i);
Related
I currently have a Page Fragment with the following code that creates an entry for a datasource and sends out an email (code below) notifying everyone.
Button:
newSalesEmailMessage(widget);
widget.datasource.createItem();
app.closeDialog();
Client Script Email notification code:
/**
* Calls a server method to send an email.
* #param {Widget} sendButton - widget that triggered the action.
*/
function newSalesEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var fullName = app.datasources.Directory.item.FullName;
var htmlbody = '<b><font size="3">' + fullName + '</font></b>' + ' has created a new sales entry for: ' +
'<h1><span style="color:#2196F3">' +pageWidgets.ProjectName.value + '</h1>' +
'<p>Contact: <b>' + pageWidgets.Contact.value + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'test#email.com',
'New Sales Entry for: ' + pageWidgets.ProjectName.value,
htmlbody);
}
onCreate code for the Model:
// onCreate
var email = Session.getActiveUser().getEmail();
var directoryQuery = app.models.Directory.newQuery();
directoryQuery.filters.PrimaryEmail._equals = email;
var reporter = directoryQuery.run()[0];
record.reported_by = email;
record.reported_full_name = reporter.FullName;
record.Date = new Date();
Everything works except for the fullName option. It keeps pulling my name even when another user creates an entry (maybe because I am an admin?). I have a Directory Model setup and that seems to work for when I am displaying the full name for a users's comments.
I would like to have fullName = the name of the person currently creating the entry.
Thank you for your help!
App Startup Script:
// App startup script
// CurrentUser - assuming that it is Directory model's datasource
// configured to load record for current user.
loader.suspendLoad();
app.datasources.Directory.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
You need to filter your Directory model datasource. If you are planning to use it for different purposes, then I'll recommend to create dedicated datasource for current user. You can filter it on server (preferable) or client side:
Filter on server, load on client:
// Directory model's Server Script for Current User datasource
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
return query.run();
// ------------------------
// Your startup script will remain almost the same:
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Client-only:
var currentUserDs = app.datasources.CurrentUser;
currentUserDs.query.filters.PrimaryEmail._equals = app.user.email;
loader.suspendLoad();
currentUserDs.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Thank you to Pavel. Everything worked, but it took me a few to understand exactly what I needed to do. For those who want to try and replicate what I did here were the steps.
First I had to create a Directory Model.
Then under the App Settings section for the app itself (click the gear) I put the following code under the App Startup Script - Client Script section:
loader.suspendLoad();
app.datasources.CurrentUser.load({
success: function() {
loader.resumeLoad();
},
failure: function(error) {
// TODO: Handle error
}
});
Next I went under the Datasources section for the Directory model and added a datasource called CurrentUser.
In the Query - Server Script section I put:
var query = app.models.Directory.newQuery();
query.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
return query.run();
This filters the datasource so that the only entry in there is the current user. Then I adjusted my "var fullName" in the email Client Script to point to the new datasource:
/**
* Calls a server method to send an email.
* #param {Widget} sendButton - widget that triggered the action.
*/
function newSalesEmailMessage(sendButton) {
var pageWidgets = sendButton.root.descendants;
var fullName = app.datasources.CurrentUser.item.FullName;
var htmlbody = '<b><font size="3">' + fullName + '</font></b>' + ' has created a new sales entry for: ' +
'<h1><span style="color:#2196F3">' +pageWidgets.ProjectName.value + '</h1>' +
'<p>Contact: <b>' + pageWidgets.Contact.value + '</b>' +
'<p>Sales Person: <b>' + pageWidgets.SalesPerson.value + '</b>' +
'<p>Notes: <b>' + pageWidgets.Notes.value + '</b>';
google.script.run
.withSuccessHandler(function() {
})
.withFailureHandler(function(err) {
console.error(JSON.stringify(err));
})
.sendEmailCreate(
'test#email.com',
'New Sales Entry for: ' + pageWidgets.ProjectName.value,
htmlbody);
}
Have a question regarding contentsync phonegap plugin (https://www.npmjs.com/package/phonegap-plugin-contentsync).
Will be very appreciated if someone could help.
The core of the problem is that my REST server allowing me to download .epub files (witch are same as .zip) only by sending GET request similar to:
https://test-api.books.com/api/getPublishedEpub?session_hash=1235&publication_id=abv1243'
Providing this link to the plugin '.sync' call I get a 'Invalid request method' response from the server...
While trying to download ordinary .zip everything works just fine.
var pub_id = $scope.currentBook.publication_id, epubUrl = 'https://test-api.books.com/api/getEpub?session_hash='
+ $rootScope.sessionHash+ '&publication_id=' + pub_id;
var downloadBtn = document.getElementById("downloadBtn");
console.log('Download cliked');
var sync = ContentSync.sync({ src: epubUrl, id: 'book'+ pub_id});
sync.on('progress', function (data) {
downloadBtn.innerHTML = "Downloading: " + data.progress + "%";
});
sync.on('complete', function (data) {
console.log(data.localPath);
for (var x = 1; x <= 17; x++) {
var fileUrl = "file://" + data.localPath;
console.log(fileUrl);
}
downloadBtn.innerHTML = 'Download';
});
I've updated my meteor to 1.2, and I'm now trying to use the email attachment feature, but not sure how to.
Meteor's guide says refer to this, but it's not very helpful..
if(true == true){
var dataAttachments = attachment;
var dataText =
"Client Name: " + name +
"\rEmail: " + email +
"\rPhone: " + phone +
"\rCompany: " + company +
"\rDeliverables: " + deliverables +
"\rCopywriting: " + copywriting +
"\rPrint Services: " + print +
"\rIllustration: " + illustration +
"\rphotography: " + photography +
"\rTimelines: " + timelines +
"\rBudget: " + budget +
"\rDescription: " + description;
Meteor.call('sendEmail', dataText, dataAttachment);
//throwAlert is my helper method which creates popup with message
alert('Email sent');
}else{
alert('An error occurred. Sorry');
return false;
}
}
});
and
Meteor.methods({
sendEmail: function (text) {
check([text], [String]);
this.unblock();
Email.send({
to: 'jaeeun#antarcti.cc',
from: 'contact#myClientProject.com',
subject: 'New message from contact form',
text: text
});
Email.send().addAttachment(attachment);
}
});
I would suggest installing this package: https://atmospherejs.com/ashutosh/email-att
Then do:
var attachments = [];
attachments.push({filename: "xxx", filePath: "xxx"});
var email = {
from: "test#gmail.com",
to: "test2#gmail.com",
subject: "Test!",
text: "Text!"
attachmentOptions: attachments
};
Meteor.call('send_one_email_with_attachments', email, function(){});
Meteor.methods({
send_one_email_with_attachments: function(email){
this.unblock();
EmailAtt.send(email);
};
});
This made my life a lot easier after I fought Meteor's built-in email for a while. It even works side-by-side, so you can still use your old non-attachment email functions!
In my meteor app, I'm doing infinite scrolling so I must have a limit set on my subscriptions in order to achieve this, but I also need to show the total count from that same collection and update it if the count changes. How would I achieve that?
I have a partial solution that achieves this but only returns the paginated counts, as follows:
function getTotalCount(system) {
var user = Meteor.user(),
queryObject = getSystemQueryObject(system);
if (queryObject) {
var query = queryObject.find({$and: [
{user: user.username},
{status: {$nin: status_complete}}
]});
var count = 0;
var handle = query.observeChanges({
added: function (id, user) {
$('#' + system + 'Count').text(++count);
$('#' + system + 'Count').addClass("ma-count-badge");
console.log(system + " count incremented: " + count);
},
removed: function () {
$('#' + system + 'Count').text(--count);
$('#' + system + 'Count').addClass("ma-count-badge");
console.log(system + " count decremented: " + count);
}
});
}
else {
return 0;
}
}
The other way is to push this method up to the server as a server method, but then it is not reactive, as follows:
Meteor.call('getSystemsTotalCount', system, function (err, counted) {
if (err) {
throw err;
}
if (counted > 0) {
$('#' + system + 'Count').text(counted);
$('#' + system + 'Count').addClass("ma-count-badge");
}
Session.get('listLimit');
});
}
you can to get the count with following way
var count= queryObject.find({$and: [
{user: user.username},
{status: {$nin: status_complete}}
]}).count();
after that, you can to save in a Session
Session('countCollection',count);
if the collection changes your Session also it will do
So the trick really is to combine both options I have in the question. The first part adds reactivity to adds/deletes and the second part calls out to the server to go get the total count. Now my code looks like:
query.observeChanges({
added: function(id, user) { updateListCount(system);},
removed: function(id) { updateListCount(system);}
});
And I just wrap the Method.call from the second excerpt above with a function called updateListCount invoked by the above. This addresses the issue.
I have a few textboxes on a form and when the user submits I want to capture the data and insert it into a database.
Here is what my code looks like
// Called just before the form is submitted.
beforeSubmit: function(data)
{
var item = $("[id$='item']");
var category = $("[id$='category']");
var record = $("[id$='record']");
var json = "{'ItemName':'" + escape(item.val()) +
"','CategoryID':'" + category.val() + "','RecordID':'" + record.val() + "'}";
//This page is where data is to be retrieved and processed.
var ajaxPage = "DataProcessor.aspx?Save=1";
var options =
{
type: "POST",
url: ajaxPage,
data: json,
contentType: "application/json;charset=utf-8",
dataType: "json",
async: false,
success: function(response)
{
alert("success: " + response);
},
error: function(msg)
{
alert("failed: " + msg);
}
};
//Execute the Ajax call and get a response.
var returnText = $.ajax(options).responseText;
if (returnText == 1) {
record.html(returnText);
$("#divMsg").html("<font color=blue>Record saved successfully.</font>");
}
else
{
record.html(returnText);
$("#divMsg").html("<font color=red>Record not saved successfully.</font>");
}
// $("#data").html("<font color=blue>Data sent to the server :</font> <br />" + $.param(data));
},
Here is what data is sent to the server: if I uncomment the following line.
// $("#data").html("<font color=blue>Data sent to the server :</font> <br />" + $.param(data));
__VIEWSTATE=%2FwEPDwULLTE4ODM1ODM4NDFkZOFEQfA7cHuTisEwOQmIaj1nYR23&__EVENTVALIDATION=%2FwEWDwLuksaHBgLniKOABAKV8o75BgLlosbxAgKUjpHvCALf9YLVCgLCtfnhAQKyqcC9BQL357nNAQLW9%2FeuDQKvpuq2CALyveCRDwKgoPWXDAKhwImNCwKiwImN &day_fi=12&month_fi=12&year_fi=1234&lastFour_fi=777&countryPrefix_fi=1&areaCode_fi=555-555&phoneNumber_fi=5555&email_fi=nisardotnet%40gmail.com&username=nisarkhan&password=123456&retypePassword=123456
Nisardotnet - are you working in C#? You've got way too much going on here. You can cut down your code by half using web methods - also, get rid of viewstate - you don't need it (remove the form from the page)
If your working in C# let me know and I can help.
Rob
****APPEND****
Ok - I built a simple "grab input values and update DB" thing - it's on my site here.
Give me a shout if you've got any questions.
Rob
****APPEND****
Ok, so in your class file you could have
internal static void updateDB(String values)
{
// do something with 'values'
}
Then in your aspx page you can call it like so...
[WebMethod]
public static void updateDB(String values)
{
yourClass.updateDB(values);
}
That should work.
You should be able to pull it all out of the Request.Form.