Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Various functions to install some application such as `pandoc <http://johnmacfarlane.net/pandoc/>`_.
4"""
5from __future__ import print_function
6import os
7import sys
8from ..installhelper.install_memoize import install_memoize2
9from ..installhelper.internet_settings import default_user_agent
11if sys.version_info[0] == 2:
12 FileNotFoundError = Exception
13 import urllib2 as urllib_request
14 import urllib2 as urllib_error
15 import httplib as http_client
16else:
17 import urllib.request as urllib_request
18 import urllib.error as urllib_error
19 import http.client as http_client
22class DownloadException(Exception):
23 """
24 Cannot download.
25 """
26 pass
29@install_memoize2
30def download_page(url, is406=False):
31 """
32 Downloads a page from a url.
34 @param url url
35 @param is406 if the function raised *HTTP Error 406*, try *True*
36 @return content
38 .. versionchanged:: 1.1
39 Parameter *is406* was added.
40 """
41 agent = "Mozilla" if is406 else default_user_agent
42 try:
43 req = urllib_request.Request(
44 url, headers={
45 'User-agent': agent})
46 u = urllib_request.urlopen(req)
47 text = u.read()
48 u.close()
49 except urllib_error.HTTPError as e:
50 raise DownloadException(
51 "Unable to get archive from: '" + url + "'.") from e
52 except urllib_error.URLError as e:
53 raise DownloadException(
54 "Unable to get archive from: '" + url + "'.") from e
55 except ConnectionResetError as e:
56 raise DownloadException(
57 "Unable to get archive from: '" + url + "'.") from e
59 typstr = str # unicode#
60 return typstr(text, encoding="utf8")
63def download_file(url, outfile, fLOG=None):
64 """
65 Downloads a file from a url, the function does not download the file
66 again if outfile already exists.
68 @param url url
69 @param outfile outfile
70 @param fLOG logging function
71 @return outfile
72 """
73 if os.path.exists(outfile):
74 return outfile
76 try:
77 if fLOG:
78 fLOG("[pymy] download", url)
79 req = urllib_request.Request(
80 url,
81 headers={
82 'User-agent': default_user_agent},
83 )
84 u = urllib_request.urlopen(req)
85 text = u.read()
86 u.close()
87 except urllib_error.HTTPError as e:
88 raise DownloadException(
89 "Unable to get archive from '{}'.".format(url)) from e
90 except urllib_error.URLError as e:
91 raise DownloadException(
92 "Unable to get archive from '{}'.".format(url)) from e
93 except http_client.IncompleteRead as ee:
94 raise DownloadException(
95 "unable to complete reading from: " + url) from ee
97 with open(outfile, "wb") as f:
98 f.write(text)
100 return outfile
103def download_from_sourceforge(url, outfile, fLOG=print, temp_folder="."):
104 """
105 Downloads a file from a url using redirection,
106 the function does not download the file
107 again if outfile already exists.
109 @param url url
110 @param outfile outfile
111 @param fLOG logging function
112 @param temp_folder only used if installation of module requests is needed
113 @return outfile
115 The function will install module `requests <http://docs.python-requests.org/en/latest/>`_
116 if not present.
117 """
118 if os.path.exists(outfile):
119 return outfile
121 try:
122 import requests
123 except ImportError:
124 fLOG("[pymy] installing module requests")
125 from ..installhelper.module_install import ModuleInstall
126 ModuleInstall("requests", fLOG=fLOG).install(temp_folder=temp_folder)
127 import requests
129 try:
130 req = requests.get(url, allow_redirects=True, stream=True)
131 text = req.raw.read()
132 fLOG("[pymy] len ", len(text))
133 except urllib_error.HTTPError as e:
134 raise DownloadException("unable to get archive from: " + url) from e
135 except requests.exceptions.ConnectionError as ee:
136 raise DownloadException("unable to get archive from: " + url) from ee
138 if len(text) < 20 and text.decode(
139 "ascii").lower().startswith("bad request"):
140 raise Exception("Bad Request for url: " + url)
142 with open(outfile, "wb") as f:
143 f.write(text)
145 return outfile
148def where_in_path(name):
149 """
150 Looks for a file in current directory and in every path in ``PATH``.
152 @param name name of the file to look for
153 @return None if not found, the absolute filename otherwise
154 """
155 if os.path.exists(name):
156 return os.path.abspath(name)
157 else:
158 path = os.environ["PATH"]
159 if path:
160 spl = path.split(";")
161 for p in spl:
162 new_name = os.path.join(p, name)
163 if os.path.exists(new_name):
164 return new_name
165 return None