Beispiel #1
0
def change_bucket_expired_date(bucket,
                               expired_date=None,
                               days=None,
                               order_id=None,
                               **kwargs):
    if expired_date is None and days is None:
        # by default, 30 days
        free_days = to_int(get_env("free_days"), default_if_fail=30) or 30
        expired_date = datetime.datetime.utcnow() + datetime.timedelta(
            days=free_days)
    elif isinstance(days, (int, float)):
        # 指定扩展的天数
        now = datetime.datetime.utcnow()
        current_expired_date = get_bucket_expired_date(bucket) or now
        if current_expired_date < now:
            current_expired_date = now
        expired_date = current_expired_date + datetime.timedelta(days=days)
    if not isinstance(expired_date, datetime.datetime):
        try:
            expired_date = utc_date_parse(expired_date)
        except:
            return
    set_bucket_service_info(bucket,
                            expired_date=expired_date,
                            order_id=order_id,
                            **kwargs)
Beispiel #2
0
def get_domains_from_env(key):
    raw_domains = get_env(key) or ''
    domain_list = re.split('[,\n]', raw_domains)
    domains_got = []
    for domain in domain_list:
        domain = domain.strip().lower()
        if domain not in domains_got and domain:
            domains_got.append(domain)
    return domains_got
Beispiel #3
0
def create_new_bucket_for_user_step_1():
    register_note = get_env("register_note") or ""
    info = ""
    invitation_code = request.values.get("invitation_code")
    if invitation_code:
        if not check_invitation_by_web_request():
            info = "invalid invitation code or used"
        else:  # 跳转到创建 bucket 的逻辑
            return p_redirect("__create_bucket?invitation_code=%s" %
                              invitation_code)
    return render_api_template_as_response("page_user_register.jade",
                                           info=info,
                                           register_note=register_note)
Beispiel #4
0
def login():
    set_not_cache_current_request()
    bucket = get_logined_bucket(check=True)
    if bucket:
        email = get_bucket_owner_email(bucket)
    else:
        email = ""
    show_donation = auto_type(get_env("show_donation"))
    response = render_api_template_as_response(
        "page_user_admin.jade",
        email=email,
        show_donation=show_donation,
        is_wechat_server_valid=is_wechat_server_valid)
    return response
Beispiel #5
0
def allowed_to_display_some_bucket_info(bucket=None):
    if bucket:
        set_pending_bucket_bucket_in_request(bucket)  # 校验用的
    logined_bucket = get_logined_bucket_by_token()
    if not logined_bucket:
        raw_token = request.values.get("api_token") or request.values.get(
            "token") or ""
        if raw_token:
            endpoint_password = get_env("endpoint_password")
            if endpoint_password and endpoint_password == raw_token:
                return True
    if not logined_bucket:
        logined_bucket = get_logined_bucket()  # try again, by cookie
    if logined_bucket and logined_bucket == bucket:
        return True
    return False
Beispiel #6
0
def get_remote_nodes_to_sync_from():
    # 从本地配置中,引入要同步的节点 list,每一行一条记录; 简单有效的是,每行一个 ip
    # 如果 node 本身没有 :<port> 的声明, 默认会认为是 :7788 端口
    nodes = []
    raw_content = get_env("server_sync_nodes") or ""
    lines = raw_content.split(',')
    for line in lines:
        line = line.strip()
        if line.startswith('#'):
            continue
        if not line:
            continue
        if ':' not in line:
            line = '%s:7788' % line
        nodes.append(line)
    return nodes
Beispiel #7
0
def sync_from_remote_node(remote_node):
    # 从 remote node 上完全同步所有 buckets 的时候, 每次任务实际上是每次 1000 个 buckets
    # 在下次 cronjob 触发的时候,会在上次 cursor 保存的状态后,进行后面 1000 个同步,如此周而复始
    buckets, cursor = get_buckets_to_sync_from_remote_node(remote_node)
    if not buckets:
        return
    server_sync_token = get_env("server_sync_token")
    if not server_sync_token:
        return
    callback_func = partial(set_buckets_cursor_for_remote_node, remote_node,
                            cursor)
    job_func = partial(sync_bucket_from_remote_node,
                       remote_node=remote_node,
                       server_sync_token=server_sync_token)
    do_by_gevent_pool(pool_size=100,
                      job_func=job_func,
                      loop_items=buckets,
                      timeout=30 * 60,
                      callback_func=callback_func)
Beispiel #8
0
def create_new_bucket_for_user_step_2():
    # 这个也负责初次的安装,还没有 bucket 的时候
    register_note = get_env("register_note") or ""
    private_key = request.values.get(
        "private_key") or get_private_key_on_server_side()
    info = ""
    invitation_code = request.values.get(
        "invitation_code") or request.values.get("code")
    if request.method == "POST":
        info = create_bucket_by_web_request(invitation_code)
        if not info:  # 创建成功了
            return p_redirect("/admin")
    else:  # GET
        if invitation_code != "admin" and not check_invitation_by_web_request(
        ):
            info = "invalid invitation code"
    return render_api_template_as_response("page_user_create_bucket.jade",
                                           private_key=private_key,
                                           info=info,
                                           register_note=register_note)
Beispiel #9
0
def show_bucket_records_for_web_request(bucket=None, default_records_per_page=100, includes_zero_ids=True,
                                        cursor=None, per_page=None):
    # return response or abort error
    # 注意: 如果传入一个有效的 bucket,那么是不会进行校验的
    bucket = bucket or get_logined_bucket_by_token()  # by api token

    if not bucket:
        # 服务器端同步相关的逻辑在这里判断
        server_sync_token = request.values.get("server_sync_token", "")
        if server_sync_token and server_sync_token == get_env("server_sync_token"):
            bucket = get_pending_bucket_bucket_in_request()

    if not bucket:
        abort(404, "no bucket matched")
    set_bucket_in_request_context(bucket)
    pre_record_id = cursor or request.values.get('cursor')
    if not includes_zero_ids and not pre_record_id: # 不包括 zero ids 相当于
        pre_record_id = zero_id_for_finder
    per_page = per_page or to_per_page(default_records_per_page, request.values.get('per_page'), max_per_page=1000)
    records = get_records_for_bucket(bucket, start_record_id=pre_record_id, limit=per_page)
    return jsonify(records)
Beispiel #10
0
def init_server_status_bucket():
    if 'utc_offset' not in os.environ:
        # 统计系统信息时候,可读性使用的 utc_offset
        utc_offset = get_env('utc_offset')
        if utc_offset is None:
            utc_offset = 8
        try:
            utc_offset = str(utc_offset)
        except:
            utc_offset = '8'
        os.environ['utc_offset'] = utc_offset

    configs = get_server_status_bucket_configs()
    bucket = configs['bucket']
    public_key = configs['public_key']
    if has_bucket(bucket):
        return

    create_bucket_by_public_key(public_key)
    set_bucket_configs(bucket,
                       config_type='pages',
                       configs=bucket_web_template)
Beispiel #11
0
def extend_bucket_yearly():
    # 考虑到 alipay 的回调,这里不限制 bucket 是否处于登录的状态
    bucket = get_logined_bucket(check=True)

    service_info = get_bucket_service_info(bucket)
    order_ids = service_info.get("order_id_list") or []
    if not isinstance(order_ids, (list, tuple)): order_ids = []

    price = BUCKET_PRICE
    price2 = BUCKET_PRICE2
    price_note = get_env("bucket_price_note") or ""

    if request.method == "GET" and not request.values.get(
            "trade_no") and request.values.get("action") != "do":
        # 不需要处理,直接呈现页面
        return render_api_template_as_response("page_user_extend_bucket.jade",
                                               order_ids=order_ids,
                                               service_info=service_info,
                                               price=price,
                                               price2=price2,
                                               price_note=price_note)

    try_price2 = request.values.get("try_price2") in ["yes", "true"]
    to_handle = extend_bucket_expired_date_yearly_by_alipay(
        bucket, try_price2=try_price2)
    if to_handle:
        # 更新一次
        service_info = get_bucket_service_info(bucket)
        order_ids = service_info.get("order_id_list") or []
        if not isinstance(order_ids, (list, tuple)): order_ids = []

    return render_api_template_as_response("page_user_extend_bucket.jade",
                                           order_ids=order_ids,
                                           service_info=service_info,
                                           price=price,
                                           price2=price2,
                                           price_note=price_note)
Beispiel #12
0
#coding: utf8
import requests
from farbox_bucket.utils.ssdb_utils import auto_cache_by_ssdb
from farbox_bucket.utils.env import get_env

WECHAT_APP_ID = get_env("wechat_app_id")
WECHAT_APP_SECRET = get_env("wechat_app_secret")

# 一个微信的open id 看起来可能是这样的: oZ454jpVhF15nHxs3ig-uCq_gqss

API_PREFIX = 'https://api.weixin.qq.com/cgi-bin/'


# 每天最多 2000 次
def _get_access_token():
    if not WECHAT_APP_ID or not WECHAT_APP_SECRET:
        return ""
    url = API_PREFIX + 'token'
    params = {
        'grant_type': 'client_credential',
        'appid': WECHAT_APP_ID,
        'secret': WECHAT_APP_SECRET
    }
    response = requests.get(url, params=params, verify=False)
    try:
        token = response.json().get('access_token')
    except:
        try:
            print(response.json().get("errmsg"))
        except:
            pass
Beispiel #13
0
# coding: utf8
import re
from flask import request, Response
from farbox_bucket.utils import to_float
from farbox_bucket.utils.functional import cached_property
from farbox_bucket.utils.env import get_env
from .alipay_api import AlipayAPI

ALIPAY_PID = get_env('ALIPAY_PID')
ALIPAY_APP_ID = get_env('ALIPAY_APP_ID')
ALIPAY_PRIVATE_KEY = get_env('ALIPAY_PRIVATE_KEY')
ALIPAY_PUBLIC_KEY = get_env('ALIPAY_PUBLIC_KEY')


class AliPay(object):
    def __init__(self,
                 private_key=None,
                 public_key=None,
                 pid=None,
                 app_id=None):
        self.alipay_public_key = public_key or ALIPAY_PUBLIC_KEY
        self.alipay_private_key = private_key or ALIPAY_PRIVATE_KEY
        self.alipay_pid = pid or ALIPAY_PID
        self.alipay_app_id = app_id or ALIPAY_APP_ID

    @cached_property
    def alipay_api(self):
        if self.alipay_pid and self.alipay_private_key:  # and self.alipay_public_key
            alipay_api = AlipayAPI(private_key=self.alipay_private_key,
                                   public_key=self.alipay_public_key,
                                   pid=self.alipay_pid,
Beispiel #14
0
#coding: utf8
from __future__ import absolute_import
from farbox_bucket.utils.env import get_env
from farbox_bucket.server.backend.service import keep_watch_nginx, restart_backend_per_day, keep_watch_memcache, run_logrotate

should_sync_buckets = get_env("should_sync_buckets_in_backend")
if should_sync_buckets == "no":
    should_sync_buckets = False

backend_jobs = [
    keep_watch_nginx,
    keep_watch_memcache,
    restart_backend_per_day,
    run_logrotate,
]

if should_sync_buckets:
    # 减少 backend 的内存占用,如果只是守护性质的话
    from farbox_bucket.server.backend.sync.buckets import sync_buckets_from_remote_marked, sync_buckets_from_remote_nodes
    backend_jobs.append(sync_buckets_from_remote_marked)
    backend_jobs.append(sync_buckets_from_remote_nodes)
Beispiel #15
0
# coding: utf8
import xmltodict
from flask import request
from farbox_bucket.settings import DEBUG
from farbox_bucket.utils import smart_unicode
from farbox_bucket.utils.env import get_env
from farbox_bucket.utils.memcache_block import is_blocked
from farbox_bucket.clouds.wechat.utils.check import check_is_from_wechat
from farbox_bucket.clouds.wechat.utils.message import send_wechat_message
from .wechat_text_image_sync_worker import wechat_text_image_handler
from .bind_wechat import unbind_wechat_account, get_wechat_account_bind_status_reply, bind_bucket_by_wechat, \
    get_bucket_by_wechat_user_id


WECHAT_TOKEN = (get_env("wechat_token") or "").strip()

is_wechat_server_valid = True if WECHAT_TOKEN else False


def compile_for_wechat(raw_data):
    if isinstance(raw_data, dict):
        xml_data = raw_data
    else:
        xml_data = xmltodict.parse(raw_data)["xml"]

    wechat_user_id = xml_data.get("FromUserName")
    msg_type = xml_data.get("MsgType")
    event_name = (xml_data.get("Event") or "").lower()
    event_key = (xml_data.get("EventKey") or "").lower()

    #with open("/tmp/test.json", "w") as f:
Beispiel #16
0
from farbox_bucket.server.utils.request_context_vars import is_resource_in_loads_in_page_already,\
    get_i18n_data_from_request, set_i18n_data_to_request
from farbox_bucket.server.utils.request_path import auto_bucket_url_path, get_request_path_for_bucket

from farbox_bucket.server.static.static_render import web_static_resources_map, static_folder_path
from farbox_bucket.server.template_system.api_template_render import render_api_template
from farbox_bucket.server.template_system.namespace.utils.form_utils import create_simple_form, create_grid_form, \
    create_form_dom_by_field as _create_form_dom_by_field, create_form_dom as _create_form_dom, \
    get_data_obj_from_POST as form_get_data_obj_from_POST

from farbox_bucket.server.template_system.namespace.utils.nav_utils import pre_nav_data
from farbox_bucket.server.helpers.smart_scss import get_smart_scss_url

from farbox_bucket.server.realtime.utils import get_bucket_ws_url

static_files_url = (get_env("static_files_url") or "").strip().strip("/")
qcloud_cdn_token = (get_env("qcloud_cdn_token") or "").strip()


def get_a_random_dom_id():
    dom_id = 'd%s' % uuid.uuid1().hex
    return dom_id


lazy_load_map = {
    'font':
    '/fb_static/lib/fontawesome/css/font-awesome.min.css',
    'jquery':
    '/fb_static/lib/jquery.js',
    'pure': ['/fb_static/lib/pure.css', '/fb_static/lib/pure_patch.css'],
    'form':
Beispiel #17
0
# coding: utf8
from farbox_bucket.utils.env import get_env
from farbox_bucket.clouds.qcloud import upload_file_obj_to_qcloud, delete_file_on_qcloud,\
    has_file_on_qcloud, get_file_content_from_qcloud

raw_qcloud_config = get_env('qcloud')
QCLOUD_REGION = get_env("qcloud_region") or 'ap-shanghai'
QCLOUD_BUCKET = get_env("qcloud_bucket")
QCLOUD_SECRET_ID = get_env("qcloud_secret_id")
QCLOUD_SECRET_KEY = get_env("qcloud_secret_key")

if QCLOUD_BUCKET and QCLOUD_SECRET_ID and QCLOUD_SECRET_KEY:
    qcloud_is_valid = True
else:
    qcloud_is_valid = False
QCLOUD_URL = (get_env("qcloud_url") or "").rstrip("/")

QCLOUD_CDN_TOKEN = (get_env("qcloud_cdn_token") or "").strip()


def upload_file_to_qcloud_for_bucket(bucket,
                                     relative_path,
                                     file_obj,
                                     content_type="",
                                     **headers):
    if not qcloud_is_valid:
        return False  # ignore
    relative_path = relative_path.strip('/')
    url_path = '%s/%s' % (bucket, relative_path)
    uploaded = upload_file_obj_to_qcloud(file_obj=file_obj,
                                         url_path=url_path,
Beispiel #18
0
#coding: utf8
from __future__ import absolute_import
import re, os, sys, uuid
from raven import Client
from farbox_bucket.utils import to_float, to_int
from farbox_bucket.utils.path import read_file, write_file
from farbox_bucket.utils.env import get_env
from farbox_bucket.utils.ssdb_client import SSDB_Client
from farbox_bucket import version
from farbox_bucket.utils.encrypt.simple import ServerSerializer
from farbox_bucket.server.dangerous.start_elasticsearch_server import auto_reset_elasticsearch_memory_config_when_app_started

ssdb_ip = get_env('SSDB_IP') or '127.0.0.1'
ssdb_port = get_env('SSDB_PORT') or 8888
try:
    ssdb_port = int(ssdb_port)
except:
    ssdb_port = 8888

db_client = SSDB_Client(ssdb_ip, ssdb_port)

STATIC_FILE_VERSION = version  # 静态资源通过 h.load 载入的时候,增加 version 的逻辑

# Markdown 解析的时候会有扩容的情况,估计 100k 的(多行)文档会膨胀到 500k
MAX_RECORD_SIZE = 500 * 1024  # 500Kb

# 这个只是对 verify 时候起作用的,如果是 system 直接写入的,不在受限范围
MAX_RECORD_SIZE_FOR_CONFIG = 800 * 1024  ## 800Kb

MAX_FILE_SIZE = to_int(
    get_env("MAX_FILE_SIZE")) or 50 * 1024 * 1024  # 最大文件 50 Mb
Beispiel #19
0
# coding: utf8
from flask import abort
from farbox_bucket.utils.env import get_env
from farbox_bucket.server.web_app import app
from farbox_bucket.bucket.token.utils import get_logined_bucket
from farbox_bucket.clouds.wechat.bind_wechat import get_wechat_bind_code_for_bucket, get_wechat_user_docs_by_bucket
from farbox_bucket.server.template_system.api_template_render import render_api_template_as_response
from .wechat_handler import wechat_web_handler, WECHAT_TOKEN

# 公众号后台获得公众号二维码,解析后是一个 URL 的字符串
wechat_account_url = get_env("wechat_account_url") or ""
wechat_account_url2 = get_env("wechat_account_url2") or ""


@app.route("/__wechat_api", methods=["POST", "GET"])
def wechat_api_view():
    return wechat_web_handler()


@app.route("/__wechat_bind", methods=["POST", "GET"])
def wechat_bind_view():
    if not WECHAT_TOKEN or not wechat_account_url:
        abort(404, "Wechat is not valid in current service")
    else:
        logined_bucket = get_logined_bucket(check=True)
        if not logined_bucket:
            return abort(404, "not login")
        bind_code = get_wechat_bind_code_for_bucket(logined_bucket)
        wechat_user_docs = get_wechat_user_docs_by_bucket(logined_bucket,
                                                          with_name=True)
        response = render_api_template_as_response(