This commit is contained in:
parent
8c979d7741
commit
faa7c1d605
|
@ -18,6 +18,7 @@ from ereuse_devicehub.resources import (
|
||||||
)
|
)
|
||||||
from ereuse_devicehub.resources.device import definitions
|
from ereuse_devicehub.resources.device import definitions
|
||||||
from ereuse_devicehub.resources.documents import documents
|
from ereuse_devicehub.resources.documents import documents
|
||||||
|
from ereuse_devicehub.resources.did import did
|
||||||
from ereuse_devicehub.resources.enums import PriceSoftware
|
from ereuse_devicehub.resources.enums import PriceSoftware
|
||||||
from ereuse_devicehub.resources.licences import licences
|
from ereuse_devicehub.resources.licences import licences
|
||||||
from ereuse_devicehub.resources.metric import definitions as metric_def
|
from ereuse_devicehub.resources.metric import definitions as metric_def
|
||||||
|
@ -36,6 +37,7 @@ class DevicehubConfig(Config):
|
||||||
import_resource(lot),
|
import_resource(lot),
|
||||||
import_resource(deliverynote),
|
import_resource(deliverynote),
|
||||||
import_resource(documents),
|
import_resource(documents),
|
||||||
|
import_resource(did),
|
||||||
import_resource(tradedocument),
|
import_resource(tradedocument),
|
||||||
import_resource(inventory),
|
import_resource(inventory),
|
||||||
import_resource(versions),
|
import_resource(versions),
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
import csv
|
||||||
|
import json
|
||||||
|
import enum
|
||||||
|
import uuid
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
from collections import OrderedDict
|
||||||
|
from io import StringIO
|
||||||
|
from typing import Callable, Iterable, Tuple
|
||||||
|
|
||||||
|
import boltons
|
||||||
|
import flask
|
||||||
|
import flask_weasyprint
|
||||||
|
import teal.marshmallow
|
||||||
|
from boltons import urlutils
|
||||||
|
from flask import make_response, g, request
|
||||||
|
from flask import current_app as app
|
||||||
|
from flask.json import jsonify
|
||||||
|
from teal.cache import cache
|
||||||
|
from teal.resource import Resource, View
|
||||||
|
|
||||||
|
from ereuse_devicehub import auth
|
||||||
|
from ereuse_devicehub.db import db
|
||||||
|
from ereuse_devicehub.resources.device.models import Device
|
||||||
|
from ereuse_devicehub.resources.did.models import Dpp
|
||||||
|
|
||||||
|
|
||||||
|
class DidView(View):
|
||||||
|
"""
|
||||||
|
This view render one public ans static page for see the links for to do the check
|
||||||
|
of one csv file
|
||||||
|
"""
|
||||||
|
def get_url_path(self):
|
||||||
|
url = urlutils.URL(request.url)
|
||||||
|
url.normalize()
|
||||||
|
url.path_parts = url.path_parts[:-2] + ['check', '']
|
||||||
|
return url.to_text()
|
||||||
|
|
||||||
|
def get(self, dpp: str):
|
||||||
|
self.dpp = dpp
|
||||||
|
template = 'dpp.html'
|
||||||
|
if len(dpp.split(":")) == 2:
|
||||||
|
result = Dpp.query.filter_by(key=dpp).one()
|
||||||
|
else:
|
||||||
|
result = Device.query.filter_by(chid=dpp).one()
|
||||||
|
template = 'chid.html'
|
||||||
|
|
||||||
|
if 'json' not in request.headers['Accept']:
|
||||||
|
result = self.get_result(result, template)
|
||||||
|
return flask.render_template(template, rq_url=self.get_url_path(),
|
||||||
|
result={"dpp": dpp, "result": result})
|
||||||
|
|
||||||
|
return jsonify(self.get_result(result, template))
|
||||||
|
|
||||||
|
def get_result(self, dpp, template):
|
||||||
|
data = {
|
||||||
|
'hardware': {},
|
||||||
|
'dpp': self.dpp,
|
||||||
|
}
|
||||||
|
result = {'data': data}
|
||||||
|
|
||||||
|
if template == 'dpp.html':
|
||||||
|
data['hardware'] = json.loads(dpp.snapshot.json_hw)
|
||||||
|
last_dpp = self.get_last_dpp(dpp)
|
||||||
|
url_last = ''
|
||||||
|
if last_dpp:
|
||||||
|
url_last = 'http://did.ereuse.org/{did}'.format(did=last_dpp)
|
||||||
|
data['url_last'] = url_last
|
||||||
|
return result
|
||||||
|
|
||||||
|
# if dpp is not a dpp then is a device
|
||||||
|
device = dpp
|
||||||
|
dpps = []
|
||||||
|
for d in device.dpps:
|
||||||
|
rr = {'dpp': d.key, 'hardware': json.loads(d.snapshot.json_hw)}
|
||||||
|
dpps.append(rr)
|
||||||
|
return {'data': dpps}
|
||||||
|
|
||||||
|
def get_last_dpp(self, dpp):
|
||||||
|
dpps = [act.dpp[0] for act in dpp.device.actions if act.t == 'Snapshot' and act.dpp]
|
||||||
|
last_dpp = ''
|
||||||
|
for d in dpps:
|
||||||
|
if d.key == dpp.key:
|
||||||
|
return last_dpp
|
||||||
|
last_dpp = d.key
|
||||||
|
|
||||||
|
return last_dpp
|
||||||
|
|
||||||
|
|
||||||
|
class DidDef(Resource):
|
||||||
|
__type__ = 'Did'
|
||||||
|
SCHEMA = None
|
||||||
|
VIEW = None # We do not want to create default / documents endpoint
|
||||||
|
AUTH = False
|
||||||
|
|
||||||
|
def __init__(self, app,
|
||||||
|
import_name=__name__,
|
||||||
|
static_folder='static',
|
||||||
|
static_url_path=None,
|
||||||
|
template_folder='templates',
|
||||||
|
url_prefix=None,
|
||||||
|
subdomain=None,
|
||||||
|
url_defaults=None,
|
||||||
|
root_path=None,
|
||||||
|
cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
||||||
|
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
||||||
|
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
||||||
|
|
||||||
|
view = DidView.as_view('main', definition=self, auth=app.auth)
|
||||||
|
|
||||||
|
# if self.AUTH:
|
||||||
|
# view = app.auth.requires_auth(view)
|
||||||
|
|
||||||
|
did_view = DidView.as_view('DidView', definition=self, auth=app.auth)
|
||||||
|
self.add_url_rule('/<string:dpp>', defaults={}, view_func=did_view, methods={'GET'})
|
|
@ -0,0 +1,100 @@
|
||||||
|
from sortedcontainers import SortedSet
|
||||||
|
from sqlalchemy.util import OrderedSet
|
||||||
|
from sqlalchemy import Unicode, BigInteger, Column, Sequence, ForeignKey
|
||||||
|
from sqlalchemy.orm import backref, relationship
|
||||||
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
|
from flask import g
|
||||||
|
from teal.db import CASCADE_OWN
|
||||||
|
from ereuse_devicehub.resources.user.models import User
|
||||||
|
from ereuse_devicehub.resources.device.models import Device
|
||||||
|
from ereuse_devicehub.resources.action.models import Snapshot, ActionStatus
|
||||||
|
|
||||||
|
|
||||||
|
from ereuse_devicehub.resources.models import Thing, STR_SM_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
PROOF_ENUM = {
|
||||||
|
'Register': 'Register',
|
||||||
|
'IssueDPP': 'IssueDPP',
|
||||||
|
'proof_of_recycling': 'proof_of_recycling',
|
||||||
|
}
|
||||||
|
|
||||||
|
_sorted_proofs = {
|
||||||
|
'order_by': lambda: Proof.created,
|
||||||
|
'collection_class': SortedSet
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Proof(Thing):
|
||||||
|
id = Column(BigInteger, Sequence('device_seq'), primary_key=True)
|
||||||
|
id.comment = """The identifier of the device for this database. Used only
|
||||||
|
internally for software; users should not use this."""
|
||||||
|
documentId = Column(Unicode(STR_SM_SIZE), nullable=True)
|
||||||
|
documentId.comment = "is the hash of snapshot.json_wb"
|
||||||
|
documentSignature = Column(Unicode(STR_SM_SIZE), nullable=True)
|
||||||
|
documentSignature.comment = "is the snapshot.json_wb with the signature of the user"
|
||||||
|
timestamp = Column(BigInteger, nullable=False)
|
||||||
|
type = Column(Unicode(STR_SM_SIZE), nullable=False)
|
||||||
|
|
||||||
|
issuer_id = Column(UUID(as_uuid=True),
|
||||||
|
ForeignKey(User.id),
|
||||||
|
nullable=False,
|
||||||
|
default=lambda: g.user.id)
|
||||||
|
issuer = relationship(User,
|
||||||
|
backref=backref('issuered_proofs', lazy=True, collection_class=set),
|
||||||
|
primaryjoin=User.id == issuer_id)
|
||||||
|
issuer_id.comment = """The user that recorded this proof in the system."""
|
||||||
|
device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False)
|
||||||
|
device = relationship(Device,
|
||||||
|
backref=backref('proofs',
|
||||||
|
lazy=True,
|
||||||
|
cascade=CASCADE_OWN),
|
||||||
|
primaryjoin=Device.id == device_id)
|
||||||
|
|
||||||
|
snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=True)
|
||||||
|
snapshot = relationship(Snapshot,
|
||||||
|
backref=backref('proofs', lazy=True),
|
||||||
|
collection_class=OrderedSet,
|
||||||
|
primaryjoin=Snapshot.id == snapshot_id)
|
||||||
|
|
||||||
|
action_status_id = Column(UUID(as_uuid=True), ForeignKey(ActionStatus.id), nullable=True)
|
||||||
|
action_status = relationship(ActionStatus,
|
||||||
|
backref=backref('proofs', lazy=True),
|
||||||
|
primaryjoin=ActionStatus.id == action_status_id)
|
||||||
|
|
||||||
|
class Dpp(Thing):
|
||||||
|
"""
|
||||||
|
Digital PassPort:
|
||||||
|
It is a type of proof with some field more.
|
||||||
|
Is the official Digital Passport
|
||||||
|
|
||||||
|
"""
|
||||||
|
id = Column(BigInteger, Sequence('device_seq'), primary_key=True)
|
||||||
|
key = Column(Unicode(STR_SM_SIZE), nullable=False)
|
||||||
|
key.comment = "chid:phid, (chid it's in device and phid it's in the snapshot)"
|
||||||
|
documentId = Column(Unicode(STR_SM_SIZE), nullable=True)
|
||||||
|
documentId.comment = "is the hash of snapshot.json_wb"
|
||||||
|
documentSignature = Column(Unicode(STR_SM_SIZE), nullable=True)
|
||||||
|
documentSignature.comment = "is the snapshot.json_wb with the signature of the user"
|
||||||
|
timestamp = Column(BigInteger, nullable=False)
|
||||||
|
|
||||||
|
issuer_id = Column(UUID(as_uuid=True),
|
||||||
|
ForeignKey(User.id),
|
||||||
|
nullable=False,
|
||||||
|
default=lambda: g.user.id)
|
||||||
|
issuer = relationship(User,
|
||||||
|
backref=backref('issuered_dpp', lazy=True, collection_class=set),
|
||||||
|
primaryjoin=User.id == issuer_id)
|
||||||
|
issuer_id.comment = """The user that recorded this proof in the system."""
|
||||||
|
device_id = Column(BigInteger, ForeignKey(Device.id), nullable=False)
|
||||||
|
device = relationship(Device,
|
||||||
|
backref=backref('dpps',
|
||||||
|
lazy=True,
|
||||||
|
cascade=CASCADE_OWN),
|
||||||
|
primaryjoin=Device.id == device_id)
|
||||||
|
|
||||||
|
snapshot_id = Column(UUID(as_uuid=True), ForeignKey(Snapshot.id), nullable=False)
|
||||||
|
snapshot = relationship(Snapshot,
|
||||||
|
backref=backref('dpp', lazy=True),
|
||||||
|
collection_class=OrderedSet,
|
||||||
|
primaryjoin=Snapshot.id == snapshot_id)
|
|
@ -0,0 +1,73 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<link href="https://stackpath.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<script src="https://use.fontawesome.com/7553aecc27.js"></script>
|
||||||
|
<title>Devicehub | Stamp create and Stamp verify</title>
|
||||||
|
<style>
|
||||||
|
/*Sticky footer*/
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin-bottom: 60px; /* Margin bottom by footer height */
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 6em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default" style="background-color: gainsboro; margin: 0 !important">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a href="https://www.usody.com/" target="_blank">
|
||||||
|
<h1 align="center">Usody</h1>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="page-header col-md-6 col-md-offset-3">
|
||||||
|
This is the info for chid: {{result.dpp}}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-md-offset-3">
|
||||||
|
{% for dpp in result.result.data %}
|
||||||
|
<h5>Digital Passport</h5>
|
||||||
|
{{ dpp.dpp }}
|
||||||
|
<h5>Hardware</h5>
|
||||||
|
<ul>
|
||||||
|
<li>Device</li>
|
||||||
|
<ul>
|
||||||
|
<li>Chassis: {{ dpp.hardware.device.chassis }}</li>
|
||||||
|
<li>Manufacturer: {{ dpp.hardware.device.manufacturer }}</li>
|
||||||
|
<li>Model: {{ dpp.hardware.device.model }}</li>
|
||||||
|
<li>SerialNumber: {{ dpp.hardware.device.serialNumber }}</li>
|
||||||
|
<li>Sku: {{ dpp.hardware.device.sku }}</li>
|
||||||
|
<li>Type: {{ dpp.hardware.device.type }}</li>
|
||||||
|
<li>Version: {{ dpp.hardware.device.version }}</li>
|
||||||
|
</ul>
|
||||||
|
<li>Components</li>
|
||||||
|
<ul>
|
||||||
|
{% for component in dpp.hardware.components %}
|
||||||
|
<li>{{ component }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
<hr />
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<link href="https://stackpath.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<script src="https://use.fontawesome.com/7553aecc27.js"></script>
|
||||||
|
<title>Devicehub | Stamp create and Stamp verify</title>
|
||||||
|
<style>
|
||||||
|
/*Sticky footer*/
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin-bottom: 60px; /* Margin bottom by footer height */
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 6em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default" style="background-color: gainsboro; margin: 0 !important">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a href="https://www.usody.com/" target="_blank">
|
||||||
|
<h1 align="center">Usody</h1>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="page-header col-md-6 col-md-offset-3">
|
||||||
|
This is the info for Digital Passport: {{result.dpp}}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-md-offset-3">
|
||||||
|
<h5>Hardware</h5>
|
||||||
|
<ul>
|
||||||
|
<li>Device</li>
|
||||||
|
<ul>
|
||||||
|
<li>Chassis: {{ result.result.data.hardware.device.chassis }}</li>
|
||||||
|
<li>Manufacturer: {{ result.result.data.hardware.device.manufacturer }}</li>
|
||||||
|
<li>Model: {{ result.result.data.hardware.device.model }}</li>
|
||||||
|
<li>SerialNumber: {{ result.result.data.hardware.device.serialNumber }}</li>
|
||||||
|
<li>Sku: {{ result.result.data.hardware.device.sku }}</li>
|
||||||
|
<li>Type: {{ result.result.data.hardware.device.type }}</li>
|
||||||
|
<li>Version: {{ result.result.data.hardware.device.version }}</li>
|
||||||
|
</ul>
|
||||||
|
<li>Components</li>
|
||||||
|
<ul>
|
||||||
|
{% for component in result.result.data.hardware.components %}
|
||||||
|
<li>{{ component }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% if result.result.data.url_last %}
|
||||||
|
<h5>Last Digital passport</h5>
|
||||||
|
<a href="{{ result.result.data.url_last }}">{{ result.result.data.url_last }}</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if result.result.data.digitalPassports %}
|
||||||
|
<h5>Digital Passports</h5>
|
||||||
|
<ul>
|
||||||
|
{% for dpp in result.result.data.digitalPassports %}
|
||||||
|
<li>{{ dpp }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,26 @@
|
||||||
|
{% import 'devices/macros.html' as macros %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<link href="https://stackpath.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="{{ url_for('Document.static', filename='print.css') }}">
|
||||||
|
<title>USOdy | {{ title }}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<header class="page-header">
|
||||||
|
<h1> {{ title }}</h1>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,74 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<link href="https://stackpath.bootstrapcdn.com/bootswatch/3.3.7/flatly/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
integrity="sha384-+ENW/yibaokMnme+vBLnHMphUYxHs34h9lpdbSLuAwGkOKFRl4C34WkjazBtb7eT"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
<script src="https://use.fontawesome.com/7553aecc27.js"></script>
|
||||||
|
<title>Devicehub | Stamp create and Stamp verify</title>
|
||||||
|
<style>
|
||||||
|
/*Sticky footer*/
|
||||||
|
html {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin-bottom: 60px; /* Margin bottom by footer height */
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 6em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default" style="background-color: gainsboro; margin: 0 !important">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a href="https://www.usody.com/" target="_blank">
|
||||||
|
<h1 align="center">Usody</h1>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="page-header col-md-6 col-md-offset-3">
|
||||||
|
<div class="row">
|
||||||
|
{% if result.0 == 'Ok' %}
|
||||||
|
<div class="alert alert-info" style="background-color: #3fb618;" role="alert">
|
||||||
|
{{ result.1 }}
|
||||||
|
</div>
|
||||||
|
{% elif result.0 == 'Bad' %}
|
||||||
|
<div class="alert alert-danger" style="background-color: #ff0039" role="alert">
|
||||||
|
{{ result.1 }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<a href="http://dlt.ereuse.org/stamps/create?url={{ rq_url }}" target="_blank">Add one new check in your csv</a>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<a href="http://dlt.ereuse.org/stamps/check?url={{ rq_url }}" target="_blank">Verify a CSV file in here.</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="page-header col-md-6 col-md-offset-3">
|
||||||
|
If you want us to verify a document issued by us, upload it using the following form
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-md-offset-3">
|
||||||
|
<form enctype="multipart/form-data" action="" method="post">
|
||||||
|
<label for="name">Document: </label>
|
||||||
|
<input type="file" name="docUpload" accept="*" /><br />
|
||||||
|
<input type="submit" id="send-signup" name="signup" value="Verify" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue