示例#1
0
文件: html.py 项目: zhiiker/FarBox
    def js_view(title, url=None, group_id=None, view_type='', **kwargs):
        if url is None:
            # 默认值, 这样图片调用的时候, 只要一个传入就可以了
            url = title

        url = smart_unicode(url)
        if isinstance(title, (tuple, list)) and len(title) == 2:
            title, thumbnail = title  # 图片类型的
        else:
            title = smart_unicode(title)
            mime_type = guess_type(title) or ''
            if mime_type.startswith('image/'):
                thumbnail = title  # title 本身就是一张图片
                title = kwargs.get('alt') or os.path.split(title)[
                    -1]  # 文件名作为 title
                title = smart_unicode(title)
            else:
                thumbnail = ''

        if not view_type:  # 自动推断
            if thumbnail:
                view_type = 'image'
            elif url.endswith('.mp4'):
                view_type = 'video'
            else:
                link_mime_type = guess_type(url) or ''
                if link_mime_type.startswith('image/'):
                    view_type = 'image'
                else:
                    view_type = 'iframe'

        class_name = kwargs.get('class_name') or ''
        css_class = 'js_view js_view_%s %s' % (view_type, class_name)
        if group_id:
            css_class += ' js_view_group '
        else:
            group_id = ''

        dom_id = get_a_random_dom_id()
        html_content = render_api_template('js_view',
                                           view_type=view_type,
                                           title=title,
                                           thumbnail=thumbnail,
                                           url=url,
                                           css_class=css_class,
                                           uuid=dom_id,
                                           group_id=group_id,
                                           return_html=True,
                                           **kwargs)
        return html_content
示例#2
0
def render_as_static_resource_in_pages_for_farbox_bucket(template_filename):
    ext = os.path.splitext(template_filename)[-1].lower()
    if ext not in [
            '.html', '.htm', '.js', '.css', '.json', '.jpg', '.png', '.scss',
            '.less', '.coffee'
    ]:
        return
    mime_type = ''
    raw_content = ''
    pages_configs = get_pages_configs()
    if not is_doc_modified(doc=pages_configs, date_field='mtime'):
        return get_304_response()
    if ext in ['.scss', '.less']:
        raw_content = get_template_static_resource_content('.'.join(
            [template_filename.rsplit('.')[0], 'css']))
        mime_type = 'text/css'
    elif ext in ['.coffee']:
        raw_content = get_template_static_resource_content('.'.join(
            [template_filename.rsplit('.')[0], 'js']))
        mime_type = 'application/javascript'
    if not raw_content:
        raw_content = get_template_static_resource_content(template_filename)
    if raw_content:
        raw_content = to_bytes(raw_content)
        mime_type = mime_type or guess_type(
            template_filename) or 'application/octet-stream'
        set_context_value_from_request("is_template_resource", True)
        file_response = send_file(io.BytesIO(raw_content), mimetype=mime_type)
        bucket = get_bucket_in_request_context()
        if bucket:
            set_304_response_for_doc(response=file_response,
                                     doc=pages_configs,
                                     date_field='mtime')
        return file_response
示例#3
0
 def get_compiled_data(self):
     mime_type = guess_type(self.path)
     if mime_type and mime_type.startswith('image/'):
         file_type = 'image'
     else:
         file_type = 'file'
     data = dict(
         _type = file_type,
         type = file_type,
         _order = self.file_order_value,
     )
     if file_type == 'file':
         # 如果纯粹是 file 类型,且大小在容许的范围内,才尝试将原始内容直接放到 record 内
         ext = os.path.splitext(self.path)[-1].lower().strip('.')
         if ext in FRONTEND_EXTS and len(self.raw_content)<MAX_RECORD_SIZE:
             data.update(dict(
                 raw_content=self.raw_content,
                 raw_content_size=len(self.raw_content),
                 _zipped=False,
             ))
             compiled_type, compiled_content = compile_frontend_resource(ext, raw_content=self.raw_content)
             if compiled_content and compiled_type:
                 data['compiled_type'] = compiled_type
                 data['compiled_content'] = compiled_content
         else:
             raw_content = self.gb64_raw_content
             if len(raw_content) < MAX_RECORD_SIZE:
                 data.update(dict(
                     raw_content=self.gb64_raw_content,
                     raw_content_size=len(self.gb64_raw_content),
                     _zipped=True,
                 ))
     # 而比如 图片,不论大小,全部直传
     return data
示例#4
0
    def accept_upload_file_from_client(self, bucket, record_data, get_raw_content_func=None):
        # return ok, failed, existed
        if not self.should_upload_file_by_client(bucket, record_data):
            return "failed"
        filepath = self.get_filepath_from_record(bucket=bucket, record_data=record_data)
        if not filepath:
            return "failed"
        if not get_raw_content_func:
            return "failed"
        if hasattr(get_raw_content_func, "__call__"):
            raw_content = get_raw_content_func()
        else:
            raw_content = get_raw_content_func

        if len(raw_content) > MAX_FILE_SIZE:
            return "failed"

        if not self.exists(bucket, record_data):
            if not raw_content or not isinstance(raw_content, string_types):
                return "failed"
            # qcloud_cos.cos_common.maplist
            content_type = guess_type(record_data.get("path"))
            relative_path = record_data.get("path") or ""
            filename = os.path.split(relative_path)[-1]
            headers = dict()
            if filename:
                headers["ContentDisposition"] = smart_str('attachment;filename="%s"' % relative_path)
            if DEBUG:
                print("upload %s to qcloud" % relative_path)
            uploaded = upload_file_to_qcloud_for_bucket(bucket, filepath, raw_content, content_type=content_type, **headers)
            if uploaded:
                file_size = len(raw_content)
                image_info = {}
                if guess_type(relative_path).startswith("image/"):
                    image_info = get_image_info_from_raw_content(raw_content)
                self.update_record_when_file_stored(bucket, record_data, file_size=file_size, image_info=image_info)
                return "ok"
            else:
                return "failed"
        else:
            if raw_content and isinstance(raw_content, string_types):
                file_size = len(raw_content)
            else:
                file_size = 0
            self.update_record_when_file_stored(bucket, record_data, file_size=file_size)  # try to update the record
            return "existed"
示例#5
0
 def post_title(self):
     # 获取post的title
     title = self.get_meta_value('title', '')
     # 文中没有声明,看有没有唯一的H1作为title
     if not title and getattr(self.content, 'title', None) and getattr(
             self.content, 'title_from_post', False):
         title = self.content.title
     if not title:  # 仍然没有title的,就取文件名
         title = self.title  # 保留了大小写
         if guess_type(title):  # 如果是后缀名的,则是把title去掉后缀
             title = os.path.splitext(title)[0]
     return smart_unicode(title.strip())
示例#6
0
def send_file_with_304(filepath, mimetype=None):
    if not os.path.isfile(filepath):
        return # ignore
    if not is_filepath_modified(filepath):
        return get_304_response()
    else:
        mimetype = mimetype or guess_type(filepath, 'application/octet-stream')
        response = send_file(filepath, mimetype=mimetype)
        try:
            mtime = int(os.path.getmtime(filepath))
            response.headers['Last-Modified'] = smart_str(mtime)
        except:
            pass
        return response
def upload_static_files_to_cdn(static_files_root,
                               cdn_static_prefix,
                               secret_id,
                               secret_key,
                               bucket,
                               region,
                               force_update=False):
    sub_filepaths = get_all_sub_files(static_files_root)
    for filepath in sub_filepaths:
        if is_a_hidden_path(filepath):
            continue
        ext = os.path.splitext(filepath)[-1]
        if ext in [".py", ".pyc", ".pyd"]:
            continue
        #print(filepath)
        relative_path = get_relative_path(filepath, static_files_root)
        cnd_path = "/%s/%s" % (cdn_static_prefix.strip("/"),
                               relative_path.strip("/"))
        if not force_update:
            if has_file_on_qcloud(cnd_path,
                                  secret_id=secret_id,
                                  secret_key=secret_key,
                                  bucket=bucket,
                                  region=region):
                qcloud_file_meta = get_file_meta_on_qcloud(
                    cnd_path,
                    secret_id=secret_id,
                    secret_key=secret_key,
                    bucket=bucket,
                    region=region)
                if qcloud_file_meta and isinstance(qcloud_file_meta, dict):
                    q_version = qcloud_file_meta.get("ETag",
                                                     "").strip("'").strip('"')
                    if q_version and get_md5_for_file(filepath) == q_version:
                        continue
        with open(filepath, "rb") as f:
            upload_file_obj_to_qcloud(file_obj=f,
                                      url_path=cnd_path,
                                      secret_id=secret_id,
                                      secret_key=secret_key,
                                      bucket=bucket,
                                      region=region,
                                      content_type=guess_type(filepath))
        print(filepath)
示例#8
0
def render_as_static_file_for_farbox_bucket(path):
    if not path or path == "/":
        path = "index.html"
    bucket = get_bucket_in_request_context()
    if not bucket:
        return
    record = get_record_by_path(bucket, path)
    if path == "favicon.ico" and not record:
        record = get_record_by_path(bucket,
                                    "_direct/favicon.ico")  # 兼容 Bitcron
    if not record:
        return
    record_path = get_path_from_record(record)
    if record_path and record_path.startswith("/_data/"):
        ext = os.path.splitext(record_path)[-1].strip(".").lower()
        if ext in ["csv"] and not is_bucket_login(bucket):
            return abort(
                404, "csv under /_data is not allowed to download directly")
    set_context_value_from_request("is_static_file", True)
    if record.get('compiled_type') and record.get('compiled_content'):
        raw_content = record.get('compiled_content')
        content_type = record.get('compiled_type')
        raw_content = to_bytes(raw_content)
        mimetype = content_type or guess_type(
            path) or 'application/octet-stream'
        compiled_file_response = send_file(io.BytesIO(to_bytes(raw_content)),
                                           mimetype=mimetype)
        return compiled_file_response
    else:
        # 先对应是否防盗链的逻辑
        site_configs = get_bucket_site_configs(bucket)
        anti_theft_chain = site_configs.get("anti_theft_chain", True)
        if anti_theft_chain and request.path.strip('/') in ['favicon.ico']:
            anti_theft_chain = False
        if anti_theft_chain and request.referrer:
            refer_host = get_host_from_url(request.referrer)
            if refer_host != request.host and "." in request.path:
                return abort(404, "this url is not allowed for outside")

        return storage.get_download_response_for_record(bucket=bucket,
                                                        record_data=record,
                                                        try_resized_image=True)
示例#9
0
    def as_web_response(self,
                        bucket,
                        record,
                        mimetype="",
                        try_resized_image=True):
        # 只处理存储在外部(包括本地),但不在 database 中的数据
        file_stored = record.get("_file_stored")
        if not file_stored:
            return
        relative_path = record.get('path')
        if not relative_path:
            return  # ignore
        local_filepath = self.get_local_filepath(bucket, record)

        mimetype = mimetype or guess_type(
            relative_path) or 'application/octet-stream'

        # 处理缩略图的对应
        if try_resized_image and mimetype.startswith("image"):
            resized_image_response = get_response_for_resized_image(
                bucket, record, self)
            if resized_image_response:
                return resized_image_response

        if local_filepath:
            if os.path.isfile(local_filepath):
                response = send_file(local_filepath, mimetype=mimetype)
                spawn(self.update_bucket_bandwidth, bucket, record)
                set_304_response_for_doc(response=response,
                                         doc=record,
                                         date_field='mtime')
                return response
            else:
                return
        else:
            file_url = self.get_url(bucket, record)
            if file_url:
                spawn(self.update_bucket_bandwidth, bucket, record)
                return p_redirect(file_url)
            else:
                return
示例#10
0
 def get_download_response_for_record(self,
                                      bucket,
                                      record_data,
                                      try_resized_image=False):
     # 同步回去的 response
     # 如果是 Web 端给普通访客的,则会根据需要自动提供缩略图的逻辑支持
     raw_content = record_data.get('raw_content') or record_data.get(
         'content') or ''
     if raw_content and record_data.get('_zipped'):
         try:
             raw_content = ungzip_content(raw_content, base64=True)
         except:
             pass
     mime_type = guess_type(record_data.get(
         "path", "")) or "application/octet-stream"
     if raw_content:
         raw_content = to_bytes(raw_content)
         return send_file(io.BytesIO(raw_content), mimetype=mime_type)
     else:
         file_response = self.as_web_response(
             bucket, record_data, try_resized_image=try_resized_image)
         return file_response  # 可能是 None
示例#11
0
    def accept_upload_file_from_client(self, bucket, record_data, get_raw_content_func=None):
        # return ok, failed, existed
        if not self.should_upload_file_by_client(bucket, record_data):
            return "failed"
        filepath = self.get_filepath_from_record(bucket=bucket, record_data=record_data)
        if not filepath:
            return "failed"
        if not get_raw_content_func:
            return "failed"
        if not os.path.isfile(filepath):
            if hasattr(get_raw_content_func, "__call__"):
                raw_content = get_raw_content_func()
            else:
                raw_content = get_raw_content_func
            if not raw_content or not isinstance(raw_content, string_types):
                return "failed"
            if len(raw_content) > MAX_FILE_SIZE:
                return "failed"
            if DEBUG:
                relative_path = record_data.get("path") or ""
                print("store %s to local" % relative_path)
            write_file(filepath, raw_content)

            file_size = len(raw_content)
            image_info = None
            if guess_type(filepath).startswith("image/"):
                image_info = get_image_info_from_raw_content(raw_content)
            self.update_record_when_file_stored(bucket, record_data, file_size=file_size, image_info=image_info) # update the record
            return "ok"
        else:
            try:
                file_size = os.path.getsize(filepath) or 0
            except:
                file_size = 0
            self.update_record_when_file_stored(bucket, record_data, file_size=file_size)  # try to update the record
            return "existed"
示例#12
0
def is_a_image_file(filepath):
    mimetype = guess_type(filepath) or ''
    if mimetype.startswith('image/'):
        return True
    else:
        return False
示例#13
0
文件: html.py 项目: zhiiker/FarBox
    def auto_a(cls,
               title,
               href,
               a_title=None,
               class_name='',
               group_id='',
               target='',
               dom_id=None,
               **kwargs):
        # 跟 js_view 关联起来, a_title=alter_title; 如果不是和 js_view 则会使用a这个生成函数
        href_mime_type = guess_type(href)
        use_js_view = False
        view_type = 'iframe'
        group_id = group_id or kwargs.pop('group', '') or ''
        dom_id = dom_id or get_a_random_dom_id()

        # 特殊 URL 的对应,因为某些场景(smartpage)中不方便定义 a_title 这个逻辑
        special_protocols = ['qrcode', 'iframe']
        for special_protocol in special_protocols:
            special_protocol_prefix = '%s://' % special_protocol
            if href.startswith(special_protocol_prefix):
                a_title = special_protocol
                href = href.replace(special_protocol_prefix, '', 1).strip()
                if '://' not in href:  # 本 site 内的url,确保以 / 开头
                    href = '/%s' % href.lstrip('/')

        if not class_name:
            class_name = kwargs.pop('class', '')

        title_mime_type = guess_type(title)
        if title_mime_type and title_mime_type.startswith('image/'):
            # 自动转为图片的 html 片段
            image_as_title = '<img src="%s">' % title
        else:
            image_as_title = title

        if title and href and isinstance(title, string_types) and isinstance(
                href, string_types):
            if href.endswith('.mp4'):
                # 视频的封面是图片
                return cls.js_view(image_as_title,
                                   href,
                                   view_type='video',
                                   class_name=class_name)
            if href.endswith('.swf') or str_has(
                    href,
                ['vimeo.com/video', 'youtube.com', 'youku.com', 'tudou.com'],
                    just_in=True):
                use_js_view = True
            elif href.startswith('.') or href.startswith('#') and len(
                    href.strip()) != 1:
                view_type = 'modal'
                use_js_view = True
            elif a_title == 'iframe' or str_has(
                    href, ['gdgdocs.org', 'jinshuju', 'mikecrm.com'],
                    just_in=True):
                use_js_view = True
            elif a_title in ["qrcode", "erweima"]:
                use_js_view = True
                view_type = 'qrcode'
            elif href_mime_type.startswith('image/'):
                use_js_view = True
                view_type = 'image'
            if use_js_view:
                return cls.js_view(title,
                                   href,
                                   view_type=view_type,
                                   class_name=class_name,
                                   group_id=group_id,
                                   target=target,
                                   dom_id=dom_id,
                                   **kwargs)
            else:
                return cls.a(image_as_title,
                             href,
                             class_name=class_name,
                             target=target,
                             dom_id=dom_id,
                             **kwargs)
        else:
            return ''  # failed
示例#14
0
文件: album.py 项目: zhiiker/FarBox
def show_albums_as_sub_site():
    bucket = get_bucket_in_request_context()
    if not bucket:
        return
    request_path = get_request_path().strip("/")
    if not re.match("album(/|$)", request_path):
        return
    if "." in request_path and guess_type(
            request_path, default_type="").startswith("image/"):
        # 可能是直接的图片地址,避免被整个 album 给拦截了
        return
    site_configs = get_bucket_site_configs(bucket)
    albums_root = smart_unicode(site_configs.get("albums_root", ""))
    if not albums_root:
        return
    albums_root = albums_root.strip("/")  #todo 允许直接设定 / ?
    albums_home_sort = site_configs.get("albums_home_sort", "-date")
    album_items_sort = site_configs.get("album_items_sort", "-date")

    page_title = site_configs.get("albums_title") or get_just_name(
        albums_root, for_folder=True)

    if re.match("album/?$", request_path):
        # folders
        doc_type = "folder"
        doc_sort = albums_home_sort
        under = albums_root
    else:
        doc_type = "image"
        doc_sort = album_items_sort
        under = "%s/%s" % (albums_root, request_path.split("/",
                                                           1)[-1].strip("/"))
        folder_doc = get_record_by_path(bucket=bucket, path=under)
        if folder_doc:
            page_title = folder_doc.get("title") or get_just_name(
                folder_doc.get("path"), for_folder=True)
        else:
            page_title = get_just_name(under, for_folder=True)

    if doc_sort not in ["date", "-date"]:
        doc_sort = "-date"

    limit = 15  # todo 可以设定?
    doc_level = 1

    # min_images_count = 1
    docs = Data.get_data(path=under,
                         type=doc_type,
                         limit=limit,
                         level=doc_level,
                         sort=doc_sort,
                         pager_name='album_docs_pager',
                         exclude='default')

    if doc_type == "folder":
        for doc in docs:
            doc_path = get_path_from_record(doc, is_lower=True)
            relative_path = doc_path.replace(albums_root.lower(), "",
                                             1).strip("/")
            doc["album_url"] = "/album/%s" % relative_path

    return render_api_template(
        "builtin_theme_album_waterfall.jade",
        docs=docs,
        page_title=page_title,
    )
示例#15
0
文件: all.py 项目: zhiiker/FarBox
def is_image(obj):  # 一个字符串是否是图片的 url
    if isinstance(obj, (str, unicode)):
        mime_type = guess_type(obj)
        if mime_type and mime_type.startswith('image/'):
            return False
    return False