dever 4 years ago
parent
commit
a76d0002f7
21 changed files with 853 additions and 0 deletions
  1. 8 0
      README.rst
  2. 10 0
      admin.py
  3. 1 0
      admin/__init__.py
  4. 5 0
      admin/main.py
  5. 1 0
      admin/page/__init__.py
  6. 2 0
      admin/page/__load__.py
  7. 164 0
      admin/page/site.py
  8. 63 0
      conf/dev.conf
  9. 63 0
      conf/env.conf
  10. 40 0
      cron.py
  11. 10 0
      front.py
  12. 25 0
      install.py
  13. 1 0
      model/__init__.py
  14. 7 0
      model/__load__.py
  15. 15 0
      opt.py
  16. 40 0
      run.py
  17. 6 0
      runtime/__init__.py
  18. 0 0
      runtime/mysql/readme.txt
  19. 7 0
      service/__init__.py
  20. 12 0
      service/__load__.py
  21. 373 0
      service/convert.py

+ 8 - 0
README.rst

@@ -0,0 +1,8 @@
+# vecan终端
+
+安装
+
+python install.py
+
+后台:python admin.py
+运行:python run.py

+ 10 - 0
admin.py

@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:admin.py
+"""
+from demeter.core import *
+
+if __name__ == "__main__":
+	Demeter.webInit('admin')

+ 1 - 0
admin/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

+ 5 - 0
admin/main.py

@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+from demeter.web import *
+import demeter.admin.page as admin_page
+import admin.page
+Web.start(application=[admin.page,admin_page])

+ 1 - 0
admin/page/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

+ 2 - 0
admin/page/__load__.py

@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+from demeter.admin.page.__load__ import *

+ 164 - 0
admin/page/site.py

@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web page
+    name:site.py 站点相关
+    author:rabin
+"""
+from .__load__ import *
+
+class site_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'站点管理'
+			,path = '/site/site'
+			,width = '600'
+			,height = '600'
+			,search = (('label-1','workdate-time-start','workdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'站点名称'))
+			,thead = (u'站点名称', u'快捷功能', u'授权信息', u'授权时间')
+			,tbody = ('name', 'func', 'app', 'time')
+			,state = True
+		)
+		menu = (
+			{'name':'转换文件列表', 'url':'/site/convert'}
+			,
+			)
+		self.list('site')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				id = str(value['id'])
+				self.data['list'][key]['time'] = Demeter.date(value['sdate']) + ' 至 ' + Demeter.date(value['edate'])
+				self.data['list'][key]['app'] = u'[appid]:' + value['appid'] + u'<br />[appsecret]:' + value['appsecret']
+				param = '?search_site_id-select-=' + id
+				self.data['list'][key]['func'] = ''
+				for i in menu:
+					self.data['list'][key]['func'] = self.data['list'][key]['func'] + '<a href="'+i['url']+''+param+'">'+i['name']+'</a>&nbsp;&nbsp;&nbsp;&nbsp;'
+		self.show('list')
+
+class site_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			path = '/site/site'
+			,label = (u'站点名称',u'站点网址',u'通知接口',u'限制页数',u'开始时间', u'结束时间')
+			,update = ('name-input-required','link-input-required','api-input-required','page-input-required','sdate-date-required','edate-date-required')
+		)
+		self.one('site')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		id = self.input('id')
+		if not id:
+			self.getAppId()
+		else:
+			info = self.service('common').one('site', id=id)
+			if not info['appid']:
+				self.getAppId()
+		self.update('site')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('site')
+	@Web.auth
+	@Web.setting
+	def getAppId(self):
+		self.data['update']['appid'] = Demeter.compressUuid(Demeter.uuid('convert'))
+		self.data['update']['appsecret'] = Demeter.hash()
+
+		model = Demeter.model('site')
+		model.appid = self.data['update']['appid']
+		model.appsecret = self.data['update']['appsecret']
+		info = model.select(type='fetchone')
+		if info:
+			self.getAppId()
+
+class convert_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'转换的文件'
+			,path = '/site/convert'
+			,width = '600'
+			,height = '600'
+			,edit = False
+			,search = (('label-1','cdate-time-start','cdate-time-end','site_id-select-','status-select-','name-input-mlike','url-input-mlike','file_id-input-'), (u'日期范围',u'开始时间',u'截止时间',u'选择站点',u'选择状态',u'源文件名',u'新文件名',u'文件ID'))
+			,thead = (u'文件id',u'所属站点', u'源文件', u'文件名', u'访问路径', u'状态', u'更新时间')
+			,tbody = ('id','site', 'file','name', 'url', 'status', 'cdate')
+			,state = True
+		)
+		self.data['common']['search_site_id-select-'] = self.service('common').list('site')
+		self.data['common']['search_status-select-'] = [{'id':1,'value':1,'name':u'待机'},{'id':2,'value':2, 'name':u'转换中'},{'id':3,'value':3,'name':u'转换完成'},{'id':4,'value':4,'name':u'转换失败'}]
+
+		self.list('convert')
+		status = {}
+		status[1] = '待机'
+		status[2] = '转换中'
+		status[3] = '转换完成'
+		status[4] = '转换失败'
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				site = self.service('common').one('site', id=value['site_id'])
+				self.data['list'][key]['site'] = site['name']
+				if value['status'] == 3:
+					self.data['list'][key]['url'] = '<a href="'+str(value['url']).replace('.html', '.pdf')+'" target="_blank">[点此访问]</a>'
+				else:
+					self.data['list'][key]['url'] = '无法访问'
+				self.data['list'][key]['status'] = status[value['status']]
+
+				if 'file_id' in value:
+					self.data['list'][key]['file'] = value['file'] + ':' + value['file_id']
+
+		self.show('list')
+
+class convert_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		status = [
+			{'id':'1', 'name': '待机'},
+		]
+		self.set(
+			path = '/site/convert'
+			,label = (u'所属站点', u'源文件路径', u'状态')
+			,update = ('site_id-select-required', 'file-input-required', 'status-select-')
+			,update_site_id = self.service('common').list('site')
+			,update_status = status
+		)
+		self.one('convert')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		model = Demeter.model('site')
+		model.id = self.data['update']['site_id']
+		site = model.select(type='fetchone')
+
+
+		info = self.service('convert').getFile(site['key'], self.data['update']['file'])
+		self.data['update']['uid'] = -1
+		self.data['update']['file_id'] = -1
+		self.data['update']['file_type'] = 2
+		self.data['update']['name'] = info['name']
+		self.data['update']['key'] = info['key']
+		self.data['update']['ext'] = info['ext']
+
+		self.data['update']['local'] = info['local']		
+		self.data['update']['path'] = info['path']
+		self.data['update']['pdf'] = info['pdf']
+		self.data['update']['html'] = info['html']
+		self.data['update']['url'] = info['url']
+
+		sid = self.update('convert')
+
+		if sid:
+			redis = Demeter.redis()
+			config = Demeter.config['redis']
+			redis.rpush(config['name'], sid)
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('convert')

+ 63 - 0
conf/dev.conf

@@ -0,0 +1,63 @@
+[base]
+;开发环境配置
+[setting]
+name				= vecan终端
+site				= http://vecan.shemic.com/
+copyright			= 2019 dever.cc v1.0.0
+
+;打印路由表
+route				= True
+
+[db]
+rdb					= mysql
+
+[mysql]
+host				= 0.0.0.0
+port				= 3309
+username			= root
+password			= 123456
+dbname				= office_convert
+prefix				= oc
+charset				= utf8
+;允许自动建表
+create				= True
+
+[redis]
+host				= 0.0.0.0
+password			= dm_redis_123
+port				= 6379
+name				= office_file
+prefix				= convert_
+
+;定义一些tornado的配置,可为空
+[tornado]
+
+;后台配置
+[admin]
+port				= 8087
+debug				= True
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 0
+;定义后台父级菜单
+menu_parent			= 站点设置:&#xe62e;
+;定义后台子级菜单
+menu_child			= 站点管理:/site/site,转换文件列表:/site/convert
+
+;cookie
+cookie_secret       = 61oETzKXQAGaYekL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=
+login_url           = /user/login
+;是否使用安全cookie
+xsrf_cookies        = True
+
+;前台配置
+[front]
+port				= 8089
+debug				= True
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 0
+;支持手机版
+mobile				= True

+ 63 - 0
conf/env.conf

@@ -0,0 +1,63 @@
+[base]
+;线上环境配置,请设置环境变量DEMETER_CONF = env
+[setting]
+name				= 文档转换系统
+site				= http://doc.dever.cc/
+copyright			= 2018 dever.cc v1.0.0
+
+;文档转换后 保存的路径 一般用于nginx使用 默认保存到runtime
+;save				= /share/files/
+
+[db]
+rdb					= mysql
+
+[mysql]
+host				= office-mysql
+port				= 3306
+username			= root
+password			= 123456
+dbname				= office_convert
+prefix				= oc
+charset				= utf8
+;允许自动建表
+create				= True
+
+[redis]
+host				= office-redis
+password			= dm_redis_123
+port				= 6379
+name				= office_file
+prefix				= convert_
+
+;定义一些tornado的配置,可为空
+[tornado]
+
+;后台配置
+[admin]
+port				= 8087
+debug				= True
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 0
+;定义后台父级菜单
+menu_parent			= 站点设置:&#xe62e;
+;定义后台子级菜单
+menu_child			= 站点管理:/site/site,转换文件列表:/site/convert
+
+;cookie
+cookie_secret		= 61oETzKXQAGaYekL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=
+login_url			= /user/login
+;是否使用安全cookie
+xsrf_cookies		= True
+
+;前台配置
+[front]
+port				= 8088
+debug				= False
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 30
+;支持手机版
+mobile				= True

+ 40 - 0
cron.py

@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import time
+from demeter.core import *
+from gevent import monkey; monkey.patch_socket()
+import gevent
+timeSleep = 15
+
+def command(file):
+	return 'python '+File.path()+'convert.py -f ' + file
+
+# 文档转换
+def convert():
+	r = Demeter.redis()
+	c = Demeter.config['redis']
+	i = 0
+	while 1:
+		file = r.lpop(c['name'])
+		if file:
+			g = command(file)
+			Shell.popen(g, True, True)
+		i = i+1
+		if i >= 10:
+			gevent.sleep(timeSleep)
+			i = 0
+
+# 清理一天前的sign
+def signature():
+	while 1:
+		service = Demeter.service('convert')
+		service.crearSignature()
+		gevent.sleep(3600)
+
+def handle():
+	gevent.joinall([
+		gevent.spawn(convert),
+		gevent.spawn(signature),
+	])
+
+handle()

+ 10 - 0
front.py

@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:front.py
+"""
+from demeter.core import *
+
+if __name__ == "__main__":
+	Demeter.webInit('front')

+ 25 - 0
install.py

@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+from demeter.core import *
+
+#CREATE DATABASE IF NOT EXISTS yourdbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
+def manage():
+	model = Demeter.model('manage_admin')
+	model.id = 1
+	info = model.select(type='fetchone')
+	if not info:
+		model.role_id = 1
+		model.username = 'admin'
+		model.mobile = '15810090845'
+		model.password = '123456'
+		model.insert()
+
+	model = Demeter.model('manage_role')
+	model.id = 1
+	info = model.select(type='fetchone')
+	if not info:
+		model.name = u'管理员'
+		model.insert()
+
+manage()
+
+Demeter.echo('install success!')

+ 1 - 0
model/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

+ 7 - 0
model/__load__.py

@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:__load__.py
+"""
+from demeter.model import *
+from demeter.core import *

+ 15 - 0
opt.py

@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:front.py
+"""
+from demeter.core import *
+
+# 测试命令行传参 python opt.py -a act
+param = {}
+param['action'] = 'a'
+param['name'] = 'n'
+param['param'] = 'p'
+Demeter.getopt(param)
+
+Demeter.echo(Demeter.option['action'])

+ 40 - 0
run.py

@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import time
+from demeter.core import *
+from gevent import monkey; monkey.patch_socket()
+import gevent
+timeSleep = 15
+
+def command(file):
+	return 'python '+File.path()+'convert.py -f ' + file
+
+# 文档转换
+def convert():
+	r = Demeter.redis()
+	c = Demeter.config['redis']
+	i = 0
+	while 1:
+		file = r.lpop(c['name'])
+		if file:
+			g = command(file)
+			Shell.popen(g, True, True)
+		i = i+1
+		if i >= 10:
+			gevent.sleep(timeSleep)
+			i = 0
+
+# 清理一天前的sign
+def signature():
+	while 1:
+		service = Demeter.service('convert')
+		service.crearSignature()
+		gevent.sleep(3600)
+
+def handle():
+	gevent.joinall([
+		gevent.spawn(convert),
+		gevent.spawn(signature),
+	])
+
+handle()

+ 6 - 0
runtime/__init__.py

@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter init
+    author:rabin
+"""

+ 0 - 0
runtime/mysql/readme.txt


+ 7 - 0
service/__init__.py

@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter init
+    author:rabin
+    实现具体的业务逻辑,前台、后台、接口都走这一套逻辑,此处可以直接生成接口
+"""

+ 12 - 0
service/__load__.py

@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter service
+    name:__load__.py
+    author:rabin
+"""
+from demeter.core import *
+from datetime import *
+import uuid
+import os
+import os.path

+ 373 - 0
service/convert.py

@@ -0,0 +1,373 @@
+# -*- coding: utf-8 -*-
+from __future__ import division
+from .__load__ import *
+
+class Convert(object):
+
+	def crearSignature(self):
+		num = Demeter.time() - 3600*24
+		model = Demeter.model('signature')
+		model.cdate.assign(num, exp='<=')
+		model.delete()
+
+	def signature(self, site_id, appid, appsecret, timestamp, nonce, file, file_id, uid, status = 1):
+		sign = Demeter.sha1(appid + '&' + appsecret + '&' + str(timestamp) + '&' + str(nonce) + '&' + file + '&' + str(file_id) + '&' + str(uid));
+
+		time = Demeter.time()
+		num = 3600*12
+		if time - int(timestamp) > num:
+			return False
+
+		# sign 只能使用一次
+		if status < 10:
+			model = Demeter.model('signature')
+			model.signature = sign
+			model.site_id = site_id
+			info = model.select(type='fetchone')
+			if info:
+				return False
+
+		param = {}
+		param['signature'] = sign
+		param['appid'] = appid
+		param['appsecret'] = appsecret
+		param['timestamp'] = timestamp
+		param['nonce'] = nonce
+		param['file'] = file
+		param['file_id'] = file_id
+		param['uid'] = uid
+
+		if status < 10:
+			model.signature = sign
+			model.site_id = site_id
+			model.insert()
+
+		return param
+
+	def update(self, site, appid, file, file_id, file_type, uid):
+
+		info = self.getFile(appid, file)
+
+		convert = Demeter.model('convert')
+		convert.site_id = site
+		convert.key = info['key']
+
+		data = convert.select(type='fetchone')
+		if not data:
+			convert.site_id = site
+			convert.uid = uid
+			convert.file_id = file_id
+			convert.file_type = file_type
+			convert.file_size = 0
+			convert.file = info['file']
+			convert.key = info['key']
+			convert.name = info['name']
+			convert.ext = info['ext']
+
+			convert.local = info['local']
+			convert.path = info['path']
+			convert.pdf = info['pdf']
+			convert.html = info['html']
+			convert.url = info['url']
+
+			id = convert.insert()
+
+			info['status'] = 1
+			info['id'] = id
+
+		else:
+			info['id'] = data['id']
+			info['status'] = data['status']
+
+		if uid:
+			self.auth(site, uid, info['id'], 1)
+
+		return info
+
+	def getAuth(self, site, uid, convert_id):
+		user = Demeter.model('user')
+		user.uid = uid
+		user.site_id = site
+		user.convert_id = convert_id
+
+		data = user.select(type='fetchone')
+
+		return data
+
+
+	def auth(self, site, uid, convert_id, status):
+		user = Demeter.model('user')
+		user.uid = uid
+		user.site_id = site
+		user.convert_id = convert_id
+
+		data = user.select(type='fetchone')
+		if not data:
+			user.site_id = site
+			user.uid = uid
+			user.convert_id = convert_id
+			user.status = status
+			user.insert()
+		elif data['status'] != status:
+			# 适用于文档转让
+			user.id = data['id']
+			update = {}
+			update['status'] = status
+			user.update(update)
+
+		return True
+
+	def get(self, site, appid, file):
+		convert = Demeter.model('convert')
+		convert.site_id = site
+		#convert.key = self.getKey(appid, file)
+		convert.key = file
+
+		data = convert.select(type='fetchone')
+
+		return data
+
+	def getKey(self, appid, file):
+		return Demeter.sha1(str(appid) + '_' + str(file))
+
+	def getFile(self, appid, file):
+		info = {}
+
+		(filepath,temp) = os.path.split(file)
+		(filename,extension) = os.path.splitext(temp)
+
+		info['file'] = file
+		info['key'] = self.getKey(appid, file)
+		info['ext'] = extension
+		info['name'] = filename
+
+		info = self.getLocalFile(appid, file, info)
+
+		return info
+
+	def getLocalFile(self, appid, file, info):
+
+		day = str(date.today())
+		day = day.split('-')
+
+		#filename =  Demeter.md5(str(uuid.uuid5(uuid.uuid1(), info['key'])))
+		filename =  info['key']
+		filepath = str(appid) + '/' + day[0] + '/' + day[1] + '/' + day[2]
+		path = ''
+
+		if 'save' in Demeter.config['setting']:
+			filepath = File.mkdirs(os.path.join(Demeter.config['setting']['save'], filepath)) + '/' + filename
+		else:
+			filepath = File.mkdirs(os.path.join(Demeter.path, 'runtime','files', filepath)) + '/' + filename
+
+		local = filepath + info['ext']
+
+		info['local'] = local
+		info['pdf'] = filepath + '/' + filename + '.pdf'
+		# 这里要增加权限控制 html不能直接访问
+		info['html'] = filepath + '/' + filename + '.html'
+		info['url'] = info['html'].replace(Demeter.path + 'runtime', '')
+		info['path'] = filepath + '/'
+
+		return info
+		if File.exists(local):
+			return info
+		else:
+			self.download(file, local);
+			return info
+
+	def download(self, file, local):
+		if 'http' in file:
+			import requests
+			r = requests.get(file, stream=True)
+			with open(local, 'wb') as up:
+				for chunk in r.iter_content(chunk_size=1024):
+					if chunk:
+						up.write(chunk)
+
+		else:
+			import shutil
+			shutil.copyfile(file, local)
+
+		if File.exists(local):
+			return True
+		return False
+
+	def command(self, info):
+		File.mkdir(info['path'])
+		convert = 'cd ' + info['path'] + ' && '
+
+		if info['ext'] != '.pdf':
+			#convert = convert + 'libreoffice  --invisible --convert-to pdf ' + info['local']
+			convert = convert + 'soffice --headless --invisible --convert-to pdf ' + info['local']
+			convert = convert + ' && '
+		else:
+			info['pdf'] = info['local']
+		convert = convert + 'pdf2htmlEX --zoom 1 --use-cropbox 0 --no-drm 1 --split-pages 1 '
+		convert = convert + '--embed-css 0  --embed-javascript 0 --embed-image 0 --embed-font 1 --process-outline 0 '
+		convert = convert + '--embed-external-font 0 --dest-dir '+info['path']+' --page-filename %d.page ' + info['pdf']
+
+		return convert
+
+
+	def total(self, path):
+		page = 0
+		for parentdir,dirname,filenames in os.walk(path):  
+			for filename in filenames:
+				if os.path.splitext(filename)[1]=='.page':
+					page = page + 1
+		return page
+
+	def handle(self, id):
+		model = Demeter.model('convert')
+		model.id = id
+		info = model.select(type='fetchone')
+
+		if not info:
+			return
+		siteModel = Demeter.model('site')
+		siteModel.id = info['site_id']
+		site = siteModel.select(type='fetchone')
+
+		status = True
+		if info['status'] == 1 or info['status'] == 4:
+			status = False
+
+		if info and status == False:
+			model.id = id
+			update = {}
+			update['status'] = 2
+			model.update(update)
+
+			if not File.exists(info['local']):
+				self.download(info['file'], info['local'])
+
+			if not File.exists(info['html']):
+			#if info:
+				handle = self.command(info)
+				Shell.popen(handle)
+				if File.exists(info['html']):
+
+					# 截屏
+					self.cut(info)
+					#self.string_switch(info['html'], "taste", "tasting")
+					# 获取有多少页
+					page = self.total(info['path'])
+					model.id = id
+					size = os.path.getsize(info['local'])
+					update = {}
+					update['file_size'] = size
+					update['page'] = page
+					update['status'] = 3
+					model.update(update)
+
+					# 通知接口 通知应用成功转换
+					info['page'] = page
+					info['file_size'] = size
+					info['convert_status'] = 1
+					self.api(info, site)
+					return
+
+			model.id = id
+			update = {}
+			update['status'] = 4
+			model.update(update)
+			# 通知接口 通知应用失败转换
+			info['page'] = 0
+			info['file_size'] = 0
+			info['convert_status'] = 2
+			self.api(info, site)
+
+	def api(self, info, site):
+		if 'file_id' in info and info['file_id']:
+			api = site['api']
+
+			appid = site['appid']
+			appsecret = site['appsecret']
+			timestamp = Demeter.time()
+			nonce = Demeter.hash()
+			file = info['key']
+			file_id = info['file_id']
+			uid = info['uid']
+
+			param = self.signature(site['id'], appid, appsecret, timestamp, nonce, file, file_id, uid)
+
+			param['url'] = 'main/view'
+			param['img'] = info['url'] + '.jpg'
+			param['page'] = info['page']
+			param['ext'] = info['ext']
+			param['file_size'] = info['file_size']
+			param['status'] = info['convert_status']
+
+			Demeter.curl(api, param, 'post')
+
+	def cut(self, info):
+		from pdf2jpg import pdf2jpg
+		from wand.image import Image
+		dest = info['html'] + '.photo'
+		result = pdf2jpg.convert_pdf2jpg(info['pdf'], dest, pages="0")
+		source = result[0]['output_jpgfiles'][0]
+		dest = info['html'] + '.jpg'
+		command = 'mv '+source+' ' + dest
+		Shell.popen(command)
+		target_width = 300
+		with Image(filename=dest) as img:
+			target_width, target_height = self.getSize(target_width, img.width, img.height)
+			img.sample(target_width, target_height)
+			img.save(filename=dest)
+
+		'''
+		from wand.image import Image
+		pdf = Image(filename=source, resolution=50)
+		jpg = pdf.convert('jpg')
+		req_image = []
+		i = 0
+		for img in jpg.sequence:
+			if i == 0:
+				img_page = Image(image=img)
+				req_image.append(img_page.make_blob('jpg'))
+			i = i+1
+
+		for img in req_image:
+			ff = open(dest, 'wb')
+			ff.write(img)
+			ff.close()
+		'''
+
+
+	def getSize(self, target_width, img_width, img_height):
+		if img_width > target_width:
+			ratio = target_width / img_width
+			target_height = int(ratio * img_height)
+		else:
+			target_width = img_width
+			target_height = img_height
+		return target_width, target_height
+
+	def string_switch(self, x,y,z,s=1):
+		with open(x, "r", encoding="utf-8") as f:
+			#readlines以列表的形式将文件读出
+			lines = f.readlines()
+	 
+		with open(x, "w", encoding="utf-8") as f_w:
+			#定义一个数字,用来记录在读取文件时在列表中的位置
+			n = 0
+			#默认选项,只替换第一次匹配到的行中的字符串
+			if s == 1:
+				for line in lines:
+					if y in line:
+						line = line.replace(y,z)
+						f_w.write(line)
+						n += 1
+						break
+					f_w.write(line)
+					n += 1
+				#将剩余的文本内容继续输出
+				for i in range(n,len(lines)):
+					f_w.write(lines[i])
+			#全局匹配替换
+			elif s == 'g':
+				for line in lines:
+					if y in line:
+						line = line.replace(y,z)
+					f_w.write(line)