From e53778324c60493db6c0c759cdbb1ca271d0a387 Mon Sep 17 00:00:00 2001 From: Victor Häggqvist Date: Thu, 21 May 2015 00:56:05 +0200 Subject: rewritten for python 3 also added search on non-exact matches --- .gitignore | 71 +++++++++++++++++---- TODO.md | 4 ++ giti.py | 206 ++++++++++++++++++++++++++++++++++++------------------------- 3 files changed, 185 insertions(+), 96 deletions(-) create mode 100644 TODO.md diff --git a/.gitignore b/.gitignore index 4e47a3b..651bf92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] +*$py.class # C extensions *.so @@ -8,11 +9,12 @@ __pycache__/ # Distribution / packaging .Python env/ -bin/ build/ develop-eggs/ dist/ +downloads/ eggs/ +.eggs/ lib/ lib64/ parts/ @@ -22,6 +24,12 @@ var/ .installed.cfg *.egg +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + # Installer logs pip-log.txt pip-delete-this-directory.txt @@ -30,26 +38,67 @@ pip-delete-this-directory.txt htmlcov/ .tox/ .coverage +.coverage.* .cache nosetests.xml coverage.xml +*,cover # Translations *.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# Rope -.ropeproject +*.pot # Django stuff: *.log -*.pot # Sphinx documentation docs/_build/ -test/ +# PyBuilder +target/ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..5c4ac42 --- /dev/null +++ b/TODO.md @@ -0,0 +1,4 @@ +# TODO + +- todo check if current .gitignore _is identical_ to the fetched one, to prevent having the same thing twice +- todo check if current .gitignore _contains_ to the fetched one, to prevent having the same thing twice diff --git a/giti.py b/giti.py index 890c6ae..e6fa716 100755 --- a/giti.py +++ b/giti.py @@ -1,100 +1,136 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # coding=utf-8 -import os.path +import os import sys -import urllib2 as urllib -import json +import requests __author__ = 'Victor Häggqvist' -__version__ = '0.1.1' - -def searchGithub(query): - url = "https://api.github.com/search/code?q="+query+"+repo:github/gitignore" - accept = "application/vnd.github.v3+json" - userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.8 Safari/537.36" - - request = urllib.Request(url, headers={"Accept": accept, "User-Agent": userAgent}) - - content = "" - try: - content = urllib.urlopen(request).read() - except urllib.HTTPError as e: - print "Some thing faild... HTTP error:",e.code - - response = json.loas(content) - if response["total_count"] == 0: - print query,"not found" - else: - print "Got",response["total_count"],"hits" - for item in response["items"]: - print item["name"] - -def gitiglobal(type): - """ - Fetch gitignore from the global directory - """ - print "Fetching .gitignore for", type,"in Global" - try: - gifile = urllib.urlopen("https://raw.githubusercontent.com/github/gitignore/master/Global/"+type+".gitignore").read() - store(gifile) - except urllib.HTTPError as e: - if e.code == 404: - print "Not found in global either" +__version__ = '0.2' + + +def repo_url(kind: str, global_dir=False) -> str: + if global_dir: + return 'https://raw.githubusercontent.com/github/gitignore/master/Global/%s.gitignore' % kind else: - print "Got unexpected answer from Github, you better check on them..." + return 'https://raw.githubusercontent.com/github/gitignore/master/%s.gitignore' % kind -def store(file): - """ - Store content in file - """ - if os.path.isfile(".gitignore") == True: +def get_ignore_file(kind: str, global_dir=False, path=False) -> str: + """ + Download the file + """ + if not path: + url = repo_url(kind, global_dir) + else: + if kind[0] == '/': + kind = kind[1:] + url = 'https://raw.githubusercontent.com/github/gitignore/master/%s' % kind + + r = requests.get(url) + if r.status_code != 200: + return None + return r.text + + +def search_for_file(kind: str) -> str: + """ + Search for file in https://github.com/github/gitignore + """ + headers = { + 'User-Agent': 'giti.py/0.0.1', + 'Accept': 'application/vnd.github.v3+json' + } + r = requests.get('https://api.github.com/search/code?q=repo:github/gitignore %s' % kind, headers=headers) + cont = r.json() + + print('One of these might be good:') + for i in range(0, len(cont['items'])): + name = cont['items'][i]['name'].split('.')[0] + print('[%s] %s' % (i, name)) + try: - merge = input("Do you want to merge with existing .gitignore [Y/n]:") - except: - merge = "y" - existingFile = open(".gitignore").read() - else: - merge = "y" - existingFile = "" - - if merge.lower() == "y": - gitignore = existingFile + file - f = open('.gitignore', 'w') - f.write(gitignore) - print ".gitignore baked :)" - else: - print "Did nothing, your .gitignore lives like before" - - -def giti(type): - """ - Fetch gitignore from directory - """ - type = type[0].upper() + type[1:] # make first upper - print "Fetching .gitignore for", type - - try: - gifile = urllib.urlopen("https://raw.githubusercontent.com/github/gitignore/master/"+type+".gitignore").read() - store(gifile) - except urllib.HTTPError as e: - if e.code == 404: - print "Not found in master" - gitiglobal(type) + choice = int(input('Enter index: ')) + except TypeError: + return None + except KeyboardInterrupt: + return None + + if -1 < choice < len(cont['items']): + return cont['items'][choice]['path'] else: - print "Got unexpected answer from Github, you better check on them..." + return None + + +def save_file(file: str): + """ + Store content in file + """ + merge = 'y' + replace = 'n' + if os.path.isfile('.gitignore'): + try: + merge = input('Do you want to merge with existing .gitignore [Y/n]: ') + merge = 'y' if merge == '' else 'n' + except KeyError: + merge = 'y' + + if merge.lower() == "n": + try: + replace = input('Do you want to replace existing .gitignore [y/N]: ') + except KeyError: + replace = 'n' + + if merge.lower() == 'y': + with open('.gitignore', 'a') as f: + f.write(file) + print('.gitignore baked :)') + + elif replace.lower() == 'y': + with open('.gitignore', 'w') as f: + f.write(file) + print('.gitignore replaced') + + else: + print('Did nothing, your .gitignore lives like before') + +def giti(kind: str): + kind = kind[0].upper() + kind[1:] + print('Fetching .gitignore for %s' % kind) -def help(): - print "Usage: giti [language or stuff]" - print "giti v"+__version__ + gifile = get_ignore_file(kind) + + if not gifile: + print('Not found in master') + gifile = get_ignore_file(kind, global_dir=True) + + if not gifile: + print('Found no exact match, let\'s give searching a try...') + filepath = search_for_file(kind) + if not filepath: + print('Can\'t help any more, exiting') + print('No changes made') + exit(0) + gifile = get_ignore_file(filepath, path=True) + + if not gifile: + print('Can\'t help any more, exiting') + print('No changes made') + exit(0) + + save_file(gifile) + + +def show_help(): + print('Usage: giti [language or stuff]') + print('giti v%s' % __version__) def main(): - if len(sys.argv) == 2: - giti(sys.argv[1]) - else: - help() + if len(sys.argv) == 2: + giti(sys.argv[1]) + else: + show_help() -if __name__ == "__main__": - main() +if __name__ == '__main__': + main() -- cgit v1.2.3