social_nets_db 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,525 @@
1
+ behance:
2
+ name: Behance
3
+ icons:
4
+ font_awesome: behance
5
+ color: "#1769ff"
6
+ domain: behance.com
7
+ tags:
8
+ - art
9
+ - design
10
+ - recruiting
11
+ profile_url:
12
+ by_username: "https://${domain}/${uid}"
13
+ by_account_id: "https://${domain}/${uid}"
14
+
15
+ bitchute:
16
+ name: Bitchute
17
+ icons:
18
+ color: "#ef4137"
19
+ domain: bitchute.com
20
+ tags:
21
+ - video-hosting
22
+ - anti-censorship
23
+ profile_url:
24
+ by_username: https://${domain}/profile/${uid}
25
+
26
+ bitclout:
27
+ name: Bitclout
28
+ icons:
29
+ color: "#ef4137"
30
+ domain: bitclout.com
31
+ tags:
32
+ - social net
33
+ - crypto
34
+ profile_url:
35
+ by_username: https://${domain}/u/${uid}
36
+
37
+ blogger:
38
+ name: Blogger
39
+ icons:
40
+ font_awesome: "link"
41
+ color: "#ff8000"
42
+ domain: blogger.com
43
+ tags:
44
+ - obsolete
45
+ profile_url:
46
+ by_username: https://${uid}.blogspot.com
47
+
48
+ discord:
49
+ name: Discord
50
+ icons:
51
+ color: "#7289da"
52
+ domain: discord.com
53
+ tags:
54
+ - gaming
55
+ profile_url:
56
+ by_account_id: "https://discord.gg/${uid}"
57
+
58
+ dribble:
59
+ name: Dribble
60
+ icons:
61
+ font_awesome: "dribble"
62
+ color: "#ea4c89"
63
+ domain: dribble.com
64
+ tags:
65
+ - art
66
+ - design
67
+ - portfolio
68
+ profile_url:
69
+ by_username: https://${domain}/${uid}
70
+ by_account_id: "https://${domain}/${uid}"
71
+
72
+ email:
73
+ name: E-mail
74
+ icons:
75
+ font_awesome: "at"
76
+ color: "#ea4c89"
77
+ domain: gmail.com
78
+ tags:
79
+ - protocols
80
+ profile_url:
81
+ by_username: ${uid}
82
+
83
+ ens:
84
+ name: Ethereum namespace
85
+ icons:
86
+ color: "#5284ff"
87
+ domain: ens.domains
88
+ tags:
89
+ -
90
+ profile_url:
91
+ by_username: https://${uid}.eth
92
+
93
+ facebook:
94
+ name: Facebook
95
+ icons:
96
+ font_awesome: "facebook"
97
+ color: "#3C5A99"
98
+ domain: facebook.com
99
+ tags:
100
+ - social net
101
+ profile_url:
102
+ by_username: https://${domain}/${uid}
103
+ by_account_id: "https://${domain}/${uid}"
104
+
105
+ fl.ru:
106
+ name: FL
107
+ icons:
108
+ color: "#4ea828"
109
+ domain: fl.ru
110
+ tags:
111
+ - free-lance
112
+ - design
113
+ - programming
114
+ profile_url:
115
+ by_username: https://${domain}/users/${uid}/
116
+
117
+ flote:
118
+ name: Flote
119
+ icons:
120
+ color: "#01f"
121
+ domain: flote.app
122
+ tags:
123
+ - anti-censorship
124
+ - social net
125
+ profile_url:
126
+ by_username: https://${domain}/user/${uid}/
127
+
128
+ freelansim:
129
+ name: Фрилансим
130
+ icons:
131
+ color: "#4abfb4"
132
+ domain: freelansim.ru
133
+ tags:
134
+ - free-lance
135
+ - design
136
+ - programming
137
+ profile_url:
138
+ by_username: https://${domain}/freelancers/${uid}
139
+
140
+ gab:
141
+ name: Gab
142
+ icons:
143
+ color: "#21cf7a"
144
+ domain: gab.com
145
+ tags:
146
+ - anti-censorship
147
+ - social net
148
+ profile_url:
149
+ by_username: https://${domain}/${uid}
150
+
151
+ gettr:
152
+ name: Gettr
153
+ icons:
154
+ color: "#ff0013"
155
+ domain: gettr.com
156
+ tags:
157
+ - anti-censorship
158
+ - social net
159
+ profile_url:
160
+ by_username: https://${domain}/user/${uid}
161
+
162
+ habr:
163
+ name: Habrahabr
164
+ icons:
165
+ color: "#65a3be"
166
+ domain: habr.com
167
+ tags:
168
+ - recruiting
169
+ - programming
170
+ - blog
171
+ profile_url:
172
+ by_username: https://${domain}/ru/users/${uid}/
173
+
174
+ habr-career:
175
+ name: Хабр Карьера
176
+ icons:
177
+ color: "#64c178"
178
+ domain: career.habr.com
179
+ tags:
180
+ - recruiting
181
+ - programming
182
+ profile_url:
183
+ by_username: https://${domain}/${uid}/
184
+
185
+ hh:
186
+ name: HeadHunter
187
+ icons:
188
+ color: "#D6001C"
189
+ domain: hh.ru
190
+ tags:
191
+ - recruiting
192
+ profile_url:
193
+ by_account_id: "https://${domain}/resume/${uid}"
194
+
195
+ github:
196
+ name: GitHub
197
+ icons:
198
+ font_awesome: "github"
199
+ color: "#333333"
200
+ domain: github.com
201
+ tags:
202
+ - programming
203
+ - recruiting
204
+ profile_url:
205
+ by_username: https://${domain}/${uid}
206
+ by_account_id: "https://${domain}/${uid}"
207
+
208
+ gitlab:
209
+ name: GitLab
210
+ icons:
211
+ font_awesome: "gitlab"
212
+ color: "#fa7035"
213
+ domain: gitlab.com
214
+ tags:
215
+ - programming
216
+ - recruiting
217
+ profile_url:
218
+ by_username: https://${domain}/${uid}
219
+
220
+ instagram:
221
+ name: Instagram
222
+ icons:
223
+ font_awesome: "instagram"
224
+ color: "#e1306c"
225
+ domain: instagram.com
226
+ tags:
227
+ - social net
228
+ profile_url:
229
+ by_username: https://${domain}/${uid}
230
+
231
+ lbry:
232
+ name: LBRY
233
+ icons:
234
+ color: "#38d9a9"
235
+ domain: lbry.tv
236
+ tags:
237
+ - video-hosting
238
+ profile_url:
239
+ by_username: https://${domain}/@${uid}
240
+
241
+ linkedin:
242
+ name: LinkedIn
243
+ icons:
244
+ font_awesome: "linkedin"
245
+ color: "#0077b5"
246
+ domain: linkedin.com
247
+ tags:
248
+ - recruiting
249
+ - social net
250
+ profile_url:
251
+ by_username: https://${domain}/in/${uid}
252
+
253
+ livejournal:
254
+ name: LiveJournal
255
+ icons:
256
+ font_awesome: "livejournal"
257
+ color: "#00A3D9"
258
+ domain: livejournal.com
259
+ tags:
260
+ - blog
261
+ - obsolete
262
+ profile_url:
263
+ by_username: https://${uid}.${domain}
264
+
265
+ locals:
266
+ name: Locals
267
+ icons:
268
+ color: "#e73348"
269
+ domain: locals.com
270
+ tags:
271
+ - anti-censorship
272
+ - paywall
273
+ profile_url:
274
+ by_username: https://${uid}.${domain}
275
+
276
+ manosphere:
277
+ name: Manosphere
278
+ icons:
279
+ color: "#d84c47"
280
+ domain: manosphere.tv
281
+ tags:
282
+ - anti-censorship
283
+ - paywall
284
+ profile_url:
285
+ by_username: https://${domain}/@${uid}
286
+
287
+ medium:
288
+ name: Medium
289
+ icons:
290
+ font_awesome: "medium"
291
+ color: "#00ab6c"
292
+ domain: medium.com
293
+ tags:
294
+ - blog
295
+ - paywall
296
+ profile_url:
297
+ by_username: https://${uid}.${domain}
298
+
299
+ minds:
300
+ name: Minds
301
+ icons:
302
+ color: "#ffdd63"
303
+ domain: minds.com
304
+ tags:
305
+ - anti-censorship
306
+ - crypto
307
+ - social net
308
+ profile_url:
309
+ by_username: https://${domain}/${uid}
310
+
311
+ my.mail.ru:
312
+ name: Мой мир
313
+ icons:
314
+ color: "#005FF9"
315
+ domain: my.mail.ru
316
+ tags:
317
+ - obsolete
318
+ - social net
319
+ profile_url:
320
+ by_username: https://${domain}/mail/${uid}/
321
+
322
+ odysee:
323
+ name: Odysee
324
+ icons:
325
+ color: "#000000"
326
+ domain: odysee.com
327
+ tags:
328
+ - anti-censorship
329
+ - crypto
330
+ - video-hosting
331
+ profile_url:
332
+ by_username: https://${domain}/@${uid}/
333
+
334
+ odnoklassniki:
335
+ name: Одноклассники
336
+ icons:
337
+ font_awesome: "odnoklassniki"
338
+ color: "#e47d08"
339
+ domain: ok.ru
340
+ tags:
341
+ - obsolete
342
+ - social net
343
+ profile_url:
344
+ by_username: https://${domain}/${uid}/
345
+
346
+ paypal:
347
+ name: PayPal
348
+ icons:
349
+ font_awesome: "paypal"
350
+ color: "#0070ba"
351
+ domain: paypal.com
352
+ tags:
353
+ - payment service
354
+ profile_url:
355
+ by_username: https://${domain}/${uid}
356
+
357
+ patreon:
358
+ name: Patreon
359
+ icons:
360
+ color: "#ff424d"
361
+ domain: patreon.com
362
+ tags:
363
+ - paywall
364
+ profile_url:
365
+ by_username: https://${domain}/${uid}
366
+
367
+ remoteok:
368
+ name: RemoteOK
369
+ icons:
370
+ color: "#ff4742"
371
+ domain: remoteok.io
372
+ tags:
373
+ - design
374
+ - programming
375
+ - recruiting
376
+ profile_url:
377
+ by_username: https://${domain}/@${uid}
378
+
379
+ rokfin:
380
+ name: Rokfin
381
+ icons:
382
+ color: "#08AD9F"
383
+ domain: rokfin.com
384
+ tags:
385
+ - anti-censorship
386
+ - video-hosting
387
+ profile_url:
388
+ by_username: https://${domain}/${uid}
389
+
390
+ rumble:
391
+ name: Rumble
392
+ icons:
393
+ font_awesome: "play-circle"
394
+ color: "#74a441"
395
+ domain: rumble.com
396
+ tags:
397
+ - anti-censorship
398
+ - video-hosting
399
+ profile_url:
400
+ by_username: https://${domain}/c/${uid}
401
+
402
+ stackoverflow:
403
+ name: StackOverflow
404
+ icons:
405
+ font_awesome: "stackoverflow"
406
+ color: "#F48024"
407
+ domain: stackoverflow.com
408
+ tags:
409
+ - recruiting
410
+ - programming
411
+ profile_url:
412
+ by_account_id: "https://${domain}/users/${uid}?tab=profile"
413
+
414
+ subscribestar:
415
+ name: SubscribeStar
416
+ icons:
417
+ color: "#ff4081"
418
+ domain: subscribestar.com
419
+ tags:
420
+ - paywall
421
+ profile_url:
422
+ by_username: https://${domain}/${uid}
423
+
424
+ substack:
425
+ name: SubStack
426
+ icons:
427
+ color: "#ff4081"
428
+ domain: substack.com
429
+ tags:
430
+ - paywall
431
+ - blog
432
+ profile_url:
433
+ by_username: https://${uid}.${domain}
434
+
435
+ telegram:
436
+ name: Telegram
437
+ icons:
438
+ font_awesome: "telegram"
439
+ color: "#0088cc"
440
+ domain: telegram.com
441
+ tags:
442
+ - anti-censorship
443
+ - blog
444
+ - messenger
445
+ profile_url:
446
+ by_username: https://t.me/${uid}
447
+
448
+ tiktok:
449
+ name: TikTok
450
+ icons:
451
+ color: "#fe2c55"
452
+ domain: tiktok.com
453
+ tags:
454
+ - video-hosting
455
+ profile_url:
456
+ by_username: https://${domain}/@${uid}
457
+
458
+ twitter:
459
+ name: Twitter
460
+ icons:
461
+ font_awesome: "twitter"
462
+ color: "#1da1f2"
463
+ domain: twitter.com
464
+ tags:
465
+ - social net
466
+ profile_url:
467
+ by_username: https://${domain}/${uid}
468
+
469
+ upwork:
470
+ name: UpWork
471
+ icons:
472
+ color: "#37A000"
473
+ domain: upwork.com
474
+ tags:
475
+ - design
476
+ - freelancers
477
+ - programming
478
+ profile_url:
479
+ by_account_id: "https://${domain}/freelancers/~${uid}"
480
+
481
+ vkontakte:
482
+ name: Вконтакте
483
+ icons:
484
+ font_awesome: "vk"
485
+ color: "#45668e"
486
+ domain: vkontakte.com
487
+ tags:
488
+ - social net
489
+ profile_url:
490
+ by_username: https://${domain}/${uid}
491
+ by_account_id: "https://${domain}/id${uid}"
492
+
493
+ youtube:
494
+ name: YouTube
495
+ icons:
496
+ font_awesome: "youtube"
497
+ color: "#ff0000"
498
+ domain: youtube.com
499
+ tags:
500
+ - video-hosting
501
+ profile_url:
502
+ by_username: https://${domain}/c/${uid}
503
+ by_account_id: "https://${domain}/channel/${uid}"
504
+
505
+ youtube_profile:
506
+ name: YouTube
507
+ icons:
508
+ font_awesome: "youtube"
509
+ color: "#ff0000"
510
+ domain: youtube.com
511
+ tags:
512
+ - video-hosting
513
+ profile_url:
514
+ by_username: https://${domain}/${uid}
515
+
516
+ website:
517
+ name: Web site
518
+ icons:
519
+ font_awesome: "link"
520
+ color: "#ff0000"
521
+ domain:
522
+ tags:
523
+ - protocols
524
+ profile_url:
525
+ by_username: ${uid}
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FnValidations
4
+
5
+ module_function
6
+
7
+ def validate_argument_type! argument, permitted_types
8
+ types = Array(permitted_types)
9
+ type_names = types.map { |klass| "`#{klass}`" }.join(" or ")
10
+ valid = types.any? { |type| argument.is_a? type }
11
+ message = "#{type_names} is expected, you pass a `#{argument.class}` (#{argument})"
12
+ fail TypeError, message unless valid
13
+ argument
14
+ end
15
+
16
+ def validate_collection_item_types! collection, permitted_types
17
+ types = Array(permitted_types)
18
+ type_names = types.map { |name| "`#{name}`" }.join(" or ")
19
+ valid = collection.all? { |item| types.include?(item.class) }
20
+ message = "#{type_names} is expected, one the items you pass is of incorrect type"
21
+ fail TypeError, message unless valid
22
+ collection
23
+ end
24
+
25
+ def validate_argument_boolean! argument
26
+ validate_argument_type! argument, [TrueClass, FalseClass]
27
+ end
28
+
29
+ def validate_argument_presence! argument
30
+ validate_argument_type! argument, [String, Symbol]
31
+ return argument if argument.is_a?(Symbol)
32
+ message = "You must pass a non-empty String, you are passing #{argument.inspect}"
33
+ fail ArgumentError, message unless argument.is_a?(String) && argument != ""
34
+ argument
35
+ end
36
+
37
+ def validate_argument_positive! argument
38
+ validate_argument_type! argument, Numeric
39
+ message = "You must pass a positive value, you pass #{argument.inspect}"
40
+ fail ArgumentError, message unless argument.positive?
41
+ argument
42
+ end
43
+
44
+ end
45
+
46
+ # RSpec.describe FnValidations do
47
+
48
+ # include described_class
49
+
50
+ # context "invalid input" do
51
+ # it do expect { validate_argument_type! 1, String }.to raise_exception(ArgumentError) end
52
+ # it do expect { validate_argument_type! 1, [String] }.to raise_exception(ArgumentError) end
53
+ # it do expect { validate_argument_type! 1, [Hash, String] }.to raise_exception(ArgumentError) end
54
+ # end
55
+
56
+ # context "valid input" do
57
+ # it do expect { validate_argument_type! 1, Integer }.not_to raise_exception(ArgumentError) end
58
+ # it do expect { validate_argument_type! 1, [Integer] }.not_to raise_exception(ArgumentError) end
59
+ # it do expect { validate_argument_type! 1, [Integer, Hash] }.not_to raise_exception(ArgumentError) end
60
+ # end
61
+
62
+ # context "valid by ancestory" do
63
+ # it do expect { validate_argument_type! 1, Numeric }.not_to raise_exception(ArgumentError) end
64
+ # it do expect { validate_argument_type! [], Enumerable }.not_to raise_exception(ArgumentError) end
65
+ # end
66
+
67
+ # end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SocialNetsDB
4
+ class SocialNet
5
+
6
+ # To have methods both on class & instance
7
+ extend Support
8
+ include Support
9
+ extend FnValidations
10
+ include FnValidations
11
+
12
+ def initialize(uid, data)
13
+ validate_argument_type! data, Hash
14
+ validate_argument_type! uid, [String, Symbol]
15
+ @data, @uid = data, uid
16
+ end
17
+
18
+ attr_accessor :uid
19
+
20
+ [:color, :domain, :icons, :name].each do |method_symbol|
21
+ define_method(method_symbol) do
22
+ to_h[method_symbol.to_s]
23
+ end
24
+ end
25
+
26
+ def to_h
27
+ self.class.send :raw_data_for, @uid
28
+ end
29
+
30
+ def url
31
+ "https://#{domain}"
32
+ end
33
+
34
+ def user_page(username: nil, account_id: nil)
35
+ return unless page = to_h["profile_url"]
36
+ return unless template = page["by_username"] || page["by_account_id"]
37
+ uid = [username, account_id].select { present_str? _1 }.first or fail(ArgumentError, "Either a username or an account id must be provided")
38
+
39
+ if username && page["by_username"]
40
+ fail ArgumentError, "Either a username or an account id must be provided" unless present_str?(username)
41
+ template.sub("${domain}", domain).sub("${uid}", username)
42
+ elsif account_id && page["by_account_id"]
43
+ fail ArgumentError, "Either a username or an account id must be provided" unless present_str?(account_id)
44
+ template.sub("${domain}", domain).sub("${uid}", account_id)
45
+ end
46
+ end
47
+
48
+ def user_page_methods
49
+ ["account_id", "username"].select { |key| present_str? to_h.dig("profile_url", "by_#{key}") }
50
+ end
51
+
52
+
53
+ # Class methods
54
+
55
+ class << self
56
+
57
+ # TODO this must be transofrmed into array of structs
58
+ def all
59
+ RECORDS
60
+ end
61
+
62
+ # @param [String] name Social network name
63
+ # @param [String, Symbol] uid Social network UID
64
+ #
65
+ def find_by(name: nil, uid: nil)
66
+ return find_by_uid(uid) if present_str?(uid)
67
+ return find_by_name(name) if present_str?(name)
68
+ fail ArgumentError, "`name:` or `uid:` must be provided. You are passing name: #{name.inspect}, uid: #{uid.inspect}"
69
+ end
70
+
71
+ def find_by_name(name)
72
+ validate_argument_presence! name
73
+ return unless record = RECORDS.select { |uid, data| data["name"] == name }.first
74
+ find_by_uid record[0]
75
+ end
76
+
77
+ # @param [String, Symbol] uid Social network UID
78
+ #
79
+ def find_by_uid(uid)
80
+ validate_argument_type! uid, String
81
+ validate_argument_presence! uid
82
+
83
+ # unless uids.include?(@uid = uid)
84
+ # fail ArgumentError, "Social net with UID #{uid} is not recognized. Currently supported UIDs are: #{uids.join(", ")}. To add a new social net, send us a PR."
85
+ # end
86
+ return unless data = raw_data_for(uid)
87
+ self.new(uid, data)
88
+ end
89
+
90
+ private def raw_data_for(uid)
91
+ RECORDS[uid.to_s]
92
+ end
93
+
94
+ def names
95
+ RECORDS.map { |uid, data| data[:name] }
96
+ end
97
+
98
+ def uids
99
+ RECORDS.map { |uid, data| data[:uid].to_s }
100
+ end
101
+
102
+ def values_for_select
103
+ RECORDS.map { |uid, data| [data[:name], uid] }
104
+ end
105
+
106
+ alias_method :find, :find_by_uid
107
+
108
+ end
109
+
110
+ end
111
+ end