├── .deepsource.toml ├── .github ├── FUNDING.yml └── workflows │ └── pytest.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── Contribution.md ├── DOCKER_DEPLOYMENT.md ├── Dockerfile ├── HOW_TO_USE.md ├── LICENSE ├── Makefile ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── TROUBLESHOOTING.md ├── assets ├── first_issues_round.png └── kite-logo.png ├── conftest.py ├── cron.sh ├── data └── example.json ├── entrypoint.sh ├── first_timers ├── __init__.py ├── first_timers.py └── run.py ├── requirements.txt ├── run.sh └── tests ├── __init__.py └── test_basic.py /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "test-coverage" 5 | enabled = true 6 | 7 | [[analyzers]] 8 | name = "javascript" 9 | enabled = true 10 | 11 | [[analyzers]] 12 | name = "python" 13 | enabled = true 14 | 15 | [analyzers.meta] 16 | runtime_version = "3.x.x" 17 | 18 | [[transformers]] 19 | name = "prettier" 20 | enabled = true 21 | 22 | [[transformers]] 23 | name = "standardjs" 24 | enabled = true 25 | 26 | [[transformers]] 27 | name = "autopep8" 28 | enabled = true -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: arshadkazmi42 2 | -------------------------------------------------------------------------------- /.github/workflows/pytest.yml: -------------------------------------------------------------------------------- 1 | name: Python CI 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | test-py37-py38: 9 | name: Testing with python37 and python 38 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | python-version: ["3.7", "3.8"] 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Set up Python ${{ matrix.python-version }} 18 | uses: actions/setup-python@v4 19 | with: 20 | python-version: ${{ matrix.python-version }} 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install pytest 25 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 26 | - name: Test with pytest 27 | run: | 28 | pytest 29 | 30 | test-py36: 31 | name: Testing with py36 and ubunto 20 32 | runs-on: ubuntu-20.04 33 | steps: 34 | - uses: actions/checkout@v3 35 | - name: setup python 3.6 36 | uses: actions/setup-python@v4 37 | with: 38 | python-version: "3.6" 39 | - name: Install dependencies 40 | run: | 41 | python -m pip install --upgrade pip 42 | pip install pytest 43 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 44 | - name: Test with pytest 45 | run: | 46 | pytest 47 | 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | 64 | credentials.json 65 | data/db.json 66 | 67 | # virtual env 68 | venv 69 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at our [Twitter](https://twitter.com/first_issues) and [Telegram](https://t.me/firstissues). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /Contribution.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | ### Thanks, for considering to contribute to this repository! 4 | 5 | You can contribute to this repository by either solving an issue or suggesting improvements/changes in the code. 6 | 7 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. 8 | 9 | To start contributing, follow the steps below 10 | 11 | - Fork the repo 12 | - Clone the repo 13 | - Create a branch using `git checkout -b feature-branch` 14 | - Make the required changes 15 | - Create a pull request using below commands 16 | - `git add --all` 17 | - `git commit -m "your commit message"` 18 | - `git push origin feature-branch` 19 | - Go to [Repository](https://github.com/arshadkazmi42/first-issues/) 20 | - Create Pull Request against `master` branch 21 | - Add a suitable title and description to the pull request and tag the issue number in Pull Request description, if the pull request is related to some issue logged here: [Issues](https://github.com/arshadkazmi42/first-issues/issues) 22 | - You're done. Wait for your code to get reviewed and merged. 23 | - Optional: Give us a :star: if you like our work. 24 | -------------------------------------------------------------------------------- /DOCKER_DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | ## DOCKER DEPLOYMENT 2 | 3 | - Clone the repository 4 | - Go to project root directory 5 | ``` 6 | cd first-issues 7 | ``` 8 | - Build image using this command 9 | ``` 10 | docker build -t firstissuescron . 11 | ``` 12 | - Create `credentials.json` file (read more about this in [HOW TO USE](HOW_TO_USE.md)) 13 | - Create container using this command 14 | ``` 15 | docker run -t -i --mount type=bind,src={CREDENTIALS_PATH},dst=/home/first-issues/credentials.json --name firstissuescron firstissuescron 16 | ``` 17 | - Restart container 18 | 19 | > **{CREDENTAILS_PATH}**: Absolute path for `credentails.json` 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | MAINTAINER Arshad Kazmi 4 | 5 | RUN apt-get update 6 | RUN apt-get -y install software-properties-common 7 | RUN add-apt-repository ppa:deadsnakes/ppa 8 | RUN apt-get update 9 | 10 | RUN apt-get install -y git vim cron python3.8 python3-pip build-essential libssl-dev libffi-dev libxml2-dev libxslt1-dev zlib1g-dev python3.8-dev python3.8-venv 11 | 12 | RUN pip3 install click 13 | RUN pip3 install requests 14 | RUN pip3 install tweepy 15 | 16 | ENV LC_ALL=C.UTF-8 17 | ENV LANG=C.UTF-8 18 | 19 | WORKDIR /home 20 | 21 | RUN git clone https://github.com/arshadkazmi42/first-issues 22 | WORKDIR /home/first-issues 23 | 24 | RUN chmod +x cron.sh entrypoint.sh 25 | 26 | ENTRYPOINT ["./entrypoint.sh"] 27 | 28 | -------------------------------------------------------------------------------- /HOW_TO_USE.md: -------------------------------------------------------------------------------- 1 | ###  How to use 2 | 3 | To use this bot, 4 | 5 | > Works only with python3.6 6 | 7 | - Clone the repository. [Steps to clone](https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository). 8 | - Install the required dependencies using the following command. 9 | `pip install -r requirements.txt` 10 | - Create a `credentials.json` in root directory and add the details from the twitter account, on which you want the bot to tweet. 11 | 12 | ```javascript 13 | // credentials.json 14 | 15 | {  16 | "Consumer Key":"TWITTER_CONSUMER_KEY",  17 | "Consumer Secret":"TWITTER_CONSUMER_SECRET", 18 | "Access Token":"TWITTER_APP_ACCESS_TOKEN",  19 | "Access Token Secret":"TWITTER_APP_TOKEN_SECRET",  20 | "Owner":"TWITTER_ACCOUNT_USERNAME",  21 | "Owner ID":"TWITTER_ACCOUNT_ID" // This should be an integer value  22 |  } 23 | ``` 24 | 25 | Don't know what these stand for? No problem, Please follow the steps below: 26 | 27 | - Create a developer account in twitter and then create an app [here](https://developer.twitter.com/en/apps) which will give the following: 28 | 29 | - TWITTER_CONSUMER_KEY, 30 | - TWITTER_CONSUMER_SECRET, 31 | - TWITTER_APP_ACCESS_TOKEN, 32 | - TWITTER_APP_TOKEN_SECRET 33 | 34 | - TWITTER_ACCOUNT_USERNAME can be found out by logging in to [Twitter](https://twitter.com) and clicking on profile. 35 | 36 | - TWITTER_ACCOUNT_ID can be found out [here](http://gettwitterid.com/). 37 | 38 | - Change the label name to the issue label which you want to fetch from github [here](https://github.com/arshadkazmi42/first-issues/blob/master/first_timers/first_timers.py#L11). 39 | - Finally to execute the script, use below command on command prompt 40 | 41 | - To create `db.json` file, use the below command (This command should be executed before all other commands) 42 | 43 | ``` 44 | python first_timers/run.py --creds-path credentials.json --db-path data/db.json --only-save --create 45 | ``` 46 | 47 | - To only fetch the issues and store without tweeting 48 | 49 | ``` 50 | python first_timers/run.py --creds-path credentials.json --db-path data/db.json --only-save 51 | ``` 52 | 53 | This command will fetch all the issues with the defined label and it will be store in `data/db.json` file. 54 | 55 | - To fetch and tweet the issues use the below command 56 | 57 | ``` 58 | python first_timers/run.py --creds-path credentials.json --db-path data/db.json 59 | ``` 60 | 61 | This will fetch the issues with the defined label and store/update `data/db.json` and then tweet the issues which are not already there in `db.json`. 62 | 63 | This script will not tweet the fetched issues which already exists in `db.json` store . 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 First Issues 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. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY: clean-pyc init lint test 3 | 4 | lint: 5 | flake8 --exclude=.tox 6 | 7 | #init: 8 | # pip install -r requirements.txt 9 | 10 | test: 11 | pytest --verbose --color=yes $(TEST_PATH) 12 | 13 | clean-pyc: 14 | echo "Cleaning, TBD" 15 | 16 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes #issuenumber 2 | 3 | Check everything which applies 4 | 5 | - [ ] I have added the issue number for which this pull request is created. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | First Issues Logo 3 | 4 | # 🚀 First Issues Bot - Your Gateway to Open Source Contribution 5 | 6 | [![Build Status](https://img.shields.io/github/actions/workflow/status/arshadkazmi42/first-issues/pytest.yml?branch=master&label=Build&logo=github)](https://github.com/arshadkazmi42/first-issues/actions/workflows/pytest.yml) 7 | [![Code Size](https://img.shields.io/github/languages/code-size/arshadkazmi42/first-issues?logo=github)](https://github.com/arshadkazmi42/first-issues) 8 | [![License](https://img.shields.io/github/license/arshadkazmi42/first-issues?color=blue&logo=opensourceinitiative)](https://github.com/arshadkazmi42/first-issues/blob/master/LICENSE) 9 | [![Contributors](https://img.shields.io/github/contributors/arshadkazmi42/first-issues?color=green&logo=github)](https://github.com/arshadkazmi42/first-issues/graphs/contributors) 10 | [![Last Commit](https://img.shields.io/github/last-commit/arshadkazmi42/first-issues?logo=git)](https://github.com/arshadkazmi42/first-issues) 11 | 12 | 🌟 **Discover beginner-friendly open source issues and make your first contribution!** 🌟 13 | 14 |
15 | 16 | ## 📑 Table of Contents 17 | - [About the Project](#-about-the-project) 18 | - [Follow Us](#-follow-us) 19 | - [How to Use](#️-how-to-use) 20 | - [Deployment Options](#-deployment-options) 21 | - [Troubleshooting](#-troubleshooting) 22 | - [Contributing](#-contributing) 23 | - [Sponsors](#-sponsors) 24 | - [License](#-license) 25 | - [Credits](#-credits) 26 | 27 | ## 📌 About the Project 28 | 29 | First Issues Bot helps newcomers find perfect entry points into open source by curating GitHub issues labeled as `good first issue` or `good-first-issue`. These are specially marked as approachable for first-time contributors. 30 | 31 | ### 📱 Follow Us 32 | - Twitter: [@first_issues](https://twitter.com/first_issues) 33 | - Telegram: [@firstissues](https://t.me/firstissues) 34 | 35 | [![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg?logo=githubsponsors)](https://saythanks.io/to/arshadkazmi42&first-issues) 36 | 37 | ## 🛠️ How to Use 38 | 39 | Get started with our comprehensive [How To Use Guide](HOW_TO_USE.md). 40 | 41 | ## 🚀 Deployment Options 42 | 43 | Choose the deployment method that works best for you: 44 | 45 | - [Docker Container Deployment](DOCKER_DEPLOYMENT.md) (Recommended) 46 | - Standalone Cron Job 47 | 48 | ## 🔍 Troubleshooting 49 | 50 | Experiencing issues? Check our [Troubleshooting Guide](TROUBLESHOOTING.md) first. 51 | 52 | Can't find your issue? [Create a new issue](https://github.com/arshadkazmi42/first-issues/issues/new) and we'll help you out! 53 | 54 | ## 👥 Contributing 55 | 56 | We welcome contributions from everyone! Here's how you can help: 57 | 58 | - 💡 Suggest improvements by [creating an issue](https://github.com/arshadkazmi42/first-issues/issues/new) 59 | - 🐛 Fix existing bugs - check out our [open issues](https://github.com/arshadkazmi42/first-issues/issues) 60 | - 📖 Improve documentation 61 | 62 | Read our [Contribution Guide](Contribution.md) to get started. 63 | 64 | ## ✨ Sponsors 65 | 66 | We're grateful to our sponsors for their support: 67 | 68 | ### 🌟 Current Sponsors 69 | [KITE Tech College](https://www.kgkite.ac.in/) 70 | | --- | 71 | [@KiTETechCollege](https://twitter.com/KiTETechCollege) 72 | 73 | ### ⭐️ Past Sponsors 74 | | [![Utkarsh Upadhyay](https://github.com/musically-ut.png?size=80)](https://github.com/musically-ut) | [![Subhrajyoti Sen](https://github.com/SubhrajyotiSen.png?size=80)](https://github.com/SubhrajyotiSen) | [![Swapnil Agarwal](https://github.com/swapagarwal.png?size=80)](https://github.com/swapagarwal) | 75 | |---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| 76 | | [@musically-ut](https://github.com/musically-ut) | [@SubhrajyotiSen](https://github.com/SubhrajyotiSen) | [@swapagarwal](https://github.com/swapagarwal) | 77 | 78 | ## 📜 License 79 | 80 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 81 | 82 | ## 🙏 Credits 83 | 84 | - Inspired by [Utkarsh Upadhyay's](https://github.com/musically-ut) [first-timers-only-bot](https://github.com/musically-ut/first-timers-only-bot) 85 | - Beautiful logo and header image designed by [Issac Mikel (@icusficus)](https://github.com/icusficus) 86 | -------------------------------------------------------------------------------- /TROUBLESHOOTING.md: -------------------------------------------------------------------------------- 1 | ## TROUBLESHOOTING 2 | 3 | This document have list of know issues and tips to fix those 4 | 5 | - `JSON object must be str, not 'bytes'` 6 | - This issue shows up on using wrong python version. This should be solved on using `python3.6` 7 | -------------------------------------------------------------------------------- /assets/first_issues_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arshadkazmi42/first-issues/b776f956b0d7da999766f3f48b68ad0995d461df/assets/first_issues_round.png -------------------------------------------------------------------------------- /assets/kite-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arshadkazmi42/first-issues/b776f956b0d7da999766f3f48b68ad0995d461df/assets/kite-logo.png -------------------------------------------------------------------------------- /conftest.py: -------------------------------------------------------------------------------- 1 | # Included this file at the root level for future testing scenarios 2 | # as per https://stackoverflow.com/a/34520971/307454 3 | # sample fixture code provided below 4 | """ 5 | import pytest 6 | 7 | @pytest.fixture 8 | def input_value(): 9 | input = 39 10 | return input 11 | """ 12 | -------------------------------------------------------------------------------- /cron.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Running Cron" 3 | python3 /home/first-issues/first_timers/run.py --creds-path /home/first-issues/credentials.json --db-path /home/first-issues/data/db.json 4 | 5 | -------------------------------------------------------------------------------- /data/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "total_count": 24, 3 | "incomplete_results": false, 4 | "items": [ 5 | { 6 | "url": "https://api.github.com/repos/tidusjar/NZBDash/issues/53", 7 | "labels_url": "https://api.github.com/repos/tidusjar/NZBDash/issues/53/labels{/name}", 8 | "comments_url": "https://api.github.com/repos/tidusjar/NZBDash/issues/53/comments", 9 | "events_url": "https://api.github.com/repos/tidusjar/NZBDash/issues/53/events", 10 | "html_url": "https://github.com/tidusjar/NZBDash/issues/53", 11 | "id": 125758032, 12 | "number": 53, 13 | "title": "Styling", 14 | "user": { 15 | "login": "tidusjar", 16 | "id": 6642220, 17 | "avatar_url": "https://avatars.githubusercontent.com/u/6642220?v=3", 18 | "gravatar_id": "", 19 | "url": "https://api.github.com/users/tidusjar", 20 | "html_url": "https://github.com/tidusjar", 21 | "followers_url": "https://api.github.com/users/tidusjar/followers", 22 | "following_url": "https://api.github.com/users/tidusjar/following{/other_user}", 23 | "gists_url": "https://api.github.com/users/tidusjar/gists{/gist_id}", 24 | "starred_url": "https://api.github.com/users/tidusjar/starred{/owner}{/repo}", 25 | "subscriptions_url": "https://api.github.com/users/tidusjar/subscriptions", 26 | "organizations_url": "https://api.github.com/users/tidusjar/orgs", 27 | "repos_url": "https://api.github.com/users/tidusjar/repos", 28 | "events_url": "https://api.github.com/users/tidusjar/events{/privacy}", 29 | "received_events_url": "https://api.github.com/users/tidusjar/received_events", 30 | "type": "User", 31 | "site_admin": false 32 | }, 33 | "labels": [ 34 | { 35 | "url": "https://api.github.com/repos/tidusjar/NZBDash/labels/Approved%20Feature", 36 | "name": "Approved Feature", 37 | "color": "5319e7" 38 | }, 39 | { 40 | "url": "https://api.github.com/repos/tidusjar/NZBDash/labels/first-timers-only", 41 | "name": "first-timers-only", 42 | "color": "e11d21" 43 | }, 44 | { 45 | "url": "https://api.github.com/repos/tidusjar/NZBDash/labels/help%20wanted", 46 | "name": "help wanted", 47 | "color": "159818" 48 | }, 49 | { 50 | "url": "https://api.github.com/repos/tidusjar/NZBDash/labels/up-for-grabs", 51 | "name": "up-for-grabs", 52 | "color": "fef2c0" 53 | } 54 | ], 55 | "state": "open", 56 | "locked": false, 57 | "assignee": { 58 | "login": "tidusjar", 59 | "id": 6642220, 60 | "avatar_url": "https://avatars.githubusercontent.com/u/6642220?v=3", 61 | "gravatar_id": "", 62 | "url": "https://api.github.com/users/tidusjar", 63 | "html_url": "https://github.com/tidusjar", 64 | "followers_url": "https://api.github.com/users/tidusjar/followers", 65 | "following_url": "https://api.github.com/users/tidusjar/following{/other_user}", 66 | "gists_url": "https://api.github.com/users/tidusjar/gists{/gist_id}", 67 | "starred_url": "https://api.github.com/users/tidusjar/starred{/owner}{/repo}", 68 | "subscriptions_url": "https://api.github.com/users/tidusjar/subscriptions", 69 | "organizations_url": "https://api.github.com/users/tidusjar/orgs", 70 | "repos_url": "https://api.github.com/users/tidusjar/repos", 71 | "events_url": "https://api.github.com/users/tidusjar/events{/privacy}", 72 | "received_events_url": "https://api.github.com/users/tidusjar/received_events", 73 | "type": "User", 74 | "site_admin": false 75 | }, 76 | "milestone": { 77 | "url": "https://api.github.com/repos/tidusjar/NZBDash/milestones/4", 78 | "html_url": "https://github.com/tidusjar/NZBDash/milestones/UI%20Features", 79 | "labels_url": "https://api.github.com/repos/tidusjar/NZBDash/milestones/4/labels", 80 | "id": 1496938, 81 | "number": 4, 82 | "title": "UI Features", 83 | "description": "", 84 | "creator": { 85 | "login": "tidusjar", 86 | "id": 6642220, 87 | "avatar_url": "https://avatars.githubusercontent.com/u/6642220?v=3", 88 | "gravatar_id": "", 89 | "url": "https://api.github.com/users/tidusjar", 90 | "html_url": "https://github.com/tidusjar", 91 | "followers_url": "https://api.github.com/users/tidusjar/followers", 92 | "following_url": "https://api.github.com/users/tidusjar/following{/other_user}", 93 | "gists_url": "https://api.github.com/users/tidusjar/gists{/gist_id}", 94 | "starred_url": "https://api.github.com/users/tidusjar/starred{/owner}{/repo}", 95 | "subscriptions_url": "https://api.github.com/users/tidusjar/subscriptions", 96 | "organizations_url": "https://api.github.com/users/tidusjar/orgs", 97 | "repos_url": "https://api.github.com/users/tidusjar/repos", 98 | "events_url": "https://api.github.com/users/tidusjar/events{/privacy}", 99 | "received_events_url": "https://api.github.com/users/tidusjar/received_events", 100 | "type": "User", 101 | "site_admin": false 102 | }, 103 | "open_issues": 8, 104 | "closed_issues": 1, 105 | "state": "open", 106 | "created_at": "2016-01-11T10:54:53Z", 107 | "updated_at": "2016-01-12T20:09:34Z", 108 | "due_on": null, 109 | "closed_at": null 110 | }, 111 | "comments": 0, 112 | "created_at": "2016-01-09T12:51:31Z", 113 | "updated_at": "2016-01-15T23:29:41Z", 114 | "closed_at": null, 115 | "body": "I have to be honest, web design is not my forte.\r\n\r\nDesign wise? I don't know! Let's just see what happens!\r\n\r\nUseful links:\r\nhttps://24ways.org/2012/how-to-make-your-site-look-half-decent/\r\n", 116 | "score": 1.0 117 | }, 118 | { 119 | "url": "https://api.github.com/repos/pybee/briefcase/issues/5", 120 | "labels_url": "https://api.github.com/repos/pybee/briefcase/issues/5/labels{/name}", 121 | "comments_url": "https://api.github.com/repos/pybee/briefcase/issues/5/comments", 122 | "events_url": "https://api.github.com/repos/pybee/briefcase/issues/5/events", 123 | "html_url": "https://github.com/pybee/briefcase/issues/5", 124 | "id": 123239403, 125 | "number": 5, 126 | "title": "Add support for Apple watchOS", 127 | "user": { 128 | "login": "freakboy3742", 129 | "id": 37345, 130 | "avatar_url": "https://avatars.githubusercontent.com/u/37345?v=3", 131 | "gravatar_id": "", 132 | "url": "https://api.github.com/users/freakboy3742", 133 | "html_url": "https://github.com/freakboy3742", 134 | "followers_url": "https://api.github.com/users/freakboy3742/followers", 135 | "following_url": "https://api.github.com/users/freakboy3742/following{/other_user}", 136 | "gists_url": "https://api.github.com/users/freakboy3742/gists{/gist_id}", 137 | "starred_url": "https://api.github.com/users/freakboy3742/starred{/owner}{/repo}", 138 | "subscriptions_url": "https://api.github.com/users/freakboy3742/subscriptions", 139 | "organizations_url": "https://api.github.com/users/freakboy3742/orgs", 140 | "repos_url": "https://api.github.com/users/freakboy3742/repos", 141 | "events_url": "https://api.github.com/users/freakboy3742/events{/privacy}", 142 | "received_events_url": "https://api.github.com/users/freakboy3742/received_events", 143 | "type": "User", 144 | "site_admin": false 145 | }, 146 | "labels": [ 147 | { 148 | "url": "https://api.github.com/repos/pybee/briefcase/labels/first-timers-only", 149 | "name": "first-timers-only", 150 | "color": "fad8c7" 151 | }, 152 | { 153 | "url": "https://api.github.com/repos/pybee/briefcase/labels/up-for-grabs", 154 | "name": "up-for-grabs", 155 | "color": "159818" 156 | } 157 | ], 158 | "state": "open", 159 | "locked": false, 160 | "assignee": null, 161 | "milestone": null, 162 | "comments": 2, 163 | "created_at": "2015-12-21T09:25:52Z", 164 | "updated_at": "2016-01-13T00:09:25Z", 165 | "closed_at": null, 166 | "body": "Now that the Python iOS support libraries support watchOS, Briefcase should also support that platform.\r\n\r\nThis will involve:\r\n* Producing a cookiecutter template project (analogous to [Python-iOS-template](https://github.com/pybee/Python-iOS-template))\r\n* Adding a new command to Briefcase to support tvOS. The implementation of this command will be almost identical to iOS, with names and images changed.", 167 | "score": 1.0 168 | }, 169 | { 170 | "url": "https://api.github.com/repos/pybee/briefcase/issues/4", 171 | "labels_url": "https://api.github.com/repos/pybee/briefcase/issues/4/labels{/name}", 172 | "comments_url": "https://api.github.com/repos/pybee/briefcase/issues/4/comments", 173 | "events_url": "https://api.github.com/repos/pybee/briefcase/issues/4/events", 174 | "html_url": "https://github.com/pybee/briefcase/issues/4", 175 | "id": 123239397, 176 | "number": 4, 177 | "title": "Add support for Apple tvOS", 178 | "user": { 179 | "login": "freakboy3742", 180 | "id": 37345, 181 | "avatar_url": "https://avatars.githubusercontent.com/u/37345?v=3", 182 | "gravatar_id": "", 183 | "url": "https://api.github.com/users/freakboy3742", 184 | "html_url": "https://github.com/freakboy3742", 185 | "followers_url": "https://api.github.com/users/freakboy3742/followers", 186 | "following_url": "https://api.github.com/users/freakboy3742/following{/other_user}", 187 | "gists_url": "https://api.github.com/users/freakboy3742/gists{/gist_id}", 188 | "starred_url": "https://api.github.com/users/freakboy3742/starred{/owner}{/repo}", 189 | "subscriptions_url": "https://api.github.com/users/freakboy3742/subscriptions", 190 | "organizations_url": "https://api.github.com/users/freakboy3742/orgs", 191 | "repos_url": "https://api.github.com/users/freakboy3742/repos", 192 | "events_url": "https://api.github.com/users/freakboy3742/events{/privacy}", 193 | "received_events_url": "https://api.github.com/users/freakboy3742/received_events", 194 | "type": "User", 195 | "site_admin": false 196 | }, 197 | "labels": [ 198 | { 199 | "url": "https://api.github.com/repos/pybee/briefcase/labels/first-timers-only", 200 | "name": "first-timers-only", 201 | "color": "fad8c7" 202 | }, 203 | { 204 | "url": "https://api.github.com/repos/pybee/briefcase/labels/up-for-grabs", 205 | "name": "up-for-grabs", 206 | "color": "159818" 207 | } 208 | ], 209 | "state": "open", 210 | "locked": false, 211 | "assignee": null, 212 | "milestone": null, 213 | "comments": 0, 214 | "created_at": "2015-12-21T09:25:49Z", 215 | "updated_at": "2015-12-22T07:51:47Z", 216 | "closed_at": null, 217 | "body": "Now that the Python iOS support libraries support tvOS, Briefcase should also support that platform.\r\n\r\nThis will involve adding a new command to Briefcase to support tvOS. The implementation of this command will be almost identical to iOS, with names and images changed.\r\n\r\nA template cookiecutter project [already exists](https://github.com/pybee/Python-tvOS-template).", 218 | "score": 1.0 219 | }, 220 | { 221 | "url": "https://api.github.com/repos/pinax/pinax/issues/103", 222 | "labels_url": "https://api.github.com/repos/pinax/pinax/issues/103/labels{/name}", 223 | "comments_url": "https://api.github.com/repos/pinax/pinax/issues/103/comments", 224 | "events_url": "https://api.github.com/repos/pinax/pinax/issues/103/events", 225 | "html_url": "https://github.com/pinax/pinax/issues/103", 226 | "id": 122078778, 227 | "number": 103, 228 | "title": "Describe how a new user can install a new application", 229 | "user": { 230 | "login": "ossanna16", 231 | "id": 8700795, 232 | "avatar_url": "https://avatars.githubusercontent.com/u/8700795?v=3", 233 | "gravatar_id": "", 234 | "url": "https://api.github.com/users/ossanna16", 235 | "html_url": "https://github.com/ossanna16", 236 | "followers_url": "https://api.github.com/users/ossanna16/followers", 237 | "following_url": "https://api.github.com/users/ossanna16/following{/other_user}", 238 | "gists_url": "https://api.github.com/users/ossanna16/gists{/gist_id}", 239 | "starred_url": "https://api.github.com/users/ossanna16/starred{/owner}{/repo}", 240 | "subscriptions_url": "https://api.github.com/users/ossanna16/subscriptions", 241 | "organizations_url": "https://api.github.com/users/ossanna16/orgs", 242 | "repos_url": "https://api.github.com/users/ossanna16/repos", 243 | "events_url": "https://api.github.com/users/ossanna16/events{/privacy}", 244 | "received_events_url": "https://api.github.com/users/ossanna16/received_events", 245 | "type": "User", 246 | "site_admin": false 247 | }, 248 | "labels": [ 249 | { 250 | "url": "https://api.github.com/repos/pinax/pinax/labels/difficulty:%20easy", 251 | "name": "difficulty: easy", 252 | "color": "bfe5bf" 253 | }, 254 | { 255 | "url": "https://api.github.com/repos/pinax/pinax/labels/docs", 256 | "name": "docs", 257 | "color": "006b75" 258 | }, 259 | { 260 | "url": "https://api.github.com/repos/pinax/pinax/labels/first-timers-only", 261 | "name": "first-timers-only", 262 | "color": "5319e7" 263 | }, 264 | { 265 | "url": "https://api.github.com/repos/pinax/pinax/labels/up-for-grabs", 266 | "name": "up-for-grabs", 267 | "color": "fbca04" 268 | } 269 | ], 270 | "state": "open", 271 | "locked": false, 272 | "assignee": null, 273 | "milestone": null, 274 | "comments": 0, 275 | "created_at": "2015-12-14T16:30:11Z", 276 | "updated_at": "2015-12-14T16:33:57Z", 277 | "closed_at": null, 278 | "body": "So far the [Quick Start section](http://pinaxproject.com/pinax/quick_start/) in our Pinax documentation only shows how you can create a new project based on [pinax-project-account](https://github.com/pinax/pinax-project-account). Pinax projects are just Django projects and Pinax apps are just Django apps so you can add any Django app or any Pinax app to a Pinax starter project. We think it would be nice to show our users how to add one or two Pinax apps to their project after they got `pinax-project-account` up and running with the help of our Quick Start.\r\nWe'd like to give someone who has never contributed to open source before a chance to tackle this task in order to make their first OSS contribution. If you have contributed to open source before, please let someone else take this one. Below you can find some guidelines and instructions on what you need to do:\r\n\r\n* Read [this blog post](http://blog.pinaxproject.com/2015/11/10/guide-how-contribute-pinax/) (especially the \"how to make a pull request section\") to learn what you need to to do set everything up.\r\n* Watch [this video](https://www.youtube.com/watch?v=VEO9sh-anCQ) and read [this blog post](http://blog.pinaxproject.com/2015/11/25/recap-november-pinax-hangout/) (especially the \"adding apps to starter projects\" section) to learn more about `pinax-project-account` (what apps it consists of etc.) and how you can add apps to a Pinax project (or really any Django project).\r\n* Open the forked `pinax/pinax` repository in your text editor, then open the `docs` folder, and finally open the `quick_start.md` file.\r\n* At the very bottom of the file you should see this \"TODO: Then add one more app\". You can remove this line and add your description on how to add an app to a Pinax starter project. Don't forget to save your changes. Please note that we use [Markdown syntax](https://daringfireball.net/projects/markdown/) for our documentation.\r\n* Let's see what our changes look like. To do so type `mkdocs serve` into your terminal. Make sure you `cd'd` into the folder in which you copied your forked repository first. Then type `127.0.0.1:8000/` into your browser and you should see the Pinax documentation including the changes you made. Awesome!\r\n* Press the ctrl+c keys in order to stop the server, then follow the instructions (\"how to make a pull request\" section) [here](http://blog.pinaxproject.com/2015/11/10/guide-how-contribute-pinax/) to learn how to push your changes to your forked repository on GitHub and make a pull request.\r\n* Celebrate! You are now an open source contributor! 🎉\r\n\r\nOne of us will then review your pull request and if everything looks great we will merge it (you will receive an email notification from GitHub). If you need to make additional changes, we will comment on your pull request and help you figure out the next steps. Don't worry, this is totally normal and doesn't mean that your pull request isn't awesome. Sometimes it just happens that a few things need to be tweaked. \r\n\r\nIf you have any questions or need help, comment on this issue and mention me @ossanna16 (I will receive a notification this way). One of us will then reply and help you. It's even better if you would join our [Pinax Slack channel](http://slack.pinaxproject.com) (it's free). Someone is always there to help and answer any questions. If you'd like to reach me personally mention me @anna in our Pinax project Slack channel. Please remember that there are no stupid questions. We want to help you succeed and want to help you make your first open source contribution. 😊\r\n\r\n", 279 | "score": 1.0 280 | }, 281 | { 282 | "url": "https://api.github.com/repos/pinax/pinax/issues/102", 283 | "labels_url": "https://api.github.com/repos/pinax/pinax/issues/102/labels{/name}", 284 | "comments_url": "https://api.github.com/repos/pinax/pinax/issues/102/comments", 285 | "events_url": "https://api.github.com/repos/pinax/pinax/issues/102/events", 286 | "html_url": "https://github.com/pinax/pinax/issues/102", 287 | "id": 121059299, 288 | "number": 102, 289 | "title": "Update Pinax Quick Start and pinax/pinax README with new pinax-cli way of starting projects", 290 | "user": { 291 | "login": "ossanna16", 292 | "id": 8700795, 293 | "avatar_url": "https://avatars.githubusercontent.com/u/8700795?v=3", 294 | "gravatar_id": "", 295 | "url": "https://api.github.com/users/ossanna16", 296 | "html_url": "https://github.com/ossanna16", 297 | "followers_url": "https://api.github.com/users/ossanna16/followers", 298 | "following_url": "https://api.github.com/users/ossanna16/following{/other_user}", 299 | "gists_url": "https://api.github.com/users/ossanna16/gists{/gist_id}", 300 | "starred_url": "https://api.github.com/users/ossanna16/starred{/owner}{/repo}", 301 | "subscriptions_url": "https://api.github.com/users/ossanna16/subscriptions", 302 | "organizations_url": "https://api.github.com/users/ossanna16/orgs", 303 | "repos_url": "https://api.github.com/users/ossanna16/repos", 304 | "events_url": "https://api.github.com/users/ossanna16/events{/privacy}", 305 | "received_events_url": "https://api.github.com/users/ossanna16/received_events", 306 | "type": "User", 307 | "site_admin": false 308 | }, 309 | "labels": [ 310 | { 311 | "url": "https://api.github.com/repos/pinax/pinax/labels/difficulty:%20easy", 312 | "name": "difficulty: easy", 313 | "color": "bfe5bf" 314 | }, 315 | { 316 | "url": "https://api.github.com/repos/pinax/pinax/labels/docs", 317 | "name": "docs", 318 | "color": "006b75" 319 | }, 320 | { 321 | "url": "https://api.github.com/repos/pinax/pinax/labels/first-timers-only", 322 | "name": "first-timers-only", 323 | "color": "5319e7" 324 | }, 325 | { 326 | "url": "https://api.github.com/repos/pinax/pinax/labels/up-for-grabs", 327 | "name": "up-for-grabs", 328 | "color": "fbca04" 329 | } 330 | ], 331 | "state": "open", 332 | "locked": false, 333 | "assignee": null, 334 | "milestone": null, 335 | "comments": 6, 336 | "created_at": "2015-12-08T17:38:00Z", 337 | "updated_at": "2015-12-09T21:04:23Z", 338 | "closed_at": null, 339 | "body": "Right now the [Quick Start](http://pinaxproject.com/pinax/quick_start/) in the [Pinax documentation](http://pinaxproject.com/pinax/) and the [README of this repository](https://github.com/pinax/pinax/blob/master/README.md) still show the \"manual\" way of starting Pinax starter projects. Since there's now an easier way to do that with the Pinax Command Line ([pinax-cli](https://github.com/pinax/pinax-cli)) both of these documents need to be updated. We'd like to give someone who has never contributed to open source before a chance to tackle this task in order to make their first OSS contribution. If you have contributed to open source before, please let someone else take this one. Below you can find some guidelines and instructions on what you need to do:\r\n\r\n* Read [this blog post](http://blog.pinaxproject.com/2015/11/10/guide-how-contribute-pinax/) (especially the \"how to make a pull request section\") to learn what you need to to do set everything up. \r\n* Watch [this video](https://www.youtube.com/watch?v=l4yVb9zrbuw#action=share) and read [this blog post](http://blog.pinaxproject.com/2015/11/02/recap-october-pinax-hangout/) to learn how @brosner uses `pinax-cli` to install `pinax-project-blog`.\r\n* Open the forked `pinax/pinax` repository in your text editor and update the \"Getting Started\" section in the `README.md` file with the new `pinax-cli` way of starting projects. Don't forget to save your changes. Please note that we use [Markdown syntax](https://daringfireball.net/projects/markdown/) for our documentation.\r\n* In your text editor open the `docs` folder of the `pinax/pinax` repository and create a new file (right click \"New File\") named `quick_start_manual.md`.\r\n* Open the `quick_start.md` file, copy the content, and paste it into your new `quick_start_manual.md` file. At the very top of the file you should change the title \"Quick Start\" to \"Quick Start Manual\", then save the file.\r\n* Go back to the `quick_start.md` file and update the file the same way you updated the `README.md` file earlier to showcase the new `pinax-cli` way of starting projects.\r\n* We want people to know that there is also a \"manual way\" of starting a project, not only the `pinax-cli` way so you should add one sentence to the document letting people know that if they are interested in learning about the manual way of installing a Pinax project, they should visit the \"Quick Start Manual\" page of the documentation. It would be good if you would link to this page from the `quick_start.md` page. Don't forget to save your changes.\r\n* Since you created a new file, you need to add this file to the navigation bar of the documentation. To do that, open the file named `mkdocs.yml` and add the following line `- [\"quick_start_manual.md\", \"Introduction\", \"Quick Start Manual\"]` right underneath this line `- [\"quick_start.md\", \"Introduction\", \"Quick Start\"]`. Save your changes.\r\n* You also need to add the new file to the table of contents in the documentation. To do that open the `index.md` file and add the following line `* [Quick Start Manaual](quick_start_manual.md)` right underneath the following line `* [Quick Start](quick_start.md)`. Don't forget to save your changes.\r\n* Let's see what our changes look like. To do so type `mkdocs serve` into your terminal. Make sure you `cd'd` into the folder in which you copied your forked repository first. Then type `127.0.0.1:8000/` into your browser and you should see the Pinax documentation including the changes you made. Awesome!\r\n* Press the ctrl+c keys in order to stop the server, then follow the instructions (\"how to make a pull request\" section) [here](http://blog.pinaxproject.com/2015/11/10/guide-how-contribute-pinax/) to learn how to push your changes to your forked repository on GitHub and make a pull request.\r\n* Celebrate! You are now an open source contributor! 🎉\r\n\r\nOne of us will then review your pull request and if everything looks great we will merge it (you will receive an email notification from GitHub). If you need to make additional changes, we will comment on your pull request and help you figure out the next steps. Don't worry, this is totally normal and doesn't mean that your pull request isn't awesome. Sometimes it just happens that a few things need to be tweaked. \r\n\r\nIf you have any questions or need help, comment on this issue and mention me @ossanna16 (I will receive a notification this way). One of us will then reply and help you. It's even better if you would join our [Pinax Slack channel](http://slack.pinaxproject.com) (it's free). Someone is always there to help and answer any questions. If you'd like to reach me personally mention me @anna in our Pinax project Slack channel. Please remember that there are no stupid questions. We want to help you succeed and want to help you make your first open source contribution. 😊\r\n", 340 | "score": 1.0 341 | }, 342 | { 343 | "url": "https://api.github.com/repos/pybee/voc/issues/38", 344 | "labels_url": "https://api.github.com/repos/pybee/voc/issues/38/labels{/name}", 345 | "comments_url": "https://api.github.com/repos/pybee/voc/issues/38/comments", 346 | "events_url": "https://api.github.com/repos/pybee/voc/issues/38/events", 347 | "html_url": "https://github.com/pybee/voc/issues/38", 348 | "id": 120507015, 349 | "number": 38, 350 | "title": "Complete implementation of methods on standard types", 351 | "user": { 352 | "login": "freakboy3742", 353 | "id": 37345, 354 | "avatar_url": "https://avatars.githubusercontent.com/u/37345?v=3", 355 | "gravatar_id": "", 356 | "url": "https://api.github.com/users/freakboy3742", 357 | "html_url": "https://github.com/freakboy3742", 358 | "followers_url": "https://api.github.com/users/freakboy3742/followers", 359 | "following_url": "https://api.github.com/users/freakboy3742/following{/other_user}", 360 | "gists_url": "https://api.github.com/users/freakboy3742/gists{/gist_id}", 361 | "starred_url": "https://api.github.com/users/freakboy3742/starred{/owner}{/repo}", 362 | "subscriptions_url": "https://api.github.com/users/freakboy3742/subscriptions", 363 | "organizations_url": "https://api.github.com/users/freakboy3742/orgs", 364 | "repos_url": "https://api.github.com/users/freakboy3742/repos", 365 | "events_url": "https://api.github.com/users/freakboy3742/events{/privacy}", 366 | "received_events_url": "https://api.github.com/users/freakboy3742/received_events", 367 | "type": "User", 368 | "site_admin": false 369 | }, 370 | "labels": [ 371 | { 372 | "url": "https://api.github.com/repos/pybee/voc/labels/enhancement", 373 | "name": "enhancement", 374 | "color": "84b6eb" 375 | }, 376 | { 377 | "url": "https://api.github.com/repos/pybee/voc/labels/first-timers-only", 378 | "name": "first-timers-only", 379 | "color": "fad8c7" 380 | }, 381 | { 382 | "url": "https://api.github.com/repos/pybee/voc/labels/up-fo-grabs", 383 | "name": "up-fo-grabs", 384 | "color": "159818" 385 | } 386 | ], 387 | "state": "open", 388 | "locked": false, 389 | "assignee": null, 390 | "milestone": null, 391 | "comments": 8, 392 | "created_at": "2015-12-04T23:26:41Z", 393 | "updated_at": "2015-12-27T02:44:10Z", 394 | "closed_at": null, 395 | "body": "The builtin types of Python have a number of methods associated with them - for example, `dict` objects have `update()`, `items()`, `keys()`, `pop()` and so on. These methods need to be implemented in Java. In many cases, there will be a simple mapping to an analogous function in the underlying Java type; however, sometimes you'll need to write an implementation using the available Java primitives.\r\n\r\nTests are are also required; they should go in the module corresponding to the data type [in the tests/datatypes directory](https://github.com/pybee/voc/blob/master/tests/datatypes).\r\n\r\nTests are based on comparing the output of some sample Python code when run through CPython to the output when run through VOC. When the two outputs are identical - and I mean byte-identical, down to the text and punctuation of the error message if appropriate - the test passes.\r\n\r\nIf you want an example to follow, look at [the implementation of `clear()` on `dict`](https://github.com/pybee/voc/blob/master/python/common/org/python/types/Dict.java#L120):\r\n* The `@org.python.Method` annotation is used to expose the clear() method as a symbol that should be available at runtime. \r\n* All arguments are exposed as org.python.Object, and then cast to the right data type as required.\r\n* Finally, the method returns a Python `None`.\r\n", 396 | "score": 1.0 397 | }, 398 | { 399 | "url": "https://api.github.com/repos/pybee/voc/issues/36", 400 | "labels_url": "https://api.github.com/repos/pybee/voc/issues/36/labels{/name}", 401 | "comments_url": "https://api.github.com/repos/pybee/voc/issues/36/comments", 402 | "events_url": "https://api.github.com/repos/pybee/voc/issues/36/events", 403 | "html_url": "https://github.com/pybee/voc/issues/36", 404 | "id": 120503421, 405 | "number": 36, 406 | "title": "Complete implementation of operations on standard types", 407 | "user": { 408 | "login": "freakboy3742", 409 | "id": 37345, 410 | "avatar_url": "https://avatars.githubusercontent.com/u/37345?v=3", 411 | "gravatar_id": "", 412 | "url": "https://api.github.com/users/freakboy3742", 413 | "html_url": "https://github.com/freakboy3742", 414 | "followers_url": "https://api.github.com/users/freakboy3742/followers", 415 | "following_url": "https://api.github.com/users/freakboy3742/following{/other_user}", 416 | "gists_url": "https://api.github.com/users/freakboy3742/gists{/gist_id}", 417 | "starred_url": "https://api.github.com/users/freakboy3742/starred{/owner}{/repo}", 418 | "subscriptions_url": "https://api.github.com/users/freakboy3742/subscriptions", 419 | "organizations_url": "https://api.github.com/users/freakboy3742/orgs", 420 | "repos_url": "https://api.github.com/users/freakboy3742/repos", 421 | "events_url": "https://api.github.com/users/freakboy3742/events{/privacy}", 422 | "received_events_url": "https://api.github.com/users/freakboy3742/received_events", 423 | "type": "User", 424 | "site_admin": false 425 | }, 426 | "labels": [ 427 | { 428 | "url": "https://api.github.com/repos/pybee/voc/labels/enhancement", 429 | "name": "enhancement", 430 | "color": "84b6eb" 431 | }, 432 | { 433 | "url": "https://api.github.com/repos/pybee/voc/labels/first-timers-only", 434 | "name": "first-timers-only", 435 | "color": "fad8c7" 436 | }, 437 | { 438 | "url": "https://api.github.com/repos/pybee/voc/labels/up-fo-grabs", 439 | "name": "up-fo-grabs", 440 | "color": "159818" 441 | } 442 | ], 443 | "state": "open", 444 | "locked": false, 445 | "assignee": null, 446 | "milestone": null, 447 | "comments": 1, 448 | "created_at": "2015-12-04T22:57:06Z", 449 | "updated_at": "2015-12-08T15:23:59Z", 450 | "closed_at": null, 451 | "body": "Java has a specific set of allowed operator and operations. Python has a set of operators and operations as well. However, the two don't match exactly. For example, Java will allow any object to be added to a `java.lang.String`; Python does not. On the other hand, Python allows multiplication of `str` by `int` (producing a duplicated string); Java does not. \r\n\r\nIn order to replicate Python behavior in Java, Python's logic for all the basic operations needs to be implemented in the VOC Java support library.\r\n\r\nThe test suite contains around 2800 tests in the that are currently marked as \"expected failures\". These reflect an attempt to do \"every operation between every base data type\". The task: pick a data type, and write the implementation of one of the dunder operation (e.g., `__add__` or `__xor__`) or comparison (`__lt__` or `__eq__`) methods. \r\n\r\nThe tests will pass (and become unexpected successes) when the output of Python code doing that operation is the same when run through CPython and VOC - and I mean byte-identical, down to the text and punctuation of the error message if appropriate.\r\n\r\nIf you want to see an example of what is involved, check out the implementation of [__add__](https://github.com/pybee/voc/blob/master/python/common/org/python/types/Int.java#L135) for integers. If you have an `int`, Python will allows you to add an `int` or a `float` to it; all other types raise a `TypeError`. The list of operations on `int` that still need to be implemented can be [found here](https://github.com/pybee/voc/blob/master/tests/datatypes/test_int.py); if you add a new operation, delete the line that corresponds to that test, and the test will report as a pass, rather than an expected fail.", 452 | "score": 1.0 453 | }, 454 | { 455 | "url": "https://api.github.com/repos/chaica/db2twitter/issues/5", 456 | "labels_url": "https://api.github.com/repos/chaica/db2twitter/issues/5/labels{/name}", 457 | "comments_url": "https://api.github.com/repos/chaica/db2twitter/issues/5/comments", 458 | "events_url": "https://api.github.com/repos/chaica/db2twitter/issues/5/events", 459 | "html_url": "https://github.com/chaica/db2twitter/issues/5", 460 | "id": 119203425, 461 | "number": 5, 462 | "title": "(for first-time contributor) Nice command line management with argparse", 463 | "user": { 464 | "login": "chaica", 465 | "id": 4236195, 466 | "avatar_url": "https://avatars.githubusercontent.com/u/4236195?v=3", 467 | "gravatar_id": "", 468 | "url": "https://api.github.com/users/chaica", 469 | "html_url": "https://github.com/chaica", 470 | "followers_url": "https://api.github.com/users/chaica/followers", 471 | "following_url": "https://api.github.com/users/chaica/following{/other_user}", 472 | "gists_url": "https://api.github.com/users/chaica/gists{/gist_id}", 473 | "starred_url": "https://api.github.com/users/chaica/starred{/owner}{/repo}", 474 | "subscriptions_url": "https://api.github.com/users/chaica/subscriptions", 475 | "organizations_url": "https://api.github.com/users/chaica/orgs", 476 | "repos_url": "https://api.github.com/users/chaica/repos", 477 | "events_url": "https://api.github.com/users/chaica/events{/privacy}", 478 | "received_events_url": "https://api.github.com/users/chaica/received_events", 479 | "type": "User", 480 | "site_admin": false 481 | }, 482 | "labels": [ 483 | { 484 | "url": "https://api.github.com/repos/chaica/db2twitter/labels/enhancement", 485 | "name": "enhancement", 486 | "color": "84b6eb" 487 | }, 488 | { 489 | "url": "https://api.github.com/repos/chaica/db2twitter/labels/first-timers-only", 490 | "name": "first-timers-only", 491 | "color": "c7def8" 492 | } 493 | ], 494 | "state": "open", 495 | "locked": false, 496 | "assignee": null, 497 | "milestone": null, 498 | "comments": 0, 499 | "created_at": "2015-11-27T14:20:08Z", 500 | "updated_at": "2015-11-27T15:12:47Z", 501 | "closed_at": null, 502 | "body": "The goal of this bug report is to write a nice commande-line management using argparse for db2twitter. This bug report should be studied by a first-time contributor to a free or opensource software. It should lead to a Github Pull Request in order to solve this bug report.\r\n\r\n1/ In your Github , fork the repository db2twitter\r\n2/ in the db2twitter module (the db2twitter directory in the root directory) , create a CliParse class . It should have a __init__ , a main() and an attribute cliargs (have a look at the structure of db2twitter/twbuild.py and organize you code the same way, it's pretty simple)\r\n3/ write the unit test to check if your CliParse class works\r\n4/ in main.py , you should instantiate CliParse before other objects, get the attribute cliargs\r\n5/ modify the ConfParse class in order ConfParse knows what configuration file it must parse\r\n6/ In your Github generate a Pull Request\r\n\r\nI'll be available if you have any question.\r\n\r\nRegards,\r\nCarl", 503 | "score": 1.0 504 | }, 505 | { 506 | "url": "https://api.github.com/repos/reactiveui/ReactiveUI/issues/988", 507 | "labels_url": "https://api.github.com/repos/reactiveui/ReactiveUI/issues/988/labels{/name}", 508 | "comments_url": "https://api.github.com/repos/reactiveui/ReactiveUI/issues/988/comments", 509 | "events_url": "https://api.github.com/repos/reactiveui/ReactiveUI/issues/988/events", 510 | "html_url": "https://github.com/reactiveui/ReactiveUI/issues/988", 511 | "id": 118639501, 512 | "number": 988, 513 | "title": "[Documentation][Bug] Code snippet won't compile: Docs -> Errors -> The Handler Chain", 514 | "user": { 515 | "login": "dsaf", 516 | "id": 3845650, 517 | "avatar_url": "https://avatars.githubusercontent.com/u/3845650?v=3", 518 | "gravatar_id": "", 519 | "url": "https://api.github.com/users/dsaf", 520 | "html_url": "https://github.com/dsaf", 521 | "followers_url": "https://api.github.com/users/dsaf/followers", 522 | "following_url": "https://api.github.com/users/dsaf/following{/other_user}", 523 | "gists_url": "https://api.github.com/users/dsaf/gists{/gist_id}", 524 | "starred_url": "https://api.github.com/users/dsaf/starred{/owner}{/repo}", 525 | "subscriptions_url": "https://api.github.com/users/dsaf/subscriptions", 526 | "organizations_url": "https://api.github.com/users/dsaf/orgs", 527 | "repos_url": "https://api.github.com/users/dsaf/repos", 528 | "events_url": "https://api.github.com/users/dsaf/events{/privacy}", 529 | "received_events_url": "https://api.github.com/users/dsaf/received_events", 530 | "type": "User", 531 | "site_admin": false 532 | }, 533 | "labels": [ 534 | { 535 | "url": "https://api.github.com/repos/reactiveui/ReactiveUI/labels/documentation", 536 | "name": "documentation", 537 | "color": "5319e7" 538 | }, 539 | { 540 | "url": "https://api.github.com/repos/reactiveui/ReactiveUI/labels/first-timers-only", 541 | "name": "first-timers-only", 542 | "color": "009800" 543 | }, 544 | { 545 | "url": "https://api.github.com/repos/reactiveui/ReactiveUI/labels/up-for-grabs", 546 | "name": "up-for-grabs", 547 | "color": "009800" 548 | } 549 | ], 550 | "state": "open", 551 | "locked": false, 552 | "assignee": null, 553 | "milestone": null, 554 | "comments": 2, 555 | "created_at": "2015-11-24T15:54:27Z", 556 | "updated_at": "2015-12-27T22:09:50Z", 557 | "closed_at": null, 558 | "body": "This code snippet does not compile:\r\n\r\nhttp://reactiveui.readthedocs.org/en/stable/basics/errors/ - 'The Handler Chain'\r\n\r\n```csharp\r\nvar disconnectHandler = UserError.RegisterHandler(async error => {\r\n // We don't know what thread a UserError can be thrown from, we usually \r\n // need to move things to the Main thread.\r\n await RxApp.MainThreadScheduler.ScheduleAsync(() => {\r\n // NOTE: This code is Incorrect, as it throws away \r\n // Recovery Options and just returns Cancel. This is Bad™.\r\n return MesssageBox.Show(error.ErrorMessage);\r\n });\r\n\r\n return RecoveryOptionResult.CancelOperation;\r\n});\r\n```\r\n\r\nReasons:\r\n\r\n1) outdated API;\r\n2) spelling error: 'MesssageBox'.", 559 | "score": 1.0 560 | }, 561 | { 562 | "url": "https://api.github.com/repos/M-Zuber/MyHome/issues/99", 563 | "labels_url": "https://api.github.com/repos/M-Zuber/MyHome/issues/99/labels{/name}", 564 | "comments_url": "https://api.github.com/repos/M-Zuber/MyHome/issues/99/comments", 565 | "events_url": "https://api.github.com/repos/M-Zuber/MyHome/issues/99/events", 566 | "html_url": "https://github.com/M-Zuber/MyHome/issues/99", 567 | "id": 114461741, 568 | "number": 99, 569 | "title": "Shallow copy methods for categories", 570 | "user": { 571 | "login": "M-Zuber", 572 | "id": 4746537, 573 | "avatar_url": "https://avatars.githubusercontent.com/u/4746537?v=3", 574 | "gravatar_id": "", 575 | "url": "https://api.github.com/users/M-Zuber", 576 | "html_url": "https://github.com/M-Zuber", 577 | "followers_url": "https://api.github.com/users/M-Zuber/followers", 578 | "following_url": "https://api.github.com/users/M-Zuber/following{/other_user}", 579 | "gists_url": "https://api.github.com/users/M-Zuber/gists{/gist_id}", 580 | "starred_url": "https://api.github.com/users/M-Zuber/starred{/owner}{/repo}", 581 | "subscriptions_url": "https://api.github.com/users/M-Zuber/subscriptions", 582 | "organizations_url": "https://api.github.com/users/M-Zuber/orgs", 583 | "repos_url": "https://api.github.com/users/M-Zuber/repos", 584 | "events_url": "https://api.github.com/users/M-Zuber/events{/privacy}", 585 | "received_events_url": "https://api.github.com/users/M-Zuber/received_events", 586 | "type": "User", 587 | "site_admin": false 588 | }, 589 | "labels": [ 590 | { 591 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/enhancement", 592 | "name": "enhancement", 593 | "color": "84b6eb" 594 | }, 595 | { 596 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/first-timers-only", 597 | "name": "first-timers-only", 598 | "color": "f7c6c7" 599 | }, 600 | { 601 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/Help%20wanted", 602 | "name": "Help wanted", 603 | "color": "ff69b4" 604 | }, 605 | { 606 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/Implementation%20Details", 607 | "name": "Implementation Details", 608 | "color": "006b75" 609 | }, 610 | { 611 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/Low%20Priority", 612 | "name": "Low Priority", 613 | "color": "009800" 614 | }, 615 | { 616 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/New%20Content", 617 | "name": "New Content", 618 | "color": "006b75" 619 | }, 620 | { 621 | "url": "https://api.github.com/repos/M-Zuber/MyHome/labels/Ready", 622 | "name": "Ready", 623 | "color": "fef2c0" 624 | } 625 | ], 626 | "state": "open", 627 | "locked": false, 628 | "assignee": null, 629 | "milestone": null, 630 | "comments": 0, 631 | "created_at": "2015-11-01T09:58:59Z", 632 | "updated_at": "2015-11-16T08:39:02Z", 633 | "closed_at": null, 634 | "body": "There is a file in `MyHome.DataClasses` with methods to create shallow copies of the transaction types.\r\nThe category types needs corresponding methods.", 635 | "score": 1.0 636 | }, 637 | { 638 | "url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/6", 639 | "labels_url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/6/labels{/name}", 640 | "comments_url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/6/comments", 641 | "events_url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/6/events", 642 | "html_url": "https://github.com/wildcard/ReCaptcha-ASP.NET-MVC/issues/6", 643 | "id": 104808555, 644 | "number": 6, 645 | "title": "Add F# build system like in octokit.net", 646 | "user": { 647 | "login": "wildcard", 648 | "id": 2939405, 649 | "avatar_url": "https://avatars.githubusercontent.com/u/2939405?v=3", 650 | "gravatar_id": "", 651 | "url": "https://api.github.com/users/wildcard", 652 | "html_url": "https://github.com/wildcard", 653 | "followers_url": "https://api.github.com/users/wildcard/followers", 654 | "following_url": "https://api.github.com/users/wildcard/following{/other_user}", 655 | "gists_url": "https://api.github.com/users/wildcard/gists{/gist_id}", 656 | "starred_url": "https://api.github.com/users/wildcard/starred{/owner}{/repo}", 657 | "subscriptions_url": "https://api.github.com/users/wildcard/subscriptions", 658 | "organizations_url": "https://api.github.com/users/wildcard/orgs", 659 | "repos_url": "https://api.github.com/users/wildcard/repos", 660 | "events_url": "https://api.github.com/users/wildcard/events{/privacy}", 661 | "received_events_url": "https://api.github.com/users/wildcard/received_events", 662 | "type": "User", 663 | "site_admin": false 664 | }, 665 | "labels": [ 666 | { 667 | "url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/labels/enhancement", 668 | "name": "enhancement", 669 | "color": "84b6eb" 670 | }, 671 | { 672 | "url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/labels/first-timers-only", 673 | "name": "first-timers-only", 674 | "color": "5319e7" 675 | } 676 | ], 677 | "state": "open", 678 | "locked": false, 679 | "assignee": null, 680 | "milestone": null, 681 | "comments": 0, 682 | "created_at": "2015-09-04T00:45:55Z", 683 | "updated_at": "2015-10-05T22:29:44Z", 684 | "closed_at": null, 685 | "body": "Use https://github.com/fsharp/FAKE\r\nlike https://github.com/octokit/octokit.net", 686 | "score": 1.0 687 | }, 688 | { 689 | "url": "https://api.github.com/repos/shanselman/firsttimersonly/issues/5", 690 | "labels_url": "https://api.github.com/repos/shanselman/firsttimersonly/issues/5/labels{/name}", 691 | "comments_url": "https://api.github.com/repos/shanselman/firsttimersonly/issues/5/comments", 692 | "events_url": "https://api.github.com/repos/shanselman/firsttimersonly/issues/5/events", 693 | "html_url": "https://github.com/shanselman/firsttimersonly/issues/5", 694 | "id": 100136548, 695 | "number": 5, 696 | "title": "Fix one of our spelling errors", 697 | "user": { 698 | "login": "shanselman", 699 | "id": 2892, 700 | "avatar_url": "https://avatars.githubusercontent.com/u/2892?v=3", 701 | "gravatar_id": "", 702 | "url": "https://api.github.com/users/shanselman", 703 | "html_url": "https://github.com/shanselman", 704 | "followers_url": "https://api.github.com/users/shanselman/followers", 705 | "following_url": "https://api.github.com/users/shanselman/following{/other_user}", 706 | "gists_url": "https://api.github.com/users/shanselman/gists{/gist_id}", 707 | "starred_url": "https://api.github.com/users/shanselman/starred{/owner}{/repo}", 708 | "subscriptions_url": "https://api.github.com/users/shanselman/subscriptions", 709 | "organizations_url": "https://api.github.com/users/shanselman/orgs", 710 | "repos_url": "https://api.github.com/users/shanselman/repos", 711 | "events_url": "https://api.github.com/users/shanselman/events{/privacy}", 712 | "received_events_url": "https://api.github.com/users/shanselman/received_events", 713 | "type": "User", 714 | "site_admin": false 715 | }, 716 | "labels": [ 717 | { 718 | "url": "https://api.github.com/repos/shanselman/firsttimersonly/labels/first-timers-only", 719 | "name": "first-timers-only", 720 | "color": "0052cc" 721 | } 722 | ], 723 | "state": "open", 724 | "locked": false, 725 | "assignee": null, 726 | "milestone": null, 727 | "comments": 3, 728 | "created_at": "2015-08-10T18:30:46Z", 729 | "updated_at": "2015-12-06T13:21:23Z", 730 | "closed_at": null, 731 | "body": "", 732 | "score": 1.0 733 | }, 734 | { 735 | "url": "https://api.github.com/repos/Kentico/ADImportService/issues/5", 736 | "labels_url": "https://api.github.com/repos/Kentico/ADImportService/issues/5/labels{/name}", 737 | "comments_url": "https://api.github.com/repos/Kentico/ADImportService/issues/5/comments", 738 | "events_url": "https://api.github.com/repos/Kentico/ADImportService/issues/5/events", 739 | "html_url": "https://github.com/Kentico/ADImportService/issues/5", 740 | "id": 99449191, 741 | "number": 5, 742 | "title": "Refactor UserExists() methods", 743 | "user": { 744 | "login": "petrsvihlik", 745 | "id": 9810625, 746 | "avatar_url": "https://avatars.githubusercontent.com/u/9810625?v=3", 747 | "gravatar_id": "", 748 | "url": "https://api.github.com/users/petrsvihlik", 749 | "html_url": "https://github.com/petrsvihlik", 750 | "followers_url": "https://api.github.com/users/petrsvihlik/followers", 751 | "following_url": "https://api.github.com/users/petrsvihlik/following{/other_user}", 752 | "gists_url": "https://api.github.com/users/petrsvihlik/gists{/gist_id}", 753 | "starred_url": "https://api.github.com/users/petrsvihlik/starred{/owner}{/repo}", 754 | "subscriptions_url": "https://api.github.com/users/petrsvihlik/subscriptions", 755 | "organizations_url": "https://api.github.com/users/petrsvihlik/orgs", 756 | "repos_url": "https://api.github.com/users/petrsvihlik/repos", 757 | "events_url": "https://api.github.com/users/petrsvihlik/events{/privacy}", 758 | "received_events_url": "https://api.github.com/users/petrsvihlik/received_events", 759 | "type": "User", 760 | "site_admin": false 761 | }, 762 | "labels": [ 763 | { 764 | "url": "https://api.github.com/repos/Kentico/ADImportService/labels/first-timers-only", 765 | "name": "first-timers-only", 766 | "color": "5319e7" 767 | }, 768 | { 769 | "url": "https://api.github.com/repos/Kentico/ADImportService/labels/idea", 770 | "name": "idea", 771 | "color": "fbca04" 772 | }, 773 | { 774 | "url": "https://api.github.com/repos/Kentico/ADImportService/labels/up-for-grabs", 775 | "name": "up-for-grabs", 776 | "color": "5319e7" 777 | } 778 | ], 779 | "state": "open", 780 | "locked": false, 781 | "assignee": null, 782 | "milestone": null, 783 | "comments": 0, 784 | "created_at": "2015-08-06T14:29:03Z", 785 | "updated_at": "2015-11-06T09:47:50Z", 786 | "closed_at": null, 787 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- adjust the `RestSender.UserExists(Guid guid)` method so that it doesn't query `/rest/cms.user/all` but `/rest/cms.user/` instead (see the [documentation](https://docs.kentico.com/display/K82/Getting+data+using+REST))\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #5 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/ADImportService](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/ADImportService?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 788 | "score": 1.0 789 | }, 790 | { 791 | "url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/2", 792 | "labels_url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/2/labels{/name}", 793 | "comments_url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/2/comments", 794 | "events_url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/issues/2/events", 795 | "html_url": "https://github.com/wildcard/ReCaptcha-ASP.NET-MVC/issues/2", 796 | "id": 98541430, 797 | "number": 2, 798 | "title": "change to explicit render", 799 | "user": { 800 | "login": "wildcard", 801 | "id": 2939405, 802 | "avatar_url": "https://avatars.githubusercontent.com/u/2939405?v=3", 803 | "gravatar_id": "", 804 | "url": "https://api.github.com/users/wildcard", 805 | "html_url": "https://github.com/wildcard", 806 | "followers_url": "https://api.github.com/users/wildcard/followers", 807 | "following_url": "https://api.github.com/users/wildcard/following{/other_user}", 808 | "gists_url": "https://api.github.com/users/wildcard/gists{/gist_id}", 809 | "starred_url": "https://api.github.com/users/wildcard/starred{/owner}{/repo}", 810 | "subscriptions_url": "https://api.github.com/users/wildcard/subscriptions", 811 | "organizations_url": "https://api.github.com/users/wildcard/orgs", 812 | "repos_url": "https://api.github.com/users/wildcard/repos", 813 | "events_url": "https://api.github.com/users/wildcard/events{/privacy}", 814 | "received_events_url": "https://api.github.com/users/wildcard/received_events", 815 | "type": "User", 816 | "site_admin": false 817 | }, 818 | "labels": [ 819 | { 820 | "url": "https://api.github.com/repos/wildcard/ReCaptcha-ASP.NET-MVC/labels/first-timers-only", 821 | "name": "first-timers-only", 822 | "color": "5319e7" 823 | } 824 | ], 825 | "state": "open", 826 | "locked": false, 827 | "assignee": null, 828 | "milestone": null, 829 | "comments": 0, 830 | "created_at": "2015-08-01T14:37:04Z", 831 | "updated_at": "2015-10-05T22:25:30Z", 832 | "closed_at": null, 833 | "body": "As explained [here](https://developers.google.com/recaptcha/docs/display?hl=en#explicit_render)\r\n\r\n change ```@helper GetHtml(...)``` in ReCaptcha.cshtml", 834 | "score": 1.0 835 | }, 836 | { 837 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/19", 838 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/19/labels{/name}", 839 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/19/comments", 840 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/19/events", 841 | "html_url": "https://github.com/Kentico/KInspector/issues/19", 842 | "id": 97050847, 843 | "number": 19, 844 | "title": "Hash salt for macro signatures", 845 | "user": { 846 | "login": "ondrejsevcik", 847 | "id": 4136929, 848 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 849 | "gravatar_id": "", 850 | "url": "https://api.github.com/users/ondrejsevcik", 851 | "html_url": "https://github.com/ondrejsevcik", 852 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 853 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 854 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 855 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 856 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 857 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 858 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 859 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 860 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 861 | "type": "User", 862 | "site_admin": false 863 | }, 864 | "labels": [ 865 | { 866 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/feature", 867 | "name": "feature", 868 | "color": "009800" 869 | }, 870 | { 871 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 872 | "name": "first-timers-only", 873 | "color": "5319e7" 874 | }, 875 | { 876 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 877 | "name": "up-for-grabs", 878 | "color": "5319e7" 879 | } 880 | ], 881 | "state": "open", 882 | "locked": false, 883 | "assignee": null, 884 | "milestone": null, 885 | "comments": 0, 886 | "created_at": "2015-07-24T13:17:11Z", 887 | "updated_at": "2015-11-06T09:47:12Z", 888 | "closed_at": null, 889 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic**:\r\n - check whether the web.config contains [`CMSHashStringSalt`](https://docs.kentico.com/display/K82/Working+with+macro+signatures#Workingwithmacrosignatures-Configuringthehashsaltformacrosignatures) appSetting (we suggest using `ConfigurationManager` to do that), if not inform the user by returning `ModuleResults` with status Error\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #19 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 890 | "score": 1.0 891 | }, 892 | { 893 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/18", 894 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/18/labels{/name}", 895 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/18/comments", 896 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/18/events", 897 | "html_url": "https://github.com/Kentico/KInspector/issues/18", 898 | "id": 97050450, 899 | "number": 18, 900 | "title": "SSL in administration", 901 | "user": { 902 | "login": "ondrejsevcik", 903 | "id": 4136929, 904 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 905 | "gravatar_id": "", 906 | "url": "https://api.github.com/users/ondrejsevcik", 907 | "html_url": "https://github.com/ondrejsevcik", 908 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 909 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 910 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 911 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 912 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 913 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 914 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 915 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 916 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 917 | "type": "User", 918 | "site_admin": false 919 | }, 920 | "labels": [ 921 | { 922 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/feature", 923 | "name": "feature", 924 | "color": "009800" 925 | }, 926 | { 927 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 928 | "name": "first-timers-only", 929 | "color": "5319e7" 930 | }, 931 | { 932 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 933 | "name": "up-for-grabs", 934 | "color": "5319e7" 935 | } 936 | ], 937 | "state": "open", 938 | "locked": false, 939 | "assignee": null, 940 | "milestone": null, 941 | "comments": 0, 942 | "created_at": "2015-07-24T13:15:18Z", 943 | "updated_at": "2015-11-06T09:47:05Z", 944 | "closed_at": null, 945 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic**:\r\n - check whether the `CMSUseSSLForAdministrationInterface` key in the `CMS_SettingsKey` table is true (if not, inform user by returning `ModuleResults` with status warning)\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #18 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 946 | "score": 1.0 947 | }, 948 | { 949 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/17", 950 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/17/labels{/name}", 951 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/17/comments", 952 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/17/events", 953 | "html_url": "https://github.com/Kentico/KInspector/issues/17", 954 | "id": 97049699, 955 | "number": 17, 956 | "title": "Check for password policy/encrtyption", 957 | "user": { 958 | "login": "ondrejsevcik", 959 | "id": 4136929, 960 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 961 | "gravatar_id": "", 962 | "url": "https://api.github.com/users/ondrejsevcik", 963 | "html_url": "https://github.com/ondrejsevcik", 964 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 965 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 966 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 967 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 968 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 969 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 970 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 971 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 972 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 973 | "type": "User", 974 | "site_admin": false 975 | }, 976 | "labels": [ 977 | { 978 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/bug", 979 | "name": "bug", 980 | "color": "fc2929" 981 | }, 982 | { 983 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 984 | "name": "first-timers-only", 985 | "color": "5319e7" 986 | }, 987 | { 988 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 989 | "name": "up-for-grabs", 990 | "color": "5319e7" 991 | } 992 | ], 993 | "state": "open", 994 | "locked": false, 995 | "assignee": null, 996 | "milestone": null, 997 | "comments": 4, 998 | "created_at": "2015-07-24T13:11:36Z", 999 | "updated_at": "2016-01-11T07:16:41Z", 1000 | "closed_at": null, 1001 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic** which consists of 2 checks:\r\n - check whether the `CMSUsePasswordPolicy` keys in the `CMS_SettingsKey` table are set to `true`. if not, return `ModuleResults` with status Warning (see [documentation](https://docs.kentico.com/display/K82/Password+strength+policy+and+its+enforcement))\r\n - check whether the `CMSPasswordFormat` key in the `CMS_SettingsKey` table is set to `SHA2SALT`. if not, return `ModuleResults` with status Error (see [documentation](https://docs.kentico.com/display/K82/Password+encryption+in+database))\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #17 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 1002 | "score": 1.0 1003 | }, 1004 | { 1005 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/16", 1006 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/16/labels{/name}", 1007 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/16/comments", 1008 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/16/events", 1009 | "html_url": "https://github.com/Kentico/KInspector/issues/16", 1010 | "id": 97049325, 1011 | "number": 16, 1012 | "title": "Check for flood protection", 1013 | "user": { 1014 | "login": "ondrejsevcik", 1015 | "id": 4136929, 1016 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 1017 | "gravatar_id": "", 1018 | "url": "https://api.github.com/users/ondrejsevcik", 1019 | "html_url": "https://github.com/ondrejsevcik", 1020 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 1021 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 1022 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 1023 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 1024 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 1025 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 1026 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 1027 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 1028 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 1029 | "type": "User", 1030 | "site_admin": false 1031 | }, 1032 | "labels": [ 1033 | { 1034 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/feature", 1035 | "name": "feature", 1036 | "color": "009800" 1037 | }, 1038 | { 1039 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 1040 | "name": "first-timers-only", 1041 | "color": "5319e7" 1042 | }, 1043 | { 1044 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 1045 | "name": "up-for-grabs", 1046 | "color": "5319e7" 1047 | } 1048 | ], 1049 | "state": "open", 1050 | "locked": false, 1051 | "assignee": null, 1052 | "milestone": null, 1053 | "comments": 0, 1054 | "created_at": "2015-07-24T13:09:42Z", 1055 | "updated_at": "2015-11-06T09:46:53Z", 1056 | "closed_at": null, 1057 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic**:\r\n - check whether the `CMSFloodProtectionEnabled` and `CMSChatEnableFloodProtection` keys in the `CMS_SettingsKey` table are set to `true`. if not, return `ModuleResults` with status Warning (see [documentation](https://docs.kentico.com/display/K82/Flood+protection))\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #16 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 1058 | "score": 1.0 1059 | }, 1060 | { 1061 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/15", 1062 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/15/labels{/name}", 1063 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/15/comments", 1064 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/15/events", 1065 | "html_url": "https://github.com/Kentico/KInspector/issues/15", 1066 | "id": 97049090, 1067 | "number": 15, 1068 | "title": "Check for enabled ClickJacking protection", 1069 | "user": { 1070 | "login": "ondrejsevcik", 1071 | "id": 4136929, 1072 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 1073 | "gravatar_id": "", 1074 | "url": "https://api.github.com/users/ondrejsevcik", 1075 | "html_url": "https://github.com/ondrejsevcik", 1076 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 1077 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 1078 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 1079 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 1080 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 1081 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 1082 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 1083 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 1084 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 1085 | "type": "User", 1086 | "site_admin": false 1087 | }, 1088 | "labels": [ 1089 | { 1090 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/feature", 1091 | "name": "feature", 1092 | "color": "009800" 1093 | }, 1094 | { 1095 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 1096 | "name": "first-timers-only", 1097 | "color": "5319e7" 1098 | }, 1099 | { 1100 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 1101 | "name": "up-for-grabs", 1102 | "color": "5319e7" 1103 | } 1104 | ], 1105 | "state": "open", 1106 | "locked": false, 1107 | "assignee": null, 1108 | "milestone": null, 1109 | "comments": 0, 1110 | "created_at": "2015-07-24T13:08:37Z", 1111 | "updated_at": "2015-11-06T09:46:43Z", 1112 | "closed_at": null, 1113 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic**:\r\n - check whether the `appSettings` section of the web.config doesn't contain `CMSXFrameOptionsExcluded` (use `ConfigurationManager` to do that)\r\n - in case it does inform the user by returning `ModuleResults` with status Warning (https://docs.kentico.com/display/K82/Clickjacking)\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #15 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 1114 | "score": 1.0 1115 | }, 1116 | { 1117 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/9", 1118 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/9/labels{/name}", 1119 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/9/comments", 1120 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/9/events", 1121 | "html_url": "https://github.com/Kentico/KInspector/issues/9", 1122 | "id": 96369447, 1123 | "number": 9, 1124 | "title": "Check for enabled debug", 1125 | "user": { 1126 | "login": "ondrejsevcik", 1127 | "id": 4136929, 1128 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 1129 | "gravatar_id": "", 1130 | "url": "https://api.github.com/users/ondrejsevcik", 1131 | "html_url": "https://github.com/ondrejsevcik", 1132 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 1133 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 1134 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 1135 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 1136 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 1137 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 1138 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 1139 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 1140 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 1141 | "type": "User", 1142 | "site_admin": false 1143 | }, 1144 | "labels": [ 1145 | { 1146 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/feature", 1147 | "name": "feature", 1148 | "color": "009800" 1149 | }, 1150 | { 1151 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 1152 | "name": "first-timers-only", 1153 | "color": "5319e7" 1154 | }, 1155 | { 1156 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 1157 | "name": "up-for-grabs", 1158 | "color": "5319e7" 1159 | } 1160 | ], 1161 | "state": "open", 1162 | "locked": false, 1163 | "assignee": null, 1164 | "milestone": null, 1165 | "comments": 0, 1166 | "created_at": "2015-07-21T17:14:11Z", 1167 | "updated_at": "2015-11-06T09:46:33Z", 1168 | "closed_at": null, 1169 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic** which consists of 2 checks:\r\n - check whether the web.config doesn't contain `debug=\"true\"` in the [compilation element](https://msdn.microsoft.com/en-us/library/e8z01xdh.aspx?f=255&MSPPError=-2147217396) (we suggest using `ConfigurationManager` to do that)\r\n - check whether all boolean records in `CMS_SettingsKey` whose `KeyName` starts with CMSDebug are disabled (their `KeyValue` is false)\r\n - if any check fails inform the user by returning `ModuleResults` with status Error (debug should be disabled on production instances)\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #9 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 1170 | "score": 1.0 1171 | }, 1172 | { 1173 | "url": "https://api.github.com/repos/Kentico/KInspector/issues/7", 1174 | "labels_url": "https://api.github.com/repos/Kentico/KInspector/issues/7/labels{/name}", 1175 | "comments_url": "https://api.github.com/repos/Kentico/KInspector/issues/7/comments", 1176 | "events_url": "https://api.github.com/repos/Kentico/KInspector/issues/7/events", 1177 | "html_url": "https://github.com/Kentico/KInspector/issues/7", 1178 | "id": 96368582, 1179 | "number": 7, 1180 | "title": "Check for disabled web parts", 1181 | "user": { 1182 | "login": "ondrejsevcik", 1183 | "id": 4136929, 1184 | "avatar_url": "https://avatars.githubusercontent.com/u/4136929?v=3", 1185 | "gravatar_id": "", 1186 | "url": "https://api.github.com/users/ondrejsevcik", 1187 | "html_url": "https://github.com/ondrejsevcik", 1188 | "followers_url": "https://api.github.com/users/ondrejsevcik/followers", 1189 | "following_url": "https://api.github.com/users/ondrejsevcik/following{/other_user}", 1190 | "gists_url": "https://api.github.com/users/ondrejsevcik/gists{/gist_id}", 1191 | "starred_url": "https://api.github.com/users/ondrejsevcik/starred{/owner}{/repo}", 1192 | "subscriptions_url": "https://api.github.com/users/ondrejsevcik/subscriptions", 1193 | "organizations_url": "https://api.github.com/users/ondrejsevcik/orgs", 1194 | "repos_url": "https://api.github.com/users/ondrejsevcik/repos", 1195 | "events_url": "https://api.github.com/users/ondrejsevcik/events{/privacy}", 1196 | "received_events_url": "https://api.github.com/users/ondrejsevcik/received_events", 1197 | "type": "User", 1198 | "site_admin": false 1199 | }, 1200 | "labels": [ 1201 | { 1202 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/feature", 1203 | "name": "feature", 1204 | "color": "009800" 1205 | }, 1206 | { 1207 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/first-timers-only", 1208 | "name": "first-timers-only", 1209 | "color": "5319e7" 1210 | }, 1211 | { 1212 | "url": "https://api.github.com/repos/Kentico/KInspector/labels/up-for-grabs", 1213 | "name": "up-for-grabs", 1214 | "color": "5319e7" 1215 | } 1216 | ], 1217 | "state": "open", 1218 | "locked": false, 1219 | "assignee": null, 1220 | "milestone": null, 1221 | "comments": 0, 1222 | "created_at": "2015-07-21T17:09:43Z", 1223 | "updated_at": "2015-11-06T09:46:19Z", 1224 | "closed_at": null, 1225 | "body": "This is a simple task that is meant to be picked up by newcomers. Check out http://www.firsttimersonly.com/.\r\n\r\nSteps to be taken:\r\n- [fork the repository](https://help.github.com/articles/fork-a-repo/)\r\n- clone it to your local machine, you can use [Visual Studio](http://www.malgreve.net/2014/06/17/cloning-getting-code-from-git-repository-to-visual-studio/), [GitHub desktop](https://help.github.com/desktop/guides/contributing/cloning-a-repository-from-github-desktop/) or [command line](https://help.github.com/articles/cloning-a-repository/)\r\n - we recommend using [GitHub extension for Visual Studio](https://visualstudio.github.com/)\r\n- open your local clone with Visual Studio\r\n- [create a new module](https://github.com/Kentico/KInspector/wiki/Writing-a-custom-module)\r\n- implement the **logic**:\r\n - search the `PageTemplateWebParts` column in the `CMS_PageTemplate` table for `False`\r\n - if you find any records inform the user by returning `ModuleResults` with status Warning and a table with results\r\n- check whether your code complies with our [contribution guidelines](https://github.com/Kentico/Home/blob/master/CONTRIBUTING.md)\r\n- push your changes to your fork (VS->Team Explorer->Changes->Commit&Sync)\r\n- create a PR and include Fixes #7 in the message\r\n\r\nWe'll review the change and either merge right away it or suggest potential changes.\r\nIf you have any questions feel free to ask in the repository chat [![Join the chat at https://gitter.im/Kentico/KInspector](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Kentico/KInspector?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)", 1226 | "score": 1.0 1227 | }, 1228 | { 1229 | "url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/292", 1230 | "labels_url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/292/labels{/name}", 1231 | "comments_url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/292/comments", 1232 | "events_url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/292/events", 1233 | "html_url": "https://github.com/OpenGeoscience/geojs/issues/292", 1234 | "id": 54471209, 1235 | "number": 292, 1236 | "title": "Add d3 polygon feature", 1237 | "user": { 1238 | "login": "jbeezley", 1239 | "id": 31890, 1240 | "avatar_url": "https://avatars.githubusercontent.com/u/31890?v=3", 1241 | "gravatar_id": "", 1242 | "url": "https://api.github.com/users/jbeezley", 1243 | "html_url": "https://github.com/jbeezley", 1244 | "followers_url": "https://api.github.com/users/jbeezley/followers", 1245 | "following_url": "https://api.github.com/users/jbeezley/following{/other_user}", 1246 | "gists_url": "https://api.github.com/users/jbeezley/gists{/gist_id}", 1247 | "starred_url": "https://api.github.com/users/jbeezley/starred{/owner}{/repo}", 1248 | "subscriptions_url": "https://api.github.com/users/jbeezley/subscriptions", 1249 | "organizations_url": "https://api.github.com/users/jbeezley/orgs", 1250 | "repos_url": "https://api.github.com/users/jbeezley/repos", 1251 | "events_url": "https://api.github.com/users/jbeezley/events{/privacy}", 1252 | "received_events_url": "https://api.github.com/users/jbeezley/received_events", 1253 | "type": "User", 1254 | "site_admin": false 1255 | }, 1256 | "labels": [ 1257 | { 1258 | "url": "https://api.github.com/repos/OpenGeoscience/geojs/labels/first-timers-only", 1259 | "name": "first-timers-only", 1260 | "color": "fbca04" 1261 | } 1262 | ], 1263 | "state": "open", 1264 | "locked": false, 1265 | "assignee": null, 1266 | "milestone": null, 1267 | "comments": 0, 1268 | "created_at": "2015-01-15T16:37:05Z", 1269 | "updated_at": "2015-09-12T15:35:32Z", 1270 | "closed_at": null, 1271 | "body": "", 1272 | "score": 1.0 1273 | }, 1274 | { 1275 | "url": "https://api.github.com/repos/code-cracker/code-cracker/issues/132", 1276 | "labels_url": "https://api.github.com/repos/code-cracker/code-cracker/issues/132/labels{/name}", 1277 | "comments_url": "https://api.github.com/repos/code-cracker/code-cracker/issues/132/comments", 1278 | "events_url": "https://api.github.com/repos/code-cracker/code-cracker/issues/132/events", 1279 | "html_url": "https://github.com/code-cracker/code-cracker/issues/132", 1280 | "id": 51005679, 1281 | "number": 132, 1282 | "title": "Verifies if \"reference type\" parameters are null", 1283 | "user": { 1284 | "login": "ElemarJR", 1285 | "id": 105970, 1286 | "avatar_url": "https://avatars.githubusercontent.com/u/105970?v=3", 1287 | "gravatar_id": "", 1288 | "url": "https://api.github.com/users/ElemarJR", 1289 | "html_url": "https://github.com/ElemarJR", 1290 | "followers_url": "https://api.github.com/users/ElemarJR/followers", 1291 | "following_url": "https://api.github.com/users/ElemarJR/following{/other_user}", 1292 | "gists_url": "https://api.github.com/users/ElemarJR/gists{/gist_id}", 1293 | "starred_url": "https://api.github.com/users/ElemarJR/starred{/owner}{/repo}", 1294 | "subscriptions_url": "https://api.github.com/users/ElemarJR/subscriptions", 1295 | "organizations_url": "https://api.github.com/users/ElemarJR/orgs", 1296 | "repos_url": "https://api.github.com/users/ElemarJR/repos", 1297 | "events_url": "https://api.github.com/users/ElemarJR/events{/privacy}", 1298 | "received_events_url": "https://api.github.com/users/ElemarJR/received_events", 1299 | "type": "User", 1300 | "site_admin": false 1301 | }, 1302 | "labels": [ 1303 | { 1304 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/1%20-%20Ready", 1305 | "name": "1 - Ready", 1306 | "color": "CCCCCC" 1307 | }, 1308 | { 1309 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/analyzer", 1310 | "name": "analyzer", 1311 | "color": "0052cc" 1312 | }, 1313 | { 1314 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/C%23", 1315 | "name": "C#", 1316 | "color": "5319e7" 1317 | }, 1318 | { 1319 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/code-fix", 1320 | "name": "code-fix", 1321 | "color": "207de5" 1322 | }, 1323 | { 1324 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/enhancement", 1325 | "name": "enhancement", 1326 | "color": "84b6eb" 1327 | }, 1328 | { 1329 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/first-timers-only", 1330 | "name": "first-timers-only", 1331 | "color": "0052cc" 1332 | }, 1333 | { 1334 | "url": "https://api.github.com/repos/code-cracker/code-cracker/labels/VB", 1335 | "name": "VB", 1336 | "color": "d4c5f9" 1337 | } 1338 | ], 1339 | "state": "open", 1340 | "locked": false, 1341 | "assignee": null, 1342 | "milestone": null, 1343 | "comments": 4, 1344 | "created_at": "2014-12-04T17:47:17Z", 1345 | "updated_at": "2015-12-02T13:43:53Z", 1346 | "closed_at": null, 1347 | "body": "````csharp\r\nvoid Foo(Fee a)\r\n{\r\n}\r\n````\r\n\r\nbecomes\r\n\r\n````csharp\r\nvoid Foo(Fee a)\r\n{\r\n if (a == null) throw new ArgumentNullException(nameof(a))\r\n}\r\n````\r\n\r\nStyle: `Refactoring`\r\nSeverity: `Hidden`\r\nId: `CC0078`", 1348 | "score": 1.0 1349 | }, 1350 | { 1351 | "url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/187", 1352 | "labels_url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/187/labels{/name}", 1353 | "comments_url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/187/comments", 1354 | "events_url": "https://api.github.com/repos/OpenGeoscience/geojs/issues/187/events", 1355 | "html_url": "https://github.com/OpenGeoscience/geojs/issues/187", 1356 | "id": 41880705, 1357 | "number": 187, 1358 | "title": "Create an example to show loading of a geotif ", 1359 | "user": { 1360 | "login": "aashish24", 1361 | "id": 146527, 1362 | "avatar_url": "https://avatars.githubusercontent.com/u/146527?v=3", 1363 | "gravatar_id": "", 1364 | "url": "https://api.github.com/users/aashish24", 1365 | "html_url": "https://github.com/aashish24", 1366 | "followers_url": "https://api.github.com/users/aashish24/followers", 1367 | "following_url": "https://api.github.com/users/aashish24/following{/other_user}", 1368 | "gists_url": "https://api.github.com/users/aashish24/gists{/gist_id}", 1369 | "starred_url": "https://api.github.com/users/aashish24/starred{/owner}{/repo}", 1370 | "subscriptions_url": "https://api.github.com/users/aashish24/subscriptions", 1371 | "organizations_url": "https://api.github.com/users/aashish24/orgs", 1372 | "repos_url": "https://api.github.com/users/aashish24/repos", 1373 | "events_url": "https://api.github.com/users/aashish24/events{/privacy}", 1374 | "received_events_url": "https://api.github.com/users/aashish24/received_events", 1375 | "type": "User", 1376 | "site_admin": false 1377 | }, 1378 | "labels": [ 1379 | { 1380 | "url": "https://api.github.com/repos/OpenGeoscience/geojs/labels/first-timers-only", 1381 | "name": "first-timers-only", 1382 | "color": "fbca04" 1383 | } 1384 | ], 1385 | "state": "open", 1386 | "locked": false, 1387 | "assignee": null, 1388 | "milestone": null, 1389 | "comments": 0, 1390 | "created_at": "2014-09-03T23:45:12Z", 1391 | "updated_at": "2015-09-12T15:35:43Z", 1392 | "closed_at": null, 1393 | "body": "", 1394 | "score": 1.0 1395 | } 1396 | ] 1397 | } 1398 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Start the run once job. 4 | echo "Docker container has been started" 5 | 6 | declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env 7 | 8 | python3 first_timers/run.py --creds-path credentials.json --db-path data/db.json --only-save --create 9 | python3 first_timers/run.py --creds-path credentials.json --db-path data/db.json --only-save 10 | 11 | # Setup a cron schedule 12 | echo "SHELL=/bin/bash 13 | BASH_ENV=/container.env 14 | */1 * * * * /home/first-issues/cron.sh >> /var/log/cron.log 2>&1 15 | # This extra line makes it a valid cron" > scheduler.txt 16 | 17 | crontab scheduler.txt 18 | cron -f 19 | -------------------------------------------------------------------------------- /first_timers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arshadkazmi42/first-issues/b776f956b0d7da999766f3f48b68ad0995d461df/first_timers/__init__.py -------------------------------------------------------------------------------- /first_timers/first_timers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function 3 | import re 4 | from datetime import datetime 5 | import requests 6 | import tweepy 7 | import logging 8 | 9 | # Set up logging 10 | logging.basicConfig(filename='app.log', level=logging.INFO) 11 | 12 | 13 | DAYS_OLD = 15 14 | MAX_TWEETS_LEN = 280 15 | 16 | ellipse = u'…' 17 | api = 'https://api.github.com/search/issues' 18 | FIRST_ISSUE_QUERY_URL = api + '?q=label:"{}"+is:issue+is:open&sort=updated&order=desc' 19 | 20 | # Logging helper function 21 | def log_info(message): 22 | logging.info(message) 23 | 24 | def log_warning(message): 25 | logging.warning(message) 26 | 27 | def log_error(message): 28 | logging.error(message) 29 | 30 | 31 | def humanize_url(api_url: str) -> str: 32 | """Make an API endpoint to a Human endpoint.""" 33 | match = re.match( 34 | 'https://api.github.com/repos/(.*)/(.*)/issues/([0-9]*)', api_url) 35 | if not match: 36 | raise ValueError(f'Format of API URLs has changed: {api_url}') 37 | user, repo, issue_num = match.group(1, 2, 3) 38 | 39 | return f'https://github.com/{user}/{repo}/issues/{issue_num}' 40 | 41 | 42 | def get_first_timer_issues(issue_label: str) -> list: 43 | """Fetches the first page of issues with the label first-timers-label 44 | which are still open. 45 | """ 46 | res = requests.get(FIRST_ISSUE_QUERY_URL.format(issue_label)) 47 | res.raise_for_status() 48 | 49 | items = [item for item in res.json()['items'] 50 | if check_days_passed(item['created_at'], DAYS_OLD)] 51 | 52 | return items 53 | 54 | 55 | def check_days_passed(date_created: str, days: int) -> bool: 56 | created_at = datetime.strptime(date_created, "%Y-%m-%dT%H:%M:%SZ") 57 | return (datetime.now() - created_at).days < days 58 | 59 | 60 | def add_repo_languages(issues): 61 | """Adds the repo languages to the issues list.""" 62 | for issue in issues: 63 | query_languages = issue['repository_url'] + '/languages' 64 | res = requests.get(query_languages) 65 | if res.status_code == 403: 66 | log_warning('Rate limit reached getting languages') 67 | return issues 68 | if res.ok: 69 | issue['languages'] = res.json() 70 | else: 71 | log_warning('Could not handle response: ' + 72 | str(res) + ' from the API.') 73 | return issues 74 | 75 | 76 | def get_fresh(old_issue_list, new_issue_list): 77 | """Returns which issues are not present in the old list of issues.""" 78 | old_urls = {x['url'] for x in old_issue_list} 79 | return [x for x in new_issue_list if x['url'] not in old_urls] 80 | 81 | 82 | def tweet_issues(issues, creds, debug=False): 83 | """Takes a list of issues and credentials and tweets through the account 84 | associated with the credentials. 85 | Also takes a parameter 'debug', which can prevent actual tweeting. 86 | Returns a list of tweets. 87 | """ 88 | if len(issues) == 0: 89 | return [] 90 | 91 | auth = tweepy.OAuthHandler(creds['Consumer Key'], creds['Consumer Secret']) 92 | auth.set_access_token(creds['Access Token'], creds['Access Token Secret']) 93 | api = tweepy.API(auth) 94 | 95 | # This results in an API call to /help/configuration 96 | # conf = api.configuration() 97 | 98 | # url_len = conf['short_url_length_https'] 99 | url_len = 30 100 | hashTags = u"#github" 101 | 102 | # 1 space with URL and 1 space before hashtags. 103 | allowed_title_len = MAX_TWEETS_LEN - (url_len + 1) - (len(hashTags) + 1) 104 | 105 | tweets = [] 106 | 107 | for issue in issues: 108 | # Not encoding here because Twitter treats code points as 1 character. 109 | language_hashTags = '' 110 | title = issue['title'] 111 | 112 | if len(title) > allowed_title_len: 113 | title = title[: allowed_title_len - 1] + ellipse 114 | else: 115 | if 'languages' in issue: 116 | language_hashTags = ''.join( 117 | ' #{}'.format(lang) for lang in issue['languages'] 118 | ) 119 | hashTags = hashTags + language_hashTags 120 | 121 | max_hashtags_len = MAX_TWEETS_LEN - \ 122 | (url_len + 1) - (len(title) + 1) 123 | 124 | if len(hashTags) > max_hashtags_len: 125 | hashTags = hashTags[:max_hashtags_len - 1] + ellipse 126 | 127 | url = humanize_url(issue['url']) 128 | 129 | try: 130 | # Encoding here because .format will fail with Unicode characters. 131 | tweet = '{title} {url} {tags}'.format( 132 | title=title, 133 | url=url, 134 | tags=hashTags 135 | ) 136 | 137 | if not debug: 138 | api.update_status(tweet) 139 | 140 | tweets.append({ 141 | 'error': None, 142 | 'tweet': tweet 143 | }) 144 | 145 | log_info('Tweeted issue: {}'.format(issue['title'])) 146 | except Exception as e: 147 | tweets.append({ 148 | 'error': e, 149 | 'tweet': tweet 150 | }) 151 | 152 | log_error('Error tweeting issue: {}'.format(issue['title'])) 153 | log_error('Error message: {}'.format(str(e))) 154 | 155 | return tweets 156 | 157 | 158 | def limit_issues(issues, limit_len=100000): 159 | """Limit the number of issues saved in our DB.""" 160 | sorted_issues = sorted(issues, key=lambda x: x['updated_at'], reverse=True) 161 | return sorted_issues[:limit_len] 162 | -------------------------------------------------------------------------------- /first_timers/run.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import print_function 3 | import click 4 | import os 5 | import sys 6 | import json 7 | import warnings 8 | import requests 9 | import first_timers as FT 10 | 11 | 12 | def updateDB(all_issues, db_path): 13 | """Truncate and write the new list of issues in the DB.""" 14 | with open(db_path, 'w') as dbFile: 15 | json.dump(FT.limit_issues(all_issues), dbFile, indent=2) 16 | 17 | 18 | @click.command() 19 | @click.option('--only-save', 20 | is_flag=True, 21 | help='Do not post any tweets, just populate the DB.') 22 | @click.option('--db-path', 23 | prompt='Database file', 24 | default='data/db.json', 25 | help='Old issues in a JSON list.') 26 | @click.option('--create', 27 | is_flag=True, 28 | help='Pass if the DB file should be created.') 29 | @click.option('--creds-path', 30 | prompt='Credentials file', 31 | default='', 32 | help='File which contains Twitter account credentials. ' 33 | 'Not needed if only saving to DB.') 34 | @click.option('--debug', 35 | is_flag=True, 36 | help='Run in debug mode (does not tweet).') 37 | def run(only_save, db_path, create, creds_path, debug): 38 | """The function that gets repetitively called via cron. 39 | - Updates the DB file with new issues 40 | - Sends out corresponding tweets for those new issues 41 | """ 42 | dbExists = os.path.exists(db_path) 43 | if not dbExists and not create: 44 | click.secho('DB file does not exist and argument' 45 | '--create was not passed.', err=True, fg='red') 46 | sys.exit(-1) 47 | elif dbExists and not create: 48 | with open(db_path, 'rb') as dbFile: 49 | old_issues = json.load(dbFile) 50 | elif not dbExists and create: 51 | old_issues = [] 52 | else: 53 | click.secho('DB file exists but --create was passed.', 54 | err=True, fg='red') 55 | sys.exit(-1) 56 | 57 | # Getting the latest list of issues from GitHub 58 | issue_labels = ('good first issue', 'good-first-issue') 59 | new_issues = [] 60 | for label in issue_labels: 61 | try: 62 | new_issues.append(FT.get_first_timer_issues(label)) 63 | except requests.HTTPError: 64 | warnings.warn('Rate limit reached getting languages') 65 | 66 | fresh_issues = FT.get_fresh(old_issues, new_issues) 67 | all_issues = fresh_issues + old_issues 68 | 69 | if not only_save: 70 | try: 71 | FT.add_repo_languages(fresh_issues) 72 | 73 | if not os.path.exists(creds_path): 74 | print('Credentials file does not exist.', file=sys.stdout) 75 | sys.exit(-1) 76 | 77 | with open(creds_path, 'r') as credsFile: 78 | creds = json.load(credsFile) 79 | 80 | click.secho('Tweeting {} tweet(s).'.format(len(fresh_issues))) 81 | for issue in fresh_issues: 82 | click.secho('\t URL: ' + issue['url'], fg='blue') 83 | 84 | tweets = FT.tweet_issues(fresh_issues, creds, debug) 85 | 86 | for tweet in tweets: 87 | if tweet['error'] is None: 88 | click.secho('\t' + tweet['tweet'], fg='green') 89 | else: 90 | click.secho('\t' + tweet['tweet'], fg='red') 91 | click.secho('\t\tError: ' + str(tweet['error']), fg='red') 92 | 93 | except UnicodeEncodeError as e: 94 | click.secho('Unable to post tweets because: ' + str(e), fg='red') 95 | 96 | updateDB(all_issues, db_path) 97 | 98 | if len(fresh_issues) > 0: 99 | click.echo('Database updated.') 100 | 101 | 102 | if __name__ == '__main__': 103 | run() 104 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | tweepy 2 | Nose 3 | requests>=2.11.1 4 | click 5 | colorama 6 | pytest 7 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | while true; do python first_timers/run.py --creds-path credentials.json --db-path data/db.json; date; sleep 600; done; 2 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arshadkazmi42/first-issues/b776f956b0d7da999766f3f48b68ad0995d461df/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_basic.py: -------------------------------------------------------------------------------- 1 | 2 | # attribution: 3 | # https://containersolutions.github.io/runbooks/posts/python/module-has-no-attribute/#step-2 4 | from first_timers import first_timers 5 | import json 6 | 7 | 8 | example_res = json.load(open('data/example.json', 'r')) 9 | example_issues = example_res['items'] 10 | 11 | 12 | def test_fetcher(): 13 | """Test whether first_timer_issues are getting picked up.""" 14 | issue_label = ('good first issue') 15 | new_issues = first_timers.get_first_timer_issues(issue_label) 16 | assert new_issues 17 | 18 | 19 | test_fetcher.__setattr__('__test__', False) # Test disabled by default. 20 | 21 | 22 | def test_get_fresh(): 23 | """Test whether fresh issues are retrieved.""" 24 | new_issues = first_timers.get_fresh(example_issues[:-1], example_issues) 25 | assert new_issues[0] == example_issues[-1] 26 | 27 | 28 | def test_humanize_url(): 29 | """Test whether the humanization of api endpoint works. 30 | Please see https://en.wikipedia.org/wiki/URI_normalization 31 | """ 32 | 33 | api_url = "https://api.github.com/repos/tidusjar/NZBDash/issues/53" 34 | human_url = 'https://github.com/tidusjar/NZBDash/issues/53' 35 | assert first_timers.humanize_url(api_url) == human_url 36 | --------------------------------------------------------------------------------