diff --git a/api/v1/file.go b/api/v1/file.go deleted file mode 100644 index 4bf040a..0000000 --- a/api/v1/file.go +++ /dev/null @@ -1,60 +0,0 @@ -package api - -import "time" - -type Files []File - -// File represents an image or sidecar file that belongs to a photo. -type File struct { - ID uint `gorm:"primary_key" json:"-" yaml:"-"` - Photo *Photo `json:"-" yaml:"-"` - PhotoID uint `gorm:"index;" json:"-" yaml:"-"` - PhotoUID string `gorm:"type:VARBINARY(42);index;" json:"PhotoUID" yaml:"PhotoUID"` - InstanceID string `gorm:"type:VARBINARY(42);index;" json:"InstanceID,omitempty" yaml:"InstanceID,omitempty"` - FileUID string `gorm:"type:VARBINARY(42);unique_index;" json:"UID" yaml:"UID"` - FileName string `gorm:"type:VARBINARY(755);unique_index:idx_files_name_root;" json:"Name" yaml:"Name"` - FileRoot string `gorm:"type:VARBINARY(16);default:'/';unique_index:idx_files_name_root;" json:"Root" yaml:"Root,omitempty"` - OriginalName string `gorm:"type:VARBINARY(755);" json:"OriginalName" yaml:"OriginalName,omitempty"` - FileHash string `gorm:"type:VARBINARY(128);index" json:"Hash" yaml:"Hash,omitempty"` - FileSize int64 `json:"Size" yaml:"Size,omitempty"` - FileCodec string `gorm:"type:VARBINARY(32)" json:"Codec" yaml:"Codec,omitempty"` - FileType string `gorm:"type:VARBINARY(32)" json:"Type" yaml:"Type,omitempty"` - FileMime string `gorm:"type:VARBINARY(64)" json:"Mime" yaml:"Mime,omitempty"` - FilePrimary bool `json:"Primary" yaml:"Primary,omitempty"` - FileSidecar bool `json:"Sidecar" yaml:"Sidecar,omitempty"` - FileMissing bool `json:"Missing" yaml:"Missing,omitempty"` - FilePortrait bool `json:"Portrait" yaml:"Portrait,omitempty"` - FileVideo bool `json:"Video" yaml:"Video,omitempty"` - FileDuration time.Duration `json:"Duration" yaml:"Duration,omitempty"` - FileWidth int `json:"Width" yaml:"Width,omitempty"` - FileHeight int `json:"Height" yaml:"Height,omitempty"` - FileOrientation int `json:"Orientation" yaml:"Orientation,omitempty"` - FileProjection string `gorm:"type:VARBINARY(16);" json:"Projection,omitempty" yaml:"Projection,omitempty"` - FileAspectRatio float32 `gorm:"type:FLOAT;" json:"AspectRatio" yaml:"AspectRatio,omitempty"` - FileMainColor string `gorm:"type:VARBINARY(16);index;" json:"MainColor" yaml:"MainColor,omitempty"` - FileColors string `gorm:"type:VARBINARY(9);" json:"Colors" yaml:"Colors,omitempty"` - FileLuminance string `gorm:"type:VARBINARY(9);" json:"Luminance" yaml:"Luminance,omitempty"` - FileDiff uint32 `json:"Diff" yaml:"Diff,omitempty"` - FileChroma uint8 `json:"Chroma" yaml:"Chroma,omitempty"` - FileError string `gorm:"type:VARBINARY(512)" json:"Error" yaml:"Error,omitempty"` - ModTime int64 `json:"ModTime" yaml:"-"` - CreatedAt time.Time `json:"CreatedAt" yaml:"-"` - CreatedIn int64 `json:"CreatedIn" yaml:"-"` - UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"` - UpdatedIn int64 `json:"UpdatedIn" yaml:"-"` - DeletedAt *time.Time `sql:"index" json:"DeletedAt,omitempty" yaml:"-"` - //Share []FileShare `json:"-" yaml:"-"` - //Sync []FileSync `json:"-" yaml:"-"` -} - -type FileInfos struct { - FileWidth int - FileHeight int - FileOrientation int - FileAspectRatio float32 - FileMainColor string - FileColors string - FileLuminance string - FileDiff uint32 - FileChroma uint8 -} diff --git a/api/v1/photo.go b/api/v1/photo.go index ab4eb6f..4e5e6c2 100644 --- a/api/v1/photo.go +++ b/api/v1/photo.go @@ -1,70 +1,6 @@ package api -import ( - "time" -) -// Photo represents a photo, all its properties, and link to all its images and sidecar files. -type Photo struct { - Meta - ID uint `gorm:"primary_key" yaml:"-"` - UUID string `gorm:"type:VARBINARY(42);index;" json:"DocumentID,omitempty" yaml:"DocumentID,omitempty"` - TakenAt time.Time `gorm:"type:datetime;index:idx_photos_taken_uid;" json:"TakenAt" yaml:"TakenAt"` - TakenAtLocal time.Time `gorm:"type:datetime;" yaml:"-"` - TakenSrc string `gorm:"type:VARBINARY(8);" json:"TakenSrc" yaml:"TakenSrc,omitempty"` - PhotoUID string `gorm:"type:VARBINARY(42);unique_index;index:idx_photos_taken_uid;" json:"UID" yaml:"UID"` - PhotoType string `gorm:"type:VARBINARY(8);default:'image';" json:"Type" yaml:"Type"` - TypeSrc string `gorm:"type:VARBINARY(8);" json:"TypeSrc" yaml:"TypeSrc,omitempty"` - PhotoTitle string `gorm:"type:VARCHAR(255);" json:"Title" yaml:"Title"` - TitleSrc string `gorm:"type:VARBINARY(8);" json:"TitleSrc" yaml:"TitleSrc,omitempty"` - PhotoDescription string `gorm:"type:TEXT;" json:"Description" yaml:"Description,omitempty"` - DescriptionSrc string `gorm:"type:VARBINARY(8);" json:"DescriptionSrc" yaml:"DescriptionSrc,omitempty"` - PhotoPath string `gorm:"type:VARBINARY(500);index:idx_photos_path_name;" json:"Path" yaml:"-"` - PhotoName string `gorm:"type:VARBINARY(255);index:idx_photos_path_name;" json:"Name" yaml:"-"` - OriginalName string `gorm:"type:VARBINARY(755);" json:"OriginalName" yaml:"OriginalName,omitempty"` - PhotoStack int8 `json:"Stack" yaml:"Stack,omitempty"` - PhotoFavorite bool `json:"Favorite" yaml:"Favorite,omitempty"` - PhotoPrivate bool `json:"Private" yaml:"Private,omitempty"` - PhotoScan bool `json:"Scan" yaml:"Scan,omitempty"` - PhotoPanorama bool `json:"Panorama" yaml:"Panorama,omitempty"` - TimeZone string `gorm:"type:VARBINARY(64);" json:"TimeZone" yaml:"-"` - PlaceID string `gorm:"type:VARBINARY(42);index;default:'zz'" json:"PlaceID" yaml:"-"` - PlaceSrc string `gorm:"type:VARBINARY(8);" json:"PlaceSrc" yaml:"PlaceSrc,omitempty"` - CellID string `gorm:"type:VARBINARY(42);index;default:'zz'" json:"CellID" yaml:"-"` - CellAccuracy int `json:"CellAccuracy" yaml:"CellAccuracy,omitempty"` - PhotoAltitude int `json:"Altitude" yaml:"Altitude,omitempty"` - PhotoLat float32 `gorm:"type:FLOAT;index;" json:"Lat" yaml:"Lat,omitempty"` - PhotoLng float32 `gorm:"type:FLOAT;index;" json:"Lng" yaml:"Lng,omitempty"` - PhotoCountry string `gorm:"type:VARBINARY(2);index:idx_photos_country_year_month;default:'zz'" json:"Country" yaml:"-"` - PhotoYear int `gorm:"index:idx_photos_country_year_month;" json:"Year" yaml:"Year"` - PhotoMonth int `gorm:"index:idx_photos_country_year_month;" json:"Month" yaml:"Month"` - PhotoDay int `json:"Day" yaml:"Day"` - PhotoIso int `json:"Iso" yaml:"ISO,omitempty"` - PhotoExposure string `gorm:"type:VARBINARY(64);" json:"Exposure" yaml:"Exposure,omitempty"` - PhotoFNumber float32 `gorm:"type:FLOAT;" json:"FNumber" yaml:"FNumber,omitempty"` - PhotoFocalLength int `json:"FocalLength" yaml:"FocalLength,omitempty"` - PhotoQuality int `gorm:"type:SMALLINT" json:"Quality" yaml:"-"` - PhotoResolution int `gorm:"type:SMALLINT" json:"Resolution" yaml:"-"` - PhotoColor uint8 `json:"Color" yaml:"-"` - CameraID uint `gorm:"index:idx_photos_camera_lens;default:1" json:"CameraID" yaml:"-"` - CameraSerial string `gorm:"type:VARBINARY(255);" json:"CameraSerial" yaml:"CameraSerial,omitempty"` - CameraSrc string `gorm:"type:VARBINARY(8);" json:"CameraSrc" yaml:"-"` - LensID uint `gorm:"index:idx_photos_camera_lens;default:1" json:"LensID" yaml:"-"` - //Details *Details `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Details" yaml:"Details"` - //Camera *Camera `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Camera" yaml:"-"` - //Lens *Lens `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Lens" yaml:"-"` - //Cell *Cell `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Cell" yaml:"-"` - //Place *Place `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Place" yaml:"-"` - //Keywords []Keyword `json:"-" yaml:"-"` - //Albums []Album `json:"-" yaml:"-"` - Files []File `yaml:"-"` - //Labels []PhotoLabel `yaml:"-"` - CreatedAt time.Time `yaml:"CreatedAt,omitempty"` - UpdatedAt time.Time `yaml:"UpdatedAt,omitempty"` - EditedAt *time.Time `yaml:"EditedAt,omitempty"` - CheckedAt *time.Time `sql:"index" yaml:"-"` - DeletedAt *time.Time `sql:"index" yaml:"DeletedAt,omitempty"` -} // GET /api/v1/photos/:uuid // diff --git a/api/v1/types.go b/api/v1/types.go new file mode 100644 index 0000000..c3ff7e6 --- /dev/null +++ b/api/v1/types.go @@ -0,0 +1,344 @@ +package api + +import ( + "database/sql" + "time" +) + +// Photo represents a photo, all its properties, and link to all its images and sidecar files. +type Photo struct { + Meta + ID uint `gorm:"primary_key" yaml:"-"` + UUID string `gorm:"type:VARBINARY(42);index;" json:"DocumentID,omitempty" yaml:"DocumentID,omitempty"` + TakenAt time.Time `gorm:"type:datetime;index:idx_photos_taken_uid;" json:"TakenAt" yaml:"TakenAt"` + TakenAtLocal time.Time `gorm:"type:datetime;" yaml:"-"` + TakenSrc string `gorm:"type:VARBINARY(8);" json:"TakenSrc" yaml:"TakenSrc,omitempty"` + PhotoUID string `gorm:"type:VARBINARY(42);unique_index;index:idx_photos_taken_uid;" json:"UID" yaml:"UID"` + PhotoType string `gorm:"type:VARBINARY(8);default:'image';" json:"Type" yaml:"Type"` + TypeSrc string `gorm:"type:VARBINARY(8);" json:"TypeSrc" yaml:"TypeSrc,omitempty"` + PhotoTitle string `gorm:"type:VARCHAR(255);" json:"Title" yaml:"Title"` + TitleSrc string `gorm:"type:VARBINARY(8);" json:"TitleSrc" yaml:"TitleSrc,omitempty"` + PhotoDescription string `gorm:"type:TEXT;" json:"Description" yaml:"Description,omitempty"` + DescriptionSrc string `gorm:"type:VARBINARY(8);" json:"DescriptionSrc" yaml:"DescriptionSrc,omitempty"` + PhotoPath string `gorm:"type:VARBINARY(500);index:idx_photos_path_name;" json:"Path" yaml:"-"` + PhotoName string `gorm:"type:VARBINARY(255);index:idx_photos_path_name;" json:"Name" yaml:"-"` + OriginalName string `gorm:"type:VARBINARY(755);" json:"OriginalName" yaml:"OriginalName,omitempty"` + PhotoStack int8 `json:"Stack" yaml:"Stack,omitempty"` + PhotoFavorite bool `json:"Favorite" yaml:"Favorite,omitempty"` + PhotoPrivate bool `json:"Private" yaml:"Private,omitempty"` + PhotoScan bool `json:"Scan" yaml:"Scan,omitempty"` + PhotoPanorama bool `json:"Panorama" yaml:"Panorama,omitempty"` + TimeZone string `gorm:"type:VARBINARY(64);" json:"TimeZone" yaml:"-"` + PlaceID string `gorm:"type:VARBINARY(42);index;default:'zz'" json:"PlaceID" yaml:"-"` + PlaceSrc string `gorm:"type:VARBINARY(8);" json:"PlaceSrc" yaml:"PlaceSrc,omitempty"` + CellID string `gorm:"type:VARBINARY(42);index;default:'zz'" json:"CellID" yaml:"-"` + CellAccuracy int `json:"CellAccuracy" yaml:"CellAccuracy,omitempty"` + PhotoAltitude int `json:"Altitude" yaml:"Altitude,omitempty"` + PhotoLat float32 `gorm:"type:FLOAT;index;" json:"Lat" yaml:"Lat,omitempty"` + PhotoLng float32 `gorm:"type:FLOAT;index;" json:"Lng" yaml:"Lng,omitempty"` + PhotoCountry string `gorm:"type:VARBINARY(2);index:idx_photos_country_year_month;default:'zz'" json:"Country" yaml:"-"` + PhotoYear int `gorm:"index:idx_photos_country_year_month;" json:"Year" yaml:"Year"` + PhotoMonth int `gorm:"index:idx_photos_country_year_month;" json:"Month" yaml:"Month"` + PhotoDay int `json:"Day" yaml:"Day"` + PhotoIso int `json:"Iso" yaml:"ISO,omitempty"` + PhotoExposure string `gorm:"type:VARBINARY(64);" json:"Exposure" yaml:"Exposure,omitempty"` + PhotoFNumber float32 `gorm:"type:FLOAT;" json:"FNumber" yaml:"FNumber,omitempty"` + PhotoFocalLength int `json:"FocalLength" yaml:"FocalLength,omitempty"` + PhotoQuality int `gorm:"type:SMALLINT" json:"Quality" yaml:"-"` + PhotoResolution int `gorm:"type:SMALLINT" json:"Resolution" yaml:"-"` + PhotoColor uint8 `json:"Color" yaml:"-"` + CameraID uint `gorm:"index:idx_photos_camera_lens;default:1" json:"CameraID" yaml:"-"` + CameraSerial string `gorm:"type:VARBINARY(255);" json:"CameraSerial" yaml:"CameraSerial,omitempty"` + CameraSrc string `gorm:"type:VARBINARY(8);" json:"CameraSrc" yaml:"-"` + LensID uint `gorm:"index:idx_photos_camera_lens;default:1" json:"LensID" yaml:"-"` + Details *Details `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Details" yaml:"Details"` + Camera *Camera `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Camera" yaml:"-"` + Lens *Lens `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Lens" yaml:"-"` + Cell *Cell `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Cell" yaml:"-"` + Place *Place `gorm:"association_autoupdate:false;association_autocreate:false;association_save_reference:false" json:"Place" yaml:"-"` + Keywords []Keyword `json:"-" yaml:"-"` + Albums []Album `json:"-" yaml:"-"` + Files []File `yaml:"-"` + //Labels []PhotoLabel `yaml:"-"` + CreatedAt time.Time `yaml:"CreatedAt,omitempty"` + UpdatedAt time.Time `yaml:"UpdatedAt,omitempty"` + EditedAt *time.Time `yaml:"EditedAt,omitempty"` + CheckedAt *time.Time `sql:"index" yaml:"-"` + DeletedAt *time.Time `sql:"index" yaml:"DeletedAt,omitempty"` +} + +// Details stores additional metadata fields for each photo to improve search performance. +type Details struct { + PhotoID uint `gorm:"primary_key;auto_increment:false" yaml:"-"` + Keywords string `gorm:"type:TEXT;" json:"Keywords" yaml:"Keywords"` + KeywordsSrc string `gorm:"type:VARBINARY(8);" json:"KeywordsSrc" yaml:"KeywordsSrc,omitempty"` + Notes string `gorm:"type:TEXT;" json:"Notes" yaml:"Notes,omitempty"` + NotesSrc string `gorm:"type:VARBINARY(8);" json:"NotesSrc" yaml:"NotesSrc,omitempty"` + Subject string `gorm:"type:VARCHAR(255);" json:"Subject" yaml:"Subject,omitempty"` + SubjectSrc string `gorm:"type:VARBINARY(8);" json:"SubjectSrc" yaml:"SubjectSrc,omitempty"` + Artist string `gorm:"type:VARCHAR(255);" json:"Artist" yaml:"Artist,omitempty"` + ArtistSrc string `gorm:"type:VARBINARY(8);" json:"ArtistSrc" yaml:"ArtistSrc,omitempty"` + Copyright string `gorm:"type:VARCHAR(255);" json:"Copyright" yaml:"Copyright,omitempty"` + CopyrightSrc string `gorm:"type:VARBINARY(8);" json:"CopyrightSrc" yaml:"CopyrightSrc,omitempty"` + License string `gorm:"type:VARCHAR(255);" json:"License" yaml:"License,omitempty"` + LicenseSrc string `gorm:"type:VARBINARY(8);" json:"LicenseSrc" yaml:"LicenseSrc,omitempty"` + CreatedAt time.Time `yaml:"-"` + UpdatedAt time.Time `yaml:"-"` +} + +// Camera model and make (as extracted from UpdateExif metadata) +type Camera struct { + ID uint `gorm:"primary_key" json:"ID" yaml:"ID"` + CameraSlug string `gorm:"type:VARBINARY(255);unique_index;" json:"Slug" yaml:"-"` + CameraName string `gorm:"type:VARCHAR(255);" json:"Name" yaml:"Name"` + CameraMake string `gorm:"type:VARCHAR(255);" json:"Make" yaml:"Make,omitempty"` + CameraModel string `gorm:"type:VARCHAR(255);" json:"Model" yaml:"Model,omitempty"` + CameraType string `gorm:"type:VARCHAR(255);" json:"Type,omitempty" yaml:"Type,omitempty"` + CameraDescription string `gorm:"type:TEXT;" json:"Description,omitempty" yaml:"Description,omitempty"` + CameraNotes string `gorm:"type:TEXT;" json:"Notes,omitempty" yaml:"Notes,omitempty"` + CreatedAt time.Time `json:"-" yaml:"-"` + UpdatedAt time.Time `json:"-" yaml:"-"` + DeletedAt *time.Time `sql:"index" json:"-" yaml:"-"` +} + +// Lens represents camera lens (as extracted from UpdateExif metadata) +type Lens struct { + ID uint `gorm:"primary_key" json:"ID" yaml:"ID"` + LensSlug string `gorm:"type:VARBINARY(255);unique_index;" json:"Slug" yaml:"Slug,omitempty"` + LensName string `gorm:"type:VARCHAR(255);" json:"Name" yaml:"Name"` + LensMake string `gorm:"type:VARCHAR(255);" json:"Make" yaml:"Make,omitempty"` + LensModel string `gorm:"type:VARCHAR(255);" json:"Model" yaml:"Model,omitempty"` + LensType string `gorm:"type:VARCHAR(255);" json:"Type" yaml:"Type,omitempty"` + LensDescription string `gorm:"type:TEXT;" json:"Description,omitempty" yaml:"Description,omitempty"` + LensNotes string `gorm:"type:TEXT;" json:"Notes,omitempty" yaml:"Notes,omitempty"` + CreatedAt time.Time `json:"-" yaml:"-"` + UpdatedAt time.Time `json:"-" yaml:"-"` + DeletedAt *time.Time `sql:"index" json:"-" yaml:"-"` +} + +// Cell represents a S2 cell with location data. +type Cell struct { + ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"ID" yaml:"ID"` + CellName string `gorm:"type:VARCHAR(255);" json:"Name" yaml:"Name,omitempty"` + CellCategory string `gorm:"type:VARCHAR(64);" json:"Category" yaml:"Category,omitempty"` + PlaceID string `gorm:"type:VARBINARY(42);default:'zz'" json:"-" yaml:"PlaceID"` + Place *Place `gorm:"PRELOAD:true" json:"Place" yaml:"-"` + CreatedAt time.Time `json:"CreatedAt" yaml:"-"` + UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"` +} + +// Place used to associate photos to places +type Place struct { + ID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;" json:"PlaceID" yaml:"PlaceID"` + PlaceLabel string `gorm:"type:VARBINARY(755);unique_index;" json:"Label" yaml:"Label"` + PlaceCity string `gorm:"type:VARCHAR(255);" json:"City" yaml:"City,omitempty"` + PlaceState string `gorm:"type:VARCHAR(255);" json:"State" yaml:"State,omitempty"` + PlaceCountry string `gorm:"type:VARBINARY(2);" json:"Country" yaml:"Country,omitempty"` + PlaceKeywords string `gorm:"type:VARCHAR(255);" json:"Keywords" yaml:"Keywords,omitempty"` + PlaceFavorite bool `json:"Favorite" yaml:"Favorite,omitempty"` + PhotoCount int `gorm:"default:1" json:"PhotoCount" yaml:"-"` + CreatedAt time.Time `json:"CreatedAt" yaml:"-"` + UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"` +} + +// Keyword used for full text search +type Keyword struct { + ID uint `gorm:"primary_key"` + Keyword string `gorm:"type:VARCHAR(64);index;"` + Skip bool +} + +// Album represents a photo album +type Album struct { + ID uint `gorm:"primary_key" json:"ID" yaml:"-"` + AlbumUID string `gorm:"type:VARBINARY(42);unique_index;" json:"UID" yaml:"UID"` + CoverUID string `gorm:"type:VARBINARY(42);" json:"CoverUID" yaml:"CoverUID,omitempty"` + FolderUID string `gorm:"type:VARBINARY(42);index;" json:"FolderUID" yaml:"FolderUID,omitempty"` + AlbumSlug string `gorm:"type:VARBINARY(255);index;" json:"Slug" yaml:"Slug"` + AlbumPath string `gorm:"type:VARBINARY(500);index;" json:"Path" yaml:"-"` + AlbumType string `gorm:"type:VARBINARY(8);default:'album';" json:"Type" yaml:"Type,omitempty"` + AlbumTitle string `gorm:"type:VARCHAR(255);" json:"Title" yaml:"Title"` + AlbumLocation string `gorm:"type:VARCHAR(255);" json:"Location" yaml:"Location,omitempty"` + AlbumCategory string `gorm:"type:VARCHAR(255);index;" json:"Category" yaml:"Category,omitempty"` + AlbumCaption string `gorm:"type:TEXT;" json:"Caption" yaml:"Caption,omitempty"` + AlbumDescription string `gorm:"type:TEXT;" json:"Description" yaml:"Description,omitempty"` + AlbumNotes string `gorm:"type:TEXT;" json:"Notes" yaml:"Notes,omitempty"` + AlbumFilter string `gorm:"type:VARBINARY(1024);" json:"Filter" yaml:"Filter,omitempty"` + AlbumOrder string `gorm:"type:VARBINARY(32);" json:"Order" yaml:"Order,omitempty"` + AlbumTemplate string `gorm:"type:VARBINARY(255);" json:"Template" yaml:"Template,omitempty"` + AlbumCountry string `gorm:"type:VARBINARY(2);index:idx_albums_country_year_month;default:'zz'" json:"Country" yaml:"Country,omitempty"` + AlbumYear int `gorm:"index:idx_albums_country_year_month;" json:"Year" yaml:"Year,omitempty"` + AlbumMonth int `gorm:"index:idx_albums_country_year_month;" json:"Month" yaml:"Month,omitempty"` + AlbumDay int `json:"Day" yaml:"Day,omitempty"` + AlbumFavorite bool `json:"Favorite" yaml:"Favorite,omitempty"` + AlbumPrivate bool `json:"Private" yaml:"Private,omitempty"` + CreatedAt time.Time `json:"CreatedAt" yaml:"CreatedAt,omitempty"` + UpdatedAt time.Time `json:"UpdatedAt" yaml:"UpdatedAt,omitempty"` + DeletedAt *time.Time `sql:"index" json:"DeletedAt" yaml:"DeletedAt,omitempty"` + Photos PhotoAlbums `gorm:"foreignkey:AlbumUID;association_foreignkey:AlbumUID" json:"-" yaml:"Photos,omitempty"` +} + +type PhotoAlbums []PhotoAlbum + +// PhotoAlbum represents the many_to_many relation between Photo and Album +type PhotoAlbum struct { + PhotoUID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false" json:"PhotoUID" yaml:"UID"` + AlbumUID string `gorm:"type:VARBINARY(42);primary_key;auto_increment:false;index" json:"AlbumUID" yaml:"-"` + Order int `json:"Order" yaml:"Order,omitempty"` + Hidden bool `json:"Hidden" yaml:"Hidden,omitempty"` + Missing bool `json:"Missing" yaml:"Missing,omitempty"` + CreatedAt time.Time `json:"CreatedAt" yaml:"CreatedAt,omitempty"` + UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"` + Photo *Photo `gorm:"PRELOAD:false" yaml:"-"` + Album *Album `gorm:"PRELOAD:true" yaml:"-"` +} + + +// File represents an image or sidecar file that belongs to a photo. +type File struct { + ID uint `gorm:"primary_key" json:"-" yaml:"-"` + Photo *Photo `json:"-" yaml:"-"` + PhotoID uint `gorm:"index;" json:"-" yaml:"-"` + PhotoUID string `gorm:"type:VARBINARY(42);index;" json:"PhotoUID" yaml:"PhotoUID"` + InstanceID string `gorm:"type:VARBINARY(42);index;" json:"InstanceID,omitempty" yaml:"InstanceID,omitempty"` + FileUID string `gorm:"type:VARBINARY(42);unique_index;" json:"UID" yaml:"UID"` + FileName string `gorm:"type:VARBINARY(755);unique_index:idx_files_name_root;" json:"Name" yaml:"Name"` + FileRoot string `gorm:"type:VARBINARY(16);default:'/';unique_index:idx_files_name_root;" json:"Root" yaml:"Root,omitempty"` + OriginalName string `gorm:"type:VARBINARY(755);" json:"OriginalName" yaml:"OriginalName,omitempty"` + FileHash string `gorm:"type:VARBINARY(128);index" json:"Hash" yaml:"Hash,omitempty"` + FileSize int64 `json:"Size" yaml:"Size,omitempty"` + FileCodec string `gorm:"type:VARBINARY(32)" json:"Codec" yaml:"Codec,omitempty"` + FileType string `gorm:"type:VARBINARY(32)" json:"Type" yaml:"Type,omitempty"` + FileMime string `gorm:"type:VARBINARY(64)" json:"Mime" yaml:"Mime,omitempty"` + FilePrimary bool `json:"Primary" yaml:"Primary,omitempty"` + FileSidecar bool `json:"Sidecar" yaml:"Sidecar,omitempty"` + FileMissing bool `json:"Missing" yaml:"Missing,omitempty"` + FilePortrait bool `json:"Portrait" yaml:"Portrait,omitempty"` + FileVideo bool `json:"Video" yaml:"Video,omitempty"` + FileDuration time.Duration `json:"Duration" yaml:"Duration,omitempty"` + FileWidth int `json:"Width" yaml:"Width,omitempty"` + FileHeight int `json:"Height" yaml:"Height,omitempty"` + FileOrientation int `json:"Orientation" yaml:"Orientation,omitempty"` + FileProjection string `gorm:"type:VARBINARY(16);" json:"Projection,omitempty" yaml:"Projection,omitempty"` + FileAspectRatio float32 `gorm:"type:FLOAT;" json:"AspectRatio" yaml:"AspectRatio,omitempty"` + FileMainColor string `gorm:"type:VARBINARY(16);index;" json:"MainColor" yaml:"MainColor,omitempty"` + FileColors string `gorm:"type:VARBINARY(9);" json:"Colors" yaml:"Colors,omitempty"` + FileLuminance string `gorm:"type:VARBINARY(9);" json:"Luminance" yaml:"Luminance,omitempty"` + FileDiff uint32 `json:"Diff" yaml:"Diff,omitempty"` + FileChroma uint8 `json:"Chroma" yaml:"Chroma,omitempty"` + FileError string `gorm:"type:VARBINARY(512)" json:"Error" yaml:"Error,omitempty"` + ModTime int64 `json:"ModTime" yaml:"-"` + CreatedAt time.Time `json:"CreatedAt" yaml:"-"` + CreatedIn int64 `json:"CreatedIn" yaml:"-"` + UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"` + UpdatedIn int64 `json:"UpdatedIn" yaml:"-"` + DeletedAt *time.Time `sql:"index" json:"DeletedAt,omitempty" yaml:"-"` + Share []FileShare `json:"-" yaml:"-"` + Sync []FileSync `json:"-" yaml:"-"` +} + +// FileSync represents a one-to-many relation between File and Account for syncing with remote services. +type FileSync struct { + RemoteName string `gorm:"primary_key;auto_increment:false;type:VARBINARY(255)"` + AccountID uint `gorm:"primary_key;auto_increment:false"` + FileID uint `gorm:"index;"` + RemoteDate time.Time + RemoteSize int64 + Status string `gorm:"type:VARBINARY(16);"` + Error string `gorm:"type:VARBINARY(512);"` + Errors int + File *File + Account *Account + CreatedAt time.Time + UpdatedAt time.Time +} + +// FileShare represents a one-to-many relation between File and Account for pushing files to remote services. +type FileShare struct { + FileID uint `gorm:"primary_key;auto_increment:false"` + AccountID uint `gorm:"primary_key;auto_increment:false"` + RemoteName string `gorm:"primary_key;auto_increment:false;type:VARBINARY(255)"` + Status string `gorm:"type:VARBINARY(16);"` + Error string `gorm:"type:VARBINARY(512);"` + Errors int + File *File + Account *Account + CreatedAt time.Time + UpdatedAt time.Time +} + + +// PhotoLabel represents the many-to-many relation between Photo and label. +// Labels are weighted by uncertainty (100 - confidence) +type PhotoLabel struct { + PhotoID uint `gorm:"primary_key;auto_increment:false"` + LabelID uint `gorm:"primary_key;auto_increment:false;index"` + LabelSrc string `gorm:"type:VARBINARY(8);"` + Uncertainty int `gorm:"type:SMALLINT"` + Photo *Photo `gorm:"PRELOAD:false"` + Label *Label `gorm:"PRELOAD:true"` +} + +// Label is used for photo, album and location categorization +type Label struct { + ID uint `gorm:"primary_key" json:"ID" yaml:"-"` + LabelUID string `gorm:"type:VARBINARY(42);unique_index;" json:"UID" yaml:"UID"` + LabelSlug string `gorm:"type:VARBINARY(255);unique_index;" json:"Slug" yaml:"-"` + CustomSlug string `gorm:"type:VARBINARY(255);index;" json:"CustomSlug" yaml:"-"` + LabelName string `gorm:"type:VARCHAR(255);" json:"Name" yaml:"Name"` + LabelPriority int `json:"Priority" yaml:"Priority,omitempty"` + LabelFavorite bool `json:"Favorite" yaml:"Favorite,omitempty"` + LabelDescription string `gorm:"type:TEXT;" json:"Description" yaml:"Description,omitempty"` + LabelNotes string `gorm:"type:TEXT;" json:"Notes" yaml:"Notes,omitempty"` + LabelCategories []*Label `gorm:"many2many:categories;association_jointable_foreignkey:category_id" json:"-" yaml:"-"` + PhotoCount int `gorm:"default:1" json:"PhotoCount" yaml:"-"` + CreatedAt time.Time `json:"CreatedAt" yaml:"-"` + UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"` + DeletedAt *time.Time `sql:"index" json:"DeletedAt,omitempty" yaml:"-"` + New bool `gorm:"-" json:"-" yaml:"-"` +} + +type Files []File + +type FileInfos struct { + FileWidth int + FileHeight int + FileOrientation int + FileAspectRatio float32 + FileMainColor string + FileColors string + FileLuminance string + FileDiff uint32 + FileChroma uint8 +} + +// Account represents a remote service account for uploading, downloading or syncing media files. +type Account struct { + ID uint `gorm:"primary_key"` + AccName string `gorm:"type:VARCHAR(255);"` + AccOwner string `gorm:"type:VARCHAR(255);"` + AccURL string `gorm:"type:VARBINARY(512);"` + AccType string `gorm:"type:VARBINARY(255);"` + AccKey string `gorm:"type:VARBINARY(255);"` + AccUser string `gorm:"type:VARBINARY(255);"` + AccPass string `gorm:"type:VARBINARY(255);"` + AccError string `gorm:"type:VARBINARY(512);"` + AccErrors int + AccShare bool + AccSync bool + RetryLimit int + SharePath string `gorm:"type:VARBINARY(500);"` + ShareSize string `gorm:"type:VARBINARY(16);"` + ShareExpires int + SyncPath string `gorm:"type:VARBINARY(500);"` + SyncStatus string `gorm:"type:VARBINARY(16);"` + SyncInterval int + SyncDate sql.NullTime `deepcopier:"skip"` + SyncUpload bool + SyncDownload bool + SyncFilenames bool + SyncRaw bool + CreatedAt time.Time `deepcopier:"skip"` + UpdatedAt time.Time `deepcopier:"skip"` + DeletedAt *time.Time `deepcopier:"skip" sql:"index"` +} diff --git a/examples/list.go b/examples/list.go new file mode 100644 index 0000000..43076b5 --- /dev/null +++ b/examples/list.go @@ -0,0 +1,29 @@ +package main + +import ( + photoprism "github.com/kris-nova/client-go" + "github.com/kris-nova/logger" +) + +func main() { + // --- + // Log Level 4 (Most) + // Log Level 3 + // Log Level 2 + // Log Level 1 + // Log Level 0 (Least) + // + logger.Level = 4 + // + // --- + + client := photoprism.New("http://localhost:8080") + err := client.Auth(photoprism.NewClientAuthLogin("admin", "missy")) + if err != nil { + halt(4, "Error logging into API: %v", err) + } + logger.Always("Logged in...") + + + +} diff --git a/sample-app/photoprism/storage/cache/sessions.json b/sample-app/photoprism/storage/cache/sessions.json index b41cc58..04a62a2 100644 --- a/sample-app/photoprism/storage/cache/sessions.json +++ b/sample-app/photoprism/storage/cache/sessions.json @@ -419,6 +419,11 @@ "tokens": null, "expiration": 1613526269423740413 }, + "eb57053b27b37cdca1d7829972d0af55f329dad18a7e3c96": { + "user": "uqnzie01i1nypnt9", + "tokens": null, + "expiration": 1613677531963129666 + }, "ece6e3ed1d36a43bd26843ee5efa547c662cc23423959316": { "user": "uqnzie01i1nypnt9", "tokens": null, diff --git a/sample-app/photoprism/storage/index.db b/sample-app/photoprism/storage/index.db index 78f2ce1..47fb180 100644 Binary files a/sample-app/photoprism/storage/index.db and b/sample-app/photoprism/storage/index.db differ diff --git a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_36A3FD61.yml b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_36A3FD61.yml index 87923ff..6248dfe 100755 --- a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_36A3FD61.yml +++ b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_36A3FD61.yml @@ -1,4 +1,4 @@ -TakenAt: 2021-02-04T03:17:07Z +TakenAt: 2021-02-04T03:21:40Z UID: pqnzigq3sidxb0j0 Type: image Title: Eptcef Voaeias @@ -6,8 +6,7 @@ OriginalName: EpTcef3VoAEiaS4 Year: -1 Month: -1 Day: -1 -Quality: 2 Details: Keywords: black, cat, eptcef, voaeias CreatedAt: 2021-02-04T03:17:14.849461459Z -UpdatedAt: 2021-02-09T18:40:53.525508824Z +UpdatedAt: 2021-02-11T19:46:41.889198363Z diff --git a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_5B740007.yml b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_5B740007.yml index adf248d..ba693e5 100755 --- a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_5B740007.yml +++ b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_5B740007.yml @@ -1,4 +1,4 @@ -TakenAt: 2021-02-04T03:17:07Z +TakenAt: 2021-02-04T03:21:40Z UID: pqnzigq351j2fqgn Type: image Title: A really great photo! @@ -10,8 +10,8 @@ Year: -1 Month: -1 Day: -1 Details: - Keywords: green, mean, tambourine + Keywords: green, tambourine KeywordsSrc: manual CreatedAt: 2021-02-04T03:17:14.613092062Z -UpdatedAt: 2021-02-11T19:24:13.286451278Z +UpdatedAt: 2021-02-11T19:46:41.863716035Z EditedAt: 2021-02-11T19:24:13Z diff --git a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_76642B51.yml b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_76642B51.yml index c6eb31b..dc6e723 100755 --- a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_76642B51.yml +++ b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_76642B51.yml @@ -1,4 +1,4 @@ -TakenAt: 2021-02-04T03:17:07Z +TakenAt: 2021-02-04T03:21:40Z UID: pqnzigq156lndozm Type: image Title: Test Nova @@ -7,9 +7,8 @@ OriginalName: ElgexEiU8AA-pQO Year: -1 Month: -1 Day: -1 -Quality: 3 Details: Keywords: blue, elgexeiu, portrait CreatedAt: 2021-02-04T03:17:14.668332772Z -UpdatedAt: 2021-02-09T18:40:53.626530938Z +UpdatedAt: 2021-02-11T19:46:42.041205155Z EditedAt: 2021-02-09T18:39:46Z diff --git a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_AE1CC552.yml b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_AE1CC552.yml index 0f4a355..35cea8d 100755 --- a/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_AE1CC552.yml +++ b/sample-app/photoprism/storage/sidecar/2021/02/20210204_031706_AE1CC552.yml @@ -1,4 +1,4 @@ -TakenAt: 2021-02-04T03:17:07Z +TakenAt: 2021-02-04T03:21:40Z UID: pqnzigq1jb1bibrz Type: image Title: Seashore @@ -6,8 +6,7 @@ OriginalName: NVA05562 Year: -1 Month: -1 Day: -1 -Quality: 2 Details: Keywords: grey, seashore CreatedAt: 2021-02-04T03:17:14.738798274Z -UpdatedAt: 2021-02-09T18:40:53.807687859Z +UpdatedAt: 2021-02-11T19:46:41.918409745Z