Clone repos from Gitolite in one action - python

Here is my attempt to simplify a process of preparing working environment. Assume your team has many Gitolite hosted repositories and you want to:
get full list of them;
clone some of them as simple and fast as can.
This script allows it. So, the answers for above questions are:
Show gitolite repos:
ssh git#server_ip
And the following code for cloning:
#!/usr/bin/python
import subprocess
import sys
import os
import re
FILTER = None
# check shell arguments
if len(sys.argv) == 2:
FILTER = sys.argv[1]
GIT_PATH = "git#server_ip"
# run system command and retrieve result
p = subprocess.Popen("ssh " + GIT_PATH, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
output = re.sub(r'^[\S\s]*?(?=web/)', '', output)
output = re.sub(r'R|W', '', output)
output = output.split()
# filter function
def f(line):
if line.find(FILTER) != -1:
return True
return False
if FILTER:
output = filter(f, output)
yes = 'yes'
no = 'no'
for line in output:
print(line)
choice = input("Do you want to clone this repo (yes/no): ")
if choice == yes:
os.system("git clone " + GIT_PATH + ':/' + line.strip())
print('Done!')
print('All work is done! Congrats!')
Syntax: python clone.py [filter]
Filter, when specified, allows to get only repos that contain filter string as substring.
Suggestions for improvement are welcome! Thanks.

Related

pbcopy in Python to copy to the clipboard on OSX?

I am receiving the following error when trying to use pbcopy to add the output to the clipboard. I tried different variations of the command and still no luck.
Does anyone have any ideas where I may have failed?
Error Screenshot:
#!/usr/bin/env python3
# This script creates a secure password using all available key combinations.
import secrets , string, os
def prRed(skk): print("\033[91m {}\033[00m" .format(skk))
chars = string.ascii_letters+string.punctuation+string.digits # Cleaner way of assigning variable
print()
pwd_length = int(input('Enter the length of the desired password: '))
print()
print('[+] ' + 'Your secure password is:')
print()
for n in range(1):
output = ""
for i in range(pwd_length):
next_index = secrets.SystemRandom().randrange(len(chars))
output = output + chars[next_index]
prRed(os.system("echo '%s' | pbcopy" % output))
print()

Python - Issues with code blocking in loops

I'm new to python and having some issues with blocking. I have a script that I'm calling with options. I'm able to see the arguments come in, however, I have been unable to get the program to work correctly. In the code sample below, I'm trying to grab the arguments and then run the piece of code after the "#if ip address is not defined qpid-route will not work" comment. If I change the indentation after the comment, I get expected indentation or unexpected indentation errors.
The problem is that the way the code currently is it will run the elif opt in ("-i", "--ipaddress"): code and then will continue and run the code through to the bottom and then come back and run the -s loop code and then rerun the code to the bottom.
To fix this, I tried a break or continue command and all I get is indentation errors on this no matter which level I align it with. Can someone help me format this correctly such that I can pull the ipaddress and scac values that I'm grabbing from the arguments and then run the code after the "#if ip address is not defined qpid-route will not work" comment as a separate block.
import re
import os
import sys
import getopt
import pdb
ipaddress = ""
scac = ''
def main(argv):
#print argv
ipaddress = ""
scac = ''
pdb.set_trace()
try:
opts, args = getopt.getopt(argv,"hi:s:",["ipaddress=","scac="])
if not opts: # if no option given
print 'usage test.py -i <ipaddress> -s <scac>'
sys.exit(2)
except getopt.GetoptError:
print 'test.py -i <ipaddress> -s <scac>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'FedConnectStatus.py -i <iobipaddress> -s <scac>'
sys.exit() # it should be on level of if
elif opt in ("-i", "--ipaddress"):
ipaddress = arg
#break
#continue
elif opt in ("-s", "--scac"):
scac = arg
#if ip address is not defined qpid-route will not work
if not ipaddress:
print 'ip address needed'
else:
print(os.getcwd())
#If no scac is given grab every federated connection and report
if not scac:
# open file to read
f = file('qpid.txt', 'r')
nameList = []
statusList = []
#skip first 4 lines
for i in range(3): f.next() # skip first four lines
# iterate over the lines in the file
for line in f:
# split the line into a list of column values
columns = line.split(None, 5)
# clean any whitespace off the items
columns = [col.strip() for col in columns]
# ensure the column has at least one value before printing
if columns:
#print "Name", columns[0] # print the first column
#print "Status", columns[4] # print the last column
nameList.append(columns[0])
statusList.append(columns[4])
#print name
#print status
#else:
print nameList
print statusList
#if __name__ == "__main__":
main(sys.argv[1:])
This statement if not scac: on line 40 and below has indentation different to that of the rest of the code.
You'll see line 38 also doesn't match the indenting of the above if.

Print new line not working in Python

The \n just doesn't seem to work for me when I use it with print. I am using Python 2.7.8. I don't get whats wrong, I think \n with a print should print a new line very straight forwardly.
import sys
import os
import subprocess
from collections import OrderedDict
import xmlrpclib
import hawkey
op_name = sys.argv[1]
pkg_name = sys.argv[2]
# Hawkey Configurations
sack = hawkey.Sack()
path = "/home/thejdeep/test_repo/repodata/%s"
repo = hawkey.Repo("test")
repo.repomd_fn = path % "repomd.xml"
repo.primary_fn = path % "b6f6911f7d9fb63f001388f1ecd0766cec060c1d04c703c6a74969eadc24ec97-primary.xml.gz"
repo.filelists_fn = path % "df5897ed6d3f87f2be4432543edf2f58996e5c9e6a7acee054f9dbfe513df4da-filelists.xml.gz"
sack.load_repo(repo,load_filelists=True)
# Main Function
if __name__ == "__main__":
print "Querying the repository\n"
print "-----------------------\n"
print "Found packages :\n"
print "--------------\n"
q = hawkey.Query(sack)
q = q.filter(name=pkg_name,latest_per_arch=True)[0]
if q:
for pkg in q:
print str(pkg)
else:
print "No packages with name "+pkg_name+" found. Exiting"
sys.exit()
print "--------------------"
print "Performing Dependency Check"
Output is something like this. Basically its printing in the same line :
Querying the repository ----------------------- Found packages : --------------
Using print method automatically add \n at the end of the line so its not necessary put \n at the end of each line.

Python refresh file from disk

I have a python script that calls a system program and reads the output from a file out.txt, acts on that output, and loops. However, it doesn't work, and a close investigation showed that the python script just opens out.txt once and then keeps on reading from that old copy. How can I make the python script reread the file on each iteration? I saw a similar question here on SO but it was about a python script running alongside a program, not calling it, and the solution doesn't work. I tried closing the file before looping back but it didn't do anything.
EDIT:
I already tried closing and opening, it didn't work. Here's the code:
import subprocess, os, sys
filename = sys.argv[1]
file = open(filename,'r')
foo = open('foo','w')
foo.write(file.read().rstrip())
foo = open('foo','a')
crap = open(os.devnull,'wb')
numSolutions = 0
while True:
subprocess.call(["minisat", "foo", "out"], stdout=crap,stderr=crap)
out = open('out','r')
if out.readline().rstrip() == "SAT":
numSolutions += 1
clause = out.readline().rstrip()
clause = clause.split(" ")
print clause
clause = map(int,clause)
clause = map(lambda x: -x,clause)
output = ' '.join(map(lambda x: str(x),clause))
print output
foo.write('\n'+output)
out.close()
else:
break
print "There are ", numSolutions, " solutions."
You need to flush foo so that the external program can see its latest changes. When you write to a file, the data is buffered in the local process and sent to the system in larger blocks. This is done because updating the system file is relatively expensive. In your case, you need to force a flush of the data so that minisat can see it.
foo.write('\n'+output)
foo.flush()
I rewrote it to hopefully be a bit easier to understand:
import os
from shutil import copyfile
import subprocess
import sys
TEMP_CNF = "tmp.in"
TEMP_SOL = "tmp.out"
NULL = open(os.devnull, "wb")
def all_solutions(cnf_fname):
"""
Given a file containing a set of constraints,
generate all possible solutions.
"""
# make a copy of original input file
copyfile(cnf_fname, TEMP_CNF)
while True:
# run minisat to solve the constraint problem
subprocess.call(["minisat", TEMP_CNF, TEMP_SOL], stdout=NULL,stderr=NULL)
# look at the result
with open(TEMP_SOL) as result:
line = next(result)
if line.startswith("SAT"):
# Success - return solution
line = next(result)
solution = [int(i) for i in line.split()]
yield solution
else:
# Failure - no more solutions possible
break
# disqualify found solution
with open(TEMP_CNF, "a") as constraints:
new_constraint = " ".join(str(-i) for i in sol)
constraints.write("\n")
constraints.write(new_constraint)
def main(cnf_fname):
"""
Given a file containing a set of constraints,
count the possible solutions.
"""
count = sum(1 for i in all_solutions(cnf_fname))
print("There are {} solutions.".format(count))
if __name__=="__main__":
if len(sys.argv) == 2:
main(sys.argv[1])
else:
print("Usage: {} cnf.in".format(sys.argv[0]))
You take your file_var and end the loop with file_var.close().
for ... :
ga_file = open(out.txt, 'r')
... do stuff
ga_file.close()
Demo of an implementation below (as simple as possible, this is all of the Jython code needed)...
__author__ = ''
import time
var = 'false'
while var == 'false':
out = open('out.txt', 'r')
content = out.read()
time.sleep(3)
print content
out.close()
generates this output:
2015-01-09, 'stuff added'
2015-01-09, 'stuff added' # <-- this is when i just saved my update
2015-01-10, 'stuff added again :)' # <-- my new output from file reads
I strongly recommend reading the error messages. They hold quite a lot of information.
I think the full file name should be written for debug purposes.

Userfriendly way of handling config files in python?

I want to write a program that sends an e-mail to one or more specified recipients when a certain event occurs. For this I need the user to write the parameters for the mail server into a config. Possible values are for example: serveradress, ports, ssl(true/false) and a list of desired recipients.
Whats the user-friendliest/best-practice way to do this?
I could of course use a python file with the correct parameters and the user has to fill it out, but I wouldn't consider this user friendly. I also read about the 'config' module in python, but it seems to me that it's made for creating config files on its own, and not to have users fill the files out themselves.
Are you saying that the fact that the config file would need to be valid Python makes it unfriendly? It seems like having lines in a file like:
server = 'mail.domain.com'
port = 25
...etc would be intuitive enough while still being valid Python. If you don't want the user to have to know that they have to quote strings, though, you might go the YAML route. I use YAML pretty much exclusively for config files and find it very intuitive, and it would also be intuitive for an end user I think (though it requires a third-party module - PyYAML):
server: mail.domain.com
port: 25
Having pyyaml load it is simple:
>>> import yaml
>>> yaml.load("""a: 1
... b: foo
... """)
{'a': 1, 'b': 'foo'}
With a file it's easy too.
>>> with open('myconfig.yaml', 'r') as cfile:
... config = yaml.load(cfile)
...
config now contains all of the parameters.
I doesn't matter technically proficient your users are; you can count on them to screw up editing a text file. (They'll save it in the wrong place. They'll use MS Word to edit a text file. They'll make typos.) I suggest making a gui that validates the input and creates the configuration file in the correct format and location. A simple gui created in Tkinter would probably fit your needs.
I've been using ConfigParser. It's designed to read .ini style files that have:
[section]
option = value
It's quite easy to use and the documentation is pretty easy to read. Basically you just load the whole file into a ConfigParser object:
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('configfile.txt')
Then you can make sure the users haven't messed anything up by checking the options. I do so with a list:
OPTIONS =
['section,option,defaultvalue',
.
.
.
]
for opt in OPTIONS:
section,option,defaultval = opt.split(',')
if not config.has_option(section,option):
print "Missing option %s in section %s" % (option,section)
Getting the values out is easy too.
val = config.get('section','option')
And I also wrote a function that creates a sample config file using that OPTIONS list.
new_config = ConfigParser.ConfigParser()
for opt in OPTIONS:
section,option,defaultval = opt.split(',')
if not new_config.has_section(section):
new_config.add_section(section)
new_config.set(section, option, defaultval)
with open("sample_configfile.txt", 'wb') as newconfigfile:
new_config.write(newconfigfile)
print "Generated file: sample_configfile.txt"
What are the drawbacks of such a solution:
ch = 'serveradress = %s\nport = %s\nssl = %s'
a = raw_input("Enter the server's address : ")
b = 'a'
bla = "\nEnter the port : "
while not all(x.isdigit() for x in b):
b = raw_input(bla)
bla = "Take care: you must enter digits exclusively\n"\
+" Re-enter the port (digits only) : "
c = ''
bla = "\nChoose the ssl option (t or f) : "
while c not in ('t','f'):
c = raw_input(bla)
bla = "Take care: you must type f or t exclusively\n"\
+" Re-choose the ssl option : "
with open('configfile.txt','w') as f:
f.write(ch % (a,b,c))
.
PS
I've read in the jonesy's post that the value in a config file may have to be quoted. If so, and you want the user not to have to write him/her-self the quotes, you simply add
a = a.join('""')
b = b.join('""')
c = c.join('""')
.
EDIT
ch = 'serveradress = %s\nport = %s\nssl = %s'
d = {0:('',
"Enter the server's address : "),
1:("Take care: you must enter digits exclusively",
"Enter the port : "),
2:("Take care: you must type f or t exclusively",
"Choose the ssl option (t or f) : ") }
def func(i,x):
if x is None:
return False
if i==0:
return True
elif i==1:
try:
ess = int(x)
return True
except:
return False
elif i==2:
if x in ('t','f'):
return True
else:
return False
li = len(d)*[None]
L = range(len(d))
while True:
for n in sorted(L):
bla = d[n][1]
val = None
while not func(n,val):
val = raw_input(bla)
bla = '\n '.join(d[n])
li[n] = val.join('""')
decision = ''
disp = "\n====== If you choose to process, =============="\
+"\n the content of the file will be :\n\n" \
+ ch % tuple(li) \
+ "\n==============================================="\
+ "\n\nDo you want to process (type y) or to correct (type c) : "
while decision not in ('y','c'):
decision = raw_input(disp)
disp = "Do you want to process (type y) or to correct (type c) ? : "
if decision=='y':
break
else:
diag = False
while not diag:
vi = '\nWhat lines do you want to correct ?\n'\
+'\n'.join(str(j)+' - '+line for j,line in enumerate((ch % tuple(li)).splitlines()))\
+'\nType numbers of lines belonging to range(0,'+str(len(d))+') separated by spaces) :\n'
to_modify = raw_input(vi)
try:
diag = all(int(entry) in xrange(len(d)) for entry in to_modify.split())
L = [int(entry) for entry in to_modify.split()]
except:
diag = False
with open('configfile.txt','w') as f:
f.write(ch % tuple(li))
print '-*- Recording of the config file : done -*-'

Categories

Resources