mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
230 lines
5.5 KiB
Go
230 lines
5.5 KiB
Go
package pocket
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
|
|
"github.com/rivo/tview"
|
|
"github.com/wtfutil/wtf/cfg"
|
|
"github.com/wtfutil/wtf/logger"
|
|
"github.com/wtfutil/wtf/utils"
|
|
"github.com/wtfutil/wtf/view"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type Widget struct {
|
|
view.ScrollableWidget
|
|
|
|
settings *Settings
|
|
client *Client
|
|
items []Item
|
|
archivedView bool
|
|
}
|
|
|
|
func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget {
|
|
widget := Widget{
|
|
ScrollableWidget: view.NewScrollableWidget(app, nil, settings.common),
|
|
settings: settings,
|
|
client: NewClient(settings.consumerKey, "http://localhost"),
|
|
archivedView: false,
|
|
}
|
|
|
|
widget.CommonSettings()
|
|
widget.SetRenderFunction(widget.Render)
|
|
widget.View.SetScrollable(true)
|
|
widget.View.SetRegions(true)
|
|
widget.KeyboardWidget.SetView(widget.View)
|
|
widget.initializeKeyboardControls()
|
|
widget.Selected = -1
|
|
widget.SetItemCount(0)
|
|
return &widget
|
|
}
|
|
|
|
/* -------------------- Exported Functions -------------------- */
|
|
|
|
func (widget *Widget) Render() {
|
|
|
|
widget.Redraw(widget.content)
|
|
}
|
|
|
|
func (widget *Widget) Refresh() {
|
|
if widget.client.accessToken == nil {
|
|
metaData, err := readMetaDataFromDisk()
|
|
if err != nil || metaData.AccessToken == nil {
|
|
widget.Redraw(widget.authorizeWorkFlow)
|
|
return
|
|
}
|
|
widget.client.accessToken = metaData.AccessToken
|
|
}
|
|
|
|
state := Unread
|
|
if widget.archivedView {
|
|
state = Read
|
|
}
|
|
response, err := widget.client.GetLinks(state)
|
|
if err != nil {
|
|
widget.SetItemCount(0)
|
|
}
|
|
|
|
widget.items = orderItemResponseByKey(response)
|
|
widget.SetItemCount(len(widget.items))
|
|
widget.Redraw(widget.content)
|
|
}
|
|
|
|
/* -------------------- Unexported Functions -------------------- */
|
|
|
|
type pocketMetaData struct {
|
|
AccessToken *string
|
|
}
|
|
|
|
func writeMetaDataToDisk(metaData pocketMetaData) error {
|
|
|
|
fileData, err := yaml.Marshal(metaData)
|
|
if err != nil {
|
|
return fmt.Errorf("could not write token to disk %w", err)
|
|
}
|
|
|
|
wtfConfigDir, err := cfg.WtfConfigDir()
|
|
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
filePath := fmt.Sprintf("%s/%s", wtfConfigDir, "pocket.data")
|
|
err = ioutil.WriteFile(filePath, fileData, 0644)
|
|
|
|
return err
|
|
}
|
|
|
|
func readMetaDataFromDisk() (pocketMetaData, error) {
|
|
wtfConfigDir, err := cfg.WtfConfigDir()
|
|
var metaData pocketMetaData
|
|
if err != nil {
|
|
return metaData, err
|
|
}
|
|
filePath := fmt.Sprintf("%s/%s", wtfConfigDir, "pocket.data")
|
|
fileData, err := utils.ReadFileBytes(filePath)
|
|
|
|
if err != nil {
|
|
return metaData, err
|
|
}
|
|
|
|
err = yaml.Unmarshal(fileData, &metaData)
|
|
|
|
return metaData, err
|
|
|
|
}
|
|
|
|
/*
|
|
Authorization workflow is documented at https://getpocket.com/developer/docs/authentication
|
|
broken to 4 steps :
|
|
1- Obtain a platform consumer key from http://getpocket.com/developer/apps/new.
|
|
2- Obtain a request token
|
|
3- Redirect user to Pocket to continue authorization
|
|
4- Receive the callback from Pocket, this wont be used
|
|
5- Convert a request token into a Pocket access token
|
|
*/
|
|
func (widget *Widget) authorizeWorkFlow() (string, string, bool) {
|
|
title := widget.CommonSettings().Title
|
|
|
|
if widget.settings.requestKey == nil {
|
|
requestToken, err := widget.client.ObtainRequestToken()
|
|
|
|
if err != nil {
|
|
logger.Log(err.Error())
|
|
return title, err.Error(), true
|
|
}
|
|
widget.settings.requestKey = &requestToken
|
|
redirectURL := widget.client.CreateAuthLink(requestToken)
|
|
content := fmt.Sprintf("Please click on %s to Authorize the app", redirectURL)
|
|
return title, content, true
|
|
}
|
|
|
|
if widget.settings.accessToken == nil {
|
|
accessToken, err := widget.client.GetAccessToken(*widget.settings.requestKey)
|
|
if err != nil {
|
|
logger.Log(err.Error())
|
|
redirectURL := widget.client.CreateAuthLink(*widget.settings.requestKey)
|
|
content := fmt.Sprintf("Please click on %s to Authorize the app", redirectURL)
|
|
return title, content, true
|
|
}
|
|
content := "Authorized"
|
|
widget.settings.accessToken = &accessToken
|
|
|
|
metaData := pocketMetaData{
|
|
AccessToken: &accessToken,
|
|
}
|
|
|
|
err = writeMetaDataToDisk(metaData)
|
|
if err != nil {
|
|
content = err.Error()
|
|
}
|
|
|
|
return title, content, true
|
|
}
|
|
|
|
content := "Authorized"
|
|
return title, content, true
|
|
|
|
}
|
|
|
|
func (widget *Widget) toggleView() {
|
|
widget.archivedView = !widget.archivedView
|
|
widget.Refresh()
|
|
}
|
|
|
|
func (widget *Widget) openLink() {
|
|
sel := widget.GetSelected()
|
|
if sel >= 0 && widget.items != nil && sel < len(widget.items) {
|
|
item := &widget.items[sel]
|
|
utils.OpenFile(item.GivenURL)
|
|
}
|
|
}
|
|
|
|
func (widget *Widget) toggleLink() {
|
|
sel := widget.GetSelected()
|
|
action := Archive
|
|
if widget.archivedView {
|
|
action = ReAdd
|
|
}
|
|
|
|
if sel >= 0 && widget.items != nil && sel < len(widget.items) {
|
|
item := &widget.items[sel]
|
|
_, err := widget.client.ModifyLink(action, item.ItemID)
|
|
if err != nil {
|
|
logger.Log(err.Error())
|
|
}
|
|
}
|
|
|
|
widget.Refresh()
|
|
}
|
|
|
|
func (widget *Widget) formatItem(item Item, isSelected bool) string {
|
|
foreColor, backColor := widget.settings.common.Colors.RowTheme.EvenForeground, widget.settings.common.Colors.RowTheme.EvenBackground
|
|
text := item.ResolvedTitle
|
|
if isSelected {
|
|
foreColor = widget.settings.common.Colors.RowTheme.HighlightedForeground
|
|
backColor = widget.settings.common.Colors.RowTheme.HighlightedBackground
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("[%s:%s]%s[white]", foreColor, backColor, tview.Escape(text))
|
|
}
|
|
|
|
func (widget *Widget) content() (string, string, bool) {
|
|
title := widget.CommonSettings().Title
|
|
currentViewTitle := "Reading List"
|
|
if widget.archivedView {
|
|
currentViewTitle = "Archived list"
|
|
}
|
|
|
|
title = fmt.Sprintf("%s-%s", title, currentViewTitle)
|
|
content := ""
|
|
|
|
for i, v := range widget.items {
|
|
content += widget.formatItem(v, i == widget.Selected) + "\n"
|
|
}
|
|
|
|
return title, content, false
|
|
}
|