paster 0.0.2 → 0.0.3

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/bin/paster +74 -31
  3. data/lib/paster.rb +9 -7
  4. data/paster.gemspec +2 -1
  5. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90ea9d39b00350a67bb06330b79e73de23eeb33a
4
- data.tar.gz: 56bac197e3adbf7926a3752ed10d99489826eb9e
3
+ metadata.gz: 676a5ebef7ac14324c4d2cd1d2098292d221c5e3
4
+ data.tar.gz: 8fbd93f4e2a726b0ec0501fa344b02e653f313f1
5
5
  SHA512:
6
- metadata.gz: 103ee1d96ee2f622f5c0bdfa73847e9ad64c2484b770f4f21dcaedb7c7c597701af76384d3b40e4a67b1c8c2ea867487c9257123029b3589c394fdac95d80fb9
7
- data.tar.gz: ef11f98d2ca13044b6bb6260bad3aef22a262ed4e7f50c2d797b0a7c0bbfced11b7efc309cc0dae915a671a0e241ca140d8b7e1836ad26d22bc9acc9266c8f6d
6
+ metadata.gz: e4871746f43300dd4cda17a2e90a7626c61d7e173d86ffe0783f58607a5752a8c231387b36ca7c4d538dc1380d8567d4827804475551f40daf132712e005cba2
7
+ data.tar.gz: 2c179c21bdbe6b248777e56fd94bf8b7f2c48dde3c2dd9a962bb21667b13a0387a368f3a6436bcb49cc3575f49073630e55a437a75b42807daea05b4d3d1154c
data/bin/paster CHANGED
@@ -1,44 +1,87 @@
1
1
  #!/usr/bin/env ruby
2
- Signal.trap(:INT){ abort "\n(interrupted by SIGINT)" }
3
2
  puts ""
4
- puts "(press ^C to abort)"
3
+ # puts "(press ^C to abort)"
4
+
5
+ paste = (!STDIN.tty? && !STDIN.closed? || ARGF.filename != ?-) ? ARGF.read : (require "clipboard"; Clipboard.paste)
6
+ # https://stackoverflow.com/a/68673623/322020
5
7
 
6
- paste = ARGF.read
7
8
  $stdin = open "/dev/tty"
8
9
  puts "paste size: #{paste.size}"
9
10
  require_relative "../lib/paster"
10
11
  paster = Paster paste
12
+ puts "preview: #{inspected = paste[0,30].inspect; inspected.size <= 30 ? inspected : inspected[0,27] + "..."}"
11
13
  puts "detected language: #{paster.lang || "unknown"}" # change 'detected' to 'assumed' if we make it guess by file extension
12
14
  puts ""
13
15
 
14
- require "tty-prompt"
15
- begin
16
- services = {
17
- "burn after reading": ["burn"],
18
- "5 minutes": [5],
19
- "1 hour": [60, 3600],
20
- "1 day": [1440, 86400],
21
- "3 days": [nil, 259200],
22
- "1 week": [10080],
23
- "1 month": [40320],
24
- "3 months": [nil, 7776000],
25
- "1 year": [483840],
26
- "keep forever": [0, -1],
27
- }.map{ |name, value|
28
- paster = paster.dup
29
- paster.expire = value
30
- size = paster.services.size
31
- size.zero? ?
32
- [size, {name: "#{name}", value: paster, disabled: "(no pastebins)"}] :
33
- [size, {name: "#{name} (#{size})", value: paster}]
34
- }
16
+ require "tty-prompt" # if we delay this the rescue matcher may say 'uninitialized constant TTY'
17
+ begin # TODO: we overwrite this identifier, why not?
18
+ options = [
19
+ [
20
+ {
21
+ "burn after reading": ["burn"],
22
+ "5 minutes": [5],
23
+ "1 hour": [60, 3600],
24
+ "1 day": [1440, 86400],
25
+ "3 days": [nil, 259200],
26
+ "1 week": [10080],
27
+ "1 month": [40320],
28
+ "3 months": [nil, 7776000],
29
+ "1 year": [483840],
30
+ "virtually forever": [0, -1],
31
+ },
32
+ :expire,
33
+ "expiration",
34
+ ],
35
+ [
36
+ {
37
+ "unlisted": true,
38
+ "public": false,
39
+ },
40
+ :unlist,
41
+ "visibility",
42
+ ],
43
+ ]
44
+ apply_variants = lambda do |paster, variants, option_name, _|
45
+ variants.map do |variant_name, value|
46
+ [variant_name, paster.dup.tap{ |_| _[option_name] = value }]
47
+ end
48
+ end
35
49
 
36
- abort "no pastebin for such size" if services.all?{ |__, _| _[:disabled] } # TODO: better error message
37
- # otherwise tty-prompt fails with an unhandled exception, lol
50
+ names, paster = options.reduce [[[], paster]] do |pasters, option|
51
+ pasters.flat_map do |names, paster|
52
+ apply_variants.call(paster, *option).map do |variant_name, paster|
53
+ [[*names, variant_name], paster]
54
+ end
55
+ end
56
+ end.max_by{ |_, paster| paster.services.size }
57
+ abort "no pastebin for such size" if paster.services.size.zero? # otherwise tty-prompt fails with an unhandled exception, lol
38
58
 
39
- TTY::Prompt.new.select "expiration:", services.map(&:last),
40
- default: services.max_by(&:first).last[:name],
41
- filter: true, cycle: true, per_page: 100
59
+ loop do
60
+ option, index = TTY::Prompt.new.select "change current options if needed:", [
61
+ *options.map.with_index{ |option, i| {name: "#{option[2]}: #{names[i]}", value: [option, i]} },
62
+ {name: "proceed", value: nil},
63
+ ], default: "proceed",
64
+ filter: true, cycle: true, per_page: 100
65
+ break unless option
66
+ paster, names[index] = TTY::Prompt.new.select "#{option[2]}:",
67
+ apply_variants.call(paster, *option).map{ |name, paster|
68
+ size = paster.services.size
69
+ size.zero? ?
70
+ {name: "#{name}", value: [paster, name], disabled: "(no pastebins)"} :
71
+ {name: "#{name} (#{size})", value: [paster, name]}
72
+ },
73
+ default: option[0].keys.index(names[index]) + 1,
74
+ filter: true, cycle: true, per_page: 100
75
+ end
42
76
  rescue TTY::Reader::InputInterrupt
43
- abort "" # we don't use TTY::Prompt.new(interrupt: :exit) because it does not finish the line
44
- end.paste
77
+ # we don't use TTY::Prompt.new(interrupt: :exit) because it does not finish the last printed line
78
+ abort "\n\n(interrupted by SIGINT)"
79
+ end
80
+ if ENV.include? "DRYRUN"
81
+ require "pp"
82
+ pp paster
83
+ else
84
+ paster.paste
85
+ end
86
+
87
+ puts ""
data/lib/paster.rb CHANGED
@@ -6,8 +6,10 @@ NetHTTPUtils.class_variable_get(:@@_405).add "paste.debian.net"
6
6
  # TODO: upgrade the NetHTTPUtils gem finally to switch to no HEAD calls by default
7
7
 
8
8
  def Paster paste
9
- Struct.new :expire, :lang do
9
+ Struct.new :lang, :expire, :unlist do
10
10
  @paste = paste
11
+ # TODO: write the reasons why we use Struct and differ its attrs from the instance variables
12
+ # one of them is that we don't want to see @paste in .inspect (but that's not the only way to do it though)
11
13
 
12
14
  def initialize
13
15
  STDOUT.sync = true
@@ -25,8 +27,8 @@ def Paster paste
25
27
  end
26
28
  [
27
29
  [
28
- 10000000, [nil], nil,
29
- nil,
30
+ 10000000, [0], nil,
31
+ expire[0], false,
30
32
  "http://sprunge.us", "sprunge", nil,
31
33
  nil,
32
34
  ->resp{
@@ -39,7 +41,7 @@ def Paster paste
39
41
  ],
40
42
  [
41
43
  15000000, ["burn", 0, 5, 60, 1440, 10080, 40320, 483840], nil,
42
- expire[0],
44
+ expire[0], true,
43
45
  "https://paste.the-compiler.org/api/create", "text", nil,
44
46
  File.read("lib/genshi.txt").scan(/'([a-z_0-9-]+)' => '([^']+)',/).rassoc(lang)&.first,
45
47
  ->resp{
@@ -57,7 +59,7 @@ def Paster paste
57
59
  ],
58
60
  [
59
61
  150000, [-1, 3600, 86400, 259200, 7776000], ->_{ 2 > _.count("\n") },
60
- expire[1],
62
+ expire[1], true,
61
63
  "https://paste.debian.net", "code", :multipart,
62
64
  File.read("lib/pygments.txt").scan(/([^']+)', \(([^)]*)/).map{ |_, __| [_, __[/(?<=')[^']*/]] }.assoc(lang)&.last || "-1",
63
65
  ->resp{
@@ -84,11 +86,11 @@ def Paster paste
84
86
  end
85
87
 
86
88
  def paste
87
- services.map do |_, _, _, expire, url, field, multipart, lang, callback, no_redirect = true, extra = nil|
89
+ services.map do |_, _, _, expire, unlistable, url, field, multipart, lang, callback, no_redirect = true, extra = {}|
88
90
  Thread.new do
89
91
  puts begin
90
92
  callback.call NetHTTPUtils.request_data url, :post, *multipart, no_redirect: no_redirect,
91
- form: {"lang" => lang, "expire" => expire}.map{ |k, v| [k, v.to_s] if v }.compact.to_h.merge(extra || {}).merge({field => self.class.instance_variable_get(:@paste)})
93
+ form: {lang: lang, expire: expire}.merge({private: (1 if unlistable && unlist)}).map{ |k, v| [k.to_s, v.to_s] if v }.compact.to_h.merge(extra).merge({field => self.class.instance_variable_get(:@paste)})
92
94
  # if we .strip the response before sending to callback it won't haev the last_response instance_variable
93
95
  rescue => e
94
96
  "failed to paste to #{url}: #{e} -- consider reporting this issue to GitHub"
data/paster.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "paster"
3
- spec.version = "0.0.2"
3
+ spec.version = "0.0.3"
4
4
  spec.summary = "universal asynchronous pastebin CLI"
5
5
 
6
6
  spec.author = "Victor Maslov aka Nakilon"
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.license = "MIT"
9
9
  spec.metadata = {"source_code_uri" => "https://github.com/nakilon/paster"}
10
10
 
11
+ spec.add_dependency "clipboard"
11
12
  spec.add_dependency "nethttputils", "~>0.4.1.3"
12
13
  spec.add_dependency "github-linguist"
13
14
  spec.add_dependency "oga"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov aka Nakilon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-27 00:00:00.000000000 Z
11
+ date: 2021-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: clipboard
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: nethttputils
15
29
  requirement: !ruby/object:Gem::Requirement