reddit_auto 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/reddit_auto.rb +836 -0
  3. metadata +59 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 93f5030b7d722f2eb99929cf9f48838e964e78840f89dd4e32bcc9da89cc12ff
4
+ data.tar.gz: cf1b9fc23e4f52539f2086545cb6229cc216d7ea6772aa669eb033859055c730
5
+ SHA512:
6
+ metadata.gz: f4631d0b5e13b58dd863e790bfb105ad2170df36c5c366ecc983be171c98187d4117d0cb7cb79872997447be8e99d5f17801e4db9f9f08259eb30a43480bf4f2
7
+ data.tar.gz: 4b7f7ed4b8f6dcc711da055174531a2bc626c65949d9196c9e0b07f1cc6e896c164861cf901611ade348c1c204ced577fbd5265cf7de200e5e067c1a9efde674
@@ -0,0 +1,836 @@
1
+ require 'watir'
2
+
3
+ #Written by Ícaro Augusto
4
+ #Website: https://icaroaugusto.com
5
+ #Github: https://github.com/IcaroAugusto
6
+
7
+ class Reddit
8
+ PAGE_MAIN = 'https://old.reddit.com/'
9
+ PAGE_MAIN_NO_SLASH = 'https://old.reddit.com'
10
+ PAGE_MESSAGES = 'https://old.reddit.com/message/'
11
+ PAGE_SUBREDDIT = 'https://old.reddit.com/r/'
12
+ PAGE_USER = 'https://old.reddit.com/user/'
13
+ PAGE_CREATE_SUB = 'https://old.reddit.com/subreddits/create'
14
+
15
+ MESSAGE_SUBPAGES = ['inbox', 'unread', 'messages', 'comments', 'sent']
16
+ SUBREDDIT_SUBPAGES = ['hot', 'new', 'rising', 'top', 'gilded']
17
+ USER_SORTBYS = ['new', 'hot', 'top', 'controversial']
18
+
19
+ attr_accessor :browser
20
+ attr_accessor :username
21
+
22
+ def has_browser
23
+ return @browser != nil
24
+ end
25
+
26
+ def is_logged_in(username)
27
+ return @browser.link(text: username).present?
28
+ end
29
+
30
+ def wait_login(username)
31
+ count = 0.0
32
+ while !is_logged_in(username)
33
+ sleep 0.25
34
+ count += 0.25
35
+ if count > 10
36
+ raise 'Reddit login failed for username: ' + username
37
+ end
38
+ end
39
+ end
40
+
41
+ def login(username, password)
42
+ @username = username
43
+ @browser.goto PAGE_MAIN
44
+ @browser.text_field(name: 'user').set username
45
+ @browser.text_field(name: 'passwd').set password
46
+ @browser.checkbox(id: 'rem-login-main').set
47
+ @browser.button(text: 'login').click
48
+ wait_login(username)
49
+ end
50
+
51
+ def wait_logout
52
+ count = 0.0
53
+ while is_logged_in(@username)
54
+ sleep 0.25
55
+ count += 0.25
56
+ if count > 10
57
+ raise 'Reddit logout failed for username: ' + @username
58
+ end
59
+ end
60
+ end
61
+
62
+ def logout
63
+ @browser.link(text: 'logout').click
64
+ wait_logout
65
+ end
66
+
67
+ def has_over_18
68
+ return @browser.button(name: 'over18').present?
69
+ end
70
+
71
+ def skip_over_18
72
+ @browser.button(text: 'continue').click
73
+ end
74
+
75
+ def has_over_18_new
76
+ @browser.h3(text: 'You must be 18+ to view this community').present?
77
+ end
78
+
79
+ def skip_over_18_new
80
+ @browser.link(text: 'Yes').click
81
+ end
82
+
83
+ #---------------------------------------------------------------------------------
84
+ #Messages handling
85
+ #---------------------------------------------------------------------------------
86
+
87
+ def get_message_type(div)
88
+ return div.attribute_value('data-type')
89
+ end
90
+
91
+ def get_message_post(div)
92
+ return div.p(class: 'subject').link(class: 'title').href
93
+ end
94
+
95
+ def get_message_author(div)
96
+ return div.attribute_value('data-author')
97
+ end
98
+
99
+ def get_message_subreddit(div)
100
+ return div.attribute_value('data-subreddit')
101
+ end
102
+
103
+ def get_message_content(div)
104
+ return div.div(class: 'md').text
105
+ end
106
+
107
+ def get_message_divs
108
+ all_divs = @browser.div(id: 'siteTable').divs
109
+ result = []
110
+ all_divs.each do |div|
111
+ result.push div if div.id.include? 'thing_'
112
+ end
113
+ return result
114
+ end
115
+
116
+ def is_message_voted(div, type) #type is 'up' or 'down'
117
+ return div.div(class: 'midcol').div(class: type + 'mod').present?
118
+ end
119
+
120
+ def get_message_vote(div)
121
+ return 'up' if is_message_voted(div, 'up')
122
+ return 'down' if is_message_voted(div, 'down')
123
+ return nil
124
+ end
125
+
126
+ def vote_message(div, type) #type is 'up' or 'down'
127
+ return if is_message_voted(div, type)
128
+ div.div(class: 'midcol').div(class: type).click
129
+ end
130
+
131
+ def reply_message(div, answer)
132
+ div.li(text: 'reply').click
133
+ div.textarea.set answer
134
+ div.button(text: 'save').click
135
+ end
136
+
137
+ def get_message(div) #returns a hash with message data
138
+ result = {}
139
+ result['type'] = get_message_type(div)
140
+ result['author'] = get_message_author(div)
141
+ result['post'] = get_message_post(div) if result['type'] == 'comment'
142
+ result['subreddit'] = result['type'] == 'comment' ? get_message_subreddit(div) : result['author']
143
+ result['vote'] = get_message_vote(div) if result['type'] == 'comment'
144
+ result['content'] = get_message_content(div)
145
+ return result
146
+ end
147
+
148
+ def message_move_page(direction) #directions: next for next page, prev for previous page
149
+ button = @browser.span(class: direction + '-button')
150
+ result = button.present?
151
+ button.click if result
152
+ return result
153
+ end
154
+
155
+ def open_messages_subpage(subpage)
156
+ raise 'Unknown message subpage: ' + subpage if !MESSAGE_SUBPAGES.include? subpage
157
+ @browser.goto PAGE_MESSAGES + subpage
158
+ end
159
+
160
+ def get_messages(subpage, all_pages = false)
161
+ open_messages_subpage(subpage)
162
+ result = []
163
+ while true
164
+ get_message_divs.each do |div|
165
+ result.push get_message(div)
166
+ end
167
+ return result if !all_pages || !message_move_page('next')
168
+ end
169
+ end
170
+
171
+ #---------------------------------------------------------------------------------
172
+ #Submit handling
173
+ #---------------------------------------------------------------------------------
174
+
175
+ def has_submit_error
176
+ return @browser.span(text: 'you are doing that too much. try again in 9 minutes.').present?
177
+ end
178
+
179
+ def is_submit_open
180
+ return @browser.textarea(name: 'title').present? || @browser.textarea(placeholder: 'Title').present?
181
+ end
182
+
183
+ def wait_submit
184
+ count = 0.0
185
+ while is_submit_open
186
+ sleep 0.25
187
+ count += 0.25
188
+ raise 'Post submission failed!' if count >= 10
189
+ end
190
+ end
191
+
192
+ def submit_link(subreddit, url, title)
193
+ @browser.goto PAGE_SUBREDDIT + subreddit + '/submit'
194
+ skip_over_18 if has_over_18
195
+ @browser.text_field(id: 'url').set url
196
+ @browser.textarea(name: 'title').set title
197
+ @browser.button(name: 'submit').click
198
+ wait_submit
199
+ end
200
+
201
+ def sub_has_flair
202
+ return !@browser.div('aria-label': 'Not available for this community').present?
203
+ end
204
+
205
+ def set_flair(flair)
206
+ return if !sub_has_flair
207
+ @browser.div('aria-label': 'Add flair').click
208
+ if flair == nil
209
+ @browser.div('aria-label': 'flair_picker').div.click
210
+ else
211
+ @browser.div('aria-label': 'flair_picker').span(text: flair).click
212
+ end
213
+ @browser.button(text: 'Apply').click
214
+ end
215
+
216
+ def submit_link_new(subreddit, url, title, flair = nil) #uses new reddit
217
+ @browser.goto 'https://www.reddit.com/r/' + subreddit + '/submit'
218
+ skip_over_18_new if has_over_18_new
219
+ blink = @browser.button(text: 'Link')
220
+ blink.click if blink.present?
221
+ @browser.textarea(placeholder: 'Title').set title
222
+ @browser.textarea(placeholder: 'Url').set url
223
+ set_flair(flair)
224
+ @browser.buttons(text: 'Post')[1].click
225
+ wait_submit
226
+ end
227
+
228
+ def submit_text(subreddit, title, text)
229
+ @browser.goto PAGE_SUBREDDIT + subreddit + '/submit?selftext=true'
230
+ skip_over_18 if has_over_18
231
+ @browser.textarea(name: 'title').set title
232
+ @browser.textarea(name: 'text').set text
233
+ @browser.button(name: 'submit').click
234
+ wait_submit
235
+ end
236
+
237
+ #---------------------------------------------------------------------------------
238
+ #Post handling
239
+ #---------------------------------------------------------------------------------
240
+
241
+ def is_original_post_voted(type)
242
+ div = @browser.div(id: 'siteTable').div(class: 'midcol')
243
+ case type
244
+ when 'up'
245
+ return div.attribute_value('class') == 'midcol likes'
246
+ when 'down'
247
+ return div.attribute_value('class') == 'midcol dislikes'
248
+ else
249
+ raise 'Unknown vote type: ' + type
250
+ end
251
+ end
252
+
253
+ def get_original_post_vote
254
+ return 'up' if is_original_post_voted('up')
255
+ return 'down' if is_original_post_voted('down')
256
+ return nil
257
+ end
258
+
259
+ def vote_original_post(type)
260
+ return if is_original_post_voted(type)
261
+ div = @browser.div(id: 'siteTable').div(class: 'midcol')
262
+ div.div(class: type).click
263
+ end
264
+
265
+ def form_post_url(link)
266
+ return PAGE_MAIN_NO_SLASH + link
267
+ end
268
+
269
+ def open_post(post)
270
+ case post
271
+ when Hash
272
+ @browser.goto form_post_url(post['link'])
273
+ when String
274
+ @browser.goto post
275
+ else
276
+ return
277
+ end
278
+ skip_over_18 if has_over_18
279
+ end
280
+
281
+ def has_reply(answer)
282
+ form = @browser.form(text: answer)
283
+ return form.present? && form.parent.parent.attribute_value('data-author') == @username
284
+ end
285
+
286
+ def has_reply_error
287
+ return @browser.span(class: 'error', style: '').present?
288
+ end
289
+
290
+ def get_reply_error
291
+ return @browser.span(class: 'error', style: '').split(" ")[1]
292
+ end
293
+
294
+ def wait_reply(time = 2)
295
+ sleep time
296
+ return !has_reply_error
297
+ end
298
+
299
+ def reply_post(post, answer)
300
+ open_post(post)
301
+ @browser.div(class: 'commentarea').textarea(name: 'text').set answer
302
+ @browser.div(class: 'commentarea').button(text: 'save').click
303
+ return wait_reply
304
+ end
305
+
306
+ def get_comment_replies_count(div)
307
+ return div.attribute_value('data-replies').to_i
308
+ end
309
+
310
+ def comment_has_replies(div)
311
+ return div.attribute_value('data-replies') != '0'
312
+ end
313
+
314
+ def get_comment_author(div)
315
+ return div.attribute_value('data-author')
316
+ end
317
+
318
+ def get_comment_link(div)
319
+ return div.attribute_value('data-permalink')
320
+ end
321
+
322
+ def get_comment_content(div)
323
+ return div.div(class: 'usertext-body').text
324
+ end
325
+
326
+ def get_comment_karma(div, vote)
327
+ case vote
328
+ when 'up'
329
+ ind = 2
330
+ when 'down'
331
+ ind = 0
332
+ else
333
+ ind = 1
334
+ end
335
+ return div.p(class: 'tagline').spans(class: 'score')[ind].text.split(' ')[0].to_i
336
+ end
337
+
338
+ def is_comment_voted(div, type) #type is 'up' or 'down'
339
+ case type
340
+ when 'up'
341
+ buffer = 'likes'
342
+ when 'down'
343
+ buffer = 'dislikes'
344
+ else
345
+ raise 'Unknown vote type!'
346
+ end
347
+ return div.div(class: 'entry').attribute_value('class') == 'entry ' + buffer
348
+ end
349
+
350
+ def get_comment_vote(div)
351
+ return 'up' if is_comment_voted(div, 'up')
352
+ return 'down' if is_comment_voted(div, 'down')
353
+ return nil
354
+ end
355
+
356
+ def comment_has_karma(div)
357
+ return div.span(class: 'score').present?
358
+ end
359
+
360
+ def get_comment(div)
361
+ result = {}
362
+ result['author'] = get_comment_author(div)
363
+ result['link'] = get_comment_link(div)
364
+ result['content'] = get_comment_content(div)
365
+ result['vote'] = get_comment_vote(div)
366
+ result['karma'] = get_comment_karma(div, result['vote']) if comment_has_karma(div)
367
+ return result
368
+ end
369
+
370
+ def get_comments_divs
371
+ divs = @browser.div(class: 'commentarea').div(class: 'sitetable nestedlisting').children
372
+ result = []
373
+ divs.each do |div|
374
+ result.push div if div.attribute_value('data-type') == 'comment'
375
+ end
376
+ return result
377
+ end
378
+
379
+ def get_replies_divs(main_div)
380
+ divs = main_div.div(class: 'child').div.children
381
+ begin #calling length if the length is 0 causes an exception
382
+ x = divs.length
383
+ rescue
384
+ return []
385
+ end
386
+ result = []
387
+ divs.each do |div|
388
+ result.push div if div.attribute_value('data-type') == 'comment'
389
+ end
390
+ return result
391
+ end
392
+
393
+ def parse_comments_divs(divs)
394
+ result = []
395
+ divs.each do |div|
396
+ result.push get_comment(div)
397
+ if comment_has_replies(div)
398
+ result[result.length-1]['replies'] = parse_comments_divs(get_replies_divs(div))
399
+ end
400
+ end
401
+ return result
402
+ end
403
+
404
+ def expand_all_comments
405
+ while true
406
+ begin
407
+ span = @browser.span(class: 'morecomments')
408
+ span.present? ? span.click : return
409
+ rescue
410
+ end
411
+ sleep 0.5
412
+ end
413
+ end
414
+
415
+ def get_comments(post, expand = false)
416
+ open_post(post)
417
+ expand_all_comments if expand
418
+ return parse_comments_divs(get_comments_divs)
419
+ end
420
+
421
+ def reply_comments(div, answer)
422
+ div.li(text: 'reply').click
423
+ div.textarea(name: 'text').set answer
424
+ div.button(class: 'save').click
425
+ end
426
+
427
+ def vote_comment(div, type)
428
+ return if is_comment_voted(div, type)
429
+ div.div(class: 'midcol').div(class: type).click
430
+ end
431
+
432
+ #---------------------------------------------------------------------------------
433
+ #Subreddit handling
434
+ #---------------------------------------------------------------------------------
435
+
436
+ def get_posts_divs
437
+ divs = @browser.div(id: 'siteTable').children
438
+ result = []
439
+ divs.each do |div|
440
+ result.push div if div.attribute_value('data-type') == 'link'
441
+ end
442
+ return result
443
+ end
444
+
445
+ def get_post_author(div)
446
+ return div.attribute_value('data-author')
447
+ end
448
+
449
+ def get_post_link(div)
450
+ return div.attribute_value('data-permalink')
451
+ end
452
+
453
+ def get_post_karma(div)
454
+ return div.attribute_value('data-score').to_i
455
+ end
456
+
457
+ def get_post_title(div)
458
+ return div.link(class: 'title').text
459
+ end
460
+
461
+ def get_post_number_of_comments(div)
462
+ return div.attribute_value('data-comments-count').to_i
463
+ end
464
+
465
+ def isPostVoted(div, type)
466
+ return is_comment_voted(div, type)
467
+ end
468
+
469
+ def get_post_vote(div)
470
+ return get_comment_vote(div)
471
+ end
472
+
473
+ def vote_post(div, type)
474
+ vote_comment(div, type)
475
+ end
476
+
477
+ def get_post(div)
478
+ result = {}
479
+ result['author'] = get_post_author(div)
480
+ result['link'] = get_post_link(div)
481
+ result['karma'] = get_post_karma(div)
482
+ result['title'] = get_post_title(div)
483
+ result['vote'] = get_post_vote(div)
484
+ result['number_of_comments'] = get_post_number_of_comments(div)
485
+ return result
486
+ end
487
+
488
+ def subreddit_move_page(direction)
489
+ return message_move_page(direction)
490
+ end
491
+
492
+ def form_subreddit_url(name, subpage = 'hot')
493
+ return PAGE_SUBREDDIT + name + '/' + subpage
494
+ end
495
+
496
+ def open_subreddit(subreddit, subpage = 'hot')
497
+ raise 'Unknown subreddit subpage: ' + subpage if !SUBREDDIT_SUBPAGES.include? subpage
498
+ case subreddit
499
+ when Hash
500
+ @browser.goto form_subreddit_url(subreddit['name'], subpage)
501
+ when String
502
+ if subreddit.include? '/'
503
+ @browser.goto subreddit
504
+ else
505
+ @browser.goto form_subreddit_url(subreddit, subpage)
506
+ end
507
+ else
508
+ return
509
+ end
510
+ skip_over_18 if has_over_18
511
+ end
512
+
513
+ def get_posts(subreddit, subpage = 'hot', max_pages = 1)
514
+ raise 'Unknown subreddit subpage: ' + subpage if !SUBREDDIT_SUBPAGES.include? subpage
515
+ open_subreddit(subreddit, subpage)
516
+ result = []
517
+ count = 0
518
+ while true
519
+ get_posts_divs.each do |div|
520
+ result.push get_post(div)
521
+ end
522
+ count += 1
523
+ break if count >= max_pages
524
+ break if !subreddit_move_page('next')
525
+ end
526
+ return result
527
+ end
528
+
529
+ def form_subreddit_mod_url(subreddit)
530
+ case subreddit
531
+ when Hash
532
+ return PAGE_SUBREDDIT + subreddit['name'] + '/about/moderators'
533
+ when String
534
+ return PAGE_SUBREDDIT + subreddit + '/about/moderators'
535
+ end
536
+ end
537
+
538
+ def get_moderators(subreddit) #an array of user names, not user structs itself
539
+ @browser.goto form_subreddit_mod_url(subreddit)
540
+ spans = @browser.div(class: 'moderator-table').spans(class: 'user')
541
+ result = []
542
+ spans.each do |span|
543
+ result.push span.link.text
544
+ end
545
+ return result
546
+ end
547
+
548
+ def get_subscribers
549
+ return @browser.span(class: 'subscribers').span(class: 'number').text.gsub(',', '').to_i
550
+ end
551
+
552
+ def get_users_online
553
+ return @browser.p(class: 'users-online').span(class: 'number').text.gsub(',', '').to_i
554
+ end
555
+
556
+ def get_side_bar
557
+ return @browser.div(class: 'usertext-body').text
558
+ end
559
+
560
+ def get_subreddit(subreddit)
561
+ result = {}
562
+ result['name'] = subreddit
563
+ open_subreddit(subreddit)
564
+ result['subscribers'] = get_subscribers
565
+ result['users_online'] = get_users_online
566
+ result['sidebar'] = get_side_bar
567
+ result['moderators'] = get_moderators(subreddit)
568
+ return result
569
+ end
570
+
571
+ def did_create_sub
572
+ return @browser.p(text: 'your subreddit has been created').present?
573
+ end
574
+
575
+ def wait_sub_creation
576
+ count = 0.0
577
+ while true
578
+ return true if did_create_sub
579
+ sleep 0.25
580
+ count += 0.25
581
+ return false if count >= 10
582
+ end
583
+ end
584
+
585
+ def create_subreddit(subreddit)
586
+ @browser.goto CREATE_SUB_PAGE
587
+ @browser.text_field(id: 'name').set subreddit.name
588
+ @browser.text_field(id: 'title').set subreddit.title
589
+ @browser.textarea(name: 'public_description').set subreddit.description
590
+ @browser.textarea(name: 'description').set subreddit.sidebar
591
+ @browser.textarea(name: 'submit_text').set subreddit.subtext
592
+ @browser.radio(id: SUB_TYPES[subreddit.type]).set
593
+ @browser.radio(id: CONTENT_OPTIONS[subreddit.content]).set
594
+ @browser.button(text: 'create').click
595
+ return wait_sub_creation
596
+ end
597
+
598
+ #---------------------------------------------------------------------------------
599
+ #User handling
600
+ #---------------------------------------------------------------------------------
601
+
602
+ def get_user_post_karma
603
+ return @browser.span(class: 'karma').text.gsub(',', '').to_i
604
+ end
605
+
606
+ def get_user_comment_karma
607
+ return @browser.spans(class: 'karma')[1].text.gsub(',', '').to_i
608
+ end
609
+
610
+ def is_moderator
611
+ return @browser.ul(id: 'side-mod-list').present?
612
+ end
613
+
614
+ def get_moderating
615
+ result = []
616
+ @browser.ul(id: 'side-mod-list').lis.each do |li|
617
+ result.push li.link.title.split('/')[1]
618
+ end
619
+ return result
620
+ end
621
+
622
+ def is_friend
623
+ return @browser.span(class: 'fancy-toggle-button').link(text: '- friends').attribute_value('class').include?('active')
624
+ end
625
+
626
+ def add_friend
627
+ return if is_friend
628
+ @browser.link(text: '+ friends').click
629
+ end
630
+
631
+ def remove_friend
632
+ return if !is_friend
633
+ @browser.link(text: '- friends').click
634
+ end
635
+
636
+ def open_user_page(user)
637
+ @browser.goto PAGE_USER + user
638
+ skip_over_18 if has_over_18
639
+ end
640
+
641
+ def get_user(user)
642
+ open_user_page(user)
643
+ return nil if @browser.div(id: 'classy-error').present?
644
+ result = {}
645
+ result['name'] = user
646
+ result['post_karma'] = get_user_post_karma
647
+ result['comment_karma'] = get_user_comment_karma
648
+ result['is_friend'] = @username ? is_friend : false
649
+ result['moderating'] = get_moderating if is_moderator
650
+ return result
651
+ end
652
+
653
+ #---------------------------------------------------------------------------------
654
+ #User Activity handling
655
+ #---------------------------------------------------------------------------------
656
+
657
+ def get_activity_divs
658
+ divs = @browser.div(id: 'siteTable').children
659
+ result = []
660
+ divs.each do |div|
661
+ result.push div if div.id.include? 'thing'
662
+ end
663
+ return result
664
+ end
665
+
666
+ def get_activity_type(div)
667
+ return div.attribute_value('data-type')
668
+ end
669
+
670
+ def get_activity_link(div)
671
+ return div.attribute_value('data-permalink')
672
+ end
673
+
674
+ def get_activity_subreddit(div)
675
+ return div.attribute_value('data-subreddit')
676
+ end
677
+
678
+ def get_activity_title(div)
679
+ return div.link(class: 'title').text
680
+ end
681
+
682
+ def get_activity_content(div) #only for comments
683
+ return div.div(class: 'usertext-body').text
684
+ end
685
+
686
+ def get_activity_karma(div, vote)
687
+ case get_activity_type(div)
688
+ when 'comment'
689
+ return get_comment_karma(div, vote)
690
+ when 'link'
691
+ case vote
692
+ when 'up'
693
+ return div.div(class: 'score likes').title.to_i
694
+ when 'down'
695
+ return div.div(class: 'score dislikes').title.to_i
696
+ else
697
+ return div.div(class: 'score unvoted').title.to_i
698
+ end
699
+ else
700
+ raise 'Unknown activity type!'
701
+ end
702
+ end
703
+
704
+ def is_activity_voted(div, type)
705
+ return is_comment_voted(div, type)
706
+ end
707
+
708
+ def get_activity_vote(div)
709
+ return get_comment_vote(div)
710
+ end
711
+
712
+ def vote_activity(div, type)
713
+ vote_message(div, type)
714
+ end
715
+
716
+ def get_activity(div)
717
+ result = {}
718
+ result['type'] = get_activity_type(div)
719
+ result['link'] = get_activity_link(div)
720
+ result['subreddit'] = get_activity_subreddit(div)
721
+ result['title'] = get_activity_title(div)
722
+ result['content'] = result['type'] == 'link' ? result['title'] : get_activity_content(div)
723
+ result['vote'] = get_activity_vote(div)
724
+ result['karma'] = get_activity_karma(div, result['vote'])
725
+ return result
726
+ end
727
+
728
+ def user_move_page(direction)
729
+ return message_move_page(direction)
730
+ end
731
+
732
+ def get_user_activities(user, sortby = 'new', max_pages = 1)
733
+ raise 'Unknown user sortby: ' + sortby if !USER_SORTBYS.include? sortby
734
+ @browser.goto PAGE_USER + user + '/?sort=' + sortby
735
+ result = []
736
+ count = 0
737
+ while true
738
+ get_activity_divs.each do |div|
739
+ result.push get_activity(div)
740
+ end
741
+ count += 1
742
+ break if count >= max_pages
743
+ break if !user_move_page('next')
744
+ end
745
+ return result
746
+ end
747
+
748
+ #---------------------------------------------------------------------------------
749
+ #Extra functions
750
+ #---------------------------------------------------------------------------------
751
+
752
+ def get_banned_subreddits
753
+ msgs = get_messages('messages', true)
754
+ result = []
755
+ msgs.each do |msg|
756
+ result.push msg['author'] if msg['content'].include?('You have been permanently banned')
757
+ end
758
+ return result
759
+ end
760
+
761
+ def phase_pick_subs
762
+ @browser.execute_script("var buttons = document.getElementsByClassName('c-btn c-btn-primary subreddit-picker__subreddit-button');\nfor (var i = 0; i < 8; i++) {\nbuttons[i].click();\n}")
763
+ end
764
+
765
+ def phase_enter_data(username, password, captcha_token)
766
+ result = {}
767
+ if username == nil
768
+ link = @browser.link(class: 'username-generator__item')
769
+ result['username'] = link.text
770
+ link.click
771
+ else
772
+ result['username'] = username
773
+ @browser.text_field(id: 'user_reg').set username
774
+ end
775
+ @browser.text_field(id: 'passwd_reg').set password
776
+ result['password'] = password
777
+ sleep 5
778
+ @browser.execute_script(%{document.getElementById("g-recaptcha-response").innerHTML="} + captcha_token + %{"})
779
+ sleep 5
780
+ return result
781
+ end
782
+
783
+ def move_phase
784
+ @browser.buttons(text: 'Submit').each do |button|
785
+ if button.present?
786
+ button.click
787
+ sleep 5
788
+ return
789
+ end
790
+ end
791
+ @browser.buttons(text: 'Next').each do |button|
792
+ if button.present?
793
+ button.click
794
+ sleep 5
795
+ return
796
+ end
797
+ end
798
+ end
799
+
800
+ def get_phase
801
+ return @browser.button(class: 'c-btn c-btn-primary subreddit-picker__subreddit-button').present? ? 'picksubs' : 'enterdata'
802
+ end
803
+
804
+ def create_account(username, password, captcha_token) #if username is nil, selects username from reddit's suggestions
805
+ @browser.goto PAGE_MAIN
806
+ @browser.div(id: 'header-bottom-right').link(text: 'sign up').click
807
+ sleep 3
808
+ @browser.button(text: 'Next').click
809
+ sleep 5
810
+ result = nil
811
+ 2.times do
812
+ case get_phase
813
+ when 'picksubs'
814
+ phase_pick_subs
815
+ when 'enterdata'
816
+ break if result != nil
817
+ result = phase_enter_data(username, password, captcha_token)
818
+ end
819
+ move_phase
820
+ end
821
+ wait_login(result['username'])
822
+ return result
823
+ end
824
+
825
+ def is_user_banned(user)
826
+ @browser.goto PAGE_USER + user
827
+ skip_over_18 if has_over_18
828
+ return @browser.div(id: 'classy-error').present? || @browser.h3(text: 'This account has been suspended').present?
829
+ end
830
+
831
+ def is_subreddit_banned(subr)
832
+ @browser.goto PAGE_SUBREDDIT + subr
833
+ skip_over_18 if has_over_18
834
+ return @browser.h3(text: 'This community has been banned').present?
835
+ end
836
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reddit_auto
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ícaro Augusto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-01-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: watir
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.16.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.16.5
27
+ description: This gem uses watir and selenium to automate almost all reddit features
28
+ using a headless browser.
29
+ email:
30
+ - icaro10100@hotmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - lib/reddit_auto.rb
36
+ homepage: https://github.com/IcaroAugusto/reddit_automation_bot
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 2.3.0
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubygems_version: 3.1.2
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: A reddit automation gem that uses watir/selenium
59
+ test_files: []