Merge branch 'main' of ssh://git.polymny.net:55554/source/nenuscanner
This commit is contained in:
commit
00789c63bd
|
|
@ -1,3 +1,6 @@
|
||||||
|
# Config file
|
||||||
|
config.py
|
||||||
|
|
||||||
.device
|
.device
|
||||||
data
|
data
|
||||||
data-*
|
data-*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
# NenuScanner
|
||||||
|
|
||||||
|
|
||||||
|
## GPIO
|
||||||
|
|
||||||
|
### Cablage des LEDs existantes de la salle noire
|
||||||
|
|
||||||
|
| GPIO | ID LED salle noire |
|
||||||
|
| GPIO 17 | LED 2 |
|
||||||
|
| GPIO 18 | LED 3 |
|
||||||
|
| GPIO 27 | LED 5 |
|
||||||
|
| GPIO 23 | LED 6 |
|
||||||
|
| GPIO 23 | LED 6 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Appareil photo
|
||||||
|
|
||||||
|
|
||||||
|
### Réglages EOS 7D
|
||||||
|
|
||||||
|
Prise de photo:
|
||||||
|
```
|
||||||
|
gphoto2 --capture-image-and-download
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Format image
|
||||||
|
|
||||||
|
Télécharger RAW et JPEG
|
||||||
|
|
||||||
|
```
|
||||||
|
gphoto2 --set-config imageformat=10
|
||||||
|
#Choice: 10 RAW + Small Fine JPEG
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Liste des formats:
|
||||||
|
```
|
||||||
|
gphoto2 --get-config imageformat
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Capture target
|
||||||
|
|
||||||
|
Stock sur la mémoire interne ou SD de l'apparail
|
||||||
|
|
||||||
|
Sur la mémoire innterne, au download c'est toujours le mêm fichier (écrasement)
|
||||||
|
|
||||||
|
```
|
||||||
|
gphoto2 --get-config capturetarget 0 ↵
|
||||||
|
|
||||||
|
Label: Capture Target
|
||||||
|
Readonly: 0
|
||||||
|
Type: RADIO
|
||||||
|
Current: Memory card
|
||||||
|
Choice: 0 Internal RAM
|
||||||
|
Choice: 1 Memory card
|
||||||
|
```
|
||||||
|
En prod choix 0 : on ne conserve pas les photos sur l'appareil
|
||||||
|
Et test choix 1 : on conserve sur l'appareil
|
||||||
|
|
||||||
|
Exemple choix 1:
|
||||||
|
```
|
||||||
|
gphoto2 --set-config capturetarget=1
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# ISO
|
||||||
|
|
||||||
|
ISO 100
|
||||||
|
|
||||||
|
```
|
||||||
|
gphoto2 --set-config iso=1
|
||||||
|
```
|
||||||
|
|
||||||
|
### réglages objectif
|
||||||
|
|
||||||
|
| Ouverture | aperture | gphoto2 --set-config aperture=14 | Ouverture f/10 |
|
||||||
|
| temps de pose | shutterspeed | gphoto2 --set-config shutterspeed=35 | Vitesse 1/100 s |
|
||||||
|
| Picture Style | picturestyle | gphoto2 --set-config picturestyle=0 | Standard |
|
||||||
|
| Exposition | aeb | gphoto2 --set-config aeb=0 | 0 |
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from flask import Flask, send_from_directory, session
|
from flask import Flask, send_from_directory, session
|
||||||
import os
|
import os
|
||||||
from . import db, config, routes, utils
|
from . import db, config, routes, utils, leds
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ def inject():
|
||||||
conn = db.get()
|
conn = db.get()
|
||||||
return {
|
return {
|
||||||
'calibration': utils.get_calibration(conn),
|
'calibration': utils.get_calibration(conn),
|
||||||
'leds': config.LEDS_UUIDS,
|
'leds': leds.get().leds,
|
||||||
'CalibrationState': db.CalibrationState,
|
'CalibrationState': db.CalibrationState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import gphoto2 as gp
|
||||||
|
import shutil
|
||||||
|
from . import leds, config
|
||||||
|
|
||||||
|
|
||||||
|
class Camera:
|
||||||
|
def capture(self, output_path: str) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class RealCamera(Camera):
|
||||||
|
def __init__(self):
|
||||||
|
self.inner = gp.Camera()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.inner.init()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.inner.exit()
|
||||||
|
|
||||||
|
def capture(self, output_path: str) -> bool:
|
||||||
|
try:
|
||||||
|
file_path = self.inner.capture(gp.GP_CAPTURE_IMAGE)
|
||||||
|
preview = self.inner.file_get(file_path.folder, file_path.name[:-3] + '.JPG', gp.GP_FILE_TYPE_NORMAL)
|
||||||
|
raw = self.inner.file_get(file_path.folder, file_path.name, gp.GP_FILE_TYPE_RAW)
|
||||||
|
|
||||||
|
preview.sve(output_path + '.jpg')
|
||||||
|
raw.save(output_path + '.cr2')
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print('An error occured when capturing photo', e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class DummyCamera(Camera):
|
||||||
|
def __init__(self, leds: leds.DummyLeds):
|
||||||
|
self.leds = leds
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def capture(self, output_path: str) -> bool:
|
||||||
|
# Find which leds are turned on
|
||||||
|
found = None
|
||||||
|
all_on = False
|
||||||
|
for led in self.leds.leds:
|
||||||
|
if led.is_on:
|
||||||
|
if found is None:
|
||||||
|
found = led
|
||||||
|
else:
|
||||||
|
all_on = True
|
||||||
|
|
||||||
|
if all_on:
|
||||||
|
shutil.copyfile('data-keep/small/all_on.jpg', output_path + '.jpg')
|
||||||
|
elif found is not None:
|
||||||
|
shutil.copyfile('data-keep/small/' + str(found) + '.jpg', output_path + '.jpg')
|
||||||
|
else:
|
||||||
|
print('ALL_OFF')
|
||||||
|
shutil.copyfile('data-keep/small/all_off.jpg', output_path + '.jpg')
|
||||||
|
|
||||||
|
|
||||||
|
camera = DummyCamera(leds.get()) if config.CAMERA == "dummy" else RealCamera()
|
||||||
|
|
||||||
|
|
||||||
|
def get():
|
||||||
|
return camera
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
from os.path import join
|
||||||
|
|
||||||
|
DATA_DIR = 'data'
|
||||||
|
BACKUPS_DIR = 'data-backups'
|
||||||
|
CALIBRATION_DIR = join(DATA_DIR, 'calibrations')
|
||||||
|
OBJECT_DIR = join(DATA_DIR, 'objects')
|
||||||
|
DATABASE_PATH = join(DATA_DIR, 'db.sqlite')
|
||||||
|
|
||||||
|
AUTO_USE_LAST_CALIBRATION = True
|
||||||
|
GPIO_CHIP = 'gpiochip0'
|
||||||
|
LEDS_UUIDS = [17, 18, 22, 23, 24, 27]
|
||||||
|
CAMERA = 'real'
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
from os.path import join
|
||||||
|
|
||||||
|
DATA_DIR = 'data'
|
||||||
|
BACKUPS_DIR = 'data-backups'
|
||||||
|
CALIBRATION_DIR = join(DATA_DIR, 'calibrations')
|
||||||
|
OBJECT_DIR = join(DATA_DIR, 'objects')
|
||||||
|
DATABASE_PATH = join(DATA_DIR, 'db.sqlite')
|
||||||
|
|
||||||
|
AUTO_USE_LAST_CALIBRATION = False
|
||||||
|
GPIO_CHIP = None
|
||||||
|
LEDS_UUIDS = [17, 18, 22, 23, 24, 27]
|
||||||
|
CAMERA = 'dummy'
|
||||||
24
config.py
24
config.py
|
|
@ -1,24 +0,0 @@
|
||||||
from os.path import join
|
|
||||||
|
|
||||||
DATA_DIR = 'data'
|
|
||||||
BACKUPS_DIR = 'data-backups'
|
|
||||||
CALIBRATION_DIR = join(DATA_DIR, 'calibrations')
|
|
||||||
OBJECT_DIR = join(DATA_DIR, 'objects')
|
|
||||||
DATABASE_PATH = join(DATA_DIR, 'db.sqlite')
|
|
||||||
|
|
||||||
AUTO_USE_LAST_CALIBRATION = False
|
|
||||||
|
|
||||||
LEDS_UUIDS = [
|
|
||||||
'ac59350e-3787-46d2-88fa-743c1d34fe86',
|
|
||||||
'83ab3133-d4de-4a42-99a7-8f8a3f3732ba',
|
|
||||||
'577d6e72-f518-4d65-af28-f8faf1ca3f5d',
|
|
||||||
'ec49a20c-bddd-4614-b828-fa45e01bfb19',
|
|
||||||
'5c249cce-d2b6-4b56-96c8-5caa43d8f040',
|
|
||||||
'22d783fb-ae55-4581-a3c6-e010d9d5e9de',
|
|
||||||
'12cb6a32-04a6-433b-8146-b753b8f1286d',
|
|
||||||
'461255a3-259a-4291-adc3-2fb736231a04',
|
|
||||||
'3896662f-9826-4445-ad70-86c2e6c143e7',
|
|
||||||
'f87698ec-3cba-42fe-9a61-5ac9f77d767a',
|
|
||||||
'4c77a655-4b68-4557-a696-29345c6676a1',
|
|
||||||
'b1cfe287-aa3b-445e-bcdc-75ae375efe43',
|
|
||||||
]
|
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
import gpiod
|
||||||
|
|
||||||
|
from . import config
|
||||||
|
|
||||||
|
|
||||||
|
class Leds:
|
||||||
|
def __enter__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GpioLed:
|
||||||
|
def __init__(self, gpio_pin: int):
|
||||||
|
self.gpio_pin = gpio_pin
|
||||||
|
self.led = None
|
||||||
|
|
||||||
|
def enter(self, chip: gpiod.Chip):
|
||||||
|
self.led = chip.get_line(self.gpio_pin)
|
||||||
|
self.led.request(consumer=str(self), type=gpiod.LINE_REQ_DIR_OUT)
|
||||||
|
self.off()
|
||||||
|
|
||||||
|
def exit(self):
|
||||||
|
self.off()
|
||||||
|
self.led.release()
|
||||||
|
self.led = None
|
||||||
|
|
||||||
|
def on(self):
|
||||||
|
self.led.set_value(1)
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
self.led.set_value(0)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'LED{self.gpio_pin:02}'
|
||||||
|
|
||||||
|
|
||||||
|
class GpioLeds(Leds):
|
||||||
|
def __init__(self, chip: str, gpio_pins: list[int]):
|
||||||
|
self.chip = gpiod.Chip(chip)
|
||||||
|
self.leds = []
|
||||||
|
for pin in gpio_pins:
|
||||||
|
self.leds.append(GpioLed(pin))
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
for led in self.leds:
|
||||||
|
led.enter(self.chip)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
for led in self.leds:
|
||||||
|
led.exit()
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
for led in self.leds:
|
||||||
|
led.off()
|
||||||
|
|
||||||
|
def on(self):
|
||||||
|
for led in self.leds:
|
||||||
|
led.on()
|
||||||
|
|
||||||
|
|
||||||
|
class DummyLed:
|
||||||
|
def __init__(self, gpio_pin: int):
|
||||||
|
self.gpio_pin = gpio_pin
|
||||||
|
self.is_on = False
|
||||||
|
|
||||||
|
def enter(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def exit(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on(self):
|
||||||
|
self.is_on = True
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
self.is_on = False
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'LED{self.gpio_pin:02}'
|
||||||
|
|
||||||
|
|
||||||
|
class DummyLeds(Leds):
|
||||||
|
def __init__(self, gpio_pins: list[int]):
|
||||||
|
self.leds = []
|
||||||
|
for pin in gpio_pins:
|
||||||
|
self.leds.append(DummyLed(pin))
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
for led in self.leds:
|
||||||
|
led.enter()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
for led in self.leds:
|
||||||
|
led.exit()
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
for led in self.leds:
|
||||||
|
led.off()
|
||||||
|
|
||||||
|
def on(self):
|
||||||
|
for led in self.leds:
|
||||||
|
led.on()
|
||||||
|
|
||||||
|
|
||||||
|
_leds = GpioLeds(config.GPIO_CHIP, config.LEDS_UUIDS) if config.GPIO_CHIP is not None else DummyLeds(config.LEDS_UUIDS)
|
||||||
|
|
||||||
|
|
||||||
|
def get() -> Leds:
|
||||||
|
return _leds
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
Flask
|
||||||
|
pillow
|
||||||
|
gphoto2
|
||||||
|
scipy
|
||||||
|
gpiod
|
||||||
|
|
@ -26,7 +26,7 @@ def scan_existing(id: int):
|
||||||
conn = db.get()
|
conn = db.get()
|
||||||
calibrated = session.get('calibration_id', None) is not None
|
calibrated = session.get('calibration_id', None) is not None
|
||||||
acquisition = db.Acquisition.get_from_id(id, conn)
|
acquisition = db.Acquisition.get_from_id(id, conn)
|
||||||
object = acquisition.object(conn)
|
object = acquisition.object(conn) if acquisition is not None else None
|
||||||
return render_template('scan.html', object=object, acquisition=acquisition, calibrated=calibrated)
|
return render_template('scan.html', object=object, acquisition=acquisition, calibrated=calibrated)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ def run(object_id: int):
|
||||||
|
|
||||||
def generate():
|
def generate():
|
||||||
yield str(acquisition.id)
|
yield str(acquisition.id)
|
||||||
length = len(config.LEDS_UUIDS)
|
length = len(config.LEDS_UUIDS) + 2 # with all_on and all_off
|
||||||
for index, led_uuid in enumerate(scanner.scan(join(config.OBJECT_DIR, str(object.id), str(acquisition.id)))):
|
for index, led_uuid in enumerate(scanner.scan(join(config.OBJECT_DIR, str(object.id), str(acquisition.id)))):
|
||||||
yield f"{led_uuid},{(index+1)/length}\n"
|
yield f"{led_uuid},{(index+1)/length}\n"
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ def rescan(acquisition_id: int):
|
||||||
object = acquisition.object(conn)
|
object = acquisition.object(conn)
|
||||||
|
|
||||||
def generate():
|
def generate():
|
||||||
length = len(config.LEDS_UUIDS)
|
length = len(config.LEDS_UUIDS) + 2 # with all_on and all_off
|
||||||
for index, led_uuid in enumerate(scanner.scan(join(config.OBJECT_DIR, str(object.id), str(acquisition.id)))):
|
for index, led_uuid in enumerate(scanner.scan(join(config.OBJECT_DIR, str(object.id), str(acquisition.id)))):
|
||||||
yield f"{led_uuid},{(index+1)/length}\n"
|
yield f"{led_uuid},{(index+1)/length}\n"
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ def validate(acquisition_id: int):
|
||||||
acquisition = db.Acquisition.get_from_id(acquisition_id, conn)
|
acquisition = db.Acquisition.get_from_id(acquisition_id, conn)
|
||||||
|
|
||||||
if acquisition is None:
|
if acquisition is None:
|
||||||
raise f"Aucune acquisition d'id {acquisition_id}"
|
raise Exception(f"Aucune acquisition d'id {acquisition_id}")
|
||||||
|
|
||||||
object = acquisition.object(conn)
|
object = acquisition.object(conn)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ def scan():
|
||||||
|
|
||||||
def generate():
|
def generate():
|
||||||
length = len(config.LEDS_UUIDS)
|
length = len(config.LEDS_UUIDS)
|
||||||
for index, led_uuid in enumerate(scanner.scan(join(config.CALIBRATION_DIR, calibration_id))):
|
for index, led_uuid in enumerate(scanner.scan(join(config.CALIBRATION_DIR, calibration_id), False)):
|
||||||
yield f"{led_uuid},{(index+1)/length}\n"
|
yield f"{led_uuid},{(index+1)/length}\n"
|
||||||
|
|
||||||
with conn:
|
with conn:
|
||||||
|
|
@ -125,4 +125,4 @@ def use_last():
|
||||||
conn = db.get()
|
conn = db.get()
|
||||||
calib = db.Calibration.get_last(conn)
|
calib = db.Calibration.get_last(conn)
|
||||||
session['calibration_id'] = calib.id
|
session['calibration_id'] = calib.id
|
||||||
return redirect('/calibrate')
|
return redirect('/calibration/calibrate')
|
||||||
|
|
|
||||||
64
scanner.py
64
scanner.py
|
|
@ -1,47 +1,51 @@
|
||||||
import cv2
|
|
||||||
import os
|
import os
|
||||||
from os.path import join
|
from os.path import join
|
||||||
import shutil
|
|
||||||
import time
|
import time
|
||||||
from . import config
|
from . import leds, camera
|
||||||
|
|
||||||
# Delay between to captures
|
# Delay between to captures
|
||||||
DELAY = 0.5
|
DELAY = 0.5
|
||||||
|
|
||||||
|
|
||||||
def capture(output_path: str) -> bool:
|
def delay_capture(cam, output_path):
|
||||||
try:
|
|
||||||
with open('.device', 'r') as f:
|
|
||||||
device_id = int(f.read().rstrip())
|
|
||||||
except:
|
|
||||||
device_id = 0
|
|
||||||
|
|
||||||
cam = cv2.VideoCapture(device_id)
|
|
||||||
s, img = cam.read()
|
|
||||||
if s:
|
|
||||||
cv2.imwrite(output_path, img)
|
|
||||||
cam.release()
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def scan(output_dir: str):
|
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
|
||||||
for led in config.LEDS_UUIDS:
|
|
||||||
print(f'Turn on {led}')
|
|
||||||
img = join(output_dir, led + '.jpg')
|
|
||||||
|
|
||||||
# Measure the time it takes to capture
|
# Measure the time it takes to capture
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
output = cam.capture(output_path)
|
||||||
# capture(img)
|
|
||||||
# For debug purposes
|
|
||||||
shutil.copyfile(join('data-keep/small', led + '.jpg'), img)
|
|
||||||
|
|
||||||
delta = time.time() - start
|
delta = time.time() - start
|
||||||
|
|
||||||
# Wait for at least one second between each capture
|
# Wait for at least one second between each capture
|
||||||
if delta < DELAY:
|
if delta < DELAY:
|
||||||
time.sleep(DELAY - delta)
|
time.sleep(DELAY - delta)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
def scan(output_dir: str, on_and_off: bool = True):
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
with leds.get() as gpio_leds:
|
||||||
|
for count, led in enumerate(gpio_leds.leds):
|
||||||
|
with camera.get() as cam:
|
||||||
|
print(f'Turn on {led}')
|
||||||
|
img = join(output_dir, f'{led}')
|
||||||
|
|
||||||
|
led.on()
|
||||||
|
delay_capture(cam, img)
|
||||||
|
led.off()
|
||||||
|
|
||||||
print(f'Turn off {led}')
|
print(f'Turn off {led}')
|
||||||
yield led
|
yield str(led)
|
||||||
|
|
||||||
|
# capture with all leds ON OFF
|
||||||
|
if on_and_off:
|
||||||
|
with camera.get() as cam:
|
||||||
|
gpio_leds.on()
|
||||||
|
img = join(output_dir, 'all_on')
|
||||||
|
delay_capture(cam, img)
|
||||||
|
yield 'all_on'
|
||||||
|
|
||||||
|
with camera.get() as cam:
|
||||||
|
gpio_leds.off()
|
||||||
|
img = join(output_dir, 'all_off')
|
||||||
|
delay_capture(cam, img)
|
||||||
|
yield 'all_off'
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<div class="fixed-grid has-6-cols">
|
<div class="fixed-grid has-6-cols">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
{% for project in projects %}
|
{% for project in projects %}
|
||||||
<a href="#" id="project-{{ loop.index0 }}" class="cell p-2 has-text-centered has-text-white" style="border: solid; border-width: 1px; border-radius: 5px;">
|
<a href="#" id="project-{{ loop.index0 }}" class="cell p-2 has-text-centered has-text-white-dark" style="border: solid; border-width: 1px; border-radius: 5px;">
|
||||||
<div>
|
<div>
|
||||||
<strong>{{ project.name }}</strong>
|
<strong>{{ project.name }}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
<div class="fixed-grid has-6-cols mb-5">
|
<div class="fixed-grid has-6-cols mb-5">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
{% for object in project.objects %}
|
{% for object in project.objects %}
|
||||||
<a href="/object/{{ object.id }}" class="cell p-2 has-text-centered has-text-white" style="border: solid; border-width: 1px; border-radius: 5px;">
|
<a href="/object/{{ object.id }}" class="cell p-2 has-text-centered has-text-white-dark" style="border: solid; border-width: 1px; border-radius: 5px;">
|
||||||
<div>
|
<div>
|
||||||
<strong>{{ object.name }}</strong>
|
<strong>{{ object.name }}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -119,9 +119,9 @@ for (let i = 0; i < {{ projects | length }}; i++) {
|
||||||
|
|
||||||
if (same) {
|
if (same) {
|
||||||
clickedProject.classList.remove('has-text-link');
|
clickedProject.classList.remove('has-text-link');
|
||||||
clickedProject.classList.add('has-text-white');
|
clickedProject.classList.add('has-text-white-dark');
|
||||||
} else {
|
} else {
|
||||||
clickedProject.classList.remove('has-text-white');
|
clickedProject.classList.remove('has-text-white-dark');
|
||||||
clickedProject.classList.add('has-text-link');
|
clickedProject.classList.add('has-text-link');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@ for (let i = 0; i < {{ projects | length }}; i++) {
|
||||||
if (j !== i) {
|
if (j !== i) {
|
||||||
let otherProject = document.getElementById('project-' + j);
|
let otherProject = document.getElementById('project-' + j);
|
||||||
otherProject.classList.remove('has-text-link');
|
otherProject.classList.remove('has-text-link');
|
||||||
otherProject.classList.add('has-text-white');
|
otherProject.classList.add('has-text-white-dark');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<span id="delete-object" class="button is-danger">Supprimer cet objet</a>
|
<button id="delete-object" class="button is-danger">Supprimer cet objet</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@
|
||||||
<div class="has-text-centered mb-3">Voulez-vous vraiment supprimer l'objet ?</div>
|
<div class="has-text-centered mb-3">Voulez-vous vraiment supprimer l'objet ?</div>
|
||||||
<div class="field is-grouped is-grouped-centered">
|
<div class="field is-grouped is-grouped-centered">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button class="button custom-modal-close">Annuler</a>
|
<button class="button custom-modal-close">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<a href="/object/delete/{{ object.id }}" class="button is-danger">Supprimer cet objet</a>
|
<a href="/object/delete/{{ object.id }}" class="button is-danger">Supprimer cet objet</a>
|
||||||
|
|
@ -83,24 +83,26 @@
|
||||||
</section>
|
</section>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block extrajs %}{% if calibration.state < CalibrationState.IsValidated %}
|
{% block extrajs %}
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('scan').addEventListener('click', () => {
|
|
||||||
let modal = document.getElementById('calibration-modal');
|
|
||||||
modal.classList.add('is-active');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('delete-object').addEventListener('click', () => {
|
document.getElementById('delete-object').addEventListener('click', () => {
|
||||||
let modal = document.getElementById('delete-modal');
|
let modal = document.getElementById('delete-modal');
|
||||||
modal.classList.add('is-active');
|
modal.classList.add('is-active');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('use-last-calibration-button').addEventListener('click', async () => {
|
{% if calibration.state < CalibrationState.IsValidated %}
|
||||||
let resp = await fetch('/calibration/use-last');
|
document.getElementById('scan').addEventListener('click', () => {
|
||||||
await resp.text();
|
let modal = document.getElementById('calibration-modal');
|
||||||
window.location.href = '/acquisition/scan/{{ object.id }}';
|
modal.classList.add('is-active');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('use-last-calibration-button').addEventListener('click', async () => {
|
||||||
|
let resp = await fetch('/api/use-last-calibration');
|
||||||
|
await resp.text();
|
||||||
|
window.location.href = '/scan/{{ object.id }}';
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
(document.querySelectorAll('.modal-background, .modal-close, .custom-modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach((close) => {
|
(document.querySelectorAll('.modal-background, .modal-close, .custom-modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach((close) => {
|
||||||
close.addEventListener('click', () => {
|
close.addEventListener('click', () => {
|
||||||
for (let modal of document.querySelectorAll('#calibration-modal, #delete-modal')) {
|
for (let modal of document.querySelectorAll('#calibration-modal, #delete-modal')) {
|
||||||
|
|
@ -109,4 +111,4 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endif %}{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@
|
||||||
<div class="has-text-centered mb-3">Voulez-vous vraiment supprimer l'acquisition ?</div>
|
<div class="has-text-centered mb-3">Voulez-vous vraiment supprimer l'acquisition ?</div>
|
||||||
<div class="field is-grouped is-grouped-centered">
|
<div class="field is-grouped is-grouped-centered">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button class="button custom-modal-close">Annuler</a>
|
<button class="button custom-modal-close">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<a id="delete-link" {% if acquisition %} href="/acquisition/delete/{{ acquisition.id }}"{% endif %} class="button is-danger">Supprimer cette acquisition</a>
|
<a id="delete-link" {% if acquisition %} href="/acquisition/delete/{{ acquisition.id }}"{% endif %} class="button is-danger">Supprimer cette acquisition</a>
|
||||||
|
|
@ -102,6 +102,22 @@
|
||||||
cell.appendChild(img);
|
cell.appendChild(img);
|
||||||
grid.appendChild(cell);
|
grid.appendChild(cell);
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
cell = document.createElement('div');
|
||||||
|
cell.classList.add('cell');
|
||||||
|
img = document.createElement('img');
|
||||||
|
img.classList.add('is-loading');
|
||||||
|
img.src = '/data/objects/{{ object.id }}/' + acquisitionId + '/all_on.jpg?v=0';
|
||||||
|
cell.appendChild(img);
|
||||||
|
grid.appendChild(cell);
|
||||||
|
|
||||||
|
cell = document.createElement('div');
|
||||||
|
cell.classList.add('cell');
|
||||||
|
img = document.createElement('img');
|
||||||
|
img.classList.add('is-loading');
|
||||||
|
img.src = '/data/objects/{{ object.id }}/' + acquisitionId + '/all_off.jpg?v=0';
|
||||||
|
cell.appendChild(img);
|
||||||
|
grid.appendChild(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
scanButton.addEventListener('click', async () => {
|
scanButton.addEventListener('click', async () => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue