FileFetcher.remote_file_path()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
c 0
b 0
f 0
1 1
require "open-uri"
2 1
require "socket"
3 1
require "tmpdir"
4 1
require "pathname"
5 1
require_relative "exceptions"
6 1
require_relative "file_system"
7
8 1
module Resume
9 1
  module CLI
10
    # The module concerned with fetching an asset file to be used in the
11
    # generation of a resume.
12
    #
13
    # @author Paul Fioravanti
14 1
    module FileFetcher
15
      REMOTE_REPO =
16 1
        "https://raw.githubusercontent.com/paulfioravanti/resume/master".freeze
17 1
      private_constant :REMOTE_REPO
18
19 1
      module_function
20
21
      # Fetches an asset file.
22
      #
23
      # File is fetched by making lookups in the following order:
24
      #
25
      # - Search in immediate local directory
26
      # - Search in the machine `/tmp` directory
27
      # - Search at the remote asset repository
28
      #
29
      # @param path [String] The path to look up to fetch an asset file.
30
      # @raise [NetworkConnectionError] if a remote asset cannot be reached.
31
      # @return [File] The fetched file.
32 1
      def fetch(path)
33 55
        pathname = Pathname.new(path)
34 55
        fetch_file(pathname)
35
      end
36
37 1
      def fetch_file(pathname)
38 55
        filename = pathname.basename.to_path
39 55
        local_file(pathname) ||
40
          tmpfile(filename) ||
41
          remote_file(pathname, filename)
42
      end
43 1
      private_class_method :fetch_file
44
45 1
      def local_file(pathname)
46 55
        File.open(pathname) if pathname.file?
47
      end
48 1
      private_class_method :local_file
49
50 1
      def tmpfile(filename)
51 35
        tmpfile = tmpfile_path(filename)
52 35
        File.open(tmpfile) if tmpfile.file?
53
      end
54 1
      private_class_method :tmpfile
55
56 1
      def remote_file(pathname, filename)
57 7
        tmpfile = tmpfile_path(filename)
58 7
        File.open(tmpfile, "wb") do |file|
59 7
          write_file(file, pathname)
60
        end
61 4
        tmpfile
62
      rescue SocketError, OpenURI::HTTPError, Errno::ECONNREFUSED
63 3
        raise NetworkConnectionError
64
      end
65 1
      private_class_method :remote_file
66
67 1
      def tmpfile_path(filename)
68 42
        FileSystem.tmpfile_path(filename)
69
      end
70 1
      private_class_method :tmpfile_path
71
72 1
      def write_file(file, pathname)
73 7
        Kernel.open(remote_file_path(pathname)) do |uri|
74 1
          file.write(uri.read)
75
        end
76
      end
77 1
      private_class_method :write_file
78
79 1
      def remote_file_path(pathname)
80 7
        path = pathname.to_path
81 7
        uri?(pathname) ? path : File.join(REMOTE_REPO, path)
82
      end
83 1
      private_class_method :remote_file_path
84
85 1
      def uri?(pathname)
86 7
        uri = URI.parse(pathname.to_path)
87 5
        %w[http https].include?(uri.scheme)
88
      rescue URI::BadURIError, URI::InvalidURIError
89 2
        false
90
      end
91 1
      private_class_method :uri?
92
    end
93
  end
94
end
95