使用 python docx 时 Python Flask GAE 中出现管道损坏错误
我有一个 Flask 应用程序,它使用 Python-docx 来自动化公司中的某些文档。我的 Flask 应用程序部署在 Google App Engine 标准环境中。 我经常遇到这个错误: Broken Pipe
我搜索到的大多数找到此问题解决方案的文章都使用
signal(SIGPIPE,SIG_DFL)
,但使用此解决方案时,我仍然收到 Broken Pipe 错误。
需要一些帮助,请
编辑: 我是编码新手,所以请放轻松 基本上我想做的是为公司中的每个人注册一个数字签名。此一次性签名会生成一个 6 位数的令牌,在想要签署文档时将使用该令牌。当用户注册签名时,除了收到带有令牌的电子邮件外,他们还会收到一个 pdf 附件,该附件是他们必须打印并签名以授权其数字签名的文档。
@app.route('/registro_firma_digital', methods=['GET','POST'])
def registro_firma_digital():
signal(SIGPIPE,SIG_DFL)
unix_socket = '/cloudsql/{}'.format(db_connection_name)
cnx = pymysql.connect(user=db_user, password=db_password,
unix_socket=unix_socket, db=db_name)
mycursor = cnx.cursor()
unix_socket2 = '/cloudsql/{}'.format(db_connection_name)
cnx2 = pymysql.connect(user=db_user, password=db_password,
unix_socket=unix_socket2, db="sedial")
mycursor2 = cnx2.cursor()
try:
signal(SIGPIPE,SIG_DFL)
if 'user' in session:
dateTimeObjr = datetime.date.today()
dateTimeObj = dateTimeObjr.strftime('%Y-%m-%d')
if request.method == "POST":
#get datestamp
data = request.form['dataurl']
cc = str(request.form['cedula']).strip()
nombre = request.form['name']
email = str(request.form['email']).strip()
mycursor2.execute(<sql sentence>)
cc_presente = mycursor2.fetchone()
if not cc_presente:
return render_template('cc_no_presente.html', cedula=cc)
user = session['user']
#allow only one registration per id
#generate random string for our token
S = 6 # number of characters in the string.
llave = ''.join(random.choices(string.digits, k=S))
l = 10 # number of characters in the string.
tiquete = ''.join(random.choices(string.digits, k=l))
#the token is sent to the user in its orignal format, but for security reasons we convert the token to hash for our database
h = hashlib.md5(llave.encode())
hash_token = h.hexdigest()
preg1 = request.form['preg1']
h_preg1 = hashlib.md5(preg1.encode())
hash_token_preg1 = h_preg1.hexdigest()
preg2 = request.form['preg2']
h_preg2 = hashlib.md5(preg2.encode())
hash_token_preg2 = h_preg2.hexdigest()
preg3 = request.form['preg3']
h_preg3 = hashlib.md5(preg3.encode())
hash_token_preg3 = h_preg3.hexdigest()
preg4 = request.form['preg4']
h_preg4 = hashlib.md5(preg4.encode())
hash_token_preg4 = h_preg4.hexdigest()
#validate the the hash token doesnt already exist, if it does it generates another. (not likely to happen)
mycursor.execute(
"select * from banco_firmas_digitales where llave = '"+str(hash_token)+"'")
key_present = mycursor.fetchone()
if key_present:
l = S + 1
llave = ''.join(random.choices(string.digits, k=l))
h = hashlib.md5(llave.encode())
hash_token = h.hexdigest()
mycursor.execute(<sql sentence>)
key_present = mycursor.fetchone()
if key_present:
m = l + 1
tiquete = ''.join(random.choices(string.digits, k=m))
mycursor.execute(<sql sentence>)
bucket = storage_client.get_bucket('<bucketname>')
blob = bucket.blob("<blob").download_as_string()
doc_obj = Document(io.BytesIO(blob))
img_blob = str(data)
encoded = re.sub("b'", "", img_blob)
encoded = re.sub("'", "", encoded)
image_64_decode = base64.b64decode(encoded)
image_result = open('/tmp/pic.png', 'wb') # create a writable image and write the decoding result
image_result.write(image_64_decode)
tables = doc_obj.tables
p = tables[0].rows[1].cells[0].paragraphs[0]
r = p.add_run()
r.add_picture('/tmp/pic.png',width=Inches(3.74), height=Inches(1.96))
p.alignment = 1
filename = "firma_digital_hv.docx"
doc_obj.save("/tmp/"+filename)
pathe = "/tmp"
filename_path = pathe+"/"+filename
file_metadata = {'name': filename_path,
'mimeType': 'application/vnd.google-apps.document'}
media = MediaFileUpload(filename_path,
mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
file = drive.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
print('File ID: %s' % file.get('id'))
fileid = file.get('id')
request_ = drive.files().export_media(fileId=fileid,
mimeType='application/pdf')
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fd=fh, request=request_)
done = False
while done is False:
status, done = downloader.next_chunk()
fh.seek(0)
file_name = '/tmp/'+fileid+'.pdf'
with open(file_name, 'wb') as fx:
fx.write(fh.read())
cnx.commit()
from_addr = "<fromemail>"
password = "<password>"
to_addr = email
subject = "Detalle Registro Firmal Digital"
content = ""
text = """\
Hi,
How are you?
Real Python has many great tutorials:
www.realpython.com
"""
html = """\
<!DOCTYPE html>
<html>
<head>
<title>Registro Firma Digital</title>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css"
integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<style>
html,
body {
min-height: 100%;
background-color: black;
}
body,
div,
form,
select,
textarea,
label {
padding: 0;
margin: 0;
outline: none;
font-family: Roboto, Arial, sans-serif;
font-size: 14px;
color: white;
line-height: 22px;
}
input {
padding: 0;
margin: 0;
outline: none;
font-family: Roboto, Arial, sans-serif;
font-size: 14px;
color: black;
line-height: 22px;
}
legend {
padding: 10px;
font-family: Roboto, Arial, sans-serif;
font-size: 18px;
color: rgb(0, 68, 255);
box-shadow: 0 0 8px rgb(0, 68, 255);
}
textarea {
width: calc(100% - 12px);
padding: 5px;
}
.testbox {
display: flex;
justify-content: center;
align-items: center;
height: inherit;
padding: 20px;
}
form {
width: 100%;
padding: 20px;
border-radius: 6px;
background: #000;
box-shadow: 0 0 8px rgb(0, 68, 255);
}
input,
select,
textarea {
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
input {
width: calc(100% - 10px);
padding: 5px;
}
input[type="date"] {
padding: 4px 5px;
}
textarea {
width: calc(100% - 12px);
padding: 5px;
}
.item:hover p,
.item:hover i,
.question:hover p,
.question label:hover,
input:hover::placeholder {
color: rgb(0, 68, 255);
}
.item input:hover,
.item select:hover,
.item textarea:hover {
border: 1px solid transparent;
box-shadow: 0 0 3px 0 rgb(0, 68, 255);
color: rgb(0, 68, 255);
}
.item {
position: relative;
margin: 10px 0;
}
.item span {
color: red;
}
input[type="date"]::-webkit-inner-spin-button {
display: none;
}
.item i,
input[type="date"]::-webkit-calendar-picker-indicator {
position: absolute;
font-size: 20px;
color: black;
}
.item i {
right: 1%;
top: 30px;
z-index: 1;
}
.week {
display: flex;
justify-content: space-between;
}
.columns {
display: flex;
justify-content: space-between;
flex-direction: row;
flex-wrap: wrap;
}
.columns div {
width: 228%;
}
[type="date"]::-webkit-calendar-picker-indicator {
right: 1%;
z-index: 2;
opacity: 0;
cursor: pointer;
}
input[type=radio],
input[type=checkbox] {
display: none;
}
label.radio {
position: relative;
display: inline-block;
margin: 5px 20px 15px 0;
cursor: pointer;
}
.question span {
margin-left: 30px;
}
.question-answer label {
display: block;
}
label.radio:before {
content: "";
position: absolute;
left: 0;
width: 17px;
height: 17px;
border-radius: 50%;
border: 2px solid #ccc;
}
input[type=radio]:checked+label:before,
label.radio:hover:before {
border: 2px solid rgb(0, 68, 255);
}
label.radio:after {
content: "";
position: absolute;
top: 6px;
left: 5px;
width: 8px;
height: 4px;
border: 3px solid #006622;
border-top: none;
border-right: none;
transform: rotate(-45deg);
opacity: 0;
}
input[type=radio]:checked+label:after {
opacity: 1;
}
.flax {
display: flex;
justify-content: space-around;
}
.btn-block {
margin-top: 10px;
text-align: center;
}
@media (min-width: 568px) {
.name-item,
.city-item {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.name-item input,
.name-item div {
width: calc(50% - 20px);
}
.name-item div input {
width: 97%;
}
.name-item div label {
display: block;
padding-bottom: 5px;
}
}
</style>
</head>
<body>
<div class="testbox">
<form align="center">
<div class="banner">
<aside> <img class="demo" src="https://i.ibb.co/ws5rF2w/SEDIAL.png" width="200" height="80"></aside>
</div>
<br />
<fieldset>
<legend>Detalle</legend>
<div align="center">
<div class="form-group">
<label class="item"><strong>Token Firma Digital: </strong>"""+str(llave)+"""</label>
<p>----------------------------------------------------</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 1:</strong></label>
<p>Descargar e imprimir el formato adjunto al correo</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 2:</strong></label>
<p>Llenar los campos requeridos del documento (Firma del testigo es quien te acompaño durante el registro)</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 3:</strong></label>
<p>Escanear el documento</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 4:</strong></label>
<p>Copiar la siguiente llave para el cargue del archivo: """+str(tiquete)+"""</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 5:</strong></label>
<p>Ingresar al siguiente <a href="https://vernal-acrobat-301119.uc.r.appspot.com/carga_procedimiento_firmadigital_firmado">link</a> para subir el archivo escaneado</p>
</div>
<p>--------------------------------------------------------------------------------------</p>
<p><strong>*DECIMOSEXTA: FIRMA DIGITAL.-*</strong></p>
<p>Para toda la documentación interna de la empresa, se utilizará una firma digital, la cual tendrá la misma validez que la firma caligráfica para todos los efectos internos y legales, incluyendo pero no limitándose a:</p>
<p><strong>1. </strong>Recibo de documentación.</p>
<p><strong>2. </strong>Firma de Otrosí al contrato laboral.</p>
<p><strong>3. </strong>Firma de recibido de evaluaciones de desempeño.</p>
<p><strong>4. </strong>Firma de procesos disciplinarios.</p>
<p></p>
<p>El empleado con la firma del presente documento declara que entiende y reconoce lo siguiente:</p>
<p><strong>1. </strong>La firma digital podrá ser utilizada únicamente con el token que le será entregado por parte de la empresa mediante correo electrónico dirigido a la dirección que el empleado registre en los formularios FR-GH-002 “Ficha Básica” y FR-SF-012 “Actualización de Datos”.</p>
<p><strong>2. </strong>El uso del token es personal e intransferible.</p>
<p><strong>3. </strong>El empleado es el único responsable de la custodia y cuidado del token.</p>
<p><strong>4. </strong>En virtud de lo anterior cualquier documento que esté firmado en el sistema Dashboard Sedial, se entiende firmado por el empleado.</p>
</div>
</fieldset>
<div class="btn-block">
</div>
</form>
</div>
</body>
</html>
"""
msg = MIMEMultipart("alternative", None, [MIMEText(text), MIMEText(html,'html')])
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
msg.attach(part1)
msg.attach(part2)
msg['From'] = from_addr
#msg['To'] = ", ".join(to_addr)
msg['To'] = to_addr
msg['Subject'] = subject
file_name_final = 'FR-GH-084_REGISTRO_FIRMA_DIGITAL_'+str(cc)+'_'+str(dateTimeObj)+'.pdf'
with open(file_name, 'rb') as f:
attachment = MIMEApplication(f.read(), Name=file_name_final)
attachment['Content-Disposition'] = 'attachment; file_name="{}"'.format(file_name_final)
msg.attach(attachment)
context = ssl.create_default_context()
server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context)
server.login(from_addr,password)
server.send_message(msg, from_addr, to_addr)
time.sleep(1)
gcs = storage.Client()
bucket = gcs.get_bucket("<buckename>")
old_file = os.path.join(pathe, fileid+".pdf")
newfilename = 'FR-GH-084_REGISTRO_FIRMA_DIGITAL_'+str(cc)+'_'+str(dateTimeObj)+'.pdf'
new_file = os.path.join(pathe, newfilename)
os.rename(old_file, new_file)
blob = bucket.blob("firmas_digitales/"+str(cc)+"/"+newfilename)
blob.upload_from_filename(
os.path.join(pathe, newfilename)
)
mycursor.execute(<sql sentence>)
cnx.commit()
#execute deleteemail function to avoid me have access to raw token
deletesubject = "Detalle Registro Firmal Digital"
deleteemail(deletesubject)
return redirect(url_for('registro_firma_digital'))
return render_template('registro_firma_digital.html')
else:
return redirect(url_for('login'))
except Exception as e:
if 'Duplicate entry' in str(e):
return render_template('cc_firma_presente.html', cc=cc)
else:
return str(e)
finally:
cnx.close()
cnx2.close()
I have a flask app that uses Python-docx to automate certain documents in my company. I have my flask app deployed in Google App Engine Standard Environment.
Ive been getting this error a lot:
Broken Pipe
Most articles I searched that found a solution to this use the
signal(SIGPIPE,SIG_DFL)
, but using this solution, I am still getting the Broken Pipe Error.
Could use some help please
EDIT:
I am new at coding so please go easy on me
basically what I am trying to do is register a digital signature for everyone in the company. This one time signature generates a 6 digit token that will be used when wanting to sign a document. When the user registers their signature, apart from getting an email with the token, they also get a pdf attachment which is a document they have to print and sign to authorize their digital signature.
@app.route('/registro_firma_digital', methods=['GET','POST'])
def registro_firma_digital():
signal(SIGPIPE,SIG_DFL)
unix_socket = '/cloudsql/{}'.format(db_connection_name)
cnx = pymysql.connect(user=db_user, password=db_password,
unix_socket=unix_socket, db=db_name)
mycursor = cnx.cursor()
unix_socket2 = '/cloudsql/{}'.format(db_connection_name)
cnx2 = pymysql.connect(user=db_user, password=db_password,
unix_socket=unix_socket2, db="sedial")
mycursor2 = cnx2.cursor()
try:
signal(SIGPIPE,SIG_DFL)
if 'user' in session:
dateTimeObjr = datetime.date.today()
dateTimeObj = dateTimeObjr.strftime('%Y-%m-%d')
if request.method == "POST":
#get datestamp
data = request.form['dataurl']
cc = str(request.form['cedula']).strip()
nombre = request.form['name']
email = str(request.form['email']).strip()
mycursor2.execute(<sql sentence>)
cc_presente = mycursor2.fetchone()
if not cc_presente:
return render_template('cc_no_presente.html', cedula=cc)
user = session['user']
#allow only one registration per id
#generate random string for our token
S = 6 # number of characters in the string.
llave = ''.join(random.choices(string.digits, k=S))
l = 10 # number of characters in the string.
tiquete = ''.join(random.choices(string.digits, k=l))
#the token is sent to the user in its orignal format, but for security reasons we convert the token to hash for our database
h = hashlib.md5(llave.encode())
hash_token = h.hexdigest()
preg1 = request.form['preg1']
h_preg1 = hashlib.md5(preg1.encode())
hash_token_preg1 = h_preg1.hexdigest()
preg2 = request.form['preg2']
h_preg2 = hashlib.md5(preg2.encode())
hash_token_preg2 = h_preg2.hexdigest()
preg3 = request.form['preg3']
h_preg3 = hashlib.md5(preg3.encode())
hash_token_preg3 = h_preg3.hexdigest()
preg4 = request.form['preg4']
h_preg4 = hashlib.md5(preg4.encode())
hash_token_preg4 = h_preg4.hexdigest()
#validate the the hash token doesnt already exist, if it does it generates another. (not likely to happen)
mycursor.execute(
"select * from banco_firmas_digitales where llave = '"+str(hash_token)+"'")
key_present = mycursor.fetchone()
if key_present:
l = S + 1
llave = ''.join(random.choices(string.digits, k=l))
h = hashlib.md5(llave.encode())
hash_token = h.hexdigest()
mycursor.execute(<sql sentence>)
key_present = mycursor.fetchone()
if key_present:
m = l + 1
tiquete = ''.join(random.choices(string.digits, k=m))
mycursor.execute(<sql sentence>)
bucket = storage_client.get_bucket('<bucketname>')
blob = bucket.blob("<blob").download_as_string()
doc_obj = Document(io.BytesIO(blob))
img_blob = str(data)
encoded = re.sub("b'", "", img_blob)
encoded = re.sub("'", "", encoded)
image_64_decode = base64.b64decode(encoded)
image_result = open('/tmp/pic.png', 'wb') # create a writable image and write the decoding result
image_result.write(image_64_decode)
tables = doc_obj.tables
p = tables[0].rows[1].cells[0].paragraphs[0]
r = p.add_run()
r.add_picture('/tmp/pic.png',width=Inches(3.74), height=Inches(1.96))
p.alignment = 1
filename = "firma_digital_hv.docx"
doc_obj.save("/tmp/"+filename)
pathe = "/tmp"
filename_path = pathe+"/"+filename
file_metadata = {'name': filename_path,
'mimeType': 'application/vnd.google-apps.document'}
media = MediaFileUpload(filename_path,
mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
file = drive.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
print('File ID: %s' % file.get('id'))
fileid = file.get('id')
request_ = drive.files().export_media(fileId=fileid,
mimeType='application/pdf')
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fd=fh, request=request_)
done = False
while done is False:
status, done = downloader.next_chunk()
fh.seek(0)
file_name = '/tmp/'+fileid+'.pdf'
with open(file_name, 'wb') as fx:
fx.write(fh.read())
cnx.commit()
from_addr = "<fromemail>"
password = "<password>"
to_addr = email
subject = "Detalle Registro Firmal Digital"
content = ""
text = """\
Hi,
How are you?
Real Python has many great tutorials:
www.realpython.com
"""
html = """\
<!DOCTYPE html>
<html>
<head>
<title>Registro Firma Digital</title>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css"
integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<style>
html,
body {
min-height: 100%;
background-color: black;
}
body,
div,
form,
select,
textarea,
label {
padding: 0;
margin: 0;
outline: none;
font-family: Roboto, Arial, sans-serif;
font-size: 14px;
color: white;
line-height: 22px;
}
input {
padding: 0;
margin: 0;
outline: none;
font-family: Roboto, Arial, sans-serif;
font-size: 14px;
color: black;
line-height: 22px;
}
legend {
padding: 10px;
font-family: Roboto, Arial, sans-serif;
font-size: 18px;
color: rgb(0, 68, 255);
box-shadow: 0 0 8px rgb(0, 68, 255);
}
textarea {
width: calc(100% - 12px);
padding: 5px;
}
.testbox {
display: flex;
justify-content: center;
align-items: center;
height: inherit;
padding: 20px;
}
form {
width: 100%;
padding: 20px;
border-radius: 6px;
background: #000;
box-shadow: 0 0 8px rgb(0, 68, 255);
}
input,
select,
textarea {
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
input {
width: calc(100% - 10px);
padding: 5px;
}
input[type="date"] {
padding: 4px 5px;
}
textarea {
width: calc(100% - 12px);
padding: 5px;
}
.item:hover p,
.item:hover i,
.question:hover p,
.question label:hover,
input:hover::placeholder {
color: rgb(0, 68, 255);
}
.item input:hover,
.item select:hover,
.item textarea:hover {
border: 1px solid transparent;
box-shadow: 0 0 3px 0 rgb(0, 68, 255);
color: rgb(0, 68, 255);
}
.item {
position: relative;
margin: 10px 0;
}
.item span {
color: red;
}
input[type="date"]::-webkit-inner-spin-button {
display: none;
}
.item i,
input[type="date"]::-webkit-calendar-picker-indicator {
position: absolute;
font-size: 20px;
color: black;
}
.item i {
right: 1%;
top: 30px;
z-index: 1;
}
.week {
display: flex;
justify-content: space-between;
}
.columns {
display: flex;
justify-content: space-between;
flex-direction: row;
flex-wrap: wrap;
}
.columns div {
width: 228%;
}
[type="date"]::-webkit-calendar-picker-indicator {
right: 1%;
z-index: 2;
opacity: 0;
cursor: pointer;
}
input[type=radio],
input[type=checkbox] {
display: none;
}
label.radio {
position: relative;
display: inline-block;
margin: 5px 20px 15px 0;
cursor: pointer;
}
.question span {
margin-left: 30px;
}
.question-answer label {
display: block;
}
label.radio:before {
content: "";
position: absolute;
left: 0;
width: 17px;
height: 17px;
border-radius: 50%;
border: 2px solid #ccc;
}
input[type=radio]:checked+label:before,
label.radio:hover:before {
border: 2px solid rgb(0, 68, 255);
}
label.radio:after {
content: "";
position: absolute;
top: 6px;
left: 5px;
width: 8px;
height: 4px;
border: 3px solid #006622;
border-top: none;
border-right: none;
transform: rotate(-45deg);
opacity: 0;
}
input[type=radio]:checked+label:after {
opacity: 1;
}
.flax {
display: flex;
justify-content: space-around;
}
.btn-block {
margin-top: 10px;
text-align: center;
}
@media (min-width: 568px) {
.name-item,
.city-item {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.name-item input,
.name-item div {
width: calc(50% - 20px);
}
.name-item div input {
width: 97%;
}
.name-item div label {
display: block;
padding-bottom: 5px;
}
}
</style>
</head>
<body>
<div class="testbox">
<form align="center">
<div class="banner">
<aside> <img class="demo" src="https://i.ibb.co/ws5rF2w/SEDIAL.png" width="200" height="80"></aside>
</div>
<br />
<fieldset>
<legend>Detalle</legend>
<div align="center">
<div class="form-group">
<label class="item"><strong>Token Firma Digital: </strong>"""+str(llave)+"""</label>
<p>----------------------------------------------------</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 1:</strong></label>
<p>Descargar e imprimir el formato adjunto al correo</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 2:</strong></label>
<p>Llenar los campos requeridos del documento (Firma del testigo es quien te acompaño durante el registro)</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 3:</strong></label>
<p>Escanear el documento</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 4:</strong></label>
<p>Copiar la siguiente llave para el cargue del archivo: """+str(tiquete)+"""</p>
</div>
<div class="form-group">
<label class="item"><strong>PASO 5:</strong></label>
<p>Ingresar al siguiente <a href="https://vernal-acrobat-301119.uc.r.appspot.com/carga_procedimiento_firmadigital_firmado">link</a> para subir el archivo escaneado</p>
</div>
<p>--------------------------------------------------------------------------------------</p>
<p><strong>*DECIMOSEXTA: FIRMA DIGITAL.-*</strong></p>
<p>Para toda la documentación interna de la empresa, se utilizará una firma digital, la cual tendrá la misma validez que la firma caligráfica para todos los efectos internos y legales, incluyendo pero no limitándose a:</p>
<p><strong>1. </strong>Recibo de documentación.</p>
<p><strong>2. </strong>Firma de Otrosí al contrato laboral.</p>
<p><strong>3. </strong>Firma de recibido de evaluaciones de desempeño.</p>
<p><strong>4. </strong>Firma de procesos disciplinarios.</p>
<p></p>
<p>El empleado con la firma del presente documento declara que entiende y reconoce lo siguiente:</p>
<p><strong>1. </strong>La firma digital podrá ser utilizada únicamente con el token que le será entregado por parte de la empresa mediante correo electrónico dirigido a la dirección que el empleado registre en los formularios FR-GH-002 “Ficha Básica” y FR-SF-012 “Actualización de Datos”.</p>
<p><strong>2. </strong>El uso del token es personal e intransferible.</p>
<p><strong>3. </strong>El empleado es el único responsable de la custodia y cuidado del token.</p>
<p><strong>4. </strong>En virtud de lo anterior cualquier documento que esté firmado en el sistema Dashboard Sedial, se entiende firmado por el empleado.</p>
</div>
</fieldset>
<div class="btn-block">
</div>
</form>
</div>
</body>
</html>
"""
msg = MIMEMultipart("alternative", None, [MIMEText(text), MIMEText(html,'html')])
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
msg.attach(part1)
msg.attach(part2)
msg['From'] = from_addr
#msg['To'] = ", ".join(to_addr)
msg['To'] = to_addr
msg['Subject'] = subject
file_name_final = 'FR-GH-084_REGISTRO_FIRMA_DIGITAL_'+str(cc)+'_'+str(dateTimeObj)+'.pdf'
with open(file_name, 'rb') as f:
attachment = MIMEApplication(f.read(), Name=file_name_final)
attachment['Content-Disposition'] = 'attachment; file_name="{}"'.format(file_name_final)
msg.attach(attachment)
context = ssl.create_default_context()
server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context)
server.login(from_addr,password)
server.send_message(msg, from_addr, to_addr)
time.sleep(1)
gcs = storage.Client()
bucket = gcs.get_bucket("<buckename>")
old_file = os.path.join(pathe, fileid+".pdf")
newfilename = 'FR-GH-084_REGISTRO_FIRMA_DIGITAL_'+str(cc)+'_'+str(dateTimeObj)+'.pdf'
new_file = os.path.join(pathe, newfilename)
os.rename(old_file, new_file)
blob = bucket.blob("firmas_digitales/"+str(cc)+"/"+newfilename)
blob.upload_from_filename(
os.path.join(pathe, newfilename)
)
mycursor.execute(<sql sentence>)
cnx.commit()
#execute deleteemail function to avoid me have access to raw token
deletesubject = "Detalle Registro Firmal Digital"
deleteemail(deletesubject)
return redirect(url_for('registro_firma_digital'))
return render_template('registro_firma_digital.html')
else:
return redirect(url_for('login'))
except Exception as e:
if 'Duplicate entry' in str(e):
return render_template('cc_firma_presente.html', cc=cc)
else:
return str(e)
finally:
cnx.close()
cnx2.close()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论