# monitor.py - a script to monitor the web for references to your site
#              that don't link to it. It uses google alerts and yql to
#              find mentions and then check for links.
#
# originally written by Will Critchlow at SEOmoz.org
#  http://www.seomoz.org/blog/futuristic-ways-of-creating-automated-link-building-tools
#
# modified and commented by Peter Coles at MrColes.com
#  http://mrcoles.com/blog/technical-look-seomoz-automated-link-building-tool/
#

import yql

# the website that you want people to monitor to see people are linking to
# it when they mention it
monitorURL = "http://www.seomoz.org"

# path to the google alerts RSS for seomoz
rssURL = "http://www.google.com/alerts/feeds/02091889458087148316/10137124638087203861"


# determines if the given url has a link or not
def findLink(y, url):

    # this query will be used to get a page for the given url.
    # the @xpath part is just a placeholder that will be filled in in the next line.
    # see here for more: http://python-yql.org/usage.html#using-placeholders-in-queries
    htmlQuery = "select * from html where url='%s' and xpath=@xpath" % url

    # htmlQuery is used, and further filtered in xpath to only return results where there is
    # a link who's href starts with our monitorUrl
    htmlResult = y.execute(htmlQuery, {"xpath": "//a[starts-with(@href,'%s')]" % monitorURL})

    # this will return True if we found a link to our monitorUrl
    return htmlResult.count > 0

# returns the result of the yql query that gets the google alerts RSS feed
def getMentions(y):
    return y.execute("select * from feed where url='%s'" % rssURL)


# this if-statement just makes it so the code below it only runs
# if the script is called from the command line (or directly by google apps engine)
if __name__ == '__main__':

    # this is an HTML header so the result of running this file can be
    # properly read by a web browser, see more here:
    # http://code.google.com/appengine/docs/python/gettingstarted/helloworld.html
    print 'Content-Type: text/plain'
    print ''

    # make sure that this is yql-0.3 and not 0.2
    assert yql.__version__ == '0.3', "Must be yql version 0.3, you're running version: %s" % yql.__version__

    y = yql.Public()           # get the yql object
    rssResult = getMentions(y) # query the google alerts RSS feed for mentions of our website
    maxLinks = 10              # limit the number of links we view to 10 (this is an arbitrary number)

    # loop through the first 10 results from getMentions() to check for links
    for row in rssResult.rows[:maxLinks]:

        # get the url of the page that mentioned us
        url = row.get('link').get('href')

        # call findLink to see if the page linked to us
        if findLink(y, url):
            print "!No links!\t%s" % url
        else:
            print "Has links:\t%s" % url
