reddit_auto 1.0.0

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 (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: []