viewgit/index.php:465 Only variables should be passed by reference [2048]

viewgit/index.php:466 Non-static method GeSHi::get_language_name_from_extension() should not be called statically [2048]

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4.  
  5. import random
  6. import urllib2
  7. import mutex
  8. import threading
  9. import re, time
  10. from optparse import OptionParser
  11.  
  12. default_page = "http://poisson.phc.unipi.it"
  13.  
  14. __author__ = "Leonardo Robol <leo@robol.it>"
  15.  
  16. mtx_url_dict = mutex.mutex()
  17.  
  18. size = 1000
  19. url_dict = {}
  20. url_counter = range(size)
  21.  
  22. max_steps = 5
  23.  
  24. debug = 0
  25. outfile = "connections.txt"
  26.  
  27. ExitRequired = False
  28.  
  29.  
  30. def get_links(page):
  31. """Restituisce una lista con i link
  32. presenti nella pagina data, in forma canonica"""
  33. content, real_url = get_content(page.url)
  34.  
  35. if(content == -1):
  36. return -1
  37.  
  38. links = re.findall(r"<a href=\"(\S*)\"[^>]*>",content)
  39. ret = []
  40. for link in links:
  41. # Espando il link in modo da (speriamo!)
  42. # garantire l'unicità
  43. ret.append(expand_url(real_url, link))
  44.  
  45. return ret
  46.  
  47.  
  48. def expand_url(parent, url):
  49. """Questa funzione prende l'url della pagina parent
  50. e l'url del link e dà all'url del link una forma unica
  51. e canonica, del tipo
  52.  
  53. http://www.example.com/pagina
  54. http://www.example.com/pagina.html
  55. """
  56.  
  57. if len(url) == 0:
  58. return url
  59.  
  60. ## Controllo che l'url non cominci con un punto
  61. ## nel qual caso cerchiamo di rimediare subito,
  62. ## ma non cadiamo nel tranello di ignorare i ..
  63. if url[0] == ".":
  64. if len(url) == 1:
  65. url = parent
  66.  
  67. else:
  68. if(url[1] != "."):
  69. url = url[1:]
  70.  
  71. ## Se all'inizio dell'url c'è uno slash non ci serve tutto
  72. ## il parent, ma solo la prima parte
  73. if url.startswith("/"):
  74. parent = re.search(".+//[^/]*", parent).group(0)
  75. else:
  76. # in caso contrario dobbiamo assicurarci di troncare
  77. # l'ultima parte dell'url dopo il /, a meno che non
  78. # finisca senza estensione (in quel caso aggiungiamo un /)
  79. if re.search("\.[^/]*$", parent):
  80. parent = re.sub("[^/]*$", "", parent)
  81. else:
  82. if not parent.endswith("/"):
  83. parent += "/"
  84.  
  85.  
  86.  
  87. ## Controlliamo prima di tutto se nell'url c'è un
  88. ## protocollo
  89. protocol = re.search(r"(\w+):", url)
  90. if protocol == None:
  91. url = parent + url
  92. return url
  93.  
  94. def get_content(url):
  95. """Cerca di scaricare l'url dato e restituisce
  96. -1 se non ce la fa, il contenuto altrimenti"""
  97. try:
  98. req = urllib2.urlopen(url)
  99. except:
  100. return (-1, None)
  101.  
  102. return (req.read(), req.geturl())
  103.  
  104. class Page():
  105. """Una pagina web. Questa classe, quando viene istanziata,
  106. controlla se una pagina con quel nome è già presente (una
  107. pagina è unica!) e se lo è restituisce lo stesso oggetto,
  108. altrimenti ne crea uno nuovo con un nuovo ID"""
  109.  
  110. def __repr__(self):
  111. return "<Page object: %s>" % self.url
  112.  
  113. def __init__(self, url="", parent=None):
  114.  
  115.  
  116. if(url != ""):
  117. mtx_url_dict.lock(self.__new_page, (url, parent))
  118. mtx_url_dict.unlock()
  119. else:
  120. mtx_url_dict.lock(self.__get_page, parent)
  121. mtx_url_dict.unlock()
  122.  
  123. def __get_page(self, parent):
  124.  
  125. if(len(url_counter) == 0):
  126. self.exhausted = True
  127. return
  128.  
  129. page_found = False
  130.  
  131. while(not page_found):
  132.  
  133. for url in url_dict:
  134. page = Page(url)
  135. if not page.analyzed:
  136. page_found = True
  137. self.url = url
  138. break
  139.  
  140. if not page_found:
  141. time.sleep(1)
  142.  
  143. # Questo è un punto dove il Crawler
  144. # si potrebbe bloccare e quindi facciamo
  145. # un check sull' ExitRequired
  146. # Ovviamente poi sarà necessario che anche
  147. # il chiamante lo faccia!
  148. if ExitRequired:
  149. return
  150.  
  151.  
  152. self.ID = page.ID
  153. self.analyzed = page.analyzed
  154. self.exhausted = False
  155. self.step = page.step
  156. url_dict[url].analyzed = True
  157.  
  158. def __new_page(self, (url, parent)):
  159. # Questo ci serve per tenere il
  160. # conto di tutti gli url
  161. global url_dict
  162. global url_counter
  163.  
  164. self.exhausted = False
  165. self.analyzed = False
  166. self.url = url
  167.  
  168.  
  169. if(url_dict.has_key(url)):
  170. # Preservo i parametri che esistono già!
  171. self.ID = url_dict[url].ID
  172. self.analyzed = url_dict[url].analyzed
  173. self.step = url_dict[url].step
  174. if parent == None:
  175. self.step = 0
  176. else:
  177. if(parent.step < self.step):
  178. self.step = parent.step + 1
  179.  
  180. else:
  181. try:
  182. self.ID = url_counter.pop()
  183. except IndexError:
  184. self.exhausted = True
  185.  
  186.  
  187. # Conto in quanti passi si raggiunge questa pagina
  188. if parent == None:
  189. self.step = 0
  190. else:
  191. self.step = parent.step + 1
  192. url_dict[url] = self
  193. url_dict[url].links = []
  194.  
  195.  
  196. def add_link(self, page):
  197.  
  198. if(page.exhausted):
  199. return -1
  200. if debug >= 2:
  201. print " => Adding link to %s" % page.url
  202. mtx_url_dict.lock(self.__add_link, page.ID)
  203. mtx_url_dict.unlock()
  204. return 0
  205.  
  206. def __add_link(self, ID):
  207. url_dict[self.url].links.append(ID)
  208.  
  209. def links(self):
  210. return url_dict[self.url].links
  211.  
  212.  
  213.  
  214.  
  215. class Crawler(threading.Thread):
  216. """Partendo da startpage, segue tutti i link registrando
  217. i vari collegamenti fra le pagine. Una volta raggiunto il
  218. limite di pagine da controllare termina"""
  219.  
  220. def __init__(self, startpage=default_page):
  221. threading.Thread.__init__(self)
  222. self.start_page = startpage
  223. self.waitingforpage = False
  224.  
  225. def WaitingForPage(self):
  226. """Ritorna True se il Crawler sta cercando di ottenere
  227. una nuova pagina"""
  228. return self.waitingforpage
  229.  
  230.  
  231. def run(self):
  232.  
  233. # Capiamo che pagina ci serve
  234. page = Page(self.start_page)
  235.  
  236. while(not page.exhausted):
  237. self.waitingforpage = True
  238. ## Stiamo attenti a non fare troppi passi
  239. ## dalla pagina di partenza
  240. page = Page()
  241.  
  242. ## Se ci chiedono di uscire perché abbiamo
  243. ## analizzato tutte la pagine ce ne andiamo
  244. if ExitRequired:
  245. return
  246.  
  247. if page.step >= max_steps:
  248. print " => Ohi, troppi step! Riparto"
  249. page = Page(self.start_page)
  250.  
  251. self.waitingforpage = False
  252.  
  253. if page.exhausted:
  254. break
  255.  
  256. if debug >= 1:
  257. print " => Analyzing page %s" % page.url
  258.  
  259.  
  260. # Come prima cosa devo fare il parsing dei
  261. # link che ci sono nella pagina
  262. # Diamo una mixata per simulare meglio
  263. # il caso.. dato che tanto è probabile che
  264. # alcuni link rimarranno non visitati!
  265. links = get_links(page)
  266.  
  267. ## A questo punto io che mi occupo della pagina devo
  268. ## aggiungere tutti i link alla pagina
  269.  
  270. if not links == -1:
  271. random.shuffle(links)
  272. for l in links:
  273. lpage = Page(l, page)
  274.  
  275. if not lpage.exhausted:
  276. page.add_link(lpage)
  277. else:
  278. break
  279.  
  280.  
  281.  
  282.  
  283. if __name__ == "__main__":
  284.  
  285. parser = OptionParser()
  286. parser.add_option("-c", "--concurrency", dest="concurrency", action="store",
  287. help="Set level of concurrency (i.e. how many threads)", default=3)
  288. parser.add_option("-d", "--debug", dest="debug", action="store",
  289. help="Set debug level", default=0)
  290. parser.add_option("-o", "--output", dest="outfile", action="store",
  291. help="Name of the output file for the connection matrix", default="connections.txt")
  292. parser.add_option("-n", "--number", dest="size", action="store",
  293. help="Number of pages to analyze", default=1000)
  294. parser.add_option("-m", "--max-steps", dest="max_steps", action="store",
  295. help="Max steps to walk from the starting page", default=5)
  296. parser.add_option("-s", "--start-page", dest="start_page",
  297. default="http://poisson.phc.unipi.it",
  298. help="Starting page for all the crawlers",
  299. action="store")
  300.  
  301.  
  302. (option, args) = parser.parse_args()
  303.  
  304. concurrency = int(option.concurrency)
  305. debug = bool(option.debug)
  306. outfile = option.outfile
  307. size = int(option.size)
  308. url_counter = range(size)
  309. url_counter.reverse()
  310. max_steps = int(option.max_steps)
  311. default_page = option.start_page
  312.  
  313.  
  314. l = time.localtime(time.time())
  315. print " => Starting with this configuration at %s:%s:%s\n\
  316. %d thread(s)\n\
  317. %d pages to analyze\n\
  318. %d max steps from the start page, %s\n\
  319. Writing on file %s\n\
  320. " % (l.tm_hour,l.tm_min,l.tm_sec, concurrency, size, max_steps, default_page, outfile)
  321.  
  322.  
  323. ## Avvio i thread, di modo che si impegnino a lavorare
  324. ## Ora il mio scopo sarà controllare che non finiscano
  325. ## le pagine
  326. threads = []
  327. for i in range(0, concurrency):
  328. threads.append(Crawler(default_page))
  329. threads[i].start()
  330.  
  331. while threads[0].isAlive():
  332. ## Controllo se tutti i thread sono
  333. ## alla ricerca di una pagina. Se la
  334. ## risposta è sì le pagine sono finite
  335. ## e possiamo uscire
  336. PageAreExhausted = True
  337. for t in threads:
  338. if not t.WaitingForPage():
  339. PageAreExhausted = False
  340. break
  341.  
  342. if PageAreExhausted:
  343. ## Questa variabile globale farà
  344. ## uscire tutti i thread
  345. ExitRequired = True
  346. print " => There are no more pages in my range, exiting"
  347. break
  348.  
  349. ## Se non c'è niente da fare posso
  350. ## anche rilassarmi ed aspettare un
  351. ## secondo prima di rieseguire il check
  352. time.sleep(1)
  353.  
  354.  
  355. ## Qui non c'è modo umano di terminare il
  356. ## suo lavoro, bisognerà studiarci sopra
  357. for t in threads:
  358. t.join()
  359.  
  360.  
  361. ## A questo punto mi devo preoccupare di salvare
  362. ## la matrice in un formato soddisfacente
  363.  
  364. out = open(outfile, 'w')
  365.  
  366. ## Il numero massimo di pagine meno quelle avanzate =
  367. ## le pagine effettivamente usate!
  368. out.write(str(size - len(url_counter)) + "\n")
  369.  
  370.  
  371.  
  372. for page in url_dict:
  373. for link in url_dict[page].links:
  374. out.write(page + "\t" + str(url_dict[page].ID) + "\t" + str(link) + "\n")
  375.  
  376. l = time.localtime(time.time())
  377. print " => Work completed at %s:%s:%s " % (l.tm_hour,l.tm_min,l.tm_sec)
  378.  
  379.  
  380.  
  381.