Skip to content

Commit

Permalink
Added Directory input support
Browse files Browse the repository at this point in the history
  • Loading branch information
ajaxray committed Mar 26, 2018
1 parent 3e750d6 commit 9510136
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 19 deletions.
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ merge2pdf output.pdf input1.pdf~1 input2.pdf input3.pdf~2,3,4
# Merge multiple Images
merge2pdf output.pdf image1.jpg image2.jpg path/to/other.png ...

# Mixing up PDF, PDF Pages and Images
merge2pdf output.pdf doc1.pdf~1,2 image1.jpg image2.png path/to/other.pdf ...
# Merge all Images/PDFs of one or multiple directory
merge2pdf output.pdf path/to/a/dir path/to/another ...

# Mixing up PDF, PDF Pages, Images and directories
merge2pdf output.pdf doc1.pdf~1,2 image1.jpg path/to/dir path/to/other.pdf ...
```

### Fine tuning Image pages
Expand Down Expand Up @@ -65,17 +68,23 @@ To see details of options,
```bash
merge2pdf -h
```
### Notes

- `--size`, `--margin`, `--scale-width`, `--scale-height` will only effect images.
- PDF pages will inherit size and margin of source PDF
- _Some_ `.tiff` files (e,g, compression level 4) may not work properly
- Directory inputs will be searched for image/PDF files on first level only. Subdirectories will be skipped.

### Roadmap

✅ Merge multiple PDFs without loosing quality
✅ Merge multiple PDFs with **selective pages**
✅ Adding Images
✅ Mixing up Images and PDFs
️ Merge all (Image and PDF) files from directory
✅ Mixing up Images and PDFs
️ Merge all (Image and PDF) files from directory
✅ Option to Resize Images to reduce filesize
◻️ Option to Greyscale Images to reduce filesize
◻️ Option to set files and pages as JSON config to make usages from other app more convenient
◻️ Option to set files and pages as JSON config to make usages from other app more convenient

### Contribute

Expand Down
40 changes: 40 additions & 0 deletions dir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
"fmt"
"io/ioutil"
"path/filepath"

"github.com/unidoc/unidoc/pdf/creator"
)

type DirSource struct {
path string
files []Mergeable
}

func (s DirSource) MergeTo(c *creator.Creator) error {
debugInfo(fmt.Sprintf("Adding Directory: %s", s.path))
var err error

for _, mergeableFile := range s.files {
err = mergeableFile.MergeTo(c)
if err != nil {
break
}
}

return err
}

func (s *DirSource) scanMergeables() {
filesInDir, _ := ioutil.ReadDir(s.path)

for _, file := range filesInDir {
if file.IsDir() {
continue
}

s.files = append(s.files, getMergeableFile(filepath.Join(s.path, file.Name()), []int{}))
}
}
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func init() {

flag.Usage = func() {
fmt.Println("merge2pdf [options...] <output_file> <input_file> [<input_file>...]")
fmt.Println("<output_file> should be a PDF file and <input_file> can be PDF or image files. PDF files can have specific page numbers to merge.")
fmt.Println("Example: merge2pdf output.pdf input1.pdf input_pages.pdf~1,2,3 input3.jpg /path/to/input.png ...")
fmt.Println("<output_file> should be a PDF file and <input_file> can be PDF, image or directory. PDF files can have specific page numbers to merge.")
fmt.Println("Example: merge2pdf output.pdf input1.pdf input_pages.pdf~1,2,3 input3.jpg /path/to/dir ...")
flag.PrintDefaults()
}
}
Expand Down
48 changes: 36 additions & 12 deletions source.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/unidoc/unidoc/pdf/creator"
)

type mergable interface {
type Mergeable interface {
MergeTo(c *creator.Creator) error
}

Expand All @@ -22,36 +22,60 @@ type source struct {
}

// Initiate new source file from input argument
func NewSource(input string) mergable {
func NewSource(input string) Mergeable {
fileInputParts := strings.Split(input, "~")

path := fileInputParts[0]
f, err := os.Open(fileInputParts[0])
var inputSource Mergeable

info, err := os.Stat(path)
if err != nil {
log.Fatal("Cannot read source file:", fileInputParts[0])
log.Fatal("Error:", err.Error())
}

switch mode := info.Mode(); {
case mode.IsDir():
inputSource = getMergeableDir(path)
case mode.IsRegular():
pages := []int{}
if len(fileInputParts) > 1 {
pages = parsePageNums(fileInputParts[1])
}
inputSource = getMergeableFile(path, pages)
}

return inputSource
}

func getMergeableDir(path string) Mergeable {
dir := DirSource{path: path}
dir.scanMergeables()

return dir
}

func getMergeableFile(path string, pages []int) Mergeable {
f, err := os.Open(path)
if err != nil {
log.Fatal("Cannot read source file:", path)
}

defer f.Close()

ext := filepath.Ext(f.Name())
mime, err := getMimeType(f)
if err != nil {
log.Fatal("Error in getting mime type of file:", fileInputParts[0])
log.Fatal("Error in getting mime type of file:", path)
}

sourceType, err := getFileType(mime, ext)
if err != nil {
log.Fatal("Error : %s (%s)", err.Error(), path)
}

pages := []int{}
if len(fileInputParts) > 1 {
pages = parsePageNums(fileInputParts[1])
}

source := source{path, sourceType, mime, ext, pages}

var m mergable
var m Mergeable
switch sourceType {
case "image":
m = ImgSource{source}
Expand All @@ -77,7 +101,7 @@ func getFileType(mime, ext string) (string, error) {
return "image", nil
}

return "error", errors.New("Could not detect file type.")
return "error", errors.New("File type not acceptable. ")
}

func parsePageNums(pagesInput string) []int {
Expand Down

0 comments on commit 9510136

Please sign in to comment.