예제 #1
0
func writeHTML(j *job.Job) {
	file := openFile(j.HTMLFilePath())
	defer file.Close()
	if err := template.Execute(file, j); err != nil {
		logger.Panicf("Failed rendering HTML to file: %s", err.Error())
	}
}
예제 #2
0
func Do(logger *log.Logger, j *job.Job, progress string, f func()) {
	defer func() {
		if r := recover(); r != nil {
			if err, ok := r.(friendly); ok {
				progress = err.Friendly()
				logger.Printf("%s: %#v", progress, j)
			} else {
				logger.Printf("%v: %#v", r, j)
			}
			logger.Printf("%s", pruneStack(debug.Stack()))
			j.Progress(progress)
			cleanup.Clean(j)
		}
	}()
	f()
}
예제 #3
0
func rewriteAndDownloadImages(j *job.Job, doc *h5.Node) *h5.Node {
	var wg sync.WaitGroup
	root := j.Root()
	t := transform.NewTransform(doc)
	fix := transform.TransformAttrib("src", func(uri string) string {
		altered := fmt.Sprintf("%x.jpg", hashie.Sha1([]byte(uri)))
		wg.Add(1)
		go safely.Ignore(logger, func() {
			defer wg.Done()
			downloadToFile(uri, fmt.Sprintf("%s/%s", root, altered))
		})
		return altered
	})
	t.Apply(fix, "img")
	wg.Wait()
	return t.Doc()
}
예제 #4
0
func Convert(j *job.Job) {
	go safely.Do(logger, j, FriendlyMessage, func() {
		writeHTML(j)
		cmd := exec.Command(kindlegen, []string{j.HTMLFilename()}...)
		cmd.Dir = j.Root()
		out, err := cmd.CombinedOutput()
		if !util.FileExists(j.MobiFilePath()) {
			logger.Panicf("Failed running kindlegen: %s {output=%s}", err.Error(), string(out))
		}
		j.Progress("Conversion complete...")
		postmark.Mail(j)
	})
}
예제 #5
0
func Extract(j *job.Job) {
	go safely.Do(logger, j, FriendlyMessage, func() {
		makeRoot(j)
		data := downloadAndParse(j)
		checkDoc(data, j)
		doc := parseHTML(data["content"].(string))
		j.Doc = rewriteAndDownloadImages(j, doc)
		j.Title = data["title"].(string)
		j.Domain = data["domain"].(string)
		if author := data["author"]; author != nil {
			j.Author = author.(string)
		}
		j.Progress("Extraction complete...")
		kindlegen.Convert(j)
	})
}
예제 #6
0
func Mail(j *job.Job) {
	go safely.Do(logger, j, FriendlyMessage, func() {
		if stat, err := os.Stat(j.MobiFilePath()); err != nil {
			logger.Panicf("Something weird happen. Mobi is missing in postmark.go: %s", err.Error())
		} else {
			if stat.Size() > MaxAttachmentSize {
				blacklist.Blacklist(j.Url.String())
				failFriendly("Sorry, this article is too big to send!")
			}
		}

		payload := map[string]Any{
			"From":     from,
			"To":       j.Email,
			"Subject":  Subject,
			"TextBody": fmt.Sprintf("Straight to your Kindle! %s: %s", j.Title, j.Url),
			"Attachments": []Any{
				map[string]Any{
					"Name":        j.MobiFilename(),
					"ContentType": "application/octet-stream",
					"Content":     readFile(j.MobiFilePath()),
				},
			},
		}

		var buffer bytes.Buffer
		json.NewEncoder(&buffer).Encode(payload)

		req, err := http.NewRequest("POST", Endpoint, &buffer)
		if err != nil {
			logger.Panicf("Making HTTP Request failed: %s", err.Error())
		}

		setupHeaders(req)
		resp, err := client.Do(req)
		if err != nil {
			logger.Panicf("Postmark failed: %s", err.Error())
		}

		defer resp.Body.Close()
		answer := util.ParseJSON(resp.Body, func(err error) {
			logger.Panicf("Something bad happened with Postmark: %s", err.Error())
		})

		if answer["ErrorCode"] != nil {
			code := int(answer["ErrorCode"].(float64))
			switch code {
			case 0:
				// All is well
			case 300:
				blacklist.Blacklist(j.Email)
				failFriendly("Your email appears invalid. Please try carefully remaking the bookmarklet.")
			default:
				logger.Panicf("Unknown error code from Postmark: %d, %s", code, answer)
			}
		}

		j.Progress("All done! Grab your Kindle and hang tight!")
		cleanup.Clean(j)
	})
}
예제 #7
0
func makeRoot(j *job.Job) {
	if err := os.MkdirAll(j.Root(), 0755); err != nil {
		logger.Panicf("Failed to make working directory: %s", err.Error())
	}
}