def send_mail(recipient, subject, body, message_id): message = Message.query.get(message_id) api_base_url = get_setting('api_base_url').value if not is_authorized(): return token_type = get_setting('token_type').value access_token = get_setting('access_token').value request = urllib.request.Request(api_base_url + '/me/messages', data=json.dumps({ 'subject': subject, 'body': { 'contentType': 'HTML', 'content': body }, 'toRecipients': [{ 'emailAddress': { 'address': recipient } }] }).encode(), method='POST') request.add_header('Authorization', token_type + ' ' + access_token) request.add_header('Content-Type', 'application/json') with urllib.request.urlopen(request) as f: result = json.loads(f.read().decode()) message_id = result['id'] web_link = result['webLink'] message.message_id = message_id message.status = '草稿' message.web_link = web_link db.session.commit() if not is_authorized(): return request = urllib.request.Request(api_base_url + '/me/messages/' + message_id + '/send', method='POST') request.add_header('Authorization', token_type + ' ' + access_token) request.add_header('Content-Length', '0') with urllib.request.urlopen(request) as f: code = f.code if code == 202: message.status = '已发送' db.session.commit() if not is_authorized(): return request = urllib.request.Request(api_base_url + 'me/messages/' + message_id) request.add_header('Authorization', token_type + ' ' + access_token) request.add_header('Prefer', 'outlook.body-content-type="html"') with urllib.request.urlopen(request) as f: result = json.loads(f.read().decode()) sent_date_time = result['sentDateTime'] recipient = result['toRecipients'][0]['emailAddress']['address'] web_link = result['webLink'] message.sent_date_time = datetime.strptime(sent_date_time, '%Y-%m-%dT%H:%M:%SZ') message.recipient = recipient message.web_link = web_link db.session.commit()
def authorize(): token_url = get_setting('token_url').value client_id = get_setting('client_id').value scope = get_setting('scope').value redirect_url = get_setting('redirect_url').value client_secret = get_setting('client_secret').value code = request.args['code'] with urllib.request.urlopen(token_url, data=urllib.parse.urlencode({ 'client_id': client_id, 'grant_type': 'authorization_code', 'scope': scope, 'code': code, 'redirect_uri': redirect_url, 'client_secret': client_secret }).encode()) as f: result = json.loads(f.read().decode()) set_setting('access_token', value=result['access_token']) set_setting('token_type', value=result['token_type']) set_setting('expires_at', value=str(int(time.time()) + result['expires_in'])) set_setting('refresh_token', value=result['refresh_token']) opener.addheaders = [ ('Authorization', result['token_type'] + ' ' + result['access_token']) ] return redirect(plugin_url_for('me', _component='admin'))
def login(): authorize_url = get_setting('authorize_url').value client_id = get_setting('client_id').value scope = get_setting('scope').value redirect_url = get_setting('redirect_url').value return redirect(authorize_url + '?' + urllib.parse.urlencode({ 'client_id': client_id, 'response_type': 'code', 'redirect_uri': redirect_url, 'response_mode': 'query', 'scope': scope }))
def admin_articles(): def get_articles(repository_id): return Article.query.filter_by(repository_id=repository_id).order_by( Article.version_timestamp.desc()).all() page = request.args.get('page', 1, type=int) query = db.session.query(Article.repository_id).order_by( func.max(Article.version_timestamp).desc()).group_by( Article.repository_id) query = {'query': query} filter(query, request.args) query = query['query'] pagination = query.paginate(page, per_page=get_setting('items_per_page').value, error_out=False) repository_ids = [item[0] for item in pagination.items] return { 'value': [{ 'repositoryId': repository_id, 'articles': [ article.to_json('admin_brief') for article in get_articles(repository_id) ] } for repository_id in repository_ids] }
def list_tags(): if request.method == 'POST': if request.form['action'] == 'delete': result = delete(request.form['id']) return jsonify(result) else: page = request.args.get('page', 1, type=int) pagination = Comment.query.order_by(desc(Comment.timestamp)).paginate( page, per_page=get_setting('items_per_page').value, error_out=False) comments = pagination.items return current_plugin.render_template( 'list.html', comments=comments, get_comment_show_info=get_comment_show_info, pagination={ 'pagination': pagination, 'fragment': {}, 'url_for': plugin_url_for, 'url_for_params': { 'args': ['list'], 'kwargs': { '_component': 'admin' } } })
def get_admin_widget_article_list(params): def get_articles(repository_id): return Article.query.filter_by(repository_id=repository_id).order_by( Article.version_timestamp.desc()).all() page = 1 if 'page' in params: page = int(params['page']) query = db.session.query(Article.repository_id).group_by( Article.repository_id).order_by(Article.version_timestamp.desc()) query = {'query': query} filter(query, request.args) query = query['query'] pagination = query.paginate(page, per_page=get_setting('items_per_page').value, error_out=False) repository_ids = [item[0] for item in pagination.items] custom_columns = Signal.send('custom_list_column') return current_plugin.render_template('list.html', repository_ids=repository_ids, pagination={ 'pagination': pagination, 'fragment': {}, 'url_for': plugin_url_for, 'url_for_params': { 'args': ['list'], 'kwargs': { '_component': 'admin' } } }, get_articles=get_articles, custom_columns=custom_columns)
def dispatch(): if request.method == 'POST': if request.form['action'] == 'delete': result = delete(request.form['id']) return jsonify(result) else: page = request.args.get('page', 1, type=int) pagination = Tag.query.order_by(Tag.name).paginate( page, per_page=get_setting('items_per_page').value, error_out=False) tags = pagination.items return current_plugin.render_template( 'list.html', tags=tags, pagination={ 'pagination': pagination, 'fragment': {}, 'url_for': plugin_url_for, 'url_for_params': { 'args': ['list'], 'kwargs': { '_component': 'admin' } } }, admin_article_list_url=admin_article_list_url)
def admin_api_proxy(widget, path, request, article): if widget == 'attachment': if request.method == 'POST': data = request.get_json() filename = data['filename'] if '.' not in filename or filename.rsplit('.', 1)[1].lower( ) not in get_setting('allowed_upload_file_extensions').value: return jsonify({'message': '禁止上传的文件类型'}), 400 extension = filename.rsplit('.', 1)[1].lower() random_filename = uuid.uuid4().hex + '.' + extension abs_file_path = os.path.join(current_app.config['TEMP_FOLDER'], random_filename) os.makedirs(os.path.dirname(abs_file_path), exist_ok=True) with open(abs_file_path, 'wb') as f: f.write(base64.b64decode(data['base64'])) attachment = Attachment.create(abs_file_path, original_filename=filename, file_extension=extension) db.session.add(attachment) article.attachments.append(attachment) db.session.commit() return jsonify({'id': attachment.id}), 201 if request.method == 'DELETE': splits = path.split('/') attachment_id = int(splits[1]) attachment = Attachment.query.get(attachment_id) db.session.delete(attachment) db.session.commit() return jsonify({'message': '删除成功'}) if widget == 'attachments': if request.method == 'GET': return { 'value': [attachment.to_json() for attachment in article.attachments] }
def list_messages(): if request.method == 'POST': if request.form['action'] == 'resend': comment_id = request.form['comment_id'] comment_submitted(sender=None, comment=Comment.query.get(comment_id)) elif request.form['action'] == 'rerun': job_id = request.form['job_id'] redis_url = current_app.config['REDIS_URL'] with Connection(redis.from_url(redis_url)): fq = get_failed_queue() fq.requeue(job_id) else: page = request.args.get('page', 1, type=int) pagination = Message.query.paginate( page, per_page=get_setting('items_per_page').value, error_out=False) messages = pagination.items with Connection(redis.from_url(current_app.config['REDIS_URL'])): queue = Queue() return current_plugin.render_template('list.html', messages=messages, queue=queue, pagination={ 'pagination': pagination, 'fragment': {}, 'url_for': plugin_url_for, 'url_for_params': { 'args': ['list'], 'kwargs': { '_component': 'admin' } } })
def main_widget(request): def get_metas(article): return Signal.send('article_list_item_meta', article=article) page = request.args.get('page', 1, type=int) query = Article.query_published().order_by(Article.timestamp.desc()) query = {'query': query} filter(query, request.args) query = query['query'] pagination = query.paginate(page, per_page=get_setting('items_per_page').value, error_out=False) articles = pagination.items return { 'slug': 'article_list', 'name': '文章列表', 'html': current_plugin.render_template('widget_article_list', 'widget.html', articles=articles, pagination=pagination, request_params=request.args, get_metas=get_metas) }
def get_navbar_item(): return { 'type': 'brand', 'brand': get_setting('site_name').value, 'more': [{ 'type': 'item', 'name': '首页', 'link': component_url_for('index') }] }
def is_authorized(): access_token = get_setting('access_token').value if access_token == '': return False expires_at = get_setting('expires_at').value if expires_at - 10 < int(time.time()): token_url = get_setting('token_url').value refresh_token = get_setting('refresh_token').value client_id = get_setting('client_id').value redirect_url = get_setting('redirect_url').value scope = get_setting('scope').value client_secret = get_setting('client_secret').value if refresh_token == '': return False with urllib.request.urlopen(token_url, data=urllib.parse.urlencode({ 'client_id': client_id, 'grant_type': 'refresh_token', 'scope': scope, 'refresh_token': refresh_token, 'redirect_uri': redirect_url, 'client_secret': client_secret }).encode()) as f: result = json.loads(f.read().decode()) set_setting('access_token', value=result['access_token']) set_setting('token_type', value=result['token_type']) set_setting('expires_at', value=str(int(time.time()) + result['expires_in'])) set_setting('refresh_token', value=result['refresh_token']) token_type = get_setting('token_type').value access_token = get_setting('access_token').value opener.addheaders = [('Authorization', token_type + ' ' + access_token)] return True
def send_email(to_address, subject, content): from_address = get_setting('email').value password = get_setting('password').value smtp_address = get_setting('smtp_address').value msg = MIMEText(content, 'plain', 'utf-8') msg['From'] = _format_address( get_setting('site_name').value + from_address) msg['To'] = _format_address('%s <%s>' % (to_address, to_address)) msg['Subject'] = Header(subject, 'utf-8').encode() log_file = tempfile.TemporaryFile() available_fd = log_file.fileno() log_file.close() os.dup2(2, available_fd) log_file = tempfile.TemporaryFile() os.dup2(log_file.fileno(), 2) try: smtp = smtplib.SMTP_SSL(smtp_address, 465) smtplib.stderr = log_file smtp.set_debuglevel(2) smtp.login(from_address, password) smtp.sendmail(from_address, [to_address], msg.as_string()) smtp.quit() except smtplib.SMTPException as e: is_success = False else: is_success = True sys.stderr.flush() log_file.flush() log_file.seek(0) stderr_bytes = log_file.read() log_file.close() os.dup2(available_fd, 2) os.close(available_fd) return is_success, stderr_bytes.decode()
def me(): if is_authorized(): api_base_url = get_setting('api_base_url').value try: f = opener.open(api_base_url + '/me') me = json.loads(f.read().decode()) except urllib.error.HTTPError as e: me = None else: me = None return current_plugin.render_template('me.html', me=me, login_url=plugin_url_for( 'login', _component='admin'))
def upload(): if 'files[]' not in request.files: return jsonify({'code': 1, 'message': '上传文件不存在'}) file = request.files['files[]'] if file.filename == '': return jsonify({'code': 2, 'message': '未选择上传文件'}) filename = file.filename if '.' not in filename or filename.rsplit('.', 1)[1].lower( ) not in get_setting('allowed_upload_file_extensions').value: return jsonify({'code': 3, 'message': '禁止上传的文件类型'}) extension = filename.rsplit('.', 1)[1].lower() random_filename = uuid.uuid4().hex + '.' + extension abs_file_path = os.path.join(current_app.config['TEMP_FOLDER'], random_filename) os.makedirs(os.path.dirname(abs_file_path), exist_ok=True) file.save(abs_file_path) attachment = Attachment.create(abs_file_path, original_filename=filename, file_extension=extension, mime=file.mimetype) db.session.add(attachment) db.session.commit() meta = json.loads(request.form.get('meta', type=str)) if 'article_id' in meta: article = Signal.send('get_article', 'article', article_id=meta['article_id']) article.attachments.append(attachment) db.session.commit() if 'page_id' in meta: page = Signal.send('get_page', 'page', page_id=meta['page_id']) page.attachments.append(attachment) db.session.commit() return jsonify({ 'code': 0, 'message': '上传成功', 'file_size': attachment.file_size, 'relative_path': random_filename, 'delete_url': component_url_for('.upload_delete', 'admin', id=attachment.id) })
def articles(): page = request.args.get('page', 1, type=int) query = Article.query_published().order_by(Article.timestamp.desc()) query = {'query': query} filter(query, request.args) query = query['query'] pagination = query.paginate(page, per_page=get_setting('items_per_page').value, error_out=False) articles = pagination.items return { 'articles': [article.to_json('basic') for article in articles], 'pagination': { 'prevNum': pagination.prev_num, 'nextNum': pagination.next_num, 'page': pagination.page, 'pages': pagination.pages, 'perPage': pagination.per_page, 'total': pagination.total } }
def send(cls, _name, _scope, **kwargs): from bearblog.settings import get_setting signal_name = _scope + '.' + _name if signal_name not in cls._signals: return signal = cls._signals[signal_name] if 'return_type' in cls._signals[signal_name]: return_type = cls._signals[signal_name]['return_type'] if return_type == 'single': for receiver in signal['receivers'].values(): item_result = cls.call_receiver_func( receiver['func'], kwargs) if item_result is not None: return item_result if return_type == 'list': if not signal.get('managed', False): result = [] for receiver in signal['receivers'].values(): result.append( cls.call_receiver_func(receiver['func'], kwargs)) return result else: result = [] signal_settings_obj = get_setting(_name, category=_scope) if signal_settings_obj is None or 'subscribers_order' not in signal_settings_obj.value: if signal['managed_default'] == 'all': for receiver in signal.get('receivers', {}).values(): result.append( cls.call_receiver_func( receiver['func'], kwargs)) return result elif signal['managed_default'] == 'none': return [] else: signal_settings = signal_settings_obj.value result = {} for list_name, items in signal_settings[ 'subscribers_order'].items(): result[list_name] = [] for item in items: if item['is_on'] and item[ 'subscriber'] in signal['receivers']: receiver = signal['receivers'][ item['subscriber']]['func'] result[list_name].append( cls.call_receiver_func( receiver, kwargs)) if 'main' in result and len(result) == 1: result = result['main'] return result if return_type == 'merged_list': result = [] for receiver in signal['receivers'].values(): item_result = cls.call_receiver_func( receiver['func'], kwargs) if type(item_result) is list: result.extend(item_result) else: result.append(item_result) return result if return_type == 'dict': result = {} for receiver in signal['receivers'].values(): key, value = cls.call_receiver_func( receiver['func'], kwargs) result[key] = value return result if return_type == 'single_not_none': for receiver in signal['receivers'].values(): item_result = cls.call_receiver_func( receiver['func'], kwargs) if item_result is not None: return item_result raise ValueError() else: for receiver in signal['receivers'].values(): cls.call_receiver_func(receiver['func'], kwargs)