58 up = os.path.dirname(p) |
58 up = os.path.dirname(p) |
59 if up == "/": |
59 if up == "/": |
60 return "/" |
60 return "/" |
61 return up + "/" |
61 return up + "/" |
62 |
62 |
63 def httphdr(type, file="", size=0): |
63 class hgrequest: |
64 sys.stdout.write('Content-type: %s\n' % type) |
64 def __init__(self, inp=None, out=None, env=None): |
65 if file: |
65 self.inp = inp or sys.stdin |
66 sys.stdout.write('Content-disposition: attachment; filename=%s\n' |
66 self.out = out or sys.stdout |
67 % file) |
67 self.env = env or os.environ |
68 if size > 0: |
68 self.form = cgi.parse(self.inp, self.env) |
69 sys.stdout.write('Content-length: %d\n' % size) |
69 |
70 sys.stdout.write('\n') |
70 def write(self, *things): |
71 |
71 for thing in things: |
72 def write(*things): |
72 if hasattr(thing, "__iter__"): |
73 for thing in things: |
73 for part in thing: |
74 if hasattr(thing, "__iter__"): |
74 self.write(part) |
75 for part in thing: |
75 else: |
76 write(part) |
76 try: |
77 else: |
77 self.out.write(thing) |
78 try: |
78 except socket.error, x: |
79 sys.stdout.write(str(thing)) |
79 if x[0] != errno.ECONNRESET: |
80 except socket.error, x: |
80 raise |
81 if x[0] != errno.ECONNRESET: |
81 |
82 raise |
82 def header(self, headers=[('Content-type','text/html')]): |
|
83 for header in headers: |
|
84 self.out.write("%s: %s\r\n" % header) |
|
85 self.out.write("\r\n") |
|
86 |
|
87 def httphdr(self, type, file="", size=0): |
|
88 |
|
89 headers = [('Content-type', type)] |
|
90 if file: |
|
91 headers.append(('Content-disposition', 'attachment; filename=%s' % file)) |
|
92 if size > 0: |
|
93 headers.append(('Content-length', str(size))) |
|
94 self.header(headers) |
83 |
95 |
84 class templater: |
96 class templater: |
85 def __init__(self, mapfile, filters={}, defaults={}): |
97 def __init__(self, mapfile, filters={}, defaults={}): |
86 self.cache = {} |
98 self.cache = {} |
87 self.map = {} |
99 self.map = {} |
686 |
700 |
687 # add tags to things |
701 # add tags to things |
688 # tags -> list of changesets corresponding to tags |
702 # tags -> list of changesets corresponding to tags |
689 # find tag, changeset, file |
703 # find tag, changeset, file |
690 |
704 |
691 def run(self): |
705 def run(self, req=hgrequest()): |
692 def header(**map): |
706 def header(**map): |
693 yield self.t("header", **map) |
707 yield self.t("header", **map) |
694 |
708 |
695 def footer(**map): |
709 def footer(**map): |
696 yield self.t("footer", **map) |
710 yield self.t("footer", **map) |
697 |
711 |
698 self.refresh() |
712 self.refresh() |
699 args = cgi.parse() |
|
700 |
713 |
701 t = self.repo.ui.config("web", "templates", templatepath()) |
714 t = self.repo.ui.config("web", "templates", templatepath()) |
702 m = os.path.join(t, "map") |
715 m = os.path.join(t, "map") |
703 style = self.repo.ui.config("web", "style", "") |
716 style = self.repo.ui.config("web", "style", "") |
704 if args.has_key('style'): |
717 if req.form.has_key('style'): |
705 style = args['style'][0] |
718 style = req.form['style'][0] |
706 if style: |
719 if style: |
707 b = os.path.basename("map-" + style) |
720 b = os.path.basename("map-" + style) |
708 p = os.path.join(t, b) |
721 p = os.path.join(t, b) |
709 if os.path.isfile(p): |
722 if os.path.isfile(p): |
710 m = p |
723 m = p |
711 |
724 |
712 port = os.environ["SERVER_PORT"] |
725 port = req.env["SERVER_PORT"] |
713 port = port != "80" and (":" + port) or "" |
726 port = port != "80" and (":" + port) or "" |
714 uri = os.environ["REQUEST_URI"] |
727 uri = req.env["REQUEST_URI"] |
715 if "?" in uri: |
728 if "?" in uri: |
716 uri = uri.split("?")[0] |
729 uri = uri.split("?")[0] |
717 url = "http://%s%s%s" % (os.environ["SERVER_NAME"], port, uri) |
730 url = "http://%s%s%s" % (req.env["SERVER_NAME"], port, uri) |
718 |
731 |
719 self.t = templater(m, common_filters, |
732 self.t = templater(m, common_filters, |
720 {"url": url, |
733 {"url": url, |
721 "repo": self.reponame, |
734 "repo": self.reponame, |
722 "header": header, |
735 "header": header, |
723 "footer": footer, |
736 "footer": footer, |
724 }) |
737 }) |
725 |
738 |
726 if not args.has_key('cmd'): |
739 if not req.form.has_key('cmd'): |
727 args['cmd'] = [self.t.cache['default'],] |
740 req.form['cmd'] = [self.t.cache['default'],] |
728 |
741 |
729 if args['cmd'][0] == 'changelog': |
742 if req.form['cmd'][0] == 'changelog': |
730 c = self.repo.changelog.count() - 1 |
743 c = self.repo.changelog.count() - 1 |
731 hi = c |
744 hi = c |
732 if args.has_key('rev'): |
745 if req.form.has_key('rev'): |
733 hi = args['rev'][0] |
746 hi = req.form['rev'][0] |
734 try: |
747 try: |
735 hi = self.repo.changelog.rev(self.repo.lookup(hi)) |
748 hi = self.repo.changelog.rev(self.repo.lookup(hi)) |
736 except RepoError: |
749 except RepoError: |
737 write(self.search(hi)) |
750 req.write(self.search(hi)) |
738 return |
751 return |
739 |
752 |
740 write(self.changelog(hi)) |
753 req.write(self.changelog(hi)) |
741 |
754 |
742 elif args['cmd'][0] == 'changeset': |
755 elif req.form['cmd'][0] == 'changeset': |
743 write(self.changeset(args['node'][0])) |
756 req.write(self.changeset(req.form['node'][0])) |
744 |
757 |
745 elif args['cmd'][0] == 'manifest': |
758 elif req.form['cmd'][0] == 'manifest': |
746 write(self.manifest(args['manifest'][0], args['path'][0])) |
759 req.write(self.manifest(req.form['manifest'][0], req.form['path'][0])) |
747 |
760 |
748 elif args['cmd'][0] == 'tags': |
761 elif req.form['cmd'][0] == 'tags': |
749 write(self.tags()) |
762 req.write(self.tags()) |
750 |
763 |
751 elif args['cmd'][0] == 'filediff': |
764 elif req.form['cmd'][0] == 'filediff': |
752 write(self.filediff(args['file'][0], args['node'][0])) |
765 req.write(self.filediff(req.form['file'][0], req.form['node'][0])) |
753 |
766 |
754 elif args['cmd'][0] == 'file': |
767 elif req.form['cmd'][0] == 'file': |
755 write(self.filerevision(args['file'][0], args['filenode'][0])) |
768 req.write(self.filerevision(req.form['file'][0], req.form['filenode'][0])) |
756 |
769 |
757 elif args['cmd'][0] == 'annotate': |
770 elif req.form['cmd'][0] == 'annotate': |
758 write(self.fileannotate(args['file'][0], args['filenode'][0])) |
771 req.write(self.fileannotate(req.form['file'][0], req.form['filenode'][0])) |
759 |
772 |
760 elif args['cmd'][0] == 'filelog': |
773 elif req.form['cmd'][0] == 'filelog': |
761 write(self.filelog(args['file'][0], args['filenode'][0])) |
774 req.write(self.filelog(req.form['file'][0], req.form['filenode'][0])) |
762 |
775 |
763 elif args['cmd'][0] == 'heads': |
776 elif req.form['cmd'][0] == 'heads': |
764 httphdr("application/mercurial-0.1") |
777 req.httphdr("application/mercurial-0.1") |
765 h = self.repo.heads() |
778 h = self.repo.heads() |
766 sys.stdout.write(" ".join(map(hex, h)) + "\n") |
779 req.write(" ".join(map(hex, h)) + "\n") |
767 |
780 |
768 elif args['cmd'][0] == 'branches': |
781 elif req.form['cmd'][0] == 'branches': |
769 httphdr("application/mercurial-0.1") |
782 req.httphdr("application/mercurial-0.1") |
770 nodes = [] |
783 nodes = [] |
771 if args.has_key('nodes'): |
784 if req.form.has_key('nodes'): |
772 nodes = map(bin, args['nodes'][0].split(" ")) |
785 nodes = map(bin, req.form['nodes'][0].split(" ")) |
773 for b in self.repo.branches(nodes): |
786 for b in self.repo.branches(nodes): |
774 sys.stdout.write(" ".join(map(hex, b)) + "\n") |
787 req.write(" ".join(map(hex, b)) + "\n") |
775 |
788 |
776 elif args['cmd'][0] == 'between': |
789 elif req.form['cmd'][0] == 'between': |
777 httphdr("application/mercurial-0.1") |
790 req.httphdr("application/mercurial-0.1") |
778 nodes = [] |
791 nodes = [] |
779 if args.has_key('pairs'): |
792 if req.form.has_key('pairs'): |
780 pairs = [map(bin, p.split("-")) |
793 pairs = [map(bin, p.split("-")) |
781 for p in args['pairs'][0].split(" ")] |
794 for p in req.form['pairs'][0].split(" ")] |
782 for b in self.repo.between(pairs): |
795 for b in self.repo.between(pairs): |
783 sys.stdout.write(" ".join(map(hex, b)) + "\n") |
796 req.write(" ".join(map(hex, b)) + "\n") |
784 |
797 |
785 elif args['cmd'][0] == 'changegroup': |
798 elif req.form['cmd'][0] == 'changegroup': |
786 httphdr("application/mercurial-0.1") |
799 req.httphdr("application/mercurial-0.1") |
787 nodes = [] |
800 nodes = [] |
788 if not self.allowpull: |
801 if not self.allowpull: |
789 return |
802 return |
790 |
803 |
791 if args.has_key('roots'): |
804 if req.form.has_key('roots'): |
792 nodes = map(bin, args['roots'][0].split(" ")) |
805 nodes = map(bin, req.form['roots'][0].split(" ")) |
793 |
806 |
794 z = zlib.compressobj() |
807 z = zlib.compressobj() |
795 f = self.repo.changegroup(nodes) |
808 f = self.repo.changegroup(nodes) |
796 while 1: |
809 while 1: |
797 chunk = f.read(4096) |
810 chunk = f.read(4096) |
798 if not chunk: |
811 if not chunk: |
799 break |
812 break |
800 sys.stdout.write(z.compress(chunk)) |
813 req.write(z.compress(chunk)) |
801 |
814 |
802 sys.stdout.write(z.flush()) |
815 req.write(z.flush()) |
803 |
816 |
804 elif args['cmd'][0] == 'archive': |
817 elif req.form['cmd'][0] == 'archive': |
805 changeset = bin(args['node'][0]) |
818 changeset = bin(req.form['node'][0]) |
806 type = args['type'][0] |
819 type = req.form['type'][0] |
807 if (type in self.archives and |
820 if (type in self.archives and |
808 self.repo.ui.configbool("web", "allow" + type, False)): |
821 self.repo.ui.configbool("web", "allow" + type, False)): |
809 self.archive(changeset, type) |
822 self.archive(req, changeset, type) |
810 return |
823 return |
811 |
824 |
812 write(self.t("error")) |
825 req.write(self.t("error")) |
813 |
826 |
814 else: |
827 else: |
815 write(self.t("error")) |
828 req.write(self.t("error")) |
816 |
829 |
817 def create_server(repo): |
830 def create_server(repo): |
818 |
831 |
819 def openlog(opt, default): |
832 def openlog(opt, default): |
820 if opt and opt != '-': |
833 if opt and opt != '-': |