Open feed entries as HTML or URL, by preference

This commit is contained in:
Jaidyn Ann 2021-02-20 20:26:42 -06:00
parent afd7ebf2d1
commit b8c27d9db5
9 changed files with 117 additions and 24 deletions

View File

@ -1,5 +1,4 @@
Important Features: Important Features:
* Open As support
* Show download progress/failures in FeedView's feedlist * Show download progress/failures in FeedView's feedlist
* Update FeedView's feedlist when feeds added/removed * Update FeedView's feedlist when feeds added/removed
* Show in desktray * Show in desktray

View File

@ -28,6 +28,7 @@
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
srand(time(0));
installMimeTypes(); installMimeTypes();
App* app = new App(); App* app = new App();
@ -113,7 +114,6 @@ App::ArgvReceived(int32 argc, char** argv)
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
entry_ref ref; entry_ref ref;
BEntry entry(argv[i]); BEntry entry(argv[i]);
std::cout << "ARGV" << std::endl;
if (entry.Exists() && entry.GetRef(&ref) == B_OK) { if (entry.Exists() && entry.GetRef(&ref) == B_OK) {
refMsg.AddRef("refs", &ref); refMsg.AddRef("refs", &ref);
@ -141,7 +141,7 @@ App::RefsReceived(BMessage* message)
char type[B_FILE_NAME_LENGTH]; char type[B_FILE_NAME_LENGTH];
while (message->HasRef("refs", i)) { while (message->HasRef("refs", i)) {
BMessage msg = BMessage(B_REFS_RECEIVED); BMessage msg(B_REFS_RECEIVED);
message->FindRef("refs", i++, &ref); message->FindRef("refs", i++, &ref);
msg.AddRef("refs", &ref); msg.AddRef("refs", &ref);
@ -160,14 +160,50 @@ App::RefsReceived(BMessage* message)
void void
App::_OpenEntryFile(BMessage* refMessage) App::_OpenEntryFile(BMessage* refMessage)
{ {
const char* openWith = fPreferences->EntryOpenWith(); entry_ref entryRef;
entry_ref openRef; refMessage->FindRef("refs", &entryRef);
if (fPreferences->EntryOpenAsHtml())
_OpenEntryFileAsHtml(entryRef);
else
_OpenEntryFileAsUrl(entryRef);
}
void
App::_OpenEntryFileAsHtml(entry_ref ref)
{
const char* openWith = fPreferences->EntryOpenWith();
entry_ref openWithRef;
BString entryTitle("untitled");
BFile(&ref, B_READ_ONLY).ReadAttrString("Feed:name", &entryTitle);
entry_ref tempRef = tempHtmlFile(&ref, entryTitle.String());
BMessage newRefMessage(B_REFS_RECEIVED);
newRefMessage.AddRef("refs", &tempRef);
if (BMimeType(openWith).IsValid()) if (BMimeType(openWith).IsValid())
BRoster().Launch(openWith, refMessage); BRoster().Launch(openWith, &newRefMessage);
else if (BEntry(openWith).GetRef(&openRef) == B_OK) else if (BEntry(openWith).GetRef(&openWithRef) == B_OK)
BRoster().Launch(&openRef, refMessage); BRoster().Launch(&openWithRef, &newRefMessage);
}
void
App::_OpenEntryFileAsUrl(entry_ref ref)
{
const char* openWith = fPreferences->EntryOpenWith();
entry_ref openWithRef;
BString entryUrl;
if (BFile(&ref, B_READ_ONLY).ReadAttrString("META:url", &entryUrl) != B_OK)
return;
const char* urlArg = entryUrl.String();
if (BMimeType(openWith).IsValid())
BRoster().Launch(openWith, 1, &urlArg);
else if (BEntry(openWith).GetRef(&openWithRef) == B_OK)
BRoster().Launch(&openWithRef, 1, &urlArg);
} }

View File

@ -32,6 +32,8 @@ public:
private: private:
void _OpenEntryFile(BMessage* refMessage); void _OpenEntryFile(BMessage* refMessage);
void _OpenEntryFileAsHtml(entry_ref ref);
void _OpenEntryFileAsUrl(entry_ref ref);
void _OpenSourceFile(BMessage* refMessage); void _OpenSourceFile(BMessage* refMessage);
FeedController* fFeedController; FeedController* fFeedController;

View File

@ -35,7 +35,6 @@ EntriesView::AttachedToWindow()
fEntryFolderText->SetTarget(this); fEntryFolderText->SetTarget(this);
fEntryFolderBrowseButton->SetTarget(this); fEntryFolderBrowseButton->SetTarget(this);
fOpenAsAutoRadio->SetTarget(this);
fOpenAsHtmlRadio->SetTarget(this); fOpenAsHtmlRadio->SetTarget(this);
fOpenAsUrlRadio->SetTarget(this); fOpenAsUrlRadio->SetTarget(this);
fOpenWithSelectButton->SetTarget(this); fOpenWithSelectButton->SetTarget(this);
@ -65,11 +64,6 @@ EntriesView::MessageReceived(BMessage* msg)
((App*)be_app)->fPreferences->fOpenAs = kOpenAsUrl; ((App*)be_app)->fPreferences->fOpenAs = kOpenAsUrl;
break; break;
} }
case kOpenAutoRadio:
{
((App*)be_app)->fPreferences->fOpenAs = kOpenAsAuto;
break;
}
case kOpenWithSelect: case kOpenWithSelect:
{ {
((App*)be_app)->fPreferences->SetEntryOpenWith( ((App*)be_app)->fPreferences->SetEntryOpenWith(
@ -124,8 +118,6 @@ EntriesView::_InitInterface()
fOpeningBox->SetLabel("Opening"); fOpeningBox->SetLabel("Opening");
fOpenAsLabel = new BStringView("openAsLabel", "Open as:"); fOpenAsLabel = new BStringView("openAsLabel", "Open as:");
fOpenAsAutoRadio = new BRadioButton("asAuto", "Auto",
new BMessage(kOpenAutoRadio));
fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML", fOpenAsHtmlRadio = new BRadioButton("asHtml", "HTML",
new BMessage(kOpenHtmlRadio)); new BMessage(kOpenHtmlRadio));
fOpenAsUrlRadio = new BRadioButton("asUrl", "URL", fOpenAsUrlRadio = new BRadioButton("asUrl", "URL",
@ -142,10 +134,8 @@ EntriesView::_InitInterface()
Preferences* prefs = ((App*)be_app)->fPreferences; Preferences* prefs = ((App*)be_app)->fPreferences;
if (prefs->fOpenAs == kOpenAsHtml) if (prefs->fOpenAs == kOpenAsHtml)
fOpenAsHtmlRadio->SetValue(B_CONTROL_ON); fOpenAsHtmlRadio->SetValue(B_CONTROL_ON);
else if (prefs->fOpenAs == kOpenAsUrl) else
fOpenAsUrlRadio->SetValue(B_CONTROL_ON); fOpenAsUrlRadio->SetValue(B_CONTROL_ON);
else
fOpenAsAutoRadio->SetValue(B_CONTROL_ON);
fEntryFolderText->SetText(prefs->EntryDir()); fEntryFolderText->SetText(prefs->EntryDir());
@ -177,7 +167,6 @@ EntriesView::_InitInterface()
.AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING) .AddGroup(B_VERTICAL, B_USE_DEFAULT_SPACING)
.SetInsets(0, 20, B_USE_ITEM_INSETS, 0) .SetInsets(0, 20, B_USE_ITEM_INSETS, 0)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
.Add(fOpenAsAutoRadio)
.Add(fOpenAsHtmlRadio) .Add(fOpenAsHtmlRadio)
.Add(fOpenAsUrlRadio) .Add(fOpenAsUrlRadio)
.AddGlue() .AddGlue()

View File

@ -25,7 +25,6 @@ enum
kEntryFolderBrowse = 'tbef', kEntryFolderBrowse = 'tbef',
kOpenHtmlRadio = 'rdow', kOpenHtmlRadio = 'rdow',
kOpenUrlRadio = 'roow', kOpenUrlRadio = 'roow',
kOpenAutoRadio = 'raow',
kOpenWithSelect = 'mnow', kOpenWithSelect = 'mnow',
kOpenWithPath = 'pbow', kOpenWithPath = 'pbow',
kOpenWithBrowse = 'tbow' kOpenWithBrowse = 'tbow'
@ -51,7 +50,6 @@ private:
BBox* fOpeningBox; BBox* fOpeningBox;
BStringView* fOpenAsLabel; BStringView* fOpenAsLabel;
BRadioButton* fOpenAsAutoRadio;
BRadioButton* fOpenAsHtmlRadio; BRadioButton* fOpenAsHtmlRadio;
BRadioButton* fOpenAsUrlRadio; BRadioButton* fOpenAsUrlRadio;
BStringView* fOpenWithLabel; BStringView* fOpenWithLabel;

View File

@ -143,3 +143,21 @@ Preferences::SetEntryOpenWith(const char* binPath)
} }
bool
Preferences::EntryOpenAsHtml()
{
return fOpenAs == kOpenAsHtml;
}
bool
Preferences::SetEntryOpenAsHtml(bool asHtml)
{
if (asHtml == true)
fOpenAs = kOpenAsHtml;
else
fOpenAs = kOpenAsUrl;
return asHtml;
}

View File

@ -14,7 +14,6 @@ static const int64 HOUR_IN_MICROSECONDS = 3600000000;
enum enum
{ {
kOpenAsAuto = 0,
kOpenAsHtml = 1, kOpenAsHtml = 1,
kOpenAsUrl = 2 kOpenAsUrl = 2
}; };
@ -38,6 +37,9 @@ public:
BString EntryOpenWith(); BString EntryOpenWith();
status_t SetEntryOpenWith(const char* binPath); status_t SetEntryOpenWith(const char* binPath);
bool EntryOpenAsHtml();
bool SetEntryOpenAsHtml(bool asHtml);
bool fNewNotify; bool fNewNotify;
bool fFailureNotify; bool fFailureNotify;
int8 fOpenAs; int8 fOpenAs;

View File

@ -5,6 +5,8 @@
#include "Util.h" #include "Util.h"
#include <Directory.h>
#include <File.h>
#include <OS.h> #include <OS.h>
#include <Url.h> #include <Url.h>
#include <UrlProtocolRoster.h> #include <UrlProtocolRoster.h>
@ -111,7 +113,18 @@ urlToFilename(BUrl url)
return filename; return filename;
} }
const char*
tempFileName(const char* dir, const char* name, const char* suffix)
{
BString tmpDir("/tmp/");
tmpDir << dir;
BDirectory().CreateDirectory(tmpDir.String(), NULL);
tmpDir << "/" << name << "-" << (rand() % 1000) << "." << suffix;
return tmpDir.String();
}
int32 int32
@ -146,3 +159,34 @@ userFileError(status_t status, const char* path)
} }
entry_ref
tempHtmlFile(entry_ref* ref, const char* title)
{
entry_ref tempRef;
BEntry(tempFileName("Pogger", title, "html")).GetRef(&tempRef);
BFile ogFile(ref, B_READ_ONLY);
BFile htmlFile(&tempRef, B_WRITE_ONLY | B_CREATE_FILE);
char readBuf[100] = {'\0'};
ssize_t readLen = 1;
BString head("<html>\n<head>\n<title>");
head << title << "</title>\n</head>\n<body>\n";
BString tail("</body>\n</html>\n");
const void* headBuf = head.String();
const void* tailBuf = tail.String();
htmlFile.Write(headBuf, head.Length());
while (readLen > 0) {
readLen = ogFile.Read(readBuf, 100);
htmlFile.Write(readBuf, readLen);
}
htmlFile.Write(tailBuf, tail.Length());
return tempRef;
}

View File

@ -24,11 +24,16 @@ bool withinDateRange(BDateTime, BDateTime, BDateTime);
bool isRemotePath(BString); bool isRemotePath(BString);
BString urlToFilename(BUrl url); BString urlToFilename(BUrl url);
const char* tempFileName(const char* dir, const char* name, const char* suffix);
int32 fetch(BUrl url, BDataIO* reply, BString* hash, int timeout); int32 fetch(BUrl url, BDataIO* reply, BString* hash, int timeout);
void userFileError(status_t status, const char* path); void userFileError(status_t status, const char* path);
// Takes a (probably invalid) bit of HTML and adds necessary elements in a
// temporary copy. Returns an entry_ref to said temporary copy.
entry_ref tempHtmlFile(entry_ref* ref, const char* title);
#endif // UTIL_H #endif // UTIL_H