<?php | <?php |
require_once '../include/common.inc.php'; | require_once '../include/common.inc.php'; |
//function createFOIDocumentsDesignDoc() { | //function createFOIDocumentsDesignDoc() { |
$foidb = $server->get_db('disclosr-foidocuments'); | $foidb = $server->get_db('disclosr-foidocuments'); |
$obj = new stdClass(); | $obj = new stdClass(); |
$obj->_id = "_design/" . urlencode("app"); | $obj->_id = "_design/" . urlencode("app"); |
$obj->language = "javascript"; | $obj->language = "javascript"; |
$obj->views->all->map = "function(doc) { emit(doc._id, doc); };"; | $obj->views->all->map = "function(doc) { emit(doc._id, doc); };"; |
$obj->views->byDate->map = "function(doc) { emit(doc.date, doc); };"; | $obj->views->byDate->map = "function(doc) { emit(doc.date, doc); };"; |
$obj->views->byDate->reduce = "_count"; | |
$obj->views->byDateMonthYear->map = "function(doc) { emit(doc.date, doc); };"; | $obj->views->byDateMonthYear->map = "function(doc) { emit(doc.date, doc); };"; |
$obj->views->byDateMonthYear->reduce = "_count"; | $obj->views->byDateMonthYear->reduce = "_count"; |
$obj->views->byAgencyID->map = "function(doc) { emit(doc.agencyID, doc); };"; | $obj->views->byAgencyID->map = "function(doc) { emit(doc.agencyID, doc); };"; |
$obj->views->byAgencyID->reduce = "_count"; | $obj->views->byAgencyID->reduce = "_count"; |
// allow safe updates (even if slightly slower due to extra: rev-detection check). | // allow safe updates (even if slightly slower due to extra: rev-detection check). |
$foidb->save($obj, true); | $foidb->save($obj, true); |
//function createDocumentsDesignDoc() { | //function createDocumentsDesignDoc() { |
$docdb = $server->get_db('disclosr-documents'); | $docdb = $server->get_db('disclosr-documents'); |
$obj = new stdClass(); | $obj = new stdClass(); |
$obj->_id = "_design/" . urlencode("app"); | $obj->_id = "_design/" . urlencode("app"); |
$obj->language = "javascript"; | $obj->language = "javascript"; |
$obj->views->web_server->map = "function(doc) {\n emit(doc.web_server, 1);\n}"; | $obj->views->web_server->map = "function(doc) {\n emit(doc.web_server, 1);\n}"; |
$obj->views->web_server->reduce = "function (key, values, rereduce) {\n return sum(values);\n}"; | $obj->views->web_server->reduce = "function (key, values, rereduce) {\n return sum(values);\n}"; |
$obj->views->byAgency->map = "function(doc) {\n emit(doc.agencyID, 1);\n}"; | $obj->views->byAgency->map = "function(doc) {\n emit(doc.agencyID, 1);\n}"; |
$obj->views->byAgency->reduce = "function (key, values, rereduce) {\n return sum(values);\n}"; | $obj->views->byAgency->reduce = "function (key, values, rereduce) {\n return sum(values);\n}"; |
$obj->views->byURL->map = "function(doc) {\n emit(doc.url, doc);\n}"; | $obj->views->byURL->map = "function(doc) {\n emit(doc.url, doc);\n}"; |
$obj->views->agency->map = "function(doc) {\n emit(doc.agencyID, doc);\n}"; | $obj->views->agency->map = "function(doc) {\n emit(doc.agencyID, doc);\n}"; |
$obj->views->byWebServer->map = "function(doc) {\n emit(doc.web_server, doc);\n}"; | $obj->views->byWebServer->map = "function(doc) {\n emit(doc.web_server, doc);\n}"; |
$obj->views->getValidationRequired = "function(doc) {\nif (doc.mime_type == \"text/html\" \n&& typeof(doc.validation) == \"undefined\") {\n emit(doc._id, doc._attachments);\n}\n}"; | $obj->views->getValidationRequired = "function(doc) {\nif (doc.mime_type == \"text/html\" \n&& typeof(doc.validation) == \"undefined\") {\n emit(doc._id, doc._attachments);\n}\n}"; |
//function createAgencyDesignDoc() { | //function createAgencyDesignDoc() { |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
$obj = new stdClass(); | $obj = new stdClass(); |
$obj->_id = "_design/" . urlencode("app"); | $obj->_id = "_design/" . urlencode("app"); |
$obj->language = "javascript"; | $obj->language = "javascript"; |
$obj->views->all->map = "function(doc) { emit(doc._id, doc); };"; | $obj->views->all->map = "function(doc) { emit(doc._id, doc); };"; |
$obj->views->byABN->map = "function(doc) { emit(doc.abn, doc); };"; | $obj->views->byABN->map = "function(doc) { emit(doc.abn, doc); };"; |
$obj->views->byCanonicalName->map = "function(doc) { | $obj->views->byCanonicalName->map = "function(doc) { |
if (doc.parentOrg || doc.orgType == 'FMA-DepartmentOfState') { | if (doc.parentOrg || doc.orgType == 'FMA-DepartmentOfState') { |
emit(doc.name, doc); | emit(doc.name, doc); |
} | } |
};"; | };"; |
$obj->views->byDeptStateName->map = "function(doc) { | $obj->views->byDeptStateName->map = "function(doc) { |
if (doc.orgType == 'FMA-DepartmentOfState') { | if (doc.orgType == 'FMA-DepartmentOfState') { |
emit(doc.name, doc._id); | emit(doc.name, doc._id); |
} | } |
};"; | };"; |
$obj->views->parentOrgs->map = "function(doc) { | $obj->views->parentOrgs->map = "function(doc) { |
if (doc.parentOrg) { | if (doc.parentOrg) { |
emit(doc._id, doc.parentOrg); | emit(doc._id, doc.parentOrg); |
} | } |
};"; | };"; |
$obj->views->byName->map = 'function(doc) { | $obj->views->byName->map = 'function(doc) { |
if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { | if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { |
emit(doc.name, doc._id); | emit(doc.name, doc._id); |
if (typeof(doc.shortName) != "undefined" && doc.shortName != doc.name) { | if (typeof(doc.shortName) != "undefined" && doc.shortName != doc.name) { |
emit(doc.shortName, doc._id); | emit(doc.shortName, doc._id); |
} | } |
for (name in doc.otherNames) { | for (name in doc.otherNames) { |
if (doc.otherNames[name] != "" && doc.otherNames[name] != doc.name) { | if (doc.otherNames[name] != "" && doc.otherNames[name] != doc.name) { |
emit(doc.otherNames[name], doc._id); | emit(doc.otherNames[name], doc._id); |
} | } |
} | } |
for (name in doc.foiBodies) { | for (name in doc.foiBodies) { |
if (doc.foiBodies[name] != "" && doc.foiBodies[name] != doc.name) { | if (doc.foiBodies[name] != "" && doc.foiBodies[name] != doc.name) { |
emit(doc.foiBodies[name], doc._id); | emit(doc.foiBodies[name], doc._id); |
} | } |
} | } |
for (name in doc.positions) { | for (name in doc.positions) { |
if (doc.positions[name] != "" && doc.positions[name] != doc.name) { | if (doc.positions[name] != "" && doc.positions[name] != doc.name) { |
emit(doc.positions[name], doc._id); | emit(doc.positions[name], doc._id); |
} | } |
} | } |
} | } |
};'; | };'; |
$obj->views->foiEmails->map = "function(doc) { | $obj->views->foiEmails->map = "function(doc) { |
emit(doc._id, doc.foiEmail); | emit(doc._id, doc.foiEmail); |
};"; | };"; |
$obj->views->byLastModified->map = "function(doc) { emit(doc.metadata.lastModified, doc); }"; | $obj->views->byLastModified->map = "function(doc) { emit(doc.metadata.lastModified, doc); }"; |
$obj->views->getActive->map = 'function(doc) { if (doc.status == "active") { emit(doc._id, doc); } };'; | $obj->views->getActive->map = 'function(doc) { if (doc.status == "active") { emit(doc._id, doc); } };'; |
$obj->views->getSuspended->map = 'function(doc) { if (doc.status == "suspended") { emit(doc._id, doc); } };'; | $obj->views->getSuspended->map = 'function(doc) { if (doc.status == "suspended") { emit(doc._id, doc); } };'; |
$obj->views->getScrapeRequired->map = "function(doc) { | $obj->views->getScrapeRequired->map = "function(doc) { |
var lastScrape = Date.parse(doc.metadata.lastScraped); | var lastScrape = Date.parse(doc.metadata.lastScraped); |
var today = new Date(); | var today = new Date(); |
if (!lastScrape || lastScrape.getTime() + 1000 != today.getTime()) { | if (!lastScrape || lastScrape.getTime() + 1000 != today.getTime()) { |
emit(doc._id, doc); | emit(doc._id, doc); |
} | } |
};"; | };"; |
$obj->views->showNamesABNs->map = "function(doc) { emit(doc._id, {name: doc.name, abn: doc.abn}); };"; | $obj->views->showNamesABNs->map = "function(doc) { emit(doc._id, {name: doc.name, abn: doc.abn}); };"; |
$obj->views->getConflicts->map = "function(doc) { | $obj->views->getConflicts->map = "function(doc) { |
if (doc._conflicts) { | if (doc._conflicts) { |
emit(null, [doc._rev].concat(doc._conflicts)); | emit(null, [doc._rev].concat(doc._conflicts)); |
} | } |
}"; | }"; |
// http://stackoverflow.com/questions/646628/javascript-startswith | // http://stackoverflow.com/questions/646628/javascript-startswith |
$obj->views->score->map = 'if(!String.prototype.startsWith){ | $obj->views->score->map = 'if(!String.prototype.startsWith){ |
String.prototype.startsWith = function (str) { | String.prototype.startsWith = function (str) { |
return !this.indexOf(str); | return !this.indexOf(str); |
} | } |
} | } |
function(doc) { | function(doc) { |
count = 0; | count = 0; |
if (doc["status"] != "suspended") { | if (doc["status"] != "suspended") { |
for(var propName in doc) { | for(var propName in doc) { |
if(typeof(doc[propName]) != "undefined" && doc[propName] != "") { | if(typeof(doc[propName]) != "undefined" && doc[propName] != "") { |
count++; | count++; |
} | } |
} | } |
portfolio = doc.parentOrg; | portfolio = doc.parentOrg; |
if (doc.orgType == "FMA-DepartmentOfState") { | if (doc.orgType == "FMA-DepartmentOfState") { |
portfolio = doc._id; | portfolio = doc._id; |
} | } |
if (doc.orgType == "Court-Commonwealth" || doc.orgType == "FMA-DepartmentOfParliament") { | if (doc.orgType == "Court-Commonwealth" || doc.orgType == "FMA-DepartmentOfParliament") { |
portfolio = doc.orgType; | portfolio = doc.orgType; |
} | } |
emit(count+doc._id, {id:doc._id, name: doc.name, score:count, orgType: doc.orgType, portfolio:portfolio}); | emit(count+doc._id, {id:doc._id, name: doc.name, score:count, orgType: doc.orgType, portfolio:portfolio}); |
} | } |
}'; | }'; |
$obj->views->scoreHas->map = 'if(!String.prototype.startsWith){ | $obj->views->scoreHas->map = 'if(!String.prototype.startsWith){ |
String.prototype.startsWith = function (str) { | String.prototype.startsWith = function (str) { |
return !this.indexOf(str); | return !this.indexOf(str); |
} | } |
} | } |
if(!String.prototype.endsWith){ | if(!String.prototype.endsWith){ |
String.prototype.endsWith = function(suffix) { | String.prototype.endsWith = function(suffix) { |
return this.indexOf(suffix, this.length - suffix.length) !== -1; | return this.indexOf(suffix, this.length - suffix.length) !== -1; |
}; | }; |
} | } |
function(doc) { | function(doc) { |
if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { | if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { |
for(var propName in doc) { | for(var propName in doc) { |
if(typeof(doc[propName]) != "undefined" && (propName.startsWith("has") || propName.endsWith("URL"))) { | if(typeof(doc[propName]) != "undefined" && (propName.startsWith("has") || propName.endsWith("URL"))) { |
emit(propName, 1); | emit(propName, 1); |
} | } |
} | } |
emit("total", 1); | emit("total", 1); |
} | } |
}'; | }'; |
$obj->views->scoreHas->reduce = 'function (key, values, rereduce) { | $obj->views->scoreHas->reduce = 'function (key, values, rereduce) { |
return sum(values); | return sum(values); |
}'; | }'; |
$obj->views->fieldNames->map = ' | $obj->views->fieldNames->map = ' |
function(doc) { | function(doc) { |
for(var propName in doc) { | for(var propName in doc) { |
emit(propName, doc._id); | emit(propName, doc._id); |
} | } |
}'; | }'; |
$obj->views->fieldNames->reduce = 'function (key, values, rereduce) { | $obj->views->fieldNames->reduce = 'function (key, values, rereduce) { |
return values.length; | return values.length; |
}'; | }'; |
// allow safe updates (even if slightly slower due to extra: rev-detection check). | // allow safe updates (even if slightly slower due to extra: rev-detection check). |
$db->save($obj, true); | $db->save($obj, true); |
?> | ?> |
<?php | |
include('template.inc.php'); | |
include_header_documents(""); | |
include_once('../include/common.inc.php'); | |
?> | |
<h1>About</h1> | |
<?php | |
include_footer_documents(); | |
?> | |
import sys,os | import sys,os |
sys.path.insert(0, os.path.join(os.path.dirname(__file__) or '.', '../')) | sys.path.insert(0, os.path.join(os.path.dirname(__file__) or '.', '../')) |
import scrape | import scrape |
from bs4 import BeautifulSoup | from bs4 import BeautifulSoup |
from time import mktime | from time import mktime |
import feedparser | import feedparser |
import abc | import abc |
import unicodedata, re | import unicodedata, re |
import dateutil | import dateutil |
from dateutil.parser import * | from dateutil.parser import * |
from datetime import * | from datetime import * |
import codecs | import codecs |
from StringIO import StringIO | from StringIO import StringIO |
from docx import * | from docx import * |
from lxml import etree | from lxml import etree |
import zipfile | import zipfile |
from pdfminer.pdfparser import PDFDocument, PDFParser | from pdfminer.pdfparser import PDFDocument, PDFParser |
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf | from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf |
from pdfminer.pdfdevice import PDFDevice, TagExtractor | from pdfminer.pdfdevice import PDFDevice, TagExtractor |
from pdfminer.converter import TextConverter | from pdfminer.converter import TextConverter |
from pdfminer.cmapdb import CMapDB | from pdfminer.cmapdb import CMapDB |
from pdfminer.layout import LAParams | from pdfminer.layout import LAParams |
class GenericDisclogScraper(object): | class GenericDisclogScraper(object): |
__metaclass__ = abc.ABCMeta | __metaclass__ = abc.ABCMeta |
agencyID = None | agencyID = None |
disclogURL = None | disclogURL = None |
def remove_control_chars(self, input): | def remove_control_chars(self, input): |
return "".join([i for i in input if ord(i) in range(32, 127)]) | return "".join([i for i in input if ord(i) in range(32, 127)]) |
def getAgencyID(self): | def getAgencyID(self): |
""" disclosr agency id """ | """ disclosr agency id """ |
if self.agencyID == None: | if self.agencyID == None: |
self.agencyID = os.path.basename(sys.argv[0]).replace(".py","") | self.agencyID = os.path.basename(sys.argv[0]).replace(".py","") |
return self.agencyID | return self.agencyID |
def getURL(self): | def getURL(self): |
""" disclog URL""" | """ disclog URL""" |
if self.disclogURL == None: | if self.disclogURL == None: |
agency = scrape.agencydb.get(self.getAgencyID()) | agency = scrape.agencydb.get(self.getAgencyID()) |
self.disclogURL = agency['FOIDocumentsURL'] | self.disclogURL = agency['FOIDocumentsURL'] |
return self.disclogURL | return self.disclogURL |
@abc.abstractmethod | @abc.abstractmethod |
def doScrape(self): | def doScrape(self): |
""" do the scraping """ | """ do the scraping """ |
return | return |
class GenericPDFDisclogScraper(GenericDisclogScraper): | class GenericPDFDisclogScraper(GenericDisclogScraper): |
def doScrape(self): | def doScrape(self): |
foidocsdb = scrape.couch['disclosr-foidocuments'] | foidocsdb = scrape.couch['disclosr-foidocuments'] |
(url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) | (url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) |
laparams = LAParams() | laparams = LAParams() |
rsrcmgr = PDFResourceManager(caching=True) | rsrcmgr = PDFResourceManager(caching=True) |
outfp = StringIO.StringIO() | outfp = StringIO.StringIO() |
device = TextConverter(rsrcmgr, outfp, codec='utf-8', laparams=laparams) | device = TextConverter(rsrcmgr, outfp, codec='utf-8', laparams=laparams) |
fp = StringIO.StringIO() | fp = StringIO.StringIO() |
fp.write(content) | fp.write(content) |
description = output.getvalue(); | description = output.getvalue(); |
process_pdf(rsrcmgr, device, fp, set(), caching=True, check_extractable=True) | process_pdf(rsrcmgr, device, fp, set(), caching=True, check_extractable=True) |
fp.close() | fp.close() |
device.close() | device.close() |
outfp.close() | outfp.close() |
hash = scrape.mkhash(description) | hash = scrape.mkhash(description) |
#print hash | #print hash |
doc = foidocsdb.get(hash) | doc = foidocsdb.get(hash) |
#print doc | #print doc |
if doc == None: | if doc == None: |
print "saving "+ hash | print "saving "+ hash |
edate = datetime.fromtimestamp(mktime( )).strftime("%Y-%m-%d") | edate = datetime.fromtimestamp(mktime( )).strftime("%Y-%m-%d") |
doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': self.getURL(), 'docID': hash, | doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': self.getURL(), 'docID': hash, |
"date": edate,"title": "Disclosure Log Updated"} | "date": edate,"title": "Disclosure Log Updated"} |
self.getDescription(entry,entry, doc) | self.getDescription(entry,entry, doc) |
foidocsdb.save(doc) | foidocsdb.save(doc) |
else: | else: |
print "already saved" | print "already saved" |
class GenericDOCXDisclogScraper(GenericDisclogScraper): | class GenericDOCXDisclogScraper(GenericDisclogScraper): |
def doScrape(self): | def doScrape(self): |
foidocsdb = scrape.couch['disclosr-foidocuments'] | foidocsdb = scrape.couch['disclosr-foidocuments'] |
(url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) | (url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) |
mydoc = zipfile.ZipFile(file) | mydoc = zipfile.ZipFile(file) |
xmlcontent = mydoc.read('word/document.xml') | xmlcontent = mydoc.read('word/document.xml') |
document = etree.fromstring(xmlcontent) | document = etree.fromstring(xmlcontent) |
## Fetch all the text out of the document we just created | ## Fetch all the text out of the document we just created |
paratextlist = getdocumenttext(document) | paratextlist = getdocumenttext(document) |
# Make explicit unicode version | # Make explicit unicode version |
newparatextlist = [] | newparatextlist = [] |
for paratext in paratextlist: | for paratext in paratextlist: |
newparatextlist.append(paratext.encode("utf-8")) | newparatextlist.append(paratext.encode("utf-8")) |
## Print our documnts test with two newlines under each paragraph | ## Print our documnts test with two newlines under each paragraph |
description = '\n\n'.join(newparatextlist) | description = '\n\n'.join(newparatextlist) |
hash = scrape.mkhash(description) | hash = scrape.mkhash(description) |
#print hash | #print hash |
doc = foidocsdb.get(hash) | doc = foidocsdb.get(hash) |
#print doc | #print doc |
if doc == None: | if doc == None: |
print "saving "+ hash | print "saving "+ hash |
edate = datetime.fromtimestamp(mktime()).strftime("%Y-%m-%d") | edate = datetime.fromtimestamp(mktime()).strftime("%Y-%m-%d") |
doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': self.getURL(), 'docID': hash, | doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': self.getURL(), 'docID': hash, |
"date": edate,"title": "Disclosure Log Updated"} | "date": edate,"title": "Disclosure Log Updated"} |
self.getDescription(entry,entry, doc) | self.getDescription(entry,entry, doc) |
foidocsdb.save(doc) | foidocsdb.save(doc) |
else: | else: |
print "already saved" | print "already saved" |
class GenericRSSDisclogScraper(GenericDisclogScraper): | class GenericRSSDisclogScraper(GenericDisclogScraper): |
def doScrape(self): | def doScrape(self): |
foidocsdb = scrape.couch['disclosr-foidocuments'] | foidocsdb = scrape.couch['disclosr-foidocuments'] |
(url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) | (url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) |
feed = feedparser.parse(content) | feed = feedparser.parse(content) |
for entry in feed.entries: | for entry in feed.entries: |
#print entry | #print entry |
print entry.id | print entry.id |
hash = scrape.mkhash(entry.id) | hash = scrape.mkhash(entry.id) |
#print hash | #print hash |
doc = foidocsdb.get(hash) | doc = foidocsdb.get(hash) |
#print doc | #print doc |
if doc == None: | if doc == None: |
print "saving "+ hash | print "saving "+ hash |
edate = datetime.fromtimestamp(mktime( entry.published_parsed)).strftime("%Y-%m-%d") | edate = datetime.fromtimestamp(mktime( entry.published_parsed)).strftime("%Y-%m-%d") |
doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': entry.link, 'docID': entry.id, | doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': entry.link, 'docID': entry.id, |
"date": edate,"title": entry.title} | "date": edate,"title": entry.title} |
self.getDescription(entry,entry, doc) | self.getDescription(entry,entry, doc) |
foidocsdb.save(doc) | foidocsdb.save(doc) |
else: | else: |
print "already saved" | print "already saved" |
def getDescription(self, content, entry, doc): | def getDescription(self, content, entry, doc): |
""" get description from rss entry""" | """ get description from rss entry""" |
doc.update({'description': content.summary}) | doc.update({'description': content.summary}) |
return | return |
class GenericOAICDisclogScraper(GenericDisclogScraper): | class GenericOAICDisclogScraper(GenericDisclogScraper): |
__metaclass__ = abc.ABCMeta | __metaclass__ = abc.ABCMeta |
@abc.abstractmethod | @abc.abstractmethod |
def getColumns(self,columns): | def getColumns(self,columns): |
""" rearranges columns if required """ | """ rearranges columns if required """ |
return | return |
def getColumnCount(self): | def getColumnCount(self): |
return 5 | return 5 |
def getDescription(self, content, entry, doc): | def getDescription(self, content, entry, doc): |
""" get description from rss entry""" | """ get description from rss entry""" |
descriptiontxt = "" | descriptiontxt = "" |
for string in content.stripped_strings: | for string in content.stripped_strings: |
descriptiontxt = descriptiontxt + " \n" + string | descriptiontxt = descriptiontxt + " \n" + string |
doc.update({'description': descriptiontxt}) | doc.update({'description': descriptiontxt}) |
return | return |
def getTitle(self, content, entry, doc): | def getTitle(self, content, entry, doc): |
doc.update({'title': (''.join(content.stripped_strings))}) | doc.update({'title': (''.join(content.stripped_strings))}) |
return | return |
def getTable(self, soup): | def getTable(self, soup): |
return soup.table | return soup.table |
def getRows(self, table): | def getRows(self, table): |
return table.find_all('tr') | return table.find_all('tr') |
def getDate(self, content, entry, doc): | def getDate(self, content, entry, doc): |
date = ''.join(content.stripped_strings).strip() | date = ''.join(content.stripped_strings).strip() |
(a,b,c) = date.partition("(") | (a,b,c) = date.partition("(") |
date = self.remove_control_chars(a.replace("Octber","October")) | date = self.remove_control_chars(a.replace("Octber","October")) |
print date | print date |
edate = parse(date, dayfirst=True, fuzzy=True).strftime("%Y-%m-%d") | edate = parse(date, dayfirst=True, fuzzy=True).strftime("%Y-%m-%d") |
print edate | print edate |
doc.update({'date': edate}) | doc.update({'date': edate}) |
return | return |
def getLinks(self, content, entry, doc): | def getLinks(self, content, entry, doc): |
links = [] | links = [] |
for atag in entry.find_all("a"): | for atag in entry.find_all("a"): |
if atag.has_key('href'): | if atag.has_key('href'): |
links.append(scrape.fullurl(content,atag['href'])) | links.append(scrape.fullurl(content,atag['href'])) |
if links != []: | if links != []: |
doc.update({'links': links}) | doc.update({'links': links}) |
return | return |
def doScrape(self): | def doScrape(self): |
foidocsdb = scrape.couch['disclosr-foidocuments'] | foidocsdb = scrape.couch['disclosr-foidocuments'] |
(url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) | (url,mime_type,content) = scrape.fetchURL(scrape.docsdb, self.getURL(), "foidocuments", self.getAgencyID()) |
if content != None: | if content != None: |
if mime_type == "text/html" or mime_type == "application/xhtml+xml" or mime_type =="application/xml": | if mime_type == "text/html" or mime_type == "application/xhtml+xml" or mime_type =="application/xml": |
# http://www.crummy.com/software/BeautifulSoup/documentation.html | # http://www.crummy.com/software/BeautifulSoup/documentation.html |
soup = BeautifulSoup(content) | soup = BeautifulSoup(content) |
table = self.getTable(soup) | table = self.getTable(soup) |
for row in self.getRows(table): | for row in self.getRows(table): |
columns = row.find_all('td') | columns = row.find_all('td') |
if len(columns) == self.getColumnCount(): | if len(columns) == self.getColumnCount(): |
(id, date, title, description, notes) = self.getColumns(columns) | (id, date, title, description, notes) = self.getColumns(columns) |
print self.remove_control_chars(''.join(id.stripped_strings)) | print self.remove_control_chars(''.join(id.stripped_strings)) |
if id.string == None: | if id.string == None: |
hash = scrape.mkhash(self.remove_control_chars(url+(''.join(date.stripped_strings)))) | hash = scrape.mkhash(self.remove_control_chars(url+(''.join(date.stripped_strings)))) |
else: | else: |
hash = scrape.mkhash(self.remove_control_chars(url+(''.join(id.stripped_strings)))) | hash = scrape.mkhash(self.remove_control_chars(url+(''.join(id.stripped_strings)))) |
doc = foidocsdb.get(hash) | doc = foidocsdb.get(hash) |
if doc == None: | if doc == None: |
print "saving " +hash | print "saving " +hash |
doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': self.getURL(), 'docID': (''.join(id.stripped_strings))} | doc = {'_id': hash, 'agencyID': self.getAgencyID(), 'url': self.getURL(), 'docID': (''.join(id.stripped_strings))} |
self.getLinks(self.getURL(),row,doc) | self.getLinks(self.getURL(),row,doc) |
self.getTitle(title,row, doc) | self.getTitle(title,row, doc) |
self.getDate(date,row, doc) | self.getDate(date,row, doc) |
self.getDescription(description,row, doc) | self.getDescription(description,row, doc) |
if notes != None: | if notes != None: |
doc.update({ 'notes': (''.join(notes.stripped_strings))}) | doc.update({ 'notes': (''.join(notes.stripped_strings))}) |
foidocsdb.save(doc) | badtitles = ['-','Summary of FOI Request','FOI request(in summary form)','Summary of FOI request received by the ASC', |
'Summary of FOI request received by agency/minister','Description of Documents Requested','FOI request','Description of FOI Request','Summary of request','Description','Summary', | |
'Summary of FOIrequest received by agency/minister','Summary of FOI request received','Description of FOI Request',"FOI request",'Results 1 to 67 of 67'] | |
if doc['title'] not in badtitles and doc['description'] != '': | |
print "saving" | |
foidocsdb.save(doc) | |
else: | else: |
print "already saved "+hash | print "already saved "+hash |
elif len(row.find_all('th')) == self.getColumnCount(): | elif len(row.find_all('th')) == self.getColumnCount(): |
print "header row" | print "header row" |
else: | else: |
print "ERROR number of columns incorrect" | print "ERROR number of columns incorrect" |
print row | print row |
<?php | <?php |
// Agency X updated Y, new files, diff of plain text/link text, | // Agency X updated Y, new files, diff of plain text/link text, |
// feed for just one agency or all | // feed for just one agency or all |
// This is a minimum example of using the Universal Feed Generator Class | // This is a minimum example of using the Universal Feed Generator Class |
include("../lib/FeedWriter/FeedTypes.php"); | include("../lib/FeedWriter/FeedTypes.php"); |
include_once('../include/common.inc.php'); | include_once('../include/common.inc.php'); |
//Creating an instance of FeedWriter class. | //Creating an instance of FeedWriter class. |
$TestFeed = new RSS2FeedWriter(); | $TestFeed = new RSS2FeedWriter(); |
//Setting the channel elements | //Setting the channel elements |
//Use wrapper functions for common channelelements | //Use wrapper functions for common channelelements |
$TestFeed->setTitle('disclosurelo.gs Newest Entries - All'); | $TestFeed->setTitle('disclosurelo.gs Newest Entries - All'); |
$TestFeed->setLink('http://disclosurelo.gs/rss.xml.php'); | $TestFeed->setLink('http://disclosurelo.gs/rss.xml.php'); |
$TestFeed->setDescription('disclosurelo.gs Newest Entries - All Agencies'); | $TestFeed->setDescription('disclosurelo.gs Newest Entries - All Agencies'); |
$TestFeed->setChannelElement('language', 'en-us'); | $TestFeed->setChannelElement('language', 'en-us'); |
$TestFeed->setChannelElement('pubDate', date(DATE_RSS, time())); | $TestFeed->setChannelElement('pubDate', date(DATE_RSS, time())); |
//Retriving informations from database | //Retriving informations from database |
$idtoname = Array(); | $idtoname = Array(); |
$agenciesdb = $server->get_db('disclosr-agencies'); | $agenciesdb = $server->get_db('disclosr-agencies'); |
foreach ($agenciesdb->get_view("app", "byCanonicalName")->rows as $row) { | foreach ($agenciesdb->get_view("app", "byCanonicalName")->rows as $row) { |
$idtoname[$row->id] = trim($row->value->name); | $idtoname[$row->id] = trim($row->value->name); |
} | } |
$foidocsdb = $server->get_db('disclosr-foidocuments'); | $foidocsdb = $server->get_db('disclosr-foidocuments'); |
$rows = $foidocsdb->get_view("app", "byDate", Array('9999-99-99','0000-00-00', 50), true)->rows; | $rows = $foidocsdb->get_view("app", "byDate", Array('9999-99-99','0000-00-00', 50), true)->rows; |
//print_r($rows); | //print_r($rows); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
//Create an empty FeedItem | //Create an empty FeedItem |
$newItem = $TestFeed->createNewItem(); | $newItem = $TestFeed->createNewItem(); |
//Add elements to the feed item | //Add elements to the feed item |
$newItem->setTitle($row->value->title); | $newItem->setTitle($row->value->title); |
$newItem->setLink("http://disclosurelo.gs/view.php?id=".$row->value->_id); | $newItem->setLink("http://disclosurelo.gs/view.php?id=".$row->value->_id); |
$newItem->setDate(strtotime($row->value->date)); | $newItem->setDate(strtotime($row->value->date)); |
$newItem->setDescription(displayLogEntry($row,$idtoname)); | $newItem->setDescription(displayLogEntry($row,$idtoname)); |
$newItem->setAuthor($idtoname[$row->value->agencyID]); | |
$newItem->addElement('guid', "http://disclosurelo.gs/view.php?id=".$row->value->_id,array('isPermaLink'=>'true')); | $newItem->addElement('guid', "http://disclosurelo.gs/view.php?id=".$row->value->_id,array('isPermaLink'=>'true')); |
//Now add the feed item | //Now add the feed item |
$TestFeed->addItem($newItem); | $TestFeed->addItem($newItem); |
} | } |
//OK. Everything is done. Now genarate the feed. | //OK. Everything is done. Now genarate the feed. |
$TestFeed->generateFeed(); | $TestFeed->generateFeed(); |
?> | ?> |
import sys,os | import sys,os |
sys.path.insert(0, os.path.join(os.path.dirname(__file__) or '.', '../')) | sys.path.insert(0, os.path.join(os.path.dirname(__file__) or '.', '../')) |
import genericScrapers | import genericScrapers |
import scrape | import scrape |
from bs4 import BeautifulSoup | from bs4 import BeautifulSoup |
#http://www.doughellmann.com/PyMOTW/abc/ | #http://www.doughellmann.com/PyMOTW/abc/ |
class ScraperImplementation(genericScrapers.GenericOAICDisclogScraper): | class ScraperImplementation(genericScrapers.GenericOAICDisclogScraper): |
def getDescription(self,content, entry,doc): | def getDescription(self,content, entry,doc): |
link = None | link = None |
links = [] | links = [] |
description = "" | description = "" |
for atag in entry.find_all('a'): | for atag in entry.find_all('a'): |
if atag.has_key('href'): | if atag.has_key('href'): |
link = scrape.fullurl(self.getURL(),atag['href']) | link = scrape.fullurl(self.getURL(),atag['href']) |
(url,mime_type,htcontent) = scrape.fetchURL(scrape.docsdb, link, "foidocuments", self.getAgencyID(), False) | (url,mime_type,htcontent) = scrape.fetchURL(scrape.docsdb, link, "foidocuments", self.getAgencyID(), False) |
if htcontent != None: | if htcontent != None: |
if mime_type == "text/html" or mime_type == "application/xhtml+xml" or mime_type =="application/xml": | if mime_type == "text/html" or mime_type == "application/xhtml+xml" or mime_type =="application/xml": |
# http://www.crummy.com/software/BeautifulSoup/documentation.html | # http://www.crummy.com/software/BeautifulSoup/documentation.html |
soup = BeautifulSoup(htcontent) | soup = BeautifulSoup(htcontent) |
for row in soup.find(class_ = "ms-rteTable-GreyAlternating").find_all('tr'): | for row in soup.find(class_ = "ms-rteTable-GreyAlternating").find_all('tr'): |
if row != None: | if row != None: |
rowtitle = row.find('th').string | rowtitle = row.find('th').string |
description = description + "\n" + rowtitle + ": " | if rowtitle != None: |
description = description + "\n" + rowtitle + ": " | |
for text in row.find('td').stripped_strings: | for text in row.find('td').stripped_strings: |
description = description + text | description = description + text |
for atag in row.find_all("a"): | for atag in row.find_all("a"): |
if atag.has_key('href'): | if atag.has_key('href'): |
links.append(scrape.fullurl(link,atag['href'])) | links.append(scrape.fullurl(link,atag['href'])) |
if links != []: | if links != []: |
doc.update({'links': links}) | doc.update({'links': links}) |
if description != "": | if description != "": |
doc.update({ 'description': description}) | doc.update({ 'description': description}) |
def getColumnCount(self): | def getColumnCount(self): |
return 2 | return 2 |
def getTable(self,soup): | def getTable(self,soup): |
return soup.find(class_ = "ms-rteTable-GreyAlternating") | return soup.find(class_ = "ms-rteTable-GreyAlternating") |
def getColumns(self,columns): | def getColumns(self,columns): |
(date, title) = columns | (date, title) = columns |
return (title, date, title, title, None) | return (title, date, title, title, None) |
if __name__ == '__main__': | if __name__ == '__main__': |
print 'Subclass:', issubclass(ScraperImplementation, genericScrapers.GenericOAICDisclogScraper) | print 'Subclass:', issubclass(ScraperImplementation, genericScrapers.GenericOAICDisclogScraper) |
print 'Instance:', isinstance(ScraperImplementation(), genericScrapers.GenericOAICDisclogScraper) | print 'Instance:', isinstance(ScraperImplementation(), genericScrapers.GenericOAICDisclogScraper) |
ScraperImplementation().doScrape() | ScraperImplementation().doScrape() |
<?php | <?php |
function include_header_documents($title) { | function include_header_documents($title) { |
?> | header('X-UA-Compatible: IE=edge,chrome=1'); |
<!doctype html> | ?> |
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> | <!doctype html> |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> | <!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> | <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> |
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> | <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> |
<!-- Consider adding a manifest.appcache: h5bp.com/d/Offline --> | <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> |
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> | <!-- Consider adding a manifest.appcache: h5bp.com/d/Offline --> |
<head> | <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> |
<meta charset="utf-8"> | <head> |
<meta charset="utf-8"> | |
<!-- Use the .htaccess and remove these lines to avoid edge case issues. | <title>Australian Disclosure Logs<?php if ($title != "") echo " - $title"; ?></title> |
More info: h5bp.com/i/378 --> | <meta name="description" content=""> |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | |
<title>Australian Disclosure Logs<?php if ($title != "") echo " - $title";?></title> | <!-- Mobile viewport optimized: h5bp.com/viewport --> |
<meta name="description" content=""> | <meta name="viewport" content="width=device-width"> |
<link rel="alternate" type="application/rss+xml" title="Latest Disclosure Log Entries" href="rss.xml.php" /> | |
<!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons --> | |
<meta name="google-site-verification" content="jkknX5g2FCpQvrW030b1Nq2hyoa6mb3EDiA7kCoHNj8" /> | |
<!-- Mobile viewport optimized: h5bp.com/viewport --> | <!-- Le styles --> |
<meta name="viewport" content="width=device-width"> | <link href="css/bootstrap.min.css" rel="stylesheet"> |
<link rel="alternate" type="application/rss+xml" title="Latest Disclosure Log Entries" href="rss.xml.php" /> | <style type="text/css"> |
<!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons --> | body { |
<meta name="google-site-verification" content="jkknX5g2FCpQvrW030b1Nq2hyoa6mb3EDiA7kCoHNj8" /> | padding-top: 60px; |
padding-bottom: 40px; | |
} | |
.sidebar-nav { | |
padding: 9px 0; | |
} | |
</style> | |
<link href="css/bootstrap-responsive.min.css" rel="stylesheet"> | |
<!-- Le styles --> | <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> |
<link href="css/bootstrap.min.css" rel="stylesheet"> | <!--[if lt IE 9]> |
<style type="text/css"> | <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> |
body { | <![endif]--> |
padding-top: 60px; | <!-- More ideas for your <head> here: h5bp.com/d/head-Tips --> |
padding-bottom: 40px; | |
} | |
.sidebar-nav { | |
padding: 9px 0; | |
} | |
</style> | |
<link href="css/bootstrap-responsive.min.css" rel="stylesheet"> | |
<!-- HTML5 shim, for IE6-8 support of HTML5 elements --> | <!-- All JavaScript at the bottom, except this Modernizr build. |
<!--[if lt IE 9]> | Modernizr enables HTML5 elements & feature detects for optimal performance. |
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> | Create your own custom Modernizr build: www.modernizr.com/download/ |
<![endif]--> | <script src="js/libs/modernizr-2.5.3.min.js"></script>--> |
<!-- More ideas for your <head> here: h5bp.com/d/head-Tips --> | <script src="js/jquery.js"></script> |
<script type="text/javascript" src="js/flotr2.min.js"></script> | |
<!-- All JavaScript at the bottom, except this Modernizr build. | </head> |
Modernizr enables HTML5 elements & feature detects for optimal performance. | <body> |
Create your own custom Modernizr build: www.modernizr.com/download/ | <div class="navbar navbar-inverse navbar-fixed-top"> |
<script src="js/libs/modernizr-2.5.3.min.js"></script>--> | <div class="navbar-inner"> |
<script src="js/jquery.js"></script> | <div class="container-fluid"> |
<script type="text/javascript" src="js/flotr2.min.js"></script> | <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> |
<span class="icon-bar"></span> | |
</head> | <span class="icon-bar"></span> |
<body> | <span class="icon-bar"></span> |
<div class="navbar navbar-inverse navbar-fixed-top"> | </a> |
<div class="navbar-inner"> | <a class="brand" href="#">Australian Disclosure Logs</a> |
<div class="container-fluid"> | <div class="nav-collapse collapse"> |
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> | <p class="navbar-text pull-right"> |
<span class="icon-bar"></span> | Check out our subsites on: |
<span class="icon-bar"></span> | <a href="http://orgs.disclosurelo.gs">Government Agencies</a> |
<span class="icon-bar"></span> | • <a href="http://lobbyists.disclosurelo.gs">Political Lobbyists</a> |
</a> | • <a href="http://contracts.disclosurelo.gs">Government Contracts and Spending</a> |
<a class="brand" href="#">Australian Disclosure Logs</a> | |
<div class="nav-collapse collapse"> | |
<p class="navbar-text pull-right"> | |
Check out our subsites on: | |
<a href="http://orgs.disclosurelo.gs">Government Agencies</a> | |
• <a href="http://lobbyists.disclosurelo.gs">Political Lobbyists</a> | |
• <a href="http://contracts.disclosurelo.gs">Government Contracts and Spending</a> | |
</p> | </p> |
<ul class="nav"> | <ul class="nav"> |
<li><a href="index.php">Home</a></li> | <li><a href="index.php">Home</a></li> |
<li><a href="disclogsList.php">List of Disclosure Logs</a></li> | <li><a href="disclogsList.php">List of Disclosure Logs</a></li> |
<li><a href="about.php">About</a></li> | <li><a href="about.php">About</a></li> |
</ul> | |
</div><!--/.nav-collapse --> | |
</div> | |
</div> | |
</div> | |
<div class="container"> | |
<?php | |
} | |
function include_footer_documents() { | |
?> | |
</div> <!-- /container --> | |
<hr> | |
<footer> | </ul> |
<p>© Company 2012</p> | </div><!--/.nav-collapse --> |
</footer> | </div> |
<script type="text/javascript"> | </div> |
</div> | |
<div class="container"> | |
<?php | |
} | |
var _gaq = _gaq || []; | function include_footer_documents() { |
_gaq.push(['_setAccount', 'UA-12341040-4']); | ?> |
_gaq.push(['_setDomainName', 'disclosurelo.gs']); | </div> <!-- /container --> |
_gaq.push(['_setAllowLinker', true]); | <hr> |
_gaq.push(['_trackPageview']); | |
(function() { | <footer> |
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | <p>Not affiliated with or endorsed by any government agency.</p> |
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | </footer> |
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | <script type="text/javascript"> |
})(); | |
</script> | var _gaq = _gaq || []; |
<!-- Le javascript | _gaq.push(['_setAccount', 'UA-12341040-4']); |
================================================== --> | _gaq.push(['_setDomainName', 'disclosurelo.gs']); |
<!-- Placed at the end of the document so the pages load faster --> | _gaq.push(['_setAllowLinker', true]); |
<!-- | _gaq.push(['_trackPageview']); |
<script src="js/bootstrap-transition.js"></script> | |
<script src="js/bootstrap-alert.js"></script> | (function() { |
<script src="js/bootstrap-modal.js"></script> | var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
<script src="js/bootstrap-dropdown.js"></script> | ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
<script src="js/bootstrap-scrollspy.js"></script> | var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
<script src="js/bootstrap-tab.js"></script> | })(); |
<script src="js/bootstrap-tooltip.js"></script> | |
<script src="js/bootstrap-popover.js"></script> | </script> |
<script src="js/bootstrap-button.js"></script> | <!-- Le javascript |
<script src="js/bootstrap-collapse.js"></script> | ================================================== --> |
<script src="js/bootstrap-carousel.js"></script> | <!-- Placed at the end of the document so the pages load faster --> |
<script src="js/bootstrap-typeahead.js"></script>--> | <!-- |
<script src="js/bootstrap-transition.js"></script> | |
<script src="js/bootstrap-alert.js"></script> | |
<script src="js/bootstrap-modal.js"></script> | |
<script src="js/bootstrap-dropdown.js"></script> | |
<script src="js/bootstrap-scrollspy.js"></script> | |
<script src="js/bootstrap-tab.js"></script> | |
<script src="js/bootstrap-tooltip.js"></script> | |
<script src="js/bootstrap-popover.js"></script> | |
<script src="js/bootstrap-button.js"></script> | |
<script src="js/bootstrap-collapse.js"></script> | |
<script src="js/bootstrap-carousel.js"></script> | |
<script src="js/bootstrap-typeahead.js"></script>--> | |
</body> | </body> |
</html> | </html> |
<?php | <?php |
} | |
function truncate($string, $length, $stopanywhere = false) { | |
//truncates a string to a certain char length, stopping on a word if not specified otherwise. | |
if (strlen($string) > $length) { | |
//limit hit! | |
$string = substr($string, 0, ($length - 3)); | |
if ($stopanywhere) { | |
//stop anywhere | |
$string .= '...'; | |
} else { | |
//stop on a word. | |
$string = substr($string, 0, strrpos($string, ' ')) . '...'; | |
} | |
} | |
return $string; | |
} | } |
function displayLogEntry($row, $idtoname) { | function displayLogEntry($row, $idtoname) { |
$result = ""; | $result = ""; |
$result .= "<div><h2>".$row->value->date.": ".$row->value->title." (".$idtoname[$row->value->agencyID].")</h2> <p>".str_replace("\n","<br>",$row->value->description); | $result .= '<div itemscope itemtype="http://schema.org/Article">'; |
if (isset($row->value->notes)) { | $result .= '<h2> <span itemprop="datePublished">' . $row->value->date . "</span>: <span itemprop='name headline'>" . truncate($row->value->title, 120)."</span>"; |
$result .= " <br>Note: ".$row->value->notes; | $result .= '(<span itemprop="author publisher creator">' . $idtoname[$row->value->agencyID] . '</span>)</h2>'; |
} | $result .= "<p itemprop='description articleBody text'> Title" . $row->value->title . "<br/>" . str_replace("\n", "<br>", $row->value->description); |
$result .= "</p>"; | if (isset($row->value->notes)) { |
$result .= " <br>Note: " . $row->value->notes; | |
} | |
$result .= "</p>"; | |
if (isset($row->value->links)){ | if (isset($row->value->links)) { |
$result .= "<h3>Links/Documents</h3><ul>"; | $result .= '<h3>Links/Documents</h3><ul itemprop="associatedMedia">'; |
foreach ($row->value->links as $link) { | foreach ($row->value->links as $link) { |
$result .= "<li><a href='$link'>".$link."</a></li>"; | $result .= '<li itemscope itemtype="http://schema.org/MediaObject"><a href='.$link.' itemprop="url contentURL">' . urlencode($link) . "</a></li>"; |
} | |
$result .= "</ul>"; | |
} | |
$result .= "<small><A itemprop='url' href='" . $row->value->url . "'>View original source...</a> ID: " . strip_tags($row->value->docID) . "</small>"; | |
$result .= "</div>"; | |
return $result; | |
} | } |
$result .= "</ul>"; | |
} | |
$result .= "<small><A href='".$row->value->url."'>View original source...</a> ID: ".strip_tags($row->value->docID)."</small>"; | |
$result .= "</div>"; | |
return $result; | |
} | |