Skip to content

Commit

Permalink
feat(exporter): PDF and MD support with txtpaper
Browse files Browse the repository at this point in the history
  • Loading branch information
ncarlier committed Apr 30, 2022
1 parent 66b013e commit 57f24e2
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/exporter/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ import (
_ "github.com/ncarlier/readflow/pkg/exporter/html"
// activate EPUB exporter
_ "github.com/ncarlier/readflow/pkg/exporter/epub"
// activate txtpaper exporter
_ "github.com/ncarlier/readflow/pkg/exporter/txtpaper"
)
71 changes: 71 additions & 0 deletions pkg/exporter/txtpaper/txtpaper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package txtpaper

import (
"context"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"

"github.com/ncarlier/readflow/pkg/exporter"
"github.com/ncarlier/readflow/pkg/model"
)

const txtpaperURL = "https://txtpaper.com/api/v1/"

// TxtpaperExporter convert an article using txtpaper service
type TxtpaperExporter struct {
format string
}

func newTxtpaperExporter(format string) func(downloader exporter.Downloader) (exporter.ArticleExporter, error) {
return func(downloader exporter.Downloader) (exporter.ArticleExporter, error) {
return &TxtpaperExporter{
format: format,
}, nil
}
}

// Export an article using txtpaper service
func (exp *TxtpaperExporter) Export(ctx context.Context, article *model.Article) (*model.FileAsset, error) {
form := url.Values{}
form.Add("byline", *article.URL)
form.Add("content", *article.HTML)
form.Add("format", exp.format)

ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "POST", txtpaperURL, strings.NewReader(form.Encode()))
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()

if res.StatusCode >= 400 {
return nil, fmt.Errorf("invalid txtpaper response: %d", res.StatusCode)
}

body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}

return &model.FileAsset{
Data: body,
ContentType: res.Header.Get("Content-Type"),
Name: strings.TrimRight(article.Title, ". ") + "." + exp.format,
}, nil
}

func init() {
exporter.Register("pdf", newTxtpaperExporter("pdf"))
exporter.Register("md", newTxtpaperExporter("md"))
exporter.Register("mobi", newTxtpaperExporter("mobi"))
}
2 changes: 2 additions & 0 deletions ui/src/articles/components/context-menu/DownloadPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const formats = [
{ value: 'html-single', label: 'HTML file with images', icon: 'image' },
{ value: 'zip', label: 'ZIP file', icon: 'archive' },
{ value: 'epub', label: 'EPUB file', icon: 'menu_book' },
{ value: 'pdf', label: 'PDF file', icon: 'picture_as_pdf' },
{ value: 'md', label: 'Markdown file', icon: 'tag' },
]

interface Props {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const formats: Map<string, string> = new Map([
['Single HTML file with images', 'html-single'],
['ZIP file with HTML and images', 'zip'],
['EPUB file', 'epub'],
['PDF file', 'pdf'],
['Markdown file', 'md'],
])

const Formats = () => (
Expand Down

0 comments on commit 57f24e2

Please sign in to comment.