Files
shopdb/apiprinters.asp
cproudlock fd295ef35e apiprinters.asp: expose mapleft + maptop for installer map UI
Adds p.mapleft, p.maptop to the SELECT and emits them as JSON values
(literal null when the columns are NULL). Consumed by the new
PrinterInstallerMap inno installer (feature/printer-map branch in
inno-installers) which renders the same Leaflet-style site map inside
a custom Inno wizard page rather than a browser, dodging the Edge
policy that blocks .bat downloads and unsigned .exe runs.

Additive change: existing consumers (PrinterInstaller.iss, tests,
installprinter.asp) read JSON by key name and ignore unknown fields.
SELECT change is additive too; no rs(0) numeric indexing in the
codebase. Schema-side: printers.mapleft, maptop already exist (they
are read by printerinstallermap.asp).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 07:53:48 -04:00

197 lines
8.5 KiB
Plaintext

<%@ Language=VBScript %>
<%
' API endpoint to return printer data as JSON
' Used by PrinterInstaller to fetch available printers
Response.ContentType = "application/json"
Response.Charset = "UTF-8"
' Disable caching
Response.AddHeader "Cache-Control", "no-cache, no-store, must-revalidate"
Response.AddHeader "Pragma", "no-cache"
Response.AddHeader "Expires", "0"
%><!--#include file="./includes/sql.asp"--><%
' Query all active HP, Xerox, and HID printers with network addresses
Dim strSQL, rs, jsonOutput, isFirst
strSQL = "SELECT p.printerid, p.printerwindowsname, p.printercsfname, p.fqdn, p.ipaddress, " & _
"v.vendor, m.modelnumber, p.isactive, ma.alias, ma.machinenumber, p.installpath, " & _
"p.mapleft, p.maptop " & _
"FROM printers p " & _
"LEFT JOIN models m ON p.modelid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"LEFT JOIN machines ma ON p.machineid = ma.machineid " & _
"WHERE p.isactive = 1 " & _
"AND (v.vendor = 'HP' OR v.vendor = 'Xerox' OR v.vendor = 'HID') " & _
"ORDER BY " & _
"CASE WHEN p.printercsfname IS NOT NULL AND p.printercsfname != '' AND p.printercsfname != 'NONE' THEN 0 ELSE 1 END, " & _
"p.printercsfname, COALESCE(ma.alias, ma.machinenumber), v.vendor, m.modelnumber"
Set rs = objConn.Execute(strSQL)
' Build JSON array
jsonOutput = "["
isFirst = True
Do While Not rs.EOF
' Skip printers without a network address
If (Not IsNull(rs("fqdn")) And rs("fqdn") <> "") Or (Not IsNull(rs("ipaddress")) And rs("ipaddress") <> "" And rs("ipaddress") <> "USB") Then
If Not isFirst Then
jsonOutput = jsonOutput & ","
End If
isFirst = False
jsonOutput = jsonOutput & vbCrLf & " {"
jsonOutput = jsonOutput & vbCrLf & " ""printerid"": " & rs("printerid") & ","
' Escape quotes in string values
Dim printerName, csfName, fqdn, ipAddr, vendor, model, machineAlias, machineNumber, machineName, standardName
printerName = Replace(rs("printerwindowsname") & "", """", "\""")
csfName = Replace(rs("printercsfname") & "", """", "\""")
fqdn = Replace(rs("fqdn") & "", """", "\""")
ipAddr = Replace(rs("ipaddress") & "", """", "\""")
vendor = Replace(rs("vendor") & "", """", "\""")
model = Replace(rs("modelnumber") & "", """", "\""")
' Get machine name (prefer alias, fallback to machinenumber)
machineAlias = rs("alias") & ""
machineNumber = rs("machinenumber") & ""
If machineAlias <> "" Then
machineName = machineAlias
Else
machineName = machineNumber
End If
machineName = Replace(machineName, """", "\""")
' Generate standardized printer name: CSFName-Location-Brand-Description
' Per naming convention: CSF##-Location-Brand-Description
' Remove spaces and "Machine" word from names
Dim cleanMachine, cleanModel, shortDescription
cleanMachine = Replace(machineName, " ", "")
cleanMachine = Replace(cleanMachine, "Machine", "")
' Extract short description from model number
' Examples: "Color LaserJet M254dw" -> "ColorLaserJet"
' "Altalink C8135" -> "Altalink"
' "Versalink C7125" -> "Versalink"
cleanModel = Replace(model, " ", "")
' Try to extract base model name (remove version numbers and suffixes)
If InStr(cleanModel, "ColorLaserJet") > 0 Then
shortDescription = "ColorLaserJet"
ElseIf InStr(cleanModel, "LaserJetPro") > 0 Then
shortDescription = "LaserJetPro"
ElseIf InStr(cleanModel, "LaserJet") > 0 Then
shortDescription = "LaserJet"
ElseIf InStr(cleanModel, "Altalink") > 0 Then
shortDescription = "Altalink"
ElseIf InStr(cleanModel, "Versalink") > 0 Then
shortDescription = "Versalink"
ElseIf InStr(cleanModel, "DesignJet") > 0 Then
shortDescription = "DesignJet"
ElseIf InStr(cleanModel, "DTC") > 0 Then
shortDescription = "DTC"
Else
' Fallback: Extract model prefix before numbers
' For models like "EC8036" -> "EC", "C7125" -> "C"
Dim i, char
shortDescription = ""
For i = 1 To Len(cleanModel)
char = Mid(cleanModel, i, 1)
' Stop when we hit a number
If char >= "0" And char <= "9" Then
Exit For
End If
shortDescription = shortDescription & char
Next
' If we got nothing (started with number), use full model
If shortDescription = "" Then
shortDescription = cleanModel
End If
End If
' Determine printer name to use
' Prefer Windows Name from database if it's already in standardized format (contains dashes)
' Otherwise generate standardized name automatically
If InStr(printerName, "-") > 0 Then
' Use database Windows Name as-is (user manually set it)
standardName = printerName
Else
' Generate standard name: CSFName-Location-VendorModel (no dash between vendor and model)
If csfName <> "" And csfName <> "NONE" And csfName <> "gage lab " Then
' Has CSF name
' Check if CSF name already matches the machine location (avoid duplication)
If cleanMachine <> "" And LCase(csfName) <> LCase(cleanMachine) Then
standardName = csfName & "-" & cleanMachine & "-" & vendor & shortDescription
Else
' CSF name same as location, or no location - just use CSF-VendorModel
standardName = csfName & "-" & vendor & shortDescription
End If
Else
' No CSF name - use Location-VendorModel
If cleanMachine <> "" Then
standardName = cleanMachine & "-" & vendor & shortDescription
Else
standardName = "Printer" & rs("printerid") & "-" & vendor & shortDescription
End If
End If
End If
standardName = Replace(standardName, """", "\""")
' Escape install path
Dim installPath, preferredAddress
installPath = Replace(rs("installpath") & "", """", "\""")
' Determine preferred address: FQDN if exists, otherwise IP
If fqdn <> "" And fqdn <> "USB" Then
preferredAddress = fqdn
Else
preferredAddress = ipAddr
End If
preferredAddress = Replace(preferredAddress, """", "\""")
jsonOutput = jsonOutput & vbCrLf & " ""printerwindowsname"": """ & standardName & ""","
jsonOutput = jsonOutput & vbCrLf & " ""printercsfname"": """ & csfName & ""","
jsonOutput = jsonOutput & vbCrLf & " ""fqdn"": """ & fqdn & ""","
jsonOutput = jsonOutput & vbCrLf & " ""ipaddress"": """ & ipAddr & ""","
jsonOutput = jsonOutput & vbCrLf & " ""address"": """ & preferredAddress & ""","
jsonOutput = jsonOutput & vbCrLf & " ""vendor"": """ & vendor & ""","
jsonOutput = jsonOutput & vbCrLf & " ""modelnumber"": """ & model & ""","
jsonOutput = jsonOutput & vbCrLf & " ""machinename"": """ & machineName & ""","
jsonOutput = jsonOutput & vbCrLf & " ""installpath"": """ & installPath & ""","
' mapleft / maptop are nullable INTs (pixel coords on the site map
' for printerinstallermap.asp + PrinterInstallerMap.exe). Emit JSON
' literal null when the column is NULL so consumers can detect "no
' map coords for this printer" without resorting to magic numbers.
Dim mapLeftVal, mapTopVal
If IsNull(rs("mapleft")) Then
mapLeftVal = "null"
Else
mapLeftVal = CStr(rs("mapleft"))
End If
If IsNull(rs("maptop")) Then
mapTopVal = "null"
Else
mapTopVal = CStr(rs("maptop"))
End If
jsonOutput = jsonOutput & vbCrLf & " ""mapleft"": " & mapLeftVal & ","
jsonOutput = jsonOutput & vbCrLf & " ""maptop"": " & mapTopVal & ","
jsonOutput = jsonOutput & vbCrLf & " ""isactive"": " & LCase(CStr(CBool(rs("isactive"))))
jsonOutput = jsonOutput & vbCrLf & " }"
End If
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
objConn.Close
jsonOutput = jsonOutput & vbCrLf & "]"
Response.Write(jsonOutput)
%>