clib.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. #!/usr/bin/env python3.6
  2. # -*- encoding: utf-8 -*-
  3. # feitor por: mrxrobot
  4. # v0.2
  5. from urllib.request import urlopen
  6. from urllib.request import Request
  7. from urllib.request import urlretrieve
  8. from bs4 import BeautifulSoup
  9. from termcolor import colored
  10. from unicodedata import normalize
  11. #modulos para executar comandos no sistema
  12. import sys
  13. import os
  14. import time
  15. # modulo para escolhar algo aleatorio, no caso, o user-agent
  16. from random import choice
  17. #define uma variavel contendo a mensagem de inicio programa
  18. msg=colored("""
  19. bbbbbbbb
  20. lllllll iiii b::::::b
  21. l:::::l i::::i b::::::b
  22. l:::::l iiii b::::::b
  23. l:::::l b:::::b
  24. cccccccccccccccc l::::l iiiiiii b:::::bbbbbbbbb
  25. cc:::::::::::::::c l::::l i:::::i b::::::::::::::bb
  26. c:::::::::::::::::c l::::l i::::i b::::::::::::::::b
  27. c:::::::cccccc:::::c l::::l i::::i b:::::bbbbb:::::::b
  28. c::::::c ccccccc l::::l i::::i b:::::b b::::::b
  29. c:::::c l::::l i::::i b:::::b b:::::b
  30. c:::::c l::::l i::::i b:::::b b:::::b
  31. c::::::c ccccccc l::::l i::::i b:::::b b:::::b
  32. c:::::::cccccc:::::c l::::::l i::::::i b:::::bbbbbb::::::b
  33. c:::::::::::::::::c l::::::l i::::::i b::::::::::::::::b
  34. cc:::::::::::::::c l::::::l i::::::i b:::::::::::::::b
  35. cccccccccccccccc llllllll iiiiiiii bbbbbbbbbbbbbbbb {v}
  36. """.format(v=colored("v0.2","green")),"red")
  37. #define uma variavel contendo as informaçoes de ajuda
  38. msg_help=colored("""
  39. _ _
  40. | |__ ___ | | _ __
  41. | '_ \ / _ \| || '_ \
  42. | | | || __/| || |_) |
  43. |_| |_| \___||_|| .__/
  44. |_|
  45. ""","red") + colored("""
  46. ------------------------------
  47. Como pesquisar por um livro?
  48. ------------------------------
  49. Para pesquisar por um livro informe o nome do livro ou nome do autor.
  50. > nome do livro ou autor [enter]
  51. -----------------------------
  52. Comandos dentro do programa
  53. -----------------------------
  54. /h --> Exibe este menu de ajuda.
  55. /setd [/home/usuario/Downloads] --> configura um diretório padrão para armazenar os livros baixados.
  56. [v]oltar --> Volta ao menu anterior.
  57. /q --> Encerra o programa.
  58. ---------------------------------
  59. Como baixar o livro pesquisado?
  60. ---------------------------------
  61. Quando o usuário informar o nome do livro ou do autor, o programa
  62. vai iniciar a busca por livros correspondentes as informações passadas pelo
  63. usuário.
  64. Quando a pesquisa terminar, será exibido em tela a lista dos livros encontrados,
  65. juntamente com um número de identificação para cada link de download.
  66. Para baixar o livro desejado, basta informar o número do link seguido de [enter]
  67. ""","yellow")
  68. # Agora é hora da brincadeira realmente começar
  69. # Primeiro irei criar uma classe que terá os métodos e argumetos para
  70. # realizar o conexão entre o computador e o servidor onde estão os arquivos.
  71. user_agents = [
  72. 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
  73. 'Opera/9.25 (Windows NT 5.1; U; en)',
  74. 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
  75. 'Mozilla/5.0 (compatible; explorer/3.5; Win7) KHTML/3.5.5 (like Gecko) (windows 7)',
  76. 'Mozilla/5.0 (X11; U; unknow i686; en-US; rv:1.8.0.12) Gecko/20070731 unknow/dapper-security Firefox/1.5.0.12',
  77. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
  78. ]
  79. def remover_acentos(txt):
  80. for i in "[]{}^~!@#$%*()_-+;.,\=":
  81. if i in txt:
  82. txt = txt.replace(i,'')
  83. return normalize('NFKD', txt).encode('ASCII','ignore').decode('ASCII')
  84. def limpa():
  85. os.system("clear")
  86. print(msg)
  87. #arquivo de configuração do diretorio de download
  88. dconf = os.path.join(os.path.expanduser('~'),".clib-config")
  89. #cores das opções do programa (quit, help, v, enter, exit)
  90. e =colored('/q','red')
  91. h = colored("/h","yellow")
  92. vv=colored('v','green')
  93. h = colored("/h","yellow")
  94. enter=colored("enter","red")
  95. class Connect:
  96. print(msg)
  97. def __init__(self, s, format_arq=".pdf"):
  98. # Comecei inicializado a classe com 2 argumetos
  99. # o primeiro 's', recebera o nome do livro
  100. # o segundo 'format_arq' define o formato do livro a ser baixado
  101. self.s = remover_acentos(s).replace("'", '')
  102. self.ext = format_arq
  103. self.verifica()
  104. if os.path.exists(dconf):
  105. with open(dconf, "r") as f:
  106. self.dd = f.readline().strip('\r\n')
  107. if not self.dd.endswith("/"): self.dd += "/"
  108. if os.access(self.dd, os.F_OK) and os.access(self.dd, os.W_OK):
  109. self.dd = self.dd
  110. else:
  111. limpa()
  112. print(colored("Falha ao adicioar diretório %s" %(colored(self.dd,"green")),"red"))
  113. time.sleep(6)
  114. limpa()
  115. print(colored("Configurando diretório temporário para armazenar os arquivos...","red"))
  116. time.sleep(6)
  117. if os.access("/tmp/", os.W_OK):
  118. limpa()
  119. print(colored("Diretório onde os livros serão salvos: %s" %(colored("/tmp/","green")),"red"))
  120. time.sleep(6)
  121. self.dd = "/tmp/"
  122. self.writeconfig()
  123. else:
  124. print(colored("Não foi possivel configurar o diretório de download!","red"))
  125. self.volta()
  126. else:
  127. self.dd = "/tmp/"
  128. self.writeconfig()
  129. def writeconfig(self):
  130. with open(dconf, "w") as f:
  131. if not self.dd.endswith("/"): self.dd += "/"
  132. if os.access(self.dd, os.F_OK) and os.access(self.dd, os.W_OK):
  133. print(colored("Novo diretório configurado com sucesso!","red"))
  134. time.sleep(4)
  135. f.write(self.dd)
  136. else:
  137. limpa()
  138. print(colored("Falha ao adicoiar diretório %s" %(colored(self.dd,"green")),"red"))
  139. time.sleep(6)
  140. limpa()
  141. print(colored("Configurando diretório temporário para armazenar os arquivos...","red"))
  142. time.sleep(6)
  143. if os.access("/tmp/", os.W_OK):
  144. limpa()
  145. print(colored("Diretório onde os livros serão salvos: %s" %(colored("/tmp/","green")),"red"))
  146. time.sleep(6)
  147. self.dd = "/tmp/"
  148. f.write(self.dd)
  149. else:
  150. print(colored("Não foi possivel configurar o diretório de download!","red"))
  151. self.volta()
  152. def volta(self):
  153. os.system("clear")
  154. print(msg)
  155. try:
  156. Connect(str(input(f"Insira o nome do livro ou [{h}] para ajuda ou [{e}] para sair.\n> ").strip(" "))).down()
  157. except KeyboardInterrupt:
  158. sys.exit(0)
  159. def verifica(self):
  160. if self.s == "/h":
  161. os.system("clear")
  162. print(msg_help)
  163. try:
  164. input(f"> Voltar para o menu principal [{enter}]")
  165. except KeyboardInterrupt:
  166. sys.exit(0)
  167. self.volta()
  168. elif self.s == "/q":
  169. sys.exit(0)
  170. elif self.s == "-h":
  171. print("Usage: clib.py [-hv] [/setd] STRING")
  172. sys.exit(0)
  173. elif self.s == "-v":
  174. print("clib v0.2 by mrxrobot\n\nhttps://notabug.org/mrxrobot_/clib\n\n")
  175. sys.exit(0)
  176. elif self.s.startswith("-"):
  177. print("Opção inválida")
  178. sys.exit(0)
  179. elif self.s.split(" ")[0] == "/setd":
  180. self.dd = self.s.split(" ")[1]
  181. self.writeconfig()
  182. self.volta()
  183. elif self.s.startswith("/"):
  184. print(colored("Opção inválida!", "red"))
  185. time.sleep(4)
  186. self.volta()
  187. elif self.s == "":
  188. print(colored("Erro, informe pelo menos o nome do livro ou do autor!\n","red"))
  189. time.sleep(5)
  190. self.volta()
  191. else:
  192. if teste == None:
  193. self.s = self.s.strip(" ").replace(' ', '+').replace('"', "")
  194. elif teste == "arg":
  195. self.s = self.s.strip(" ").replace(' ', '+').replace('"', "")
  196. return True
  197. def down(self):
  198. if self.verifica():
  199. os.system("clear")
  200. print(msg)
  201. try:
  202. print("Pesquisando por {s}".format(s=colored("'{s}'".format(s=self.s.replace('+', ' ')),"yellow")))
  203. self.links = []
  204. self.lista = {}
  205. self.url = f"http://lelivros.bid/?x=0&y=0&s={self.s}"
  206. self.req = Request(
  207. self.url,
  208. data=None,
  209. headers={'User-Agent': choice(user_agents)})
  210. self.resp = urlopen(self.req).read()
  211. self.soup = BeautifulSoup(self.resp, "html.parser")
  212. self.links = [x.get('href') for x in self.soup.find_all('a', {'class':' button product_type_simple'})]
  213. except KeyboardInterrupt:
  214. sys.exit(0)
  215. i = 0
  216. self.nome = []
  217. for j in self.links:
  218. self.lista[ str(i)] = str(j)
  219. self.nome.append(str(self.soup.find_all(
  220. 'li', {'class':'post-17105 product type-product status-publish has-post-thumbnail hentry first instock'
  221. })[i].find('a').find('h3').text))
  222. i += 1
  223. os.system("clear")
  224. print(msg)
  225. def lista_livro_d():
  226. cores = ['magenta', 'cyan']
  227. l = 0
  228. if len(self.lista) > 0:
  229. print("\n{n}\t\t{livro}".format(n=colored("Numero","red"), livro=colored("Livro\n","red")))
  230. for x in self.lista:
  231. #nome = self.lista[x].split("/"+self.lista[x].split('/')[4].split('-')[0] + "-")[1][:-1]
  232. print("[" + colored(str(x), cores[l]) + "]\t\t" + colored(self.nome[int(x)].upper(), cores[l]))
  233. l += 1
  234. if l == len(cores):
  235. l = 0
  236. print(" ")
  237. else:
  238. print(colored("Livro não encontrado!".upper(), "red"))
  239. try:
  240. input(f"> Voltar para o menu principal [{enter}]")
  241. except KeyboardInterrupt:
  242. sys.exit(0)
  243. self.volta()
  244. lista_livro_d()
  245. try:
  246. self.op = str(input(f'\n\nInforme o número do download ou [{e}] para sair [{vv}]oltar\n> '))
  247. except KeyboardInterrupt:
  248. sys.exit(0)
  249. def reporthook(blocknum, blocksize, totalsize):
  250. readsofar = blocknum * blocksize
  251. if totalsize > 0:
  252. percent =readsofar * 1e2 / totalsize
  253. s = "\rBaixando:\t{a}\t:\t%5.0f%% %*d".format(a=self.nome[int(self.op)]) % (
  254. percent, len(str(totalsize)), readsofar)
  255. sys.stderr.write(s)
  256. if readsofar >= totalsize:
  257. sys.stderr.write("\n")
  258. else:
  259. sys.stderr.write("read %d\n" %(readsofar,))
  260. def testa():
  261. while self.op != "/q" and self.op != "v":
  262. if self.op.isalpha(): break
  263. if self.op not in self.lista.keys(): break
  264. self.req = Request(
  265. self.lista[ str(self.op) ],
  266. data=None,
  267. headers={'User-Agent':choice(user_agents)}
  268. )
  269. self.resp = urlopen( self.req).read()
  270. self.soup = BeautifulSoup( self.resp, "html.parser" )
  271. self.d = [
  272. x.get('href').split('&')[0]
  273. for x in self.soup.find_all('div', {'class':'links-download'})[0].find_all('a')
  274. if x.get('href') not in "javascript:void(0);"
  275. ]
  276. os.system("clear")
  277. print(msg)
  278. lista_livro_d()
  279. try:
  280. urlretrieve(self.d[0], self.dd + self.nome[int(self.op)] + self.ext, reporthook)
  281. except KeyboardInterrupt:
  282. sys.exit(0)
  283. except:
  284. print("Erro no download!")
  285. os.system("clear")
  286. print(msg)
  287. lista_livro_d()
  288. print("{a} {b}\n\n".format( a=colored("\nArquivo salvo em: ", "green"), b=colored(self.dd + self.nome[int(self.op)] + self.ext, "red") ) )
  289. time.sleep(10)
  290. os.system("clear")
  291. print(msg)
  292. lista_livro_d()
  293. try:
  294. self.op = str(input(f'\n\nInforme o número do download ou [{e}] para sair [{vv}]voltar\n> '))
  295. except KeyboardInterrupt:
  296. sys.exit(0)
  297. if self.op == "/q": sys.exit(0)
  298. elif self.op == "v": self.volta()
  299. else:
  300. print(colored("Opção inválida", "red"))
  301. time.sleep(3)
  302. os.system("clear")
  303. print(msg)
  304. lista_livro_d()
  305. try:
  306. self.op = str(input(f'\n\nInforme o número do download ou [{e}] para sair [{vv}]voltar\n> '))
  307. except KeyboardInterrupt:
  308. sys.exit(0)
  309. testa()
  310. testa()
  311. if len(sys.argv) < 2:
  312. teste = None
  313. try:
  314. op=str(input(f"Insira o nome do livro ou [{h}] para ajuda ou [{e}] para sair.\n> ")).strip(" ")
  315. except KeyboardInterrupt:
  316. sys.exit(0)
  317. download = Connect(op)
  318. download.down()
  319. else:
  320. teste = "arg"
  321. arg = []
  322. for i in range(int(len(sys.argv))):
  323. arg.append(sys.argv[i])
  324. op = " ".join(arg[1:])
  325. download = Connect(op)
  326. download.down()