├── .gitignore ├── external └── awsconn │ ├── repository.go │ ├── usecase.go │ ├── s3external.go │ ├── model │ └── s3model.go │ ├── repository │ ├── s3repository_test.go │ └── s3repository.go │ ├── helper │ ├── awshelper_test.go │ └── awshelper.go │ ├── usecase │ ├── s3usecase.go │ └── s3usecase_test.go │ └── mocks │ ├── IUsecase.go │ ├── IRepository.go │ └── IS3External.go ├── pdfgenerate ├── model │ └── workrequest.go ├── usecase │ ├── collector.go │ ├── dispatcher.go │ └── worker.go └── api │ └── pdfhandler.go ├── Dockerfile ├── Gopkg.toml ├── README.md ├── main.go ├── Gopkg.lock └── main1.go /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | .chrome/ 4 | 5 | 6 | 7 | tmp 8 | coverage 9 | 10 | 11 | 12 | *log* 13 | *docx* 14 | **.orig 15 | *\.pdf 16 | .env 17 | vendor -------------------------------------------------------------------------------- /external/awsconn/repository.go: -------------------------------------------------------------------------------- 1 | package awsconn 2 | 3 | type IRepository interface { 4 | PullFileFromS3(bucket string, destFilename string, sourceFilename string) error 5 | PutFileToS3(bucket string, destFilename string, sourceFilename string) error 6 | DeleteFileFromS3(bucket string, destFilename string) error 7 | } 8 | -------------------------------------------------------------------------------- /pdfgenerate/model/workrequest.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type WorkRequest struct { 8 | Name string 9 | Delay time.Duration 10 | File string 11 | } 12 | 13 | //COLLECTOR 14 | // A buffered channel that we can send work requests on. 15 | var WorkQueue = make(chan WorkRequest, 100) 16 | -------------------------------------------------------------------------------- /external/awsconn/usecase.go: -------------------------------------------------------------------------------- 1 | package awsconn 2 | 3 | // Interface for Usecase. Can be used for testing if called from API layer 4 | type IUsecase interface { 5 | PullFileFromS3(bucket string, destFilename string, sourceFilename string) error 6 | PutFileToS3(bucket string, destFilename string, sourceFilename string) error 7 | DeleteFileFromS3(bucket string, destFilename string) error 8 | } 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.10 2 | RUN go version 3 | RUN apt-get update 4 | # RUN apt-get install -y build-essential libssl-dev libffi-dev python-dev 5 | RUN apt-get install -y libreoffice 6 | ENV GOOS=linux 7 | WORKDIR /go/src/app 8 | ADD . /go/src/app/ 9 | WORKDIR /go/src/app 10 | 11 | # RUN go build -o main . 12 | CMD ["go","run","main.go","sample2.docx","2"] 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /external/awsconn/s3external.go: -------------------------------------------------------------------------------- 1 | package awsconn 2 | 3 | import ( 4 | "github.com/aws/aws-sdk-go/aws" 5 | "github.com/aws/aws-sdk-go/aws/request" 6 | "github.com/aws/aws-sdk-go/service/s3" 7 | ) 8 | 9 | // Interface for S3 methods 10 | type IS3External interface { 11 | PutObjectWithContext(ctx aws.Context, input *s3.PutObjectInput, opts ...request.Option) (*s3.PutObjectOutput, error) 12 | DeleteObject(input *s3.DeleteObjectInput) (*s3.DeleteObjectOutput, error) 13 | } 14 | -------------------------------------------------------------------------------- /external/awsconn/model/s3model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type S3Config struct { 4 | AccessKeyID string 5 | SecretKey string 6 | S3ReportBucket string 7 | S3ImageBucket string 8 | S3UserFileBucket string 9 | Region string 10 | } 11 | 12 | func NewS3Config(accessKeyID string, secretKey string, reportBucket string, imageBucket string, fileBucket string, region string) *S3Config { 13 | return &S3Config{ 14 | AccessKeyID: accessKeyID, 15 | SecretKey: secretKey, 16 | S3ReportBucket: reportBucket, 17 | S3ImageBucket: imageBucket, 18 | S3UserFileBucket: fileBucket, 19 | Region: region, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pdfgenerate/usecase/collector.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/karuppaiah/docxtopdf/pdfgenerate/model" 8 | ) 9 | 10 | // CollectorJob is the function to be called for PDF generation with requestor name of work and filename with path for docx 11 | func CollectorJob(name string, delay time.Duration, filename string) { 12 | // Now, we take the delay, and the person's name, and make a model.WorkRequest out of them. 13 | work := model.WorkRequest{Name: name, Delay: delay, File: filename} 14 | // Push the work onto the queue. 15 | model.WorkQueue <- work 16 | fmt.Println("Work request queued for PDF generation") 17 | } 18 | -------------------------------------------------------------------------------- /external/awsconn/repository/s3repository_test.go: -------------------------------------------------------------------------------- 1 | package repository_test 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | //TODO: Yet to find a mock for S3 and write unit testing 8 | func TestPutFileToS3Success(t *testing.T) { 9 | // mockS3 := new(mocks.IS3External) 10 | // config, err := awshelper.GetAWSConfig("key", "secretVal", "bucket", "region") 11 | // if err != nil { 12 | // fmt.Println("Unable to create config for s3conn: ", err) 13 | 14 | // } 15 | // mockS3.On("PutObjectWithContext", mock.AnythingOfType("Context"), mock.AnythingOfType("Interface")).Return(nil, nil) 16 | 17 | // u := repository.NewERepository(config, mockS3) 18 | 19 | // err = u.PutFileToS3("bucket", "destfile", "sourcefile") 20 | 21 | // assert.NoError(t, err) 22 | 23 | // mockS3.AssertExpectations(t) 24 | } 25 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://golang.github.io/dep/docs/Gopkg.toml.html 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | # 22 | # [prune] 23 | # non-go = false 24 | # go-tests = true 25 | # unused-packages = true 26 | 27 | 28 | [prune] 29 | go-tests = true 30 | unused-packages = true 31 | 32 | 33 | [[constraint]] 34 | name = "github.com/aws/aws-sdk-go" 35 | version = "1.15.42" 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docxtopdf 2 | # golang docx to pdf convertor and S3 package 3 | 4 | - Packages dependent on aws sdk go: https://github.com/aws/aws-sdk-go 5 | - For PDF generation, since libreoffice/soffice is sequential,we use collector, dispatcher and worker model to run things in sequence 6 | 7 | ``` 8 | git clone https://github.com/karuppaiah/docxtopdf.git 9 | cd docxtopdf 10 | dep ensure // make sure https://github.com/aws/aws-sdk-go is installed 11 | apt-get install -y libreoffice // If linux env else install libreoffice for mac and put the executables in env PATH 12 | go run main.go // will show a sample of S3 put, pull and del and also main1() for worker,dispatcher and collector pdf generator. Enable the respective main and view the sample 13 | 14 | 15 | ``` 16 | #TODO 17 | 18 | - [ ] Unit testing for S3 repository 19 | - [ ] Unit testing for collector, dispatcher and worker pdf generator 20 | -------------------------------------------------------------------------------- /pdfgenerate/usecase/dispatcher.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/karuppaiah/docxtopdf/pdfgenerate/model" 7 | ) 8 | 9 | //DISPATCHER 10 | 11 | var WorkerQueue chan chan model.WorkRequest 12 | 13 | func StartDispatcher(nworkers int) { 14 | // First, initialize the channel we are going to but the workers' work channels into. 15 | WorkerQueue = make(chan chan model.WorkRequest, nworkers) 16 | 17 | // Now, create all of our workers. 18 | for i := 0; i < nworkers; i++ { 19 | fmt.Println("Starting worker", i+1) 20 | worker := NewWorker(i+1, WorkerQueue) 21 | worker.Start() 22 | } 23 | 24 | go func() { 25 | for { 26 | select { 27 | case work := <-model.WorkQueue: 28 | fmt.Println("Received work requeust") 29 | go func() { 30 | worker := <-WorkerQueue 31 | 32 | fmt.Println("Dispatching work request") 33 | worker <- work 34 | }() 35 | } 36 | } 37 | }() 38 | } 39 | -------------------------------------------------------------------------------- /external/awsconn/helper/awshelper_test.go: -------------------------------------------------------------------------------- 1 | package helper_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/aws/aws-sdk-go/aws" 8 | "github.com/aws/aws-sdk-go/aws/credentials" 9 | 10 | awshelper "github.com/karuppaiah/docxtopdf/external/awsconn/helper" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestGetAWSConfigSuccess(t *testing.T) { 15 | creds := credentials.NewStaticCredentials("key", "secret", "") 16 | config, err := awshelper.GetAWSConfig("key", "secret", "bucket", "region") 17 | assert.Equal(t, aws.String("region"), config.Region) 18 | assert.Equal(t, creds, config.Credentials) 19 | assert.NoError(t, err) 20 | 21 | } 22 | 23 | func TestGetAWSConfigFailure(t *testing.T) { 24 | // creds := credentials.NewStaticCredentials("key", "secret", "") 25 | config, err := awshelper.GetAWSConfig("key", "secret", "bucket", "") 26 | fmt.Println(err) 27 | assert.Equal(t, aws.String("us-east-1"), config.Region) 28 | 29 | assert.NoError(t, err) 30 | 31 | } 32 | -------------------------------------------------------------------------------- /external/awsconn/helper/awshelper.go: -------------------------------------------------------------------------------- 1 | package helper 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/aws/aws-sdk-go/aws" 8 | "github.com/aws/aws-sdk-go/aws/credentials" 9 | "github.com/aws/aws-sdk-go/aws/endpoints" 10 | "github.com/aws/aws-sdk-go/aws/session" 11 | "github.com/aws/aws-sdk-go/service/s3/s3manager" 12 | ) 13 | 14 | func GetAWSConfig(accessKeyID string, secretAccessKey string, bucket string, region string) (*aws.Config, error) { 15 | creds := credentials.NewStaticCredentials(accessKeyID, secretAccessKey, "") 16 | var err error 17 | if len(region) == 0 { 18 | sess := session.Must(session.NewSession(&aws.Config{ 19 | Credentials: creds, 20 | })) 21 | region, err = s3manager.GetBucketRegion(context.Background(), sess, bucket, endpoints.UsEast1RegionID) 22 | fmt.Println("region:", region) 23 | if err != nil { 24 | return nil, err 25 | } 26 | } 27 | config := &aws.Config{ 28 | Region: aws.String(region), 29 | Credentials: creds, 30 | } 31 | return config, nil 32 | } 33 | -------------------------------------------------------------------------------- /external/awsconn/usecase/s3usecase.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/karuppaiah/docxtopdf/external/awsconn" 7 | ) 8 | 9 | //eUseCase with Connection to AWS 10 | type eUsecase struct { 11 | eRepos awsconn.IRepository 12 | // contextTimeout time.Duration 13 | } 14 | 15 | // To create new UseCase 16 | func NewEUseCase(a awsconn.IRepository) awsconn.IUsecase { 17 | return &eUsecase{a} 18 | } 19 | 20 | func (a *eUsecase) PullFileFromS3(bucket string, destFilename string, sourceFilename string) error { 21 | fmt.Println("Usecase|in PullFileFromS3") 22 | err := a.eRepos.PullFileFromS3(bucket, destFilename, sourceFilename) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | return nil 28 | 29 | } 30 | 31 | func (a *eUsecase) PutFileToS3(bucket string, destFilename string, sourceFilename string) error { 32 | fmt.Println("Usecase|in PutFileToS3") 33 | 34 | err := a.eRepos.PutFileToS3(bucket, destFilename, sourceFilename) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | return nil 40 | 41 | } 42 | 43 | func (a *eUsecase) DeleteFileFromS3(bucket string, destFilename string) error { 44 | fmt.Println("Usecase|in DelFileInS3") 45 | 46 | err := a.eRepos.DeleteFileFromS3(bucket, destFilename) 47 | if err != nil { 48 | return err 49 | } 50 | 51 | return nil 52 | 53 | } 54 | -------------------------------------------------------------------------------- /external/awsconn/mocks/IUsecase.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v1.0.0. DO NOT EDIT. 2 | 3 | package mocks 4 | 5 | import mock "github.com/stretchr/testify/mock" 6 | 7 | // IUsecase is an autogenerated mock type for the IUsecase type 8 | type IUsecase struct { 9 | mock.Mock 10 | } 11 | 12 | // DeleteFileFromS3 provides a mock function with given fields: bucket, destFilename 13 | func (_m *IUsecase) DeleteFileFromS3(bucket string, destFilename string) error { 14 | ret := _m.Called(bucket, destFilename) 15 | 16 | var r0 error 17 | if rf, ok := ret.Get(0).(func(string, string) error); ok { 18 | r0 = rf(bucket, destFilename) 19 | } else { 20 | r0 = ret.Error(0) 21 | } 22 | 23 | return r0 24 | } 25 | 26 | // PullFileFromS3 provides a mock function with given fields: bucket, destFilename, sourceFilename 27 | func (_m *IUsecase) PullFileFromS3(bucket string, destFilename string, sourceFilename string) error { 28 | ret := _m.Called(bucket, destFilename, sourceFilename) 29 | 30 | var r0 error 31 | if rf, ok := ret.Get(0).(func(string, string, string) error); ok { 32 | r0 = rf(bucket, destFilename, sourceFilename) 33 | } else { 34 | r0 = ret.Error(0) 35 | } 36 | 37 | return r0 38 | } 39 | 40 | // PutFileToS3 provides a mock function with given fields: bucket, destFilename, sourceFilename 41 | func (_m *IUsecase) PutFileToS3(bucket string, destFilename string, sourceFilename string) error { 42 | ret := _m.Called(bucket, destFilename, sourceFilename) 43 | 44 | var r0 error 45 | if rf, ok := ret.Get(0).(func(string, string, string) error); ok { 46 | r0 = rf(bucket, destFilename, sourceFilename) 47 | } else { 48 | r0 = ret.Error(0) 49 | } 50 | 51 | return r0 52 | } 53 | -------------------------------------------------------------------------------- /external/awsconn/mocks/IRepository.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v1.0.0. DO NOT EDIT. 2 | 3 | package mocks 4 | 5 | import mock "github.com/stretchr/testify/mock" 6 | 7 | // IRepository is an autogenerated mock type for the IRepository type 8 | type IRepository struct { 9 | mock.Mock 10 | } 11 | 12 | // DeleteFileFromS3 provides a mock function with given fields: bucket, destFilename 13 | func (_m *IRepository) DeleteFileFromS3(bucket string, destFilename string) error { 14 | ret := _m.Called(bucket, destFilename) 15 | 16 | var r0 error 17 | if rf, ok := ret.Get(0).(func(string, string) error); ok { 18 | r0 = rf(bucket, destFilename) 19 | } else { 20 | r0 = ret.Error(0) 21 | } 22 | 23 | return r0 24 | } 25 | 26 | // PullFileFromS3 provides a mock function with given fields: bucket, destFilename, sourceFilename 27 | func (_m *IRepository) PullFileFromS3(bucket string, destFilename string, sourceFilename string) error { 28 | ret := _m.Called(bucket, destFilename, sourceFilename) 29 | 30 | var r0 error 31 | if rf, ok := ret.Get(0).(func(string, string, string) error); ok { 32 | r0 = rf(bucket, destFilename, sourceFilename) 33 | } else { 34 | r0 = ret.Error(0) 35 | } 36 | 37 | return r0 38 | } 39 | 40 | // PutFileToS3 provides a mock function with given fields: bucket, destFilename, sourceFilename 41 | func (_m *IRepository) PutFileToS3(bucket string, destFilename string, sourceFilename string) error { 42 | ret := _m.Called(bucket, destFilename, sourceFilename) 43 | 44 | var r0 error 45 | if rf, ok := ret.Get(0).(func(string, string, string) error); ok { 46 | r0 = rf(bucket, destFilename, sourceFilename) 47 | } else { 48 | r0 = ret.Error(0) 49 | } 50 | 51 | return r0 52 | } 53 | -------------------------------------------------------------------------------- /pdfgenerate/api/pdfhandler.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "net/http" 5 | "time" 6 | 7 | "github.com/karuppaiah/docxtopdf/pdfgenerate/usecase" 8 | ) 9 | 10 | func Collector(w http.ResponseWriter, r *http.Request) { 11 | // Make sure we can only be called with an HTTP POST request. 12 | if r.Method != "POST" { 13 | w.Header().Set("Allow", "POST") 14 | w.WriteHeader(http.StatusMethodNotAllowed) 15 | return 16 | } 17 | 18 | // Parse the delay. 19 | delay, err := time.ParseDuration(r.FormValue("delay")) 20 | if err != nil { 21 | http.Error(w, "Bad delay value: "+err.Error(), http.StatusBadRequest) 22 | return 23 | } 24 | 25 | // Check to make sure the delay is anywhere from 1 to 10 seconds. 26 | if delay.Seconds() < 1 || delay.Seconds() > 10 { 27 | http.Error(w, "The delay must be between 1 and 10 seconds, inclusively.", http.StatusBadRequest) 28 | return 29 | } 30 | 31 | // Now, we retrieve the person's name from the request. 32 | name := r.FormValue("name") 33 | 34 | // Just do a quick bit of sanity checking to make sure the client actually provided us with a name. 35 | if name == "" { 36 | http.Error(w, "You must specify a name.", http.StatusBadRequest) 37 | return 38 | } 39 | // Now, we retrieve the person's name from the request. 40 | filename := r.FormValue("filename") 41 | // Just do a quick bit of sanity checking to make sure the client actually provided us with a name. 42 | if filename == "" { 43 | http.Error(w, "You must specify a docx filename.", http.StatusBadRequest) 44 | return 45 | } 46 | usecase.CollectorJob(name, delay, filename) 47 | // And let the user know their work request was created. 48 | w.WriteHeader(http.StatusCreated) 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /external/awsconn/mocks/IS3External.go: -------------------------------------------------------------------------------- 1 | // Code generated by mockery v1.0.0. DO NOT EDIT. 2 | 3 | package mocks 4 | 5 | import aws "github.com/aws/aws-sdk-go/aws" 6 | 7 | import mock "github.com/stretchr/testify/mock" 8 | import request "github.com/aws/aws-sdk-go/aws/request" 9 | import s3 "github.com/aws/aws-sdk-go/service/s3" 10 | 11 | // IS3External is an autogenerated mock type for the IS3External type 12 | type IS3External struct { 13 | mock.Mock 14 | } 15 | 16 | // DeleteObject provides a mock function with given fields: input 17 | func (_m *IS3External) DeleteObject(input *s3.DeleteObjectInput) (*s3.DeleteObjectOutput, error) { 18 | ret := _m.Called(input) 19 | 20 | var r0 *s3.DeleteObjectOutput 21 | if rf, ok := ret.Get(0).(func(*s3.DeleteObjectInput) *s3.DeleteObjectOutput); ok { 22 | r0 = rf(input) 23 | } else { 24 | if ret.Get(0) != nil { 25 | r0 = ret.Get(0).(*s3.DeleteObjectOutput) 26 | } 27 | } 28 | 29 | var r1 error 30 | if rf, ok := ret.Get(1).(func(*s3.DeleteObjectInput) error); ok { 31 | r1 = rf(input) 32 | } else { 33 | r1 = ret.Error(1) 34 | } 35 | 36 | return r0, r1 37 | } 38 | 39 | // PutObjectWithContext provides a mock function with given fields: ctx, input, opts 40 | func (_m *IS3External) PutObjectWithContext(ctx aws.Context, input *s3.PutObjectInput, opts ...request.Option) (*s3.PutObjectOutput, error) { 41 | _va := make([]interface{}, len(opts)) 42 | for _i := range opts { 43 | _va[_i] = opts[_i] 44 | } 45 | var _ca []interface{} 46 | _ca = append(_ca, ctx, input) 47 | _ca = append(_ca, _va...) 48 | ret := _m.Called(_ca...) 49 | 50 | var r0 *s3.PutObjectOutput 51 | if rf, ok := ret.Get(0).(func(aws.Context, *s3.PutObjectInput, ...request.Option) *s3.PutObjectOutput); ok { 52 | r0 = rf(ctx, input, opts...) 53 | } else { 54 | if ret.Get(0) != nil { 55 | r0 = ret.Get(0).(*s3.PutObjectOutput) 56 | } 57 | } 58 | 59 | var r1 error 60 | if rf, ok := ret.Get(1).(func(aws.Context, *s3.PutObjectInput, ...request.Option) error); ok { 61 | r1 = rf(ctx, input, opts...) 62 | } else { 63 | r1 = ret.Error(1) 64 | } 65 | 66 | return r0, r1 67 | } 68 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "net/http" 7 | "os" 8 | 9 | "github.com/aws/aws-sdk-go/aws/session" 10 | "github.com/aws/aws-sdk-go/service/s3" 11 | awshelper "github.com/karuppaiah/docxtopdf/external/awsconn/helper" 12 | awsRepo "github.com/karuppaiah/docxtopdf/external/awsconn/repository" 13 | awsusecase "github.com/karuppaiah/docxtopdf/external/awsconn/usecase" 14 | pdfapi "github.com/karuppaiah/docxtopdf/pdfgenerate/api" 15 | pdfUsecase "github.com/karuppaiah/docxtopdf/pdfgenerate/usecase" 16 | ) 17 | 18 | var ( 19 | NWorkers = flag.Int("n", 1, "The number of workers to start") 20 | HTTPAddr = flag.String("http", "127.0.0.1:8000", "Address to listen for HTTP requests on") 21 | ) 22 | 23 | func main1() { 24 | // Parse the command-line flags. 25 | flag.Parse() 26 | 27 | // Start the dispatcher. 28 | fmt.Println("Starting the dispatcher") 29 | pdfUsecase.StartDispatcher(*NWorkers) 30 | 31 | // Register our collector as an HTTP handler function. 32 | fmt.Println("Registering the collector") 33 | http.HandleFunc("/work", pdfapi.Collector) 34 | 35 | // Start the HTTP server! 36 | fmt.Println("HTTP server listening on", *HTTPAddr) 37 | if err := http.ListenAndServe(*HTTPAddr, nil); err != nil { 38 | fmt.Println(err.Error()) 39 | } 40 | } 41 | func main() { 42 | 43 | bucket := os.Getenv("AWS_REPORTS_BUCKET") 44 | keyVal := os.Getenv("AWS_ACCESS_KEY_ID") 45 | secretVal := os.Getenv("AWS_SECRET_ACCESS_KEY") 46 | region := os.Getenv("AWS_REGION") 47 | 48 | config, err := awshelper.GetAWSConfig(keyVal, secretVal, bucket, region) 49 | if err != nil { 50 | fmt.Println("Unable to create config for s3conn: ", err) 51 | 52 | } 53 | sess := session.New(config) 54 | svc := s3.New(sess) 55 | s3Repository := awsRepo.NewERepository(config, svc) 56 | s3Usecase := awsusecase.NewEUseCase(s3Repository) 57 | // Push file to s3 58 | destFilename := "sample0.docx" + "_" + "kal" 59 | sourceLocalFilename := "sample0.docx" 60 | err = s3Usecase.PutFileToS3(bucket, destFilename, sourceLocalFilename) 61 | if err != nil { 62 | fmt.Println("Unable to Put file in s3conn: ", err) 63 | } 64 | // Pull file from S3 65 | destFilename = "pull_sample0.docx" + "_" + "kal" 66 | sourceLocalFilename = "sample0.docx" + "_" + "kal" 67 | err = s3Usecase.PullFileFromS3(bucket, destFilename, sourceLocalFilename) 68 | if err != nil { 69 | fmt.Println("Unable to pull file in s3conn: ", err) 70 | } 71 | 72 | // Delete file from S3 73 | destFilename = "sample0.docx" + "_" + "kal" 74 | 75 | err = s3Usecase.DeleteFileFromS3(bucket, destFilename) 76 | if err != nil { 77 | fmt.Println("Unable to Delete file in s3conn: ", err) 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /pdfgenerate/usecase/worker.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | 8 | "github.com/karuppaiah/docxtopdf/pdfgenerate/model" 9 | ) 10 | 11 | ///////WORKER 12 | // NewWorker creates, and returns a new Worker object. Its only argument 13 | // is a channel that the worker can add itself to whenever it is done its 14 | // work. 15 | func NewWorker(id int, workerQueue chan chan model.WorkRequest) Worker { 16 | // Create, and return the worker. 17 | worker := Worker{ 18 | ID: id, 19 | Work: make(chan model.WorkRequest), 20 | WorkerQueue: workerQueue, 21 | QuitChan: make(chan bool)} 22 | 23 | return worker 24 | } 25 | 26 | type Worker struct { 27 | ID int 28 | Work chan model.WorkRequest 29 | WorkerQueue chan chan model.WorkRequest 30 | QuitChan chan bool 31 | } 32 | 33 | // This function "starts" the worker by starting a goroutine, that is 34 | // an infinite "for-select" loop. 35 | func (w *Worker) Start() { 36 | go func() { 37 | for { 38 | // Add ourselves into the worker queue. 39 | w.WorkerQueue <- w.Work 40 | 41 | select { 42 | case work := <-w.Work: 43 | // Receive a work request. 44 | fmt.Printf("worker%d: Received work request, delaying for %f seconds\n", w.ID, work.Delay.Seconds()) 45 | 46 | //time.Sleep(work.Delay) 47 | fmt.Printf("Before Generating file:%s", work.File) 48 | err := RConvertUsingLibreOffice(work.File) 49 | if err != nil { 50 | fmt.Printf("Error Generating file:%s", work.File) 51 | // Failure recovery code here 52 | } else { 53 | fmt.Printf("Generated file:%s", work.File) 54 | } 55 | 56 | fmt.Printf("worker%d: Hello, %s!\n", w.ID, work.Name) 57 | 58 | case <-w.QuitChan: 59 | // We have been asked to stop. 60 | fmt.Printf("worker%d stopping\n", w.ID) 61 | return 62 | } 63 | } 64 | }() 65 | } 66 | 67 | //ConvertUsingLibreOffice will use libreoffice to convert the docsx to pdf 68 | func RConvertUsingLibreOffice(inputFile string) error { 69 | executable := "libreoffice" 70 | if os.Getenv("GOOS") == "darwin" || os.Getenv("GOOS") == "" { 71 | executable = "/Applications/LibreOffice.app/Contents/MacOS/soffice" 72 | } 73 | fmt.Println(os.Getenv("GOOS")) 74 | 75 | fmt.Println(executable) 76 | docxToPDFCmd := exec.Command("bash", "-c", executable+" --headless --convert-to pdf "+inputFile) 77 | docxToPDFCmdErr := docxToPDFCmd.Run() 78 | if docxToPDFCmdErr != nil { 79 | fmt.Println("1.Conversion issue to pdf", docxToPDFCmdErr) 80 | return docxToPDFCmdErr 81 | } 82 | return nil 83 | 84 | } 85 | 86 | // Stop tells the worker to stop listening for work requests. 87 | // 88 | // Note that the worker will only stop *after* it has finished its work. 89 | func (w *Worker) Stop() { 90 | go func() { 91 | w.QuitChan <- true 92 | }() 93 | } 94 | -------------------------------------------------------------------------------- /external/awsconn/usecase/s3usecase_test.go: -------------------------------------------------------------------------------- 1 | package usecase_test 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | "github.com/karuppaiah/docxtopdf/external/awsconn/mocks" 8 | "github.com/karuppaiah/docxtopdf/external/awsconn/usecase" 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/mock" 11 | ) 12 | 13 | func TestPullFileFromS3Success(t *testing.T) { 14 | mockRepo := new(mocks.IRepository) 15 | 16 | mockRepo.On("PullFileFromS3", mock.AnythingOfType("string"), mock.Anything, mock.Anything).Return(nil) 17 | 18 | u := usecase.NewEUseCase(mockRepo) 19 | 20 | err := u.PullFileFromS3("bucket", "destfile", "sourcefile") 21 | 22 | assert.NoError(t, err) 23 | 24 | mockRepo.AssertExpectations(t) 25 | 26 | } 27 | 28 | func TestPullFileFromS3Failure(t *testing.T) { 29 | mockRepo := new(mocks.IRepository) 30 | 31 | mockRepo.On("PullFileFromS3", mock.AnythingOfType("string"), mock.Anything, mock.Anything).Return(errors.New("Unexpexted Error")) 32 | 33 | u := usecase.NewEUseCase(mockRepo) 34 | 35 | err := u.PullFileFromS3("bucket", "destfile", "sourcefile") 36 | 37 | assert.Error(t, err) 38 | 39 | mockRepo.AssertExpectations(t) 40 | 41 | } 42 | 43 | func TestPushFileToS3Success(t *testing.T) { 44 | mockRepo := new(mocks.IRepository) 45 | 46 | mockRepo.On("PutFileToS3", mock.AnythingOfType("string"), mock.Anything, mock.Anything).Return(nil) 47 | 48 | u := usecase.NewEUseCase(mockRepo) 49 | 50 | err := u.PutFileToS3("bucket", "destfile", "sourcefile") 51 | 52 | assert.NoError(t, err) 53 | 54 | mockRepo.AssertExpectations(t) 55 | 56 | } 57 | 58 | func TestPushFileToS3Failure(t *testing.T) { 59 | mockRepo := new(mocks.IRepository) 60 | 61 | mockRepo.On("PutFileToS3", mock.AnythingOfType("string"), mock.Anything, mock.Anything).Return(errors.New("Unexpexted Error")) 62 | 63 | u := usecase.NewEUseCase(mockRepo) 64 | 65 | err := u.PutFileToS3("bucket", "destfile", "sourcefile") 66 | 67 | assert.Error(t, err) 68 | 69 | mockRepo.AssertExpectations(t) 70 | 71 | } 72 | 73 | func TestDelFileInS3Success(t *testing.T) { 74 | mockRepo := new(mocks.IRepository) 75 | 76 | mockRepo.On("DeleteFileFromS3", mock.AnythingOfType("string"), mock.Anything).Return(nil) 77 | 78 | u := usecase.NewEUseCase(mockRepo) 79 | 80 | err := u.DeleteFileFromS3("bucket", "destfile") 81 | 82 | assert.NoError(t, err) 83 | 84 | mockRepo.AssertExpectations(t) 85 | 86 | } 87 | 88 | func TestDelFileInS3Failure(t *testing.T) { 89 | mockRepo := new(mocks.IRepository) 90 | 91 | mockRepo.On("DeleteFileFromS3", mock.AnythingOfType("string"), mock.Anything).Return(errors.New("Unexpexted Error")) 92 | 93 | u := usecase.NewEUseCase(mockRepo) 94 | 95 | err := u.DeleteFileFromS3("bucket", "destfile") 96 | 97 | assert.Error(t, err) 98 | 99 | mockRepo.AssertExpectations(t) 100 | 101 | } 102 | -------------------------------------------------------------------------------- /external/awsconn/repository/s3repository.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "time" 8 | 9 | "github.com/aws/aws-sdk-go/aws" 10 | "github.com/aws/aws-sdk-go/aws/awserr" 11 | "github.com/aws/aws-sdk-go/aws/session" 12 | "github.com/aws/aws-sdk-go/service/s3" 13 | "github.com/aws/aws-sdk-go/service/s3/s3manager" 14 | "github.com/karuppaiah/docxtopdf/external/awsconn" 15 | ) 16 | 17 | //eUseCase with Connection to AWS 18 | type eRepository struct { 19 | Conn *aws.Config 20 | Svc *s3.S3 //*s3iface.S3API 21 | } 22 | 23 | // To create new UseCase 24 | func NewERepository(conn *aws.Config, svc *s3.S3) awsconn.IRepository { 25 | // sess := session.New(conn) 26 | // svc := s3.New(sess) 27 | return &eRepository{Conn: conn, Svc: svc} 28 | } 29 | 30 | func (a *eRepository) PullFileFromS3(bucket string, destFilename string, sourceFilename string) error { 31 | fmt.Println("Repo: in PullFileToS3") 32 | 33 | sess := session.New(a.Conn) 34 | 35 | downloader := s3manager.NewDownloader(sess) 36 | f, err := os.Create(destFilename) 37 | fmt.Println("Creating file", destFilename) 38 | if err != nil { 39 | return err 40 | } 41 | defer f.Close() 42 | 43 | n, pullErr := downloader.Download(f, &s3.GetObjectInput{ 44 | Bucket: aws.String(bucket), 45 | Key: aws.String(sourceFilename), 46 | }) 47 | fmt.Printf("file downloaded, %d bytes\n", n) 48 | return pullErr 49 | 50 | // sess := session.New(config) 51 | // svc := s3.New(sess) 52 | // input := &s3.GetObjectInput{ 53 | // Bucket: aws.String(bucket), 54 | // Key: aws.String(sourceFilename), 55 | // } 56 | // fmt.Println(sourceFilename) 57 | // result, err := svc.GetObject(input) 58 | // if err != nil { 59 | // if aerr, ok := err.(awserr.Error); ok { 60 | // switch aerr.Code() { 61 | // case s3.ErrCodeNoSuchKey: 62 | // fmt.Println(s3.ErrCodeNoSuchKey, aerr.Error()) 63 | // default: 64 | // fmt.Println(aerr.Error()) 65 | // } 66 | // } else { 67 | // // Print the error, cast err to awserr.Error to get the Code and 68 | // // Message from an error. 69 | // fmt.Println(err.Error()) 70 | // } 71 | // return nil 72 | // } 73 | 74 | // fmt.Println(result) 75 | // return nil 76 | } 77 | 78 | func (a *eRepository) PutFileToS3(bucket string, destFilename string, sourceFilename string) error { 79 | fmt.Println("in PutFileToS3") 80 | 81 | var timeout = 100 * time.Second 82 | 83 | ctx, cancelFn := context.WithTimeout(context.Background(), timeout) 84 | defer cancelFn() 85 | 86 | f, err := os.Open(sourceFilename) 87 | fmt.Println("Opening file", sourceFilename) 88 | if err != nil { 89 | return nil 90 | } 91 | defer f.Close() 92 | _, putErr := a.Svc.PutObjectWithContext(ctx, &s3.PutObjectInput{ 93 | Bucket: aws.String(bucket), 94 | Key: aws.String(destFilename), 95 | Body: f, 96 | }) 97 | fmt.Println("done with put s3") 98 | return putErr 99 | } 100 | 101 | func (a *eRepository) DeleteFileFromS3(bucket string, destFilename string) error { 102 | fmt.Println("in DeleteFileFromS3") 103 | 104 | input := &s3.DeleteObjectInput{ 105 | Bucket: aws.String(bucket), 106 | Key: aws.String(destFilename), 107 | } 108 | 109 | result, err := a.Svc.DeleteObject(input) 110 | if err != nil { 111 | if aerr, ok := err.(awserr.Error); ok { 112 | switch aerr.Code() { 113 | default: 114 | fmt.Println(aerr.Error()) 115 | return aerr 116 | } 117 | } 118 | // Print the error, cast err to awserr.Error to get the Code and 119 | // Message from an error. 120 | fmt.Println(err.Error()) 121 | 122 | return err 123 | } 124 | 125 | fmt.Println(result) 126 | 127 | return nil 128 | } 129 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | digest = "1:d76c131361e2535e8031b250f331dfd4617bfcb6564cf04c01a7371de0e4c202" 6 | name = "github.com/aws/aws-sdk-go" 7 | packages = [ 8 | "aws", 9 | "aws/awserr", 10 | "aws/awsutil", 11 | "aws/client", 12 | "aws/client/metadata", 13 | "aws/corehandlers", 14 | "aws/credentials", 15 | "aws/credentials/ec2rolecreds", 16 | "aws/credentials/endpointcreds", 17 | "aws/credentials/stscreds", 18 | "aws/csm", 19 | "aws/defaults", 20 | "aws/ec2metadata", 21 | "aws/endpoints", 22 | "aws/request", 23 | "aws/session", 24 | "aws/signer/v4", 25 | "internal/sdkio", 26 | "internal/sdkrand", 27 | "internal/sdkuri", 28 | "internal/shareddefaults", 29 | "private/protocol", 30 | "private/protocol/eventstream", 31 | "private/protocol/eventstream/eventstreamapi", 32 | "private/protocol/query", 33 | "private/protocol/query/queryutil", 34 | "private/protocol/rest", 35 | "private/protocol/restxml", 36 | "private/protocol/xml/xmlutil", 37 | "service/s3", 38 | "service/s3/s3iface", 39 | "service/s3/s3manager", 40 | "service/sts", 41 | ] 42 | pruneopts = "UT" 43 | revision = "85d9dfd77e6d694e83c3ac054141cb5e81eecc7f" 44 | version = "v1.15.43" 45 | 46 | [[projects]] 47 | digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" 48 | name = "github.com/davecgh/go-spew" 49 | packages = ["spew"] 50 | pruneopts = "UT" 51 | revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" 52 | version = "v1.1.1" 53 | 54 | [[projects]] 55 | digest = "1:5abd6a22805b1919f6a6bca0ae58b13cef1f3412812f38569978f43ef02743d4" 56 | name = "github.com/go-ini/ini" 57 | packages = ["."] 58 | pruneopts = "UT" 59 | revision = "5cf292cae48347c2490ac1a58fe36735fb78df7e" 60 | version = "v1.38.2" 61 | 62 | [[projects]] 63 | digest = "1:e22af8c7518e1eab6f2eab2b7d7558927f816262586cd6ed9f349c97a6c285c4" 64 | name = "github.com/jmespath/go-jmespath" 65 | packages = ["."] 66 | pruneopts = "UT" 67 | revision = "0b12d6b5" 68 | 69 | [[projects]] 70 | digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" 71 | name = "github.com/pmezard/go-difflib" 72 | packages = ["difflib"] 73 | pruneopts = "UT" 74 | revision = "792786c7400a136282c1664665ae0a8db921c6c2" 75 | version = "v1.0.0" 76 | 77 | [[projects]] 78 | digest = "1:ac83cf90d08b63ad5f7e020ef480d319ae890c208f8524622a2f3136e2686b02" 79 | name = "github.com/stretchr/objx" 80 | packages = ["."] 81 | pruneopts = "UT" 82 | revision = "477a77ecc69700c7cdeb1fa9e129548e1c1c393c" 83 | version = "v0.1.1" 84 | 85 | [[projects]] 86 | digest = "1:15a4a7e5afac3cea801fa24831fce3bf3b5bd3620cbf8355a07b7dbf06877883" 87 | name = "github.com/stretchr/testify" 88 | packages = [ 89 | "assert", 90 | "mock", 91 | ] 92 | pruneopts = "UT" 93 | revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" 94 | version = "v1.2.2" 95 | 96 | [solve-meta] 97 | analyzer-name = "dep" 98 | analyzer-version = 1 99 | input-imports = [ 100 | "github.com/aws/aws-sdk-go/aws", 101 | "github.com/aws/aws-sdk-go/aws/awserr", 102 | "github.com/aws/aws-sdk-go/aws/credentials", 103 | "github.com/aws/aws-sdk-go/aws/endpoints", 104 | "github.com/aws/aws-sdk-go/aws/request", 105 | "github.com/aws/aws-sdk-go/aws/session", 106 | "github.com/aws/aws-sdk-go/service/s3", 107 | "github.com/aws/aws-sdk-go/service/s3/s3manager", 108 | "github.com/stretchr/testify/assert", 109 | "github.com/stretchr/testify/mock", 110 | ] 111 | solver-name = "gps-cdcl" 112 | solver-version = 1 113 | -------------------------------------------------------------------------------- /main1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // import ( 4 | // "flag" 5 | // "fmt" 6 | // "net/http" 7 | // "os" 8 | // "os/exec" 9 | // "strconv" 10 | // "strings" 11 | // "time" 12 | // ) 13 | 14 | // //Convertor is the custom type to hold the docx to pdf conversion values 15 | // type PDFConvertor struct { 16 | // inputFile string 17 | // method string 18 | // } 19 | 20 | // func main1() { 21 | // //Check if input file is docx 22 | 23 | // //Check if libreoffice or textutil/cupsfilter is present 24 | 25 | // // 26 | // if len(os.Args) == 3 { 27 | // pdfConv := PDFConvertor{inputFile: os.Args[1], method: os.Args[2]} 28 | // //First solution 29 | // if pdfConv.method == "1" { 30 | // err := ConvertUsingTextUtil(pdfConv.inputFile) 31 | // if err != nil { 32 | // fmt.Println(err) 33 | // } 34 | // return 35 | // } else if pdfConv.method == "2" { 36 | // err := ConvertUsingLibreOffice(pdfConv.inputFile) 37 | // if err != nil { 38 | // fmt.Println(err) 39 | // } 40 | // return 41 | // } else { 42 | // fmt.Println("Please enter the method as 1 or 2") 43 | // } 44 | 45 | // } else { 46 | // fmt.Println("Please enter the files as argument and method") 47 | // } 48 | 49 | // // } else if len(os.Args) == 2 { 50 | // // //Second solution 51 | // // //soffice --headless --convert-to pdf sample.docx 52 | // // err := ConvertUsingLibreOffice(os.Args[1]) 53 | // // if err != nil { 54 | // // fmt.Println(err) 55 | // // } 56 | 57 | // // } 58 | 59 | // } 60 | 61 | // func main2() { 62 | // // ch := make(chan int, 100) 63 | // for i := 0; i < 10; i++ { 64 | // fmt.Println("started ", i, " routine") 65 | // go RConvertUsingLibreOffice("sample" + strconv.Itoa(i) + ".docx") 66 | // } 67 | 68 | // } 69 | 70 | // // ConvertUsingTextUtil uses textutil and cupsfilter to convert docs to pdf 71 | // // textutil -convert html -output "sample.html" sample.docx 72 | // // cupsfilter sample.html > sample.pdf 73 | // func ConvertUsingTextUtil(inputFile string) error { 74 | 75 | // tempOutputHTMLFile := strings.Replace(inputFile, ".docx", ".html", -1) 76 | // outputFile := strings.Replace(inputFile, ".docx", ".pdf", -1) 77 | 78 | // docxToHTMLCmd := exec.Command("bash", "-c", "textutil -convert html -output "+tempOutputHTMLFile+" "+inputFile) 79 | // docxToHTMLCmdErr := docxToHTMLCmd.Run() 80 | // if docxToHTMLCmdErr != nil { 81 | // fmt.Println("1.Conversion issue to pdf") 82 | // return docxToHTMLCmdErr 83 | // } else { 84 | // htmlToPdfCmd := exec.Command("bash", "-c", "cupsfilter "+tempOutputHTMLFile+" > "+outputFile) 85 | // htmlToPdfCmdErr := htmlToPdfCmd.Run() 86 | // if htmlToPdfCmdErr != nil { 87 | // fmt.Println("2.Conversion issue to pdf") 88 | // return htmlToPdfCmdErr 89 | // } 90 | // } 91 | 92 | // return nil 93 | // } 94 | 95 | // //ConvertUsingLibreOffice will use libreoffice to convert the docsx to pdf 96 | // func ConvertUsingLibreOffice(inputFile string) error { 97 | // executable := "libreoffice" 98 | // if os.Getenv("GOOS") == "darwin" || os.Getenv("GOOS") == "" { 99 | 100 | // executable = "/Applications/LibreOffice.app/Contents/MacOS/soffice" 101 | // } 102 | // fmt.Println(os.Getenv("GOOS")) 103 | 104 | // fmt.Println(executable) 105 | // docxToPDFCmd := exec.Command("bash", "-c", executable+" --headless --convert-to pdf "+inputFile) 106 | // docxToPDFCmdErr := docxToPDFCmd.Run() 107 | // if docxToPDFCmdErr != nil { 108 | // fmt.Println("1.Conversion issue to pdf", docxToPDFCmdErr) 109 | // return docxToPDFCmdErr 110 | // } 111 | // return nil 112 | // } 113 | 114 | // //ValidateInputFile is to validate if the inputfile value is correct 115 | // func (c *PDFConvertor) ValidateInputFile() (bool, error) { 116 | // if c.inputFile == "" { 117 | // err := fmt.Errorf("Convertor| InputFile Empty") 118 | // return false, err 119 | // } 120 | // if strings.Index(c.inputFile, ".docx") == -1 { 121 | // err := fmt.Errorf("Convertor| InputFile is not in docx format") 122 | // return false, err 123 | // } 124 | 125 | // return true, nil 126 | 127 | // } 128 | 129 | // // GO ROUTINES 130 | 131 | // type WorkRequest struct { 132 | // Name string 133 | // Delay time.Duration 134 | // File string 135 | // } 136 | 137 | // //COLLECTOR 138 | // // A buffered channel that we can send work requests on. 139 | // var WorkQueue = make(chan WorkRequest, 100) 140 | 141 | // func Collector(w http.ResponseWriter, r *http.Request) { 142 | // // Make sure we can only be called with an HTTP POST request. 143 | // if r.Method != "POST" { 144 | // w.Header().Set("Allow", "POST") 145 | // w.WriteHeader(http.StatusMethodNotAllowed) 146 | // return 147 | // } 148 | 149 | // // Parse the delay. 150 | // delay, err := time.ParseDuration(r.FormValue("delay")) 151 | // if err != nil { 152 | // http.Error(w, "Bad delay value: "+err.Error(), http.StatusBadRequest) 153 | // return 154 | // } 155 | 156 | // // Check to make sure the delay is anywhere from 1 to 10 seconds. 157 | // if delay.Seconds() < 1 || delay.Seconds() > 10 { 158 | // http.Error(w, "The delay must be between 1 and 10 seconds, inclusively.", http.StatusBadRequest) 159 | // return 160 | // } 161 | 162 | // // Now, we retrieve the person's name from the request. 163 | // name := r.FormValue("name") 164 | 165 | // // Just do a quick bit of sanity checking to make sure the client actually provided us with a name. 166 | // if name == "" { 167 | // http.Error(w, "You must specify a name.", http.StatusBadRequest) 168 | // return 169 | // } 170 | // // Now, we retrieve the person's name from the request. 171 | // filename := r.FormValue("filename") 172 | // // Just do a quick bit of sanity checking to make sure the client actually provided us with a name. 173 | // if filename == "" { 174 | // http.Error(w, "You must specify a docx filename.", http.StatusBadRequest) 175 | // return 176 | // } 177 | // CollectorJob(name, delay, filename) 178 | // // And let the user know their work request was created. 179 | // w.WriteHeader(http.StatusCreated) 180 | // return 181 | // } 182 | 183 | // // CollectorJob is the function to be called for PDF generation with requestor name of work and filename with path for docx 184 | // func CollectorJob(name string, delay time.Duration, filename string) { 185 | // // Now, we take the delay, and the person's name, and make a WorkRequest out of them. 186 | // work := WorkRequest{Name: name, Delay: delay, File: filename} 187 | // // Push the work onto the queue. 188 | // WorkQueue <- work 189 | // fmt.Println("Work request queued for PDF generation") 190 | // } 191 | 192 | // ///////WORKER 193 | // // NewWorker creates, and returns a new Worker object. Its only argument 194 | // // is a channel that the worker can add itself to whenever it is done its 195 | // // work. 196 | // func NewWorker(id int, workerQueue chan chan WorkRequest) Worker { 197 | // // Create, and return the worker. 198 | // worker := Worker{ 199 | // ID: id, 200 | // Work: make(chan WorkRequest), 201 | // WorkerQueue: workerQueue, 202 | // QuitChan: make(chan bool)} 203 | 204 | // return worker 205 | // } 206 | 207 | // type Worker struct { 208 | // ID int 209 | // Work chan WorkRequest 210 | // WorkerQueue chan chan WorkRequest 211 | // QuitChan chan bool 212 | // } 213 | 214 | // // This function "starts" the worker by starting a goroutine, that is 215 | // // an infinite "for-select" loop. 216 | // func (w *Worker) Start() { 217 | // go func() { 218 | // for { 219 | // // Add ourselves into the worker queue. 220 | // w.WorkerQueue <- w.Work 221 | 222 | // select { 223 | // case work := <-w.Work: 224 | // // Receive a work request. 225 | // fmt.Printf("worker%d: Received work request, delaying for %f seconds\n", w.ID, work.Delay.Seconds()) 226 | 227 | // //time.Sleep(work.Delay) 228 | // fmt.Printf("Before Generating file:%s", work.File) 229 | // err := RConvertUsingLibreOffice(work.File) 230 | // if err != nil { 231 | // fmt.Printf("Error Generating file:%s", work.File) 232 | // // Failure recovery code here 233 | // } else { 234 | // fmt.Printf("Generated file:%s", work.File) 235 | // } 236 | 237 | // fmt.Printf("worker%d: Hello, %s!\n", w.ID, work.Name) 238 | 239 | // case <-w.QuitChan: 240 | // // We have been asked to stop. 241 | // fmt.Printf("worker%d stopping\n", w.ID) 242 | // return 243 | // } 244 | // } 245 | // }() 246 | // } 247 | 248 | // //ConvertUsingLibreOffice will use libreoffice to convert the docsx to pdf 249 | // func RConvertUsingLibreOffice(inputFile string) error { 250 | // executable := "libreoffice" 251 | // if os.Getenv("GOOS") == "darwin" || os.Getenv("GOOS") == "" { 252 | // executable = "/Applications/LibreOffice.app/Contents/MacOS/soffice" 253 | // } 254 | // fmt.Println(os.Getenv("GOOS")) 255 | 256 | // fmt.Println(executable) 257 | // docxToPDFCmd := exec.Command("bash", "-c", executable+" --headless --convert-to pdf "+inputFile) 258 | // docxToPDFCmdErr := docxToPDFCmd.Run() 259 | // if docxToPDFCmdErr != nil { 260 | // fmt.Println("1.Conversion issue to pdf", docxToPDFCmdErr) 261 | // return docxToPDFCmdErr 262 | // } 263 | // return nil 264 | 265 | // } 266 | 267 | // // Stop tells the worker to stop listening for work requests. 268 | // // 269 | // // Note that the worker will only stop *after* it has finished its work. 270 | // func (w *Worker) Stop() { 271 | // go func() { 272 | // w.QuitChan <- true 273 | // }() 274 | // } 275 | 276 | // //DISPATCHER 277 | 278 | // var WorkerQueue chan chan WorkRequest 279 | 280 | // func StartDispatcher(nworkers int) { 281 | // // First, initialize the channel we are going to but the workers' work channels into. 282 | // WorkerQueue = make(chan chan WorkRequest, nworkers) 283 | 284 | // // Now, create all of our workers. 285 | // for i := 0; i < nworkers; i++ { 286 | // fmt.Println("Starting worker", i+1) 287 | // worker := NewWorker(i+1, WorkerQueue) 288 | // worker.Start() 289 | // } 290 | 291 | // go func() { 292 | // for { 293 | // select { 294 | // case work := <-WorkQueue: 295 | // fmt.Println("Received work requeust") 296 | // go func() { 297 | // worker := <-WorkerQueue 298 | 299 | // fmt.Println("Dispatching work request") 300 | // worker <- work 301 | // }() 302 | // } 303 | // } 304 | // }() 305 | // } 306 | 307 | // var ( 308 | // NWorkers = flag.Int("n", 1, "The number of workers to start") 309 | // HTTPAddr = flag.String("http", "127.0.0.1:8000", "Address to listen for HTTP requests on") 310 | // ) 311 | 312 | // func main3() { 313 | // // Parse the command-line flags. 314 | // flag.Parse() 315 | 316 | // // Start the dispatcher. 317 | // fmt.Println("Starting the dispatcher") 318 | // StartDispatcher(*NWorkers) 319 | 320 | // // Register our collector as an HTTP handler function. 321 | // fmt.Println("Registering the collector") 322 | // http.HandleFunc("/work", Collector) 323 | 324 | // // Start the HTTP server! 325 | // fmt.Println("HTTP server listening on", *HTTPAddr) 326 | // if err := http.ListenAndServe(*HTTPAddr, nil); err != nil { 327 | // fmt.Println(err.Error()) 328 | // } 329 | // } 330 | --------------------------------------------------------------------------------