I'm trying to write an AppleScript that saves and downloads all the urls from a particular part of a webpage (a table) and saves them into a folder. All the links are either pdfs or videos that link to Youtube. The table I want to get the links from is organized by week, date and material. I want a folder containing all the weeks, and then inside would be a folder for each date, and another folder that contains the material for that date. (MyStuff/Week/Date/Material)
e.g.
<div class="table">
<div class="row">
<div class="topcell">Week </div>
<div class="topcell">Date</div>
<div class="topcell">Material</div>
</div>
</div> <!-- end table-->
From some research I've seen that some people are using JavaScript in their implementations to open the document? http://macscripter.net/viewtopic.php?id=20287 I tried using something like this but couldn't get it to compile.
I'm completely new at this, so any help would be appreciated! :)
What I have so far:
tell application "Finder"
set p1 to path to user/Desktop
make new folder at p with properties {name:"AllMaterial"}
--Make AllMaterial Folder--
set p2 to path to user/Desktop/AllMaterial
repeat with i from 1 to 18
make new folder at p2 with properties {name:"Week" + i}
--Make all the weeks--
--in each week, make 3 days--
set p3 to path3 to user/Desktop/AllMaterial/"Week" + i
repeat with j from 1 to 3
make new folder at p2 with properties {name:"Day" + j}
end repeat
end repeat
--Make all the days--
end
set siteURL to "XXX"
tell application " Safari"
activate
open location siteURL
--wait until page loaded
if my page_loaded(20) is false then error numner - 128
set numLinks to (do JavaScript "document.links.length" in document1)
--(do JavaScript "document.body.table.links.length" in document1)--
--get num of links --(doesn't account for the "table" that I want ^^. There are multiple different links on the page )
set count to numLinks - 1,
set thisLink to "",
set f to false
repeat with i from 0 to count
set thisLink to do JavaScript
end tell
The question is are you wanting to learn how to do it or are you just wanting someone to provide you a completed script? I can help with the former rather than the later.
To learn how to write the script you need to understand what you trying to achieve and the tools you are using to get the job done.
Three things you must learn, or understand, to solve the problem you are dealing with: Applescript, Javascript and the Document Object Model.
JS & the DOM
First of all, let's deal with the content and why you can't grab it with Javascript:
<div class="table">
<div class="row">
<div class="topcell">Week </div>
<div class="topcell">Date</div>
<div class="topcell">Material</div>
</div>
</div> <!-- end table-->
This is NOT a table!
These are divs with classes that are laid out in such a way using CSS to look like a table. Which is why you are having issues navigating the DOM of the page.
(do JavaScript "document.body.table.links.length" in document1)--
--get num of links --(doesn't account for the "table" that I want ^^. There are multiple different links on the page )
This does not work because there is NO TABLE!
You need to retrieve the links from the right place. No real table there, each is a div.
I would love to show you a working example, but the 'table' does not contain enough to give a working example. Where exactly are the links?
So, let's make a working example
<div class="table">
<div class="row">
<div class="topcell">Week</div>
<div class="example">
TEST
</div>
<div class="topcell">Date</div>
<div class="topcell">Material</div>
</div>
</div> <!-- end table-->
Now we know where the links are, but you need to understand the DOM...
The following:
document.getElementsByClassName('example')[0].getElementsByTagName('a')[0].href;
would get the href of the first a link of the first element of the document whose class name is example (0 being first in Javascript). We move up to the next a by going to 1:
document.getElementsByClassName('example')[0].getElementsByTagName('a')[1].href;
This is not the method to use for your issue, but is a good example of where you need to head.
You can read more about the navigating the DOM with Javascript here or tons of places, just google it.
Applescript
The only reason you are using applescript is because you are on a mac... You don't need to learn applescript to get this done, but it wouldn't hurt.
You do need to learn to do it properly though...Zero is correct, your Applescript is all wrong on many levels...
Small steps, but here is an example of something like how it should be
tell application "Finder"
set p1 to (path to desktop folder) as string
--Make AllMaterial Folder--
try
make new folder at p1 with properties {name:"AllMaterial"}
on error
--it exists! IT WILL ERROR IF THERE IS A FOLDER ALREADY
end try
set p2 to p1 & "AllMaterial" as string
repeat with i from 1 to 18
set thisfolder to make new folder at p2 with properties {name:"Week" & i as string}
--Make all the weeks--
--in each week, make 3 days--
repeat with j from 1 to 3
set thisdaysfolder to make new folder at thisfolder with properties {name:"Day" & j as string}
---WHILE IN THIS LOOP thisdaysfolder IS THE REFERENCE TO THE FOLDER TO SAVE IN… SO HERE IS WHERE YOU SAVE TO OR SOME ORDER OR LOGIC...
end repeat
end repeat
end tell
TYING IT TOGETHER
Bringing it all together to make a complete script depends on the actual data on the website.
The part that grabs the data from the website needs to store the data into applescript lists or possibly grab the data in the repeat when making the folders, etc... it's up to you the coder really.
In the end you need to save the files and you will most likely want to use cURL via shell script and some quoted forms:
do shell script "curl -f " & quoted form of thisURL & " -o " & quoted form of (POSIX path of savelocation) & filesname ---(this is a variable with the file name)
This is not a complete solution obviously but will get you going in the right direction.
Related
So this is a slightly obscure one.
I'm using Formidable Forms Pro on Wordpress to make quite a complex form. I use a Dynamic Field (who's selections come from entries from another form, hence dynamic) where users can make multiple selections.
I then use a Dynamic List Field to show the users choices more visually.
That image doesn't look too bad, not the best styling but I'm trying to get the mechanics right before making it look pretty.
The styling is in place because I'm hiding commas put in dynamically by Formidable Forms. Herein lies the issue.
This approach would work fine if I wanted the list to appear one on top of the other, but anticipating that users may want to make 10 or more selections in some cases, the list will start to take up too much of the screen.
Now, there are plenty of examples out there of how to remove delimiters from strings and arrays (I believe this is an array of strings,) but, I have no access to either to make the variable to allow that procedure to happen. Leaving it as it is means I can't use CSS Grid to style the list as my hope is to use the repeat auto-fit method to align them all side by side when there's enough space, as the commas are considered a child of the grid element like the list elements.
Inspecting the code shows that there are no html elements encasing the commas so there's no hope to use Javascript there either to remove commas within a class or whatever.
If it's possible for anyone with the know how to point me in the right direction it would be gratefully appreciated.
Since I'm using Formidable Forms to create the forms, the only code I can retrieve for you really is the output, which is what I have supplied in the images. Not ideal, I know.
The only pre-rendering code I have access to in Formidable is below. Though I suspect this will be of no use to anyone, which is why I didn't post it originally:
<div id="frm_field_[id]_container" class="frm_form_field form-field [required_class][error_class]">
<label for="field_[key]" id="field_[key]_label" class="frm_primary_label">[field_name]
<span class="frm_required">[required_label]</span>
</label>
<div class="frm_opt_container" aria-labelledby="field_[key]_label" role="group">[input]</div>
[if description]<div class="frm_description" id="frm_desc_field_[key]">[description]</div>[/if description]
[if error]<div class="frm_error" id="frm_error_field_[key]">[error]</div>[/if error]
</div>
And the rendered code:
<div id="frm_field_70_container" class="frm_form_field form-field frm_none_container frm_dynamic_data_container">
<label for="field_b0r85" id="field_b0r85_label" class="frm_primary_label">Dynamic
<span class="frm_required"></span>
</label>
<div class="frm_opt_container" aria-labelledby="field_b0r85_label" role="group" style=""><p class="frm_show_it"></p><div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-29-150x150.jpg" alt="Image of exercise 5545" style="width:60px;height:60px"><h3>5545</h3><p>Abdominals</p></div>, <div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-13-150x150.jpg" alt="Image of exercise goo" style="width:60px;height:60px"><h3>goo</h3><p>Abdominals</p></div>, <div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-27-150x150.jpg" alt="Image of exercise should work" style="width:60px;height:60px"><h3>should work</h3><p>Abdominals</p></div>, <div class="combined_field_output"><img src="http://3.11.173.147.xip.io/wp-content/uploads/formidable/2/IMG-20190512-WA0005-14-150x150.jpg" alt="Image of exercise Walking Lunges" style="width:60px;height:60px"><h3>Walking Lunges</h3><p>Abdominals</p></div><p></p>
5545Abdominals, gooAbdominals, should workAbdominals, Walking LungesAbdominals">
Edit: Formidable provide a way to Customise a dynamic link fieldwhich mentions nothing of the delimiter. It is my understanding that if no delimiter is specified, a comma will be added dynamically, which is what I think is happening in here. Can this PHP hook be edited to specify no delimiter be added at all?
I don't know if you have access to javascript post rendering. If you do, you can always use regex to fix your innerHTML
var text = document.getElementsByClassName("frm_opt_container")[0].innerHTML;
var reg = new RegExp("(<div class=\"combined_field_output\">.*</div>[.\n\r]*)(,)");
while(reg.test(text)){
text = text.replace(reg, "$1")
}
document.getElementsByClassName("frm_opt_container")[0].innerHTML = text
I would like to be able to allow a user to "filter" the contents of an HTML page from a drop down menu.
I have minimal coding skills but maintain a simple website produced using Emacs org-mode. (easy to assemble pages and produce different versions of the same content using tags.) The output is simple HTML.
I can easily produce different versions of a page and make them selectable with a drop down menu to move between them, but this means I have different versions of the same content on my website, which makes retrieval from search engines confusing.
Ideally, I would like user A to be able to select to see the whole page, user B to see some of it, and user C to see most of it except a small portion. This is a convenience to the users (not for security, etc.)
What is the simplest way of implementing this? I realize a web developer would probably use Ajax, etc., but that's not me.
Sounds like you could make use of showing/hiding sections of the page with some DIVs based on a drop down SELECT.
To do this, you wrap the content that you want to filter in some DIVs and create a JavaScript function that "filters" the displayed content based on the value attribute of the SELECT.
Here is a simple example:
HTML
<select id="myDropdown" onchange="filterContent();">
<option value="A">All content</option>
<option value="B">Some content</option>
<option value="C">Little content</option>
</select>
<div id="contentA">
** Content A ***
</div>
<div id="contentB">
** Content B ***
</div>
<div id="contentC">
** Content C ***
</div>
JavaScript
function filterContent() {
var user = document.getElementById("myDropdown").value;
var contentA = document.getElementById("contentA");
var contentB = document.getElementById("contentB");
var contentC = document.getElementById("contentC");
if(user=="A") {
contentA.style.display="block";
contentB.style.display="block";
contentC.style.display="block";
} else if (user=="B") {
contentA.style.display="none";
contentB.style.display="block";
contentC.style.display="block";
} else if (user=="C") {
contentA.style.display="none";
contentB.style.display="none";
contentC.style.display="block";
}
}
Try it here: http://jsfiddle.net/JsZ8S/
Here is another example with multiple different sections that can be shown or hidden based on the selection. Note that the scheme used for IDs is contentA1, contentA2, etc. the letter being the user and the number after the letter is the sequence since IDs must be unique. Also note the difference in the JavaScript code - because we have more sections, we have to account for showing and hiding them in the if/else block: http://jsfiddle.net/JsZ8S/2/
In case you are ready to use jQuery another example is using classes. If you find that you are creating numerous sections and are tired of keeping track of IDs, you might want to use classes. Classes in this case, work like IDs that you can use again and again. You mark any section you want displayed to all users (user A) with class="contentA", any area for users A and B with class="contentB" and everything else just leave unmarked. This is starting to get a bit un-simple at this point but see what you think.
Here is an example (requires jQuery) using classes: http://jsfiddle.net/JsZ8S/5/
You cannot do it with HTML alone. HTML defines a static document with static formatting. You need at least a little bit of JavaScript to dynamically change the page. Otherwise you have to create some sort of link or button that takes the browser to a new page with the desired changes. (This is about how the web worked for the first 5 or so years.)
A small about of JavaScript plus a library like jQuery should make this easy enough to do if you have any programming experience.
HTML is used to just creating the markup and CSS is used to style it. There is no way you can do "filtering" in plain HTML. You will definitely need some JavaScript knowledge. Try your hands on jQuery and angularJS. They are really easy to learn and the documentation is pretty amazing.
I am creating a UI, in which user can add / delete items (of similar layout).
It starts with one item and you can click 'add' to add more. The UI consists of several different types of items.
What I am doing currently is populating a single item item 1 ( of each type ) and on add event, I clone the item 1, replace the changes done by user in item 1 and append the clone to the container.
In simple words, instead of dynamically creating html with jQuery, I am cloning html of a div. But in this approach , I had to change a lot of things to keep to give the new item to initial state.
So, I want to avoid the replacing the edits done by user, so I was thinking something like below,
<script type="text/template" id="item_type1">
<div>
<div>Box</div>
</div>
</script>
<script type="text/template" id="item_type2">
<div>
<div>Box2</div>
</div>
</script>
And on add event, I want to do something like $('#item_type1').html() and $('#item_type2') to create new items.
I know there are sophisticated libraries like handlebar and mustache and underscore has its own way of implementing templates.
But I am not using any of these already and thus do not want to included them just to copy content. I dont want anything special. I am not passing variables. I am just cloning some markup to use again and again.
Is this way to insert html in script tags , going to work in all browsers ? and is it a good way ?
EDIT:
Its for the wp plugin and I assume js is turned on , else the plugin wont work anyways.
What about:
Your HTML should be, for example:
<script type="text/template" id="item_type1">
<div>
<h1>Box1</h1>
<p>
</p>
</div>
</script>
And your code would be:
var templateHtml = $('#item_type1').html();
var $item = $(templateHtml);
$('body').append($item);
$item.on('click', function() {});
This is an easy way that will work on all browsers.
Step 1: Create an HTML file with your template inside of it
Step 2: Using jQuery's load() method, call your HTML template into a div element in the main HTML file:
$("#main-div").load("yourtemplate.html")
Step 3: Be amazed
Is this a good idea? It depends:
If it's a self contained application on a known environment with a determined supported browser and with equally determined settings (like if JavaScript is on or not) then yea, sure. Why not?
If it's open to the public in every single browser possible with many different configurations, then no, it's a horrible idea. If your user doesn't have JavaScript enabled, then your content doesn't show up. Also, if one of your scripts break in production, then you are again left with no content. You can learn this lesson from when Gawker made this same mistake
I have a site which will have a gallery with 3 sections. Each section has up to 30 images. I will store the images in folders relating to the relevant sections (ie "img/gallery/category1", "img/gallery/category2" and "img/gallery/category3")
Basically instead of writing html to display each individual image, I would like to have a javascript loop which will look in the folder and display each image, and place the url within a predefined snippet of code, ie:
<div class="span4">
<img src="img/gallery/category1/IMAGE-FILENAME1">
</div>
<div class="span4">
<img src="img/gallery/category1/IMAGE-FILENAME2">
</div>
... etc, until all images from the folder have been processed... (also, I know I could be a bit smarter with the html above, but I want to communicate that I want each found image url to sit amongst a repeated snippet of code).
I'm still training in javascript, so I wondered whether there was a way I could do this?
Thanks
Javascript can't do this by iteself... however, if you had an XML or JSON formatted list of images and their respective locations, you could use ajax to get that file, parse it's contents, and create your markup.
I found an alternative solution.
I wasn't quite ready to tackle AJAX, JSON or anything listed below just yet. So I decided to look into using PHP. Solution as folows:
I first of all used the following to go to and read the contents of the folder to an array:
$directory = "DIRECTORY"
$dirhandler = opendir($directory);
$nofiles=0;
while ($file = readdir($dirhandler)) {
if ($file != '.' && $file != '..')
{
$nofiles++;
$files[$nofiles]=$file;
}}
And then using a foreach loop I iterated through the array, everytime echoing the html output which referenced the filename found.
Works perfectly.
You cannot look directly at the directory on the server from Javascript. You could make an AJAX call to the server to get the list (in XML or JSON), and then create and append a new div for each file as you loop through the response.
I don't know anything about programming, so I'm trying to find out where to start learning + how difficult my problem is. Since I don't have any programming knowledge, I'll try to describe my problem in natural language, hope that is OK.
I have the html file of the penal code (a type of law). It contains many different rules, that are in numbered paragraphs (§ 1, § 4, etc).
Now I want to look at the source code and manually “tag” the paragraphs according to specific criteria. For example all the paragraphs that concern the use of a weapon get the “weapon” tag, or that have a minimum sentencing of 1 year and higher get a “crime” tag, etc.
At the end I want to view an interactive html file in Firefox/Chrome, where I could for example click on a “crime” button, and all §§§ that were tagged with “crime” would appear in bold red, keeping the rest of the document intact. Ideally I would also be able to click on “weapon” and would only see the §§§ tagged with “weapon”, making the rest of the document disappear.
The function it's just for me, so it would only need to work on a Xubuntu 11.04 desktop with Firefox or Chrome. The original source file would be http://bundesrecht.juris.de/stgb/BJNR001270871.html. The code looks strange to me, is there a way to convert it into something more easily manually editable?
Any help would be greatly appreciated. Primarily I don't know where to start learning. Do I need to know HTML, jQuery, or a programming language like Python? Do I need to set up an Apache server on my PC? Perhaps because of my ignorance of programming, this seems like a not too complex function. Am I mistaken in the belief that an amateur could build something like thins maybe one month?
I think this is not very difficult to make, although the tagging process can be quite labour-intensive.
You don't need much programming skills, especially when you want to tag stuff manually. You probably only need basic HTML and CSS and some Javascript to pull this off.
What I would do is the following
Create a local copy of the HTML file (use Save As in your browser)
Manually tag each § by giving it the appropriate tag as a classname
Create a list of all available tags and let javascript filter out the § you'd like to see
Now Step 1 is pretty easy I guess, so I'll go right to Step 2. The paragraphs in the HTML file are formatted according to a certain pattern, e.g.:
<div class="jnnorm" id="BJNR001270871BJNE009802307" title="Einzelnorm">
<div class="jnheader">
<a name="BJNR001270871BJNE009802307"/>Nichtamtliches Inhaltsverzeichnis
<h3><span class="jnenbez">§ 31</span> <span class="jnentitel">Rücktritt vom Versuch der Beteiligung</span></h3>
</div>
<div class="jnhtml">
<div>
<div class="jurAbsatz">
(1) Nach § 30 wird nicht bestraft, wer freiwillig etc.
</div>
</div>
</div>
</div>
What you want to do now is add your tag to the <div> element with the class jnnorm. So the above example would become (if the tag weapon would be appropriate):
<div class="jnnorm weapon" id="BJNR001270871BJNE009802307" title="Einzelnorm">
You do that for each paragraph in the HTML. This will be pretty boring, but okay.
Now Step 3. First create a list of links of all the tags you've just created. How you create lists in html is explained here. Put this at the top of the HTML document. What you want to do with javascript is when you click on one of the links in your list that only the paragraphs with the given class are shown. This is most easily done with jQuery's click event and the show and hide methods.
Updated with jQuery example
Make a menu like this
<ul id="menu">
<li id="weapon">Weapons</li>
<li id="crime">Crime</li>
</ul>
And then use the following jQuery
<script>
$(document).ready(function(){
// When a <li> element inside an <ul> with the id "menu" is clicked, do the following
$('ul#menu li').click(function(){
// Get the id of the <li> element and append a '.' so we get the right name for the tag (class) we want to show
var tag = '.' + $(this).attr('id');
// Hide all elements of class 'jnnorm'
$('.jnnorm').hide();
// Show all elements with the class name of tag we want
$(tag).show();
});
});
</script>
Note: HTML classes are denoted as .classname in jQuery whereas HTML id's are denoted as #idname.
Good luck!
This could be done using purely HTML/CSS and Javascript, so not server would be needed. JQuery would make the javascript side easier.
Basic idea of how to do it:
Use CSS style classes for your "tags"
Have a button for each tag with an onclick handler that uses JQuery to highlight everything with that tag (or make everything else invisible)
The HTML source code actually looks nicely structured, though it could use a few more linebreaks for sub-paragraphs. Any good HTML/XML editor has an autoformat feature that handles this, though you could get any specific format you want using a programming language with convenient text-manipulation facilities, such as Perl, awk or Python.