Beispiel #1
0
 def actionCertAdd(self, to, domain, auth_type, auth_user_name, cert):
     try:
         res = self.user.addCert(self.user.getAuthAddress(self.site.address), domain, auth_type, auth_user_name, cert)
         if res is True:
             self.cmd(
                 "notification",
                 ["done", _("{_[New certificate added]:} <b>{auth_type}/{auth_user_name}@{domain}</b>.")]
             )
             self.user.setCert(self.site.address, domain)
             self.site.updateWebsocket(cert_changed=domain)
             self.response(to, "ok")
         elif res is False:
             # Display confirmation of change
             cert_current = self.user.certs[domain]
             body = _("{_[Your current certificate]:} <b>{cert_current[auth_type]}/{cert_current[auth_user_name]}@{domain}</b>")
             self.cmd(
                 "confirm",
                 [body, _("Change it to {auth_type}/{auth_user_name}@{domain}")],
                 lambda (res): self.cbCertAddConfirm(to, domain, auth_type, auth_user_name, cert)
             )
         else:
             self.response(to, "Not changed")
     except Exception, err:
         self.log.error("CertAdd error: Exception - %s" % err.message)
         self.response(to, {"error": err.message})
Beispiel #2
0
 def actionCertAdd(self, to, domain, auth_type, auth_user_name, cert):
     try:
         res = self.user.addCert(self.user.getAuthAddress(self.site.address), domain, auth_type, auth_user_name, cert)
         if res is True:
             self.cmd(
                 "notification",
                 ["done", _("{_[New certificate added]:} <b>{auth_type}/{auth_user_name}@{domain}</b>.")]
             )
             self.user.setCert(self.site.address, domain)
             self.site.updateWebsocket(cert_changed=domain)
             self.response(to, "ok")
         elif res is False:
             # Display confirmation of change
             cert_current = self.user.certs[domain]
             body = _("{_[Your current certificate]:} <b>{cert_current[auth_type]}/{cert_current[auth_user_name]}@{domain}</b>")
             self.cmd(
                 "confirm",
                 [body, _("Change it to {auth_type}/{auth_user_name}@{domain}")],
                 lambda (res): self.cbCertAddConfirm(to, domain, auth_type, auth_user_name, cert)
             )
         else:
             self.response(to, "Not changed")
     except Exception, err:
         self.log.error("CertAdd error: Exception - %s" % err.message)
         self.response(to, {"error": err.message})
Beispiel #3
0
    def actionCertSelect(self, to, accepted_domains=[], accept_any=False):
        accounts = []
        accounts.append(["", _["Unique to site"], ""])  # Default option
        active = ""  # Make it active if no other option found

        # Add my certs
        auth_address = self.user.getAuthAddress(
            self.site.address)  # Current auth address
        for domain, cert in self.user.certs.items():
            if auth_address == cert["auth_address"]:
                active = domain
            title = cert["auth_user_name"] + "@" + domain
            if domain in accepted_domains or not accepted_domains or accept_any:
                accounts.append([domain, title, ""])
            else:
                accounts.append([domain, title, "disabled"])

        # Render the html
        body = "<span style='padding-bottom: 5px; display: inline-block'>" + _[
            "Select account you want to use in this site:"] + "</span>"
        # Accounts
        for domain, account, css_class in accounts:
            if domain == active:
                css_class += " active"  # Currently selected option
                title = _(u"<b>%s</b> <small>({_[currently selected]})</small>"
                          ) % account
            else:
                title = "<b>%s</b>" % account
            body += "<a href='#Select+account' class='select select-close cert %s' title='%s'>%s</a>" % (
                css_class, domain, title)
        # More available  providers
        more_domains = [
            domain for domain in accepted_domains
            if domain not in self.user.certs
        ]  # Domains we not displayed yet
        if more_domains:
            # body+= "<small style='margin-top: 10px; display: block'>Accepted authorization providers by the site:</small>"
            body += "<div style='background-color: #F7F7F7; margin-right: -30px'>"
            for domain in more_domains:
                body += _(u"""
                 <a href='/{domain}' onclick='wrapper.gotoSite(this)' class='select'>
                  <small style='float: right; margin-right: 40px; margin-top: -1px'>{_[Register]} &raquo;</small>{domain}
                 </a>
                """)
            body += "</div>"

        body += """
            <script>
             $(".notification .select.cert").on("click", function() {
                $(".notification .select").removeClass('active')
                wrapper.ws.cmd('certSet', [this.title])
                return false
             })
            </script>
        """

        # Send the notification
        self.cmd("notification", ["ask", body])
Beispiel #4
0
    def actionCertSelect(self, to, accepted_domains=[], accept_any=False, accepted_pattern=None):
        accounts = []
        accounts.append(["", _["No certificate"], ""])  # Default option
        active = ""  # Make it active if no other option found

        # Add my certs
        auth_address = self.user.getAuthAddress(self.site.address)  # Current auth address
        site_data = self.user.getSiteData(self.site.address)  # Current auth address

        if not accepted_domains and not accepted_pattern:  # Accept any if no filter defined
            accept_any = True

        for domain, cert in self.user.certs.items():
            if auth_address == cert["auth_address"] and domain == site_data.get("cert"):
                active = domain
            title = cert["auth_user_name"] + "@" + domain
            accepted_pattern_match = accepted_pattern and SafeRe.match(accepted_pattern, domain)
            if domain in accepted_domains or accept_any or accepted_pattern_match:
                accounts.append([domain, title, ""])
            else:
                accounts.append([domain, title, "disabled"])

        # Render the html
        body = "<span style='padding-bottom: 5px; display: inline-block'>" + _["Select account you want to use in this site:"] + "</span>"
        # Accounts
        for domain, account, css_class in accounts:
            if domain == active:
                css_class += " active"  # Currently selected option
                title = _(u"<b>%s</b> <small>({_[currently selected]})</small>") % account
            else:
                title = "<b>%s</b>" % account
            body += "<a href='#Select+account' class='select select-close cert %s' title='%s'>%s</a>" % (css_class, domain, title)
        # More available  providers
        more_domains = [domain for domain in accepted_domains if domain not in self.user.certs]  # Domains we not displayed yet
        if more_domains:
            # body+= "<small style='margin-top: 10px; display: block'>Accepted authorization providers by the site:</small>"
            body += "<div style='background-color: #F7F7F7; margin-right: -30px'>"
            for domain in more_domains:
                body += _(u"""
                 <a href='/{domain}' onclick='zeroframe.certSelectGotoSite(this)' class='select'>
                  <small style='float: right; margin-right: 40px; margin-top: -1px'>{_[Register]} &raquo;</small>{domain}
                 </a>
                """)
            body += "</div>"

        body += """
            <script>
             $(".notification .select.cert").on("click", function() {
                $(".notification .select").removeClass('active')
                zeroframe.response(%s, this.title)
                return false
             })
            </script>
        """ % self.next_message_id

        # Send the notification
        self.cmd("notification", ["ask", body], lambda domain: self.actionCertSet(to, domain))
Beispiel #5
0
    def addHomepageNotifications(self):
        if not(self.hasPlugin("Multiuser")) and not(self.hasPlugin("UiPassword")):
            bind_ip = getattr(config, "ui_ip", "")
            whitelist = getattr(config, "ui_restrict", [])
            # binds to the Internet, no IP whitelist, no UiPassword, no Multiuser
            if ("0.0.0.0" == bind_ip or "*" == bind_ip) and (not whitelist):
                self.site.notifications.append([
                    "error",
                    _(u"You are not going to set up a public gateway. However, <b>your Web UI is<br>" + \
                        "open to the whole Internet.</b> " + \
                        "Please check your configuration.")
                ])

        file_server = sys.modules["main"].file_server
        if file_server.port_opened is True:
            self.site.notifications.append([
                "done",
                _["Congratulations, your port <b>{0}</b> is opened.<br>You are a full member of the ZeroNet network!"].format(config.fileserver_port),
                10000
            ])
        elif config.tor == "always" and file_server.tor_manager.start_onions:
            self.site.notifications.append([
                "done",
                _(u"""
                {_[Tor mode active, every connection using Onion route.]}<br>
                {_[Successfully started Tor onion hidden services.]}
                """),
                10000
            ])
        elif config.tor == "always" and file_server.tor_manager.start_onions is not False:
            self.site.notifications.append([
                "error",
                _(u"""
                {_[Tor mode active, every connection using Onion route.]}<br>
                {_[Unable to start hidden services, please check your config.]}
                """),
                0
            ])
        elif file_server.port_opened is False and file_server.tor_manager.start_onions:
            self.site.notifications.append([
                "done",
                _(u"""
                {_[Successfully started Tor onion hidden services.]}<br>
                {_[For faster connections open <b>{0}</b> port on your router.]}
                """).format(config.fileserver_port),
                10000
            ])
        else:
            self.site.notifications.append([
                "error",
                _(u"""
                {_[Your connection is restricted. Please, open <b>{0}</b> port on your router]}<br>
                {_[or configure Tor to become a full member of the ZeroNet network.]}
                """).format(config.fileserver_port),
                0
            ])
Beispiel #6
0
    def addHomepageNotifications(self):
        if not(self.hasPlugin("Multiuser")) and not(self.hasPlugin("UiPassword")):
            bind_ip = getattr(config, "ui_ip", "")
            whitelist = getattr(config, "ui_restrict", [])
            # binds to the Internet, no IP whitelist, no UiPassword, no Multiuser
            if ("0.0.0.0" == bind_ip or "*" == bind_ip) and (not whitelist):
                self.site.notifications.append([
                    "error",
                    _(u"You are not going to set up a public gateway. However, <b>your Web UI is<br>" +
                        "open to the whole Internet.</b> " +
                        "Please check your configuration.")
                ])

        file_server = sys.modules["main"].file_server
        if file_server.port_opened is True:
            self.site.notifications.append([
                "done",
                _["Congratulations, your port <b>{0}</b> is opened.<br>You are a full member of the ZeroNet network!"].format(config.fileserver_port),
                10000
            ])
        elif config.tor == "always" and file_server.tor_manager.start_onions:
            self.site.notifications.append([
                "done",
                _(u"""
                {_[Tor mode active, every connection using Onion route.]}<br>
                {_[Successfully started Tor onion hidden services.]}
                """),
                10000
            ])
        elif config.tor == "always" and file_server.tor_manager.start_onions is not False:
            self.site.notifications.append([
                "error",
                _(u"""
                {_[Tor mode active, every connection using Onion route.]}<br>
                {_[Unable to start hidden services, please check your config.]}
                """),
                0
            ])
        elif file_server.port_opened is False and file_server.tor_manager.start_onions:
            self.site.notifications.append([
                "done",
                _(u"""
                {_[Successfully started Tor onion hidden services.]}<br>
                {_[For faster connections open <b>{0}</b> port on your router.]}
                """).format(config.fileserver_port),
                10000
            ])
        else:
            self.site.notifications.append([
                "error",
                _(u"""
                {_[Your connection is restricted. Please, open <b>{0}</b> port on your router]}<br>
                {_[or configure Tor to become a full member of the ZeroNet network.]}
                """).format(config.fileserver_port),
                0
            ])
Beispiel #7
0
    def actionCertSelect(self, to, accepted_domains=[], accept_any=False, accepted_pattern=None):
        accounts = []
        accounts.append(["", _["No certificate"], ""])  # Default option
        active = ""  # Make it active if no other option found

        # Add my certs
        auth_address = self.user.getAuthAddress(self.site.address)  # Current auth address
        site_data = self.user.getSiteData(self.site.address)  # Current auth address

        if not accepted_domains and not accepted_pattern:  # Accept any if no filter defined
            accept_any = True

        for domain, cert in self.user.certs.items():
            if auth_address == cert["auth_address"] and domain == site_data.get("cert"):
                active = domain
            title = cert["auth_user_name"] + "@" + domain
            accepted_pattern_match = accepted_pattern and SafeRe.match(accepted_pattern, domain)
            if domain in accepted_domains or accept_any or accepted_pattern_match:
                accounts.append([domain, title, ""])
            else:
                accounts.append([domain, title, "disabled"])

        # Render the html
        body = "<span style='padding-bottom: 5px; display: inline-block'>" + _["Select account you want to use in this site:"] + "</span>"
        # Accounts
        for domain, account, css_class in accounts:
            if domain == active:
                css_class += " active"  # Currently selected option
                title = _(u"<b>%s</b> <small>({_[currently selected]})</small>") % account
            else:
                title = "<b>%s</b>" % account
            body += "<a href='#Select+account' class='select select-close cert %s' title='%s'>%s</a>" % (css_class, domain, title)
        # More available  providers
        more_domains = [domain for domain in accepted_domains if domain not in self.user.certs]  # Domains we not displayed yet
        if more_domains:
            # body+= "<small style='margin-top: 10px; display: block'>Accepted authorization providers by the site:</small>"
            body += "<div style='background-color: #F7F7F7; margin-right: -30px'>"
            for domain in more_domains:
                body += _(u"""
                 <a href='/{domain}' target='_top' class='select'>
                  <small style='float: right; margin-right: 40px; margin-top: -1px'>{_[Register]} &raquo;</small>{domain}
                 </a>
                """)
            body += "</div>"

        script = """
             $(".notification .select.cert").on("click", function() {
                $(".notification .select").removeClass('active')
                zeroframe.response(%s, this.title)
                return false
             })
        """ % self.next_message_id

        self.cmd("notification", ["ask", body], lambda domain: self.actionCertSet(to, domain))
        self.cmd("injectScript", script)
Beispiel #8
0
    def actionCertSelect(self, to, accepted_domains=[], accept_any=False):
        accounts = []
        accounts.append(["", _["Unique to site"], ""])  # Default option
        active = ""  # Make it active if no other option found

        # Add my certs
        auth_address = self.user.getAuthAddress(self.site.address)  # Current auth address
        site_data = self.user.getSiteData(self.site.address)  # Current auth address
        for domain, cert in self.user.certs.items():
            if auth_address == cert["auth_address"] and domain == site_data.get("cert"):
                active = domain
            title = cert["auth_user_name"] + "@" + domain
            if domain in accepted_domains or not accepted_domains or accept_any:
                accounts.append([domain, title, ""])
            else:
                accounts.append([domain, title, "disabled"])

        # Render the html
        body = "<span style='padding-bottom: 5px; display: inline-block'>" + _["Select account you want to use in this site:"] + "</span>"
        # Accounts
        for domain, account, css_class in accounts:
            if domain == active:
                css_class += " active"  # Currently selected option
                title = _(u"<b>%s</b> <small>({_[currently selected]})</small>") % account
            else:
                title = "<b>%s</b>" % account
            body += "<a href='#Select+account' class='select select-close cert %s' title='%s'>%s</a>" % (css_class, domain, title)
        # More available  providers
        more_domains = [domain for domain in accepted_domains if domain not in self.user.certs]  # Domains we not displayed yet
        if more_domains:
            # body+= "<small style='margin-top: 10px; display: block'>Accepted authorization providers by the site:</small>"
            body += "<div style='background-color: #F7F7F7; margin-right: -30px'>"
            for domain in more_domains:
                body += _(u"""
                 <a href='/{domain}' onclick='wrapper.gotoSite(this)' class='select'>
                  <small style='float: right; margin-right: 40px; margin-top: -1px'>{_[Register]} &raquo;</small>{domain}
                 </a>
                """)
            body += "</div>"

        body += """
            <script>
             $(".notification .select.cert").on("click", function() {
                $(".notification .select").removeClass('active')
                wrapper.ws.cmd('certSet', [this.title], function() {
                    wrapper.sendInner({"cmd": "response", "to": %s, "result": this.title})
                })
                return false
             })
            </script>
        """ % to

        # Send the notification
        self.cmd("notification", ["ask", body])
Beispiel #9
0
    def cbSitePublish(self, to, site, thread, notification=True, callback=True):
        published = thread.value
        if published > 0:  # Successfully published
            if notification:
                # self.cmd("notification", ["done", _["Content published to {0} peers."].format(published), 5000])
                site.updateWebsocket()  # Send updated site data to local websocket clients
            if callback:
                self.response(to, "ok")
        else:
            if len(site.peers) == 0:
                if sys.modules["main"].file_server.port_opened or sys.modules["main"].file_server.tor_manager.start_onions:
                    if notification:
                        self.cmd("notification", ["info", _["No peers found, but your content is ready to access."]])
                    if callback:
                        self.response(to, "ok")
                else:
                    if notification:
                        self.cmd("notification", [
                            "info",
                            _(u"""{_[Your network connection is restricted. Please, open <b>{0}</b> port]}<br>
                            {_[on your router to make your site accessible for everyone.]}""").format(config.fileserver_port)
                        ])
                    if callback:
                        self.response(to, {"error": "Port not opened."})

            else:
                if notification:
                    self.response(to, {"error": "Content publish failed."})
Beispiel #10
0
    def cbSitePublish(self, to, site, thread, notification=True, callback=True):
        published = thread.value
        if published > 0:  # Successfully published
            if notification:
                # self.cmd("notification", ["done", _["Content published to {0} peers."].format(published), 5000])
                site.updateWebsocket()  # Send updated site data to local websocket clients
            if callback:
                self.response(to, "ok")
        else:
            if len(site.peers) == 0:
                if sys.modules["main"].file_server.port_opened or sys.modules["main"].file_server.tor_manager.start_onions:
                    if notification:
                        self.cmd("notification", ["info", _["No peers found, but your content is ready to access."]])
                    if callback:
                        self.response(to, "ok")
                else:
                    if notification:
                        self.cmd("notification", [
                            "info",
                            _(u"""{_[Your network connection is restricted. Please, open <b>{0}</b> port]}<br>
                            {_[on your router to make your site accessible for everyone.]}""").format(config.fileserver_port)
                        ])
                    if callback:
                        self.response(to, {"error": "Port not opened."})

            else:
                if notification:
                    self.response(to, {"error": "Content publish failed."})
Beispiel #11
0
 def hasCmdPermission(self, cmd):
     flags = flag.db.get(self.getCmdFuncName(cmd), ())
     is_public_proxy_user = not config.multiuser_local and self.user.master_address not in local_master_addresses
     if is_public_proxy_user and "no_multiuser" in flags:
         self.cmd("notification", ["info", _("This function ({cmd}) is disabled on this proxy!")])
         return False
     else:
         return super(UiWebsocketPlugin, self).hasCmdPermission(cmd)
Beispiel #12
0
 def cbCertAddConfirm(self, to, domain, auth_type, auth_user_name, cert):
     self.user.deleteCert(domain)
     self.user.addCert(self.user.getAuthAddress(self.site.address), domain, auth_type, auth_user_name, cert)
     self.cmd(
         "notification",
         ["done", _("Certificate changed to: <b>{auth_type}/{auth_user_name}@{domain}</b>.")]
     )
     self.response(to, "ok")
Beispiel #13
0
    def start(self):
        ws = self.ws
        if self.site.address == config.homepage and not self.site.page_requested:
            # Add open fileserver port message or closed port error to homepage at first request after start
            self.site.page_requested = True  # Dont add connection notification anymore
            file_server = sys.modules["main"].file_server
            if file_server.port_opened is None or file_server.tor_manager.start_onions is None:
                self.site.page_requested = False  # Not ready yet, check next time
            elif file_server.port_opened is True:
                self.site.notifications.append([
                    "done",
                    _["Congratulation, your port <b>{0}</b> is opened.<br>You are full member of ZeroNet network!"]
                    .format(config.fileserver_port), 10000
                ])
            elif config.tor == "always" and file_server.tor_manager.start_onions:
                self.site.notifications.append([
                    "done",
                    _(u"""
                    {_[Tor mode active, every connection using Onion route.]}<br>
                    {_[Successfully started Tor onion hidden services.]}
                    """), 10000
                ])
            elif config.tor == "always" and file_server.tor_manager.start_onions is not False:
                self.site.notifications.append([
                    "error",
                    _(u"""
                    {_[Tor mode active, every connection using Onion route.]}<br>
                    {_[Unable to start hidden services, please check your config.]}
                    """), 0
                ])
            elif file_server.port_opened is False and file_server.tor_manager.start_onions:
                self.site.notifications.append([
                    "done",
                    _(u"""
                    {_[Successfully started Tor onion hidden services.]}<br>
                    {_[For faster connections open <b>{0}</b> port on your router.]}
                    """).format(config.fileserver_port), 10000
                ])
            else:
                self.site.notifications.append([
                    "error",
                    _(u"""
                    {_[Your connection is restricted. Please, open <b>{0}</b> port on your router]}<br>
                    {_[or configure Tor to become full member of ZeroNet network.]}
                    """).format(config.fileserver_port), 0
                ])

        for notification in self.site.notifications:  # Send pending notification messages
            self.cmd("notification", notification)
        self.site.notifications = []
        while True:
            try:
                message = ws.receive()
            except Exception, err:
                return "Bye."  # Close connection

            if message:
                try:
                    self.handleRequest(message)
                except Exception, err:
                    if config.debug:  # Allow websocket errors to appear on /Debug
                        sys.modules["main"].DebugHook.handleError()
                    self.log.error("WebSocket handleRequest error: %s" %
                                   Debug.formatException(err))
                    self.cmd(
                        "error", "Internal error: %s" %
                        Debug.formatException(err, "html"))
Beispiel #14
0
    def start(self):
        ws = self.ws
        if self.site.address == config.homepage and not self.site.page_requested:
            # Add open fileserver port message or closed port error to homepage at first request after start
            self.site.page_requested = True  # Dont add connection notification anymore
            file_server = sys.modules["main"].file_server
            if file_server.port_opened is None or file_server.tor_manager.start_onions is None:
                self.site.page_requested = False  # Not ready yet, check next time
            elif file_server.port_opened is True:
                self.site.notifications.append([
                    "done",
                    _["Congratulation, your port <b>{0}</b> is opened.<br>You are full member of ZeroNet network!"].format(config.fileserver_port),
                    10000
                ])
            elif config.tor == "always" and file_server.tor_manager.start_onions:
                self.site.notifications.append([
                    "done",
                    _(u"""
                    {_[Tor mode active, every connection using Onion route.]}<br>
                    {_[Successfully started Tor onion hidden services.]}
                    """),
                    10000
                ])
            elif config.tor == "always" and file_server.tor_manager.start_onions is not False:
                self.site.notifications.append([
                    "error",
                    _(u"""
                    {_[Tor mode active, every connection using Onion route.]}<br>
                    {_[Unable to start hidden services, please check your config.]}
                    """),
                    0
                ])
            elif file_server.port_opened is False and file_server.tor_manager.start_onions:
                self.site.notifications.append([
                    "done",
                    _(u"""
                    {_[Successfully started Tor onion hidden services.]}<br>
                    {_[For faster connections open <b>{0}</b> port on your router.]}
                    """).format(config.fileserver_port),
                    10000
                ])
            else:
                self.site.notifications.append([
                    "error",
                    _(u"""
                    {_[Your connection is restricted. Please, open <b>{0}</b> port on your router]}<br>
                    {_[or configure Tor to become full member of ZeroNet network.]}
                    """).format(config.fileserver_port),
                    0
                ])

        for notification in self.site.notifications:  # Send pending notification messages
            self.cmd("notification", notification)
        self.site.notifications = []
        while True:
            try:
                message = ws.receive()
            except Exception, err:
                return "Bye."  # Close connection

            if message:
                try:
                    self.handleRequest(message)
                except Exception, err:
                    if config.debug:  # Allow websocket errors to appear on /Debug
                        sys.modules["main"].DebugHook.handleError()
                    self.log.error("WebSocket handleRequest error: %s" % Debug.formatException(err))
                    self.cmd("error", "Internal error: %s" % Debug.formatException(err, "html"))
Beispiel #15
0
    def deleteFiles(self):
        site_title = self.site.content_manager.contents.get(
            "content.json", {}).get("title", self.site.address)
        message_id = "delete-%s" % self.site.address
        self.log.debug("Deleting files from content.json (title: %s)..." %
                       site_title)

        files = []  # Get filenames
        content_inner_paths = list(self.site.content_manager.contents.keys())
        for i, content_inner_path in enumerate(content_inner_paths):
            content = self.site.content_manager.contents.get(
                content_inner_path, {})
            files.append(content_inner_path)
            # Add normal files
            for file_relative_path in list(content.get("files", {}).keys()):
                file_inner_path = helper.getDirname(
                    content_inner_path
                ) + file_relative_path  # Relative to site dir
                files.append(file_inner_path)
            # Add optional files
            for file_relative_path in list(
                    content.get("files_optional", {}).keys()):
                file_inner_path = helper.getDirname(
                    content_inner_path
                ) + file_relative_path  # Relative to site dir
                files.append(file_inner_path)

            if i % 100 == 0:
                num_files = len(files)
                self.site.messageWebsocket(
                    _("Deleting site <b>{site_title}</b>...<br>Collected {num_files} files"
                      ), message_id, (i / len(content_inner_paths)) * 25)

        if self.isFile("dbschema.json"):
            self.log.debug("Deleting db file...")
            self.closeDb("Deleting site")
            self.has_db = False
            try:
                schema = self.loadJson("dbschema.json")
                db_path = self.getPath(schema["db_file"])
                if os.path.isfile(db_path):
                    os.unlink(db_path)
            except Exception as err:
                self.log.error("Db file delete error: %s" % err)

        num_files = len(files)
        for i, inner_path in enumerate(files):
            path = self.getPath(inner_path)
            if os.path.isfile(path):
                for retry in range(5):
                    try:
                        os.unlink(path)
                        break
                    except Exception as err:
                        self.log.error("Error removing %s: %s, try #%s" %
                                       (inner_path, err, retry))
                    time.sleep(float(retry) / 10)
            if i % 100 == 0:
                self.site.messageWebsocket(
                    _("Deleting site <b>{site_title}</b>...<br>Deleting file {i}/{num_files}"
                      ), message_id, 25 + (i / num_files) * 50)
            self.onUpdated(inner_path, False)

        self.log.debug("Deleting empty dirs...")
        i = 0
        for root, dirs, files in os.walk(self.directory, topdown=False):
            for dir in dirs:
                path = os.path.join(root, dir)
                if os.path.isdir(path):
                    try:
                        i += 1
                        if i % 100 == 0:
                            self.site.messageWebsocket(
                                _("Deleting site <b>{site_title}</b>...<br>Deleting empty directories {i}"
                                  ), message_id, 85)
                        os.rmdir(path)
                    except OSError:  # Not empty
                        pass

        if os.path.isdir(self.directory) and os.listdir(self.directory) == []:
            os.rmdir(self.directory)  # Remove sites directory if empty

        if os.path.isdir(self.directory):
            self.log.debug(
                "Some unknown file remained in site data dir: %s..." %
                self.directory)
            self.site.messageWebsocket(
                _("Deleting site <b>{site_title}</b>...<br>Site deleted, but some unknown files left in the directory"
                  ), message_id, 100)
            return False  # Some files not deleted
        else:
            self.log.debug("Site %s data directory deleted: %s..." %
                           (site_title, self.directory))

            self.site.messageWebsocket(
                _("Deleting site <b>{site_title}</b>...<br>All files deleted successfully"
                  ), message_id, 100)

            return True  # All clean