-
-
Save kanzure/25a38b9c5df048dcec4a to your computer and use it in GitHub Desktop.
phantomly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# docco documentation goes here | |
#phantom.injectJs("underscore.js") | |
# for removing an element from an array | |
# or with underscore... | |
#a = _(a).reject (v)-> v is e | |
Array::remove = (e) -> @splice(t,1)[0] if (t = @indexOf(e)) > -1 | |
alert: (message) -> | |
console.log(message) | |
exit: -> | |
alert "exiting" | |
phantom.exit() | |
pages = [] | |
class Page | |
# instead of base_url just use the parent's url | |
url: null | |
# per-page settings (phantomjs) | |
settings: | |
loadImages: true | |
loadPlugins: true | |
javascriptEnabled: true | |
userAgent: "StyleOwner/Phantomly" | |
# custom settings | |
jquery: true | |
log: (msg) -> | |
console.log("Page" + ": " + msg) | |
constructor: -> | |
@current_analysis = {} | |
@transition_history = [] | |
@jquery_injected = false | |
@loaded = false | |
@error = null | |
@page = require("webpage").create() | |
# these are attributes on any WebPage that can be customized | |
overrides = [ | |
"settings", | |
"onAlert", | |
"onConsoleMessage", | |
"onError", | |
"onInitialized", | |
"onLoadStarted", | |
"onLoadFinished", | |
"onResourceRequested", | |
"onResourceReceived", | |
] | |
# each attribute will be replaced unless there's no override | |
for override in overrides | |
if @[override] != null and @[override] != undefined | |
console.log("TEST override?") | |
@page[override] = @[override] | |
# starts to load the page | |
start: -> | |
@log("start called, url is: " + @url) | |
self = @ | |
# is called when the page is finished loading | |
onLoadFinished = (status) -> | |
self.log("onLoadFinished called") | |
self.loaded = true | |
if self.settings.jquery && !self.jquery_injected | |
self.log("injecting jquery into the page") | |
self.page.includeJs("http://code.jquery.com/jquery-latest.min.js") | |
self.jquery_injected = true | |
# status will be 'failed' on 404s, disconnects and timeouts | |
self.log("about to call analyze") | |
analysis = self.analyze() | |
pages.push(self) | |
onLoadStarted = -> | |
self.loaded = false | |
@page.open(@url, onLoadFinished) | |
@log("start done") | |
# runs the method on the page with the given args | |
run: (method, callback_handler, passed_args) -> | |
@log("run called (with method and passed_args)") | |
result = @page.evaluate(method) # passed_args) | |
if typeof(callback_handler) == "function" | |
@log("run calling callback_handler(result)") | |
result = callback_handler(result) | |
@log("run done") | |
return result | |
# analyzes html and returns a analysis | |
analyzer: -> | |
console.log("analyzer running inside the page") | |
analysis = | |
state: null | |
console.log("analyzer done running inside the page") | |
return analysis | |
# injects the actual deduction code into the page context | |
analyze: -> | |
@log("analyze: injecting @analyzer") | |
analysis = @page.evaluate(@analyzer) | |
# historical: moving from @current_analysis to this new analysis | |
@transition_history.push(analysis) | |
@previous_analysis = @current_analysis | |
@current_analysis = analysis | |
return analysis | |
# chooses a manipulation to perform based on previous_analysis and current_analysis | |
transition: -> | |
console.log("transition: nothing to do, exiting...") | |
exit() | |
class HackerNewsPage extends Page | |
#super: @constructor.__super__ | |
url: "http://news.ycombinator.com" | |
class HomePage extends HackerNewsPage | |
#super: @constructor.__super__ | |
analyzer: -> | |
console.log("analyzer running inside the page") | |
analysis = | |
title: document.title | |
url: document.location.href | |
if analysis.title == null || analysis.title == "" | |
analysis["state"] = "HAS_NO_TITLE" | |
else | |
analysis["state"] = "HAS_TITLE" | |
if Math.floor(Math.random()*4) == 3 | |
analysis["state"] = "SIMULATED_DISASTER" | |
console.log("analyzer done running inside the page") | |
return analysis | |
transition: -> | |
@log("transition looking at the analysis") | |
analysis = @current_analysis | |
state = analysis["state"] | |
if state == "HAS_NO_TITLE" | |
@run(@set_title) | |
else if state == "HAS_TITLE" || @previous_analysis == null | |
@run(@unset_title) | |
else | |
@error = new Error("unknown state") | |
@loaded = false | |
throw @error | |
@log("transition done looking at the analysis") | |
set_title: -> | |
document.title = "hello world!" | |
unset_title: -> | |
document.title = "" | |
console.log("creating a new HomePage"); | |
page = new HomePage | |
console.log("about to start running the HomePage...") | |
page.start() | |
main_loop = -> | |
for page in pages | |
if page.error | |
pages.remove(page) | |
else if page.loaded | |
console.log("main_loop: calling transition on page") | |
page.transition() | |
console.log("main_loop: calling analyze on page") | |
page.analyze() | |
if pages.length == 0 | |
phantom.exit() | |
window.setInterval(main_loop, 1000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment