codebadges 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68955f2962ad30ae0a1383f20570db988bcfc0d5
4
- data.tar.gz: e63d0319bae4948256dc1bede00cccafaa8ae5c2
3
+ metadata.gz: 5c22abfa1d1de1379c39807dd72bd53b331a011b
4
+ data.tar.gz: 3674c115ef9068fb5152085a23d14d39d6a731ee
5
5
  SHA512:
6
- metadata.gz: 21bd415f2d143fc070da51a01ee641fe532d236159e24734adfb3a046adbe876cd6c61af0ddcff021201c31d20b01380e22e663d840158fbbb26946dfc1bd7f8
7
- data.tar.gz: 909c44137fb280380f5b2ac9719de8ef2f6907aeb5cb4f175b120cdf679ce8d1f2d6e6d0ed997b250ef0e10ca471d719994d1f667d3ba6f77d99d5477e5d7343
6
+ metadata.gz: 4715c01e03c0776b9f32b6be4a25f36c634feb3c07c52271fcafd1bdddf1e1938b60108b0de1253ee12fcabe4585ca06d3ffab280036961f57be66293f5c72e9
7
+ data.tar.gz: 94ba8ce903b4290bebffc9ece7cb31a9f2c7428176b7353d9660613960f52564fb3f9c3c995105086c13e67bd60380c9de75aabae1490bd300b6ca56930a8f23
data/.travis.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - ruby-head
4
+ - jruby-head
4
5
  branches:
5
6
  only:
6
7
  - master
8
+ - develop
data/Gemfile CHANGED
@@ -3,5 +3,5 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
- gem 'rake'
7
- end
6
+ gem 'rake'
7
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Soumya Ray, Chen Li-Zhan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,24 +1,31 @@
1
- CodeBadges
2
- ===============
1
+ # CodeBadges [![Build Status](https://travis-ci.org/ISS-SOA/Codecademy-Ruby.svg?branch=develop)](https://travis-ci.org/ISS-SOA/Codecademy-Ruby)
3
2
 
4
- CodeBadges. It tries to grabs some information on the Codecademy. What it grab? Badges!
3
+ Codecademy is a great place to learn coding! Unfortunately, Codecademy's website
4
+ doesn't provide an API to help us monitor our own coding.
5
+ So we made the CodeBadges gem to scrape user achievements from Codecademy!
5
6
 
6
- ## About
7
-
8
- Once you done a section of course on the Codecademy(The online programming tutorial), you will get a badges.
9
- The gem is to understand that what course and the level the user take on the Codecademy.
7
+ Note that we respect Codecademy's `robots.txt`
10
8
 
11
9
  ## Usage
12
10
 
13
11
  Install it with the following command:
14
- ````ruby
15
- gem install codebadges
16
- ````
12
+ ```sh
13
+ $ gem install codebadges
14
+ ```
17
15
 
18
- Then in your file:
16
+ Or else put it in your `Gemfile` as:
17
+ ```ruby
18
+ gem codebadges
19
+ ```
20
+
21
+ Run it from the command line. For example, to get the achievements of user `chenlizhan`:
22
+ ```
23
+ $ codebadges chenlizhan
24
+ ```
25
+
26
+ Or use it from your Ruby code:
19
27
  ````ruby
20
- require "codebadges"
21
- CodecademyBadges.get_badges(username)
22
- ````
23
- The argument username is the user's account who you want to check it out!
28
+ require 'codebadges'
29
+ lee = CodeBadges::CodecademyBadges.new('chenlizhan')
30
+ badges = lee.badges
24
31
  ````
data/Rakefile CHANGED
@@ -3,6 +3,6 @@ require 'rake/testtask'
3
3
  task :default => [:spec]
4
4
 
5
5
  desc 'Run specs'
6
- task :spec do
7
- sh 'ruby -I lib spec/badges_test.rb'
6
+ Rake::TestTask.new(name=:spec) do |t|
7
+ t.pattern = 'spec/*_spec.rb'
8
8
  end
data/bin/codebadges CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # require '../lib/codebadges/badges.rb' # for cmd line testing purposes
4
3
  require 'codebadges' # for production
4
+ # require '../lib/codebadges/badges.rb' # for cmd line testing purposes
5
5
 
6
6
  def get_users_array_from_file(file)
7
7
  users_array = []
data/codebadges.gemspec CHANGED
@@ -1,21 +1,23 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
2
  require 'codebadges/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'codebadges'
6
6
  s.version = CodeBadges::VERSION
7
+ s.date = CodeBadges::DATE
7
8
  s.executables << 'codebadges'
8
- s.date = '2015-07-21'
9
- s.summary = 'Grab the badges information from the Codecademy'
10
- s.description = 'Use username as an input, automatically give you the badges the user has.'
9
+ s.summary = 'Access user and course information on Codecademy'
10
+ s.description = 'Get user achievements and course info from Codecademy'
11
11
  s.authors = ['Lee Chen', 'Soumya Ray']
12
- s.email = 'chung1350@hotmail.com'
12
+ s.email = ['chung1350@hotmail.com', 'soumya.ray@gmail.com']
13
13
  s.files = `git ls-files`.split("\n")
14
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ s.test_files = `git ls-files spec/*`.split("\n")
15
15
  s.homepage = 'https://github.com/ISS-SOA/Codecademy-Ruby'
16
16
  s.license = 'MIT'
17
17
 
18
18
  s.add_development_dependency 'minitest'
19
19
  s.add_development_dependency 'minitest-rg'
20
- s.add_runtime_dependency 'nokogiri', '>= 1.6.2' # v.1.6.2 has documented problems
20
+ s.add_development_dependency 'vcr'
21
+ s.add_development_dependency 'webmock'
22
+ s.add_runtime_dependency 'oga'
21
23
  end
@@ -1,44 +1,38 @@
1
- require 'nokogiri'
1
+ require 'oga'
2
2
  require 'open-uri'
3
3
  require 'date'
4
- # Author: Lee Chen (mailto: chung1350@hotmail.com)
5
- # License: MIT
4
+
6
5
  module CodeBadges
7
6
  # This class get the user account as an input
8
7
  # return a hash of user's badges information
9
8
  class CodecademyBadges
10
- TITLE_XPATH = "//div[@class = 'grid-row']//h5[@class = 'margin-top--1']"
11
- DATE_XPATH = "//small[@class = 'text--ellipsis']"
12
9
  USERS_URL = 'https://www.codecademy.com/users'
13
10
  ACHIEVEMENTS_DIR = 'achievements'
11
+ ACHIEVEMENT_XPATH = "//div[contains(@class,'achievement-card')]"
12
+ ACH_TITLE_XPATH = 'h5'
13
+ ACH_DATE_XPATH = 'small/small'
14
14
 
15
- def self.get_badges(username)
16
- doc = get_html(username)
17
- titles = get_titles(doc)
18
- dates = get_dates(doc)
19
- integrate(titles, dates)
15
+ def initialize(username)
16
+ parse_html(username)
20
17
  end
21
18
 
22
- def self.get_html(username)
23
- url = "#{USERS_URL}/#{username}/#{ACHIEVEMENTS_DIR}"
24
- Nokogiri::HTML(open(url))
19
+ def badges
20
+ @badges ||= extract_achievements
25
21
  end
26
22
 
27
- def self.get_titles(document)
28
- titles = document.xpath(TITLE_XPATH)
29
- titles.map { |t| t.text }
30
- end
23
+ private
31
24
 
32
- def self.get_dates(document)
33
- dates = document.xpath(DATE_XPATH)
34
- dates.map { |d| Date.parse(d) }
25
+ def parse_html(username)
26
+ url = "#{USERS_URL}/#{username}/#{ACHIEVEMENTS_DIR}"
27
+ @document = Oga.parse_html(open(url))
35
28
  end
36
29
 
37
- def self.integrate(titles, dates)
38
- badge_array = titles.each_with_index.map do |_, index|
39
- [titles[index], dates[index]]
40
- end
41
- Hash[badge_array]
30
+ def extract_achievements
31
+ @document.xpath(ACHIEVEMENT_XPATH).map do |achievement|
32
+ title = achievement.xpath(ACH_TITLE_XPATH).text
33
+ date = Date.parse(achievement.xpath(ACH_DATE_XPATH).text)
34
+ [title, date]
35
+ end.to_h
42
36
  end
43
37
  end
44
38
  end
@@ -0,0 +1,25 @@
1
+ require 'oga'
2
+ require 'open-uri'
3
+ require 'date'
4
+
5
+ module CodeBadges
6
+ # This class get the user account as an input
7
+ # return a hash of user's badges information
8
+ class CodecademyCourses
9
+ MAIN_URL = 'https://www.codecademy.com'
10
+ XPATH_COURSES = "//div[h5/strong/text()='Learn To Code']/div/div/ul/li/a"
11
+
12
+ def courses
13
+ @courses ||= extract_main_courses
14
+ end
15
+
16
+ private
17
+
18
+ def extract_main_courses
19
+ doc = Oga.parse_html(open(MAIN_URL))
20
+ doc.xpath(XPATH_COURSES).map do |course|
21
+ [course.text, URI.join(MAIN_URL, course.get('href'))]
22
+ end.to_h
23
+ end
24
+ end
25
+ end
@@ -1,4 +1,5 @@
1
1
  # Versioning
2
2
  module CodeBadges
3
- VERSION = '1.0.0'
3
+ VERSION = '2.0.0'
4
+ DATE = '2015-10-11'
4
5
  end
data/lib/codebadges.rb CHANGED
@@ -1 +1,2 @@
1
1
  require 'codebadges/badges.rb'
2
+ require 'codebadges/courses.rb'
@@ -0,0 +1,30 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/rg'
3
+ require 'yaml'
4
+ require 'vcr'
5
+ require 'webmock/minitest'
6
+ require './lib/codebadges.rb'
7
+
8
+ USERNAME = 'soumya.ray'
9
+ badges_from_file = YAML.load(File.read('./spec/fixtures/badges.yml'))
10
+
11
+ VCR.configure do |config|
12
+ config.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
13
+ config.hook_into :webmock
14
+ end
15
+
16
+ VCR.use_cassette('badges') do
17
+ badges_found = CodeBadges::CodecademyBadges.new(USERNAME).badges
18
+
19
+ describe 'Get badges for one user' do
20
+ it 'has the right number of badges' do
21
+ badges_found.size.wont_be :<, badges_from_file[USERNAME].size
22
+ end
23
+
24
+ badges_from_file[USERNAME].map do |b_name, b_date|
25
+ it "finds '#{b_name}' badge" do
26
+ badges_found[b_name].must_equal Date.parse(b_date)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/rg'
3
+ require 'yaml'
4
+ require 'vcr'
5
+ require 'webmock/minitest'
6
+ require './lib/codebadges.rb'
7
+
8
+ test_courses = YAML.load(File.read('spec/fixtures/courses.yml'))
9
+
10
+ VCR.configure do |config|
11
+ config.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
12
+ config.hook_into :webmock
13
+ end
14
+
15
+ VCR.use_cassette('courses') do
16
+ codecademy = CodeBadges::CodecademyCourses.new
17
+ courses = codecademy.courses
18
+
19
+ describe 'Find all test courses' do
20
+ it 'has the right number of badges' do
21
+ courses.size.wont_be :<, test_courses.size
22
+ end
23
+
24
+ test_courses.map do |course_name|
25
+ it "finds course '#{course_name}'" do
26
+ codecademy.courses.keys.include? course_name
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,75 @@
1
+ ---
2
+ soumya.ray:
3
+ Sorting Your Friends: May 18, 2014
4
+ 100 Exercises: May 18, 2014
5
+ Max Streak Count of 3: May 11, 2014
6
+ Design a Button for Your Website: May 9, 2014
7
+ 'CSS: An Overview': May 9, 2014
8
+ Build Your Own Webpage: May 9, 2014
9
+ 50 Exercises: May 9, 2014
10
+ Clickable Photo Page: May 9, 2014
11
+ HTML Basics III: May 9, 2014
12
+ 25 points earned in one day: May 9, 2014
13
+ HTML Basics: May 9, 2014
14
+ 25 Exercises: May 9, 2014
15
+ 10 Exercises: Dec 12, 2012
16
+ Max Streak Count of 1: Dec 12, 2012
17
+ First Lesson: Jun 20, 2012
18
+ chenlizhan:
19
+ Animate Your Name: Sep 26, 2014
20
+ Banking on Ruby: Aug 25, 2014
21
+ Object-Oriented Programming II: Aug 25, 2014
22
+ Virtual Computer: Aug 25, 2014
23
+ 500 Exercises: Aug 25, 2014
24
+ Object-Oriented Programming I: Aug 22, 2014
25
+ Blocks, Procs, and Lambdas: Aug 22, 2014
26
+ The Refactor Factory: Aug 21, 2014
27
+ The Zen of Ruby: Aug 21, 2014
28
+ 150 points earned in one day: Aug 21, 2014
29
+ A Night at the Movies: Aug 21, 2014
30
+ Hashes and Symbols: Aug 21, 2014
31
+ 125 points earned in one day: Aug 21, 2014
32
+ Ordering Your Library: Aug 21, 2014
33
+ Methods, Blocks, & Sorting: Aug 21, 2014
34
+ 100 points earned in one day: Aug 21, 2014
35
+ Create a Histogram: Aug 21, 2014
36
+ Data Structures: Aug 21, 2014
37
+ Redacted!: Aug 21, 2014
38
+ Loops & Iterators: Aug 21, 2014
39
+ Thith Meanth War!: Aug 21, 2014
40
+ Control Flow in Ruby: Aug 21, 2014
41
+ Putting the Form in Formatter: Aug 21, 2014
42
+ Introduction to Ruby: Aug 21, 2014
43
+ File Input/Output: Jul 24, 2014
44
+ Max Streak Count of 5: Jul 24, 2014
45
+ Classes: Jul 24, 2014
46
+ Introduction to Classes: Jul 23, 2014
47
+ Introduction to Bitwise Operators: Jul 22, 2014
48
+ Advanced Topics in Python: Jul 22, 2014
49
+ Exam Statistics: Jul 22, 2014
50
+ Max Streak Count of 3: Jul 22, 2014
51
+ Practice Makes Perfect: Jul 21, 2014
52
+ 200 Exercises: Jul 21, 2014
53
+ 75 points earned in one day: Jul 21, 2014
54
+ Loops: Jul 21, 2014
55
+ Battleship!: Jul 20, 2014
56
+ Lists and Functions: Jul 20, 2014
57
+ Student Becomes the Teacher: Jul 20, 2014
58
+ PygLatin: Jul 20, 2014
59
+ A Day at the Supermarket: Jul 19, 2014
60
+ Python Lists and Dictionaries: Jul 19, 2014
61
+ 100 Exercises: Jul 19, 2014
62
+ Taking a Vacation: Jul 19, 2014
63
+ Functions: Jul 19, 2014
64
+ Conditionals & Control Flow: Jul 18, 2014
65
+ 50 points earned in one day: Jul 18, 2014
66
+ 50 Exercises: Jul 18, 2014
67
+ Date and Time: Jul 18, 2014
68
+ Strings & Console Output: Jul 18, 2014
69
+ 25 points earned in one day: Jul 18, 2014
70
+ 25 Exercises: Jul 18, 2014
71
+ Tip Calculator: Jul 18, 2014
72
+ Python Syntax: Jul 18, 2014
73
+ First Lesson: Jul 18, 2014
74
+ 10 Exercises: Jul 18, 2014
75
+ Max Streak Count of 1: Mar 29, 2014
@@ -0,0 +1,17 @@
1
+ ---
2
+ - Make a Website
3
+ - Make a Website Projects
4
+ - Make an Interactive Website
5
+ - Learn Rails
6
+ - Learn AngularJS
7
+ - Ruby on Rails Authentication
8
+ - Learn the Command Line
9
+ - Learn SQL
10
+ - Learn Java
11
+ - HTML & CSS
12
+ - JavaScript
13
+ - jQuery
14
+ - PHP
15
+ - Python
16
+ - Ruby
17
+ - Learn APIs