def test_spid_logo(self): abs_path = finders.find('spid/logo.jpg') self.assertTrue(os.path.isfile(abs_path)) # For using staticfiles_storage you have to configure STATIC_ROOT setting with self.assertRaises(ImproperlyConfigured): staticfiles_storage.exists(abs_path)
def replace_static_url(original, prefix, quote, rest): """ Replace a single matched url. """ # Don't mess with things that end in '?raw' if rest.endswith('?raw'): return original # In debug mode, if we can find the url as is, if settings.DEBUG and finders.find(rest, True): return original # if we're running with a MongoBacked store course_namespace is not None, then use studio style urls elif (not static_asset_path) and course_id: # first look in the static file pipeline and see if we are trying to reference # a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule) exists_in_staticfiles_storage = False try: exists_in_staticfiles_storage = staticfiles_storage.exists( rest) except Exception as err: log.warning( "staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) if exists_in_staticfiles_storage: url = staticfiles_storage.url(rest) else: # if not, then assume it's courseware specific content and then look in the # Mongo-backed database # Import is placed here to avoid model import at project startup. from static_replace.models import AssetBaseUrlConfig, AssetExcludedExtensionsConfig base_url = AssetBaseUrlConfig.get_base_url() excluded_exts = AssetExcludedExtensionsConfig.get_excluded_extensions( ) url = StaticContent.get_canonicalized_asset_path( course_id, rest, base_url, excluded_exts) if AssetLocator.CANONICAL_NAMESPACE in url: url = url.replace('block@', 'block/', 1) # Otherwise, look the file up in staticfiles_storage, and append the data directory if needed else: course_path = "/".join((static_asset_path or data_directory, rest)) try: if staticfiles_storage.exists(rest): url = staticfiles_storage.url(rest) else: url = staticfiles_storage.url(course_path) # And if that fails, assume that it's course content, and add manually data directory except Exception as err: log.warning( "staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) url = "".join([prefix, course_path]) return "".join([quote, url, quote])
def replace_static_url(original, prefix, quote, rest): """ Replace a single matched url. """ original_uri = "".join([prefix, rest]) # Don't mess with things that end in '?raw' if rest.endswith('?raw'): static_paths_out.append((original_uri, original_uri)) return original # In debug mode, if we can find the url as is, if settings.DEBUG and finders.find(rest, True): static_paths_out.append((original_uri, original_uri)) return original # if we're running with a MongoBacked store course_namespace is not None, then use studio style urls elif (not static_asset_path) and course_id: # first look in the static file pipeline and see if we are trying to reference # a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule) exists_in_staticfiles_storage = False try: exists_in_staticfiles_storage = staticfiles_storage.exists(rest) except Exception as err: log.warning("staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) if exists_in_staticfiles_storage: url = staticfiles_storage.url(rest) else: # if not, then assume it's courseware specific content and then look in the # Mongo-backed database # Import is placed here to avoid model import at project startup. from static_replace.models import AssetBaseUrlConfig, AssetExcludedExtensionsConfig base_url = AssetBaseUrlConfig.get_base_url() excluded_exts = AssetExcludedExtensionsConfig.get_excluded_extensions() url = StaticContent.get_canonicalized_asset_path(course_id, rest, base_url, excluded_exts) if AssetLocator.CANONICAL_NAMESPACE in url: url = url.replace('block@', 'block/', 1) # Otherwise, look the file up in staticfiles_storage, and append the data directory if needed else: course_path = "/".join((static_asset_path or data_directory, rest)) try: if staticfiles_storage.exists(rest): url = staticfiles_storage.url(rest) else: url = staticfiles_storage.url(course_path) # And if that fails, assume that it's course content, and add manually data directory except Exception as err: log.warning("staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) url = "".join([prefix, course_path]) static_paths_out.append((original_uri, url)) return "".join([quote, url, quote])
def replace_static_url(original, prefix, quote, rest): """ Replace a single matched url. """ # Don't mess with things that end in '?raw' if rest.endswith('?raw'): return original # In debug mode, if we can find the url as is, if settings.DEBUG and finders.find(rest, True): return original # if we're running with a MongoBacked store course_namespace is not None, then use studio style urls elif (not static_asset_path) \ and course_id \ and modulestore().get_modulestore_type(course_id) != ModuleStoreEnum.Type.xml: # first look in the static file pipeline and see if we are trying to reference # a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule) exists_in_staticfiles_storage = False try: exists_in_staticfiles_storage = staticfiles_storage.exists( rest) except Exception as err: log.warning( u"staticfiles_storage couldn't find path {0}: {1}".format( rest, unicode(err))) if exists_in_staticfiles_storage: url = staticfiles_storage.url(rest) else: # if not, then assume it's courseware specific content and then look in the # Mongo-backed database url = StaticContent.convert_legacy_static_url_with_course_id( rest, course_id) if AssetLocator.CANONICAL_NAMESPACE in url: url = url.replace('block@', 'block/', 1) # Otherwise, look the file up in staticfiles_storage, and append the data directory if needed else: course_path = "/".join((static_asset_path or data_directory, rest)) try: if staticfiles_storage.exists(rest): url = staticfiles_storage.url(rest) else: url = staticfiles_storage.url(course_path) # And if that fails, assume that it's course content, and add manually data directory except Exception as err: log.warning( "staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) url = "".join([prefix, course_path]) return "".join([quote, url, quote])
def icon_url(self): mt = mimetypes.guess_type(self.file.path)[0] if mt: path = u'img/mimetypes/%s.png' % mt.replace('/', '-') if staticfiles_storage.exists(path): return staticfiles_storage.url(path) path = u'img/mimetypes/%s.png' % self.file.path.rsplit('.', 1)[-1] if staticfiles_storage.exists(path): return staticfiles_storage.url(path) return staticfiles_storage.url(u'img/mimetypes/unknown.png')
def replace_static_url(original, prefix, quote, rest): """ Replace a single matched url. """ # Don't mess with things that end in '?raw' if rest.endswith('?raw'): return original # In debug mode, if we can find the url as is, if settings.DEBUG and finders.find(rest, True): return original # if we're running with a MongoBacked store course_namespace is not None, then use studio style urls elif (not static_asset_path) \ and course_id \ and modulestore().get_modulestore_type(course_id) != ModuleStoreEnum.Type.xml: # first look in the static file pipeline and see if we are trying to reference # a piece of static content which is in the edx-platform repo (e.g. JS associated with an xmodule) exists_in_staticfiles_storage = False try: exists_in_staticfiles_storage = staticfiles_storage.exists(rest) except Exception as err: log.warning("staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) if exists_in_staticfiles_storage: url = staticfiles_storage.url(rest) else: # if not, then assume it's courseware specific content and then look in the # Mongo-backed database url = StaticContent.convert_legacy_static_url_with_course_id(rest, course_id) if AssetLocator.CANONICAL_NAMESPACE in url: url = url.replace('block@', 'block/', 1) # Otherwise, look the file up in staticfiles_storage, and append the data directory if needed else: course_path = "/".join((static_asset_path or data_directory, rest)) try: if staticfiles_storage.exists(rest): url = staticfiles_storage.url(rest) else: url = staticfiles_storage.url(course_path) # And if that fails, assume that it's course content, and add manually data directory except Exception as err: log.warning("staticfiles_storage couldn't find path {0}: {1}".format( rest, str(err))) url = "".join([prefix, course_path]) return "".join([quote, url, quote])
def handle(self, *args, **kwargs): for screenshot in models.Screenshot.load(): print screenshot.name img = Image.open(staticfiles_storage.path(screenshot.path)) # Ensure we're in RGB if img.mode not in ('L', 'RGB'): img = img.convert('RGB') # Magic! # The thumbnail is only limited by width, so use # a larger-than-needed height. img.thumbnail((200 * screenshot.screens, 1000), Image.ANTIALIAS) # Save the thumbnail to a tmpfile fd, tmp = tempfile.mkstemp() file = os.fdopen(fd, 'w+b') type = mimetypes.guess_type(screenshot.name)[0].split('/')[1] img.save(file, type) file.close() # Nuke previous version if it exists if staticfiles_storage.exists(screenshot.thumbnail): staticfiles_storage.delete(screenshot.thumbnail) # save thumbnail to stattic dir file = File(open(tmp, 'rb')) staticfiles_storage.save(screenshot.thumbnail, file) file.close() os.unlink(tmp)
def get_buster_json(buster_file=BUSTER_FILE): """ Returns json data either from cache or from the busters file from staticfiles storage. """ # First check for cached version if BUSTER_CACHE: buster_json = cache.get(BUSTER_CACHE_KEY) if buster_json is not None: return buster_json # Look for busters file in staticfiles storage buster_json = '' if staticfiles_storage.exists(buster_file): with staticfiles_storage.open(buster_file) as file_: contents = file_.read() file_.flush() # Try to load the json from file try: buster_json = json.loads(contents) except ValueError: pass # cache the json cache[BUSTER_CACHE_KEY] = buster_json return buster_json
def view_2048(request, style_2048=None): context_dict = {"meme_images": []} style_2048 = "Memes" if style_2048 is None else style_2048 for i in range(1, 12): for f in ['png', 'jpg', 'jpeg', 'gif']: file_name = "devsite/img/2048/" + style_2048 + "/meme" + \ str(math.floor(math.pow(2,i))) + "." + f logger.debug("Searching for: " + file_name) if staticfiles_storage.exists(file_name): context_dict["meme_images"].append({ "num": str(math.floor(math.pow(2, i))), "img": file_name }) logger.debug(file_name + " found") break logger.debug("meme_images dict: %s", context_dict["meme_images"]) if len(context_dict["meme_images"]) == 11: context_dict["meme_images"] = sorted(context_dict["meme_images"], key=lambda x: int(x["num"])) return render(request, "devsite/projects/2048.html", context=context_dict) return render(request, "devsite/error/404.html")
def iglob(pathname): """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. """ if not has_magic(pathname): try: if staticfiles_storage.exists(pathname): yield pathname except NotImplementedError: # Being optimistic yield pathname return dirname, basename = os.path.split(pathname) if not dirname: for name in glob1(dirname, basename): yield name return if has_magic(dirname): dirs = iglob(dirname) else: dirs = [dirname] if has_magic(basename): glob_in_dir = glob1 else: glob_in_dir = glob0 for dirname in dirs: for name in glob_in_dir(dirname, basename): yield os.path.join(dirname, name)
def dev_menu_2048(request): context_dict = {"styles": []} with os.scandir( '/Users/devmoney/DesktopDir/Programming/Python/devsdigest/devsdigest/devsite/static/devsite/img/2048' ) as scanner: for d in scanner: if d.is_dir(): style_dict = {"name": "", "url": "", "banner": ""} style_dict["url"] = "/2048/" + d.name with open(os.path.join(d.path, "info.json")) as f: style_dict["name"] = json.load(f)["name"] for file_type in ['jpg', 'jpeg', 'png', 'gif']: if staticfiles_storage.exists("devsite/img/2048/" + d.name + "/banner." + file_type): style_dict["banner"] = staticfiles_storage.url( "devsite/img/2048/" + d.name + "/banner." + file_type) context_dict["styles"].append(style_dict) return render(request, "devsite/projects/menu_2048.html", context=context_dict)
def handle(self, *args, **options): locale = options["locale"] content = generate_js(locale) file_name = staticfiles_storage.path(f"choices-{locale}.js") if staticfiles_storage.exists(file_name): staticfiles_storage.delete(file_name) staticfiles_storage.save(file_name, ContentFile(content)) self.stdout.write(f"{file_name} saved to static root!")
def find(self, path, all=False): if not env.is_collecting and env.output and staticfiles_storage.exists(path): absolute_path = staticfiles_storage.path(path) if all: return [absolute_path] else: return absolute_path return []
def image_exists(urlname): return True path = "/static/favicon/{0}.ico".format(urlname) #abspath = finders.find(path) if staticfiles_storage.exists(path): return True else: return False
def test_images(self): """ Use the abs_path to test if the image location saved in the Product exits in the static files """ products = Product.objects.all() for prod in products: abs_path = finders.find(prod.image_one) self.assertTrue(staticfiles_storage.exists(abs_path))
def get_file_from_storage(self, filename): try: filename = staticfiles_storage.path(filename) except NotImplementedError: # remote storages don't implement path pass if staticfiles_storage.exists(filename): return filename, staticfiles_storage else: return None, None
def render(self, context): val1 = self.var1.resolve(context, True) if staticfiles_storage.exists(val1): context.push() context['static'] = static(val1) x = self.nodelist_true.render(context) context.pop() else: x = self.nodelist_false.render(context) return x
def get_file_from_storage(filename): try: filename = staticfiles_storage.path(filename) except NotImplementedError: # remote storages don't implement path pass if staticfiles_storage.exists(filename): return filename, staticfiles_storage else: return None, None
def check_staticfile(filename): # type: (str) -> None """ Verify a static file is reachable :param str filename: static file to verify :return None: """ if not staticfiles_storage.exists(filename): log.error("Can't find %s in static files.", filename) raise HealthcheckFailure("static files error")
def _get_city_image(self, city): """ определение изображения города """ city_tr = self.translite(city) if staticfiles_storage.exists( settings.STATIC_ROOT + '/images/city/{0}.jpg'.format(city_tr) ): city_img = city_tr else: city_img = 'default' return city_img
def read_static_file(path, mode="r"): """ Return the contents of a static file. """ if settings.DEBUG: # Lookup file in using Django's static finder, e.g. when in # local development mode. filename = find(path) if filename: return open(filename, mode=mode).read() elif staticfiles_storage.exists(path): # Look up file in collectstatic target directory (regular # deployment). return staticfiles_storage.open(path, mode=mode).read() message = 'Unable to include inline static file "%s", file not found.' logger.warning(message, path) raise ValueError(message % path)
def get_filename(self, basename): """ Returns full path to a file, for example: get_filename('css/one.css') -> '/full/path/to/static/css/one.css' """ filename = None # First try finding the file using the storage class. # This is skipped in DEVELOPER_MODE mode as files might be outdated # Or may not even be on disk. if not getattr(settings, "DEVELOPER_MODE", False): filename = staticfiles_storage.path(basename) if not staticfiles_storage.exists(basename): filename = None # secondly try to find it with staticfiles if not filename: filename = find_staticfiles(url2pathname(basename)) return filename
def admin_index(request): user = request.user #if not user.groups.filter(name="admins").exists(): # raise Exception school = user.staff.school context = { 'user': user, 'school': school, 'view': 'admin_index', 'is-admin': True, } if staticfiles_storage.exists("css/{}.css".format(school.number)): context['school_theme'] = "css/{}.css".format(school.number) return render(request, 'resources/admin_index.html', context)
def load_staticfile(name, postprocessor=None, fail_silently=False): if postprocessor: cache_key = '{0}:{1}.{2}'.format(name, postprocessor.__module__, postprocessor.__name__) else: cache_key = name if cache_key in load_staticfile._cache: return load_staticfile._cache[cache_key] if settings.DEBUG: # Dont access file via staticfile storage in debug mode. Not available # without collectstatic management command. path = find(name) else: # Ensure that we include the hashed version of the static file if # staticfiles storage uses the HashedFilesMixin. if hasattr(staticfiles_storage, 'stored_name'): name = staticfiles_storage.stored_name(name) if staticfiles_storage.exists(name): # get path if target file exists. path = staticfiles_storage.path(name) else: path = None if not path: if not fail_silently: raise ValueError( 'Staticfile not found for inlining: {0}'.format(name)) return '' with open(path, 'r') as staticfile: content = staticfile.read() if postprocessor: content = postprocessor(name, path, content) if not settings.DEBUG: load_staticfile._cache[cache_key] = content return content
def summernote_settings(self): lang = get_proper_language() summernote_settings = config.get('summernote', {}).copy() language_url = '' if staticfiles_storage.exists('summernote/lang/summernote-' + lang + '.min.js'): language_url = staticfiles_storage.url( 'summernote/lang/summernote-' + lang + '.min.js') summernote_settings.update({ 'lang': lang, 'url': { 'language': static('summernote/lang/summernote-' + lang + '.min.js'), 'upload_attachment': reverse('django_summernote-upload_attachment'), }, }) return summernote_settings
def getMapImage(input): path = input[0] lat = input[1] long = input[2] name = input[3].replace(' ', '') imageName = str(name) + 'mapImage.png' if staticfiles_storage.exists( os.path.join(django_settings.STATIC_ROOT, imageName)): return imageName encodedCoordinatesList = urllib.parse.quote(path, safe='') requestUrl = "https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-s+ff2600(" + str( long ) + "," + str( lat ) + ")," + "path-3+0061ff-0.55(" + encodedCoordinatesList + ")/auto/300x200@2x?access_token=pk.eyJ1IjoiZ2FveXVzaGkwMDEiLCJhIjoiY2tubGM0cmV1MGY5aTJucGVtMHAwZGtpNyJ9.xApcEalgtGPF4fQc4to1DA" res = requests.get(requestUrl) with staticfiles_storage.open( os.path.join(django_settings.STATIC_ROOT, imageName), 'wb') as out_file: out_file.write(res.content) del res return imageName
def load_staticfile(name, postprocessor=None, fail_silently=False): if not hasattr(load_staticfile, '_cache'): load_staticfile._cache = {} if postprocessor: cache_key = '{0}:{1}.{2}'.format( name, postprocessor.__module__, postprocessor.__name__) else: cache_key = name if cache_key in load_staticfile._cache: return load_staticfile._cache[cache_key] if settings.DEBUG: # Dont access file via staticfile storage in debug mode. Not available # without collectstatic management command. path = find(name) elif staticfiles_storage.exists(name): # get path if target file exists. path = staticfiles_storage.path(name) else: path = None if not path: if not fail_silently: raise ValueError('Staticfile not found for inlining: {0}'.format(name)) return '' with open(path, 'r') as staticfile: content = staticfile.read() if postprocessor: content = postprocessor(name, path, content) if not settings.DEBUG: load_staticfile._cache[cache_key] = content return content
def importer(path, prev=None): # import pudb; pu.db # if not prev: # result = finders.find(path) # if result: # return load(path, result) # else: # return None n = Path(path) p = Path(prev) for name in ( n.with_suffix(".scss"), n.with_name(f"_{n.name}").with_suffix(".scss"), ): if p.is_absolute(): search = str(name) else: search = str(p.parent / name) if not staticfiles_storage.exists(search): continue with staticfiles_storage.open(search) as content: return [(search, content.read())]
def menu_2048(request): context_dict = {"styles": []} # https://github.com/boto/boto3/issues/134#issuecomment-116766812 s3 = boto3.client('s3') paginator = s3.get_paginator('list_objects_v2') for res in paginator.paginate( Bucket=django_settings.AWS_STORAGE_BUCKET_NAME, Delimiter='/', Prefix='static/devsite/img/2048/'): for prefix in res.get('CommonPrefixes'): style_dict = {"name": "", "url": "", "banner": ""} style_dir_name = re.split('/', prefix.get('Prefix'))[4] style_dict["url"] = "/2048/" + style_dir_name logger.debug(style_dir_name) # get object, call read() on StreamingBody object, load into dictionary, then read "name" key style_dict['name'] = json.loads( s3.get_object(Bucket=django_settings.AWS_STORAGE_BUCKET_NAME, Key=prefix.get('Prefix') + "info.json")['Body'].read())["name"] logger.debug("Display name: " + style_dict['name']) for f in ['jpg', 'png', 'jpeg', 'gif']: if staticfiles_storage.exists("devsite/img/2048/" + style_dir_name + "/banner." + f): style_dict['banner'] = staticfiles_storage.url( "devsite/img/2048/" + style_dir_name + "/banner." + f) logger.debug(style_dict['banner']) context_dict['styles'].append(style_dict) #with open(staticfiles_storage.url('staticfiles.json')) as f: # logger.debug(json.loads(f)) return render(request, "devsite/projects/menu_2048.html", context=context_dict)
def glob0(dirname, basename): if staticfiles_storage.exists(os.path.join(dirname, basename)): return [basename] return []
def test_images(self): abs_path = finders.find('blogango/images/agiliq_blog_logo.png') self.assertTrue(staticfiles_storage.exists(abs_path)) abs_path = finders.find('blogango/images/person_default.jpg') self.assertTrue(staticfiles_storage.exists(abs_path))
def test_images(self): for image_name in images: abs_path = os.path.join(s_root, 'images/', image_name) self.assertTrue(staticfiles_storage.exists(abs_path))
def test_css(self): for sheet_name in css: abs_path = os.path.join(s_root, 'css/', sheet_name) self.assertTrue(staticfiles_storage.exists(abs_path))
def test_css(self): abs_path = finders.find('motogp/style.css') self.assertTrue(staticfiles_storage.exists(abs_path))
def find(self, path, all=False): full_path = staticfiles_storage.path(path) if staticfiles_storage.exists(full_path): return [full_path] if all else full_path return []
def test_images(self): abs_path = finders.find('default.jpg') self.assertTrue(staticfiles_storage.exists(abs_path))
def test_favicon_file_path(self): """ Tests that favicon.ico exists in the path specified in FAVICON_PATH setting """ absolute_path = finders.find('favicon.ico') assert staticfiles_storage.exists(absolute_path)
def staticinline(path, encode=None): """ Similiar to Django's native `static` templatetag, but this includes the file directly in the template, rather than a link to it. Example:: {% load staticinline %} <style type="text/css">{% staticinline "myfile.css" %}</style> <script>{% staticinline "myfile.js" %}</script> Becomes:: <style type="text/css">body{ color: red; }</style> <script>alert("Hello World");</script> Raises a ValueError if the the file does not exist, and DEBUG is enabled. :param str path: Filename of the file to include. :return: Returns the the file content *or* ``''`` (empty string) if the file was not found, and ``DEBUG`` is ``False``. :rtype: str :raises ValueError: if the file is not found and ``DEBUG`` is ``True`` """ filename = None # Look up file in collectstatic target directory (regular deployment) # unless DEBUG is on. Then we skip it and lookup the file in the # app directory. (Thats what to expect when in DEBUG mode.) if not settings.DEBUG and staticfiles_storage.exists(path): filename = staticfiles_storage.path(path) # Lookup file in /app/static/ directory, e.g. when in local # development mode and DEBUG is True. if not filename: filename = find(path) # If it wasn't found, return an empty string # or raise ValueError if in DEBUG mode if not filename or not os.path.exists(filename): logger.error( 'Unable to include inline static file "%s", ' 'file not found.', filename) if settings.DEBUG: raise ValueError('Unable to include inline static file "{0}", ' 'file not found.'.format(filename)) return '' # If we don't encode the file further, we can return it right away. if not encode: return open(filename).read() # FIXME: Use staticfiles.open() encoder_registry = config.get_encoder() data = open(filename, 'rb').read() if not encode in encoder_registry: raise ImproperlyConfigured( '"{0}" is not a registered encoder. Valid values are: {1}'.format( encode, ', '.join(encoder_registry.keys()))) try: return mark_safe(encoder_registry[encode](data)) # Anything could go wrong since we don't control the encoding # list itself. In case of an error raise that exception, unless # DEBUG mode is off. Then, same as above, return an empty string. except Exception as e: logger.error( 'Unable to include inline static file "%s", ' 'file not found.', filename) logger.exception(e) if settings.DEBUG: raise e return ''
def test_css(self): abs_path = finders.find('blogango/css/as_blog_styles.css') self.assertTrue(staticfiles_storage.exists(abs_path)) abs_path = finders.find('blogango/css/prettify.css')
def screenshot(request): """ Return screenshot of a given URL on this site. This is a light wrapper around "node scripts/screenshot.js". Do not generate URLs for this page directly, but by calling page_image_url(). This view requires a signed JSON object within the ?payload= query parameter so it can't be called unexpectedly. """ if not settings.SCREENSHOT_FEATURE: raise Http404 # read payload try: payload = json.loads(Signer().unsign(request.GET.get('payload', ''))) except signing.BadSignature: return HttpResponseBadRequest() ### NOTE: after this point, contents of 'payload' are verified as coming from a signed request we created, # though the 'url' parameter may be partially user-controlled. ### # validate that submitted URL is a complete URL on our site url = payload.get('url') if not url: return HttpResponseBadRequest("URL parameter required.") if not url.startswith( 'https://' if settings.MAKE_HTTPS_URLS else 'http://'): return HttpResponseBadRequest("Invalid URL protocol.") if not is_safe_url(url, safe_domains): return HttpResponseBadRequest( "URL should match one of these domains: %s" % safe_domains) # apply target= and wait= query params command_args = [] for selector in payload.get('waits', []): command_args += ['--wait', selector] for selector in payload.get('targets', []): command_args += ['--target', selector] for selector in payload.get('disable', []): command_args += ['--disable', selector] timeout = payload.get('timeout', settings.SCREENSHOT_DEFAULT_TIMEOUT) # disable puppeteer sandbox just for dockerized dev/test env # this is needed because puppeteer can't run as root without --no-sandbox; the alternative would be to set up docker # to not run as root if os.environ.get('DOCKERIZED') and settings.DEBUG: command_args += ['--no-sandbox'] # get screenshot from node scripts/screenshot.js subprocess_args = [ 'node', os.path.join(settings.BASE_DIR, 'scripts/screenshot.js'), '-m', str(timeout * 1000) ] + command_args + [url] print(" ".join(subprocess_args)) try: screenshot = subprocess.check_output(subprocess_args, timeout=timeout) content_type = "image/png" except (subprocess.TimeoutExpired, subprocess.CalledProcessError) as e: print("Using fallback for screenshot with payload %s: %s" % (payload, e)) fallback_path = payload.get('fallback') if not fallback_path or not staticfiles_storage.exists(fallback_path): fallback_path = 'img/og_image/api.jpg' with staticfiles_storage.open(fallback_path) as screenshot_file: screenshot = screenshot_file.read() content_types_by_suffix = {'png': 'image/png', 'jpg': 'image/jpeg'} content_type = content_types_by_suffix[fallback_path.rsplit('.', 1)[1]] return HttpResponse(screenshot, content_type=content_type)