├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── bin └── wwdc ├── lib ├── wwdc.rb └── wwdc │ ├── commands.rb │ ├── commands │ ├── info.rb │ ├── open.rb │ └── search.rb │ ├── helpers.rb │ └── version.rb └── wwdc.gemspec /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Mattt Thompson (http://mattt.me/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WWDC 2 | 3 | **A command-line interface for accessing WWDC session content** 4 | 5 | [ASCIIwwdc](http://asciiwwdc.com) provides searchable full-text transcripts of WWDC content. `wwdc` builds on its API, [which is documented in the project's README](https://github.com/mattt/asciiwwdc.com#README). 6 | 7 | ## Installation 8 | 9 | ```bash 10 | $ gem install wwdc 11 | ``` 12 | 13 | ## Usage 14 | 15 | ### Info 16 | 17 | Displays title and description for the specified session. 18 | 19 | ```bash 20 | $ wwdc info 228 21 | 22 | WWDC 2014 23 | Session 228: "A Look Inside Presentation Controllers" 24 | 25 | iOS 8 brings you powerful new means of presenting content within your apps. Hear 26 | how presentation controllers were leveraged by UIKit to give you fine grain 27 | control using new alert and searching APIs. Dive deep into how presentation 28 | controllers work and how you can use them to present content within your app in 29 | exciting new ways. 30 | 31 | $ wwdc info 228 --year 2013 32 | 33 | WWDC 2013 34 | Session 228: "Hidden Gems in Cocoa and Cocoa Touch" 35 | 36 | Learn from the experts about the Cocoa and Cocoa Touch classes you may not even 37 | know exist, as well as some very obscure but extremely valuable classes that are 38 | favorites of the presenters. 39 | ``` 40 | 41 | ### Open 42 | 43 | Opens browser to Apple Developer page with links to slides and video for specified session. 44 | 45 | ```bash 46 | $ wwdc open 101 --year 2014 47 | ``` 48 | 49 | ### Search 50 | 51 | Finds most relevant sessions based on the specified search query 52 | 53 | ```bash 54 | $ wwdc search Swift 55 | 56 | WWDC 2014 57 | Session 407: "Swift Interoperability In Depth" 58 | 59 | Swift and Objective-C work together at multiple levels to ensure that you can 60 | create great apps for iOS and OS X. Dive deep with us to see how to use 61 | fundamental Core Foundation and C types in your Swift code. Learn how bridging 62 | values work and gain a practical understanding of how Swift and Objective-C can 63 | accelerate your app development. 64 | 65 | ... 66 | ``` 67 | 68 | ## Contact 69 | 70 | ASCIIwwdc ([@asciiwwdc](https://twitter.com/asciiwwdc)) 71 | 72 | ## License 73 | 74 | WWDC is available under the MIT license. See the LICENSE file for more info. 75 | 76 | All content copyright © 2010 – 2018 Apple Inc. All rights reserved. 77 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler" 2 | Bundler.setup 3 | 4 | gemspec = eval(File.read("wwdc.gemspec")) 5 | 6 | task :build => "#{gemspec.full_name}.gem" 7 | 8 | file "#{gemspec.full_name}.gem" => gemspec.files + ["wwdc.gemspec"] do 9 | system "gem build wwdc.gemspec" 10 | end 11 | -------------------------------------------------------------------------------- /bin/wwdc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'commander/import' 4 | 5 | require 'wwdc' 6 | 7 | HighLine.track_eof = false # Fix for built-in Ruby 8 | Signal.trap("INT") {} # Suppress backtrace when exiting command 9 | 10 | program :version, WWDC::VERSION 11 | program :description, 'A command-line interface for accessing WWDC session content' 12 | 13 | program :help, 'Author', 'Mattt ' 14 | program :help, 'Website', 'https://github.com/mattt' 15 | program :help_formatter, :compact 16 | 17 | default_command :help 18 | -------------------------------------------------------------------------------- /lib/wwdc.rb: -------------------------------------------------------------------------------- 1 | require 'wwdc/version' 2 | require 'wwdc/helpers' 3 | require 'wwdc/commands' 4 | -------------------------------------------------------------------------------- /lib/wwdc/commands.rb: -------------------------------------------------------------------------------- 1 | include WWDC::Helpers 2 | 3 | require 'wwdc/commands/info' 4 | require 'wwdc/commands/open' 5 | require 'wwdc/commands/search' 6 | -------------------------------------------------------------------------------- /lib/wwdc/commands/info.rb: -------------------------------------------------------------------------------- 1 | command :info do |c| 2 | c.syntax = 'wwdc info SESSION' 3 | c.summary = 'Get information about a session by its number and year' 4 | c.option '-y', '--year YEAR', 'WWDC Year' 5 | 6 | c.action do |args, options| 7 | determine_session!(args, options) 8 | determine_year!(args, options) 9 | 10 | @session = get(path: "/#{@year}/sessions/#{@number}") 11 | 12 | describe @session 13 | end 14 | end 15 | 16 | alias_command :session, :info 17 | -------------------------------------------------------------------------------- /lib/wwdc/commands/open.rb: -------------------------------------------------------------------------------- 1 | command :open do |c| 2 | c.syntax = 'wwdc open [SESSION]' 3 | c.summary = 'Open your browser to the Apple Developer Center to view session slides and video' 4 | c.option '-y', '--year YEAR', 'WWDC Year' 5 | 6 | c.action do |args, options| 7 | determine_session!(args, options) 8 | determine_year!(args, options) 9 | 10 | @session = get(path: "/#{@year}/sessions/#{@number}") do |response| 11 | url = response.headers['Link'].scan(/\<(.+)\>/).flatten.first 12 | `open "#{url}"` 13 | end 14 | end 15 | end 16 | 17 | alias_command :video, :open 18 | alias_command :slides, :open 19 | -------------------------------------------------------------------------------- /lib/wwdc/commands/search.rb: -------------------------------------------------------------------------------- 1 | command :search do |c| 2 | c.syntax = 'wwdc search [QUERY]' 3 | c.summary = 'Find sessions containing the specified search terms' 4 | c.option '-y', '--year YEAR', 'WWDC Year' 5 | 6 | c.action do |args, options| 7 | determine_query!(args, options) 8 | determine_year!(args, options) if options.year 9 | 10 | @results = get(path: "search", query: {q: @query, year: @year})['results'] 11 | 12 | say_warning "No results" and abort if @results.empty? 13 | 14 | describe *@results 15 | end 16 | end 17 | 18 | alias_command :'?', :search 19 | alias_command :query, :search 20 | -------------------------------------------------------------------------------- /lib/wwdc/helpers.rb: -------------------------------------------------------------------------------- 1 | require 'excon' 2 | require 'json' 3 | require 'rubygems/text' 4 | 5 | module WWDC 6 | YEARS = (2010..2018) 7 | 8 | module Helpers 9 | include Gem::Text 10 | 11 | def get(options = {}, &block) 12 | response = client.get(options) 13 | say_error "Error #{response.status}" and abort unless response.status == 200 14 | 15 | yield response if block_given? 16 | 17 | JSON.parse(response.body) 18 | end 19 | 20 | def describe(*sessions) 21 | enable_paging if sessions.length > 5 22 | 23 | sessions.each do |session| 24 | puts %{\033[1mWWDC #{session['year']}\033[0m} 25 | puts %{\033[1mSession #{session['number']}: "#{session['title']}"\033[0m} 26 | puts 27 | puts format_text(session['description'], 80) 28 | puts 29 | end 30 | end 31 | 32 | private 33 | 34 | def determine_session!(args = [], options = {}) 35 | @number = (Integer(args.first).nonzero? rescue nil) 36 | say_error "Missing session number" and abort unless @number 37 | end 38 | 39 | def determine_year!(args = [], options = {}) 40 | @year = (Integer(options.year).nonzero? rescue nil) || YEARS.last 41 | say_error "Invalid year: #{@year}" and abort unless YEARS.include?(@year) 42 | end 43 | 44 | def determine_query!(args = [], options = {}) 45 | @query = args.join(" ") 46 | say_error "Missing query" and abort if @query.empty? 47 | end 48 | 49 | def client 50 | @client ||= Excon.new('https://asciiwwdc.com', headers: {'Accept' => "application/json"}) 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/wwdc/version.rb: -------------------------------------------------------------------------------- 1 | module WWDC 2 | VERSION = '1.1.1' 3 | end 4 | -------------------------------------------------------------------------------- /wwdc.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | 4 | require "wwdc/version" 5 | 6 | Gem::Specification.new do |s| 7 | s.name = "wwdc" 8 | s.license = "MIT" 9 | s.authors = ["Mattt"] 10 | s.email = "mattt@me.com" 11 | s.homepage = "http://mat.tt" 12 | s.version = WWDC::VERSION 13 | s.platform = Gem::Platform::RUBY 14 | s.summary = "WWDC" 15 | s.description = "A command-line interface for accessing WWDC session content" 16 | 17 | s.add_dependency "commander", "~> 4.1" 18 | s.add_dependency "excon", ">= 0.71.0" 19 | 20 | s.add_development_dependency "rspec" 21 | s.add_development_dependency "rake" 22 | 23 | s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(log|pkg|script|spec|test|vendor)/ } 24 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 25 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 26 | s.require_paths = ["lib"] 27 | end 28 | --------------------------------------------------------------------------------