implement dummy printer

This commit is contained in:
2025-04-10 14:26:20 +02:00
parent 9e3a04cd78
commit f87a6352dd
4 changed files with 170 additions and 55 deletions

View File

@@ -3,6 +3,7 @@ package controllers
import (
"fmt"
"net/http"
"strconv"
"example.com/gin/test/models"
"example.com/gin/test/repositories"
@@ -11,7 +12,8 @@ import (
type PrintController interface {
PrintVariantView(*gin.Context)
PrintVariantHandler(*gin.Context)
PrintCartView(*gin.Context)
PrintHandler(*gin.Context)
}
type printController struct{}
@@ -25,12 +27,14 @@ func (rc *printController) PrintVariantView(c *gin.Context) {
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
shopItem, err := repositories.ShopItems.GetById(fmt.Sprintf("%v", variant.ShopItemID))
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
type ShopItemVariantPair struct {
@@ -49,27 +53,86 @@ func (rc *printController) PrintVariantView(c *gin.Context) {
c.HTML(http.StatusOK, "printvariant.html", data)
}
func (rc *printController) PrintVariantHandler(c *gin.Context) {
err := repositories.ShopItems.DeleteById(c.Param("id"))
func (rc *printController) PrintCartView(c *gin.Context) {
sessionId := GetSessionId(c)
cartItems, err := repositories.CartItems.GetAllBySession(sessionId)
if err != nil {
data := CreateSessionData(c, gin.H{
"error": err,
"success": "",
})
c.HTML(http.StatusOK, "deleteitem.html", data)
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
shopItems, _ := repositories.ShopItems.GetAll()
fmt.Println(len(shopItems))
type ShopItemVariantPair struct {
ShopItem models.ShopItem
ItemVariant models.ItemVariant
}
var items []ShopItemVariantPair
for _, cartItem := range cartItems {
items = append(items, ShopItemVariantPair{ShopItem: cartItem.ShopItem, ItemVariant: cartItem.ItemVariant})
}
data := CreateSessionData(c, gin.H{
"title": "shopItem Page",
"shopItems": shopItems,
"itemVariants": items,
})
fmt.Println(data)
c.HTML(http.StatusOK, "index.html", data)
c.HTML(http.StatusOK, "printvariant.html", data)
}
func (rc *printController) PrintHandler(c *gin.Context) {
variantIds := c.PostFormArray("variant-id[]")
variantAmounts := c.PostFormArray("variant-amount[]")
variantCoverPages := c.PostFormArray("variant-coverpage[]")
if len(variantIds) != len(variantAmounts) || len(variantIds) != len(variantCoverPages) {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": "Invalid arguments"}})
return
}
var printJobs []models.PrintJob
for idx := range variantIds {
variant, err := repositories.ShopItems.GetVariantById(variantIds[idx])
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
shopItem, err := repositories.ShopItems.GetById(fmt.Sprintf("%v", variant.ShopItemID))
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
coverPage := false
if variantCoverPages[idx] == "1" {
coverPage = true
}
variantAmount, err := strconv.Atoi(variantAmounts[idx])
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
printJob, err := models.NewPrintJob(shopItem, variant, coverPage, uint(variantAmount))
if err != nil {
c.HTML(http.StatusBadRequest, "error.html", gin.H{"data": gin.H{"error": err}})
return
}
printJobs = append(printJobs, printJob)
}
executeJobs := func() {
for _, printJob := range printJobs {
printJob.Execute()
}
}
go executeJobs()
c.HTML(http.StatusOK, "index.html", nil)
}

View File

@@ -83,7 +83,9 @@ func main() {
viewRoutes.GET("/shopitems/:id/delete", authValidator.RequireAuth, shopItemController.DeleteItemView)
viewRoutes.POST("/shopitems/:id/delete", authValidator.RequireAuth, shopItemController.DeleteItemHandler)
viewRoutes.GET("/variant/:id/print", authValidator.RequireAuth, printController.PrintVariantView)
viewRoutes.POST("/variant/:id/print", authValidator.RequireAuth, printController.PrintVariantHandler)
viewRoutes.GET("/cart/print", authValidator.RequireAuth, printController.PrintCartView)
viewRoutes.POST("/print", authValidator.RequireAuth, printController.PrintHandler)
viewRoutes.GET("/tags", authValidator.RequireAuth, shopItemController.TagView)
viewRoutes.POST("/tags/:id", authValidator.RequireAuth, shopItemController.TagHandler)
viewRoutes.POST("/tags", authValidator.RequireAuth, shopItemController.AddTagHandler)

55
models/printer.go Normal file
View File

@@ -0,0 +1,55 @@
package models
import (
"fmt"
)
type PrintOption string
const (
CoverPage PrintOption = "-o FrontCoverPage=Printed -o FrontCoverTray=BypassTray -o InputSlot=Tray1"
Colored PrintOption = "-o SelectColor=Color"
Grayscale PrintOption = "-o SelectColor=Grayscale"
)
type PrintJob struct {
Pdf string
Amount uint
Options []PrintOption
}
func NewPrintJob(shopItem ShopItem, variant ItemVariant, coverPage bool, amount uint) (PrintJob, error) {
if shopItem.Pdf == "" {
return PrintJob{}, fmt.Errorf("ShopItem has no PDF assigned")
}
if amount > 100 {
return PrintJob{}, fmt.Errorf("Amount to big. This is denied for security reasons")
}
var result PrintJob
result.Pdf = shopItem.Pdf
result.Amount = amount
if variant.Name == "Colored" {
result.Options = append(result.Options, Colored)
}
if coverPage {
result.Options = append(result.Options, CoverPage)
}
return result, nil
}
func (p *PrintJob) Execute() error {
baseCommand := "lp -p KONICA_MINOLTA_KONICA_MINOLTA_bizhub_C258/Booklet "
baseCommand += fmt.Sprintf("-n %v ", p.Amount)
for _, option := range p.Options {
baseCommand += fmt.Sprintf(" %v ", option)
}
fmt.Println(baseCommand)
return nil
}

View File

@@ -17,52 +17,47 @@
</p>
<form action="#" method="POST">
<table class="w-full text-left font-medium text-gray-900 dark:text-white ">
<tbody class="divide-y divide-gray-200 dark:divide-gray-800">
{{ range .data.itemVariants }}
<tr>
<form action="/print" method="POST">
<table class="w-full text-left font-medium text-gray-900 dark:text-white">
<tbody class="divide-y divide-gray-200 dark:divide-gray-800">
{{ range .data.itemVariants }}
<tr>
<input type="hidden" name="variant-id[]" value="{{ .ItemVariant.ID }}" required>
<td class="whitespace-nowrap py-4">
<div class="flex items-center gap-4">
<a href="/shopitems/{{ .ItemVariant.ShopItemID }}" class="flex items-center aspect-square w-8 h-10 shrink-0">
<img class="h-auto w-full max-h-full dark:hidden" src="/{{ .ShopItem.Image }}" alt="imac image" />
</a>
<a href="/shopitems/{{ .ItemVariant.ShopItemID }}" class="hover:underline">{{ .ShopItem.Name }} - {{ .ItemVariant.Name }}</a>
</div>
<div class="flex items-center gap-4">
<a href="/shopitems/{{ .ItemVariant.ShopItemID }}" class="flex items-center aspect-square w-8 h-10 shrink-0">
<img class="h-auto w-full max-h-full dark:hidden" src="/{{ .ShopItem.Image }}" alt="imac image" />
</a>
<a href="/shopitems/{{ .ItemVariant.ShopItemID }}" class="hover:underline">{{ .ShopItem.Name }} - {{ .ItemVariant.Name }}</a>
</div>
</td>
<td class="whitespace-nowrap py-4">
<select name="variant-coverpage[]" required class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
<option selected value="0">Normal</option>
<option value="1">CoverPage</option>
</select>
</td>
<td class="whitespace-nowrap py-4">
<label class="flex text-sm/6 items-center">
<input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="CoverPage" name="CoverPage">
<span class="ml-2 text-sm/6 text-gray-900">CoverPage</span>
</label>
</td>
<td class="whitespace-nowrap py-4">
Amount:
Amount:
</td>
<td class="p-4 text-right text-base font-bold text-gray-900 dark:text-white">
<div>
<input type="hidden" id="variant-name1" name="variant-name[]" value="B/W" required>
<div class="mt-2">
<input type="number" name="variant-value[]" id="variant-value1" step="1" min="1" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
<div>
<div class="mt-2">
<input type="number" name="variant-amount[]" step="1" min="0" required class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
</div>
</div>
</div>
</td>
</tr>
{{ end }}
</tbody>
</table>
</tr>
{{ end }}
</tbody>
</table>
<div class="max-lg:max-w-lg max-lg:mx-auto">
<p class="font-normal text-base leading-7 text-gray-500 text-center mb-5 mt-6">If CoverPage
selected, make sure you put paper in the BypassTray</p>
<button type="submit"
class="rounded-full py-4 px-6 bg-indigo-600 text-white font-semibold text-lg w-full text-center
transition-all duration-500 hover:bg-indigo-700 ">Print</button>
</div>
</form>
<div class="max-lg:max-w-lg max-lg:mx-auto">
<p class="font-normal text-base leading-7 text-gray-500 text-center mb-5 mt-6">If CoverPage selected, make sure you put paper in the BypassTray</p>
<button type="submit" class="rounded-full py-4 px-6 bg-indigo-600 text-white font-semibold text-lg w-full text-center transition-all duration-500 hover:bg-indigo-700">Print</button>
</div>
</form>
</div>
</div>
</div>