tinyletter 0.0.6

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3360309e0cfa8ceaada75812e814e3419432aaff
4
+ data.tar.gz: dd43cd9db03c595a81cc09b5a2ac66aef9ff380e
5
+ SHA512:
6
+ metadata.gz: f108d124288f2c8f2ee458f3d99109f5fbf2a145e75fd8f4408507d5677b0dad1b5528b832958767e7c21bed629747479bb032eaa4209432fa4b67589c9eabac
7
+ data.tar.gz: 40664228495431b803d36c8d0d4d3007d4282267fdd9fb46e0818b6a4074c2ecc109636e8a97212e28c238da8a0daa4ab6a1e3d994e07ad9b8133ab0ed20084d
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ Ruby gem that retrieves the metadata of a given tinyletter newsletter.
2
+
3
+ ### Installation
4
+
5
+ ```gem install tinyletter```
6
+
7
+ ### Usage
8
+
9
+ ```ruby
10
+ require 'rubygems'
11
+ require 'tinyletter'
12
+
13
+ newsletter = Tinyletter::Newsletter.new('metafoundry')
14
+ puts newsletter.metadata
15
+ ```
16
+
17
+ That will output:
18
+
19
+ ```ruby
20
+ {
21
+ :title => "Metafoundry",
22
+ :by => "Deb Chachra",
23
+ :description => "Ingredients include: technology, systems, design, language, social justice, and geography. Less than 0.1% cats by volume. Manufactured in a facility that contains personality, emotions and a worldview.",
24
+ :archive_url => "http://tinyletter.com/metafoundry/archive"
25
+ }
26
+ ```
27
+
28
+ #### Requesting the newsletter archive
29
+
30
+ ```ruby
31
+ require 'rubygems'
32
+ require 'tinyletter'
33
+
34
+ newsletter = Tinyletter::Newsletter.new('vruba', { with_archive: true })
35
+ puts newsletter.metadata
36
+ ```
37
+
38
+ If the newsletter has enabled its archives, that will output:
39
+
40
+ ```ruby
41
+ {
42
+ :title => "6",
43
+ :by => "Charlie Loyd",
44
+ :description => "Notes on things I’m thinking about, most weekends. Strictly a personal project, representing my own views alone. Recurring themes include psychogeography, space shuttles, food, and complaining.",
45
+ :archive_url => "http://tinyletter.com/vruba/archive",
46
+ :archive => [
47
+ {
48
+ :date => "2016-07-25",
49
+ :title => "6, 84: Antennapedia",
50
+ :url => "http://tinyletter.com/vruba/letters/6-84-antennapedia",
51
+ :description => "Of course everyone is talking about the Martha Nussbaum profile in *The New Yorker* (via @equartey"
52
+ }, {
53
+ :date => "2016-07-11",
54
+ :title => "6, 83: Build a ray",
55
+ :url => "http://tinyletter.com/vruba/letters/6-83-build-a-ray",
56
+ :description => "Hi! I think it’s time to re-introduce myself. This is an irregular newsletter on mixed topics. It comes from wanting to stay in loose touch with more people than I can personally. What I put here is..."
57
+ }
58
+ }
59
+ ```
data/bin/tinyletter ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
3
+
4
+ require 'tinyletter'
5
+ Tinyletter::CLI.start(ARGV)
@@ -0,0 +1,80 @@
1
+ require 'mechanize'
2
+ require 'logger'
3
+
4
+ WEB_USER_AGENT = 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKit/535.19 (KHTML, ' \
5
+ 'like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19'.freeze
6
+
7
+ module Tinyletter
8
+ class Newsletter
9
+ BASE_ENDPOINT = 'http://tinyletter.com/'.freeze
10
+
11
+ def initialize(username, params = {})
12
+ @username = username
13
+ @with_archive = params[:with_archive] || false
14
+ initialize_http_client
15
+ end
16
+
17
+ def metadata
18
+ return @metadata unless @metadata.nil?
19
+
20
+ begin
21
+ page = get(BASE_ENDPOINT + @username)
22
+ @metadata = extract_metadata(page)
23
+ rescue Mechanize::ResponseCodeError => e
24
+ { error: e }
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def extract_metadata(page)
31
+ archive = page.at('#view-messages-link')
32
+
33
+ metadata = { title: page.at('h1.title').text.strip,
34
+ by: page.at('.byline').text.strip.gsub(/^by /, ''),
35
+ description: page.at('.description').text.strip,
36
+ archive_url: archive ? archive['href'] : nil
37
+ }
38
+
39
+ if archive && @with_archive
40
+ metadata[:archive] = extract_archive_metadata(archive)
41
+ end
42
+
43
+ metadata
44
+ end
45
+
46
+ def extract_archive_metadata(archive)
47
+ get(archive['href']).search('.message-item').map do |item|
48
+ extract_archive_item_metadata(item)
49
+ end
50
+ end
51
+
52
+ def extract_archive_item_metadata(item)
53
+ date = Date.parse(item.at('.message-date').text.strip).to_s
54
+ {
55
+ date: date,
56
+ title: item.at('.message-link').text.strip,
57
+ url: item.at('.message-link')['href'],
58
+ description: item.at('.message-snippet').text.strip
59
+ }
60
+ end
61
+
62
+ def get(url, params: [], referer: nil)
63
+ @http.get(url, params, referer, @headers)
64
+ end
65
+
66
+ def initialize_http_client
67
+ @http = Mechanize.new do |mechanize|
68
+ mechanize.user_agent = WEB_USER_AGENT
69
+ mechanize.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
+ mechanize.log = Logger.new(STDOUT) if Tinyletter.debug
71
+ end
72
+
73
+ @headers = {}
74
+ end
75
+
76
+ def log(msg)
77
+ puts msg if Tinyletter.log
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,3 @@
1
+ module Tinyletter
2
+ VERSION = '0.0.6'.freeze
3
+ end
data/lib/tinyletter.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require_relative 'tinyletter/version'
3
+ require_relative 'tinyletter/newsletter'
4
+
5
+ module Tinyletter
6
+ class << self
7
+ attr_accessor :log
8
+ attr_accessor :debug
9
+ end
10
+
11
+ self.log = false
12
+ self.debug = false
13
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tinyletter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Javier Arce
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.5'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 3.5.1
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '3.5'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 3.5.1
61
+ - !ruby/object:Gem::Dependency
62
+ name: rubocop
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.39.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.39.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: mechanize
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 2.7.4
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 2.7.4
85
+ type: :runtime
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: 2.7.4
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 2.7.4
95
+ description: Retrieves the metadata of a given tinyletter.
96
+ email: javierarce@gmail.com
97
+ executables:
98
+ - tinyletter
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - README.md
103
+ - bin/tinyletter
104
+ - lib/tinyletter.rb
105
+ - lib/tinyletter/newsletter.rb
106
+ - lib/tinyletter/version.rb
107
+ homepage: https://github.com/javierarce/tinyletter
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '2.1'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.6.6
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Retrieves the metadata of a given tinyletter.
131
+ test_files: []