-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrun.rb
executable file
·143 lines (121 loc) · 3.96 KB
/
run.rb
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
# frozen_string_literal: true
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'interact'
gem 'selenium-webdriver'
end
require 'selenium-webdriver'
require 'interact'
# This is are the actions, as the activity log page, does name them. If you want to not unlike stuff,
# then you can just remove the 'Unlike' item from here. If you want to unfriend all people you
# befriended that year, you could also add 'Unfriend' here.
POSSIBLE_ACTIONS = ['Delete', 'Unlike', 'Hide from Timeline'].freeze
BROKEN_STRING = 'The page you requested was not found.'
MORE_STRING = 'Load more from'
class Eraser
include Interactive
def run
@retry = 0
@running = true
@broken_actions = []
@closed_months = []
ask_input
login
set_language unless uk_english?
delete_from_activity_log(@year)
ensure
driver.quit
end
def ask_input
@email = ask 'E-Mail'
@password = ask 'Password', echo: '*', forget: true
@profile_name = ask 'Profile name'
@year = ask 'Delete what year?'
exit unless ask 'We might need to change your Facebook language to English (UK), is that ok?', default: true
end
def login
driver.navigate.to 'https://mbasic.facebook.com'
email_element = driver.find_element(id: 'm_login_email')
email_element.send_keys(@email)
password_element = driver.find_element(xpath: '//input[@type="password"]')
password_element.send_keys(@password)
password_element.submit()
# Ensure not to land on the one tap login page
driver.navigate.to 'https://mbasic.facebook.com'
end
def set_language
driver.navigate.to 'https://mbasic.facebook.com/language.php'
driver.find_element(:link_text, 'English (UK)').click
driver.navigate.to 'https://mbasic.facebook.com'
end
def delete_from_activity_log(year)
goto_profile
driver.find_elements(:css, 'a').find {|link| link.text.downcase == 'activity log'}.tap(&:location_once_scrolled_into_view).click
driver.find_element(:css, "#year_#{year} a").click
while @running
begin
days = driver.find_elements(:xpath, '//div[contains(@id, "tlUnit_")]')
actions = days
.map {|d| d.find_elements(:css, 'a')}
.flatten
.select {|l| POSSIBLE_ACTIONS.include?(l.text) && !@broken_actions.include?(l['href'].gsub(/ext=(.*)/, '')) }
.sort_by { |a| POSSIBLE_ACTIONS.index(a) }
if actions.length > 0
action = actions.first
last_href = action['href'].gsub(/ext=(.*)/, '')
action.click()
if is_broken?
@broken_actions.push(last_href)
driver.navigate.back
else
end
else
begin
click_more_link
rescue Selenium::WebDriver::Error::NoSuchElementError => e
goto_next_month
end
end
rescue StandardError => e
sleep 1
@retry += 1
throw e if @retry > 3
p "Something happened"
p e
p "retrying #{@retry}…"
end
end
rescue StandardError => e
p e
end
def goto_profile
driver.find_element(:css, '[role=navigation] a:nth-child(2)').click
end
def goto_next_month
months = driver.find_elements(:xpath, "//div[contains(@id, 'month_#{@year}_')]/a")
selected_month = months.find {|l| !@closed_months.include?(l.text) }
if selected_month
@closed_months.push(selected_month.text)
selected_month.click
else
p "We are done. GREAT!"
@running = false
end
end
def is_broken?
driver.find_elements(:xpath, "//*[contains(text(), '#{BROKEN_STRING}')]").length > 0
end
def click_more_link
driver.find_element(:xpath, "//*[contains(text(), '#{MORE_STRING}')]").click
end
def uk_english?
driver.find_elements(:xpath, "//*[contains(text(), 'Log Out (')]").length > 0
end
private
def driver
# If you need another browser, please change it here. E.g. :firefox
@driver ||= Selenium::WebDriver.for :chrome
end
end
Eraser.new.run