Skip to content

Commit

Permalink
working
Browse files Browse the repository at this point in the history
  • Loading branch information
bendavisnc committed Nov 23, 2015
1 parent 2469211 commit 1091773
Show file tree
Hide file tree
Showing 11 changed files with 1,542 additions and 447 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

243 changes: 217 additions & 26 deletions .idea/workspace.xml

Large diffs are not rendered by default.

303 changes: 209 additions & 94 deletions RedWall.coffee
Original file line number Diff line number Diff line change
@@ -1,106 +1,221 @@
# Rx = require("./bower_components/rxjs/rx.all.js")
Rx = require("rx")
cheerio = require("cheerio")
fs = require('fs')

Observable = Rx.Observable

class RedWall

theRoughIdea = """
get-day -->
get-index -->
get-url -> try-in-three-x-second-spans --> -- fetch-reddit-doc -->
get-image-links
until-success-or-x-tries -->
download-image -->
save-image -->
.
"""

# scope = null
scope = RedWall.prototype

constructor: () ->
null
# scope = this



getDay: () ->
return new Date()

getIndex: (fromWhichDay) ->
return fromWhichDay.getDay()

getUrl: (fromWhichIndex) ->
indexsToDays = {
0: "monday",
1: "tuesday",
2: "wednesday",
3: "thursday",
4: "friday",
5: "saturday",
6: "sunday",
}
daysToPages = {
"monday": "https://www.reddit.com/r/bikeporn",
"tuesday": "https://www.reddit.com/r/spaceporn",
"wednesday": "https://www.reddit.com/r/roomporn",
"thursday": "https://www.reddit.com/r/cityporn",
"friday": "https://www.reddit.com/r/earthporn",
"saturday": "https://www.reddit.com/r/bikeporn",
"sunday": "https://www.reddit.com/r/bikeporn",
}
daysToPages[indexsToDays[fromWhichIndex]]

getImageLinks: (fromWhichUrl) ->
downloadContent = null # todo
return "data"

tryInThreeXSecondSpans: (xSeconds, whichUrl, whichAction) ->
return Observable.interval(xSeconds * 1000)
.map(whichAction whichUrl)
.startWith(whichAction whichUrl)
# .takeUntil(scope.successFetchingDoc)
# .takeWhile(() ->
# return ! scope.todaysSubscription.isStopped
Array.prototype.contains = (what) ->
return this.indexOf(what) != -1

Array::randomized = -> @sort -> 0.5 - Math.random()

class RedWallV3

helpSpace = null
bigDance = null
logger = null

constructor: (whichHelpSpaceToUse) ->
helpSpace = whichHelpSpaceToUse
logger =
log: (whatToLog) ->
console.log(whatToLog)

go = () ->
bigDance.subscribe(
((emitted) ->
logger.log("Successfully set #{emitted} as today's wallpaper")
),
((error) ->
logger.log("Uncaught error: #{error}")
),
(() ->
logger.log("Finished")
)
)
test = () ->
null

# test()
go()

dayIndexStream = Observable.from([(new Date()).getDay()])

dayStream = dayIndexStream.map \
(whichIndex) ->
{
0: "sunday",
1: "monday",
2: "tuesday",
3: "wednesday",
4: "thursday",
5: "friday",
6: "saturday",
}[whichIndex]

redditUrlStream = dayStream.map \
(whichDay) ->
{
"monday": "http://www.reddit.com/r/bikeporn",
"tuesday": "http://www.reddit.com/r/spaceporn",
"wednesday": "http://www.reddit.com/r/roomporn",
"thursday": "http://www.reddit.com/r/cityporn",
"friday": "http://www.reddit.com/r/earthporn",
"saturday": "http://www.reddit.com/r/bikeporn",
# "sunday": "http://www.reddit.com/r/dirtysmall",
"sunday": "http://www.reddit.com/r/bikeporn",
}[whichDay]


redditPageStream = redditUrlStream.flatMap \
(redditUrl) ->
return Observable.create \
(observer) ->
helpSpace.download(
redditUrl,
(successfullyDownloaded) ->
logger.log("Successfully downloaded #{redditUrl}")
observer.onNext(successfullyDownloaded)
observer.onCompleted()
(failedDownload) ->
logger.log("Couldn't download #{redditUrl}")
observer.onError(failedDownload)
)

# return Observable.catch(redditPageStream, Observable.empty())
redditPageStreamGivenThreeChances = \
Observable.amb([
Observable.catch(redditPageStream, Observable.empty()).delay(0 * 1000),
Observable.catch(redditPageStream, Observable.empty()).delay(30 * 1000),
Observable.catch(redditPageStream, Observable.empty()).delay(90 * 1000),
# Observable.throw(new Error('Failed to retrieve reddit page content')).delay(10000)
# Observable.create(
# (observer) ->
# throw new Error('Failed to retrieve reddit page content')
# )



# mappable promised reddit dom doc
todaysFetchedDoc = Observable.return(scope.getDay())
.map(scope.getIndex)
.map(scope.getUrl)
.map((theUrl) ->
scope.tryInThreeXSecondSpans(3, theUrl, scope.getImageLinks)) # TODO

todaysSubscription:
todaysFetchedDoc.subscribe(
(e) ->
window.testObj = e
console.dir(e)

]).defaultIfEmpty(Observable.throw(new Error('Failed to retrieve reddit page content')))

jqueryDocStream = redditPageStreamGivenThreeChances.map \
(docText) ->
return cheerio.load(docText);

imageUrlsStream = jqueryDocStream.map \
(jqueryDoc) ->
return jqueryDoc("div.entry.unvoted")
.find("a.title.may-blank")
.filter(
(i, eachLink) ->
linkFileExtension = helpSpace.getFileExtension(eachLink)
return (linkFileExtension == "jpg") or
(linkFileExtension == "jpeg") or
(linkFileExtension == "png")
).toArray() \
.randomized()
.map(
(eachLink) ->
return eachLink.attribs.href
)


imageContentStreamTriedSuccessively = imageUrlsStream.flatMap \
(imageUrls) ->
successiveTries = []
howMuchDelay = -3000
for imageUrl in imageUrls
howMuchDelay += 3000
fileExtension = helpSpace.getFileExtension(imageUrl)
successiveTries.push (Observable.create \
(observer) ->
helpSpace.downloadForBinary(
imageUrl,
(successfullyDownloaded) ->
logger.log("Successfully downloaded #{imageUrl}")
observer.onNext([successfullyDownloaded, fileExtension])
observer.onCompleted()
(failedDownload) ->
logger.log("Couldn't download #{imageUrl}")
null
)
).delay(howMuchDelay)
# successiveTries.push Rx.Observable.throw(new Error('Failed to retrieve reddit image content')).delay(100)
return Observable.amb(successiveTries) \
.defaultIfEmpty(Observable.throw(new Error('Failed to retrieve reddit image content')))
.first()

imageContentSaved = imageContentStreamTriedSuccessively.map(
([whichImageContent, whichFileExtenstion]) ->
filename = "redwall.#{whichFileExtenstion}"
fs.writeFile(filename, whichImageContent, {encoding: 'binary'},
(err) ->
if (err)
throw new Error("image content not saved")
)
return filename
).take(1)

# untilSuccesOrXTries: (xTries, )
imageContentHeard = imageContentSaved.map(
(whichFilename) ->
helpSpace.informOS(whichFilename)
return whichFilename
)

bigDance = imageContentHeard

# ourConnectionTries
# .map(this.untilSuccesOrXTries)
# .map(this.downloadImage)
# .map(this.saveImage)



class HelpSpace



# whatWeAreDoing.subscribe(
# ([wasSuccessful, urlTried]) ->
# # NOTE: would love to use pattern matching here
# if (wasSuccessful)
# printToLog("success using #{urlTried} at #{Timer.getX()}")
# killAll() # Note: Less than the sexy I want
# else
# printToLog("failure using #{urlTried} at #{Timer.getX()}")
# )

new RedWall()
http = require("http");
# http://www.storminthecastle.com/2013/08/25/use-node-js-to-extract-data-from-the-web-for-fun-and-profit/
@downloadForBinary: (url, successCallback, badnewsCallback) ->
http.get(url, (res) ->
data = ""
res.setEncoding('binary')
res.on('data', (chunk) ->
data += chunk
)
res.on("end", () ->
successCallback(data)
)
).on("error", (e) ->
badnewsCallback(e);
)


request = require("request")
# http://www.sitepoint.com/web-scraping-in-node-js/
@download: (url, successCallback, badnewsCallback) ->
console.log("@ HelpSpace.download")
# thisUrl = url
request({uri: url,
},
(error, response, body) ->
if (error)
badnewsCallback(error)
else
successCallback(body)
)

@getFileExtension: (fromLinkorText) ->
linkHref = if fromLinkorText.attribs then fromLinkorText.attribs.href else fromLinkorText
return linkHref[(linkHref.lastIndexOf('.') + 1)..]

exec = require('child_process').exec
# http://stackoverflow.com/questions/20643470/execute-a-command-line-binary-with-node-js
@informOS: (whichFilename) ->
preciseFilename = require('path').resolve(
__dirname,
whichFilename)
cmd = """
gsettings set org.gnome.desktop.background picture-uri file://#{preciseFilename} &&
gsettings set org.gnome.desktop.background picture-options scaled
"""

exec(cmd, (error, stdout, stderr) ->
null
) # todo: error handling

new RedWallV3(HelpSpace)
Loading

0 comments on commit 1091773

Please sign in to comment.