I have created 2 buttons that allow a user to download a HTML table as TXT or Excel. The appropriate files are generated by my Rails app. Everything works fine except for IE. I tested IE11 on Win7.
Live example (See buttons at bottom): http://en.mycoursewalk.com/course_walk/distance_table/3575
HTML Code:
<i class="fa fa-file-excel-o fa-lg"></i> Export to Excel
<script>
var cw_id = <%= #coursewalk.id %>;
$(document).on("pageshow",function(event) {
$("#Export_Excel").click(function(event) {
export_table('xml');
});
});
function export_table(export_format) {
var table = $('#distance_table').tableToJSON();
window.open('/application/export_table/' + cw_id + '.' + export_format + '?table_type=distance_table&export_format=' + export_format + "&_json=" + encodeURIComponent(JSON.stringify(table)), "_self");
}
</script>
Controller:
def export_table
# Code here to create appropriate text or Excel file. Removed for clarity
formatted_data = ''
formatted_data << "test" + "\t" + "test2" + "\n"
i = Iconv.new('UTF-8','iso-8859-1')
formatted_data_utf8 = i.iconv(formatted_data)
send_data formatted_data_utf8, :filename => "test.txt", :type => "text/csv;charset=UTF-8", :disposition => "attachment"
end
In the IE Developer Tools and Console, IE shows "Navigation Occurred" and a complaint about DOCTYPE when you click on the Export buttons. Clicking on the DOCTYPE warning will actually load the TXT or Excel file into the console.
How can I fix this?
I fixed this issue by using rails templates instead as described in this Rail Cast:
http://railscasts.com/episodes/362-exporting-csv-and-excel?view=asciicast
Related
I have a Laravel 8 web project which need to stop downloading video files from my website. I need a function which will totally stop download & will say "The requested file doesn't exist" if the video file link input on IDM or at others downloader softwares. Tell me how can I stop?
View page & Controller code:
<video oncontextmenu="return false;" src="{{asset('uploads/drama-movie-video/trailers/'. $video->trailer)}}" controls controlsList="nodownload" width="250px" height="250px" poster="{{asset('images/profile1.jpg')}}">
</video>
**My video controller:**
public function show($id) {
//views count
$oldviews = Video_views::where('video_id', $id)->value('amount');
$newviews = $oldviews + 1 ;
$updateviews = Video_views::where('video_id', $id)
->update(['amount' => $newviews]);
//seen count
$visitor = request()->ip();
$searchvisitorip = Video_seen::where('video_id', $id)->where('visitor_ip', $visitor)->value('id');
if ($searchvisitorip < 1) {
$seen = new Video_seen;
$seen->video_id = $id;
$seen->visitor_ip = $visitor;
$seen->save();
}
$video = Video::find($id);
$user = Auth::User()->id;
$queryviewer= Viewer::where('video_id', $video->id)->where('viewer_id', $user)->value('viewer_id');
return view('frontend.pages.video.video.show', compact('video', 'queryviewer', 'user', 'newviews'));
}
I would like to pass google tag manager id based on the environment to my script in index.html in my vue app but I can't find a way to pass configs to a html file. Kindly assist.
Here is the script
<script>
(function (w, d, s, l, i) {
w[l] = w[l] || [];
w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l != "dataLayer" ? "&l=" + l : "";
j.async = true;
j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
f.parentNode.insertBefore(j, f);
})(window, document, "script", "dataLayer", "<env-gtm-id-goes-here>"
</script>
You can use the html interpolation. Refer here
In combination with the vue Environment Variables. Refer Here
For example:
make a new file name .env and make entry
VUE_APP_ENVARS=prod and use it inside your index.html with the html interpolation
<p>The username to test is <%= VUE_APP_ENVIR %></p>
Update: Since you need to access this variable in the <script> tag, use this
(window, document, "script", "dataLayer", "<%= VUE_APP_ENVIR %>"
I am trying to scrape data from this link https://www.flatstats.co.uk/racing-system-builder.php using scrapy.
I want to automate the ajax call using scrapy.
When I click "Full SP" Button (inspect in Firebug) the post parameter has the sql string which is "strange"
race|2|eq|Ordinary|0|~tRIDER_TYPE
What dialect is this?
My code :
import scrapy
import urllib
class FlatStat(scrapy.Spider):
name= "flatstat"
allowed_domains = ["flatstats.co.uk"]
start_urls = ["https://www.flatstats.co.uk/racing-system-builder.php"]
def parse(self, response):
query_lst = response.xpath('//table[#id="system"]//tr/td[last()]/text()').extract()
query_str = ' '.join(query_lst)
url = 'https://www.flatstats.co.uk/ajax/sb_report.php'
body_dict = {'a_e_max': '9.99',
'a_e_min': '0',
'arch_min': '0',
'exp_min': '0',
'report_type':'S',
# copied from the Post parameters by inspecting. Actually I tried everything.
'sqlFullString' : u'''Type%20(Rider)%7C%3D%7COrdinary%20(Exclude%20Amatr%2C%20App%2C%20Lady%20Races
)%7CAND%7Crace%7C2%7C0%7COrdinary%7C0%7C~tRIDER_TYPE%7C-t%7Ceq''',
#I tried copying this from the post parameters as well but no success.
#I also tried sql from the table //td text() which is "normal" sql but no success
'sqlString': query_str}
#here i tried everything FormRequest as well though there is no form.
return scrapy.Request(url, method="POST", body=urllib.urlencode(body_dict), callback=self.parse_page)
def parse_page(self, response):
with open("response.html", "w") as f:
f.write(response.body)
So questions are:
What is this sql.
Why isn't it returning me the required page. How can I run the right query?
I tried Selenium as well to click the button and let it do the stuff it self but that is another unsuccessful story. :(
It's not easy to say what the website creator is doing with the submitted sqlString. It probably means something very specific to how the data is processed by their backend.
This is an extract of the page JavaScript in-HTML code:
...
function system_report(type) {
sqlString = '', sqlFullString = '', rowcount = 0;
$('#system tr').each(function() {
if(rowcount > 0) {
var editdata = this.cells[6].innerHTML.split("|");
sqlString += editdata[0] + '|' + editdata[1] + '|' + editdata[7] + '|' + editdata[3] + '|' + editdata[4] + '|' + editdata[5] + '^';
sqlFullString += this.cells[0].innerHTML + '|' + encodeURIComponent(this.cells[1].innerHTML) + '|' + this.cells[2].innerHTML + '|' + this.cells[3].innerHTML + '|' + this.cells[6].innerHTML + '^';
}
rowcount++;
});
sqlString = sqlString.slice(0, -1)
...
Looks non trivial to reverse-engineer.
Although it's not a solution to your "sql" question above, I suggest that you try using splash (an alternative to selenium in some cases).
You can launch it with docker (the easiest way):
$ sudo docker run -p 5023:5023 -p 8050:8050 -p 8051:8051 scrapinghub/splash
With the following script:
function main(splash)
local url = splash.args.url
assert(splash:go(url))
assert(splash:wait(0.5))
-- this clicks the "Full SP" button
assert(splash:runjs("$('#b-full-report').click()"))
-- loading the report takes some time
assert(splash:wait(5))
return {
html = splash:html()
}
end
you can get the page HTML with the popup of the report.
You can integrate Splash with Scrapy using scrapyjs (a.k.a scrapy-splash)
See https://stackoverflow.com/a/35851072/ with an example how to do so with a custom script.
I'm looking for a way to give my SharePoint users a way to create new wiki pages from an existing template. In the process of researching I found a great walkthrough that seems to fit the need (http://www.mssharepointtips.com/tip.asp?id=1072&page=2), but I'm having trouble getting it to work. The problem seems to lie in the assignment of a path to PATHTOWIKI-- if I use "/Weekly Update Wiki", the script returns an error of "There is no Web named '/Weekly Update Wiki'." If I use "Weekly Update Wiki" without the forward slash, I instead get an error of "There is no Web named '/sites/[parentSite]/[childSite]/Weekly Update Wiki/Weekly Update Wiki'."
Any ideas about what I'm not understanding here?
function myCreateProject() {
// Configure these for your environment
// include no slashes in paths
var PATHTOWIKI = "Weekly Update Wiki";
var PATHTOPAGES = "Pages";
// file name only for template page, no extension
var TEMPLATEFILENAME = "Template";
var myPathToWiki = encodeURIComponent(PATHTOWIKI);
var myPathToPages = PATHTOPAGES + "%2f";
var myTemplateFileName = encodeURIComponent(TEMPLATEFILENAME) + "%2easpx";
var EnteredProject = document.getElementById("NewProjName");
var myNewName = EnteredProject.value;
if(myNewName == "") {
alert('Please enter a name for the new project page');
} else {
myNewName = encodeURIComponent(myNewName) + "%2easpx"
$.ajax({
url: PATHTOWIKI + "/_vti_bin/_vti_aut/author.dll",
data: ( "method=move+document%3a14%2e0%2e0%2e4730&service%5fname="
+ myPathToWiki +
"&oldUrl=" + myPathToPages + myTemplateFileName +
"&newUrl=" + myPathToPages + myNewName +
"&url%5flist=%5b%5d&rename%5foption=nochangeall&put%5foption=edit&docopy=true"
),
success: function(data) {
var rpcmsg1 = getMessage(data, "message=", "<p>");
$("#myInfo").append("<br />" + rpcmsg1);
if(rpcmsg1.indexOf("successfully") < 0) {
// get error info
var rpcmsg2 = getMessage(data, "msg=", "<li>");
$("#myInfo").append("<br />" + rpcmsg2 + "<br />");
} else {
$("#myInfo").append("<br />Go to new page<br />");
}
},
type: "POST",
beforeSend: function(XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("X-Vermeer-Content-Type",
"application/x-www-form-urlencoded");
}
});
}
}
Update: I figured out what needed to happen in my case. Since I couldn't get a grasp on the relative approach, I just went with the absolute path for PATHTOWIKI and slightly modified the append in the ajax call.
PATHTOWIKI:
var PATHTOWIKI = "https://[domain]/sites/[parentSite]/[childSite]";
append:
$("#myInfo").append("<br />Go to new page<br />");
The change in the latter line of code is subtle; since I used an absolute path in PATHTOWIKI, I just removed the leading forward slash in the anchor tag, so that <a href=\"/" became <a href=\"". This renders the script slightly less portable, but since it's a one-off effort I'll stick with this unless anything comes along to expand the scope.
I was playing around with Google Dart and chrome apps. I tried to select a single file: No problem here!
The code looks like this and prints the filename.
Future<ChooseEntryResult> res = chrome.fileSystem.chooseEntry(new ChooseEntryOptions());
res.then((ChooseEntryResult entry) {
print("entries: " + entry.entry.name);
});
But selecting multiple files does not work. In a native chrome app I can do:
chrome.fileSystem.chooseEntry({"acceptsMultiple":true}, function(entries) {
console.log(entries);
});
Even this code fails (I only added acceptsMultiple: false)
Future<ChooseEntryResult> res = chrome.fileSystem.chooseEntry(new ChooseEntryOptions(acceptsMultiple: false));
res.then((ChooseEntryResult entry) {
print("entries: " + entry.entry.name);
});
I would expect this to work:
Future<ChooseEntryResult> res = chrome.fileSystem.chooseEntry(new ChooseEntryOptions(acceptsMultiple: true));
res.then((ChooseEntryResult entry) {
print("entries: " + entry.entries);
});
But whenever I select multiple files the "entry" and "entries" fields of ChooseEntryResult gives me null. Has anyone managed to get this working?