use native_db::{native_db, ToKey};
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};
pub use super::v1::{
Action, AncestorLocal, Device, DevicePrettyLocation, DeviceType, Heartbeat, Herd, Layer,
MediaType, Plan, PlanInsert, PlanType, ResponseScout, ResponseScoutStatus, Session,
SessionLocal, Syncable, TagObservationType, Zone,
};
pub use super::v2::{Operator, OperatorLocal};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[native_model(id = 15, version = 5)]
#[native_db]
pub struct ConnectivityLocal {
pub id: Option<i64>,
#[primary_key]
pub id_local: Option<String>,
#[secondary_key]
pub session_id: Option<i64>,
#[secondary_key]
pub device_id: Option<i64>,
#[secondary_key]
pub ancestor_id_local: Option<String>,
pub inserted_at: Option<String>,
pub timestamp_start: String,
pub signal: f64,
pub noise: f64,
pub altitude: f64,
pub heading: f64,
pub location: Option<String>,
pub h14_index: String,
pub h13_index: String,
pub h12_index: String,
pub h11_index: String,
pub battery_percentage: Option<f32>,
pub frequency_hz: Option<f32>,
pub bandwidth_hz: Option<f32>,
pub associated_station: Option<String>,
pub mode: Option<String>,
pub battery_volts: Option<f32>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Connectivity {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
pub session_id: Option<i64>,
pub device_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inserted_at: Option<String>,
pub timestamp_start: String,
pub signal: f64,
pub noise: f64,
pub altitude: f64,
pub heading: f64,
pub location: Option<String>,
pub h14_index: String,
pub h13_index: String,
pub h12_index: String,
pub h11_index: String,
pub battery_percentage: Option<f32>,
pub frequency_hz: Option<f32>,
pub bandwidth_hz: Option<f32>,
pub associated_station: Option<String>,
pub mode: Option<String>,
pub battery_volts: Option<f32>,
}
impl Default for ConnectivityLocal {
fn default() -> Self {
Self {
id: None,
id_local: None,
session_id: None,
device_id: None,
ancestor_id_local: None,
inserted_at: None,
timestamp_start: String::new(),
signal: 0.0,
noise: 0.0,
altitude: 0.0,
heading: 0.0,
location: None,
h14_index: String::new(),
h13_index: String::new(),
h12_index: String::new(),
h11_index: String::new(),
battery_percentage: None,
frequency_hz: None,
bandwidth_hz: None,
associated_station: None,
mode: None,
battery_volts: None,
}
}
}
impl super::v1::Syncable for ConnectivityLocal {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
self.id_local.clone()
}
fn set_id_local(&mut self, id_local: String) {
self.id_local = Some(id_local);
}
}
impl super::v1::AncestorLocal for ConnectivityLocal {
fn ancestor_id_local(&self) -> Option<String> {
self.ancestor_id_local.clone()
}
fn set_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
}
impl From<ConnectivityLocal> for Connectivity {
fn from(local: ConnectivityLocal) -> Self {
Self {
id: local.id,
session_id: local.session_id,
device_id: local.device_id,
inserted_at: local.inserted_at,
timestamp_start: local.timestamp_start,
signal: local.signal,
noise: local.noise,
altitude: local.altitude,
heading: local.heading,
location: local.location,
h14_index: local.h14_index,
h13_index: local.h13_index,
h12_index: local.h12_index,
h11_index: local.h11_index,
battery_percentage: local.battery_percentage,
frequency_hz: local.frequency_hz,
bandwidth_hz: local.bandwidth_hz,
associated_station: local.associated_station,
mode: local.mode,
battery_volts: local.battery_volts,
}
}
}
impl From<Connectivity> for ConnectivityLocal {
fn from(remote: Connectivity) -> Self {
Self {
id: remote.id,
id_local: None,
session_id: remote.session_id,
device_id: remote.device_id,
ancestor_id_local: None,
inserted_at: remote.inserted_at,
timestamp_start: remote.timestamp_start,
signal: remote.signal,
noise: remote.noise,
altitude: remote.altitude,
heading: remote.heading,
location: remote.location,
h14_index: remote.h14_index,
h13_index: remote.h13_index,
h12_index: remote.h12_index,
h11_index: remote.h11_index,
battery_percentage: remote.battery_percentage,
frequency_hz: remote.frequency_hz,
bandwidth_hz: remote.bandwidth_hz,
associated_station: remote.associated_station,
mode: remote.mode,
battery_volts: remote.battery_volts,
}
}
}
impl Connectivity {
pub fn new(
session_id: Option<i64>,
device_id: Option<i64>,
timestamp_start: u64,
signal: f64,
noise: f64,
altitude: f64,
heading: f64,
location: String,
h14_index: String,
h13_index: String,
h12_index: String,
h11_index: String,
battery_percentage: Option<f32>,
frequency_hz: Option<f32>,
bandwidth_hz: Option<f32>,
associated_station: Option<String>,
mode: Option<String>,
battery_volts: Option<f32>,
) -> Self {
use chrono::{DateTime, Utc};
let timestamp_start_str = DateTime::from_timestamp(timestamp_start as i64, 0)
.unwrap_or_else(|| DateTime::<Utc>::from_timestamp(0, 0).unwrap())
.to_rfc3339();
Self {
id: None,
session_id,
device_id,
inserted_at: None,
timestamp_start: timestamp_start_str,
signal,
noise,
altitude,
heading,
location: Some(location),
h14_index,
h13_index,
h12_index,
h11_index,
battery_percentage,
frequency_hz,
bandwidth_hz,
associated_station,
mode,
battery_volts,
}
}
}
impl ConnectivityLocal {
pub fn new(
session_id: Option<i64>,
device_id: Option<i64>,
timestamp_start: u64,
signal: f64,
noise: f64,
altitude: f64,
heading: f64,
location: String,
h14_index: String,
h13_index: String,
h12_index: String,
h11_index: String,
battery_percentage: Option<f32>,
frequency_hz: Option<f32>,
bandwidth_hz: Option<f32>,
associated_station: Option<String>,
mode: Option<String>,
battery_volts: Option<f32>,
) -> Self {
use chrono::{DateTime, Utc};
let timestamp_start_str = DateTime::from_timestamp(timestamp_start as i64, 0)
.unwrap_or_else(|| DateTime::<Utc>::from_timestamp(0, 0).unwrap())
.to_rfc3339();
Self {
id: None,
id_local: None,
session_id,
device_id,
ancestor_id_local: None,
inserted_at: None,
timestamp_start: timestamp_start_str,
signal,
noise,
altitude,
heading,
location: Some(location),
h14_index,
h13_index,
h12_index,
h11_index,
battery_percentage,
frequency_hz,
bandwidth_hz,
associated_station,
mode,
battery_volts,
}
}
}
impl From<super::v4::ConnectivityLocal> for ConnectivityLocal {
fn from(v4: super::v4::ConnectivityLocal) -> Self {
Self {
id: v4.id,
id_local: v4.id_local,
session_id: v4.session_id,
device_id: v4.device_id,
ancestor_id_local: v4.ancestor_id_local,
inserted_at: v4.inserted_at,
timestamp_start: v4.timestamp_start,
signal: v4.signal,
noise: v4.noise,
altitude: v4.altitude,
heading: v4.heading,
location: v4.location,
h14_index: v4.h14_index,
h13_index: v4.h13_index,
h12_index: v4.h12_index,
h11_index: v4.h11_index,
battery_percentage: v4.battery_percentage,
frequency_hz: v4.frequency_hz,
bandwidth_hz: v4.bandwidth_hz,
associated_station: v4.associated_station,
mode: v4.mode,
battery_volts: None,
}
}
}
impl From<super::v4::Connectivity> for Connectivity {
fn from(v4: super::v4::Connectivity) -> Self {
Self {
id: v4.id,
session_id: v4.session_id,
device_id: v4.device_id,
inserted_at: v4.inserted_at,
timestamp_start: v4.timestamp_start,
signal: v4.signal,
noise: v4.noise,
altitude: v4.altitude,
heading: v4.heading,
location: v4.location,
h14_index: v4.h14_index,
h13_index: v4.h13_index,
h12_index: v4.h12_index,
h11_index: v4.h11_index,
battery_percentage: v4.battery_percentage,
frequency_hz: v4.frequency_hz,
bandwidth_hz: v4.bandwidth_hz,
associated_station: v4.associated_station,
mode: v4.mode,
battery_volts: None,
}
}
}
impl From<super::v3::ConnectivityLocal> for ConnectivityLocal {
fn from(v3: super::v3::ConnectivityLocal) -> Self {
super::v4::ConnectivityLocal::from(v3).into()
}
}
impl From<super::v3::Connectivity> for Connectivity {
fn from(v3: super::v3::Connectivity) -> Self {
super::v4::Connectivity::from(v3).into()
}
}
impl From<super::v2::ConnectivityLocal> for ConnectivityLocal {
fn from(v2: super::v2::ConnectivityLocal) -> Self {
super::v4::ConnectivityLocal::from(v2).into()
}
}
impl From<super::v2::Connectivity> for Connectivity {
fn from(v2: super::v2::Connectivity) -> Self {
super::v4::Connectivity::from(v2).into()
}
}
impl From<super::v1::ConnectivityLocal> for ConnectivityLocal {
fn from(v1: super::v1::ConnectivityLocal) -> Self {
super::v4::ConnectivityLocal::from(v1).into()
}
}
impl From<super::v1::Connectivity> for Connectivity {
fn from(v1: super::v1::Connectivity) -> Self {
super::v4::Connectivity::from(v1).into()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[native_model(id = 16, version = 3)]
#[native_db]
pub struct EventLocal {
pub id: Option<i64>,
#[primary_key]
pub id_local: Option<String>,
pub message: Option<String>,
pub media_url: Option<String>,
pub file_path: Option<String>,
pub location: Option<String>,
pub altitude: f64,
pub heading: f64,
pub media_type: super::v1::MediaType,
pub device_id: i64,
pub earthranger_url: Option<String>,
pub timestamp_observation: String,
pub is_public: bool,
#[secondary_key]
pub session_id: Option<i64>,
#[secondary_key]
pub ancestor_id_local: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Event {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
pub message: Option<String>,
pub media_url: Option<String>,
pub file_path: Option<String>,
pub location: Option<String>,
pub altitude: f64,
pub heading: f64,
pub media_type: super::v1::MediaType,
pub device_id: i64,
pub earthranger_url: Option<String>,
pub timestamp_observation: String,
pub is_public: bool,
pub session_id: Option<i64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[native_model(id = 19, version = 5)]
#[native_db]
pub struct ArtifactLocal {
pub id: Option<i64>,
#[primary_key]
pub id_local: Option<String>,
#[secondary_key]
pub ancestor_id_local: Option<String>,
pub created_at: Option<String>,
pub file_path: String,
#[secondary_key]
pub session_id: Option<i64>,
pub timestamp_observation: Option<String>,
pub modality: Option<String>,
pub device_id: i64,
pub updated_at: Option<String>,
pub timestamp_observation_end: String,
pub has_uploaded_file_to_storage: bool,
pub upload_url: Option<String>,
pub upload_url_generated_at: Option<String>,
pub file_size_bytes: Option<i64>,
pub tagged_at: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Artifact {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<String>,
pub file_path: String,
pub session_id: Option<i64>,
pub timestamp_observation: Option<String>,
pub modality: Option<String>,
pub device_id: i64,
pub updated_at: Option<String>,
pub timestamp_observation_end: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub file_size_bytes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tagged_at: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[native_model(id = 17, version = 3)]
#[native_db]
pub struct TagLocal {
pub id: Option<i64>,
#[primary_key]
pub id_local: Option<String>,
pub inserted_at: Option<String>,
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
pub conf: f64,
pub observation_type: super::v1::TagObservationType,
#[serde(rename = "class")]
pub class: String,
#[secondary_key]
pub event_id: Option<i64>,
#[secondary_key]
pub ancestor_id_local: Option<String>,
pub origin_location: Option<String>,
pub origin_pitch: Option<f64>,
pub origin_heading: Option<f64>,
pub origin_roll: Option<f64>,
pub sensor_pitch: Option<f64>,
pub sensor_yaw: Option<f64>,
pub sensor_roll: Option<f64>,
pub origin_height: Option<f64>,
pub subject_location: Option<String>,
pub subject_height: Option<f64>,
pub artifact_id: Option<i64>,
#[serde(default)]
pub detector: String,
pub timestamp_observation: Option<String>,
pub frame_index: Option<i64>,
#[serde(default)]
pub subject_id: Option<i64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Tag {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inserted_at: Option<String>,
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
pub conf: f64,
pub observation_type: super::v1::TagObservationType,
#[serde(rename = "class")]
pub class: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_pitch: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_heading: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_roll: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sensor_pitch: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sensor_yaw: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sensor_roll: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_height: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject_location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject_height: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub artifact_id: Option<i64>,
#[serde(default)]
pub detector: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp_observation: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub frame_index: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subject_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score_source: Option<String>,
}
impl Default for EventLocal {
fn default() -> Self {
Self {
id: None,
id_local: None,
message: None,
media_url: None,
file_path: None,
location: None,
altitude: 0.0,
heading: 0.0,
media_type: super::v1::MediaType::Image,
device_id: 0,
earthranger_url: None,
timestamp_observation: String::new(),
is_public: false,
session_id: None,
ancestor_id_local: None,
}
}
}
impl Default for Event {
fn default() -> Self {
Self {
id: None,
message: None,
media_url: None,
file_path: None,
location: None,
altitude: 0.0,
heading: 0.0,
media_type: super::v1::MediaType::Image,
device_id: 0,
earthranger_url: None,
timestamp_observation: String::new(),
is_public: false,
session_id: None,
}
}
}
impl super::v1::AncestorLocal for EventLocal {
fn ancestor_id_local(&self) -> Option<String> {
self.ancestor_id_local.clone()
}
fn set_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
}
impl super::v1::Syncable for EventLocal {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
self.id_local.clone()
}
fn set_id_local(&mut self, id_local: String) {
self.id_local = Some(id_local);
}
}
impl super::v1::Syncable for Event {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
None
}
fn set_id_local(&mut self, _: String) {}
}
impl From<EventLocal> for Event {
fn from(local: EventLocal) -> Self {
Self {
id: local.id,
message: local.message,
media_url: local.media_url,
file_path: local.file_path,
location: local.location,
altitude: local.altitude,
heading: local.heading,
media_type: local.media_type,
device_id: local.device_id,
earthranger_url: local.earthranger_url,
timestamp_observation: local.timestamp_observation,
is_public: local.is_public,
session_id: local.session_id,
}
}
}
impl From<Event> for EventLocal {
fn from(event: Event) -> Self {
Self {
id: event.id,
id_local: None,
message: event.message,
media_url: event.media_url,
file_path: event.file_path,
location: event.location,
altitude: event.altitude,
heading: event.heading,
media_type: event.media_type,
device_id: event.device_id,
earthranger_url: event.earthranger_url,
timestamp_observation: event.timestamp_observation,
is_public: event.is_public,
session_id: event.session_id,
ancestor_id_local: None,
}
}
}
impl From<super::v2::EventLocal> for EventLocal {
fn from(v2: super::v2::EventLocal) -> Self {
Self {
id: v2.id,
id_local: v2.id_local,
message: v2.message,
media_url: v2.media_url,
file_path: v2.file_path,
location: v2.location,
altitude: v2.altitude,
heading: v2.heading,
media_type: v2.media_type,
device_id: v2.device_id,
earthranger_url: v2.earthranger_url,
timestamp_observation: v2.timestamp_observation,
is_public: v2.is_public,
session_id: v2.session_id,
ancestor_id_local: v2.ancestor_id_local,
}
}
}
impl From<super::v2::Event> for Event {
fn from(v2: super::v2::Event) -> Self {
Self {
id: v2.id,
message: v2.message,
media_url: v2.media_url,
file_path: v2.file_path,
location: v2.location,
altitude: v2.altitude,
heading: v2.heading,
media_type: v2.media_type,
device_id: v2.device_id,
earthranger_url: v2.earthranger_url,
timestamp_observation: v2.timestamp_observation,
is_public: v2.is_public,
session_id: v2.session_id,
}
}
}
impl Event {
pub fn new(
message: Option<String>,
media_url: Option<String>,
file_path: Option<String>,
earthranger_url: Option<String>,
latitude: f64,
longitude: f64,
altitude: f64,
heading: f64,
media_type: super::v1::MediaType,
device_id: i64,
timestamp_observation: u64,
is_public: bool,
session_id: Option<i64>,
) -> Self {
use chrono::{DateTime, Utc};
let timestamp_observation_str = DateTime::from_timestamp(timestamp_observation as i64, 0)
.unwrap_or_else(|| DateTime::<Utc>::from_timestamp(0, 0).unwrap())
.to_rfc3339();
Self {
id: None,
message,
media_url,
file_path,
location: Some(Self::format_location(latitude, longitude)),
altitude,
heading,
media_type,
device_id,
earthranger_url,
timestamp_observation: timestamp_observation_str,
is_public,
session_id,
}
}
pub fn format_location(latitude: f64, longitude: f64) -> String {
format!("POINT({} {})", longitude, latitude)
}
}
impl EventLocal {
pub fn new(
message: Option<String>,
media_url: Option<String>,
file_path: Option<String>,
earthranger_url: Option<String>,
latitude: f64,
longitude: f64,
altitude: f64,
heading: f64,
media_type: super::v1::MediaType,
device_id: i64,
timestamp_observation: u64,
is_public: bool,
session_id: Option<i64>,
) -> Self {
use chrono::{DateTime, Utc};
let location = Self::format_location(latitude, longitude);
let timestamp_observation = DateTime::from_timestamp(timestamp_observation as i64, 0)
.unwrap_or_else(|| Utc::now())
.to_rfc3339();
Self {
id: None,
id_local: None,
message,
media_url,
file_path,
location: Some(location),
altitude,
heading,
media_type,
device_id,
earthranger_url,
timestamp_observation,
is_public,
session_id,
ancestor_id_local: None,
}
}
pub fn format_location(latitude: f64, longitude: f64) -> String {
format!("POINT({} {})", longitude, latitude)
}
}
impl Default for ArtifactLocal {
fn default() -> Self {
use chrono::Utc;
Self {
id: None,
id_local: None,
ancestor_id_local: None,
created_at: None,
file_path: String::new(),
session_id: None,
timestamp_observation: None,
modality: None,
device_id: 0,
updated_at: None,
timestamp_observation_end: Utc::now().to_rfc3339(),
has_uploaded_file_to_storage: false,
upload_url: None,
upload_url_generated_at: None,
file_size_bytes: None,
tagged_at: None,
}
}
}
impl super::v1::Syncable for ArtifactLocal {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
self.id_local.clone()
}
fn set_id_local(&mut self, id_local: String) {
self.id_local = Some(id_local);
}
}
impl super::v1::AncestorLocal for ArtifactLocal {
fn ancestor_id_local(&self) -> Option<String> {
self.ancestor_id_local.clone()
}
fn set_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
}
impl From<ArtifactLocal> for Artifact {
fn from(local: ArtifactLocal) -> Self {
Self {
id: local.id,
created_at: local.created_at,
file_path: local.file_path,
session_id: local.session_id,
timestamp_observation: local.timestamp_observation,
modality: local.modality,
device_id: local.device_id,
updated_at: local.updated_at,
timestamp_observation_end: local.timestamp_observation_end,
file_size_bytes: local.file_size_bytes,
tagged_at: local.tagged_at,
}
}
}
impl From<Artifact> for ArtifactLocal {
fn from(a: Artifact) -> Self {
Self {
id: a.id,
id_local: None,
ancestor_id_local: None,
created_at: a.created_at,
file_path: a.file_path,
session_id: a.session_id,
timestamp_observation: a.timestamp_observation,
modality: a.modality,
device_id: a.device_id,
updated_at: a.updated_at,
timestamp_observation_end: a.timestamp_observation_end,
has_uploaded_file_to_storage: false,
upload_url: None,
upload_url_generated_at: None,
file_size_bytes: a.file_size_bytes,
tagged_at: a.tagged_at,
}
}
}
impl From<super::v5::ArtifactLocal> for ArtifactLocal {
fn from(v5: super::v5::ArtifactLocal) -> Self {
Self {
id: v5.id,
id_local: v5.id_local,
ancestor_id_local: v5.ancestor_id_local,
created_at: v5.created_at,
file_path: v5.file_path,
session_id: v5.session_id,
timestamp_observation: v5.timestamp_observation,
modality: v5.modality,
device_id: v5.device_id,
updated_at: v5.updated_at,
timestamp_observation_end: v5.timestamp_observation_end,
has_uploaded_file_to_storage: v5.has_uploaded_file_to_storage,
upload_url: v5.upload_url,
upload_url_generated_at: v5.upload_url_generated_at,
file_size_bytes: v5.file_size_bytes,
tagged_at: v5.tagged_at,
}
}
}
impl From<super::v5::Artifact> for Artifact {
fn from(v5: super::v5::Artifact) -> Self {
Self {
id: v5.id,
created_at: v5.created_at,
file_path: v5.file_path,
session_id: v5.session_id,
timestamp_observation: v5.timestamp_observation,
modality: v5.modality,
device_id: v5.device_id,
updated_at: v5.updated_at,
timestamp_observation_end: v5.timestamp_observation_end,
file_size_bytes: v5.file_size_bytes,
tagged_at: v5.tagged_at,
}
}
}
impl Artifact {
pub fn new(
file_path: String,
session_id: Option<i64>,
device_id: i64,
modality: Option<String>,
timestamp_observation: Option<String>,
) -> Self {
use chrono::Utc;
Self {
id: None,
created_at: None,
file_path,
session_id,
timestamp_observation,
modality,
device_id,
updated_at: None,
timestamp_observation_end: Utc::now().to_rfc3339(),
file_size_bytes: None,
tagged_at: None,
}
}
}
impl ArtifactLocal {
pub fn new(
file_path: String,
session_id: Option<i64>,
device_id: i64,
modality: Option<String>,
timestamp_observation: Option<String>,
) -> Self {
use chrono::Utc;
Self {
id: None,
id_local: None,
ancestor_id_local: None,
created_at: None,
file_path,
session_id,
timestamp_observation,
modality,
device_id,
updated_at: None,
timestamp_observation_end: Utc::now().to_rfc3339(),
has_uploaded_file_to_storage: false,
upload_url: None,
upload_url_generated_at: None,
file_size_bytes: None,
tagged_at: None,
}
}
pub fn mark_file_uploaded(&mut self) {
self.has_uploaded_file_to_storage = true;
}
pub fn mark_file_not_uploaded(&mut self) {
self.has_uploaded_file_to_storage = false;
}
pub fn is_file_uploaded(&self) -> bool {
self.has_uploaded_file_to_storage
}
pub fn needs_file_upload(&self) -> bool {
!self.has_uploaded_file_to_storage
}
}
impl Default for TagLocal {
fn default() -> Self {
Self {
id: None,
id_local: None,
inserted_at: None,
x: 0.0,
y: 0.0,
width: 0.0,
height: 0.0,
conf: 0.0,
observation_type: super::v1::TagObservationType::Auto,
class: String::new(),
event_id: None,
ancestor_id_local: None,
origin_location: None,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
detector: String::new(),
timestamp_observation: None,
frame_index: None,
subject_id: None,
}
}
}
impl Default for Tag {
fn default() -> Self {
Self {
id: None,
inserted_at: None,
x: 0.0,
y: 0.0,
width: 0.0,
height: 0.0,
conf: 0.0,
observation_type: super::v1::TagObservationType::Manual,
class: String::new(),
event_id: None,
origin_location: None,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
detector: String::new(),
timestamp_observation: None,
frame_index: None,
subject_id: None,
score: None,
score_source: None,
}
}
}
impl super::v1::Syncable for TagLocal {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
self.id_local.clone()
}
fn set_id_local(&mut self, id_local: String) {
self.id_local = Some(id_local);
}
}
impl super::v1::Syncable for Tag {
fn id(&self) -> Option<i64> {
self.id
}
fn set_id(&mut self, id: i64) {
self.id = Some(id);
}
fn id_local(&self) -> Option<String> {
None
}
fn set_id_local(&mut self, _: String) {}
}
impl super::v1::AncestorLocal for TagLocal {
fn ancestor_id_local(&self) -> Option<String> {
self.ancestor_id_local.clone()
}
fn set_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
}
impl From<TagLocal> for Tag {
fn from(local: TagLocal) -> Self {
Self {
id: local.id,
inserted_at: local.inserted_at,
x: local.x,
y: local.y,
width: local.width,
height: local.height,
conf: local.conf,
observation_type: local.observation_type,
class: local.class,
event_id: local.event_id,
origin_location: local.origin_location,
origin_pitch: local.origin_pitch,
origin_heading: local.origin_heading,
origin_roll: local.origin_roll,
sensor_pitch: local.sensor_pitch,
sensor_yaw: local.sensor_yaw,
sensor_roll: local.sensor_roll,
origin_height: local.origin_height,
subject_location: local.subject_location,
subject_height: local.subject_height,
artifact_id: local.artifact_id,
detector: local.detector,
timestamp_observation: local.timestamp_observation,
frame_index: local.frame_index,
subject_id: local.subject_id,
score: None,
score_source: None,
}
}
}
impl From<Tag> for TagLocal {
fn from(tag: Tag) -> Self {
Self {
id: tag.id,
id_local: None,
inserted_at: tag.inserted_at,
x: tag.x,
y: tag.y,
width: tag.width,
height: tag.height,
conf: tag.conf,
observation_type: tag.observation_type,
class: tag.class,
event_id: tag.event_id,
ancestor_id_local: None,
origin_location: tag.origin_location,
origin_pitch: tag.origin_pitch,
origin_heading: tag.origin_heading,
origin_roll: tag.origin_roll,
sensor_pitch: tag.sensor_pitch,
sensor_yaw: tag.sensor_yaw,
sensor_roll: tag.sensor_roll,
origin_height: tag.origin_height,
subject_location: tag.subject_location,
subject_height: tag.subject_height,
artifact_id: tag.artifact_id,
detector: tag.detector,
timestamp_observation: tag.timestamp_observation,
frame_index: tag.frame_index,
subject_id: tag.subject_id,
}
}
}
impl From<super::v5::TagLocal> for TagLocal {
fn from(v5: super::v5::TagLocal) -> Self {
Self {
id: v5.id,
id_local: v5.id_local,
inserted_at: v5.inserted_at,
x: v5.x,
y: v5.y,
width: v5.width,
height: v5.height,
conf: v5.conf,
observation_type: v5.observation_type,
class: v5.class,
event_id: v5.event_id,
ancestor_id_local: v5.ancestor_id_local,
origin_location: v5.origin_location.or(v5.location),
origin_pitch: v5.origin_pitch,
origin_heading: v5.origin_heading,
origin_roll: v5.origin_roll,
sensor_pitch: v5.sensor_pitch,
sensor_yaw: v5.sensor_yaw,
sensor_roll: v5.sensor_roll,
origin_height: v5.origin_height,
subject_location: v5.subject_location,
subject_height: v5.subject_height,
artifact_id: v5.artifact_id,
detector: v5.detector,
timestamp_observation: v5.timestamp_observation,
frame_index: v5.frame_index,
subject_id: None,
}
}
}
impl From<super::v5::Tag> for Tag {
fn from(v5: super::v5::Tag) -> Self {
Self {
id: v5.id,
inserted_at: v5.inserted_at,
x: v5.x,
y: v5.y,
width: v5.width,
height: v5.height,
conf: v5.conf,
observation_type: v5.observation_type,
class: v5.class,
event_id: v5.event_id,
origin_location: v5.origin_location.or(v5.location),
origin_pitch: v5.origin_pitch,
origin_heading: v5.origin_heading,
origin_roll: v5.origin_roll,
sensor_pitch: v5.sensor_pitch,
sensor_yaw: v5.sensor_yaw,
sensor_roll: v5.sensor_roll,
origin_height: v5.origin_height,
subject_location: v5.subject_location,
subject_height: v5.subject_height,
artifact_id: v5.artifact_id,
detector: v5.detector,
timestamp_observation: v5.timestamp_observation,
frame_index: v5.frame_index,
subject_id: None,
score: None,
score_source: None,
}
}
}
impl From<super::v1::TagLocal> for TagLocal {
fn from(v1: super::v1::TagLocal) -> Self {
Self {
id: v1.id,
id_local: v1.id_local,
inserted_at: v1.inserted_at,
x: v1.x,
y: v1.y,
width: v1.width,
height: v1.height,
conf: v1.conf,
observation_type: v1.observation_type,
class: v1.class_name,
event_id: Some(v1.event_id),
ancestor_id_local: v1.ancestor_id_local,
origin_location: v1.location,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
detector: String::new(),
timestamp_observation: None,
frame_index: None,
subject_id: None,
}
}
}
impl From<super::v1::Tag> for Tag {
fn from(v1: super::v1::Tag) -> Self {
Self {
id: v1.id,
inserted_at: v1.inserted_at,
x: v1.x,
y: v1.y,
width: v1.width,
height: v1.height,
conf: v1.conf,
observation_type: v1.observation_type,
class: v1.class_name,
event_id: Some(v1.event_id),
origin_location: v1.location,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
detector: String::new(),
timestamp_observation: None,
frame_index: None,
subject_id: None,
score: None,
score_source: None,
}
}
}
impl Tag {
pub fn new(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
) -> Self {
Self {
id: None,
inserted_at: None,
x,
y,
width,
height,
conf,
observation_type,
class,
event_id: None,
origin_location: None,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
detector: String::new(),
timestamp_observation: None,
frame_index: None,
subject_id: None,
score: None,
score_source: None,
}
}
pub fn new_with_location(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
latitude: f64,
longitude: f64,
) -> Self {
let mut tag = Self::new(
_class_id,
x,
y,
width,
height,
conf,
observation_type,
class,
);
tag.set_location(latitude, longitude);
tag
}
pub fn update_event_id(&mut self, event_id: i64) {
self.event_id = Some(event_id);
}
pub fn set_location(&mut self, latitude: f64, longitude: f64) {
self.origin_location = Some(Self::format_location(latitude, longitude));
}
pub fn clear_location(&mut self) {
self.origin_location = None;
}
pub fn format_location(latitude: f64, longitude: f64) -> String {
format!("POINT({} {})", longitude, latitude)
}
pub fn parse_location(location: &str) -> Option<(f64, f64)> {
if let Some(coords) = location
.strip_prefix("POINT(")
.and_then(|s| s.strip_suffix(")"))
{
let parts: Vec<&str> = coords.split_whitespace().collect();
if parts.len() == 2 {
if let (Ok(lon), Ok(lat)) = (parts[0].parse::<f64>(), parts[1].parse::<f64>()) {
return Some((lat, lon));
}
}
}
None
}
pub fn get_coordinates(&self) -> Option<(f64, f64)> {
self.origin_location
.as_ref()
.and_then(|loc| Self::parse_location(loc))
}
}
impl TagLocal {
pub fn new(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
) -> Self {
Self {
id: None,
id_local: None,
inserted_at: None,
x,
y,
width,
height,
conf,
observation_type,
class,
event_id: None,
ancestor_id_local: None,
origin_location: None,
origin_pitch: None,
origin_heading: None,
origin_roll: None,
sensor_pitch: None,
sensor_yaw: None,
sensor_roll: None,
origin_height: None,
subject_location: None,
subject_height: None,
artifact_id: None,
detector: String::new(),
timestamp_observation: None,
frame_index: None,
subject_id: None,
}
}
pub fn new_with_location(
_class_id: i64,
x: f64,
y: f64,
width: f64,
height: f64,
conf: f64,
observation_type: super::v1::TagObservationType,
class: String,
latitude: f64,
longitude: f64,
) -> Self {
let mut tag = Self::new(
_class_id,
x,
y,
width,
height,
conf,
observation_type,
class,
);
tag.set_location(latitude, longitude);
tag
}
pub fn update_event_id(&mut self, event_id: i64) {
self.event_id = Some(event_id);
}
pub fn update_ancestor_id_local(&mut self, ancestor_id_local: String) {
self.ancestor_id_local = Some(ancestor_id_local);
}
pub fn set_location(&mut self, latitude: f64, longitude: f64) {
self.origin_location = Some(Self::format_location(latitude, longitude));
}
pub fn clear_location(&mut self) {
self.origin_location = None;
}
pub fn format_location(latitude: f64, longitude: f64) -> String {
format!("POINT({} {})", longitude, latitude)
}
pub fn parse_location(location: &str) -> Option<(f64, f64)> {
if let Some(coords) = location
.strip_prefix("POINT(")
.and_then(|s| s.strip_suffix(")"))
{
let parts: Vec<&str> = coords.split_whitespace().collect();
if parts.len() == 2 {
if let (Ok(lon), Ok(lat)) = (parts[0].parse::<f64>(), parts[1].parse::<f64>()) {
return Some((lat, lon));
}
}
}
None
}
pub fn get_coordinates(&self) -> Option<(f64, f64)> {
self.origin_location
.as_ref()
.and_then(|loc| Self::parse_location(loc))
}
}