Class: DManga::SiteParserBase

Inherits:
Object
  • Object
show all
Defined in:
lib/dmanga/site_parser_base.rb

Direct Known Subclasses

MangaHostParser

Constant Summary collapse

USER_AGENT =
"Mozilla/5.0 (X11; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ SiteParserBase

Returns a new instance of SiteParserBase.



16
17
18
19
20
21
22
# File 'lib/dmanga/site_parser_base.rb', line 16

def initialize(argv)
  @options = Options.new(argv)
  @manga_url = nil
  # manga_name is also used as manga directory name
  @manga_name = nil
  @chapters = nil
end

Instance Attribute Details

#chaptersObject

Returns the value of attribute chapters.



13
14
15
# File 'lib/dmanga/site_parser_base.rb', line 13

def chapters
  @chapters
end

#manga_nameObject

Returns the value of attribute manga_name.



13
14
15
# File 'lib/dmanga/site_parser_base.rb', line 13

def manga_name
  @manga_name
end

#manga_urlObject

Returns the value of attribute manga_url.



13
14
15
# File 'lib/dmanga/site_parser_base.rb', line 13

def manga_url
  @manga_url
end

#verboseObject

Returns the value of attribute verbose.



13
14
15
# File 'lib/dmanga/site_parser_base.rb', line 13

def verbose
  @verbose
end

Instance Method Details

#create_dir(relative_path) ⇒ Object

check if the directory exists and create a directory relative to downlaod directory



177
178
179
180
181
182
183
184
185
186
# File 'lib/dmanga/site_parser_base.rb', line 177

def create_dir(relative_path)
  absolute_path = [@options.download_dir, relative_path].join(File::SEPARATOR)
  DManga::display_feedback "\nCriando diretorio '#{relative_path}' em '#{@options.download_dir}'" if @options.verbose
  unless Dir.exist? absolute_path
    Dir.mkdir(absolute_path)
    puts if @options.verbose ## just a blank line for prettier output
  else
    DManga::display_feedback "'#{relative_path}' directorio ja existe" if @options.verbose
  end
end

#download_dirObject

Returns the download destination directory



193
194
195
# File 'lib/dmanga/site_parser_base.rb', line 193

def download_dir
  @options.download_dir
end

#get_progressbarObject

return a progressbar suitable to the user operating system



132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/dmanga/site_parser_base.rb', line 132

def get_progressbar
  if DManga::OS.windows?
    return  ProgressBar.create(:title => 'Baixando',
                               :starting_at => 20,
                               :length => 70,
                               :total => nil)
  else
    return  ProgressBar.create(:title => 'Baixando',
                               :starting_at => 20,
                               :total => nil)
  end
end

#imgs_download(chp_path, imgs_urls) ⇒ Object

download images to path relative to Downloads directory



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/dmanga/site_parser_base.rb', line 146

def imgs_download(chp_path, imgs_urls)
  imgs_urls.each do |url|
    original_filename =  url.slice(/(?u)(\w|[_-])+\.(png|jpg)/i)

    img_path = [@options.download_dir,
                chp_path,
                original_filename].join(File::SEPARATOR)
    unless File.exist? img_path
      encoded_url = Addressable::URI.encode(url)
      DManga::display_feedback "\n#{encoded_url}"
      pbar = get_progressbar
      URI.open(
        encoded_url, "User-Agent" => USER_AGENT,
        :progress_proc => lambda {|s| pbar.increment }
      ) do |response|
        if response.status[1] == "OK"
          DManga::display_feedback "Salvando imagem em:'#{img_path}'" if @options.verbose
          File.open(img_path, "wb") do |img|
            img.puts response.read
          end
        else
          puts "Error #{reponse.status}"
        end
      end
      puts
    end
  end
end

#parse(url, regex) ⇒ Object

Parse the html and extract links that match the pattern. Can receive a block.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/dmanga/site_parser_base.rb', line 26

def parse(url, regex)
  DManga::display_feedback "\nfetching #{url}" if @options.verbose
  result = []
  URI.open(url, "User-Agent" => USER_AGENT) do |response|
    if response.status[1] == "OK"
      DManga::display_feedback "parsing #{url}" if @options.verbose
      page = response.read
      page.scan(regex) do |r| # => try first regex
        if r.length < 2
          result << r[0]
        else
          result << r
        end
      end
      result = yield(result, page) if block_given?
    else
      DManga::display_error("ERRO: Servidor respondeu: #{response.status.inpect}")
    end
  end
  result
end

#remove_invalid_simbols(name) ⇒ Object



197
198
199
200
# File 'lib/dmanga/site_parser_base.rb', line 197

def remove_invalid_simbols(name)
  # windows OS dont accept these simbols in folder name
  name.gsub!(%r{[/\\:*?"<>|]|(\.+$)|(^\.+)}, '_')
end

#search(url, regex) ⇒ Object



48
49
50
51
52
# File 'lib/dmanga/site_parser_base.rb', line 48

def search(url, regex)
  DManga::display_feedback "Iniciando busca em #{@options.site}"
  search_result = parse(url, regex)
  select_manga(search_result)
end

#select_chaptersObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/dmanga/site_parser_base.rb', line 79

def select_chapters
  DManga::display_feedback "\nCapítulos:"
  @chapters.reverse_each.with_index do |chapter, index|
    DManga::display_feedback "(#{index + 1})\t#{chapter[0]}"
  end
  answer = nil
  DManga::display_feedback "\n#{@chapters.length} capitulos encontrados\n"
  loop do
    DManga::display_prompt("Quais capitulos você quer baixar? ")
    answer = $stdin.gets.chomp
    if answer == "o" || answer.empty?
      DManga::display_feedback(
        <<-EOS
  o                         - exibe opções.
c                         - cancelar.
todos                     - baixar todos os capítulos.
inicio-fim                - baixar intervalo selecionado.
                                Ex: 0-10 - baixa do 0 ao 10.
capNum,capNum,capNum      - baixar capitulos selecionados.
                                Ex: 29,499,1 - baixa capitulos 29, 499 e 1.
        EOS
      )
    elsif answer == "c"
      DManga::display_feedback("Saindo")
      exit true
    elsif answer == "todos"
      DManga::display_feedback "Baixando todos os capítulos" if @options.verbose
      break
    elsif answer =~ /(\d+)-(\d+)/
      b = Integer($2) <= @chapters.length ? Integer($2) * -1 : @chapters.length * -1
      e = Integer($1) * -1
      @chapters = @chapters[b..e]
      DManga::display_feedback "Baixando capítulos do #{$1} ao #{$2}" if @options.verbose
      break
    elsif answer =~ /^(\d+,?)+$/
      answer = answer.split(',')
      aux = []
      # downloads are processed in reverse order (to make
      # it in crescent order)so the answer is reversed too
      answer.reverse_each do |c|
        chp = @chapters[Integer(c) * -1]
        aux << chp unless chp.nil?
      end
      @chapters = aux
      DManga::display_feedback "Baixando capítulos #{answer.to_s}" if @options.verbose
      break
    else
      DManga::display_warn("\tOpção invalida")
    end
  end
end

#select_manga(mangas) ⇒ Object

Raises:



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/dmanga/site_parser_base.rb', line 54

def select_manga(mangas)
  puts # just a new line for better output
  unless mangas.empty?
    mangas.each_with_index do |manga, index|
      DManga::display_feedback "(#{index + 1}) #{manga[1]}"
    end
    DManga::display_prompt "Selecionar manga: "
    res = $stdin.gets.chomp
    if res =~ /^\d+$/
      res = res.to_i
      if res > 0 && res <= mangas.length
        @manga_name = mangas[res - 1][1]
        @manga_url = mangas[res - 1][0]
      else
        DManga::display_warn("ERRO: Opção inválida")
      end
    else
      DManga::display_warn("ERRO: Opção inválida")
    end
  else
    raise MangaNotFoundError, "manga não encontrado"
  end
  raise MangaNotFoundError, "manga não encontrado" if @manga_url.nil?
end