Wang Dingwei avatar Wang Dingwei committed 1e8710c

using custom email module instead of hgext.notify

Comments (0)

Files changed (7)

+import os
 import logging
 import logging.handlers
-from configparser import ConfigParser
+from ConfigParser import ConfigParser
 
 from mercurial import ui
 
 VERSION = '0.7'
 CONFIG_FILE = 'settings.ini'
 LOGNAME = 'hgsync.log'
-
+HGIGNORE = os.path.join('templates', 'hgignore.template')
+HGRC = os.path.join('templates', 'hgrc.template')
 
 
 def get_logger():
         self.cfg.read(self.cfg_file)
         self._groups = None
         self.init_dirs()
-
+    
+    @property
     def path_groups(self):
         "Returns groups of paths"
         newtime = os.path.getmtime(self.cfg_file)
                 return self._groups
 
         groups = []
-        for sect in cfg.sections():
-            if sect.startswith('/'):
-                roots = cfg.get(sect, 'paths').split()
-                paths = [os.path.join(sect, loc) for loc in roots]
+        for sect in self.cfg.sections():
+            if sect.startswith('\\'):
+                roots = self.cfg.get(sect, 'group').split()
+                paths = [os.path.join(loc, sect.lstrip('\\')) 
+                         for loc in roots]
                 groups.append(paths)
         
         self._groups = groups
-
+        
         return groups
 
     def init_dirs(self):
         "Create directories if not exist."
-        for group in self.path_groups():
+        for group in self.path_groups:
             for path in group:
                 if not os.path.exists(path):
                     os.makedirs(path)
                         os.makedirs(path)
 
 logger = get_logger()
+ui = ui.ui()
 config = Config(CONFIG_FILE)
-ui = ui.ui()
 import os
+import shutil
 import logging, logging.config
 from datetime import datetime
 from mercurial import commands, hg
 
-from config import logger
-
+from config import logger, HGIGNORE, HGRC
+from util import makemail, sendmail
 
 def auto_branch_name(dest):
     "generates branch name based on datetime.now()"
 
 def init(ui, dest):
     "Initiate hg repo in dest."
+    logger.info("Initiating repo %s" % dest)
     commands.init(ui, dest=dest)
-
-
-def diff(ui, dest):
-    "Returns diff output for destpath"
-    repo = hg.repository(ui, dest)
-    ui.pushbuffer()
-    commands.diff(ui, repo)
-    return ui.popbuffer()
+    shutil.copy(HGIGNORE, os.path.join(dest, '.hgignore'))
+    shutil.copy(HGRC, os.path.join(dest, '.hg', 'hgrc'))
 
 
 def commit(ui, dest, user, comment):
     return len(filter(lambda x: len(x)!=0, stat)) != 0
 
 
+def diff(ui, dest):
+    repo = hg.repository(ui, dest)
+    ui.flush()
+    ui.pushbuffer()
+    commands.diff(ui, repo)
+    return ui.popbuffer()
+
+
 def autosync(ui, project_dir, syncgroup, user, message):
     "Recursively synchronizes changes of all project dirs"
     ui.pushbuffer()
+
+    frm = ui.config('email', 'from')
+    to = ui.config('email', 'to')
+    server = ui.config('smtp', 'host')
+    subject = '%s changed - %s' % (project_dir, message)
+    msg = makemail(frm, subject, to, diff(ui, project_dir))
+    sendmail(server, frm, to, msg)
+    
     commit(ui, project_dir, user, message)
+    
     for syncdir in syncgroup:
         logger.info("Synchronizing %s" % syncdir)
         if repo_is_changed(ui, syncdir):
 import os
+import sys
 import time
 from config import logger, config, ui
-from hgsync import autosync
-
-def with_doing(func):
-    "Decorator to add 'doing' flags for all actions."
-    def wrapper(*args, **kwargs):
-        flag = os.path.join(args[-1], 'DOING')
-        f = open(flag, 'w')
-        f.close()
-        func(args)
-        os.remove(flag)
-    return wrapper
-
-class SyncGroup(object):
-    "A group of directories needs to be synced"
-
-    command_actions = [self.synchronize, self.rollback, self.getlogs]
-    status_actions = [self.doing_, self.locked_, self.error_]
-
-    def __init__(self, dirs):
-        self.dirs = dirs
-        self.is_clean = True
-
-    def check_status(self):
-        "Checks for status flags."
-        for action in self.status_actions:
-            for d in self.dirs.copy():
-                action(d)
-
-    def run(self):
-        "Run all checks and actions against the directory group."
-        self.check_status()
-        if not self.is_clean:
-            return 
-        for d in self.dirs:
-            for action in command_actions:
-                    action(d)
-                    
-    def locked_(self, path):
-        "For processing LOCKED flag. -- Ignore the path."
-        flag = os.path.join(path, 'LOCKED')
-        if os.path.exists(flag):
-            self.dirs.remove(path)
-            logger.debug("%s is locked and will be skipped." % path)
-
-    def doing_(self, path):
-        "For processing DOING flag -- Just remove the flag."
-        flag = os.path.join(path, 'DOING')
-        if os.path.exists(flag):
-            if time.time() - os.path.getmtime(flag) > 300:
-                shutil.remove(flag)
-            else:
-                self.is_clean = False
-                logger.warning("'DOING' flag exists in %s" % path)
-
-    def error_(self, path):
-        logger.warning("'ERROR' flag exists in %s" % path)
-
-    @with_doing
-    def synchronize(self, path):
-        "For processing SYNC! flag."
-        flag = os.path.join(path, 'SYNC'!)
-        def parse_flag(flag):
-            with open(flag) as f:
-                user, msg = tuple(f.readline().strip().split(' ', 1))
-            return user, msg
-        user, comment = parse_flag(flag)
-
-        os.remove(flag)
-        dest_dirs = self.dirs.remove(path)
-        autosync(ui, path, dest_dirs, user, msg)
-    
-    @with_doing
-    def rollback(self, path):
-        "For processing BACK! flag."
-        flag = os.path.join(path, 'BACK!')
-        def parse_flag(flag):
-            with open(flag) as f:
-                user, rev = tuple(f.readline().strip().split(' ', 1))
-            return user, int(rev)          
-        user, rev = parse_flag(flag)
-        os.remove(flag)
-        rollback(ui, path, user, rev=rev)
-    
-    @with_doing
-    def getlog(self, path):
-        "Generates a file of changelogs."
-        flag = os.path.join(path, 'STAT!')
-        rev = parse_flag(flag)
-        os.remove(flag)
-        hg_log(ui, path, 'CHANGES.LOG')
+from model import SyncGroup
 
 
 def main():
     while True:
-        grouplist = load_config(cfg_file)
-        for group in groupist:
+        time.sleep(1)
+        for group in config.path_groups:
             worker = SyncGroup(group)
             worker.run()
 
+import os
+import time
+from functools import wraps
+
+from hgcmd import init, autosync
+from config import logger, ui
+
+def with_doing(func):
+    "Decorator to add 'doing' flags for all actions."
+    @wraps(func)
+    def wrapper(*args, **kwargs):
+        flag = os.path.join(args[-1], 'DOING')
+        f = open(flag, 'w')
+        f.close()
+        func(*args, **kwargs)
+        os.remove(flag)
+    return wrapper
+
+class SyncGroup(object):
+    "A group of directories needs to be synced"
+
+    def __init__(self, dirs):
+        self.dirs = dirs
+        self.is_clean = True
+        self.command_actions = [self.synchronize, self.rollback, self.getlog]
+        self.status_actions = [self.doing_, self.locked_, self.error_]
+        for d in self.dirs:
+            if not os.path.exists(os.path.join(d, '.hg')):
+                init(ui, d)
+    
+    def check_status(self):
+        "Checks for status flags."
+        for action in self.status_actions:
+            for d in self.dirs[:]:
+                action(d)
+
+    def run(self):
+        "Run all checks and actions against the directory group."
+        self.check_status()
+        if not self.is_clean:
+            return 
+        for d in self.dirs:
+            for action in self.command_actions:
+                    action(d)
+                    
+    def locked_(self, path):
+        "For processing LOCKED flag. -- Ignore the path."
+        flag = os.path.join(path, 'LOCKED')
+        if os.path.exists(flag):
+            self.dirs.remove(path)
+            logger.debug("%s is locked and will be skipped." % path)
+
+    def doing_(self, path):
+        "For processing DOING flag -- Just remove the flag."
+        flag = os.path.join(path, 'DOING')
+        if os.path.exists(flag):
+            os.remove(flag)
+
+    def error_(self, path):
+        flag = os.path.join(path, 'ERROR')
+        if os.path.exists(flag):
+            if time.time() - os.path.getmtime(flag) > 300:
+                os.remove(flag)
+            else:
+                self.is_clean = False
+                logger.warning("'ERROR' flag exists in %s" % path)
+
+    @with_doing
+    def synchronize(self, path):
+        "For processing SYNC! flag."
+        flag = os.path.join(path, 'SYNC!')
+        if not os.path.exists(flag):
+            return
+
+        def parse_flag(flag):
+            with open(flag) as f:
+                user, msg = tuple(f.readline().strip().split(' ', 1))
+            return user, msg
+        
+        user, msg = parse_flag(flag)
+        os.remove(flag)
+        autosync(ui, path, self.dirs, user, msg)
+    
+    @with_doing
+    def rollback(self, path):
+        "For processing BACK! flag."
+        flag = os.path.join(path, 'BACK!')
+        if not os.path.exists(flag):
+            return
+
+        def parse_flag(flag):
+            with open(flag) as f:
+                user, rev = tuple(f.readline().strip().split(' ', 1))
+            return user, int(rev)          
+        
+        user, rev = parse_flag(flag)
+        os.remove(flag)
+        rollback(ui, path, user, rev=rev)
+    
+    @with_doing
+    def getlog(self, path):
+        "Generates a file of changelogs."
+        flag = os.path.join(path, 'STAT!')
+        if not os.path.exists(flag):
+            return
+
+        rev = parse_flag(flag)
+        os.remove(flag)
+        hg_log(ui, path, 'CHANGES.LOG')
+
 [DEFAULT]
-all=\\192.168.200.1
-    \\192.168.200.2
-    \\192.168.200.3
-    \\192.168.200.4
-    \\192.168.200.16
-    \\192.168.200.17
-    \\192.168.200.18
-    \\192.168.200.20
-    \\192.168.200.21
-    \\192.168.200.22
-    \\192.168.200.23
+email=True
+mailserver=wksmail.wistron.com
+sender=filter@wistron.com
+receiver=joel_wang@wistron.com
 
-[IMAGE\IMAGE\LAYER]
-location=%(all)s
+
+[\4XX01]
+group=test\1 test\2 test\3

templates/hgrc.template

 [ui]
-quiet=True
+verbose = false
+debug = false
+quiet = true
 
-[extensions]
+[email]
+from = test@wistron.com
+to = joel_wang@wistron.com
+
+[smtp]
+host = wksmail.wistron.com
+
+# -*- coding: utf-8 -*-
+import os
+import smtplib
+
+from email.mime.text import MIMEText
+from email.mime.multipart import MIMEMultipart
+from email.mime.base import MIMEBase
+from email import encoders as Encoders
+
+from datetime import date, timedelta
+
+def makemail(sender, subject, receiver, message, attachment=None, attas=None):
+    """Generates an email message.
+    sender(str) -> mail address of the sender
+    subject(str) -> Subject of the mail
+    receiver(str) -> mail address of the receiver
+    message(str) -> mail context, as html
+    attachment(str filepath or file like object)
+    attas(str) -> attach as filename. If not specified, attachment or
+        attachment.name will be used"""
+    msg = MIMEMultipart()
+    msg['From'] = sender
+    msg['To'] = receiver
+    msg['Subject'] = subject
+    msg.attach(MIMEText(message, 'html'))
+    if attachment:
+        part = MIMEBase('application', 'octet-stream')
+        if isinstance(attachment, str):
+            part.set_payload(open(attachment, 'rb').read())
+            fname = os.path.split(attachment)[1]
+        elif hasattr(attachment, 'read'):
+            part.set_payload(attachment.read())
+            fname = os.path.split(attachment.name)[1]
+        else:
+            raise
+    if attas:
+        fname = attas
+        part.add_header('Content-Disposition', 'attachment', filename=fname)
+        Encoders.encode_base64(part)
+        msg.attach(part)
+    return msg
+
+def sendmail(server, sender, receiver, msg):
+    "Sends out an email message."
+    server = smtplib.SMTP(server)
+    try:
+        server.sendmail(sender, receiver, msg.as_string())
+    except Exception, e:
+        raise
+    finally:
+        server.quit()
+
+def iterdate(start, end=date.today(), reverse=False):
+    """Yields datetime.date object of the specified time period and order.
+    
+    >>> it = iterdate(date(2011, 1, 1))
+    >>> it.next()
+    datetime.date(2011, 1, 1)
+    >>> it.next()
+    datetime.date(2011, 1, 2)
+    """
+    while start <= end:
+        if reverse:
+            yield end
+            end -= timedelta(1)
+        else:
+            yield start
+            start += timedelta(1)
+    return
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.