~reesmichael1/roman

ref: 7a95a17d006e08e02f638b15caba2a56ce590741 roman/src/romanpkg/main.nim -rw-r--r-- 3.7 KiB
7a95a17dMichael Rees Allow toggling read status from post selection 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import options
import sequtils
import strutils
import tables

import errors
import feeds
import subscriptions
import termask

import types


proc chooseSubscription(subs: seq[Subscription]): Subscription {.raises: [
    RomanError, InterruptError].} =
  var displayNames = initTable[Subscription, string]()
  for sub in subs:
    # TODO: wrap width if necessary
    displayNames[sub] = sub.name & " (" & sub.url & ")"
  try:
    let selectedName = promptList("Select Subscription", subs,
        displayNames = displayNames, show = 10)
    if selectedName.isNone:
      raise newException(InterruptError, "no subscription selected")
    result = selectedName.unsafeGet()
  except ValueError, IOError:
    raise newException(RomanError, getCurrentExceptionMsg())


proc chooseFeed(feeds: seq[Feed]): Feed {.raises: [RomanError,
    InterruptError].} =
  var displayNames = initTable[Feed, string]()
  for feed in feeds:
    displayNames[feed] = feed.formatTitle()
  try:
    let selectedName = promptList("Select Feed", feeds,
        displayNames = displayNames, show = 10)
    if selectedName.isNone:
      raise newException(InterruptError, "no feed selected")
    result = selectedName.unsafeGet()
  except ValueError, IOError:
    raise newException(RomanError, getCurrentExceptionMsg())


proc chooseManageAction(): ManageAction {.raises: [RomanError].} =
  # TODO: implement more actions
  try:
    var displayNames = {
      EditTitle: "edit title",
      NoOp: "do nothing",
      Unsubscribe: "unsubscribe"
    }.toTable
    let action = promptList("Choose operation", [EditTitle, Unsubscribe, NoOp], displayNames)
    if action.isNone:
      return NoOp
    return action.unsafeGet()
  except InterruptError:
    return NoOp
  except ValueError, IOError:
    let msg = getCurrentExceptionMsg()
    raise newException(RomanError, "error when choosing operation: " & msg)


const NOT_SUBSCRIBED_MSG = "You aren't subscribed to any feeds yet! " &
  "Use roman subscribe [url] to add some."



proc runMainPath() {.raises: [RomanError, InterruptError].} =
  let subs = getSubscriptions()
  var feeds: seq[Feed]
  var feed: Feed
  if subs.len == 0:
    echo NOT_SUBSCRIBED_MSG
    return
  feeds = getFeeds(subs)

  while true:
    if feeds.len == 1:
      feed = feeds[0]
      displayFeed(feed)
    else:
      feed = chooseFeed(feeds)
      try:
        displayFeed(feed)
      except InterruptError:
        # This error comes from declining to select a post
        # Instead of exiting, return to the feed selection
        continue


proc subscribe*(url, feedKindRaw: string) {.raises: [].} =
  try:
    var feedKind = Unknown
    if cmpIgnoreCase(feedKindRaw, "rss") == 0:
      feedKind = RSS
    elif cmpIgnoreCase(feedKindRaw, "atom") == 0:
      feedKind = Atom
    elif feedKindRaw != "":
      raise newException(RomanError, "unrecognized feed type: " & feedKindRaw)
    addSubscriptionToSubsFile(url, feedKind)
  except RomanError as e:
    echo "error: ", e.msg
    quit(1)


proc manage*() {.raises: [].} =
  while true:
    try:
      let subs = getSubscriptions()
      var sub: Subscription
      if subs.len == 0:
        echo NOT_SUBSCRIBED_MSG
        return
      elif subs.len == 1:
        sub = subs[0]
      else:
        sub = chooseSubscription(subs)
      let action = chooseManageAction()
      case action
      of NoOp:
        discard
      of EditTitle:
        editSubscriptionTitle(sub)
      of Unsubscribe:
        removeSubscriptionFromSubsFile(sub)
    except InterruptError:
      quit(0)
    except RomanError as e:
      echo "error: ", e.msg
      quit(1)


proc main*() {.raises: [].} =
  try:
    runMainPath()
  except RomanError as e:
    echo "error: ", e.msg
    quit(1)

  except InterruptError:
    quit(0)