diff --git a/.gitignore b/.gitignore index ee0675c..d5ba7a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.xml config.json +*.mp3 diff --git a/README.md b/README.md index dd583fa..cc43509 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,7 @@ MDRSS is a markdown to RSS converter written in GO. With this tool, you can write articles in a local folder and have them automatically formatted to an RSS compliant XML file. As a result, you don't have to write articles on your website first and have them be read by an RSS reader. Moreover, MDRSS automatically takes care of publication dates, categories (next update), formatting, etc. ### Getting started -You can install the binary using `go install github.com/TimoKats/mdrss@latest` (make sure your GOPATH is set correctly!). After this you can add your configuration in `~/.mdrss/config.json`. This is a JSON file with a number of settings. You can use this template to setup your configuration. Note, the most recent update also allows users to specify their own config path, which you can define like so. - -```shell -mdrss --config other/path/to/config update -``` +You can install the binary using `go install github.com/TimoKats/mdrss@latest` (make sure your GOPATH is set correctly!). After this you can add your configuration in `~/.mdrss/config.json`. This is a JSON file with a number of settings. You can use this template to setup your configuration. ```JSON { @@ -19,7 +15,18 @@ mdrss --config other/path/to/config update } ``` -In your input folder, you can add an article by creating a `.md` file. **Note, if your filename is prefixed with `draft-` it will not be included in the RSS file**. Finally, you can type `mdrss ls` to view the articles ready for publishing and `mdrss update` to create the RSS feed. Note, the title of the RSS articles are based on markdown headers. E.g. format the first line of the markdown articles as so: `# this is a title`. +Note, the most recent update also allows users to specify their own config path, which you can define like so. +```shell +mdrss --config other/path/to/config update +``` + +In your input folder, you can add an article by creating a `.md` file. **Note, if your filename is prefixed with `draft-` it will not be included in the RSS file**. Finally, you can type `mdrss ls` to view the articles ready for publishing and `mdrss update` to create the RSS feed. Note, the title of the RSS articles are based on markdown headers. E.g. format the first line of the markdown articles as so: `# this is a title`. + +Mdrss also supports the usage of RSS enclosures (relevant for podcasts). To create an enclosure link: create a regular markdown link to the audio file with the identifier as "audio/mpeg". + +```markdown +[audio/mpeg](https://link.to.mp3/file.mp3) +``` ### Publishing the RSS file You can submit your RSS file to a public website, or put it somewhere easily available on a public drive, apache server, etc. Note, there is a chance I will make a function for this on my website so that people who can't host RSS feeds themselves can still publish their feeds. Please let me know if you're interested in such a service. @@ -29,7 +36,6 @@ List of features that are on the planning. Feel free to send suggestions here. * Display source code from markdown more correctly. * For non textual RSS readers: render images. * Ordered lists - * RSS enclosures for podcasts ### Why RSS? * No ads/trackers/cookies. diff --git a/lib/filesize.go b/lib/filesize.go new file mode 100644 index 0000000..bb05393 --- /dev/null +++ b/lib/filesize.go @@ -0,0 +1,37 @@ +package lib + +import ( + "unicode" + "strings" + "os/exec" + "errors" +) + +func extractInt(text string) string { + filteredString := "" + for _, character := range text { + if unicode.IsDigit(character) { + filteredString += string(character) + } + } + if len(filteredString) == 0 { + return "1" + } else { + return filteredString + } +} + +func FileSizeUrl(url string) (string, error) { + cmd := exec.Command("curl", "-sIL", url) + cmdOutput, cmdErr := cmd.Output() + if cmdErr != nil { + return "1", errors.New("Issues when running curl to get filesize.") + } else { + for _, line := range strings.Split(string(cmdOutput), "\n") { + if strings.Contains(line, "content-length") { + return extractInt(line), nil + } + } + } + return "1", errors.New("No content-length found for url") +} diff --git a/lib/markdown.go b/lib/markdown.go index 0585a79..91cd9f2 100644 --- a/lib/markdown.go +++ b/lib/markdown.go @@ -31,6 +31,16 @@ func convertMarkdownLink(text string, markdownLinks *regexp.Regexp) string { return "

" + markdownLinks.ReplaceAllString(text, "$1") + "

" } +func convertMarkdownEnclosure(text string, markdownLinks *regexp.Regexp) string { + url := markdownLinks.ReplaceAllString(text, "$2") + size, fileSizeErr := FileSizeUrl(url) + if fileSizeErr != nil { + Error.Println(fileSizeErr) + return "" + } + return "" +} + func convertMarkdownList(text string) string { if !markdownListActive { markdownListActive = true @@ -42,6 +52,9 @@ func convertMarkdownList(text string) string { func ConvertMarkdownToRSS(text string) string { markdownLinks := regexp.MustCompile(`\[(.*)\]\((.*)\)`) markdownLists := regexp.MustCompile(`^(\s*)(-|\*|\+)(.*)`) + if markdownLinks.Match([]byte(text)) && strings.Contains(text, "audio/mpeg") { + return convertMarkdownEnclosure(text, markdownLinks) + } if markdownLinks.Match([]byte(text)) { return convertMarkdownLink(text, markdownLinks) } @@ -59,7 +72,7 @@ func GetArticles(config Config) ([]Article, error) { articles := []Article{} if fileErr == nil { for _, file := range RawArticles { - if !file.IsDir() && !strings.HasPrefix(file.Name(), "draft-") { + if !file.IsDir() && !strings.HasPrefix(file.Name(), "draft-") && strings.HasSuffix(file.Name(), ".md") { var article Article fileInfo, _ := file.Info() article.Filename = file.Name() diff --git a/mdrss_test.go b/mdrss_test.go index d788b70..bc59c83 100644 --- a/mdrss_test.go +++ b/mdrss_test.go @@ -64,6 +64,24 @@ func TestConvertLinks(t *testing.T) { } } +func TestEnclosures(t *testing.T) { + got, fileSizeErr := mdrss.FileSizeUrl("https://file-examples.com/storage/fec2f2681466d1d67a0683d/2017/11/file_example_MP3_700KB.mp3") + want := "733645" + if got != want { + t.Errorf("got %v, wanted %v", got, want) + } + if fileSizeErr != nil { + t.Errorf("not good %v", fileSizeErr) + } +} + +func TestFakeEnclosures(t *testing.T) { + _, fileSizeErr := mdrss.FileSizeUrl("hello.mp3") + if fileSizeErr == nil { + t.Errorf("Should give Error, but no.") + } +} + func TestBasics(t *testing.T) { config := testConfig() articles, _ := mdrss.GetArticles(config) diff --git a/test/another-article.md b/test/another-article.md index b2eda9f..6d10075 100644 --- a/test/another-article.md +++ b/test/another-article.md @@ -5,6 +5,8 @@ Hi all. I've added my public PGP key to the files section of this website. It's linked to my main e-mail address (hello[at]timokats[dot]xyz). +[audio/mpeg](https://www.native-instruments.com/fileadmin/ni_media/producer/koresoundpack/fm8transientattacks/audio/1_FM8ROXXS.mp3) + Note, for me it's not a hard requirement to use it when sending me an email. In fact, it's mainly there for those that prefer/require encrypted correspondence when contacting me. Timo