tumblr_cleanr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +7 -0
  2. data/bin/tumblr_cleanr.rb +180 -0
  3. data/lib/tumblr_cleanr.rb +178 -0
  4. metadata +48 -0
data/README ADDED
@@ -0,0 +1,7 @@
1
+ == TumblrCleanr
2
+
3
+ Delete all posts on your tumblr tumblelog.
4
+
5
+ * To run 'ruby bin/tumblr_cleanr.rb'
6
+
7
+ Documentation is in doc/index.html
@@ -0,0 +1,180 @@
1
+ #See TumblrCleanr class for full documentation
2
+
3
+ require 'rubygems'
4
+ # Note: not using Tumblr API because it does not support delete
5
+ # http://ruby-tumblr.rubyforge.org/
6
+ require 'mechanize' # http://mechanize.rubyforge.org/mechanize
7
+ require 'net/http' # http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP.html
8
+ require 'uri'
9
+ require 'logger'
10
+
11
+ #== TumblrCleanr - clean/reset your tumblr by deleting all posts
12
+ #Author:: engtech (http://InternetDuctTape.com, http://rubeh.tumblr.com)
13
+ #Copyright:: Copyright (c) 2008 engtech
14
+ #License:: Creative Commons Attribution-Noncommercial 2.5 License
15
+ #
16
+ #Tumblr is rapidly becoming my favorite hosted blogging platform (more so than Blogger/WordPress.com) because of all the things they do correct:
17
+ #
18
+ #- RSS feed importing
19
+ #- free domain name support
20
+ #- free CSS/theme support
21
+ #- Google Analytics support
22
+ #- keeping it simple
23
+ #
24
+ #However, there's one feature that's missing: <b>how do you delete your Tumblr?</b> At some point you might want to destroy all traces of your tumblr (privacy concerns, or you want to use it for something else) and there isn't an option to do that -- other than click the delete button on every individual post. I wanted to repurpose a tumblr I had been using for feed aggregation and it had over 18,000 posts. That's a lot of clicks.
25
+ #
26
+ #Enter the TumblrCleanr. Provide it with your tumblr domain name as well as your username and password and it will delete up to the latest 3000 posts at a time. You can keep running it until your entire tumblr is clean as a whistle.
27
+ #
28
+ #== Privacy Concerns
29
+ #
30
+ #TumblrCleanr does not store your login information anywhere and only uses it to communicate with tumblr.com. Every time you run the program you will have to re-enter your login details.
31
+ #
32
+ #== Why Not Create a New Tumblr?
33
+ #
34
+ #That's true, it's much easier to create a new tumblr account with a different email address than it is to "reset" your existing Tumblr. You can even just change the tumblr domain name if you want to "free up" your good domain for something else. I created this more for my own learning process, because I wanted to try WWW::Mechanize, rdoc, rake and rubyscript2exe for the first time and give myself some more experience coding in Ruby.
35
+ #
36
+ #== License
37
+ #
38
+ #This work is licensed under the Creative Commons
39
+ #Attribution-Noncommercial 2.5 License.
40
+ #
41
+ #To view a copy of this license, visit
42
+ # http://creativecommons.org/licenses/by-nc/2.5/ or
43
+ #send a letter to
44
+ # Creative Commons, 543 Howard Street, 5th Floor,
45
+ # San Francisco, California, 94105, USA.
46
+ #
47
+ class TumblrCleanr
48
+ # tumblr domain name is set by login method
49
+ @domain
50
+ # email address is set by login method
51
+ @email
52
+ # password is set by login method
53
+ @password
54
+ # WWW::Mechanize agent is created in login method
55
+ @agent
56
+ # Array of tumblr postids is set by post_archive method
57
+ @postids
58
+
59
+ #Initializing TumblrCleanr will start an interactive prompt asking your your tumblr domain name, email address and password.
60
+ #domain name:: the domain name used to access your tumblr, without the http:// prefix (eg: popstar.tumblr.com)
61
+ #email address:: the email address used to login to tumblr (eg: brittney.spears@gmail.com)
62
+ #password:: the password for your tumblr account, <b>not the password for your email address</b>
63
+ #
64
+ #When the program finishes the user is prompted to press enter to quit.
65
+ #
66
+ def initialize
67
+ begin
68
+ puts "Welcome to TumblrCleanr by http://InternetDuctTape.com"
69
+ query_loop
70
+ parse_archive
71
+ clean
72
+ print "Success"
73
+ rescue Interrupt => e
74
+ puts "User pressed Ctrl-C"
75
+ rescue Exception => e
76
+ puts "#{e.class}: #{e.message}"
77
+ puts e.backtrace.join("\n")
78
+ end
79
+ puts "Press enter to exit..."
80
+ gets
81
+ end
82
+
83
+ private
84
+
85
+ #Keeps asking the user for their login information until they enter something that works.
86
+ #Press Ctrl-C to exit the loop (and the program).
87
+ #
88
+ def query_loop
89
+ login_success = false
90
+ while not login_success do
91
+ begin
92
+ query_user
93
+ login
94
+ login_success = true
95
+ rescue Interrupt => e
96
+ raise Interrupt, "user abort"
97
+ rescue Exception => e
98
+ puts "#{e.class}: #{e.message}"
99
+ puts e.backtrace.join("\n")
100
+ login_success = false
101
+ puts ""
102
+ puts "Unable to login with #{@email}/#{@password} on #{@domain}"
103
+ puts "Type 'Ctrl-C' to abort"
104
+ end
105
+ end
106
+ end
107
+
108
+ #Asks the user for @domain, @email, and @password
109
+ #
110
+ #Side Effect:: sets @domain, @email and @password
111
+ #
112
+ def query_user
113
+ puts ""
114
+ puts "Tumblr domain (ie: popstar.tumblr.com): "
115
+ @domain = gets.chomp
116
+ puts "Tumblr email address (ie: brittney.spears@gmail.com): "
117
+ @email = gets.chomp
118
+ puts "Tumblr password (ie: kfedsux): "
119
+ @password = gets.chomp
120
+ end
121
+
122
+ #Creates a WWW::Mechanize @agent and uses it to verify that @domain is correct and
123
+ #that the @email/@password combination logs in.
124
+ #
125
+ #Side Effect:: creates @agent
126
+ #
127
+ def login
128
+ puts "Trying to connect to tumblr"
129
+ @agent = WWW::Mechanize.new do |a|
130
+ # a.log = Logger.new("mech.log")
131
+ # a.log.level = Logger::DEBUG
132
+ a.redirect_ok = true
133
+ a.user_agent_alias = 'Windows Mozilla'
134
+ end
135
+ # Is the domain any good? This will raise 404 error if bad.
136
+ @agent.get("http://#{@domain}")
137
+ # Can the user login?
138
+ page = @agent.get('http://www.tumblr.com/login')
139
+ login_form = page.forms.first
140
+ login_form.email = @email
141
+ login_form.password = @password
142
+ result = login_form.submit(login_form.buttons.first)
143
+ raise "Bad username or password" unless "Logging in..." == result.title
144
+ end
145
+
146
+ #The Tumblr API does not provide a bandwidth efficient means of getting a list of all postids
147
+ #without getting the entire posts as well.
148
+ #This is a bad hack to use the /archive page to get a list of 3000 post_ids at a time.
149
+ #It uses Net::HTTP because the post_ids which are stored as javascript, so Mechanize can't access them.
150
+ #ie: location.href='http://rubeh.tumblr.com/post/22655521
151
+ #
152
+ #Side Effect:: sets up @postids as an array of postids (as strings)
153
+ #
154
+ def parse_archive
155
+ url = URI.parse("http://#{@domain}/archive")
156
+ req = Net::HTTP::Get.new(url.path)
157
+ res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) }
158
+ # with the body of the archive page, split it into chunks that have one postid each.
159
+ # use a regular expression to extract the postid
160
+ @postids = res.body.split("onclick").map{|chunk| (chunk =~ /location.href='http:\/\/[^\/]+\/post\/(\d+)/) ? $1 : nil }.reject{|i| nil == i}
161
+ end
162
+
163
+ # Using the list of @postids from parse_archive, iterate through them and send HTTP POSTs to the /delete/id action.
164
+ # It does not check that the delete occurs. As a matter of fact, it intentionally asks to redirect to a 404 to reduce
165
+ # bandwidth.
166
+ #
167
+ def clean
168
+ total_ids = @postids.size
169
+ @postids.each_with_index do |postid, i|
170
+ puts "\nDeleted #{i}/#{total_ids}" if i % 25 == 0
171
+ print "."
172
+ result = @agent.post("http://www.tumblr.com/delete", 'id' => postid, 'redirect_to' => '/404') rescue nil
173
+ # usually tumblr redirects to the dashboard after a delete happens
174
+ # I'm intentially creating a 404 because it's much less bandwidth intensive
175
+ end
176
+ puts
177
+ end
178
+ end
179
+
180
+ TumblrCleanr.new # appended by Rakefile
@@ -0,0 +1,178 @@
1
+ #See TumblrCleanr class for full documentation
2
+
3
+ require 'rubygems'
4
+ # Note: not using Tumblr API because it does not support delete
5
+ # http://ruby-tumblr.rubyforge.org/
6
+ require 'mechanize' # http://mechanize.rubyforge.org/mechanize
7
+ require 'net/http' # http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP.html
8
+ require 'uri'
9
+ require 'logger'
10
+
11
+ #== TumblrCleanr - clean/reset your tumblr by deleting all posts
12
+ #Author:: engtech (http://InternetDuctTape.com, http://rubeh.tumblr.com)
13
+ #Copyright:: Copyright (c) 2008 engtech
14
+ #License:: Creative Commons Attribution-Noncommercial 2.5 License
15
+ #
16
+ #Tumblr is rapidly becoming my favorite hosted blogging platform (more so than Blogger/WordPress.com) because of all the things they do correct:
17
+ #
18
+ #- RSS feed importing
19
+ #- free domain name support
20
+ #- free CSS/theme support
21
+ #- Google Analytics support
22
+ #- keeping it simple
23
+ #
24
+ #However, there's one feature that's missing: <b>how do you delete your Tumblr?</b> At some point you might want to destroy all traces of your tumblr (privacy concerns, or you want to use it for something else) and there isn't an option to do that -- other than click the delete button on every individual post. I wanted to repurpose a tumblr I had been using for feed aggregation and it had over 18,000 posts. That's a lot of clicks.
25
+ #
26
+ #Enter the TumblrCleanr. Provide it with your tumblr domain name as well as your username and password and it will delete up to the latest 3000 posts at a time. You can keep running it until your entire tumblr is clean as a whistle.
27
+ #
28
+ #== Privacy Concerns
29
+ #
30
+ #TumblrCleanr does not store your login information anywhere and only uses it to communicate with tumblr.com. Every time you run the program you will have to re-enter your login details.
31
+ #
32
+ #== Why Not Create a New Tumblr?
33
+ #
34
+ #That's true, it's much easier to create a new tumblr account with a different email address than it is to "reset" your existing Tumblr. You can even just change the tumblr domain name if you want to "free up" your good domain for something else. I created this more for my own learning process, because I wanted to try WWW::Mechanize, rdoc, rake and rubyscript2exe for the first time and give myself some more experience coding in Ruby.
35
+ #
36
+ #== License
37
+ #
38
+ #This work is licensed under the Creative Commons
39
+ #Attribution-Noncommercial 2.5 License.
40
+ #
41
+ #To view a copy of this license, visit
42
+ # http://creativecommons.org/licenses/by-nc/2.5/ or
43
+ #send a letter to
44
+ # Creative Commons, 543 Howard Street, 5th Floor,
45
+ # San Francisco, California, 94105, USA.
46
+ #
47
+ class TumblrCleanr
48
+ # tumblr domain name is set by login method
49
+ @domain
50
+ # email address is set by login method
51
+ @email
52
+ # password is set by login method
53
+ @password
54
+ # WWW::Mechanize agent is created in login method
55
+ @agent
56
+ # Array of tumblr postids is set by post_archive method
57
+ @postids
58
+
59
+ #Initializing TumblrCleanr will start an interactive prompt asking your your tumblr domain name, email address and password.
60
+ #domain name:: the domain name used to access your tumblr, without the http:// prefix (eg: popstar.tumblr.com)
61
+ #email address:: the email address used to login to tumblr (eg: brittney.spears@gmail.com)
62
+ #password:: the password for your tumblr account, <b>not the password for your email address</b>
63
+ #
64
+ #When the program finishes the user is prompted to press enter to quit.
65
+ #
66
+ def initialize
67
+ begin
68
+ puts "Welcome to TumblrCleanr by http://InternetDuctTape.com"
69
+ query_loop
70
+ parse_archive
71
+ clean
72
+ print "Success"
73
+ rescue Interrupt => e
74
+ puts "User pressed Ctrl-C"
75
+ rescue Exception => e
76
+ puts "#{e.class}: #{e.message}"
77
+ puts e.backtrace.join("\n")
78
+ end
79
+ puts "Press enter to exit..."
80
+ gets
81
+ end
82
+
83
+ private
84
+
85
+ #Keeps asking the user for their login information until they enter something that works.
86
+ #Press Ctrl-C to exit the loop (and the program).
87
+ #
88
+ def query_loop
89
+ login_success = false
90
+ while not login_success do
91
+ begin
92
+ query_user
93
+ login
94
+ login_success = true
95
+ rescue Interrupt => e
96
+ raise Interrupt, "user abort"
97
+ rescue Exception => e
98
+ puts "#{e.class}: #{e.message}"
99
+ puts e.backtrace.join("\n")
100
+ login_success = false
101
+ puts ""
102
+ puts "Unable to login with #{@email}/#{@password} on #{@domain}"
103
+ puts "Type 'Ctrl-C' to abort"
104
+ end
105
+ end
106
+ end
107
+
108
+ #Asks the user for @domain, @email, and @password
109
+ #
110
+ #Side Effect:: sets @domain, @email and @password
111
+ #
112
+ def query_user
113
+ puts ""
114
+ puts "Tumblr domain (ie: popstar.tumblr.com): "
115
+ @domain = gets.chomp
116
+ puts "Tumblr email address (ie: brittney.spears@gmail.com): "
117
+ @email = gets.chomp
118
+ puts "Tumblr password (ie: kfedsux): "
119
+ @password = gets.chomp
120
+ end
121
+
122
+ #Creates a WWW::Mechanize @agent and uses it to verify that @domain is correct and
123
+ #that the @email/@password combination logs in.
124
+ #
125
+ #Side Effect:: creates @agent
126
+ #
127
+ def login
128
+ puts "Trying to connect to tumblr"
129
+ @agent = WWW::Mechanize.new do |a|
130
+ # a.log = Logger.new("mech.log")
131
+ # a.log.level = Logger::DEBUG
132
+ a.redirect_ok = true
133
+ a.user_agent_alias = 'Windows Mozilla'
134
+ end
135
+ # Is the domain any good? This will raise 404 error if bad.
136
+ @agent.get("http://#{@domain}")
137
+ # Can the user login?
138
+ page = @agent.get('http://www.tumblr.com/login')
139
+ login_form = page.forms.first
140
+ login_form.email = @email
141
+ login_form.password = @password
142
+ result = login_form.submit(login_form.buttons.first)
143
+ raise "Bad username or password" unless "Logging in..." == result.title
144
+ end
145
+
146
+ #The Tumblr API does not provide a bandwidth efficient means of getting a list of all postids
147
+ #without getting the entire posts as well.
148
+ #This is a bad hack to use the /archive page to get a list of 3000 post_ids at a time.
149
+ #It uses Net::HTTP because the post_ids which are stored as javascript, so Mechanize can't access them.
150
+ #ie: location.href='http://rubeh.tumblr.com/post/22655521
151
+ #
152
+ #Side Effect:: sets up @postids as an array of postids (as strings)
153
+ #
154
+ def parse_archive
155
+ url = URI.parse("http://#{@domain}/archive")
156
+ req = Net::HTTP::Get.new(url.path)
157
+ res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) }
158
+ # with the body of the archive page, split it into chunks that have one postid each.
159
+ # use a regular expression to extract the postid
160
+ @postids = res.body.split("onclick").map{|chunk| (chunk =~ /location.href='http:\/\/[^\/]+\/post\/(\d+)/) ? $1 : nil }.reject{|i| nil == i}
161
+ end
162
+
163
+ # Using the list of @postids from parse_archive, iterate through them and send HTTP POSTs to the /delete/id action.
164
+ # It does not check that the delete occurs. As a matter of fact, it intentionally asks to redirect to a 404 to reduce
165
+ # bandwidth.
166
+ #
167
+ def clean
168
+ total_ids = @postids.size
169
+ @postids.each_with_index do |postid, i|
170
+ puts "\nDeleted #{i}/#{total_ids}" if i % 25 == 0
171
+ print "."
172
+ result = @agent.post("http://www.tumblr.com/delete", 'id' => postid, 'redirect_to' => '/404') rescue nil
173
+ # usually tumblr redirects to the dashboard after a delete happens
174
+ # I'm intentially creating a 404 because it's much less bandwidth intensive
175
+ end
176
+ puts
177
+ end
178
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: tumblr_cleanr
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2008-02-25 00:00:00 -05:00
8
+ summary: Script for deleting your tumblr account
9
+ require_paths:
10
+ - lib
11
+ email: engtechnology+tumblrcleanr@gmail.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: tumblr_cleanr
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - engtech
31
+ files:
32
+ - bin/tumblr_cleanr.rb
33
+ - lib/tumblr_cleanr.rb
34
+ - README
35
+ test_files: []
36
+
37
+ rdoc_options: []
38
+
39
+ extra_rdoc_files:
40
+ - README
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ requirements: []
46
+
47
+ dependencies: []
48
+