glima 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d5f7b67ff62c0d7d8ec231492f2c8231e5f83dbd
4
+ data.tar.gz: 16537a6a41967c56c017cc0fe541344c6d787cb6
5
+ SHA512:
6
+ metadata.gz: '089186482f1ac400e4a999523640c38e18ce5632676ba65e83a14968b25170beefde1073d1fbe6150c806454f2df609d17a4777dbf3dcfea1918e092260ab017'
7
+ data.tar.gz: 43e2325cbafdac0b0e243a1742191c77eadb76def1369ab364e42485e3d41ca010ad28bfc21fb27c41152660c4fcf4fa26cbd3280c98da3011228583cc1e5047
@@ -0,0 +1,52 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ #
11
+ # Added from https://raw.github.com/github/gitignore/master/Ruby.gitignore
12
+ #
13
+ *.gem
14
+ *.rbc
15
+ /.config
16
+ /coverage/
17
+ /InstalledFiles
18
+ /pkg/
19
+ /spec/reports/
20
+ /spec/examples.txt
21
+ /test/tmp/
22
+ /test/version_tmp/
23
+ /tmp/
24
+
25
+ ## Specific to RubyMotion:
26
+ .dat*
27
+ .repl_history
28
+ build/
29
+
30
+ ## Documentation cache and generated files:
31
+ /.yardoc/
32
+ /_yardoc/
33
+ /doc/
34
+ /rdoc/
35
+
36
+ ## Environment normalization:
37
+ /.bundle/
38
+ /vendor/bundle
39
+ /lib/bundler/man/
40
+
41
+ # for a library or gem, you might want to ignore these files since the code is
42
+ # intended to run in multiple environments; otherwise, check them in:
43
+ # Gemfile.lock
44
+ # .ruby-version
45
+ # .ruby-gemset
46
+
47
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
48
+ .rvmrc
49
+ #
50
+ # Added from /Users/nom/sys/bin/gem-new
51
+ #
52
+ /vendor
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in glima.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Yoshinari Nomura
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ #+TITLE: Glima -- Gmail CLI client.
2
+ #+AUTHOR:
3
+ #+EMAIL:
4
+ #+DATE:
5
+ #+OPTIONS: H:3 num:2 toc:nil
6
+ #+OPTIONS: ^:nil @:t \n:nil ::t |:t f:t TeX:t
7
+ #+OPTIONS: skip:nil
8
+ #+OPTIONS: author:t
9
+ #+OPTIONS: email:nil
10
+ #+OPTIONS: creator:nil
11
+ #+OPTIONS: timestamp:nil
12
+ #+OPTIONS: timestamps:nil
13
+ #+OPTIONS: d:nil
14
+ #+OPTIONS: tags:t
15
+ #+TEXT:
16
+ #+DESCRIPTION:
17
+ #+KEYWORDS:
18
+ #+LANGUAGE: ja
19
+ #+STARTUP: odd
20
+ #+LATEX_CLASS: jsarticle
21
+ #+LATEX_CLASS_OPTIONS: [a4j,dvipdfmx]
22
+ # #+LATEX_HEADER: \usepackage{plain-article}
23
+ # #+LATEX_HEADER: \renewcommand\maketitle{}
24
+ # #+LATEX_HEADER: \pagestyle{empty}
25
+ # #+LaTeX: \thispagestyle{empty}
26
+
27
+ * Installation
28
+ Glima requires Ruby 2.3 or newer.
29
+ It uses safe navigation operator (=&.=) introduced in Ruby 2.3.
30
+
31
+ #+BEGIN_SRC sh
32
+ $ gem install bundler
33
+ $ mkdir /path/to/install/glima
34
+ $ cd /path/to/install/glima
35
+ $ bundle init
36
+ $ echo 'gem "glima"' >> Gemfile
37
+ $ bundle install --path=vendor/bundle --binstubs=exe
38
+ $ export PATH=/path/to/install/glima/exe:$PATH
39
+ #+END_SRC
40
+
41
+ * Setup
42
+ #+BEGIN_SRC sh
43
+ # Create mail cache directory
44
+ $ mkdir -p ~/Mail/all
45
+
46
+ # Create config file
47
+ $ mkdir -p ~/.config/glima
48
+ $ cp examples/config_example.yml ~/.config/glima/config.yml
49
+ $ vi ~/.config/glima/config.yml
50
+
51
+ # Check your inbox
52
+ $ glima scan +inbox
53
+ #+END_SRC
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "glima"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,8 @@
1
+ ################################################################
2
+ GENERAL:
3
+ ################################################################
4
+ CLIENT_ID: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com"
5
+ CLIENT_SECRET: "yyyyyyyyyyyyyyyyyyyyyyyy"
6
+ TOKEN_STORE: "/Users/nom/.config/glima/token_store.yml"
7
+ CONTEXT_STORE: "/Users/nom/.config/glima/context.yml"
8
+ DEFAULT_USER: "????????@gmail.com"
@@ -0,0 +1,287 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ################################################################
4
+ # rbenv support:
5
+ # If this file is a symlink, and bound to a specific ruby
6
+ # version via rbenv (indicated by RBENV_VERSION),
7
+ # I want to resolve the symlink and re-exec
8
+ # the original executable respecting the .ruby_version
9
+ # which should indicate the right version.
10
+ #
11
+ if File.symlink?(__FILE__) and ENV["RBENV_VERSION"]
12
+ ENV["RBENV_VERSION"] = nil
13
+ shims_path = File.expand_path("shims", ENV["RBENV_ROOT"])
14
+ ENV["PATH"] = shims_path + ":" + ENV["PATH"]
15
+ exec(File.readlink(__FILE__), *ARGV)
16
+ end
17
+
18
+ gemfile = File.expand_path("../../Gemfile", __FILE__)
19
+
20
+ if File.exists?(gemfile + ".lock")
21
+ ENV["BUNDLE_GEMFILE"] = gemfile
22
+ require "bundler/setup"
23
+ end
24
+
25
+ require "rubygems"
26
+ require "glima"
27
+ require "cgi"
28
+ require "logger"
29
+
30
+ Encoding.default_external="UTF-8"
31
+
32
+ class GlimaCLI < Glima::Cli
33
+ package_name 'GLIMA'
34
+
35
+ ################################################################
36
+ # global option
37
+
38
+ class_option :profile, :desc => "Set profiler flag", :type => :boolean
39
+
40
+ ################################################################
41
+ # register frequently used options
42
+
43
+ named_option :format, :desc => "Set printing format", :enum => %w(short full metadata minimal raw mewl)
44
+ named_option :dry_run, :desc => "Perform a trial run with no changes made", :type => :boolean
45
+ named_option :query, :desc => "Filter messages by QUERY"
46
+
47
+ ################################################################
48
+ # Command: dezip
49
+ ################################################################
50
+ desc "dezip MSGID DIRECTORY", "Decrypt zip found in MSGID to DIRECTORY"
51
+
52
+ method_option :zip_passwords_file, :desc => "Set additional password-list file."
53
+
54
+ def dezip(gmail_id, directory)
55
+ password_file = options[:password_file] || config.general.zip_passwords_file
56
+ Glima::Command::Dezip.new(gmail_id, directory, password_file)
57
+ end
58
+
59
+ ################################################################
60
+ # Command: events
61
+ ################################################################
62
+ desc "events SINCE", "List operation history SINCE."
63
+
64
+ def events(since)
65
+ client.each_events(since: since) do |ev|
66
+ puts ev.dump
67
+ end
68
+ end
69
+
70
+ ################################################################
71
+ # Command: guess
72
+ ################################################################
73
+ desc "guess MSGID", "Guess labels to add to MSGID"
74
+
75
+ def guess(message_id)
76
+ Glima::Command::Guess.new(message_id)
77
+ end
78
+
79
+ ################################################################
80
+ # Command: label
81
+ ################################################################
82
+ desc "label MSGID", "Add/Remove labels to/from MSGID"
83
+
84
+ method_option :add, :desc => "List of label names to add separated by comma"
85
+ method_option :del, :desc => "List of label names to del separated by comma"
86
+
87
+ def label(message_id)
88
+ add = parse_label_names(options[:add])
89
+ del = parse_label_names(options[:del])
90
+ Glima::Command::Label.new(message_id, add, del)
91
+ end
92
+
93
+ ################################################################
94
+ # Command: labels
95
+ ################################################################
96
+ desc "labels", "List labels"
97
+
98
+ method_option :verbose, :desc => "Show verbose information for each label.", :type => :boolean
99
+
100
+ def labels
101
+ Glima::Command::Labels.new(options[:verbose])
102
+ end
103
+
104
+ ################################################################
105
+ # Command: open
106
+ ################################################################
107
+ desc "open MSGID", "Open article in browser by MSGID"
108
+
109
+ def open(id)
110
+ Launchy.open("https://mail.google.com/mail/u/1/#all/#{id}")
111
+ end
112
+
113
+ ################################################################
114
+ # Command: profile
115
+ ################################################################
116
+ desc "profile", "Show user's profile."
117
+
118
+ def profile
119
+ Glima::Command::Profile.new
120
+ end
121
+
122
+ ################################################################
123
+ # Command: push
124
+ ################################################################
125
+ desc "push EMAIL_FILE", "Push EMAIL_FILE to INBOX"
126
+
127
+ method_option :date, :desc => "Set date source", :enum => %w(time header)
128
+ method_option :thread, :desc => "Set thread Id"
129
+ method_option :label, :desc => "List of label names to add separated by comma"
130
+
131
+ def push(email_file)
132
+ labels = parse_label_names(options[:label])
133
+ date = if options[:date] == "header" then "dateHeader" else "receivedTime" end
134
+ Glima::Command::Push.new(email_file, date, options[:thread], labels)
135
+ end
136
+
137
+ ################################################################
138
+ # Command: relabel
139
+ ################################################################
140
+ desc "relabel SOURCE TARGET", "Rename label SOURCE to TARGET."
141
+
142
+ expand_option :dry_run
143
+
144
+ def relabel(source_name, dest_name)
145
+ Glima::Command::Relabel.new(source_name, dest_name, options[:dry_run])
146
+ end
147
+
148
+ ################################################################
149
+ # Command: scan
150
+ ################################################################
151
+ desc "scan +FOLDER [QUERY]", "Scan FOLDER with QUERY."
152
+
153
+ method_option :format, :desc => "Set printing format", :enum => %w(mew text archive)
154
+
155
+ def scan(folder, search_or_range = nil)
156
+ format = options[:format].to_s.to_sym
157
+ Glima::Command::Scan.new(folder, format, search_or_range)
158
+ end
159
+
160
+ ################################################################
161
+ # Command: show
162
+ ################################################################
163
+ desc "show MSGID", "Show article."
164
+
165
+ method_option :raw, :desc => "Cat raw mail article.", :type => :boolean
166
+
167
+ def show(id)
168
+ client.get_user_smart_message(id) do |message|
169
+ error_and_exit("No message found id:#{id}.") unless message
170
+
171
+ if options[:raw]
172
+ print message.raw
173
+ else
174
+ print message.to_plain_text
175
+ end
176
+ end
177
+ end
178
+
179
+ ################################################################
180
+ # Command: trash
181
+ ################################################################
182
+ desc "trash MSGID ...", "Move messages to trash"
183
+
184
+ def trash(*message_ids)
185
+ if message_ids.empty?
186
+ puts "Do nothing."
187
+ return 0
188
+ end
189
+ Glima::Command::Trash.new(message_ids)
190
+ end
191
+
192
+ ################################################################
193
+ # Command: watch
194
+ ################################################################
195
+ desc "watch [LABEL]", "Watch gmail server and xzip."
196
+
197
+ def watch(queue_label, mark_label)
198
+ queue_label = parse_label_names(queue_label).first
199
+ mark_label = parse_label_names(mark_label).first
200
+ Glima::Command::Watch.new(queue_label, mark_label)
201
+ end
202
+
203
+ ################################################################
204
+ # Command: xzip
205
+ ################################################################
206
+ desc "xzip TARGET", "Transform zip-attachments in TARGET and transmit to Gmail."
207
+
208
+ method_option :add_src_labels, :desc => "Add labels to source", :banner => "LABEL,..."
209
+ method_option :add_dst_labels, :desc => "Add labels to destination", :banner => "LABEL,..."
210
+ method_option :del_src_labels, :desc => "Del labels from source", :banner => "LABEL,..."
211
+ method_option :del_dst_labels, :desc => "Del labels from destination", :banner => "LABEL,..."
212
+
213
+ def xzip(target)
214
+ Glima::Command::Xzip.new(target,
215
+ add_src_labels: parse_label_names(options[:add_src_labels]),
216
+ del_src_labels: parse_label_names(options[:del_src_labels]),
217
+ add_dst_labels: parse_label_names(options[:add_dst_labels]),
218
+ del_dst_labels: parse_label_names(options[:del_dst_labels]))
219
+ end
220
+
221
+ ################################################################
222
+ # add some hooks to Thor
223
+
224
+ no_commands do
225
+ def invoke_command(command, *args)
226
+ setup_global_options unless command.name == "init"
227
+ result = super
228
+ teardown
229
+ result
230
+ end
231
+ end
232
+
233
+ ################################################################
234
+ # private
235
+
236
+ private
237
+
238
+ def error_and_exit(message)
239
+ STDERR.puts message
240
+ exit 1
241
+ end
242
+
243
+ def parse_label_names(label_names)
244
+ (label_names&.split(/ *, */) || []).map do |name|
245
+ unless label = client.label_by_name(name)
246
+ error_and_exit("No label named #{name}")
247
+ end
248
+ label
249
+ end
250
+ end
251
+
252
+ attr_reader :builder, :config, :client, :context
253
+
254
+ def setup_global_options
255
+ exit_on_error do
256
+ @config = Glima::Config.create_from_file(options[:config] || CONFIG_PATH)
257
+ @datastore = Glima::DataStore.new(File.expand_path("~/Mail"))
258
+ @client = Glima::GmailClient.new(config.general, @datastore)
259
+ @context = Glima::Context.new(File.expand_path(CONFIG_HOME))
260
+
261
+ logger = ::Logger.new($stderr)
262
+ logger.formatter = proc {|severity, datetime, progname, msg| "#{msg}\n"}
263
+
264
+ Glima::Command.client = client
265
+ Glima::Command.logger = logger
266
+ # Glima::GmailClient.logger = logger
267
+
268
+ if options[:profile]
269
+ require 'profiler'
270
+ Profiler__.start_profile
271
+ end
272
+ if options[:debug]
273
+ require "pp"
274
+ $GLIMA_DEBUG = true
275
+ $GLIMA_DEBUG_FOR_DEVELOPER = true if ENV["GLIMA_DEBUG_FOR_DEVELOPER"]
276
+ end
277
+ end
278
+ end
279
+ end
280
+
281
+ def teardown
282
+ if options[:profile]
283
+ Profiler__.print_profile($stdout)
284
+ end
285
+ end
286
+
287
+ GlimaCLI.start(ARGV)