class ControlPanelUserApi(BaseApi): resource_name = 'cp/user' form_service = FormService() @expose('/', methods=['POST']) def register(self): """ :return: """ user = request.json.copy() form = self.form_service.add_new_user(user) return jsonify(form.asdict()) @expose('/collaborators/add', methods=['GET']) def add_collaborators(self, username): username = request.json['username'] form_id = request.json['form_id'] collaboration_user = self.form_service.add_new_collaboration_user( username, form_id) return jsonify(collaboration_user.asdict()) @expose('/collaborators/list/<form_id>', methods=['GET']) def get_collaborators_list(self, form_id): collaboration_users = self.form_service.fetch_collaboration_users( form_id, PageRequest.create(request.args)) return jsonify(collaboration_users.asdict()) @expose('/collaborators/<c_id>', methods=['DELETE']) def delete(self, c_id): collaboration_user = self.form_service.remove_collaboration_user(c_id) return jsonify(collaboration_user.asdict())
class ControlPanelValueApi(BaseApi): resource_name = "cp/value" form_service: FormService = FormService() @expose('<form_id>') def get(self, form_id): data = self.form_service.fetch_values(1, 1, 50) return jsonify(data)
class ControlPanelFieldApi(BaseApi): resource_name = 'cp/field' form_service: FormService = FormService() @expose('', methods=['POST']) def create(self): """Create a field --- post: requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Field' responses: 200: description: Create a field content: application/json: schema: $ref: '#/components/schemas/Field' """ field = self.form_service.add_new_field(request.json) return jsonify(field.asdict()), 201 @expose('<field_id>', methods=['PUT']) def update(self, field_id): changed = self.form_service.change_field(field_id, request.json) return jsonify(changed.asdict()) @expose('<field_id>', methods=['DELETE']) def delete(self, field_id): field = self.form_service.remove_field(field_id) return jsonify(field.asdict()) @expose('<field_id>') def get(self, field_id): """Get a form --- get: responses: 200: description: Get a form content: application/json: schema: $ref: '#/components/schemas/Field' """ field = self.form_service.fetch_field(field_id) return jsonify(field.asdict())
class FormApi(BaseApi): resource_name = 'form' apispec_parameter_schemas = SCHEMAS form_service = FormService() @expose('<form_id>', methods=['GET']) def get(self, form_id): """Get a form --- get: parameters: - name: form_id description: "表单ID" required: true type: integer format: int64 responses: '200': description: Get a form content: application/json: schema: $ref: '#/components/schemas/Form' """ user_agent = to_user_agent(request) form = self.form_service.fetch_form(form_id, current_user) return jsonify( form.asdict(follow={ 'fields': { "follow": { "options": {}, "constraints": {}, } } })) @expose('/{id}/value', methods=['POST']) def submit(self): """Submit a form --- post: description: "提交表单数据" responses: 200: content: application/json: schema: $ref: "#/components/schemas/Value" """ pass
class FormApi(BaseApi): resource_name = 'form' apispec_parameter_schemas = SCHEMAS form_service = FormService() @expose('<form_id>', methods=['GET']) def get(self, form_id): """Get a form --- get: responses: '200': description: Get a form content: application/json: schema: $ref: '#/components/schemas/Form' """ user_agent = to_user_agent(request) form = self.form_service.fetch_form(form_id, current_user, user_agent) return jsonify( form.asdict(follow={ 'fields': { "follow": { "options": {}, "constraints": {}, } } })) @expose('/{id}/value', methods=['POST']) def submit(self): """Submit a form --- post: responses: 200: description: Submit form list content: application/json: schema: type: object properties: message: type: string """ pass
def test_create(self): service = FormService(self.db) form = service.add_new_form(MVP_FORM) for f in form.fields: print(f.id) v = service.submit(1, {"name": None, 2: 1, 3: "18621068396"}) i = 1 for opt in form.fields[1].options: self.assertEquals(i, opt.value) i += 1 service.change_form(form.id, CHANGED_FORM) changed = service.fetch_form(form.id) self.assertEquals("在 JotForm 上测试 openform MVP Changed", changed.title) for field in changed.fields: if field.id == 3: self.assertTrue(False) if field.id == 2: for option in field.options: if option.id == 7: self.assertTrue(False) mobile = changed.fields[-1] self.assertEquals("手机号码", mobile.title) print(changed.fields) from app import db for i in db.session.query(models.Field).all(): print(i.to_json()) v = service.submit(1, {"name": "魏琮举", 2: 1, 3: "18621068396"}) v = service.submit(1, {"name": None, 2: 1, 3: "18621068396"}) print(changed.fields[0].title) print(changed.fields[0].errors)
class FormView(BaseView): form_service = FormService() route_base = '/form' assembler = FormViewModelAssembler() @expose('/<form_id>', methods=["GET", "POST"]) def form(self, form_id): user_agent = to_user_agent(request) form = self.form_service.fetch_form(form_id, g.user, user_agent) form_view = self.assembler.to_view_model(form, request.form) if "POST" == request.method: user_agent = to_user_agent(request) if self.form_service.submit(form, user_agent): return self.render_template('openform/form_success.html') return self.render_template("openform/form.html", form_view=form_view, form=form)
class FormView(BaseView): form_service = FormService() route_base = '/form' assembler = FormViewModelAssembler() @expose('/<form_id>', methods=["GET", "POST"]) def form(self, form_id): user_agent = to_user_agent(request) form = self.form_service.fetch_form(form_id, g.user, user_agent) form_view = self.assembler.to_view_model(form, ParameterContainer()) if "POST" == request.method: user_agent = to_user_agent(request) if self.form_service.submit(form, g.user, user_agent): return redirect( url_for("FormView.success_redirect", form_id=form_id) ) return self.render_template( "openform/form.html", form_view = form_view, form = form ) @expose('/<form_id>/success_redirect', methods=['GET']) def success_redirect(self, form_id): return redirect( url_for("FormView.form_success", form_id=form_id) ) @expose('/<form_id>/success', methods=['GET']) def form_success(self, form_id): return self.render_template( 'openform/form_success.html' )
class ControlPanelFormRoleApi(BaseApi): resource_name = 'cp/form/role' def __init__(self): super().__init__() self.form_service = FormService() @expose('') def get(self): """Get a form --- get: responses: 200: description: 查询表单协作的角色 content: application/json: schema: $ref: "#/components/schemas/Form" """ roles = self.form_service.all_roles() return jsonify([role.asdict() for role in roles])
class ControlPanelFormApi(BaseApi): resource_name = 'cp/form' form_service = FormService() def __init__(self): super().__init__() self.event_repository = EventRepository(db) self.value_repository = ValueRepository(db) self.form_repository = FormRepository(db) @jwt_required @expose('/', methods=['POST']) def create(self): """Create a form --- post: summary: 创建表单 description: 创建表单 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Form' responses: 200: description: Create a form content: application/json: schema: $ref: '#/components/schemas/Form' """ form = request.json.copy() form["user_id"] = current_user.id form = self.form_service.add_new_form(form) return jsonify(form.asdict()), 201 @expose('/{id}', methods=['PUT']) def update(self): """Create a form --- put: summary: 更新表单 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Form' responses: 200: description: Create a form content: application/json: schema: $ref: '#/components/schemas/Form' """ return self.response(200, **{}) @expose('/{id}/publish', methods=['POST']) def publish(self): """Publish a form --- post: summary: 发布表单 responses: 200: content: application/json: schema: $ref: '#/components/schemas/Form' """ return self.response(200, **{}) @expose('/{id}/publish', methods=['DELETE']) def unpublish(self): """Delete a form --- delete: summary: 取消表单发布 responses: 200: description: Delete a form content: application/json: schema: type: object properties: message: type: string """ return self.response(200, **{}) @jwt_required @expose('/', methods=['GET']) def get_list(self): """Get form list --- get: summary: 查询表单列表 responses: 200: content: application/json: schema: type: array items: $ref: "#/components/schemas/Form" """ forms = self.form_service.fetch_forms( current_user.id, PageRequest.create(request.args) ) return jsonify(forms.asdict()) @expose('/{id}', methods=['GET']) def get_detail(self): """Get a form --- get: responses: 200: description: Get a form content: application/json: schema: $ref: "#/components/schemas/Form" """ return self.response(200, **{}) @jwt_required @expose("/<form_id>/summary", methods=["GET"]) def summary(self, form_id): user = current_user submit_count_by_days = self.value_repository.count_by_8_days(user.id, form_id) form = self.form_repository.find_one(form_id) return jsonify({ "submit_count": self.value_repository.count_all(user.id, form_id), "submit_count_today": self.value_repository.count_today( user.id, form_id), "reads_today": self.event_repository.count_today(form_id, EventType.VIEW_FORM), "submit_count_by_days": submit_count_by_days, "read_count_by_days": self.event_repository.count_by_8_days(form_id, EventType.VIEW_FORM), "submit_count_by_mintes": self.value_repository.count_by_24_minute( user.id, form_id), "form": form.asdict(), }) @expose('/<form_id>/value', methods=['GET']) def value(self, form_id): page_request = PageRequest.create(request.args) value = self.form_service.fetch_values( form_id, page_request ) return jsonify(value.asdict()) @jwt_required @expose("/<form_id>/export", methods=["GET"]) def export(self, form_id): """ --- get: description: "导出CSV文件" responses: 200: content: application/json: schema: $ref: "#/components/schemas/Form" """ # TODO: 根据 Request Content Type 来导出返回的内容,例如JSON form_id = int(form_id) count = self.value_repository.count(form_id) form = self.form_repository.find_one(form_id) db.session.commit() fields_map = {} for field in form.fields: fields_map[int(field.id)] = field def to_export(row): ex = {} for field_id, value in row['values'].items(): field = fields_map[int(field_id)] ex[field.title] = field.to_text_value(value) ex['id'] = row['sequence'] ex['created_at'] = row['created_at'] ex['updated_at'] = row['updated_at'] return ex def generate(): paginator = PageRequest.create(request.args) args = [int(form_id), paginator] i = 0 position = 0 while i < paginator.page_size: print(i) args[1].page = i + 1 values = self.value_repository.find(*args) if i == 0: iostream = io.StringIO() first = to_export(values[0].asdict()) keys = first.keys() csv_writer = csv.DictWriter(iostream, fieldnames=keys) csv_writer.writeheader() for value in values: csv_writer.writerow(to_export(value.asdict())) iostream.seek(position) for line in iostream.readline(): yield line position = iostream.tell() i += 1 response = Response(stream_with_context(generate())) response.headers["Content-Type"] = "text/csv" return response @jwt_required @expose("/excel", methods=['GET']) def from_excel(self): book = xlwt.Workbook() sheet = book.add_sheet('form') title = ['%s' % item for item in ff.Form.__dict__.keys() if not str(item).startswith("_")] i = 0 for h in title: sheet.write(0, i, h) i = 1 forms = self.form_service.fetch_forms_not_page(current_user.id) for row, form in enumerate(forms): for col in range(0, len(title)): sheet.write(row 1, col, form[title[col]]) bio = BytesIO() book.save(bio) return bio.getvalue() @jwt_required @expose("/statement", methods=['GET']) def statement(self): """ 表单报表 :return: """ field_num = self.form_service.count_field() select_field_num = self.form_service.count_select_field() return self.response(200, **{"statement": round(select_field_num / field_num, 2)})
class ControlPanelValueApi(BaseApi): resource_name = "cp/value" def __init__(self): super(ControlPanelValueApi, self).__init__() self.form_service = FormService() @expose('') def get(self, form_id): """ --- get: summary: "查询表格数据" description: "查询表格数据" responses: 200: description: Get a form content: application/json: schema: type: array items: $ref: "#/components/schemas/Value" """ data = self.form_service.fetch_values(1, 1, 50) return jsonify(data) @expose("", methods=["POST"]) def create(self, values): """ --- post: summary: "创建表格数据" description: "创建表格数据" responses: 200: description: Get a form content: application/json: schema: $ref: "#/components/schemas/Value" """ return jsonify({}) @expose('/<value_id>') def fetch_one(self, value_id): """ --- get: summary: "查询表格数据" description: "查询表格数据" parameters: - name: value_id in: path type: integer format: int64 description: "Value 主键ID" responses: 200: content: application/json: schema: $ref: "#/components/schemas/Value" """ return jsonify({}) @expose('/<value_id>', methods=["PUT"]) def update(self, value_id): """ --- put: summary: "更新表格数据" description: "更新表格数据" parameters: - name: value_id in: path type: integer format: int64 description: "Value 主键ID" requestBody: content: application/json: schema: $ref: "#/components/schemas/Value" responses: 200: content: application/json: schema: $ref: "#/components/schemas/Value" """ return jsonify({}) @expose('/<value_id>', methods=["DELETE"]) def delete(self, value_id): """ --- delete: summary: "删除表格数据" description: "删除表格数据" parameters: - name: value_id in: path type: integer format: int64 description: "Value 主键ID" responses: 200: content: application/json: schema: $ref: "#/components/schemas/Value" """ return jsonify({}) @expose('/<value_id>') def duplicate(self, value_id): return jsonify({})
def __init__(self): super(ControlPanelValueApi, self).__init__() self.form_service = FormService()
def __init__(self): super().__init__() self.form_service = FormService()
class ControlPanelFieldApi(BaseApi): resource_name = 'cp/field' form_service : FormService = FormService() @expose('', methods=['POST']) def create(self): """Create a field --- post: requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Field' responses: 200: description: Create a field content: application/json: schema: $ref: '#/components/schemas/Field' """ field = self.form_service.add_new_field(request.json) return jsonify(field.asdict()), 201 @expose('<field_id>', methods=['PUT']) def update(self, field_id): changed = self.form_service.change_field(field_id, request.json) return jsonify(changed.asdict()) @expose('<field_id>', methods=['DELETE']) def delete(self, field_id): field = self.form_service.remove_field(field_id) return jsonify(field.asdict()) @expose('<field_id>') def get(self, field_id): """Get a form --- get: responses: 200: description: Get a form content: application/json: schema: $ref: '#/components/schemas/Field' """ field = self.form_service.fetch_field(field_id) return jsonify(field.asdict()) @expose('/list_by_form_id/<from_id>', methods=['GET']) def get_list(self, form_id): """ 表单数据查询接口,包括排序 :param form_id: :return: """ fields = self.form_service.fetch_fields(form_id, PageRequest.create(request.args)) return jsonify(fields.asdict()) @expose('/add_by_form_id/<from_id>', methods=['POST']) def add_by_form_id(self, form_id): """ 插入提条数据到表单 :param form_id: :return: """ field = request.json.copy() field["form_id"] = form_id form = self.form_service.add_new_field(field) return jsonify(form.asdict()), 200
class ControlPanelFormApi(BaseApi): resource_name = 'cp/form' form_service = FormService() def __init__(self): super().__init__() self.event_repository = EventRepository(db) self.value_repository = ValueRepository(db) self.form_repository = FormRepository(db) @jwt_required @expose('', methods=['POST']) def create(self): """Create a form --- post: requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Form' responses: 200: description: Create a form content: application/json: schema: $ref: '#/components/schemas/Form' """ form = request.json.copy() form["user_id"] = current_user.id form = self.form_service.add_new_form(form) return jsonify(form.asdict()), 201 @expose('/{id}', methods=['PUT']) def update(self): """Create a form --- put: requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Form' responses: 200: description: Create a form content: application/json: schema: $ref: '#/components/schemas/Form' """ return self.response(200, **{}) @expose('/{id}/publish', methods=['DELETE']) def publish(self): """Publish a form --- delete: responses: 200: description: Publish a form content: application/json: schema: $ref: '#/components/schemas/Form' """ return self.response(200, **{}) @expose('/{id}/publish', methods=['DELETE']) def unpublish(self): """Delete a form --- delete: responses: 200: description: Delete a form content: application/json: schema: type: object properties: message: type: string """ return self.response(200, **{}) @jwt_required @expose('/', methods=['GET']) def get_list(self): """Get form list --- get: responses: 200: description: Get form list content: application/json: schema: type: object properties: message: type: string """ forms = self.form_service.fetch_forms(current_user.id, PageRequest.create(request.args)) return jsonify(forms.asdict()) @expose('/{id}', methods=['GET']) def get_detail(self): """Get a form --- get: responses: 200: description: Get a form content: application/json: schema: type: object properties: message: type: string """ return self.response(200, **{}) @jwt_required @expose("/<form_id>/summary", methods=["GET"]) def summary(self, form_id): user = current_user submit_count_by_days = self.value_repository.count_by_8_days( user.id, form_id) form = self.form_repository.find_one(form_id) return jsonify({ "submit_count": self.value_repository.count_all(user.id, form_id), "submit_count_today": self.value_repository.count_today(user.id, form_id), "reads_today": self.event_repository.count_today(form_id, EventType.VIEW_FORM), "submit_count_by_days": submit_count_by_days, "read_count_by_days": self.event_repository.count_by_8_days(form_id, EventType.VIEW_FORM), "submit_count_by_mintes": self.value_repository.count_by_24_minute(user.id, form_id), "form": form.asdict(), }) @jwt_required @expose("/<form_id>/export", methods=["GET"]) def export(self, form_id): # TODO: 根据 Request Content Type 来导出返回的内容,例如JSON form_id = int(form_id) count = self.value_repository.count(form_id) form = self.form_repository.find_one(form_id) db.session.commit() fields_map = {} for field in form.fields: fields_map[int(field.id)] = field def to_export(row): ex = {} for field_id, value in row['values'].items(): field = fields_map[int(field_id)] ex[field.title] = field.to_text_value(value) ex['id'] = row['sequence'] ex['created_at'] = row['created_at'] ex['updated_at'] = row['updated_at'] return ex def generate(): args = [int(form_id), PageRequest.create(request.args)] i = 0 position = 0 while i < count: args[1].page = i + 1 values = self.value_repository.find(*args) if i == 0: iostream = io.StringIO() first = to_export(values[0].asdict()) keys = first.keys() csv_writer = csv.DictWriter(iostream, fieldnames=keys) csv_writer.writeheader() for value in values: csv_writer.writerow(to_export(value.asdict())) iostream.seek(position) for line in iostream.readline(): print(line) yield line position = iostream.tell() i += 1 response = Response(stream_with_context(generate())) response.headers["Content-Type"] = "text/csv" return response
class ControlPanelFormApi(BaseApi): resource_name = 'cp/form' form_service = FormService() def __init__(self): super().__init__() self.event_repository = EventRepository(db) self.value_repository = ValueRepository(db) self.form_repository = FormRepository(db) self.logger = logging.getLogger('ControlPanelFormApi') @jwt_required @expose('', methods=['POST']) def create(self): """Create a form --- post: summary: 创建表单 description: 创建表单 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FormCreation' responses: 200: description: Create a form content: application/json: schema: $ref: '#/components/schemas/Form' """ form = request.json.copy() form["user_id"] = current_user.id form = self.form_service.add_new_form(form) return jsonify( form.asdict(follow={ 'fields': { "follow": { "options": {}, "constraints": {}, } } })), 201 @jwt_required @expose('/<int:form_id>', methods=['PUT']) def update(self, form_id: int): """Create a form --- put: summary: 更新表单 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FormEdition' responses: 200: description: Create a form content: application/json: schema: $ref: '#/components/schemas/Form' """ form_guard(int(form_id), ['Manager']) form_dto = request.json.copy() form_dto['id'] = int(form_id) form = self.form_service.change_form(form_id, form_dto) return jsonify( form.asdict(follow={ 'fields': { "follow": { "options": {}, "constraints": {}, } } })) @expose('/{id}/publish', methods=['POST']) def publish(self): """Publish a form --- post: summary: 发布表单 responses: 200: content: application/json: schema: $ref: '#/components/schemas/Form' """ return self.response(200, **{}) @expose('/{id}/publish', methods=['DELETE']) def unpublish(self): """Delete a form --- delete: summary: 取消表单发布 responses: 200: description: Delete a form content: application/json: schema: type: object properties: message: type: string """ return self.response(200, **{}) @jwt_required @expose('/', methods=['GET']) def get_list(self): """Get form list --- get: summary: 查询表单列表 responses: 200: content: application/json: schema: type: array items: $ref: "#/components/schemas/Form" """ forms = self.form_service.fetch_forms(current_user.id, PageRequest.create(request.args)) return jsonify(forms.asdict()) @jwt_required @expose('/<int:form_id>', methods=['GET']) def get_detail(self, form_id: int): """Get a form --- get: responses: 200: description: Get a form content: application/json: schema: $ref: "#/components/schemas/Form" """ form_guard(form_id, ['Viewer', 'Editor', 'Manager']) form = self.form_service.fetch_form(form_id, current_user) return jsonify( form.asdict(follow={ 'fields': { "follow": { "options": {}, "constraints": {}, } } })) @jwt_required @expose("/<int:form_id>/summary", methods=["GET"]) def summary(self, form_id: int): form_guard(form_id, ['Viewer', 'Editor', 'Manager']) user = current_user submit_count_by_days = self.value_repository.count_by_8_days( user.id, form_id) form = self.form_repository.find_one(form_id) return jsonify({ "submit_count": self.value_repository.count_all(user.id, form_id), "submit_count_today": self.value_repository.count_today(user.id, form_id), "reads_today": self.event_repository.count_today(form_id, EventType.VIEW_FORM), "submit_count_by_days": submit_count_by_days, "read_count_by_days": self.event_repository.count_by_8_days(form_id, EventType.VIEW_FORM), "submit_count_by_mintes": self.value_repository.count_by_24_minute(user.id, form_id), "form": form.asdict(), }) @jwt_required @expose('/<int:form_id>/value', methods=['GET']) def value(self, form_id: int): form_guard(form_id, ['Viewer', 'Editor', 'Manager']) page_request = PageRequest.create(request.args) page_request.order("created_at", "desc") value = self.form_service.fetch_values(form_id, page_request) return jsonify(value.asdict()) @jwt_required @expose("/<form_id>/export", methods=["GET"]) def export(self, form_id): """ --- get: description: "导出CSV文件" responses: 200: content: application/json: schema: $ref: "#/components/schemas/Form" """ # TODO: 根据 Request Content Type 来导出返回的内容,例如JSON form_id = int(form_id) count = self.value_repository.count(form_id) form = self.form_repository.find_one(form_id) db.session.commit() fields_map = {} for field in form.fields: fields_map[int(field.id)] = field def to_export(row): ex = {} for field_id, value in row['values'].items(): field = fields_map[int(field_id)] ex[field.title] = field.to_text_value(value) ex['id'] = row['sequence'] ex['created_at'] = row['created_at'] ex['updated_at'] = row['updated_at'] return ex def generate(): paginator = PageRequest.create(request.args) args = [int(form_id), paginator] i = 0 position = 0 while i < paginator.page_size: print(i) args[1].page = i + 1 values = self.value_repository.find(*args) if i == 0: iostream = io.StringIO() first = to_export(values[0].asdict()) keys = first.keys() csv_writer = csv.DictWriter(iostream, fieldnames=keys) csv_writer.writeheader() for value in values: csv_writer.writerow(to_export(value.asdict())) iostream.seek(position) for line in iostream.readline(): yield line position = iostream.tell() i += 1 response = Response(stream_with_context(generate())) response.headers["Content-Type"] = "text/csv" return response