text:
<repo_name>MarioSamperi75/junit-5-basics<file_sep>/README.md
# junit-5-basics

A very simple project just to show syntax and functionalities of JUnit5. Look at the folder src/test.

branch_name: refs/heads/master

repo_language: Markdown


text:
<repo_name>seandong/mina-ci<file_sep>/lib/mina/ci.rb
require 'mina/ci/version'
require 'mina/ci/tasks'<file_sep>/README.md
# mina-ci
Mina recipe for checking Circle CI build status

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'mina-ci', require: false
```

And then execute:

    $ bundle

## Usage

    require 'mina/ci'

    ...
    set :circle_token,      'your circle API token'
    set :circle_username,   'your circle project username'
    set :circle_project,    'your circle project'
    set :circle_notify_url, 'notify special url if check status failed'

    task deploy: :environment do
      deploy do
        invoke :'ci:verify_status'
        ...

        to :launch do
          ...
        end
      end
    end

## Options

| Name                         | Description                         |
| ---------------------------- | ----------------------------------- |
| `circle_token`               | CircleCI API token                  |
| `circle_username`            | CircleCI project username           |
| `circle_project`             | CircleCI project name               |

## Contributing

1. Fork it ( https://github.com/seandong/mina-ci/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request<file_sep>/mina-ci.gemspec
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'mina/ci/version'

Gem::Specification.new do |spec|
  spec.name          = 'mina-ci'
  spec.version       = Mina::Ci::VERSION
  spec.authors       = ['<NAME>']
  spec.email         = ['<EMAIL>']
  spec.summary       = %q{Mina recipe for checking Circle CI build status}
  spec.description   = %q{Mina recipe for checking Circle CI build status of your repo.}
  spec.homepage      = 'https://github.com/seandong/mina-ci'
  spec.license       = 'MIT'

  spec.files         = `git ls-files`.split($/)
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ['lib']

  spec.add_development_dependency 'bundler', '~> 1.6'
  spec.add_development_dependency 'rake',    '~> 10.0'
  spec.add_development_dependency 'minitest', '~> 5.0'
  spec.add_runtime_dependency     'mina',    '~> 0.3'
end
<file_sep>/lib/mina/ci/tasks.rb
require 'json'

# # Modules: CI
# Adds settings and tasks for checking CircleCI status.
#
#     require 'mina/ci'
#
# ## Settings
#
# ### circle_token
# CircleCI API access token.
#
# ### circle_username
# CircleCI username
#
# ### circle_project
# Name by which CircleCI knows your project
#

set_default :circle_token,      -> { ENV['CIRCLE_TOKEN'] }
set_default :circle_username,   -> { ENV['CIRCLE_USERNAME'] }
set_default :circle_project,    -> { ENV['CIRCLE_PROJECT'] }
set_default :circle_notify_url, -> { '' }

namespace :ci do

  desc 'Verify CircleCI build status.'
  task :verify_status => :environment do
    queue %[echo "-----> check CircleCI build status"]
    die 0, 'Please set `:circle_token`.'     unless circle_token
    die 0, 'Please set `:circle_username`.'  unless circle_username
    die 0, 'Please set `:circle_project`.'   unless circle_project

    unless success?
      notify_error
      die 0, "CircleCI build failed. current status: #{cricle_status}), please check and fix it first."
    end
  end

  private

  def circle_url
    "https://circleci.com/api/v1/project/#{circle_username}/#{circle_project}/tree/#{branch}?circle-token=#{circle_token}&limit=1"
  end

  def circle_repsonse
    JSON.parse `curl -s -H 'Accept: application/json' #{circle_url}`
  end

  def notify_error
    if circle_notify_url && circle_notify_url != ''
      `curl -d "subject=#{circle_project}(#{branch}) deploy failed." -d "message=status: #{cricle_status}" #{circle_notify_url}`
    end
  end

  def success?
    %w(success fixed).include?(cricle_status)
  end

  def cricle_status
    @cricle_status ||= begin
      response = circle_repsonse.find { |item| item['branch'] == branch }
      response.nil? ? '' : response['status']
    end
  end
end

languages: Markdown Ruby

repo_name: seandong/mina-ci


text:
<repo_name>AlexEidt/UW-Course-Planner<file_sep>/app.py
"""
<NAME>

Runs the Flask Application for the UW Course Planner Web App.
"""

import re
import json
import os
import uwtools
import pandas as pd
from create_tree import create_tree, graph_department
from schedule import get_combinations
from schedule import main as check_schedules
from flask import Flask, redirect, url_for, render_template, jsonify, request

app = Flask(__name__)
app.config['SECRET_KEY'] = <KEY>'

PATH = os.path.join(os.getcwd(), 'static')

CATALOGS = pd.read_csv(os.path.join(PATH, 'Course_Catalogs.csv'), dtype=str, index_col=0).fillna('')
with open(os.path.join(PATH, 'departments.json'), mode='r') as f:
    UW_DEPARTMENTS = json.loads(f.read())
with open(os.path.join(PATH, 'geocode.json'), mode='r') as f:
    GEOCODED = json.loads(f.read())
# Used to check courses entered in MyMap to verify they are actually offered that quarter
with open(os.path.join(PATH, 'Time_Schedules.json'), mode='r') as f:
    TIME_SCHEDULE = json.loads(f.read())

@app.route('/')
@app.route('/home/')
def index():
    return render_template('index.html')

"""
@app.route('/upload', methods=['GET', 'POST'])
def get_transcript():
    # Download Transcript from user and save as 'Transcript.txt'
    if request.method == 'POST':
        transcript = request.files['transcript']
        transcript.save('Transcript.txt')
    found_transcript = 'Transcript.txt' in os.listdir()
    return render_template('requirements.html', url=request.url_root, transcript=found_transcript)
"""

@app.route('/search/', methods=['POST'])
def search():
    # Search used for the Search Bar in right corner of the Nav Bar
    course = request.form['name'].upper().replace(' ', '')
    if course in CATALOGS.index:
        # Create the Prerequisite Tree if necessary for the course page
        svg = create_tree(CATALOGS, course, request.url_root)
        return render_template(
            'course.html',
            svg=svg,
            course=course,
            course_data=CATALOGS.loc[course].to_dict()
        )
    return redirect(url_for('index'))

@app.route('/_get_tree/', methods=['POST'])
def _get_tree():
    # Used to generate trees for the 'Create Tree' page
    course = request.form['name'].upper().replace(' ', '')
    # SEARCHCOURSE is a flag indicating this request came from the search bar
    search_course = course.endswith('SEARCHCOURSE')
    course = course.replace('SEARCHCOURSE', '', 1)
    if re.search(r'[A-Z]+', course) and not re.search(r'\d{3}', course):
        if course in {c for v in UW_DEPARTMENTS.values() for c in v}:
            img = graph_department(
                CATALOGS[CATALOGS['Department Name'] == course],
                course,
                request.url_root
            ) if not search_course else course
        else:
            # ND -> Not a Department
            img = f'ND {course}'
    elif course in CATALOGS.index:
        if CATALOGS.loc[course, 'Prerequisites'] or CATALOGS.loc[course, 'Co-Requisites']:
            img = create_tree(CATALOGS, course, request.url_root) if not search_course else course
        else:
            # NP -> No Prerequisites
            img = f'NP {course}'
    else:
        # NA -> Not Available
        img = f'NA {course}' if course else ''
    return jsonify({'data': img})

@app.route('/_keyword_search/', methods=['POST'])
def _keyword_search():
    # Used for the case-insensitive keyword search
    keyword = request.form['keyword'].lower()
    lower = CATALOGS['Description'].str.lower()
    courses = CATALOGS[lower.str.contains(keyword, regex=False)].to_dict(orient='index')
    return jsonify({'matches': courses})

@app.route('/get_geocode/', methods=['POST'])
def get_geocode():
    return jsonify({'coords': GEOCODED})

@app.route('/check_course/', methods=['POST'])
def check_course():
    course = request.form['course'].upper().replace(' ', '')
    planned_course = None
    if re.search(r'[A-Z& ]+\d+ ?[A-Z]?', course):
        check_in = course if not course[-1].isalpha() else course[:-1]
        if check_in in TIME_SCHEDULE:
            planned_course = course
            check = True
            if course[-1].isalpha():
                planned_course = f'{course[:-1]} {course[-1]}'
                if course[:-1] in CATALOGS.index:
                    if course[:-1] in TIME_SCHEDULE:
                        check = f'Lecture {course[-1]}' in TIME_SCHEDULE[course[:-1]]
                    else:
                        check = False
                else:
                    check = False
            else:
                check = course in CATALOGS.index
        else:
            check = False
    else:
        check = False
    return jsonify({'data': check, 'name': planned_course})

course_options = None
@app.route('/create_schedule/', methods=['POST'])
def create_schedule():
    # Creates all possible schedules based on the courses entered by the user
    courses = request.form['course'].strip(',').split(',')
    global course_options
    course_options = get_combinations(courses)
    try:
        next_option = next(course_options)
    except StopIteration:
        next_option = None
    return jsonify({'option': next_option, 'coords': GEOCODED})

@app.route('/get_schedules/', methods=['POST'])
def get_schedules():
    # Cycles through course options
    global course_options
    try:
        next_option = next(course_options)
    except StopIteration:
        next_option = None
    return jsonify({'option': next_option, 'coords': GEOCODED})

@app.route('/keyword/')
def keyword():
    return render_template('keyword.html')

@app.route('/departments/', methods=['GET', 'POST'])
def departments():
    # Displays all departments at every UW Campus
    if request.method == 'POST':
        return redirect(url_for('index'))
    total = {}
    for campus in sorted(UW_DEPARTMENTS):
        total[campus] = {
            d: UW_DEPARTMENTS[campus][d] for d in sorted(UW_DEPARTMENTS[campus])
        }
    return render_template(
        'departments.html',
        department_dict=total,
        url=request.url_root
    )

@app.route('/geocode/')
def geocode():
    if 'Time_Schedules.json' not in os.listdir(PATH):
        check_schedules()
    return render_template('geocode.html')

@app.route('/<department>/')
def department(department):
    if request.method == 'POST':
        return redirect(url_for('index'))
    department = department.upper()
    if not re.search(r'[A-Z]+\d+', department):
        department_chosen = {}
        department = department.replace('&', '&')
        department_df = CATALOGS[CATALOGS['Department Name'] == department]
        svg = graph_department(department_df, department, request.url_root)
        if not department_df.empty:
            for dict_ in department_df.to_dict(orient='records'):
                department_chosen[f"{dict_['Department Name']}{dict_['Course Number']}"] = dict_
        return render_template(
            'department.html',
            course_dict=department_chosen,
            department_dict={c: d for v in UW_DEPARTMENTS.values() for c, d in v.items()},
            url=request.url_root,
            department=department,
            in_dict=bool(department_chosen),
            svg=svg
        )
    else:
        svg = create_tree(CATALOGS, department, request.url_root)
        in_dict = department in CATALOGS.index
        if in_dict:
            course_data = CATALOGS.loc[department].to_dict()
            split_course = re.compile(r'/|,|&&|;')
            for data in ['Prerequisites', 'Co-Requisites', 'Offered with']:
                course_data[data] = list(filter(
                    lambda x: x in CATALOGS.index and x != 'POI',
                    split_course.split(course_data[data])
                ))
        else:
            course_data = None
        return render_template(
            'course.html',
            svg=svg,
            course=department,
            course_data=course_data,
            in_dict=in_dict,
            url=request.url_root
        )

@app.route('/generate/')
def generate():
    return render_template('generate.html')

@app.route('/update_course_catalog/')
def update_course_catalog():
    uwtools.course_catalogs().to_csv(os.path.join(PATH, 'Course_Catalogs.csv'))
    return redirect(url_for('index'))

@app.route('/update_time_schedules/<quarter>/')
def update_time_schedules(quarter):
    year, q = quarter.split('#', 1)
    check_schedules(int(year), q.upper())
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=False)<file_sep>/README.md
# UW Course Planner

Web App with schedule visualization, recursive prerequisite tree generation and keyword search for courses offered at the University of Washington (UW).

Check out http://alexeidt.pythonanywhere.com/ for a live demo!

***

**Always make sure to check the actual prerequisites for any course before making a decision on which course to take!**

***

### Scripts

Script | Purpose
--- | ---
`app.py` | Runs the Flask Application on the localhost. Alternatively go to [alexeidt.pythonanywhere.com](http://alexeidt.pythonanywhere.com/) to see the same site.
`create_tree.py` | Creates Prerequisite Trees. Not runnable by itself.
`schedule.py` | Creates an Organized Time Schedule for the courses offered for the current quarter at UW.

#### UW Course Catalogs

 >[Bothell](http://www.washington.edu/students/crscatb/)
 [Seattle](http://www.washington.edu/students/crscat/)
 [Tacoma](http://www.washington.edu/students/crscatt/)

#### UW Time Schedules

 >[Bothell](https://www.uwb.edu/registration/time)
 [Seattle](https://www.washington.edu/students/timeschd/)
 [Tacoma](https://www.washington.edu/students/timeschd/T/)

### Prerequisite Tree

A prerequisite tree for any course offered at the UW can be created as a PNG file or in the console (see below).
The prerequisite tree for **EE235** as a PNG is shown below.

All courses at the same 'level' in the tree are the same color. Courses with the same shape at the end of the arrow
indicate that **ONE** of those courses is enough to statisfy the prerequisite requirement.

### Department Tree

A graph showing the prerequisite connections of all courses in the same department gives a good overview of the department as a whole.

### MyMap

The UW Course Tool can show you all combinations of course sections at UW that do not overlap. All three UW Campuses are included.

### Flask Application

There is an option to run this application on a server and to generate prerequisite trees on the web.
In order to run the `Flask` application on the localhost open the Command Line and `cd` into the directory where the application is stored. Once there input the following command:

```
python app.py
```

Then open the following link to access the website: http://127.0.0.1:5000/

Alternatively, go to the live demo at: [alexeidt.pythonanywhere.com](http://alexeidt.pythonanywhere.com/)

### Requirements/Dependencies

`Python 3.6+`

Install Requirements with

```
pip install -r requirements.txt
```

The directory for the application is structured according to the diagram below:
```
static
    Images
        Images used for website
    Prerequisite_Trees
        All generated Prerequisite Trees
    JavaScript
        All JavaScript files for each HTML file in 'templates'
    UW_Time_Schedules
        Organized_Time_Schedules
            All offered courses with quiz/lab/studio sections assigned to their respective lecture
        All Time Schedules for each UW Campus
templates
    All HTML files
```

***

In order for the visual representation with Graphviz to work, [Graphviz](https://graphviz.gitlab.io/download/) must be downloaded. Once downloaded go to `create_tree.py`. and change the System Path under `GRAPHVIZ PATH SETUP`
Make sure to add the `bin` folder of the downloaded Graphviz folder to the end of the system path.

```python
# --------------------------GRAPHVIZ PATH SETUP-------------------------- #
os.environ["PATH"] += os.pathsep + [FILE PATH TO GRAPHVIZ bin FOLDER]
# ----------------------------------------------------------------------- #
```

#### 'Graphviz Executables not on system Path' Error
If this error comes up try:
```
pip install graphviz
```
followed by:
```
conda install graphviz
```

If the error persists:

##### MAC
```
brew install graphviz
```
##### Ubuntu
```
sudo apt-get install graphviz
```
<file_sep>/static/JavaScript/keyword.js
$(document).ready(function() {
    var input = document.getElementById('keywordInput');
    input.addEventListener('keyup', function(event) {
        if (event.keyCode === 13) { // Enter Key
            event.preventDefault();
            document.getElementById('btn').click();
        }
    });
    $('button#btn').on('click', function() {
        var inputKey = $('#keywordInput').val();
        $.ajax({
            data: {
                keyword: inputKey,
            },
            url: "/_keyword_search/",
            type: "POST",
            beforeSend: function() {
                $('#btn').attr('disabled', true);
                $('span').addClass('spinner-border spinner-border-sm');
            },
        }).done(function(resp) {
            var root = window.location.protocol + '//' + window.location.host + '/';
            var table = document.getElementById('results');
            $("#results tbody tr").remove();
            var header = table.insertRow();
            header.insertCell().innerHTML = 'Course';
            header.insertCell().innerHTML = 'Course Name';
            header.insertCell().innerHTML = 'Campus';
            if (Object.keys(resp.matches).length > 0) {
                jQuery.each(resp.matches, function(course, courseData) {
                    var row = table.insertRow();
                    row.insertCell().innerHTML = '' + course + '';
                    row.insertCell().innerHTML = courseData['Course Name'];
                    row.insertCell().innerHTML = courseData.Campus;
                });
            } else {
                $("#results tbody tr").remove();
                var noresults = table.insertRow();
                var cell = noresults.insertCell();
                cell.colSpan = 3;
                cell.innerHTML = 'No Courses Found	';
            }
            $('#btn').attr('disabled', false);
            $('span').removeClass('spinner-border spinner-border-sm');
        });
    });
});<file_sep>/create_tree.py
"""
<NAME>

Creates a Prerequisite Tree Graph for any course at the University of Washington.
Creates Department course graphs showing connections between all courses in that department.
"""

import os
import re
from graphviz import Digraph

# Change PATH setup for Graphviz folder here:
# --------------------------GRAPHVIZ PATH SETUP------------------------- #
os.environ['PATH'] += os.pathsep + 'C:\\Graphviz\\bin'
# ---------------------------------------------------------------------- #

total = set()
REQUISITE_TYPES = ['Prerequisites', 'Co-Requisites']
PATH = os.path.join(os.getcwd(), 'static', 'Prerequisite_Trees')
SPLIT_COURSE = re.compile(r'/|,|&&')
ARROWHEADS = [
    'box', 'dot', 'normal', 'diamond', 'inv', 'tee', 'crow',
    'icurve', 'curve', 'vee', 'none'
]

def create_tree(course_df, course, url):
    """Starts the tree by adding the selected course as the top element
    @params
        'course_df': The DataFrame of courses
        'course': The course in question
        'url': URL of current webpage
    """
    file_path = os.path.join('..', 'static', 'Prerequisite_Trees', f'{course}.svg')
    if f'{course}.svg' in os.listdir(PATH):
        return file_path
    # Tree used to draw the course prerequisite tree
    tree = Digraph(
        comment=f'{course} Prerequisites',
        graph_attr={'rankdir': 'TB', 'splines': 'ortho', 'overlap': 'scale'},
        edge_attr={'arrowhead': 'dot', 'arrowsize': '0.8'},
    )
    course_df = course_df[course_df['Campus'] == course_df.loc[course, 'Campus']]
    prereqs = set(course_df.loc[course, REQUISITE_TYPES])
    splitted = list(filter(
        lambda x: x in course_df.index and x != 'POI',
        re.compile(r'/|,|&&|;').split(','.join(prereqs))
    ))
    if any(prereqs) and splitted and course in course_df.index:
        del splitted
        global total
        total.clear()
        tree.node(course, course, fontname='helvetica')
        tree.attr('node', shape='rectangle', style='filled', color='gray30', fontname='helvetica')
        # Recursively build up tree
        create_tree_helper(course_df, course, 0, tree, url)
        path = os.path.join(PATH, course)
        tree.render(path, view=False, format='svg')
        os.remove(path)
        return file_path
    return None

def create_tree_helper(course_df, course, level, tree, url):
    """Builds up the prerequisite tree
    @params
        'course_df': The DataFrame of courses
        'course': The course in question
        'level': The current level of the tree
        'tree': The tree being built
        'url': URL of the current webpage
    """
    if course not in total:
        total.add(course)
        for i, requisite_type in enumerate(REQUISITE_TYPES):
            for index, crs in enumerate(course_df.loc[course.replace('&', '&'), requisite_type].split(';')):
                for option in SPLIT_COURSE.split(crs):
                    if option and option != 'POI' and option in course_df.index:
                        option = option.replace('&', '&')
                        tree.attr(
                            'edge',
                            arrowhead=ARROWHEADS[index] if not i else f'o{ARROWHEADS[index]}',
                        )
                        tree.attr(
                            'node',
                            fillcolor=f'grey{99 - (level * 3)}' if not i else 'cyan',
                            URL=f'{url}{option}',
                            target="_blank"
                        )
                        tree.edge(course, option)
                        create_tree_helper(course_df, option, level + 1, tree, url)

def post_requisites(course_df, course, url):
    """Starts the tree by adding the selected course as the top element
    @params
        'course_df': The DataFrame of courses
        'course': The course in question
        'url': URL of current webpage
    """
    postreqs = {}
    post_requisites_helper(course_df, course, postreqs)

    # Tree used to draw the postrequisite tree
    tree = Digraph(
        comment=f'{course} Course Post Requisites',
        graph_attr={'rankdir': 'BT', 'splines': 'ortho', 'overlap': 'false'},
        edge_attr={'arrowhead': 'normal', 'arrowsize': '0.8'},
    )
    tree.attr('node', shape='rectangle', fontname='helvetica')

    for crs, postreq in postreqs.items():
        crs = crs.replace('&', '&')
        tree.attr('node', URL=f'{url}{crs}', target="_blank")
        tree.node(crs)
        for post in postreq:
            post = post.replace('&', '&')
            tree.attr('node', URL=f'{url}{post}', target="_blank")
            tree.edge(crs, post)

    path = os.path.join(PATH, f'{course}_POST')
    tree.render(path, view=False, format='svg')
    os.remove(path)
    return None

def post_requisites_helper(course_df, course, postreqs):
    # Get post-requisites
    mask = (course_df['Prerequisites'] != '') & (course_df['Prerequisites'] != 'POI')
    campus_mask = course_df['Campus'] == course_df.loc[course, 'Campus']
    postreqs_df = course_df[mask & campus_mask]['Prerequisites'].str.split(r'/|,|&&|;')
    postreqs_df = postreqs_df.apply(lambda x: set(filter(lambda y: y != 'POI', x)))
    post_requisites = postreqs_df[postreqs_df.apply(lambda x: course in x)].index

    if post_requisites.empty:
        return
    if course not in postreqs:
        postreqs[course] = set()
    postreqs[course].update(post_requisites)
    for postreq in post_requisites:
        post_requisites_helper(course_df, postreq, postreqs)

def graph_department(department_df, department, url):
    """Builds up the department prerequisite tree
    @params
        'department_df': The DataFrame of courses in the department
        'department': The department in question
        'url': URL of the current webpage
    """
    file_path = os.path.join('..', 'static', 'Prerequisite_Trees', f'{department}.svg')
    if f'{department}.svg' in os.listdir(PATH):
        return file_path

    course_prereqs = {}
    split_prereqs = re.compile(r'/|,|&&|;')
    for course in department_df.index:
        if course not in course_prereqs:
            course_prereqs[course] = set()
        for requisite_type in REQUISITE_TYPES:
            for prereq in split_prereqs.split(department_df.loc[course, requisite_type]):
                if prereq and ''.join(filter(lambda x: not x.isdigit() or x == '&', prereq)) == department and \
                    prereq in department_df.index:
                    course_prereqs[course].add(prereq)
        if not course_prereqs[course]:
            del course_prereqs[course]

    if not course_prereqs:
        return None

    # Tree used to draw the department tree
    tree = Digraph(
        comment=f'{department} Course Connections by Pre/Co-Requisites',
        graph_attr={'layout': 'dot', 'rankdir': 'LR', 'splines': 'true', 'overlap': 'false'},
        edge_attr={'arrowhead': 'normal', 'arrowsize': '0.6'},
    )
    tree.attr('node', shape='rectangle', fontname='helvetica')

    for course, prereqs in course_prereqs.items():
        course = course.replace('&', '&')
        tree.attr('node', URL=f'{url}{course}', target='_blank')
        tree.node(course)
        for prereq in prereqs:
            prereq = prereq.replace('&', '&')
            tree.attr('node', URL=f'{url}{prereq}', target='_blank')
            tree.node(prereq)
            tree.edge(course, prereq)

    path = os.path.join(PATH, department)
    tree.render(path, view=False, format='svg')
    os.remove(path)
    return file_path<file_sep>/static/JavaScript/layout.js
$(document).ready(function() {
    $('button#searchBtn').on('click', function() {
        var course = $('#courseSearch').val();
        course += ' SearchCourse';
        $.ajax({
            url: '/_get_tree/',
            type: 'POST',
            data: {
                name: course
            }
        }).done(function(resp) {
            if (resp.data.includes(' ') && (resp.data.startsWith('NA'))) {
                alert(resp.data.split(' ')[1] + ' is not a course offered at UW');
            } else if (resp.data.includes(' ') && resp.data.startsWith('ND')) {
                alert(resp.data.split(' ')[1] + ' is not a department at UW');
            } else if (resp.data.length > 0) {
                var searched = resp.data
                if (resp.data.includes(' ')) {
                    searched = searched.split(' ')[1];
                }
                var root = window.location.protocol + '//' + window.location.host + '/' + searched;
                window.open(root, '_top');
            }
        });
    });
});<file_sep>/static/JavaScript/generate.js
$(document).ready(function() {
    var input = document.getElementById('courseInput');
    input.addEventListener('keyup', function(event) {
        if (event.keyCode === 13) { // Enter Key
            event.preventDefault();
            document.getElementById('btn').click();
        }
    });
    $('img#tree').hide();
    $('button#btn').on('click', function() {
        var course = $('#courseInput').val();
        $.ajax({
            data: {
                name: course,
            },
            url: "/_get_tree/",
            type: "POST",
            beforeSend: function() {
                $('#btn').attr('disabled', true);
                $('span').addClass('spinner-border spinner-border-sm');
            },
        }).done(function(resp) {
            $('#btn').attr('disabled', false);
            var image = String(resp.data);
            if (image.endsWith('.svg')) {
                $('img#tree').attr('src', image);
                $('img#tree').show();
            } else if (image.length > 0) {
                var text = image.split(' ')[1];
                if (image.startsWith('NA')) {
                    alert(`${text} is not a course offered at UW`);
                } else if (image.startsWith('NP')) {
                    alert(`${text} has no Prerequisites`);
                } else if (image.startsWith('ND')) {
                    alert(`${text} is not a Department`);
                } else {
                    alert(`${text} not found`)
                }
            }
            $('span').removeClass('spinner-border spinner-border-sm');
        });
    });
});<file_sep>/schedule.py
"""
<NAME>

Finds all combinations of classes given a list of courses to search.
"""

from json import dump, loads
from re import search as re_search
from os import path, getcwd
from itertools import chain, combinations, product, filterfalse
from time import strftime, strptime
import uwtools

# --------------------------Time Methods--------------------------#
get_time = lambda t: [t[0:1], t[1:]] if len(t) == 3 else [t[0:2], t[2:]]
check_pm = lambda t: ' PM' if t else ' AM'
convert = lambda t: strftime('%H:%M:%S', strptime(t, '%I:%M %p'))
check_convert_pm = lambda t: convert('12:01 AM') < convert(t) < convert('6:30 AM') or convert('10:30 PM') < convert(t) < convert('11:59 PM')
convert_pm = lambda t, pm: f'{pm[0]} {switch_pm(pm[-1])}' if check_convert_pm(t) else t
switch_pm = lambda t: 'AM' if t.strip() == 'PM' else 'PM'
# --------------------------Time Methods--------------------------#

def has_overlap(time1, time2):
    """Checks if the two times overlap
    @params
        'time1': First time to check
        'time2': Second time to check
    Returns
        True if there is overlap, otherwise False
    """
    pm1 = 'P' in time1
    pm2 = 'P' in time2
    time1 = time1.replace('P', '', 1)
    time2 = time2.replace('P', '', 1)
    times = list(chain(time1.split('-', 1), time2.split('-', 1)))
    times = list(map(get_time, times))
    course_times = []
    for i in range(0, len(times), 2):
        pm = pm1 if not i else pm2
        t1 = f'{times[i][0]}:{times[i][1]}{check_pm(pm)}'
        t2 = f'{times[i + 1][0]}:{times[i + 1][1]}{check_pm(pm)}'
        time1 = convert(convert_pm(t1, t1.rsplit(' ', 1)))
        time2 = convert(convert_pm(t2, t2.rsplit(' ', 1)))
        course_times.append((time1, time2))
    t1 = course_times[0]
    return t1[0] <= course_times[1][0] <= t1[1] or t1[0] <= course_times[1][1] <= t1[1]

def get_days(offered):
    """Gets the days a course is offered
    @params
        'offered': String representing the days a course is offered
        Example: 'MWF' -> Monday, Wednesday, Friday
    Returns
        Set of abbreviated days the course is offered
    """
    days = ['Th', 'M', 'T', 'W', 'F', 'S']
    result = set()
    for day in days:
        if day in offered:
            result.add(day)
            offered = offered.replace(day, '', 1)
    return result

def check_overlap(schedule):
    """Checks if the courses in the 'schedule' overlap
    @params
        'schedule': List of dictionaries representing a combination of courses
    Returns
        True if there is overlap between any sections in the 'schedule'.
        False otherwise.
    """
    course_information = {
            'M': [], 'T': [], 'W': [], 'Th': [], 'F': [], 'S':[]
    }
    for course in schedule:
        for course_dict in course:
            for i, d in enumerate(course_dict['Days']):
                for day in get_days(d):
                    course_information[day].append(course_dict['Time'][i])
    for times in course_information.values():
        if len(set(times)) == len(times):
            date_combos = list(combinations(times, 2))
            dates = [list(set(x)) for x in date_combos if len(set(x)) > 1]
            for date in dates:
                if has_overlap(date[0], date[1]):
                    return True
        else:
            return True
    return False

def get_combinations(planned_courses):
    """Finds all possible combinations of the courses in 'planned_courses'
    such that no sections of any course overlap
    @params
        'planned_courses': List of courses to find combinations from
    Returns
        Generator object with all valid combinations of courses
    """
    with open(path.join(getcwd(), 'static', 'Time_Schedules.json'), mode='r') as f:
        courses_offered = loads(f.read())
    total = []
    for course in planned_courses:
        course_sections = []
        lecture = course.rsplit(' ', 1)[-1].strip().upper()
        if re_search(r'[A-Z]\d?', lecture) and ' ' in course:
            search = [courses_offered[course.rsplit(' ', 1)[0]][f'Lecture {lecture}']]
        else:
            search = courses_offered[course].values()
        # Get all Lecture/Quiz/Lab/Studio combinations for the given course
        for section in search:
            products = []
            for section_type in ['QZ', 'LB', 'ST']:
                if section[section_type]:
                    products.append(section[section_type])
            products.append([section['LECT']])
            course_sections.append(list(product(*products)))
        total.append([y for x in course_sections for y in x])
    # Find all course combinations where there are no course overlaps
    for combo in filterfalse(lambda x: check_overlap(x), product(*total)):
        yield combo

# Sections class used for the organized Time Schedule
class Sections:
    def __init__(self):
        self.LECT = ''
        self.QZ = []
        self.LB = []
        self.ST = []

    def add_section(self, section_type, data):
        if section_type == 'QZ':
            s_type = self.QZ
        elif section_type == 'LB':
            s_type = self.LB
        elif section_type == 'ST':
            s_type = self.ST
        else:
            return

        # Check if Section is already in the list for that section type.
        # For some courses, such as CHEM142 on the Seattle Campus, the Quiz and Lab Section
        # are grouped in the same section. This is why the 'Building', 'Days', 'Room Number',
        # 'Seats', and 'Time' sections are represented as lists.
        for section in s_type[::-1]:
            if section['Section'] == data['Section']:
                break
        else:
            for section_data in ['Building', 'Days', 'Room Number', 'Seats', 'Time']:
                data[section_data] = [data[section_data]]
            s_type.append(data)
            return

        for section in s_type:
            if section['Section'] == data['Section']:
                for section_data in ['Building', 'Days', 'Room Number', 'Seats', 'Time']:
                    section[section_data].append(data[section_data])

def main(year, quarter):
    """Creates an Organized Time Schedule as a json file with all courses from
    all UW Campuses included for the current UW Quarter.
    Organized Time Schedules include the Course as the Key. The associated value to
    this key are all the lectures for this course with quiz, lab and studio sections
    included as a list.

    @params
        'year': Year of Quarter to get time schedules from.
        'quarter': Quarter to get time schedules from.
    """
    section_times = ['Building', 'Days', 'Room Number', 'Seats', 'Time']

    # Replace 'year' and 'quarter' with the values for the quarter you'd like to parse.
    # Make sure that quarter's time schedules are available.
    df = uwtools.time_schedules(year, quarter, json_ready=True, struct='dict')

    # Create a dictionary with Course Names (i.e EE235) as keys and a list of course sections
    # (as dictionaries) as values.
    total = {}
    for dict_ in df:
        # Check if a building exists for the section
        if dict_['Building'] and dict_['Room Number']:
            course_name = dict_['Course Name']
            if course_name not in total:
                total[course_name] = []
            total[course_name].append(dict_)

    # Create a dictionary with course names (i.e EE235) as keys.
    # The value for every key is another dictionary with Lectures as keys (i.e Lecture A).
    # These lecture keys have another dictionary with section types as keys (LECT, QZ, LB, ST).
    # The LECT key has the information for the lecture, every other key has a list as a value with
    # dictionaries representing every QZ/LB/ST section for that lecture.
    course_map = {}
    for course, course_list in total.items():
        section_map = {}
        for section in course_list:
            section_type = section['Type']
            if section_type == 'LECT':
                course_sections = Sections()
                for section_data in section_times:
                    section[section_data] = [section[section_data]]
                course_sections.LECT = section
                section_map[f"Lecture {section['Section']}"] = course_sections.__dict__
            else:
                course_sections.add_section(section_type, section)
        if section_map:
            course_map[course] = section_map

    # Store these Organized Time Schedules as a .json file
    with open(path.join(getcwd(), 'static', 'Time_Schedules.json'), mode='w') as f:
        dump(course_map, f, indent=4, sort_keys=True)

if __name__ == '__main__':
    year = input('Year: ')
    quarter = input('Quarter: ')
    main(int(year), quarter.upper())

languages: Markdown JavaScript Python

repo_name: AlexEidt/UW-Course-Planner


text:
<file_sep># semantic-rs

[![Build Status](https://travis-ci.org/semantic-rs/semantic-rs.svg?branch=master)](https://travis-ci.org/semantic-rs/semantic-rs)

The purpose of this tool is to help people to publish crates following the [semver](http://semver.org/) specification.

Right now if you're building a new crate publishing new versions includes a high amount of work. You need to decide if the new version will be either a new Major, Minor or Patch version. If that decision is made, the next step is to write a changelog with all the things changed. Then increase the version in `Cargo.toml`. Make a commit and a new tag for the new version and lastly publish it to crates.io.
If you need to repeat these steps every time, chances are high you make mistakes.
semantic-rs automates all these steps for you so you can focus more on developing new features instead.

## Workflow

- Install semantic-rs on your machine.
- Follow the [Angular.js commit message conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit?pref=2&pli=1) when you commit changes to your repository
- When you're done with development, run semantic-rs
- Based on your changes it determines the next version number, generates a changelog, commits it and creates a new tag
- Done.

## Usage

If you run semantic-rs without any arguments, it operates on your current working directory:

```bash
$ semantic-rs
semantic.rs 🚀
Analyzing your repository
Current version: 0.5.0
Analyzing commits
Commits analyzed. Bump would be Minor
New version would be: 0.6.0
Would write the following Changelog:
====================================
## v0.6.0 (2016-01-30)

#### Features

*   Improve user interface ([497485a0](497485a0))

====================================
Would create annotated git tag
```

By default it runs in dry-run mode. This means it doens't perform changes automatically. You see which changes would be performed and also the resulting changelog.

To perform the changes, pass `-w` as an argument:

```bash
$ semantic-rs -w
semantic.rs 🚀
Analyzing your repository
Current version: 0.5.0
Analyzing commits
Commits analyzed. Bump will be Minor
New version: 0.6.0
Writing Changelog
Creating annotated git tag
```
This performs the following operations:
- Create or update `Changelog.md` containing everything that changed
- Create a new commit containing the following changes:
  - `Changelog.md`
  - An updated `Cargo.toml` with the new version number
- Create a new annotated git tag pointing to the last commit created recently and including the Changelog for the new version

Note that commits and tags are created with your configured git user and email.

## Development

Requirements:
- cmake
- OpenSSL development package
  - Ubuntu: `libssl-dev`
  - Mac Homebrew: `openssl`
- Rust 1.5

Clone this project:

```bash
$ git clone git@github.com:semantic-rs/semantic-rs.git
```

You can run semantic-rs by calling:

```bash
$ cargo run
```

This analyzes the current git repository and updates the project's `Cargo.toml`.

## Run semantic-rs in CI environment

Make sure to set the `CI=true` environment variable to disable dry-run mode.

## Contributing

Bug reports and pull requests are welcome on [GitHub](https://github.com/semantic-rs/semantic-rs).
You can find more information about contributing in the [CONTRIBUTING.md](https://github.com/semantic-rs/semantic-rs/blob/master/CONTRIBUTING.md).
This project is intended to be a safe, welcoming space for collaboration and discussion, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org/) code of conduct.

## License

This project is licensed under the MIT license.
<file_sep>#![cfg_attr(feature = "dev", allow(unstable_features))]
#![cfg_attr(feature = "dev", feature(plugin))]
#![cfg_attr(feature = "dev", plugin(clippy))]

mod logger;
mod toml_file;
mod git;
mod changelog;
mod commit_analyzer;
mod cargo;
mod error;
mod github;
mod config;

extern crate rustc_serialize;
extern crate toml;
extern crate regex;
extern crate semver;
extern crate docopt;
extern crate git2;
extern crate clog;
extern crate hyper;
extern crate hubcaps;
extern crate url;

use docopt::Docopt;
use commit_analyzer::CommitType;
use config::ConfigBuilder;
use std::process;
use semver::Version;
use std::{env,fs};
use std::path::Path;
use std::error::Error;
use url::Url;

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USERAGENT: &'static str = concat!("semantic-rs/", env!("CARGO_PKG_VERSION"));
const USAGE: &'static str = "
semantic.rs 🚀

Usage:
  semantic-rs [options]
  semantic-rs --version

Options:
  -h --help              Show this screen.
  --version              Show version.
  -p PATH, --path=PATH   Specifies the repository path. [default: .]
  -w, --write            Run with writing the changes afterwards.
  -r <r>, --release=<r>  Create release on GitHub and publish on crates.io (only in write mode) [default: yes]
  -b <b>, --branch=<b>   The branch on which releases should happen. [default: master]
";

macro_rules! print_exit {
    ($fmt:expr) => {{
        logger::stderr(format!($fmt));
        process::exit(1);
    }};
    ($fmt:expr, $($arg:tt)*) => {{
        logger::stderr(format!($fmt, $($arg)*));
        process::exit(1);
    }};
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_path: String,
    flag_write: bool,
    flag_version: bool,
    flag_release: String,
    flag_branch: String,
}

fn string_to_bool(answer: &str) -> bool {
    match &answer.to_lowercase()[..] {
        "yes" | "true" | "1" => true,
        "no" | "false" | "0" => false,
        _ => false
    }
}

fn version_bump(version: &Version, bump: CommitType) -> Option<Version> {
    let mut version = version.clone();
    match bump {
        CommitType::Unknown => return None,
        CommitType::Patch => version.increment_patch(),
        CommitType::Minor => version.increment_minor(),
        CommitType::Major => version.increment_major(),
    }

    Some(version)
}

fn ci_env_set() -> bool {
    env::var("CI").is_ok()
}

fn user_repo_from_url(url: Url) -> Result<(String, String), String> {
    let path = match url.path() {
        Some(path) => path,
        None => return Err("URL should contain user and repository".into()),
    };

    let user = path[0].clone();
    let repo = match path[1].rfind(".git") {
        None => path[1].clone(),
        Some(suffix_pos) => {
            let valid_pos = path[1].len() - 4;
            if valid_pos == suffix_pos {
                let path = &path[1][0..suffix_pos];
                path.into()
            } else {
                return Err("URL does not point to a git repository".into())
            }
        }
    };

    Ok((user, repo))
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let mut cb = ConfigBuilder::new();

    if args.flag_version {
        println!("semantic.rs 🚀 -- v{}", VERSION);
        process::exit(0);
    }

    let is_dry_run = if ci_env_set() {
        false
    }
    else {
        !args.flag_write
    };

    let release_mode = string_to_bool(&args.flag_release);

    cb.write(args.flag_write);
    cb.release(release_mode);
    cb.branch(args.flag_branch);

    println!("semantic.rs 🚀");

    logger::stdout("Analyzing your repository");
    let path = Path::new(&args.flag_path);
    let path = fs::canonicalize(path)
        .unwrap_or_else(|_| print_exit!("Path does not exist or a component is not a directory"));
    let repository_path = path.to_str()
        .unwrap_or_else(|| print_exit!("Path is not valid unicode"));

    let repo = match git2::Repository::open(repository_path) {
        Ok(repo) => repo,
        Err(e) => {
            logger::stderr(format!("Could not open the git repository: {:?}", e));
            process::exit(1);
        }
    };

    cb.repository_path(repository_path.to_owned());

    // extra scope scope to make sure borrow of `repo` is dropped
    {
        let signature = match git::get_signature(&repo) {
            Ok(sig) => sig,
            Err(e) => {
                logger::stderr(format!("Failed to get the committer's name and email address: {}", e.description()));
                logger::stderr(r"
A release commit needs a committer name and email address.
We tried fetching it from different locations, but couldn't find one.

Committer information is taken from the following environment variables, if set:

GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL

If none is set the normal git config is tried in the following order:

Local repository config
User config
Global config");
                process::exit(1);
            }
        };

        cb.signature(signature.to_owned());
    }

    // In case we are in write-mode AND release mode,
    // we will make sure we got all configuration settings
    if !is_dry_run && release_mode {
        let remote_url = match repo.find_remote("origin") {
            Err(e) => print_exit!("Could not determine the origin remote url: {:?}", e),
            Ok(remote) => {
                let url = remote.url().expect("Remote URL is not valid UTF-8");
                Url::parse(&url).expect("Remote URL can't be parsed")
            }
        };

        let (user, repo_name) = user_repo_from_url(remote_url)
            .unwrap_or_else(|e| print_exit!("Could not extract user and repository name from URL: {:?}", e));
        cb.user(user);
        cb.repository_name(repo_name);

        let gh_token = env::var("GH_TOKEN")
            .unwrap_or_else(|err| print_exit!("GH_TOKEN not set: {:?}", err));

        let cargo_token = env::var("CARGO_TOKEN")
            .unwrap_or_else(|err| print_exit!("CARGO_TOKEN not set: {:?}", err));

        cb.gh_token(gh_token);
        cb.cargo_token(cargo_token);
    }

    cb.repository(repo);
    let config = cb.build();

    let version = toml_file::read_from_file(&config.repository_path)
        .unwrap_or_else(|err| print_exit!("Reading `Cargo.toml` failed: {:?}", err));

    let version = Version::parse(&version).expect("Not a valid version");
    logger::stdout(format!("Current version: {}", version.to_string()));

    logger::stdout("Analyzing commits");

    let bump = git::version_bump_since_latest(&config.repository);
    if is_dry_run {
        logger::stdout(format!("Commits analyzed. Bump would be {:?}", bump));
    }
    else {
        logger::stdout(format!("Commits analyzed. Bump will be {:?}", bump));
    }
    let new_version = match version_bump(&version, bump) {
        Some(new_version) => new_version.to_string(),
        None => {
            logger::stdout("No version bump. Nothing to do.");
            process::exit(0);
        }
    };

    if is_dry_run {
        logger::stdout(format!("New version would be: {}", new_version));
        logger::stdout("Would write the following Changelog:");
        let changelog = match changelog::generate(repository_path, &version.to_string(), &new_version) {
            Ok(log) => log,
            Err(err) => {
                logger::stderr(format!("Generating Changelog failed: {:?}", err));
                process::exit(1);
            }
        };
        logger::stdout("====================================");
        logger::stdout(changelog);
        logger::stdout("====================================");
        logger::stdout("Would create annotated git tag");
    }
    else {
        logger::stdout(format!("New version: {}", new_version));

        toml_file::write_new_version(repository_path, &new_version)
            .unwrap_or_else(|err| print_exit!("Writing `Cargo.toml` failed: {:?}", err));

        logger::stdout(format!("Writing Changelog"));
        changelog::write(repository_path, &version.to_string(), &new_version)
            .unwrap_or_else(|err| print_exit!("Writing Changelog failed: {:?}", err));

        if config.release_mode {
            logger::stdout("Updating lockfile");
            if !cargo::update_lockfile(repository_path) {
                print_exit!("`cargo fetch` failed. See above for the cargo error message.");
            }
        }

        logger::stdout("Package crate");
        if !cargo::package(repository_path) {
            print_exit!("`cargo package` failed. See above for the cargo error message.");
        }

        git::commit_files(&config, &new_version)
            .unwrap_or_else(|err| print_exit!("Committing files failed: {:?}", err));

        logger::stdout("Creating annotated git tag");
        let tag_message = changelog::generate(repository_path, &version.to_string(), &new_version)
            .unwrap_or_else(|err| print_exit!("Can't generate changelog: {:?}", err));

        let tag_name = format!("v{}", new_version);
        git::tag(&config, &tag_name, &tag_message)
            .unwrap_or_else(|err| print_exit!("Failed to create git tag: {:?}", err));

        if config.release_mode {
            logger::stdout("Pushing new commit and tag");
            git::push(&config, &tag_name)
                .unwrap_or_else(|err| print_exit!("Failed to push git: {:?}", err));

            logger::stdout("Creating GitHub release");
            github::release(&config, &tag_name, &tag_message)
                .unwrap_or_else(|err| print_exit!("Failed to create GitHub release: {:?}", err));

            logger::stdout("Publishing crate on crates.io");
            if !cargo::publish(&config.repository_path, &config.cargo_token.as_ref().unwrap()) {
                print_exit!("Failed to publish on crates.io");
            }

            println!("{} v{} is released. 🚀🚀🚀", config.repository_name, new_version);
        }
    }
}
<file_sep>[package]
name = "semantic-rs"
version = "0.1.0"
authors = ["<NAME> <<EMAIL>>", "<NAME> <<EMAIL>>"]
description = "Automatic crate publishing"
license = "MIT"

[dependencies]
term = "0.2"
toml = "0.1"
regex = "0.1"
semver = "0.2.1"
docopt = "0.6.78"
rustc-serialize = "0.3.16"
git2 = "0.4.2"
clog = { git = "https://github.com/clog-tool/clog-lib.git" }
hubcaps = "0.2"
hyper = "0.7"
url = "0.5"
clippy = {version = "<0.1.0", optional = true}

[features]
default = []
dev = ["clippy"]
<file_sep>use hyper::Client;
use hubcaps::{Github, ReleaseOptions, Credentials};
use error::Error;
use super::USERAGENT;
use config::Config;

pub fn release(config: &Config, tag_name: &str, tag_message: &str) -> Result<(), Error> {
    let user      = &config.user[..];
    let repo_name = &config.repository_name[..];
    let branch    = &config.branch[..];
    let token     = config.gh_token.as_ref().unwrap();

    let client = Client::new();
    let credentials = Credentials::Token(token.to_owned());
    let github = Github::new(USERAGENT, &client, credentials);

    let opts = ReleaseOptions::builder(tag_name)
        .name(tag_name)
        .body(tag_message)
        .commitish(branch)
        .draft(false)
        .prerelease(false)
        .build();

    let repo = github.repo(user, repo_name);
    let release = repo.releases();

    release
        .create(&opts)
        .map(|_| ())
        .map_err(Error::from)
}
<file_sep>version: 1.0.{build}
os:
  - Visual Studio 2015
clone_depth: 1
configuration:
  - Debug
platform:
  - Win32
  - x64
environment:
  OPENSSL_INCLUDE_DIR: C:\OpenSSL\include
  OPENSSL_LIB_DIR: C:\OpenSSL\lib
  OPENSSL_LIBS: ssleay32:libeay32

  matrix:
    - TOOLCHAIN_VERSION: 14.0
      RUST: 1.7.0

build_script: mk/appveyor.bat
<file_sep>language: rust
sudo: required
dist: trusty
addons:
  apt:
    packages:
      - libcurl4-openssl-dev
      - libelf-dev
      - libdw-dev

# run builds for both all the trains
rust:
  - stable
  - beta
  - nightly

before_script:
  - |
      pip install git+https://github.com/huonw/travis-cargo --user &&
      git clone https://github.com/sstephenson/bats/ &&
      export WORKSPACE=$HOME/workspace &&
      mkdir $WORKSPACE &&
      cp -ar $TRAVIS_BUILD_DIR/tests/integration/fixtures/* $WORKSPACE &&
      export PATH=$HOME/.local/bin:$(pwd)/bats/bin:$TRAVIS_BUILD_DIR/target/debug:$PATH &&
      git config --global user.name semantic-rs &&
      git config --global user.email semantic@rs

script:
  - |
      travis-cargo build &&
      travis-cargo test &&
      pushd tests/integration && bats integration.bats && popd &&
      travis-cargo --only stable doc
after_success:
  - travis-cargo coveralls --no-sudo

env:
  global:
    - TRAVIS_CARGO_NIGHTLY_FEATURE=""

notifications:
  email: false
<file_sep>#!/bin/bash

set -e

cd $(dirname $(readlink -f $0))

export WORKSPACE=$(readlink -f ../../..)/workspace

git clone https://github.com/sstephenson/bats/ || true
export PATH=$(pwd)/bats/bin:$(readlink -f ../../target/debug):$PATH

rm -rf $WORKSPACE
mkdir $WORKSPACE
cp -ar fixtures/* $WORKSPACE

bats integration.bats

languages: TOML Shell Markdown Rust YAML

repo_language: TOML

repo_name: badboy/semantic-rs-win


text:
<repo_name>dan909/WirelessHouseMonitors<file_sep>/GetSerial.py
import serial
import time
import csv

sercon = serial.Serial("COM4",9600)

while True:
    received = sercon.readline().strip()
    received = received.split("_")
    datetime = time.strftime("%Y-%m-%d %H:%M:%S")
    received.append(datetime)
    #print received

    if received[0][0] == '!':
        #print "started"
        #print "sensor " + received[0][2] + " restarted at " + datetime
        with open("Log.txt", 'a') as logfile:
            logfile.write("sensor " + received[0][2] + " restarted at " + datetime + "\n")

    elif len(received) == 4:
        if received[0][0] is not "N":
            with open("SensorLog.csv", 'ab') as csvfile:
                filewrite = csv.writer(csvfile, delimiter=",")
                filewrite.writerow(received)

    #print "Done"
<file_sep>/WirelessHouseMonitor/WirelessHouseMonitor.ino
char devise[2] = {"0"}; //Devise no
# define SLEEP 10 // leanth of time to sleep in minits

#include "DHT.h"
#include <VirtualWire.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

DHT dht;
char reading[12];
volatile int wakeCount = 0;

void setup()
{
  dht.setup(0); // data pin 0

  MCUSR &= ~(1<<WDRF);
  WDTCR |= (1<<WDCE) | (1<<WDE);
  WDTCR = 1<<WDP0 | 1<<WDP3;
  WDTCR |= _BV(WDIE);

  vw_set_ptt_inverted(true);  // Required by the RF module
  vw_setup(2000);            // bps connection speed
  vw_set_tx_pin(1);         // Arduino pin to connect the receiver data pin

  //send startup
  char sensor[3] = {"!#"};
  strcat(reading, sensor);
  strcat(reading, devise);
  vw_send((uint8_t *)reading, strlen(reading));
  vw_wait_tx();        // We wait to finish sending the message
  delay(200);         // We wait to send the message again

  pinMode(2, INPUT);
}

void loop(){

  char sensor[4] = {"_#_"};

  if(wakeCount == (SLEEP*60)/8) {
  //if(wakeCount == 2) { //For testing only

    float humid = dht.getHumidity();
    dtostrf(humid, 3, 1, reading);
    sensor[1] = 'H';
    strcat(reading, sensor);
    strcat(reading, devise);
    //Message to send:
    //const char *msg = reading;
    vw_send((uint8_t *)reading, strlen(reading));

    vw_wait_tx();        // We wait to finish sending the message
    delay(200);         // We wait to send the message again

    float temp = dht.getTemperature();
    dtostrf(temp, 3, 1, reading);
    sensor[1] = 'T';
    strcat(reading, sensor);
    strcat(reading, devise);
    //Message to send:
    //const char *msg = reading;
    vw_send((uint8_t *)reading, strlen(reading));

    vw_wait_tx();        // We wait to finish sending the message
    delay(200);         // We wait to send the message again

    float light = (analogRead(1)/1024.0)*100;
    dtostrf(light, 3, 1, reading);
    sensor[1] = 'L';
    strcat(reading, sensor);
    strcat(reading, devise);

    //Message to send:
    //const char *msg = reading;
    vw_send((uint8_t *)reading, strlen(reading));

    vw_wait_tx();        // We wait to finish sending the message
    delay(200);         // We wait to send the message again

    wakeCount = 0;
  }

  goToSleep();
}

ISR(WDT_vect) {
  wakeCount = wakeCount + 1;
}

void goToSleep(void) {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  sleep_disable();

  power_all_enable();
}

<file_sep>/README.md
# WirelessHouseMonitors
A simple wireless house house for Temp, RH, and Light, to be graphed and emailed.

Using AtTiny85 chips and their digispark version.

Monitoring with DHT11 or DHT22 sensors, and LDR light readings.

In a CNC Box. Using wireless radio signals.

Transmitting back to a base arduino nano connected to a RasPI.

languages: Markdown C++ Python


text:
<file_sep># style
CSS parser, with questionable code.
<file_sep>export default function CSSToConfig() {
    // const whitespace = /[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
    const aroundWhitespaces = /[\s\uFEFF\xA0]+[^*#.\w!-{}]|[\s\uFEFF\xA0]+$/gi;
    const importQuery = /@import .*?/gi;
    const supportQuery = /((@supports [\s\S]*?){([\s\S]*?}\s*?)})/gi;
    const commentQuery = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gi;
    const cssQuery = /([\s\S]*?){([\s\S]*?)}{1,2}/gi;
    const selectorQuery = /([\s\S]*?){([\s\S]*?)}/gi;
    const ruleCaseQuery = /-([a-zA-Z])/gi;

    // const supportStatements = [];

    this.init = function() {
        String.prototype.trimWhitespace = function() {
            return this.replace(aroundWhitespaces, '');
        };
        String.prototype.convertToRuleCase = function() {
            return this.replace(ruleCaseQuery, m => m[1].toUpperCase());
        }
    };
    this.init();
    let isEmpty = function (arg) {
        return typeof arg == 'undefined' || arg.length === 0 || !arg;
    };
    let parseStyle = (rules) => {
        let split = rules.split(';').filter(Boolean);
        let temp = {};
        split.map((rule) => rule.split(':')).map(arr => { if (arr[0] && arr[1]) return temp[arr[0].convertToRuleCase()] = arr[1].trim(); else return null; });
        return temp;
    };
    let parseMedia = (rules) => {
        let css = [];
        let ind = rules.indexOf('{');
        let end = rules.lastIndexOf('}');
        rules = rules.substring(ind+1, end);
        while(true) {
            let arr = selectorQuery.exec(rules);
            if (arr === null) break;

            css.push({ selector: arr[1].trim(), style: parseStyle(arr[2]) });
        }
        return css;
    };
    let stripComments = (css) => {
        return css.replace(commentQuery, '');
    };
    let stripImports = (css) => {
        return css.replace(importQuery, '');
    };
    let stripSupports = (css) => {
        return css.replace(supportQuery, '');
    };

    let clear_out = (css) => {
        css = css.trimWhitespace();
        css = stripComments(css);
        css = stripImports(css);
        css = stripSupports(css);
        return css;
    };

    this.toJSON = (contents, args) => {
        let t0 = performance.now();
        if (!contents) return [];
        contents = clear_out(contents);

        let css = [];
        let mediaStart;
        let mediaEnd;
        let mediaArr;
        while (true) {
            let arr = cssQuery.exec(contents);
            if (arr === null) break;

            const mediaFlag = arr[0].startsWith('@media');

            if (mediaFlag) {
                mediaStart = arr.index;
                mediaArr = arr[0].substring(0, arr[0].indexOf('{'));
            } else if (arr[0].endsWith('}}')) {
                mediaEnd = cssQuery.lastIndex;
            }
            if (mediaStart && mediaEnd && (mediaStart !== mediaEnd)) {
                css.push({ selector: mediaArr.trim(), style: parseMedia(contents.slice(mediaStart, mediaEnd))});
                mediaStart = undefined;
                mediaEnd = undefined;

            } else if (arr[2] !== '' && !mediaFlag) {
                css.push({ selector: arr[1].trim(), style: parseStyle(arr[2]) });
            }
        }
        let t1 = performance.now();
        console.log('Execution took: ' + (t1-t0) + 'ms');
        return css;
    };

    return this;
};

languages: Markdown JavaScript

repo_name: ravuy/css-parser