Printing via Winspool - winapi

I'm trying to set up a kind of print service for a website to communicate with and send printable documents to (pdf, html, excel). I decided on Go.
I created the simple program below. On some PCs it works (Windows 7) on other ones (Windows 8) it doesn't work (right). When it doesn't work the job is visible in the print queue for less then a second and then disappears. The code doesn't output any errors. I can't find anything in the Windows event log.
I also tried a RawPrinter example in c++ I could find online but that shows the same behavior.
Does anyone know what I'm doing wrong? :(
package main
import (
"fmt"
"code.google.com/p/brainman/printer"
)
func main() {
defaultPrinterName, _ := printer.Default()
fmt.Println(defaultPrinterName)
p, err := printer.Open(defaultPrinterName)
if err != nil {
fmt.Println("Open failed: %v", err)
}
defer p.Close()
err = p.StartDocument("my document", "RAW")
if err != nil {
fmt.Println("StartDocument failed: %v", err)
}
defer p.EndDocument()
err = p.StartPage()
if err != nil {
fmt.Println("StartPage failed: %v", err)
}
str := "testing 123"
mySlice := []byte(str)
_, err = p.Write(mySlice)
if err != nil {
fmt.Println("Write failed: %v", err)
}
err = p.EndPage()
if err != nil {
fmt.Println("EndPage failed: %v", err)
}
}

You're using the datatype "RAW", it should be "XPS_PASS".
Windows 8 (and Server 2012) uses XPS-based drivers so you can't use the RAW flag.
Check out these articles:
http://support.microsoft.com/kb/2779300
http://msdn.microsoft.com/en-us/library/windows/desktop/ff686812%28v=vs.85%29.aspx

Related

Upload image fails with error "dial tcp: lookup api.cloudinary.com: no such host"

I have been trying to upload to cloudinary via golang sdk. but sometimes it seems to fail after several requests (sometimes it works, other times it doesn't).
I run the app in localhost (windows) and without vpn.
error message:
"https://api.cloudinary.com/v1_1/dd6mdlpgj/auto/upload": dial tcp: lookup api.cloudinary.com: no such host
type cloudinaryStorageRepository struct {
cld *cloudinary.Cloudinary
}
func NewCloudinaryStorageRepository(cloudName string, apiKey string, apiSecret string) domain.StorageRepository {
cld, err := cloudinary.NewFromParams(cloudName, apiKey, apiSecret)
if err != nil {
panic(err)
}
return &cloudinaryStorageRepository{cld}
}
func (c *cloudinaryStorageRepository) Upload(ctx context.Context, storage *domain.Storage) (string, error) {
file, err := storage.File.Open()
defer func(file multipart.File) {
err := file.Close()
if err != nil {
logrus.Error(err)
}
}(file)
if err != nil {
logrus.Error(err)
return "", err
}
uploaded, err := c.cld.Upload.Upload(ctx, file, uploader.UploadParams{
Folder: storage.Folder,
PublicID: storage.Name,
})
if err != nil {
logrus.Error(err)
return "", err
}
return uploaded.SecureURL, nil
}
If I understand you correctly, you can try to reset your DNS on your computer or use another computer to run the code because it might be a misconfiguration of your local host.

Transfering file using tcp golang

I'm trying to make a music app that sends file through tcp protocol using go and microservice architecture. Now I'm creating a player service that should:
Get user token and get claims from it
Check is user exists using claims and user_service microservice
Get song from redis
Check is song exists using music_service
Read file by chunks and send it to client using tcp
Redis data looks like this:
{
"user_id": [{
"song_id": "<song_id>"
}]
}
But I faced with a small problem. My music files stored in a flac format and when I receive it on the client, my player doesn't play it. I don't really know what can be the problem. So here's my code:
SERVER
service_setup.go
//this function is called in main function
func setService() {
ln, err := net.Listen("tcp", config.TCPAddress)
if err != nil {
panic("couldn't start tcp server")
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
logger.ErrorLog(fmt.Sprintf("Error: couldn't accept connection. Details: %v", err))
return
}
service.DownloadSong(conn)
}
}
downloader_service.go
func DownloadSong(conn net.Conn) {
token, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
logger.ErrorLog(fmt.Sprintf("Error: couldn't get token. Details: %v", token))
conn.Close()
return
}
claims, err := jwt_funcs.DecodeJwt(token)
if err != nil {
conn.Close()
return
}
songs, err := redis_repo.Get(claims.Id)
if err != nil {
conn.Close()
return
}
for _, song := range songs {
download(song, conn)
}
}
func download(song models.SongsModel, conn net.Conn) {
filePath, err := filepath.Abs(fmt.Sprintf("./songs/%s.flac", song.SongId))
if err != nil {
logger.ErrorLog(fmt.Sprintf("Errror: couldn't create filepath. Details: %v", err))
conn.Close()
return
}
file, err := os.Open(filePath)
defer file.Close()
if err != nil {
logger.ErrorLog(fmt.Sprintf("Errror: couldn't open file. Details: %v", err))
conn.Close()
return
}
read(file, conn)
}
func read(file *os.File, conn net.Conn) {
reader := bufio.NewReader(file)
buf := make([]byte, 15)
defer conn.Close()
for {
_, err := reader.Read(buf)
if err != nil && err == io.EOF {
logger.InfoLog(fmt.Sprintf("Details: %v", err))
fmt.Println()
return
}
conn.Write(buf)
}
}
CLIENT
main.go
func main() {
conn, _ := net.Dial("tcp", "127.0.0.1:6060")
var glMessage []byte
text := "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzYzlhNmE1OWI3ZmQyNTQ2ZjA4ZWEyYSIsInVzZXJuYW1lIjoiMTIiLCJleHAiOjE2NzQyMTE5ODl9.aarSDhrFF1df3i2pIRyjNxTfSHKObqLU3kHJiPreredIhLNCzs7z7jMgRHQIcLaIvCOECN7bX0OaSvKdW7VKsQ\n"
fmt.Fprint(conn, text)
reader := bufio.NewReader(conn)
b := make([]byte, 15)
c := 0
for i, _ := reader.Read(b); int(i) != 0; i, _ = reader.Read(b) {
c += i
glMessage = append(glMessage, b...)
}
os.WriteFile("./test.flac", glMessage, 0644)
}
If you know what can be the problem, please tell me. I'd really appreciate it!
It looks like you're trying to send the music file over the network in 15 byte chunks, which is likely not enough to play the song on the client side.
You can try increasing the chunk size, for example, to 8192 bytes. To do this, replace buf := make([]byte, 15) with buf := make([]byte, 8192).
Also, it's better to write the received data directly to the file rather than storing it in memory. You can do this by creating a file and using os.Create to write the received data to it:
file, err := os.Create("./test.flac")
if err != nil {
fmt.Println("Error: couldn't create file")
return
}
defer file.Close()
for {
i, err := reader.Read(buf)
if err != nil && err == io.EOF {
break
}
file.Write(buf[:i])
}
I believe that this can solve the issue.

How to use commands conveyor in Goland powershell terminal?

I have written two simple applications on Golang. The first app fetch.go displays html content of the main page by incoming links in arguments. The second app findlinks1.go find all href links in html tree. Here's the snippets:
func main() {
for _, url := range os.Args[1:] {
resp, err := http.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
os.Exit(1)
}
b, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
os.Exit(1)
}
fmt.Printf("%s", b)
}
}
func main() {
doc, err := html.Parse(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "findlinks1: %v\n", err)
}
for _, link := range visit(nil, doc) {
fmt.Println(link)
}
//it doesn't matter what the visit function does
}
I want to redirect the output of the 1st program to the input of the 2nd program in powershell terminal in Goland development environment, but I can't.
I have tried to run these commands in terminal:
./fetch.go https://golang.org | ./findlinks1.go
I got an error:
InvalidOperation: Cannot run a document in the middle of a pipeline
go run fetch.go https://golang.org | go run findlinks1.go
I didn't get an error, but nothing happened after running this

Testing NATS-streaming in Kubernetes with minimal effort

I wanted to test a very basic application for NATS-streaming on Kubernetes. To do so, I followed the commands from the official NATS-docs.
It basically comes down to running
kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-server/single-server-nats.yml
kubectl apply -f https://raw.githubusercontent.com/nats-io/k8s/master/nats-streaming-server/single-server-stan.yml
in a terminal with access to the cluster (it's a kind-cluster in my case).
I used stan.go as the NATS-streaming-client. Here is the code I tried to connect to the NATS-streaming-server:
package main
import stan "github.com/nats-io/stan.go"
func main() {
sc, err := stan.Connect("stan", "test-client")
if err != nil {
panic(err)
}
if err := sc.Publish("test-subject", []byte("This is a test-message!")); err != nil {
panic(err)
}
}
and this is the error I'm getting:
panic: nats: no servers available for connection
goroutine 1 [running]:
main.main()
/Users/thilt/tmp/main.go:9 +0x15d
exit status 2
so I think another name was used for the cluster or something. If I use the provided example with nats-box from the docs.nats-link above, it also doesn't work! Where did I go wrong here?
I will happily provide more information, if needed.
There is a great example in stan.go docs:
// Connect to NATS
nc, err := nats.Connect(URL, opts...)
if err != nil {
log.Fatal(err)
}
defer nc.Close()
sc, err := stan.Connect(clusterID, clientID, stan.NatsConn(nc))
if err != nil {
log.Fatalf("Can't connect: %v.\nMake sure a NATS Streaming Server is running at: %s", err, URL)
}
defer sc.Close()
Your error happens because by default stan connects to localhost address (source code):
// DefaultNatsURL is the default URL the client connects to
DefaultNatsURL = "nats://127.0.0.1:4222"
Notice that povided above example overwrite this default connection.
Stan source code is short and easy to analyze. I really recommend you to try to analyze it and figure out what it does.
Now let's put it all together; here is a working example:
package main
import (
nats "github.com/nats-io/nats.go"
stan "github.com/nats-io/stan.go"
)
func main() {
// Create a NATS connection
nc, err := nats.Connect("nats://nats:4222")
if err != nil {
panic(err)
}
// Then pass it to the stan.Connect() call.
sc, err := stan.Connect("stan", "me", stan.NatsConn(nc))
if err != nil {
panic(err)
}
if err := sc.Publish("test-subject", []byte("This is a test-message!")); err != nil {
panic(err)
}
}

One file two different outputs - Windows Server 2012

My program reads in an sql file and performs operation on a database.
I edited one of the sql files on the server via notepad yesterday.
I made one more change on the same file today, again via notepad.
When program reads in the file, the changes I made to the sql are not there.
Printing the sql contents to the console reveals that the binary is reading in the version from yesterday.
What black magic is at play here?
Deleting the file does not work.
If I create it again the Date created time stamp is from 1 month ago. Date modified is from yesterday.
Opening the file in notepad, wordpad any text reader you can think of shows the correct contents.
Binary reads the version from yesterday.
This is how the binary reads the file
file, err := ioutil.ReadFile("appointment.sql")
if err != nil {
log.Fatal(err)
}
Program was cross compiled for windows on a mac.
Sql files were written originally on a mac via vim and then uploaded to the server.
EDIT: I include the code from the method after suggested debugging.
func (r *Icar) ReadAppointments(qCfg dms.QueryConfig) []dms.Appointment {
// r.conn contains the db connection
/*DEBUGGING*/
name := "appointment.sql"
fmt.Printf("%q\n", name)
path, err := filepath.Abs(name)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", path) //correct path
file, err := ioutil.ReadFile("appointment.sql")
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", file) //correct output
/*END*/
appointmentQuery := string(file)
fmt.Println(appointmentQuery) //correct output
appointmentQuery = strings.Replace(appointmentQuery, "#", qCfg.QueryLocationID, -1)
fmt.Println(appointmentQuery) //correct output
rows, err := r.conn.Query(appointmentQuery)
if err != nil {
fmt.Println(appointmentQuery) //wrong output. output contains edits from a previous version
log.Fatal("Error reading from the database: %s", err.Error())
}
appointments := []dms.Appointment{}
var (
ExternalID,
WONumber,
CustomerWaiting interface{}
)
for rows.Next() {
appointment := dms.Appointment{}
err = rows.Scan(&ExternalID, &WONumber, &appointment.AppointmentDate, &CustomerWaiting)
if err != nil {
fmt.Println(appointmentQuery)
log.Fatal(err)
}
toStr := []interface{}{ExternalID, WONumber}
toInt := []interface{}{CustomerWaiting}
convertedString := d.ConvertToStr(toStr)
convertedInt := d.ConvertToInt(toInt)
appointment.ExternalID = convertedString[0]
appointment.WONumber = convertedString[1]
appointment.CustomerWaiting = convertedInt[0]
appointments = append(appointments, appointment)
}
err = rows.Close()
return appointments
}
I close the db connection in a deferred statement in my main func.
Here is the constructor for reference
func New(config QueryConfig) (*Icar, func()) {
db, err := sql.Open("odbc", config.Connection)
if err != nil {
log.Fatal("The database doesn't open correctly:\n", err.Error())
}
icar := &Icar{
conn: db,
}
return icar, func() {
icar.conn.Close()
}
}
Basic debugging says check your inputs and outputs. You may be looking at different files. Clearly, "appointment.sql" is not necessarily unique in the file system. For example, does this give you expected results?
package main
import (
"fmt"
"io/ioutil"
"log"
"path/filepath"
)
func main() {
name := "appointment.sql"
fmt.Printf("%q\n", name)
path, err := filepath.Abs(name)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", path)
file, err := ioutil.ReadFile(name)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", file)
}
Output:
"appointment.sql"
"C:\\Users\\peter\\gopath\\src\\so\\appointment.sql"
"SELECT * FROM appointments;\n"

Resources