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