~reesmichael1/roman

ref: b02f932604e5b3cb96b5663c6d54b50b61903ea7 roman/src/romanpkg/main.nim -rw-r--r-- 4.0 KiB View raw
b02f9326Michael Rees Escape fields in subscriptions file 2 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
143
144
145
146
147
148
import options
import sequtils
import strutils
import tables

import errors
import feeds
import subscriptions
import termask

import seqreplace
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)



proc runMainPath() {.raises: [RomanError, InterruptError].} =
  let subs = getSubscriptions()
  var feeds: seq[Feed]
  var feed: Feed
  if subs.len == 0:
    echo "You aren't subscribed to any feeds yet! ",
      "Use roman subscribe [url] to add some."
    return
  feeds = getFeeds(subs)

  while true:
    if feeds.len == 1:
      feed = feeds[0]
      displayFeed(feed)
    else:
      feed = chooseFeed(feeds)
      # Keep track of the originally selected feed
      # so that we can replace it with the updated unread counts later
      var oldFeed = feed
      try:
        displayFeed(feed)
      except InterruptError:
        # These errors are coming from declining to select a post
        # Instead of exiting, return to the feed selection
        try:
          feeds.replace(oldFeed, feed)
        except KeyError as e:
          raise newException(RomanError,
            "could not find feed in list of feeds: " & e.msg)
        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 subs.len
        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)