Print open home-gitops issues on the Epson receipt printer
deploy / deploy (push) Successful in 10s

Reads a Gitea API token from .gitea_token (gitignored, not present yet --
needs creating on the server), fetches open issues via the API, and prints
number/title/labels per issue with a running total. Button on the home page.
This commit is contained in:
randy committed 2026-09-13 11:43:53 +02:00
1 parent abb4eb0edb
commit b44985b75f
3 files changed
+61

No files matched your search

+1
View File
@@ -1,4 +1,5 @@
.session_secret .session_secret
.gitea_token
public/files/* public/files/*
!public/files/.gitkeep !public/files/.gitkeep
data/labels/* data/labels/*
+50
View File
@@ -3,6 +3,7 @@ require 'sinatra'
require "sinatra/reloader" require "sinatra/reloader"
require 'tmpdir' require 'tmpdir'
require 'net/http' require 'net/http'
require 'json'
require_relative 'lib/receipt_builder' require_relative 'lib/receipt_builder'
require_relative 'lib/label_repository' require_relative 'lib/label_repository'
@@ -154,6 +155,45 @@ helpers do
receipt.print!(PRINTER_DEVICE_EPSON) receipt.print!(PRINTER_DEVICE_EPSON)
end end
GITEA_TOKEN_FILE = File.join(File.dirname(__FILE__), '.gitea_token')
def fetch_open_issues(repo)
token = File.read(GITEA_TOKEN_FILE).strip
uri = URI("https://git.priesol.net/api/v1/repos/randy/#{repo}/issues?state=open&type=issues&limit=50")
req = Net::HTTP::Get.new(uri)
req['Authorization'] = "token #{token}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
raise "Gitea API returned #{res.code}" unless res.is_a?(Net::HTTPSuccess)
JSON.parse(res.body)
end
# Prints a receipt-style summary of a repo's open issues -- number, title,
# labels, one separator per issue, total at the end.
def print_issues(repo)
issues = fetch_open_issues(repo).sort_by { |i| i['number'] }
receipt = ReceiptBuilder.new
receipt.align(:center).bold.text("Open issues: #{repo}\n").bold(false)
receipt.text("#{Time.now.strftime('%Y-%m-%d %H:%M')}\n")
receipt.align(:left).text(('-' * 32) + "\n")
if issues.empty?
receipt.text("(no open issues)\n")
else
issues.each do |issue|
receipt.bold.text("##{issue['number']} #{issue['title']}\n").bold(false)
labels = issue['labels'].map { |l| l['name'] }.join(', ')
receipt.text("#{labels}\n") unless labels.empty?
receipt.text(('-' * 32) + "\n")
end
end
receipt.text("Total: #{issues.size}\n")
receipt.feed(3).cut
receipt.print!(PRINTER_DEVICE_EPSON)
end
# Renders ZPL to a PNG via Labelary's public API for an inline preview. # Renders ZPL to a PNG via Labelary's public API for an inline preview.
# Fixed at the Datamax label size (4x6in @ 8dpmm ~= 203dpi) -- good enough # Fixed at the Datamax label size (4x6in @ 8dpmm ~= 203dpi) -- good enough
# for a thumbnail, not meant to be exact for other sizes. # for a thumbnail, not meant to be exact for other sizes.
@@ -213,6 +253,16 @@ get '/' do
erb :index erb :index
end end
post '/issues/print' do
begin
print_issues('home-gitops')
flash 'Open issues sent to printer', 'success'
rescue => e
flash "Failed to print issues (#{e.message})", 'danger'
end
redirect '/'
end
get '/upload' do get '/upload' do
erb :upload erb :upload
end end
+10
View File
@@ -9,3 +9,13 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="card mt-3">
<div class="card-body">
<h5 class="card-title">home-gitops open issues</h5>
<p class="card-text">Print a receipt-style summary of currently open issues.</p>
<form action="/issues/print" method="POST">
<button class="btn btn-secondary" type="submit">Print open issues</button>
</form>
</div>
</div>