mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-10-29 02:08:30 -04:00
feat: add packet labeling functionality and awaiting text scope for seed photos
This commit is contained in:
1 parent
062bf738b3
commit
cd6f8f1876
8 files changed
+72
-12
No files matched your search
@@ -18,6 +18,12 @@ module PhotosHelper
|
||||
{ photo_dialog: true, photo_label: photo_label(model) }
|
||||
end
|
||||
|
||||
# The link that sets which side of a seed's packet a photo of it is of; an
|
||||
# empty label says it is not of the packet.
|
||||
def packet_label_path(seed, photo, label)
|
||||
photo_association_path(photo_id: photo.id, type: 'seed', id: seed.id, label:)
|
||||
end
|
||||
|
||||
def crop_image_path(crop)
|
||||
thumbnail_url(crop.default_photo)
|
||||
end
|
||||
|
||||
@@ -27,6 +27,9 @@ class PhotoAssociation < ApplicationRecord
|
||||
# Photos of a seed packet say what the packet says, not what the crop looks
|
||||
# like, so a photo labelled as one is left out of a crop's own photos.
|
||||
scope :of_packets, -> { where(photographable_type: 'Seed').where.not(label: nil) }
|
||||
# Those of a seed that has no text from its packet yet, which is what still
|
||||
# needs reading.
|
||||
scope :awaiting_text, -> { of_packets.where(photographable_id: Seed.unscoped.where(packet_text: [nil, '']).select(:id)) }
|
||||
|
||||
def self.item(item_id, item_type)
|
||||
find_by!(photographable_id: item_id, photographable_type: item_type).photographable
|
||||
|
||||
@@ -60,6 +60,12 @@ class Seed < ApplicationRecord
|
||||
photo_associations.find_by(label: side)&.photo
|
||||
end
|
||||
|
||||
# Which side of the packet a photo of this seed is of, if it is of one. Uses
|
||||
# the loaded photo associations, so a page of photos reads them once.
|
||||
def label_of(photo)
|
||||
photo_associations.find { |association| association.photo_id == photo.id }&.label
|
||||
end
|
||||
|
||||
# The packet's front, if there is a photo of it. Otherwise the most liked
|
||||
# photo that is not of the back.
|
||||
def default_photo
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
-# On a seed's own page: whether each of its photos is of the packet, and which
|
||||
-# side. Everyone sees what it is; the seed's owner can change it.
|
||||
- label = seed.photo_associations.find { |association| association.photo_id == photo.id }&.label
|
||||
- label_path = ->(choice) { photo_association_path(photo_id: photo.id, type: 'seed', id: seed.id, label: choice) }
|
||||
- label = seed.label_of(photo)
|
||||
.packet-label.small.mt-1
|
||||
- if label
|
||||
%span.badge.text-bg-secondary= t("seeds.packet.label_#{label}")
|
||||
- if can?(:update, seed)
|
||||
- choices = PhotoAssociation::LABELS['Seed'].without(label)
|
||||
- choices.each do |choice|
|
||||
= link_to t("seeds.packet.mark_#{choice}"), label_path.call(choice), method: :patch, class: 'me-2'
|
||||
- if label
|
||||
= link_to t('seeds.packet.not_packet'), label_path.call(''), method: :patch, class: 'me-2'
|
||||
- PhotoAssociation::LABELS['Seed'].without(label).each do |choice|
|
||||
= link_to t("seeds.packet.mark_#{choice}"), packet_label_path(seed, photo, choice), method: :patch, class: 'me-2'
|
||||
- not_packet_path = packet_label_path(seed, photo, '')
|
||||
= link_to t('seeds.packet.not_packet'), not_packet_path, method: :patch, class: 'me-2' if label
|
||||
@@ -5,10 +5,7 @@ namespace :packets do
|
||||
# usage: rake packets:needing_ocr LIMIT=5
|
||||
task needing_ocr: :environment do
|
||||
limit = ENV.fetch('LIMIT', nil).to_i
|
||||
associations = PhotoAssociation.of_packets
|
||||
.joins('INNER JOIN seeds ON seeds.id = photo_associations.photographable_id')
|
||||
.where(seeds: { packet_text: [nil, ''] })
|
||||
.includes(:photo).order(:photo_id, :id)
|
||||
associations = PhotoAssociation.awaiting_text.includes(:photo).order(:photo_id, :id)
|
||||
associations = associations.limit(limit) if limit.positive?
|
||||
|
||||
associations.each do |association|
|
||||
|
||||
@@ -31,12 +31,12 @@ Needs only the python3 standard library, and whatever OCR command is used.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import os
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe PhotoAssociation, '.awaiting_text' do
|
||||
let(:seed) { create(:seed) }
|
||||
|
||||
def attach(item, label)
|
||||
item.photo_associations.create!(photo: create(:photo, owner: item.owner), label:)
|
||||
end
|
||||
|
||||
it 'has the photos of a packet whose seed has no text' do
|
||||
association = attach(seed, 'back')
|
||||
expect(described_class.awaiting_text).to eq [association]
|
||||
end
|
||||
|
||||
it 'has the photos of a packet whose seed has only empty text' do
|
||||
seed.update!(packet_text: '')
|
||||
association = attach(seed, 'front')
|
||||
expect(described_class.awaiting_text).to eq [association]
|
||||
end
|
||||
|
||||
it 'leaves out a seed that has its text' do
|
||||
attach(create(:seed, packet_text: 'Sow by: December 2026'), 'back')
|
||||
expect(described_class.awaiting_text).to be_empty
|
||||
end
|
||||
|
||||
it 'leaves out a photo that is not of the packet' do
|
||||
attach(seed, nil)
|
||||
expect(described_class.awaiting_text).to be_empty
|
||||
end
|
||||
|
||||
it 'leaves out the photos of something that is not a seed' do
|
||||
attach(create(:job), 'before')
|
||||
expect(described_class.awaiting_text).to be_empty
|
||||
end
|
||||
end
|
||||
@@ -21,4 +21,17 @@ describe Seed, '#packet_photo' do
|
||||
|
||||
it('is nothing') { expect(seed.packet_photo('back')).to be_nil }
|
||||
end
|
||||
|
||||
describe '#label_of' do
|
||||
it('is front for the front') { expect(seed.reload.label_of(front)).to eq 'front' }
|
||||
it('is back for the back') { expect(seed.reload.label_of(back)).to eq 'back' }
|
||||
|
||||
it('is nothing for a photo that is not of the packet') do
|
||||
expect(seed.reload.label_of(seed.photos.reject { |photo| [front, back].include?(photo) }.first)).to be_nil
|
||||
end
|
||||
|
||||
it('is nothing for a photo that is not of this seed') do
|
||||
expect(seed.reload.label_of(create(:photo, owner: seed.owner))).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user