I would like to use git-multimail as post receive hook in one of my git repositories (no gitolite used). Unfortunately, I cannot get it work, and I have hardly any experience using Python.
What I did so far:
I added the following block to the project.git/config file:
[multimailhook]
mailingList = email#example.com
from = email#example.com
envelopeSender = email#example.com
mailer = smtp
smtpServer = smtp.mydomain.com
smtpUser = myUser
smtpPass = myPassword
Please note that I do not know whether "smtp", which is defined in the mailer variable, is installed on my machine.
I copied the current git_multimail.py file into project.git/hooks.
I created a project.git/hook/post-receive file with the following content. The file is executable, I copied this from https://github.com/git-multimail/git-multimail/blob/master/git-multimail/post-receive.example
#! /usr/bin/env python
import sys
import os
import git_multimail
config = git_multimail.Config('multimailhook')
try:
environment = git_multimail.GenericEnvironment(config=config)
#environment = git_multimail.GitoliteEnvironment(config=config)
except git_multimail.ConfigurationException:
sys.stderr.write('*** %s\n' % sys.exc_info()[1])
sys.exit(1)
mailer = git_multimail.choose_mailer(config, environment)
git_multimail.run_as_post_receive_hook(environment, mailer)
What happens:
When I push a change, a file project.git/hooks/git_multimail.pyc is created, but no email is sent.
Doing a configuration test using GIT_MULTIMAIL_CHECK_SETUP=true python git_multimail.py as described on https://github.com/git-multimail/git-multimail/blob/master/doc/troubleshooting.rst tells me that git-multimail seems properly set up
Is there a way to log something like an output of the script? What can I do to find out what is not working? Are there even errors in my files?
Thanks in advance.
Using post-receive.example is by far not the simplest way to set up git_multimail.py: as the header of post-receive.example script says:
The simplest way to use git-multimail is to use the script
git_multimail.py directly as a post-receive hook, and to configure it
using Git's configuration files and command-line parameters.
In other words, just
cp /path/to/git_multimail.py /path/to/project.git/hooks/post-receive
and you're all set (since you already have project.git/config filled-in). See Invocation in git-multimail's README for a bit more detail.
(note: admitedly, the doc is not so clear for beginners, I'll try to improve that when I get time)
OK guys, the error was probably as little as it could be. I did just one very little mistake in the post receive hook file: The sys.exit(1) command is not indented.
So, the WRONG version from my question:
try:
environment = git_multimail.GenericEnvironment(config=config)
except git_multimail.ConfigurationException:
sys.stderr.write('*** %s\n' % sys.exc_info()[1])
sys.exit(1)
CORRECT is (compare last line):
try:
environment = git_multimail.GenericEnvironment(config=config)
except git_multimail.ConfigurationException:
sys.stderr.write('*** %s\n' % sys.exc_info()[1])
sys.exit(1)
Like I said, I hardly know Python, so I did not pay attention to the indents. After correcting this, the email was sent, so feel free to use the above steps as a little tutorial for setting up git-multimail the "easiest" way. (I did not find a tutorial for this exact solution.)
Related
I'm trying to get the patches for a given revision using hglib. I know the hg command is
hg log -pr rev
but I can't find how to do this or equivalent with hglib. It seems there is not functionality to do that, unless I hack the code myself to run the above command. Any help would be greatly appreciated?
The hglib client.log() interface doesn't support what I wanted to do, but I found a simple way to run an arbitrary hg command. This two lines print the patch of revision rev:
out = client.rawcommand([b'log', b'-pr', b'%i'%rev])
print(str(out, 'utf-8'))
May be this is the actual answer!
import hglib
client = hglib.open(<path>)
client.export (revs = str(<revision number>), output = <output file path>)
You can execute the same with subprocess package by yourself to save interpretation time. Rawcommand just builds a command with the parameters we pass and executes with subprocess again.
I'm editing a program called TF2idle that can be seen here:
http://facepunch.com/showthread.php?t=1161862
I'm adding a button to defrag any of the accounts that are selected using the person's source he has available.
I found in the python files that this is where all the magic happens and is what I need to edit to add my Defrag button.
http://pastebin.com/9PjzqU5u
Lines 136 - 142 and 328-337 I added myself. These lines are below:
startDefragIcon = QtGui.QIcon()
startDefragIcon.addPixmap(QtGui.QPixmap(returnResourcePath('images/defrag.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.startDefragAction = self.mainwindow.htoolBar.addAction(startDefragIcon, 'Defrag Accounts')
QtCore.QObject.connect(self.startDefragAction, QtCore.SIGNAL('triggered()'), curry(self.startUpAccounts, action='start_Defrag'))
and
if action == 'start_Defrag':
command = r'"%s/Steam.exe" -login %s %s' % (sandbox_install, username, password)
if easy_sandbox_mode == 'yes' and self.settings.get_option('Account-' + account, 'sandbox_install') == '':
self.commandthread.addSandbox('TF2Idle' + username)
self.createdSandboxes.append(username)
command = r'"%s/Start.exe" /box:%s %s' % (sandboxielocation, 'TF2Idle' + username, command)
else:
command = r'"%s/Start.exe" /box:%s %s' % (sandboxielocation, sandboxname, command)
#Right here add script to launch steam://defrag/440
A way the program can defrag the accounts is to launch "steam://defrag/440" and that will automatically do it. For an example, I can put in my google chrome address bar that address and it will tell steam to defrag the program with the ID 440, which is TF2.
Thing is, I have no idea how to add that to the script. I was thinking of adding a BAT file which would have "steam://defrag/440" inside it and add a line that would launch said BAT file at line 336.
I'm hoping someone here knows how I can accomplish this.
Second problem is that I have no idea how to turn all these source files after I finished editing into an .EXE. I know this is all advanced for me, but I gotta start learning if I want to go to college for computer science, plus this would really help out many users using this tool.
I suspect you want the webbrowser module:
import webbrowser
webbrowser.open_new('steam://defrag/440')
If all you want to do is a request to that address, python supplies simple modules to handle it.
from httplib2 import Http
h = Http
h.request('steam://defrag/440', 'GET')
This may not qualify as an answer per se, but since your question doesn't really qualify as a question either (:-P), here are some tips:
The Steam client registers itself as a URL handler for the steam:// protocol.
You should be able to achieve the workflow you proposed using the webbrowser module.
Anything you can do in a BAT file, you can do in a Python script.
In general, Python scripts are not compiled (e.g. to .exe files). That said, there is py2exe which wraps the interpreter, code, and dependencies into a .exe file package.
EDIT: See Eric's comment on your question regarding the last bit.
I am trying to use paramiko to download a file via SFTP. I create the SFTP object like this:
transport = paramiko.Transport((sftp_server, sftp_port))
transport.connect(username = sftp_login, password = sftp_password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.get("file_name", '.', None)
and, I get the exception:
Exception python : Folder not found: \\$IP_ADDRESS\folder_1/folder_2\file_name.
I'm running paramiko to connect to a client chrooted SFTP. The file, 'file_name', is located at the root of my client's chroot.
I don't get why I have this error showing apparently the full path (outside the chroot) of my client's server.
I don't know why my dummy file is not going to be downloaded :O
I will provide any necessary information.
The following code worked for me in Ubuntu 11.10:
sftp.get("file_name", "file_name")
I just made a couple of changes that shouldn't affect to your problem:
localpath: Used full path to the local file name instead of just '.' (directories aren't allowed)
callback: Removed it since None is already the default value and that's not really needed
Since I'm not getting the same error you're getting regarding the remotepath parameter, I guess you might be using a different sftp server that has a different behaviour.
My advice would be to:
Verify with another client, for example the sftp command, that the file you're looking for is really where you are trying to get it.
Use sftp.chdir just to make sure that the default directory being used is the one you expect.
I hope this helps.
My problem is that logging stops for a python program when the log is rotated.
I have tracked it down to the stream itself. I don't see any way to tell if the stream is broken from python. After the file is deleted it still accepts writes without any issue.
import os
FILE = 'testing.txt'
fs = open(FILE, 'a')
fs.write('word')
os.remove(FILE)
fs.write('Nothing....') # Nothing breaks
print(fs.errors) # No errors
So, how can I find out if the file stream is still valid?
And checking to see if the file exists will not help since the file will always exist regardless of whether or not the stream is still valid.
Upon much more inspection, I found the solution. It is an OS specific problem. When the file is deleted in Linux (or Macintosh) it just unlinks it. (I was not aware of this)
So if you run lsof on the machine, it still shows the file as open.
[user#machine]$ lsof | grep --color -i "testing.txt"
python26 26495 user 8w REG 8,33 23474 671920 /home/user/temp/testing.txt (deleted)
The solution is to stat the stream in python.
stat = os.fstat(fs.fileno())
Which will give you the number of links it has.
if stat.st_nlink < 1:
#has been deleted
And there you go. Now you know if you should reload it or not. Hopefully this helps someone else.
Try Exception handling:
import os
FILE = 'testing.txt'
try:
fs = open(FILE, 'a')
fs.write('word')
os.remove(FILE)
fs.write('Nothing....') # Nothing breaks
except Exception, e:
print "Error:", e
print(fs.errors) # No errors
There are python bindings for ionotify if you need more intelligence than just an try: except: clause. But I think its only pertinent to Linux (im not sure of your platform)
Another solution I found is to add the "copytruncate" flag into the logrotate config.
See "man logrotate" for more info.
I'm trying to save myself just a few keystrokes for a command I type fairly regularly in Python.
In my python startup script, I define a function called load which is similar to import, but adds some functionality. It takes a single string:
def load(s):
# Do some stuff
return something
In order to call this function I have to type
>>> load('something')
I would rather be able to simply type:
>>> load something
I am running Python with readline support, so I know there exists some programmability there, but I don't know if this sort of thing is possible using it.
I attempted to get around this by using the InteractivConsole and creating an instance of it in my startup file, like so:
import code, re, traceback
class LoadingInteractiveConsole(code.InteractiveConsole):
def raw_input(self, prompt = ""):
s = raw_input(prompt)
match = re.match('^load\s+(.+)', s)
if match:
module = match.group(1)
try:
load(module)
print "Loaded " + module
except ImportError:
traceback.print_exc()
return ''
else:
return s
console = LoadingInteractiveConsole()
console.interact("")
This works with the caveat that I have to hit Ctrl-D twice to exit the python interpreter: once to get out of my custom console, once to get out of the real one.
Is there a way to do this without writing a custom C program and embedding the interpreter into it?
Edit
Out of channel, I had the suggestion of appending this to the end of my startup file:
import sys
sys.exit()
It works well enough, but I'm still interested in alternative solutions.
You could try ipython - which gives a python shell which does allow many things including automatic parentheses which gives you the function call as you requested.
I think you want the cmd module.
See a tutorial here:
http://wiki.python.org/moin/CmdModule
Hate to answer my own question, but there hasn't been an answer that works for all the versions of Python I use. Aside from the solution I posted in my question edit (which is what I'm now using), here's another:
Edit .bashrc to contain the following lines:
alias python3='python3 ~/py/shellreplace.py'
alias python='python ~/py/shellreplace.py'
alias python27='python27 ~/py/shellreplace.py'
Then simply move all of the LoadingInteractiveConsole code into the file ~/py/shellreplace.py Once the script finishes executing, python will cease executing, and the improved interactive session will be seamless.