Skip to content

Instantly share code, notes, and snippets.

@kanzure
Created April 25, 2012 04:50
Show Gist options
  • Save kanzure/25a38b9c5df048dcec4a to your computer and use it in GitHub Desktop.
Save kanzure/25a38b9c5df048dcec4a to your computer and use it in GitHub Desktop.
phantomly
# 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